1 /*
2 * Copyright (c) 2021-2023, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== RNGLPF3RF.c ========
34 */
35
36 #include <ti/drivers/RNG.h>
37 #include <ti/drivers/rng/RNGLPF3RF.h>
38 #include <ti/drivers/AESCMAC.h>
39 #include <ti/drivers/AESCTRDRBG.h>
40 #include <ti/drivers/aescmac/AESCMACLPF3.h>
41 #include <ti/drivers/aesctrdrbg/AESCTRDRBGXX.h>
42 #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
43 #include <ti/drivers/cryptoutils/sharedresources/CryptoResourceLPF3.h>
44 #include <ti/drivers/cryptoutils/utils/CryptoUtils.h>
45
46 #include <ti/drivers/dpl/SemaphoreP.h>
47 #include <ti/drivers/dpl/HwiP.h>
48
49 #include <ti/devices/DeviceFamily.h>
50 #include DeviceFamily_constructPath(inc/hw_memmap.h)
51
52 extern const RNGLPF3RF_HWAttrs RNGLPF3RF_hwAttrs;
53 extern uint8_t RNG_instancePool[];
54
55 extern const RNG_ReturnBehavior RNGLPF3RF_returnBehavior;
56
57 /* CBC MAC key words used to compute RNG seed */
58 extern uint32_t RNGLPF3RF_noiseConditioningKeyWord0;
59 extern uint32_t RNGLPF3RF_noiseConditioningKeyWord1;
60 extern uint32_t RNGLPF3RF_noiseConditioningKeyWord2;
61 extern uint32_t RNGLPF3RF_noiseConditioningKeyWord3;
62
63 typedef struct RNGLPF3RF_OperationParameters_ RNGLPF3RF_OperationParameters;
64
65 typedef bool (*RNGLPF3RF_validator)(RNGLPF3RF_OperationParameters *opParams);
66
67 /* Mask used to extract the upper or lower byte of a word */
68 #define BYTE_MASK 0xff
69
70 /*
71 * These values are used with the validator function prototype to provide potentially relevant parameters
72 * for validation after a candidate number has been generated.
73 */
74 struct RNGLPF3RF_OperationParameters_
75 {
76 uint8_t *output;
77 size_t outputBitLength;
78 CryptoUtils_Endianess endianess;
79 const uint8_t *lowerLimit;
80 const uint8_t *upperLimit;
81 };
82
83 typedef struct
84 {
85 /* No data in the structure should be read or written without first taking this semaphore. */
86 SemaphoreP_Struct accessSemaphore;
87 size_t poolLevel;
88 AESCTRDRBG_Config drbgConfig;
89 AESCTRDRBGXX_Object drbgObject;
90 AESCTRDRBGXX_HWAttrs drbgHWattrs;
91 } RNGLPF3RF_Instance;
92
93 RNGLPF3RF_Instance RNGLPF3RF_instanceData;
94
95 static bool RNGLPF3RF_isInitialized = false;
96 static bool RNGLPF3RF_isSeeded = false;
97
98 /*** Prototypes ***/
99 static int_fast16_t RNGLPF3RF_translateDRBGStatus(int_fast16_t drbgStatus);
100 static int_fast16_t RNGLPF3RF_generateEntropy(AESCTRDRBG_Handle drbgHandle, uint8_t *byteDest, size_t byteSize);
101 static int_fast16_t RNGLPF3RF_fillPoolIfLessThan(size_t bytes);
102 static int_fast16_t RNGLPF3RF_getEntropyFromPool(void *dest, size_t byteSize, size_t *bytesRemaining);
103 static bool RNGLPF3RF_checkRange(RNGLPF3RF_OperationParameters *opParams);
104 static int_fast16_t RNGLPF3RF_getValidatedNumber(RNG_Handle handle,
105 void *randomNumber,
106 size_t randomNumberBitLength,
107 CryptoUtils_Endianess endianess,
108 RNGLPF3RF_validator validator,
109 const void *lowerLimit,
110 const void *upperLimit);
111 static int_fast16_t RNGLPF3RF_createDRBGInstance(void);
112 static int_fast16_t RNGLPF3RF_conditionNoise(uint32_t *noiseInput, uint32_t *seed);
113
114 /*
115 * ======== RNGLPF3RF_translateDRBGStatus ========
116 */
RNGLPF3RF_translateDRBGStatus(int_fast16_t drbgStatus)117 static int_fast16_t RNGLPF3RF_translateDRBGStatus(int_fast16_t drbgStatus)
118 {
119 int_fast16_t returnValue;
120
121 switch (drbgStatus)
122 {
123 case AESCTRDRBG_STATUS_SUCCESS:
124 returnValue = RNG_STATUS_SUCCESS;
125 break;
126 case AESCTRDRBG_STATUS_ERROR:
127 returnValue = RNG_STATUS_ERROR;
128 break;
129 case AESCTRDRBG_STATUS_RESOURCE_UNAVAILABLE:
130 returnValue = RNG_STATUS_RESOURCE_UNAVAILABLE;
131 break;
132 case AESCTRDRBG_STATUS_RESEED_REQUIRED:
133 /* Map to RNG_ENTROPY_EXHAUSTED, reboot required for recovery. */
134 returnValue = RNG_ENTROPY_EXHAUSTED;
135 break;
136 case AESCTRDRBG_STATUS_UNINSTANTIATED:
137 /* Map to RNG_ENTROPY_EXHAUSTED, reboot required for recovery. */
138 returnValue = RNG_ENTROPY_EXHAUSTED;
139 break;
140 default:
141 returnValue = RNG_STATUS_ERROR;
142 break;
143 }
144
145 return returnValue;
146 }
147
148 /*
149 * ======== RNGLPF3RF_generateEntropy ========
150 */
RNGLPF3RF_generateEntropy(AESCTRDRBG_Handle drbgHandle,uint8_t * byteDest,size_t byteSize)151 int_fast16_t RNGLPF3RF_generateEntropy(AESCTRDRBG_Handle drbgHandle, uint8_t *byteDest, size_t byteSize)
152 {
153 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
154 int_fast16_t drbgResult;
155
156 if (!RNGLPF3RF_isInitialized)
157 {
158 returnValue = RNG_STATUS_NOT_INITIALIZED;
159 }
160
161 if (returnValue != RNG_STATUS_NOT_INITIALIZED)
162 {
163 drbgResult = AESCTRDRBG_getRandomBytes(drbgHandle, byteDest, byteSize);
164
165 returnValue = RNGLPF3RF_translateDRBGStatus(drbgResult);
166 }
167
168 return returnValue;
169 }
170
171 /*
172 * ======== RNGLPF3RF_fillPoolIfLessThan ========
173 */
RNGLPF3RF_fillPoolIfLessThan(size_t bytes)174 static int_fast16_t RNGLPF3RF_fillPoolIfLessThan(size_t bytes)
175 {
176 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
177 size_t bytesNeeded;
178
179 if (RNGLPF3RF_instanceData.poolLevel < bytes)
180 {
181 /*
182 * Adjust poolLevel to ensure word alignment as underlying AES
183 * driver may only support output to word aligned addresses.
184 */
185 RNGLPF3RF_instanceData.poolLevel = (RNGLPF3RF_instanceData.poolLevel >> 2u) << 2u;
186
187 bytesNeeded = RNG_poolByteSize - RNGLPF3RF_instanceData.poolLevel;
188
189 returnValue = RNGLPF3RF_generateEntropy((AESCTRDRBG_Handle)&RNGLPF3RF_instanceData.drbgConfig,
190 &RNG_instancePool[RNGLPF3RF_instanceData.poolLevel],
191 bytesNeeded);
192
193 if (returnValue == RNG_STATUS_SUCCESS)
194 {
195 RNGLPF3RF_instanceData.poolLevel = RNG_poolByteSize;
196 }
197 }
198
199 return returnValue;
200 }
201
202 /*
203 * Precondition: RNGLPF3RF_instanceData.accessSemaphore has been taken.
204 *
205 * Updates bytesRemaining to fulfill the total request (rounded up from number of bits remaining.)
206 * These will have to be generated since these additional bytes could not be copied from the pool.
207 *
208 * Postcondition: If dest is not word aligned, then bytesRemaining will either be 0 or dest[byteSize-bytesRemaining]
209 * will be word aligned.
210 */
211 /*
212 * ======== RNGLPF3RF_getEntropyFromPool ========
213 */
RNGLPF3RF_getEntropyFromPool(void * dest,size_t byteSize,size_t * bytesRemaining)214 static int_fast16_t RNGLPF3RF_getEntropyFromPool(void *dest, size_t byteSize, size_t *bytesRemaining)
215 {
216
217 uint8_t *byteDest = (uint8_t *)dest;
218 size_t bytesToCopy = byteSize;
219 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
220
221 if (RNGLPF3RF_instanceData.poolLevel < byteSize && ((uintptr_t)dest & 0x3u) != 0u &&
222 RNGLPF3RF_instanceData.poolLevel < (4 - ((uintptr_t)dest & 0x3u)))
223 {
224 /* Fill pool so there will be enough entropy to get to an aligned address within dest[]. */
225 returnValue = RNGLPF3RF_fillPoolIfLessThan(RNG_poolByteSize);
226 }
227
228 if (RNGLPF3RF_instanceData.poolLevel < byteSize)
229 {
230 /*
231 * Cap number of bytes taken from pool to ensure next byte of entropy to generate into dest
232 * is at a word-aligned address.
233 */
234 bytesToCopy = (4 - ((uintptr_t)dest & 0x3u));
235 bytesToCopy = bytesToCopy + (((RNGLPF3RF_instanceData.poolLevel - bytesToCopy) >> 2u) << 2u);
236 }
237
238 /* Get entropy from pool */
239 if ((bytesToCopy > 0u) && (RNGLPF3RF_instanceData.poolLevel > 0u))
240 {
241 (void)memcpy(byteDest, &RNG_instancePool[RNGLPF3RF_instanceData.poolLevel - bytesToCopy], bytesToCopy);
242 CryptoUtils_memset(&RNG_instancePool[RNGLPF3RF_instanceData.poolLevel - bytesToCopy],
243 RNG_poolByteSize,
244 0,
245 bytesToCopy);
246 RNGLPF3RF_instanceData.poolLevel -= bytesToCopy;
247 }
248
249 *bytesRemaining = byteSize - bytesToCopy;
250
251 return returnValue;
252 }
253
254 /*
255 * ======== RNGLPF3RF_checkRange ========
256 */
RNGLPF3RF_checkRange(RNGLPF3RF_OperationParameters * opParams)257 static bool RNGLPF3RF_checkRange(RNGLPF3RF_OperationParameters *opParams)
258 {
259 return CryptoUtils_isNumberInRange(opParams->output,
260 opParams->outputBitLength,
261 opParams->endianess,
262 opParams->lowerLimit,
263 opParams->upperLimit);
264 }
265
266 /*
267 * ======== RNGLPF3RF_getValidatedNumber ========
268 */
RNGLPF3RF_getValidatedNumber(RNG_Handle handle,void * randomNumber,size_t randomNumberBitLength,CryptoUtils_Endianess endianess,RNGLPF3RF_validator validator,const void * lowerLimit,const void * upperLimit)269 static int_fast16_t RNGLPF3RF_getValidatedNumber(RNG_Handle handle,
270 void *randomNumber,
271 size_t randomNumberBitLength,
272 CryptoUtils_Endianess endianess,
273 RNGLPF3RF_validator validator,
274 const void *lowerLimit,
275 const void *upperLimit)
276 {
277 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
278 RNGLPF3RF_Object *object;
279 size_t bytesToGenerate = 0;
280 size_t byteSize = 0;
281 uint8_t *byteDestination = NULL;
282 uint8_t bitMask = 0;
283 bool isValid = false;
284 RNGLPF3RF_OperationParameters opParams;
285
286 if ((handle == NULL) || (randomNumber == NULL) || (randomNumberBitLength >= RNG_MAX_BIT_LENGTH))
287 {
288 returnValue = RNG_STATUS_INVALID_INPUTS;
289 }
290
291 if (returnValue == RNG_STATUS_SUCCESS)
292 {
293 object = (RNGLPF3RF_Object *)handle->object;
294
295 if (SemaphoreP_pend(&RNGLPF3RF_instanceData.accessSemaphore, object->timeout) != SemaphoreP_OK)
296 {
297 returnValue = RNG_STATUS_RESOURCE_UNAVAILABLE;
298 }
299 }
300
301 if (returnValue == RNG_STATUS_SUCCESS)
302 {
303 /*
304 * Convert bit length to byte size by rounding up the number of bytes.
305 * Mask the extra bits from rounding up written in the destination buffer.
306 */
307 byteSize = (randomNumberBitLength + 7u) >> 3u;
308 byteDestination = (uint8_t *)randomNumber;
309 bitMask = (2u << (((randomNumberBitLength + 7u) % 8u))) - 1u;
310 }
311
312 while ((returnValue == RNG_STATUS_SUCCESS) && !isValid)
313 {
314
315 returnValue = RNGLPF3RF_getEntropyFromPool(byteDestination, byteSize, &bytesToGenerate);
316
317 if (returnValue == RNG_STATUS_SUCCESS && bytesToGenerate > 0u)
318 {
319 returnValue = RNGLPF3RF_generateEntropy((AESCTRDRBG_Handle)&RNGLPF3RF_instanceData.drbgConfig,
320 &byteDestination[byteSize - bytesToGenerate],
321 bytesToGenerate);
322 }
323
324 /* Mask off extra bits in MSB */
325 if (endianess == CryptoUtils_ENDIANESS_BIG)
326 {
327 byteDestination[0] &= bitMask;
328 }
329 else
330 {
331 byteDestination[byteSize - 1u] &= bitMask;
332 }
333
334 if (validator != NULL)
335 {
336 opParams.outputBitLength = randomNumberBitLength;
337 opParams.output = randomNumber;
338 opParams.endianess = endianess;
339 opParams.lowerLimit = lowerLimit;
340 opParams.upperLimit = upperLimit;
341
342 isValid = validator(&opParams);
343 }
344 else
345 {
346 isValid = true;
347 }
348 }
349
350 SemaphoreP_post(&RNGLPF3RF_instanceData.accessSemaphore);
351
352 return returnValue;
353 }
354
355 /*
356 * ======== RNGLPF3RF_createDRBGInstance ========
357 */
RNGLPF3RF_createDRBGInstance(void)358 static int_fast16_t RNGLPF3RF_createDRBGInstance(void)
359 {
360 int_fast16_t returnValue = RNG_STATUS_ERROR;
361 AESCTRDRBG_Handle drbgHandle;
362 AESCTRDRBG_Params drbgParams;
363
364 AESCTRDRBG_init();
365
366 /* Copy RNG interrupt priority (set in syscfg) to AES CTR interrupt priority */
367 RNGLPF3RF_instanceData.drbgHWattrs.aesctrHWAttrs.intPriority = RNGLPF3RF_hwAttrs.intPriority;
368
369 RNGLPF3RF_instanceData.drbgConfig.object = &RNGLPF3RF_instanceData.drbgObject;
370 RNGLPF3RF_instanceData.drbgConfig.hwAttrs = &RNGLPF3RF_instanceData.drbgHWattrs;
371 RNGLPF3RF_instanceData.drbgObject.isOpen = false;
372
373 AESCTRDRBG_Params_init(&drbgParams);
374 /* Ensure seed length will be 32 bytes long. (Seed length = key length + AES block length.) */
375 drbgParams.keyLength = AESCTRDRBG_AES_KEY_LENGTH_128;
376 drbgParams.returnBehavior = (AESCTRDRBG_ReturnBehavior)RNGLPF3RF_returnBehavior;
377
378 drbgHandle = AESCTRDRBG_construct((AESCTRDRBG_Handle)&RNGLPF3RF_instanceData.drbgConfig, &drbgParams);
379
380 if (drbgHandle != NULL)
381 {
382 returnValue = RNG_STATUS_SUCCESS;
383 }
384
385 return returnValue;
386 }
387
388 /* Store a 32-bit unsigned integer as bytes in big-endian order in memory. */
389 /*
390 * ======== RNGLPF3RF_storeUint32InArray ========
391 */
RNGLPF3RF_storeUint32InArray(uint8_t * dst,uint32_t x)392 static void RNGLPF3RF_storeUint32InArray(uint8_t *dst, uint32_t x)
393 {
394 uint8_t *buf;
395
396 buf = dst;
397 buf[0] = (uint8_t)(x >> 24U) & BYTE_MASK;
398 buf[1] = (uint8_t)(x >> 16U) & BYTE_MASK;
399 buf[2] = (uint8_t)(x >> 8U) & BYTE_MASK;
400 buf[3] = (uint8_t)x;
401 }
402
403 /* Condition the noise input using CBC MAC to generate the seed */
404 /*
405 * ======== RNGLPF3RF_conditionNoise ========
406 */
RNGLPF3RF_conditionNoise(uint32_t * noiseInput,uint32_t * seed)407 static int_fast16_t RNGLPF3RF_conditionNoise(uint32_t *noiseInput, uint32_t *seed)
408 {
409 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
410 uint8_t *rawData;
411 size_t rawDataLength;
412
413 /* CBC MAC variables */
414 uint8_t keyMaterial[AES_BLOCK_SIZE];
415 CryptoKey cryptoKey;
416 int_fast16_t cbcMacResult;
417 AESCMAC_Operation cbcmacOperation;
418 AESCMAC_Handle dynHandle;
419 AESCMAC_Config dynConfig;
420 AESCMACLPF3_Object dynObject;
421 const AESCMACLPF3_HWAttrs dynHWAttrs = {.intPriority = (~0)};
422 AESCMAC_Params params;
423
424 RNGLPF3RF_storeUint32InArray(keyMaterial, RNGLPF3RF_noiseConditioningKeyWord0);
425 RNGLPF3RF_storeUint32InArray(keyMaterial + 4, RNGLPF3RF_noiseConditioningKeyWord1);
426 RNGLPF3RF_storeUint32InArray(keyMaterial + 8, RNGLPF3RF_noiseConditioningKeyWord2);
427 RNGLPF3RF_storeUint32InArray(keyMaterial + 12, RNGLPF3RF_noiseConditioningKeyWord3);
428
429 /* Check if the Noise input pointer was initialized */
430 if (noiseInput == NULL)
431 {
432 return RNG_STATUS_NOISE_INPUT_INVALID;
433 }
434 /* Check if noise input was populated by user before calling RNG_init() */
435 bool noiseFilled = CryptoUtils_isBufferAllZeros(noiseInput, AES_BLOCK_SIZE);
436 if (noiseFilled)
437 {
438 return RNG_STATUS_NOISE_INPUT_INVALID;
439 }
440
441 rawData = (uint8_t *)noiseInput;
442 rawDataLength = RNGLPF3RF_noiseInputWordLen * 4;
443
444 memset(&dynObject, 0x00, sizeof(dynObject));
445
446 dynConfig.object = &dynObject;
447 dynConfig.hwAttrs = &dynHWAttrs;
448
449 AESCMAC_init();
450 AESCMAC_Params_init(¶ms);
451
452 params.operationalMode = AESCMAC_OPMODE_CBCMAC;
453 params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_POLLING;
454
455 dynHandle = AESCMAC_construct(&dynConfig, ¶ms);
456
457 if (dynHandle == NULL)
458 {
459 return RNG_STATUS_ERROR;
460 }
461
462 /* Setup Entropy Conditioning Key */
463 CryptoKeyPlaintext_initKey(&cryptoKey, keyMaterial, sizeof(keyMaterial));
464
465 AESCMAC_Operation_init(&cbcmacOperation);
466
467 /* Generate 16B of seed using half the entropy*/
468 cbcmacOperation.input = rawData;
469 cbcmacOperation.inputLength = rawDataLength / 2;
470 cbcmacOperation.macLength = 16;
471 cbcmacOperation.mac = (uint8_t *)seed;
472 cbcMacResult = AESCMAC_oneStepSign(dynHandle, &cbcmacOperation, &cryptoKey);
473
474 if (cbcMacResult != AESCMAC_STATUS_SUCCESS)
475 {
476 returnValue = RNG_STATUS_ERROR;
477 }
478
479 if (cbcMacResult == AESCMAC_STATUS_SUCCESS)
480 {
481 /* Generate another 16B of seed using the rest of the entropy */
482 cbcmacOperation.input = rawData + rawDataLength / 2;
483 cbcmacOperation.mac = (uint8_t *)seed + 16;
484 cbcMacResult = AESCMAC_oneStepSign(dynHandle, &cbcmacOperation, &cryptoKey);
485
486 if (cbcMacResult != AESCMAC_STATUS_SUCCESS)
487 {
488 returnValue = RNG_STATUS_ERROR;
489 }
490 }
491
492 /* Clear noise input after conditioning */
493 memset(noiseInput, 0, RNGLPF3RF_noiseInputWordLen * sizeof(uint32_t));
494
495 /* Destroy dynamic instance */
496 AESCMAC_close(dynHandle);
497
498 return returnValue;
499 }
500
501 /*
502 * ======== RNG_Params_init ========
503 */
RNG_Params_init(RNG_Params * params)504 void RNG_Params_init(RNG_Params *params)
505 {
506 *params = RNG_defaultParams;
507 params->returnBehavior = RNGLPF3RF_returnBehavior;
508 }
509
510 /*
511 * ======== RNGLPF3RF_conditionNoiseToGenerateSeed ========
512 */
RNGLPF3RF_conditionNoiseToGenerateSeed(uint32_t * noisePtr)513 int_fast16_t RNGLPF3RF_conditionNoiseToGenerateSeed(uint32_t *noisePtr)
514 {
515 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
516 int_fast16_t drbgResult;
517 uint32_t seed[256 / 32]; /* Seed is SHA256 Digest: 256 bits */
518 if (RNGLPF3RF_isSeeded == false)
519 {
520 RNGLPF3RF_instanceData.poolLevel = 0;
521
522 if (SemaphoreP_constructBinary(&RNGLPF3RF_instanceData.accessSemaphore, 1) == NULL)
523 {
524 returnValue = RNG_STATUS_ERROR;
525 }
526
527 if (returnValue == RNG_STATUS_SUCCESS)
528 {
529 returnValue = RNGLPF3RF_conditionNoise(noisePtr, seed);
530 }
531
532 if (returnValue == RNG_STATUS_SUCCESS)
533 {
534
535 returnValue = RNGLPF3RF_createDRBGInstance();
536
537 if (returnValue == RNG_STATUS_SUCCESS)
538 {
539 drbgResult = AESCTRDRBG_reseed((AESCTRDRBG_Handle)&RNGLPF3RF_instanceData.drbgConfig, seed, NULL, 0);
540 returnValue = RNGLPF3RF_translateDRBGStatus(drbgResult);
541 CryptoUtils_memset(seed, sizeof(seed), 0, sizeof(seed));
542 }
543
544 if (returnValue == RNG_STATUS_SUCCESS)
545 {
546 RNGLPF3RF_isSeeded = true;
547 }
548 }
549 }
550
551 return returnValue;
552 }
553
554 /*
555 * ======== RNG_init ========
556 */
RNG_init(void)557 int_fast16_t RNG_init(void)
558 {
559 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
560
561 if (RNGLPF3RF_isInitialized == false)
562 {
563 /* If the RNG driver was seeded, initialization was successful */
564 if (RNGLPF3RF_isSeeded == true)
565 {
566 RNGLPF3RF_isInitialized = true;
567 }
568 }
569
570 return returnValue;
571 }
572
573 /*
574 * ======== RNG_construct ========
575 */
RNG_construct(const RNG_Config * config,const RNG_Params * params)576 RNG_Handle RNG_construct(const RNG_Config *config, const RNG_Params *params)
577 {
578 RNG_Handle handle;
579 RNGLPF3RF_Object *object;
580 uintptr_t key;
581
582 handle = (RNG_Handle)config;
583 object = handle->object;
584
585 key = HwiP_disable();
586
587 if (object->isOpen)
588 {
589 HwiP_restore(key);
590 handle = NULL;
591 }
592
593 if (handle != NULL)
594 {
595 object->isOpen = true;
596
597 HwiP_restore(key);
598
599 /* If params are NULL, use defaults */
600 if (params == NULL)
601 {
602 object->timeout = RNG_defaultParams.timeout;
603 }
604 else
605 {
606 /*
607 * Return behavior is set statically for all instances and on open the requesting setting must
608 * match the static setting.
609 */
610 if (params->returnBehavior != RNGLPF3RF_returnBehavior)
611 {
612 handle = NULL;
613 }
614
615 /*
616 * Callback return behavior is not supported.
617 */
618 if (params->returnBehavior == RNG_RETURN_BEHAVIOR_CALLBACK)
619 {
620 handle = NULL;
621 }
622 }
623 }
624
625 return handle;
626 }
627
628 /*
629 * ======== RNG_close ========
630 */
RNG_close(RNG_Handle handle)631 void RNG_close(RNG_Handle handle)
632 {
633 RNGLPF3RF_Object *object;
634
635 if (handle != NULL)
636 {
637 object = (RNGLPF3RF_Object *)handle->object;
638 object->isOpen = false;
639 }
640 }
641
642 /*
643 * ======== RNG_getRandomBits ========
644 */
RNG_getRandomBits(RNG_Handle handle,void * randomBits,size_t randomBitsLength)645 int_fast16_t RNG_getRandomBits(RNG_Handle handle, void *randomBits, size_t randomBitsLength)
646 {
647
648 return RNGLPF3RF_getValidatedNumber(handle,
649 randomBits,
650 randomBitsLength,
651 CryptoUtils_ENDIANESS_LITTLE,
652 NULL,
653 NULL,
654 NULL);
655 }
656
657 /*
658 * ======== RNG_getLERandomNumberInRange ========
659 */
RNG_getLERandomNumberInRange(RNG_Handle handle,const void * lowerLimit,const void * upperLimit,void * randomNumber,size_t randomNumberBitLength)660 int_fast16_t RNG_getLERandomNumberInRange(RNG_Handle handle,
661 const void *lowerLimit,
662 const void *upperLimit,
663 void *randomNumber,
664 size_t randomNumberBitLength)
665 {
666
667 return RNGLPF3RF_getValidatedNumber(handle,
668 randomNumber,
669 randomNumberBitLength,
670 CryptoUtils_ENDIANESS_LITTLE,
671 &RNGLPF3RF_checkRange,
672 lowerLimit,
673 upperLimit);
674 }
675
676 /*
677 * ======== RNG_getBERandomNumberInRange ========
678 */
RNG_getBERandomNumberInRange(RNG_Handle handle,const void * lowerLimit,const void * upperLimit,void * randomNumber,size_t randomNumberBitLength)679 int_fast16_t RNG_getBERandomNumberInRange(RNG_Handle handle,
680 const void *lowerLimit,
681 const void *upperLimit,
682 void *randomNumber,
683 size_t randomNumberBitLength)
684 {
685
686 return RNGLPF3RF_getValidatedNumber(handle,
687 randomNumber,
688 randomNumberBitLength,
689 CryptoUtils_ENDIANESS_BIG,
690 &RNGLPF3RF_checkRange,
691 lowerLimit,
692 upperLimit);
693 }
694
695 /*
696 * ======== RNG_generateKey ========
697 */
RNG_generateKey(RNG_Handle handle,CryptoKey * key)698 int_fast16_t RNG_generateKey(RNG_Handle handle, CryptoKey *key)
699 {
700 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
701 uint8_t *randomBits;
702 size_t randomBitsLength;
703
704 if (key->encoding != CryptoKey_BLANK_PLAINTEXT)
705 {
706 returnValue = RNG_STATUS_INVALID_INPUTS;
707 }
708
709 if (key->u.plaintext.keyLength > (RNG_MAX_BIT_LENGTH >> 3u))
710 {
711 returnValue = RNG_STATUS_INVALID_INPUTS;
712 }
713
714 if (returnValue == RNG_STATUS_SUCCESS)
715 {
716 randomBits = key->u.plaintext.keyMaterial;
717 randomBitsLength = key->u.plaintext.keyLength << 3u; /* Bytes to bits */
718
719 returnValue = RNGLPF3RF_getValidatedNumber(handle,
720 randomBits,
721 randomBitsLength,
722 CryptoUtils_ENDIANESS_LITTLE,
723 NULL,
724 NULL,
725 NULL);
726 }
727
728 return returnValue;
729 }
730
731 /*
732 * ======== RNG_generateLEKeyInRange ========
733 */
RNG_generateLEKeyInRange(RNG_Handle handle,const void * lowerLimit,const void * upperLimit,CryptoKey * key,size_t randomNumberBitLength)734 int_fast16_t RNG_generateLEKeyInRange(RNG_Handle handle,
735 const void *lowerLimit,
736 const void *upperLimit,
737 CryptoKey *key,
738 size_t randomNumberBitLength)
739 {
740 int_fast16_t returnValue;
741 uint8_t *randomBits;
742
743 if (key->encoding != CryptoKey_BLANK_PLAINTEXT)
744 {
745 returnValue = RNG_STATUS_INVALID_INPUTS;
746 }
747 else
748 {
749
750 randomBits = key->u.plaintext.keyMaterial;
751
752 returnValue = RNGLPF3RF_getValidatedNumber(handle,
753 randomBits,
754 randomNumberBitLength,
755 CryptoUtils_ENDIANESS_LITTLE,
756 &RNGLPF3RF_checkRange,
757 lowerLimit,
758 upperLimit);
759 }
760
761 return returnValue;
762 }
763
764 /*
765 * ======== RNG_generateBEKeyInRange ========
766 */
RNG_generateBEKeyInRange(RNG_Handle handle,const void * lowerLimit,const void * upperLimit,CryptoKey * key,size_t randomNumberBitLength)767 int_fast16_t RNG_generateBEKeyInRange(RNG_Handle handle,
768 const void *lowerLimit,
769 const void *upperLimit,
770 CryptoKey *key,
771 size_t randomNumberBitLength)
772 {
773 int_fast16_t returnValue;
774 uint8_t *randomBits;
775
776 if (key->encoding != CryptoKey_BLANK_PLAINTEXT)
777 {
778 returnValue = RNG_STATUS_INVALID_INPUTS;
779 }
780 else
781 {
782 randomBits = key->u.plaintext.keyMaterial;
783
784 returnValue = RNGLPF3RF_getValidatedNumber(handle,
785 randomBits,
786 randomNumberBitLength,
787 CryptoUtils_ENDIANESS_BIG,
788 &RNGLPF3RF_checkRange,
789 lowerLimit,
790 upperLimit);
791 }
792
793 return returnValue;
794 }
795
796 /*
797 * ======== RNG_fillPoolIfLessThan ========
798 */
RNG_fillPoolIfLessThan(size_t bytes)799 int_fast16_t RNG_fillPoolIfLessThan(size_t bytes)
800 {
801 int_fast16_t returnValue = RNG_STATUS_SUCCESS;
802
803 if (SemaphoreP_pend(&RNGLPF3RF_instanceData.accessSemaphore, SemaphoreP_WAIT_FOREVER) != SemaphoreP_OK)
804 {
805 returnValue = RNG_STATUS_RESOURCE_UNAVAILABLE;
806 }
807 else
808 {
809 returnValue = RNGLPF3RF_fillPoolIfLessThan(bytes);
810
811 SemaphoreP_post(&RNGLPF3RF_instanceData.accessSemaphore);
812 }
813
814 return returnValue;
815 }
816
817 /*
818 * ======== RNG_cancelOperation ========
819 */
RNG_cancelOperation(RNG_Handle handle)820 int_fast16_t RNG_cancelOperation(RNG_Handle handle)
821 {
822 /* Cancel not supported in this implementation since AESCTRDRBG driver does not support cancellation. */
823 return RNG_STATUS_ERROR;
824 }
825