AESCBC.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  * @file AESCBC.h
34  *
35  * @brief AESCBC driver header
36  *
37  * @anchor ti_drivers_AESCBC_Overview
38  * # Overview #
39  * The Cipher Block Chaining (CBC) mode of operation is a generic
40  * block cipher mode of operation. It can be used with any block cipher
41  * including AES.
42  *
43  * CBC mode encrypts messages of any practical length that have a length
44  * evenly divisible by the block size. Unlike ECB, it guarantees
45  * confidentiality of the entire message when the message is larger than
46  * one block.
47  *
48  * ## Operation #
49  * In CBC encryption, the initialization vector (IV) is XOR'd with a block of
50  * plaintext and then encrypted. The output ciphertext block is then XOR'd with
51  * the next plaintext block and the result is encrypted. This process is repeated
52  * until the final block of plaintext has been encrypted.
53  *
54  * To decrypt the message, decrypt the first block of ciphertext and XOR the result
55  * with the IV. The result is the first plaintext block. For subsequent ciphertext
56  * blocks, decrypt each block and XOR the previous block of the encrypted message
57  * into the result.
58  *
59  * ## Padding #
60  * CBC operates on entire blocks of ciphertext and plaintext at a time. This
61  * means that message lengths must be a multiple of the block cipher block size.
62  * AES has a block size of 16 bytes no matter the key size. Since messages do
63  * not necessarily always have a length that is a multiple of 16 bytes, it may
64  * be necessary to pad the message to a 16-byte boundary. Padding requires
65  * the sender and receiver to implicitly agree on the padding convention.
66  * Improperly designed or implemented padding schemes may leak information
67  * to an attacker through a padding oracle attack for example.
68  *
69  * ## Initialization Vectors #
70  * The IV is generated by the party performing the encryption operation.
71  * Within the scope of any encryption key, the IV value must be unique.
72  * The IV does not need to be kept secret and is usually transmitted together
73  * with the ciphertext to the decrypting party.
74  * In CBC mode, the IVs must not be predictable. Two recommended ways to
75  * generate IVs is to either:
76  *
77  * - Apply the block cipher (AESCBC), using the same key used with CBC,
78  * to a nonce. This nonce must be unique for each key-message pair.
79  * A counter will usually suffice. If the same symmetric key is used
80  * by both parties to encrypt messages, they should agree to use a
81  * nonce scheme that avoids generating the same nonce and thus IV twice.
82  * Incrementing the counter by two and making one party use even numbers
83  * and the other odd numbers is a common method to avoid such collisions.
84  * - Use a TRNG (True Random Number Generator) or PRNG
85  * (Pseudo-Random Number Generator) to generate a random number for use
86  * as IV.
87  *
88  * ## Drawbacks #
89  * CBC mode has several drawbacks. Unless interfacing with legacy devices,
90  * it is recommended to use an AEAD (Authenticated Encryption with Associated Data)
91  * mode such as CCM or GCM. Below is a non-exhaustive list of reasons to use
92  * a different block cipher mode of operation.
93  *
94  * - CBC mode does not offer authentication or integrity guarantees. In practice,
95  * this means that attackers can intercept the encrypted message and manipulate
96  * the ciphertext before sending the message on to the receiver. While this
97  * does not break confidentiality and reveal the plaintext, it has enabled several
98  * attacks in the past. This is especially problematic given that changing the
99  * ciphertext of a block will only corrupt the block itself and the subsequent
100  * block of resultant plaintext. This property may be used to manipulate only
101  * certain parts of the message.
102  *
103  * - CBC mode requires message lengths to be evenly divisible by the block size.
104  * This necessitates a padding scheme. Improperly implemented padding schemes
105  * may lead to vulnerabilities that can be exploited by attackers. It often
106  * makes more sense to use a dedicated stream cipher such as CTR (Counter) that
107  * does not have this restriction. CCM and GCM both use CTR for encryption.
108  *
109  * ## Device-Specific Requirements #
110  *
111  * For CC27XX devices, CBC operations leveraging the HSM engine
112  * (key encoding suffixed with _HSM) have the following requirements:
113  * - Output buffer address must be 32-bit aligned.
114  *
115  * @anchor ti_drivers_AESCBC_Usage
116  * # Usage #
117  * ## Before starting a CBC operation #
118  *
119  * Before starting a CBC operation, the application must do the following:
120  * - Call #AESCBC_init() to initialize the driver
121  * - Call #AESCBC_Params_init() to initialize the #AESCBC_Params to default values.
122  * - Modify the #AESCBC_Params as desired
123  * - Call #AESCBC_open() to open an instance of the driver
124  * - Initialize a CryptoKey. These opaque data structures are representations
125  * of keying material and its storage. Depending on how the keying material
126  * is stored (RAM or flash, key store), the CryptoKey must be
127  * initialized differently. The AESCBC API can handle all types of CryptoKey.
128  * However, not all device-specific implementations support all types of CryptoKey.
129  * Devices without a key store will not support CryptoKeys with keying material
130  * stored in a key store for example.
131  * All devices support plaintext CryptoKeys.
132  * - Initialize the appropriate AESCBC operation struct using the relevant
133  * operation init functions and set all fields. For example, one-step (one-shot
134  * or single call) operations should initialize AESCBC_Operation or
135  * AESCBC_OneStepOperation using AESCBC_Operation_init() or
136  * AESCBC_OneStepOperation_init(). For multi-step (segmented or multiple call)
137  * operations, AESCBC_SegmentedOperation must be initialized and set.
138  *
139  * ## Starting a CBC operation #
140  *
141  * The #AESCBC_oneStepEncrypt and #AESCBC_oneStepDecrypt functions perform a CBC operation
142  * in a single call. They will always be the most highly optimized routines with the
143  * least overhead and the fastest runtime. However, they require all plaintext
144  * or ciphertext to be available to the function at the start of the call.
145  * All devices support single call operations.
146  *
147  * ## After the CBC operation completes #
148  *
149  * After the CBC operation completes, the application should either start
150  * another operation or close the driver by calling #AESCBC_close().
151  *
152  * @anchor ti_drivers_AESCBC_Synopsis
153  * ## Synopsis
154  * @anchor ti_drivers_AESCBC_Synopsis_Code
155  * @code
156  * // Import AESCBC Driver definitions
157  * #include <ti/drivers/AESCBC.h>
158  *
159  * // Define name for AESCBC channel index
160  * #define AESCBC_INSTANCE 0
161  *
162  * AESCBC_init();
163  *
164  * handle = AESCBC_open(AESCBC_INSTANCE, NULL);
165  *
166  * // Initialize symmetric key
167  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
168  *
169  * // Set up AESCBC_Operation
170  * AESCBC_OneStepOperation operation;
171  * AESCBC_OneStepOperation_init(&operation);
172  * operation.key = &cryptoKey;
173  * operation.input = plaintext;
174  * operation.output = ciphertext;
175  * operation.inputLength = sizeof(plaintext);
176  * operation.iv = iv;
177  *
178  * encryptionResult = AESCBC_oneStepEncrypt(handle, &operation);
179  *
180  * AESCBC_close(handle);
181  * @endcode
182  *
183  * @anchor ti_drivers_AESCBC_Examples
184  * ## Examples
185  *
186  * ### Single call CBC encryption with plaintext CryptoKey in blocking return mode #
187  * @code
188  *
189  * #include <ti/drivers/AESCBC.h>
190  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
191  *
192  * ...
193  *
194  * AESCBC_Handle handle;
195  * CryptoKey cryptoKey;
196  * int_fast16_t encryptionResult;
197  *
198  * // For example purposes only. Generate IVs in a non-static way in practice.
199  * // Test vector 0 from NIST CAPV set CBCMMT128
200  * uint8_t iv[16] = {0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98,
201  * 0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8};
202  * uint8_t plaintext[16] = {0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab,
203  * 0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22};
204  * uint8_t ciphertext[sizeof(plaintext)];
205  * uint8_t keyingMaterial[16] = {0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0,
206  * 0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17};
207  *
208  * // The ciphertext should be the following after the encryption operation:
209  * // 0x0f, 0x61, 0xc4, 0xd4, 0x4c, 0x51, 0x47, 0xc0
210  * // 0x3c, 0x19, 0x5a, 0xd7, 0xe2, 0xcc, 0x12, 0xb2
211  *
212  *
213  * handle = AESCBC_open(0, NULL);
214  *
215  * if (handle == NULL) {
216  * // handle error
217  * }
218  *
219  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
220  *
221  * AESCBC_OneStepOperation operation;
222  * AESCBC_OneStepOperation_init(&operation);
223  *
224  * operation.key = &cryptoKey;
225  * operation.input = plaintext;
226  * operation.output = ciphertext;
227  * operation.inputLength = sizeof(plaintext);
228  * operation.iv = iv;
229  *
230  * encryptionResult = AESCBC_oneStepEncrypt(handle, &operation);
231  *
232  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
233  * // handle error
234  * }
235  *
236  * AESCBC_close(handle);
237  *
238  * @endcode
239  *
240  * <h4> The following code snippet is for CC27XX devices only and leverages the HSM which is a seperate Hardware
241  * Accelerator </h4>
242  *
243  * ### Single call CBC encryption with plaintext CryptoKey in blocking return mode using the HSM accelerator #
244  * @code
245  *
246  * #include <ti/drivers/AESCBC.h>
247  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
248  *
249  * ...
250  *
251  * AESCBC_Handle handle;
252  * CryptoKey cryptoKey;
253  * int_fast16_t encryptionResult;
254  *
255  * // For example purposes only. Generate IVs in a non-static way in practice.
256  * // Test vector 0 from NIST CAPV set CBCMMT128
257  * uint8_t iv[16] = {0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98,
258  * 0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8};
259  * uint8_t plaintext[16] = {0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab,
260  * 0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22};
261  * uint8_t ciphertext[sizeof(plaintext)];
262  * uint8_t keyingMaterial[16] = {0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0,
263  * 0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17};
264  *
265  * // The ciphertext should be the following after the encryption operation:
266  * // 0x0f, 0x61, 0xc4, 0xd4, 0x4c, 0x51, 0x47, 0xc0
267  * // 0x3c, 0x19, 0x5a, 0xd7, 0xe2, 0xcc, 0x12, 0xb2
268  *
269  *
270  * handle = AESCBC_open(0, NULL);
271  *
272  * if (handle == NULL) {
273  * // handle error
274  * }
275  *
276  * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
277  *
278  * AESCBC_OneStepOperation operation;
279  * AESCBC_OneStepOperation_init(&operation);
280  *
281  * operation.key = &cryptoKey;
282  * operation.input = plaintext;
283  * operation.output = ciphertext;
284  * operation.inputLength = sizeof(plaintext);
285  * operation.iv = iv;
286  *
287  * encryptionResult = AESCBC_oneStepEncrypt(handle, &operation);
288  *
289  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
290  * // handle error
291  * }
292  *
293  * AESCBC_close(handle);
294  *
295  * @endcode
296  *
297  * ### Single call CBC decryption with plaintext CryptoKey in callback return mode #
298  *
299  * @note The following code example presented uses a 256-bit key. However,
300  * CC13x1/CC26x1 and CC23x0 only support a maximum key size of 128-bits,
301  * so reduction of keyingMaterial would be required.
302  *
303  * @code
304  *
305  * #include <ti/drivers/AESCBC.h>
306  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
307  *
308  * ...
309  *
310  * // Test vector 0 from NIST CAPV set CBCMMT256
311  *
312  * uint8_t iv[16] = {0xdd, 0xbb, 0xb0, 0x17, 0x3f, 0x1e, 0x2d, 0xeb,
313  * 0x23, 0x94, 0xa6, 0x2a, 0xa2, 0xa0, 0x24, 0x0e};
314  * uint8_t ciphertext[16] = {0xd5, 0x1d, 0x19, 0xde, 0xd5, 0xca, 0x4a, 0xe1,
315  * 0x4b, 0x2b, 0x20, 0xb0, 0x27, 0xff, 0xb0, 0x20};
316  * uint8_t keyingMaterial[32] = {0x43, 0xe9, 0x53, 0xb2, 0xae, 0xa0, 0x8a, 0x3a,
317  * 0xd5, 0x2d, 0x18, 0x2f, 0x58, 0xc7, 0x2b, 0x9c,
318  * 0x60, 0xfb, 0xe4, 0xa9, 0xca, 0x46, 0xa3, 0xcb,
319  * 0x89, 0xe3, 0x86, 0x38, 0x45, 0xe2, 0x2c, 0x9e};
320  * uint8_t plaintext[sizeof(ciphertext)];
321  *
322  * // The plaintext should be the following after the decryption operation:
323  * // 0x07, 0x27, 0x0d, 0x0e, 0x63, 0xaa, 0x36, 0xda
324  * // 0xed, 0x8c, 0x6a, 0xde, 0x13, 0xac, 0x1a, 0xf1
325  *
326  *
327  * void cbcCallback(AESCBC_Handle handle,
328  * int_fast16_t returnValue,
329  * AESCBC_OperationUnion *operation,
330  * AESCBC_OperationType operationType) {
331  *
332  * if (returnValue != AESCBC_STATUS_SUCCESS) {
333  * // handle error
334  * }
335  *
336  * if (operationType == AESCBC_OPERATION_TYPE_DECRYPT ||
337  * operationType == AESCBC_OPERATION_TYPE_ENCRYPT) {
338  * // do something with operation->oneStepOperation
339  * } else {
340  * // do something with operation->segmentedOperation
341  * }
342  * }
343  *
344  * AESCBC_OneStepOperation operation;
345  *
346  * void cbcStartFunction(void) {
347  * AESCBC_Handle handle;
348  * AESCBC_Params params;
349  * CryptoKey cryptoKey;
350  * int_fast16_t decryptionResult;
351  *
352  * AESCBC_Params_init(&params);
353  * params.returnBehavior = AESCBC_RETURN_BEHAVIOR_CALLBACK;
354  * params.callbackFxn = cbcCallback;
355  *
356  * handle = AESCBC_open(0, &params);
357  *
358  * if (handle == NULL) {
359  * // handle error
360  * }
361  *
362  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
363  *
364  * AESCBC_OneStepOperation_init(&operation);
365  *
366  * operation.key = &cryptoKey;
367  * operation.input = ciphertext;
368  * operation.output = plaintext;
369  * operation.inputLength = sizeof(ciphertext);
370  * operation.iv = iv;
371  *
372  * decryptionResult = AESCBC_oneStepDecrypt(handle, &operation);
373  *
374  * if (decryptionResult != AESCBC_STATUS_SUCCESS) {
375  * // handle error
376  * }
377  *
378  * // do other things while CBC operation completes in the background
379  * }
380  *
381  * @endcode
382  *
383  * ### Multi-step CBC encryption with plaintext CryptoKey in blocking return mode #
384  * @code
385  *
386  * #include <ti/drivers/AESCBC.h>
387  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
388  *
389  * ...
390  *
391  * #define AES_BLOCK_SIZE 16 // bytes
392  *
393  * AESCBC_Handle handle;
394  * CryptoKey cryptoKey;
395  * int_fast16_t encryptionResult;
396  *
397  * // For example purposes only. Generate IVs in a non-static way in practice.
398  * // Test vector 0 from NIST CAPV set CBCMMT128
399  * uint8_t iv[16] = {0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98,
400  * 0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8};
401  * uint8_t plaintext[16] = {0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab,
402  * 0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22};
403  * uint8_t ciphertext[sizeof(plaintext)];
404  * uint8_t keyingMaterial[16] = {0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0,
405  * 0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17};
406  *
407  * // The ciphertext should be the following after the encryption operation:
408  * // 0x0f, 0x61, 0xc4, 0xd4, 0x4c, 0x51, 0x47, 0xc0
409  * // 0x3c, 0x19, 0x5a, 0xd7, 0xe2, 0xcc, 0x12, 0xb2
410  *
411  *
412  * handle = AESCBC_open(0, NULL);
413  *
414  * if (handle == NULL) {
415  * // handle error
416  * }
417  *
418  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
419  *
420  * AESCBC_SegmentedOperation operation;
421  * AESCBC_SegmentedOperation_init(&operation);
422  *
423  * operation.input = plaintext;
424  * operation.output = ciphertext;
425  * operation.inputLength = sizeof(plaintext);
426  *
427  * encryptionResult = AESCBC_setupEncrypt(handle, &cryptoKey);
428  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
429  * // handle error
430  * }
431  *
432  * encryptionResult = AESCBC_setIV(handle, iv, AES_BLOCK_SIZE);
433  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
434  * // handle error
435  * }
436  *
437  * encryptionResult = AESCBC_addData(handle, &operation);
438  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
439  * // handle error
440  * }
441  *
442  * operation.inputLength = 0;
443  * encryptionResult = AESCBC_finalize(handle, &operation);
444  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
445  * // handle error
446  * }
447  *
448  * AESCBC_close(handle);
449  *
450  * @endcode
451  *
452  * ### Multi-step CBC decryption with plaintext CryptoKey in callback return mode #
453  *
454  * @note The following code example presented uses a 256-bit key. However,
455  * CC13x1/CC26x1 and CC23x0 only support a maximum key size of 128-bits,
456  * so reduction of keyingMaterial would be required.
457  *
458  * @code
459  *
460  * #include <ti/drivers/AESCBC.h>
461  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
462  *
463  * ...
464  *
465  * #define AES_BLOCK_SIZE 16 // bytes
466  *
467  * // Test vector 0 from NIST CAPV set CBCMMT256
468  *
469  * uint8_t iv[16] = {0xdd, 0xbb, 0xb0, 0x17, 0x3f, 0x1e, 0x2d, 0xeb,
470  * 0x23, 0x94, 0xa6, 0x2a, 0xa2, 0xa0, 0x24, 0x0e};
471  * uint8_t ciphertext[16] = {0xd5, 0x1d, 0x19, 0xde, 0xd5, 0xca, 0x4a, 0xe1,
472  * 0x4b, 0x2b, 0x20, 0xb0, 0x27, 0xff, 0xb0, 0x20};
473  * uint8_t keyingMaterial[32] = {0x43, 0xe9, 0x53, 0xb2, 0xae, 0xa0, 0x8a, 0x3a,
474  * 0xd5, 0x2d, 0x18, 0x2f, 0x58, 0xc7, 0x2b, 0x9c,
475  * 0x60, 0xfb, 0xe4, 0xa9, 0xca, 0x46, 0xa3, 0xcb,
476  * 0x89, 0xe3, 0x86, 0x38, 0x45, 0xe2, 0x2c, 0x9e};
477  * uint8_t plaintext[sizeof(ciphertext)];
478  *
479  * // The plaintext should be the following after the decryption operation:
480  * // 0x07, 0x27, 0x0d, 0x0e, 0x63, 0xaa, 0x36, 0xda
481  * // 0xed, 0x8c, 0x6a, 0xde, 0x13, 0xac, 0x1a, 0xf1
482  *
483  *
484  * void cbcCallback(AESCBC_Handle handle,
485  * int_fast16_t returnValue,
486  * AESCBC_OperationUnion *operation,
487  * AESCBC_OperationType operationType) {
488  *
489  * if (returnValue != AESCBC_STATUS_SUCCESS) {
490  * // handle error
491  * }
492  *
493  * if (operationType == AESCBC_OPERATION_TYPE_DECRYPT ||
494  * operationType == AESCBC_OPERATION_TYPE_ENCRYPT) {
495  * // do something with operation->oneStepOperation
496  * } else {
497  * // do something with operation->segmentedOperation
498  * }
499  * }
500  *
501  * AESCBC_SegmentedOperation operation;
502  *
503  * void cbcStartFunction(void) {
504  * AESCBC_Handle handle;
505  * AESCBC_Params params;
506  * CryptoKey cryptoKey;
507  * int_fast16_t decryptionResult;
508  *
509  * AESCBC_Params_init(&params);
510  * params.returnBehavior = AESCBC_RETURN_BEHAVIOR_CALLBACK;
511  * params.callbackFxn = cbcCallback;
512  *
513  * handle = AESCBC_open(0, &params);
514  *
515  * if (handle == NULL) {
516  * // handle error
517  * }
518  *
519  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
520  *
521  * AESCBC_SegmentedOperation_init(&operation);
522  *
523  * operation.input = ciphertext;
524  * operation.output = plaintext;
525  * operation.inputLength = sizeof(ciphertext);
526  *
527  * decryptionResult = AESCBC_setupDecrypt(handle, &cryptoKey);
528  * if (decryptionResult != AESCBC_STATUS_SUCCESS) {
529  * // handle error
530  * }
531  *
532  * decryptionResult = AESCBC_setIV(handle, iv, AES_BLOCK_SIZE);
533  * if (decryptionResult != AESCBC_STATUS_SUCCESS) {
534  * // handle error
535  * }
536  *
537  * decryptionResult = AESCBC_addData(handle, &operation);
538  * if (decryptionResult != AESCBC_STATUS_SUCCESS) {
539  * // handle error
540  * }
541  *
542  * // do other things while CBC operation completes in the background
543  *
544  * operation.inputLength = 0;
545  * decryptionResult = AESCBC_finalize(handle, &operation);
546  * if (decryptionResult != AESCBC_STATUS_SUCCESS) {
547  * // handle error
548  * }
549  *
550  * }
551  *
552  * @endcode
553  *
554  * ### Multi-step CBC encryption with plaintext CryptoKey and non-empty finalize in blocking return mode #
555  * @code
556  *
557  * #include <ti/drivers/AESCBC.h>
558  * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
559  *
560  * ...
561  *
562  * #define AES_BLOCK_SIZE 16 // bytes
563  *
564  * AESCBC_Handle handle;
565  * CryptoKey cryptoKey;
566  * int_fast16_t encryptionResult;
567  *
568  * // For example purposes only. Generate IVs in a non-static way in practice.
569  * // Test vector 1 from NIST CAPV set CBCMMT128
570  * uint8_t iv[16] = {0xaa, 0xd1, 0x58, 0x3c, 0xd9, 0x13, 0x65, 0xe3,
571  * 0xbb, 0x2f, 0x0c, 0x34, 0x30, 0xd0, 0x65, 0xbb};
572  * uint8_t plaintext[32] = {0x06, 0x8b, 0x25, 0xc7, 0xbf, 0xb1, 0xf8, 0xbd,
573  * 0xd4, 0xcf, 0xc9, 0x08, 0xf6, 0x9d, 0xff, 0xc5,
574  * 0xdd, 0xc7, 0x26, 0xa1, 0x97, 0xf0, 0xe5, 0xf7,
575  * 0x20, 0xf7, 0x30, 0x39, 0x32, 0x79, 0xbe, 0x91};
576  * uint8_t ciphertext[sizeof(plaintext)];
577  * uint8_t keyingMaterial[16] = {0x07, 0x00, 0xd6, 0x03, 0xa1, 0xc5, 0x14, 0xe4,
578  * 0x6b, 0x61, 0x91, 0xba, 0x43, 0x0a, 0x3a, 0x0c};
579  *
580  * // The ciphertext should be the following after the encryption operation:
581  * // 0xc4, 0xdc, 0x61, 0xd9, 0x72, 0x59, 0x67, 0xa3
582  * // 0x02, 0x01, 0x04, 0xa9, 0x73, 0x8f, 0x23, 0x86
583  * // 0x85, 0x27, 0xce, 0x83, 0x9a, 0xab, 0x17, 0x52
584  * // 0xfd, 0x8b, 0xdb, 0x95, 0xa8, 0x2c, 0x4d, 0x00
585  *
586  *
587  * handle = AESCBC_open(0, NULL);
588  *
589  * if (handle == NULL) {
590  * // handle error
591  * }
592  *
593  * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
594  *
595  * AESCBC_SegmentedOperation operation;
596  * AESCBC_SegmentedOperation_init(&operation);
597  *
598  * operation.input = plaintext;
599  * operation.output = ciphertext;
600  * // One should pass in data that is a block-sized multiple length (16 bytes)
601  * operation.inputLength = AES_BLOCK_SIZE;
602  *
603  * encryptionResult = AESCBC_setupEncrypt(handle, &cryptoKey);
604  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
605  * // handle error
606  * }
607  *
608  * encryptionResult = AESCBC_setIV(handle, iv, AES_BLOCK_SIZE);
609  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
610  * // handle error
611  * }
612  *
613  * encryptionResult = AESCBC_addData(handle, &operation);
614  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
615  * // handle error
616  * }
617  *
618  * operation.input = plaintext + AES_BLOCK_SIZE;
619  * operation.output = ciphertext + AES_BLOCK_SIZE;
620  *
621  * // You can also finalize with more data (non-zero inputLength)
622  * operation.inputLength = sizeof(plaintext) - AES_BLOCK_SIZE;
623  * encryptionResult = AESCBC_finalize(handle, &operation);
624  * if (encryptionResult != AESCBC_STATUS_SUCCESS) {
625  * // handle error
626  * }
627  *
628  * AESCBC_close(handle);
629  *
630  * @endcode
631  */
632 
633 #ifndef ti_drivers_AESCBC__include
634 #define ti_drivers_AESCBC__include
635 
636 #include <stdbool.h>
637 #include <stddef.h>
638 #include <stdint.h>
639 
640 #include <ti/drivers/AESCommon.h>
642 
643 #ifdef __cplusplus
644 extern "C" {
645 #endif
646 
659 #define AESCBC_STATUS_RESERVED AES_STATUS_RESERVED
660 
667 #define AESCBC_STATUS_SUCCESS AES_STATUS_SUCCESS
668 
675 #define AESCBC_STATUS_ERROR AES_STATUS_ERROR
676 
685 #define AESCBC_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
686 
690 #define AESCBC_STATUS_CANCELED AES_STATUS_CANCELED
691 
699 #define AESCBC_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
700 
704 #define AESCBC_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
705 
710 #define AESCBC_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
711 
718 #define AESCBC_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
719 
732 
736 typedef AESCBC_Config *AESCBC_Handle;
737 
759 typedef enum
760 {
779 
783 typedef enum
784 {
787 } AESCBC_Mode;
788 
793 typedef struct
794 {
796  uint8_t *input;
801  uint8_t *output;
810  uint8_t *iv;
816  size_t inputLength;
830 
836 typedef struct
837 {
838  uint8_t *input;
843  uint8_t *output;
852  size_t inputLength;
861 
870 
876 {
877  AESCBC_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */
878  AESCBC_SegmentedOperation segmentedOperation; /* Segmented operation element of the operation union */
880 
884 typedef enum
885 {
886  AESCBC_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */
888  AESCBC_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not
889  being unique */
896 
912 typedef void (*AESCBC_CallbackFxn)(AESCBC_Handle handle,
913  int_fast16_t returnValue,
914  AESCBC_OperationUnion *operation,
915  AESCBC_OperationType operationType);
916 
925 typedef struct
926 {
927  AESCBC_ReturnBehavior returnBehavior;
929  uint32_t timeout;
932  void *custom;
935 } AESCBC_Params;
936 
943 
952 void AESCBC_init(void);
953 
966 void AESCBC_Params_init(AESCBC_Params *params);
967 
985 AESCBC_Handle AESCBC_open(uint_least8_t index, const AESCBC_Params *params);
986 
996 void AESCBC_close(AESCBC_Handle handle);
997 
1009 void AESCBC_Operation_init(AESCBC_Operation *operationStruct);
1010 
1020 
1030 
1051 int_fast16_t AESCBC_oneStepEncrypt(AESCBC_Handle handle, AESCBC_OneStepOperation *operationStruct);
1052 
1073 int_fast16_t AESCBC_oneStepDecrypt(AESCBC_Handle handle, AESCBC_OneStepOperation *operationStruct);
1074 
1092 int_fast16_t AESCBC_setupEncrypt(AESCBC_Handle handle, const CryptoKey *key);
1093 
1111 int_fast16_t AESCBC_setupDecrypt(AESCBC_Handle handle, const CryptoKey *key);
1112 
1134 int_fast16_t AESCBC_setIV(AESCBC_Handle handle, const uint8_t *iv, size_t ivLength);
1135 
1162 int_fast16_t AESCBC_generateIV(AESCBC_Handle handle, uint8_t *iv, size_t ivSize, size_t *ivLength);
1163 
1187 int_fast16_t AESCBC_addData(AESCBC_Handle handle, AESCBC_SegmentedOperation *operation);
1188 
1211 int_fast16_t AESCBC_finalize(AESCBC_Handle handle, AESCBC_SegmentedOperation *operation);
1212 
1226 int_fast16_t AESCBC_cancelOperation(AESCBC_Handle handle);
1227 
1251 AESCBC_Handle AESCBC_construct(AESCBC_Config *config, const AESCBC_Params *params);
1252 
1253 #ifdef __cplusplus
1254 }
1255 #endif
1256 
1257 #endif /* ti_drivers_AESCBC__include */
const AESCBC_Params AESCBC_defaultParams
Default AESCBC_Params structure.
int_fast16_t AESCBC_setupEncrypt(AESCBC_Handle handle, const CryptoKey *key)
Function to prepare a segmented AESCBC encryption operation.
Definition: AESCBC.h:773
uint8_t * input
Definition: AESCBC.h:796
The CryptoKey type is an opaque representation of a cryptographic key.
int_fast16_t AESCBC_oneStepEncrypt(AESCBC_Handle handle, AESCBC_OneStepOperation *operationStruct)
Function to perform an AESCBC encryption operation in one call.
Definition: AESCBC.h:768
int_fast16_t AESCBC_oneStepDecrypt(AESCBC_Handle handle, AESCBC_OneStepOperation *operationStruct)
Function to perform an AESCBC decryption operation in one call.
AESCBC_ReturnBehavior returnBehavior
Definition: AESCBC.h:927
union AESCBC_OperationUnion AESCBC_OperationUnion
Union containing a reference to a one step or segmented operation.
int_fast16_t AESCBC_cancelOperation(AESCBC_Handle handle)
Cancels an ongoing AESCBC operation.
AESCommon_Config AESCBC_Config
AESCBC Global configuration.
Definition: AESCBC.h:731
Definition: AESCBC.h:892
AES Global configuration.
Definition: AESCommon.h:154
Definition: AESCBC.h:886
uint8_t * output
Definition: AESCBC.h:843
CryptoKey datastructure.
Definition: CryptoKey.h:211
Definition: AESCommon.h:186
AESCBC_CallbackFxn callbackFxn
Definition: AESCBC.h:928
Definition: AESCBC.h:890
AESCBC_Mode
Enum for the direction of the CBC operation.
Definition: AESCBC.h:783
Definition: AESCommon.h:196
AESCBC_ReturnBehavior
The way in which CBC function calls return after performing an encryption or decryption operation...
Definition: AESCBC.h:759
uint8_t * input
Definition: AESCBC.h:838
Struct containing the parameters required for encrypting/decrypting a message in a segmented operatio...
Definition: AESCBC.h:836
void AESCBC_close(AESCBC_Handle handle)
Function to close a CBC peripheral specified by the CBC handle.
int_fast16_t AESCBC_generateIV(AESCBC_Handle handle, uint8_t *iv, size_t ivSize, size_t *ivLength)
Function to generate an initialization vector for an AES CBC segmented encryption operation...
int_fast16_t AESCBC_finalize(AESCBC_Handle handle, AESCBC_SegmentedOperation *operation)
Finalize the AES operation. If new data needs to be added, inputLength will be used to govern how man...
AESCBC_OneStepOperation AESCBC_Operation
Definition: AESCBC.h:869
AESCBC_Handle AESCBC_construct(AESCBC_Config *config, const AESCBC_Params *params)
Constructs a new AESCBC object.
Definition: AESCommon.h:192
uint8_t * output
Definition: AESCBC.h:801
Struct containing the parameters required for encrypting/decrypting a message in a single-step operat...
Definition: AESCBC.h:793
AESCBC_SegmentedOperation segmentedOperation
Definition: AESCBC.h:878
Definition: AESCBC.h:786
int_fast16_t AESCBC_addData(AESCBC_Handle handle, AESCBC_SegmentedOperation *operation)
Encrypts or decrypts a segment of data defined by the AESCBC_SegmentedOperation struct.
void AESCBC_OneStepOperation_init(AESCBC_OneStepOperation *operationStruct)
Function to initialize an AESCBC_OneStepOperation struct to its defaults.
CryptoKey * key
Definition: AESCBC.h:795
void AESCBC_init(void)
This function initializes the CBC module.
void AESCBC_Operation_init(AESCBC_Operation *operationStruct)
Function to initialize an AESCBC_Operation struct to its defaults.
AESCBC_Handle AESCBC_open(uint_least8_t index, const AESCBC_Params *params)
This function opens a given CBC peripheral.
bool ivInternallyGenerated
Definition: AESCBC.h:825
void * custom
Definition: AESCBC.h:932
AESCBC_OneStepOperation oneStepOperation
Definition: AESCBC.h:877
void AESCBC_SegmentedOperation_init(AESCBC_SegmentedOperation *operationStruct)
Function to initialize an AESCBC_SegmentedOperation struct to its defaults.
Definition: AESCBC.h:785
Definition: AESCBC.h:761
AESCBC_OperationType
Enum for the operation types supported by the driver.
Definition: AESCBC.h:884
size_t inputLength
Definition: AESCBC.h:816
Definition: AESCBC.h:887
Union containing a reference to a one step or segmented operation.
Definition: AESCBC.h:875
uint8_t * iv
Definition: AESCBC.h:810
AESCBC_Config * AESCBC_Handle
A handle that is returned from an AESCBC_open() call.
Definition: AESCBC.h:736
AES common module header for all devices.
CBC Parameters.
Definition: AESCBC.h:925
int_fast16_t AESCBC_setupDecrypt(AESCBC_Handle handle, const CryptoKey *key)
Function to prepare a segmented AESCBC decryption operation.
size_t inputLength
Definition: AESCBC.h:852
int_fast16_t AESCBC_setIV(AESCBC_Handle handle, const uint8_t *iv, size_t ivLength)
Function to set an initialization vector for an AES CBC segmented operation.
uint32_t timeout
Definition: AESCBC.h:929
Definition: AESCBC.h:891
Definition: AESCBC.h:888
void AESCBC_Params_init(AESCBC_Params *params)
Function to initialize the AESCBC_Params struct to its defaults.
void(* AESCBC_CallbackFxn)(AESCBC_Handle handle, int_fast16_t returnValue, AESCBC_OperationUnion *operation, AESCBC_OperationType operationType)
The definition of a callback function used by the AESCBC driver when used in AESCBC_RETURN_BEHAVIOR_C...
Definition: AESCBC.h:912
© Copyright 1995-2025, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale