1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright (C) 2022 Xilinx, Inc. All rights reserved. 4 * Copyright (C) 2022 Foundries Ltd. 5 * 6 * Driver port from Xilinx's FSBL implementation, jorge@foundries.io 7 * 8 * The Xilinx True Random Number Generator(TRNG) module in Versal - PMC TRNG 9 * consists of an entropy source, a deterministic random bit generator (DRBG) 10 * and health test logic, which tests the randomness of the generated data. 11 * The entropy source for the unit is an array of Ring Oscillators. 12 * 13 * The Versal PMC TRNG is envisaged to operate in three basic modes: DRNG, PTRNG 14 * and HRNG . Each of these can be operated with or without Derivative Function 15 * (DF), resulting in a total of 6 different modes of operation. 16 * 17 * NIST SP-800-90A practically requires the true random generators based on 18 * CTR_DRBG to include a derivation function (DF). This is expected to be 19 * implemented inside the Silicon (TRNG IP). However, the version of the IP used 20 * in Versal PMC does not have this capability. Hence, a software 21 * implementation of the DF is done in this driver. 22 * 23 * DRNG mode: Deterministic Random Number Generator mode. 24 * In this mode, the DRBG portion of the TRNG is used. User provides 25 * the (external) seed. 26 * PTRNG mode: Physical True Random Number Generator mode (aka Entropy mode). 27 * In this mode digitized Entropy source is output as random number. 28 * HRNG mode: Hybrid Random Number Generator mode. 29 * This is combination of above two modes in which the Entropy source 30 * is used to provide the seed, which is fed to the DRBG, which in 31 * turn generates the random number. 32 * 33 * DRNG mode with DF: It may not be common usecase to use the DF with DRNG as 34 * the general expectation would be that the seed would have sufficient entropy. 35 * However, the below guideline from section 10.2.1 of NIST SP-800-90A implies 36 * that need for DF for DRNG mode too: "..the DRBG mechanism is specified to 37 * allow an implementation tradeoff with respect to the use of this derivation 38 * function. The use of the derivation function is optional if either an 39 * approved RBG or an entropy source provides full entropy output when entropy 40 * input is requested by the DRBG mechanism. Otherwise, the derivation function 41 * shall be used". Sufficient large entropy data from user is fed to DF to 42 * generate the seed which will be loaded into the external seed registers. 43 * From here, it is similar to regular DRNG mode. 44 * 45 * PTRNG mode with DF: This mode is similar to PTRNG mode, however, the entropy 46 * data from the core output registers are accumulated and fed to the DF 47 * (instead of directly consuming it). The output of the DF would be final 48 * random data. In this mode, the output of DF is not seed but the random data. 49 * 50 * HRNG mode with DF: This mode is the combination of the above two modes. 51 * The entropy data is fed to the DF to produce seed. This seed is loaded to the 52 * external seed registers which provide seed to the DRBG. 53 */ 54 #include <arm.h> 55 #include <crypto/crypto.h> 56 #include <initcall.h> 57 #include <io.h> 58 #include <kernel/delay.h> 59 #include <kernel/panic.h> 60 #include <mm/core_mmu.h> 61 #include <platform_config.h> 62 #include <rng_support.h> 63 #include <stdlib.h> 64 #include <string.h> 65 #include <tee/tee_cryp_utl.h> 66 #include <trace.h> 67 68 #define TRNG_BASE 0xF1230000 69 #define TRNG_SIZE 0x10000 70 71 #define TRNG_STATUS 0x04 72 #define TRNG_STATUS_QCNT_SHIFT 9 73 #define TRNG_STATUS_QCNT_MASK (BIT(9) | BIT(10) | BIT(11)) 74 #define TRNG_STATUS_CERTF_MASK BIT(3) 75 #define TRNG_STATUS_DTF_MASK BIT(1) 76 #define TRNG_STATUS_DONE_MASK BIT(0) 77 #define TRNG_CTRL 0x08 78 #define TRNG_CTRL_EUMODE_MASK BIT(8) 79 #define TRNG_CTRL_PRNGMODE_MASK BIT(7) 80 #define TRNG_CTRL_PRNGSTART_MASK BIT(5) 81 #define TRNG_CTRL_PRNGXS_MASK BIT(3) 82 #define TRNG_CTRL_TRSSEN_MASK BIT(2) 83 #define TRNG_CTRL_PRNGSRST_MASK BIT(0) 84 #define TRNG_EXT_SEED_0 0x40 85 /* 86 * Below registers are not directly referenced in driver but are accessed 87 * with offset from TRNG_EXT_SEED_0 88 * Register: TRNG_EXT_SEED_1 0x00000044 89 * Register: TRNG_EXT_SEED_2 0x00000048 90 * Register: TRNG_EXT_SEED_3 0x0000004C 91 * Register: TRNG_EXT_SEED_4 0x00000050 92 * Register: TRNG_EXT_SEED_5 0x00000054 93 * Register: TRNG_EXT_SEED_6 0x00000058 94 * Register: TRNG_EXT_SEED_7 0x0000005C 95 * Register: TRNG_EXT_SEED_8 0x00000060 96 * Register: TRNG_EXT_SEED_9 0x00000064 97 * Register: TRNG_EXT_SEED_10 0x00000068 98 * Register: TRNG_EXT_SEED_11 0x0000006C 99 */ 100 #define TRNG_PER_STRING_0 0x80 101 /* 102 * Below registers are not directly referenced in driver but are accessed 103 * with offset from TRNG_PER_STRING_0 104 * Register: TRNG_PER_STRING_1 0x00000084 105 * Register: TRNG_PER_STRING_2 0x00000088 106 * Register: TRNG_PER_STRING_3 0x0000008C 107 * Register: TRNG_PER_STRING_4 0x00000090 108 * Register: TRNG_PER_STRING_5 0x00000094 109 * Register: TRNG_PER_STRING_6 0x00000098 110 * Register: TRNG_PER_STRING_7 0x0000009C 111 * Register: TRNG_PER_STRING_8 0x000000A0 112 * Register: TRNG_PER_STRING_9 0x000000A4 113 * Register: TRNG_PER_STRING_10 0x000000A8 114 * Register: TRNG_PER_STRING_11 0x000000AC 115 */ 116 #define TRNG_CORE_OUTPUT 0xC0 117 #define TRNG_RESET 0xD0 118 #define TRNG_RESET_VAL_MASK BIT(0) 119 #define TRNG_OSC_EN 0xD4 120 #define TRNG_OSC_EN_VAL_MASK BIT(0) 121 122 /* TRNG configuration */ 123 #define TRNG_BURST_SIZE 16 124 #define TRNG_BURST_SIZE_BITS 128 125 #define TRNG_NUM_INIT_REGS 12 126 #define TRNG_REG_SIZE 32 127 #define TRNG_BYTES_PER_REG 4 128 #define TRNG_MAX_QCNT 4 129 #define TRNG_RESEED_TIMEOUT 15000 130 #define TRNG_GENERATE_TIMEOUT 8000 131 #define TRNG_MIN_DFLENMULT 2 132 #define TRNG_MAX_DFLENMULT 9 133 #define PRNGMODE_RESEED 0 134 #define PRNGMODE_GEN TRNG_CTRL_PRNGMODE_MASK 135 #define RESET_DELAY 10 136 #define TRNG_SEC_STRENGTH_LEN 32 137 #define TRNG_PERS_STR_REGS 12 138 #define TRNG_PERS_STR_LEN 48 139 #define TRNG_SEED_REGS 12 140 #define TRNG_SEED_LEN 48 141 #define TRNG_GEN_LEN 32 142 #define RAND_BUF_LEN 4 143 #define BYTES_PER_BLOCK 16 144 #define ALL_A_PATTERN_32 0xAAAAAAAA 145 #define ALL_5_PATTERN_32 0x55555555 146 147 /* Derivative function helper macros */ 148 #define DF_SEED 0 149 #define DF_RAND 1 150 #define DF_IP_IV_LEN 4 151 #define DF_PAD_DATA_LEN 8 152 #define MAX_PRE_DF_LEN 160 153 #define MAX_PRE_DF_LEN_WORDS 40 154 #define DF_PERS_STR_LEN TRNG_PERS_STR_LEN 155 #define DF_PAD_VAL 0x80 156 #define DF_KEY_LEN 32 157 #define BLK_SIZE 16 158 #define MAX_ROUNDS 14 159 160 enum trng_status { 161 TRNG_UNINITIALIZED = 0, 162 TRNG_HEALTHY, 163 TRNG_ERROR, 164 TRNG_CATASTROPHIC 165 }; 166 167 enum trng_mode { 168 TRNG_HRNG = 0, 169 TRNG_DRNG, 170 TRNG_PTRNG 171 }; 172 173 struct trng_cfg { 174 paddr_t base; 175 vaddr_t addr; 176 size_t len; 177 }; 178 179 struct trng_usr_cfg { 180 enum trng_mode mode; 181 uint64_t seed_life; /* number of TRNG requests per seed */ 182 bool predict_en; /* enable prediction resistance */ 183 bool pstr_en; /* enable personalization string */ 184 uint32_t pstr[TRNG_PERS_STR_REGS]; 185 bool iseed_en; /* enable an initial seed */ 186 uint32_t init_seed[MAX_PRE_DF_LEN_WORDS]; 187 uint32_t df_disable; /* disable the derivative function */ 188 uint32_t dfmul; /* derivative function multiplier */ 189 }; 190 191 struct trng_stats { 192 uint64_t bytes; 193 uint64_t bytes_reseed; 194 uint64_t elapsed_seed_life; 195 }; 196 197 /* block cipher derivative function algorithm */ 198 struct trng_dfin { 199 uint32_t ivc[DF_IP_IV_LEN]; 200 uint32_t val1; 201 uint32_t val2; 202 uint8_t entropy[MAX_PRE_DF_LEN]; /* input entropy */ 203 uint8_t pstr[DF_PERS_STR_LEN]; /* personalization string */ 204 uint8_t pad_data[DF_PAD_DATA_LEN]; /* pad to multiples of 16 bytes*/ 205 }; 206 207 struct versal_trng { 208 struct trng_cfg cfg; 209 struct trng_usr_cfg usr_cfg; 210 struct trng_stats stats; 211 enum trng_status status; 212 uint32_t buf[RAND_BUF_LEN]; /* buffer of random bits */ 213 size_t len; 214 struct trng_dfin dfin; 215 uint8_t dfout[TRNG_SEED_LEN]; /* output of the DF operation */ 216 }; 217 218 /* Derivative function variables */ 219 static unsigned char sbx1[256]; 220 static unsigned char sbx2[256]; 221 static unsigned char sbx3[256]; 222 static unsigned char schedule[BLK_SIZE * (MAX_ROUNDS + 1)]; 223 static unsigned int rounds; 224 225 static void rota4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d) 226 { 227 uint8_t t = *a; 228 229 *a = sbx1[*b]; 230 *b = sbx1[*c]; 231 *c = sbx1[*d]; 232 *d = sbx1[t]; 233 } 234 235 static void rota2(uint8_t *a, uint8_t *b) 236 { 237 uint8_t t = *a; 238 239 *a = sbx1[*b]; 240 *b = sbx1[t]; 241 } 242 243 static void sbox4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d) 244 { 245 *a = sbx1[*a]; 246 *b = sbx1[*b]; 247 *c = sbx1[*c]; 248 *d = sbx1[*d]; 249 } 250 251 static void xorb(uint8_t *res, const uint8_t *in) 252 { 253 size_t i = 0; 254 255 for (i = 0; i < BLK_SIZE; ++i) 256 res[i] ^= in[i]; 257 } 258 259 static void set_key(uint8_t *res, const uint8_t *src, unsigned int roundval) 260 { 261 memcpy(res, src, BLK_SIZE); 262 xorb(res, schedule + roundval * BLK_SIZE); 263 } 264 265 static void mix_column_sbox(uint8_t *dst, const uint8_t *f) 266 { 267 size_t i = 0; 268 size_t a = 0; 269 size_t b = 0; 270 size_t c = 0; 271 size_t d = 0; 272 273 for (i = 0; i < 4; i++) { 274 a = 4 * i; 275 b = (0x5 + a) % 16; 276 c = (0xa + a) % 16; 277 d = (0xf + a) % 16; 278 dst[0 + a] = sbx2[f[a]] ^ sbx3[f[b]] ^ sbx1[f[c]] ^ sbx1[f[d]]; 279 dst[1 + a] = sbx1[f[a]] ^ sbx2[f[b]] ^ sbx3[f[c]] ^ sbx1[f[d]]; 280 dst[2 + a] = sbx1[f[a]] ^ sbx1[f[b]] ^ sbx2[f[c]] ^ sbx3[f[d]]; 281 dst[3 + a] = sbx3[f[a]] ^ sbx1[f[b]] ^ sbx1[f[c]] ^ sbx2[f[d]]; 282 } 283 } 284 285 static void shift_row_sbox(uint8_t *f) 286 { 287 sbox4(&f[0], &f[4], &f[8], &f[12]); 288 rota4(&f[1], &f[5], &f[9], &f[13]); 289 rota2(&f[2], &f[10]); 290 rota2(&f[6], &f[14]); 291 rota4(&f[15], &f[11], &f[7], &f[3]); 292 } 293 294 static void encrypt(uint8_t *in, uint8_t *out) 295 { 296 uint8_t fa[BLK_SIZE] = { 0 }; 297 uint8_t fb[BLK_SIZE] = { 0 }; 298 size_t roundval = 0; 299 300 set_key(fa, in, 0); 301 for (roundval = 1; roundval < rounds; ++roundval) { 302 mix_column_sbox(fb, fa); 303 set_key(fa, fb, roundval); 304 } 305 306 shift_row_sbox(fa); 307 set_key(out, fa, roundval); 308 } 309 310 static void checksum(unsigned char *in, uint8_t *iv, int max_blk) 311 { 312 while (max_blk > 0) { 313 xorb(iv, in); 314 encrypt(iv, iv); 315 in += BLK_SIZE; 316 max_blk -= 1; 317 } 318 } 319 320 static void setup_key(const unsigned char *k, size_t klen) 321 { 322 unsigned char rcon = 1; 323 size_t sch_size = 240; 324 size_t i = 0; 325 326 rounds = MAX_ROUNDS; 327 memcpy(schedule, k, klen); 328 for (i = klen; i < sch_size; i += 4) { 329 unsigned char t0 = 0; 330 unsigned char t1 = 0; 331 unsigned char t2 = 0; 332 unsigned char t3 = 0; 333 int ik = 0; 334 335 t0 = schedule[i - 4]; 336 t1 = schedule[i - 3]; 337 t2 = schedule[i - 2]; 338 t3 = schedule[i - 1]; 339 if (i % klen == 0) { 340 rota4(&t0, &t1, &t2, &t3); 341 t0 ^= rcon; 342 rcon = (rcon << 1) ^ (((rcon >> 7) & 1) * 0x1B); 343 } else if (i % klen == 16) { 344 sbox4(&t0, &t1, &t2, &t3); 345 } 346 ik = i - klen; 347 schedule[i + 0] = schedule[ik + 0] ^ t0; 348 schedule[i + 1] = schedule[ik + 1] ^ t1; 349 schedule[i + 2] = schedule[ik + 2] ^ t2; 350 schedule[i + 3] = schedule[ik + 3] ^ t3; 351 } 352 } 353 354 static void trng_df_init(void) 355 { 356 const uint8_t sb[] = { 357 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 358 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 359 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 360 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 361 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 362 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 363 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 364 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 365 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 366 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 367 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 368 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 369 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 370 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 371 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 372 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 373 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 374 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 375 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 376 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 377 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 378 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 379 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 380 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 381 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 382 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, 383 }; 384 size_t i = 0; 385 386 memcpy(sbx1, sb, sizeof(sb)); 387 for (i = 0; i < sizeof(sb); i++) { 388 sbx2[i] = (sb[i] << 1) ^ (((sb[i] >> 7) & 1) * 0x1B); 389 sbx3[i] = sbx2[i] ^ sb[i]; 390 } 391 } 392 393 /* 394 * This function implements the Derivative Function by distilling the entropy 395 * available in its input into a smaller number of bits on the output. 396 * - per NIST SP80090A. 397 * 398 * The Block Cipher algorithm follows sections 10.3.2 and 10.3.3 of the 399 * NIST.SP.800-90Ar1 document 400 */ 401 static void trng_df_algorithm(struct versal_trng *trng, uint8_t *dfout, 402 uint32_t flag, const uint8_t *pstr) 403 { 404 static bool df_init; 405 const uint8_t df_key[DF_KEY_LEN] = { 406 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 407 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 408 }; 409 size_t dfin_len = sizeof(struct trng_dfin) + trng->len; 410 uint8_t *inp_blk = NULL; 411 uint8_t *out_blk = NULL; 412 uintptr_t reminder = 0; 413 size_t xfer_len = 0; 414 uint32_t index = 0; 415 uintptr_t src = 0; 416 uintptr_t dst = 0; 417 size_t offset = 0; 418 419 if (!df_init) { 420 trng_df_init(); 421 df_init = true; 422 } 423 424 if (flag == DF_SEED) 425 trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_PERS_STR_LEN); 426 else 427 trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_GEN_LEN); 428 429 trng->dfin.pad_data[0] = DF_PAD_VAL; 430 431 if (!pstr) { 432 if (trng->len > (MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN)) 433 panic(); 434 435 dfin_len = dfin_len - TRNG_PERS_STR_LEN - MAX_PRE_DF_LEN; 436 trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len); 437 438 xfer_len = DF_PAD_DATA_LEN; 439 src = (uintptr_t)trng->dfin.pad_data; 440 offset = MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN - trng->len; 441 } else { 442 if (trng->len > MAX_PRE_DF_LEN) 443 panic(); 444 445 memcpy(trng->dfin.pstr, pstr, TRNG_PERS_STR_LEN); 446 dfin_len = dfin_len - MAX_PRE_DF_LEN; 447 trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len + 448 TRNG_PERS_STR_LEN); 449 xfer_len = DF_PAD_DATA_LEN + TRNG_PERS_STR_LEN; 450 src = (uintptr_t)trng->dfin.pstr; 451 offset = MAX_PRE_DF_LEN - trng->len; 452 } 453 454 /* Move back into the dfin structure */ 455 dst = src - offset; 456 reminder = (uintptr_t)&trng->dfin + sizeof(trng->dfin) - offset; 457 if (offset) { 458 if (xfer_len > offset) 459 panic("Overlapping data"); 460 461 memcpy((void *)dst, (void *)src, xfer_len); 462 memset((void *)reminder, 0, offset); 463 } 464 465 /* DF algorithm - step 1 */ 466 setup_key(df_key, DF_KEY_LEN); 467 for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) { 468 memset((void *)(trng->dfout + index), 0, BLK_SIZE); 469 trng->dfin.ivc[0] = TEE_U32_TO_BIG_ENDIAN(index / BLK_SIZE); 470 checksum((unsigned char *)&trng->dfin, 471 trng->dfout + index, dfin_len / BLK_SIZE); 472 } 473 474 /* DF algorithm - step 2 */ 475 setup_key(trng->dfout, DF_KEY_LEN); 476 for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) { 477 if (!index) 478 inp_blk = &dfout[TRNG_SEC_STRENGTH_LEN]; 479 else 480 inp_blk = &dfout[index - BLK_SIZE]; 481 482 out_blk = &dfout[index]; 483 encrypt(inp_blk, out_blk); 484 } 485 } 486 487 static uint32_t trng_read32(vaddr_t addr, size_t off) 488 { 489 return io_read32(addr + off); 490 } 491 492 static void trng_write32(vaddr_t addr, size_t off, uint32_t val) 493 { 494 io_write32(addr + off, val); 495 } 496 497 static void trng_clrset32(vaddr_t addr, size_t off, uint32_t mask, uint32_t val) 498 { 499 io_clrsetbits32(addr + off, mask, mask & val); 500 } 501 502 static void trng_write32_range(const struct versal_trng *trng, uint32_t start, 503 uint32_t num_regs, const uint8_t *buf) 504 { 505 size_t off = 0; 506 uint32_t val = 0; 507 size_t cnt = 0; 508 size_t i = 0; 509 510 for (i = 0; i < num_regs; ++i) { 511 if (!buf) { 512 off = start + i * TRNG_BYTES_PER_REG; 513 trng_write32(trng->cfg.addr, off, 0); 514 continue; 515 } 516 517 val = 0; 518 for (cnt = 0; cnt < TRNG_BYTES_PER_REG; ++cnt) 519 val = (val << 8) | buf[i * TRNG_BYTES_PER_REG + cnt]; 520 521 off = start + (TRNG_NUM_INIT_REGS - 1 - i) * TRNG_BYTES_PER_REG; 522 trng_write32(trng->cfg.addr, off, val); 523 } 524 } 525 526 static TEE_Result trng_wait_for_event(vaddr_t addr, size_t off, uint32_t mask, 527 uint32_t event, uint32_t time_out) 528 { 529 uint64_t tref = timeout_init_us(time_out); 530 531 do { 532 if (timeout_elapsed(tref)) 533 break; 534 } while ((io_read32(addr + off) & mask) != event); 535 536 /* Normal world might have suspended the OP-TEE thread, check again */ 537 if ((io_read32(addr + off) & mask) != event) 538 return TEE_ERROR_GENERIC; 539 540 return TEE_SUCCESS; 541 } 542 543 static void trng_soft_reset(const struct versal_trng *trng) 544 { 545 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK, 546 TRNG_CTRL_PRNGSRST_MASK); 547 udelay(RESET_DELAY); 548 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK, 0); 549 } 550 551 static void trng_reset(const struct versal_trng *trng) 552 { 553 trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK); 554 udelay(RESET_DELAY); 555 trng_write32(trng->cfg.addr, TRNG_RESET, 0); 556 trng_soft_reset(trng); 557 } 558 559 static void trng_hold_reset(const struct versal_trng *trng) 560 { 561 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 562 TRNG_CTRL_PRNGSRST_MASK, TRNG_CTRL_PRNGSRST_MASK); 563 trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK); 564 udelay(RESET_DELAY); 565 } 566 567 static TEE_Result trng_check_seed(uint8_t *entropy, uint32_t len) 568 { 569 uint32_t *p = (void *)entropy; 570 size_t i = 0; 571 572 for (i = 0; i < len / sizeof(*p); i++) { 573 if (p[i] == ALL_A_PATTERN_32) 574 return TEE_ERROR_GENERIC; 575 576 if (p[i] == ALL_5_PATTERN_32) 577 return TEE_ERROR_GENERIC; 578 } 579 580 return TEE_SUCCESS; 581 } 582 583 static TEE_Result trng_collect_random(struct versal_trng *trng, uint8_t *dst, 584 size_t len) 585 { 586 const size_t bursts = len / TRNG_BURST_SIZE; 587 const size_t words = TRNG_BURST_SIZE_BITS / TRNG_REG_SIZE; 588 uint32_t *p = (void *)dst; 589 size_t bcnt = 0; 590 size_t wcnt = 0; 591 size_t index = 0; 592 uint32_t val = 0; 593 bool match = false; 594 595 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 596 TRNG_CTRL_PRNGSTART_MASK, TRNG_CTRL_PRNGSTART_MASK); 597 598 /* 599 * Loop as many times based on len requested. In each burst 128 bits 600 * are generated, which is reflected in QCNT value of 4 by hardware. 601 */ 602 for (bcnt = 0; bcnt < bursts; bcnt++) { 603 if (trng_wait_for_event(trng->cfg.addr, 604 TRNG_STATUS, TRNG_STATUS_QCNT_MASK, 605 TRNG_MAX_QCNT << TRNG_STATUS_QCNT_SHIFT, 606 TRNG_GENERATE_TIMEOUT)) { 607 EMSG("Timeout waiting for randomness"); 608 return TEE_ERROR_GENERIC; 609 } 610 611 /* 612 * DTF flag set during generate indicates catastrophic 613 * condition, which needs to be checked for every time unless we 614 * are in PTRNG mode 615 */ 616 if (trng->usr_cfg.mode != TRNG_PTRNG) { 617 val = trng_read32(trng->cfg.addr, TRNG_STATUS); 618 if (val & TRNG_STATUS_DTF_MASK) { 619 EMSG("Catastrophic DFT error"); 620 trng->status = TRNG_CATASTROPHIC; 621 622 return TEE_ERROR_GENERIC; 623 } 624 } 625 /* 626 * Read the core output register 4 times to consume the random 627 * data generated for every burst. 628 */ 629 match = true; 630 for (wcnt = 0; wcnt < words; wcnt++) { 631 val = trng_read32(trng->cfg.addr, TRNG_CORE_OUTPUT); 632 633 if (bcnt > 0 && trng->buf[wcnt] != val) 634 match = false; 635 636 trng->buf[wcnt] = val; 637 638 if (dst) { 639 p[index] = TEE_U32_TO_BIG_ENDIAN(val); 640 index++; 641 } 642 } 643 644 if (bursts > 1 && bcnt > 0 && match) { 645 EMSG("Catastrophic software error"); 646 trng->status = TRNG_CATASTROPHIC; 647 return TEE_ERROR_GENERIC; 648 } 649 } 650 651 return TEE_SUCCESS; 652 } 653 654 static TEE_Result trng_reseed_internal_nodf(struct versal_trng *trng, 655 uint8_t *eseed, uint8_t *str) 656 { 657 uint8_t entropy[TRNG_SEED_LEN] = { 0 }; 658 uint8_t *seed = NULL; 659 660 switch (trng->usr_cfg.mode) { 661 case TRNG_HRNG: 662 trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK); 663 trng_soft_reset(trng); 664 trng_write32(trng->cfg.addr, TRNG_CTRL, 665 TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK); 666 667 if (trng_collect_random(trng, entropy, TRNG_SEED_LEN)) 668 return TEE_ERROR_GENERIC; 669 670 if (trng_check_seed(entropy, TRNG_SEED_LEN)) 671 return TEE_ERROR_GENERIC; 672 673 seed = entropy; 674 break; 675 case TRNG_DRNG: 676 seed = eseed; 677 break; 678 default: 679 seed = NULL; 680 break; 681 } 682 683 trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, seed); 684 if (str) 685 trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, 686 str); 687 688 return TEE_SUCCESS; 689 } 690 691 static TEE_Result trng_reseed_internal_df(struct versal_trng *trng, 692 uint8_t *eseed, uint8_t *str) 693 { 694 memset(&trng->dfin, 0, sizeof(trng->dfin)); 695 696 switch (trng->usr_cfg.mode) { 697 case TRNG_HRNG: 698 trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK); 699 trng_soft_reset(trng); 700 trng_write32(trng->cfg.addr, TRNG_CTRL, 701 TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK); 702 703 if (trng_collect_random(trng, trng->dfin.entropy, trng->len)) 704 return TEE_ERROR_GENERIC; 705 706 if (trng_check_seed(trng->dfin.entropy, trng->len)) 707 return TEE_ERROR_GENERIC; 708 break; 709 case TRNG_DRNG: 710 memcpy(trng->dfin.entropy, eseed, trng->len); 711 break; 712 default: 713 break; 714 } 715 716 trng_df_algorithm(trng, trng->dfout, DF_SEED, str); 717 trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, trng->dfout); 718 719 return TEE_SUCCESS; 720 } 721 722 static TEE_Result trng_reseed_internal(struct versal_trng *trng, 723 uint8_t *eseed, uint8_t *str, 724 uint32_t mul) 725 { 726 uint32_t val = 0; 727 728 trng->stats.bytes_reseed = 0; 729 trng->stats.elapsed_seed_life = 0; 730 731 if (trng->usr_cfg.df_disable) 732 trng->len = TRNG_SEED_LEN; 733 else 734 trng->len = (mul + 1) * BYTES_PER_BLOCK; 735 736 if (trng->usr_cfg.df_disable) { 737 if (trng_reseed_internal_nodf(trng, eseed, str)) 738 goto error; 739 } else { 740 if (trng_reseed_internal_df(trng, eseed, str)) 741 goto error; 742 } 743 744 trng_write32(trng->cfg.addr, TRNG_CTRL, 745 PRNGMODE_RESEED | TRNG_CTRL_PRNGXS_MASK); 746 747 /* Start the reseed operation */ 748 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSTART_MASK, 749 TRNG_CTRL_PRNGSTART_MASK); 750 751 if (trng_wait_for_event(trng->cfg.addr, TRNG_STATUS, 752 TRNG_STATUS_DONE_MASK, TRNG_STATUS_DONE_MASK, 753 TRNG_RESEED_TIMEOUT)) 754 goto error; 755 756 /* Check SP800 - 90B (entropy health test error) */ 757 val = trng_read32(trng->cfg.addr, TRNG_STATUS) & TRNG_STATUS_CERTF_MASK; 758 if (val == TRNG_STATUS_CERTF_MASK) 759 goto error; 760 761 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSTART_MASK, 0); 762 return TEE_SUCCESS; 763 error: 764 trng->status = TRNG_ERROR; 765 return TEE_ERROR_GENERIC; 766 } 767 768 static TEE_Result trng_instantiate(struct versal_trng *trng, 769 const struct trng_usr_cfg *usr_cfg) 770 { 771 uint8_t *seed = NULL; 772 uint8_t *pers = NULL; 773 774 if (!trng) 775 return TEE_ERROR_GENERIC; 776 777 if (!usr_cfg) 778 goto error; 779 780 if (trng->status != TRNG_UNINITIALIZED) 781 goto error; 782 783 if (usr_cfg->mode != TRNG_HRNG && usr_cfg->mode != TRNG_DRNG && 784 usr_cfg->mode != TRNG_PTRNG) 785 goto error; 786 787 if (usr_cfg->mode != TRNG_PTRNG && !usr_cfg->seed_life) 788 goto error; 789 790 if (!usr_cfg->iseed_en && usr_cfg->mode == TRNG_DRNG) 791 goto error; 792 793 if (usr_cfg->iseed_en && usr_cfg->mode == TRNG_HRNG) 794 goto error; 795 796 if (!usr_cfg->df_disable && 797 (usr_cfg->dfmul < TRNG_MIN_DFLENMULT || 798 usr_cfg->dfmul > TRNG_MAX_DFLENMULT)) 799 goto error; 800 801 if (usr_cfg->df_disable && usr_cfg->dfmul) 802 goto error; 803 804 if (usr_cfg->mode == TRNG_PTRNG && 805 (usr_cfg->iseed_en || usr_cfg->pstr_en || 806 usr_cfg->predict_en || usr_cfg->seed_life)) 807 goto error; 808 809 memcpy(&trng->usr_cfg, usr_cfg, sizeof(struct trng_usr_cfg)); 810 trng_reset(trng); 811 812 if (trng->usr_cfg.iseed_en) 813 seed = (void *)trng->usr_cfg.init_seed; 814 815 if (trng->usr_cfg.pstr_en) 816 pers = (void *)trng->usr_cfg.pstr; 817 818 if (trng->usr_cfg.mode != TRNG_PTRNG) { 819 if (trng_reseed_internal(trng, seed, pers, trng->usr_cfg.dfmul)) 820 goto error; 821 } 822 823 trng->status = TRNG_HEALTHY; 824 return TEE_SUCCESS; 825 error: 826 trng->status = TRNG_ERROR; 827 return TEE_ERROR_GENERIC; 828 } 829 830 static TEE_Result trng_reseed(struct versal_trng *trng, uint8_t *eseed, 831 uint32_t mul) 832 { 833 if (!trng) 834 return TEE_ERROR_GENERIC; 835 836 if (trng->status != TRNG_HEALTHY) 837 goto error; 838 839 if (trng->usr_cfg.mode != TRNG_DRNG && trng->usr_cfg.mode != TRNG_HRNG) 840 goto error; 841 842 if (trng->usr_cfg.mode == TRNG_DRNG && !eseed) 843 goto error; 844 845 if (trng->usr_cfg.mode != TRNG_DRNG && eseed) 846 goto error; 847 848 if (!trng->usr_cfg.df_disable) { 849 if (mul < TRNG_MIN_DFLENMULT || mul > TRNG_MAX_DFLENMULT) 850 goto error; 851 } 852 853 if (trng->usr_cfg.df_disable && mul) 854 goto error; 855 856 if (eseed && !memcmp(eseed, trng->usr_cfg.init_seed, trng->len)) 857 goto error; 858 859 if (trng_reseed_internal(trng, eseed, NULL, mul)) 860 goto error; 861 862 return TEE_SUCCESS; 863 error: 864 trng->status = TRNG_ERROR; 865 return TEE_ERROR_GENERIC; 866 } 867 868 static TEE_Result trng_generate(struct versal_trng *trng, uint8_t *buf, 869 size_t blen, bool predict) 870 { 871 uint32_t len = TRNG_SEC_STRENGTH_LEN; 872 uint8_t *p = buf; 873 874 if (!trng) 875 return TEE_ERROR_GENERIC; 876 877 if (!p) 878 goto error; 879 880 if (blen < TRNG_SEC_STRENGTH_LEN) 881 goto error; 882 883 if (trng->status != TRNG_HEALTHY) 884 goto error; 885 886 if (trng->usr_cfg.mode == TRNG_PTRNG && predict) 887 goto error; 888 889 if (!trng->usr_cfg.predict_en && predict) 890 goto error; 891 892 switch (trng->usr_cfg.mode) { 893 case TRNG_HRNG: 894 if (trng->stats.elapsed_seed_life >= trng->usr_cfg.seed_life) { 895 if (trng_reseed_internal(trng, NULL, NULL, 0)) 896 goto error; 897 } 898 899 if (predict && trng->stats.elapsed_seed_life > 0) { 900 if (trng_reseed_internal(trng, NULL, NULL, 0)) 901 goto error; 902 } 903 904 trng_write32(trng->cfg.addr, TRNG_CTRL, PRNGMODE_GEN); 905 break; 906 case TRNG_DRNG: 907 if (trng->stats.elapsed_seed_life > trng->usr_cfg.seed_life) 908 goto error; 909 910 if (predict && trng->stats.elapsed_seed_life > 0) 911 goto error; 912 913 trng_write32(trng->cfg.addr, TRNG_CTRL, PRNGMODE_GEN); 914 break; 915 default: 916 if (!trng->usr_cfg.df_disable) { 917 memset(&trng->dfin, 0, sizeof(trng->dfin)); 918 len = (trng->usr_cfg.dfmul + 1) * BYTES_PER_BLOCK; 919 trng->len = len; 920 p = trng->dfin.entropy; 921 } 922 /* Enable the 8 ring oscillators used for entropy source */ 923 trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK); 924 trng_soft_reset(trng); 925 trng_write32(trng->cfg.addr, TRNG_CTRL, 926 TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK); 927 break; 928 } 929 930 if (trng_collect_random(trng, p, len)) 931 goto error; 932 933 trng->stats.bytes_reseed += len; 934 trng->stats.bytes += len; 935 trng->stats.elapsed_seed_life++; 936 937 if (!trng->usr_cfg.df_disable && trng->usr_cfg.mode == TRNG_PTRNG) 938 trng_df_algorithm(trng, buf, DF_RAND, NULL); 939 940 return TEE_SUCCESS; 941 error: 942 if (trng->status != TRNG_CATASTROPHIC) 943 trng->status = TRNG_ERROR; 944 945 return TEE_ERROR_GENERIC; 946 } 947 948 static TEE_Result trng_release(struct versal_trng *trng) 949 { 950 if (!trng) 951 return TEE_ERROR_GENERIC; 952 953 if (trng->status == TRNG_UNINITIALIZED) 954 goto error; 955 956 trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, NULL); 957 trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, NULL); 958 trng_hold_reset(trng); 959 960 /* Clear the instance */ 961 memset(&trng->usr_cfg, 0, sizeof(trng->usr_cfg)); 962 memset(trng->buf, 0, sizeof(trng->buf)); 963 memset(trng->dfout, 0, sizeof(trng->dfout)); 964 trng->status = TRNG_UNINITIALIZED; 965 966 return TEE_SUCCESS; 967 error: 968 trng->status = TRNG_ERROR; 969 970 return TEE_ERROR_GENERIC; 971 } 972 973 /* Health tests should be run when the configured mode is of PTRNG or HRNG */ 974 static TEE_Result trng_health_test(struct versal_trng *trng) 975 { 976 struct trng_usr_cfg tests = { 977 .mode = TRNG_HRNG, 978 .seed_life = 10, 979 .dfmul = 7, 980 .predict_en = false, 981 .iseed_en = false, 982 .pstr_en = false, 983 .df_disable = false, 984 }; 985 986 if (trng_instantiate(trng, &tests)) 987 goto error; 988 989 if (trng_release(trng)) 990 goto error; 991 992 return TEE_SUCCESS; 993 error: 994 trng->status = TRNG_ERROR; 995 996 return TEE_ERROR_GENERIC; 997 } 998 999 /* 1000 * The KAT test should be run when the TRNG is configured in DRNG or HRNG mode. 1001 * If KAT fails, the driver has to be put in error state. 1002 */ 1003 static TEE_Result trng_kat_test(struct versal_trng *trng) 1004 { 1005 struct trng_usr_cfg tests = { 1006 .mode = TRNG_DRNG, 1007 .seed_life = 5, 1008 .dfmul = 2, 1009 .predict_en = false, 1010 .iseed_en = true, 1011 .pstr_en = true, 1012 .df_disable = false, 1013 }; 1014 const uint8_t ext_seed[TRNG_SEED_LEN] = { 1015 0x3BU, 0xC3U, 0xEDU, 0x64U, 0xF4U, 0x80U, 0x1CU, 0xC7U, 1016 0x14U, 0xCCU, 0x35U, 0xEDU, 0x57U, 0x01U, 0x2AU, 0xE4U, 1017 0xBCU, 0xEFU, 0xDEU, 0xF6U, 0x7CU, 0x46U, 0xA6U, 0x34U, 1018 0xC6U, 0x79U, 0xE8U, 0x91U, 0x5DU, 0xB1U, 0xDBU, 0xA7U, 1019 0x49U, 0xA5U, 0xBBU, 0x4FU, 0xEDU, 0x30U, 0xB3U, 0x7BU, 1020 0xA9U, 0x8BU, 0xF5U, 0x56U, 0x4DU, 0x40U, 0x18U, 0x9FU, 1021 }; 1022 const uint8_t pers_str[TRNG_PERS_STR_LEN] = { 1023 0xB2U, 0x80U, 0x7EU, 0x4CU, 0xD0U, 0xE4U, 0xE2U, 0xA9U, 1024 0x2FU, 0x1FU, 0x5DU, 0xC1U, 0xA2U, 0x1FU, 0x40U, 0xFCU, 1025 0x1FU, 0x24U, 0x5DU, 0x42U, 0x61U, 0x80U, 0xE6U, 0xE9U, 1026 0x71U, 0x05U, 0x17U, 0x5BU, 0xAFU, 0x70U, 0x30U, 0x18U, 1027 0xBCU, 0x23U, 0x18U, 0x15U, 0xCBU, 0xB8U, 0xA6U, 0x3EU, 1028 0x83U, 0xB8U, 0x4AU, 0xFEU, 0x38U, 0xFCU, 0x25U, 0x87U, 1029 }; 1030 const uint8_t expected_out[TRNG_GEN_LEN] = { 1031 0x91U, 0x9AU, 0x6BU, 0x99U, 0xD5U, 0xBCU, 0x2CU, 0x11U, 1032 0x5FU, 0x3AU, 0xFCU, 0x0BU, 0x0EU, 0x7BU, 0xC7U, 0x69U, 1033 0x4DU, 0xE1U, 0xE5U, 0xFEU, 0x59U, 0x9EU, 0xAAU, 0x41U, 1034 0xD3U, 0x48U, 0xFDU, 0x3DU, 0xD2U, 0xC4U, 0x50U, 0x1EU, 1035 }; 1036 uint8_t out[TRNG_GEN_LEN] = { 0 }; 1037 1038 if (!trng) 1039 return TEE_ERROR_GENERIC; 1040 1041 memcpy(&tests.init_seed, ext_seed, sizeof(ext_seed)); 1042 memcpy(tests.pstr, pers_str, sizeof(pers_str)); 1043 1044 if (trng_instantiate(trng, &tests)) 1045 goto error; 1046 1047 if (trng_generate(trng, out, sizeof(out), false)) 1048 goto error; 1049 1050 if (memcmp(out, expected_out, TRNG_GEN_LEN)) { 1051 EMSG("K.A.T mismatch"); 1052 goto error; 1053 } 1054 1055 if (trng_release(trng)) 1056 goto error; 1057 1058 return TEE_SUCCESS; 1059 error: 1060 trng->status = TRNG_ERROR; 1061 return TEE_ERROR_GENERIC; 1062 } 1063 1064 static struct versal_trng versal_trng = { 1065 .cfg.base = TRNG_BASE, 1066 .cfg.len = TRNG_SIZE, 1067 }; 1068 1069 TEE_Result hw_get_random_bytes(void *buf, size_t len) 1070 { 1071 uint8_t random[TRNG_SEC_STRENGTH_LEN] = { 0 }; 1072 uint8_t *p = buf; 1073 size_t i = 0; 1074 1075 for (i = 0; i < len / TRNG_SEC_STRENGTH_LEN; i++) { 1076 if (trng_generate(&versal_trng, p + i * TRNG_SEC_STRENGTH_LEN, 1077 TRNG_SEC_STRENGTH_LEN, false)) 1078 panic(); 1079 } 1080 1081 if (len % TRNG_SEC_STRENGTH_LEN) { 1082 if (trng_generate(&versal_trng, random, TRNG_SEC_STRENGTH_LEN, 1083 false)) 1084 panic(); 1085 memcpy(p + i * TRNG_SEC_STRENGTH_LEN, random, 1086 len % TRNG_SEC_STRENGTH_LEN); 1087 } 1088 1089 return TEE_SUCCESS; 1090 } 1091 1092 void plat_rng_init(void) 1093 { 1094 } 1095 1096 static TEE_Result trng_hrng_mode_init(void) 1097 { 1098 const uint8_t pers_str[TRNG_PERS_STR_LEN] = { 1099 0xB2, 0x80, 0x7E, 0x4C, 0xD0, 0xE4, 0xE2, 0xA9, 1100 0x2F, 0x1F, 0x5D, 0xC1, 0xA2, 0x1F, 0x40, 0xFC, 1101 0x1F, 0x24, 0x5D, 0x42, 0x61, 0x80, 0xE6, 0xE9, 1102 0x71, 0x05, 0x17, 0x5B, 0xAF, 0x70, 0x30, 0x18, 1103 0xBC, 0x23, 0x18, 0x15, 0xCB, 0xB8, 0xA6, 0x3E, 1104 0x83, 0xB8, 0x4A, 0xFE, 0x38, 0xFC, 0x25, 0x87, 1105 }; 1106 /* configure in hybrid mode with derivative function enabled */ 1107 struct trng_usr_cfg usr_cfg = { 1108 .mode = TRNG_HRNG, 1109 .seed_life = CFG_VERSAL_TRNG_SEED_LIFE, 1110 .predict_en = false, 1111 .df_disable = false, 1112 .dfmul = CFG_VERSAL_TRNG_DF_MUL, 1113 .iseed_en = false, 1114 .pstr_en = true, 1115 }; 1116 1117 memcpy(usr_cfg.pstr, pers_str, TRNG_PERS_STR_LEN); 1118 versal_trng.cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, 1119 versal_trng.cfg.base, 1120 versal_trng.cfg.len); 1121 if (!versal_trng.cfg.addr) { 1122 EMSG("Failed to map TRNG"); 1123 panic(); 1124 } 1125 1126 if (trng_kat_test(&versal_trng)) { 1127 EMSG("KAT Failed"); 1128 panic(); 1129 } 1130 1131 if (trng_health_test(&versal_trng)) { 1132 EMSG("RunHealthTest Failed"); 1133 panic(); 1134 } 1135 1136 if (trng_instantiate(&versal_trng, &usr_cfg)) { 1137 EMSG("Driver instantiation Failed"); 1138 panic(); 1139 } 1140 1141 if (trng_reseed(&versal_trng, NULL, usr_cfg.dfmul)) { 1142 EMSG("Reseed Failed"); 1143 panic(); 1144 } 1145 1146 return TEE_SUCCESS; 1147 } 1148 1149 driver_init(trng_hrng_mode_init); 1150