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
xtrng_readwrite32(void __iomem * addr,u32 mask,u8 value)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
xtrng_trng_reset(void __iomem * addr)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
xtrng_hold_reset(void __iomem * addr)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
xtrng_softreset(struct xilinx_rng * rng)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. */
xtrng_readblock32(void __iomem * rng_base,__be32 * buf,int blocks32,bool wait)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
xtrng_collect_random_data(struct xilinx_rng * rng,u8 * rand_gen_buf,int no_of_random_bytes,bool wait)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
xtrng_write_multiple_registers(void __iomem * base_addr,u32 * values,size_t n)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
xtrng_enable_entropy(struct xilinx_rng * rng)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
xtrng_reseed_internal(struct xilinx_rng * rng)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
xtrng_random_bytes_generate(struct xilinx_rng * rng,u8 * rand_buf_ptr,u32 rand_buf_size,int wait)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
xtrng_hwrng_trng_read(struct hwrng * hwrng,void * data,size_t max,bool wait)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
xtrng_hwrng_register(struct hwrng * trng)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
xtrng_hwrng_unregister(struct hwrng * trng)284 static void xtrng_hwrng_unregister(struct hwrng *trng)
285 {
286 hwrng_unregister(trng);
287 }
288
xtrng_probe(struct platform_device * pdev)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
xtrng_remove(struct platform_device * pdev)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