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(&params);
451 
452     params.operationalMode = AESCMAC_OPMODE_CBCMAC;
453     params.returnBehavior  = AESCMAC_RETURN_BEHAVIOR_POLLING;
454 
455     dynHandle = AESCMAC_construct(&dynConfig, &params);
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