1 /* 2 * Copyright (c) 2017-2023, 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 AESCCM.h 34 * 35 * @brief AESCCM driver header 36 * 37 * @anchor ti_drivers_AESCCM_Overview 38 * # Overview # 39 * The Counter with CBC-MAC (CCM) mode of operation is a generic 40 * authenticated encryption block cipher mode. It can be used with 41 * any block cipher. 42 * AESCCM combines CBC-MAC with an AES block cipher in CTR mode of operation. 43 * 44 * This combination of block cipher modes enables CCM to encrypt messages of any 45 * length and not only multiples of the block cipher block size. 46 * 47 * CTR provides confidentiality. The defined application of CBC-MAC provides 48 * message integrity and authentication. 49 * 50 * AESCCM has the following inputs and outputs: 51 * 52 * <table> 53 * <caption id="AESCCM_multi_row">AES-CCM input and output parameters</caption> 54 * <tr><th>Encryption</th><th>Decryption</th></tr> 55 * <tr><th colspan=2>Input</th></tr> 56 * <tr><td>Shared AES key</td><td> Shared AES key</td></tr> 57 * <tr><td>Nonce</td><td>Nonce</td></tr> 58 * <tr><td>Cleartext</td><td>Ciphertext</td></tr> 59 * <tr><td></td><td>MAC</td></tr> 60 * <tr><td>AAD (optional)</td><td>AAD (optional)</td></tr> 61 * <tr><th colspan=2>Output</th></tr> 62 * <tr><td>Ciphertext</td><td>Cleartext</td></tr> 63 * <tr><td>MAC</td><td></td></tr> 64 * </table> 65 * 66 * The AES key is a shared secret between the two parties and has a length 67 * of 128, 192, or 256 bits. 68 * 69 * The nonce is generated by the party performing the authenticated 70 * encryption operation. Within the scope of any authenticated 71 * encryption key, the nonce value must be unique. That is, the set of 72 * nonce values used with any given key must not contain any duplicate 73 * values. Using the same nonce for two different messages encrypted 74 * with the same key destroys the security properties. 75 * 76 * The length of the nonce determines the maximum number of messages that may 77 * be encrypted and authenticated before you must regenerate the key. 78 * Reasonable session key rotation schemes will regenerate the key before reaching 79 * this limit. 80 * There is a trade-off between the nonce-length and the maximum length of 81 * the plaintext to encrypt and authenticate per nonce. This is because 82 * CTR concatenates the nonce and an internal counter into one 16-byte 83 * IV. The counter is incremented after generating an AES-block-sized 84 * pseudo-random bitstream. This bitstream is XOR'd with the plaintext. 85 * The counter would eventually roll over for a sufficiently long message. 86 * This is must not happen. Hence, the longer the nonce and the more messages 87 * you can send before needing to rotate the key, the shorter the 88 * lengths of individual messages sent may be. The minimum and maximum 89 * nonce length defined by the CCM standard provide for both a reasonable 90 * number of messages before key rotation and a reasonable maximum message length. 91 * Check NIST SP 800-38C for details. 92 * 93 * The optional additional authentication data (AAD) is authenticated 94 * but not encrypted. Thus, the AAD is not included in the AES-CCM output. 95 * It can be used to authenticate packet headers. 96 * 97 * After the encryption operation, the ciphertext contains the encrypted 98 * data. The message authentication code (MAC) is also provided. 99 * 100 * # CCM Variations # 101 * The AESCCM driver supports both classic CCM as defined by NIST SP 800-38C and 102 * the CCM* variant used in IEEE 802.15.4. 103 * CCM* allows for unauthenticated encryption using CCM by permitting a MAC length 104 * of 0. It also imposes the requirement that the MAC length be embedded in 105 * the nonce used for each message if the MAC length varies within the protocol 106 * using CCM*. 107 * 108 * @anchor ti_drivers_AESCCM_Usage 109 * # Usage # 110 * 111 * ## Before starting a CCM operation # 112 * 113 * Before starting a CCM operation, the application must do the following: 114 * - Call AESCCM_init() to initialize the driver 115 * - Call AESCCM_Params_init() to initialize the AESCCM_Params to default values. 116 * - Modify the AESCCM_Params as desired 117 * - Call AESCCM_open() to open an instance of the driver 118 * - Initialize a CryptoKey. These opaque data structures are representations 119 * of keying material and its storage. Depending on how the keying material 120 * is stored (RAM or flash, key store), the CryptoKey must be 121 * initialized differently. The AESCCM API can handle all types of CryptoKey. 122 * However, not all device-specific implementations support all types of CryptoKey. 123 * Devices without a key store will not support CryptoKeys with keying material 124 * stored in a key store for example. 125 * All devices support plaintext CryptoKeys. 126 * - Initialize the appropriate AESCCM operation struct using the relevant 127 * operation init functions and set all fields. For example, one-step (one-shot 128 * or single call) operations should initialize AESCCM_Operation or 129 * AESCCM_OneStepOperation using AESCCM_Operation_init() or 130 * AESCCM_OneStepOperation_init(). For multi-step (segmented or multiple call) 131 * operations, AESCCM_SegmentedAADOperation must be initialized and set when 132 * processing AAD. AESCCM_SegmentedDataOperation must be initialized and set when 133 * dealing with payload data (plaintext or ciphertext). AESCCM_SegmentedFinalizeOperation 134 * must be initialized and set when finalizing the segmented operation. 135 * 136 * ## Starting a CCM operation # 137 * 138 * The AESCCM_oneStepEncrypt and AESCCM_oneStepDecrypt functions do a CCM operation in a single call. 139 * They will always be the most highly optimized routines with the least overhead and the fastest 140 * runtime. However, they require all AAD and plaintext or ciphertext data to be 141 * available to the function at the start of the call. 142 * All devices support single call operations. 143 * 144 * When performing a decryption operation with AESCCM_oneStepDecrypt(), the MAC is 145 * automatically verified. 146 * 147 * ## After the CCM operation completes # 148 * 149 * After the CCM operation completes, the application should either start another operation 150 * or close the driver by calling AESCCM_close() 151 * 152 * @anchor ti_drivers_AESCCM_Synopsis 153 * ## Synopsis 154 * 155 * @anchor ti_drivers_AESCCM_Synopsis_Code 156 * @code 157 * 158 * // Import AESCCM Driver definitions 159 * #include <ti/drivers/AESCCM.h> 160 * 161 * // Define name for AESCCM channel index 162 * #define AESCCM_INSTANCE 0 163 * 164 * AESCCM_init(); 165 * 166 * handle = AESCCM_open(AESCCM_INSTANCE, NULL); 167 * 168 * // Initialize symmetric key 169 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 170 * 171 * // Set up AESCCM_OneStepOperation 172 * AESCCM_OneStepOperation_init(&operation); 173 * operation.key = &cryptoKey; 174 * operation.aad = aad; 175 * operation.aadLength = sizeof(aad); 176 * operation.input = plaintext; 177 * operation.output = ciphertext; 178 * operation.inputLength = sizeof(plaintext); 179 * operation.nonce = nonce; 180 * operation.nonceLength = sizeof(nonce); 181 * operation.mac = mac; 182 * operation.macLength = sizeof(mac); 183 * 184 * encryptionResult = AESCCM_oneStepEncrypt(handle, &operation); 185 * 186 * AESCCM_close(handle); 187 * @endcode 188 * 189 * @anchor ti_drivers_AESCCM_Examples 190 * ## Examples 191 * 192 * ### Single call CCM encryption + authentication with plaintext CryptoKey in blocking return mode # 193 * @code 194 * 195 * #include <ti/drivers/AESCCM.h> 196 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 197 * 198 * ... 199 * 200 * AESCCM_Handle handle; 201 * CryptoKey cryptoKey; 202 * int_fast16_t encryptionResult; 203 * uint8_t nonce[] = "Thisisanonce"; 204 * uint8_t aad[] = "This string will be authenticated but not encrypted."; 205 * uint8_t plaintext[] = "This string will be encrypted and authenticated."; 206 * uint8_t mac[16]; 207 * uint8_t ciphertext[sizeof(plaintext)]; 208 * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 209 * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 210 * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 211 * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; 212 * 213 * handle = AESCCM_open(0, NULL); 214 * 215 * if (handle == NULL) { 216 * // handle error 217 * } 218 * 219 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 220 * 221 * AESCCM_OneStepOperation operation; 222 * AESCCM_OneStepOperation_init(&operation); 223 * 224 * operation.key = &cryptoKey; 225 * operation.aad = aad; 226 * operation.aadLength = sizeof(aad); 227 * operation.input = plaintext; 228 * operation.output = ciphertext; 229 * operation.inputLength = sizeof(plaintext); 230 * operation.nonce = nonce; 231 * operation.nonceLength = sizeof(nonce); 232 * operation.mac = mac; 233 * operation.macLength = sizeof(mac); 234 * 235 * encryptionResult = AESCCM_oneStepEncrypt(handle, &operation); 236 * 237 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 238 * // handle error 239 * } 240 * 241 * AESCCM_close(handle); 242 * 243 * @endcode 244 * ### The following code snippet is for CC27XX devices only and leverages the HSM 245 * which is a seperate Hardware Accelerator ### 246 * ### Single call CCM encryption + authentication with plaintext HSM CryptoKey in Polling Mode ### 247 * 248 * @code 249 * 250 * #include <ti/drivers/AESCCM.h> 251 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 252 * 253 * ... 254 * 255 * AESCCM_Params params; 256 * AESCCM_Handle handle; 257 * CryptoKey cryptoKey; 258 * int_fast16_t encryptionResult; 259 * uint8_t nonce[] = "Thisisanonce"; 260 * uint8_t aad[] = "This string will be authenticated but not encrypted."; 261 * uint8_t plaintext[] = "This string will be encrypted and authenticated."; 262 * uint8_t mac[16]; 263 * uint8_t ciphertext[sizeof(plaintext)]; 264 * uint8_t keyingMaterial[32] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 265 * 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 266 * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 267 * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; 268 * 269 * AESCCM_Params_init(¶ms) 270 * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_POLLING; 271 * 272 * handle = AESCCM_open(0, ¶ms); 273 * 274 * if (handle == NULL) { 275 * // handle error 276 * } 277 * 278 * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 279 * 280 * AESCCM_OneStepOperation operation; 281 * AESCCM_OneStepOperation_init(&operation); 282 * 283 * operation.key = &cryptoKey; 284 * operation.aad = aad; 285 * operation.aadLength = sizeof(aad); 286 * operation.input = plaintext; 287 * operation.output = ciphertext; 288 * operation.inputLength = sizeof(plaintext); 289 * operation.nonce = nonce; 290 * operation.nonceLength = sizeof(nonce); 291 * operation.mac = mac; 292 * operation.macLength = sizeof(mac); 293 * 294 * encryptionResult = AESCCM_oneStepEncrypt(handle, &operation); 295 * 296 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 297 * // handle error 298 * } 299 * 300 * AESCCM_close(handle); 301 * 302 * @endcode 303 * 304 * ### Single call CCM decryption + verification with plaintext CryptoKey in callback return mode # 305 * @code 306 * 307 * #include <ti/drivers/AESCCM.h> 308 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 309 * 310 * ... 311 * 312 * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF. 313 * 314 * uint8_t nonce[] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 315 * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; 316 * uint8_t aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; 317 * uint8_t mac[] = {0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0}; 318 * uint8_t ciphertext[] = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 319 * 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 320 * 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84}; 321 * uint8_t keyingMaterial[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 322 * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}; 323 * uint8_t plaintext[sizeof(ciphertext)]; 324 * 325 * // The plaintext should be the following after the decryption operation: 326 * // {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 327 * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 328 * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E} 329 * 330 * 331 * void ccmCallback(AESCCM_Handle handle, 332 * int_fast16_t returnValue, 333 * AESCCM_OperationUnion *operation, 334 * AESCCM_OperationType operationType) { 335 * 336 * if (returnValue != AESCCM_STATUS_SUCCESS) { 337 * // handle error 338 * } 339 * } 340 * 341 * AESCCM_OneStepOperation operation; 342 * 343 * void ccmStartFunction(void) { 344 * AESCCM_Handle handle; 345 * AESCCM_Params params; 346 * CryptoKey cryptoKey; 347 * int_fast16_t decryptionResult; 348 * 349 * AESCCM_Params_init(¶ms); 350 * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK; 351 * params.callbackFxn = ccmCallback; 352 * 353 * handle = AESCCM_open(0, ¶ms); 354 * 355 * if (handle == NULL) { 356 * // handle error 357 * } 358 * 359 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 360 * 361 * AESCCM_OneStepOperation_init(&operation); 362 * 363 * operation.key = &cryptoKey; 364 * operation.aad = aad; 365 * operation.aadLength = sizeof(aad); 366 * operation.input = ciphertext; 367 * operation.output = plaintext; 368 * operation.inputLength = sizeof(ciphertext); 369 * operation.nonce = nonce; 370 * operation.nonceLength = sizeof(nonce); 371 * operation.mac = mac; 372 * operation.macLength = sizeof(mac); 373 * 374 * decryptionResult = AESCCM_oneStepDecrypt(handle, &operation); 375 * 376 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 377 * // handle error 378 * } 379 * 380 * // do other things while CCM operation completes in the background 381 * 382 * } 383 * 384 * 385 * @endcode 386 * 387 * ### Multi-step CCM encryption + authentication with plaintext CryptoKey in blocking return mode # 388 * @code 389 * 390 * #include <ti/drivers/AESCCM.h> 391 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 392 * 393 * ... 394 * 395 * #define AES_BLOCK_SIZE 16 // bytes 396 * 397 * AESCCM_Handle handle; 398 * CryptoKey cryptoKey; 399 * int_fast16_t encryptionResult; 400 * 401 * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF. 402 * 403 * uint8_t keyingMaterial[16] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 404 * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}; 405 * uint8_t aad[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; 406 * uint8_t plaintext[23] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 407 * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 408 * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}; 409 * uint8_t nonce[13] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 410 * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; 411 * uint8_t mac[8]; 412 * uint8_t ciphertext[sizeof(plaintext)]; 413 * 414 * // The ciphertext should be the following after the encryption operation: 415 * // {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 416 * // 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 417 * // 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84} 418 * 419 * handle = AESCCM_open(0, NULL); 420 * 421 * if (handle == NULL) { 422 * // handle error 423 * } 424 * 425 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 426 * 427 * 428 * encryptionResult = AESCCM_setupEncrypt(handle, &cryptoKey, sizeof(aad), sizeof(plaintext), sizeof(mac)); 429 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 430 * // handle error 431 * } 432 * 433 * encryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce)); 434 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 435 * // handle error 436 * } 437 * 438 * #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX) // and the HSM is the engine of choice 439 * 440 * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 441 * 442 * // You will also need to populate the mac in handle->object->mac because HSM needs the mac to construct each 443 * // segmented token. 444 * encryptionResult = AESCCMLPF3HSM_setMac(handle, &mac[0], 8); 445 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 446 * // handle error 447 * } 448 * 449 * #endif 450 * 451 * AESCCM_SegmentedAADOperation segmentedAADOperation; 452 * AESCCM_SegmentedAADOperation_init(&segmentedAADOperation); 453 * segmentedAADOperation.aad = aad; 454 * segmentedAADOperation.aadLength = sizeof(aad); 455 * 456 * encryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation); 457 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 458 * // handle error 459 * } 460 * 461 * AESCCM_SegmentedDataOperation segmentedDataOperation; 462 * AESCCM_SegmentedDataOperation_init(&segmentedDataOperation); 463 * segmentedDataOperation.input = plaintext; 464 * segmentedDataOperation.output = ciphertext; 465 * // One should pass in data that is a block-sized multiple length 466 * // until passing in the last segment of data. 467 * // In that case, the input length simply needs to be a non-zero value. 468 * segmentedDataOperation.inputLength = AES_BLOCK_SIZE; 469 * 470 * encryptionResult = AESCCM_addData(handle, &segmentedDataOperation); 471 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 472 * // handle error 473 * } 474 * 475 * segmentedDataOperation.input = plaintext + AES_BLOCK_SIZE; 476 * segmentedDataOperation.output = ciphertext + AES_BLOCK_SIZE; 477 * segmentedDataOperation.inputLength = sizeof(plaintext) - AES_BLOCK_SIZE; 478 * 479 * encryptionResult = AESCCM_addData(handle, &segmentedDataOperation); 480 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 481 * // handle error 482 * } 483 * 484 * AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; 485 * AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation); 486 * segmentedFinalizeOperation.input = plaintext; 487 * segmentedFinalizeOperation.output = ciphertext; 488 * 489 * // You can finalize with no new data 490 * segmentedFinalizeOperation.inputLength = 0; 491 * segmentedFinalizeOperation.mac = mac; 492 * segmentedFinalizeOperation.macLength = sizeof(mac); 493 * encryptionResult = AESCCM_finalizeEncrypt(handle, &segmentedFinalizeOperation); 494 * 495 * if (encryptionResult != AESCCM_STATUS_SUCCESS) { 496 * // handle error 497 * } 498 * 499 * AESCCM_close(handle); 500 * 501 * @endcode 502 * 503 * ### Multi-step CCM decryption + verification with plaintext CryptoKey in callback return mode # 504 * @code 505 * 506 * #include <ti/drivers/AESCCM.h> 507 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 508 * 509 * ... 510 * 511 * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF. 512 * 513 * uint8_t nonce[] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 514 * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; 515 * uint8_t aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; 516 * uint8_t mac[] = {0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0}; 517 * uint8_t ciphertext[] = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 518 * 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 519 * 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84}; 520 * uint8_t keyingMaterial[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 521 * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}; 522 * uint8_t plaintext[sizeof(ciphertext)]; 523 * 524 * // The plaintext should be the following after the decryption operation: 525 * // {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 526 * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 527 * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E} 528 * 529 * 530 * void ccmCallback(AESCCM_Handle handle, 531 * int_fast16_t returnValue, 532 * AESCCM_OperationUnion *operation, 533 * AESCCM_OperationType operationType) { 534 * 535 * if (returnValue != AESCCM_STATUS_SUCCESS) { 536 * // handle error 537 * } 538 * 539 * if(operationType == AESCCM_OPERATION_TYPE_DECRYPT || 540 * operationType == AESCCM_OPERATION_TYPE_ENCRYPT) 541 * { 542 * // Callback fxn only used for one-shot operations 543 * // Use operation->oneStepOperation 544 * } 545 * else if(operationType == AESCCM_OP_TYPE_AAD_DECRYPT || 546 * operationType == AESCCM_OP_TYPE_AAD_ENCRYPT) 547 * { 548 * // Callback fxn only used for segmented AAD operations 549 * // Use operation->segmentedAADOperation 550 * } 551 * else if(operationType == AESCCM_OP_TYPE_DATA_DECRYPT || 552 * operationType == AESCCM_OP_TYPE_DATA_ENCRYPT) 553 * { 554 * // Callback fxn only used for segmented data operations 555 * // Use operation->segmentedDataOperation 556 * } 557 * else 558 * { 559 * // Callback fxn only used for segmented finalize operations 560 * // Use operation->segmentedFinalizeOperation 561 * } 562 * } 563 * 564 * void ccmStartFunction(void) { 565 * AESCCM_Handle handle; 566 * AESCCM_Params params; 567 * CryptoKey cryptoKey; 568 * int_fast16_t decryptionResult; 569 * 570 * AESCCM_Params_init(¶ms); 571 * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK; 572 * params.callbackFxn = ccmCallback; 573 * 574 * handle = AESCCM_open(0, ¶ms); 575 * 576 * if (handle == NULL) { 577 * // handle error 578 * } 579 * 580 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 581 * 582 * decryptionResult = AESCCM_setupDecrypt(handle, &cryptoKey, 0, 0, 0); 583 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 584 * // handle error 585 * } 586 * 587 * // setLengths must be called if the AAD, input, and MAC lengths aren't provided in setupXXXX. 588 * decryptionResult = AESCCM_setLengths(handle, sizeof(aad), sizeof(ciphertext), sizeof(mac)); 589 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 590 * // handle error 591 * } 592 * 593 * decryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce)); 594 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 595 * // handle error 596 * } 597 * 598 * AESCCM_SegmentedAADOperation segmentedAADOperation; 599 * AESCCM_SegmentedAADOperation_init(&segmentedAADOperation); 600 * segmentedAADOperation.aad = aad; 601 * segmentedAADOperation.aadLength = sizeof(aad); 602 * 603 * decryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation); 604 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 605 * // handle error 606 * } 607 * 608 * AESCCM_SegmentedDataOperation segmentedDataOperation; 609 * AESCCM_SegmentedDataOperation_init(&segmentedDataOperation); 610 * segmentedDataOperation.input = ciphertext; 611 * segmentedDataOperation.output = plaintext; 612 * segmentedDataOperation.inputLength = AES_BLOCK_SIZE; 613 * 614 * decryptionResult = AESCCM_addData(handle, &segmentedDataOperation); 615 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 616 * // handle error 617 * } 618 * 619 * AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; 620 * AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation); 621 * segmentedFinalizeOperation.input = ciphertext + AES_BLOCK_SIZE; 622 * segmentedFinalizeOperation.output = plaintext + AES_BLOCK_SIZE; 623 * segmentedFinalizeOperation.inputLength = sizeof(ciphertext) - AES_BLOCK_SIZE; 624 * segmentedFinalizeOperation.mac = mac; 625 * segmentedFinalizeOperation.macLength = sizeof(mac); 626 * 627 * decryptionResult = AESCCM_finalizeDecrypt(handle, &segmentedFinalizeOperation); 628 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 629 * // handle error 630 * } 631 * 632 * // do other things while CCM operation completes in the background 633 * 634 * } 635 * 636 * @endcode 637 * 638 * ### Multi-step CCM* decryption + verification with plaintext CryptoKey in callback return mode # 639 * @code 640 * 641 * #include <ti/drivers/AESCCM.h> 642 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 643 * 644 * ... 645 * 646 * // The following test vector is Packet Vector 1 from RFC 3610 of the IETF. 647 * 648 * uint8_t nonce[] = {0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 649 * 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; 650 * uint8_t aad[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; 651 * uint8_t mac[] = {0}; 652 * 653 * // CCM* allows for unauthenticated encryption using CCM by allowing a MAC length of 0 654 * uint8_t macLength = 0; 655 * uint8_t ciphertext[] = {0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 656 * 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 657 * 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84}; 658 * uint8_t keyingMaterial[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 659 * 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}; 660 * uint8_t plaintext[sizeof(ciphertext)]; 661 * 662 * // The plaintext should be the following after the decryption operation: 663 * // {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 664 * // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 665 * // 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E} 666 * 667 * 668 * void ccmCallback(AESCCM_Handle handle, 669 * int_fast16_t returnValue, 670 * AESCCM_OperationUnion *operation, 671 * AESCCM_OperationType operationType) { 672 * 673 * if (returnValue != AESCCM_STATUS_SUCCESS) { 674 * // handle error 675 * } 676 * 677 * if(operationType == AESCCM_OPERATION_TYPE_DECRYPT || 678 * operationType == AESCCM_OPERATION_TYPE_ENCRYPT) 679 * { 680 * // Callback fxn only used for one-shot operations 681 * // Use operation->oneStepOperation 682 * } 683 * else if(operationType == AESCCM_OP_TYPE_AAD_DECRYPT || 684 * operationType == AESCCM_OP_TYPE_AAD_ENCRYPT) 685 * { 686 * // Callback fxn only used for segmented AAD operations 687 * // Use operation->segmentedAADOperation 688 * } 689 * else if(operationType == AESCCM_OP_TYPE_DATA_DECRYPT || 690 * operationType == AESCCM_OP_TYPE_DATA_ENCRYPT) 691 * { 692 * // Callback fxn only used for segmented data operations 693 * // Use operation->segmentedDataOperation 694 * } 695 * else 696 * { 697 * // Callback fxn only used for segmented finalize operations 698 * // Use operation->segmentedFinalizeOperation 699 * } 700 * } 701 * 702 * void ccmStartFunction(void) { 703 * AESCCM_Handle handle; 704 * AESCCM_Params params; 705 * CryptoKey cryptoKey; 706 * int_fast16_t decryptionResult; 707 * 708 * AESCCM_Params_init(¶ms); 709 * params.returnBehavior = AESCCM_RETURN_BEHAVIOR_CALLBACK; 710 * params.callbackFxn = ccmCallback; 711 * 712 * handle = AESCCM_open(0, ¶ms); 713 * 714 * if (handle == NULL) { 715 * // handle error 716 * } 717 * 718 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 719 * 720 * decryptionResult = AESCCM_setupDecrypt(handle, &cryptoKey, 0, 0, 0); 721 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 722 * // handle error 723 * } 724 * 725 * // setLengths must be called if the AAD, input, and MAC lengths aren't provided in setupXXXX. 726 * decryptionResult = AESCCM_setLengths(handle, sizeof(aad), sizeof(ciphertext), macLength); 727 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 728 * // handle error 729 * } 730 * 731 * decryptionResult = AESCCM_setNonce(handle, nonce, sizeof(nonce)); 732 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 733 * // handle error 734 * } 735 * 736 * AESCCM_SegmentedAADOperation segmentedAADOperation; 737 * AESCCM_SegmentedAADOperation_init(&segmentedAADOperation); 738 * segmentedAADOperation.aad = aad; 739 * segmentedAADOperation.aadLength = sizeof(aad); 740 * 741 * decryptionResult = AESCCM_addAAD(handle, &segmentedAADOperation); 742 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 743 * // handle error 744 * } 745 * 746 * AESCCM_SegmentedDataOperation segmentedDataOperation; 747 * AESCCM_SegmentedDataOperation_init(&segmentedDataOperation); 748 * segmentedDataOperation.input = ciphertext; 749 * segmentedDataOperation.output = plaintext; 750 * segmentedDataOperation.inputLength = AES_BLOCK_SIZE; 751 * 752 * decryptionResult = AESCCM_addData(handle, &segmentedDataOperation); 753 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 754 * // handle error 755 * } 756 * 757 * AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; 758 * AESCCM_SegmentedFinalizeOperation_init(&egmentedFinalizeOperation); 759 * segmentedFinalizeOperation.input = ciphertext + AES_BLOCK_SIZE; 760 * segmentedFinalizeOperation.output = plaintext + AES_BLOCK_SIZE; 761 * segmentedFinalizeOperation.inputLength = sizeof(ciphertext) - AES_BLOCK_SIZE; 762 * segmentedFinalizeOperation.mac = mac; 763 * segmentedFinalizeOperation.macLength = macLength; 764 * 765 * decryptionResult = AESCCM_finalizeDecrypt(handle, &segmentedFinalizeOperation); 766 * if (decryptionResult != AESCCM_STATUS_SUCCESS) { 767 * // handle error 768 * } 769 * 770 * // do other things while CCM operation completes in the background 771 * 772 * } 773 * 774 * @endcode 775 */ 776 777 #ifndef ti_drivers_AESCCM__include 778 #define ti_drivers_AESCCM__include 779 780 #include <stdbool.h> 781 #include <stddef.h> 782 #include <stdint.h> 783 784 #include <ti/drivers/AESCommon.h> 785 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h> 786 787 #ifdef __cplusplus 788 extern "C" { 789 #endif 790 791 /*! 792 * Common AESCCM status code reservation offset. 793 * AESCCM driver implementations should offset status codes with 794 * AESCCM_STATUS_RESERVED growing negatively. 795 * 796 * Example implementation specific status codes: 797 * @code 798 * #define AESCCMXYZ_STATUS_ERROR0 AESCCM_STATUS_RESERVED - 0 799 * #define AESCCMXYZ_STATUS_ERROR1 AESCCM_STATUS_RESERVED - 1 800 * #define AESCCMXYZ_STATUS_ERROR2 AESCCM_STATUS_RESERVED - 2 801 * @endcode 802 */ 803 #define AESCCM_STATUS_RESERVED AES_STATUS_RESERVED 804 805 /*! 806 * @brief Successful status code. 807 * 808 * Functions return AESCCM_STATUS_SUCCESS if the function was executed 809 * successfully. 810 */ 811 #define AESCCM_STATUS_SUCCESS AES_STATUS_SUCCESS 812 813 /*! 814 * @brief Generic error status code. 815 * 816 * Functions return AESCCM_STATUS_ERROR if the function was not executed 817 * successfully and no more pertinent error code could be returned. 818 */ 819 #define AESCCM_STATUS_ERROR AES_STATUS_ERROR 820 821 /*! 822 * @brief An error status code returned if the hardware or software resource 823 * is currently unavailable. 824 * 825 * AESCCM driver implementations may have hardware or software limitations on how 826 * many clients can simultaneously perform operations. This status code is returned 827 * if the mutual exclusion mechanism signals that an operation cannot currently be performed. 828 */ 829 #define AESCCM_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE 830 831 /*! 832 * @brief The ongoing operation was canceled. 833 */ 834 #define AESCCM_STATUS_CANCELED AES_STATUS_CANCELED 835 836 /*! 837 * @brief An error status code returned if the MAC provided by the application for 838 * a decryption operation does not match the one calculated during the operation. 839 * 840 * This code is returned by AESCCM_oneStepDecrypt() or AESCCM_finalizeDecrypt() 841 * if the verification of the MAC fails. 842 */ 843 #define AESCCM_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID 844 845 /*! 846 * @brief The operation requested is not supported either by the target hardware 847 * or the driver implementation. 848 */ 849 #define AESCCM_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED 850 851 /*! 852 * @brief The operation tried to load a key from the keystore using an invalid key ID. 853 */ 854 #define AESCCM_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID 855 856 /*! 857 * @brief The key store module returned a generic error. See key store documentation 858 * for additional details. 859 */ 860 #define AESCCM_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR 861 862 /*! 863 * @brief The operation does not support non-word-aligned input and/or output. 864 * 865 * AESCCM driver implementations may have restrictions on the alignment of 866 * input/output data due to performance limitations of the hardware. 867 */ 868 #define AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED 869 870 /*! 871 * @brief AESCCM Global configuration 872 * 873 * The AESCCM_Config structure contains a set of pointers used to characterize 874 * the AESCCM driver implementation. 875 * 876 * This structure needs to be defined before calling AESCCM_init() and it must 877 * not be changed thereafter. 878 * 879 * @sa AESCCM_init() 880 */ 881 typedef AESCommon_Config AESCCM_Config; 882 883 /*! 884 * @brief A handle that is returned from an AESCCM_open() call. 885 */ 886 typedef AESCCM_Config *AESCCM_Handle; 887 888 /*! 889 * @brief The way in which CCM function calls return after performing an 890 * encryption + authentication or decryption + verification operation. 891 * 892 * Not all CCM operations exhibit the specified return behavior. Functions that do not 893 * require significant computation and cannot offload that computation to a background thread 894 * behave like regular functions. Which functions exhibit the specified return behavior is not 895 * implementation dependent. Specifically, a software-backed implementation run on the same 896 * CPU as the application will emulate the return behavior while not actually offloading 897 * the computation to the background thread. 898 * 899 * AESCCM functions exhibiting the specified return behavior have restrictions on the 900 * context from which they may be called. 901 * 902 * | | Task | Hwi | Swi | 903 * |--------------------------------|-------|-------|-------| 904 * |AESCCM_RETURN_BEHAVIOR_CALLBACK | X | X | X | 905 * |AESCCM_RETURN_BEHAVIOR_BLOCKING | X | | | 906 * |AESCCM_RETURN_BEHAVIOR_POLLING | X | X | X | 907 * 908 */ 909 typedef enum 910 { 911 AESCCM_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK, 912 /*!< The function call will return immediately while the 913 * CCM operation goes on in the background. The registered 914 * callback function is called after the operation completes. 915 * The context the callback function is called (task, HWI, SWI) 916 * is implementation-dependent. 917 */ 918 AESCCM_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING, 919 /*!< The function call will block while the CCM operation goes 920 * on in the background. CCM operation results are available 921 * after the function returns. 922 */ 923 AESCCM_RETURN_BEHAVIOR_POLLING = AES_RETURN_BEHAVIOR_POLLING, 924 /*!< The function call will continuously poll a flag while CCM 925 * operation goes on in the background. CCM operation results 926 * are available after the function returns. 927 */ 928 } AESCCM_ReturnBehavior; 929 930 /*! 931 * @brief Enum for the direction of the CCM operation. 932 */ 933 typedef enum 934 { 935 AESCCM_MODE_ENCRYPT = 1, 936 AESCCM_MODE_DECRYPT = 2, 937 } AESCCM_Mode; 938 939 /*! 940 * @brief Struct containing the parameters required for encrypting/decrypting 941 * and authenticating/verifying a message for one-step operations. 942 */ 943 typedef struct 944 { 945 CryptoKey *key; /*!< A previously initialized CryptoKey */ 946 uint8_t *aad; /*!< A buffer of length \c aadLength containing additional 947 * authentication data to be authenticated/verified but not 948 * encrypted/decrypted. 949 */ 950 uint8_t *input; /*!< 951 * - Encryption: The plaintext buffer to be encrypted and authenticated 952 * in the CCM operation. 953 * - Decryption: The ciphertext to be decrypted and verified. 954 */ 955 uint8_t *output; /*!< 956 * - Encryption: The output ciphertext buffer that the encrypted plaintext 957 * is copied to. 958 * - Decryption: The plaintext derived from the decrypted and verified 959 * ciphertext is copied here. 960 */ 961 uint8_t *nonce; /*!< A buffer containing a nonce. Nonces must be unique to 962 * each CCM operation and may not be reused. If 963 * nonceInternallyGenerated is set, the nonce will be 964 * generated by #AESCCM_oneStepEncrypt() and copied to this buffer. 965 */ 966 uint8_t *mac; /*!< 967 * - Encryption: The buffer where the message authentication 968 * code is copied. 969 * - Decryption: The buffer containing the received message 970 * authentication code. 971 */ 972 size_t aadLength; /*!< Length of the total \c aad in bytes. Either \c aadLength or 973 * \c inputLength must be non-zero. Unlike this field in 974 * AESCCM_SegmentedAADOperation, the length doesn't need to be 975 * block-aligned. 976 */ 977 size_t inputLength; /*!< Length of the input/output data in bytes. Either \c aadLength or 978 * \c inputLength must be non-zero. Unlike this field in 979 * AESCCM_SegmentedDataOperation, the length doesn't need to be 980 * block-aligned. 981 * Max length supported may be limited depending on the return behavior. 982 */ 983 uint8_t nonceLength; /*!< Length of \c nonce in bytes. 984 * Valid nonce lengths are [7, 8, ... 13]. 985 */ 986 uint8_t macLength; /*!< Length of \c mac in bytes. 987 * Valid MAC lengths are [0, 4, 6, 8, 10, 12, 14, 16]. 988 * A length of 0 disables authentication and verification. This is 989 * only permitted when using CCM*. 990 */ 991 bool nonceInternallyGenerated; /*!< When true, the nonce buffer passed into #AESCCM_oneStepEncrypt() 992 * will be overwritten with a randomly generated nonce. 993 * Not supported by all implementations. 994 */ 995 } AESCCM_OneStepOperation; 996 997 /*! 998 * @brief Struct containing the parameters required for 999 * authenticating/verifying additional data in a segmented operation. 1000 * Must be updated for each add AAD step of a segmented operation. 1001 */ 1002 typedef struct 1003 { 1004 uint8_t *aad; /*!< A buffer of length \c aadLength containing additional 1005 * authentication data to be authenticated/verified but not 1006 * encrypted/decrypted. 1007 */ 1008 size_t aadLength; /*!< Length of the \c aad in bytes. Must be non-zero, multiple 1009 * of the AES block size (16 bytes) unless the last chunk of 1010 * AAD is being passed in. In that case, this value doesn't 1011 * need to be an AES block-sized multiple. 1012 */ 1013 } AESCCM_SegmentedAADOperation; 1014 1015 /*! 1016 * @brief Struct containing the parameters required for encrypting/decrypting 1017 * a message in a segmented operation. Must be updated between each 1018 * add data step of a segmented operation. 1019 */ 1020 typedef struct 1021 { 1022 uint8_t *input; /*!< 1023 * - Encryption: The plaintext buffer to be encrypted and authenticated 1024 * in the CCM operation. 1025 * - Decryption: The ciphertext to be decrypted and verified. 1026 */ 1027 uint8_t *output; /*!< 1028 * - Encryption: The output ciphertext buffer that the encrypted plaintext 1029 * is copied to. 1030 * - Decryption: The plaintext derived from the decrypted and verified 1031 * ciphertext is copied here. 1032 */ 1033 size_t inputLength; /*!< Length of the input/output data in bytes. Must be non-zero, multiple 1034 * of the AES block size (16 bytes) unless the last chunk of data is being 1035 * passed in. In that case, this value doesn't need to a block size multiple. 1036 * Max length supported may be limited depending on the return behavior. 1037 */ 1038 } AESCCM_SegmentedDataOperation; 1039 1040 /*! 1041 * @brief Struct containing the parameters required for finalizing an 1042 * encryption/decryption and authentication/verification of a message 1043 * in a segmented operation. 1044 */ 1045 typedef struct 1046 { 1047 uint8_t *input; /*!< 1048 * - Encryption: The plaintext buffer to be encrypted and authenticated 1049 * in the CCM operation. 1050 * - Decryption: The ciphertext to be decrypted and verified. 1051 */ 1052 uint8_t *output; /*!< 1053 * - Encryption: The output ciphertext buffer that the encrypted plaintext 1054 * is copied to. 1055 * - Decryption: The plaintext derived from the decrypted and verified 1056 * ciphertext is copied here. 1057 */ 1058 uint8_t *mac; /*!< 1059 * - Encryption: The buffer where the message authentication 1060 * code is copied. 1061 * - Decryption: The buffer containing the received message 1062 * authentication code. 1063 */ 1064 size_t inputLength; /*!< Length of the input/output data in bytes. Can be 0 if finalizing 1065 * without new payload data. Unlike this field in 1066 * AESCCM_SegmentedDataOperation, the length doesn't need to be 1067 * block-aligned. 1068 * Max length supported may be limited depending on the return behavior. 1069 */ 1070 uint8_t macLength; /*!< Length of \c mac in bytes. 1071 * Valid MAC lengths are [0, 4, 6, 8, 10, 12, 14, 16]. 1072 * A length of 0 disables authentication and verification. This is 1073 * only permitted when using CCM*. 1074 */ 1075 } AESCCM_SegmentedFinalizeOperation; 1076 1077 /** 1078 * @deprecated 1079 * Define a typedef for deprecated operation AESCCM_Operation. 1080 * Existing code should be refactored to use AESCCM_OneStepOperation. 1081 * This reference may be removed at some point in the future 1082 * 1083 */ 1084 typedef AESCCM_OneStepOperation AESCCM_Operation; 1085 1086 /*! 1087 * @brief Union containing a reference to a one step, 1088 * segmented AAD, segmented data, or segmented finalize operation. 1089 */ 1090 typedef union AESCCM_OperationUnion 1091 { 1092 AESCCM_OneStepOperation oneStepOperation; /* One-step operation element of the operation union */ 1093 AESCCM_SegmentedAADOperation segmentedAADOperation; /* Segmented AAD operation element of the operation union */ 1094 AESCCM_SegmentedDataOperation segmentedDataOperation; /* Segmented data operation element of the operation union */ 1095 AESCCM_SegmentedFinalizeOperation segmentedFinalizeOperation; /* Segmented finalize operation element of the 1096 operation union */ 1097 } AESCCM_OperationUnion; 1098 1099 /*! 1100 * @brief Enum for the operation types supported by the driver. 1101 */ 1102 typedef enum 1103 { 1104 AESCCM_OPERATION_TYPE_ENCRYPT = 1, /* Fields 1 and 2 are for backward compatibility */ 1105 AESCCM_OPERATION_TYPE_DECRYPT = 2, 1106 AESCCM_OP_TYPE_ONESTEP_ENCRYPT = 1, /* Names changed to _OP_TYPE_ to avoid MISRA deviation from first 31 chars not 1107 being unique */ 1108 AESCCM_OP_TYPE_ONESTEP_DECRYPT = 2, 1109 AESCCM_OP_TYPE_AAD_ENCRYPT = 3, 1110 AESCCM_OP_TYPE_AAD_DECRYPT = 4, 1111 AESCCM_OP_TYPE_DATA_ENCRYPT = 5, 1112 AESCCM_OP_TYPE_DATA_DECRYPT = 6, 1113 AESCCM_OP_TYPE_FINALIZE_ENCRYPT = 7, 1114 AESCCM_OP_TYPE_FINALIZE_DECRYPT = 8, 1115 } AESCCM_OperationType; 1116 1117 /*! 1118 * @brief The definition of a callback function used by the AESCCM driver 1119 * when used in ::AESCCM_RETURN_BEHAVIOR_CALLBACK 1120 * 1121 * @param handle Handle of the client that started the CCM operation. 1122 * 1123 * @param returnValue The result of the CCM operation. May contain an error code. 1124 * Informs the application of why the callback function was 1125 * called. 1126 * 1127 * @param operationUnion A pointer to an operation union. 1128 * 1129 * @param operationType This parameter determines which operation the 1130 * callback refers to. 1131 */ 1132 typedef void (*AESCCM_CallbackFxn)(AESCCM_Handle handle, 1133 int_fast16_t returnValue, 1134 AESCCM_OperationUnion *operation, 1135 AESCCM_OperationType operationType); 1136 1137 /*! 1138 * @brief CCM Parameters 1139 * 1140 * CCM Parameters used with the AESCCM_open() call. Default values for 1141 * these parameters are set using AESCCM_Params_init(). 1142 * 1143 * @sa AESCCM_Params_init() 1144 */ 1145 typedef struct 1146 { 1147 AESCCM_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */ 1148 AESCCM_CallbackFxn callbackFxn; /*!< Callback function pointer */ 1149 uint32_t timeout; /*!< Timeout before the driver returns an error in 1150 * ::AESCCM_RETURN_BEHAVIOR_BLOCKING 1151 */ 1152 void *custom; /*!< Custom argument used by driver 1153 * implementation 1154 */ 1155 } AESCCM_Params; 1156 1157 /*! 1158 * @brief Default AESCCM_Params structure 1159 * 1160 * @sa #AESCCM_Params_init() 1161 */ 1162 extern const AESCCM_Params AESCCM_defaultParams; 1163 1164 /*! 1165 * @brief This function initializes the CCM module. 1166 * 1167 * @pre The AESCCM_config structure must exist and be persistent before this 1168 * function can be called. This function must also be called before 1169 * any other CCM driver APIs. This function call does not modify any 1170 * peripheral registers. 1171 */ 1172 void AESCCM_init(void); 1173 1174 /*! 1175 * @brief Function to initialize the #AESCCM_Params struct to its defaults 1176 * 1177 * @param params An pointer to #AESCCM_Params structure for 1178 * initialization 1179 * 1180 * Defaults values are: 1181 * returnBehavior = AESCCM_RETURN_BEHAVIOR_BLOCKING 1182 * callbackFxn = NULL 1183 * timeout = SemaphoreP_WAIT_FOREVER 1184 * custom = NULL 1185 */ 1186 void AESCCM_Params_init(AESCCM_Params *params); 1187 1188 /*! 1189 * @brief This function opens a given CCM peripheral. 1190 * 1191 * @pre CCM controller has been initialized using #AESCCM_init() 1192 * 1193 * @param [in] index Logical peripheral number for the CCM indexed into 1194 * the AESCCM_config table 1195 * 1196 * @param [in] params Pointer to an parameter block, if NULL it will use 1197 * default values. 1198 * 1199 * @return An AESCCM_Handle on success or a NULL on an error or if it has been 1200 * opened already. 1201 * 1202 * @sa #AESCCM_init() 1203 * @sa #AESCCM_close() 1204 */ 1205 AESCCM_Handle AESCCM_open(uint_least8_t index, const AESCCM_Params *params); 1206 1207 /*! 1208 * @brief Function to close a CCM peripheral specified by the CCM handle 1209 * 1210 * @pre #AESCCM_open() or #AESCCM_construct() 1211 * 1212 * @param [in] handle A CCM handle 1213 * 1214 * @sa #AESCCM_open() 1215 */ 1216 void AESCCM_close(AESCCM_Handle handle); 1217 1218 /*! 1219 * @brief Function to prepare a segmented AESCCM encryption operation. 1220 * 1221 * This function sets up a segmented AESCCM encryption operation. 1222 * 1223 * @pre #AESCCM_open() or #AESCCM_construct() 1224 * 1225 * @param [in] handle A CCM handle returned from #AESCCM_open() 1226 * or #AESCCM_construct() 1227 * 1228 * @param [in] key Pointer to a previously initialized CryptoKey. 1229 * 1230 * @param [in] totalAADLength Total size of the AAD in bytes. 1231 * This value can be 0 and later provided 1232 * by #AESCCM_setLengths(). 1233 * 1234 * @param [in] totalPlaintextLength Total size of the plaintext in bytes. 1235 * This value can be 0 and later provided 1236 * by #AESCCM_setLengths(). 1237 * 1238 * @param [in] macLength Size of the MAC in bytes. This value 1239 * can be 0 and later provided by 1240 * #AESCCM_setLengths(). 1241 * 1242 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1243 * @retval #AESCCM_STATUS_ERROR The operation failed. 1244 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1245 * 1246 * @post #AESCCM_addAAD() 1247 * @post #AESCCM_addData() 1248 */ 1249 int_fast16_t AESCCM_setupEncrypt(AESCCM_Handle handle, 1250 const CryptoKey *key, 1251 size_t totalAADLength, 1252 size_t totalPlaintextLength, 1253 size_t macLength); 1254 1255 /*! 1256 * @brief Function to prepare a segmented AESCCM decryption operation. 1257 * 1258 * This function sets up a segmented AESCCM decryption operation. 1259 * 1260 * @pre #AESCCM_open() or #AESCCM_construct() 1261 * 1262 * @param [in] handle A CCM handle returned from #AESCCM_open() 1263 * or #AESCCM_construct() 1264 * 1265 * @param [in] key Pointer to a previously initialized CryptoKey. 1266 * 1267 * @param [in] totalAADLength Total size of the AAD in bytes. 1268 * This value can be 0 and later provided 1269 * by #AESCCM_setLengths(). 1270 * 1271 * @param [in] totalPlaintextLength Total size of the plaintext in bytes 1272 * This value can be 0 and later provided 1273 * by #AESCCM_setLengths(). 1274 * 1275 * @param [in] macLength Size of the MAC in bytes. This value 1276 * can be 0 and later provided by 1277 * #AESCCM_setLengths(). 1278 * 1279 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1280 * @retval #AESCCM_STATUS_ERROR The operation failed. 1281 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1282 * 1283 * @post #AESCCM_addAAD() 1284 * @post #AESCCM_addData() 1285 */ 1286 int_fast16_t AESCCM_setupDecrypt(AESCCM_Handle handle, 1287 const CryptoKey *key, 1288 size_t totalAADLength, 1289 size_t totalPlaintextLength, 1290 size_t macLength); 1291 1292 /*! 1293 * @brief Function to set the lengths of the message, additional data, and MAC. 1294 * 1295 * This function declares the lengths of the message, 1296 * additional authenticated data (AAD), and MAC. 1297 * 1298 * @note This function doesn't have to be called if the lengths above were 1299 * specified in #AESCCM_setupEncrypt() or #AESCCM_setupDecrypt(). 1300 * 1301 * @pre #AESCCM_setupEncrypt() or #AESCCM_setupDecrypt() 1302 * 1303 * @param [in] handle A CCM handle returned from #AESCCM_open() 1304 * or #AESCCM_construct() 1305 * 1306 * @param [in] aadLength Size of the non-encrypted AAD in bytes 1307 * 1308 * @param [in] plaintextLength Size of the plaintext or ciphertext to encrypt or decrypt in bytes 1309 * 1310 * @param [in] macLength Size of the MAC in bytes 1311 * 1312 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1313 * @retval #AESCCM_STATUS_ERROR The operation failed. 1314 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1315 * 1316 * @post #AESCCM_setNonce() 1317 * @post #AESCCM_generateNonce() 1318 */ 1319 int_fast16_t AESCCM_setLengths(AESCCM_Handle handle, size_t aadLength, size_t plaintextLength, size_t macLength); 1320 1321 /*! 1322 * @brief Function to set the nonce for an AES CCM segmented operation. 1323 * 1324 * @pre #AESCCM_setupEncrypt(), #AESCCM_setupDecrypt(), or #AESCCM_setLengths() 1325 * 1326 * @param [in] handle A CCM handle returned from #AESCCM_open() 1327 * or #AESCCM_construct() 1328 * 1329 * @param [in] nonce Pointer to the buffer containing the nonce 1330 * 1331 * @param [in] nonceLength The length of the nonce in bytes 1332 * 1333 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1334 * @retval #AESCCM_STATUS_ERROR The operation failed. 1335 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not 1336 * supported in this device. 1337 * 1338 * @post #AESCCM_addAAD() 1339 * @post #AESCCM_addData() 1340 */ 1341 int_fast16_t AESCCM_setNonce(AESCCM_Handle handle, const uint8_t *nonce, size_t nonceLength); 1342 1343 /*! 1344 * @brief Function to generate a nonce for an AES CCM segmented encryption operation. 1345 * 1346 * @pre #AESCCM_setupEncrypt() or #AESCCM_setLengths() 1347 * 1348 * @param [in] handle A CCM handle returned from #AESCCM_open() 1349 * or #AESCCM_construct() 1350 * 1351 * @param [in] nonce Pointer to the buffer where the generated nonce 1352 * is to be written to 1353 * 1354 * @param [in] nonceSize The length of the nonce buffer in bytes 1355 * 1356 * @param [out] nonceLength The length of the nonce actually written if the 1357 * operation was successful 1358 * 1359 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1360 * @retval #AESCCM_STATUS_ERROR The operation failed. 1361 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not 1362 * supported in this device. 1363 * 1364 * @post #AESCCM_addAAD() 1365 * @post #AESCCM_addData() 1366 */ 1367 int_fast16_t AESCCM_generateNonce(AESCCM_Handle handle, uint8_t *nonce, size_t nonceSize, size_t *nonceLength); 1368 1369 /*! 1370 * @brief Adds a segment of @a aad with a @a length in bytes to the generated MAC. 1371 * The length must be a multiple of a block size, 16 bytes, unless passing in the last 1372 * chunk of AAD. 1373 * 1374 * #AESCCM_addAAD() may be called an arbitrary number of times before continuing the operation with 1375 * #AESCCM_addData(), #AESCCM_finalizeEncrypt() or #AESCCM_finalizeDecrypt(). 1376 * 1377 * This function returns according to the return behavior set when opening the driver. 1378 * 1379 * @note This function must not be called after passing data to encrypt or 1380 * decrypt with #AESCCM_addData(). 1381 * 1382 * @warning When decrypting, do not use the output until 1383 * #AESCCM_finalizeDecrypt() succeeds. 1384 * 1385 * @pre #AESCCM_setNonce() or #AESCCM_generateNonce() 1386 * 1387 * @param [in] handle A CCM handle returned from #AESCCM_open() or #AESCCM_construct() 1388 * 1389 * @param [in] operation Pointer to segmented AAD CCM operation structure 1390 * 1391 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1392 * @retval #AESCCM_STATUS_ERROR The operation failed. 1393 * @retval #AESCCM_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. 1394 * Try again later. 1395 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1396 * @retval #AESCCM_STATUS_CANCELED The operation was canceled. 1397 * 1398 * @post #AESCCM_addAAD() 1399 * @post #AESCCM_addData() 1400 * @post #AESCCM_finalizeEncrypt() 1401 * @post #AESCCM_finalizeDecrypt() 1402 */ 1403 int_fast16_t AESCCM_addAAD(AESCCM_Handle handle, AESCCM_SegmentedAADOperation *operation); 1404 1405 /*! 1406 * @brief Adds a segment of @a data with a @a length in bytes to the plaintext/ciphertext 1407 * output and generated MAC. The length must be a multiple of a block size, 16 bytes, unless 1408 * passing in the last chunk of payload data. 1409 * 1410 * #AESCCM_addData() may be called an arbitrary number of times before finishing the operation 1411 * with #AESCCM_finalizeEncrypt() or #AESCCM_finalizeDecrypt(). 1412 * 1413 * This function returns according to the return behavior set when opening the driver. 1414 * 1415 * @warning When decrypting, do not use the output until 1416 * #AESCCM_finalizeDecrypt() succeeds. 1417 * 1418 * @pre #AESCCM_setNonce() or #AESCCM_generateNonce() 1419 * 1420 * @param [in] handle A CCM handle returned from #AESCCM_open() or #AESCCM_construct() 1421 * 1422 * @param [in] operation Pointer to segmented data CCM operation structure 1423 * 1424 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1425 * @retval #AESCCM_STATUS_ERROR The operation failed. 1426 * @retval #AESCCM_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. 1427 * Try again later. 1428 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1429 * @retval #AESCCM_STATUS_CANCELED The operation was canceled. 1430 * @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 1431 * 1432 * @post #AESCCM_addData() 1433 * @post #AESCCM_finalizeEncrypt() 1434 * @post #AESCCM_finalizeDecrypt() 1435 */ 1436 int_fast16_t AESCCM_addData(AESCCM_Handle handle, AESCCM_SegmentedDataOperation *operation); 1437 1438 /*! 1439 * @brief Finalize the MAC and ciphertext. 1440 * 1441 * This function finalizes the encryption of a dataset earlier provided 1442 * by calls to #AESCCM_addAAD() and #AESCCM_addData() and creates a message 1443 * authentication code. If additional data needs to be encrypted and verified 1444 * as part of this call, set the operation structure @a inputLength accordingly. 1445 * 1446 * The resulting output is a message authentication code and ciphertext. 1447 * 1448 * @pre #AESCCM_addAAD() or #AESCCM_addData() 1449 * 1450 * @param [in] handle A CCM handle returned from #AESCCM_open() or #AESCCM_construct() 1451 * 1452 * @param [in] operation Pointer to segmented finalize CCM operation structure 1453 * 1454 * @retval #AESCCM_STATUS_SUCCESS In ::AESCCM_RETURN_BEHAVIOR_BLOCKING and 1455 * ::AESCCM_RETURN_BEHAVIOR_POLLING, this means the MAC 1456 * was generated successfully. In ::AESCCM_RETURN_BEHAVIOR_CALLBACK, 1457 * this means the operation started successfully. 1458 * @retval #AESCCM_STATUS_ERROR The operation failed. 1459 * @retval #AESCCM_STATUS_CANCELED The operation was canceled. 1460 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1461 * @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 1462 */ 1463 int_fast16_t AESCCM_finalizeEncrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation); 1464 1465 /*! 1466 * @brief Finalize the MAC and plaintext and verify it. 1467 * 1468 * This function finalizes the decryption of a dataset earlier provided 1469 * by calls to AESCCM_addAAD() and AESCCM_addData() and verifies a provided message 1470 * authentication code. If additional data needs to be decrypted and verified 1471 * as part of this call, set the operation structure @a inputLength accordingly. 1472 * 1473 * @note None of the buffers provided as arguments may be altered by the application during an ongoing operation. 1474 * Doing so can yield a corrupted MAC comparison. 1475 * 1476 * The resulting output is a verification return code and plaintext. 1477 * 1478 * @pre #AESCCM_addAAD() or #AESCCM_addData() 1479 * 1480 * @param [in] handle A CCM handle returned from #AESCCM_open() or #AESCCM_construct() 1481 * 1482 * @param [in] operation Pointer to segmented finalize CCM operation structure 1483 * 1484 * @retval #AESCCM_STATUS_SUCCESS In ::AESCCM_RETURN_BEHAVIOR_BLOCKING and 1485 * ::AESCCM_RETURN_BEHAVIOR_POLLING, this means the MAC 1486 * was verified successfully. In ::AESCCM_RETURN_BEHAVIOR_CALLBACK, 1487 * this means the operation started successfully. 1488 * @retval #AESCCM_STATUS_ERROR The operation failed. 1489 * @retval #AESCCM_STATUS_MAC_INVALID The provided MAC did not match the recomputed one. 1490 * @retval #AESCCM_STATUS_CANCELED The operation was canceled. 1491 * @retval #AESCCM_STATUS_FEATURE_NOT_SUPPORTED The operation is not supported in this device. 1492 * @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 1493 */ 1494 int_fast16_t AESCCM_finalizeDecrypt(AESCCM_Handle handle, AESCCM_SegmentedFinalizeOperation *operation); 1495 1496 /*! 1497 * @brief Function to initialize an #AESCCM_Operation struct to its defaults 1498 * 1499 * @deprecated This function should be replaced by calls to operation-specific 1500 * init functions. 1501 * 1502 * @param [in] operationStruct A pointer to an #AESCCM_Operation structure for 1503 * initialization 1504 * 1505 * Defaults values are all zeros. 1506 */ 1507 void AESCCM_Operation_init(AESCCM_Operation *operationStruct); 1508 1509 /*! 1510 * @brief Function to initialize an #AESCCM_OneStepOperation struct to its defaults 1511 * 1512 * @param [in] operationStruct A pointer to an #AESCCM_OneStepOperation structure for 1513 * initialization 1514 * 1515 * Defaults values are all zeros. 1516 */ 1517 void AESCCM_OneStepOperation_init(AESCCM_OneStepOperation *operationStruct); 1518 1519 /*! 1520 * @brief Function to initialize an #AESCCM_SegmentedAADOperation struct to its defaults 1521 * 1522 * @param [in] operationStruct A pointer to an #AESCCM_SegmentedAADOperation structure 1523 * for initialization 1524 * 1525 * Defaults values are all zeros. 1526 */ 1527 void AESCCM_SegmentedAADOperation_init(AESCCM_SegmentedAADOperation *operationStruct); 1528 1529 /*! 1530 * @brief Function to initialize an #AESCCM_SegmentedDataOperation struct to its defaults 1531 * 1532 * @param [in] operationStruct A pointer to an #AESCCM_SegmentedDataOperation structure 1533 * for initialization 1534 * 1535 * Defaults values are all zeros. 1536 */ 1537 void AESCCM_SegmentedDataOperation_init(AESCCM_SegmentedDataOperation *operationStruct); 1538 1539 /*! 1540 * @brief Function to initialize an #AESCCM_SegmentedFinalizeOperation struct to its defaults 1541 * 1542 * @param [in] operationStruct A pointer to an #AESCCM_SegmentedFinalizeOperation structure 1543 * for initialization 1544 * 1545 * Defaults values are all zeros. 1546 */ 1547 void AESCCM_SegmentedFinalizeOperation_init(AESCCM_SegmentedFinalizeOperation *operationStruct); 1548 1549 /*! 1550 * @brief Function to perform an AESCCM encryption + authentication operation in one call. 1551 * 1552 * @note None of the buffers provided as arguments may be altered by the application during an ongoing operation. 1553 * Doing so can yield corrupted ciphertext or incorrect authentication. 1554 * 1555 * @pre #AESCCM_open() or #AESCCM_construct() and #AESCCM_Operation_init() have to be called first. 1556 * 1557 * @param [in] handle A CCM handle returned from #AESCCM_open() or #AESCCM_construct() 1558 * 1559 * @param [in] operationStruct A pointer to a struct containing the parameters required to perform the 1560 * operation. 1561 * 1562 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1563 * @retval #AESCCM_STATUS_ERROR The operation failed. 1564 * @retval #AESCCM_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later. 1565 * @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 1566 * 1567 * @sa AESCCM_oneStepDecrypt() 1568 */ 1569 int_fast16_t AESCCM_oneStepEncrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct); 1570 1571 /*! 1572 * @brief Function to perform an AESCCM decryption + verification operation in one call. 1573 * 1574 * @note None of the buffers provided as arguments may be altered by the application during an ongoing operation. 1575 * Doing so can yield corrupted plaintext or incorrectly failed verification. 1576 * 1577 * @pre #AESCCM_open() or #AESCCM_construct() and #AESCCM_Operation_init() have to be called first. 1578 * 1579 * @param [in] handle A CCM handle returned from #AESCCM_open() or #AESCCM_construct() 1580 * 1581 * @param [in] operationStruct A pointer to a struct containing the parameters required to perform the 1582 * operation. 1583 * 1584 * @retval #AESCCM_STATUS_SUCCESS The operation succeeded. 1585 * @retval #AESCCM_STATUS_ERROR The operation failed. 1586 * @retval #AESCCM_STATUS_RESOURCE_UNAVAILABLE The required hardware resource was not available. Try again later. 1587 * @retval #AESCCM_STATUS_MAC_INVALID The provided MAC did not match the recomputed one. 1588 * @retval #AESCCM_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input and/or output buffer were not word-aligned. 1589 * 1590 * @sa AESCCM_oneStepEncrypt() 1591 */ 1592 int_fast16_t AESCCM_oneStepDecrypt(AESCCM_Handle handle, AESCCM_OneStepOperation *operationStruct); 1593 1594 /*! 1595 * @brief Cancels an ongoing AESCCM operation. 1596 * 1597 * Asynchronously cancels an AESCCM operation. Only available when using 1598 * AESCCM_RETURN_BEHAVIOR_CALLBACK. 1599 * The operation will terminate as though an error occurred. The 1600 * return status code of the operation will be AESCCM_STATUS_CANCELED. 1601 * 1602 * @param [in] handle Handle of the operation to cancel 1603 * 1604 * @retval #AESCCM_STATUS_SUCCESS The operation was canceled, or the operation had already completed. 1605 * @retval #AESCCM_STATUS_ERROR The driver was not in callback mode, or the operation's output 1606 * and generated MAC weren't properly cleared. 1607 */ 1608 int_fast16_t AESCCM_cancelOperation(AESCCM_Handle handle); 1609 1610 /** 1611 * @brief Constructs a new AESCCM object 1612 * 1613 * Unlike #AESCCM_open(), #AESCCM_construct() does not require the hwAttrs and 1614 * object to be allocated in a #AESCCM_Config array that is indexed into. 1615 * Instead, the #AESCCM_Config, hwAttrs, and object can be allocated at any 1616 * location. This allows for relatively simple run-time allocation of temporary 1617 * driver instances on the stack or the heap. 1618 * The drawback is that this makes it more difficult to write device-agnostic 1619 * code. If you use an ifdef with DeviceFamily, you can choose the correct 1620 * object and hwAttrs to allocate. That compilation unit will be tied to the 1621 * device it was compiled for at this point. To change devices, recompilation 1622 * of the application with a different DeviceFamily setting is necessary. 1623 * 1624 * @param config #AESCCM_Config describing the location of the object and hwAttrs. 1625 * 1626 * @param params #AESCCM_Params to configure the driver instance. 1627 * 1628 * @return Returns a #AESCCM_Handle on success or NULL on failure. 1629 * 1630 * @pre The object struct @c config points to must be zeroed out prior to 1631 * calling this function. Otherwise, unexpected behavior may ensue. 1632 */ 1633 AESCCM_Handle AESCCM_construct(AESCCM_Config *config, const AESCCM_Params *params); 1634 1635 #ifdef __cplusplus 1636 } 1637 #endif 1638 1639 #endif /* ti_drivers_AESCCM__include */ 1640