1 /*
2  * Copyright (c) 2018-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       AESCTR.h
34  *
35  * @brief      AESCTR driver header
36  *
37  * @anchor ti_drivers_AESCTR_Overview
38  * <h3> Overview </h3>
39  * The Counter (CTR) mode of operation is a generic block cipher mode of operation
40  * that can be used with any block cipher including AES which is used in this
41  * implementation.
42  *
43  * CTR mode encrypts and decrypts messages. It is not required for the message
44  * length to be evenly divisible by the cipher block size. This also means
45  * that padding the message is not required.
46  *
47  * <h3> Operation </h3>
48  * CTR encryption and decryption perform the following steps:
49  *     -# Set the counter value to the initial counter value
50  *     -# Encrypt the counter value under the symmetric key
51  *     -# XOR the encrypted counter value with the input block (plaintext or ciphertext)
52  *     -# Increment the counter value. Interpret the byte array as a big-endian number.
53  *     -# Repeat steps 2 to 4 until the input is completely processed. If the
54  *        input is not evenly divisible by the block size, XOR the last
55  *        (u = input length % block size) input bytes with the most significant
56  *        u bytes of the last encrypted counter value.
57  *
58  * CTR performs the same steps regardless of whether it is used to
59  * encrypt or decrypt a message. The input merely changes.
60  *
61  * <h3> Choosing Initial Counter Values </h3>
62  * CTR requires that each counter value used to encrypt a block of a message
63  * is unique for each key used. If this requirement is not kept, the
64  * confidentiality of that message block may be compromised.
65  *
66  * There are two general strategies when choosing the initial counter value
67  * of a CTR operation to ensure this requirement holds.
68  *
69  * The first is to choose an initial counter value for the first message
70  * and increment the initial counter value for a subsequent message by
71  * by message length % block length (16-bytes for AES). This effectively
72  * turns a sequence of messages into one long message. If 0 is chosen
73  * as the initial counter value, up to 2^128 - 1 blocks may be encrypted before
74  * key rotation is mandatory.
75  *
76  * The second is to split the initial counter value into a nonce and
77  * counter section. The nonce of length n bits must be unique per message.
78  * This allows for up to 2^n - 1 messages to be encrypted before
79  * key rotation is required. The counter section of length c is incremented
80  * as usual. This limits messages to a length of at most 2^c - 1 blocks.
81  * n and c must be chosen such that n + c = block length in bits
82  * (128 bits for AES) holds.
83  *
84  * @anchor ti_drivers_AESCTR_Usage
85  * <h3> Usage </h3>
86  * <h4> Before starting a CTR operation </h4>
87  *
88  * Before starting a CTR operation, the application must do the following:
89  *     - Call #AESCTR_init() to initialize the driver
90  *     - Call #AESCTR_Params_init() to initialize the #AESCTR_Params to default values.
91  *     - Modify the #AESCTR_Params as desired
92  *     - Call #AESCTR_open() to open an instance of the driver
93  *     - Initialize a CryptoKey. These opaque data structures are representations
94  *       of keying material and its storage. Depending on how the keying material
95  *       is stored (RAM or flash, key store), the CryptoKey must be
96  *       initialized differently. The AESCTR API can handle all types of CryptoKey.
97  *       However, not all device-specific implementations support all types of CryptoKey.
98  *       Devices without a key store will not support CryptoKeys with keying material
99  *       stored in a key store for example.
100  *       All devices support plaintext CryptoKeys.
101  *     - Initialize a single-step AESCTR operation using #AESCTR_OneStepOperation_init()
102  *       which is equivalent to the deprecated #AESCTR_Operation_init(). If it's
103  *       a segmented AESCTR operation, use #AESCTR_SegmentedOperation_init() instead.
104  *       Then set all the fields of the one-step or segmented operation struct accordingly.
105  *
106  * <h4> Starting a CTR operation </h4>
107  *
108  * The AESCTR_oneStepEncrypt() and AESCTR_oneStepDecrypt() functions perform a CTR operation
109  * in a single call.
110  *
111  * <h4> After the CTR operation completes </h4>
112  *
113  * After the CTR operation completes, the application should either start
114  * another operation or close the driver by calling #AESCTR_close().
115  *
116  * @anchor ti_drivers_AESCTR_Synopsis
117  * ## Synopsis
118  *
119  * @anchor ti_drivers_AESCTR_Synopsis_Code
120  * @code
121  *
122  * // Import AESCTR Driver definitions
123  * #include <ti/drivers/AESCTR.h>
124  *
125  * // Define name for AESCTR channel index
126  * #define AESCTR_INSTANCE 0
127  *
128  * AESCTR_init();
129  *
130  * handle = AESCTR_open(AESCTR_INSTANCE, NULL);
131  *
132  * // Initialize symmetric key
133  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
134  *
135  * // Set up AESCTR_Operation
136  * AESCTR_OneStepOperation_init(&operation);
137  * operation.key               = &cryptoKey;
138  * operation.input             = plaintext;
139  * operation.output            = ciphertext;
140  * operation.inputLength       = sizeof(plaintext);
141  * operation.initialCounter    = initialCounter;
142  *
143  * encryptionResult = AESCTR_oneStepEncrypt(handle, &operation);
144  *
145  * AESCTR_close(handle);
146  * @endcode
147  *
148  * @anchor ti_drivers_AESCTR_Examples
149  * <h4> Examples </h4>
150  *
151  * <h5> One step CTR encryption with plaintext CryptoKey in blocking return mode </h5>
152  * @code
153  *
154  * #include <ti/drivers/AESCTR.h>
155  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
156  *
157  * ...
158  *
159  *     AESCTR_Handle handle;
160  *     CryptoKey cryptoKey;
161  *     int_fast16_t encryptionResult;
162  *
163  *     // For example purposes only. Generate IVs in a non-static way in practice.
164  *     // Test vector from NIST SP 800-38A
165  *     uint8_t initialCounter[16] =    {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
166  *                                      0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
167  *     uint8_t plaintext[64] =         {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
168  *                                      0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
169  *                                      0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
170  *                                      0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
171  *                                      0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
172  *                                      0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
173  *                                      0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
174  *                                      0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
175  *     uint8_t ciphertext[sizeof(plaintext)];
176  *     uint8_t keyingMaterial[16] =    {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
177  *                                      0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
178  *
179  *     handle = AESCTR_open(0, NULL);
180  *
181  *     if (handle == NULL) {
182  *         // handle error
183  *         while(1);
184  *     }
185  *
186  *     CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
187  *
188  *     AESCTR_OneStepOperation operation;
189  *     AESCTR_OneStepOperation_init(&operation);
190  *
191  *     operation.key               = &cryptoKey;
192  *     operation.input             = plaintext;
193  *     operation.output            = ciphertext;
194  *     operation.inputLength       = sizeof(plaintext);
195  *     operation.initialCounter    = initialCounter;
196  *
197  *     encryptionResult = AESCTR_oneStepEncrypt(handle, &operation);
198  *
199  *     if (encryptionResult != AESCTR_STATUS_SUCCESS) {
200  *         // handle error
201  *         while(1);
202  *     }
203  *
204  *     // The ciphertext should be the following after the encryption operation:
205  *     // 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
206  *     // 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
207  *     // 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
208  *     // 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
209  *     // 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
210  *     // 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
211  *     // 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
212  *     // 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
213  *
214  *     AESCTR_close(handle);
215  *
216  * @endcode
217  *
218  * <h4> The following code snippet is for CC27XX devices only and leverages the HSM which is a seperate Hardware
219  * Accelerator </h4>
220  *
221  * <h5> One step CTR encryption with plaintext CryptoKey in blocking return mode using the HSM accelerator </h5>
222  * @code
223  *
224  * #include <ti/drivers/AESCTR.h>
225  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
226  *
227  * ...
228  *
229  *     AESCTR_Handle handle;
230  *     CryptoKey cryptoKey;
231  *     int_fast16_t encryptionResult;
232  *
233  *     // For example purposes only. Generate IVs in a non-static way in practice.
234  *     // Test vector from NIST SP 800-38A
235  *     uint8_t initialCounter[16] =    {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
236  *                                      0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
237  *     uint8_t plaintext[64] =         {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
238  *                                      0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
239  *                                      0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
240  *                                      0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
241  *                                      0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
242  *                                      0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
243  *                                      0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
244  *                                      0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
245  *     uint8_t ciphertext[sizeof(plaintext)];
246  *     uint8_t keyingMaterial[16] =    {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
247  *                                      0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
248  *
249  *     handle = AESCTR_open(0, NULL);
250  *
251  *     if (handle == NULL) {
252  *         // handle error
253  *         while(1);
254  *     }
255  *
256  *     CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
257  *
258  *     AESCTR_OneStepOperation operation;
259  *     AESCTR_OneStepOperation_init(&operation);
260  *
261  *     operation.key               = &cryptoKey;
262  *     operation.input             = plaintext;
263  *     operation.output            = ciphertext;
264  *     operation.inputLength       = sizeof(plaintext);
265  *     operation.initialCounter    = initialCounter;
266  *
267  *     encryptionResult = AESCTR_oneStepEncrypt(handle, &operation);
268  *
269  *     if (encryptionResult != AESCTR_STATUS_SUCCESS) {
270  *         // handle error
271  *         while(1);
272  *     }
273  *
274  *     // The ciphertext should be the following after the encryption operation:
275  *     // 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
276  *     // 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
277  *     // 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
278  *     // 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
279  *     // 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
280  *     // 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
281  *     // 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
282  *     // 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
283  *
284  *     AESCTR_close(handle);
285  *
286  * @endcode
287  *
288  * <h5> One step CTR decryption with plaintext CryptoKey in callback return mode </h5>
289  * @code
290  *
291  * #include <ti/drivers/AESCTR.h>
292  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
293  *
294  * ...
295  *
296  *
297  * void ctrCallback(AESCTR_Handle handle,
298  *                  int_fast16_t returnValue,
299  *                  AESCTR_OperationUnion *operation,
300  *                  AESCTR_OperationType operationType) {
301  *
302  *     if (returnValue != AESCTR_STATUS_SUCCESS) {
303  *         // handle error
304  *         while(1);
305  *     }
306  * }
307  * AESCTR_Operation operation;
308  *
309  * void ctrStartFunction(void) {
310  *     uint8_t initialCounter[16] =  {0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
311  *                                    0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01};
312  *     uint8_t ciphertext[] =        {0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
313  *                                    0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
314  *                                    0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
315  *                                    0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
316  *                                    0x25, 0xB2, 0x07, 0x2F};
317  *     uint8_t keyingMaterial[] =    {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
318  *                                    0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
319  *     uint8_t plaintext[sizeof(ciphertext)];
320  *
321  *     AESCTR_Handle handle;
322  *     AESCTR_Params params;
323  *     CryptoKey cryptoKey;
324  *     int_fast16_t decryptionResult;
325  *
326  *     AESCTR_OneStepOperation operation;
327  *
328  *     AESCTR_Params_init(&params);
329  *     params.returnBehavior = AESCTR_RETURN_BEHAVIOR_CALLBACK;
330  *     params.callbackFxn = ctrCallback;
331  *
332  *     handle = AESCTR_open(0, &params);
333  *
334  *     if (handle == NULL) {
335  *         // handle error
336  *         while(1);
337  *     }
338  *
339  *     CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
340  *
341  *     AESCTR_OneStepOperation_init(&operation); // Optional as all struct members will be set before use.
342  *
343  *     operation.key               = &cryptoKey;
344  *     operation.input             = ciphertext;
345  *     operation.output            = plaintext;
346  *     operation.inputLength       = sizeof(ciphertext);
347  *     operation.initialCounter    = initialCounter;
348  *
349  *     decryptionResult = AESCTR_oneStepDecrypt(handle, &operation);
350  *
351  *     if (decryptionResult != AESCTR_STATUS_SUCCESS) {
352  *         // handle error
353  *         while(1);
354  *     }
355  *
356  *     // do other things while CTR operation completes in the background
357  *
358  *     // After the operation completes and the callback is invoked, the resultant
359  *     // plaintext should be:
360  *     // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
361  *     // 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
362  *     // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
363  *     // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
364  *     // 0x20, 0x21, 0x22, 0x23
365  *
366  *     AESCTR_close(handle);
367  * }
368  *
369  * @endcode
370  *
371  *  <h5> Multi-step AES CTR encrypt with plaintext CryptoKey in polling return mode </h5>
372  *  @code
373  *
374  *  #include <ti/drivers/AESCTR.h>
375  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
376  *
377  *  #define AES_BLOCK_SIZE 16  // bytes
378  *  ...
379  *
380  *  AESCTR_Params params;
381  *  AESCTR_Handle handle;
382  *  CryptoKey cryptoKey;
383  *  int_fast16_t retVal;
384  *
385  *  // For example purposes only.
386  *  uint8_t plaintext[36] =    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
387  *                              0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
388  *                              0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
389  *                              0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
390  *                              0x20, 0x21, 0x22, 0x23};
391  *  uint8_t initialCounter[] = {0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
392  *                              0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01};
393  *  uint8_t keyingMaterial[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
394  *                              0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
395  *  uint8_t ciphertext[sizeof(plaintext)];
396  *
397  *  AESCTR_Params_init(&params)
398  *  params.returnBehavior = AESCTR_RETURN_BEHAVIOR_POLLING;
399  *
400  *  handle = AESCTR_open(0, &params);
401  *
402  *  if (handle == NULL) {
403  *      // handle error
404  *  }
405  *
406  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
407  *
408  *  AESCTR_SegmentedOperation operation;
409  *  AESCTR_SegmentedOperation_init(&operation); // Optional as all struct members will be set before use.
410  *
411  *  retVal = AESCTR_setupEncrypt(handle, &cryptoKey, initialCounter);
412  *
413  *  if (retVal != AESCTR_STATUS_SUCCESS) {
414  *      // handle error
415  *  }
416  *
417  *  operation.input        = plaintext;
418  *  operation.inputLength  = AES_BLOCK_SIZE;  // Only block multiple lengths are permitted when adding data.
419  *  operation.output       = ciphertext;
420  *
421  *  retVal = AESCTR_addData(handle, &operation);
422  *
423  *  if (retVal != AESCTR_STATUS_SUCCESS) {
424  *      // handle error
425  *  }
426  *
427  *  operation.input        = plaintext + AES_BLOCK_SIZE;
428  *  operation.inputLength  = sizeof(plaintext) - AES_BLOCK_SIZE;  // Non-block multiple length permitted during
429  * finalization. operation.output       = ciphertext + AES_BLOCK_SIZE;
430  *
431  *  retVal = AESCTR_finalize(handle, &operation);
432  *
433  *  if (retVal != AESCTR_STATUS_SUCCESS) {
434  *      // handle error
435  *  }
436  *
437  *  // Upon successful return, the resulting ciphertext should be:
438  *  //   0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
439  *  //   0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
440  *  //   0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
441  *  //   0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
442  *  //   0x25, 0xB2, 0x07, 0x2F
443  *
444  *  AESCTR_close(handle);
445  *
446  *  @endcode
447  */
448 
449 #ifndef ti_drivers_AESCTR__include
450 #define ti_drivers_AESCTR__include
451 
452 #include <stddef.h>
453 #include <stdint.h>
454 
455 #include <ti/drivers/AESCommon.h>
456 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
457 
458 #ifdef __cplusplus
459 extern "C" {
460 #endif
461 
462 /*!
463  * Common AESCTR status code reservation offset.
464  * AESCTR driver implementations should offset status codes with
465  * #AESCTR_STATUS_RESERVED growing negatively.
466  *
467  * Example implementation specific status codes:
468  * @code
469  * #define AESCTRXYZ_STATUS_ERROR0    AESCTR_STATUS_RESERVED - 0
470  * #define AESCTRXYZ_STATUS_ERROR1    AESCTR_STATUS_RESERVED - 1
471  * #define AESCTRXYZ_STATUS_ERROR2    AESCTR_STATUS_RESERVED - 2
472  * @endcode
473  */
474 #define AESCTR_STATUS_RESERVED AES_STATUS_RESERVED
475 
476 /*!
477  * @brief   Successful status code.
478  *
479  * Functions return #AESCTR_STATUS_SUCCESS if the function was executed
480  * successfully.
481  */
482 #define AESCTR_STATUS_SUCCESS AES_STATUS_SUCCESS
483 
484 /*!
485  * @brief   Generic error status code.
486  *
487  * Functions return #AESCTR_STATUS_ERROR if the function was not executed
488  * successfully and no more pertinent error code could be returned.
489  */
490 #define AESCTR_STATUS_ERROR AES_STATUS_ERROR
491 
492 /*!
493  * @brief   An error status code returned if the hardware or software resource
494  * is currently unavailable.
495  *
496  * AESCTR driver implementations may have hardware or software limitations on how
497  * many clients can simultaneously perform operations. This status code is returned
498  * if the mutual exclusion mechanism signals that an operation cannot currently be performed.
499  */
500 #define AESCTR_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
501 
502 /*!
503  *  @brief  The ongoing operation was canceled.
504  */
505 #define AESCTR_STATUS_CANCELED AES_STATUS_CANCELED
506 
507 /*!
508  * @brief   The operation requested is not supported.
509  */
510 #define AESCTR_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
511 
512 /*!
513  *  @brief  The operation tried to load a key from the keystore using an invalid key ID.
514  */
515 #define AESCTR_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
516 
517 /*!
518  *  @brief  The key store module returned a generic error. See key store documentation
519  *  for additional details.
520  */
521 #define AESCTR_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
522 
523 /*!
524  * @brief   The operation does not support non-word-aligned input and/or output.
525  *
526  * AESCTR driver implementations may have restrictions on the alignment of
527  * input/output data due to performance limitations of the hardware.
528  */
529 #define AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
530 
531 /*!
532  * @brief   The way in which CTR function calls return after performing an
533  * encryption or decryption operation.
534  *
535  * Not all CTR operations exhibit the specified return behavior. Functions that do not
536  * require significant computation and cannot offload that computation to a background thread
537  * behave like regular functions. Which functions exhibit the specified return behavior is not
538  * implementation dependent. Specifically, a software-backed implementation run on the same
539  * CPU as the application will emulate the return behavior while not actually offloading
540  * the computation to the background thread.
541  *
542  * AESCTR functions exhibiting the specified return behavior have restrictions on the
543  * context from which they may be called.
544  *
545  * |                                | Task  | Hwi   | Swi   |
546  * |--------------------------------|-------|-------|-------|
547  * |AESCTR_RETURN_BEHAVIOR_CALLBACK | X     | X     | X     |
548  * |AESCTR_RETURN_BEHAVIOR_BLOCKING | X     |       |       |
549  * |AESCTR_RETURN_BEHAVIOR_POLLING  | X     | X     | X     |
550  *
551  */
552 typedef enum
553 {
554     AESCTR_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK,
555     /*!< The function call will return immediately while the
556      *   CTR operation goes on in the background. The registered
557      *   callback function is called after the operation completes.
558      *   The context the callback function is called (task, HWI, SWI)
559      *   is implementation-dependent.
560      */
561     AESCTR_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING,
562     /*!< The function call will block while the CTR operation goes
563      *   on in the background. CTR operation results are available
564      *   after the function returns.
565      */
566     AESCTR_RETURN_BEHAVIOR_POLLING  = AES_RETURN_BEHAVIOR_POLLING,
567     /*!< The function call will continuously poll a flag while CTR
568      *   operation goes on in the background. CTR operation results
569      *   are available after the function returns.
570      */
571 } AESCTR_ReturnBehavior;
572 
573 /*!
574  *  @brief  Struct containing the parameters required for encrypting/decrypting
575  *          a message using a one-step operation.
576  *
577  *  The driver may access it at any point during the operation. It must remain
578  *  in scope for the entire duration of the operation.
579  */
580 typedef struct
581 {
582     const CryptoKey *key;          /*!< Pointer to a previously initialized CryptoKey. */
583     const uint8_t *input;          /*!<
584                                     *   - Encryption: The plaintext buffer to be
585                                     *     encrypted in the CTR operation.
586                                     *   - Decryption: The ciphertext to be decrypted.
587                                     */
588     uint8_t *output;               /*!<
589                                     *   - Encryption: The output ciphertext buffer that
590                                     *     the encrypted plaintext is copied to.
591                                     *   - Decryption: The plaintext derived from the
592                                     *     decrypted ciphertext is copied here.
593                                     *   Size of the output buffer must be greater than
594                                     *   or equal to the inputLength.
595                                     */
596     const uint8_t *initialCounter; /*!< A buffer containing an initial counter. Under
597                                     *   the same key, each counter value may only be
598                                     *   used to encrypt or decrypt a single input
599                                     *   block. If NULL, zero will be used for the
600                                     *   initial counter value. The buffer's size must
601                                     *   be at least 16-bytes.
602                                     */
603     size_t inputLength;            /*!< Length of the input in bytes. An equal number
604                                     *   of bytes will be output by the operation.
605                                     *   Max length supported may be limited depending on
606                                     *   the return behavior.
607                                     */
608 } AESCTR_OneStepOperation;
609 
610 /*!
611  *  @brief  Struct containing the parameters required for encrypting/decrypting
612  *          a message using a segmented operation.  This struct must be updated
613  *          for each "add data" and "finalize" step. Modifying the structure and any buffers that
614  *          it points to while an operation is in progress is prohibited.
615  *
616  *  The driver may access it at any point during the operation. It must remain
617  *  in scope for the entire duration of the operation.
618  */
619 typedef struct
620 {
621     const uint8_t *input; /*!<
622                            *   - Encryption: The plaintext buffer to be
623                            *     encrypted in the CTR operation.
624                            *   - Decryption: The ciphertext to be decrypted.
625                            */
626     uint8_t *output;      /*!<
627                            *   - Encryption: The output ciphertext buffer that
628                            *     the encrypted plaintext is copied to.
629                            *   - Decryption: The plaintext derived from the
630                            *     decrypted ciphertext is copied here.
631                            *   Size of the output buffer must be greater than
632                            *   or equal to the inputLength.
633                            */
634     size_t inputLength;   /*!< Length of the input in bytes. An equal number
635                            *   of bytes will be output by the operation. Must
636                            *   be a non-zero multiple of block size (16-bytes) when
637                            *   calling #AESCTR_addData(). May be zero when calling
638                            *   #AESCTR_finalize() to finalize a segmented
639                            *   operation without additional data.
640                            */
641 } AESCTR_SegmentedOperation;
642 
643 /**
644  * @deprecated
645  * Define a typedef for deprecated operation AESCTR_Operation.
646  * Existing code should be refactored to use AESCTR_OneStepOperation.
647  * This reference may be removed at some point in the future.
648  */
649 typedef AESCTR_OneStepOperation AESCTR_Operation;
650 
651 /*!
652  *  @brief Union containing a reference to a one-step and segmented operation
653  *         structure.
654  */
655 typedef union
656 {
657     AESCTR_OneStepOperation oneStepOperation;     /* One-step operation element of the operation union */
658     AESCTR_SegmentedOperation segmentedOperation; /* Segmented operation element of the operation union */
659 } AESCTR_OperationUnion;
660 
661 /*!
662  *  @brief  Enum for the direction of the CTR operation.
663  */
664 typedef enum
665 {
666     AESCTR_MODE_ENCRYPT = 1,
667     AESCTR_MODE_DECRYPT = 2,
668 } AESCTR_Mode;
669 
670 /*!
671  *  @brief  Mask for the operation mode.
672  */
673 #define AESCTR_OP_MODE_MASK 0x0F
674 
675 /*!
676  *  @brief  Flag indicating a segmented operation.
677  */
678 #define AESCTR_OP_FLAG_SEGMENTED 0x10 /* bit 4 */
679 
680 /*!
681  *  @brief  Flag indicating a finalize operation.
682  */
683 #define AESCTR_OP_FLAG_FINALIZE 0x20 /* bit 5 */
684 
685 /*!
686  *  @brief  Mask for all valid operation flags.
687  */
688 #define AESCTR_OP_FLAGS_MASK (AESCTR_OP_FLAG_SEGMENTED | AESCTR_OP_FLAG_FINALIZE)
689 
690 /*!
691  *  @brief  Enum for the operation types supported by the driver.
692  */
693 typedef enum
694 {
695     AESCTR_OPERATION_TYPE_ENCRYPT           = AESCTR_MODE_ENCRYPT,
696     AESCTR_OPERATION_TYPE_DECRYPT           = AESCTR_MODE_DECRYPT,
697     AESCTR_OPERATION_TYPE_ENCRYPT_SEGMENTED = (AESCTR_MODE_ENCRYPT | AESCTR_OP_FLAG_SEGMENTED),
698     AESCTR_OPERATION_TYPE_DECRYPT_SEGMENTED = (AESCTR_MODE_DECRYPT | AESCTR_OP_FLAG_SEGMENTED),
699     AESCTR_OPERATION_TYPE_ENCRYPT_FINALIZE  = (AESCTR_MODE_ENCRYPT | AESCTR_OP_FLAG_FINALIZE),
700     AESCTR_OPERATION_TYPE_DECRYPT_FINALIZE  = (AESCTR_MODE_DECRYPT | AESCTR_OP_FLAG_FINALIZE),
701 } AESCTR_OperationType;
702 
703 /*!
704  *  @brief AESCTR Global configuration
705  *
706  *  The #AESCTR_Config structure contains a set of pointers used to characterize
707  *  the AESCTR driver implementation.
708  *
709  *  This structure needs to be defined before calling #AESCTR_init() and it must
710  *  not be changed thereafter.
711  *
712  *  @sa     #AESCTR_init()
713  */
714 typedef AESCommon_Config AESCTR_Config;
715 
716 /*!
717  *  @brief  A handle that is returned from an #AESCTR_open() call.
718  */
719 typedef AESCTR_Config *AESCTR_Handle;
720 
721 /*!
722  *  @brief  The definition of a callback function used by the AESCTR driver
723  *          when used in ::AESCTR_RETURN_BEHAVIOR_CALLBACK
724  *
725  *  @param  handle        Handle of the client that started the CTR operation.
726  *
727  *  @param  returnValue   The result of the CTR operation. May contain an error code.
728  *                        Informs the application of why the callback function was
729  *                        called.
730  *
731  *  @param  operation     Pointer to the operation union struct.
732  *
733  *  @param  operationType This parameter determines which operation the
734  *                        callback refers to.
735  */
736 typedef void (*AESCTR_CallbackFxn)(AESCTR_Handle handle,
737                                    int_fast16_t returnValue,
738                                    AESCTR_OperationUnion *operation,
739                                    AESCTR_OperationType operationType);
740 
741 /*!
742  *  @brief  CTR Parameters
743  *
744  *  CTR Parameters are for #AESCTR_open() and #AESCTR_construct() calls.
745  *  Default values for these parameters are set using #AESCTR_Params_init().
746  *
747  *  @sa     #AESCTR_Params_init()
748  */
749 typedef struct
750 {
751     AESCTR_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */
752     AESCTR_CallbackFxn callbackFxn;       /*!< Callback function pointer */
753     uint32_t timeout;                     /*!< Timeout before the driver returns an error in
754                                            *   ::AESCTR_RETURN_BEHAVIOR_BLOCKING
755                                            */
756     void *custom;                         /*!< Custom argument used by driver
757                                            *   implementation
758                                            */
759 } AESCTR_Params;
760 
761 /*!
762  *  @brief Default #AESCTR_Params structure
763  *
764  *  @sa     #AESCTR_Params_init()
765  */
766 extern const AESCTR_Params AESCTR_defaultParams;
767 
768 /*!
769  *  @brief  This function initializes the CTR module.
770  *
771  *  @pre    The AESCTR_config structure must exist and be persistent before this
772  *          function can be called. This function must also be called before
773  *          any other CTR driver APIs. This function call does not modify any
774  *          peripheral registers.
775  */
776 void AESCTR_init(void);
777 
778 /*!
779  *  @brief  Function to initialize the #AESCTR_Params struct to its defaults
780  *
781  *  @param  [in] params   Pointer to #AESCTR_Params structure for
782  *                        initialization
783  *
784  *  Defaults values are:
785  *      returnBehavior              = AESCTR_RETURN_BEHAVIOR_BLOCKING
786  *      callbackFxn                 = NULL
787  *      timeout                     = SemaphoreP_WAIT_FOREVER
788  *      custom                      = NULL
789  */
790 void AESCTR_Params_init(AESCTR_Params *params);
791 
792 /*!
793  *  @brief  This function opens a given AESCTR peripheral.
794  *
795  *  @pre    AESCTR driver has been initialized using #AESCTR_init()
796  *
797  *  @param  [in] index    Logical peripheral number for the CTR indexed into
798  *                        the AESCTR_config table
799  *
800  *  @param  [in] params   Pointer to a parameter block, if NULL it will use
801  *                        default values.
802  *
803  *  @return A #AESCTR_Handle on success or a NULL on an error or if it has
804  *          been opened already.
805  *
806  *  @sa     #AESCTR_init()
807  *  @sa     #AESCTR_close()
808  */
809 AESCTR_Handle AESCTR_open(uint_least8_t index, const AESCTR_Params *params);
810 
811 /*!
812  *  @brief  Function to close a CTR peripheral specified by the AESCTR handle
813  *
814  *  @pre    #AESCTR_open() or #AESCTR_construct()
815  *
816  *  @param  [in] handle         AESCTR handle
817  *
818  *  @sa     #AESCTR_open()
819  */
820 void AESCTR_close(AESCTR_Handle handle);
821 
822 /*!
823  *  @brief  Function to prepare a segmented AESCTR encryption operation.
824  *
825  *  This function sets up a segmented AESCTR encryption operation.
826  *
827  *  @pre    #AESCTR_open() or #AESCTR_construct()
828  *
829  *  @param  [in] handle          AESCTR handle
830  *  @param  [in] key             Pointer to a previously initialized CryptoKey
831  *  @param  [in] initialCounter  Pointer to initial counter value.
832  *                               The buffer size must be at least 16-bytes.
833  *                               If NULL, zero will be used for the initial counter value.
834  *
835  *  @retval #AESCTR_STATUS_SUCCESS    The operation succeeded.
836  *  @retval #AESCTR_STATUS_ERROR      The operation failed.
837  *
838  *  @post   #AESCTR_addData()
839  */
840 int_fast16_t AESCTR_setupEncrypt(AESCTR_Handle handle, const CryptoKey *key, const uint8_t *initialCounter);
841 
842 /*!
843  *  @brief  Function to prepare a segmented AESCTR decryption operation.
844  *
845  *  This function sets up a segmented AESCTR decryption operation.
846  *
847  *  @pre    #AESCTR_open() or #AESCTR_construct()
848  *
849  *  @param  [in] handle          AESCTR handle
850  *  @param  [in] key             Pointer to a previously initialized CryptoKey.
851  *  @param  [in] initialCounter  Pointer to initial counter value.
852  *                               The buffer size must be at least 16-bytes.
853  *                               If NULL, zero will be used for the initial counter value.
854  *
855  *  @retval #AESCTR_STATUS_SUCCESS    The operation succeeded.
856  *  @retval #AESCTR_STATUS_ERROR      The operation failed.
857  *
858  *  @post   #AESCTR_addData()
859  */
860 int_fast16_t AESCTR_setupDecrypt(AESCTR_Handle handle, const CryptoKey *key, const uint8_t *initialCounter);
861 
862 /*!
863  *  @brief  Encrypts or decrypts a segment of @a data with a @a length
864  *
865  *  The @a inputLength must be a non-zero multiple of the block size (16-bytes).
866  *  #AESCTR_addData() may be called an arbitrary number of times before
867  *  finishing the operation with #AESCTR_finalize().
868  *
869  *  This function blocks until the final stream bytes have been computed.
870  *  It returns immediately when ::AESCTR_RETURN_BEHAVIOR_CALLBACK is set.
871  *
872  *  @pre    A segmented operation has been setup using #AESCTR_setupEncrypt() or
873  *          #AESCTR_setupDecrypt()
874  *
875  *  @param  [in] handle         AESCTR handle
876  *  @param  [in] operation      Pointer to #AESCTR_SegmentedOperation structure
877  *                              containing the parameters required to perform the operation.
878  *
879  *  @retval #AESCTR_STATUS_SUCCESS    The operation succeeded.
880  *  @retval #AESCTR_STATUS_ERROR      The operation failed.
881  *  @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE     The required hardware
882  *                                                  resource was not available.
883  *                                                  Try again later.
884  *  @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
885  *
886  *  @post   #AESCTR_addData() or #AESCTR_finalize()
887  */
888 int_fast16_t AESCTR_addData(AESCTR_Handle handle, AESCTR_SegmentedOperation *operation);
889 
890 /*!
891  *  @brief  Finalize the AES operation. If new data needs to be added,
892  *          @c inputLength will be used to govern how many bytes will be written.
893  *
894  *  @note   To finalize an operation without any additional data,
895  *          set @c inputLength to zero. The input and output buffers
896  *          will not be used in this scenario.
897  *
898  *  @pre    #AESCTR_setupEncrypt() or #AESCTR_setupDecrypt()
899  *  @pre    #AESCTR_addData()
900  *
901  *  @param  [in] handle         AESCTR handle
902  *  @param  [in] operation      Pointer to #AESCTR_SegmentedOperation structure
903  *                              containing the parameters required to perform the operation.
904  *
905  *  @retval #AESCTR_STATUS_SUCCESS    In ::AESCTR_RETURN_BEHAVIOR_BLOCKING and
906  *                                    ::AESCTR_RETURN_BEHAVIOR_POLLING, this means the CTR
907  *                                    was generated successfully. In ::AESCTR_RETURN_BEHAVIOR_CALLBACK,
908  *                                    this means the operation started successfully.
909  *  @retval #AESCTR_STATUS_ERROR      The operation failed.
910  *  @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE     The required hardware
911  *                                                  resource was not available.
912  *                                                  Try again later.
913  *  @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
914  */
915 int_fast16_t AESCTR_finalize(AESCTR_Handle handle, AESCTR_SegmentedOperation *operation);
916 
917 /*!
918  *  @brief  Function to initialize an #AESCTR_Operation struct to its defaults (all zeroes)
919  *
920  *  @deprecated Use #AESCTR_OneStepOperation_init() or #AESCTR_SegmentedOperation_init()
921  *              based on whether it is a one-step or a segmented AESCTR operation.
922  *
923  *  @param  operation     Pointer to an #AESCTR_Operation structure for
924  *                        initialization
925  */
926 void AESCTR_Operation_init(AESCTR_Operation *operation);
927 
928 /*!
929  *  @brief  Function to initialize an #AESCTR_OneStepOperation struct to its defaults (all zeroes)
930  *
931  *  @param  [in] operation   Pointer to an #AESCTR_OneStepOperation structure for
932  *                           initialization
933  */
934 void AESCTR_OneStepOperation_init(AESCTR_OneStepOperation *operation);
935 
936 /*!
937  *  @brief  Function to initialize an #AESCTR_SegmentedOperation struct to its defaults (all zeroes)
938  *
939  *  @param  [in] operation   Pointer to an #AESCTR_SegmentedOperation structure for
940  *                           initialization
941  */
942 void AESCTR_SegmentedOperation_init(AESCTR_SegmentedOperation *operation);
943 
944 /*!
945  *  @brief  Function to perform an AESCTR encryption operation in one call.
946  *
947  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
948  *          Doing so can yield corrupted ciphertext.
949  *
950  *  @pre    #AESCTR_open() or #AESCTR_construct()
951  *
952  *  @param  [in] handle     AESCTR handle
953  *  @param  [in] operation  Pointer to a struct containing the parameters required to perform the operation.
954  *
955  *  @retval #AESCTR_STATUS_SUCCESS               The operation succeeded.
956  *  @retval #AESCTR_STATUS_ERROR                 The operation failed.
957  *  @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
958  *  @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
959  *
960  *  @sa     #AESCTR_oneStepDecrypt()
961  */
962 int_fast16_t AESCTR_oneStepEncrypt(AESCTR_Handle handle, AESCTR_OneStepOperation *operation);
963 
964 /*!
965  *  @brief  Function to perform an AESCTR decryption operation in one call.
966  *
967  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
968  *          Doing so can yield corrupted plaintext.
969  *
970  *  @pre    #AESCTR_open() or #AESCTR_construct()
971  *
972  *  @param  [in] handle      AESCTR handle
973  *  @param  [in] operation   Pointer to a struct containing the parameters required to perform the operation.
974  *
975  *  @retval #AESCTR_STATUS_SUCCESS               The operation succeeded.
976  *  @retval #AESCTR_STATUS_ERROR                 The operation failed.
977  *  @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
978  *  @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
979  *
980  *  @sa     AESCTR_oneStepEncrypt()
981  */
982 int_fast16_t AESCTR_oneStepDecrypt(AESCTR_Handle handle, AESCTR_OneStepOperation *operation);
983 
984 /*!
985  *  @brief Cancels an ongoing AESCTR operation.
986  *
987  *  Asynchronously cancels an AESCTR operation. Only available when using
988  *  AESCTR_RETURN_BEHAVIOR_CALLBACK.
989  *  The operation will terminate as though an error occurred. The
990  *  return status code of the operation will be AESCTR_STATUS_CANCELED.
991  *
992  *  @param  [in] handle      AESCTR handle
993  *
994  *  @retval #AESCTR_STATUS_SUCCESS   The operation was canceled or the operation had already completed.
995  */
996 int_fast16_t AESCTR_cancelOperation(AESCTR_Handle handle);
997 
998 /**
999  *  @brief  Constructs a new AESCTR object
1000  *
1001  *  Unlike #AESCTR_open(), #AESCTR_construct() does not require the hwAttrs and
1002  *  object to be allocated in a #AESCTR_Config array that is indexed into.
1003  *  Instead, the #AESCTR_Config, hwAttrs, and object can be allocated at any
1004  *  location. This allows for relatively simple run-time allocation of temporary
1005  *  driver instances on the stack or the heap.
1006  *  The drawback is that this makes it more difficult to write device-agnostic
1007  *  code. If you use an ifdef with DeviceFamily, you can choose the correct
1008  *  object and hwAttrs to allocate. That compilation unit will be tied to the
1009  *  device it was compiled for at this point. To change devices, recompilation
1010  *  of the application with a different DeviceFamily setting is necessary.
1011  *
1012  *  @pre    The object struct @c config points to must be zeroed out prior to
1013  *          calling this function. Otherwise, unexpected behavior may occur.
1014  *
1015  *  @param  [in] config   #AESCTR_Config describing the location of the object and hwAttrs.
1016  *
1017  *  @param  [in] params   #AESCTR_Params to configure the driver instance.
1018  *
1019  *  @return Returns a #AESCTR_Handle on success or NULL on failure.
1020  *
1021 
1022  */
1023 AESCTR_Handle AESCTR_construct(AESCTR_Config *config, const AESCTR_Params *params);
1024 
1025 #ifdef __cplusplus
1026 }
1027 #endif
1028 
1029 #endif /* ti_drivers_AESCTR__include */
1030