1 /*
2  * Copyright (c) 2017-2023, 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       AESCCM.h
34  *
35  *  @brief      AESCCM driver header
36  *
37  *  @anchor ti_drivers_AESCCM_Overview
38  *  # Overview #
39  *  The Counter with CBC-MAC (CCM) mode of operation is a generic
40  *  authenticated encryption block cipher mode.  It can be used with
41  *  any block cipher.
42  *  AESCCM combines CBC-MAC with an AES block cipher in CTR mode of operation.
43  *
44  *  This combination of block cipher modes enables CCM to encrypt messages of any
45  *  length and not only multiples of the block cipher block size.
46  *
47  *  CTR provides confidentiality. The defined application of CBC-MAC provides
48  *  message integrity and authentication.
49  *
50  *  AESCCM has the following inputs and outputs:
51  *
52  * <table>
53  * <caption id="AESCCM_multi_row">AES-CCM input and output parameters</caption>
54  * <tr><th>Encryption</th><th>Decryption</th></tr>
55  * <tr><th colspan=2>Input</th></tr>
56  * <tr><td>Shared AES key</td><td> Shared AES key</td></tr>
57  * <tr><td>Nonce</td><td>Nonce</td></tr>
58  * <tr><td>Cleartext</td><td>Ciphertext</td></tr>
59  * <tr><td></td><td>MAC</td></tr>
60  * <tr><td>AAD (optional)</td><td>AAD (optional)</td></tr>
61  * <tr><th colspan=2>Output</th></tr>
62  * <tr><td>Ciphertext</td><td>Cleartext</td></tr>
63  * <tr><td>MAC</td><td></td></tr>
64  * </table>
65  *
66  *  The AES key is a shared secret between the two parties and has a length
67  *  of 128, 192, or 256 bits.
68  *
69  *  The nonce is generated by the party performing the authenticated
70  *  encryption operation.  Within the scope of any authenticated
71  *  encryption key, the nonce value must be unique.  That is, the set of
72  *  nonce values used with any given key must not contain any duplicate
73  *  values.  Using the same nonce for two different messages encrypted
74  *  with the same key destroys the security properties.
75  *
76  *  The length of the nonce determines the maximum number of messages that may
77  *  be encrypted and authenticated before you must regenerate the key.
78  *  Reasonable session key rotation schemes will regenerate the key before reaching
79  *  this limit.
80  *  There is a trade-off between the nonce-length and the maximum length of
81  *  the plaintext to encrypt and authenticate per nonce. This is because
82  *  CTR concatenates the nonce and an internal counter into one 16-byte
83  *  IV. The counter is incremented after generating an AES-block-sized
84  *  pseudo-random bitstream. This bitstream is XOR'd with the plaintext.
85  *  The counter would eventually roll over for a sufficiently long message.
86  *  This is must not happen. Hence, the longer the nonce and the more messages
87  *  you can send before needing to rotate the key, the shorter the
88  *  lengths of individual messages sent may be. The minimum and maximum
89  *  nonce length defined by the CCM standard provide for both a reasonable
90  *  number of messages before key rotation and a reasonable maximum message length.
91  *  Check NIST SP 800-38C for details.
92  *
93  *  The optional additional authentication data (AAD) is authenticated
94  *  but not encrypted. Thus, the AAD is not included in the AES-CCM output.
95  *  It can be used to authenticate packet headers.
96  *
97  *  After the encryption operation, the ciphertext contains the encrypted
98  *  data. The message authentication code (MAC) is also provided.
99  *
100  *  # CCM Variations #
101  *  The AESCCM driver supports both classic CCM as defined by NIST SP 800-38C and
102  *  the CCM* variant used in IEEE 802.15.4.
103  *  CCM* allows for unauthenticated encryption using CCM by permitting a MAC length
104  *  of 0. It also imposes the requirement that the MAC length be embedded in
105  *  the nonce used for each message if the MAC length varies within the protocol
106  *  using CCM*.
107  *
108  *  @anchor ti_drivers_AESCCM_Usage
109  *  # Usage #
110  *
111  *  ## Before starting a CCM operation #
112  *
113  *  Before starting a CCM operation, the application must do the following:
114  *      - Call AESCCM_init() to initialize the driver
115  *      - Call AESCCM_Params_init() to initialize the AESCCM_Params to default values.
116  *      - Modify the AESCCM_Params as desired
117  *      - Call AESCCM_open() to open an instance of the driver
118  *      - Initialize a CryptoKey. These opaque data structures are representations
119  *        of keying material and its storage. Depending on how the keying material
120  *        is stored (RAM or flash, key store), the CryptoKey must be
121  *        initialized differently. The AESCCM API can handle all types of CryptoKey.
122  *        However, not all device-specific implementations support all types of CryptoKey.
123  *        Devices without a key store will not support CryptoKeys with keying material
124  *        stored in a key store for example.
125  *        All devices support plaintext CryptoKeys.
126  *      - Initialize the appropriate AESCCM operation struct using the relevant
127  *        operation init functions and set all fields. For example, one-step (one-shot
128  *        or single call) operations should initialize AESCCM_Operation or
129  *        AESCCM_OneStepOperation using AESCCM_Operation_init() or
130  *        AESCCM_OneStepOperation_init(). For multi-step (segmented or multiple call)
131  *        operations, AESCCM_SegmentedAADOperation must be initialized and set when
132  *        processing AAD. AESCCM_SegmentedDataOperation must be initialized and set when
133  *        dealing with payload data (plaintext or ciphertext). AESCCM_SegmentedFinalizeOperation
134  *        must be initialized and set when finalizing the segmented operation.
135  *
136  *  ## Starting a CCM operation #
137  *
138  *  The AESCCM_oneStepEncrypt and AESCCM_oneStepDecrypt functions do a CCM operation in a single call.
139  *  They will always be the most highly optimized routines with the least overhead and the fastest
140  *  runtime. However, they require all AAD and plaintext or ciphertext data to be
141  *  available to the function at the start of the call.
142  *  All devices support single call operations.
143  *
144  *  When performing a decryption operation with AESCCM_oneStepDecrypt(), the MAC is
145  *  automatically verified.
146  *
147  *  ## After the CCM operation completes #
148  *
149  *  After the CCM operation completes, the application should either start another operation
150  *  or close the driver by calling AESCCM_close()
151  *
152  *  @anchor ti_drivers_AESCCM_Synopsis
153  *  ## Synopsis
154  *
155  *  @anchor ti_drivers_AESCCM_Synopsis_Code
156  *  @code
157  *
158  *  // Import AESCCM Driver definitions
159  *  #include <ti/drivers/AESCCM.h>
160  *
161  *  // Define name for AESCCM channel index
162  *  #define AESCCM_INSTANCE 0
163  *
164  *  AESCCM_init();
165  *
166  *  handle = AESCCM_open(AESCCM_INSTANCE, NULL);
167  *
168  *  // Initialize symmetric key
169  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
170  *
171  *  // Set up AESCCM_OneStepOperation
172  *  AESCCM_OneStepOperation_init(&operation);
173  *  operation.key               = &cryptoKey;
174  *  operation.aad               = aad;
175  *  operation.aadLength         = sizeof(aad);
176  *  operation.input             = plaintext;
177  *  operation.output            = ciphertext;
178  *  operation.inputLength       = sizeof(plaintext);
179  *  operation.nonce             = nonce;
180  *  operation.nonceLength       = sizeof(nonce);
181  *  operation.mac               = mac;
182  *  operation.macLength         = sizeof(mac);
183  *
184  *  encryptionResult = AESCCM_oneStepEncrypt(handle, &operation);
185  *
186  *  AESCCM_close(handle);
187  *  @endcode
188  *
189  *  @anchor ti_drivers_AESCCM_Examples
190  *  ## Examples
191  *
192  *  ### Single call CCM encryption + authentication with plaintext CryptoKey in blocking return mode #
193  *  @code
194  *
195  *  #include <ti/drivers/AESCCM.h>
196  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
197  *
198  *  ...
199  *
200  *  AESCCM_Handle handle;
201  *  CryptoKey cryptoKey;
202  *  int_fast16_t encryptionResult;
203  *  uint8_t nonce[] = "Thisisanonce";
204  *  uint8_t aad[] = "This string will be authenticated but not encrypted.";
205  *  uint8_t plaintext[] = "This string will be encrypted and authenticated.";
206  *  uint8_t mac[16];
207  *  uint8_t ciphertext[sizeof(plaintext)];
208  *  uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
209  *                                0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
210  *                                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
211  *                                0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
212  *
213  *  handle = AESCCM_open(0, NULL);
214  *
215  *  if (handle == NULL) {
216  *      // handle error
217  *  }
218  *
219  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
220  *
221  *      AESCCM_OneStepOperation operation;
222  *      AESCCM_OneStepOperation_init(&operation);
223  *
224  *      operation.key               = &cryptoKey;
225  *      operation.aad               = aad;
226  *      operation.aadLength         = sizeof(aad);
227  *      operation.input             = plaintext;
228  *      operation.output            = ciphertext;
229  *      operation.inputLength       = sizeof(plaintext);
230  *      operation.nonce             = nonce;
231  *      operation.nonceLength       = sizeof(nonce);
232  *      operation.mac               = mac;
233  *      operation.macLength         = sizeof(mac);
234  *
235  *  encryptionResult = AESCCM_oneStepEncrypt(handle, &operation);
236  *
237  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
238  *      // handle error
239  *  }
240  *
241  *  AESCCM_close(handle);
242  *
243  *  @endcode
244  *  ### The following code snippet is for CC27XX devices only and leverages the HSM
245  *      which is a seperate Hardware Accelerator ###
246  *  ### Single call CCM encryption + authentication with plaintext HSM CryptoKey in Polling Mode ###
247  *
248  *  @code
249  *
250  *  #include <ti/drivers/AESCCM.h>
251  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
252  *
253  *  ...
254  *
255  *  AESCCM_Params params;
256  *  AESCCM_Handle handle;
257  *  CryptoKey cryptoKey;
258  *  int_fast16_t encryptionResult;
259  *  uint8_t nonce[] = "Thisisanonce";
260  *  uint8_t aad[] = "This string will be authenticated but not encrypted.";
261  *  uint8_t plaintext[] = "This string will be encrypted and authenticated.";
262  *  uint8_t mac[16];
263  *  uint8_t ciphertext[sizeof(plaintext)];
264  *  uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
265  *                                0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
266  *                                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
267  *                                0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
268  *
269  *  AESCCM_Params_init(&params)
270  *  params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING;
271  *
272  *  handle = AESCCM_open(0, &params);
273  *
274  *  if (handle == NULL) {
275  *      // handle error
276  *  }
277  *
278  *  CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
279  *
280  *  AESCCM_OneStepOperation operation;
281  *  AESCCM_OneStepOperation_init(&operation);
282  *
283  *  operation.key           = &cryptoKey;
284  *  operation.aad           = aad;
285  *  operation.aadLength     = sizeof(aad);
286  *  operation.input         = plaintext;
287  *  operation.output        = ciphertext;
288  *  operation.inputLength   = sizeof(plaintext);
289  *  operation.nonce         = nonce;
290  *  operation.nonceLength   = sizeof(nonce);
291  *  operation.mac           = mac;
292  *  operation.macLength     = sizeof(mac);
293  *
294  *  encryptionResult = AESCCM_oneStepEncrypt(handle, &operation);
295  *
296  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
297  *      // handle error
298  *  }
299  *
300  *  AESCCM_close(handle);
301  *
302  *  @endcode
303  *
304  *  ### Single call CCM decryption + verification with plaintext CryptoKey in callback return mode #
305  *  @code
306  *
307  *  #include <ti/drivers/AESCCM.h>
308  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
309  *
310  *  ...
311  *
312  *  // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
313  *
314  *  uint8_t nonce[]                         = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
315  *                                             0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
316  *  uint8_t aad[]                           = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
317  *  uint8_t mac[]                           = {0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0};
318  *  uint8_t ciphertext[]                    = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
319  *                                             0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
320  *                                             0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84};
321  *  uint8_t keyingMaterial[]                = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
322  *                                             0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
323  *  uint8_t plaintext[sizeof(ciphertext)];
324  *
325  *  // The plaintext should be the following after the decryption operation:
326  *  //  {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
327  *  //  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
328  *  //  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}
329  *
330  *
331  *  void ccmCallback(AESCCM_Handle handle,
332  *                   int_fast16_t returnValue,
333  *                   AESCCM_OperationUnion *operation,
334  *                   AESCCM_OperationType operationType) {
335  *
336  *      if (returnValue != AESCCM_STATUS_SUCCESS) {
337  *          // handle error
338  *      }
339  *  }
340  *
341  *  AESCCM_OneStepOperation operation;
342  *
343  *  void ccmStartFunction(void) {
344  *      AESCCM_Handle handle;
345  *      AESCCM_Params params;
346  *      CryptoKey cryptoKey;
347  *      int_fast16_t decryptionResult;
348  *
349  *      AESCCM_Params_init(&params);
350  *      params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK;
351  *      params.callbackFxn = ccmCallback;
352  *
353  *      handle = AESCCM_open(0, &params);
354  *
355  *      if (handle == NULL) {
356  *          // handle error
357  *      }
358  *
359  *      CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
360  *
361  *      AESCCM_OneStepOperation_init(&operation);
362  *
363  *      operation.key               = &cryptoKey;
364  *      operation.aad               = aad;
365  *      operation.aadLength         = sizeof(aad);
366  *      operation.input             = ciphertext;
367  *      operation.output            = plaintext;
368  *      operation.inputLength       = sizeof(ciphertext);
369  *      operation.nonce             = nonce;
370  *      operation.nonceLength       = sizeof(nonce);
371  *      operation.mac               = mac;
372  *      operation.macLength         = sizeof(mac);
373  *
374  *      decryptionResult = AESCCM_oneStepDecrypt(handle, &operation);
375  *
376  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
377  *          // handle error
378  *      }
379  *
380  *      // do other things while CCM operation completes in the background
381  *
382  *  }
383  *
384  *
385  *  @endcode
386  *
387  *  ### Multi-step CCM encryption + authentication with plaintext CryptoKey in blocking return mode #
388  *  @code
389  *
390  *  #include <ti/drivers/AESCCM.h>
391  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
392  *
393  *  ...
394  *
395  *  #define AES_BLOCK_SIZE     16 // bytes
396  *
397  *  AESCCM_Handle handle;
398  *  CryptoKey cryptoKey;
399  *  int_fast16_t encryptionResult;
400  *
401  *  // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
402  *
403  *  uint8_t keyingMaterial[16] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
404  *                                0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
405  *  uint8_t aad[8]             = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
406  *  uint8_t plaintext[23]      = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
407  *                                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
408  *                                0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E};
409  *  uint8_t nonce[13]          = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
410  *                                0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
411  *  uint8_t mac[8];
412  *  uint8_t ciphertext[sizeof(plaintext)];
413  *
414  *  // The ciphertext should be the following after the encryption operation:
415  *  //  {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
416  *  //  0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
417  *  //  0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84}
418  *
419  *  handle = AESCCM_open(0, NULL);
420  *
421  *  if (handle == NULL) {
422  *      // handle error
423  *  }
424  *
425  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
426  *
427  *
428  *  encryptionResult = AESCCM_setupEncrypt(handle, &cryptoKey, sizeof(aad), sizeof(plaintext), sizeof(mac));
429  *  if (decryptionResult != AESCCM_STATUS_SUCCESS) {
430  *      // handle error
431  *  }
432  *
433  *  encryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce));
434  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
435  *      // handle error
436  *  }
437  *
438  *  #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX) // and the HSM is the engine of choice
439  *
440  *  CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
441  *
442  *  // You will also need to populate the mac in handle->object->mac because HSM needs the mac to construct each
443  *  // segmented token.
444  *  encryptionResult = AESCCMLPF3HSM_setMac(handle, &mac[0], 8);
445  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
446  *      // handle error
447  *  }
448  *
449  *  #endif
450  *
451  *  AESCCM_SegmentedAADOperation segmentedAADOperation;
452  *  AESCCM_SegmentedAADOperation_init(&segmentedAADOperation);
453  *  segmentedAADOperation.aad = aad;
454  *  segmentedAADOperation.aadLength = sizeof(aad);
455  *
456  *  encryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation);
457  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
458  *      // handle error
459  *  }
460  *
461  *  AESCCM_SegmentedDataOperation segmentedDataOperation;
462  *  AESCCM_SegmentedDataOperation_init(&segmentedDataOperation);
463  *  segmentedDataOperation.input = plaintext;
464  *  segmentedDataOperation.output = ciphertext;
465  *  // One should pass in data that is a block-sized multiple length
466  *  // until passing in the last segment of data.
467  *  // In that case, the input length simply needs to be a non-zero value.
468  *  segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
469  *
470  *  encryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
471  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
472  *      // handle error
473  *  }
474  *
475  *  segmentedDataOperation.input = plaintext + AES_BLOCK_SIZE;
476  *  segmentedDataOperation.output = ciphertext + AES_BLOCK_SIZE;
477  *  segmentedDataOperation.inputLength = sizeof(plaintext) - AES_BLOCK_SIZE;
478  *
479  *  encryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
480  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
481  *      // handle error
482  *  }
483  *
484  *  AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
485  *  AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
486  *  segmentedFinalizeOperation.input = plaintext;
487  *  segmentedFinalizeOperation.output = ciphertext;
488  *
489  *  // You can finalize with no new data
490  *  segmentedFinalizeOperation.inputLength = 0;
491  *  segmentedFinalizeOperation.mac = mac;
492  *  segmentedFinalizeOperation.macLength = sizeof(mac);
493  *  encryptionResult = AESCCM_finalizeEncrypt(handle, &segmentedFinalizeOperation);
494  *
495  *  if (encryptionResult != AESCCM_STATUS_SUCCESS) {
496  *      // handle error
497  *  }
498  *
499  *  AESCCM_close(handle);
500  *
501  *  @endcode
502  *
503  *  ### Multi-step CCM decryption + verification with plaintext CryptoKey in callback return mode #
504  *  @code
505  *
506  *  #include <ti/drivers/AESCCM.h>
507  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
508  *
509  *  ...
510  *
511  *  // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
512  *
513  *  uint8_t nonce[]                         = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
514  *                                             0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
515  *  uint8_t aad[]                           = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
516  *  uint8_t mac[]                           = {0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0};
517  *  uint8_t ciphertext[]                    = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
518  *                                             0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
519  *                                             0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84};
520  *  uint8_t keyingMaterial[]                = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
521  *                                             0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
522  *  uint8_t plaintext[sizeof(ciphertext)];
523  *
524  *  // The plaintext should be the following after the decryption operation:
525  *  //  {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
526  *  //  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
527  *  //  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}
528  *
529  *
530  *  void ccmCallback(AESCCM_Handle handle,
531  *                   int_fast16_t returnValue,
532  *                   AESCCM_OperationUnion *operation,
533  *                   AESCCM_OperationType operationType) {
534  *
535  *      if (returnValue != AESCCM_STATUS_SUCCESS) {
536  *          // handle error
537  *      }
538  *
539  *      if(operationType == AESCCM_OPERATION_TYPE_DECRYPT ||
540  *         operationType == AESCCM_OPERATION_TYPE_ENCRYPT)
541  *      {
542  *          // Callback fxn only used for one-shot operations
543  *          // Use operation->oneStepOperation
544  *      }
545  *      else if(operationType == AESCCM_OP_TYPE_AAD_DECRYPT ||
546  *              operationType == AESCCM_OP_TYPE_AAD_ENCRYPT)
547  *      {
548  *          // Callback fxn only used for segmented AAD operations
549  *          // Use operation->segmentedAADOperation
550  *      }
551  *      else if(operationType == AESCCM_OP_TYPE_DATA_DECRYPT ||
552  *              operationType == AESCCM_OP_TYPE_DATA_ENCRYPT)
553  *      {
554  *          // Callback fxn only used for segmented data operations
555  *          // Use operation->segmentedDataOperation
556  *      }
557  *      else
558  *      {
559  *          // Callback fxn only used for segmented finalize operations
560  *          // Use operation->segmentedFinalizeOperation
561  *      }
562  *  }
563  *
564  *  void ccmStartFunction(void) {
565  *      AESCCM_Handle handle;
566  *      AESCCM_Params params;
567  *      CryptoKey cryptoKey;
568  *      int_fast16_t decryptionResult;
569  *
570  *      AESCCM_Params_init(&params);
571  *      params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK;
572  *      params.callbackFxn = ccmCallback;
573  *
574  *      handle = AESCCM_open(0, &params);
575  *
576  *      if (handle == NULL) {
577  *          // handle error
578  *      }
579  *
580  *      CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
581  *
582  *      decryptionResult = AESCCM_setupDecrypt(handle, &cryptoKey, 0, 0, 0);
583  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
584  *          // handle error
585  *      }
586  *
587  *      // setLengths must be called if the AAD, input, and MAC lengths aren't provided in setupXXXX.
588  *      decryptionResult = AESCCM_setLengths(handle, sizeof(aad), sizeof(ciphertext), sizeof(mac));
589  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
590  *          // handle error
591  *      }
592  *
593  *      decryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce));
594  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
595  *          // handle error
596  *      }
597  *
598  *      AESCCM_SegmentedAADOperation segmentedAADOperation;
599  *      AESCCM_SegmentedAADOperation_init(&segmentedAADOperation);
600  *      segmentedAADOperation.aad = aad;
601  *      segmentedAADOperation.aadLength = sizeof(aad);
602  *
603  *      decryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation);
604  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
605  *          // handle error
606  *      }
607  *
608  *      AESCCM_SegmentedDataOperation segmentedDataOperation;
609  *      AESCCM_SegmentedDataOperation_init(&segmentedDataOperation);
610  *      segmentedDataOperation.input = ciphertext;
611  *      segmentedDataOperation.output = plaintext;
612  *      segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
613  *
614  *      decryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
615  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
616  *          // handle error
617  *      }
618  *
619  *      AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
620  *      AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
621  *      segmentedFinalizeOperation.input = ciphertext + AES_BLOCK_SIZE;
622  *      segmentedFinalizeOperation.output = plaintext + AES_BLOCK_SIZE;
623  *      segmentedFinalizeOperation.inputLength = sizeof(ciphertext) - AES_BLOCK_SIZE;
624  *      segmentedFinalizeOperation.mac = mac;
625  *      segmentedFinalizeOperation.macLength = sizeof(mac);
626  *
627  *      decryptionResult = AESCCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
628  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
629  *          // handle error
630  *      }
631  *
632  *      // do other things while CCM operation completes in the background
633  *
634  *  }
635  *
636  *  @endcode
637  *
638  *  ### Multi-step CCM* decryption + verification with plaintext CryptoKey in callback return mode #
639  *  @code
640  *
641  *  #include <ti/drivers/AESCCM.h>
642  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
643  *
644  *  ...
645  *
646  *  // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
647  *
648  *  uint8_t nonce[]                         = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
649  *                                             0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
650  *  uint8_t aad[]                           = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
651  *  uint8_t mac[]                           = {0};
652  *
653  *  // CCM* allows for unauthenticated encryption using CCM by allowing a MAC length of 0
654  *  uint8_t macLength                       = 0;
655  *  uint8_t ciphertext[]                    = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
656  *                                             0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
657  *                                             0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84};
658  *  uint8_t keyingMaterial[]                = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
659  *                                             0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
660  *  uint8_t plaintext[sizeof(ciphertext)];
661  *
662  *  // The plaintext should be the following after the decryption operation:
663  *  //  {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
664  *  //  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
665  *  //  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}
666  *
667  *
668  *  void ccmCallback(AESCCM_Handle handle,
669  *                   int_fast16_t returnValue,
670  *                   AESCCM_OperationUnion *operation,
671  *                   AESCCM_OperationType operationType) {
672  *
673  *      if (returnValue != AESCCM_STATUS_SUCCESS) {
674  *          // handle error
675  *      }
676  *
677  *      if(operationType == AESCCM_OPERATION_TYPE_DECRYPT ||
678  *         operationType == AESCCM_OPERATION_TYPE_ENCRYPT)
679  *      {
680  *          // Callback fxn only used for one-shot operations
681  *          // Use operation->oneStepOperation
682  *      }
683  *      else if(operationType == AESCCM_OP_TYPE_AAD_DECRYPT ||
684  *              operationType == AESCCM_OP_TYPE_AAD_ENCRYPT)
685  *      {
686  *          // Callback fxn only used for segmented AAD operations
687  *          // Use operation->segmentedAADOperation
688  *      }
689  *      else if(operationType == AESCCM_OP_TYPE_DATA_DECRYPT ||
690  *              operationType == AESCCM_OP_TYPE_DATA_ENCRYPT)
691  *      {
692  *          // Callback fxn only used for segmented data operations
693  *          // Use operation->segmentedDataOperation
694  *      }
695  *      else
696  *      {
697  *          // Callback fxn only used for segmented finalize operations
698  *          // Use operation->segmentedFinalizeOperation
699  *      }
700  *  }
701  *
702  *  void ccmStartFunction(void) {
703  *      AESCCM_Handle handle;
704  *      AESCCM_Params params;
705  *      CryptoKey cryptoKey;
706  *      int_fast16_t decryptionResult;
707  *
708  *      AESCCM_Params_init(&params);
709  *      params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK;
710  *      params.callbackFxn = ccmCallback;
711  *
712  *      handle = AESCCM_open(0, &params);
713  *
714  *      if (handle == NULL) {
715  *          // handle error
716  *      }
717  *
718  *      CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
719  *
720  *      decryptionResult = AESCCM_setupDecrypt(handle, &cryptoKey, 0, 0, 0);
721  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
722  *          // handle error
723  *      }
724  *
725  *      // setLengths must be called if the AAD, input, and MAC lengths aren't provided in setupXXXX.
726  *      decryptionResult = AESCCM_setLengths(handle, sizeof(aad), sizeof(ciphertext), macLength);
727  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
728  *          // handle error
729  *      }
730  *
731  *      decryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce));
732  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
733  *          // handle error
734  *      }
735  *
736  *      AESCCM_SegmentedAADOperation segmentedAADOperation;
737  *      AESCCM_SegmentedAADOperation_init(&segmentedAADOperation);
738  *      segmentedAADOperation.aad = aad;
739  *      segmentedAADOperation.aadLength = sizeof(aad);
740  *
741  *      decryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation);
742  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
743  *          // handle error
744  *      }
745  *
746  *      AESCCM_SegmentedDataOperation segmentedDataOperation;
747  *      AESCCM_SegmentedDataOperation_init(&segmentedDataOperation);
748  *      segmentedDataOperation.input = ciphertext;
749  *      segmentedDataOperation.output = plaintext;
750  *      segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
751  *
752  *      decryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
753  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
754  *          // handle error
755  *      }
756  *
757  *      AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
758  *      AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
759  *      segmentedFinalizeOperation.input = ciphertext + AES_BLOCK_SIZE;
760  *      segmentedFinalizeOperation.output = plaintext + AES_BLOCK_SIZE;
761  *      segmentedFinalizeOperation.inputLength = sizeof(ciphertext) - AES_BLOCK_SIZE;
762  *      segmentedFinalizeOperation.mac = mac;
763  *      segmentedFinalizeOperation.macLength = macLength;
764  *
765  *      decryptionResult = AESCCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
766  *      if (decryptionResult != AESCCM_STATUS_SUCCESS) {
767  *          // handle error
768  *      }
769  *
770  *      // do other things while CCM operation completes in the background
771  *
772  *  }
773  *
774  *  @endcode
775  */
776 
777 #ifndef ti_drivers_AESCCM__include
778 #define ti_drivers_AESCCM__include
779 
780 #include <stdbool.h>
781 #include <stddef.h>
782 #include <stdint.h>
783 
784 #include <ti/drivers/AESCommon.h>
785 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
786 
787 #ifdef __cplusplus
788 extern "C" {
789 #endif
790 
791 /*!
792  * Common AESCCM status code reservation offset.
793  * AESCCM driver implementations should offset status codes with
794  * AESCCM_STATUS_RESERVED growing negatively.
795  *
796  * Example implementation specific status codes:
797  * @code
798  * #define AESCCMXYZ_STATUS_ERROR0    AESCCM_STATUS_RESERVED - 0
799  * #define AESCCMXYZ_STATUS_ERROR1    AESCCM_STATUS_RESERVED - 1
800  * #define AESCCMXYZ_STATUS_ERROR2    AESCCM_STATUS_RESERVED - 2
801  * @endcode
802  */
803 #define AESCCM_STATUS_RESERVED AES_STATUS_RESERVED
804 
805 /*!
806  * @brief   Successful status code.
807  *
808  * Functions return AESCCM_STATUS_SUCCESS if the function was executed
809  * successfully.
810  */
811 #define AESCCM_STATUS_SUCCESS AES_STATUS_SUCCESS
812 
813 /*!
814  * @brief   Generic error status code.
815  *
816  * Functions return AESCCM_STATUS_ERROR if the function was not executed
817  * successfully and no more pertinent error code could be returned.
818  */
819 #define AESCCM_STATUS_ERROR AES_STATUS_ERROR
820 
821 /*!
822  * @brief   An error status code returned if the hardware or software resource
823  * is currently unavailable.
824  *
825  * AESCCM driver implementations may have hardware or software limitations on how
826  * many clients can simultaneously perform operations. This status code is returned
827  * if the mutual exclusion mechanism signals that an operation cannot currently be performed.
828  */
829 #define AESCCM_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
830 
831 /*!
832  *  @brief  The ongoing operation was canceled.
833  */
834 #define AESCCM_STATUS_CANCELED AES_STATUS_CANCELED
835 
836 /*!
837  * @brief   An error status code returned if the MAC provided by the application for
838  *  a decryption operation does not match the one calculated during the operation.
839  *
840  * This code is returned by AESCCM_oneStepDecrypt() or AESCCM_finalizeDecrypt()
841  * if the verification of the MAC fails.
842  */
843 #define AESCCM_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID
844 
845 /*!
846  *  @brief  The operation requested is not supported either by the target hardware
847  *          or the driver implementation.
848  */
849 #define AESCCM_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
850 
851 /*!
852  *  @brief  The operation tried to load a key from the keystore using an invalid key ID.
853  */
854 #define AESCCM_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
855 
856 /*!
857  *  @brief  The key store module returned a generic error. See key store documentation
858  *  for additional details.
859  */
860 #define AESCCM_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
861 
862 /*!
863  * @brief   The operation does not support non-word-aligned input and/or output.
864  *
865  * AESCCM driver implementations may have restrictions on the alignment of
866  * input/output data due to performance limitations of the hardware.
867  */
868 #define AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
869 
870 /*!
871  *  @brief AESCCM Global configuration
872  *
873  *  The AESCCM_Config structure contains a set of pointers used to characterize
874  *  the AESCCM driver implementation.
875  *
876  *  This structure needs to be defined before calling AESCCM_init() and it must
877  *  not be changed thereafter.
878  *
879  *  @sa     AESCCM_init()
880  */
881 typedef AESCommon_Config AESCCM_Config;
882 
883 /*!
884  *  @brief  A handle that is returned from an AESCCM_open() call.
885  */
886 typedef AESCCM_Config *AESCCM_Handle;
887 
888 /*!
889  * @brief   The way in which CCM function calls return after performing an
890  * encryption + authentication or decryption + verification operation.
891  *
892  * Not all CCM operations exhibit the specified return behavior. Functions that do not
893  * require significant computation and cannot offload that computation to a background thread
894  * behave like regular functions. Which functions exhibit the specified return behavior is not
895  * implementation dependent. Specifically, a software-backed implementation run on the same
896  * CPU as the application will emulate the return behavior while not actually offloading
897  * the computation to the background thread.
898  *
899  * AESCCM functions exhibiting the specified return behavior have restrictions on the
900  * context from which they may be called.
901  *
902  * |                                | Task  | Hwi   | Swi   |
903  * |--------------------------------|-------|-------|-------|
904  * |AESCCM_RETURN_BEHAVIOR_CALLBACK | X     | X     | X     |
905  * |AESCCM_RETURN_BEHAVIOR_BLOCKING | X     |       |       |
906  * |AESCCM_RETURN_BEHAVIOR_POLLING  | X     | X     | X     |
907  *
908  */
909 typedef enum
910 {
911     AESCCM_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK,
912     /*!< The function call will return immediately while the
913      *   CCM operation goes on in the background. The registered
914      *   callback function is called after the operation completes.
915      *   The context the callback function is called (task, HWI, SWI)
916      *   is implementation-dependent.
917      */
918     AESCCM_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING,
919     /*!< The function call will block while the CCM operation goes
920      *   on in the background. CCM operation results are available
921      *   after the function returns.
922      */
923     AESCCM_RETURN_BEHAVIOR_POLLING  = AES_RETURN_BEHAVIOR_POLLING,
924     /*!< The function call will continuously poll a flag while CCM
925      *   operation goes on in the background. CCM operation results
926      *   are available after the function returns.
927      */
928 } AESCCM_ReturnBehavior;
929 
930 /*!
931  *  @brief  Enum for the direction of the CCM operation.
932  */
933 typedef enum
934 {
935     AESCCM_MODE_ENCRYPT = 1,
936     AESCCM_MODE_DECRYPT = 2,
937 } AESCCM_Mode;
938 
939 /*!
940  *  @brief  Struct containing the parameters required for encrypting/decrypting
941  *          and authenticating/verifying a message for one-step operations.
942  */
943 typedef struct
944 {
945     CryptoKey *key;                /*!< A previously initialized CryptoKey */
946     uint8_t *aad;                  /*!< A buffer of length \c aadLength containing additional
947                                     *   authentication data to be authenticated/verified but not
948                                     *   encrypted/decrypted.
949                                     */
950     uint8_t *input;                /*!<
951                                     *   - Encryption: The plaintext buffer to be encrypted and authenticated
952                                     *   in the CCM operation.
953                                     *   - Decryption: The ciphertext to be decrypted and verified.
954                                     */
955     uint8_t *output;               /*!<
956                                     *   - Encryption: The output ciphertext buffer that the encrypted plaintext
957                                     *   is copied to.
958                                     *   - Decryption: The plaintext derived from the decrypted and verified
959                                     *   ciphertext is copied here.
960                                     */
961     uint8_t *nonce;                /*!< A buffer containing a nonce. Nonces must be unique to
962                                     *   each CCM operation and may not be reused. If
963                                     *   nonceInternallyGenerated is set, the nonce will be
964                                     *   generated by #AESCCM_oneStepEncrypt() and copied to this buffer.
965                                     */
966     uint8_t *mac;                  /*!<
967                                     *   - Encryption: The buffer where the message authentication
968                                     *   code is copied.
969                                     *   - Decryption: The buffer containing the received message
970                                     *   authentication code.
971                                     */
972     size_t aadLength;              /*!< Length of the total \c aad in bytes. Either \c aadLength or
973                                     *   \c inputLength must be non-zero. Unlike this field in
974                                     *   AESCCM_SegmentedAADOperation, the length doesn't need to be
975                                     *   block-aligned.
976                                     */
977     size_t inputLength;            /*!< Length of the input/output data in bytes. Either \c aadLength or
978                                     *   \c inputLength must be non-zero. Unlike this field in
979                                     *   AESCCM_SegmentedDataOperation, the length doesn't need to be
980                                     *   block-aligned.
981                                     *   Max length supported may be limited depending on the return behavior.
982                                     */
983     uint8_t nonceLength;           /*!< Length of \c nonce in bytes.
984                                     *   Valid nonce lengths are [7, 8, ... 13].
985                                     */
986     uint8_t macLength;             /*!< Length of \c mac in bytes.
987                                     *   Valid MAC lengths are [0, 4, 6, 8, 10, 12, 14, 16].
988                                     *   A length of 0 disables authentication and verification. This is
989                                     *   only permitted when using CCM*.
990                                     */
991     bool nonceInternallyGenerated; /*!< When true, the nonce buffer passed into #AESCCM_oneStepEncrypt()
992                                     *   will be overwritten with a randomly generated nonce.
993                                     *   Not supported by all implementations.
994                                     */
995 } AESCCM_OneStepOperation;
996 
997 /*!
998  *  @brief  Struct containing the parameters required for
999  *          authenticating/verifying additional data in a segmented operation.
1000  *          Must be updated for each add AAD step of a segmented operation.
1001  */
1002 typedef struct
1003 {
1004     uint8_t *aad;     /*!< A buffer of length \c aadLength containing additional
1005                        *   authentication data to be authenticated/verified but not
1006                        *   encrypted/decrypted.
1007                        */
1008     size_t aadLength; /*!< Length of the \c aad in bytes. Must be non-zero, multiple
1009                        *   of the AES block size (16 bytes) unless the last chunk of
1010                        *   AAD is being passed in. In that case, this value doesn't
1011                        *   need to be an AES block-sized multiple.
1012                        */
1013 } AESCCM_SegmentedAADOperation;
1014 
1015 /*!
1016  *  @brief  Struct containing the parameters required for encrypting/decrypting
1017  *          a message in a segmented operation. Must be updated between each
1018  *          add data step of a segmented operation.
1019  */
1020 typedef struct
1021 {
1022     uint8_t *input;     /*!<
1023                          *   - Encryption: The plaintext buffer to be encrypted and authenticated
1024                          *   in the CCM operation.
1025                          *   - Decryption: The ciphertext to be decrypted and verified.
1026                          */
1027     uint8_t *output;    /*!<
1028                          *   - Encryption: The output ciphertext buffer that the encrypted plaintext
1029                          *   is copied to.
1030                          *   - Decryption: The plaintext derived from the decrypted and verified
1031                          *   ciphertext is copied here.
1032                          */
1033     size_t inputLength; /*!< Length of the input/output data in bytes. Must be non-zero, multiple
1034                          *   of the AES block size (16 bytes) unless the last chunk of data is being
1035                          *   passed in. In that case, this value doesn't need to a block size multiple.
1036                          *   Max length supported may be limited depending on the return behavior.
1037                          */
1038 } AESCCM_SegmentedDataOperation;
1039 
1040 /*!
1041  *  @brief  Struct containing the parameters required for finalizing an
1042  *          encryption/decryption and authentication/verification of a message
1043  *          in a segmented operation.
1044  */
1045 typedef struct
1046 {
1047     uint8_t *input;     /*!<
1048                          *   - Encryption: The plaintext buffer to be encrypted and authenticated
1049                          *   in the CCM operation.
1050                          *   - Decryption: The ciphertext to be decrypted and verified.
1051                          */
1052     uint8_t *output;    /*!<
1053                          *   - Encryption: The output ciphertext buffer that the encrypted plaintext
1054                          *   is copied to.
1055                          *   - Decryption: The plaintext derived from the decrypted and verified
1056                          *   ciphertext is copied here.
1057                          */
1058     uint8_t *mac;       /*!<
1059                          *   - Encryption: The buffer where the message authentication
1060                          *   code is copied.
1061                          *   - Decryption: The buffer containing the received message
1062                          *   authentication code.
1063                          */
1064     size_t inputLength; /*!< Length of the input/output data in bytes. Can be 0 if finalizing
1065                          *   without new payload data. Unlike this field in
1066                          *   AESCCM_SegmentedDataOperation, the length doesn't need to be
1067                          *   block-aligned.
1068                          *   Max length supported may be limited depending on the return behavior.
1069                          */
1070     uint8_t macLength;  /*!< Length of \c mac in bytes.
1071                          *   Valid MAC lengths are [0, 4, 6, 8, 10, 12, 14, 16].
1072                          *   A length of 0 disables authentication and verification. This is
1073                          *   only permitted when using CCM*.
1074                          */
1075 } AESCCM_SegmentedFinalizeOperation;
1076 
1077 /**
1078  * @deprecated
1079  * Define a typedef for deprecated operation AESCCM_Operation.
1080  * Existing code should be refactored to use AESCCM_OneStepOperation.
1081  * This reference may be removed at some point in the future
1082  *
1083  */
1084 typedef AESCCM_OneStepOperation AESCCM_Operation;
1085 
1086 /*!
1087  *  @brief Union containing a reference to a one step,
1088  *  segmented AAD, segmented data, or segmented finalize operation.
1089  */
1090 typedef union AESCCM_OperationUnion
1091 {
1092     AESCCM_OneStepOperation oneStepOperation;             /* One-step operation element of the operation union */
1093     AESCCM_SegmentedAADOperation segmentedAADOperation;   /* Segmented AAD operation element of the operation union */
1094     AESCCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */
1095     AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the
1096                                                                      operation union */
1097 } AESCCM_OperationUnion;
1098 
1099 /*!
1100  *  @brief  Enum for the operation types supported by the driver.
1101  */
1102 typedef enum
1103 {
1104     AESCCM_OPERATION_TYPE_ENCRYPT   = 1, /* Fields 1 and 2 are for backward compatibility */
1105     AESCCM_OPERATION_TYPE_DECRYPT   = 2,
1106     AESCCM_OP_TYPE_ONESTEP_ENCRYPT  = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not
1107                                             being unique */
1108     AESCCM_OP_TYPE_ONESTEP_DECRYPT  = 2,
1109     AESCCM_OP_TYPE_AAD_ENCRYPT      = 3,
1110     AESCCM_OP_TYPE_AAD_DECRYPT      = 4,
1111     AESCCM_OP_TYPE_DATA_ENCRYPT     = 5,
1112     AESCCM_OP_TYPE_DATA_DECRYPT     = 6,
1113     AESCCM_OP_TYPE_FINALIZE_ENCRYPT = 7,
1114     AESCCM_OP_TYPE_FINALIZE_DECRYPT = 8,
1115 } AESCCM_OperationType;
1116 
1117 /*!
1118  *  @brief  The definition of a callback function used by the AESCCM driver
1119  *          when used in ::AESCCM_RETURN_BEHAVIOR_CALLBACK
1120  *
1121  *  @param  handle         Handle of the client that started the CCM operation.
1122  *
1123  *  @param  returnValue    The result of the CCM operation. May contain an error code.
1124  *                         Informs the application of why the callback function was
1125  *                         called.
1126  *
1127  *  @param  operationUnion A pointer to an operation union.
1128  *
1129  *  @param  operationType  This parameter determines which operation the
1130  *                         callback refers to.
1131  */
1132 typedef void (*AESCCM_CallbackFxn)(AESCCM_Handle handle,
1133                                    int_fast16_t returnValue,
1134                                    AESCCM_OperationUnion *operation,
1135                                    AESCCM_OperationType operationType);
1136 
1137 /*!
1138  *  @brief  CCM Parameters
1139  *
1140  *  CCM Parameters used with the AESCCM_open() call. Default values for
1141  *  these parameters are set using AESCCM_Params_init().
1142  *
1143  *  @sa     AESCCM_Params_init()
1144  */
1145 typedef struct
1146 {
1147     AESCCM_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */
1148     AESCCM_CallbackFxn callbackFxn;       /*!< Callback function pointer */
1149     uint32_t timeout;                     /*!< Timeout before the driver returns an error in
1150                                            *   ::AESCCM_RETURN_BEHAVIOR_BLOCKING
1151                                            */
1152     void *custom;                         /*!< Custom argument used by driver
1153                                            *   implementation
1154                                            */
1155 } AESCCM_Params;
1156 
1157 /*!
1158  *  @brief Default AESCCM_Params structure
1159  *
1160  *  @sa    #AESCCM_Params_init()
1161  */
1162 extern const AESCCM_Params AESCCM_defaultParams;
1163 
1164 /*!
1165  *  @brief  This function initializes the CCM module.
1166  *
1167  *  @pre    The AESCCM_config structure must exist and be persistent before this
1168  *          function can be called. This function must also be called before
1169  *          any other CCM driver APIs. This function call does not modify any
1170  *          peripheral registers.
1171  */
1172 void AESCCM_init(void);
1173 
1174 /*!
1175  *  @brief  Function to initialize the #AESCCM_Params struct to its defaults
1176  *
1177  *  @param  params      An pointer to #AESCCM_Params structure for
1178  *                      initialization
1179  *
1180  *  Defaults values are:
1181  *      returnBehavior              = AESCCM_RETURN_BEHAVIOR_BLOCKING
1182  *      callbackFxn                 = NULL
1183  *      timeout                     = SemaphoreP_WAIT_FOREVER
1184  *      custom                      = NULL
1185  */
1186 void AESCCM_Params_init(AESCCM_Params *params);
1187 
1188 /*!
1189  *  @brief  This function opens a given CCM peripheral.
1190  *
1191  *  @pre    CCM controller has been initialized using #AESCCM_init()
1192  *
1193  *  @param  [in] index    Logical peripheral number for the CCM indexed into
1194  *                        the AESCCM_config table
1195  *
1196  *  @param  [in] params   Pointer to an parameter block, if NULL it will use
1197  *                        default values.
1198  *
1199  *  @return An AESCCM_Handle on success or a NULL on an error or if it has been
1200  *          opened already.
1201  *
1202  *  @sa     #AESCCM_init()
1203  *  @sa     #AESCCM_close()
1204  */
1205 AESCCM_Handle AESCCM_open(uint_least8_t index, const AESCCM_Params *params);
1206 
1207 /*!
1208  *  @brief  Function to close a CCM peripheral specified by the CCM handle
1209  *
1210  *  @pre    #AESCCM_open() or #AESCCM_construct()
1211  *
1212  *  @param  [in] handle A CCM handle
1213  *
1214  *  @sa     #AESCCM_open()
1215  */
1216 void AESCCM_close(AESCCM_Handle handle);
1217 
1218 /*!
1219  *  @brief  Function to prepare a segmented AESCCM encryption operation.
1220  *
1221  *  This function sets up a segmented AESCCM encryption operation.
1222  *
1223  *  @pre    #AESCCM_open() or #AESCCM_construct()
1224  *
1225  *  @param  [in] handle                A CCM handle returned from #AESCCM_open()
1226  *                                     or #AESCCM_construct()
1227  *
1228  *  @param  [in] key                   Pointer to a previously initialized CryptoKey.
1229  *
1230  *  @param  [in] totalAADLength        Total size of the AAD in bytes.
1231  *                                     This value can be 0 and later provided
1232  *                                     by #AESCCM_setLengths().
1233  *
1234  *  @param  [in] totalPlaintextLength  Total size of the plaintext in bytes.
1235  *                                     This value can be 0 and later provided
1236  *                                     by #AESCCM_setLengths().
1237  *
1238  *  @param  [in] macLength             Size of the MAC in bytes. This value
1239  *                                     can be 0 and later provided by
1240  *                                     #AESCCM_setLengths().
1241  *
1242  *  @retval #AESCCM_STATUS_SUCCESS                  The operation succeeded.
1243  *  @retval #AESCCM_STATUS_ERROR                    The operation failed.
1244  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED    The operation is not supported in this device.
1245  *
1246  *  @post   #AESCCM_addAAD()
1247  *  @post   #AESCCM_addData()
1248  */
1249 int_fast16_t AESCCM_setupEncrypt(AESCCM_Handle handle,
1250                                  const CryptoKey *key,
1251                                  size_t totalAADLength,
1252                                  size_t totalPlaintextLength,
1253                                  size_t macLength);
1254 
1255 /*!
1256  *  @brief  Function to prepare a segmented AESCCM decryption operation.
1257  *
1258  *  This function sets up a segmented AESCCM decryption operation.
1259  *
1260  *  @pre    #AESCCM_open() or #AESCCM_construct()
1261  *
1262  *  @param  [in] handle                A CCM handle returned from #AESCCM_open()
1263  *                                     or #AESCCM_construct()
1264  *
1265  *  @param  [in] key                   Pointer to a previously initialized CryptoKey.
1266  *
1267  *  @param  [in] totalAADLength        Total size of the AAD in bytes.
1268  *                                     This value can be 0 and later provided
1269  *                                     by #AESCCM_setLengths().
1270  *
1271  *  @param  [in] totalPlaintextLength  Total size of the plaintext in bytes
1272  *                                     This value can be 0 and later provided
1273  *                                     by #AESCCM_setLengths().
1274  *
1275  *  @param  [in] macLength             Size of the MAC in bytes. This value
1276  *                                     can be 0 and later provided by
1277  *                                     #AESCCM_setLengths().
1278  *
1279  *  @retval #AESCCM_STATUS_SUCCESS                  The operation succeeded.
1280  *  @retval #AESCCM_STATUS_ERROR                    The operation failed.
1281  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED    The operation is not supported in this device.
1282  *
1283  *  @post   #AESCCM_addAAD()
1284  *  @post   #AESCCM_addData()
1285  */
1286 int_fast16_t AESCCM_setupDecrypt(AESCCM_Handle handle,
1287                                  const CryptoKey *key,
1288                                  size_t totalAADLength,
1289                                  size_t totalPlaintextLength,
1290                                  size_t macLength);
1291 
1292 /*!
1293  *  @brief  Function to set the lengths of the message, additional data, and MAC.
1294  *
1295  *  This function declares the lengths of the message,
1296  *  additional authenticated data (AAD), and MAC.
1297  *
1298  *  @note   This function doesn't have to be called if the lengths above were
1299  *          specified in #AESCCM_setupEncrypt() or #AESCCM_setupDecrypt().
1300  *
1301  *  @pre    #AESCCM_setupEncrypt() or #AESCCM_setupDecrypt()
1302  *
1303  *  @param  [in] handle           A CCM handle returned from #AESCCM_open()
1304  *                                or #AESCCM_construct()
1305  *
1306  *  @param  [in] aadLength        Size of the non-encrypted AAD in bytes
1307  *
1308  *  @param  [in] plaintextLength  Size of the plaintext or ciphertext to encrypt or decrypt in bytes
1309  *
1310  *  @param  [in] macLength        Size of the MAC in bytes
1311  *
1312  *  @retval #AESCCM_STATUS_SUCCESS                  The operation succeeded.
1313  *  @retval #AESCCM_STATUS_ERROR                    The operation failed.
1314  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED    The operation is not supported in this device.
1315  *
1316  *  @post   #AESCCM_setNonce()
1317  *  @post   #AESCCM_generateNonce()
1318  */
1319 int_fast16_t AESCCM_setLengths(AESCCM_Handle handle, size_t aadLength, size_t plaintextLength, size_t macLength);
1320 
1321 /*!
1322  *  @brief  Function to set the nonce for an AES CCM segmented operation.
1323  *
1324  *  @pre    #AESCCM_setupEncrypt(), #AESCCM_setupDecrypt(), or #AESCCM_setLengths()
1325  *
1326  *  @param  [in] handle           A CCM handle returned from #AESCCM_open()
1327  *                                or #AESCCM_construct()
1328  *
1329  *  @param  [in] nonce            Pointer to the buffer containing the nonce
1330  *
1331  *  @param  [in] nonceLength      The length of the nonce in bytes
1332  *
1333  *  @retval #AESCCM_STATUS_SUCCESS                  The operation succeeded.
1334  *  @retval #AESCCM_STATUS_ERROR                    The operation failed.
1335  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED    The operation is not
1336  *                                                  supported in this device.
1337  *
1338  *  @post   #AESCCM_addAAD()
1339  *  @post   #AESCCM_addData()
1340  */
1341 int_fast16_t AESCCM_setNonce(AESCCM_Handle handle, const uint8_t *nonce, size_t nonceLength);
1342 
1343 /*!
1344  *  @brief  Function to generate a nonce for an AES CCM segmented encryption operation.
1345  *
1346  *  @pre    #AESCCM_setupEncrypt() or #AESCCM_setLengths()
1347  *
1348  *  @param  [in] handle       A CCM handle returned from #AESCCM_open()
1349  *                            or #AESCCM_construct()
1350  *
1351  *  @param  [in] nonce        Pointer to the buffer where the generated nonce
1352  *                            is to be written to
1353  *
1354  *  @param  [in] nonceSize    The length of the nonce buffer in bytes
1355  *
1356  *  @param  [out] nonceLength The length of the nonce actually written if the
1357  *                            operation was successful
1358  *
1359  *  @retval #AESCCM_STATUS_SUCCESS                  The operation succeeded.
1360  *  @retval #AESCCM_STATUS_ERROR                    The operation failed.
1361  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED    The operation is not
1362  *                                                  supported in this device.
1363  *
1364  *  @post   #AESCCM_addAAD()
1365  *  @post   #AESCCM_addData()
1366  */
1367 int_fast16_t AESCCM_generateNonce(AESCCM_Handle handle, uint8_t *nonce, size_t nonceSize, size_t *nonceLength);
1368 
1369 /*!
1370  *  @brief  Adds a segment of @a aad with a @a length in bytes to the generated MAC.
1371  *  The length must be a multiple of a block size, 16 bytes, unless passing in the last
1372  *  chunk of AAD.
1373  *
1374  *  #AESCCM_addAAD() may be called an arbitrary number of times before continuing the operation with
1375  *  #AESCCM_addData(), #AESCCM_finalizeEncrypt() or #AESCCM_finalizeDecrypt().
1376  *
1377  *  This function returns according to the return behavior set when opening the driver.
1378  *
1379  *  @note     This function must not be called after passing data to encrypt or
1380  *            decrypt with #AESCCM_addData().
1381  *
1382  *  @warning  When decrypting, do not use the output until
1383  *            #AESCCM_finalizeDecrypt() succeeds.
1384  *
1385  *  @pre      #AESCCM_setNonce() or #AESCCM_generateNonce()
1386  *
1387  *  @param    [in] handle         A CCM handle returned from #AESCCM_open() or #AESCCM_construct()
1388  *
1389  *  @param    [in] operation      Pointer to segmented AAD CCM operation structure
1390  *
1391  *  @retval   #AESCCM_STATUS_SUCCESS               The operation succeeded.
1392  *  @retval   #AESCCM_STATUS_ERROR                 The operation failed.
1393  *  @retval   #AESCCM_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available.
1394  *                                                 Try again later.
1395  *  @retval   #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device.
1396  *  @retval   #AESCCM_STATUS_CANCELED              The operation was canceled.
1397  *
1398  *  @post     #AESCCM_addAAD()
1399  *  @post     #AESCCM_addData()
1400  *  @post     #AESCCM_finalizeEncrypt()
1401  *  @post     #AESCCM_finalizeDecrypt()
1402  */
1403 int_fast16_t AESCCM_addAAD(AESCCM_Handle handle, AESCCM_SegmentedAADOperation *operation);
1404 
1405 /*!
1406  *  @brief  Adds a segment of @a data with a @a length in bytes to the plaintext/ciphertext
1407  *  output and generated MAC. The length must be a multiple of a block size, 16 bytes, unless
1408  *  passing in the last chunk of payload data.
1409  *
1410  *  #AESCCM_addData() may be called an arbitrary number of times before finishing the operation
1411  *  with #AESCCM_finalizeEncrypt() or #AESCCM_finalizeDecrypt().
1412  *
1413  *  This function returns according to the return behavior set when opening the driver.
1414  *
1415  *  @warning  When decrypting, do not use the output until
1416  *            #AESCCM_finalizeDecrypt() succeeds.
1417  *
1418  *  @pre      #AESCCM_setNonce() or #AESCCM_generateNonce()
1419  *
1420  *  @param    [in] handle         A CCM handle returned from #AESCCM_open() or #AESCCM_construct()
1421  *
1422  *  @param    [in] operation      Pointer to segmented data CCM operation structure
1423  *
1424  *  @retval   #AESCCM_STATUS_SUCCESS               The operation succeeded.
1425  *  @retval   #AESCCM_STATUS_ERROR                 The operation failed.
1426  *  @retval   #AESCCM_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available.
1427  *                                                 Try again later.
1428  *  @retval   #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device.
1429  *  @retval   #AESCCM_STATUS_CANCELED              The operation was canceled.
1430  *  @retval   #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
1431  *
1432  *  @post     #AESCCM_addData()
1433  *  @post     #AESCCM_finalizeEncrypt()
1434  *  @post     #AESCCM_finalizeDecrypt()
1435  */
1436 int_fast16_t AESCCM_addData(AESCCM_Handle handle, AESCCM_SegmentedDataOperation *operation);
1437 
1438 /*!
1439  *  @brief  Finalize the MAC and ciphertext.
1440  *
1441  *  This function finalizes the encryption of a dataset earlier provided
1442  *  by calls to #AESCCM_addAAD() and #AESCCM_addData() and creates a message
1443  *  authentication code. If additional data needs to be encrypted and verified
1444  *  as part of this call, set the operation structure @a inputLength accordingly.
1445  *
1446  *  The resulting output is a message authentication code and ciphertext.
1447  *
1448  *  @pre    #AESCCM_addAAD() or #AESCCM_addData()
1449  *
1450  *  @param  [in] handle         A CCM handle returned from #AESCCM_open() or #AESCCM_construct()
1451  *
1452  *  @param  [in] operation      Pointer to segmented finalize CCM operation structure
1453  *
1454  *  @retval #AESCCM_STATUS_SUCCESS               In ::AESCCM_RETURN_BEHAVIOR_BLOCKING and
1455  *                                               ::AESCCM_RETURN_BEHAVIOR_POLLING, this means the MAC
1456  *                                               was generated successfully. In ::AESCCM_RETURN_BEHAVIOR_CALLBACK,
1457  *                                               this means the operation started successfully.
1458  *  @retval #AESCCM_STATUS_ERROR                 The operation failed.
1459  *  @retval #AESCCM_STATUS_CANCELED              The operation was canceled.
1460  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device.
1461  *  @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
1462  */
1463 int_fast16_t AESCCM_finalizeEncrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation);
1464 
1465 /*!
1466  *  @brief  Finalize the MAC and plaintext and verify it.
1467  *
1468  *  This function finalizes the decryption of a dataset earlier provided
1469  *  by calls to AESCCM_addAAD() and AESCCM_addData() and verifies a provided message
1470  *  authentication code. If additional data needs to be decrypted and verified
1471  *  as part of this call, set the operation structure @a inputLength accordingly.
1472  *
1473  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
1474  *          Doing so can yield a corrupted MAC comparison.
1475  *
1476  *  The resulting output is a verification return code and plaintext.
1477  *
1478  *  @pre    #AESCCM_addAAD() or #AESCCM_addData()
1479  *
1480  *  @param  [in] handle         A CCM handle returned from #AESCCM_open() or #AESCCM_construct()
1481  *
1482  *  @param  [in] operation      Pointer to segmented finalize CCM operation structure
1483  *
1484  *  @retval #AESCCM_STATUS_SUCCESS               In ::AESCCM_RETURN_BEHAVIOR_BLOCKING and
1485  *                                               ::AESCCM_RETURN_BEHAVIOR_POLLING, this means the MAC
1486  *                                               was verified successfully. In ::AESCCM_RETURN_BEHAVIOR_CALLBACK,
1487  *                                               this means the operation started successfully.
1488  *  @retval #AESCCM_STATUS_ERROR                 The operation failed.
1489  *  @retval #AESCCM_STATUS_MAC_INVALID           The provided MAC did not match the recomputed one.
1490  *  @retval #AESCCM_STATUS_CANCELED              The operation was canceled.
1491  *  @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device.
1492  *  @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
1493  */
1494 int_fast16_t AESCCM_finalizeDecrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation);
1495 
1496 /*!
1497  *  @brief  Function to initialize an #AESCCM_Operation struct to its defaults
1498  *
1499  *  @deprecated  This function should be replaced by calls to operation-specific
1500  *               init functions.
1501  *
1502  *  @param       [in] operationStruct     A pointer to an #AESCCM_Operation structure for
1503  *                                        initialization
1504  *
1505  *  Defaults values are all zeros.
1506  */
1507 void AESCCM_Operation_init(AESCCM_Operation *operationStruct);
1508 
1509 /*!
1510  *  @brief  Function to initialize an #AESCCM_OneStepOperation struct to its defaults
1511  *
1512  *  @param       [in] operationStruct     A pointer to an #AESCCM_OneStepOperation structure for
1513  *                                        initialization
1514  *
1515  *  Defaults values are all zeros.
1516  */
1517 void AESCCM_OneStepOperation_init(AESCCM_OneStepOperation *operationStruct);
1518 
1519 /*!
1520  *  @brief  Function to initialize an #AESCCM_SegmentedAADOperation struct to its defaults
1521  *
1522  *  @param       [in] operationStruct     A pointer to an #AESCCM_SegmentedAADOperation structure
1523  *                                        for initialization
1524  *
1525  *  Defaults values are all zeros.
1526  */
1527 void AESCCM_SegmentedAADOperation_init(AESCCM_SegmentedAADOperation *operationStruct);
1528 
1529 /*!
1530  *  @brief  Function to initialize an #AESCCM_SegmentedDataOperation struct to its defaults
1531  *
1532  *  @param       [in] operationStruct     A pointer to an #AESCCM_SegmentedDataOperation structure
1533  *                                        for initialization
1534  *
1535  *  Defaults values are all zeros.
1536  */
1537 void AESCCM_SegmentedDataOperation_init(AESCCM_SegmentedDataOperation *operationStruct);
1538 
1539 /*!
1540  *  @brief  Function to initialize an #AESCCM_SegmentedFinalizeOperation struct to its defaults
1541  *
1542  *  @param       [in] operationStruct     A pointer to an #AESCCM_SegmentedFinalizeOperation structure
1543  *                                        for initialization
1544  *
1545  *  Defaults values are all zeros.
1546  */
1547 void AESCCM_SegmentedFinalizeOperation_init(AESCCM_SegmentedFinalizeOperation *operationStruct);
1548 
1549 /*!
1550  *  @brief  Function to perform an AESCCM encryption + authentication operation in one call.
1551  *
1552  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
1553  *          Doing so can yield corrupted ciphertext or incorrect authentication.
1554  *
1555  *  @pre    #AESCCM_open() or #AESCCM_construct() and #AESCCM_Operation_init() have to be called first.
1556  *
1557  *  @param  [in] handle                 A CCM handle returned from #AESCCM_open() or #AESCCM_construct()
1558  *
1559  *  @param  [in] operationStruct        A pointer to a struct containing the parameters required to perform the
1560  * operation.
1561  *
1562  *  @retval #AESCCM_STATUS_SUCCESS               The operation succeeded.
1563  *  @retval #AESCCM_STATUS_ERROR                 The operation failed.
1564  *  @retval #AESCCM_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
1565  *  @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
1566  *
1567  *  @sa     AESCCM_oneStepDecrypt()
1568  */
1569 int_fast16_t AESCCM_oneStepEncrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct);
1570 
1571 /*!
1572  *  @brief  Function to perform an AESCCM decryption + verification operation in one call.
1573  *
1574  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
1575  *          Doing so can yield corrupted plaintext or incorrectly failed verification.
1576  *
1577  *  @pre    #AESCCM_open() or #AESCCM_construct() and #AESCCM_Operation_init() have to be called first.
1578  *
1579  *  @param  [in] handle                 A CCM handle returned from #AESCCM_open() or #AESCCM_construct()
1580  *
1581  *  @param  [in] operationStruct        A pointer to a struct containing the parameters required to perform the
1582  * operation.
1583  *
1584  *  @retval #AESCCM_STATUS_SUCCESS               The operation succeeded.
1585  *  @retval #AESCCM_STATUS_ERROR                 The operation failed.
1586  *  @retval #AESCCM_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
1587  *  @retval #AESCCM_STATUS_MAC_INVALID           The provided MAC did not match the recomputed one.
1588  *  @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
1589  *
1590  *  @sa     AESCCM_oneStepEncrypt()
1591  */
1592 int_fast16_t AESCCM_oneStepDecrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct);
1593 
1594 /*!
1595  *  @brief Cancels an ongoing AESCCM operation.
1596  *
1597  *  Asynchronously cancels an AESCCM operation. Only available when using
1598  *  AESCCM_RETURN_BEHAVIOR_CALLBACK.
1599  *  The operation will terminate as though an error occurred. The
1600  *  return status code of the operation will be AESCCM_STATUS_CANCELED.
1601  *
1602  *  @param  [in] handle Handle of the operation to cancel
1603  *
1604  *  @retval #AESCCM_STATUS_SUCCESS               The operation was canceled, or the operation had already completed.
1605  *  @retval #AESCCM_STATUS_ERROR                 The driver was not in callback mode, or the operation's output
1606  *                                               and generated MAC weren't properly cleared.
1607  */
1608 int_fast16_t AESCCM_cancelOperation(AESCCM_Handle handle);
1609 
1610 /**
1611  *  @brief  Constructs a new AESCCM object
1612  *
1613  *  Unlike #AESCCM_open(), #AESCCM_construct() does not require the hwAttrs and
1614  *  object to be allocated in a #AESCCM_Config array that is indexed into.
1615  *  Instead, the #AESCCM_Config, hwAttrs, and object can be allocated at any
1616  *  location. This allows for relatively simple run-time allocation of temporary
1617  *  driver instances on the stack or the heap.
1618  *  The drawback is that this makes it more difficult to write device-agnostic
1619  *  code. If you use an ifdef with DeviceFamily, you can choose the correct
1620  *  object and hwAttrs to allocate. That compilation unit will be tied to the
1621  *  device it was compiled for at this point. To change devices, recompilation
1622  *  of the application with a different DeviceFamily setting is necessary.
1623  *
1624  *  @param  config #AESCCM_Config describing the location of the object and hwAttrs.
1625  *
1626  *  @param  params #AESCCM_Params to configure the driver instance.
1627  *
1628  *  @return        Returns a #AESCCM_Handle on success or NULL on failure.
1629  *
1630  *  @pre    The object struct @c config points to must be zeroed out prior to
1631  *          calling this function. Otherwise, unexpected behavior may ensue.
1632  */
1633 AESCCM_Handle AESCCM_construct(AESCCM_Config *config, const AESCCM_Params *params);
1634 
1635 #ifdef __cplusplus
1636 }
1637 #endif
1638 
1639 #endif /* ti_drivers_AESCCM__include */
1640