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 
712 
713 #ifdef __cplusplus
714 extern "C" {
715 #endif
716 
729 #define AESCCM_STATUS_RESERVED (-32)
730 
737 #define AESCCM_STATUS_SUCCESS (0)
738 
745 #define AESCCM_STATUS_ERROR (-1)
746 
755 #define AESCCM_STATUS_RESOURCE_UNAVAILABLE (-2)
756 
764 #define AESCCM_STATUS_MAC_INVALID (-3)
765 
769 #define AESCCM_STATUS_CANCELED (-4)
770 
777 #define AESCCM_STATUS_KEYSTORE_INVALID_ID (-5)
778 
785 #define AESCCM_STATUS_FEATURE_NOT_SUPPORTED (-6)
786 
791 #define AESCCM_STATUS_KEYSTORE_GENERIC_ERROR (-7)
792 
804 typedef struct {
806  void *object;
807 
809  void const *hwAttrs;
810 } AESCCM_Config;
811 
816 
838 typedef enum {
854 
858 typedef enum {
861 } AESCCM_Mode;
862 
867 typedef struct {
869  uint8_t *aad;
873  uint8_t *input;
878  uint8_t *output;
884  uint8_t *nonce;
889  uint8_t *mac;
895  size_t aadLength;
900  size_t inputLength;
905  uint8_t nonceLength;
908  uint8_t macLength;
918 
924 typedef struct {
925  uint8_t *aad;
929  size_t aadLength;
935 
941 typedef struct {
942  uint8_t *input;
947  uint8_t *output;
953  size_t inputLength;
958 
964 typedef struct {
965  uint8_t *input;
970  uint8_t *output;
976  uint8_t *mac;
982  size_t inputLength;
987  uint8_t macLength;
993 
1002 
1008 {
1009  AESCCM_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */
1010  AESCCM_SegmentedAADOperation segmentedAADOperation; /* Segmented AAD operation element of the operation union */
1011  AESCCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */
1012  AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the operation union */
1014 
1018 typedef enum {
1019  AESCCM_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */
1021  AESCCM_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not being unique */
1030 
1046 typedef void (*AESCCM_CallbackFxn) (AESCCM_Handle handle,
1047  int_fast16_t returnValue,
1048  AESCCM_OperationUnion *operation,
1049  AESCCM_OperationType operationType);
1050 
1059 typedef struct {
1062  uint32_t timeout;
1065  void *custom;
1068 } AESCCM_Params;
1069 
1075 extern const AESCCM_Params AESCCM_defaultParams;
1076 
1085 void AESCCM_init(void);
1086 
1100 
1118 AESCCM_Handle AESCCM_open(uint_least8_t index, const AESCCM_Params *params);
1119 
1129 void AESCCM_close(AESCCM_Handle handle);
1130 
1162 int_fast16_t AESCCM_setupEncrypt(AESCCM_Handle handle,
1163  const CryptoKey *key,
1164  size_t totalAADLength,
1165  size_t totalPlaintextLength,
1166  size_t macLength);
1167 
1199 int_fast16_t AESCCM_setupDecrypt(AESCCM_Handle handle,
1200  const CryptoKey *key,
1201  size_t totalAADLength,
1202  size_t totalPlaintextLength,
1203  size_t macLength);
1204 
1232 int_fast16_t AESCCM_setLengths(AESCCM_Handle handle,
1233  size_t aadLength,
1234  size_t plaintextLength,
1235  size_t macLength);
1236 
1257 int_fast16_t AESCCM_setNonce(AESCCM_Handle handle,
1258  const uint8_t *nonce,
1259  size_t nonceLength);
1260 
1285 int_fast16_t AESCCM_generateNonce(AESCCM_Handle handle,
1286  uint8_t *nonce,
1287  size_t nonceSize,
1288  size_t* nonceLength);
1289 
1323 int_fast16_t AESCCM_addAAD(AESCCM_Handle handle,
1324  AESCCM_SegmentedAADOperation *operation);
1325 
1355 int_fast16_t AESCCM_addData(AESCCM_Handle handle,
1356  AESCCM_SegmentedDataOperation *operation);
1357 
1382 int_fast16_t AESCCM_finalizeEncrypt(AESCCM_Handle handle,
1384 
1413 int_fast16_t AESCCM_finalizeDecrypt(AESCCM_Handle handle,
1415 
1427 void AESCCM_Operation_init(AESCCM_Operation *operationStruct);
1428 
1438 
1448 
1458 
1468 
1488 int_fast16_t AESCCM_oneStepEncrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct);
1489 
1510 int_fast16_t AESCCM_oneStepDecrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct);
1511 
1526 int_fast16_t AESCCM_cancelOperation(AESCCM_Handle handle);
1527 
1551 AESCCM_Handle AESCCM_construct(AESCCM_Config *config, const AESCCM_Params *params);
1552 
1553 #ifdef __cplusplus
1554 }
1555 #endif
1556 
1557 #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:947
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:925
Struct containing the parameters required for encrypting/decrypting a message in a segmented operatio...
Definition: AESCCM.h:941
Struct containing the parameters required for finalizing an encryption/decryption and authentication/...
Definition: AESCCM.h:964
uint8_t * output
Definition: AESCCM.h:970
void * object
Definition: AESCCM.h:806
Definition: AESCCM.h:1022
Definition: AESCCM.h:1024
Struct containing the parameters required for encrypting/decrypting and authenticating/verifying a me...
Definition: AESCCM.h:867
void AESCCM_OneStepOperation_init(AESCCM_OneStepOperation *operationStruct)
Function to initialize an AESCCM_OneStepOperation struct to its defaults.
uint32_t timeout
Definition: AESCCM.h:1062
AESCCM_SegmentedDataOperation segmentedDataOperation
Definition: AESCCM.h:1011
void * custom
Definition: AESCCM.h:1065
uint8_t macLength
Definition: AESCCM.h:987
Definition: AESCCM.h:1021
Definition: AESCCM.h:845
size_t inputLength
Definition: AESCCM.h:953
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.
Definition: AESCCM.h:860
AESCCM_SegmentedAADOperation segmentedAADOperation
Definition: AESCCM.h:1010
Definition: AESCCM.h:1020
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:1059
CryptoKey datastructure.
Definition: CryptoKey.h:192
uint8_t nonceLength
Definition: AESCCM.h:905
uint8_t * mac
Definition: AESCCM.h:976
int_fast16_t AESCCM_cancelOperation(AESCCM_Handle handle)
Cancels an ongoing AESCCM operation.
bool nonceInternallyGenerated
Definition: AESCCM.h:913
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:839
void AESCCM_Params_init(AESCCM_Params *params)
Function to initialize the AESCCM_Params struct to its defaults.
Definition: AESCCM.h:1028
Struct containing the parameters required for authenticating/verifying additional data in a segmented...
Definition: AESCCM.h:924
uint8_t * input
Definition: AESCCM.h:965
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:868
size_t aadLength
Definition: AESCCM.h:895
size_t inputLength
Definition: AESCCM.h:900
size_t aadLength
Definition: AESCCM.h:929
Definition: AESCCM.h:849
uint8_t * output
Definition: AESCCM.h:878
void const * hwAttrs
Definition: AESCCM.h:809
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:982
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:1046
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:1026
uint8_t * aad
Definition: AESCCM.h:869
AESCCM_ReturnBehavior returnBehavior
Definition: AESCCM.h:1060
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:1007
AESCCM Global configuration.
Definition: AESCCM.h:804
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:1061
Definition: AESCCM.h:1025
AESCCM_Mode
Enum for the direction of the CCM operation.
Definition: AESCCM.h:858
uint8_t * mac
Definition: AESCCM.h:889
AESCCM_OperationType
Enum for the operation types supported by the driver.
Definition: AESCCM.h:1018
AESCCM_Config * AESCCM_Handle
A handle that is returned from an AESCCM_open() call.
Definition: AESCCM.h:815
uint8_t * input
Definition: AESCCM.h:942
AESCCM_ReturnBehavior
The way in which CCM function calls return after performing an encryption + authentication or decrypt...
Definition: AESCCM.h:838
Definition: AESCCM.h:859
void AESCCM_init(void)
This function initializes the CCM module.
Definition: AESCCM.h:1023
uint8_t macLength
Definition: AESCCM.h:908
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.
uint8_t * input
Definition: AESCCM.h:873
AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation
Definition: AESCCM.h:1012
Definition: AESCCM.h:1027
AESCCM_OneStepOperation oneStepOperation
Definition: AESCCM.h:1009
Definition: AESCCM.h:1019
void AESCCM_SegmentedDataOperation_init(AESCCM_SegmentedDataOperation *operationStruct)
Function to initialize an AESCCM_SegmentedDataOperation struct to its defaults.
uint8_t * nonce
Definition: AESCCM.h:884
AESCCM_OneStepOperation AESCCM_Operation
Definition: AESCCM.h:1001
int_fast16_t AESCCM_finalizeEncrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and ciphertext.
© Copyright 1995-2021, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale