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 
307 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
308 
309 #ifdef __cplusplus
310 extern "C" {
311 #endif
312 
313 /*!
314  * Common RNG status code reservation offset.
315  * RNG driver implementations should offset status codes with
316  * RNG_STATUS_RESERVED growing negatively.
317  *
318  * Example implementation specific status codes:
319  * @code
320  * #define RNGXYZ_STATUS_ERROR0    ((int_fast16_t) (RNG_STATUS_RESERVED - 0))
321  * #define RNGXYZ_STATUS_ERROR1    ((int_fast16_t) (RNG_STATUS_RESERVED - 1))
322  * #define RNGXYZ_STATUS_ERROR2    ((int_fast16_t) (RNG_STATUS_RESERVED - 2))
323  * @endcode
324  */
325 #define RNG_STATUS_RESERVED (-32)
326 
327 /*!
328  * @brief   Successful status code.
329  *
330  * Functions return RNG_STATUS_SUCCESS if the function was executed
331  * successfully.
332  */
333 #define RNG_STATUS_SUCCESS ((int_fast16_t)0)
334 
335 /*!
336  * @brief   Generic error status code.
337  *
338  * Functions return RNG_STATUS_ERROR if the function was not executed
339  * successfully.
340  */
341 #define RNG_STATUS_ERROR ((int_fast16_t)-1)
342 
343 /*!
344  * @brief   An error status code returned if the hardware or software resource
345  * is currently unavailable.
346  *
347  * RNG driver implementations may have hardware or software limitations on how
348  * many clients can simultaneously perform operations. This status code is
349  * returned if the mutual exclusion mechanism signals that an operation cannot
350  * currently be performed.
351  */
352 #define RNG_STATUS_RESOURCE_UNAVAILABLE ((int_fast16_t)-2)
353 
354 /*!
355  * @brief   Operation failed due to invalid inputs.
356  *
357  * Functions return RNG_STATUS_INVALID_INPUTS if input validation fails.
358  */
359 #define RNG_STATUS_INVALID_INPUTS ((int_fast16_t)-3)
360 
361 /*!
362  * @brief  The ongoing operation was canceled.
363  */
364 #define RNG_STATUS_CANCELED ((int_fast16_t)-4)
365 
366 /*!
367  * @brief  The pool of entropy has been exhausted and additional entropy cannot
368  *         be generated. A reset of the system may be required to generate more
369  *         entropy.
370  */
371 #define RNG_ENTROPY_EXHAUSTED ((int_fast16_t)-5)
372 
373 /*!
374  * @brief Some implementations have restrictions on how often or when
375  *        RNG_init may be called. See the documentation for the implementation
376  *        for more information.
377  */
378 #define RNG_STATUS_INIT_NOT_ALLOWED ((int_fast16_t)-6)
379 
380 /*!
381  * @brief Some implementations require a noise input during initialization
382  *        which is conditioned to seed the RNG driver. RNG_init() will return this
383  *        error if the noise input pointer is not intialized with valid information.
384  *        See documentation for the implementation for more information.
385  */
386 #define RNG_STATUS_NOISE_INPUT_INVALID ((int_fast16_t)-7)
387 
388 /*!
389  * @brief RNG driver not intialized.
390  *
391  * @note Some implementations restrict when RNG_init() may be called.
392  *       Refer to #RNG_init() for more information.
393  */
394 #define RNG_STATUS_NOT_INITIALIZED ((int_fast16_t)-7)
395 
396 /*!
397  * @brief  Maximum number of bits that may be requested in a single call
398  */
399 #define RNG_MAX_BIT_LENGTH ((size_t)1u << 20u) /* 1 MiB */
400 
401 /*!
402  *  @brief RNG Global configuration
403  *
404  *  The RNG_Config structure contains a set of pointers used to characterize
405  *  the RNG driver implementation.
406  *
407  *  This structure needs to be defined before calling RNG_init() and it must
408  *  not be changed thereafter.
409  *
410  *  @sa     RNG_init()
411  */
412 typedef struct
413 {
414     /*! Pointer to a driver specific data object */
415     void *object;
416 
417     /*! Pointer to a driver specific hardware attributes structure */
418     void const *hwAttrs;
419 } RNG_Config;
420 
421 /*!
422  *  @brief  A handle that is returned from a RNG_open() call.
423  */
424 typedef const RNG_Config *RNG_Handle;
425 
426 /*!
427  * @brief   The way in which RNG function calls return after generating
428  *          the requested entropy.
429  *
430  * Not all RNG implementations support all of the return behavior options.
431  *
432  * Not all RNG operations exhibit the specified return behavior. Functions that
433  * do not require significant computation and cannot offload that computation to
434  * a background thread behave like regular functions. Which functions exhibit
435  * the specified return behavior is not implementation dependent. Specifically,
436  * a software-backed implementation run on the same CPU as the application will
437  * emulate the return behavior while not actually offloading the computation to
438  * the background thread.
439  *
440  * RNG functions exhibiting the specified return behavior have restrictions on
441  * the context from which they may be called.
442  *
443  * |                              | Task  | Hwi   | Swi   |
444  * |------------------------------|-------|-------|-------|
445  * | RNG_RETURN_BEHAVIOR_CALLBACK | X     |       |       |
446  * | RNG_RETURN_BEHAVIOR_BLOCKING | X     |       |       |
447  * | RNG_RETURN_BEHAVIOR_POLLING  | X     | X     | X     |
448  *
449  */
450 typedef enum
451 {
452     RNG_RETURN_BEHAVIOR_CALLBACK = 1, /*!< The function call will return immediately while the
453                                        *   RNG operation goes on in the background. The
454                                        *   registered callback function is called after the
455                                        *   operation completes. The context the callback
456                                        *   function is called (task, HWI, SWI) is
457                                        *   implementation-dependent.
458                                        */
459     RNG_RETURN_BEHAVIOR_BLOCKING = 2, /*!< The function call will block while RNG operation
460                                        *   goes on in the background. RNG operation results
461                                        *    are available after the function returns.
462                                        */
463     RNG_RETURN_BEHAVIOR_POLLING  = 4, /*!< The function call will continuously poll a flag
464                                        *   while RNG operation goes on in the background. RNG
465                                        *   operation results are available after the function
466                                        *   returns.
467                                        */
468 } RNG_ReturnBehavior;
469 
470 /*!
471  *  @brief  The definition of a callback function used by the RNG driver
472  *          when RNG_generateKey(), RNG_generateLEKeyInRange(), or
473  *          RNG_generateBEKeyInRange() is called with ::RNG_RETURN_BEHAVIOR_CALLBACK
474  *
475  *  @warning Attempting to make calls to the RNG driver from the callback
476  *           may result in deadlock.
477  *
478  *  @param  handle  Handle of the client that started the RNG operation.
479  *
480  *  @param  returnValue Return status code describing the outcome of the operation.
481  *
482  *  @param  key     The CryptoKey that describes the location the generated
483  *                      entropy will be copied to.
484  */
485 typedef void (*RNG_CryptoKeyCallbackFxn)(RNG_Handle handle, int_fast16_t returnValue, CryptoKey *key);
486 
487 /*!
488  *  @brief  The definition of a callback function used by the RNG driver
489  *          when RNG_getRandomBits(), RNG_getLERandomNumberInRange(),
490  *          or RNG_getBERandomNumberInRange is called with
491  *          ::RNG_RETURN_BEHAVIOR_CALLBACK
492  *
493  *  @warning Attempting to make calls to the RNG driver from the callback
494  *           may result in deadlock.
495  *
496  *  @param  handle  Handle of the client that started the RNG operation.
497  *
498  *  @param  returnValue Return status code describing the outcome of the operation.
499  *
500  *  @param  randomBits Pointer to an array that stores the random bits
501  *                      output by this function.
502  *
503  *  @param  randomBitsLength The length of the random data generated, in bits.
504  */
505 typedef void (*RNG_RandomBitsCallbackFxn)(RNG_Handle handle,
506                                           int_fast16_t returnValue,
507                                           uint8_t *randomBits,
508                                           size_t randomBitsLength);
509 
510 /*!
511  *  @brief  RNG Parameters
512  *
513  *  RNG Parameters are used with the RNG_open() call. Default values for
514  *  these parameters are set using RNG_Params_init().
515  *
516  *  @attention When using the driver in #RNG_RETURN_BEHAVIOR_CALLBACK,
517  *             set the appropriate callback function field to point to a
518  *             valid callback function and set the other one to NULL.
519  *
520  *  @sa     RNG_Params_init()
521  */
522 typedef struct
523 {
524     RNG_ReturnBehavior returnBehavior;               /*!< Blocking, callback, or polling return behavior */
525     RNG_CryptoKeyCallbackFxn cryptoKeyCallbackFxn;   /*!< Callback function to use with RNG_generateKey()
526                                                       *   and RNG_generateKeyInRange().
527                                                       *   Set randomBitsCallbackFxn to NULL if using this.
528                                                       */
529     RNG_RandomBitsCallbackFxn randomBitsCallbackFxn; /*!< Callback function to use with RNG_getRandomBits(),
530                                                       *   RNG_getLERandomNumberInRange(), and
531                                                       *   RNG_getBERandomNumberInRange().
532                                                       *   Set cryptoKeyCallbackFxn to NULL if using this.
533                                                       */
534     uint32_t timeout;                                /*!< Timeout (in ClockP ticks) before the driver
535                                                       *   returns an error in ::RNG_RETURN_BEHAVIOR_BLOCKING
536                                                       */
537 } RNG_Params;
538 
539 /*!
540  *  @brief Default RNG_Params structure
541  *
542  *  @sa     RNG_Params_init()
543  */
544 extern const RNG_Params RNG_defaultParams;
545 
546 /*!
547  *  @brief The byte size of the pool
548  */
549 extern const size_t RNG_poolByteSize;
550 
551 /*!
552  *  @brief  This function initializes the RNG module.
553  *
554  *  @pre    The RNG_config structure must exist and be persistent before this
555  *          function can be called. This function must also be called before
556  *          any other RNG driver APIs. This function call does not modify any
557  *          peripheral registers.
558  *          For CC23X0, RNG must be initialized by application in a task context with interrupts enabled
559  *          using the following steps prior to the use of the Radio because CC23X0 uses the ADC samples
560  *          from radio as noise that is conditioned using CBC MAC
561  *          to generate the seed for RNG driver
562  *          1. Read radio noise using RCL_AdcNoise_get_samples_blocking(). This RCL function must
563  *             be called from a task context with interrupts enabled and therefore cannot be called
564  *             by startup code. This must be executed prior to the use of the radio.
565  *          2. Condition the noise to seed the RNG using RNGLPF3RF_conditionNoiseToGenerateSeed().
566  *          3. Initialize the RNG from the application with RNG_init()
567  *
568  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
569  *  @retval #RNG_STATUS_ERROR                 The operation failed.
570  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
571  *                                            not available. Try again later.
572  */
573 int_fast16_t RNG_init(void);
574 
575 /*!
576  *  @brief  Fills the pool with entropy if the number of bytes with entropy in
577  *          the pool is less than the value specified.
578  *
579  *  @note   This function does not take in a handle and the implementation
580  *          may run in either blocking or polling mode.
581  *
582  *  @pre    RNG_init() has to be called first.
583  *
584  *  @param  bytes Pool will be filled if current level is less than this number.
585  *                Use RNG_POOL_BYTE_SIZE (from ti_drivers_config.h) to always fill.
586  *
587  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
588  *  @retval #RNG_STATUS_ERROR                 The operation failed.
589  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
590  *                                            not available. Try again later.
591  *  @retval #RNG_ENTROPY_EXHAUSTED            Pool could not be refilled, device
592  *                                            may need reset.
593  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
594  */
595 int_fast16_t RNG_fillPoolIfLessThan(size_t bytes);
596 
597 /*!
598  *  @brief  Function to initialize the RNG_Params struct to its defaults
599  *
600  *  @param  params      An pointer to RNG_Params structure for
601  *                      initialization
602  *
603  *  Default values are:    <br>
604  *      returnBehavior              = RNG_RETURN_BEHAVIOR_BLOCKING  <br>
605  *      cryptoKeyCallbackFxn        = NULL                          <br>
606  *      randomBitsCallbackFxn       = NULL                          <br>
607  *      timeout                     = SemaphoreP_WAIT_FOREVER       <br>
608  *      custom                      = NULL                          <br>
609  */
610 void RNG_Params_init(RNG_Params *params);
611 
612 /*!
613  *  @brief  This function opens a given RNG peripheral.
614  *
615  *  @pre    RNG controller has been initialized using RNG_init()
616  *
617  *  @param  index         Logical peripheral number for the RNG indexed into
618  *                        the RNG_config table
619  *
620  *  @param  params        Pointer to an parameter block, if NULL it will use
621  *                        default values.
622  *
623  *  @return A RNG_Handle on success or a NULL on an error or if it has been
624  *          opened already.
625  *
626  *  @sa     RNG_init()
627  *  @sa     RNG_close()
628  */
629 RNG_Handle RNG_open(uint_least8_t index, const RNG_Params *params);
630 
631 /*!
632  *  @brief  Function to close a RNG peripheral specified by the RNG handle
633  *
634  *  @pre    RNG_open() has to be called first.
635  *
636  *  @param  handle A RNG handle returned from RNG_open()
637  *
638  *  @sa     RNG_open()
639  */
640 void RNG_close(RNG_Handle handle);
641 
642 /*!
643  *  @brief  Generate random bits and output to the given array.
644  *
645  *  Generates random a random number of bits with length of \c randomBitsLength.
646  *  The output length in bytes will be the minimum number of bytes needed
647  *  to contain \c randomBitsLength. The output will be placed at the address
648  *  pointed to by \c randomBits. The user shall be responsible for allocating
649  *  sufficient memory starting at the address pointed at by \c randomBits to
650  *  hold the number of bytes output.
651  *
652  *  @attention When called with ::RNG_RETURN_BEHAVIOR_CALLBACK, provide a
653  *             callback function of type #RNG_RandomBitsCallbackFxn.
654  *
655  *  @note See #RNG_generateKey() to output random bytes to a \c CryptoKey instead.
656  *
657  *  @pre    RNG_open() has to be called first.
658  *
659  *  @param  handle A RNG handle returned from RNG_open().
660  *
661  *  @param  randomBits Pointer to an array that stores the random bits
662  *                     output by this function.
663  *
664  *  @param  randomBitsLength The length of the random data required, in bits.
665  *                           A maximum of 1MiB is allowed.
666  *
667  *  @sa RNG_getLERandomNumberInRange
668  *  @sa RNG_getBERandomNumberInRange
669  *
670  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
671  *  @retval #RNG_STATUS_ERROR                 The operation failed.
672  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
673  *                                            not available. Try again later.
674  *  @retval #RNG_STATUS_INVALID_INPUTS        Inputs provided are not valid.
675  *  @retval #RNG_ENTROPY_EXHAUSTED            Requested number of bytes could
676  *                                            not be obtained. Device may need reset.
677  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
678  */
679 int_fast16_t RNG_getRandomBits(RNG_Handle handle, void *randomBits, size_t randomBitsLength);
680 
681 /*!
682  *  @brief  Generate random number, stored in little-endian (LE) format, where
683  *          the number is within the specified range.
684  *
685  *  Generates random a random number within the range [lowerLimit, upperLimit)
686  *  of bit size \c randomNumberBitLength. The output length in bytes will be the
687  *  minimum number of bytes needed to contain \c randomNumberBitLength. The
688  *  output will be placed at the address pointed to by \c randomNumber. The user
689  *  shall be responsible for allocating sufficient memory starting at the
690  *  address pointed at by \c randomNumber to hold the number of bytes output.
691  *
692  *  Note that the special values of #CryptoUtils_limitZero and
693  *  #CryptoUtils_limitOne are available to pass in for the \c lowerLimit.
694  *  (These values can also be used for the \c upperLimit but their use for the
695  *  upperLimit has no practical use.)
696  *
697  *  If \c lowerLimit is NULL then the lower limit is taken as 0.
698  *  If \c upperLimit is NULL then the upper limit is taken as
699  *  2<sup>(\c bitLength + 1)</sup>.
700  *
701  *  @attention When called with ::RNG_RETURN_BEHAVIOR_CALLBACK, provide a callback
702  *              function of type #RNG_RandomBitsCallbackFxn.
703  *
704  *  @note See #RNG_generateLEKeyInRange() to output a ranged number to a \c CryptoKey instead.
705  *
706  *  @pre    RNG_open() has to be called first.
707  *
708  *  @param  handle A RNG handle returned from RNG_open().
709  *
710  *  @param  lowerLimit Pointer to an array that stores the lower limit (inclusive)
711  *                     in LE format for the generated number.
712  *
713  *  @param  upperLimit Pointer to an array that stores the upper limit (exclusive)
714  *                     in LE format for the generated number.
715  *
716  *  @param  randomNumber Pointer to an array that stores the random number
717  *                       output by this function.
718  *
719  *  @param  randomNumberBitLength The length, in bits, of both the limit values
720  *                                and the random number to be generated.
721  *
722  *  @sa     CryptoUtils_limitZero
723  *  @sa     CryptoUtils_limitOne
724  *
725  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
726  *  @retval #RNG_STATUS_ERROR                 The operation failed.
727  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
728  *                                            not available. Try again later.
729  *  @retval #RNG_STATUS_INVALID_INPUTS        Inputs provided are not valid.
730  *  @retval #RNG_ENTROPY_EXHAUSTED            Requested number of bytes could
731  *                                            not be obtained. Device may need reset.
732  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
733  */
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 
740 /*!
741  *  @brief  Generate random number, stored in big-endian (BE) format, where
742  *          the number is within the specified range.
743  *
744  *  Generates random a random number within the range [lowerLimit, upperLimit)
745  *  of bit size \c randomNumberBitLength. The output length in bytes will be the
746  *  minimum number of bytes needed to contain \c randomNumberBitLength. The
747  *  output will be placed at the address pointed to by \c randomNumber. The user
748  *  shall be responsible for allocating sufficient memory starting at the address
749  *  pointed at by \c randomNumber to hold the number of bytes output.
750  *
751  *  Note that the special values of #CryptoUtils_limitZero and
752  *  #CryptoUtils_limitOne are available to pass in for the \c lowerLimit.
753  *  (These values can also be used for the \c upperLimit but their use for the
754  *  upperLimit has no practical use.)
755  *
756  *  If \c lowerLimit is NULL then the lower limit is taken as 0.
757  *  If \c upperLimit is NULL then the upper limit is taken as
758  *  2<sup>(\c bitLength + 1)</sup>.
759  *
760  *  @attention When called with ::RNG_RETURN_BEHAVIOR_CALLBACK, provide a callback
761  *              function of type #RNG_RandomBitsCallbackFxn.
762  *
763  *  @note See #RNG_generateBEKeyInRange() to output a ranged number to a \c CryptoKey instead.
764  *
765  *  @pre    RNG_open() has to be called first.
766  *
767  *  @param  handle A RNG handle returned from RNG_open().
768  *
769  *  @param  lowerLimit Pointer to an array that stores the lower limit (inclusive)
770  *                     in BE format for the generated number.
771  *
772  *  @param  upperLimit Pointer to an array that stores the upper limit (exclusive)
773  *                     in BE format for the generated number.
774  *
775  *  @param  randomNumber Pointer to an array that stores the random number
776  *                       output by this function.
777  *
778  *  @param  randomNumberBitLength The length, in bits, of both the limit value
779  *                                and the random number to be generated.
780  *
781  *  @sa     CryptoUtils_limitZero
782  *  @sa     CryptoUtils_limitOne
783  *
784  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
785  *  @retval #RNG_STATUS_ERROR                 The operation failed.
786  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
787  *                                            not available. Try again later.
788  *  @retval #RNG_STATUS_INVALID_INPUTS        Inputs provided are not valid.
789  *  @retval #RNG_ENTROPY_EXHAUSTED            Requested number of bytes could
790  *                                            not be obtained. Device may need reset.
791  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
792  */
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 
799 /*!
800  *  @brief  Generate random bits and output them to the given \c CryptoKey object.
801  *
802  *  Generates a random bitstream of the size defined in the \c key
803  *  CryptoKey in the range 0 <= \c key buffer < 2 ^ (entropy length * 8).
804  *  The entropy will be generated and stored according to the storage
805  *  requirements defined in the CryptoKey. The length of the entropy
806  *  generated will be the same as the key length.
807  *
808  *  @attention When called with ::RNG_RETURN_BEHAVIOR_CALLBACK, provide a
809  *             callback function of type #RNG_CryptoKeyCallbackFxn.
810  *
811  *  @pre    RNG_open() has to be called first.
812  *
813  *  @param  handle A RNG handle returned from RNG_open().
814  *
815  *  @param  key Pointer to a blank CryptoKey, initialized with a length and
816  *              appropriate storage for storing a key of the specified length.
817  *
818  *  @sa RNG_generateLEKeyInRange
819  *  @sa RNG_generateBEKeyInRange
820  *
821  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
822  *  @retval #RNG_STATUS_ERROR                 The operation failed.
823  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
824  *                                            not available. Try again later.
825  *  @retval #RNG_STATUS_INVALID_INPUTS        Inputs provided are not valid.
826  *  @retval #RNG_ENTROPY_EXHAUSTED            Requested number of bytes could
827  *                                            not be obtained. Device may need reset.
828  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
829  */
830 int_fast16_t RNG_generateKey(RNG_Handle handle, CryptoKey *key);
831 
832 /*!
833  *  @brief  Generate random number, in little-endian (LE) format, where the
834  *          number is within the specified range. Store the random number in
835  *          the given \c CryptoKey object.
836  *
837  *  Generates a random number within the range [lowerLimit, upperLimit) of bit
838  *  size \c randomNumberBitLength. The output length in bytes will be the minimum
839  *  number of bytes needed to contain \c randomNumberBitLength. The output will
840  *  be placed as specified by the members of \c key.
841  *
842  *  Note that the special values of #CryptoUtils_limitZero and
843  *  #CryptoUtils_limitOne are available to pass in for the \c lowerLimit.
844  *  (These values can also be used for the \c upperLimit but their use for the
845  *  upperLimit has no practical use.)
846  *
847  *  If \c lowerLimit is NULL then the lower limit is taken as 0.
848  *  If \c upperLimit is NULL then the upper limit is taken as
849  *  2<sup>(\c bitLength + 1)</sup>.
850  *
851  *  @attention When called with ::RNG_RETURN_BEHAVIOR_CALLBACK, provide a callback
852  *              function of type #RNG_CryptoKeyCallbackFxn.
853  *
854  *  @pre    RNG_open() has to be called first.
855  *
856  *  @param  handle A RNG handle returned from RNG_open().
857  *
858  *  @param  lowerLimit Pointer to an array that stores the lower limit (inclusive)
859  *                     in LE format for the generated number.
860  *
861  *  @param  upperLimit Pointer to an array that stores the upper limit (exclusive)
862  *                     in LE format for the generated number.
863  *
864  *  @param  key Pointer to a blank CryptoKey, initialized with a length and
865  *              appropriate storage for storing a key of the specified length.
866  *
867  *  @param  randomNumberBitLength The length, in bits, of both the limit values
868  *                                and the random number to be generated.
869  *
870  *  @sa     CryptoUtils_limitZero
871  *  @sa     CryptoUtils_limitOne
872  *
873  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
874  *  @retval #RNG_STATUS_ERROR                 The operation failed.
875  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
876  *                                            not available. Try again later.
877  *  @retval #RNG_STATUS_INVALID_INPUTS        Inputs provided are not valid.
878  *  @retval #RNG_ENTROPY_EXHAUSTED            Requested number of bytes could
879  *                                            not be obtained. Device may need reset.
880  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
881  */
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 
888 /*!
889  *  @brief  Generate random number, stored in big-endian (BE) format, where the
890  *          number is within the specified range. Store the random number in
891  *          the given \c CryptoKey object.
892  *
893  *  Generates a random number within the range [lowerLimit, upperLimit) of bit
894  *  size \c randomNumberBitLength. The output length in bytes will be the
895  *  minimum number of bytes needed to contain \c randomNumberBitLength. The
896  *  output will be placed as specified by the members of \c key.
897  *
898  *  Note that the special values of #CryptoUtils_limitZero and
899  *  #CryptoUtils_limitOne are available to pass in for the \c lowerLimit.
900  *  (These values can also be used for the \c upperLimit but their use for the
901  *  upperLimit has no practical use.)
902  *
903  *  If \c lowerLimit is NULL then the lower limit is taken as 0.
904  *  If \c upperLimit is NULL then the upper limit is taken as
905  *  2<sup>(\c bitLength + 1)</sup>.
906  *
907  *  @attention When called with ::RNG_RETURN_BEHAVIOR_CALLBACK, provide a callback
908  *              function of type #RNG_CryptoKeyCallbackFxn.
909  *
910  *  @pre    RNG_open() has to be called first.
911  *
912  *  @param  handle A RNG handle returned from RNG_open().
913  *
914  *  @param  lowerLimit Pointer to an array that stores the lower limit (inclusive)
915  *                     in BE format for the generated number.
916  *
917  *  @param  upperLimit Pointer to an array that stores the upper limit (exclusive)
918  *                     in BE format for the generated number.
919  *
920  *  @param  key Pointer to a blank CryptoKey, initialized with a length and
921  *              appropriate storage for storing a key of the specified length.
922  *
923  *  @param  randomNumberBitLength The length, in bits, of both the limit values
924  *                                and the random number to be generated.
925  *
926  *  @sa     CryptoUtils_limitZero
927  *  @sa     CryptoUtils_limitOne
928  *
929  *  @retval #RNG_STATUS_SUCCESS               The operation succeeded.
930  *  @retval #RNG_STATUS_ERROR                 The operation failed.
931  *  @retval #RNG_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was
932  *                                            not available. Try again later.
933  *  @retval #RNG_STATUS_INVALID_INPUTS        Inputs provided are not valid.
934  *  @retval #RNG_ENTROPY_EXHAUSTED            Requested number of bytes could
935  *                                            not be obtained. Device may need reset.
936  *  @retval #RNG_STATUS_NOT_INITIALIZED       RNG not intialized.
937  */
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 
944 /**
945  *  @brief  Constructs a new RNG object
946  *
947  *  Unlike #RNG_open(), #RNG_construct() does not require the hwAttrs and
948  *  object to be allocated in a #RNG_Config array that is indexed into.
949  *  Instead, the #RNG_Config, hwAttrs, and object can be allocated at any
950  *  location. This allows for relatively simple run-time allocation of temporary
951  *  driver instances on the stack or the heap.
952  *  The drawback is that this makes it more difficult to write device-agnostic
953  *  code. If you use an ifdef with DeviceFamily, you can choose the correct
954  *  object and hwAttrs to allocate. That compilation unit will be tied to the
955  *  device it was compiled for at this point. To change devices, recompilation
956  *  of the application with a different DeviceFamily setting is necessary.
957  *
958  *  @param config #RNG_Config describing the location of the object and hwAttrs.
959  *
960  *  @param params #RNG_Params to configure the driver instance.
961  *
962  *  @return Returns a #RNG_Handle on success or NULL on failure.
963  *
964  *  @pre    The object struct @c config points to must be zeroed out prior to
965  *          calling this function. Otherwise, unexpected behavior may ensue.
966  */
967 RNG_Handle RNG_construct(const RNG_Config *config, const RNG_Params *params);
968 
969 /*!
970  *  @brief Aborts an ongoing RNG operation and clears internal buffers.
971  *
972  *  Aborts an operation to generate random bytes/entropy. The operation will
973  *  terminate as though an error occurred and the status code of the operation
974  *  will be #RNG_STATUS_CANCELED in this case.
975  *
976  *  Any entropy already copied out of the pool will have already been removed
977  *  from the pool and will not be reused for later requests.
978  *
979  *  Canceling an operation may be delayed if the entropy pool is below its
980  *  minimum fill mark as the driver will refill the pool before finishing
981  *  the cancelled operation.
982  *
983  *  @param  handle A #RNG_Handle returned from #RNG_open()
984  *
985  *  @retval #RNG_STATUS_SUCCESS    The operation was canceled or there was no
986  *                                 operation in progress to be canceled.
987  */
988 int_fast16_t RNG_cancelOperation(RNG_Handle handle);
989 
990 #ifdef __cplusplus
991 }
992 #endif
993 
994 #endif /* ti_drivers_RNG__include */
995