Lines Matching +full:rng +full:-

1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc.
11 #include <linux/firmware/xlnx-zynqmp.h>
24 #include <crypto/internal/rng.h>
69 struct xilinx_rng *rng; member
98 static void xtrng_softreset(struct xilinx_rng *rng) in xtrng_softreset() argument
100 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, in xtrng_softreset()
103 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, 0); in xtrng_softreset()
133 static int xtrng_collect_random_data(struct xilinx_rng *rng, u8 *rand_gen_buf, in xtrng_collect_random_data() argument
140 byteleft = no_of_random_bytes & (TRNG_SEC_STRENGTH_BYTES - 1); in xtrng_collect_random_data()
142 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, in xtrng_collect_random_data()
145 ret = xtrng_readblock32(rng->rng_base, (__be32 *)rand_gen_buf, blocks, wait); in xtrng_collect_random_data()
152 ret = xtrng_readblock32(rng->rng_base, (__be32 *)randbuf, 1, wait); in xtrng_collect_random_data()
159 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, in xtrng_collect_random_data()
172 reg_addr = (base_addr + ((n - 1 - i) * TRNG_BYTES_PER_REG)); in xtrng_write_multiple_registers()
177 static void xtrng_enable_entropy(struct xilinx_rng *rng) in xtrng_enable_entropy() argument
179 iowrite32(TRNG_OSC_EN_VAL_MASK, rng->rng_base + TRNG_OSC_EN_OFFSET); in xtrng_enable_entropy()
180 xtrng_softreset(rng); in xtrng_enable_entropy()
181 iowrite32(TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK, rng->rng_base + TRNG_CTRL_OFFSET); in xtrng_enable_entropy()
184 static int xtrng_reseed_internal(struct xilinx_rng *rng) in xtrng_reseed_internal() argument
195 xtrng_enable_entropy(rng); in xtrng_reseed_internal()
198 ret = xtrng_collect_random_data(rng, entropy, TRNG_SEED_LEN_BYTES, true); in xtrng_reseed_internal()
200 return -EINVAL; in xtrng_reseed_internal()
201 ret = crypto_drbg_ctr_df(rng->aesctx, rng->scratchpadbuf, in xtrng_reseed_internal()
207 xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, in xtrng_reseed_internal()
208 (u32 *)rng->scratchpadbuf, TRNG_NUM_INIT_REGS); in xtrng_reseed_internal()
210 iowrite32(TRNG_CTRL_PRNGXS_MASK, rng->rng_base + TRNG_CTRL_OFFSET); in xtrng_reseed_internal()
213 * set. Monitor STATUS.CERTF bit, if set indicates SP800-90B entropy health test has failed. in xtrng_reseed_internal()
215 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, in xtrng_reseed_internal()
218 ret = readl_poll_timeout(rng->rng_base + TRNG_STATUS_OFFSET, val, in xtrng_reseed_internal()
224 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, 0U); in xtrng_reseed_internal()
229 static int xtrng_random_bytes_generate(struct xilinx_rng *rng, u8 *rand_buf_ptr, in xtrng_random_bytes_generate() argument
235 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, in xtrng_random_bytes_generate()
238 nbytes = xtrng_collect_random_data(rng, rand_buf_ptr, rand_buf_size, wait); in xtrng_random_bytes_generate()
240 ret = xtrng_reseed_internal(rng); in xtrng_random_bytes_generate()
242 dev_err(rng->dev, "Re-seed fail\n"); in xtrng_random_bytes_generate()
255 mutex_lock(&ctx->rng->lock); in xtrng_trng_generate()
256 ret = xtrng_random_bytes_generate(ctx->rng, dst, dlen, true); in xtrng_trng_generate()
257 mutex_unlock(&ctx->rng->lock); in xtrng_trng_generate()
271 ctx->rng = xilinx_rng_dev; in xtrng_trng_init()
282 .cra_driver_name = "xilinx-trng",
293 struct xilinx_rng *rng; in xtrng_hwrng_trng_read() local
294 int ret = -EINVAL, i = 0; in xtrng_hwrng_trng_read()
296 rng = container_of(hwrng, struct xilinx_rng, trng); in xtrng_hwrng_trng_read()
298 if (!mutex_trylock(&rng->lock) && !wait) in xtrng_hwrng_trng_read()
300 else if (!mutex_is_locked(&rng->lock) && wait) in xtrng_hwrng_trng_read()
301 mutex_lock(&rng->lock); in xtrng_hwrng_trng_read()
304 ret = xtrng_random_bytes_generate(rng, buf, TRNG_SEC_STRENGTH_BYTES, wait); in xtrng_hwrng_trng_read()
308 memcpy(data + i, buf, min_t(int, ret, (max - i))); in xtrng_hwrng_trng_read()
309 i += min_t(int, ret, (max - i)); in xtrng_hwrng_trng_read()
311 mutex_unlock(&rng->lock); in xtrng_hwrng_trng_read()
320 trng->name = "Xilinx Versal Crypto Engine TRNG"; in xtrng_hwrng_register()
321 trng->read = xtrng_hwrng_trng_read; in xtrng_hwrng_register()
337 struct xilinx_rng *rng; in xtrng_probe() local
341 rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); in xtrng_probe()
342 if (!rng) in xtrng_probe()
343 return -ENOMEM; in xtrng_probe()
345 rng->dev = &pdev->dev; in xtrng_probe()
346 rng->rng_base = devm_platform_ioremap_resource(pdev, 0); in xtrng_probe()
347 if (IS_ERR(rng->rng_base)) { in xtrng_probe()
348 dev_err(&pdev->dev, "Failed to map resource %pe\n", rng->rng_base); in xtrng_probe()
349 return PTR_ERR(rng->rng_base); in xtrng_probe()
352 rng->aesctx = devm_kzalloc(&pdev->dev, sizeof(*rng->aesctx), GFP_KERNEL); in xtrng_probe()
353 if (!rng->aesctx) in xtrng_probe()
354 return -ENOMEM; in xtrng_probe()
357 rng->scratchpadbuf = devm_kzalloc(&pdev->dev, sb_size, GFP_KERNEL); in xtrng_probe()
358 if (!rng->scratchpadbuf) { in xtrng_probe()
359 ret = -ENOMEM; in xtrng_probe()
363 xtrng_trng_reset(rng->rng_base); in xtrng_probe()
364 ret = xtrng_reseed_internal(rng); in xtrng_probe()
366 dev_err(&pdev->dev, "TRNG Seed fail\n"); in xtrng_probe()
370 xilinx_rng_dev = rng; in xtrng_probe()
371 mutex_init(&rng->lock); in xtrng_probe()
374 dev_err(&pdev->dev, "Crypto Random device registration failed: %d\n", ret); in xtrng_probe()
378 ret = xtrng_hwrng_register(&rng->trng); in xtrng_probe()
380 dev_err(&pdev->dev, "HWRNG device registration failed: %d\n", ret); in xtrng_probe()
383 platform_set_drvdata(pdev, rng); in xtrng_probe()
396 struct xilinx_rng *rng; in xtrng_remove() local
399 rng = platform_get_drvdata(pdev); in xtrng_remove()
400 xtrng_hwrng_unregister(&rng->trng); in xtrng_remove()
402 xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, zero, in xtrng_remove()
404 xtrng_write_multiple_registers(rng->rng_base + TRNG_PER_STRNG_OFFSET, zero, in xtrng_remove()
406 xtrng_hold_reset(rng->rng_base); in xtrng_remove()
411 { .compatible = "xlnx,versal-trng", },
419 .name = "xlnx,versal-trng",