AESGCM.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2024, 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  * ## Device-Specific Requirements #
121  *
122  * For CC27XX devices, GCM operations leveraging the HSM engine
123  * (key encoding suffixed with _HSM) have the following requirements:
124  * - Output buffer address must be 32-bit aligned.
125  *
126  * #### Starting a GCM operation #
127  *
128  * The AESGCM_oneStepEncrypt() and AESGCM_oneStepDecrypt() functions perform a GCM operation in a single call.
129  *
130  * When performing a decryption operation with AESGCM_oneStepDecrypt(), the MAC is
131  * automatically verified.
132  *
133  * #### After the GCM operation completes #
134  *
135  * After the GCM operation completes, the application should either start another operation
136  * or close the driver by calling AESGCM_close()
137  *
138  * @anchor ti_drivers_AESGCM_Synopsis
139  * ## Synopsis
140  *
141  * @anchor ti_drivers_AESGCM_Synopsis_Code
142  * @code
143  *
144  * // Import AESGCM Driver definitions
145  * #include <ti/drivers/AESGCM.h>
146  *
147  * // Define name for AESGCM channel index
148  * #define AESGCM_INSTANCE 0
149  *
150  * AESGCM_init();
151  *
152  * handle = AESGCM_open(AESGCM_INSTANCE, NULL);
153  *
154  * // Initialize symmetric key
155  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
156  *
157  * // Set up AESGCM_OneStepOperation
158  * AESGCM_OneStepOperation_init(&operation);
159  * operation.key = &cryptoKey;
160  * operation.aad = aad;
161  * operation.aadLength = sizeof(aad);
162  * operation.input = plaintext;
163  * operation.output = ciphertext;
164  * operation.inputLength = sizeof(plaintext);
165  * operation.iv = iv;
166  * operation.ivLength = sizeof(iv);
167  * operation.mac = mac;
168  * operation.macLength = sizeof(mac);
169  *
170  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
171  *
172  * AESGCM_close(handle);
173  * @endcode
174  *
175  * @anchor ti_drivers_AESGCM_Examples
176  * #### Examples
177  *
178  * ##### Single call GCM encryption + authentication with plaintext CryptoKey in blocking return mode #
179  *
180  * @code
181  *
182  * #include <ti/drivers/AESGCM.h>
183  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
184  *
185  * ...
186  *
187  * AESGCM_Handle handle;
188  * CryptoKey cryptoKey;
189  * int_fast16_t encryptionResult;
190  * uint8_t iv[12] = "12-byte IV ";
191  * uint8_t aad[] = "This string will be authenticated but not encrypted.";
192  * uint8_t plaintext[] = "This string will be encrypted and authenticated.";
193  * uint8_t mac[16];
194  * uint8_t ciphertext[sizeof(plaintext)];
195  * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
196  * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
197  * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
198  * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
199  *
200  * handle = AESGCM_open(0, NULL);
201  *
202  * if (handle == NULL) {
203  * // handle error
204  * }
205  *
206  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
207  *
208  * AESGCM_OneStepOperation operation;
209  * AESGCM_OneStepOperation_init(&operation);
210  *
211  * operation.key = &cryptoKey;
212  * operation.aad = aad;
213  * operation.aadLength = sizeof(aad);
214  * operation.input = plaintext;
215  * operation.output = ciphertext;
216  * operation.inputLength = sizeof(plaintext);
217  * operation.iv = iv;
218  * operation.ivLength = 12;
219  * operation.mac = mac;
220  * operation.macLength = sizeof(mac);
221  *
222  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
223  *
224  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
225  * // handle error
226  * }
227  *
228  * AESGCM_close(handle);
229  *
230  * @endcode
231  *
232  * <h4> The following code snippet is for CC27XX devices only and leverages the HSM which is a separate Hardware
233  * Accelerator </h4>
234  *
235  * ##### Single call GCM encryption + authentication with plaintext CryptoKey in blocking return mode
236  * for the HSM accelerator #
237  *
238  * @code
239  *
240  * #include <ti/drivers/AESGCM.h>
241  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
242  *
243  * ...
244  *
245  * AESGCM_Handle handle;
246  * CryptoKey cryptoKey;
247  * int_fast16_t encryptionResult;
248  * uint8_t iv[12] = "12-byte IV ";
249  * uint8_t aad[] = "This string will be authenticated but not encrypted.";
250  * uint8_t plaintext[] = "This string will be encrypted and authenticated.";
251  * uint8_t mac[16];
252  * uint8_t ciphertext[sizeof(plaintext)];
253  * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
254  * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
255  * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
256  * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
257  *
258  * handle = AESGCM_open(0, NULL);
259  *
260  * if (handle == NULL) {
261  * // handle error
262  * }
263  *
264  * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
265  *
266  * AESGCM_OneStepOperation operation;
267  * AESGCM_OneStepOperation_init(&operation);
268  *
269  * operation.key = &cryptoKey;
270  * operation.aad = aad;
271  * operation.aadLength = sizeof(aad);
272  * operation.input = plaintext;
273  * operation.output = ciphertext;
274  * operation.inputLength = sizeof(plaintext);
275  * operation.iv = iv;
276  * operation.ivLength = 12;
277  * operation.mac = mac;
278  * operation.macLength = sizeof(mac);
279  *
280  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
281  *
282  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
283  * // handle error
284  * }
285  *
286  * AESGCM_close(handle);
287  *
288  * @endcode
289  *
290  * ##### Single call GCM decryption + verification with plaintext CryptoKey in callback return mode #
291  *
292  * @code
293  *
294  * #include <ti/drivers/AESGCM.h>
295  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
296  *
297  * ...
298  *
299  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
300  *
301  * uint8_t iv[] = {0x1f, 0x80, 0x3c, 0x52, 0xca, 0xc4, 0x97, 0xe1,
302  * 0x55, 0xaa, 0x55, 0x2d};
303  * uint8_t aad[] = {0x3b, 0xba, 0x31, 0x28, 0x9d, 0x05, 0xf5, 0x0f,
304  * 0xed, 0x6c, 0x53, 0x35, 0x3c, 0x1f, 0x74, 0xd8,
305  * 0x28, 0xa9, 0x96, 0xb8, 0xd6, 0x84, 0xfe, 0x64,
306  * 0x7f, 0x7c, 0x40, 0xc0, 0xd5, 0x68, 0x8c, 0x89,
307  * 0x68, 0x1a, 0x33, 0xb1, 0x0c, 0xb7, 0x14, 0xb6,
308  * 0x49, 0x0b, 0xdf, 0x1f, 0x16, 0x60, 0x60, 0xa7};
309  * uint8_t mac[] = {0x39, 0x03, 0xe4, 0xdc, 0xa4, 0xe7, 0xc8, 0x21,
310  * 0x62, 0x1a, 0xbb, 0xb2, 0x37, 0x2c, 0x97};
311  * uint8_t ciphertext[] = {0xf8, 0x7e, 0xf7, 0x99, 0x4a, 0x86, 0xf3, 0xe9,
312  * 0xa3, 0xab, 0x6a, 0x6f, 0x2d, 0x34, 0x3b, 0xbd};
313  * uint8_t keyingMaterial[] = {0x4f, 0xd7, 0xf2, 0x09, 0xdf, 0xb0, 0xdf, 0xbd,
314  * 0xd9, 0x8d, 0x2d, 0xb4, 0x98, 0x66, 0x4c, 0x88};
315  * uint8_t plaintext[sizeof(ciphertext)];
316  *
317  * // The plaintext should be the following after the decryption operation:
318  * // 0x17, 0x9d, 0xcb, 0x79, 0x5c, 0x09, 0x8f, 0xc5, 0x31, 0x4b, 0xde, 0x0d, 0x39, 0x9d, 0x7a, 0x10
319  *
320  *
321  * void gcmCallback(AESGCM_Handle handle,
322  * int_fast16_t returnValue,
323  * AESGCM_OperationUnion *operation,
324  * AESGCM_OperationType operationType) {
325  *
326  * if (returnValue != AESGCM_STATUS_SUCCESS) {
327  * // handle error
328  * }
329  * }
330  *
331  * AESGCM_OneStepOperation operation;
332  * CryptoKey cryptoKey;
333  *
334  * void gcmStartFunction(void) {
335  * AESGCM_Handle handle;
336  * AESGCM_Params params;
337  * int_fast16_t decryptionResult;
338  *
339  * AESGCM_Params_init(&params);
340  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
341  * params.callbackFxn = gcmCallback;
342  *
343  * handle = AESGCM_open(0, &params);
344  *
345  * if (handle == NULL) {
346  * // handle error
347  * }
348  *
349  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
350  *
351  * AESGCM_OneStepOperation_init(&operation);
352  *
353  * operation.key = &cryptoKey;
354  * operation.aad = aad;
355  * operation.aadLength = sizeof(aad);
356  * operation.input = ciphertext;
357  * operation.output = plaintext;
358  * operation.inputLength = sizeof(ciphertext);
359  * operation.iv = iv;
360  * operation.ivLength = sizeof(iv);
361  * operation.mac = mac;
362  * operation.macLength = sizeof(mac);
363  *
364  * decryptionResult = AESGCM_oneStepDecrypt(handle, &operation);
365  *
366  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
367  * // handle error
368  * }
369  *
370  * // do other things while GCM operation completes in the background
371  *
372  * }
373  *
374  * @endcode
375  *
376  * ### Multi-step GCM encryption + authentication with plaintext CryptoKey in blocking return mode #
377  * @code
378  *
379  * #include <ti/drivers/AESGCM.h>
380  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
381  *
382  * ...
383  *
384  * #define AES_BLOCK_SIZE 16 // bytes
385  *
386  * AESGCM_Handle handle;
387  * CryptoKey cryptoKey;
388  * int_fast16_t encryptionResult;
389  *
390  * uint8_t keyingMaterial[32] = {0x58, 0x53, 0xc0, 0x20, 0x94, 0x6b, 0x35, 0xf2,
391  * 0xc5, 0x8e, 0xc4, 0x27, 0x15, 0x2b, 0x84, 0x04,
392  * 0x20, 0xc4, 0x00, 0x29, 0x63, 0x6a, 0xdc, 0xbb,
393  * 0x02, 0x74, 0x71, 0x37, 0x8c, 0xfd, 0xde, 0x0f};
394  * uint8_t aad[20] = {0x13, 0x89, 0xb5, 0x22, 0xc2, 0x4a, 0x77, 0x41,
395  * 0x81, 0x70, 0x05, 0x53, 0xf0, 0x24, 0x6b, 0xba,
396  * 0xbd, 0xd3, 0x8d, 0x6f};
397  * uint8_t plaintext[32] = {0xce, 0x74, 0x58, 0xe5, 0x6a, 0xef, 0x90, 0x61,
398  * 0xcb, 0x0c, 0x42, 0xec, 0x23, 0x15, 0x56, 0x5e,
399  * 0x61, 0x68, 0xf5, 0xa6, 0x24, 0x9f, 0xfd, 0x31,
400  * 0x61, 0x0b, 0x6d, 0x17, 0xab, 0x64, 0x93, 0x5e};
401  * uint8_t iv[12] = {0xee, 0xc3, 0x13, 0xdd, 0x07, 0xcc, 0x1b, 0x3e,
402  * 0x6b, 0x06, 0x8a, 0x47};
403  * uint8_t mac[16];
404  * uint8_t ciphertext[sizeof(plaintext)];
405  *
406  * // The ciphertext should be the following after the encryption operation:
407  * // {0xea, 0xdc, 0x3b, 0x87, 0x66, 0xa7, 0x7d, 0xed,
408  * // 0x1a, 0x58, 0xcb, 0x72, 0x7e, 0xca, 0x2a, 0x97,
409  * // 0x90, 0x49, 0x6c, 0x29, 0x86, 0x54, 0xcd, 0xa7,
410  * // 0x8f, 0xeb, 0xf0, 0xda, 0x16, 0xb6, 0x90, 0x3b}
411  *
412  * handle = AESGCM_open(0, NULL);
413  *
414  * if (handle == NULL) {
415  * // handle error
416  * }
417  *
418  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
419  *
420  * encryptionResult = AESGCM_setupEncrypt(handle, &cryptoKey, sizeof(aad), sizeof(plaintext));
421  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
422  * // handle error
423  * }
424  *
425  * encryptionResult = AESGCM_setIV(handle, iv, sizeof(iv));
426  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
427  * // handle error
428  * }
429  *
430  * AESGCM_SegmentedAADOperation segmentedAADOperation;
431  * AESGCM_SegmentedAADOperation_init(&segmentedAADOperation);
432  * segmentedAADOperation.aad = aad;
433  * // One should pass in data that is a block-sized multiple length
434  * // until passing in the last segment of data.
435  * // In that case, the input length simply needs to be a non-zero value.
436  * segmentedAADOperation.aadLength = sizeof(aad);
437  *
438  * encryptionResult = AESGCM_addAAD(handle, &segmentedAADOperation);
439  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
440  * // handle error
441  * }
442  *
443  * AESGCM_SegmentedDataOperation segmentedDataOperation;
444  * AESGCM_SegmentedDataOperation_init(&segmentedDataOperation);
445  * segmentedDataOperation.input = plaintext;
446  * segmentedDataOperation.output = ciphertext;
447  * // One should pass in data that is a block-sized multiple length
448  * // until passing in the last segment of data.
449  * // In that case, the input length simply needs to be a non-zero value.
450  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
451  *
452  * encryptionResult = AESGCM_addData(handle, &segmentedDataOperation);
453  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
454  * // handle error
455  * }
456  *
457  * AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
458  * AESGCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
459  * segmentedFinalizeOperation.input = plaintext + AES_BLOCK_SIZE;
460  * segmentedFinalizeOperation.output = ciphertext + AES_BLOCK_SIZE;
461  * segmentedFinalizeOperation.inputLength = AES_BLOCK_SIZE;
462  * segmentedFinalizeOperation.mac = mac;
463  * segmentedFinalizeOperation.macLength = sizeof(mac);
464  * encryptionResult = AESGCM_finalizeEncrypt(handle, &segmentedFinalizeOperation);
465  *
466  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
467  * // handle error
468  * }
469  *
470  * AESGCM_close(handle);
471  *
472  * @endcode
473  *
474  * ### Multi-step GCM decryption + verification with plaintext CryptoKey in callback return mode #
475  * @code
476  *
477  * #include <ti/drivers/AESGCM.h>
478  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
479  *
480  * ...
481  *
482  * #define AES_BLOCK_SIZE 16 // bytes
483  *
484  * uint8_t iv[] = {0x7f, 0xc2, 0x5c, 0x0c, 0x7a, 0x65, 0xb9, 0x50,
485  * 0x00, 0x23, 0xd0, 0x58};
486  * uint8_t aad[] = {0x9e, 0xca, 0x27, 0x10, 0xbc, 0x1c, 0xaa, 0x99,
487  * 0x50, 0x2d, 0xe3, 0x0f, 0x08, 0x94, 0x30, 0x69,
488  * 0x7a, 0xee, 0xfc, 0x03};
489  * uint8_t mac[] = {0x77, 0xb6, 0x4e, 0x40};
490  * uint8_t ciphertext[] = {0xbd, 0xb4, 0x3f, 0x90, 0xf1, 0x6e, 0x26, 0xdc,
491  * 0xff, 0x60, 0xdb, 0x92, 0xb9, 0x6c, 0x4a, 0x2f};
492  * uint8_t keyingMaterial[] = {0xfb, 0x96, 0x31, 0x2b, 0xdb, 0x8a, 0x22, 0xf1,
493  * 0x6f, 0xad, 0xc4, 0x23, 0x69, 0x4f, 0x45, 0x70};
494  * uint8_t plaintext[sizeof(ciphertext)];
495  *
496  * // The plaintext should be the following after the decryption operation:
497  * // {0xae, 0xe4, 0x16, 0xa2, 0x1f, 0x0e, 0x98, 0x3f,
498  * // 0xd7, 0x05, 0x20, 0xb8, 0xce, 0xdb, 0x24, 0xe5}
499  *
500  * void gcmCallback(AESGCM_Handle handle,
501  * int_fast16_t returnValue,
502  * AESGCM_OperationUnion *operation,
503  * AESGCM_OperationType operationType) {
504  *
505  * if (returnValue != AESGCM_STATUS_SUCCESS) {
506  * // handle error
507  * }
508  *
509  * if(operationType == AESGCM_OPERATION_TYPE_DECRYPT ||
510  * operationType == AESGCM_OPERATION_TYPE_ENCRYPT)
511  * {
512  * // Callback fxn only used for one-shot operations
513  * // Use operation->oneStepOperation
514  * }
515  * else if(operationType == AESGCM_OP_TYPE_AAD_DECRYPT ||
516  * operationType == AESGCM_OP_TYPE_AAD_ENCRYPT)
517  * {
518  * // Callback fxn only used for segmented AAD operations
519  * // Use operation->segmentedAADOperation
520  * }
521  * else if(operationType == AESGCM_OP_TYPE_DATA_DECRYPT ||
522  * operationType == AESGCM_OP_TYPE_DATA_ENCRYPT)
523  * {
524  * // Callback fxn only used for segmented data operations
525  * // Use operation->segmentedDataOperation
526  * }
527  * else
528  * {
529  * // Callback fxn only used for segmented finalize operations
530  * // Use operation->segmentedFinalizeOperation
531  * }
532  * }
533  *
534  * void gcmStartFunction(void) {
535  * AESGCM_Handle handle;
536  * AESGCM_Params params;
537  * CryptoKey cryptoKey;
538  * int_fast16_t decryptionResult;
539  *
540  * AESGCM_Params_init(&params);
541  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
542  * params.callbackFxn = gcmCallback;
543  *
544  * handle = AESGCM_open(0, &params);
545  *
546  * if (handle == NULL) {
547  * // handle error
548  * }
549  *
550  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
551  *
552  * decryptionResult = AESGCM_setupDecrypt(handle, &cryptoKey, 0, 0);
553  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
554  * // handle error
555  * }
556  *
557  * // setLengths must be called if the AAD and input lengths aren't provided in setupXXXX.
558  * decryptionResult = AESGCM_setLengths(handle, sizeof(aad), sizeof(ciphertext));
559  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
560  * // handle error
561  * }
562  *
563  * decryptionResult = AESGCM_setIV(handle, iv, sizeof(iv));
564  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
565  * // handle error
566  * }
567  *
568  * AESGCM_SegmentedAADOperation segmentedAADOperation;
569  * AESGCM_SegmentedAADOperation_init(&segmentedAADOperation);
570  * segmentedAADOperation.aad = aad;
571  * segmentedAADOperation.aadLength = sizeof(aad);
572  *
573  * decryptionResult = AESGCM_addAAD(handle, &segmentedAADOperation);
574  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
575  * // handle error
576  * }
577  *
578  * AESGCM_SegmentedDataOperation segmentedDataOperation;
579  * AESGCM_SegmentedDataOperation_init(&segmentedDataOperation);
580  * segmentedDataOperation.input = ciphertext;
581  * segmentedDataOperation.output = plaintext;
582  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
583  *
584  * decryptionResult = AESGCM_addData(handle, &segmentedDataOperation);
585  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
586  * // handle error
587  * }
588  *
589  * AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
590  * AESGCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
591  * segmentedFinalizeOperation.input = ciphertext;
592  * segmentedFinalizeOperation.output = plaintext;
593  *
594  * // You can finalize with no new data
595  * segmentedFinalizeOperation.inputLength = 0;
596  * segmentedFinalizeOperation.mac = mac;
597  * segmentedFinalizeOperation.macLength = sizeof(mac);
598  *
599  * decryptionResult = AESGCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
600  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
601  * // handle error
602  * }
603  *
604  * // do other things while GCM operation completes in the background
605  *
606  * }
607  *
608  * @endcode
609  */
610 
611 #ifndef ti_drivers_AESGCM__include
612 #define ti_drivers_AESGCM__include
613 
614 #include <stdbool.h>
615 #include <stddef.h>
616 #include <stdint.h>
617 
618 #include <ti/drivers/AESCommon.h>
620 
621 #ifdef __cplusplus
622 extern "C" {
623 #endif
624 
625 /* Only IVs with a length of 12 bytes are supported for now */
626 #define AESGCM_IV_LENGTH_BYTES 12
627 
640 #define AESGCM_STATUS_RESERVED AES_STATUS_RESERVED
641 
647 #define AESGCM_STATUS_SUCCESS AES_STATUS_SUCCESS
648 
655 #define AESGCM_STATUS_ERROR AES_STATUS_ERROR
656 
665 #define AESGCM_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
666 
670 #define AESGCM_STATUS_CANCELED AES_STATUS_CANCELED
671 
679 #define AESGCM_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID
680 
687 #define AESGCM_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
688 
692 #define AESGCM_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
693 
698 #define AESGCM_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
699 
706 #define AESGCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
707 
723 typedef AESGCM_Config *AESGCM_Handle;
724 
746 typedef enum
747 {
766 
770 typedef enum
771 {
774 } AESGCM_Mode;
775 
780 typedef struct
781 {
783  uint8_t *aad;
787  uint8_t *input;
792  uint8_t *output;
800  uint8_t *iv;
806  uint8_t *mac;
812  size_t aadLength;
818  size_t inputLength;
823  uint8_t ivLength;
826  uint8_t macLength;
834 
840 typedef struct
841 {
842  uint8_t *aad;
846  size_t aadLength;
855 
861 typedef struct
862 {
863  uint8_t *input;
868  uint8_t *output;
876  size_t inputLength;
882 
888 typedef struct
889 {
890  uint8_t *input;
895  uint8_t *output;
903  uint8_t *mac;
909  size_t inputLength;
914  uint8_t macLength;
918 
927 
933 {
934  AESGCM_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */
935  AESGCM_SegmentedAADOperation segmentedAADOperation; /* Segmented AAD operation element of the operation union */
936  AESGCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */
937  AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the
938  operation union */
940 
944 typedef enum
945 {
946  AESGCM_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */
948  AESGCM_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not
949  being unique */
958 
974 typedef void (*AESGCM_CallbackFxn)(AESGCM_Handle handle,
975  int_fast16_t returnValue,
976  AESGCM_OperationUnion *operation,
977  AESGCM_OperationType operationType);
978 
987 typedef struct
988 {
989  AESGCM_ReturnBehavior returnBehavior;
991  uint32_t timeout;
994  void *custom;
997 } AESGCM_Params;
998 
1004 extern const AESGCM_Params AESGCM_defaultParams;
1005 
1014 void AESGCM_init(void);
1015 
1028 void AESGCM_Params_init(AESGCM_Params *params);
1029 
1047 AESGCM_Handle AESGCM_open(uint_least8_t index, const AESGCM_Params *params);
1048 
1058 void AESGCM_close(AESGCM_Handle handle);
1059 
1087 int_fast16_t AESGCM_setupEncrypt(AESGCM_Handle handle,
1088  const CryptoKey *key,
1089  size_t totalAADLength,
1090  size_t totalPlaintextLength);
1091 
1119 int_fast16_t AESGCM_setupDecrypt(AESGCM_Handle handle,
1120  const CryptoKey *key,
1121  size_t totalAADLength,
1122  size_t totalPlaintextLength);
1123 
1150 int_fast16_t AESGCM_setLengths(AESGCM_Handle handle, size_t aadLength, size_t plaintextLength);
1151 
1172 int_fast16_t AESGCM_setIV(AESGCM_Handle handle, const uint8_t *iv, size_t ivLength);
1173 
1198 int_fast16_t AESGCM_generateIV(AESGCM_Handle handle, uint8_t *iv, size_t ivSize, size_t *ivLength);
1199 
1231 int_fast16_t AESGCM_addAAD(AESGCM_Handle handle, AESGCM_SegmentedAADOperation *operation);
1232 
1262 int_fast16_t AESGCM_addData(AESGCM_Handle handle, AESGCM_SegmentedDataOperation *operation);
1263 
1289 int_fast16_t AESGCM_finalizeEncrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation);
1290 
1320 int_fast16_t AESGCM_finalizeDecrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation);
1321 
1333 void AESGCM_Operation_init(AESGCM_Operation *operationStruct);
1334 
1344 
1354 
1364 
1374 
1395 int_fast16_t AESGCM_oneStepEncrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct);
1396 
1418 int_fast16_t AESGCM_oneStepDecrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct);
1419 
1434 int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle);
1435 
1459 AESGCM_Handle AESGCM_construct(AESGCM_Config *config, const AESGCM_Params *params);
1460 
1461 #ifdef __cplusplus
1462 }
1463 #endif
1464 
1465 #endif /* ti_drivers_AESGCM__include */
Definition: AESGCM.h:950
void * custom
Definition: AESGCM.h:994
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:944
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:954
uint8_t * mac
Definition: AESGCM.h:903
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:829
int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle)
Cancels an ongoing AESGCM operation.
uint8_t * iv
Definition: AESGCM.h:800
Definition: AESGCM.h:952
const AESGCM_Params AESGCM_defaultParams
Default AESGCM_Params structure.
uint8_t * input
Definition: AESGCM.h:863
Definition: AESGCM.h:948
AES Global configuration.
Definition: AESCommon.h:154
Definition: AESGCM.h:748
size_t inputLength
Definition: AESGCM.h:909
CryptoKey datastructure.
Definition: CryptoKey.h:211
AESGCM_SegmentedAADOperation segmentedAADOperation
Definition: AESGCM.h:935
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:861
size_t inputLength
Definition: AESGCM.h:818
uint8_t * input
Definition: AESGCM.h:787
Definition: AESCommon.h:186
Definition: AESGCM.h:953
uint8_t * aad
Definition: AESGCM.h:783
Definition: AESCommon.h:196
uint8_t ivLength
Definition: AESGCM.h:823
void AESGCM_Operation_init(AESGCM_Operation *operationStruct)
Function to initialize an AESGCM_Operation struct to its defaults.
Definition: AESGCM.h:956
Struct containing the parameters required for authenticating/verifying additional data in a segmented...
Definition: AESGCM.h:840
AESGCM_ReturnBehavior returnBehavior
Definition: AESGCM.h:989
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:806
uint8_t * aad
Definition: AESGCM.h:842
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:914
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:974
Definition: AESGCM.h:947
Struct containing the parameters required for finalizing an encryption/decryption and authentication/...
Definition: AESGCM.h:888
Definition: AESGCM.h:951
AESGCM_ReturnBehavior
The way in which GCM function calls return after performing an encryption + authentication or decrypt...
Definition: AESGCM.h:746
Definition: AESGCM.h:773
Definition: AESGCM.h:760
size_t aadLength
Definition: AESGCM.h:812
Struct containing the parameters required for encrypting/decrypting and authenticating/verifying a me...
Definition: AESGCM.h:780
AESGCM_OneStepOperation oneStepOperation
Definition: AESGCM.h:934
AESGCM_SegmentedDataOperation segmentedDataOperation
Definition: AESGCM.h:936
uint8_t * input
Definition: AESGCM.h:890
Definition: AESGCM.h:946
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:991
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:895
AESGCM_Config * AESGCM_Handle
A handle that is returned from an AESGCM_open() call.
Definition: AESGCM.h:723
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESGCM.h:932
uint8_t * output
Definition: AESGCM.h:792
size_t inputLength
Definition: AESGCM.h:876
size_t aadLength
Definition: AESGCM.h:846
void AESGCM_Params_init(AESGCM_Params *params)
Function to initialize the AESGCM_Params struct to its defaults.
uint8_t macLength
Definition: AESGCM.h:826
int_fast16_t AESGCM_finalizeEncrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and ciphertext.
Definition: AESGCM.h:955
uint8_t * output
Definition: AESGCM.h:868
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:782
AESGCM_Mode
Enum for the direction of the GCM operation.
Definition: AESGCM.h:770
AES common module header for all devices.
GCM Parameters.
Definition: AESGCM.h:987
AESCommon_Config AESGCM_Config
AESGCM Global configuration.
Definition: AESGCM.h:719
AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation
Definition: AESGCM.h:937
AESGCM_OneStepOperation AESGCM_Operation
Definition: AESGCM.h:926
union AESGCM_OperationUnion AESGCM_OperationUnion
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESGCM.h:755
Definition: AESGCM.h:772
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:990
© Copyright 1995-2025, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale