1 /*
2  * Copyright (c) 2017-2022, 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       AESECB.h
34  *
35  *  @brief      AESECB driver header
36  *
37  *  @anchor ti_drivers_AESECB_Overview
38  *  # Overview #
39  *  The Electronic Code Book (ECB) mode of operation is a generic
40  *  encryption block cipher mode. It can be used with any block cipher.
41  *  AESECB encrypts or decrypts one or multiple blocks of plaintext or ciphertext
42  *  using the Advanced Encryption Standard (AES) block cipher.
43  *  Each input block is individually encrypted or decrypted. This means that
44  *  blocks of ciphertext can be decrypted individually and out of order.
45  *  Encrypting the same plaintext using the same key yields identical ciphertext.
46  *  This raises several security issues. For this reason, ECB is not recommended
47  *  unless interfacing with legacy systems which cannot be updated
48  *  or where a standard specifies its use. Better alternatives would be an
49  *  authenticated encryption with associated data (AEAD) mode such as
50  *  CCM or GCM.
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  *  @anchor ti_drivers_AESECB_Usage
56  *  # Usage #
57  *
58  *  ## Before starting an ECB operation #
59  *
60  *  Before starting an ECB operation, the application must do the following:
61  *      - Call AESECB_init() to initialize the driver
62  *      - Call AESECB_Params_init() to initialize the AESECB_Params to default values.
63  *      - Modify the AESECB_Params as desired
64  *      - Call AESECB_open() to open an instance of the driver
65  *      - Initialize a CryptoKey. These opaque data structures are representations
66  *        of keying material and its storage. Depending on how the keying material
67  *        is stored (RAM or flash, key store), the CryptoKey must be
68  *        initialized differently. The AESECB API can handle all types of CryptoKey.
69  *        However, not all device-specific implementations support all types of CryptoKey.
70  *        Devices without a key store will not support CryptoKeys with keying material
71  *        stored in a key store for example.
72  *        All devices support plaintext CryptoKeys.
73  *      - Initialize the AESECB_Operation using AESECB_Operation_init() and set all
74  *        length, key, and buffer fields.
75  *
76  *  ## Starting an ECB operation #
77  *
78  *  The AESECB_oneStepEncrypt and AESECB_oneStepDecrypt functions do an ECB operation in a single call.
79  *  They will always be the most highly optimized routines with the least overhead and the fastest
80  *  runtime. Since ECB plaintext blocks are simply encrypted with the block cipher block by block,
81  *  there is no difference in the ciphertext between encrypting two blocks in one go or encrypting
82  *  each block individually.
83  *
84  *  ## After the ECB operation completes #
85  *
86  *  After the ECB operation completes, the application should either start another operation
87  *  or close the driver by calling AESECB_close()
88  *
89  *  @anchor ti_drivers_AESECB_Synopsis
90  *  ## Synopsis
91  *  @anchor ti_drivers_AESECB_Synopsis_Code
92  *  @code
93  *  // Import AESECB Driver definitions
94  *  #include <ti/drivers/AESECB.h>
95  *
96  *  AESECB_init();
97  *
98  *  // Define name for AESECB channel index
99  *  #define AESECB_INSTANCE 0
100  *
101  *  handle = AESECB_open(AESECB_INSTANCE, NULL);
102  *
103  *  // Initialize symmetric key
104  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
105  *
106  *  // Set up AESECB_Operation
107  *  AESECB_Operation_init(&operation);
108  *  operation.key               = &cryptoKey;
109  *  operation.input             = plaintext;
110  *  operation.output            = ciphertext;
111  *  // Input length must be a non-zero multiple of block-size (16 bytes)
112  *  // for one-step operations. The user or application should take care of
113  *  // necessary padding.
114  *  operation.inputLength       = sizeof(plaintext);
115  *
116  *  encryptionResult = AESECB_oneStepEncrypt(handle, &operation);
117  *
118  *  AESECB_close(handle);
119  *  @endcode
120  *
121  *  @anchor ti_drivers_AESECB_Examples
122  *
123  *  ## Examples
124  *
125  *  ### Encryption of multiple plaintext blocks in blocking mode #
126  *  @code
127  *
128  *  #include <ti/drivers/AESECB.h>
129  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
130  *
131  *  ...
132  *
133  *  AESECB_Handle handle;
134  *  CryptoKey cryptoKey;
135  *  int_fast16_t encryptionResult;
136  *  uint8_t plaintext[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
137  *                         0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
138  *                         0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
139  *                         0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
140  *  uint8_t ciphertext[sizeof(plaintext)];
141  *  uint8_t keyingMaterial[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
142  *                                0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
143  *
144  *  handle = AESECB_open(0, NULL);
145  *
146  *  if (handle == NULL) {
147  *      // handle error
148  *  }
149  *
150  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
151  *
152  *      AESECB_Operation operation;
153  *      AESECB_Operation_init(&operation);
154  *
155  *      operation.key               = &cryptoKey;
156  *      operation.input             = plaintext;
157  *      operation.output            = ciphertext;
158  *      // Input length must be a non-zero multiple of block-size (16 bytes)
159  *      // for one-step operations. The user or application should take care of
160  *      // necessary padding.
161  *      operation.inputLength       = sizeof(plaintext);
162  *
163  *  encryptionResult = AESECB_oneStepEncrypt(handle, &operation);
164  *
165  *  if (encryptionResult != AESECB_STATUS_SUCCESS) {
166  *      // handle error
167  *  }
168  *
169  *  // The resultant ciphertext should be:
170  *  // 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
171  *  // 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
172  *  // 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
173  *  // 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf
174  *
175  *
176  *  AESECB_close(handle);
177  *
178  *  @endcode
179  *
180  *  ### One step ECB decryption in callback mode #
181  *  @code
182  *
183  *  #include <ti/drivers/AESECB.h>
184  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
185  *
186  *  ...
187  *
188  *  uint8_t ciphertext[]                    = {0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
189  *                                             0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8};
190  *  uint8_t keyingMaterial[32]              = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
191  *                                             0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
192  *                                             0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
193  *                                             0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
194  *  uint8_t plaintext[sizeof(ciphertext)];
195  *
196  *  // The plaintext should be the following after the decryption operation:
197  *  // 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
198  *  // 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
199  *
200  *
201  *  void ecbCallback(AESECB_Handle handle,
202  *                   int_fast16_t returnValue,
203  *                   AESECB_Operation *operation,
204  *                   AESECB_OperationType operationType) {
205  *
206  *      if (returnValue != AESECB_STATUS_SUCCESS) {
207  *          // handle error
208  *      }
209  *  }
210  *
211  *  AESECB_Operation operation;
212  *
213  *  void ecbStartFunction(void) {
214  *      AESECB_Handle handle;
215  *      AESECB_Params params;
216  *      CryptoKey cryptoKey;
217  *      int_fast16_t decryptionResult;
218  *
219  *      AESECB_Params_init(&params);
220  *      params.returnBehavior = AESECB_RETURN_BEHAVIOR_CALLBACK;
221  *      params.callbackFxn = ecbCallback;
222  *
223  *      handle = AESECB_open(0, &params);
224  *
225  *      if (handle == NULL) {
226  *          // handle error
227  *      }
228  *
229  *      CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
230  *
231  *      AESECB_Operation_init(&operation);
232  *
233  *      operation.key               = &cryptoKey;
234  *      operation.input             = plaintext;
235  *      operation.output            = ciphertext;
236  *      // Input length must be a non-zero multiple of block-size (16 bytes)
237  *      // for one-step operations. The user or application should take care of
238  *      // necessary padding.
239  *      operation.inputLength       = sizeof(plaintext);
240  *
241  *      decryptionResult = AESECB_oneStepDecrypt(handle, &operation);
242  *
243  *      if (decryptionResult != AESECB_STATUS_SUCCESS) {
244  *          // handle error
245  *      }
246  *
247  *      // do other things while ECB operation completes in the background
248  *
249  *  }
250  *
251  *  @endcode
252  *
253  *  ### Multi-step ECB encryption in blocking mode #
254  *  @code
255  *
256  *  #include <ti/drivers/AESECB.h>
257  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
258  *
259  *  #define AES_BLOCK_SIZE  16      // bytes
260  *
261  *  ...
262  *
263  *  AESECB_Handle handle;
264  *  CryptoKey cryptoKey;
265  *  int_fast16_t encryptionResult;
266  *  int_fast16_t setupEncryptionResult;
267  *  int_fast16_t finalizeEncryptionResult;
268  *  uint8_t plaintext[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
269  *                         0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
270  *                         0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
271  *                         0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51};
272  *  uint8_t ciphertext[sizeof(plaintext)];
273  *  uint8_t keyingMaterial[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
274  *                                0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
275  *
276  *  handle = AESECB_open(0, NULL);
277  *
278  *  if (handle == NULL) {
279  *      // handle error
280  *  }
281  *
282  *  CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
283  *
284  *  setupEncryptionResult = AESECB_setupEncrypt(handle, &cryptoKey);
285  *  if (setupEncryptionResult != AESECB_STATUS_SUCCESS) {
286  *      // handle error
287  *  }
288  *
289  *  AESECB_Operation operation;
290  *  AESECB_Operation_init(&operation);
291  *
292  *  // No need to set operation.key for multi-step operations.
293  *  operation.input             = plaintext;
294  *  operation.output            = ciphertext;
295  *  // Input length must be a non-zero multiple of block-size (16 bytes) for calling
296  *  // #AESECB_addData(). The user or application should take care of necessary padding
297  *  // if the final block of data is being added for the entire segmented operation.
298  *  operation.inputLength       = AES_BLOCK_SIZE;
299  *
300  *  encryptionResult = AESECB_addData(handle, &operation);
301  *  if (encryptionResult != AESECB_STATUS_SUCCESS) {
302  *      // handle error
303  *  }
304  *
305  *  // No need to set operation.key for multi-step operations.
306  *  operation.input             = plaintext + AES_BLOCK_SIZE;
307  *  operation.output            = ciphertext + AES_BLOCK_SIZE;
308  *  // Input length must either be a non-zero multiple of block-size (16 bytes)
309  *  // for calling #AESECB_finalize(), or it could be zero in case of finalizing without
310  *  // any more data. The user or application should take care of necessary padding
311  *  // for the last block of data.
312  *  operation.inputLength       = AES_BLOCK_SIZE;
313  *
314  *  finalizeEncryptionResult = AESECB_finalize(handle, &operation);
315  *  if (finalizeEncryptionResult != AESECB_STATUS_SUCCESS) {
316  *      // handle error
317  *  }
318  *
319  *  // The resultant ciphertext should be:
320  *  // 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
321  *  // 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
322  *  // 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
323  *  // 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf
324  *
325  *
326  *  AESECB_close(handle);
327  *
328  *  }
329  *
330  *  @endcode
331  *
332  *  ### Multi-step ECB decryption in callback mode #
333  *  @code
334  *
335  *  #include <ti/drivers/AESECB.h>
336  *  #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>
337  *
338  *  #define AES_BLOCK_SIZE  16      // bytes
339  *
340  *  ...
341  *  uint8_t ciphertext[]                    = {0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
342  *                                             0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8};
343  *  uint8_t keyingMaterial[32]              = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
344  *                                             0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
345  *                                             0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
346  *                                             0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
347  *  uint8_t plaintext[sizeof(ciphertext)];
348  *
349  *  // The plaintext should be the following after the decryption operation:
350  *  // 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
351  *  // 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
352  *
353  *
354  *  void ecbCallback(AESECB_Handle handle,
355  *                   int_fast16_t returnValue,
356  *                   AESECB_Operation *operation,
357  *                   AESECB_OperationType operationType) {
358  *
359  *      if (returnValue != AESECB_STATUS_SUCCESS) {
360  *          // handle error
361  *      }
362  *  }
363  *
364  *  AESECB_Operation operation;
365  *
366  *  void ecbStartFunction(void) {
367  *      AESECB_Handle handle;
368  *      AESECB_Params params;
369  *      CryptoKey cryptoKey;
370  *      int_fast16_t decryptionResult;
371  *      int_fast16_t setupDecryptionResult;
372  *      int_fast16_t finalizeDecryptionResult;
373  *
374  *      AESECB_Params_init(&params);
375  *      params.returnBehavior = AESECB_RETURN_BEHAVIOR_CALLBACK;
376  *      params.callbackFxn = ecbCallback;
377  *
378  *      handle = AESECB_open(0, &params);
379  *
380  *      if (handle == NULL) {
381  *          // handle error
382  *      }
383  *
384  *      CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial));
385  *
386  *      setupDecryptionResult = AESECB_setupDecrypt(handle, &cryptoKey);
387  *      if (setupDecryptionResult != AESECB_STATUS_SUCCESS) {
388  *          // handle error
389  *      }
390  *
391  *      AESECB_Operation_init(&operation);
392  *
393  *      // No need to set operation.key for multi-step operations.
394  *      operation.input             = plaintext;
395  *      operation.output            = ciphertext;
396  *      // Input length must be a non-zero multiple of block-size (16 bytes) for calling
397  *      // #AESECB_addData(). The user or application should take care of necessary padding
398  *      // if the final block of data is being added for the entire segmented operation.
399  *      operation.inputLength       = AES_BLOCK_SIZE;
400  *
401  *      decryptionResult = AESECB_addData(handle, &operation);
402  *      if (decryptionResult != AESECB_STATUS_SUCCESS) {
403  *          // handle error
404  *      }
405  *
406  *      // do other things while ECB operation completes in the background
407  *
408  *      // Input length must either be a non-zero multiple of block-size (16 bytes)
409  *      // for calling #AESECB_finalize(), or it could be zero in case of finalizing without
410  *      // any more data as shown in this example. There's no more data involved and padding
411  *      // is not applicable for this finalization operation.
412  *      operation.inputLength       = 0;
413  *
414  *      finalizeDecryptionResult = AESECB_finalize(handle, &operation);
415  *      if (finalizeDecryptionResult != AESECB_STATUS_SUCCESS) {
416  *          // handle error
417  *      }
418  *
419  *  }
420  *
421  *  @endcode
422  */
423 
424 #ifndef ti_drivers_AESECB__include
425 #define ti_drivers_AESECB__include
426 
427 #include <stdbool.h>
428 #include <stddef.h>
429 #include <stdint.h>
430 
431 #include <ti/drivers/AESCommon.h>
432 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
433 
434 #ifdef __cplusplus
435 extern "C" {
436 #endif
437 
438 /*!
439  * Common AESECB status code reservation offset.
440  * AESECB driver implementations should offset status codes with
441  * AESECB_STATUS_RESERVED growing negatively.
442  *
443  * Example implementation specific status codes:
444  * @code
445  * #define AESECBXYZ_STATUS_ERROR0    AESECB_STATUS_RESERVED - 0
446  * #define AESECBXYZ_STATUS_ERROR1    AESECB_STATUS_RESERVED - 1
447  * #define AESECBXYZ_STATUS_ERROR2    AESECB_STATUS_RESERVED - 2
448  * @endcode
449  */
450 #define AESECB_STATUS_RESERVED AES_STATUS_RESERVED
451 
452 /*!
453  * @brief   Successful status code.
454  *
455  * Functions return AESECB_STATUS_SUCCESS if the function was executed
456  * successfully.
457  */
458 #define AESECB_STATUS_SUCCESS AES_STATUS_SUCCESS
459 
460 /*!
461  * @brief   Generic error status code.
462  *
463  * Functions return AESECB_STATUS_ERROR if the function was not executed
464  * successfully and no more pertinent error code could be returned.
465  */
466 #define AESECB_STATUS_ERROR AES_STATUS_ERROR
467 
468 /*!
469  * @brief   An error status code returned if the hardware or software resource
470  * is currently unavailable.
471  *
472  * AESECB driver implementations may have hardware or software limitations on how
473  * many clients can simultaneously perform operations. This status code is returned
474  * if the mutual exclusion mechanism signals that an operation cannot currently be performed.
475  */
476 #define AESECB_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE
477 
478 /*!
479  *  @brief  The ongoing operation was canceled.
480  */
481 #define AESECB_STATUS_CANCELED AES_STATUS_CANCELED
482 
483 /*!
484  * @brief   The operation requested is not supported on the target hardware
485  *          or by the current state of the SW implementation.
486  */
487 #define AESECB_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED
488 
489 /*!
490  *  @brief  The operation tried to load a key from the keystore using an invalid key ID.
491  */
492 #define AESECB_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID
493 
494 /*!
495  *  @brief  The key store module returned a generic error. See key store documentation
496  *  for additional details.
497  */
498 #define AESECB_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR
499 
500 /*!
501  * @brief   The operation does not support non-word-aligned input and/or output.
502  *
503  * AESECB driver implementations may have restrictions on the alignment of
504  * input/output data due to performance limitations of the hardware.
505  */
506 #define AESECB_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED
507 
508 /*!
509  *  @brief AESECB Global configuration
510  *
511  *  The AESECB_Config structure contains a set of pointers used to characterize
512  *  the AESECB driver implementation.
513  *
514  *  This structure needs to be defined before calling AESECB_init() and it must
515  *  not be changed thereafter.
516  *
517  *  @sa     AESECB_init()
518  */
519 typedef AESCommon_Config AESECB_Config;
520 
521 /*!
522  *  @brief  A handle that is returned from an AESECB_open() call.
523  */
524 typedef AESECB_Config *AESECB_Handle;
525 
526 /*!
527  * @brief   The way in which ECB function calls return after performing an
528  * encryption + authentication or decryption + verification operation.
529  *
530  * Not all ECB operations exhibit the specified return behavior. Functions that do not
531  * require significant computation and cannot offload that computation to a background thread
532  * behave like regular functions. Which functions exhibit the specified return behavior is not
533  * implementation dependent. Specifically, a software-backed implementation run on the same
534  * CPU as the application will emulate the return behavior while not actually offloading
535  * the computation to the background thread.
536  *
537  * AESECB functions exhibiting the specified return behavior have restrictions on the
538  * context from which they may be called.
539  *
540  * |                                | Task  | Hwi   | Swi   |
541  * |--------------------------------|-------|-------|-------|
542  * |AESECB_RETURN_BEHAVIOR_CALLBACK | X     | X     | X     |
543  * |AESECB_RETURN_BEHAVIOR_BLOCKING | X     |       |       |
544  * |AESECB_RETURN_BEHAVIOR_POLLING  | X     | X     | X     |
545  *
546  */
547 typedef enum
548 {
549     AESECB_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK,
550     /*!< The function call will return immediately while the
551      *   ECB operation goes on in the background. The registered
552      *   callback function is called after the operation completes.
553      *   The context the callback function is called (task, HWI, SWI)
554      *   is implementation-dependent.
555      */
556     AESECB_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING,
557     /*!< The function call will block while ECB operation goes
558      *   on in the background. ECB operation results are available
559      *   after the function returns.
560      */
561     AESECB_RETURN_BEHAVIOR_POLLING  = AES_RETURN_BEHAVIOR_POLLING,
562     /*!< The function call will continuously poll a flag while ECB
563      *   operation goes on in the background. ECB operation results
564      *   are available after the function returns.
565      */
566 } AESECB_ReturnBehavior;
567 
568 /*!
569  *  @brief  Enum for the direction of the ECB operation.
570  */
571 typedef enum
572 {
573     AESECB_MODE_ENCRYPT = 1,
574     AESECB_MODE_DECRYPT = 2,
575 } AESECB_Mode;
576 
577 /*!
578  *  @brief  Struct containing the parameters required for encrypting/decrypting
579  *          and a message.
580  */
581 typedef struct
582 {
583     CryptoKey *key;     /*!< A previously initialized CryptoKey.
584                          *   @note: Required for one-step operations only.
585                          *   For segmented operations, this pointer is not used
586                          *   and may be left uninitialized or set to NULL.
587                          */
588     uint8_t *input;     /*!<
589                          *   - Encryption: A pointer to the plaintext buffer.
590                          *   - Decryption: A pointer to the ciphertext buffer.
591                          *
592                          *   Both input and output buffers should be of the size
593                          *   \c inputLength in bytes each.
594                          */
595     uint8_t *output;    /*!<
596                          *   - Encryption: A pointer to the buffer to store the
597                          *     resulting ciphertext.
598                          *   - Decryption: A pointer to the buffer to store the
599                          *   resulting plaintext.
600                          *
601                          *   Both input and output buffers should be of the size
602                          *   \c inputLength in bytes each.
603                          */
604     size_t inputLength; /*!<
605                          *   - One-step operation: Total length of the input in
606                          *     bytes.
607                          *   - Multi-step / Segmented operation: Length of the
608                          *     input in bytes for that #AESECB_addData()
609                          *     or #AESECB_finalize() call.
610                          *
611                          *   The output will be the same length as the input.
612                          *   Max length supported may be limited depending on the
613                          *   return behavior.
614                          *
615                          *   Must be a non-zero multiple of AES block size (16 bytes).
616                          *   May be 0 only when calling #AESECB_finalize() to
617                          *   finalize a multi-step operation without additional
618                          *   data.
619                          *   The user or application should take care of any
620                          *   necessary padding.
621                          */
622 } AESECB_Operation;
623 
624 /*!
625  *  @brief  Enum for the operation types supported by the driver.
626  */
627 typedef enum
628 {
629     AESECB_OPERATION_TYPE_ENCRYPT                    = 1,
630     AESECB_OPERATION_TYPE_DECRYPT                    = 2,
631     AESECB_OPERATION_TYPE_ENCRYPT_SEGMENTED          = 3,
632     AESECB_OPERATION_TYPE_DECRYPT_SEGMENTED          = 4,
633     AESECB_OPERATION_TYPE_FINALIZE_ENCRYPT_SEGMENTED = 5,
634     AESECB_OPERATION_TYPE_FINALIZE_DECRYPT_SEGMENTED = 6
635 } AESECB_OperationType;
636 
637 /*!
638  *  @brief  The definition of a callback function used by the AESECB driver
639  *          when used in ::AESECB_RETURN_BEHAVIOR_CALLBACK
640  *
641  *  @param  handle        Handle of the client that started the ECB operation.
642  *
643  *  @param  returnValue   The result of the ECB operation. May contain an error code.
644  *                        Informs the application of why the callback function was
645  *                        called.
646  *
647  *  @param  operation     A pointer to an operation struct.
648  *
649  *  @param  operationType This parameter determines which operation the
650  *                        callback refers to.
651  */
652 typedef void (*AESECB_CallbackFxn)(AESECB_Handle handle,
653                                    int_fast16_t returnValue,
654                                    AESECB_Operation *operation,
655                                    AESECB_OperationType operationType);
656 
657 /*!
658  *  @brief  ECB Parameters
659  *
660  *  ECB Parameters are used with the #AESECB_open() call. Default values for
661  *  these parameters are set using #AESECB_Params_init().
662  *
663  *  @sa     #AESECB_Params_init()
664  */
665 typedef struct
666 {
667     AESECB_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */
668     AESECB_CallbackFxn callbackFxn;       /*!< Callback function pointer */
669     uint32_t timeout;                     /*!< Timeout before the driver returns an error in
670                                            *   ::AESECB_RETURN_BEHAVIOR_BLOCKING
671                                            */
672     void *custom;                         /*!< Custom argument used by driver
673                                            *   implementation
674                                            */
675 } AESECB_Params;
676 
677 /*!
678  *  @brief Default #AESECB_Params structure
679  *
680  *  @sa     #AESECB_Params_init()
681  */
682 extern const AESECB_Params AESECB_defaultParams;
683 
684 /*!
685  *  @brief  This function initializes the ECB module.
686  *
687  *  @pre    The AESECB_config structure must exist and be persistent before this
688  *          function can be called. This function must also be called before
689  *          any other ECB driver APIs. This function call does not modify any
690  *          peripheral registers.
691  */
692 void AESECB_init(void);
693 
694 /*!
695  *  @brief  Function to initialize the #AESECB_Params struct to its defaults
696  *
697  *  @param  params      An pointer to #AESECB_Params structure for
698  *                      initialization
699  *
700  *  Defaults values are:
701  *      returnBehavior              = AESECB_RETURN_BEHAVIOR_BLOCKING
702  *      callbackFxn                 = NULL
703  *      timeout                     = SemaphoreP_WAIT_FOREVER
704  *      custom                      = NULL
705  */
706 void AESECB_Params_init(AESECB_Params *params);
707 
708 /*!
709  *  @brief  This function opens a given ECB peripheral.
710  *
711  *  @pre    ECB controller has been initialized using #AESECB_init()
712  *
713  *  @param  [in] index    Logical peripheral number for the ECB indexed into
714  *                        the AESECB_config table
715  *
716  *  @param  [in] params   Pointer to an parameter block, if NULL it will use
717  *                        default values.
718  *
719  *  @return An #AESECB_Handle on success or a NULL on an error or if it has been
720  *          opened already.
721  *
722  *  @sa     #AESECB_init()
723  *  @sa     #AESECB_close()
724  */
725 AESECB_Handle AESECB_open(uint_least8_t index, const AESECB_Params *params);
726 
727 /*!
728  *  @brief  Function to close an ECB peripheral specified by the ECB handle
729  *
730  *  @pre    #AESECB_open() or #AESECB_construct()
731  *
732  *  @param  [in] handle An ECB handle returned from #AESECB_open() or #AESECB_construct()
733  *
734  *  @sa     AESECB_open()
735  */
736 void AESECB_close(AESECB_Handle handle);
737 
738 /*!
739  *  @brief  Function to initialize an #AESECB_Operation struct to its defaults
740  *
741  *  @param  [in] operationStruct     An pointer to #AESECB_Operation structure for
742  *                                  initialization
743  *
744  *  Defaults values are all zeros.
745  */
746 void AESECB_Operation_init(AESECB_Operation *operationStruct);
747 
748 /*!
749  *  @brief  Function to perform an AESECB encryption operation in one call.
750  *
751  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
752  *          Doing so can yield corrupted ciphertext or incorrect authentication.
753  *
754  *  @pre    #AESECB_open() or #AESECB_construct(), and AESECB_Operation_init() have to be called first.
755  *
756  *  @param  [in] handle                 An ECB handle returned from #AESECB_open() or #AESECB_construct()
757  *
758  *  @param  [in] operation              A pointer to a struct containing the parameters required to perform the
759  * operation.
760  *
761  *  @retval #AESECB_STATUS_SUCCESS               The operation succeeded.
762  *  @retval #AESECB_STATUS_ERROR                 The operation failed.
763  *  @retval #AESECB_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
764  *  @retval #AESECB_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
765  *
766  *  @sa     AESECB_oneStepDecrypt()
767  */
768 int_fast16_t AESECB_oneStepEncrypt(AESECB_Handle handle, AESECB_Operation *operation);
769 
770 /*!
771  *  @brief  Function to perform an AESECB decryption in one call.
772  *
773  *  @note   None of the buffers provided as arguments may be altered by the application during an ongoing operation.
774  *          Doing so can yield corrupted plaintext or incorrectly failed verification.
775  *
776  *  @pre    #AESECB_open() or #AESECB_construct(), and AESECB_Operation_init() have to be called first.
777  *
778  *  @param  [in] handle                 An ECB handle returned from #AESECB_open() or #AESECB_construct()
779  *
780  *  @param  [in] operation              A pointer to a struct containing the parameters required to perform the
781  * operation.
782  *
783  *  @retval #AESECB_STATUS_SUCCESS               The operation succeeded.
784  *  @retval #AESECB_STATUS_ERROR                 The operation failed.
785  *  @retval #AESECB_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
786  *  @retval #AESECB_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
787  *
788  *  @sa     AESECB_oneStepEncrypt()
789  */
790 int_fast16_t AESECB_oneStepDecrypt(AESECB_Handle handle, AESECB_Operation *operation);
791 
792 /*!
793  *  @brief  Function to prepare a segmented AESECB encryption operation.
794  *
795  *  This functions sets up a segmented AESECB encryption operation.
796  *
797  *  @pre    #AESECB_open() or #AESECB_construct()
798  *
799  *  @param  [in] handle     An ECB handle returned from #AESECB_open()
800  *                          or #AESECB_construct()
801  *
802  *  @param  [in] key        A previously initialized CryptoKey.
803  *
804  *  @retval #AESECB_STATUS_SUCCESS                  The operation succeeded.
805  *  @retval #AESECB_STATUS_ERROR                    The operation failed.
806  *
807  *  @post   #AESECB_addData()
808  */
809 int_fast16_t AESECB_setupEncrypt(AESECB_Handle handle, const CryptoKey *key);
810 
811 /*!
812  *  @brief  Function to prepare a segmented AESECB decryption operation.
813  *
814  *  This functions sets up a segmented AESECB decryption operation.
815  *
816  *  @pre    #AESECB_open() or #AESECB_construct()
817  *
818  *  @param  [in] handle     An ECB handle returned from #AESECB_open()
819  *                          or #AESECB_construct()
820  *
821  *  @param  [in] key        A previously initialized CryptoKey.
822  *
823  *  @retval #AESECB_STATUS_SUCCESS                  The operation succeeded.
824  *  @retval #AESECB_STATUS_ERROR                    The operation failed.
825  *
826  *  @post   #AESECB_addData()
827  */
828 int_fast16_t AESECB_setupDecrypt(AESECB_Handle handle, const CryptoKey *key);
829 
830 /*!
831  *  @brief  Encrypts or decrypts segment of @a data with a @a length
832  *
833  *  #AESECB_addData() may be called an arbitrary number times before finishing the operation with
834  *  #AESECB_finalize(). Note that this function is called for use with segmented operations. For
835  *  segmented operations, @c inputLength will govern the input/output lengths and
836  *  must be a AES block size multiple (16-bytes).
837  *
838  *  @pre    #AESECB_setupEncrypt() or #AESECB_setupDecrypt()
839  *
840  *  @param  [in] handle         An ECB handle returned from #AESECB_open() or #AESECB_construct()
841  *
842  *  @param  [in] operation      Pointer to ECB operation structure()
843  *
844  *  @retval #AESECB_STATUS_SUCCESS               The operation succeeded.
845  *  @retval #AESECB_STATUS_ERROR                 The operation failed.
846  *  @retval #AESECB_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
847  *  @retval #AESECB_STATUS_CANCELED              The operation was canceled.
848  *  @retval #AESECB_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
849  *
850  *  @post   #AESECB_addData() or #AESECB_finalize()
851  */
852 int_fast16_t AESECB_addData(AESECB_Handle handle, AESECB_Operation *operation);
853 
854 /*!
855  *  @brief  Finalize the AES transaction. If new data needs to be added,
856  *  @c inputLength will be used to govern how many bytes will be written.
857  *
858  *  @pre    #AESECB_addData()
859  *
860  *  @param  [in] handle         An ECB handle returned from #AESECB_open() or #AESECB_construct()
861  *
862  *  @param  [in] operation      Pointer to ECB operation structure()
863  *
864  *  @retval #AESECB_STATUS_SUCCESS               In ::AESECB_RETURN_BEHAVIOR_BLOCKING and
865  *                                               ::AESECB_RETURN_BEHAVIOR_POLLING, this means the ECB output
866  *                                               was generated successfully. In ::AESECB_RETURN_BEHAVIOR_CALLBACK,
867  *                                               this means the operation started successfully.
868  *  @retval #AESECB_STATUS_ERROR                 The operation failed.
869  *  @retval #AESECB_STATUS_RESOURCE_UNAVAILABLE  The required hardware resource was not available. Try again later.
870  *  @retval #AESECB_STATUS_CANCELED              The operation was canceled.
871  *  @retval #AESECB_STATUS_UNALIGNED_IO_NOT_SUPPORTED  The input and/or output buffer were not word-aligned.
872  */
873 int_fast16_t AESECB_finalize(AESECB_Handle handle, AESECB_Operation *operation);
874 
875 /*!
876  *  @brief Cancels an ongoing AESECB operation.
877  *
878  *  Asynchronously cancels an AESECB operation. Only available when using
879  *  AESECB_RETURN_BEHAVIOR_CALLBACK.
880  *  The operation will terminate as though an error occurred. The
881  *  return status code of the operation will be AESECB_STATUS_CANCELED.
882  *
883  *  @param  [in] handle Handle of the operation to cancel
884  *
885  *  @retval #AESECB_STATUS_SUCCESS               The operation was canceled, or the requested operation had already
886  * completed.
887  */
888 int_fast16_t AESECB_cancelOperation(AESECB_Handle handle);
889 
890 /**
891  *  @brief  Constructs a new AESECB object
892  *
893  *  Unlike #AESECB_open(), #AESECB_construct() does not require the hwAttrs and
894  *  object to be allocated in a #AESECB_Config array that is indexed into.
895  *  Instead, the #AESECB_Config, hwAttrs, and object can be allocated at any
896  *  location. This allows for relatively simple run-time allocation of temporary
897  *  driver instances on the stack or the heap.
898  *  The drawback is that this makes it more difficult to write device-agnostic
899  *  code. If you use an ifdef with DeviceFamily, you can choose the correct
900  *  object and hwAttrs to allocate. That compilation unit will be tied to the
901  *  device it was compiled for at this point. To change devices, recompilation
902  *  of the application with a different DeviceFamily setting is necessary.
903  *
904  *  @param  config #AESECB_Config describing the location of the object and hwAttrs.
905  *
906  *  @param  params #AESECB_Params to configure the driver instance.
907  *
908  *  @return        Returns a #AESECB_Handle on success or NULL on failure.
909  *
910  *  @pre    The object struct @c config points to must be zeroed out prior to
911  *          calling this function. Otherwise, unexpected behavior may ensue.
912  */
913 AESECB_Handle AESECB_construct(AESECB_Config *config, const AESECB_Params *params);
914 
915 #ifdef __cplusplus
916 }
917 #endif
918 
919 #endif /* ti_drivers_AESECB__include */
920