AESGCM.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2019, 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  * @warning This is a beta API. It may change in future releases.
39  *
40  * @anchor ti_drivers_AESGCM_Overview
41  * ### Overview #
42  *
43  * The Galois Counter Mode (GCM) mode of operation is a generic
44  * authenticated encryption with associated data (AEAD) block cipher mode.
45  * It can be implemented with any block cipher.
46  * AESGCM combines GHASH with the AES block cipher in CTR mode of operation.
47  *
48  * This combination of block cipher modes enables GCM to encrypt messages of any
49  * length and not only multiples of the block cipher block size.
50  *
51  * CTR provides confidentiality. The using GHASH and encrypting the result provides
52  * message integrity and authentication.
53  *
54  * The AES key is a shared secret between the two parties and has a length
55  * of 128, 192, or 256 bits.
56  *
57  * The IV is generated by the party performing the authenticated
58  * encryption operation. Within the scope of any authenticated
59  * encryption key, the IV value must be unique. That is, the set of
60  * IV values used with any given key must not contain any duplicate
61  * values. Using the same IV for two different messages encrypted
62  * with the same key destroys the security properties of GCM.
63  *
64  * The optional additional authentication data (AAD) is authenticated
65  * but not encrypted. Thus, the AAD is not included in the AES-GCM output.
66  * It can be used to authenticate packet headers, timestamps and other
67  * metadata.
68  *
69  * After the encryption operation, the ciphertext contains the encrypted
70  * data and the message authentication code (MAC).
71  *
72  * GCM is highly performant for an AEAD mode. Counter with CBC-MAC requires
73  * one invocation per block of AAD and two invocations of the block cipher
74  * per proccessed block of input; one to compute the CBC-MAC and one to
75  * perform CTR. GCM substitutes the block cipher invocation during CBC-MAC
76  * computation with computing GHASH over the same input. GHASH is significantly
77  * faster per block than AES. In turn, this gives GCM a performance edge
78  * over CCM.
79  *
80  * ### Security Considerations
81  *
82  * In each operation, GCM limits the length of the input and AAD to guarantee
83  * its security properties:
84  * - inputLength <= 2^36 - 32 bytes
85  * - aadLength <= 2^61 - 1 bytes
86  *
87  * The security properties of GCM rely on the MAC size. While MAC lengths of
88  * [4, 8, 12, 13, 14, 15, 16] bytes are permitted, it is recommended to
89  * use the full 16-byte MAC.
90  *
91  * See NIST SP 800-38D for more a more detailed discussion of security
92  * considerations.
93  *
94  * @anchor ti_drivers_AESGCM_Usage
95  * ### Usage #
96  *
97  * #### Before starting a GCM operation #
98  *
99  * Before starting a GCM operation, the application must do the following:
100  * - Call AESGCM_init() to initialize the driver
101  * - Call AESGCM_Params_init() to initialize the #AESGCM_Params to default values.
102  * - Modify the #AESGCM_Params as desired
103  * - Call AESGCM_open() to open an instance of the driver
104  * - Initialize a CryptoKey. These opaque datastructures are representations
105  * of keying material and its storage. Depending on how the keying material
106  * is stored (RAM or flash, key store, key blob), the CryptoKey must be
107  * initialized differently. The AESGCM API can handle all types of CryptoKey.
108  * However, not all device-specific implementions support all types of CryptoKey.
109  * Devices without a key store will not support CryptoKeys with keying material
110  * stored in a key store for example.
111  * All devices support plaintext CryptoKeys.
112  * - Initialise the #AESGCM_Operation using AESGCM_Operation_init() and set all
113  * length, key, and buffer fields.
114  *
115  * #### Starting a GCM operation #
116  *
117  * The AESGCM_oneStepEncrypt() and AESGCM_oneStepDecrypt() functions perform a GCM operation in a single call.
118  *
119  * When performing a decryption operation with AESGCM_oneStepDecrypt(), the MAC is
120  * automatically verified.
121  *
122  * #### After the GCM operation completes #
123  *
124  * After the GCM operation completes, the application should either start another operation
125  * or close the driver by calling AESGCM_close()
126  *
127  * @anchor ti_drivers_AESGCM_Synopsis
128  * ## Synopsis
129  *
130  * @anchor ti_drivers_AESGCM_Synopsis_Code
131  * @code
132  *
133  * // Import AESGCM Driver definitions
134  * #include <ti/drivers/AESGCM.h>
135  *
136  * // Define name for AESGCM channel index
137  * #define AESGCM_INSTANCE 0
138  *
139  * AESGCM_init();
140  *
141  * handle = AESGCM_open(AESGCM_INSTANCE, NULL);
142  *
143  * // Initialize symmetric key
144  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
145  *
146  * // Set up AESGCM_Operation
147  * AESGCM_Operation_init(&operation);
148  * operation.key = &cryptoKey;
149  * operation.aad = aad;
150  * operation.aadLength = sizeof(aad);
151  * operation.input = plaintext;
152  * operation.output = ciphertext;
153  * operation.inputLength = sizeof(plaintext);
154  * operation.nonce = nonce;
155  * operation.nonceLength = sizeof(nonce);
156  * operation.mac = mac;
157  * operation.macLength = sizeof(mac);
158  *
159  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
160  *
161  * AESGCM_close(handle);
162  * @endcode
163  *
164  * @anchor ti_drivers_AESGCM_Examples
165  * #### Examples
166  *
167  * ##### Single call GCM encryption + authentication with plaintext CryptoKey in blocking return mode #
168  *
169  * @code
170  *
171  * #include <ti/drivers/AESGCM.h>
172  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
173  *
174  * ...
175  *
176  * AESGCM_Handle handle;
177  * CryptoKey cryptoKey;
178  * int_fast16_t encryptionResult;
179  * uint8_t iv[12] = "12-byte IV ";
180  * uint8_t aad[] = "This string will be authenticated but not encrypted.";
181  * uint8_t plaintext[] = "This string will be encrypted and authenticated.";
182  * uint8_t mac[16];
183  * uint8_t ciphertext[sizeof(plaintext)];
184  * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
185  * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
186  * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
187  * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
188  *
189  * handle = AESGCM_open(0, NULL);
190  *
191  * if (handle == NULL) {
192  * // handle error
193  * }
194  *
195  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
196  *
197  * AESGCM_Operation operation;
198  * AESGCM_Operation_init(&operation);
199  *
200  * operation.key = &cryptoKey;
201  * operation.aad = aad;
202  * operation.aadLength = sizeof(aad);
203  * operation.input = plaintext;
204  * operation.output = ciphertext;
205  * operation.inputLength = sizeof(plaintext);
206  * operation.iv = iv;
207  * operation.ivLength = 12;
208  * operation.mac = mac;
209  * operation.macLength = sizeof(mac);
210  *
211  * encryptionResult = AESGCM_oneStepEncrypt(handle, &operation);
212  *
213  * if (encryptionResult != AESGCM_STATUS_SUCCESS) {
214  * // handle error
215  * }
216  *
217  * AESGCM_close(handle);
218  *
219  * @endcode
220  *
221  * ##### Single call GCM decryption + verification with plaintext CryptoKey in callback return mode #
222  *
223  * @code
224  *
225  * #include <ti/drivers/AESGCM.h>
226  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
227  *
228  * ...
229  *
230  * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF.
231  *
232  * uint8_t iv[] = {0x1f, 0x80, 0x3c, 0x52, 0xca, 0xc4, 0x97, 0xe1,
233  * 0x55, 0xaa, 0x55, 0x2d};
234  * uint8_t aad[] = {0x3b, 0xba, 0x31, 0x28, 0x9d, 0x05, 0xf5, 0x0f,
235  * 0xed, 0x6c, 0x53, 0x35, 0x3c, 0x1f, 0x74, 0xd8,
236  * 0x28, 0xa9, 0x96, 0xb8, 0xd6, 0x84, 0xfe, 0x64,
237  * 0x7f, 0x7c, 0x40, 0xc0, 0xd5, 0x68, 0x8c, 0x89,
238  * 0x68, 0x1a, 0x33, 0xb1, 0x0c, 0xb7, 0x14, 0xb6,
239  * 0x49, 0x0b, 0xdf, 0x1f, 0x16, 0x60, 0x60, 0xa7};
240  * uint8_t mac[] = {0x39, 0x03, 0xe4, 0xdc, 0xa4, 0xe7, 0xc8, 0x21,
241  * 0x62, 0x1a, 0xbb, 0xb2, 0x37, 0x2c, 0x97};
242  * uint8_t ciphertext[] = {0xf8, 0x7e, 0xf7, 0x99, 0x4a, 0x86, 0xf3, 0xe9,
243  * 0xa3, 0xab, 0x6a, 0x6f, 0x2d, 0x34, 0x3b, 0xbd};
244  * uint8_t keyingMaterial[] = {0x4f, 0xd7, 0xf2, 0x09, 0xdf, 0xb0, 0xdf, 0xbd,
245  * 0xd9, 0x8d, 0x2d, 0xb4, 0x98, 0x66, 0x4c, 0x88};
246  * uint8_t plaintext[sizeof(ciphertext)];
247  *
248  * // The plaintext should be the following after the decryption operation:
249  * // 0x17, 0x9d, 0xcb, 0x79, 0x5c, 0x09, 0x8f, 0xc5, 0x31, 0x4b, 0xde, 0x0d, 0x39, 0x9d, 0x7a, 0x10
250  *
251  *
252  * void gcmCallback(AESGCM_Handle handle,
253  * int_fast16_t returnValue,
254  * AESGCM_Operation *operation,
255  * AESGCM_OperationType operationType) {
256  *
257  * if (returnValue != AESGCM_STATUS_SUCCESS) {
258  * // handle error
259  * }
260  * }
261  *
262  * AESGCM_Operation operation;
263  * CryptoKey cryptoKey;
264  *
265  * void gcmStartFunction(void) {
266  * AESGCM_Handle handle;
267  * AESGCM_Params params;
268  * int_fast16_t decryptionResult;
269  *
270  * AESGCM_Params_init(&params);
271  * params.returnBehavior = AESGCM_RETURN_BEHAVIOR_CALLBACK;
272  * params.callbackFxn = gcmCallback;
273  *
274  * handle = AESGCM_open(0, &params);
275  *
276  * if (handle == NULL) {
277  * // handle error
278  * }
279  *
280  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
281  *
282  * AESGCM_Operation_init(&operation);
283  *
284  * operation.key = &cryptoKey;
285  * operation.aad = aad;
286  * operation.aadLength = sizeof(aad);
287  * operation.input = ciphertext;
288  * operation.output = plaintext;
289  * operation.inputLength = sizeof(ciphertext);
290  * operation.iv = iv;
291  * operation.mac = mac;
292  * operation.macLength = sizeof(mac);
293  *
294  * decryptionResult = AESGCM_oneStepDecrypt(handle, &operation);
295  *
296  * if (decryptionResult != AESGCM_STATUS_SUCCESS) {
297  * // handle error
298  * }
299  *
300  * // do other things while GCM operation completes in the background
301  *
302  * }
303  * @endcode
304  */
305 
306 #ifndef ti_drivers_AESGCM__include
307 #define ti_drivers_AESGCM__include
308 
309 #include <stdbool.h>
310 #include <stddef.h>
311 #include <stdint.h>
312 
314 
315 #ifdef __cplusplus
316 extern "C" {
317 #endif
318 
331 #define AESGCM_STATUS_RESERVED (-32)
332 
339 #define AESGCM_STATUS_SUCCESS (0)
340 
347 #define AESGCM_STATUS_ERROR (-1)
348 
357 #define AESGCM_STATUS_RESOURCE_UNAVAILABLE (-2)
358 
366 #define AESGCM_STATUS_MAC_INVALID (-3)
367 
371 #define AESGCM_STATUS_CANCELED (-4)
372 
384 typedef struct {
386  void *object;
387 
389  void const *hwAttrs;
390 } AESGCM_Config;
391 
396 
418 typedef enum {
434 
438 typedef enum {
441 } AESGCM_Mode;
442 
447 typedef struct {
449  uint8_t *aad;
453  uint8_t *input;
458  uint8_t *output;
464  uint8_t *iv;
470  uint8_t *mac;
476  size_t aadLength;
480  size_t inputLength;
484  uint8_t ivLength;
487  uint8_t macLength;
495 
499 typedef enum {
503 
519 typedef void (*AESGCM_CallbackFxn) (AESGCM_Handle handle,
520  int_fast16_t returnValue,
521  AESGCM_Operation *operation,
522  AESGCM_OperationType operationType);
523 
532 typedef struct {
535  uint32_t timeout;
538  void *custom;
541 } AESGCM_Params;
542 
549 
558 void AESGCM_init(void);
559 
572 void AESGCM_Params_init(AESGCM_Params *params);
573 
591 AESGCM_Handle AESGCM_open(uint_least8_t index, const AESGCM_Params *params);
592 
602 void AESGCM_close(AESGCM_Handle handle);
603 
612 void AESGCM_Operation_init(AESGCM_Operation *operationStruct);
613 
633 int_fast16_t AESGCM_oneStepEncrypt(AESGCM_Handle handle, AESGCM_Operation *operationStruct);
634 
655 int_fast16_t AESGCM_oneStepDecrypt(AESGCM_Handle handle, AESGCM_Operation *operationStruct);
656 
670 int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle);
671 
695 AESGCM_Handle AESGCM_construct(AESGCM_Config *config, const AESGCM_Params *params);
696 
697 #ifdef __cplusplus
698 }
699 #endif
700 
701 #endif /* ti_drivers_AESGCM__include */
void * custom
Definition: AESGCM.h:538
The CryptoKey type is an opaque representation of a cryptographic key.
uint8_t * input
Definition: AESGCM.h:453
uint8_t macLength
Definition: AESGCM.h:487
CryptoKey * key
Definition: AESGCM.h:448
AESGCM_OperationType
Enum for the operation types supported by the driver.
Definition: AESGCM.h:499
int_fast16_t AESGCM_cancelOperation(AESGCM_Handle handle)
Cancels an ongoing AESGCM operation.
const AESGCM_Params AESGCM_defaultParams
Default AESGCM_Params structure.
uint8_t ivLength
Definition: AESGCM.h:484
Definition: AESGCM.h:419
void * object
Definition: AESGCM.h:386
CryptoKey datastructure.
Definition: CryptoKey.h:209
int_fast16_t AESGCM_oneStepEncrypt(AESGCM_Handle handle, AESGCM_Operation *operationStruct)
Function to perform an AESGCM encryption + authentication operation in one call.
void AESGCM_Operation_init(AESGCM_Operation *operationStruct)
Function to initialize an AESGCM_Operation struct to its defaults.
AESGCM_ReturnBehavior returnBehavior
Definition: AESGCM.h:533
void AESGCM_init(void)
This function initializes the GCM module.
uint8_t * mac
Definition: AESGCM.h:470
int_fast16_t AESGCM_oneStepDecrypt(AESGCM_Handle handle, AESGCM_Operation *operationStruct)
Function to perform an AESGCM decryption + verification operation in one call.
AESGCM Global configuration.
Definition: AESGCM.h:384
size_t aadLength
Definition: AESGCM.h:476
void(* AESGCM_CallbackFxn)(AESGCM_Handle handle, int_fast16_t returnValue, AESGCM_Operation *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:519
Definition: AESGCM.h:501
AESGCM_ReturnBehavior
The way in which GCM function calls return after performing an encryption + authentication or decrypt...
Definition: AESGCM.h:418
Definition: AESGCM.h:440
Definition: AESGCM.h:429
uint8_t * output
Definition: AESGCM.h:458
Definition: AESGCM.h:500
uint32_t timeout
Definition: AESGCM.h:535
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.
AESGCM_Config * AESGCM_Handle
A handle that is returned from an AESGCM_open() call.
Definition: AESGCM.h:395
void AESGCM_Params_init(AESGCM_Params *params)
Function to initialize the AESGCM_Params struct to its defaults.
uint8_t * aad
Definition: AESGCM.h:449
AESGCM_Handle AESGCM_open(uint_least8_t index, const AESGCM_Params *params)
This function opens a given GCM peripheral.
AESGCM_Mode
Enum for the direction of the GCM operation.
Definition: AESGCM.h:438
GCM Parameters.
Definition: AESGCM.h:532
size_t inputLength
Definition: AESGCM.h:480
Definition: AESGCM.h:425
bool ivInternallyGenerated
Definition: AESGCM.h:490
uint8_t * iv
Definition: AESGCM.h:464
Definition: AESGCM.h:439
AESGCM_CallbackFxn callbackFxn
Definition: AESGCM.h:534
void const * hwAttrs
Definition: AESGCM.h:389
Struct containing the parameters required for encrypting/decrypting and authenticating/verifying a me...
Definition: AESGCM.h:447
© Copyright 1995-2019, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale