1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * AMD Versal True Random Number Generator driver 4 * Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. 5 */ 6 7 #include <crypto/sha2.h> 8 #include <linux/bitfield.h> 9 #include <linux/clk.h> 10 #include <linux/delay.h> 11 #include <linux/firmware/xlnx-zynqmp.h> 12 #include <linux/hw_random.h> 13 #include <linux/io.h> 14 #include <linux/iopoll.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/platform_device.h> 18 19 /* TRNG Registers Offsets */ 20 #define TRNG_STATUS_OFFSET 0x4U 21 #define TRNG_CTRL_OFFSET 0x8U 22 #define TRNG_EXT_SEED_OFFSET 0x40U 23 #define TRNG_PER_STRNG_OFFSET 0x80U 24 #define TRNG_CORE_OUTPUT_OFFSET 0xC0U 25 #define TRNG_RESET_OFFSET 0xD0U 26 #define TRNG_OSC_EN_OFFSET 0xD4U 27 28 /* Mask values */ 29 #define TRNG_RESET_VAL_MASK BIT(0) 30 #define TRNG_OSC_EN_VAL_MASK BIT(0) 31 #define TRNG_CTRL_PRNGSRST_MASK BIT(0) 32 #define TRNG_CTRL_EUMODE_MASK BIT(8) 33 #define TRNG_CTRL_TRSSEN_MASK BIT(2) 34 #define TRNG_CTRL_PRNGSTART_MASK BIT(5) 35 #define TRNG_CTRL_PRNGXS_MASK BIT(3) 36 #define TRNG_CTRL_PRNGMODE_MASK BIT(7) 37 #define TRNG_STATUS_DONE_MASK BIT(0) 38 #define TRNG_STATUS_QCNT_MASK GENMASK(11, 9) 39 #define TRNG_STATUS_QCNT_16_BYTES 0x800 40 41 /* Sizes in bytes */ 42 #define TRNG_SEED_LEN_BYTES 48U 43 #define TRNG_SEC_STRENGTH_SHIFT 5U 44 #define TRNG_SEC_STRENGTH_BYTES BIT(TRNG_SEC_STRENGTH_SHIFT) 45 #define TRNG_BYTES_PER_REG 4U 46 #define TRNG_RESET_DELAY 10 47 #define TRNG_NUM_INIT_REGS 12U 48 #define TRNG_READ_4_WORD 4 49 #define TRNG_DATA_READ_DELAY 8000 50 51 struct xilinx_rng { 52 void __iomem *rng_base; 53 struct device *dev; 54 struct hwrng trng; 55 }; 56 57 static void xtrng_readwrite32(void __iomem *addr, u32 mask, u8 value) 58 { 59 u32 val; 60 61 val = ioread32(addr); 62 val = (val & (~mask)) | (mask & value); 63 iowrite32(val, addr); 64 } 65 66 static void xtrng_trng_reset(void __iomem *addr) 67 { 68 xtrng_readwrite32(addr + TRNG_RESET_OFFSET, TRNG_RESET_VAL_MASK, TRNG_RESET_VAL_MASK); 69 udelay(TRNG_RESET_DELAY); 70 xtrng_readwrite32(addr + TRNG_RESET_OFFSET, TRNG_RESET_VAL_MASK, 0); 71 } 72 73 static void xtrng_hold_reset(void __iomem *addr) 74 { 75 xtrng_readwrite32(addr + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, 76 TRNG_CTRL_PRNGSRST_MASK); 77 iowrite32(TRNG_RESET_VAL_MASK, addr + TRNG_RESET_OFFSET); 78 udelay(TRNG_RESET_DELAY); 79 } 80 81 static void xtrng_softreset(struct xilinx_rng *rng) 82 { 83 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, 84 TRNG_CTRL_PRNGSRST_MASK); 85 udelay(TRNG_RESET_DELAY); 86 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, 0); 87 } 88 89 /* Return no. of bytes read or a negative error before any data is read. */ 90 static int xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks32, bool wait) 91 { 92 int read = 0, ret; 93 int timeout = 1; 94 int i, idx; 95 u32 val; 96 97 if (wait) 98 timeout = TRNG_DATA_READ_DELAY; 99 100 for (i = 0; i < (blocks32 * 2); i++) { 101 /* TRNG core generate data in 16 bytes. Read twice to complete 32 bytes read */ 102 ret = readl_poll_timeout(rng_base + TRNG_STATUS_OFFSET, val, 103 (val & TRNG_STATUS_QCNT_MASK) == 104 TRNG_STATUS_QCNT_16_BYTES, !!wait, timeout); 105 if (ret) { 106 if (!read) 107 return ret; 108 break; 109 } 110 111 for (idx = 0; idx < TRNG_READ_4_WORD; idx++) { 112 *(buf + read) = cpu_to_be32(ioread32(rng_base + TRNG_CORE_OUTPUT_OFFSET)); 113 read += 1; 114 } 115 } 116 return read * 4; 117 } 118 119 static int xtrng_collect_random_data(struct xilinx_rng *rng, u8 *rand_gen_buf, 120 int no_of_random_bytes, bool wait) 121 { 122 u8 randbuf[TRNG_SEC_STRENGTH_BYTES]; 123 int byteleft, blocks, count = 0; 124 int full_blocks_bytes; 125 int ret; 126 127 byteleft = no_of_random_bytes & (TRNG_SEC_STRENGTH_BYTES - 1); 128 blocks = no_of_random_bytes >> TRNG_SEC_STRENGTH_SHIFT; 129 full_blocks_bytes = blocks * TRNG_SEC_STRENGTH_BYTES; 130 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, 131 TRNG_CTRL_PRNGSTART_MASK); 132 if (blocks) { 133 ret = xtrng_readblock32(rng->rng_base, (__be32 *)rand_gen_buf, blocks, wait); 134 if (ret <= 0) { 135 count = ret; 136 goto out_stop; 137 } 138 count += ret; 139 if (ret < full_blocks_bytes) 140 goto out_stop; 141 } 142 143 if (byteleft) { 144 ret = xtrng_readblock32(rng->rng_base, (__be32 *)randbuf, 1, wait); 145 if (ret < 0) { 146 if (!count) 147 count = ret; 148 goto out_stop; 149 } 150 if (!ret) 151 goto out_stop; 152 ret = min(ret, no_of_random_bytes - count); 153 memcpy(rand_gen_buf + count, randbuf, ret); 154 count += ret; 155 } 156 157 out_stop: 158 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, 159 TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGSTART_MASK, 0U); 160 161 return count; 162 } 163 164 static void xtrng_write_multiple_registers(void __iomem *base_addr, u32 *values, size_t n) 165 { 166 void __iomem *reg_addr; 167 size_t i; 168 169 /* Write seed value into EXTERNAL_SEED Registers in big endian format */ 170 for (i = 0; i < n; i++) { 171 reg_addr = (base_addr + ((n - 1 - i) * TRNG_BYTES_PER_REG)); 172 iowrite32((u32 __force)(cpu_to_be32(values[i])), reg_addr); 173 } 174 } 175 176 static void xtrng_enable_entropy(struct xilinx_rng *rng) 177 { 178 iowrite32(TRNG_OSC_EN_VAL_MASK, rng->rng_base + TRNG_OSC_EN_OFFSET); 179 xtrng_softreset(rng); 180 iowrite32(TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK, rng->rng_base + TRNG_CTRL_OFFSET); 181 } 182 183 static int xtrng_reseed_internal(struct xilinx_rng *rng) 184 { 185 static const u8 default_salt[SHA512_DIGEST_SIZE]; 186 u8 entropy[SHA512_DIGEST_SIZE] __aligned(4); 187 u32 val; 188 int ret; 189 190 xtrng_enable_entropy(rng); 191 192 /* Collect some output from the TRNG. */ 193 static_assert(sizeof(entropy) >= TRNG_SEED_LEN_BYTES); 194 ret = xtrng_collect_random_data(rng, entropy, TRNG_SEED_LEN_BYTES, true); 195 if (ret != TRNG_SEED_LEN_BYTES) 196 return -EINVAL; 197 198 /* Extract entropy from the TRNG output using HKDF-SHA512-Extract. */ 199 hmac_sha512_usingrawkey(default_salt, sizeof(default_salt), entropy, 200 TRNG_SEED_LEN_BYTES, entropy); 201 202 /* Write the extracted entropy to the hardware. */ 203 xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, 204 (u32 *)entropy, TRNG_NUM_INIT_REGS); 205 206 /* Clear the entropy from the stack. */ 207 memzero_explicit(entropy, sizeof(entropy)); 208 209 /* select reseed operation */ 210 iowrite32(TRNG_CTRL_PRNGXS_MASK, rng->rng_base + TRNG_CTRL_OFFSET); 211 212 /* Start the reseed operation with above configuration and wait for STATUS.Done bit to be 213 * set. Monitor STATUS.CERTF bit, if set indicates SP800-90B entropy health test has failed. 214 */ 215 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, 216 TRNG_CTRL_PRNGSTART_MASK); 217 218 ret = readl_poll_timeout(rng->rng_base + TRNG_STATUS_OFFSET, val, 219 (val & TRNG_STATUS_DONE_MASK) == TRNG_STATUS_DONE_MASK, 220 1U, 15000U); 221 if (ret) 222 return ret; 223 224 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK, 0U); 225 226 return 0; 227 } 228 229 static int xtrng_random_bytes_generate(struct xilinx_rng *rng, u8 *rand_buf_ptr, 230 u32 rand_buf_size, int wait) 231 { 232 int nbytes; 233 int ret; 234 235 xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, 236 TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGXS_MASK, 237 TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGXS_MASK); 238 nbytes = xtrng_collect_random_data(rng, rand_buf_ptr, rand_buf_size, wait); 239 240 ret = xtrng_reseed_internal(rng); 241 if (ret) { 242 dev_err(rng->dev, "Re-seed fail\n"); 243 return ret; 244 } 245 246 return nbytes; 247 } 248 249 static int xtrng_hwrng_trng_read(struct hwrng *hwrng, void *data, size_t max, bool wait) 250 { 251 u8 buf[TRNG_SEC_STRENGTH_BYTES]; 252 struct xilinx_rng *rng; 253 int ret = 0, i = 0; 254 255 rng = container_of(hwrng, struct xilinx_rng, trng); 256 while (i < max) { 257 ret = xtrng_random_bytes_generate(rng, buf, TRNG_SEC_STRENGTH_BYTES, wait); 258 if (ret < 0) { 259 if (i == 0) 260 return ret; 261 break; 262 } 263 264 memcpy(data + i, buf, min_t(int, ret, (max - i))); 265 i += min_t(int, ret, (max - i)); 266 } 267 return i; 268 } 269 270 static int xtrng_hwrng_register(struct hwrng *trng) 271 { 272 int ret; 273 274 trng->name = "Xilinx Versal Crypto Engine TRNG"; 275 trng->read = xtrng_hwrng_trng_read; 276 277 ret = hwrng_register(trng); 278 if (ret) 279 pr_err("Fail to register the TRNG\n"); 280 281 return ret; 282 } 283 284 static void xtrng_hwrng_unregister(struct hwrng *trng) 285 { 286 hwrng_unregister(trng); 287 } 288 289 static int xtrng_probe(struct platform_device *pdev) 290 { 291 struct xilinx_rng *rng; 292 int ret; 293 294 rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); 295 if (!rng) 296 return -ENOMEM; 297 298 rng->dev = &pdev->dev; 299 rng->rng_base = devm_platform_ioremap_resource(pdev, 0); 300 if (IS_ERR(rng->rng_base)) { 301 dev_err(&pdev->dev, "Failed to map resource %pe\n", rng->rng_base); 302 return PTR_ERR(rng->rng_base); 303 } 304 305 xtrng_trng_reset(rng->rng_base); 306 ret = xtrng_reseed_internal(rng); 307 if (ret) { 308 dev_err(&pdev->dev, "TRNG Seed fail\n"); 309 return ret; 310 } 311 312 ret = xtrng_hwrng_register(&rng->trng); 313 if (ret) { 314 dev_err(&pdev->dev, "HWRNG device registration failed: %d\n", ret); 315 return ret; 316 } 317 platform_set_drvdata(pdev, rng); 318 319 return 0; 320 } 321 322 static void xtrng_remove(struct platform_device *pdev) 323 { 324 struct xilinx_rng *rng; 325 u32 zero[TRNG_NUM_INIT_REGS] = { }; 326 327 rng = platform_get_drvdata(pdev); 328 xtrng_hwrng_unregister(&rng->trng); 329 xtrng_write_multiple_registers(rng->rng_base + TRNG_EXT_SEED_OFFSET, zero, 330 TRNG_NUM_INIT_REGS); 331 xtrng_write_multiple_registers(rng->rng_base + TRNG_PER_STRNG_OFFSET, zero, 332 TRNG_NUM_INIT_REGS); 333 xtrng_hold_reset(rng->rng_base); 334 } 335 336 static const struct of_device_id xtrng_of_match[] = { 337 { .compatible = "xlnx,versal-trng", }, 338 {}, 339 }; 340 341 MODULE_DEVICE_TABLE(of, xtrng_of_match); 342 343 static struct platform_driver xtrng_driver = { 344 .driver = { 345 .name = "xlnx,versal-trng", 346 .of_match_table = xtrng_of_match, 347 }, 348 .probe = xtrng_probe, 349 .remove = xtrng_remove, 350 }; 351 352 module_platform_driver(xtrng_driver); 353 MODULE_LICENSE("GPL"); 354 MODULE_AUTHOR("Harsh Jain <h.jain@amd.com>"); 355 MODULE_AUTHOR("Mounika Botcha <mounika.botcha@amd.com>"); 356 MODULE_DESCRIPTION("True Random Number Generator Driver"); 357