RNG.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-2024, 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  * @anchor ti_drivers_RNG_Usage
46  * # Usage #
47  *
48  * ## Initialization ##
49  * Unlike most drivers, there is a global instance of RNG driver data
50  * that is always available once #RNG_init() is called. This data will contain
51  * the entropy pool and any needed state information required to refill the
52  * pool. #RNG_init() should be called once before using other RNG
53  * driver APIs.
54  *
55  * @note Some implementations restrict when RNG_init() may be called.
56  * Check the implementation's documentation for more information.
57  *
58  * For CC23X0, RNG must be initialized by application in a task context with interrupts enabled
59  * using the following steps prior to the use of the Radio because CC23X0 uses the ADC samples
60  * from radio as noise that is conditioned using CBC MAC to generate the seed for RNG driver
61  *
62  * ### Step 1: Required header file ###
63  *
64  * @code
65  *
66  * #include <ti/drivers/rng/RNGLPF3RF.h> // required for external syscfg variable RNGLPF3RF_noiseInputWordLen
67  *
68  * @endcode
69  *
70  * ### Step 2: External APIs ###
71  *
72  * @code
73  *
74  * // Use the function provided by RCL to read noise input //
75  * extern int_fast16_t RCL_AdcNoise_get_samples_blocking(uint32_t *buffer, uint32_t numWords);
76  *
77  * @endcode
78  *
79  * ### Step 3: Read noise input from RCL using RCL_AdcNoise_get_samples_blocking() ###
80  *
81  * @code
82  *
83  * int_fast16_t rclStatus, result;
84 
85  * // User's global array for noise input based on size provided in syscfg //
86  * uint32_t localNoiseInput[]; //Minimum array size 80 words
87  *
88  * // Clear noise input //
89  * memset(localNoiseInput, 0, sizeof(localNoiseInput));
90  *
91  * // Fill noise input from RCL //
92  * //RNGLPF3RF_noiseInputWordLen is external variable from RNGLPF3RF.h
93  * rclStatus = RCL_AdcNoise_get_samples_blocking(localNoiseInput, RNGLPF3RF_noiseInputWordLen);
94  *
95  * if (rclStatus != 0)
96  * {
97  * //Handle error;
98  * }
99  *
100  * // Initialize the RNG driver noise input pointer with global noise input array from user //
101  * result = RNGLPF3RF_conditionNoiseToGenerateSeed(localNoiseInput);
102  * if ( rclStatus != 0)
103  * {
104  * //Handle error;
105  * }
106  *
107  * @endcode
108  *
109  *
110  * ## Before starting a RNG operation ##
111  *
112  * Before starting a RNG operation, the application must do the following:
113  * - Call RNG_init() to initialize the driver's global instance data.
114  * - Call RNG_Params_init() to initialize the RNG_Params to default values.
115  * - Modify the RNG_Params as desired.
116  * - Call RNG_open() to open an instance of the driver.
117  *
118  * @note Some implementations restrict when RNG_init() may be called.
119  * Check the implementation's documentation for more information.
120  *
121  * ## Entropy Pool Management ##
122  *
123  * At any time after calling RNG_init(), the application may call
124  * RNG_fillPoolIfLessThan() to add entropy to the pool which will then make
125  * future requests for entropy execute faster. Note that the driver never
126  * automatically refills the pool. However, if the pool is empty, the RNG
127  * driver will still generate entropy upon request (for example when
128  * RNG_getRandomBits() is called).
129  *
130  * The application is responsible for deciding when it is appropriate to
131  * spend the time and energy to refill the pool. One suggested location
132  * to do so is the idle thread.
133  *
134  * ## RNG operations ##
135  *
136  * Use RNG_getRandomBits() to obtain random bits from the entropy pool and
137  * copy them to a buffer/array. The caller must allocate memory sufficient
138  * to hold at least the number of bits of random data requested.
139  *
140  * ## After the RNG operation completes ##
141  *
142  * After the RNG operation completes, the application should either start
143  * another operation or close the driver by calling RNG_close(). Note that the
144  * singleton instance of the driver, along with its associated pool of entropy
145  * will still exist and will be used by any future RNG_open() calls. Note that
146  * closing the driver instance may not be strictly required, but is good
147  * practice.
148  *
149  * ## Security ##
150  *
151  * ### Data Protection ###
152  *
153  * The entropy pool and any required state to generate more entropy is
154  * maintained in memory, in the driver's global instance data. The entirety of
155  * this data is stored in two global variables called RNG_instanceData and
156  * RNG_instancePool. It is up to the system to provide adequate
157  * protection (primarily confidentiality and integrity) of these in-memory
158  * assets.
159  *
160  * ### Timing Side Channels ###
161  *
162  * Functions which provide for generation of a value within a range use
163  * an algorithm which is timing-constant when the following parameters
164  * are held constant: lowerLimit, upperLimit, bitLength,
165  * and endianess. Thus, while the driver may create multiple candidates for the
166  * value to find one within the range, timing will not leak the final
167  * value's relation to the limits. However, timing may leak the bitLength,
168  * the endianess, and the use of #CryptoUtils_limitZero, #CryptoUtils_limitOne,
169  * or NULL for the limit values.
170  *
171  * @anchor ti_drivers_RNG_Synopsis
172  * ## Synopsis
173  * @anchor ti_drivers_RNG_Synopsis_Code
174  * ### Generate random bytes to a user provided buffer #
175  *
176  * @code
177  *
178  * #include <ti/drivers/RNG.h>
179  * #include "ti_drivers_config.h"
180  *
181  * // Setup RNG
182  * RNG_Init();
183  * RNG_fillPoolIfLessThan(RNG_POOL_BYTE_SIZE);
184  *
185  * // Use RNG
186  * #define RANDOM_BYTES_SIZE 16u
187  * RNG_Handle handle;
188  * int_fast16_t result;
189  *
190  * uint8_t randomBytesArray[RANDOM_BYTES_SIZE] = {0};
191  *
192  * handle = RNG_open(0, NULL);
193  *
194  * if (!handle) {
195  * // Handle error
196  * while(1);
197  * }
198  *
199  * result = RNG_getRandomBits(handle, randomBytesArray, RANDOM_BYTES_SIZE * 8);
200  *
201  * if (result != RNG_STATUS_SUCCESS) {
202  * // Handle error
203  * while(1);
204  * }
205  *
206  * RNG_close(handle);
207  *
208  * // Refill RNG Pool when convenient
209  * RNG_fillPoolIfLessThan(RNG_POOL_BYTE_SIZE);
210  * @endcode
211  *
212  * @anchor ti_drivers_RNG_Examples
213  * ## Examples
214  *
215  * The following examples do not show the process of initializing the RNG
216  * module and refilling the pool.
217  * See @ref ti_drivers_RNG_Synopsis RNG Driver Synopsis for an example
218  * showing those parts of RNG operation. *
219  *
220  * ### Generate a number within a range ###
221  *
222  * @code
223  *
224  * #include <ti/drivers/RNG.h>
225  *
226  * #define RANDOM_BIT_SIZE 15u
227  * #define RANDOM_BYTE_SIZE ((RANDOM_BIT_SIZE + 7u)/8u)
228  *
229  * RNG_Handle handle;
230  * int_fast16_t result;
231  *
232  * uint8_t randomBytesArray[RANDOM_BYTES_SIZE] = {0};
233  * uint8_t upperLimit[RANDOM_BYTES_SIZE] = {0xA9, 0x61}; // 25,001, LE format
234  *
235  * handle = RNG_open(0, NULL);
236  *
237  * if (!handle) {
238  * // Handle error
239  * while(1);
240  * }
241  *
242  * // Generate a number from 1 to 25,000 (inclusive)
243  * // Note that lowerLimit parameter is inclusive and upperLimit is
244  * // exclusive. Thus, upperLimit is set to 25,001.
245  * result = RNG_getLERandomNumberInRange(RNG_Handle handle, RNG_limitOne,
246  * upperLimit, randomBytesArray,
247  * RANDOM_BIT_SIZE);
248  *
249  *
250  * if (result != RNG_STATUS_SUCCESS) {
251  * // Handle error
252  * while(1);
253  * }
254  *
255  * RNG_close(handle);
256  *
257  * @endcode
258  *
259  *
260  * ### Generate an ECC private key ###
261  *
262  * @code
263  *
264  * #include <ti/drivers/RNG.h>
265  * #include <ti/drivers/cryptoutils/ecc/ECCParams.h>
266  *
267  * // Values are chosen to generate a NIST 256 bit key.
268  * CryptoKey privateKey;
269  * uint8_t privateKeyingMaterial[NISTP256_PARAM_SIZE_BYTES];
270  * RNG_Handle handle;
271  * int_fast16_t result;
272  *
273  * handle = RNG_open(0, NULL);
274  *
275  * if (!handle) {
276  * // Handle error
277  * while(1);
278  * }
279  *
280  * CryptoKeyPlaintext_initBlankKey(&privateKey, privateKeyingMaterial,
281  * ECCParams_NISTP256.length);
282  *
283  * // Generate NIST 256 bit key in BE format.
284  * result = RNG_generateBEKeyInRange(RNG_Handle handle, RNG_limitOne,
285  * ECCParams_NISTP256.order, privateKey,
286  * 256);
287  *
288  *
289  * if (result != RNG_STATUS_SUCCESS) {
290  * // Handle error
291  * while(1);
292  * }
293  *
294  * RNG_close(handle);
295  *
296  * @endcode
297  *
298  */
299 
300 #ifndef ti_drivers_RNG__include
301 #define ti_drivers_RNG__include
302 
303 #include <stdbool.h>
304 #include <stddef.h>
305 #include <stdint.h>
306 
308 
309 #ifdef __cplusplus
310 extern "C" {
311 #endif
312 
325 #define RNG_STATUS_RESERVED (-32)
326 
333 #define RNG_STATUS_SUCCESS ((int_fast16_t)0)
334 
341 #define RNG_STATUS_ERROR ((int_fast16_t)-1)
342 
352 #define RNG_STATUS_RESOURCE_UNAVAILABLE ((int_fast16_t)-2)
353 
359 #define RNG_STATUS_INVALID_INPUTS ((int_fast16_t)-3)
360 
364 #define RNG_STATUS_CANCELED ((int_fast16_t)-4)
365 
371 #define RNG_ENTROPY_EXHAUSTED ((int_fast16_t)-5)
372 
378 #define RNG_STATUS_INIT_NOT_ALLOWED ((int_fast16_t)-6)
379 
386 #define RNG_STATUS_NOISE_INPUT_INVALID ((int_fast16_t)-7)
387 
394 #define RNG_STATUS_NOT_INITIALIZED ((int_fast16_t)-7)
395 
399 #define RNG_MAX_BIT_LENGTH ((size_t)1u << 20u) /* 1 MiB */
400 
412 typedef struct
413 {
415  void *object;
416 
418  void const *hwAttrs;
419 } RNG_Config;
420 
424 typedef const RNG_Config *RNG_Handle;
425 
450 typedef enum
451 {
469 
485 typedef void (*RNG_CryptoKeyCallbackFxn)(RNG_Handle handle, int_fast16_t returnValue, CryptoKey *key);
486 
505 typedef void (*RNG_RandomBitsCallbackFxn)(RNG_Handle handle,
506  int_fast16_t returnValue,
507  uint8_t *randomBits,
508  size_t randomBitsLength);
509 
522 typedef struct
523 {
534  uint32_t timeout;
537 } RNG_Params;
538 
544 extern const RNG_Params RNG_defaultParams;
545 
549 extern const size_t RNG_poolByteSize;
550 
573 int_fast16_t RNG_init(void);
574 
595 int_fast16_t RNG_fillPoolIfLessThan(size_t bytes);
596 
611 
629 RNG_Handle RNG_open(uint_least8_t index, const RNG_Params *params);
630 
640 void RNG_close(RNG_Handle handle);
641 
679 int_fast16_t RNG_getRandomBits(RNG_Handle handle, void *randomBits, size_t randomBitsLength);
680 
734 int_fast16_t RNG_getLERandomNumberInRange(RNG_Handle handle,
735  const void *lowerLimit,
736  const void *upperLimit,
737  void *randomNumber,
738  size_t randomNumberBitLength);
739 
793 int_fast16_t RNG_getBERandomNumberInRange(RNG_Handle handle,
794  const void *lowerLimit,
795  const void *upperLimit,
796  void *randomNumber,
797  size_t randomNumberBitLength);
798 
830 int_fast16_t RNG_generateKey(RNG_Handle handle, CryptoKey *key);
831 
882 int_fast16_t RNG_generateLEKeyInRange(RNG_Handle handle,
883  const void *lowerLimit,
884  const void *upperLimit,
885  CryptoKey *key,
886  size_t randomNumberBitLength);
887 
938 int_fast16_t RNG_generateBEKeyInRange(RNG_Handle handle,
939  const void *lowerLimit,
940  const void *upperLimit,
941  CryptoKey *key,
942  size_t randomNumberBitLength);
943 
967 RNG_Handle RNG_construct(const RNG_Config *config, const RNG_Params *params);
968 
988 int_fast16_t RNG_cancelOperation(RNG_Handle handle);
989 
990 #ifdef __cplusplus
991 }
992 #endif
993 
994 #endif /* ti_drivers_RNG__include */
ADC_Params params
Definition: Driver_Init.h:11
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:524
int_fast16_t RNG_init(void)
This function initializes the RNG module.
RNG_RandomBitsCallbackFxn randomBitsCallbackFxn
Definition: RNG.h:529
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:415
CryptoKey datastructure.
Definition: CryptoKey.h:208
Definition: RNG.h:459
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:450
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:525
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:505
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:418
uint32_t timeout
Definition: RNG.h:534
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:452
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:522
RNG Global configuration.
Definition: RNG.h:412
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:424
Definition: RNG.h:463
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:485
© Copyright 1995-2024, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale