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