Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: xilinx-trng - Add CTR_DRBG DF processing of seed

Versal TRNG IP does not support Derivation Function (DF) of seed.
Add DF processing for CTR_DRBG mode.

Signed-off-by: Harsh Jain <h.jain@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Harsh Jain and committed by
Herbert Xu
1a098379 ba0570bd

+31 -6
+31 -6
drivers/crypto/xilinx/xilinx-trng.c
··· 8 8 #include <linux/clk.h> 9 9 #include <linux/crypto.h> 10 10 #include <linux/delay.h> 11 - #include <linux/errno.h> 12 11 #include <linux/firmware/xlnx-zynqmp.h> 13 12 #include <linux/hw_random.h> 14 13 #include <linux/io.h> ··· 17 18 #include <linux/mutex.h> 18 19 #include <linux/mod_devicetable.h> 19 20 #include <linux/platform_device.h> 20 - #include <linux/string.h> 21 + #include <crypto/aes.h> 22 + #include <crypto/df_sp80090a.h> 23 + #include <crypto/internal/drbg.h> 21 24 #include <crypto/internal/cipher.h> 22 25 #include <crypto/internal/rng.h> 23 - #include <crypto/aes.h> 24 26 25 27 /* TRNG Registers Offsets */ 26 28 #define TRNG_STATUS_OFFSET 0x4U ··· 59 59 struct xilinx_rng { 60 60 void __iomem *rng_base; 61 61 struct device *dev; 62 + unsigned char *scratchpadbuf; 63 + struct crypto_aes_ctx *aesctx; 62 64 struct mutex lock; /* Protect access to TRNG device */ 63 65 struct hwrng trng; 64 66 }; ··· 184 182 static int xtrng_reseed_internal(struct xilinx_rng *rng) 185 183 { 186 184 u8 entropy[TRNG_ENTROPY_SEED_LEN_BYTES]; 185 + struct drbg_string data; 186 + LIST_HEAD(seedlist); 187 187 u32 val; 188 188 int ret; 189 189 190 + drbg_string_fill(&data, entropy, TRNG_SEED_LEN_BYTES); 191 + list_add_tail(&data.list, &seedlist); 190 192 memset(entropy, 0, sizeof(entropy)); 191 193 xtrng_enable_entropy(rng); 192 194 ··· 198 192 ret = xtrng_collect_random_data(rng, entropy, TRNG_SEED_LEN_BYTES, true); 199 193 if (ret != TRNG_SEED_LEN_BYTES) 200 194 return -EINVAL; 195 + ret = crypto_drbg_ctr_df(rng->aesctx, rng->scratchpadbuf, 196 + TRNG_SEED_LEN_BYTES, &seedlist, AES_BLOCK_SIZE, 197 + TRNG_SEED_LEN_BYTES); 198 + if (ret) 199 + return ret; 201 200 202 201 xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, 203 - (u32 *)entropy, TRNG_NUM_INIT_REGS); 202 + (u32 *)rng->scratchpadbuf, TRNG_NUM_INIT_REGS); 204 203 /* select reseed operation */ 205 204 iowrite32(TRNG_CTRL_PRNGXS_MASK, rng->rng_base + TRNG_CTRL_OFFSET); 206 205 ··· 335 324 static int xtrng_probe(struct platform_device *pdev) 336 325 { 337 326 struct xilinx_rng *rng; 327 + size_t sb_size; 338 328 int ret; 339 329 340 330 rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); ··· 349 337 return PTR_ERR(rng->rng_base); 350 338 } 351 339 340 + rng->aesctx = devm_kzalloc(&pdev->dev, sizeof(*rng->aesctx), GFP_KERNEL); 341 + if (!rng->aesctx) 342 + return -ENOMEM; 343 + 344 + sb_size = crypto_drbg_ctr_df_datalen(TRNG_SEED_LEN_BYTES, AES_BLOCK_SIZE); 345 + rng->scratchpadbuf = devm_kzalloc(&pdev->dev, sb_size, GFP_KERNEL); 346 + if (!rng->scratchpadbuf) { 347 + ret = -ENOMEM; 348 + goto end; 349 + } 350 + 352 351 xtrng_trng_reset(rng->rng_base); 353 352 ret = xtrng_reseed_internal(rng); 354 353 if (ret) { 355 354 dev_err(&pdev->dev, "TRNG Seed fail\n"); 356 - return ret; 355 + goto end; 357 356 } 358 357 359 358 xilinx_rng_dev = rng; ··· 372 349 ret = crypto_register_rng(&xtrng_trng_alg); 373 350 if (ret) { 374 351 dev_err(&pdev->dev, "Crypto Random device registration failed: %d\n", ret); 375 - return ret; 352 + goto end; 376 353 } 354 + 377 355 ret = xtrng_hwrng_register(&rng->trng); 378 356 if (ret) { 379 357 dev_err(&pdev->dev, "HWRNG device registration failed: %d\n", ret); ··· 387 363 crypto_rng_free: 388 364 crypto_unregister_rng(&xtrng_trng_alg); 389 365 366 + end: 390 367 return ret; 391 368 } 392 369