AESCCM.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021, 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  *
245  * ### Single call CCM decryption + verification with plaintext CryptoKey in callback return mode #
246  * @code
247  *
248  * #include <ti/drivers/AESCCM.h>
249  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
250  *
251  * ...
252  *
253  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
254  *
255  * uint8_t nonce[] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
256  * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
257  * uint8_t aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
258  * uint8_t mac[] = {0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0};
259  * uint8_t ciphertext[] = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
260  * 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
261  * 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84};
262  * uint8_t keyingMaterial[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
263  * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
264  * uint8_t plaintext[sizeof(ciphertext)];
265  *
266  * // The plaintext should be the following after the decryption operation:
267  * // {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
268  * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
269  * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}
270  *
271  *
272  * void ccmCallback(AESCCM_Handle handle,
273  * int_fast16_t returnValue,
274  * AESCCM_OperationUnion *operation,
275  * AESCCM_OperationType operationType) {
276  *
277  * if (returnValue != AESCCM_STATUS_SUCCESS) {
278  * // handle error
279  * }
280  * }
281  *
282  * AESCCM_OneStepOperation operation;
283  *
284  * void ccmStartFunction(void) {
285  * AESCCM_Handle handle;
286  * AESCCM_Params params;
287  * CryptoKey cryptoKey;
288  * int_fast16_t decryptionResult;
289  *
290  * AESCCM_Params_init(&params);
291  * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK;
292  * params.callbackFxn = ccmCallback;
293  *
294  * handle = AESCCM_open(0, &params);
295  *
296  * if (handle == NULL) {
297  * // handle error
298  * }
299  *
300  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
301  *
302  * AESCCM_OneStepOperation_init(&operation);
303  *
304  * operation.key = &cryptoKey;
305  * operation.aad = aad;
306  * operation.aadLength = sizeof(aad);
307  * operation.input = ciphertext;
308  * operation.output = plaintext;
309  * operation.inputLength = sizeof(ciphertext);
310  * operation.nonce = nonce;
311  * operation.nonceLength = sizeof(nonce);
312  * operation.mac = mac;
313  * operation.macLength = sizeof(mac);
314  *
315  * decryptionResult = AESCCM_oneStepDecrypt(handle, &operation);
316  *
317  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
318  * // handle error
319  * }
320  *
321  * // do other things while CCM operation completes in the background
322  *
323  * }
324  *
325  *
326  * @endcode
327  *
328  * ### Multi-step CCM encryption + authentication with plaintext CryptoKey in blocking return mode #
329  * @code
330  *
331  * #include <ti/drivers/AESCCM.h>
332  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
333  *
334  * ...
335  *
336  * #define AES_BLOCK_SIZE 16 // bytes
337  *
338  * AESCCM_Handle handle;
339  * CryptoKey cryptoKey;
340  * int_fast16_t encryptionResult;
341  *
342  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
343  *
344  * uint8_t keyingMaterial[16] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
345  * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
346  * uint8_t aad[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
347  * uint8_t plaintext[23] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
348  * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
349  * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E};
350  * uint8_t nonce[13] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
351  * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
352  * uint8_t mac[8];
353  * uint8_t ciphertext[sizeof(plaintext)];
354  *
355  * // The ciphertext should be the following after the encryption operation:
356  * // {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
357  * // 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
358  * // 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84}
359  *
360  * handle = AESCCM_open(0, NULL);
361  *
362  * if (handle == NULL) {
363  * // handle error
364  * }
365  *
366  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
367  *
368  * encryptionResult = AESCCM_setupEncrypt(handle, &cryptoKey, sizeof(aad), sizeof(plaintext), sizeof(mac));
369  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
370  * // handle error
371  * }
372  *
373  * encryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce));
374  * if (encryptionResult != AESCCM_STATUS_SUCCESS) {
375  * // handle error
376  * }
377  *
378  * AESCCM_SegmentedAADOperation segmentedAADOperation;
379  * AESCCM_SegmentedAADOperation_init(&segmentedAADOperation);
380  * segmentedAADOperation.aad = aad;
381  * segmentedAADOperation.aadLength = sizeof(aad);
382  *
383  * encryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation);
384  * if (encryptionResult != AESCCM_STATUS_SUCCESS) {
385  * // handle error
386  * }
387  *
388  * AESCCM_SegmentedDataOperation segmentedDataOperation;
389  * AESCCM_SegmentedDataOperation_init(&segmentedDataOperation);
390  * segmentedDataOperation.input = plaintext;
391  * segmentedDataOperation.output = ciphertext;
392  * // One should pass in data that is a block-sized multiple length
393  * // until passing in the last segment of data.
394  * // In that case, the input length simply needs to be a non-zero value.
395  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
396  *
397  * encryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
398  * if (encryptionResult != AESCCM_STATUS_SUCCESS) {
399  * // handle error
400  * }
401  *
402  * segmentedDataOperation.input = plaintext + AES_BLOCK_SIZE;
403  * segmentedDataOperation.output = ciphertext + AES_BLOCK_SIZE;
404  * segmentedDataOperation.inputLength = sizeof(plaintext) - AES_BLOCK_SIZE;
405  *
406  * encryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
407  * if (encryptionResult != AESCCM_STATUS_SUCCESS) {
408  * // handle error
409  * }
410  *
411  * AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
412  * AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
413  * segmentedFinalizeOperation.input = plaintext;
414  * segmentedFinalizeOperation.output = ciphertext;
415  *
416  * // You can finalize with no new data
417  * segmentedFinalizeOperation.inputLength = 0;
418  * segmentedFinalizeOperation.mac = mac;
419  * segmentedFinalizeOperation.macLength = sizeof(mac);
420  * encryptionResult = AESCCM_finalizeEncrypt(handle, &segmentedFinalizeOperation);
421  *
422  * if (encryptionResult != AESCCM_STATUS_SUCCESS) {
423  * // handle error
424  * }
425  *
426  * AESCCM_close(handle);
427  *
428  * @endcode
429  *
430  * ### Multi-step CCM decryption + verification with plaintext CryptoKey in callback return mode #
431  * @code
432  *
433  * #include <ti/drivers/AESCCM.h>
434  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
435  *
436  * ...
437  *
438  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
439  *
440  * uint8_t nonce[] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
441  * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
442  * uint8_t aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
443  * uint8_t mac[] = {0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0};
444  * uint8_t ciphertext[] = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
445  * 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
446  * 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84};
447  * uint8_t keyingMaterial[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
448  * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
449  * uint8_t plaintext[sizeof(ciphertext)];
450  *
451  * // The plaintext should be the following after the decryption operation:
452  * // {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
453  * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
454  * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}
455  *
456  *
457  * void ccmCallback(AESCCM_Handle handle,
458  * int_fast16_t returnValue,
459  * AESCCM_OperationUnion *operation,
460  * AESCCM_OperationType operationType) {
461  *
462  * if (returnValue != AESCCM_STATUS_SUCCESS) {
463  * // handle error
464  * }
465  *
466  * if(operationType == AESCCM_OPERATION_TYPE_DECRYPT ||
467  * operationType == AESCCM_OPERATION_TYPE_ENCRYPT)
468  * {
469  * // Callback fxn only used for one-shot operations
470  * // Use operation->oneStepOperation
471  * }
472  * else if(operationType == AESCCM_OP_TYPE_AAD_DECRYPT ||
473  * operationType == AESCCM_OP_TYPE_AAD_ENCRYPT)
474  * {
475  * // Callback fxn only used for segmented AAD operations
476  * // Use operation->segmentedAADOperation
477  * }
478  * else if(operationType == AESCCM_OP_TYPE_DATA_DECRYPT ||
479  * operationType == AESCCM_OP_TYPE_DATA_ENCRYPT)
480  * {
481  * // Callback fxn only used for segmented data operations
482  * // Use operation->segmentedDataOperation
483  * }
484  * else
485  * {
486  * // Callback fxn only used for segmented finalize operations
487  * // Use operation->segmentedFinalizeOperation
488  * }
489  * }
490  *
491  * void ccmStartFunction(void) {
492  * AESCCM_Handle handle;
493  * AESCCM_Params params;
494  * CryptoKey cryptoKey;
495  * int_fast16_t decryptionResult;
496  *
497  * AESCCM_Params_init(&params);
498  * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK;
499  * params.callbackFxn = ccmCallback;
500  *
501  * handle = AESCCM_open(0, &params);
502  *
503  * if (handle == NULL) {
504  * // handle error
505  * }
506  *
507  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
508  *
509  * decryptionResult = AESCCM_setupDecrypt(handle, &cryptoKey, 0, 0, 0);
510  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
511  * // handle error
512  * }
513  *
514  * // setLengths must be called if the AAD, input, and MAC lengths aren't provided in setupXXXX.
515  * decryptionResult = AESCCM_setLengths(handle, sizeof(aad), sizeof(ciphertext), sizeof(mac));
516  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
517  * // handle error
518  * }
519  *
520  * decryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce));
521  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
522  * // handle error
523  * }
524  *
525  * AESCCM_SegmentedAADOperation segmentedAADOperation;
526  * AESCCM_SegmentedAADOperation_init(&segmentedAADOperation);
527  * segmentedAADOperation.aad = aad;
528  * segmentedAADOperation.aadLength = sizeof(aad);
529  *
530  * decryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation);
531  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
532  * // handle error
533  * }
534  *
535  * AESCCM_SegmentedDataOperation segmentedDataOperation;
536  * AESCCM_SegmentedDataOperation_init(&segmentedDataOperation);
537  * segmentedDataOperation.input = ciphertext;
538  * segmentedDataOperation.output = plaintext;
539  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
540  *
541  * decryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
542  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
543  * // handle error
544  * }
545  *
546  * AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
547  * AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
548  * segmentedFinalizeOperation.input = ciphertext + AES_BLOCK_SIZE;
549  * segmentedFinalizeOperation.output = plaintext + AES_BLOCK_SIZE;
550  * segmentedFinalizeOperation.inputLength = sizeof(ciphertext) - AES_BLOCK_SIZE;
551  * segmentedFinalizeOperation.mac = mac;
552  * segmentedFinalizeOperation.macLength = sizeof(mac);
553  *
554  * decryptionResult = AESCCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
555  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
556  * // handle error
557  * }
558  *
559  * // do other things while CCM operation completes in the background
560  *
561  * }
562  *
563  * @endcode
564  *
565  * ### Multi-step CCM* decryption + verification with plaintext CryptoKey in callback return mode #
566  * @code
567  *
568  * #include <ti/drivers/AESCCM.h>
569  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
570  *
571  * ...
572  *
573  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
574  *
575  * uint8_t nonce[] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
576  * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5};
577  * uint8_t aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
578  * uint8_t mac[] = {0};
579  *
580  * // CCM* allows for unauthenticated encryption using CCM by allowing a MAC length of 0
581  * uint8_t macLength = 0;
582  * uint8_t ciphertext[] = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
583  * 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
584  * 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84};
585  * uint8_t keyingMaterial[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
586  * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
587  * uint8_t plaintext[sizeof(ciphertext)];
588  *
589  * // The plaintext should be the following after the decryption operation:
590  * // {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
591  * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
592  * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}
593  *
594  *
595  * void ccmCallback(AESCCM_Handle handle,
596  * int_fast16_t returnValue,
597  * AESCCM_OperationUnion *operation,
598  * AESCCM_OperationType operationType) {
599  *
600  * if (returnValue != AESCCM_STATUS_SUCCESS) {
601  * // handle error
602  * }
603  *
604  * if(operationType == AESCCM_OPERATION_TYPE_DECRYPT ||
605  * operationType == AESCCM_OPERATION_TYPE_ENCRYPT)
606  * {
607  * // Callback fxn only used for one-shot operations
608  * // Use operation->oneStepOperation
609  * }
610  * else if(operationType == AESCCM_OP_TYPE_AAD_DECRYPT ||
611  * operationType == AESCCM_OP_TYPE_AAD_ENCRYPT)
612  * {
613  * // Callback fxn only used for segmented AAD operations
614  * // Use operation->segmentedAADOperation
615  * }
616  * else if(operationType == AESCCM_OP_TYPE_DATA_DECRYPT ||
617  * operationType == AESCCM_OP_TYPE_DATA_ENCRYPT)
618  * {
619  * // Callback fxn only used for segmented data operations
620  * // Use operation->segmentedDataOperation
621  * }
622  * else
623  * {
624  * // Callback fxn only used for segmented finalize operations
625  * // Use operation->segmentedFinalizeOperation
626  * }
627  * }
628  *
629  * void ccmStartFunction(void) {
630  * AESCCM_Handle handle;
631  * AESCCM_Params params;
632  * CryptoKey cryptoKey;
633  * int_fast16_t decryptionResult;
634  *
635  * AESCCM_Params_init(&params);
636  * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK;
637  * params.callbackFxn = ccmCallback;
638  *
639  * handle = AESCCM_open(0, &params);
640  *
641  * if (handle == NULL) {
642  * // handle error
643  * }
644  *
645  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
646  *
647  * decryptionResult = AESCCM_setupDecrypt(handle, &cryptoKey, 0, 0, 0);
648  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
649  * // handle error
650  * }
651  *
652  * // setLengths must be called if the AAD, input, and MAC lengths aren't provided in setupXXXX.
653  * decryptionResult = AESCCM_setLengths(handle, sizeof(aad), sizeof(ciphertext), macLength);
654  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
655  * // handle error
656  * }
657  *
658  * decryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce));
659  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
660  * // handle error
661  * }
662  *
663  * AESCCM_SegmentedAADOperation segmentedAADOperation;
664  * AESCCM_SegmentedAADOperation_init(&segmentedAADOperation);
665  * segmentedAADOperation.aad = aad;
666  * segmentedAADOperation.aadLength = sizeof(aad);
667  *
668  * decryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation);
669  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
670  * // handle error
671  * }
672  *
673  * AESCCM_SegmentedDataOperation segmentedDataOperation;
674  * AESCCM_SegmentedDataOperation_init(&segmentedDataOperation);
675  * segmentedDataOperation.input = ciphertext;
676  * segmentedDataOperation.output = plaintext;
677  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
678  *
679  * decryptionResult = AESCCM_addData(handle, &segmentedDataOperation);
680  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
681  * // handle error
682  * }
683  *
684  * AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
685  * AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
686  * segmentedFinalizeOperation.input = ciphertext + AES_BLOCK_SIZE;
687  * segmentedFinalizeOperation.output = plaintext + AES_BLOCK_SIZE;
688  * segmentedFinalizeOperation.inputLength = sizeof(ciphertext) - AES_BLOCK_SIZE;
689  * segmentedFinalizeOperation.mac = mac;
690  * segmentedFinalizeOperation.macLength = macLength;
691  *
692  * decryptionResult = AESCCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
693  * if (decryptionResult != AESCCM_STATUS_SUCCESS) {
694  * // handle error
695  * }
696  *
697  * // do other things while CCM operation completes in the background
698  *
699  * }
700  *
701  * @endcode
702  */
703 
704 #ifndef ti_drivers_AESCCM__include
705 #define ti_drivers_AESCCM__include
706 
707 #include <stdbool.h>
708 #include <stddef.h>
709 #include <stdint.h>
710 
711 #include <ti/drivers/AESCommon.h>
713 
714 #ifdef __cplusplus
715 extern "C" {
716 #endif
717 
730 #define AESCCM_STATUS_RESERVED AES_STATUS_RESERVED
731 
738 #define AESCCM_STATUS_SUCCESS AES_STATUS_SUCCESS
739 
746 #define AESCCM_STATUS_ERROR AES_STATUS_ERROR
747 
756 #define AESCCM_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
757 
761 #define AESCCM_STATUS_CANCELED AES_STATUS_CANCELED
762 
770 #define AESCCM_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID
771 
776 #define AESCCM_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
777 
781 #define AESCCM_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
782 
787 #define AESCCM_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
788 
795 #define AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
796 
809 
813 typedef AESCCM_Config *AESCCM_Handle;
814 
836 typedef enum
837 {
856 
860 typedef enum
861 {
864 } AESCCM_Mode;
865 
870 typedef struct
871 {
873  uint8_t *aad;
877  uint8_t *input;
882  uint8_t *output;
888  uint8_t *nonce;
893  uint8_t *mac;
899  size_t aadLength;
904  size_t inputLength;
910  uint8_t nonceLength;
913  uint8_t macLength;
923 
929 typedef struct
930 {
931  uint8_t *aad;
935  size_t aadLength;
941 
947 typedef struct
948 {
949  uint8_t *input;
954  uint8_t *output;
960  size_t inputLength;
966 
972 typedef struct
973 {
974  uint8_t *input;
979  uint8_t *output;
985  uint8_t *mac;
991  size_t inputLength;
997  uint8_t macLength;
1003 
1012 
1018 {
1019  AESCCM_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */
1020  AESCCM_SegmentedAADOperation segmentedAADOperation; /* Segmented AAD operation element of the operation union */
1021  AESCCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */
1022  AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the
1023  operation union */
1025 
1029 typedef enum
1030 {
1031  AESCCM_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */
1033  AESCCM_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not
1034  being unique */
1043 
1059 typedef void (*AESCCM_CallbackFxn)(AESCCM_Handle handle,
1060  int_fast16_t returnValue,
1061  AESCCM_OperationUnion *operation,
1062  AESCCM_OperationType operationType);
1063 
1072 typedef struct
1073 {
1074  AESCCM_ReturnBehavior returnBehavior;
1076  uint32_t timeout;
1079  void *custom;
1082 } AESCCM_Params;
1083 
1089 extern const AESCCM_Params AESCCM_defaultParams;
1090 
1099 void AESCCM_init(void);
1100 
1114 
1132 AESCCM_Handle AESCCM_open(uint_least8_t index, const AESCCM_Params *params);
1133 
1143 void AESCCM_close(AESCCM_Handle handle);
1144 
1176 int_fast16_t AESCCM_setupEncrypt(AESCCM_Handle handle,
1177  const CryptoKey *key,
1178  size_t totalAADLength,
1179  size_t totalPlaintextLength,
1180  size_t macLength);
1181 
1213 int_fast16_t AESCCM_setupDecrypt(AESCCM_Handle handle,
1214  const CryptoKey *key,
1215  size_t totalAADLength,
1216  size_t totalPlaintextLength,
1217  size_t macLength);
1218 
1246 int_fast16_t AESCCM_setLengths(AESCCM_Handle handle, size_t aadLength, size_t plaintextLength, size_t macLength);
1247 
1268 int_fast16_t AESCCM_setNonce(AESCCM_Handle handle, const uint8_t *nonce, size_t nonceLength);
1269 
1294 int_fast16_t AESCCM_generateNonce(AESCCM_Handle handle, uint8_t *nonce, size_t nonceSize, size_t *nonceLength);
1295 
1330 int_fast16_t AESCCM_addAAD(AESCCM_Handle handle, AESCCM_SegmentedAADOperation *operation);
1331 
1363 int_fast16_t AESCCM_addData(AESCCM_Handle handle, AESCCM_SegmentedDataOperation *operation);
1364 
1390 int_fast16_t AESCCM_finalizeEncrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation);
1391 
1421 int_fast16_t AESCCM_finalizeDecrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation);
1422 
1434 void AESCCM_Operation_init(AESCCM_Operation *operationStruct);
1435 
1445 
1455 
1465 
1475 
1496 int_fast16_t AESCCM_oneStepEncrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct);
1497 
1519 int_fast16_t AESCCM_oneStepDecrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct);
1520 
1535 int_fast16_t AESCCM_cancelOperation(AESCCM_Handle handle);
1536 
1560 AESCCM_Handle AESCCM_construct(AESCCM_Config *config, const AESCCM_Params *params);
1561 
1562 #ifdef __cplusplus
1563 }
1564 #endif
1565 
1566 #endif /* ti_drivers_AESCCM__include */
int_fast16_t AESCCM_oneStepDecrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct)
Function to perform an AESCCM decryption + verification operation in one call.
uint8_t * output
Definition: AESCCM.h:954
int_fast16_t AESCCM_generateNonce(AESCCM_Handle handle, uint8_t *nonce, size_t nonceSize, size_t *nonceLength)
Function to generate a nonce for an AES CCM segmented encryption operation.
ADC_Params params
Definition: Driver_Init.h:11
int_fast16_t AESCCM_finalizeDecrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and plaintext and verify it.
The CryptoKey type is an opaque representation of a cryptographic key.
uint8_t * aad
Definition: AESCCM.h:931
Struct containing the parameters required for encrypting/decrypting a message in a segmented operatio...
Definition: AESCCM.h:947
Struct containing the parameters required for finalizing an encryption/decryption and authentication/...
Definition: AESCCM.h:972
uint8_t * output
Definition: AESCCM.h:979
Definition: AESCCM.h:1035
Definition: AESCCM.h:1037
Struct containing the parameters required for encrypting/decrypting and authenticating/verifying a me...
Definition: AESCCM.h:870
void AESCCM_OneStepOperation_init(AESCCM_OneStepOperation *operationStruct)
Function to initialize an AESCCM_OneStepOperation struct to its defaults.
uint32_t timeout
Definition: AESCCM.h:1076
AESCCM_SegmentedDataOperation segmentedDataOperation
Definition: AESCCM.h:1021
void * custom
Definition: AESCCM.h:1079
uint8_t macLength
Definition: AESCCM.h:997
Definition: AESCCM.h:1033
Definition: AESCCM.h:845
size_t inputLength
Definition: AESCCM.h:960
AESCCM_Handle AESCCM_open(uint_least8_t index, const AESCCM_Params *params)
This function opens a given CCM peripheral.
const AESCCM_Params AESCCM_defaultParams
Default AESCCM_Params structure.
AES Global configuration.
Definition: AESCommon.h:154
Definition: AESCCM.h:863
AESCCM_SegmentedAADOperation segmentedAADOperation
Definition: AESCCM.h:1020
Definition: AESCCM.h:1032
int_fast16_t AESCCM_setupDecrypt(AESCCM_Handle handle, const CryptoKey *key, size_t totalAADLength, size_t totalPlaintextLength, size_t macLength)
Function to prepare a segmented AESCCM decryption operation.
CCM Parameters.
Definition: AESCCM.h:1072
CryptoKey datastructure.
Definition: CryptoKey.h:198
uint8_t nonceLength
Definition: AESCCM.h:910
uint8_t * mac
Definition: AESCCM.h:985
int_fast16_t AESCCM_cancelOperation(AESCCM_Handle handle)
Cancels an ongoing AESCCM operation.
Definition: AESCommon.h:186
bool nonceInternallyGenerated
Definition: AESCCM.h:918
Definition: AESCommon.h:196
void AESCCM_SegmentedFinalizeOperation_init(AESCCM_SegmentedFinalizeOperation *operationStruct)
Function to initialize an AESCCM_SegmentedFinalizeOperation struct to its defaults.
int_fast16_t AESCCM_setLengths(AESCCM_Handle handle, size_t aadLength, size_t plaintextLength, size_t macLength)
Function to set the lengths of the message, additional data, and MAC.
Definition: AESCCM.h:838
void AESCCM_Params_init(AESCCM_Params *params)
Function to initialize the AESCCM_Params struct to its defaults.
Definition: AESCCM.h:1041
Struct containing the parameters required for authenticating/verifying additional data in a segmented...
Definition: AESCCM.h:929
uint8_t * input
Definition: AESCCM.h:974
int_fast16_t AESCCM_setNonce(AESCCM_Handle handle, const uint8_t *nonce, size_t nonceLength)
Function to set the nonce for an AES CCM segmented operation.
CryptoKey * key
Definition: AESCCM.h:872
size_t aadLength
Definition: AESCCM.h:899
size_t inputLength
Definition: AESCCM.h:904
size_t aadLength
Definition: AESCCM.h:935
Definition: AESCommon.h:192
Definition: AESCCM.h:850
uint8_t * output
Definition: AESCCM.h:882
int_fast16_t AESCCM_setupEncrypt(AESCCM_Handle handle, const CryptoKey *key, size_t totalAADLength, size_t totalPlaintextLength, size_t macLength)
Function to prepare a segmented AESCCM encryption operation.
size_t inputLength
Definition: AESCCM.h:991
union AESCCM_OperationUnion AESCCM_OperationUnion
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
void(* AESCCM_CallbackFxn)(AESCCM_Handle handle, int_fast16_t returnValue, AESCCM_OperationUnion *operation, AESCCM_OperationType operationType)
The definition of a callback function used by the AESCCM driver when used in AESCCM_RETURN_BEHAVIOR_C...
Definition: AESCCM.h:1059
AESCCM_Handle AESCCM_construct(AESCCM_Config *config, const AESCCM_Params *params)
Constructs a new AESCCM object.
int_fast16_t AESCCM_oneStepEncrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct)
Function to perform an AESCCM encryption + authentication operation in one call.
Definition: AESCCM.h:1039
uint8_t * aad
Definition: AESCCM.h:873
AESCCM_ReturnBehavior returnBehavior
Definition: AESCCM.h:1074
void AESCCM_Operation_init(AESCCM_Operation *operationStruct)
Function to initialize an AESCCM_Operation struct to its defaults.
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESCCM.h:1017
int_fast16_t AESCCM_addData(AESCCM_Handle handle, AESCCM_SegmentedDataOperation *operation)
Adds a segment of data with a length in bytes to the plaintext/ciphertext output and generated MAC...
void AESCCM_close(AESCCM_Handle handle)
Function to close a CCM peripheral specified by the CCM handle.
AESCCM_CallbackFxn callbackFxn
Definition: AESCCM.h:1075
Definition: AESCCM.h:1038
AESCCM_Mode
Enum for the direction of the CCM operation.
Definition: AESCCM.h:860
uint8_t * mac
Definition: AESCCM.h:893
AESCCM_OperationType
Enum for the operation types supported by the driver.
Definition: AESCCM.h:1029
AESCCM_Config * AESCCM_Handle
A handle that is returned from an AESCCM_open() call.
Definition: AESCCM.h:813
uint8_t * input
Definition: AESCCM.h:949
AESCCM_ReturnBehavior
The way in which CCM function calls return after performing an encryption + authentication or decrypt...
Definition: AESCCM.h:836
Definition: AESCCM.h:862
void AESCCM_init(void)
This function initializes the CCM module.
Definition: AESCCM.h:1036
uint8_t macLength
Definition: AESCCM.h:913
int_fast16_t AESCCM_addAAD(AESCCM_Handle handle, AESCCM_SegmentedAADOperation *operation)
Adds a segment of aad with a length in bytes to the generated MAC. The length must be a multiple of a...
void AESCCM_SegmentedAADOperation_init(AESCCM_SegmentedAADOperation *operationStruct)
Function to initialize an AESCCM_SegmentedAADOperation struct to its defaults.
AES common module header for all devices.
uint8_t * input
Definition: AESCCM.h:877
AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation
Definition: AESCCM.h:1022
Definition: AESCCM.h:1040
AESCCM_OneStepOperation oneStepOperation
Definition: AESCCM.h:1019
Definition: AESCCM.h:1031
void AESCCM_SegmentedDataOperation_init(AESCCM_SegmentedDataOperation *operationStruct)
Function to initialize an AESCCM_SegmentedDataOperation struct to its defaults.
AESCommon_Config AESCCM_Config
AESCCM Global configuration.
Definition: AESCCM.h:808
uint8_t * nonce
Definition: AESCCM.h:888
AESCCM_OneStepOperation AESCCM_Operation
Definition: AESCCM.h:1011
int_fast16_t AESCCM_finalizeEncrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and ciphertext.
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale