1 /*
2  * Copyright (c) 2019-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       AESCMAC.h
34  *
35  *  @brief      AESCMAC (CMAC and CBC-MAC) driver header
36  *
37  *  @anchor ti_drivers_AESCMAC_Overview
38  *  # Overview #
39  *  The Cipher-based Message Authentication Code (CMAC) and Cipher Block Chaining
40  *  Message Authentication Code (CBC-MAC) are generic block cipher modes of
41  *  operation. They can be used with any block cipher but this driver
42  *  implementation uses AES.
43  *
44  *  Both CMAC and CBC-MAC create a message authentication code from a message of
45  *  any practical length to provide authenticity and integrity assurances.
46  *  CMAC is recommended over CBC-MAC because CBC-MAC is not secure for variable
47  *  length messages.
48  *
49  *  ## CBC-MAC Drawbacks #
50  *  CBC-MAC is only secure for fixed-length messages. Any single key must only be
51  *  used for messages of a fixed and known length. The CMAC algorithm, which
52  *  is based on a variation of CBC-MAC at its core, was developed to address that
53  *  security deficiency and is the MAC algorithm recommended by NIST.
54  *
55  *  @anchor ti_drivers_AESCMAC_Usage
56  *  # CMAC Usage #
57  *  ## Before starting a CMAC operation #
58  *
59  *  Before starting a CMAC operation, the application must do the following:
60  *      - Call #AESCMAC_init() to initialize the driver
61  *      - Call #AESCMAC_Params_init() to initialize the #AESCMAC_Params to default values.
62  *      - Modify the #AESCMAC_Params as desired
63  *      - Call #AESCMAC_open() to open an instance of the driver
64  *      - Initialize a CryptoKey. These opaque data structures are representations
65  *        of keying material and its storage. Depending on how the keying material
66  *        is stored (RAM or flash, key store), the CryptoKey must be
67  *        initialized differently. The CMAC API can handle all types of CryptoKey.
68  *        However, not all device-specific implementations support all types of CryptoKey.
69  *        Devices without a key store will not support CryptoKeys with keying material
70  *        stored in a key store for example.
71  *        All devices support plaintext CryptoKeys.
72  *
73  *  ## Starting a CMAC operation #
74  *
75  *  The #AESCMAC_oneStepSign and #AESCMAC_oneStepVerify functions perform a CMAC operation
76  *  in a single call. They will always be the most highly optimized routines with the
77  *  least overhead and the fastest runtime. However, they require all plaintext
78  *  or ciphertext to be available to the function at the start of the call.
79  *  All devices support single call operations.
80  *
81  *  ## After the CMAC operation completes #
82  *
83  *  After the CMAC operation completes, the application should either start
84  *  another operation or close the driver by calling #AESCMAC_close().
85  *
86  *  @anchor ti_drivers_AESCMAC_Synopsis
87  *  ## Synopsis
88  *  @anchor ti_drivers_AESCMAC_Synopsis_Code
89  *  @code
90  *  // Import CMAC Driver definitions
91  *  #include <ti/drivers/CMAC.h>
92  *
93  *  // Define name for CMAC channel index
94  *  #define AESCMAC_INSTANCE 0
95  *
96  *  AESCMAC_init();
97  *
98  *  handle = AESCMAC_open(AESCMAC_INSTANCE, NULL);
99  *
100  *  // Initialize symmetric key
101  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
102  *
103  *  // Initialize the operation
104  *  AESCMAC_Operation_init(&operation);
105  *  operation.input         = input;
106  *  operation.inputLength   = sizeof(input);
107  *  operation.mac           = mac;
108  *  operation.macLength     = sizeof(mac);
109  *
110  *  signResult = AESCMAC_oneStepSign(handle, &operation, &cryptoKey);
111  *
112  *  AESCMAC_close(handle);
113  *  @endcode
114  *
115  *  @anchor ti_drivers_AESCMAC_Examples
116  *  ## Examples
117  *
118  *  ### Single call CMAC authentication with plaintext CryptoKey in blocking return mode #
119  *  @code
120  *
121  *  #include <ti/drivers/AESCMAC.h>
122  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
123  *
124  *  ...
125  *
126  *  uint8_t message[16]         = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
127  *                                 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A};
128  *  uint8_t keyingMaterial[16]  = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
129  *                                 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
130  *  uint8_t mac[16];
131  *
132  *  ...
133  *
134  *  CryptoKey cryptoKey;
135  *  AESCMAC_Params params;
136  *  AESCMAC_Operation operation;
137  *
138  *  AESCMAC_init();
139  *
140  *  AESCMAC_Handle handle = AESCMAC_open(0, NULL);
141  *
142  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
143  *
144  *  AESCMAC_Operation_init(&operation);
145  *  operation.input        = input;
146  *  operation.inputLength  = sizeof(input);
147  *  operation.mac          = mac;
148  *  operation.macLength    = sizeof(mac);
149  *
150  *  int_fast16_t result = AESCMAC_oneStepSign(handle, &operation, &cryptoKey);
151  *
152  *  if (result != AESCMAC_STATUS_SUCCESS) {
153  *      // handle error
154  *  }
155  *
156  *  // The resulting MAC should equal the following after the operation:
157  *  // 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44,
158  *  // 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C
159  *
160  *  AESCMAC_close(handle);
161  *
162  *  @endcode
163  *
164  *  ### Single call CMAC authentication with plaintext CryptoKey in polling return mode and using HSM engine #
165  *  @code
166  *
167  *  #include <ti/drivers/AESCMAC.h>
168  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
169  *
170  *  ...
171  *
172  *  uint8_t message[16]         = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
173  *                                 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A};
174  *  uint8_t keyingMaterial[16]  = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
175  *                                 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
176  *  uint8_t mac[16];
177  *
178  *  ...
179  *
180  *  AESCMAC_Params params;
181  *  AESCMAC_Handle handle;
182  *  CryptoKey cryptoKey;
183  *  AESCMAC_Params_init(&params)
184  *  params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_POLLING;
185  *  params.operationalMode = AESCMAC_OPMODE_CBCMAC;
186  *  AESCMAC_Operation operation;
187  *
188  *  AESCMAC_init();
189  *
190  *  handle = AESCMAC_open(0, &params);
191  *
192  *  CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
193  *
194  *  AESCMAC_Operation_init(&operation);
195  *  operation.input        = input;
196  *  operation.inputLength  = sizeof(input);
197  *  operation.mac          = mac;
198  *  operation.macLength    = sizeof(mac);
199  *
200  *  int_fast16_t result = AESCMAC_oneStepSign(handle, &operation, &cryptoKey);
201  *
202  *  if (result != AESCMAC_STATUS_SUCCESS) {
203  *      // handle error
204  *  }
205  *
206  *  // The resulting MAC should equal the following after the operation:
207  *  // 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44,
208  *  // 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C
209  *
210  *  AESCMAC_close(handle);
211  *
212  *  @endcode
213  *
214  *  ### Single call CMAC verification with plaintext CryptoKey in callback return mode #
215  *  @code
216  *
217  *  #include <ti/drivers/AESCMAC.h>
218  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
219  *
220  *  ...
221  *  uint8_t message[16]         = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
222  *                                 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A};
223  *  uint8_t keyingMaterial[16]  = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
224  *                                 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
225  *  uint8_t expectedMac[16]     = {0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44,
226  *                                 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C};
227  *
228  *  void cmacCallback(AESCMAC_Handle handle,
229  *                    int_fast16_t returnValue) {
230  *      if (returnValue != AESCMAC_STATUS_SUCCESS) {
231  *          // handle error
232  *      }
233  *  }
234  *
235  *  void cmacStartFunction(void) {
236  *      AESCMAC_Handle handle;
237  *      AESCMAC_Params params;
238  *      AESCMAC_Operation operation;
239  *      CryptoKey cryptoKey;
240  *      int_fast16_t verificationResult;
241  *
242  *      AESCMAC_Params_init(&params);
243  *      params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_CALLBACK;
244  *      params.callbackFxn = cmacCallback;
245  *      handle = AESCMAC_open(0, &params);
246  *      if (handle == NULL) {
247  *          // handle error
248  *      }
249  *
250  *      CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
251  *
252  *      AESCMAC_Operation_init(&operation);
253  *      operation.input        = input;
254  *      operation.inputLength  = sizeof(input);
255  *      operation.mac          = expectedMac;
256  *      operation.macLength    = sizeof(expectedMac);
257  *      verificationResult = AESCMAC_oneStepVerify(handle, &operation, &cryptoKey);
258  *
259  *      if (verificationResult != AESCMAC_STATUS_SUCCESS) {
260  *          // handle error
261  *      }
262  *      // do other things while CMAC operation completes in the background
263  *  }
264  *  @endcode
265  *
266  *  ### Multi-step CMAC signature with plaintext CryptoKey in blocking return mode #
267  *  @code
268  *
269  *  #include <ti/drivers/AESCMAC.h>
270  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
271  *
272  *  #define AES_BLOCK_SIZE 16  // bytes
273  *  ...
274  *
275  *  uint8_t keyingMaterial[32]  = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
276  *                                 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
277  *                                 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
278  *                                 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
279  *  uint8_t message[40]         = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
280  *                                 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
281  *                                 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
282  *                                 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
283  *                                 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11};
284  *  uint8_t mac[16];
285  *
286  *  CryptoKey cryptoKey;
287  *  AESCMAC_Params params;
288  *  AESCMAC_Operation operation;
289  *
290  *  AESCMAC_init();
291  *
292  *  AESCMAC_Handle handle = AESCMAC_open(0, NULL);
293  *
294  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
295  *
296  *  AESCMAC_Operation_init(&operation);
297  *
298  *  // Set up multi-step sign.
299  *  int_fast16_t result = AESCMAC_setupSign(handle, &cryptoKey);
300  *
301  *  if (result != AESCMAC_STATUS_SUCCESS) {
302  *      // handle error
303  *  }
304  *
305  *  size_t initialSegmentSize = AES_BLOCK_SIZE;
306  *
307  *  // Add first segment of data.
308  *  operation.input       = input;
309  *  operation.inputLength = initialSegmentSize;  // Must be a non-zero multiple of the block size (16-bytes) unless
310  * finalizing. result = AESCMAC_addData(handle, &operation);
311  *
312  *  if (result != AESCMAC_STATUS_SUCCESS) {
313  *      // handle error
314  *  }
315  *
316  *  // Finalize with the last segment of data.
317  *  operation.input        = &input[initialSegmentSize];
318  *  operation.inputLength  = sizeof(input) - initialSegmentSize;
319  *  operation.mac          = mac;
320  *  operation.macLength    = sizeof(mac);
321  *
322  *  result = AESCMAC_finalize(handle, &operation);
323  *
324  *  if (result != AESCMAC_STATUS_SUCCESS) {
325  *      // handle error
326  *  }
327  *
328  *  // The resulting MAC should equal the following after the operation:
329  *  // 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
330  *  // 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6
331  *  ...
332  *
333  *  AESCMAC_close(handle);
334  *
335  *  @endcode
336  *
337  *  @anchor ti_drivers_AESCBCMAC_Usage
338  *  # CBC-MAC Usage #
339  *  ## Before starting a CBC-MAC operation #
340  *
341  *  Before starting a CBC-MAC operation, the application must do the following:
342  *  - Call #AESCMAC_init() to initialize the driver
343  *  - Call #AESCMAC_Params_init() to initialize the #AESCMAC_Params to
344  *    default values.
345  *  - Set #AESCMAC_Params.operationalMode to #AESCMAC_OPMODE_CBCMAC.
346  *  - Modify the #AESCMAC_Params as desired
347  *    - Call #AESCMAC_open() to open an instance of the driver
348  *    - Initialize a CryptoKey. These opaque data structures are representations
349  *      of keying material and its storage. Depending on how the keying material
350  *      is stored (RAM or flash, key store, key blob), the CryptoKey must be
351  *      initialized differently. The AESCMAC API can handle all types of
352  *      CryptoKey. However, not all device-specific implementations support all
353  *      types of CryptoKey. Devices without a key store will not support
354  *      CryptoKeys with keying material stored in a key store for example. All
355  *      devices support plaintext CryptoKeys.
356  *  - Initialize the #AESCMAC_Operation using #AESCMAC_Operation_init()
357  *    and set all length, key, and buffer fields.
358  *
359  *  ## Starting a CBC-MAC operation #
360  *
361  *  The #AESCMAC_oneStepSign and #AESCMAC_oneStepVerify functions perform a
362  *  CBC-MAC operation in a single call. They will always be the most highly
363  *  optimized routines with the least overhead and the fastest runtime. However,
364  *  they require all plaintext or ciphertext to be available to the function at
365  *  the start of the call. All devices support single call operations.
366  *
367  *  ## After the CBC-MAC operation completes #
368  *
369  *  After the CBC-MAC operation completes, the application should either start
370  *  another operation or close the driver by calling #AESCMAC_close().
371  *
372  *  @anchor ti_drivers_AESCBCMAC_Synopsis
373  *  ## Synopsis
374  *  @anchor ti_drivers_AESCBCMAC_Synopsis_Code
375  *  @code
376  *  // Import AESCMAC Driver definitions
377  *  #include <ti/drivers/AESCMAC.h>
378  *
379  *  // Define name for AESCMAC channel index
380  *  #define AESCMAC_INSTANCE 0
381  *
382  *  AESCMAC_init();
383  *
384  *  AESCMAC_Params params;
385  *
386  *  AESCMAC_Params_init(&params);
387  *  params.operationalMode = AESCMAC_OPMODE_CBCMAC;
388  *
389  *  handle = AESCMAC_open(AESCMAC_INSTANCE, &params);
390  *
391  *  // Initialize symmetric key
392  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
393  *
394  *  // Set up AESCMAC_Operation
395  *  AESCMAC_Operation_init(&operation);
396  *  operation.input       = plaintext;
397  *  operation.inputLength = sizeof(plaintext);
398  *  operation.mac         = mac;
399  *  operation.macLength   = sizeof(mac);
400  *
401  *  signResult = AESCMAC_oneStepSign(handle, &operation);
402  *
403  *  AESCMAC_close(handle);
404  *  @endcode
405  *
406  *  @anchor ti_drivers_AESCBCMAC_Examples
407  *  ## Examples
408  *
409  *  ### One step AES CBC-MAC signature with plaintext CryptoKey in blocking return mode #
410  *  @code
411  *
412  *  #include <ti/drivers/AESCMAC.h>
413  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
414  *
415  *  ...
416  *
417  *  AESCMAC_Params params;
418  *  AESCMAC_Handle handle;
419  *  CryptoKey cryptoKey;
420  *  int_fast16_t signResult;
421  *
422  *  // For example purposes only.
423  *  // Test vector derived from RFC 3602 Case #2
424  *  uint8_t plaintext[32] =       {0x56, 0x2F, 0x15, 0x9A, 0x69, 0x0C, 0x3B, 0x2F,
425  *                                 0xD5, 0xBA, 0xB0, 0x62, 0x56, 0x23, 0x61, 0x57,
426  *                                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
427  *                                 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
428  *  uint8_t mac[16];
429  *  uint8_t keyingMaterial[16] =  {0xC2, 0x86, 0x69, 0x6D, 0x88, 0x7C, 0x9A, 0xA0,
430  *                                 0x61, 0x1B, 0xBB, 0x3E, 0x20, 0x25, 0xA4, 0x5A};
431  *
432  *  // The MAC should equal the following after the operation:
433  *  //  0x75, 0x86, 0x60, 0x2D, 0x25, 0x3C, 0xFF, 0xF9,
434  *  //  0x1B, 0x82, 0x66, 0xBE, 0xA6, 0xD6, 0x1A, 0xB1
435  *
436  *  AESCMAC_Params_init(&params);
437  *  params.operationalMode = AESCMAC_OPMODE_CBCMAC;
438  *
439  *  handle = AESCMAC_open(0, &params);
440  *
441  *  if (handle == NULL) {
442  *      // handle error
443  *  }
444  *
445  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
446  *
447  *  AESCMAC_Operation operation;
448  *  AESCMAC_Operation_init(&operation); // Optional as all struct members will be set before use.
449  *
450  *  operation.input         = plaintext;
451  *  operation.inputLength   = sizeof(plaintext);
452  *  operation.mac           = mac;
453  *  operation.macLength     = sizeof(mac);
454  *
455  *  signResult = AESCMAC_oneStepSign(handle, &operation, &cryptoKey);
456  *
457  *  if (signResult == AESCMAC_STATUS_SUCCESS) {
458  *      // signature is available in mac[] buffer.
459  *  }
460  *  else {
461  *      // handle error
462  *  }
463  *
464  *  AESCMAC_close(handle);
465  *
466  *  @endcode
467  *
468  *
469  *  ### Multi-step AES CBC-MAC verify with plaintext CryptoKey in polling return mode #
470  *  @code
471  *
472  *  #include <ti/drivers/AESCMAC.h>
473  *  #include <ti/drivers/types/cryptoKey/CryptoKey_Plaintext.h>
474  *
475  *  #define AES_BLOCK_SIZE 16  // bytes
476  *  ...
477  *
478  *  AESCMAC_Params params;
479  *  AESCMAC_Handle handle;
480  *  CryptoKey cryptoKey;
481  *  int_fast16_t retVal;
482  *
483  *  // For example purposes only.
484  *  // Test vector derived from RFC 3602 Case #2
485  *  uint8_t plaintext[32] =       {0x56, 0x2F, 0x15, 0x9A, 0x69, 0x0C, 0x3B, 0x2F,
486  *                                 0xD5, 0xBA, 0xB0, 0x62, 0x56, 0x23, 0x61, 0x57,
487  *                                 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
488  *                                 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
489  *  uint8_t mac[16] =             {0x75, 0x86, 0x60, 0x2D, 0x25, 0x3C, 0xFF, 0xF9,
490  *                                 0x1B, 0x82, 0x66, 0xBE, 0xA6, 0xD6, 0x1A, 0xB1}
491  *  uint8_t keyingMaterial[16] =  {0xC2, 0x86, 0x69, 0x6D, 0x88, 0x7C, 0x9A, 0xA0,
492  *                                 0x61, 0x1B, 0xBB, 0x3E, 0x20, 0x25, 0xA4, 0x5A};
493  *
494  *  AESCMAC_Params_init(&params)
495  *  params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_POLLING;
496  *  params.operationalMode = AESCMAC_OPMODE_CBCMAC;
497  *
498  *  handle = AESCMAC_open(0, &params);
499  *
500  *  if (handle == NULL) {
501  *      // handle error
502  *  }
503  *
504  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
505  *
506  *  AESCMAC_Operation operation;
507  *  AESCMAC_Operation_init(&operation); // Optional as all struct members will be set before use.
508  *
509  *  retVal = AESCMAC_setupVerify(handle, &cryptoKey);
510  *
511  *  if (retVal != AESCMAC_STATUS_SUCCESS) {
512  *      // handle error
513  *  }
514  *
515  *  operation.input        = plaintext;
516  *  operation.inputLength  = AES_BLOCK_SIZE;   // Must be a non-zero multiple of the block size (16-bytes) unless
517  * finalizing.
518  *  // Note: MAC pointer only needs to be set when finalizing operation.
519  *
520  *  retVal = AESCMAC_addData(handle, &operation);
521  *
522  *  if (retVal != AESCMAC_STATUS_SUCCESS) {
523  *      // handle error
524  *  }
525  *
526  *  operation.input        = plaintext + AES_BLOCK_SIZE;
527  *  operation.inputLength  = AES_BLOCK_SIZE;
528  *  operation.mac          = mac;
529  *  operation.macLength    = sizeof(mac);
530  *
531  *  retVal = AESCMAC_finalize(handle, &operation);
532  *
533  *  // retVal should be AESCMAC_STATUS_SUCCESS to indicate that the signature
534  *  // verification passed.
535  *
536  *  if (retVal == AESCMAC_STATUS_MAC_INVALID) {
537  *      // handle invalid MAC
538  *  }
539  *  else if (retVal != AESCMAC_STATUS_SUCCESS) {
540  *      // handle error
541  *  }
542  *
543  *  AESCMAC_close(handle);
544  *
545  *  @endcode
546  */
547 
548 #ifndef ti_drivers_AESCMAC__include
549 #define ti_drivers_AESCMAC__include
550 
551 #include <stdbool.h>
552 #include <stddef.h>
553 #include <stdint.h>
554 
555 #include <ti/drivers/AESCommon.h>
556 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
557 
558 #ifdef __cplusplus
559 extern "C" {
560 #endif
561 
562 /*!
563  * Common CMAC status code reservation offset.
564  * CMAC driver implementations should offset status codes with
565  * #AESCMAC_STATUS_RESERVED growing negatively.
566  *
567  * Example implementation specific status codes:
568  * @code
569  * #define AESCMACXYZ_STATUS_ERROR0    AESCMAC_STATUS_RESERVED - 0
570  * #define AESCMACXYZ_STATUS_ERROR1    AESCMAC_STATUS_RESERVED - 1
571  * #define AESCMACXYZ_STATUS_ERROR2    AESCMAC_STATUS_RESERVED - 2
572  * @endcode
573  */
574 #define AESCMAC_STATUS_RESERVED AES_STATUS_RESERVED
575 
576 /*!
577  * @brief   Successful status code.
578  *
579  * Functions return #AESCMAC_STATUS_SUCCESS if the function was executed
580  * successfully.
581  */
582 #define AESCMAC_STATUS_SUCCESS AES_STATUS_SUCCESS
583 
584 /*!
585  * @brief   Generic error status code.
586  *
587  * Functions return #AESCMAC_STATUS_ERROR if the function was not executed
588  * successfully and no more pertinent error code could be returned.
589  */
590 #define AESCMAC_STATUS_ERROR AES_STATUS_ERROR
591 
592 /*!
593  * @brief   An error status code returned if the hardware or software resource
594  * is currently unavailable.
595  *
596  * CMAC driver implementations may have hardware or software limitations on how
597  * many clients can simultaneously perform operations. This status code is returned
598  * if the mutual exclusion mechanism signals that an operation cannot currently be performed.
599  */
600 #define AESCMAC_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
601 
602 /*!
603  * @brief   The MAC verification failed.
604  *
605  * Functions return #AESCMAC_STATUS_MAC_INVALID if the MAC computed
606  * for the provided (key, message) pair did not match the MAC provided.
607  */
608 #define AESCMAC_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID
609 
610 /*!
611  *  @brief  The ongoing operation was canceled.
612  */
613 #define AESCMAC_STATUS_CANCELED AES_STATUS_CANCELED
614 
615 /*!
616  *  @brief  The operation requested is not supported either by the target hardware
617  *          or the driver implementation.
618  */
619 #define AESCMAC_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
620 
621 /*!
622  *  @brief  The operation tried to load a key from the keystore using an invalid key ID.
623  */
624 #define AESCMAC_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
625 
626 /*!
627  *  @brief  The key store module returned a generic error. See key store documentation
628  *  for additional details.
629  */
630 #define AESCMAC_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
631 
632 /*!
633  * @brief   The operation does not support non-word-aligned input.
634  *
635  * AESCMAC driver implementations may have restrictions on the alignment of
636  * input data due to performance limitations of the hardware.
637  */
638 #define AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
639 
640 /*!
641  *  @brief CMAC Global configuration
642  *
643  *  The #AESCMAC_Config structure contains a set of pointers used to characterize
644  *  the CMAC driver implementation.
645  *
646  *  This structure needs to be defined before calling #AESCMAC_init() and it must
647  *  not be changed thereafter.
648  *
649  *  @sa     #AESCMAC_init()
650  */
651 typedef AESCommon_Config AESCMAC_Config;
652 
653 /*!
654  *  @brief  A handle that is returned from an #AESCMAC_open() call.
655  */
656 typedef AESCMAC_Config *AESCMAC_Handle;
657 
658 /*!
659  * @brief   The return behavior of AESCMAC functions
660  *
661  * Not all AESCMAC operations exhibit the specified return behavior. Functions that do not
662  * require significant computation and cannot offload that computation to a background thread
663  * behave like regular functions. Which functions exhibit the specified return behavior is not
664  * implementation dependent. Specifically, a software-backed implementation run on the same
665  * CPU as the application will emulate the return behavior while not actually offloading
666  * the computation to the background thread.
667  *
668  * AESCMAC functions exhibiting the specified return behavior have restrictions on the
669  * context from which they may be called.
670  *
671  * |                                 | Task  | Hwi   | Swi   |
672  * |---------------------------------|-------|-------|-------|
673  * |AESCMAC_RETURN_BEHAVIOR_CALLBACK | X     | X     | X     |
674  * |AESCMAC_RETURN_BEHAVIOR_BLOCKING | X     |       |       |
675  * |AESCMAC_RETURN_BEHAVIOR_POLLING  | X     | X     | X     |
676  *
677  */
678 typedef enum
679 {
680     AESCMAC_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK,
681     /*!< The function call will return immediately while the
682      * MAC operation goes on in the background. The registered
683      * callback function is called after the operation completes.
684      * The context the callback function is called (task, HWI, SWI)
685      * is implementation-dependent.
686      */
687     AESCMAC_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING,
688     /*!< The function call will block while the MAC operation goes
689      * on in the background. MAC operation results are available
690      * after the function returns.
691      */
692     AESCMAC_RETURN_BEHAVIOR_POLLING  = AES_RETURN_BEHAVIOR_POLLING,
693     /*!< The function call will continuously poll a flag while MAC
694      * operation goes on in the background. MAC operation results
695      * are available after the function returns.
696      */
697 } AESCMAC_ReturnBehavior;
698 
699 /*!
700  *  @brief  Defines the operation modes for the AESCMAC driver.
701  *
702  *  By default, the driver will use CMAC to sign and verify messages.
703  *  To use CBC-MAC instead of CMAC, set the operationalMode in
704  *  #AESCMAC_Params accordingly before calling #AESCMAC_open or
705  *  #AESCMAC_construct. The operational mode persists throughout
706  *  the existance of the driver instance.
707  */
708 typedef enum
709 {
710     AESCMAC_OPMODE_CMAC   = 1, /*!< CMAC operational mode */
711     AESCMAC_OPMODE_CBCMAC = 2, /*!< CBC-MAC operational mode */
712 } AESCMAC_OperationalMode;
713 
714 /*!
715  *  @brief  Struct containing the parameters required for signing or verifying a message.
716  */
717 typedef struct
718 {
719     uint8_t *input;     /*!< - Sign: Pointer to the input message to
720                          *     be authenticated.
721                          *   - Verify: Pointer to the input message to be
722                          *     verified.
723                          */
724     uint8_t *mac;       /*!< - Sign: Pointer to the output buffer to write
725                          *     the generated MAC. Buffer size must be
726                          *     at least equal to @a macLength.
727                          *   - Verify: Pointer to the input MAC to be
728                          *     used for verification.
729                          */
730     size_t inputLength; /*!< Length of the input message in bytes.
731                          *   May be zero for CMAC but must be non-zero for CBC-MAC.
732                          *   See function descriptions for further restrictions.
733                          *   Max length supported may be limited depending on the return behavior.
734                          */
735     size_t macLength;   /*!< Length of the MAC in bytes.
736                          *   Must be <= 16. A length of < 8 is not recommended and
737                          *   should severely restrict MAC recomputation attempts.
738                          *   See appendix A of NIST SP800-38b for more information.
739                          */
740 } AESCMAC_Operation;
741 
742 /*!
743  *  @brief  Mask for the operation code.
744  */
745 #define AESCMAC_OP_CODE_MASK 0x0F /* bits 0-3 */
746 
747 /*!
748  *  @brief  Enum for the operation codes supported by the driver.
749  */
750 typedef enum
751 {
752     AESCMAC_OP_CODE_ONE_STEP = 0,
753     AESCMAC_OP_CODE_SEGMENTED,
754     AESCMAC_OP_CODE_FINALIZE
755 } AESCMAC_OperationCode;
756 
757 /*!
758  *  @brief  Flag indicating a sign operation. If this bit is not set, then it
759  *          is a verify operation.
760  */
761 #define AESCMAC_OP_FLAG_SIGN 0x10 /* bit 4 */
762 
763 /*!
764  *  @brief  Mask for all valid operation flags.
765  */
766 #define AESCMAC_OP_FLAGS_MASK (AESCMAC_OP_FLAG_SIGN | AESCMAC_OP_FLAG_VERIFY)
767 
768 /*!
769  *  @brief  Enum for the operation types supported by the driver.
770  */
771 typedef enum
772 {
773     AESCMAC_OP_TYPE_SIGN             = AESCMAC_OP_CODE_ONE_STEP | AESCMAC_OP_FLAG_SIGN,
774     AESCMAC_OP_TYPE_VERIFY           = AESCMAC_OP_CODE_ONE_STEP,
775     AESCMAC_OP_TYPE_SEGMENTED_SIGN   = AESCMAC_OP_CODE_SEGMENTED | AESCMAC_OP_FLAG_SIGN,
776     AESCMAC_OP_TYPE_SEGMENTED_VERIFY = AESCMAC_OP_CODE_SEGMENTED,
777     AESCMAC_OP_TYPE_FINALIZE_SIGN    = AESCMAC_OP_CODE_FINALIZE | AESCMAC_OP_FLAG_SIGN,
778     AESCMAC_OP_TYPE_FINALIZE_VERIFY  = AESCMAC_OP_CODE_FINALIZE
779 } AESCMAC_OperationType;
780 
781 /*!
782  *  @brief  The definition of a callback function used by the AESCMAC driver
783  *          when used in ::AESCMAC_RETURN_BEHAVIOR_CALLBACK
784  *
785  *  @param  handle        Handle of the client that started the AESCMAC operation.
786  *
787  *  @param  returnValue   The result of the AESCMAC operation. May contain an error code.
788  *                        Informs the application of why the callback function was
789  *                        called.
790  *
791  *  @param  operation     Pointer to an operation struct.
792  *
793  *  @param  operationType Indicates which operation the callback refers to.
794  */
795 typedef void (*AESCMAC_CallbackFxn)(AESCMAC_Handle handle,
796                                     int_fast16_t returnValue,
797                                     AESCMAC_Operation *operation,
798                                     AESCMAC_OperationType operationType);
799 
800 /*!
801  *  @brief  AESCMAC Parameters
802  *
803  *  CMAC Parameters are used to with the #AESCMAC_open() or #AESCMAC_construct() call.
804  *  Default values for these parameters are set using #AESCMAC_Params_init().
805  *
806  *  @sa     #AESCMAC_Params_init()
807  */
808 typedef struct
809 {
810     AESCMAC_ReturnBehavior returnBehavior;   /*!< Blocking, callback, or polling return behavior */
811     AESCMAC_OperationalMode operationalMode; /*!< CMAC or CBC-MAC operational mode */
812     AESCMAC_CallbackFxn callbackFxn;         /*!< Callback function pointer */
813     uint32_t timeout;                        /*!< Timeout before the driver returns an error in
814                                               *   ::AESCMAC_RETURN_BEHAVIOR_BLOCKING
815                                               */
816     void *custom;                            /*!< Custom argument used by driver
817                                               *   implementation
818                                               */
819 } AESCMAC_Params;
820 
821 /*!
822  *  @brief  Default #AESCMAC_Params structure
823  *
824  *  @sa     #AESCMAC_Params_init()
825  */
826 extern const AESCMAC_Params AESCMAC_defaultParams;
827 
828 /*!
829  *  @brief  Initializes the CMAC module.
830  *
831  *  @pre    The AESCMAC_config structure must exist and be persistent before this
832  *          function can be called. This function must also be called before
833  *          any other CMAC driver APIs. This function call does not modify any
834  *          peripheral registers.
835  */
836 void AESCMAC_init(void);
837 
838 /*!
839  *  @brief  Initializes the #AESCMAC_Params struct to its defaults
840  *
841  *  @param  [in] params  Pointer to #AESCMAC_Params structure for
842  *                       initialization
843  *
844  *  Defaults values are:
845  *      returnBehavior              = AESCMAC_RETURN_BEHAVIOR_BLOCKING
846  *      operationalMode             = AESCMAC_OPMODE_CMAC
847  *      callbackFxn                 = NULL
848  *      timeout                     = SemaphoreP_WAIT_FOREVER
849  *      custom                      = NULL
850  */
851 void AESCMAC_Params_init(AESCMAC_Params *params);
852 
853 /*!
854  *  @brief  Initializes an #AESCMAC_Operation struct to its defaults
855  *
856  *  @param  [in] operation  Pointer to an #AESCMAC_Operation structure for
857  *                          initialization
858  *
859  *  Defaults values are all zeros.
860  */
861 void AESCMAC_Operation_init(AESCMAC_Operation *operation);
862 
863 /*!
864  *  @brief  Opens a given AESCMAC peripheral.
865  *
866  *  @note   #AESCMAC_Params @a operationalMode may be set to enable CBC-MAC
867  *          mode but the default is CMAC mode
868  *
869  *  @pre    AESCMAC driver has been initialized using #AESCMAC_init()
870  *
871  *  @param  [in] index    Logical peripheral number for the CMAC indexed into
872  *                        the AESCMAC_config table
873  *
874  *  @param  [in] params   Pointer to a parameter block, if NULL it will use
875  *                        default values
876  *
877  *  @return An #AESCMAC_Handle on success or a NULL on an error or if it has
878  *          been opened already.
879  *
880  *  @sa     #AESCMAC_init()
881  *  @sa     #AESCMAC_close()
882  */
883 AESCMAC_Handle AESCMAC_open(uint_least8_t index, const AESCMAC_Params *params);
884 
885 /*!
886  *  @brief  Closes a AESCMAC peripheral specified by the CMAC handle
887  *
888  *  @pre    #AESCMAC_open() or #AESCMAC_construct()
889  *
890  *  @param  handle  AESCMAC handle
891  *
892  *  @sa     #AESCMAC_open()
893  *  @sa     #AESCMAC_construct()
894  */
895 void AESCMAC_close(AESCMAC_Handle handle);
896 
897 /*!
898  *  @brief  Prepares a segmented AESCMAC sign operation
899  *
900  *  This function sets up a segmented AESCMAC sign operation.
901  *  After a segmented operation is setup, it must be completed
902  *  with #AESCMAC_finalize or cancelled with #AESCMAC_cancelOperation
903  *  before another operation can be started.
904  *
905  *  @pre     #AESCMAC_open() or #AESCMAC_construct()
906  *
907  *  @param  [in] handle   AESCMAC handle
908  *
909  *  @param  [in] key      Pointer to a previously initialized CryptoKey.
910  *
911  *  @retval #AESCMAC_STATUS_SUCCESS   The operation succeeded. Segmented
912  *                                    data may now be added.
913  *  @retval #AESCMAC_STATUS_ERROR     The operation failed.
914  *
915  *  @post   #AESCMAC_addData() or #AESCMAC_finalize()
916  *
917  *  @sa     #AESCMAC_setupVerify()
918  */
919 int_fast16_t AESCMAC_setupSign(AESCMAC_Handle handle, const CryptoKey *key);
920 
921 /*!
922  *  @brief  Prepares a segmented AESCMAC verify operation
923  *
924  *  This function sets up a segmented AESCMAC verify operation.
925  *  After a segmented operation is setup, it must be completed
926  *  with #AESCMAC_finalize or cancelled with #AESCMAC_cancelOperation
927  *  before another operation can be started.
928  *
929  *  @pre    #AESCMAC_open() or #AESCMAC_construct()
930  *
931  *  @param  [in] handle   AESCMAC handle
932  *
933  *  @param  [in] key      Pointer to a previously initialized CryptoKey.
934  *
935  *  @retval #AESCMAC_STATUS_SUCCESS   The operation succeeded. Segmented
936  *                                    data may now be added.
937  *  @retval #AESCMAC_STATUS_ERROR     The operation failed.
938  *
939  *  @post   #AESCMAC_addData() or #AESCMAC_finalize()
940  *
941  *  @sa     #AESCMAC_setupSign()
942  */
943 int_fast16_t AESCMAC_setupVerify(AESCMAC_Handle handle, const CryptoKey *key);
944 
945 /*!
946  *  @brief  Adds data to the current segmented operation
947  *
948  *  The @a inputLength must be a non-zero multiple of the block size (16-bytes).
949  *  #AESCMAC_addData() may be called an arbitrary number of times before
950  *  finishing the operation with #AESCMAC_finalize().
951  *
952  *  This function blocks until the final MAC been computed.
953  *  It returns immediately when ::AESCMAC_RETURN_BEHAVIOR_CALLBACK is set.
954  *
955  *  @note   None of the buffers provided as arguments may be altered by the application
956  *          during an ongoing operation. Doing so can yield corrupted plaintext.
957  *
958  *  @pre    #AESCMAC_setupSign() or #AESCMAC_setupVerify()
959  *
960  *  @param  [in] handle      AESCMAC handle
961  *
962  *  @param  [in] operation   Pointer to CMAC operation structure()
963  *
964  *  @retval #AESCMAC_STATUS_SUCCESS               The operation succeeded.
965  *  @retval #AESCMAC_STATUS_ERROR                 The operation failed.
966  *  @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE  The required hardware
967  *                                                resource was not available.
968  *                                                Try again later.
969  *  @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input buffer was not word-aligned.
970  *
971  *  @post   #AESCMAC_addData() or #AESCMAC_finalize()
972  */
973 int_fast16_t AESCMAC_addData(AESCMAC_Handle handle, AESCMAC_Operation *operation);
974 
975 /*!
976  *  @brief  Finalizes the current segmented operation
977  *
978  *  For sign operations:
979  *  This function computes and writes back the final MAC @a mac of length
980  *  @a macLength.
981  *
982  *  For verify operations:
983  *  This function uses the provided MAC @a mac to authenticate an input message.
984  *  The return value indicates whether the authentication was successful.
985  *
986  *  @note   Finalizing without additional input data is not supported.
987  *          If finalization is attempted with @a inputLength of zero,
988  *          #AESCMAC_STATUS_ERROR will be returned and the caller must either
989  *          retry finalization with data or terminate the segmented operation
990  *          by calling #AESCMAC_cancelOperation.
991  *
992  *  @note   None of the buffers provided as arguments may be altered by the application
993  *          during an ongoing operation. Doing so can yield corrupted plaintext.
994  *
995  *  @pre    #AESCMAC_addData() or #AESCMAC_setupSign() or #AESCMAC_setupVerify()
996  *
997  *  @param  [in] handle      AESCMAC handle
998  *
999  *  @param  [in] operation   Pointer to CMAC operation structure()
1000  *
1001  *  @retval #AESCMAC_STATUS_SUCCESS       In ::AESCMAC_RETURN_BEHAVIOR_BLOCKING and
1002  *                                        ::AESCMAC_RETURN_BEHAVIOR_POLLING, this means the MAC
1003  *                                        was generated successfully. In ::AESCMAC_RETURN_BEHAVIOR_CALLBACK,
1004  *                                        this means the operation started successfully.
1005  *  @retval #AESCMAC_STATUS_ERROR         The operation failed.
1006  *  @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE    The required hardware
1007  *                                                  resource was not available.
1008  *                                                  Try again later.
1009  *  @retval #AESCMAC_STATUS_MAC_INVALID   The provided MAC did not match the generated MAC.
1010  *                                        This return value is only valid for verify operations.
1011  *  @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input buffer was not word-aligned.
1012  */
1013 int_fast16_t AESCMAC_finalize(AESCMAC_Handle handle, AESCMAC_Operation *operation);
1014 
1015 /*!
1016  *  @brief  Performs a AESCMAC signature in one call
1017  *
1018  *  This function uses the provided key to authenticate an input message.
1019  *  The resulting output is a message authentication code.
1020  *
1021  *  @note   None of the buffers provided as arguments may be altered by the application
1022  *          during an ongoing operation. Doing so can yield corrupted plaintext.
1023  *
1024  *  @pre    #AESCMAC_open() or #AESCMAC_construct()
1025  *
1026  *  @param  [in] handle      AESCMAC handle
1027  *
1028  *  @param  [in] operation   Pointer to AESCMAC operation structure
1029  *
1030  *  @param  [in] key         Pointer to a previously initialized CryptoKey
1031  *
1032  *  @retval #AESCMAC_STATUS_SUCCESS     In ::AESCMAC_RETURN_BEHAVIOR_BLOCKING and
1033  *                                      ::AESCMAC_RETURN_BEHAVIOR_POLLING, this means the MAC
1034  *                                      was generated successfully. In ::AESCMAC_RETURN_BEHAVIOR_CALLBACK,
1035  *                                      this means the operation started successfully.
1036  *  @retval #AESCMAC_STATUS_ERROR       The operation failed.
1037  *  @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE    The required hardware
1038  *                                                  resource was not available.
1039  *                                                  Try again later.
1040  *  @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input buffer was not word-aligned.
1041  *
1042  *  @sa     #AESCMAC_oneStepVerify()
1043  */
1044 int_fast16_t AESCMAC_oneStepSign(AESCMAC_Handle handle, AESCMAC_Operation *operation, CryptoKey *key);
1045 
1046 /*!
1047  *  @brief  Performs a AESCMAC verification in one call
1048  *
1049  *  This function verifies that the provided message authentication code
1050  *  matches the one generated by the provided key and input message.
1051  *
1052  *  @note   None of the buffers provided as arguments may be altered by the application
1053  *          during an ongoing operation. Doing so can yield corrupted plaintext.
1054  *
1055  *  @pre    #AESCMAC_open() or #AESCMAC_construct()
1056  *
1057  *  @param  [in] handle      AESCMAC handle
1058  *
1059  *  @param  [in] operation   Pointer to AESCMAC operation structure
1060  *
1061  *  @param  [in] key         Pointer to a previously initialized CryptoKey
1062  *
1063  *  @retval #AESCMAC_STATUS_SUCCESS      In ::AESCMAC_RETURN_BEHAVIOR_BLOCKING and
1064  *                                       ::AESCMAC_RETURN_BEHAVIOR_POLLING, this means the MAC
1065  *                                       was verified successfully. In ::AESCMAC_RETURN_BEHAVIOR_CALLBACK,
1066  *                                       this means the operation started successfully.
1067  *  @retval #AESCMAC_STATUS_ERROR        The operation failed.
1068  *  @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE    The required hardware
1069  *                                                  resource was not available.
1070  *                                                  Try again later.
1071  *  @retval #AESCMAC_STATUS_MAC_INVALID  The provided MAC did not match the generated MAC.
1072  *                                       This return value is only valid for verify operations.
1073  *  @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input buffer was not word-aligned.
1074  *
1075  *  @sa     AESCMAC_oneStepSign()
1076  */
1077 int_fast16_t AESCMAC_oneStepVerify(AESCMAC_Handle handle, AESCMAC_Operation *operation, CryptoKey *key);
1078 
1079 /*!
1080  *  @brief Cancels an ongoing AESCMAC operation.
1081  *
1082  *  Asynchronously cancels an AESCMAC operation. Only available when using
1083  *  AESCMAC_RETURN_BEHAVIOR_CALLBACK.
1084  *  The operation will terminate as though an error occurred. The
1085  *  return status code of the operation will be AESCMAC_STATUS_CANCELED.
1086  *
1087  *  @note Only the same thread that started an operation is permitted to cancel it.
1088  *        This function cannot be be called from an interrupt context or callback.
1089  *
1090  *  @param  [in] handle Handle of the operation to cancel
1091  *
1092  *  @retval #AESCMAC_STATUS_SUCCESS     The operation was canceled or the operation had already completed.
1093  */
1094 int_fast16_t AESCMAC_cancelOperation(AESCMAC_Handle handle);
1095 
1096 /**
1097  *  @brief  Constructs a new AESCMAC object
1098  *
1099  *  Unlike #AESCMAC_open(), #AESCMAC_construct() does not require the hwAttrs and
1100  *  object to be allocated in a #AESCMAC_Config array that is indexed into.
1101  *  Instead, the #AESCMAC_Config, hwAttrs, and object can be allocated at any
1102  *  location. This allows for relatively simple run-time allocation of temporary
1103  *  driver instances on the stack or the heap.
1104  *  The drawback is that this makes it more difficult to write device-agnostic
1105  *  code. If you use an ifdef with DeviceFamily, you can choose the correct
1106  *  object and hwAttrs to allocate. That compilation unit will be tied to the
1107  *  device it was compiled for at this point. To change devices, recompilation
1108  *  of the application with a different DeviceFamily setting is necessary.
1109  *
1110  *  @note   #AESCMAC_Params @a operationalMode may be set to
1111  *          enable CBC-MAC mode but the default is CMAC mode
1112  *
1113  *  @pre    The object struct @c config points to must be zeroed out prior to
1114  *          calling this function. Otherwise, unexpected behavior may ensue.
1115  *
1116  *  @param [in] config #AESCMAC_Config describing the location of the object and hwAttrs.
1117  *
1118  *  @param [in] params #AESCMAC_Params to configure the driver instance.
1119  *
1120  *  @return     Returns a #AESCMAC_Handle on success or NULL on failure.
1121  */
1122 AESCMAC_Handle AESCMAC_construct(AESCMAC_Config *config, const AESCMAC_Params *params);
1123 
1124 #ifdef __cplusplus
1125 }
1126 #endif
1127 
1128 #endif /* ti_drivers_AESCMAC__include */
1129