AESGCM.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2022, 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  *
34  * @file AESGCM.h
35  *
36  * @brief AESGCM driver header
37  *
38  * @anchor ti_drivers_AESGCM_Overview
39  * ### Overview #
40  *
41  * The Galois Counter Mode (GCM) mode of operation is a generic
42  * authenticated encryption with associated data (AEAD) block cipher mode.
43  * It can be implemented with any block cipher.
44  * AESGCM combines GHASH with the AES block cipher in CTR mode of operation.
45  *
46  * This combination of block cipher modes enables GCM to encrypt messages of any
47  * length and not only multiples of the block cipher block size.
48  *
49  * CTR provides confidentiality. The using GHASH and encrypting the result provides
50  * message integrity and authentication.
51  *
52  * The AES key is a shared secret between the two parties and has a length
53  * of 128, 192, or 256 bits.
54  *
55  * The IV is generated by the party performing the authenticated
56  * encryption operation. Within the scope of any authenticated
57  * encryption key, the IV value must be unique. That is, the set of
58  * IV values used with any given key must not contain any duplicate
59  * values. Using the same IV for two different messages encrypted
60  * with the same key destroys the security properties of GCM.
61  *
62  * The optional additional authentication data (AAD) is authenticated
63  * but not encrypted. Thus, the AAD is not included in the AES-GCM output.
64  * It can be used to authenticate packet headers, timestamps and other
65  * metadata.
66  *
67  * After the encryption operation, the ciphertext contains the encrypted
68  * data and the message authentication code (MAC).
69  *
70  * GCM is highly performant for an AEAD mode. Counter with CBC-MAC requires
71  * one invocation per block of AAD and two invocations of the block cipher
72  * per proccessed block of input; one to compute the CBC-MAC and one to
73  * perform CTR. GCM substitutes the block cipher invocation during CBC-MAC
74  * computation with computing GHASH over the same input. GHASH is significantly
75  * faster per block than AES. In turn, this gives GCM a performance edge
76  * over CCM.
77  *
78  * ### Security Considerations
79  *
80  * In each operation, GCM limits the length of the input and AAD to guarantee
81  * its security properties:
82  * - inputLength <= 2^36 - 32 bytes
83  * - aadLength <= 2^61 - 1 bytes
84  *
85  * The security properties of GCM rely on the MAC size. While MAC lengths of
86  * [4, 8, 12, 13, 14, 15, 16] bytes are permitted, it is recommended to
87  * use the full 16-byte MAC.
88  *
89  * See NIST SP 800-38D for more a more detailed discussion of security
90  * considerations.
91  *
92  * @anchor ti_drivers_AESGCM_Usage
93  * ### Usage #
94  *
95  * #### Before starting a GCM operation #
96  *
97  * Before starting a GCM operation, the application must do the following:
98  * - Call AESGCM_init() to initialize the driver
99  * - Call AESGCM_Params_init() to initialize the #AESGCM_Params to default values.
100  * - Modify the #AESGCM_Params as desired
101  * - Call AESGCM_open() to open an instance of the driver
102  * - Initialize a CryptoKey. These opaque data structures are representations
103  * of keying material and its storage. Depending on how the keying material
104  * is stored (RAM or flash, key store), the CryptoKey must be
105  * initialized differently. The AESGCM API can handle all types of CryptoKey.
106  * However, not all device-specific implementations support all types of CryptoKey.
107  * Devices without a key store will not support CryptoKeys with keying material
108  * stored in a key store for example.
109  * All devices support plaintext CryptoKeys.
110  * - Initialize the appropriate AESGCM operation struct using the relevant
111  * operation init functions and set all fields. For example, one-step (one-shot
112  * or single call) operations should initialize AESGCM_Operation or
113  * AESGCM_OneStepOperation using AESGCM_Operation_init() or
114  * AESGCM_OneStepOperation_init(). For multi-step (segmented or multiple call)
115  * operations, AESGCM_SegmentedAADOperation must be initialized and set when
116  * processing AAD. AESGCM_SegmentedDataOperation must be initialized and set when
117  * dealing with payload data (plaintext or ciphertext). AESGCM_SegmentedFinalizeOperation
118  * must be initialized and set when finalizing the segmented operation.
119  *
120  * #### Starting a GCM operation #
121  *
122  * The AESGCM_oneStepEncrypt() and AESGCM_oneStepDecrypt() functions perform a GCM operation in a single call.
123  *
124  * When performing a decryption operation with AESGCM_oneStepDecrypt(), the MAC is
125  * automatically verified.
126  *
127  * #### After the GCM operation completes #
128  *
129  * After the GCM operation completes, the application should either start another operation
130  * or close the driver by calling AESGCM_close()
131  *
132  * @anchor ti_drivers_AESGCM_Synopsis
133  * ## Synopsis
134  *
135  * @anchor ti_drivers_AESGCM_Synopsis_Code
136  * @code
137  *
138  * // Import AESGCM Driver definitions
139  * #include <ti/drivers/AESGCM.h>
140  *
141  * // Define name for AESGCM channel index
142  * #define AESGCM_INSTANCE 0
143  *
144  * AESGCM_init();
145  *
146  * handle = AESGCM_open(AESGCM_INSTANCE, NULL);
147  *
148  * // Initialize symmetric key
149  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
150  *
151  * // Set up AESGCM_OneStepOperation
152  * AESGCM_OneStepOperation_init(&operation);
153  * operation.key = &cryptoKey;
154  * operation.aad = aad;
155  * operation.aadLength = sizeof(aad);
156  * operation.input = plaintext;
157  * operation.output = ciphertext;
158  * operation.inputLength = sizeof(plaintext);
159  * operation.iv = iv;
160  * operation.ivLength = sizeof(iv);
161  * operation.mac = mac;
162  * operation.macLength = sizeof(mac);
163  *
164  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
165  *
166  * AESGCM_close(handle);
167  * @endcode
168  *
169  * @anchor ti_drivers_AESGCM_Examples
170  * #### Examples
171  *
172  * ##### Single call GCM encryption + authentication with plaintext CryptoKey in blocking return mode #
173  *
174  * @code
175  *
176  * #include <ti/drivers/AESGCM.h>
177  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
178  *
179  * ...
180  *
181  * AESGCM_Handle handle;
182  * CryptoKey cryptoKey;
183  * int_fast16_t encryptionResult;
184  * uint8_t iv[12] = "12-byte IV ";
185  * uint8_t aad[] = "This string will be authenticated but not encrypted.";
186  * uint8_t plaintext[] = "This string will be encrypted and authenticated.";
187  * uint8_t mac[16];
188  * uint8_t ciphertext[sizeof(plaintext)];
189  * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
190  * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
191  * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
192  * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
193  *
194  * handle = AESGCM_open(0, NULL);
195  *
196  * if (handle == NULL) {
197  * // handle error
198  * }
199  *
200  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
201  *
202  * AESGCM_OneStepOperation operation;
203  * AESGCM_OneStepOperation_init(&operation);
204  *
205  * operation.key = &cryptoKey;
206  * operation.aad = aad;
207  * operation.aadLength = sizeof(aad);
208  * operation.input = plaintext;
209  * operation.output = ciphertext;
210  * operation.inputLength = sizeof(plaintext);
211  * operation.iv = iv;
212  * operation.ivLength = 12;
213  * operation.mac = mac;
214  * operation.macLength = sizeof(mac);
215  *
216  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
217  *
218  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
219  * // handle error
220  * }
221  *
222  * AESGCM_close(handle);
223  *
224  * @endcode
225  *
226  * ##### Single call GCM decryption + verification with plaintext CryptoKey in callback return mode #
227  *
228  * @code
229  *
230  * #include <ti/drivers/AESGCM.h>
231  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
232  *
233  * ...
234  *
235  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
236  *
237  * uint8_t iv[] = {0x1f, 0x80, 0x3c, 0x52, 0xca, 0xc4, 0x97, 0xe1,
238  * 0x55, 0xaa, 0x55, 0x2d};
239  * uint8_t aad[] = {0x3b, 0xba, 0x31, 0x28, 0x9d, 0x05, 0xf5, 0x0f,
240  * 0xed, 0x6c, 0x53, 0x35, 0x3c, 0x1f, 0x74, 0xd8,
241  * 0x28, 0xa9, 0x96, 0xb8, 0xd6, 0x84, 0xfe, 0x64,
242  * 0x7f, 0x7c, 0x40, 0xc0, 0xd5, 0x68, 0x8c, 0x89,
243  * 0x68, 0x1a, 0x33, 0xb1, 0x0c, 0xb7, 0x14, 0xb6,
244  * 0x49, 0x0b, 0xdf, 0x1f, 0x16, 0x60, 0x60, 0xa7};
245  * uint8_t mac[] = {0x39, 0x03, 0xe4, 0xdc, 0xa4, 0xe7, 0xc8, 0x21,
246  * 0x62, 0x1a, 0xbb, 0xb2, 0x37, 0x2c, 0x97};
247  * uint8_t ciphertext[] = {0xf8, 0x7e, 0xf7, 0x99, 0x4a, 0x86, 0xf3, 0xe9,
248  * 0xa3, 0xab, 0x6a, 0x6f, 0x2d, 0x34, 0x3b, 0xbd};
249  * uint8_t keyingMaterial[] = {0x4f, 0xd7, 0xf2, 0x09, 0xdf, 0xb0, 0xdf, 0xbd,
250  * 0xd9, 0x8d, 0x2d, 0xb4, 0x98, 0x66, 0x4c, 0x88};
251  * uint8_t plaintext[sizeof(ciphertext)];
252  *
253  * // The plaintext should be the following after the decryption operation:
254  * // 0x17, 0x9d, 0xcb, 0x79, 0x5c, 0x09, 0x8f, 0xc5, 0x31, 0x4b, 0xde, 0x0d, 0x39, 0x9d, 0x7a, 0x10
255  *
256  *
257  * void gcmCallback(AESGCM_Handle handle,
258  * int_fast16_t returnValue,
259  * AESGCM_OperationUnion *operation,
260  * AESGCM_OperationType operationType) {
261  *
262  * if (returnValue != AESGCM_STATUS_SUCCESS) {
263  * // handle error
264  * }
265  * }
266  *
267  * AESGCM_OneStepOperation operation;
268  * CryptoKey cryptoKey;
269  *
270  * void gcmStartFunction(void) {
271  * AESGCM_Handle handle;
272  * AESGCM_Params params;
273  * int_fast16_t decryptionResult;
274  *
275  * AESGCM_Params_init(&params);
276  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
277  * params.callbackFxn = gcmCallback;
278  *
279  * handle = AESGCM_open(0, &params);
280  *
281  * if (handle == NULL) {
282  * // handle error
283  * }
284  *
285  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
286  *
287  * AESGCM_OneStepOperation_init(&operation);
288  *
289  * operation.key = &cryptoKey;
290  * operation.aad = aad;
291  * operation.aadLength = sizeof(aad);
292  * operation.input = ciphertext;
293  * operation.output = plaintext;
294  * operation.inputLength = sizeof(ciphertext);
295  * operation.iv = iv;
296  * operation.ivLength = sizeof(iv);
297  * operation.mac = mac;
298  * operation.macLength = sizeof(mac);
299  *
300  * decryptionResult = AESGCM_oneStepDecrypt(handle, &operation);
301  *
302  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
303  * // handle error
304  * }
305  *
306  * // do other things while GCM operation completes in the background
307  *
308  * }
309  *
310  * @endcode
311  *
312  * ### Multi-step GCM encryption + authentication with plaintext CryptoKey in blocking return mode #
313  * @code
314  *
315  * #include <ti/drivers/AESGCM.h>
316  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
317  *
318  * ...
319  *
320  * #define AES_BLOCK_SIZE 16 // bytes
321  *
322  * AESGCM_Handle handle;
323  * CryptoKey cryptoKey;
324  * int_fast16_t encryptionResult;
325  *
326  * uint8_t keyingMaterial[32] = {0x58, 0x53, 0xc0, 0x20, 0x94, 0x6b, 0x35, 0xf2,
327  * 0xc5, 0x8e, 0xc4, 0x27, 0x15, 0x2b, 0x84, 0x04,
328  * 0x20, 0xc4, 0x00, 0x29, 0x63, 0x6a, 0xdc, 0xbb,
329  * 0x02, 0x74, 0x71, 0x37, 0x8c, 0xfd, 0xde, 0x0f};
330  * uint8_t aad[20] = {0x13, 0x89, 0xb5, 0x22, 0xc2, 0x4a, 0x77, 0x41,
331  * 0x81, 0x70, 0x05, 0x53, 0xf0, 0x24, 0x6b, 0xba,
332  * 0xbd, 0xd3, 0x8d, 0x6f};
333  * uint8_t plaintext[32] = {0xce, 0x74, 0x58, 0xe5, 0x6a, 0xef, 0x90, 0x61,
334  * 0xcb, 0x0c, 0x42, 0xec, 0x23, 0x15, 0x56, 0x5e,
335  * 0x61, 0x68, 0xf5, 0xa6, 0x24, 0x9f, 0xfd, 0x31,
336  * 0x61, 0x0b, 0x6d, 0x17, 0xab, 0x64, 0x93, 0x5e};
337  * uint8_t iv[12] = {0xee, 0xc3, 0x13, 0xdd, 0x07, 0xcc, 0x1b, 0x3e,
338  * 0x6b, 0x06, 0x8a, 0x47};
339  * uint8_t mac[16];
340  * uint8_t ciphertext[sizeof(plaintext)];
341  *
342  * // The ciphertext should be the following after the encryption operation:
343  * // {0xea, 0xdc, 0x3b, 0x87, 0x66, 0xa7, 0x7d, 0xed,
344  * // 0x1a, 0x58, 0xcb, 0x72, 0x7e, 0xca, 0x2a, 0x97,
345  * // 0x90, 0x49, 0x6c, 0x29, 0x86, 0x54, 0xcd, 0xa7,
346  * // 0x8f, 0xeb, 0xf0, 0xda, 0x16, 0xb6, 0x90, 0x3b}
347  *
348  * handle = AESGCM_open(0, NULL);
349  *
350  * if (handle == NULL) {
351  * // handle error
352  * }
353  *
354  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
355  *
356  * encryptionResult = AESGCM_setupEncrypt(handle, &cryptoKey, sizeof(aad), sizeof(plaintext));
357  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
358  * // handle error
359  * }
360  *
361  * encryptionResult = AESGCM_setIV(handle, iv, sizeof(iv));
362  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
363  * // handle error
364  * }
365  *
366  * AESGCM_SegmentedAADOperation segmentedAADOperation;
367  * AESGCM_SegmentedAADOperation_init(&segmentedAADOperation);
368  * segmentedAADOperation.aad = aad;
369  * // One should pass in data that is a block-sized multiple length
370  * // until passing in the last segment of data.
371  * // In that case, the input length simply needs to be a non-zero value.
372  * segmentedAADOperation.aadLength = sizeof(aad);
373  *
374  * encryptionResult = AESGCM_addAAD(handle, &segmentedAADOperation);
375  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
376  * // handle error
377  * }
378  *
379  * AESGCM_SegmentedDataOperation segmentedDataOperation;
380  * AESGCM_SegmentedDataOperation_init(&segmentedDataOperation);
381  * segmentedDataOperation.input = plaintext;
382  * segmentedDataOperation.output = ciphertext;
383  * // One should pass in data that is a block-sized multiple length
384  * // until passing in the last segment of data.
385  * // In that case, the input length simply needs to be a non-zero value.
386  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
387  *
388  * encryptionResult = AESGCM_addData(handle, &segmentedDataOperation);
389  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
390  * // handle error
391  * }
392  *
393  * AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
394  * AESGCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
395  * segmentedFinalizeOperation.input = plaintext + AES_BLOCK_SIZE;
396  * segmentedFinalizeOperation.output = ciphertext + AES_BLOCK_SIZE;
397  * segmentedFinalizeOperation.inputLength = AES_BLOCK_SIZE;
398  * segmentedFinalizeOperation.mac = mac;
399  * segmentedFinalizeOperation.macLength = sizeof(mac);
400  * encryptionResult = AESGCM_finalizeEncrypt(handle, &segmentedFinalizeOperation);
401  *
402  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
403  * // handle error
404  * }
405  *
406  * AESGCM_close(handle);
407  *
408  * @endcode
409  *
410  * ### Multi-step GCM decryption + verification with plaintext CryptoKey in callback return mode #
411  * @code
412  *
413  * #include <ti/drivers/AESGCM.h>
414  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
415  *
416  * ...
417  *
418  * #define AES_BLOCK_SIZE 16 // bytes
419  *
420  * uint8_t iv[] = {0x7f, 0xc2, 0x5c, 0x0c, 0x7a, 0x65, 0xb9, 0x50,
421  * 0x00, 0x23, 0xd0, 0x58};
422  * uint8_t aad[] = {0x9e, 0xca, 0x27, 0x10, 0xbc, 0x1c, 0xaa, 0x99,
423  * 0x50, 0x2d, 0xe3, 0x0f, 0x08, 0x94, 0x30, 0x69,
424  * 0x7a, 0xee, 0xfc, 0x03};
425  * uint8_t mac[] = {0x77, 0xb6, 0x4e, 0x40};
426  * uint8_t ciphertext[] = {0xbd, 0xb4, 0x3f, 0x90, 0xf1, 0x6e, 0x26, 0xdc,
427  * 0xff, 0x60, 0xdb, 0x92, 0xb9, 0x6c, 0x4a, 0x2f};
428  * uint8_t keyingMaterial[] = {0xfb, 0x96, 0x31, 0x2b, 0xdb, 0x8a, 0x22, 0xf1,
429  * 0x6f, 0xad, 0xc4, 0x23, 0x69, 0x4f, 0x45, 0x70};
430  * uint8_t plaintext[sizeof(ciphertext)];
431  *
432  * // The plaintext should be the following after the decryption operation:
433  * // {0xae, 0xe4, 0x16, 0xa2, 0x1f, 0x0e, 0x98, 0x3f,
434  * // 0xd7, 0x05, 0x20, 0xb8, 0xce, 0xdb, 0x24, 0xe5}
435  *
436  * void gcmCallback(AESGCM_Handle handle,
437  * int_fast16_t returnValue,
438  * AESGCM_OperationUnion *operation,
439  * AESGCM_OperationType operationType) {
440  *
441  * if (returnValue != AESGCM_STATUS_SUCCESS) {
442  * // handle error
443  * }
444  *
445  * if(operationType == AESGCM_OPERATION_TYPE_DECRYPT ||
446  * operationType == AESGCM_OPERATION_TYPE_ENCRYPT)
447  * {
448  * // Callback fxn only used for one-shot operations
449  * // Use operation->oneStepOperation
450  * }
451  * else if(operationType == AESGCM_OP_TYPE_AAD_DECRYPT ||
452  * operationType == AESGCM_OP_TYPE_AAD_ENCRYPT)
453  * {
454  * // Callback fxn only used for segmented AAD operations
455  * // Use operation->segmentedAADOperation
456  * }
457  * else if(operationType == AESGCM_OP_TYPE_DATA_DECRYPT ||
458  * operationType == AESGCM_OP_TYPE_DATA_ENCRYPT)
459  * {
460  * // Callback fxn only used for segmented data operations
461  * // Use operation->segmentedDataOperation
462  * }
463  * else
464  * {
465  * // Callback fxn only used for segmented finalize operations
466  * // Use operation->segmentedFinalizeOperation
467  * }
468  * }
469  *
470  * void gcmStartFunction(void) {
471  * AESGCM_Handle handle;
472  * AESGCM_Params params;
473  * CryptoKey cryptoKey;
474  * int_fast16_t decryptionResult;
475  *
476  * AESGCM_Params_init(&params);
477  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
478  * params.callbackFxn = gcmCallback;
479  *
480  * handle = AESGCM_open(0, &params);
481  *
482  * if (handle == NULL) {
483  * // handle error
484  * }
485  *
486  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
487  *
488  * decryptionResult = AESGCM_setupDecrypt(handle, &cryptoKey, 0, 0);
489  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
490  * // handle error
491  * }
492  *
493  * // setLengths must be called if the AAD and input lengths aren't provided in setupXXXX.
494  * decryptionResult = AESGCM_setLengths(handle, sizeof(aad), sizeof(ciphertext));
495  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
496  * // handle error
497  * }
498  *
499  * decryptionResult = AESGCM_setIV(handle, iv, sizeof(iv));
500  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
501  * // handle error
502  * }
503  *
504  * AESGCM_SegmentedAADOperation segmentedAADOperation;
505  * AESGCM_SegmentedAADOperation_init(&segmentedAADOperation);
506  * segmentedAADOperation.aad = aad;
507  * segmentedAADOperation.aadLength = sizeof(aad);
508  *
509  * decryptionResult = AESGCM_addAAD(handle, &segmentedAADOperation);
510  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
511  * // handle error
512  * }
513  *
514  * AESGCM_SegmentedDataOperation segmentedDataOperation;
515  * AESGCM_SegmentedDataOperation_init(&segmentedDataOperation);
516  * segmentedDataOperation.input = ciphertext;
517  * segmentedDataOperation.output = plaintext;
518  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
519  *
520  * decryptionResult = AESGCM_addData(handle, &segmentedDataOperation);
521  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
522  * // handle error
523  * }
524  *
525  * AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
526  * AESGCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
527  * segmentedFinalizeOperation.input = ciphertext;
528  * segmentedFinalizeOperation.output = plaintext;
529  *
530  * // You can finalize with no new data
531  * segmentedFinalizeOperation.inputLength = 0;
532  * segmentedFinalizeOperation.mac = mac;
533  * segmentedFinalizeOperation.macLength = sizeof(mac);
534  *
535  * decryptionResult = AESGCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
536  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
537  * // handle error
538  * }
539  *
540  * // do other things while GCM operation completes in the background
541  *
542  * }
543  *
544  * @endcode
545  */
546 
547 #ifndef ti_drivers_AESGCM__include
548 #define ti_drivers_AESGCM__include
549 
550 #include <stdbool.h>
551 #include <stddef.h>
552 #include <stdint.h>
553 
554 #include <ti/drivers/AESCommon.h>
556 
557 #ifdef __cplusplus
558 extern "C" {
559 #endif
560 
561 /* Only IVs with a length of 12 bytes are supported for now */
562 #define AESGCM_IV_LENGTH_BYTES 12
563 
576 #define AESGCM_STATUS_RESERVED AES_STATUS_RESERVED
577 
583 #define AESGCM_STATUS_SUCCESS AES_STATUS_SUCCESS
584 
591 #define AESGCM_STATUS_ERROR AES_STATUS_ERROR
592 
601 #define AESGCM_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
602 
606 #define AESGCM_STATUS_CANCELED AES_STATUS_CANCELED
607 
615 #define AESGCM_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID
616 
623 #define AESGCM_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
624 
628 #define AESGCM_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
629 
634 #define AESGCM_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
635 
651 typedef AESGCM_Config *AESGCM_Handle;
652 
674 typedef enum
675 {
694 
698 typedef enum
699 {
702 } AESGCM_Mode;
703 
708 typedef struct
709 {
711  uint8_t *aad;
715  uint8_t *input;
720  uint8_t *output;
726  uint8_t *iv;
732  uint8_t *mac;
738  size_t aadLength;
741  size_t inputLength;
746  uint8_t ivLength;
749  uint8_t macLength;
757 
763 typedef struct
764 {
765  uint8_t *aad;
769  size_t aadLength;
775 
781 typedef struct
782 {
783  uint8_t *input;
788  uint8_t *output;
794  size_t inputLength;
800 
806 typedef struct
807 {
808  uint8_t *input;
813  uint8_t *output;
819  uint8_t *mac;
825  size_t inputLength;
830  uint8_t macLength;
834 
843 
849 {
850  AESGCM_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */
851  AESGCM_SegmentedAADOperation segmentedAADOperation; /* Segmented AAD operation element of the operation union */
852  AESGCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */
853  AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the
854  operation union */
856 
860 typedef enum
861 {
862  AESGCM_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */
864  AESGCM_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not
865  being unique */
874 
890 typedef void (*AESGCM_CallbackFxn)(AESGCM_Handle handle,
891  int_fast16_t returnValue,
892  AESGCM_OperationUnion *operation,
893  AESGCM_OperationType operationType);
894 
903 typedef struct
904 {
905  AESGCM_ReturnBehavior returnBehavior;
907  uint32_t timeout;
910  void *custom;
913 } AESGCM_Params;
914 
921 
930 void AESGCM_init(void);
931 
945 
963 AESGCM_Handle AESGCM_open(uint_least8_t index, const AESGCM_Params *params);
964 
974 void AESGCM_close(AESGCM_Handle handle);
975 
1003 int_fast16_t AESGCM_setupEncrypt(AESGCM_Handle handle,
1004  const CryptoKey *key,
1005  size_t totalAADLength,
1006  size_t totalPlaintextLength);
1007 
1035 int_fast16_t AESGCM_setupDecrypt(AESGCM_Handle handle,
1036  const CryptoKey *key,
1037  size_t totalAADLength,
1038  size_t totalPlaintextLength);
1039 
1066 int_fast16_t AESGCM_setLengths(AESGCM_Handle handle, size_t aadLength, size_t plaintextLength);
1067 
1088 int_fast16_t AESGCM_setIV(AESGCM_Handle handle, const uint8_t *iv, size_t ivLength);
1089 
1114 int_fast16_t AESGCM_generateIV(AESGCM_Handle handle, uint8_t *iv, size_t ivSize, size_t *ivLength);
1115 
1147 int_fast16_t AESGCM_addAAD(AESGCM_Handle handle, AESGCM_SegmentedAADOperation *operation);
1148 
1178 int_fast16_t AESGCM_addData(AESGCM_Handle handle, AESGCM_SegmentedDataOperation *operation);
1179 
1205 int_fast16_t AESGCM_finalizeEncrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation);
1206 
1236 int_fast16_t AESGCM_finalizeDecrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation);
1237 
1249 void AESGCM_Operation_init(AESGCM_Operation *operationStruct);
1250 
1260 
1270 
1280 
1290 
1310 int_fast16_t AESGCM_oneStepEncrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct);
1311 
1332 int_fast16_t AESGCM_oneStepDecrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct);
1333 
1348 int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle);
1349 
1373 AESGCM_Handle AESGCM_construct(AESGCM_Config *config, const AESGCM_Params *params);
1374 
1375 #ifdef __cplusplus
1376 }
1377 #endif
1378 
1379 #endif /* ti_drivers_AESGCM__include */
ADC_Params params
Definition: Driver_Init.h:11
Definition: AESGCM.h:866
void * custom
Definition: AESGCM.h:910
The CryptoKey type is an opaque representation of a cryptographic key.
void AESGCM_SegmentedFinalizeOperation_init(AESGCM_SegmentedFinalizeOperation *operationStruct)
Function to initialize an AESGCM_SegmentedFinalizeOperation struct to its defaults.
int_fast16_t AESGCM_finalizeDecrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and plaintext and verify it.
AESGCM_OperationType
Enum for the operation types supported by the driver.
Definition: AESGCM.h:860
int_fast16_t AESGCM_setupEncrypt(AESGCM_Handle handle, const CryptoKey *key, size_t totalAADLength, size_t totalPlaintextLength)
Function to prepare a segmented AESGCM encryption operation.
Definition: AESGCM.h:870
uint8_t * mac
Definition: AESGCM.h:819
int_fast16_t AESGCM_oneStepDecrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct)
Function to perform an AESGCM decryption + verification operation in one call.
bool ivInternallyGenerated
Definition: AESGCM.h:752
int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle)
Cancels an ongoing AESGCM operation.
uint8_t * iv
Definition: AESGCM.h:726
Definition: AESGCM.h:868
const AESGCM_Params AESGCM_defaultParams
Default AESGCM_Params structure.
uint8_t * input
Definition: AESGCM.h:783
Definition: AESGCM.h:864
AES Global configuration.
Definition: AESCommon.h:154
Definition: AESGCM.h:676
size_t inputLength
Definition: AESGCM.h:825
CryptoKey datastructure.
Definition: CryptoKey.h:198
AESGCM_SegmentedAADOperation segmentedAADOperation
Definition: AESGCM.h:851
int_fast16_t AESGCM_addData(AESGCM_Handle handle, AESGCM_SegmentedDataOperation *operation)
Adds a segment of data with a length that is a multiple of an AES block-size (16 bytes) to the plaint...
Struct containing the parameters required for encrypting/decrypting a message in a segmented operatio...
Definition: AESGCM.h:781
size_t inputLength
Definition: AESGCM.h:741
uint8_t * input
Definition: AESGCM.h:715
Definition: AESCommon.h:186
Definition: AESGCM.h:869
uint8_t * aad
Definition: AESGCM.h:711
Definition: AESCommon.h:196
uint8_t ivLength
Definition: AESGCM.h:746
void AESGCM_Operation_init(AESGCM_Operation *operationStruct)
Function to initialize an AESGCM_Operation struct to its defaults.
Definition: AESGCM.h:872
Struct containing the parameters required for authenticating/verifying additional data in a segmented...
Definition: AESGCM.h:763
AESGCM_ReturnBehavior returnBehavior
Definition: AESGCM.h:905
void AESGCM_init(void)
This function initializes the GCM module.
int_fast16_t AESGCM_addAAD(AESGCM_Handle handle, AESGCM_SegmentedAADOperation *operation)
Adds a segment of aad with a length in bytes to the generated MAC.
uint8_t * mac
Definition: AESGCM.h:732
uint8_t * aad
Definition: AESGCM.h:765
int_fast16_t AESGCM_setIV(AESGCM_Handle handle, const uint8_t *iv, size_t ivLength)
Function to set the initialization vector (IV) for an AES GCM segmented operation.
int_fast16_t AESGCM_setLengths(AESGCM_Handle handle, size_t aadLength, size_t plaintextLength)
Function to set the lengths of the message and additional data.
Definition: AESCommon.h:192
uint8_t macLength
Definition: AESGCM.h:830
void(* AESGCM_CallbackFxn)(AESGCM_Handle handle, int_fast16_t returnValue, AESGCM_OperationUnion *operation, AESGCM_OperationType operationType)
The definition of a callback function used by the AESGCM driver when used in AESGCM_RETURN_BEHAVIOR_C...
Definition: AESGCM.h:890
Definition: AESGCM.h:863
Struct containing the parameters required for finalizing an encryption/decryption and authentication/...
Definition: AESGCM.h:806
Definition: AESGCM.h:867
AESGCM_ReturnBehavior
The way in which GCM function calls return after performing an encryption + authentication or decrypt...
Definition: AESGCM.h:674
Definition: AESGCM.h:701
Definition: AESGCM.h:688
size_t aadLength
Definition: AESGCM.h:738
Struct containing the parameters required for encrypting/decrypting and authenticating/verifying a me...
Definition: AESGCM.h:708
AESGCM_OneStepOperation oneStepOperation
Definition: AESGCM.h:850
AESGCM_SegmentedDataOperation segmentedDataOperation
Definition: AESGCM.h:852
uint8_t * input
Definition: AESGCM.h:808
Definition: AESGCM.h:862
int_fast16_t AESGCM_oneStepEncrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct)
Function to perform an AESGCM encryption + authentication operation in one call.
int_fast16_t AESGCM_generateIV(AESGCM_Handle handle, uint8_t *iv, size_t ivSize, size_t *ivLength)
Function to generate an IV for an AES GCM segmented encryption operation.
uint32_t timeout
Definition: AESGCM.h:907
void AESGCM_close(AESGCM_Handle handle)
Function to close a GCM peripheral specified by the GCM handle.
AESGCM_Handle AESGCM_construct(AESGCM_Config *config, const AESGCM_Params *params)
Constructs a new AESGCM object.
uint8_t * output
Definition: AESGCM.h:813
AESGCM_Config * AESGCM_Handle
A handle that is returned from an AESGCM_open() call.
Definition: AESGCM.h:651
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESGCM.h:848
uint8_t * output
Definition: AESGCM.h:720
size_t inputLength
Definition: AESGCM.h:794
size_t aadLength
Definition: AESGCM.h:769
void AESGCM_Params_init(AESGCM_Params *params)
Function to initialize the AESGCM_Params struct to its defaults.
uint8_t macLength
Definition: AESGCM.h:749
int_fast16_t AESGCM_finalizeEncrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and ciphertext.
Definition: AESGCM.h:871
uint8_t * output
Definition: AESGCM.h:788
AESGCM_Handle AESGCM_open(uint_least8_t index, const AESGCM_Params *params)
This function opens a given GCM peripheral.
int_fast16_t AESGCM_setupDecrypt(AESGCM_Handle handle, const CryptoKey *key, size_t totalAADLength, size_t totalPlaintextLength)
Function to prepare a segmented AESGCM decryption operation.
CryptoKey * key
Definition: AESGCM.h:710
AESGCM_Mode
Enum for the direction of the GCM operation.
Definition: AESGCM.h:698
AES common module header for all devices.
GCM Parameters.
Definition: AESGCM.h:903
AESCommon_Config AESGCM_Config
AESGCM Global configuration.
Definition: AESGCM.h:647
AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation
Definition: AESGCM.h:853
AESGCM_OneStepOperation AESGCM_Operation
Definition: AESGCM.h:842
union AESGCM_OperationUnion AESGCM_OperationUnion
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESGCM.h:683
Definition: AESGCM.h:700
void AESGCM_OneStepOperation_init(AESGCM_OneStepOperation *operationStruct)
Function to initialize an AESGCM_OneStepOperation struct to its defaults.
void AESGCM_SegmentedDataOperation_init(AESGCM_SegmentedDataOperation *operationStruct)
Function to initialize an AESGCM_SegmentedDataOperation struct to its defaults.
void AESGCM_SegmentedAADOperation_init(AESGCM_SegmentedAADOperation *operationStruct)
Function to initialize an AESGCM_SegmentedAADOperation struct to its defaults.
AESGCM_CallbackFxn callbackFxn
Definition: AESGCM.h:906
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale