1 /*
2  * Copyright (c) 2019-2022, 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       AESCTRDRBG.h
34  *
35  * @brief      AESCTRDRBG driver header
36  *
37  * @anchor ti_drivers_AESCTRDRBG_Overview
38  * <h3> Overview </h3>
39  * AESCTRDRBG is a cryptographically secure deterministic random bit generator
40  * that is used to efficiently generate random numbers for use in keying material
41  * or other security related purposes. It is based on the AES block cipher
42  * operating in Counter (CTR) mode and is defined by NIST SP 800-90A.
43  *
44  * AESCTRDRBG derives a sequence of pseudo-random numbers based on an initial
45  * secret seed and additional, non-secret personalization data provided during
46  * instantiation. A sequence of random bits generated by AESCTRDRBG will have
47  * an equivalent entropy content of MIN(sequenceLength, security strength).
48  * The security strength is based on the seed length and the AES key length used
49  * in the AESCTRDRBG instance.
50  *
51  * |                                       | AES-128 | AES-192 | AES-256 |
52  * |---------------------------------------|---------|---------|---------|
53  * | Security Strength (bits)              | 128     | 192     | 256     |
54  * | Seed Length (bits)                    | 192     | 320     | 384     |
55  * | Personalization String Length (bits)  | <= 192  | <= 320  | <= 384  |
56  * | Max Requests Between Reseeds          | 2^48    | 2^48    | 2^48    |
57  * | Max Request Length (bits)             | 2^19    | 2^19    | 2^19    |
58  *
59  * <h3> Security Strength </h3>
60  * The seed must be sourced from a cryptographically secure source such as
61  * a True Random Number Generator and contain seed length bits of entropy.
62  * Since the seed length is always larger than the security strength for
63  * any one AES key length, the output of one AESCTRDRBG instance may not
64  * be used to seed another instance of the same or higher security strength.
65  *
66  * <h3> Reseeding </h3>
67  * Because of the way AES CTR operates, there are a limited number of output
68  * bitstreams that may be generated before the AESCTRDRBG instance must be
69  * reseeded. The reseeding interval is set by the number of random bit
70  * sequences generated and not by their individual or combined lengths. Each time
71  * random bits are requested of the AESCTRDRBG instance by the application,
72  * the reseed counter is incremented by one regardless of how many bits at a
73  * time are requested. When this counter reaches the configured reseed limit,
74  * the AESCTRDRBG instance will return #AESCTRDRBG_STATUS_RESEED_REQUIRED
75  * until it is reseeded.
76  *
77  * The maximum permitted number of requests between reseeds is 2^48.
78  * The default counter is only 2^32 long for ease of implementation.
79  * A more conservative reseed limit may be configured by the application
80  * for increased security.
81  *
82  * A previously used seed may never be reused to reseed an AESCTRDRBG instance.
83  * The seed used to instantiate or reseed an instance must be generated by
84  * an approved entropy source.
85  *
86  * <h3> Derivation Function </h3>
87  * NIST specifies the the use of an optional derivation function to reduced
88  * entropy and personalization string lengths longer than the seed
89  * length down to the seed length. This feature is not presently supported.
90  *
91  * @anchor ti_drivers_AESCTRDRBG_Usage
92  * <h3> Usage </h3>
93  *
94  * This documentation provides a basic @ref ti_drivers_AESCTRDRBG_Synopsis
95  * "usage summary" and a set of @ref ti_drivers_AESCTRDRBG_Examples "examples"
96  * in the form of commented code fragments. Detailed descriptions of the
97  * APIs are provided in subsequent sections.
98  *
99  * @anchor ti_drivers_AESCTRDRBG_Synopsis
100  * <h3> Synopsis </h3>
101  * @anchor ti_drivers_AESCTRDRBG_Synopsis_Code
102  * @code
103  *     #include <ti/drivers/AESCTRDRBG.h>
104  *
105  *     AESCTRDRBG_init();
106  *
107  *     // Instantiate the AESCTRDRBG instance
108  *     AESCTRDRBG_Params_init(&params);
109  *     params.keyLength = AESCTRDRBG_AES_KEY_LENGTH_128;
110  *     params.reseedInterval = 0xFFFFFFFF;
111  *     params.seed = seedBuffer;
112  *
113  *     handle = AESCTRDRBG_open(0, &params);
114  *
115  *     result = AESCTRDRBG_generateKey(handle, &resultKey);
116  *
117  *     reseedResult = AESCTRDRBG_reseed(handle, reseedBuffer, NULL, 0);
118  *
119  *     AESCTRDRBG_close(handle);
120  * @endcode
121  *
122  * @anchor ti_drivers_AESCTRDRBG_Examples
123  * <h3> Examples </h3>
124  *
125  * <h4> Instantiating an AESCTRDRBG Instance with TRNG </h4>
126  * @code
127  *
128  * #include <ti/drivers/AESCTRDRBG.h>
129  * #include <ti/drivers/TRNG.h>
130  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
131  *
132  * ...
133  *
134  *     AESCTRDRBG_Handle handle;
135  *     AESCTRDRBG_Params params;
136  *     TRNG_Handle trngHandle;
137  *     int_fast16_t result;
138  *
139  *     uint8_t seedBuffer[AESCTRDRBG_SEED_LENGTH_AES_128];
140  *
141  *     // Open a TRNG driver instance
142  *     trngHandle = TRNG_open(0, NULL);
143  *     if (trngHandle == NULL) {
144  *         // Failed to open TRNG instance
145  *         while(1);
146  *     }
147  *
148  *     // Generate entropy for the seed
149  *     result = TRNG_getRandomBytes(trngHandle, seedBuffer, AESCTRDRBG_SEED_LENGTH_AES_128);
150  *     if (result != TRNG_STATUS_SUCCESS) {
151  *         // Failed to generate entropy
152  *         while(1);
153  *     }
154  *
155  *     TRNG_close(trngHandle);
156  *
157  *     // Instantiate the AESCTRDRBG parameters and the driver instance
158  *     AESCTRDRBG_Params_init(&params);
159  *     params.keyLength = AESCTRDRBG_AES_KEY_LENGTH_128;
160  *     params.reseedInterval = 0xFFFFFFFF;
161  *     params.seed = seedBuffer;
162  *
163  *     handle = AESCTRDRBG_open(0, &params);
164  *     if (handle == NULL) {
165  *         // Failed to open AESCTRDRBG instance
166  *         while(1);
167  *     }
168  * @endcode
169  *
170  * <h4> Generating random key with Reseeding </h4>
171  *
172  * @code
173  *
174  * #include <ti/drivers/AESCTRDRBG.h>
175  * #include <ti/drivers/TRNG.h>
176  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
177  *
178  * ...
179  *
180  *     #define RANDOM_KEY_LENGTH_BYTES 32
181  *
182  *     AESCTRDRBG_Handle handle;
183  *     TRNG_Handle trngHandle;
184  *     CryptoKey randomKey;
185  *     int_fast16_t result;
186  *
187  *     uint8_t randomKeyBuffer[RANDOM_KEY_LENGTH_BYTES];
188  *
189  *     // Initialise the AESCTRDRBG params and driver instance here
190  *     ...
191  *
192  *     // Initialize a blank CryptoKey
193  *     CryptoKeyPlaintext_initBlankKey(&randomKey, randomKeyBuffer, RANDOM_KEY_LENGTH_BYTES);
194  *
195  *     // Generate key-material for the CryptoKey
196  *     result = AESCTRDRBG_generateKey(handle, &randomKey);
197  *
198  *     // Check return value and reseed if needed. This should happen only after many invocations
199  *     // of AESCTRDRBG_generateKey().
200  *     if (result == AESCTRDRBG_STATUS_RESEED_REQUIRED) {
201  *         TRNG_Handle trngHandle;
202  *         int_fast16_t reseedResult;
203  *         uint8_t reseedBuffer[AESCTRDRBG_SEED_LENGTH_AES_128];
204  *
205  *         reseedResult = TRNG_getRandomBytes(trngHandle, reseedBuffer, AESCTRDRBG_SEED_LENGTH_AES_128);
206  *         if (reseedResult != TRNG_STATUS_SUCCESS) {
207  *             // Failed to generate entropy
208  *             while(1);
209  *         }
210  *
211  *         TRNG_close(trngHandle);
212  *
213  *         // Reseed the DRBG instance
214  *         reseedResult = AESCTRDRBG_reseed(handle, reseedBuffer, NULL, 0);
215  *         if (reseedResult != AESCTRDRBG_STATUS_SUCCESS) {
216  *             // Failed to reseed the DRBG instance
217  *             while(1);
218  *         }
219  *
220  *         // If AESCTRDRBG_STATUS_RESEED_REQUIRED was returned from the previous call to
221  *         // AESCTRDRBG_generateKey(), the random key was never generated by that call.
222  *         // So the user must invoke that call again (after reseeding) to get a random key.
223  *         result = AESCTRDRBG_generateKey(handle, &randomKey);
224  *         if (result != AESCTRDRBG_STATUS_SUCCESS) {
225  *             // Failed to generate key-material
226  *             while(1);
227  *         }
228  *     }
229  *     else if (result != AESCTRDRBG_STATUS_SUCCESS) {
230  *         // Failed to generate key-material
231  *         while(1);
232  *     }
233  *
234  * @endcode
235  *
236  * <h4> Generating random bytes output to an array </h4>
237  *
238  * @code
239  *
240  * #include <ti/drivers/AESCTRDRBG.h>
241  * #include <ti/drivers/TRNG.h>
242  *
243  * ...
244  *
245  *     #define RANDOM_BYTES_SIZE 16
246  *
247  *     AESCTRDRBG_Handle handle;
248  *     TRNG_Handle trngHandle;
249  *     int_fast16_t result;
250  *     uint8_t randomBytesBuffer[RANDOM_BYTES_SIZE];
251  *
252  *     // Initialise the AESCTRDRBG params and driver instance here
253  *     ...
254  *
255  *     // Get random bytes output to the buffer/array
256  *     result = AESCTRDRBG_getRandomBytes(handle, &randomBytesBuffer, RANDOM_BYTES_SIZE);
257  *
258  *     // Check and reseed if required. This should happen only after many invocations
259  *     // of AESCTRDRBG_getRandomBytes().
260  *     if (result == AESCTRDRBG_STATUS_RESEED_REQUIRED) {
261  *          // Reseed the DRBG instance using AESCTRDRBG_reseed()
262  *          // and invoke AESCTRDRBG_getRandomBytes() similar to the previous example.
263  *     }
264  *     else if (result != AESCTRDRBG_STATUS_SUCCESS) {
265  *         // Failed to generate random bytes
266  *         while(1);
267  *     }
268  *
269  * @endcode
270  *
271  */
272 
273 #ifndef ti_drivers_AESCTRDRBG__include
274 #define ti_drivers_AESCTRDRBG__include
275 
276 #include <stdbool.h>
277 #include <stddef.h>
278 #include <stdint.h>
279 
280 #include <ti/drivers/AESCTR.h>
281 #include <ti/drivers/AESCommon.h>
282 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
283 
284 #ifdef __cplusplus
285 extern "C" {
286 #endif
287 
288 /*!
289  * Common AESCTRDRBG status code reservation offset.
290  * AESCTRDRBG driver implementations should offset status codes with
291  * #AESCTRDRBG_STATUS_RESERVED growing negatively.
292  *
293  * Example implementation specific status codes:
294  * @code
295  * #define AESCTRDRBGXYZ_STATUS_ERROR0    AESCTRDRBG_STATUS_RESERVED - 0
296  * #define AESCTRDRBGXYZ_STATUS_ERROR1    AESCTRDRBG_STATUS_RESERVED - 1
297  * #define AESCTRDRBGXYZ_STATUS_ERROR2    AESCTRDRBG_STATUS_RESERVED - 2
298  * @endcode
299  */
300 #define AESCTRDRBG_STATUS_RESERVED AES_STATUS_RESERVED
301 
302 /*!
303  * @brief   Successful status code.
304  *
305  * Functions return #AESCTRDRBG_STATUS_SUCCESS if the function was executed
306  * successfully.
307  */
308 #define AESCTRDRBG_STATUS_SUCCESS AES_STATUS_SUCCESS
309 
310 /*!
311  * @brief   Generic error status code.
312  *
313  * Functions return #AESCTRDRBG_STATUS_ERROR if the function was not executed
314  * successfully and no more pertinent error code could be returned.
315  */
316 #define AESCTRDRBG_STATUS_ERROR AES_STATUS_ERROR
317 
318 /*!
319  * @brief   An error status code returned if the hardware or software resource
320  * is currently unavailable.
321  *
322  * AESCTRDRBG driver implementations may have hardware or software limitations on how
323  * many clients can simultaneously perform operations. This status code is returned
324  * if the mutual exclusion mechanism signals that an operation cannot currently be performed.
325  */
326 #define AESCTRDRBG_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
327 
328 /*!
329  * @brief   The AESCTRDRBG instance must be reseeded.
330  *
331  * An AESCTRDRBG instance may only service a limited number of bit
332  * generation requests before reseeding with more entropy is required.
333  */
334 #define AESCTRDRBG_STATUS_RESEED_REQUIRED (AES_STATUS_DRIVER_SPECIFIC_ERROR - 0)
335 
336 /*!
337  * @brief   The AESCTRDRBG instance is uninstantiated. Close and reopen
338  *          the instance.
339  */
340 #define AESCTRDRBG_STATUS_UNINSTANTIATED (AES_STATUS_DRIVER_SPECIFIC_ERROR - 1)
341 
342 /*!
343  * @brief   The operation does not support non-word-aligned input and/or output.
344  *
345  * AESCTR driver implementations used by AESCTRDRBG may have restrictions on the
346  * alignment of input/output data due to performance limitations of the
347  * hardware.
348  */
349 #define AESCTRDRBG_STATUS_UNALIGNED_IO_NOT_SUPPORTED (AES_STATUS_DRIVER_SPECIFIC_ERROR - 2)
350 
351 /*!
352  * @brief   Importing generated key into KeyStore failed
353  *
354  * Functions return AESCTRDRBG_STATUS_KEYSTORE_ERROR if the KeyStore_PSA_importKey()
355  * did not return KEYSTORE_PSA_STATUS_SUCCESS
356  */
357 #define AESCTRDRBG_STATUS_KEYSTORE_ERROR (AES_STATUS_KEYSTORE_GENERIC_ERROR)
358 
359 /*!
360  * @brief   The AES block size in bytes.
361  */
362 #define AESCTRDRBG_AES_BLOCK_SIZE_BYTES 16
363 
364 /*!
365  * @brief   Length in bytes of the internal AES key used by an instance
366  */
367 typedef enum
368 {
369     AESCTRDRBG_AES_KEY_LENGTH_128 = 16,
370     AESCTRDRBG_AES_KEY_LENGTH_256 = 32,
371 } AESCTRDRBG_AES_KEY_LENGTH;
372 
373 /*!
374  * @brief   Length in bytes of seed used to instantiate or reseed instance
375  */
376 typedef enum
377 {
378     AESCTRDRBG_SEED_LENGTH_AES_128 = AESCTRDRBG_AES_KEY_LENGTH_128 + AESCTRDRBG_AES_BLOCK_SIZE_BYTES,
379     AESCTRDRBG_SEED_LENGTH_AES_256 = AESCTRDRBG_AES_KEY_LENGTH_256 + AESCTRDRBG_AES_BLOCK_SIZE_BYTES,
380 } AESCTRDRBG_SEED_LENGTH;
381 
382 /*!
383  * @brief   The way in which AESCTRDRBG function calls return after generating
384  *          the requested entropy.
385  *
386  * Not all AESCTRDRBG operations exhibit the specified return behavior. Functions that do not
387  * require significant computation and cannot offload that computation to a background thread
388  * behave like regular functions. Which functions exhibit the specified return behavior is not
389  * implementation dependent. Specifically, a software-backed implementation run on the same
390  * CPU as the application will emulate the return behavior while not actually offloading
391  * the computation to the background thread.
392  *
393  * AESCTRDRBG functions exhibiting the specified return behavior have restrictions on the
394  * context from which they may be called.
395  *
396  * |                                     | Task  | Hwi   | Swi   |
397  * |-------------------------------------|-------|-------|-------|
398  * |#AESCTRDRBG_RETURN_BEHAVIOR_BLOCKING | X     |       |       |
399  * |#AESCTRDRBG_RETURN_BEHAVIOR_POLLING  | X     | X     | X     |
400  *
401  */
402 typedef enum
403 {
404     /*!< The function call will block while AESCTRDRBG operation goes
405      *   on in the background. AESCTRDRBG operation results are available
406      *   after the function returns.
407      */
408     AESCTRDRBG_RETURN_BEHAVIOR_BLOCKING = AESCTR_RETURN_BEHAVIOR_BLOCKING,
409     /*!< The function call will continuously poll a flag while AESCTRDRBG
410      *   operation goes on in the background. AESCTRDRBG operation results
411      *   are available after the function returns.
412      */
413     AESCTRDRBG_RETURN_BEHAVIOR_POLLING  = AESCTR_RETURN_BEHAVIOR_POLLING,
414 } AESCTRDRBG_ReturnBehavior;
415 
416 /*!
417  *  @brief AESCTRDRBG Global configuration
418  *
419  *  The #AESCTRDRBG_Config structure contains a set of pointers used to characterize
420  *  the AESCTRDRBG driver implementation.
421  *
422  *  This structure needs to be defined before calling #AESCTRDRBG_init() and it must
423  *  not be changed thereafter.
424  *
425  *  @sa     #AESCTRDRBG_init()
426  */
427 typedef AESCommon_Config AESCTRDRBG_Config;
428 
429 /*!
430  *  @brief  A handle that is returned from an #AESCTRDRBG_open() call.
431  */
432 typedef AESCTRDRBG_Config *AESCTRDRBG_Handle;
433 
434 /*!
435  *  @brief  AESCTRDRBG Parameters
436  *
437  *  AESCTRDRBG Parameters are used to with the #AESCTRDRBG_open() call. Default values for
438  *  these parameters are set using #AESCTRDRBG_Params_init().
439  *
440  *  @sa     #AESCTRDRBG_Params_init()
441  */
442 typedef struct
443 {
444     AESCTRDRBG_AES_KEY_LENGTH keyLength;      /*!< Length of the internal AES key
445                                                *   of the driver instance.
446                                                */
447     uint32_t reseedInterval;                  /*!< Number of random number generation
448                                                *   requests before the application is
449                                                *   required to reseed the driver.
450                                                */
451     const void *seed;                         /*!< Entropy used to seed the internal
452                                                *   state of the driver. Must be one of
453                                                *   #AESCTRDRBG_SEED_LENGTH long depending
454                                                *   on \c keyLength.
455                                                */
456     const void *personalizationData;          /*!< Optional non-secret personalization
457                                                *   data to mix into the driver's internal
458                                                *   state.
459                                                */
460     size_t personalizationDataLength;         /*!< Length of the optional
461                                                *   \c personalizationData. Must satisfy
462                                                *   0 <= \c personalizationDataLength <= seed length.
463                                                */
464     AESCTRDRBG_ReturnBehavior returnBehavior; /*!< Return behavior of the driver instance.
465                                                *   #AESCTRDRBG_RETURN_BEHAVIOR_POLLING is
466                                                *   strongly recommended unless requests
467                                                *   for > 500 bytes with AES-256 or
468                                                *   1250 bytes for AES-128 will be common
469                                                *   use cases for this driver instance.
470                                                */
471     void *custom;                             /*!< Custom argument used by driver
472                                                *   implementation
473                                                */
474 } AESCTRDRBG_Params;
475 
476 /*!
477  *  @brief Default #AESCTRDRBG_Params structure
478  *
479  *  @sa     #AESCTRDRBG_Params_init()
480  */
481 extern const AESCTRDRBG_Params AESCTRDRBG_defaultParams;
482 
483 /*!
484  *  @brief  This function initializes the AESCTRDRBG driver.
485  *
486  *  @pre    The #AESCTRDRBG_Config structure must exist and be persistent before this
487  *          function can be called. This function must also be called before
488  *          any other AESCTRDRBG driver APIs. This function call does not modify any
489  *          peripheral registers.
490  */
491 void AESCTRDRBG_init(void);
492 
493 /*!
494  *  @brief  Function to initialize the #AESCTRDRBG_Params struct to its defaults
495  *
496  *  @param  [out]    params  Pointer to #AESCTRDRBG_Params structure for
497  *                           initialization
498  */
499 void AESCTRDRBG_Params_init(AESCTRDRBG_Params *params);
500 
501 /*!
502  *  @brief  This function opens a given AESCTRDRBG instance.
503  *
504  *  @pre    AESCTRDRBG controller has been initialized using #AESCTRDRBG_init()
505  *
506  *  @param  [in]    index   Logical peripheral number for the AESCTRDRBG indexed into
507  *                          the #AESCTRDRBG_Config table
508  *
509  *  @param  [in]    params  Pointer to an parameter block, if NULL it will use
510  *                          default values.
511  *
512  *  @return An #AESCTRDRBG_Handle on success or a NULL on an error or if it has
513  *          been opened already.
514  *
515  *  @sa     #AESCTRDRBG_init()
516  *  @sa     #AESCTRDRBG_close()
517  */
518 AESCTRDRBG_Handle AESCTRDRBG_open(uint_least8_t index, const AESCTRDRBG_Params *params);
519 
520 /*!
521  *  @brief  Function to close an AESCTRDRBG instance specified by the #AESCTRDRBG_Handle
522  *
523  *  @pre    #AESCTRDRBG_open() has to be called first.
524  *
525  *  @param  [in]    handle  An #AESCTRDRBG_Handle returned from #AESCTRDRBG_open()
526  *
527  *  @sa     #AESCTRDRBG_open()
528  */
529 void AESCTRDRBG_close(AESCTRDRBG_Handle handle);
530 
531 /*!
532  *  @brief  Generates the requested number of random bytes.
533  *
534  *  @deprecated This function has been replaced by a pair of new functions.
535  *              See #AESCTRDRBG_generateKey() and #AESCTRDRBG_getRandomBytes().
536  *
537  *  @param  [in]        handle      An #AESCTRDRBG_Handle returned from #AESCTRDRBG_open()
538  *
539  *  @param  [in,out]    randomBytes Pointer to a \c CryptoKey object that should be already initialized
540  *                                  to hold a plaintext key, provided with the length and the address
541  *                                  of the plaintext key-material where the generated random bytes will
542  *                                  be populated. Some implementations may require key-material to be
543  *                                  word-aligned.
544  *
545  *  @retval #AESCTRDRBG_STATUS_SUCCESS              Random bytes generated.
546  *  @retval #AESCTRDRBG_STATUS_ERROR                Generic driver error. Random bytes not generated.
547  *  @retval #AESCTRDRBG_STATUS_RESOURCE_UNAVAILABLE The required hardware was unavailable. Random bytes not generated.
548  *  @retval #AESCTRDRBG_STATUS_RESEED_REQUIRED      Reseed counter >= reseed limit. Reseed required. Random bytes not
549  * generated.
550  *  @retval #AESCTRDRBG_STATUS_UNINSTANTIATED       DRBG uninstantiated. Close and reopen the instance with fresh seed.
551  * Random bytes not generated.
552  *  @retval #AESCTRDRBG_STATUS_UNALIGNED_IO_NOT_SUPPORTED  Pointer to \c randomBytes key material must be word-aligned.
553  */
554 int_fast16_t AESCTRDRBG_getBytes(AESCTRDRBG_Handle handle, CryptoKey *randomBytes);
555 
556 /*!
557  *  @brief  Populates the provided \c CryptoKey object's plaintext key-material with random bytes.
558  *
559  *  @note This function replaces #AESCTRDRBG_getBytes().
560  *        See #AESCTRDRBG_getRandomBytes() to output random bytes to an array instead.
561  *
562  *  @param  [in]        handle      An #AESCTRDRBG_Handle returned from #AESCTRDRBG_open()
563  *
564  *  @param  [in,out]    randomKey   Pointer to a \c CryptoKey object that should be already initialized
565  *                                  to hold a plaintext key, provided with the length and the address
566  *                                  of the plaintext key-material where the generated random bytes will
567  *                                  be populated. Some implementations may require key-material to be
568  *                                  word-aligned.
569  *
570  *  @retval #AESCTRDRBG_STATUS_SUCCESS              Key-material generated.
571  *  @retval #AESCTRDRBG_STATUS_ERROR                Generic driver error. Key-material not generated.
572  *  @retval #AESCTRDRBG_STATUS_RESOURCE_UNAVAILABLE The required hardware was unavailable. Key-material not generated.
573  *  @retval #AESCTRDRBG_STATUS_RESEED_REQUIRED      Reseed counter >= reseed limit. Reseed required. Key-material not
574  * generated.
575  *  @retval #AESCTRDRBG_STATUS_UNINSTANTIATED       DRBG uninstantiated. Close and reopen the instance with fresh seed.
576  * Key-material not generated.
577  *  @retval #AESCTRDRBG_STATUS_UNALIGNED_IO_NOT_SUPPORTED  Pointer to \c randomKey key material must be word-aligned.
578  */
579 int_fast16_t AESCTRDRBG_generateKey(AESCTRDRBG_Handle handle, CryptoKey *randomKey);
580 
581 /*!
582  *  @brief  Generates the requested number of random bytes and outputs to the given array.
583  *
584  *  @attention This function should not be confused with the deprecated #AESCTRDRBG_getBytes().
585  *             #AESCTRDRBG_getBytes() output random bytes to a \c CryptoKey while this new
586  *             function outputs random bytes to an array.
587  *
588  *  @note See #AESCTRDRBG_generateKey() to output random bytes to a \c CryptoKey instead.
589  *
590  *  @param  [in]        handle          An #AESCTRDRBG_Handle returned from #AESCTRDRBG_open()
591  *
592  *  @param  [out]       randomBytes     A pointer to an array that stores the random bytes
593  *                                      output by this function. Some implementations may
594  *                                      require this array to be word-aligned.
595  *
596  *  @param  [in]        randomBytesSize The size in bytes of the random data required.
597  *
598  *  @retval #AESCTRDRBG_STATUS_SUCCESS              Random bytes generated.
599  *  @retval #AESCTRDRBG_STATUS_ERROR                Generic driver error. Random bytes not generated.
600  *  @retval #AESCTRDRBG_STATUS_RESOURCE_UNAVAILABLE The required hardware was unavailable. Random bytes not generated.
601  *  @retval #AESCTRDRBG_STATUS_RESEED_REQUIRED      Reseed counter >= reseed limit. Reseed required. Random bytes not
602  * generated.
603  *  @retval #AESCTRDRBG_STATUS_UNINSTANTIATED       DRBG uninstantiated. Close and reopen the instance with fresh seed.
604  * Random bytes not generated.
605  *  @retval #AESCTRDRBG_STATUS_UNALIGNED_IO_NOT_SUPPORTED  Pointer to \c randomBytes array must be word-aligned.
606  */
607 int_fast16_t AESCTRDRBG_getRandomBytes(AESCTRDRBG_Handle handle, void *randomBytes, size_t randomBytesSize);
608 
609 /*!
610  *  @brief  Reseed an AESCTRDRBG instance.
611  *
612  *  @param  [in]    handle                  An #AESCTRDRBG_Handle returned from #AESCTRDRBG_open()
613  *
614  *  @param  [in]    seed                    Entropy to mix into the AESCTRDRBG instance state
615  *
616  *  @param  [in]    additionalData          Optional non-secret additional data to mix into the
617  *                                          instance state.
618  *
619  *  @param  [in]    additionalDataLength    Length of the optional additional data.
620  *                                          0 <= \c additionalDataLength <= seed length of the
621  *                                          instance.
622  *
623  *  @retval #AESCTRDRBG_STATUS_SUCCESS                  Reseed successful. Reseed counter reset.
624  *  @retval #AESCTRDRBG_STATUS_ERROR                    Reseed not successful. Reseed counter not reset.
625  *  @retval #AESCTRDRBG_STATUS_RESOURCE_UNAVAILABLE     The requires hardware was unavailable.
626  *  @retval #AESCTRDRBG_STATUS_UNINSTANTIATED           DRBG uninstantiated. Close and reopen the instance with fresh
627  * seed.
628  */
629 int_fast16_t AESCTRDRBG_reseed(AESCTRDRBG_Handle handle,
630                                const void *seed,
631                                const void *additionalData,
632                                size_t additionalDataLength);
633 
634 /**
635  *  @brief  Constructs a new AESCTRDRBG object
636  *
637  *  Unlike #AESCTRDRBG_open(), #AESCTRDRBG_construct() does not require the hwAttrs and
638  *  object to be allocated in a #AESCTRDRBG_Config array that is indexed into.
639  *  Instead, the #AESCTRDRBG_Config, hwAttrs, and object can be allocated at any
640  *  location. This allows for relatively simple run-time allocation of temporary
641  *  driver instances on the stack or the heap.
642  *  The drawback is that this makes it more difficult to write device-agnostic
643  *  code. If you use an ifdef with DeviceFamily, you can choose the correct
644  *  object and hwAttrs to allocate. That compilation unit will be tied to the
645  *  device it was compiled for at this point. To change devices, recompilation
646  *  of the application with a different DeviceFamily setting is necessary.
647  *
648  *  @param  config #AESCTRDRBG_Config describing the location of the object and hwAttrs.
649  *
650  *  @param  params #AESCTRDRBG_Params to configure the driver instance.
651  *
652  *  @return        Returns an #AESCTRDRBG_Handle on success or NULL on failure.
653  *
654  *  @pre    The object struct @c config points to must be zeroed out prior to
655  *          calling this function. Otherwise, unexpected behavior may ensue.
656  */
657 AESCTRDRBG_Handle AESCTRDRBG_construct(AESCTRDRBG_Config *config, const AESCTRDRBG_Params *params);
658 
659 #ifdef __cplusplus
660 }
661 #endif
662 
663 #endif /* ti_drivers_AESCTRDRBG__include */
664