RNG.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-2025, 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  * @file RNG.h
34  *
35  * @brief RNG driver header
36  *
37  * @anchor ti_drivers_RNG_Overview
38  * # Overview #
39  * The Random Number Generator (RNG) module generates random data of variable
40  * lengths from a pool of entropy. The pool of entropy is maintained by the
41  * driver using implementation-specific sources of entropy.
42  * The output is suitable for applications requiring cryptographically
43  * random data such as keying material for private or symmetric keys.
44  *
45  * The RNG driver for CC27XX devices is strictly a HSM implementation only. #RNG_init()
46  * only constructs RTOS-related objects, and #RNG_open() initializes the driver's internal metadata.
47  * To get random data, use one of the following APIs:
48  * - #RNG_getRandomBits()
49  * - #RNG_getLERandomNumberInRange()
50  * - #RNG_getBERandomNumberInRange()
51  * - #RNG_generateKey()
52  * - #RNG_generateLEKeyInRange()
53  * - #RNG_generateBEKeyInRange()
54  *
55  * HSM (Hardware Security Module) is a HW IP used for RNG operations
56  *
57  * @anchor ti_drivers_RNG_Usage
58  * # Usage #
59  *
60  * ## Initialization ##
61  * Unlike most drivers, there is a global instance of RNG driver data
62  * that is always available once #RNG_init() is called. This data will contain
63  * the entropy pool and any needed state information required to refill the
64  * pool. #RNG_init() should be called once before using other RNG
65  * driver APIs.
66  *
67  * @note Some implementations restrict when RNG_init() may be called.
68  * Check the implementation's documentation for more information.
69  *
70  * For CC23X0, RNG must be initialized by application in a task context with interrupts enabled
71  * using the following steps prior to the use of the Radio because CC23X0 uses the ADC samples
72  * from radio as noise that is conditioned using CBC MAC to generate the seed for RNG driver
73  *
74  * ### Step 1: Required header file ###
75  *
76  * @code
77  *
78  * #include <ti/drivers/rng/RNGLPF3RF.h> // required for external syscfg variable RNGLPF3RF_noiseInputWordLen
79  *
80  * @endcode
81  *
82  * ### Step 2: External APIs ###
83  *
84  * @code
85  *
86  * // Use the function provided by RCL to read noise input
87  * extern int_fast16_t RCL_AdcNoise_get_samples_blocking(uint32_t *buffer, uint32_t numWords);
88  *
89  * @endcode
90  *
91  * ### Step 3: Read noise input from RCL using RCL_AdcNoise_get_samples_blocking() ###
92  *
93  * @code
94  *
95  * int_fast16_t rclStatus, result, i;
96 
97  * // User's global array for noise input based on size provided in syscfg //
98  * uint32_t localNoiseInput[]; //Minimum array size 80 words
99  * uint8_t maxRetries = 4; //Maximum retries to get noise input from RCL
100  *
101  * // Clear noise input //
102  * memset(localNoiseInput, 0, sizeof(localNoiseInput));
103  *
104  * // Fill noise input from RCL //
105  * // RNGLPF3RF_noiseInputWordLen is external variable from RNGLPF3RF.h
106  * // Collect noise input from RCL till input has enough entropy.
107  * for (i = 0; i < maxRetries; i++)
108  * {
109  * rclStatus = RCL_AdcNoise_get_samples_blocking(localNoiseInput, RNGLPF3RF_noiseInputWordLen);
110  * if (rclStatus != 0)
111  * {
112  * // Handle error
113  * }
114  *
115  * // Initialize the RNG driver noise input pointer with global noise input array from user //
116  * rclStatus = RNGLPF3RF_conditionNoiseToGenerateSeed(localNoiseInput);
117  * if ((rclStatus == RNG_STATUS_RCT_FAIL) || (rclStatus == RNG_STATUS_APT_FAIL) ||
118  * (rclStatus == RNG_STATUS_APT_BIMODAL_FAIL))
119  * {
120  * continue; // retry if health checks fail
121  * }
122  * else if (rclStatus != 0)
123  * {
124  * // Handle error
125  * }
126  * else
127  * {
128  * break; // break out of loop if success
129  * }
130  * }
131  *
132  * @endcode
133  *
134  *
135  * ## Before starting a RNG operation ##
136  *
137  * Before starting a RNG operation, the application must do the following:
138  * - Call RNG_init() to initialize the driver's global instance data.
139  * - Call RNG_Params_init() to initialize the RNG_Params to default values.
140  * - Modify the RNG_Params as desired.
141  * - Call RNG_open() to open an instance of the driver.
142  *
143  * @note Some implementations restrict when RNG_init() may be called.
144  * Check the implementation's documentation for more information.
145  *
146  * ## Entropy Pool Management ##
147  *
148  * At any time after calling RNG_init(), the application may call
149  * RNG_fillPoolIfLessThan() to add entropy to the pool which will then make
150  * future requests for entropy execute faster. Note that the driver never
151  * automatically refills the pool. However, if the pool is empty, the RNG
152  * driver will still generate entropy upon request (for example when
153  * RNG_getRandomBits() is called).
154  *
155  * The application is responsible for deciding when it is appropriate to
156  * spend the time and energy to refill the pool. One suggested location
157  * to do so is the idle thread.
158  *
159  * ## RNG operations ##
160  *
161  * Use RNG_getRandomBits() to obtain random bits from the entropy pool and
162  * copy them to a buffer/array. The caller must allocate memory sufficient
163  * to hold at least the number of bits of random data requested.
164  *
165  * ## After the RNG operation completes ##
166  *
167  * After the RNG operation completes, the application should either start
168  * another operation or close the driver by calling RNG_close(). Note that the
169  * singleton instance of the driver, along with its associated pool of entropy
170  * will still exist and will be used by any future RNG_open() calls. Note that
171  * closing the driver instance may not be strictly required, but is good
172  * practice.
173  *
174  * ## Security ##
175  *
176  * ### Data Protection ###
177  *
178  * The entropy pool and any required state to generate more entropy is
179  * maintained in memory, in the driver's global instance data. The entirety of
180  * this data is stored in two global variables called RNG_instanceData and
181  * RNG_instancePool. It is up to the system to provide adequate
182  * protection (primarily confidentiality and integrity) of these in-memory
183  * assets.
184  *
185  * ### Timing Side Channels ###
186  *
187  * Functions which provide for generation of a value within a range use
188  * an algorithm which is timing-constant when the following parameters
189  * are held constant: lowerLimit, upperLimit, bitLength,
190  * and endianess. Thus, while the driver may create multiple candidates for the
191  * value to find one within the range, timing will not leak the final
192  * value's relation to the limits. However, timing may leak the bitLength,
193  * the endianess, and the use of #CryptoUtils_limitZero, #CryptoUtils_limitOne,
194  * or NULL for the limit values.
195  *
196  * @anchor ti_drivers_RNG_Synopsis
197  * ## Synopsis
198  * @anchor ti_drivers_RNG_Synopsis_Code
199  * ### Generate random bytes to a user provided buffer #
200  *
201  * @code
202  *
203  * #include <ti/drivers/RNG.h>
204  * #include "ti_drivers_config.h"
205  *
206  * // Setup RNG
207  * RNG_Init();
208  * RNG_fillPoolIfLessThan(RNG_POOL_BYTE_SIZE);
209  *
210  * // Use RNG
211  * #define RANDOM_BYTES_SIZE 16u
212  * RNG_Handle handle;
213  * int_fast16_t result;
214  *
215  * uint8_t randomBytesArray[RANDOM_BYTES_SIZE] = {0};
216  *
217  * handle = RNG_open(0, NULL);
218  *
219  * if (!handle) {
220  * // Handle error
221  * while(1);
222  * }
223  *
224  * result = RNG_getRandomBits(handle, randomBytesArray, RANDOM_BYTES_SIZE * 8);
225  *
226  * if (result != RNG_STATUS_SUCCESS) {
227  * // Handle error
228  * while(1);
229  * }
230  *
231  * RNG_close(handle);
232  *
233  * // Refill RNG Pool when convenient
234  * RNG_fillPoolIfLessThan(RNG_POOL_BYTE_SIZE);
235  * @endcode
236  *
237  * @anchor ti_drivers_RNG_Examples
238  * ## Examples
239  *
240  * The following examples do not show the process of initializing the RNG
241  * module and refilling the pool.
242  * See @ref ti_drivers_RNG_Synopsis RNG Driver Synopsis for an example
243  * showing those parts of RNG operation. *
244  *
245  * ### Generate a number within a range ###
246  *
247  * @code
248  *
249  * #include <ti/drivers/RNG.h>
250  *
251  * #define RANDOM_BIT_SIZE 15u
252  * #define RANDOM_BYTE_SIZE ((RANDOM_BIT_SIZE + 7u)/8u)
253  *
254  * RNG_Handle handle;
255  * int_fast16_t result;
256  *
257  * uint8_t randomBytesArray[RANDOM_BYTES_SIZE] = {0};
258  * uint8_t upperLimit[RANDOM_BYTES_SIZE] = {0xA9, 0x61}; // 25,001, LE format
259  *
260  * handle = RNG_open(0, NULL);
261  *
262  * if (!handle) {
263  * // Handle error
264  * while(1);
265  * }
266  *
267  * // Generate a number from 1 to 25,000 (inclusive)
268  * // Note that lowerLimit parameter is inclusive and upperLimit is
269  * // exclusive. Thus, upperLimit is set to 25,001.
270  * result = RNG_getLERandomNumberInRange(RNG_Handle handle, RNG_limitOne,
271  * upperLimit, randomBytesArray,
272  * RANDOM_BIT_SIZE);
273  *
274  *
275  * if (result != RNG_STATUS_SUCCESS) {
276  * // Handle error
277  * while(1);
278  * }
279  *
280  * RNG_close(handle);
281  *
282  * @endcode
283  *
284  *
285  * ### Generate an ECC private key ###
286  *
287  * @code
288  *
289  * #include <ti/drivers/RNG.h>
290  * #include <ti/drivers/cryptoutils/ecc/ECCParams.h>
291  *
292  * // Values are chosen to generate a NIST 256 bit key.
293  * CryptoKey privateKey;
294  * uint8_t privateKeyingMaterial[NISTP256_PARAM_SIZE_BYTES];
295  * RNG_Handle handle;
296  * int_fast16_t result;
297  *
298  * handle = RNG_open(0, NULL);
299  *
300  * if (!handle) {
301  * // Handle error
302  * while(1);
303  * }
304  *
305  * CryptoKeyPlaintext_initBlankKey(&privateKey, privateKeyingMaterial,
306  * ECCParams_NISTP256.length);
307  *
308  * // Generate NIST 256 bit key in BE format.
309  * result = RNG_generateBEKeyInRange(RNG_Handle handle, RNG_limitOne,
310  * ECCParams_NISTP256.order, privateKey,
311  * 256);
312  *
313  *
314  * if (result != RNG_STATUS_SUCCESS) {
315  * // Handle error
316  * while(1);
317  * }
318  *
319  * RNG_close(handle);
320  *
321  * @endcode
322  *
323  */
324 
325 #ifndef ti_drivers_RNG__include
326 #define ti_drivers_RNG__include
327 
328 #include <stdbool.h>
329 #include <stddef.h>
330 #include <stdint.h>
331 
333 
334 #ifdef __cplusplus
335 extern "C" {
336 #endif
337 
350 #define RNG_STATUS_RESERVED (-32)
351 
358 #define RNG_STATUS_SUCCESS ((int_fast16_t)0)
359 
366 #define RNG_STATUS_ERROR ((int_fast16_t)-1)
367 
377 #define RNG_STATUS_RESOURCE_UNAVAILABLE ((int_fast16_t)-2)
378 
384 #define RNG_STATUS_INVALID_INPUTS ((int_fast16_t)-3)
385 
389 #define RNG_STATUS_CANCELED ((int_fast16_t)-4)
390 
396 #define RNG_ENTROPY_EXHAUSTED ((int_fast16_t)-5)
397 
403 #define RNG_STATUS_INIT_NOT_ALLOWED ((int_fast16_t)-6)
404 
411 #define RNG_STATUS_NOISE_INPUT_INVALID ((int_fast16_t)-7)
412 
419 #define RNG_STATUS_NOT_INITIALIZED ((int_fast16_t)-8)
420 
424 #define RNG_MAX_BIT_LENGTH ((size_t)1u << 20u) /* 1 MiB */
425 
437 typedef struct
438 {
440  void *object;
441 
443  void const *hwAttrs;
444 } RNG_Config;
445 
449 typedef const RNG_Config *RNG_Handle;
450 
477 typedef enum
478 {
496 
512 typedef void (*RNG_CryptoKeyCallbackFxn)(RNG_Handle handle, int_fast16_t returnValue, CryptoKey *key);
513 
532 typedef void (*RNG_RandomBitsCallbackFxn)(RNG_Handle handle,
533  int_fast16_t returnValue,
534  uint8_t *randomBits,
535  size_t randomBitsLength);
536 
549 typedef struct
550 {
561  uint32_t timeout;
564 } RNG_Params;
565 
571 extern const RNG_Params RNG_defaultParams;
572 
576 extern const size_t RNG_poolByteSize;
577 
600 int_fast16_t RNG_init(void);
601 
622 int_fast16_t RNG_fillPoolIfLessThan(size_t bytes);
623 
637 void RNG_Params_init(RNG_Params *params);
638 
656 RNG_Handle RNG_open(uint_least8_t index, const RNG_Params *params);
657 
667 void RNG_close(RNG_Handle handle);
668 
706 int_fast16_t RNG_getRandomBits(RNG_Handle handle, void *randomBits, size_t randomBitsLength);
707 
761 int_fast16_t RNG_getLERandomNumberInRange(RNG_Handle handle,
762  const void *lowerLimit,
763  const void *upperLimit,
764  void *randomNumber,
765  size_t randomNumberBitLength);
766 
820 int_fast16_t RNG_getBERandomNumberInRange(RNG_Handle handle,
821  const void *lowerLimit,
822  const void *upperLimit,
823  void *randomNumber,
824  size_t randomNumberBitLength);
825 
857 int_fast16_t RNG_generateKey(RNG_Handle handle, CryptoKey *key);
858 
909 int_fast16_t RNG_generateLEKeyInRange(RNG_Handle handle,
910  const void *lowerLimit,
911  const void *upperLimit,
912  CryptoKey *key,
913  size_t randomNumberBitLength);
914 
965 int_fast16_t RNG_generateBEKeyInRange(RNG_Handle handle,
966  const void *lowerLimit,
967  const void *upperLimit,
968  CryptoKey *key,
969  size_t randomNumberBitLength);
970 
994 RNG_Handle RNG_construct(const RNG_Config *config, const RNG_Params *params);
995 
1015 int_fast16_t RNG_cancelOperation(RNG_Handle handle);
1016 
1017 #ifdef __cplusplus
1018 }
1019 #endif
1020 
1021 #endif /* ti_drivers_RNG__include */
const RNG_Params RNG_defaultParams
Default RNG_Params structure.
The CryptoKey type is an opaque representation of a cryptographic key.
RNG_ReturnBehavior returnBehavior
Definition: RNG.h:551
int_fast16_t RNG_init(void)
This function initializes the RNG module.
RNG_RandomBitsCallbackFxn randomBitsCallbackFxn
Definition: RNG.h:556
int_fast16_t RNG_generateKey(RNG_Handle handle, CryptoKey *key)
Generate random bits and output them to the given CryptoKey object.
const size_t RNG_poolByteSize
The byte size of the pool.
void * object
Definition: RNG.h:440
CryptoKey datastructure.
Definition: CryptoKey.h:211
Definition: RNG.h:486
int_fast16_t RNG_generateBEKeyInRange(RNG_Handle handle, const void *lowerLimit, const void *upperLimit, CryptoKey *key, size_t randomNumberBitLength)
Generate random number, stored in big-endian (BE) format, where the number is within the specified ra...
RNG_ReturnBehavior
The way in which RNG function calls return after generating the requested entropy.
Definition: RNG.h:477
RNG_Handle RNG_construct(const RNG_Config *config, const RNG_Params *params)
Constructs a new RNG object.
int_fast16_t RNG_getBERandomNumberInRange(RNG_Handle handle, const void *lowerLimit, const void *upperLimit, void *randomNumber, size_t randomNumberBitLength)
Generate random number, stored in big-endian (BE) format, where the number is within the specified ra...
RNG_CryptoKeyCallbackFxn cryptoKeyCallbackFxn
Definition: RNG.h:552
void(* RNG_RandomBitsCallbackFxn)(RNG_Handle handle, int_fast16_t returnValue, uint8_t *randomBits, size_t randomBitsLength)
The definition of a callback function used by the RNG driver when RNG_getRandomBits(), RNG_getLERandomNumberInRange(), or RNG_getBERandomNumberInRange is called with RNG_RETURN_BEHAVIOR_CALLBACK.
Definition: RNG.h:532
void RNG_close(RNG_Handle handle)
Function to close a RNG peripheral specified by the RNG handle.
int_fast16_t RNG_fillPoolIfLessThan(size_t bytes)
Fills the pool with entropy if the number of bytes with entropy in the pool is less than the value sp...
void const * hwAttrs
Definition: RNG.h:443
uint32_t timeout
Definition: RNG.h:561
int_fast16_t RNG_getLERandomNumberInRange(RNG_Handle handle, const void *lowerLimit, const void *upperLimit, void *randomNumber, size_t randomNumberBitLength)
Generate random number, stored in little-endian (LE) format, where the number is within the specified...
int_fast16_t RNG_getRandomBits(RNG_Handle handle, void *randomBits, size_t randomBitsLength)
Generate random bits and output to the given array.
Definition: RNG.h:479
int_fast16_t RNG_cancelOperation(RNG_Handle handle)
Aborts an ongoing RNG operation and clears internal buffers.
int_fast16_t RNG_generateLEKeyInRange(RNG_Handle handle, const void *lowerLimit, const void *upperLimit, CryptoKey *key, size_t randomNumberBitLength)
Generate random number, in little-endian (LE) format, where the number is within the specified range...
RNG_Handle RNG_open(uint_least8_t index, const RNG_Params *params)
This function opens a given RNG peripheral.
RNG Parameters.
Definition: RNG.h:549
RNG Global configuration.
Definition: RNG.h:437
void RNG_Params_init(RNG_Params *params)
Function to initialize the RNG_Params struct to its defaults.
const RNG_Config * RNG_Handle
A handle that is returned from a RNG_open() call.
Definition: RNG.h:449
Definition: RNG.h:490
void(* RNG_CryptoKeyCallbackFxn)(RNG_Handle handle, int_fast16_t returnValue, CryptoKey *key)
The definition of a callback function used by the RNG driver when RNG_generateKey(), RNG_generateLEKeyInRange(), or RNG_generateBEKeyInRange() is called with RNG_RETURN_BEHAVIOR_CALLBACK.
Definition: RNG.h:512
© Copyright 1995-2025, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale