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  * #### 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  * <h4> The following code snippet is for CC27XX devices only and leverages the HSM which is a seperate Hardware
227  * Accelerator </h4>
228  *
229  * ##### Single call GCM encryption + authentication with plaintext CryptoKey in blocking return mode
230  * for the HSM accelerator #
231  *
232  * @code
233  *
234  * #include <ti/drivers/AESGCM.h>
235  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
236  *
237  * ...
238  *
239  * AESGCM_Handle handle;
240  * CryptoKey cryptoKey;
241  * int_fast16_t encryptionResult;
242  * uint8_t iv[12] = "12-byte IV ";
243  * uint8_t aad[] = "This string will be authenticated but not encrypted.";
244  * uint8_t plaintext[] = "This string will be encrypted and authenticated.";
245  * uint8_t mac[16];
246  * uint8_t ciphertext[sizeof(plaintext)];
247  * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
248  * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
249  * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
250  * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
251  *
252  * handle = AESGCM_open(0, NULL);
253  *
254  * if (handle == NULL) {
255  * // handle error
256  * }
257  *
258  * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
259  *
260  * AESGCM_OneStepOperation operation;
261  * AESGCM_OneStepOperation_init(&operation);
262  *
263  * operation.key = &cryptoKey;
264  * operation.aad = aad;
265  * operation.aadLength = sizeof(aad);
266  * operation.input = plaintext;
267  * operation.output = ciphertext;
268  * operation.inputLength = sizeof(plaintext);
269  * operation.iv = iv;
270  * operation.ivLength = 12;
271  * operation.mac = mac;
272  * operation.macLength = sizeof(mac);
273  *
274  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
275  *
276  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
277  * // handle error
278  * }
279  *
280  * AESGCM_close(handle);
281  *
282  * @endcode
283  *
284  * ##### Single call GCM decryption + verification with plaintext CryptoKey in callback return mode #
285  *
286  * @code
287  *
288  * #include <ti/drivers/AESGCM.h>
289  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
290  *
291  * ...
292  *
293  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
294  *
295  * uint8_t iv[] = {0x1f, 0x80, 0x3c, 0x52, 0xca, 0xc4, 0x97, 0xe1,
296  * 0x55, 0xaa, 0x55, 0x2d};
297  * uint8_t aad[] = {0x3b, 0xba, 0x31, 0x28, 0x9d, 0x05, 0xf5, 0x0f,
298  * 0xed, 0x6c, 0x53, 0x35, 0x3c, 0x1f, 0x74, 0xd8,
299  * 0x28, 0xa9, 0x96, 0xb8, 0xd6, 0x84, 0xfe, 0x64,
300  * 0x7f, 0x7c, 0x40, 0xc0, 0xd5, 0x68, 0x8c, 0x89,
301  * 0x68, 0x1a, 0x33, 0xb1, 0x0c, 0xb7, 0x14, 0xb6,
302  * 0x49, 0x0b, 0xdf, 0x1f, 0x16, 0x60, 0x60, 0xa7};
303  * uint8_t mac[] = {0x39, 0x03, 0xe4, 0xdc, 0xa4, 0xe7, 0xc8, 0x21,
304  * 0x62, 0x1a, 0xbb, 0xb2, 0x37, 0x2c, 0x97};
305  * uint8_t ciphertext[] = {0xf8, 0x7e, 0xf7, 0x99, 0x4a, 0x86, 0xf3, 0xe9,
306  * 0xa3, 0xab, 0x6a, 0x6f, 0x2d, 0x34, 0x3b, 0xbd};
307  * uint8_t keyingMaterial[] = {0x4f, 0xd7, 0xf2, 0x09, 0xdf, 0xb0, 0xdf, 0xbd,
308  * 0xd9, 0x8d, 0x2d, 0xb4, 0x98, 0x66, 0x4c, 0x88};
309  * uint8_t plaintext[sizeof(ciphertext)];
310  *
311  * // The plaintext should be the following after the decryption operation:
312  * // 0x17, 0x9d, 0xcb, 0x79, 0x5c, 0x09, 0x8f, 0xc5, 0x31, 0x4b, 0xde, 0x0d, 0x39, 0x9d, 0x7a, 0x10
313  *
314  *
315  * void gcmCallback(AESGCM_Handle handle,
316  * int_fast16_t returnValue,
317  * AESGCM_OperationUnion *operation,
318  * AESGCM_OperationType operationType) {
319  *
320  * if (returnValue != AESGCM_STATUS_SUCCESS) {
321  * // handle error
322  * }
323  * }
324  *
325  * AESGCM_OneStepOperation operation;
326  * CryptoKey cryptoKey;
327  *
328  * void gcmStartFunction(void) {
329  * AESGCM_Handle handle;
330  * AESGCM_Params params;
331  * int_fast16_t decryptionResult;
332  *
333  * AESGCM_Params_init(&params);
334  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
335  * params.callbackFxn = gcmCallback;
336  *
337  * handle = AESGCM_open(0, &params);
338  *
339  * if (handle == NULL) {
340  * // handle error
341  * }
342  *
343  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
344  *
345  * AESGCM_OneStepOperation_init(&operation);
346  *
347  * operation.key = &cryptoKey;
348  * operation.aad = aad;
349  * operation.aadLength = sizeof(aad);
350  * operation.input = ciphertext;
351  * operation.output = plaintext;
352  * operation.inputLength = sizeof(ciphertext);
353  * operation.iv = iv;
354  * operation.ivLength = sizeof(iv);
355  * operation.mac = mac;
356  * operation.macLength = sizeof(mac);
357  *
358  * decryptionResult = AESGCM_oneStepDecrypt(handle, &operation);
359  *
360  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
361  * // handle error
362  * }
363  *
364  * // do other things while GCM operation completes in the background
365  *
366  * }
367  *
368  * @endcode
369  *
370  * ### Multi-step GCM encryption + authentication with plaintext CryptoKey in blocking return mode #
371  * @code
372  *
373  * #include <ti/drivers/AESGCM.h>
374  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
375  *
376  * ...
377  *
378  * #define AES_BLOCK_SIZE 16 // bytes
379  *
380  * AESGCM_Handle handle;
381  * CryptoKey cryptoKey;
382  * int_fast16_t encryptionResult;
383  *
384  * uint8_t keyingMaterial[32] = {0x58, 0x53, 0xc0, 0x20, 0x94, 0x6b, 0x35, 0xf2,
385  * 0xc5, 0x8e, 0xc4, 0x27, 0x15, 0x2b, 0x84, 0x04,
386  * 0x20, 0xc4, 0x00, 0x29, 0x63, 0x6a, 0xdc, 0xbb,
387  * 0x02, 0x74, 0x71, 0x37, 0x8c, 0xfd, 0xde, 0x0f};
388  * uint8_t aad[20] = {0x13, 0x89, 0xb5, 0x22, 0xc2, 0x4a, 0x77, 0x41,
389  * 0x81, 0x70, 0x05, 0x53, 0xf0, 0x24, 0x6b, 0xba,
390  * 0xbd, 0xd3, 0x8d, 0x6f};
391  * uint8_t plaintext[32] = {0xce, 0x74, 0x58, 0xe5, 0x6a, 0xef, 0x90, 0x61,
392  * 0xcb, 0x0c, 0x42, 0xec, 0x23, 0x15, 0x56, 0x5e,
393  * 0x61, 0x68, 0xf5, 0xa6, 0x24, 0x9f, 0xfd, 0x31,
394  * 0x61, 0x0b, 0x6d, 0x17, 0xab, 0x64, 0x93, 0x5e};
395  * uint8_t iv[12] = {0xee, 0xc3, 0x13, 0xdd, 0x07, 0xcc, 0x1b, 0x3e,
396  * 0x6b, 0x06, 0x8a, 0x47};
397  * uint8_t mac[16];
398  * uint8_t ciphertext[sizeof(plaintext)];
399  *
400  * // The ciphertext should be the following after the encryption operation:
401  * // {0xea, 0xdc, 0x3b, 0x87, 0x66, 0xa7, 0x7d, 0xed,
402  * // 0x1a, 0x58, 0xcb, 0x72, 0x7e, 0xca, 0x2a, 0x97,
403  * // 0x90, 0x49, 0x6c, 0x29, 0x86, 0x54, 0xcd, 0xa7,
404  * // 0x8f, 0xeb, 0xf0, 0xda, 0x16, 0xb6, 0x90, 0x3b}
405  *
406  * handle = AESGCM_open(0, NULL);
407  *
408  * if (handle == NULL) {
409  * // handle error
410  * }
411  *
412  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
413  *
414  * encryptionResult = AESGCM_setupEncrypt(handle, &cryptoKey, sizeof(aad), sizeof(plaintext));
415  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
416  * // handle error
417  * }
418  *
419  * encryptionResult = AESGCM_setIV(handle, iv, sizeof(iv));
420  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
421  * // handle error
422  * }
423  *
424  * AESGCM_SegmentedAADOperation segmentedAADOperation;
425  * AESGCM_SegmentedAADOperation_init(&segmentedAADOperation);
426  * segmentedAADOperation.aad = aad;
427  * // One should pass in data that is a block-sized multiple length
428  * // until passing in the last segment of data.
429  * // In that case, the input length simply needs to be a non-zero value.
430  * segmentedAADOperation.aadLength = sizeof(aad);
431  *
432  * encryptionResult = AESGCM_addAAD(handle, &segmentedAADOperation);
433  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
434  * // handle error
435  * }
436  *
437  * AESGCM_SegmentedDataOperation segmentedDataOperation;
438  * AESGCM_SegmentedDataOperation_init(&segmentedDataOperation);
439  * segmentedDataOperation.input = plaintext;
440  * segmentedDataOperation.output = ciphertext;
441  * // One should pass in data that is a block-sized multiple length
442  * // until passing in the last segment of data.
443  * // In that case, the input length simply needs to be a non-zero value.
444  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
445  *
446  * encryptionResult = AESGCM_addData(handle, &segmentedDataOperation);
447  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
448  * // handle error
449  * }
450  *
451  * AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
452  * AESGCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
453  * segmentedFinalizeOperation.input = plaintext + AES_BLOCK_SIZE;
454  * segmentedFinalizeOperation.output = ciphertext + AES_BLOCK_SIZE;
455  * segmentedFinalizeOperation.inputLength = AES_BLOCK_SIZE;
456  * segmentedFinalizeOperation.mac = mac;
457  * segmentedFinalizeOperation.macLength = sizeof(mac);
458  * encryptionResult = AESGCM_finalizeEncrypt(handle, &segmentedFinalizeOperation);
459  *
460  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
461  * // handle error
462  * }
463  *
464  * AESGCM_close(handle);
465  *
466  * @endcode
467  *
468  * ### Multi-step GCM decryption + verification with plaintext CryptoKey in callback return mode #
469  * @code
470  *
471  * #include <ti/drivers/AESGCM.h>
472  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
473  *
474  * ...
475  *
476  * #define AES_BLOCK_SIZE 16 // bytes
477  *
478  * uint8_t iv[] = {0x7f, 0xc2, 0x5c, 0x0c, 0x7a, 0x65, 0xb9, 0x50,
479  * 0x00, 0x23, 0xd0, 0x58};
480  * uint8_t aad[] = {0x9e, 0xca, 0x27, 0x10, 0xbc, 0x1c, 0xaa, 0x99,
481  * 0x50, 0x2d, 0xe3, 0x0f, 0x08, 0x94, 0x30, 0x69,
482  * 0x7a, 0xee, 0xfc, 0x03};
483  * uint8_t mac[] = {0x77, 0xb6, 0x4e, 0x40};
484  * uint8_t ciphertext[] = {0xbd, 0xb4, 0x3f, 0x90, 0xf1, 0x6e, 0x26, 0xdc,
485  * 0xff, 0x60, 0xdb, 0x92, 0xb9, 0x6c, 0x4a, 0x2f};
486  * uint8_t keyingMaterial[] = {0xfb, 0x96, 0x31, 0x2b, 0xdb, 0x8a, 0x22, 0xf1,
487  * 0x6f, 0xad, 0xc4, 0x23, 0x69, 0x4f, 0x45, 0x70};
488  * uint8_t plaintext[sizeof(ciphertext)];
489  *
490  * // The plaintext should be the following after the decryption operation:
491  * // {0xae, 0xe4, 0x16, 0xa2, 0x1f, 0x0e, 0x98, 0x3f,
492  * // 0xd7, 0x05, 0x20, 0xb8, 0xce, 0xdb, 0x24, 0xe5}
493  *
494  * void gcmCallback(AESGCM_Handle handle,
495  * int_fast16_t returnValue,
496  * AESGCM_OperationUnion *operation,
497  * AESGCM_OperationType operationType) {
498  *
499  * if (returnValue != AESGCM_STATUS_SUCCESS) {
500  * // handle error
501  * }
502  *
503  * if(operationType == AESGCM_OPERATION_TYPE_DECRYPT ||
504  * operationType == AESGCM_OPERATION_TYPE_ENCRYPT)
505  * {
506  * // Callback fxn only used for one-shot operations
507  * // Use operation->oneStepOperation
508  * }
509  * else if(operationType == AESGCM_OP_TYPE_AAD_DECRYPT ||
510  * operationType == AESGCM_OP_TYPE_AAD_ENCRYPT)
511  * {
512  * // Callback fxn only used for segmented AAD operations
513  * // Use operation->segmentedAADOperation
514  * }
515  * else if(operationType == AESGCM_OP_TYPE_DATA_DECRYPT ||
516  * operationType == AESGCM_OP_TYPE_DATA_ENCRYPT)
517  * {
518  * // Callback fxn only used for segmented data operations
519  * // Use operation->segmentedDataOperation
520  * }
521  * else
522  * {
523  * // Callback fxn only used for segmented finalize operations
524  * // Use operation->segmentedFinalizeOperation
525  * }
526  * }
527  *
528  * void gcmStartFunction(void) {
529  * AESGCM_Handle handle;
530  * AESGCM_Params params;
531  * CryptoKey cryptoKey;
532  * int_fast16_t decryptionResult;
533  *
534  * AESGCM_Params_init(&params);
535  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
536  * params.callbackFxn = gcmCallback;
537  *
538  * handle = AESGCM_open(0, &params);
539  *
540  * if (handle == NULL) {
541  * // handle error
542  * }
543  *
544  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
545  *
546  * decryptionResult = AESGCM_setupDecrypt(handle, &cryptoKey, 0, 0);
547  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
548  * // handle error
549  * }
550  *
551  * // setLengths must be called if the AAD and input lengths aren't provided in setupXXXX.
552  * decryptionResult = AESGCM_setLengths(handle, sizeof(aad), sizeof(ciphertext));
553  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
554  * // handle error
555  * }
556  *
557  * decryptionResult = AESGCM_setIV(handle, iv, sizeof(iv));
558  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
559  * // handle error
560  * }
561  *
562  * AESGCM_SegmentedAADOperation segmentedAADOperation;
563  * AESGCM_SegmentedAADOperation_init(&segmentedAADOperation);
564  * segmentedAADOperation.aad = aad;
565  * segmentedAADOperation.aadLength = sizeof(aad);
566  *
567  * decryptionResult = AESGCM_addAAD(handle, &segmentedAADOperation);
568  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
569  * // handle error
570  * }
571  *
572  * AESGCM_SegmentedDataOperation segmentedDataOperation;
573  * AESGCM_SegmentedDataOperation_init(&segmentedDataOperation);
574  * segmentedDataOperation.input = ciphertext;
575  * segmentedDataOperation.output = plaintext;
576  * segmentedDataOperation.inputLength = AES_BLOCK_SIZE;
577  *
578  * decryptionResult = AESGCM_addData(handle, &segmentedDataOperation);
579  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
580  * // handle error
581  * }
582  *
583  * AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation;
584  * AESGCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation);
585  * segmentedFinalizeOperation.input = ciphertext;
586  * segmentedFinalizeOperation.output = plaintext;
587  *
588  * // You can finalize with no new data
589  * segmentedFinalizeOperation.inputLength = 0;
590  * segmentedFinalizeOperation.mac = mac;
591  * segmentedFinalizeOperation.macLength = sizeof(mac);
592  *
593  * decryptionResult = AESGCM_finalizeDecrypt(handle, &segmentedFinalizeOperation);
594  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
595  * // handle error
596  * }
597  *
598  * // do other things while GCM operation completes in the background
599  *
600  * }
601  *
602  * @endcode
603  */
604 
605 #ifndef ti_drivers_AESGCM__include
606 #define ti_drivers_AESGCM__include
607 
608 #include <stdbool.h>
609 #include <stddef.h>
610 #include <stdint.h>
611 
612 #include <ti/drivers/AESCommon.h>
614 
615 #ifdef __cplusplus
616 extern "C" {
617 #endif
618 
619 /* Only IVs with a length of 12 bytes are supported for now */
620 #define AESGCM_IV_LENGTH_BYTES 12
621 
634 #define AESGCM_STATUS_RESERVED AES_STATUS_RESERVED
635 
641 #define AESGCM_STATUS_SUCCESS AES_STATUS_SUCCESS
642 
649 #define AESGCM_STATUS_ERROR AES_STATUS_ERROR
650 
659 #define AESGCM_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
660 
664 #define AESGCM_STATUS_CANCELED AES_STATUS_CANCELED
665 
673 #define AESGCM_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID
674 
681 #define AESGCM_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
682 
686 #define AESGCM_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
687 
692 #define AESGCM_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
693 
700 #define AESGCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
701 
717 typedef AESGCM_Config *AESGCM_Handle;
718 
740 typedef enum
741 {
760 
764 typedef enum
765 {
768 } AESGCM_Mode;
769 
774 typedef struct
775 {
777  uint8_t *aad;
781  uint8_t *input;
786  uint8_t *output;
792  uint8_t *iv;
798  uint8_t *mac;
804  size_t aadLength;
807  size_t inputLength;
812  uint8_t ivLength;
815  uint8_t macLength;
823 
829 typedef struct
830 {
831  uint8_t *aad;
835  size_t aadLength;
841 
847 typedef struct
848 {
849  uint8_t *input;
854  uint8_t *output;
860  size_t inputLength;
866 
872 typedef struct
873 {
874  uint8_t *input;
879  uint8_t *output;
885  uint8_t *mac;
891  size_t inputLength;
896  uint8_t macLength;
900 
909 
915 {
916  AESGCM_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */
917  AESGCM_SegmentedAADOperation segmentedAADOperation; /* Segmented AAD operation element of the operation union */
918  AESGCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */
919  AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the
920  operation union */
922 
926 typedef enum
927 {
928  AESGCM_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */
930  AESGCM_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not
931  being unique */
940 
956 typedef void (*AESGCM_CallbackFxn)(AESGCM_Handle handle,
957  int_fast16_t returnValue,
958  AESGCM_OperationUnion *operation,
959  AESGCM_OperationType operationType);
960 
969 typedef struct
970 {
971  AESGCM_ReturnBehavior returnBehavior;
973  uint32_t timeout;
976  void *custom;
979 } AESGCM_Params;
980 
987 
996 void AESGCM_init(void);
997 
1011 
1029 AESGCM_Handle AESGCM_open(uint_least8_t index, const AESGCM_Params *params);
1030 
1040 void AESGCM_close(AESGCM_Handle handle);
1041 
1069 int_fast16_t AESGCM_setupEncrypt(AESGCM_Handle handle,
1070  const CryptoKey *key,
1071  size_t totalAADLength,
1072  size_t totalPlaintextLength);
1073 
1101 int_fast16_t AESGCM_setupDecrypt(AESGCM_Handle handle,
1102  const CryptoKey *key,
1103  size_t totalAADLength,
1104  size_t totalPlaintextLength);
1105 
1132 int_fast16_t AESGCM_setLengths(AESGCM_Handle handle, size_t aadLength, size_t plaintextLength);
1133 
1154 int_fast16_t AESGCM_setIV(AESGCM_Handle handle, const uint8_t *iv, size_t ivLength);
1155 
1180 int_fast16_t AESGCM_generateIV(AESGCM_Handle handle, uint8_t *iv, size_t ivSize, size_t *ivLength);
1181 
1213 int_fast16_t AESGCM_addAAD(AESGCM_Handle handle, AESGCM_SegmentedAADOperation *operation);
1214 
1244 int_fast16_t AESGCM_addData(AESGCM_Handle handle, AESGCM_SegmentedDataOperation *operation);
1245 
1271 int_fast16_t AESGCM_finalizeEncrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation);
1272 
1302 int_fast16_t AESGCM_finalizeDecrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation);
1303 
1315 void AESGCM_Operation_init(AESGCM_Operation *operationStruct);
1316 
1326 
1336 
1346 
1356 
1377 int_fast16_t AESGCM_oneStepEncrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct);
1378 
1400 int_fast16_t AESGCM_oneStepDecrypt(AESGCM_Handle handle, AESGCM_OneStepOperation *operationStruct);
1401 
1416 int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle);
1417 
1441 AESGCM_Handle AESGCM_construct(AESGCM_Config *config, const AESGCM_Params *params);
1442 
1443 #ifdef __cplusplus
1444 }
1445 #endif
1446 
1447 #endif /* ti_drivers_AESGCM__include */
ADC_Params params
Definition: Driver_Init.h:11
Definition: AESGCM.h:932
void * custom
Definition: AESGCM.h:976
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:926
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:936
uint8_t * mac
Definition: AESGCM.h:885
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:818
int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle)
Cancels an ongoing AESGCM operation.
uint8_t * iv
Definition: AESGCM.h:792
Definition: AESGCM.h:934
const AESGCM_Params AESGCM_defaultParams
Default AESGCM_Params structure.
uint8_t * input
Definition: AESGCM.h:849
Definition: AESGCM.h:930
AES Global configuration.
Definition: AESCommon.h:154
Definition: AESGCM.h:742
size_t inputLength
Definition: AESGCM.h:891
CryptoKey datastructure.
Definition: CryptoKey.h:208
AESGCM_SegmentedAADOperation segmentedAADOperation
Definition: AESGCM.h:917
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:847
size_t inputLength
Definition: AESGCM.h:807
uint8_t * input
Definition: AESGCM.h:781
Definition: AESCommon.h:186
Definition: AESGCM.h:935
uint8_t * aad
Definition: AESGCM.h:777
Definition: AESCommon.h:196
uint8_t ivLength
Definition: AESGCM.h:812
void AESGCM_Operation_init(AESGCM_Operation *operationStruct)
Function to initialize an AESGCM_Operation struct to its defaults.
Definition: AESGCM.h:938
Struct containing the parameters required for authenticating/verifying additional data in a segmented...
Definition: AESGCM.h:829
AESGCM_ReturnBehavior returnBehavior
Definition: AESGCM.h:971
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:798
uint8_t * aad
Definition: AESGCM.h:831
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:896
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:956
Definition: AESGCM.h:929
Struct containing the parameters required for finalizing an encryption/decryption and authentication/...
Definition: AESGCM.h:872
Definition: AESGCM.h:933
AESGCM_ReturnBehavior
The way in which GCM function calls return after performing an encryption + authentication or decrypt...
Definition: AESGCM.h:740
Definition: AESGCM.h:767
Definition: AESGCM.h:754
size_t aadLength
Definition: AESGCM.h:804
Struct containing the parameters required for encrypting/decrypting and authenticating/verifying a me...
Definition: AESGCM.h:774
AESGCM_OneStepOperation oneStepOperation
Definition: AESGCM.h:916
AESGCM_SegmentedDataOperation segmentedDataOperation
Definition: AESGCM.h:918
uint8_t * input
Definition: AESGCM.h:874
Definition: AESGCM.h:928
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:973
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:879
AESGCM_Config * AESGCM_Handle
A handle that is returned from an AESGCM_open() call.
Definition: AESGCM.h:717
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESGCM.h:914
uint8_t * output
Definition: AESGCM.h:786
size_t inputLength
Definition: AESGCM.h:860
size_t aadLength
Definition: AESGCM.h:835
void AESGCM_Params_init(AESGCM_Params *params)
Function to initialize the AESGCM_Params struct to its defaults.
uint8_t macLength
Definition: AESGCM.h:815
int_fast16_t AESGCM_finalizeEncrypt(AESGCM_Handle handle, AESGCM_SegmentedFinalizeOperation *operation)
Finalize the MAC and ciphertext.
Definition: AESGCM.h:937
uint8_t * output
Definition: AESGCM.h:854
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:776
AESGCM_Mode
Enum for the direction of the GCM operation.
Definition: AESGCM.h:764
AES common module header for all devices.
GCM Parameters.
Definition: AESGCM.h:969
AESCommon_Config AESGCM_Config
AESGCM Global configuration.
Definition: AESGCM.h:713
AESGCM_SegmentedFinalizeOperation segmentedFinalizeOperation
Definition: AESGCM.h:919
AESGCM_OneStepOperation AESGCM_Operation
Definition: AESGCM.h:908
union AESGCM_OperationUnion AESGCM_OperationUnion
Union containing a reference to a one step, segmented AAD, segmented data, or segmented finalize oper...
Definition: AESGCM.h:749
Definition: AESGCM.h:766
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:972
© Copyright 1995-2024, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale