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 AESCTR.h 34 * 35 * @brief AESCTR driver header 36 * 37 * @anchor ti_drivers_AESCTR_Overview 38 * <h3> Overview </h3> 39 * The Counter (CTR) mode of operation is a generic block cipher mode of operation 40 * that can be used with any block cipher including AES which is used in this 41 * implementation. 42 * 43 * CTR mode encrypts and decrypts messages. It is not required for the message 44 * length to be evenly divisible by the cipher block size. This also means 45 * that padding the message is not required. 46 * 47 * <h3> Operation </h3> 48 * CTR encryption and decryption perform the following steps: 49 * -# Set the counter value to the initial counter value 50 * -# Encrypt the counter value under the symmetric key 51 * -# XOR the encrypted counter value with the input block (plaintext or ciphertext) 52 * -# Increment the counter value. Interpret the byte array as a big-endian number. 53 * -# Repeat steps 2 to 4 until the input is completely processed. If the 54 * input is not evenly divisible by the block size, XOR the last 55 * (u = input length % block size) input bytes with the most significant 56 * u bytes of the last encrypted counter value. 57 * 58 * CTR performs the same steps regardless of whether it is used to 59 * encrypt or decrypt a message. The input merely changes. 60 * 61 * <h3> Choosing Initial Counter Values </h3> 62 * CTR requires that each counter value used to encrypt a block of a message 63 * is unique for each key used. If this requirement is not kept, the 64 * confidentiality of that message block may be compromised. 65 * 66 * There are two general strategies when choosing the initial counter value 67 * of a CTR operation to ensure this requirement holds. 68 * 69 * The first is to choose an initial counter value for the first message 70 * and increment the initial counter value for a subsequent message by 71 * by message length % block length (16-bytes for AES). This effectively 72 * turns a sequence of messages into one long message. If 0 is chosen 73 * as the initial counter value, up to 2^128 - 1 blocks may be encrypted before 74 * key rotation is mandatory. 75 * 76 * The second is to split the initial counter value into a nonce and 77 * counter section. The nonce of length n bits must be unique per message. 78 * This allows for up to 2^n - 1 messages to be encrypted before 79 * key rotation is required. The counter section of length c is incremented 80 * as usual. This limits messages to a length of at most 2^c - 1 blocks. 81 * n and c must be chosen such that n + c = block length in bits 82 * (128 bits for AES) holds. 83 * 84 * @anchor ti_drivers_AESCTR_Usage 85 * <h3> Usage </h3> 86 * <h4> Before starting a CTR operation </h4> 87 * 88 * Before starting a CTR operation, the application must do the following: 89 * - Call #AESCTR_init() to initialize the driver 90 * - Call #AESCTR_Params_init() to initialize the #AESCTR_Params to default values. 91 * - Modify the #AESCTR_Params as desired 92 * - Call #AESCTR_open() to open an instance of the driver 93 * - Initialize a CryptoKey. These opaque data structures are representations 94 * of keying material and its storage. Depending on how the keying material 95 * is stored (RAM or flash, key store), the CryptoKey must be 96 * initialized differently. The AESCTR API can handle all types of CryptoKey. 97 * However, not all device-specific implementations support all types of CryptoKey. 98 * Devices without a key store will not support CryptoKeys with keying material 99 * stored in a key store for example. 100 * All devices support plaintext CryptoKeys. 101 * - Initialize a single-step AESCTR operation using #AESCTR_OneStepOperation_init() 102 * which is equivalent to the deprecated #AESCTR_Operation_init(). If it's 103 * a segmented AESCTR operation, use #AESCTR_SegmentedOperation_init() instead. 104 * Then set all the fields of the one-step or segmented operation struct accordingly. 105 * 106 * <h4> Starting a CTR operation </h4> 107 * 108 * The AESCTR_oneStepEncrypt() and AESCTR_oneStepDecrypt() functions perform a CTR operation 109 * in a single call. 110 * 111 * <h4> After the CTR operation completes </h4> 112 * 113 * After the CTR operation completes, the application should either start 114 * another operation or close the driver by calling #AESCTR_close(). 115 * 116 * @anchor ti_drivers_AESCTR_Synopsis 117 * ## Synopsis 118 * 119 * @anchor ti_drivers_AESCTR_Synopsis_Code 120 * @code 121 * 122 * // Import AESCTR Driver definitions 123 * #include <ti/drivers/AESCTR.h> 124 * 125 * // Define name for AESCTR channel index 126 * #define AESCTR_INSTANCE 0 127 * 128 * AESCTR_init(); 129 * 130 * handle = AESCTR_open(AESCTR_INSTANCE, NULL); 131 * 132 * // Initialize symmetric key 133 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 134 * 135 * // Set up AESCTR_Operation 136 * AESCTR_OneStepOperation_init(&operation); 137 * operation.key = &cryptoKey; 138 * operation.input = plaintext; 139 * operation.output = ciphertext; 140 * operation.inputLength = sizeof(plaintext); 141 * operation.initialCounter = initialCounter; 142 * 143 * encryptionResult = AESCTR_oneStepEncrypt(handle, &operation); 144 * 145 * AESCTR_close(handle); 146 * @endcode 147 * 148 * @anchor ti_drivers_AESCTR_Examples 149 * <h4> Examples </h4> 150 * 151 * <h5> One step CTR encryption with plaintext CryptoKey in blocking return mode </h5> 152 * @code 153 * 154 * #include <ti/drivers/AESCTR.h> 155 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 156 * 157 * ... 158 * 159 * AESCTR_Handle handle; 160 * CryptoKey cryptoKey; 161 * int_fast16_t encryptionResult; 162 * 163 * // For example purposes only. Generate IVs in a non-static way in practice. 164 * // Test vector from NIST SP 800-38A 165 * uint8_t initialCounter[16] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 166 * 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}; 167 * uint8_t plaintext[64] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 168 * 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 169 * 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 170 * 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 171 * 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 172 * 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 173 * 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 174 * 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; 175 * uint8_t ciphertext[sizeof(plaintext)]; 176 * uint8_t keyingMaterial[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 177 * 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; 178 * 179 * handle = AESCTR_open(0, NULL); 180 * 181 * if (handle == NULL) { 182 * // handle error 183 * while(1); 184 * } 185 * 186 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 187 * 188 * AESCTR_OneStepOperation operation; 189 * AESCTR_OneStepOperation_init(&operation); 190 * 191 * operation.key = &cryptoKey; 192 * operation.input = plaintext; 193 * operation.output = ciphertext; 194 * operation.inputLength = sizeof(plaintext); 195 * operation.initialCounter = initialCounter; 196 * 197 * encryptionResult = AESCTR_oneStepEncrypt(handle, &operation); 198 * 199 * if (encryptionResult != AESCTR_STATUS_SUCCESS) { 200 * // handle error 201 * while(1); 202 * } 203 * 204 * // The ciphertext should be the following after the encryption operation: 205 * // 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 206 * // 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, 207 * // 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, 208 * // 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff, 209 * // 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, 210 * // 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, 211 * // 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, 212 * // 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee 213 * 214 * AESCTR_close(handle); 215 * 216 * @endcode 217 * 218 * <h4> The following code snippet is for CC27XX devices only and leverages the HSM which is a seperate Hardware 219 * Accelerator </h4> 220 * 221 * <h5> One step CTR encryption with plaintext CryptoKey in blocking return mode using the HSM accelerator </h5> 222 * @code 223 * 224 * #include <ti/drivers/AESCTR.h> 225 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 226 * 227 * ... 228 * 229 * AESCTR_Handle handle; 230 * CryptoKey cryptoKey; 231 * int_fast16_t encryptionResult; 232 * 233 * // For example purposes only. Generate IVs in a non-static way in practice. 234 * // Test vector from NIST SP 800-38A 235 * uint8_t initialCounter[16] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 236 * 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff}; 237 * uint8_t plaintext[64] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 238 * 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 239 * 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 240 * 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 241 * 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 242 * 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 243 * 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 244 * 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10}; 245 * uint8_t ciphertext[sizeof(plaintext)]; 246 * uint8_t keyingMaterial[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 247 * 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; 248 * 249 * handle = AESCTR_open(0, NULL); 250 * 251 * if (handle == NULL) { 252 * // handle error 253 * while(1); 254 * } 255 * 256 * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 257 * 258 * AESCTR_OneStepOperation operation; 259 * AESCTR_OneStepOperation_init(&operation); 260 * 261 * operation.key = &cryptoKey; 262 * operation.input = plaintext; 263 * operation.output = ciphertext; 264 * operation.inputLength = sizeof(plaintext); 265 * operation.initialCounter = initialCounter; 266 * 267 * encryptionResult = AESCTR_oneStepEncrypt(handle, &operation); 268 * 269 * if (encryptionResult != AESCTR_STATUS_SUCCESS) { 270 * // handle error 271 * while(1); 272 * } 273 * 274 * // The ciphertext should be the following after the encryption operation: 275 * // 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 276 * // 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, 277 * // 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, 278 * // 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff, 279 * // 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, 280 * // 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, 281 * // 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, 282 * // 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee 283 * 284 * AESCTR_close(handle); 285 * 286 * @endcode 287 * 288 * <h5> One step CTR decryption with plaintext CryptoKey in callback return mode </h5> 289 * @code 290 * 291 * #include <ti/drivers/AESCTR.h> 292 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 293 * 294 * ... 295 * 296 * 297 * void ctrCallback(AESCTR_Handle handle, 298 * int_fast16_t returnValue, 299 * AESCTR_OperationUnion *operation, 300 * AESCTR_OperationType operationType) { 301 * 302 * if (returnValue != AESCTR_STATUS_SUCCESS) { 303 * // handle error 304 * while(1); 305 * } 306 * } 307 * AESCTR_Operation operation; 308 * 309 * void ctrStartFunction(void) { 310 * uint8_t initialCounter[16] = {0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, 311 * 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01}; 312 * uint8_t ciphertext[] = {0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, 313 * 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, 314 * 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, 315 * 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, 316 * 0x25, 0xB2, 0x07, 0x2F}; 317 * uint8_t keyingMaterial[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, 318 * 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC}; 319 * uint8_t plaintext[sizeof(ciphertext)]; 320 * 321 * AESCTR_Handle handle; 322 * AESCTR_Params params; 323 * CryptoKey cryptoKey; 324 * int_fast16_t decryptionResult; 325 * 326 * AESCTR_OneStepOperation operation; 327 * 328 * AESCTR_Params_init(¶ms); 329 * params.returnBehavior = AESCTR_RETURN_BEHAVIOR_CALLBACK; 330 * params.callbackFxn = ctrCallback; 331 * 332 * handle = AESCTR_open(0, ¶ms); 333 * 334 * if (handle == NULL) { 335 * // handle error 336 * while(1); 337 * } 338 * 339 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 340 * 341 * AESCTR_OneStepOperation_init(&operation); // Optional as all struct members will be set before use. 342 * 343 * operation.key = &cryptoKey; 344 * operation.input = ciphertext; 345 * operation.output = plaintext; 346 * operation.inputLength = sizeof(ciphertext); 347 * operation.initialCounter = initialCounter; 348 * 349 * decryptionResult = AESCTR_oneStepDecrypt(handle, &operation); 350 * 351 * if (decryptionResult != AESCTR_STATUS_SUCCESS) { 352 * // handle error 353 * while(1); 354 * } 355 * 356 * // do other things while CTR operation completes in the background 357 * 358 * // After the operation completes and the callback is invoked, the resultant 359 * // plaintext should be: 360 * // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 361 * // 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 362 * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 363 * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 364 * // 0x20, 0x21, 0x22, 0x23 365 * 366 * AESCTR_close(handle); 367 * } 368 * 369 * @endcode 370 * 371 * <h5> Multi-step AES CTR encrypt with plaintext CryptoKey in polling return mode </h5> 372 * @code 373 * 374 * #include <ti/drivers/AESCTR.h> 375 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 376 * 377 * #define AES_BLOCK_SIZE 16 // bytes 378 * ... 379 * 380 * AESCTR_Params params; 381 * AESCTR_Handle handle; 382 * CryptoKey cryptoKey; 383 * int_fast16_t retVal; 384 * 385 * // For example purposes only. 386 * uint8_t plaintext[36] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 387 * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 388 * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 389 * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 390 * 0x20, 0x21, 0x22, 0x23}; 391 * uint8_t initialCounter[] = {0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, 392 * 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01}; 393 * uint8_t keyingMaterial[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, 394 * 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC}; 395 * uint8_t ciphertext[sizeof(plaintext)]; 396 * 397 * AESCTR_Params_init(¶ms) 398 * params.returnBehavior = AESCTR_RETURN_BEHAVIOR_POLLING; 399 * 400 * handle = AESCTR_open(0, ¶ms); 401 * 402 * if (handle == NULL) { 403 * // handle error 404 * } 405 * 406 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 407 * 408 * AESCTR_SegmentedOperation operation; 409 * AESCTR_SegmentedOperation_init(&operation); // Optional as all struct members will be set before use. 410 * 411 * retVal = AESCTR_setupEncrypt(handle, &cryptoKey, initialCounter); 412 * 413 * if (retVal != AESCTR_STATUS_SUCCESS) { 414 * // handle error 415 * } 416 * 417 * operation.input = plaintext; 418 * operation.inputLength = AES_BLOCK_SIZE; // Only block multiple lengths are permitted when adding data. 419 * operation.output = ciphertext; 420 * 421 * retVal = AESCTR_addData(handle, &operation); 422 * 423 * if (retVal != AESCTR_STATUS_SUCCESS) { 424 * // handle error 425 * } 426 * 427 * operation.input = plaintext + AES_BLOCK_SIZE; 428 * operation.inputLength = sizeof(plaintext) - AES_BLOCK_SIZE; // Non-block multiple length permitted during 429 * finalization. operation.output = ciphertext + AES_BLOCK_SIZE; 430 * 431 * retVal = AESCTR_finalize(handle, &operation); 432 * 433 * if (retVal != AESCTR_STATUS_SUCCESS) { 434 * // handle error 435 * } 436 * 437 * // Upon successful return, the resulting ciphertext should be: 438 * // 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, 439 * // 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, 440 * // 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, 441 * // 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, 442 * // 0x25, 0xB2, 0x07, 0x2F 443 * 444 * AESCTR_close(handle); 445 * 446 * @endcode 447 */ 448 449 #ifndef ti_drivers_AESCTR__include 450 #define ti_drivers_AESCTR__include 451 452 #include <stddef.h> 453 #include <stdint.h> 454 455 #include <ti/drivers/AESCommon.h> 456 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h> 457 458 #ifdef __cplusplus 459 extern "C" { 460 #endif 461 462 /*! 463 * Common AESCTR status code reservation offset. 464 * AESCTR driver implementations should offset status codes with 465 * #AESCTR_STATUS_RESERVED growing negatively. 466 * 467 * Example implementation specific status codes: 468 * @code 469 * #define AESCTRXYZ_STATUS_ERROR0 AESCTR_STATUS_RESERVED - 0 470 * #define AESCTRXYZ_STATUS_ERROR1 AESCTR_STATUS_RESERVED - 1 471 * #define AESCTRXYZ_STATUS_ERROR2 AESCTR_STATUS_RESERVED - 2 472 * @endcode 473 */ 474 #define AESCTR_STATUS_RESERVED AES_STATUS_RESERVED 475 476 /*! 477 * @brief Successful status code. 478 * 479 * Functions return #AESCTR_STATUS_SUCCESS if the function was executed 480 * successfully. 481 */ 482 #define AESCTR_STATUS_SUCCESS AES_STATUS_SUCCESS 483 484 /*! 485 * @brief Generic error status code. 486 * 487 * Functions return #AESCTR_STATUS_ERROR if the function was not executed 488 * successfully and no more pertinent error code could be returned. 489 */ 490 #define AESCTR_STATUS_ERROR AES_STATUS_ERROR 491 492 /*! 493 * @brief An error status code returned if the hardware or software resource 494 * is currently unavailable. 495 * 496 * AESCTR driver implementations may have hardware or software limitations on how 497 * many clients can simultaneously perform operations. This status code is returned 498 * if the mutual exclusion mechanism signals that an operation cannot currently be performed. 499 */ 500 #define AESCTR_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE 501 502 /*! 503 * @brief The ongoing operation was canceled. 504 */ 505 #define AESCTR_STATUS_CANCELED AES_STATUS_CANCELED 506 507 /*! 508 * @brief The operation requested is not supported. 509 */ 510 #define AESCTR_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED 511 512 /*! 513 * @brief The operation tried to load a key from the keystore using an invalid key ID. 514 */ 515 #define AESCTR_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID 516 517 /*! 518 * @brief The key store module returned a generic error. See key store documentation 519 * for additional details. 520 */ 521 #define AESCTR_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR 522 523 /*! 524 * @brief The operation does not support non-word-aligned input and/or output. 525 * 526 * AESCTR driver implementations may have restrictions on the alignment of 527 * input/output data due to performance limitations of the hardware. 528 */ 529 #define AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED 530 531 /*! 532 * @brief The way in which CTR function calls return after performing an 533 * encryption or decryption operation. 534 * 535 * Not all CTR operations exhibit the specified return behavior. Functions that do not 536 * require significant computation and cannot offload that computation to a background thread 537 * behave like regular functions. Which functions exhibit the specified return behavior is not 538 * implementation dependent. Specifically, a software-backed implementation run on the same 539 * CPU as the application will emulate the return behavior while not actually offloading 540 * the computation to the background thread. 541 * 542 * AESCTR functions exhibiting the specified return behavior have restrictions on the 543 * context from which they may be called. 544 * 545 * | | Task | Hwi | Swi | 546 * |--------------------------------|-------|-------|-------| 547 * |AESCTR_RETURN_BEHAVIOR_CALLBACK | X | X | X | 548 * |AESCTR_RETURN_BEHAVIOR_BLOCKING | X | | | 549 * |AESCTR_RETURN_BEHAVIOR_POLLING | X | X | X | 550 * 551 */ 552 typedef enum 553 { 554 AESCTR_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK, 555 /*!< The function call will return immediately while the 556 * CTR operation goes on in the background. The registered 557 * callback function is called after the operation completes. 558 * The context the callback function is called (task, HWI, SWI) 559 * is implementation-dependent. 560 */ 561 AESCTR_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING, 562 /*!< The function call will block while the CTR operation goes 563 * on in the background. CTR operation results are available 564 * after the function returns. 565 */ 566 AESCTR_RETURN_BEHAVIOR_POLLING = AES_RETURN_BEHAVIOR_POLLING, 567 /*!< The function call will continuously poll a flag while CTR 568 * operation goes on in the background. CTR operation results 569 * are available after the function returns. 570 */ 571 } AESCTR_ReturnBehavior; 572 573 /*! 574 * @brief Struct containing the parameters required for encrypting/decrypting 575 * a message using a one-step operation. 576 * 577 * The driver may access it at any point during the operation. It must remain 578 * in scope for the entire duration of the operation. 579 */ 580 typedef struct 581 { 582 const CryptoKey *key; /*!< Pointer to a previously initialized CryptoKey. */ 583 const uint8_t *input; /*!< 584 * - Encryption: The plaintext buffer to be 585 * encrypted in the CTR operation. 586 * - Decryption: The ciphertext to be decrypted. 587 */ 588 uint8_t *output; /*!< 589 * - Encryption: The output ciphertext buffer that 590 * the encrypted plaintext is copied to. 591 * - Decryption: The plaintext derived from the 592 * decrypted ciphertext is copied here. 593 * Size of the output buffer must be greater than 594 * or equal to the inputLength. 595 */ 596 const uint8_t *initialCounter; /*!< A buffer containing an initial counter. Under 597 * the same key, each counter value may only be 598 * used to encrypt or decrypt a single input 599 * block. If NULL, zero will be used for the 600 * initial counter value. The buffer's size must 601 * be at least 16-bytes. 602 */ 603 size_t inputLength; /*!< Length of the input in bytes. An equal number 604 * of bytes will be output by the operation. 605 * Max length supported may be limited depending on 606 * the return behavior. 607 */ 608 } AESCTR_OneStepOperation; 609 610 /*! 611 * @brief Struct containing the parameters required for encrypting/decrypting 612 * a message using a segmented operation. This struct must be updated 613 * for each "add data" and "finalize" step. Modifying the structure and any buffers that 614 * it points to while an operation is in progress is prohibited. 615 * 616 * The driver may access it at any point during the operation. It must remain 617 * in scope for the entire duration of the operation. 618 */ 619 typedef struct 620 { 621 const uint8_t *input; /*!< 622 * - Encryption: The plaintext buffer to be 623 * encrypted in the CTR operation. 624 * - Decryption: The ciphertext to be decrypted. 625 */ 626 uint8_t *output; /*!< 627 * - Encryption: The output ciphertext buffer that 628 * the encrypted plaintext is copied to. 629 * - Decryption: The plaintext derived from the 630 * decrypted ciphertext is copied here. 631 * Size of the output buffer must be greater than 632 * or equal to the inputLength. 633 */ 634 size_t inputLength; /*!< Length of the input in bytes. An equal number 635 * of bytes will be output by the operation. Must 636 * be a non-zero multiple of block size (16-bytes) when 637 * calling #AESCTR_addData(). May be zero when calling 638 * #AESCTR_finalize() to finalize a segmented 639 * operation without additional data. 640 */ 641 } AESCTR_SegmentedOperation; 642 643 /** 644 * @deprecated 645 * Define a typedef for deprecated operation AESCTR_Operation. 646 * Existing code should be refactored to use AESCTR_OneStepOperation. 647 * This reference may be removed at some point in the future. 648 */ 649 typedef AESCTR_OneStepOperation AESCTR_Operation; 650 651 /*! 652 * @brief Union containing a reference to a one-step and segmented operation 653 * structure. 654 */ 655 typedef union 656 { 657 AESCTR_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */ 658 AESCTR_SegmentedOperation segmentedOperation; /* Segmented operation element of the operation union */ 659 } AESCTR_OperationUnion; 660 661 /*! 662 * @brief Enum for the direction of the CTR operation. 663 */ 664 typedef enum 665 { 666 AESCTR_MODE_ENCRYPT = 1, 667 AESCTR_MODE_DECRYPT = 2, 668 } AESCTR_Mode; 669 670 /*! 671 * @brief Mask for the operation mode. 672 */ 673 #define AESCTR_OP_MODE_MASK 0x0F 674 675 /*! 676 * @brief Flag indicating a segmented operation. 677 */ 678 #define AESCTR_OP_FLAG_SEGMENTED 0x10 /* bit 4 */ 679 680 /*! 681 * @brief Flag indicating a finalize operation. 682 */ 683 #define AESCTR_OP_FLAG_FINALIZE 0x20 /* bit 5 */ 684 685 /*! 686 * @brief Mask for all valid operation flags. 687 */ 688 #define AESCTR_OP_FLAGS_MASK (AESCTR_OP_FLAG_SEGMENTED | AESCTR_OP_FLAG_FINALIZE) 689 690 /*! 691 * @brief Enum for the operation types supported by the driver. 692 */ 693 typedef enum 694 { 695 AESCTR_OPERATION_TYPE_ENCRYPT = AESCTR_MODE_ENCRYPT, 696 AESCTR_OPERATION_TYPE_DECRYPT = AESCTR_MODE_DECRYPT, 697 AESCTR_OPERATION_TYPE_ENCRYPT_SEGMENTED = (AESCTR_MODE_ENCRYPT | AESCTR_OP_FLAG_SEGMENTED), 698 AESCTR_OPERATION_TYPE_DECRYPT_SEGMENTED = (AESCTR_MODE_DECRYPT | AESCTR_OP_FLAG_SEGMENTED), 699 AESCTR_OPERATION_TYPE_ENCRYPT_FINALIZE = (AESCTR_MODE_ENCRYPT | AESCTR_OP_FLAG_FINALIZE), 700 AESCTR_OPERATION_TYPE_DECRYPT_FINALIZE = (AESCTR_MODE_DECRYPT | AESCTR_OP_FLAG_FINALIZE), 701 } AESCTR_OperationType; 702 703 /*! 704 * @brief AESCTR Global configuration 705 * 706 * The #AESCTR_Config structure contains a set of pointers used to characterize 707 * the AESCTR driver implementation. 708 * 709 * This structure needs to be defined before calling #AESCTR_init() and it must 710 * not be changed thereafter. 711 * 712 * @sa #AESCTR_init() 713 */ 714 typedef AESCommon_Config AESCTR_Config; 715 716 /*! 717 * @brief A handle that is returned from an #AESCTR_open() call. 718 */ 719 typedef AESCTR_Config *AESCTR_Handle; 720 721 /*! 722 * @brief The definition of a callback function used by the AESCTR driver 723 * when used in ::AESCTR_RETURN_BEHAVIOR_CALLBACK 724 * 725 * @param handle Handle of the client that started the CTR operation. 726 * 727 * @param returnValue The result of the CTR operation. May contain an error code. 728 * Informs the application of why the callback function was 729 * called. 730 * 731 * @param operation Pointer to the operation union struct. 732 * 733 * @param operationType This parameter determines which operation the 734 * callback refers to. 735 */ 736 typedef void (*AESCTR_CallbackFxn)(AESCTR_Handle handle, 737 int_fast16_t returnValue, 738 AESCTR_OperationUnion *operation, 739 AESCTR_OperationType operationType); 740 741 /*! 742 * @brief CTR Parameters 743 * 744 * CTR Parameters are for #AESCTR_open() and #AESCTR_construct() calls. 745 * Default values for these parameters are set using #AESCTR_Params_init(). 746 * 747 * @sa #AESCTR_Params_init() 748 */ 749 typedef struct 750 { 751 AESCTR_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */ 752 AESCTR_CallbackFxn callbackFxn; /*!< Callback function pointer */ 753 uint32_t timeout; /*!< Timeout before the driver returns an error in 754 * ::AESCTR_RETURN_BEHAVIOR_BLOCKING 755 */ 756 void *custom; /*!< Custom argument used by driver 757 * implementation 758 */ 759 } AESCTR_Params; 760 761 /*! 762 * @brief Default #AESCTR_Params structure 763 * 764 * @sa #AESCTR_Params_init() 765 */ 766 extern const AESCTR_Params AESCTR_defaultParams; 767 768 /*! 769 * @brief This function initializes the CTR module. 770 * 771 * @pre The AESCTR_config structure must exist and be persistent before this 772 * function can be called. This function must also be called before 773 * any other CTR driver APIs. This function call does not modify any 774 * peripheral registers. 775 */ 776 void AESCTR_init(void); 777 778 /*! 779 * @brief Function to initialize the #AESCTR_Params struct to its defaults 780 * 781 * @param [in] params Pointer to #AESCTR_Params structure for 782 * initialization 783 * 784 * Defaults values are: 785 * returnBehavior = AESCTR_RETURN_BEHAVIOR_BLOCKING 786 * callbackFxn = NULL 787 * timeout = SemaphoreP_WAIT_FOREVER 788 * custom = NULL 789 */ 790 void AESCTR_Params_init(AESCTR_Params *params); 791 792 /*! 793 * @brief This function opens a given AESCTR peripheral. 794 * 795 * @pre AESCTR driver has been initialized using #AESCTR_init() 796 * 797 * @param [in] index Logical peripheral number for the CTR indexed into 798 * the AESCTR_config table 799 * 800 * @param [in] params Pointer to a parameter block, if NULL it will use 801 * default values. 802 * 803 * @return A #AESCTR_Handle on success or a NULL on an error or if it has 804 * been opened already. 805 * 806 * @sa #AESCTR_init() 807 * @sa #AESCTR_close() 808 */ 809 AESCTR_Handle AESCTR_open(uint_least8_t index, const AESCTR_Params *params); 810 811 /*! 812 * @brief Function to close a CTR peripheral specified by the AESCTR handle 813 * 814 * @pre #AESCTR_open() or #AESCTR_construct() 815 * 816 * @param [in] handle AESCTR handle 817 * 818 * @sa #AESCTR_open() 819 */ 820 void AESCTR_close(AESCTR_Handle handle); 821 822 /*! 823 * @brief Function to prepare a segmented AESCTR encryption operation. 824 * 825 * This function sets up a segmented AESCTR encryption operation. 826 * 827 * @pre #AESCTR_open() or #AESCTR_construct() 828 * 829 * @param [in] handle AESCTR handle 830 * @param [in] key Pointer to a previously initialized CryptoKey 831 * @param [in] initialCounter Pointer to initial counter value. 832 * The buffer size must be at least 16-bytes. 833 * If NULL, zero will be used for the initial counter value. 834 * 835 * @retval #AESCTR_STATUS_SUCCESS The operation succeeded. 836 * @retval #AESCTR_STATUS_ERROR The operation failed. 837 * 838 * @post #AESCTR_addData() 839 */ 840 int_fast16_t AESCTR_setupEncrypt(AESCTR_Handle handle, const CryptoKey *key, const uint8_t *initialCounter); 841 842 /*! 843 * @brief Function to prepare a segmented AESCTR decryption operation. 844 * 845 * This function sets up a segmented AESCTR decryption operation. 846 * 847 * @pre #AESCTR_open() or #AESCTR_construct() 848 * 849 * @param [in] handle AESCTR handle 850 * @param [in] key Pointer to a previously initialized CryptoKey. 851 * @param [in] initialCounter Pointer to initial counter value. 852 * The buffer size must be at least 16-bytes. 853 * If NULL, zero will be used for the initial counter value. 854 * 855 * @retval #AESCTR_STATUS_SUCCESS The operation succeeded. 856 * @retval #AESCTR_STATUS_ERROR The operation failed. 857 * 858 * @post #AESCTR_addData() 859 */ 860 int_fast16_t AESCTR_setupDecrypt(AESCTR_Handle handle, const CryptoKey *key, const uint8_t *initialCounter); 861 862 /*! 863 * @brief Encrypts or decrypts a segment of @a data with a @a length 864 * 865 * The @a inputLength must be a non-zero multiple of the block size (16-bytes). 866 * #AESCTR_addData() may be called an arbitrary number of times before 867 * finishing the operation with #AESCTR_finalize(). 868 * 869 * This function blocks until the final stream bytes have been computed. 870 * It returns immediately when ::AESCTR_RETURN_BEHAVIOR_CALLBACK is set. 871 * 872 * @pre A segmented operation has been setup using #AESCTR_setupEncrypt() or 873 * #AESCTR_setupDecrypt() 874 * 875 * @param [in] handle AESCTR handle 876 * @param [in] operation Pointer to #AESCTR_SegmentedOperation structure 877 * containing the parameters required to perform the operation. 878 * 879 * @retval #AESCTR_STATUS_SUCCESS The operation succeeded. 880 * @retval #AESCTR_STATUS_ERROR The operation failed. 881 * @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE The required hardware 882 * resource was not available. 883 * Try again later. 884 * @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 885 * 886 * @post #AESCTR_addData() or #AESCTR_finalize() 887 */ 888 int_fast16_t AESCTR_addData(AESCTR_Handle handle, AESCTR_SegmentedOperation *operation); 889 890 /*! 891 * @brief Finalize the AES operation. If new data needs to be added, 892 * @c inputLength will be used to govern how many bytes will be written. 893 * 894 * @note To finalize an operation without any additional data, 895 * set @c inputLength to zero. The input and output buffers 896 * will not be used in this scenario. 897 * 898 * @pre #AESCTR_setupEncrypt() or #AESCTR_setupDecrypt() 899 * @pre #AESCTR_addData() 900 * 901 * @param [in] handle AESCTR handle 902 * @param [in] operation Pointer to #AESCTR_SegmentedOperation structure 903 * containing the parameters required to perform the operation. 904 * 905 * @retval #AESCTR_STATUS_SUCCESS In ::AESCTR_RETURN_BEHAVIOR_BLOCKING and 906 * ::AESCTR_RETURN_BEHAVIOR_POLLING, this means the CTR 907 * was generated successfully. In ::AESCTR_RETURN_BEHAVIOR_CALLBACK, 908 * this means the operation started successfully. 909 * @retval #AESCTR_STATUS_ERROR The operation failed. 910 * @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE The required hardware 911 * resource was not available. 912 * Try again later. 913 * @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 914 */ 915 int_fast16_t AESCTR_finalize(AESCTR_Handle handle, AESCTR_SegmentedOperation *operation); 916 917 /*! 918 * @brief Function to initialize an #AESCTR_Operation struct to its defaults (all zeroes) 919 * 920 * @deprecated Use #AESCTR_OneStepOperation_init() or #AESCTR_SegmentedOperation_init() 921 * based on whether it is a one-step or a segmented AESCTR operation. 922 * 923 * @param operation Pointer to an #AESCTR_Operation structure for 924 * initialization 925 */ 926 void AESCTR_Operation_init(AESCTR_Operation *operation); 927 928 /*! 929 * @brief Function to initialize an #AESCTR_OneStepOperation struct to its defaults (all zeroes) 930 * 931 * @param [in] operation Pointer to an #AESCTR_OneStepOperation structure for 932 * initialization 933 */ 934 void AESCTR_OneStepOperation_init(AESCTR_OneStepOperation *operation); 935 936 /*! 937 * @brief Function to initialize an #AESCTR_SegmentedOperation struct to its defaults (all zeroes) 938 * 939 * @param [in] operation Pointer to an #AESCTR_SegmentedOperation structure for 940 * initialization 941 */ 942 void AESCTR_SegmentedOperation_init(AESCTR_SegmentedOperation *operation); 943 944 /*! 945 * @brief Function to perform an AESCTR encryption operation in one call. 946 * 947 * @note None of the buffers provided as arguments may be altered by the application during an ongoing operation. 948 * Doing so can yield corrupted ciphertext. 949 * 950 * @pre #AESCTR_open() or #AESCTR_construct() 951 * 952 * @param [in] handle AESCTR handle 953 * @param [in] operation Pointer to a struct containing the parameters required to perform the operation. 954 * 955 * @retval #AESCTR_STATUS_SUCCESS The operation succeeded. 956 * @retval #AESCTR_STATUS_ERROR The operation failed. 957 * @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later. 958 * @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 959 * 960 * @sa #AESCTR_oneStepDecrypt() 961 */ 962 int_fast16_t AESCTR_oneStepEncrypt(AESCTR_Handle handle, AESCTR_OneStepOperation *operation); 963 964 /*! 965 * @brief Function to perform an AESCTR decryption operation in one call. 966 * 967 * @note None of the buffers provided as arguments may be altered by the application during an ongoing operation. 968 * Doing so can yield corrupted plaintext. 969 * 970 * @pre #AESCTR_open() or #AESCTR_construct() 971 * 972 * @param [in] handle AESCTR handle 973 * @param [in] operation Pointer to a struct containing the parameters required to perform the operation. 974 * 975 * @retval #AESCTR_STATUS_SUCCESS The operation succeeded. 976 * @retval #AESCTR_STATUS_ERROR The operation failed. 977 * @retval #AESCTR_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later. 978 * @retval #AESCTR_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 979 * 980 * @sa AESCTR_oneStepEncrypt() 981 */ 982 int_fast16_t AESCTR_oneStepDecrypt(AESCTR_Handle handle, AESCTR_OneStepOperation *operation); 983 984 /*! 985 * @brief Cancels an ongoing AESCTR operation. 986 * 987 * Asynchronously cancels an AESCTR operation. Only available when using 988 * AESCTR_RETURN_BEHAVIOR_CALLBACK. 989 * The operation will terminate as though an error occurred. The 990 * return status code of the operation will be AESCTR_STATUS_CANCELED. 991 * 992 * @param [in] handle AESCTR handle 993 * 994 * @retval #AESCTR_STATUS_SUCCESS The operation was canceled or the operation had already completed. 995 */ 996 int_fast16_t AESCTR_cancelOperation(AESCTR_Handle handle); 997 998 /** 999 * @brief Constructs a new AESCTR object 1000 * 1001 * Unlike #AESCTR_open(), #AESCTR_construct() does not require the hwAttrs and 1002 * object to be allocated in a #AESCTR_Config array that is indexed into. 1003 * Instead, the #AESCTR_Config, hwAttrs, and object can be allocated at any 1004 * location. This allows for relatively simple run-time allocation of temporary 1005 * driver instances on the stack or the heap. 1006 * The drawback is that this makes it more difficult to write device-agnostic 1007 * code. If you use an ifdef with DeviceFamily, you can choose the correct 1008 * object and hwAttrs to allocate. That compilation unit will be tied to the 1009 * device it was compiled for at this point. To change devices, recompilation 1010 * of the application with a different DeviceFamily setting is necessary. 1011 * 1012 * @pre The object struct @c config points to must be zeroed out prior to 1013 * calling this function. Otherwise, unexpected behavior may occur. 1014 * 1015 * @param [in] config #AESCTR_Config describing the location of the object and hwAttrs. 1016 * 1017 * @param [in] params #AESCTR_Params to configure the driver instance. 1018 * 1019 * @return Returns a #AESCTR_Handle on success or NULL on failure. 1020 * 1021 1022 */ 1023 AESCTR_Handle AESCTR_construct(AESCTR_Config *config, const AESCTR_Params *params); 1024 1025 #ifdef __cplusplus 1026 } 1027 #endif 1028 1029 #endif /* ti_drivers_AESCTR__include */ 1030