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 55 #include <config.h> 56 #include <drivers/versal_pmc.h> 57 #include <drivers/versal_trng.h> 58 #include <initcall.h> 59 #include <io.h> 60 #include <kernel/delay.h> 61 #include <kernel/panic.h> 62 #include <mm/core_mmu.h> 63 #include <mm/core_memprot.h> 64 #include <rng_support.h> 65 #include <stdint.h> 66 #include <string.h> 67 #include <tee/tee_cryp_utl.h> 68 #include <util.h> 69 70 #ifdef CFG_VERSAL_RNG_IO 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_TSTMODE_MASK BIT(6) 81 #define TRNG_CTRL_PRNGSTART_MASK BIT(5) 82 #define TRNG_CTRL_PRNGXS_MASK BIT(3) 83 #define TRNG_CTRL_TRSSEN_MASK BIT(2) 84 #define TRNG_CTRL_PRNGSRST_MASK BIT(0) 85 86 #define TRNG_CTRL_PERSODISABLE_MASK BIT(10) 87 #define TRNG_CTRL_SINGLEGENMODE_MASK BIT(9) 88 89 #ifdef CFG_VERSAL_RNG_V2 90 /* register CTRL_2 is also called CONF_0 */ 91 #define TRNG_CTRL_2 0x0C 92 #define TRNG_CTRL_2_RCTCUTOFF_SHIFT 8 93 #define TRNG_CTRL_2_RCTCUTOFF_MASK GENMASK_32(16, 8) 94 #define TRNG_CTRL_2_RCTCUTOFF_DEFVAL 0x21 95 #define TRNG_CTRL_2_DIT_SHIFT 0 96 #define TRNG_CTRL_2_DIT_MASK GENMASK_32(4, 0) 97 #define TRNG_CTRL_2_DIT_DEFVAL 0xC 98 /* register CTRL_3 is also called CONF_1 */ 99 #define TRNG_CTRL_3 0x10 100 #define TRNG_CTRL_3_APTCUTOFF_SHIFT 8 101 #define TRNG_CTRL_3_APTCUTOFF_MASK GENMASK_32(17, 8) 102 #define TRNG_CTRL_3_APTCUTOFF_DEFVAL 0x264 103 #define TRNG_CTRL_3_DLEN_SHIFT 0 104 #define TRNG_CTRL_3_DLEN_MASK GENMASK_32(7, 0) 105 #define TRNG_CTRL_3_DLEN_DEFVAL 0x9 106 /* register CTRL_4 is also called TEST */ 107 #define TRNG_CTRL_4 0x14 108 #define TRNG_CTRL_4_SINGLEBITRAW_MASK BIT(0) 109 #endif 110 111 #define TRNG_EXT_SEED_0 0x40 112 /* 113 * Below registers are not directly referenced in driver but are accessed 114 * with offset from TRNG_EXT_SEED_0 115 * Register: TRNG_EXT_SEED_1 0x00000044 116 * Register: TRNG_EXT_SEED_2 0x00000048 117 * Register: TRNG_EXT_SEED_3 0x0000004C 118 * Register: TRNG_EXT_SEED_4 0x00000050 119 * Register: TRNG_EXT_SEED_5 0x00000054 120 * Register: TRNG_EXT_SEED_6 0x00000058 121 * Register: TRNG_EXT_SEED_7 0x0000005C 122 * Register: TRNG_EXT_SEED_8 0x00000060 123 * Register: TRNG_EXT_SEED_9 0x00000064 124 * Register: TRNG_EXT_SEED_10 0x00000068 125 * Register: TRNG_EXT_SEED_11 0x0000006C 126 */ 127 #define TRNG_PER_STRING_0 0x80 128 /* 129 * Below registers are not directly referenced in driver but are accessed 130 * with offset from TRNG_PER_STRING_0 131 * Register: TRNG_PER_STRING_1 0x00000084 132 * Register: TRNG_PER_STRING_2 0x00000088 133 * Register: TRNG_PER_STRING_3 0x0000008C 134 * Register: TRNG_PER_STRING_4 0x00000090 135 * Register: TRNG_PER_STRING_5 0x00000094 136 * Register: TRNG_PER_STRING_6 0x00000098 137 * Register: TRNG_PER_STRING_7 0x0000009C 138 * Register: TRNG_PER_STRING_8 0x000000A0 139 * Register: TRNG_PER_STRING_9 0x000000A4 140 * Register: TRNG_PER_STRING_10 0x000000A8 141 * Register: TRNG_PER_STRING_11 0x000000AC 142 */ 143 #define TRNG_CORE_OUTPUT 0xC0 144 #define TRNG_RESET 0xD0 145 #define TRNG_RESET_VAL_MASK BIT(0) 146 #define TRNG_OSC_EN 0xD4 147 #define TRNG_OSC_EN_VAL_MASK BIT(0) 148 149 /* TRNG configuration */ 150 #define TRNG_BURST_SIZE 16 151 #define TRNG_BURST_SIZE_BITS 128 152 #define TRNG_NUM_INIT_REGS 12 153 #define TRNG_REG_SIZE 32 154 #define TRNG_BYTES_PER_REG 4 155 #define TRNG_MAX_QCNT 4 156 #define TRNG_RESEED_TIMEOUT 15000 157 #define TRNG_GENERATE_TIMEOUT 8000 158 #define TRNG_V2_RESEED_TIMEOUT 1500000 159 #define TRNG_V2_GENERATE_TIMEOUT 1500000 160 #define TRNG_V2_MIN_SEEDLIFE 1 161 #define TRNG_V2_MAX_SEEDLIFE 0x80000 162 #define TRNG_MIN_DFLENMULT 2 163 #define TRNG_MAX_DFLENMULT 9 164 #define TRNG_V2_MIN_DFLENMULT TRNG_MIN_DFLENMULT 165 #define TRNG_V2_MAX_DFLENMULT 31 166 #define PRNGMODE_RESEED 0 167 #define PRNGMODE_GEN TRNG_CTRL_PRNGMODE_MASK 168 #define RESET_DELAY 10 169 #define TRNG_ENTROPY_SEED_LEN 64 170 #define TRNG_SEC_STRENGTH_LEN 32 171 #define TRNG_SEED_REGS 12 172 #define TRNG_GEN_LEN 32 173 #define BYTES_PER_BLOCK 16 174 #define ALL_A_PATTERN_32 0xAAAAAAAA 175 #define ALL_5_PATTERN_32 0x55555555 176 177 #ifdef CFG_VERSAL_RNG_V2 178 #define TRNG_DF_2CLKS_WAIT 2 179 #define TRNG_DF_700CLKS_WAIT 10 180 #define TRNG_DF_NUM_OF_BYTES_BEFORE_MIN_700CLKS_WAIT 8 181 #endif 182 183 /* Derivative function helper macros */ 184 #define DF_SEED 0 185 #define DF_RAND 1 186 187 #ifdef CFG_VERSAL_RNG_V1 188 #define DF_PAD_VAL 0x80 189 #define DF_KEY_LEN 32 190 #define BLK_SIZE 16 191 #define MAX_ROUNDS 14 192 193 /* Derivative function variables */ 194 static unsigned char sbx1[256]; 195 static unsigned char sbx2[256]; 196 static unsigned char sbx3[256]; 197 static unsigned char schedule[BLK_SIZE * (MAX_ROUNDS + 1)]; 198 static unsigned int rounds; 199 200 static void rota4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d) 201 { 202 uint8_t t = *a; 203 204 *a = sbx1[*b]; 205 *b = sbx1[*c]; 206 *c = sbx1[*d]; 207 *d = sbx1[t]; 208 } 209 210 static void rota2(uint8_t *a, uint8_t *b) 211 { 212 uint8_t t = *a; 213 214 *a = sbx1[*b]; 215 *b = sbx1[t]; 216 } 217 218 static void sbox4(uint8_t *a, uint8_t *b, uint8_t *c, uint8_t *d) 219 { 220 *a = sbx1[*a]; 221 *b = sbx1[*b]; 222 *c = sbx1[*c]; 223 *d = sbx1[*d]; 224 } 225 226 static void xorb(uint8_t *res, const uint8_t *in) 227 { 228 size_t i = 0; 229 230 for (i = 0; i < BLK_SIZE; ++i) 231 res[i] ^= in[i]; 232 } 233 234 static void set_key(uint8_t *res, const uint8_t *src, unsigned int roundval) 235 { 236 memcpy(res, src, BLK_SIZE); 237 xorb(res, schedule + roundval * BLK_SIZE); 238 } 239 240 static void mix_column_sbox(uint8_t *dst, const uint8_t *f) 241 { 242 size_t i = 0; 243 size_t a = 0; 244 size_t b = 0; 245 size_t c = 0; 246 size_t d = 0; 247 248 for (i = 0; i < 4; i++) { 249 a = 4 * i; 250 b = (0x5 + a) % 16; 251 c = (0xa + a) % 16; 252 d = (0xf + a) % 16; 253 dst[0 + a] = sbx2[f[a]] ^ sbx3[f[b]] ^ sbx1[f[c]] ^ sbx1[f[d]]; 254 dst[1 + a] = sbx1[f[a]] ^ sbx2[f[b]] ^ sbx3[f[c]] ^ sbx1[f[d]]; 255 dst[2 + a] = sbx1[f[a]] ^ sbx1[f[b]] ^ sbx2[f[c]] ^ sbx3[f[d]]; 256 dst[3 + a] = sbx3[f[a]] ^ sbx1[f[b]] ^ sbx1[f[c]] ^ sbx2[f[d]]; 257 } 258 } 259 260 static void shift_row_sbox(uint8_t *f) 261 { 262 sbox4(&f[0], &f[4], &f[8], &f[12]); 263 rota4(&f[1], &f[5], &f[9], &f[13]); 264 rota2(&f[2], &f[10]); 265 rota2(&f[6], &f[14]); 266 rota4(&f[15], &f[11], &f[7], &f[3]); 267 } 268 269 static void encrypt(uint8_t *in, uint8_t *out) 270 { 271 uint8_t fa[BLK_SIZE] = { 0 }; 272 uint8_t fb[BLK_SIZE] = { 0 }; 273 size_t roundval = 0; 274 275 set_key(fa, in, 0); 276 for (roundval = 1; roundval < rounds; ++roundval) { 277 mix_column_sbox(fb, fa); 278 set_key(fa, fb, roundval); 279 } 280 281 shift_row_sbox(fa); 282 set_key(out, fa, roundval); 283 } 284 285 static void checksum(unsigned char *in, uint8_t *iv, int max_blk) 286 { 287 while (max_blk > 0) { 288 xorb(iv, in); 289 encrypt(iv, iv); 290 in += BLK_SIZE; 291 max_blk -= 1; 292 } 293 } 294 295 static void setup_key(const unsigned char *k, size_t klen) 296 { 297 unsigned char rcon = 1; 298 size_t sch_size = 240; 299 size_t i = 0; 300 301 rounds = MAX_ROUNDS; 302 memcpy(schedule, k, klen); 303 for (i = klen; i < sch_size; i += 4) { 304 unsigned char t0 = 0; 305 unsigned char t1 = 0; 306 unsigned char t2 = 0; 307 unsigned char t3 = 0; 308 int ik = 0; 309 310 t0 = schedule[i - 4]; 311 t1 = schedule[i - 3]; 312 t2 = schedule[i - 2]; 313 t3 = schedule[i - 1]; 314 if (i % klen == 0) { 315 rota4(&t0, &t1, &t2, &t3); 316 t0 ^= rcon; 317 rcon = (rcon << 1) ^ (((rcon >> 7) & 1) * 0x1B); 318 } else if (i % klen == 16) { 319 sbox4(&t0, &t1, &t2, &t3); 320 } 321 ik = i - klen; 322 schedule[i + 0] = schedule[ik + 0] ^ t0; 323 schedule[i + 1] = schedule[ik + 1] ^ t1; 324 schedule[i + 2] = schedule[ik + 2] ^ t2; 325 schedule[i + 3] = schedule[ik + 3] ^ t3; 326 } 327 } 328 329 static void trng_df_init(void) 330 { 331 const uint8_t sb[] = { 332 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 333 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 334 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 335 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 336 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 337 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 338 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 339 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 340 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 341 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 342 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 343 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 344 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 345 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 346 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 347 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 348 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 349 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 350 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 351 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 352 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 353 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 354 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 355 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 356 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 357 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, 358 }; 359 size_t i = 0; 360 361 memcpy(sbx1, sb, sizeof(sb)); 362 for (i = 0; i < sizeof(sb); i++) { 363 sbx2[i] = (sb[i] << 1) ^ (((sb[i] >> 7) & 1) * 0x1B); 364 sbx3[i] = sbx2[i] ^ sb[i]; 365 } 366 } 367 368 /* 369 * This function implements the Derivative Function by distilling the entropy 370 * available in its input into a smaller number of bits on the output. 371 * - per NIST SP80090A. 372 * 373 * The Block Cipher algorithm follows sections 10.3.2 and 10.3.3 of the 374 * NIST.SP.800-90Ar1 document 375 */ 376 static void trng_df_algorithm(struct versal_trng *trng, uint8_t *dfout, 377 uint32_t flag, const uint8_t *pstr) 378 { 379 static bool df_init; 380 const uint8_t df_key[DF_KEY_LEN] = { 381 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 382 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 383 }; 384 size_t dfin_len = sizeof(struct trng_dfin) + trng->len; 385 uint8_t *inp_blk = NULL; 386 uint8_t *out_blk = NULL; 387 uintptr_t reminder = 0; 388 size_t xfer_len = 0; 389 uint32_t index = 0; 390 uintptr_t src = 0; 391 uintptr_t dst = 0; 392 size_t offset = 0; 393 394 if (!df_init) { 395 trng_df_init(); 396 df_init = true; 397 } 398 399 if (flag == DF_SEED) 400 trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_PERS_STR_LEN); 401 else 402 trng->dfin.val2 = TEE_U32_TO_BIG_ENDIAN(TRNG_GEN_LEN); 403 404 trng->dfin.pad_data[0] = DF_PAD_VAL; 405 406 if (!pstr) { 407 if (trng->len > (MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN)) 408 panic(); 409 410 dfin_len = dfin_len - TRNG_PERS_STR_LEN - MAX_PRE_DF_LEN; 411 trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len); 412 413 xfer_len = DF_PAD_DATA_LEN; 414 src = (uintptr_t)trng->dfin.pad_data; 415 offset = MAX_PRE_DF_LEN + TRNG_PERS_STR_LEN - trng->len; 416 } else { 417 if (trng->len > MAX_PRE_DF_LEN) 418 panic(); 419 420 memcpy(trng->dfin.pstr, pstr, TRNG_PERS_STR_LEN); 421 dfin_len = dfin_len - MAX_PRE_DF_LEN; 422 trng->dfin.val1 = TEE_U32_TO_BIG_ENDIAN(trng->len + 423 TRNG_PERS_STR_LEN); 424 xfer_len = DF_PAD_DATA_LEN + TRNG_PERS_STR_LEN; 425 src = (uintptr_t)trng->dfin.pstr; 426 offset = MAX_PRE_DF_LEN - trng->len; 427 } 428 429 /* Move back into the dfin structure */ 430 dst = src - offset; 431 reminder = (uintptr_t)&trng->dfin + sizeof(trng->dfin) - offset; 432 if (offset) { 433 if (xfer_len > offset) 434 panic("Overlapping data"); 435 436 memcpy((void *)dst, (void *)src, xfer_len); 437 memset((void *)reminder, 0, offset); 438 } 439 440 /* DF algorithm - step 1 */ 441 setup_key(df_key, DF_KEY_LEN); 442 for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) { 443 memset((void *)(trng->dfout + index), 0, BLK_SIZE); 444 trng->dfin.ivc[0] = TEE_U32_TO_BIG_ENDIAN(index / BLK_SIZE); 445 checksum((unsigned char *)&trng->dfin, 446 trng->dfout + index, dfin_len / BLK_SIZE); 447 } 448 449 /* DF algorithm - step 2 */ 450 setup_key(trng->dfout, DF_KEY_LEN); 451 for (index = 0; index < TRNG_SEED_LEN; index += BLK_SIZE) { 452 if (!index) 453 inp_blk = &dfout[TRNG_SEC_STRENGTH_LEN]; 454 else 455 inp_blk = &dfout[index - BLK_SIZE]; 456 457 out_blk = &dfout[index]; 458 encrypt(inp_blk, out_blk); 459 } 460 } 461 #endif 462 463 static uint32_t trng_read32(vaddr_t addr, size_t off) 464 { 465 return io_read32(addr + off); 466 } 467 468 static void trng_write32(vaddr_t addr, size_t off, uint32_t val) 469 { 470 io_write32(addr + off, val); 471 } 472 473 static void trng_clrset32(vaddr_t addr, size_t off, uint32_t mask, uint32_t val) 474 { 475 io_clrsetbits32(addr + off, mask, mask & val); 476 } 477 478 static void trng_write32_range(const struct versal_trng *trng, uint32_t start, 479 uint32_t num_regs, const uint8_t *buf) 480 { 481 size_t off = 0; 482 uint32_t val = 0; 483 size_t cnt = 0; 484 size_t i = 0; 485 486 for (i = 0; i < num_regs; ++i) { 487 if (!buf) { 488 off = start + i * TRNG_BYTES_PER_REG; 489 trng_write32(trng->cfg.addr, off, 0); 490 continue; 491 } 492 493 val = 0; 494 for (cnt = 0; cnt < TRNG_BYTES_PER_REG; ++cnt) 495 val = (val << 8) | buf[i * TRNG_BYTES_PER_REG + cnt]; 496 497 off = start + (TRNG_NUM_INIT_REGS - 1 - i) * TRNG_BYTES_PER_REG; 498 trng_write32(trng->cfg.addr, off, val); 499 } 500 } 501 502 static TEE_Result trng_wait_for_event(vaddr_t addr, size_t off, uint32_t mask, 503 uint32_t event, uint32_t time_out) 504 { 505 uint64_t tref = timeout_init_us(time_out); 506 507 do { 508 if (timeout_elapsed(tref)) 509 break; 510 } while ((io_read32(addr + off) & mask) != event); 511 512 /* Normal world might have suspended the OP-TEE thread, check again */ 513 if ((io_read32(addr + off) & mask) != event) 514 return TEE_ERROR_GENERIC; 515 516 return TEE_SUCCESS; 517 } 518 519 static void trng_soft_reset(const struct versal_trng *trng) 520 { 521 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK, 522 TRNG_CTRL_PRNGSRST_MASK); 523 udelay(RESET_DELAY); 524 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSRST_MASK, 0); 525 } 526 527 static void trng_reset(const struct versal_trng *trng) 528 { 529 trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK); 530 udelay(RESET_DELAY); 531 trng_write32(trng->cfg.addr, TRNG_RESET, 0); 532 trng_soft_reset(trng); 533 } 534 535 static void trng_hold_reset(const struct versal_trng *trng) 536 { 537 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 538 TRNG_CTRL_PRNGSRST_MASK, TRNG_CTRL_PRNGSRST_MASK); 539 trng_write32(trng->cfg.addr, TRNG_RESET, TRNG_RESET_VAL_MASK); 540 udelay(RESET_DELAY); 541 } 542 543 #ifdef CFG_VERSAL_RNG_V2 544 static int trng_v2_write_seed(const struct versal_trng *trng, 545 const uint8_t *seed, uint8_t dlen) 546 { 547 int status = TEE_ERROR_GENERIC; 548 uint32_t seed_len = (dlen + 1) * BYTES_PER_BLOCK; 549 uint32_t idx = 0; 550 uint8_t cnt = 0; 551 552 while (idx < seed_len) { 553 uint8_t seed_construct = 0; 554 555 for (cnt = 0; cnt < 8; cnt++) { 556 uint32_t bit = (seed[idx] >> (8 - 1 - cnt)) & 0x01; 557 558 trng_write32(trng->cfg.addr, TRNG_CTRL_4, bit); 559 seed_construct = (seed_construct << 1) | bit; 560 } 561 562 if (seed_construct != seed[idx]) 563 goto END; 564 565 udelay(TRNG_DF_2CLKS_WAIT); 566 if (!(idx % TRNG_DF_NUM_OF_BYTES_BEFORE_MIN_700CLKS_WAIT)) 567 udelay(TRNG_DF_700CLKS_WAIT); 568 569 idx++; 570 } 571 if (idx == seed_len) 572 status = TEE_SUCCESS; 573 574 END: 575 return status; 576 } 577 #endif 578 579 #ifdef CFG_VERSAL_RNG_V1 580 static TEE_Result trng_check_seed(uint8_t *entropy, uint32_t len) 581 { 582 uint32_t *p = (void *)entropy; 583 size_t i = 0; 584 585 for (i = 0; i < len / sizeof(*p); i++) { 586 if (p[i] == ALL_A_PATTERN_32) 587 return TEE_ERROR_GENERIC; 588 589 if (p[i] == ALL_5_PATTERN_32) 590 return TEE_ERROR_GENERIC; 591 } 592 593 return TEE_SUCCESS; 594 } 595 #endif 596 597 static TEE_Result trng_collect_random(struct versal_trng *trng, uint8_t *dst, 598 size_t len) 599 { 600 const size_t bursts = len / TRNG_BURST_SIZE; 601 const size_t words = TRNG_BURST_SIZE_BITS / TRNG_REG_SIZE; 602 uint32_t *p = (void *)dst; 603 size_t bcnt = 0; 604 size_t wcnt = 0; 605 size_t index = 0; 606 uint32_t val = 0; 607 bool match = false; 608 uint32_t timeout = TRNG_GENERATE_TIMEOUT; 609 bool do_start = true; 610 611 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2) { 612 if (trng->usr_cfg.predict_en || 613 !trng->stats.elapsed_seed_life) { 614 uint32_t singlegen = 0; 615 616 if (trng->usr_cfg.predict_en) 617 singlegen = TRNG_CTRL_SINGLEGENMODE_MASK; 618 619 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 620 TRNG_CTRL_PRNGMODE_MASK | 621 TRNG_CTRL_SINGLEGENMODE_MASK | 622 TRNG_CTRL_PRNGSTART_MASK, 623 PRNGMODE_GEN | singlegen); 624 } else { 625 do_start = false; 626 } 627 628 timeout = TRNG_V2_GENERATE_TIMEOUT; 629 } 630 631 if (do_start) 632 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 633 TRNG_CTRL_PRNGSTART_MASK, 634 TRNG_CTRL_PRNGSTART_MASK); 635 636 /* 637 * Loop as many times based on len requested. In each burst 128 bits 638 * are generated, which is reflected in QCNT value of 4 by hardware. 639 */ 640 for (bcnt = 0; bcnt < bursts; bcnt++) { 641 if (trng_wait_for_event(trng->cfg.addr, 642 TRNG_STATUS, TRNG_STATUS_QCNT_MASK, 643 TRNG_MAX_QCNT << TRNG_STATUS_QCNT_SHIFT, 644 timeout)) { 645 EMSG("Timeout waiting for randomness"); 646 return TEE_ERROR_GENERIC; 647 } 648 649 /* 650 * DTF flag set during generate indicates catastrophic 651 * condition, which needs to be checked for every time unless we 652 * are in PTRNG mode 653 */ 654 if (trng->usr_cfg.mode != TRNG_PTRNG) { 655 val = trng_read32(trng->cfg.addr, TRNG_STATUS); 656 if (val & TRNG_STATUS_DTF_MASK) { 657 EMSG("Catastrophic DFT error"); 658 trng->status = TRNG_CATASTROPHIC; 659 660 return TEE_ERROR_GENERIC; 661 } 662 } 663 /* 664 * Read the core output register 4 times to consume the random 665 * data generated for every burst. 666 */ 667 match = true; 668 for (wcnt = 0; wcnt < words; wcnt++) { 669 val = trng_read32(trng->cfg.addr, TRNG_CORE_OUTPUT); 670 671 if (bcnt > 0 && trng->buf[wcnt] != val) 672 match = false; 673 674 trng->buf[wcnt] = val; 675 676 if (dst) { 677 p[index] = TEE_U32_TO_BIG_ENDIAN(val); 678 index++; 679 } 680 } 681 682 if (bursts > 1 && bcnt > 0 && match) { 683 EMSG("Catastrophic software error"); 684 trng->status = TRNG_CATASTROPHIC; 685 return TEE_ERROR_GENERIC; 686 } 687 } 688 689 return TEE_SUCCESS; 690 } 691 692 #ifdef CFG_VERSAL_RNG_V2 693 static TEE_Result trng_v2_reseed_internal(struct versal_trng *trng, 694 uint8_t *eseed, uint8_t *str, 695 uint32_t mul) 696 { 697 uint32_t ret = TEE_ERROR_GENERIC; 698 uint32_t persmask = TRNG_CTRL_PERSODISABLE_MASK; 699 uint32_t val = 0; 700 701 trng->stats.bytes_reseed = 0; 702 trng->stats.elapsed_seed_life = 0; 703 704 /* Configure DF Len */ 705 trng_clrset32(trng->cfg.addr, TRNG_CTRL_3, TRNG_CTRL_3_DLEN_MASK, 706 (mul << TRNG_CTRL_3_DLEN_SHIFT)); 707 708 if (str) { 709 trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, 710 str); 711 persmask = 0; 712 } 713 714 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 715 TRNG_CTRL_PERSODISABLE_MASK | TRNG_CTRL_PRNGSTART_MASK, 716 persmask); 717 718 switch (trng->usr_cfg.mode) { 719 case TRNG_HRNG: 720 /* Enable ring oscillators for random seed source */ 721 trng_clrset32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK, 722 TRNG_OSC_EN_VAL_MASK); 723 724 /* Enable TRSSEN and set PRNG mode for reseed operation */ 725 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 726 TRNG_CTRL_PRNGMODE_MASK | 727 TRNG_CTRL_TRSSEN_MASK | TRNG_CTRL_PRNGXS_MASK, 728 PRNGMODE_RESEED | 729 TRNG_CTRL_TRSSEN_MASK); 730 731 /* Start reseed operation */ 732 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 733 TRNG_CTRL_PRNGSTART_MASK, 734 TRNG_CTRL_PRNGSTART_MASK); 735 break; 736 case TRNG_DRNG: 737 /* Enable TST mode and set PRNG mode for reseed operation */ 738 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 739 TRNG_CTRL_PRNGMODE_MASK | 740 TRNG_CTRL_TSTMODE_MASK | TRNG_CTRL_TRSSEN_MASK, 741 PRNGMODE_RESEED | 742 TRNG_CTRL_TSTMODE_MASK | TRNG_CTRL_TRSSEN_MASK); 743 744 /* Start reseed operation */ 745 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 746 TRNG_CTRL_PRNGSTART_MASK, 747 TRNG_CTRL_PRNGSTART_MASK); 748 749 ret = trng_v2_write_seed(trng, eseed, mul); 750 if (ret) 751 return ret; 752 break; 753 default: 754 /* shall not be reached */ 755 panic(); 756 } 757 758 /* Wait for reseed operation */ 759 if (trng_wait_for_event(trng->cfg.addr, TRNG_STATUS, 760 TRNG_STATUS_DONE_MASK, 761 TRNG_STATUS_DONE_MASK, 762 TRNG_V2_RESEED_TIMEOUT)) 763 goto error; 764 765 /* Check SP800 - 90B (entropy health test error) */ 766 val = trng_read32(trng->cfg.addr, TRNG_STATUS) & TRNG_STATUS_CERTF_MASK; 767 if (val == TRNG_STATUS_CERTF_MASK) 768 goto error; 769 770 /* Stop reseed operation */ 771 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 772 TRNG_CTRL_PRNGSTART_MASK | TRNG_CTRL_TRSSEN_MASK, 0); 773 return TEE_SUCCESS; 774 775 error: 776 trng->status = TRNG_ERROR; 777 return TEE_ERROR_GENERIC; 778 } 779 #else 780 static TEE_Result trng_v2_reseed_internal(struct versal_trng *trng __unused, 781 uint8_t *eseed __unused, 782 uint8_t *str __unused, 783 uint32_t mul __unused) 784 { 785 return TEE_ERROR_NOT_SUPPORTED; 786 } 787 #endif 788 789 #ifdef CFG_VERSAL_RNG_V1 790 static TEE_Result trng_reseed_internal_nodf(struct versal_trng *trng, 791 uint8_t *eseed, uint8_t *str) 792 { 793 uint8_t entropy[TRNG_ENTROPY_SEED_LEN] = { 0 }; 794 uint8_t *seed = NULL; 795 796 switch (trng->usr_cfg.mode) { 797 case TRNG_HRNG: 798 /* 799 * Versal TRNG IP doesn't recognize alternate 1 and 0 pattern, 800 * hence the entropy output need to be monitored before using it 801 * as seed. This means, TRNG couldn't be configured for entropy 802 * source as seed source. Instead, entropy data is collected as 803 * random data, and after inspecting for pattern, is fed again 804 * to the external seed registers. This is essentially similar 805 * to HRNG + DF case except that there is no DF involved. This 806 * actually is configuration for PTRNG mode (not for reseed) to 807 * collect random output data from entropy source. 808 */ 809 trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK); 810 trng_soft_reset(trng); 811 trng_write32(trng->cfg.addr, TRNG_CTRL, 812 TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK); 813 814 if (trng_collect_random(trng, entropy, TRNG_ENTROPY_SEED_LEN)) 815 return TEE_ERROR_GENERIC; 816 817 if (trng_check_seed(entropy, TRNG_ENTROPY_SEED_LEN)) 818 return TEE_ERROR_GENERIC; 819 820 seed = entropy; 821 break; 822 case TRNG_DRNG: 823 seed = eseed; 824 break; 825 default: 826 seed = NULL; 827 break; 828 } 829 830 trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, seed); 831 if (str) 832 trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, 833 str); 834 835 return TEE_SUCCESS; 836 } 837 838 static TEE_Result trng_reseed_internal_df(struct versal_trng *trng, 839 uint8_t *eseed, uint8_t *str) 840 { 841 memset(&trng->dfin, 0, sizeof(trng->dfin)); 842 843 switch (trng->usr_cfg.mode) { 844 case TRNG_HRNG: 845 /* see comment in _nodf() */ 846 trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK); 847 trng_soft_reset(trng); 848 trng_write32(trng->cfg.addr, TRNG_CTRL, 849 TRNG_CTRL_EUMODE_MASK | TRNG_CTRL_TRSSEN_MASK); 850 851 if (trng_collect_random(trng, trng->dfin.entropy, trng->len)) 852 return TEE_ERROR_GENERIC; 853 854 if (trng_check_seed(trng->dfin.entropy, trng->len)) 855 return TEE_ERROR_GENERIC; 856 break; 857 case TRNG_DRNG: 858 memcpy(trng->dfin.entropy, eseed, trng->len); 859 break; 860 default: 861 break; 862 } 863 864 trng_df_algorithm(trng, trng->dfout, DF_SEED, str); 865 trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, trng->dfout); 866 867 return TEE_SUCCESS; 868 } 869 870 static TEE_Result trng_v1_reseed_internal(struct versal_trng *trng, 871 uint8_t *eseed, uint8_t *str, 872 uint32_t mul) 873 { 874 uint32_t val = 0; 875 876 trng->stats.bytes_reseed = 0; 877 trng->stats.elapsed_seed_life = 0; 878 879 if (trng->usr_cfg.df_disable) 880 trng->len = TRNG_SEED_LEN; 881 else 882 trng->len = (mul + 1) * BYTES_PER_BLOCK; 883 884 if (trng->usr_cfg.df_disable) { 885 if (trng_reseed_internal_nodf(trng, eseed, str)) 886 goto error; 887 } else { 888 if (trng_reseed_internal_df(trng, eseed, str)) 889 goto error; 890 } 891 892 /* 893 * Set PRNGMODE to reseed and seed source (PRNGXS) to 894 * TRNG_EXT_SEED_*; the latter especially also for HRNG due to 895 * not being able to selected entropy source as seed source. 896 */ 897 trng_write32(trng->cfg.addr, TRNG_CTRL, 898 PRNGMODE_RESEED | TRNG_CTRL_PRNGXS_MASK); 899 900 /* Start the reseed operation */ 901 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 902 TRNG_CTRL_PRNGSTART_MASK, 903 TRNG_CTRL_PRNGSTART_MASK); 904 905 /* Wait for reseed operation */ 906 if (trng_wait_for_event(trng->cfg.addr, TRNG_STATUS, 907 TRNG_STATUS_DONE_MASK, 908 TRNG_STATUS_DONE_MASK, 909 TRNG_RESEED_TIMEOUT)) 910 goto error; 911 912 /* Check SP800 - 90B (entropy health test error) */ 913 val = trng_read32(trng->cfg.addr, TRNG_STATUS) & TRNG_STATUS_CERTF_MASK; 914 if (val == TRNG_STATUS_CERTF_MASK) 915 goto error; 916 917 /* Stop reseed operation */ 918 trng_clrset32(trng->cfg.addr, TRNG_CTRL, TRNG_CTRL_PRNGSTART_MASK, 0); 919 return TEE_SUCCESS; 920 error: 921 trng->status = TRNG_ERROR; 922 return TEE_ERROR_GENERIC; 923 } 924 #else 925 static void trng_df_algorithm(struct versal_trng *trng __unused, 926 uint8_t *dfout __unused, 927 uint32_t flag __unused, 928 const uint8_t *pstr __unused) 929 930 { 931 panic(); 932 } 933 934 static TEE_Result trng_v1_reseed_internal(struct versal_trng *trng __unused, 935 uint8_t *eseed __unused, 936 uint8_t *str __unused, 937 uint32_t mul __unused) 938 { 939 return TEE_ERROR_NOT_SUPPORTED; 940 } 941 #endif 942 943 static TEE_Result trng_reseed_internal(struct versal_trng *trng, 944 uint8_t *eseed, uint8_t *str, 945 uint32_t mul) 946 { 947 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1) 948 return trng_v1_reseed_internal(trng, eseed, str, mul); 949 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2) 950 return trng_v2_reseed_internal(trng, eseed, str, mul); 951 952 return TEE_ERROR_GENERIC; 953 } 954 955 static TEE_Result trng_instantiate(struct versal_trng *trng, 956 const struct trng_usr_cfg *usr_cfg) 957 { 958 uint8_t *seed = NULL; 959 uint8_t *pers = NULL; 960 961 if (!trng) 962 return TEE_ERROR_GENERIC; 963 964 if (!usr_cfg) 965 goto error; 966 967 if (trng->status != TRNG_UNINITIALIZED) 968 goto error; 969 970 if (usr_cfg->mode != TRNG_HRNG && usr_cfg->mode != TRNG_DRNG && 971 usr_cfg->mode != TRNG_PTRNG) 972 goto error; 973 974 if (usr_cfg->mode != TRNG_PTRNG && !usr_cfg->seed_life) 975 goto error; 976 977 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2 && 978 usr_cfg->mode != TRNG_PTRNG) 979 if (usr_cfg->seed_life < TRNG_V2_MIN_SEEDLIFE || 980 usr_cfg->seed_life > TRNG_V2_MAX_SEEDLIFE) 981 goto error; 982 983 if (!usr_cfg->iseed_en && usr_cfg->mode == TRNG_DRNG) 984 goto error; 985 986 if (usr_cfg->iseed_en && usr_cfg->mode == TRNG_HRNG) 987 goto error; 988 989 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 && 990 !usr_cfg->df_disable && 991 (usr_cfg->dfmul < TRNG_MIN_DFLENMULT || 992 usr_cfg->dfmul > TRNG_MAX_DFLENMULT)) 993 goto error; 994 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2 && 995 (usr_cfg->df_disable || 996 (usr_cfg->dfmul < TRNG_V2_MIN_DFLENMULT || 997 usr_cfg->dfmul > TRNG_V2_MAX_DFLENMULT))) 998 goto error; 999 1000 if (usr_cfg->df_disable && usr_cfg->dfmul) 1001 goto error; 1002 1003 if (usr_cfg->mode == TRNG_PTRNG && 1004 (usr_cfg->iseed_en || usr_cfg->pstr_en || 1005 usr_cfg->predict_en || usr_cfg->seed_life)) 1006 goto error; 1007 1008 memcpy(&trng->usr_cfg, usr_cfg, sizeof(struct trng_usr_cfg)); 1009 trng_reset(trng); 1010 1011 if (trng->usr_cfg.iseed_en) 1012 seed = (void *)trng->usr_cfg.init_seed; 1013 1014 if (trng->usr_cfg.pstr_en) 1015 pers = (void *)trng->usr_cfg.pstr; 1016 1017 if (trng->usr_cfg.mode != TRNG_PTRNG) { 1018 if (trng_reseed_internal(trng, seed, pers, trng->usr_cfg.dfmul)) 1019 goto error; 1020 } 1021 1022 trng->status = TRNG_HEALTHY; 1023 return TEE_SUCCESS; 1024 error: 1025 trng->status = TRNG_ERROR; 1026 return TEE_ERROR_GENERIC; 1027 } 1028 1029 static TEE_Result trng_reseed(struct versal_trng *trng, uint8_t *eseed, 1030 uint32_t mul) 1031 { 1032 if (!trng) 1033 return TEE_ERROR_GENERIC; 1034 1035 if (trng->status != TRNG_HEALTHY) 1036 goto error; 1037 1038 if (trng->usr_cfg.mode != TRNG_DRNG && trng->usr_cfg.mode != TRNG_HRNG) 1039 goto error; 1040 1041 if (trng->usr_cfg.mode == TRNG_DRNG && !eseed) 1042 goto error; 1043 1044 if (trng->usr_cfg.mode != TRNG_DRNG && eseed) 1045 goto error; 1046 1047 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 && 1048 !trng->usr_cfg.df_disable) { 1049 if (mul < TRNG_MIN_DFLENMULT || mul > TRNG_MAX_DFLENMULT) 1050 goto error; 1051 } 1052 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && trng->cfg.version == TRNG_V2 && 1053 (trng->usr_cfg.df_disable || 1054 (mul < TRNG_V2_MIN_DFLENMULT || mul > TRNG_V2_MAX_DFLENMULT))) 1055 goto error; 1056 1057 if (trng->usr_cfg.df_disable && mul) 1058 goto error; 1059 1060 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 && 1061 eseed && (trng->len > TRNG_SEED_LEN || 1062 !memcmp(eseed, trng->usr_cfg.init_seed, trng->len))) 1063 goto error; 1064 1065 if (trng_reseed_internal(trng, eseed, NULL, mul)) 1066 goto error; 1067 1068 return TEE_SUCCESS; 1069 error: 1070 trng->status = TRNG_ERROR; 1071 return TEE_ERROR_GENERIC; 1072 } 1073 1074 static TEE_Result trng_generate(struct versal_trng *trng, uint8_t *buf, 1075 size_t blen, bool predict) 1076 { 1077 uint32_t len = TRNG_SEC_STRENGTH_LEN; 1078 uint8_t *p = buf; 1079 uint32_t mul = 0; 1080 1081 if (!trng) 1082 return TEE_ERROR_GENERIC; 1083 1084 if (!p) 1085 goto error; 1086 1087 if (blen < TRNG_SEC_STRENGTH_LEN) 1088 goto error; 1089 1090 if (trng->status != TRNG_HEALTHY) 1091 goto error; 1092 1093 if (trng->usr_cfg.mode == TRNG_PTRNG && predict) 1094 goto error; 1095 1096 if (!trng->usr_cfg.predict_en && predict) 1097 goto error; 1098 1099 switch (trng->usr_cfg.mode) { 1100 case TRNG_HRNG: 1101 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && 1102 trng->cfg.version == TRNG_V2) 1103 mul = trng->usr_cfg.dfmul; 1104 1105 if (trng->stats.elapsed_seed_life >= trng->usr_cfg.seed_life) { 1106 if (trng_reseed_internal(trng, NULL, NULL, mul)) 1107 goto error; 1108 } 1109 1110 if (predict && trng->stats.elapsed_seed_life > 0) { 1111 if (trng_reseed_internal(trng, NULL, NULL, mul)) 1112 goto error; 1113 } 1114 1115 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && 1116 trng->cfg.version == TRNG_V1) 1117 trng_write32(trng->cfg.addr, TRNG_CTRL, 1118 PRNGMODE_GEN | TRNG_CTRL_PRNGXS_MASK); 1119 break; 1120 case TRNG_DRNG: 1121 if (trng->stats.elapsed_seed_life >= trng->usr_cfg.seed_life) { 1122 EMSG("Reseeding required"); 1123 goto error; 1124 } 1125 1126 if (predict && trng->stats.elapsed_seed_life > 0) { 1127 EMSG("Reseeding required"); 1128 goto error; 1129 } 1130 1131 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && 1132 trng->cfg.version == TRNG_V1) 1133 trng_write32(trng->cfg.addr, TRNG_CTRL, 1134 PRNGMODE_GEN | TRNG_CTRL_PRNGXS_MASK); 1135 break; 1136 default: 1137 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && 1138 trng->cfg.version == TRNG_V1 && 1139 !trng->usr_cfg.df_disable) { 1140 memset(&trng->dfin, 0, sizeof(trng->dfin)); 1141 len = (trng->usr_cfg.dfmul + 1) * BYTES_PER_BLOCK; 1142 trng->len = len; 1143 p = trng->dfin.entropy; 1144 } 1145 /* Enable the 8 ring oscillators used for entropy source */ 1146 trng_write32(trng->cfg.addr, TRNG_OSC_EN, TRNG_OSC_EN_VAL_MASK); 1147 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && 1148 trng->cfg.version == TRNG_V1) { 1149 trng_soft_reset(trng); 1150 trng_write32(trng->cfg.addr, TRNG_CTRL, 1151 TRNG_CTRL_EUMODE_MASK | 1152 TRNG_CTRL_TRSSEN_MASK); 1153 } 1154 1155 if (IS_ENABLED(CFG_VERSAL_RNG_V2) && 1156 trng->cfg.version == TRNG_V2) 1157 trng_clrset32(trng->cfg.addr, TRNG_CTRL, 1158 TRNG_CTRL_TRSSEN_MASK | 1159 TRNG_CTRL_EUMODE_MASK | 1160 TRNG_CTRL_PRNGXS_MASK, 1161 TRNG_CTRL_TRSSEN_MASK | 1162 TRNG_CTRL_EUMODE_MASK); 1163 break; 1164 } 1165 1166 if (trng_collect_random(trng, p, len)) 1167 goto error; 1168 1169 trng->stats.bytes_reseed += len; 1170 trng->stats.bytes += len; 1171 trng->stats.elapsed_seed_life++; 1172 1173 if (IS_ENABLED(CFG_VERSAL_RNG_V1) && trng->cfg.version == TRNG_V1 && 1174 !trng->usr_cfg.df_disable && trng->usr_cfg.mode == TRNG_PTRNG) 1175 trng_df_algorithm(trng, buf, DF_RAND, NULL); 1176 1177 return TEE_SUCCESS; 1178 error: 1179 if (trng->status != TRNG_CATASTROPHIC) 1180 trng->status = TRNG_ERROR; 1181 1182 return TEE_ERROR_GENERIC; 1183 } 1184 1185 static TEE_Result trng_release(struct versal_trng *trng) 1186 { 1187 if (!trng) 1188 return TEE_ERROR_GENERIC; 1189 1190 if (trng->status == TRNG_UNINITIALIZED) 1191 goto error; 1192 1193 trng_write32_range(trng, TRNG_EXT_SEED_0, TRNG_SEED_REGS, NULL); 1194 trng_write32_range(trng, TRNG_PER_STRING_0, TRNG_PERS_STR_REGS, NULL); 1195 trng_hold_reset(trng); 1196 1197 /* Clear the instance */ 1198 memset(&trng->usr_cfg, 0, sizeof(trng->usr_cfg)); 1199 memset(trng->buf, 0, sizeof(trng->buf)); 1200 memset(trng->dfout, 0, sizeof(trng->dfout)); 1201 trng->status = TRNG_UNINITIALIZED; 1202 1203 return TEE_SUCCESS; 1204 error: 1205 trng->status = TRNG_ERROR; 1206 1207 return TEE_ERROR_GENERIC; 1208 } 1209 1210 /* Health tests should be run when the configured mode is of PTRNG or HRNG */ 1211 static TEE_Result trng_health_test(struct versal_trng *trng) 1212 { 1213 struct trng_usr_cfg tests = { 1214 .mode = TRNG_HRNG, 1215 .seed_life = 10, 1216 .dfmul = 7, 1217 .predict_en = false, 1218 .iseed_en = false, 1219 .pstr_en = false, 1220 .df_disable = false, 1221 }; 1222 1223 if (trng_instantiate(trng, &tests)) 1224 goto error; 1225 1226 if (trng_release(trng)) 1227 goto error; 1228 1229 return TEE_SUCCESS; 1230 error: 1231 trng->status = TRNG_ERROR; 1232 1233 return TEE_ERROR_GENERIC; 1234 } 1235 1236 const uint8_t trng_pers_str[TRNG_PERS_STR_LEN] = { 1237 0xB2U, 0x80U, 0x7EU, 0x4CU, 0xD0U, 0xE4U, 0xE2U, 0xA9U, 1238 0x2FU, 0x1FU, 0x5DU, 0xC1U, 0xA2U, 0x1FU, 0x40U, 0xFCU, 1239 0x1FU, 0x24U, 0x5DU, 0x42U, 0x61U, 0x80U, 0xE6U, 0xE9U, 1240 0x71U, 0x05U, 0x17U, 0x5BU, 0xAFU, 0x70U, 0x30U, 0x18U, 1241 0xBCU, 0x23U, 0x18U, 0x15U, 0xCBU, 0xB8U, 0xA6U, 0x3EU, 1242 0x83U, 0xB8U, 0x4AU, 0xFEU, 0x38U, 0xFCU, 0x25U, 0x87U, 1243 }; 1244 1245 #ifdef CFG_VERSAL_RNG_V1 1246 static const uint8_t trng_ext_seed[TRNG_SEED_LEN] = { 1247 0x3BU, 0xC3U, 0xEDU, 0x64U, 0xF4U, 0x80U, 0x1CU, 0xC7U, 1248 0x14U, 0xCCU, 0x35U, 0xEDU, 0x57U, 0x01U, 0x2AU, 0xE4U, 1249 0xBCU, 0xEFU, 0xDEU, 0xF6U, 0x7CU, 0x46U, 0xA6U, 0x34U, 1250 0xC6U, 0x79U, 0xE8U, 0x91U, 0x5DU, 0xB1U, 0xDBU, 0xA7U, 1251 0x49U, 0xA5U, 0xBBU, 0x4FU, 0xEDU, 0x30U, 0xB3U, 0x7BU, 1252 0xA9U, 0x8BU, 0xF5U, 0x56U, 0x4DU, 0x40U, 0x18U, 0x9FU, 1253 }; 1254 1255 static const uint8_t trng_ext_reseed[TRNG_SEED_LEN] = { 1256 0xFDU, 0x85U, 0xA8U, 0x36U, 0xBBU, 0xA8U, 0x50U, 0x19U, 1257 0x88U, 0x1EU, 0x8CU, 0x6BU, 0xADU, 0x23U, 0xC9U, 0x06U, 1258 0x1AU, 0xDCU, 0x75U, 0x47U, 0x76U, 0x59U, 0xACU, 0xAEU, 1259 0xA8U, 0xE4U, 0xA0U, 0x1DU, 0xFEU, 0x07U, 0xA1U, 0x83U, 1260 0x2DU, 0xADU, 0x1CU, 0x13U, 0x6FU, 0x59U, 0xD7U, 0x0FU, 1261 0x86U, 0x53U, 0xA5U, 0xDCU, 0x11U, 0x86U, 0x63U, 0xD6U, 1262 }; 1263 1264 static const uint8_t trng_expected_out[TRNG_GEN_LEN] = { 1265 0xEBU, 0xF6U, 0x97U, 0x6EU, 0x7EU, 0xF0U, 0x4AU, 0x34U, 1266 0xEEU, 0xF6U, 0xA8U, 0x1AU, 0x67U, 0x33U, 0xF2U, 0x3CU, 1267 0x27U, 0x24U, 0x7AU, 0x6DU, 0x0EU, 0x12U, 0xD7U, 0x42U, 1268 0x73U, 0xEDU, 0xDDU, 0x3FU, 0x07U, 0x23U, 0xD8U, 0x52U, 1269 }; 1270 #endif 1271 1272 #ifdef CFG_VERSAL_RNG_V2 1273 #define TRNG_V2_KAT_SEED_LIFE 2 1274 #define TRNG_V2_KAT_DF_LEN 7 1275 #define TRNG_V2_KAT_SEED_LEN ((TRNG_V2_KAT_DF_LEN + 1) * BYTES_PER_BLOCK) 1276 1277 static const uint8_t trng_v2_ext_seed[TRNG_V2_KAT_SEED_LEN] = { 1278 0x3BU, 0xC3U, 0xEDU, 0x64U, 0xF4U, 0x80U, 0x1CU, 0xC7U, 1279 0x14U, 0xCCU, 0x35U, 0xEDU, 0x57U, 0x01U, 0x2AU, 0xE4U, 1280 0xBCU, 0xEFU, 0xDEU, 0xF6U, 0x7CU, 0x46U, 0xA6U, 0x34U, 1281 0xC6U, 0x79U, 0xE8U, 0x91U, 0x5DU, 0xB1U, 0xDBU, 0xA7U, 1282 0x49U, 0xA5U, 0xBBU, 0x4FU, 0xEDU, 0x30U, 0xB3U, 0x7BU, 1283 0xA9U, 0x8BU, 0xF5U, 0x56U, 0x4DU, 0x40U, 0x18U, 0x9FU, 1284 0x66U, 0x4EU, 0x39U, 0xC0U, 0x60U, 0xC8U, 0x8EU, 0xF4U, 1285 0x1CU, 0xB9U, 0x9DU, 0x7BU, 0x97U, 0x8BU, 0x69U, 0x62U, 1286 0x45U, 0x0CU, 0xD4U, 0x85U, 0xFCU, 0xDCU, 0x5AU, 0x2BU, 1287 0xFDU, 0xABU, 0x92U, 0x4AU, 0x12U, 0x52U, 0x7DU, 0x45U, 1288 0xD2U, 0x61U, 0x0AU, 0x06U, 0x74U, 0xA7U, 0x88U, 0x36U, 1289 0x4BU, 0xA2U, 0x65U, 0xEEU, 0x71U, 0x0BU, 0x5AU, 0x4EU, 1290 0x33U, 0xB2U, 0x7AU, 0x2EU, 0xC0U, 0xA6U, 0xF2U, 0x7DU, 1291 0xBDU, 0x7DU, 0xDFU, 0x07U, 0xBBU, 0xE2U, 0x86U, 0xFFU, 1292 0xF0U, 0x8EU, 0xA4U, 0xB1U, 0x46U, 0xDBU, 0xF7U, 0x8CU, 1293 0x3CU, 0x62U, 0x4DU, 0xF0U, 0x51U, 0x50U, 0xE7U, 0x85U 1294 }; 1295 1296 static const uint8_t trng_v2_ext_reseed[TRNG_V2_KAT_SEED_LEN] = { 1297 0xDFU, 0x5EU, 0x4DU, 0x4FU, 0x38U, 0x9EU, 0x2AU, 0x3EU, 1298 0xF2U, 0xABU, 0x46U, 0xE3U, 0xA0U, 0x26U, 0x77U, 0x84U, 1299 0x0BU, 0x9DU, 0x29U, 0xB0U, 0x5DU, 0xCEU, 0xC8U, 0xC3U, 1300 0xF9U, 0x4DU, 0x32U, 0xF7U, 0xBAU, 0x6FU, 0xA3U, 0xB5U, 1301 0x35U, 0xCBU, 0xC7U, 0x5CU, 0x62U, 0x48U, 0x01U, 0x65U, 1302 0x3AU, 0xAAU, 0x34U, 0x2DU, 0x89U, 0x6EU, 0xEFU, 0x6FU, 1303 0x69U, 0x96U, 0xE7U, 0x84U, 0xDAU, 0xEFU, 0x4EU, 0xBEU, 1304 0x27U, 0x4EU, 0x9FU, 0x88U, 0xB1U, 0xA0U, 0x7FU, 0x83U, 1305 0xDBU, 0x4AU, 0xA9U, 0x42U, 0x01U, 0xF1U, 0x84U, 0x71U, 1306 0xA9U, 0xEFU, 0xB9U, 0xE8U, 0x7FU, 0x81U, 0xC7U, 0xC1U, 1307 0x6CU, 0x5EU, 0xACU, 0x00U, 0x47U, 0x34U, 0xA1U, 0x75U, 1308 0xC0U, 0xE8U, 0x7FU, 0x48U, 0x00U, 0x45U, 0xC9U, 0xE9U, 1309 0x41U, 0xE3U, 0x8DU, 0xD8U, 0x4AU, 0x63U, 0xC4U, 0x94U, 1310 0x77U, 0x59U, 0xD9U, 0x50U, 0x2AU, 0x1DU, 0x4CU, 0x47U, 1311 0x64U, 0xA6U, 0x66U, 0x60U, 0x16U, 0xE7U, 0x29U, 0xC0U, 1312 0xB1U, 0xCFU, 0x3BU, 0x3FU, 0x54U, 0x49U, 0x31U, 0xD4U 1313 }; 1314 1315 static const uint8_t trng_v2_expected_out[TRNG_SEC_STRENGTH_LEN] = { 1316 0xEEU, 0xA7U, 0x5BU, 0xB6U, 0x2BU, 0x97U, 0xF0U, 0xC0U, 1317 0x0FU, 0xD6U, 0xABU, 0x13U, 0x00U, 0x87U, 0x7EU, 0xF4U, 1318 0x00U, 0x7FU, 0xD7U, 0x56U, 0xFEU, 0xE5U, 0xDFU, 0xA6U, 1319 0x55U, 0x5BU, 0xB2U, 0x86U, 0xDDU, 0x81U, 0x73U, 0xB2U 1320 }; 1321 #endif 1322 1323 static TEE_Result trng_kat_test(struct versal_trng *trng) 1324 { 1325 struct trng_usr_cfg tests = { 1326 .mode = TRNG_DRNG, 1327 .seed_life = 5, 1328 .dfmul = 2, 1329 .predict_en = false, 1330 .iseed_en = true, 1331 .pstr_en = true, 1332 .df_disable = false, 1333 }; 1334 uint32_t seed_len = TRNG_SEED_LEN; 1335 const uint8_t *ext_seed = NULL; 1336 const uint8_t *ext_reseed = NULL; 1337 const uint8_t *expected_out = NULL; 1338 uint8_t out[TRNG_GEN_LEN] = { 0 }; 1339 1340 if (!trng) 1341 return TEE_ERROR_GENERIC; 1342 1343 #ifdef CFG_VERSAL_RNG_V1 1344 if (trng->cfg.version == TRNG_V1) { 1345 ext_seed = trng_ext_seed; 1346 ext_reseed = trng_ext_reseed; 1347 expected_out = trng_expected_out; 1348 } 1349 #endif 1350 1351 #ifdef CFG_VERSAL_RNG_V2 1352 if (trng->cfg.version == TRNG_V2) { 1353 tests.seed_life = TRNG_V2_KAT_SEED_LIFE; 1354 tests.dfmul = TRNG_V2_KAT_DF_LEN; 1355 1356 seed_len = TRNG_V2_KAT_SEED_LEN; 1357 ext_seed = trng_v2_ext_seed; 1358 ext_reseed = trng_v2_ext_reseed; 1359 expected_out = trng_v2_expected_out; 1360 } 1361 #endif 1362 1363 memcpy(&tests.init_seed, ext_seed, seed_len); 1364 memcpy(tests.pstr, trng_pers_str, sizeof(trng_pers_str)); 1365 1366 if (trng_instantiate(trng, &tests)) 1367 goto error; 1368 1369 if (trng_reseed(trng, (uint8_t *)ext_reseed, tests.dfmul)) 1370 goto error; 1371 1372 if (trng_generate(trng, out, sizeof(out), false)) 1373 goto error; 1374 1375 if (memcmp(out, expected_out, TRNG_GEN_LEN)) { 1376 EMSG("K.A.T mismatch"); 1377 goto error; 1378 } 1379 1380 if (trng_release(trng)) 1381 goto error; 1382 1383 return TEE_SUCCESS; 1384 error: 1385 trng->status = TRNG_ERROR; 1386 return TEE_ERROR_GENERIC; 1387 } 1388 1389 TEE_Result versal_trng_get_random_bytes(struct versal_trng *trng, 1390 void *buf, size_t len) 1391 { 1392 uint8_t random[TRNG_SEC_STRENGTH_LEN] = { 0 }; 1393 uint8_t *p = buf; 1394 size_t i = 0; 1395 1396 for (i = 0; i < len / TRNG_SEC_STRENGTH_LEN; i++) { 1397 if (trng_generate(trng, p + i * TRNG_SEC_STRENGTH_LEN, 1398 TRNG_SEC_STRENGTH_LEN, false)) 1399 panic(); 1400 } 1401 1402 if (len % TRNG_SEC_STRENGTH_LEN) { 1403 if (trng_generate(trng, random, TRNG_SEC_STRENGTH_LEN, 1404 false)) 1405 panic(); 1406 memcpy(p + i * TRNG_SEC_STRENGTH_LEN, random, 1407 len % TRNG_SEC_STRENGTH_LEN); 1408 } 1409 1410 return TEE_SUCCESS; 1411 } 1412 1413 TEE_Result versal_trng_hw_init(struct versal_trng *trng, 1414 struct trng_usr_cfg *usr_cfg) 1415 { 1416 trng->cfg.addr = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, 1417 trng->cfg.base, 1418 trng->cfg.len); 1419 if (!trng->cfg.addr) { 1420 EMSG("Failed to map TRNG"); 1421 panic(); 1422 } 1423 1424 if (trng_kat_test(trng)) { 1425 EMSG("KAT Failed"); 1426 panic(); 1427 } 1428 1429 if (trng_health_test(trng)) { 1430 EMSG("RunHealthTest Failed"); 1431 panic(); 1432 } 1433 1434 if (trng_instantiate(trng, usr_cfg)) { 1435 EMSG("Driver instantiation Failed"); 1436 panic(); 1437 } 1438 1439 if (trng->usr_cfg.mode == TRNG_HRNG && 1440 trng_reseed(trng, NULL, trng->usr_cfg.dfmul)) { 1441 EMSG("Reseed Failed"); 1442 panic(); 1443 } 1444 1445 return TEE_SUCCESS; 1446 } 1447 #endif 1448 1449 #ifdef CFG_VERSAL_RNG_PLM 1450 #define SEC_MODULE_SHIFT 8 1451 #define SEC_MODULE_ID 5 1452 1453 #define CRYPTO_API_ID(__x) ((SEC_MODULE_ID << SEC_MODULE_SHIFT) | (__x)) 1454 1455 #define VERSAL_TRNG_GENERATE 22 1456 1457 #define TRNG_SEC_STRENGTH_LEN 32 1458 1459 static TEE_Result versal_plm_get_random_bytes(void *buf, size_t len) 1460 { 1461 uint32_t low = 0; 1462 uint32_t hi = 0; 1463 struct versal_ipi_cmd cmd = { }; 1464 struct versal_mbox_mem p = { }; 1465 TEE_Result ret = TEE_SUCCESS; 1466 uint32_t status = 0; 1467 uint32_t offset = 0; 1468 1469 ret = versal_mbox_alloc(TRNG_SEC_STRENGTH_LEN, NULL, &p); 1470 if (ret) 1471 return ret; 1472 1473 cmd.data[0] = CRYPTO_API_ID(VERSAL_TRNG_GENERATE); 1474 cmd.ibuf[0].mem = p; 1475 1476 reg_pair_from_64(virt_to_phys(p.buf), &hi, &low); 1477 cmd.data[1] = low; 1478 cmd.data[2] = hi; 1479 1480 while (len) { 1481 uint32_t _len = (uint32_t)TRNG_SEC_STRENGTH_LEN; 1482 1483 if (len < TRNG_SEC_STRENGTH_LEN) 1484 _len = (uint32_t)len; 1485 1486 cmd.data[3] = _len; 1487 1488 ret = versal_pmc_notify(&cmd, NULL, &status); 1489 if (ret) 1490 panic(); 1491 1492 memcpy((uint8_t *)buf + offset, p.buf, _len); 1493 1494 offset += TRNG_SEC_STRENGTH_LEN; 1495 len -= _len; 1496 } 1497 1498 versal_mbox_free(&p); 1499 return ret; 1500 } 1501 #endif 1502 1503 #if !defined(PLATFORM_FLAVOR_net) 1504 1505 #define TRNG_BASE 0xF1230000 1506 #define TRNG_SIZE 0x10000 1507 1508 static struct versal_trng versal_trng = { 1509 .cfg.base = TRNG_BASE, 1510 .cfg.len = TRNG_SIZE, 1511 .cfg.version = TRNG_V1, 1512 }; 1513 1514 TEE_Result hw_get_random_bytes(void *buf, size_t len) 1515 { 1516 return versal_trng_get_random_bytes(&versal_trng, buf, len); 1517 } 1518 1519 static TEE_Result trng_hrng_mode_init(void) 1520 { 1521 /* configure in hybrid mode with derivative function enabled */ 1522 struct trng_usr_cfg usr_cfg = { 1523 .mode = TRNG_HRNG, 1524 .seed_life = CFG_VERSAL_TRNG_SEED_LIFE, 1525 .predict_en = false, 1526 .df_disable = false, 1527 .dfmul = CFG_VERSAL_TRNG_DF_MUL, 1528 .iseed_en = false, 1529 .pstr_en = true, 1530 }; 1531 1532 memcpy(usr_cfg.pstr, trng_pers_str, sizeof(trng_pers_str)); 1533 return versal_trng_hw_init(&versal_trng, &usr_cfg); 1534 } 1535 1536 early_init(trng_hrng_mode_init); 1537 1538 #else 1539 1540 TEE_Result hw_get_random_bytes(void *buf, size_t len) 1541 { 1542 return versal_plm_get_random_bytes(buf, len); 1543 } 1544 1545 #endif 1546 1547 void plat_rng_init(void) 1548 { 1549 } 1550