1 /* 2 * Copyright (c) 2019-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 AESCMAC.h 34 * 35 * @brief AESCMAC (CMAC and CBC-MAC) driver header 36 * 37 * @anchor ti_drivers_AESCMAC_Overview 38 * # Overview # 39 * The Cipher-based Message Authentication Code (CMAC) and Cipher Block Chaining 40 * Message Authentication Code (CBC-MAC) are generic block cipher modes of 41 * operation. They can be used with any block cipher but this driver 42 * implementation uses AES. 43 * 44 * Both CMAC and CBC-MAC create a message authentication code from a message of 45 * any practical length to provide authenticity and integrity assurances. 46 * CMAC is recommended over CBC-MAC because CBC-MAC is not secure for variable 47 * length messages. 48 * 49 * ## CBC-MAC Drawbacks # 50 * CBC-MAC is only secure for fixed-length messages. Any single key must only be 51 * used for messages of a fixed and known length. The CMAC algorithm, which 52 * is based on a variation of CBC-MAC at its core, was developed to address that 53 * security deficiency and is the MAC algorithm recommended by NIST. 54 * 55 * @anchor ti_drivers_AESCMAC_Usage 56 * # CMAC Usage # 57 * ## Before starting a CMAC operation # 58 * 59 * Before starting a CMAC operation, the application must do the following: 60 * - Call #AESCMAC_init() to initialize the driver 61 * - Call #AESCMAC_Params_init() to initialize the #AESCMAC_Params to default values. 62 * - Modify the #AESCMAC_Params as desired 63 * - Call #AESCMAC_open() to open an instance of the driver 64 * - Initialize a CryptoKey. These opaque data structures are representations 65 * of keying material and its storage. Depending on how the keying material 66 * is stored (RAM or flash, key store), the CryptoKey must be 67 * initialized differently. The CMAC API can handle all types of CryptoKey. 68 * However, not all device-specific implementations support all types of CryptoKey. 69 * Devices without a key store will not support CryptoKeys with keying material 70 * stored in a key store for example. 71 * All devices support plaintext CryptoKeys. 72 * 73 * ## Starting a CMAC operation # 74 * 75 * The #AESCMAC_oneStepSign and #AESCMAC_oneStepVerify functions perform a CMAC operation 76 * in a single call. They will always be the most highly optimized routines with the 77 * least overhead and the fastest runtime. However, they require all plaintext 78 * or ciphertext to be available to the function at the start of the call. 79 * All devices support single call operations. 80 * 81 * ## After the CMAC operation completes # 82 * 83 * After the CMAC operation completes, the application should either start 84 * another operation or close the driver by calling #AESCMAC_close(). 85 * 86 * @anchor ti_drivers_AESCMAC_Synopsis 87 * ## Synopsis 88 * @anchor ti_drivers_AESCMAC_Synopsis_Code 89 * @code 90 * // Import CMAC Driver definitions 91 * #include <ti/drivers/CMAC.h> 92 * 93 * // Define name for CMAC channel index 94 * #define AESCMAC_INSTANCE 0 95 * 96 * AESCMAC_init(); 97 * 98 * handle = AESCMAC_open(AESCMAC_INSTANCE, NULL); 99 * 100 * // Initialize symmetric key 101 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 102 * 103 * // Initialize the operation 104 * AESCMAC_Operation_init(&operation); 105 * operation.input = input; 106 * operation.inputLength = sizeof(input); 107 * operation.mac = mac; 108 * operation.macLength = sizeof(mac); 109 * 110 * signResult = AESCMAC_oneStepSign(handle, &operation, &cryptoKey); 111 * 112 * AESCMAC_close(handle); 113 * @endcode 114 * 115 * @anchor ti_drivers_AESCMAC_Examples 116 * ## Examples 117 * 118 * ### Single call CMAC authentication with plaintext CryptoKey in blocking return mode # 119 * @code 120 * 121 * #include <ti/drivers/AESCMAC.h> 122 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 123 * 124 * ... 125 * 126 * uint8_t message[16] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 127 * 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; 128 * uint8_t keyingMaterial[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 129 * 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; 130 * uint8_t mac[16]; 131 * 132 * ... 133 * 134 * CryptoKey cryptoKey; 135 * AESCMAC_Params params; 136 * AESCMAC_Operation operation; 137 * 138 * AESCMAC_init(); 139 * 140 * AESCMAC_Handle handle = AESCMAC_open(0, NULL); 141 * 142 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 143 * 144 * AESCMAC_Operation_init(&operation); 145 * operation.input = input; 146 * operation.inputLength = sizeof(input); 147 * operation.mac = mac; 148 * operation.macLength = sizeof(mac); 149 * 150 * int_fast16_t result = AESCMAC_oneStepSign(handle, &operation, &cryptoKey); 151 * 152 * if (result != AESCMAC_STATUS_SUCCESS) { 153 * // handle error 154 * } 155 * 156 * // The resulting MAC should equal the following after the operation: 157 * // 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, 158 * // 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C 159 * 160 * AESCMAC_close(handle); 161 * 162 * @endcode 163 * 164 * ### Single call CMAC authentication with plaintext CryptoKey in polling return mode and using HSM engine # 165 * @code 166 * 167 * #include <ti/drivers/AESCMAC.h> 168 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 169 * 170 * ... 171 * 172 * uint8_t message[16] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 173 * 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; 174 * uint8_t keyingMaterial[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 175 * 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; 176 * uint8_t mac[16]; 177 * 178 * ... 179 * 180 * AESCMAC_Params params; 181 * AESCMAC_Handle handle; 182 * CryptoKey cryptoKey; 183 * AESCMAC_Params_init(¶ms) 184 * params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_POLLING; 185 * params.operationalMode = AESCMAC_OPMODE_CBCMAC; 186 * AESCMAC_Operation operation; 187 * 188 * AESCMAC_init(); 189 * 190 * handle = AESCMAC_open(0, ¶ms); 191 * 192 * CryptoKeyPlaintextHSM_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 193 * 194 * AESCMAC_Operation_init(&operation); 195 * operation.input = input; 196 * operation.inputLength = sizeof(input); 197 * operation.mac = mac; 198 * operation.macLength = sizeof(mac); 199 * 200 * int_fast16_t result = AESCMAC_oneStepSign(handle, &operation, &cryptoKey); 201 * 202 * if (result != AESCMAC_STATUS_SUCCESS) { 203 * // handle error 204 * } 205 * 206 * // The resulting MAC should equal the following after the operation: 207 * // 0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, 208 * // 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C 209 * 210 * AESCMAC_close(handle); 211 * 212 * @endcode 213 * 214 * ### Single call CMAC verification with plaintext CryptoKey in callback return mode # 215 * @code 216 * 217 * #include <ti/drivers/AESCMAC.h> 218 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 219 * 220 * ... 221 * uint8_t message[16] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 222 * 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; 223 * uint8_t keyingMaterial[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 224 * 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; 225 * uint8_t expectedMac[16] = {0x07, 0x0A, 0x16, 0xB4, 0x6B, 0x4D, 0x41, 0x44, 226 * 0xF7, 0x9B, 0xDD, 0x9D, 0xD0, 0x4A, 0x28, 0x7C}; 227 * 228 * void cmacCallback(AESCMAC_Handle handle, 229 * int_fast16_t returnValue) { 230 * if (returnValue != AESCMAC_STATUS_SUCCESS) { 231 * // handle error 232 * } 233 * } 234 * 235 * void cmacStartFunction(void) { 236 * AESCMAC_Handle handle; 237 * AESCMAC_Params params; 238 * AESCMAC_Operation operation; 239 * CryptoKey cryptoKey; 240 * int_fast16_t verificationResult; 241 * 242 * AESCMAC_Params_init(¶ms); 243 * params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_CALLBACK; 244 * params.callbackFxn = cmacCallback; 245 * handle = AESCMAC_open(0, ¶ms); 246 * if (handle == NULL) { 247 * // handle error 248 * } 249 * 250 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 251 * 252 * AESCMAC_Operation_init(&operation); 253 * operation.input = input; 254 * operation.inputLength = sizeof(input); 255 * operation.mac = expectedMac; 256 * operation.macLength = sizeof(expectedMac); 257 * verificationResult = AESCMAC_oneStepVerify(handle, &operation, &cryptoKey); 258 * 259 * if (verificationResult != AESCMAC_STATUS_SUCCESS) { 260 * // handle error 261 * } 262 * // do other things while CMAC operation completes in the background 263 * } 264 * @endcode 265 * 266 * ### Multi-step CMAC signature with plaintext CryptoKey in blocking return mode # 267 * @code 268 * 269 * #include <ti/drivers/AESCMAC.h> 270 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 271 * 272 * #define AES_BLOCK_SIZE 16 // bytes 273 * ... 274 * 275 * uint8_t keyingMaterial[32] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 276 * 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 277 * 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 278 * 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4}; 279 * uint8_t message[40] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 280 * 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 281 * 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 282 * 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 283 * 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11}; 284 * uint8_t mac[16]; 285 * 286 * CryptoKey cryptoKey; 287 * AESCMAC_Params params; 288 * AESCMAC_Operation operation; 289 * 290 * AESCMAC_init(); 291 * 292 * AESCMAC_Handle handle = AESCMAC_open(0, NULL); 293 * 294 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 295 * 296 * AESCMAC_Operation_init(&operation); 297 * 298 * // Set up multi-step sign. 299 * int_fast16_t result = AESCMAC_setupSign(handle, &cryptoKey); 300 * 301 * if (result != AESCMAC_STATUS_SUCCESS) { 302 * // handle error 303 * } 304 * 305 * size_t initialSegmentSize = AES_BLOCK_SIZE; 306 * 307 * // Add first segment of data. 308 * operation.input = input; 309 * operation.inputLength = initialSegmentSize; // Must be a non-zero multiple of the block size (16-bytes) unless 310 * finalizing. result = AESCMAC_addData(handle, &operation); 311 * 312 * if (result != AESCMAC_STATUS_SUCCESS) { 313 * // handle error 314 * } 315 * 316 * // Finalize with the last segment of data. 317 * operation.input = &input[initialSegmentSize]; 318 * operation.inputLength = sizeof(input) - initialSegmentSize; 319 * operation.mac = mac; 320 * operation.macLength = sizeof(mac); 321 * 322 * result = AESCMAC_finalize(handle, &operation); 323 * 324 * if (result != AESCMAC_STATUS_SUCCESS) { 325 * // handle error 326 * } 327 * 328 * // The resulting MAC should equal the following after the operation: 329 * // 0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2, 330 * // 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6 331 * ... 332 * 333 * AESCMAC_close(handle); 334 * 335 * @endcode 336 * 337 * @anchor ti_drivers_AESCBCMAC_Usage 338 * # CBC-MAC Usage # 339 * ## Before starting a CBC-MAC operation # 340 * 341 * Before starting a CBC-MAC operation, the application must do the following: 342 * - Call #AESCMAC_init() to initialize the driver 343 * - Call #AESCMAC_Params_init() to initialize the #AESCMAC_Params to 344 * default values. 345 * - Set #AESCMAC_Params.operationalMode to #AESCMAC_OPMODE_CBCMAC. 346 * - Modify the #AESCMAC_Params as desired 347 * - Call #AESCMAC_open() to open an instance of the driver 348 * - Initialize a CryptoKey. These opaque data structures are representations 349 * of keying material and its storage. Depending on how the keying material 350 * is stored (RAM or flash, key store, key blob), the CryptoKey must be 351 * initialized differently. The AESCMAC API can handle all types of 352 * CryptoKey. However, not all device-specific implementations support all 353 * types of CryptoKey. Devices without a key store will not support 354 * CryptoKeys with keying material stored in a key store for example. All 355 * devices support plaintext CryptoKeys. 356 * - Initialize the #AESCMAC_Operation using #AESCMAC_Operation_init() 357 * and set all length, key, and buffer fields. 358 * 359 * ## Starting a CBC-MAC operation # 360 * 361 * The #AESCMAC_oneStepSign and #AESCMAC_oneStepVerify functions perform a 362 * CBC-MAC operation in a single call. They will always be the most highly 363 * optimized routines with the least overhead and the fastest runtime. However, 364 * they require all plaintext or ciphertext to be available to the function at 365 * the start of the call. All devices support single call operations. 366 * 367 * ## After the CBC-MAC operation completes # 368 * 369 * After the CBC-MAC operation completes, the application should either start 370 * another operation or close the driver by calling #AESCMAC_close(). 371 * 372 * @anchor ti_drivers_AESCBCMAC_Synopsis 373 * ## Synopsis 374 * @anchor ti_drivers_AESCBCMAC_Synopsis_Code 375 * @code 376 * // Import AESCMAC Driver definitions 377 * #include <ti/drivers/AESCMAC.h> 378 * 379 * // Define name for AESCMAC channel index 380 * #define AESCMAC_INSTANCE 0 381 * 382 * AESCMAC_init(); 383 * 384 * AESCMAC_Params params; 385 * 386 * AESCMAC_Params_init(¶ms); 387 * params.operationalMode = AESCMAC_OPMODE_CBCMAC; 388 * 389 * handle = AESCMAC_open(AESCMAC_INSTANCE, ¶ms); 390 * 391 * // Initialize symmetric key 392 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 393 * 394 * // Set up AESCMAC_Operation 395 * AESCMAC_Operation_init(&operation); 396 * operation.input = plaintext; 397 * operation.inputLength = sizeof(plaintext); 398 * operation.mac = mac; 399 * operation.macLength = sizeof(mac); 400 * 401 * signResult = AESCMAC_oneStepSign(handle, &operation); 402 * 403 * AESCMAC_close(handle); 404 * @endcode 405 * 406 * @anchor ti_drivers_AESCBCMAC_Examples 407 * ## Examples 408 * 409 * ### One step AES CBC-MAC signature with plaintext CryptoKey in blocking return mode # 410 * @code 411 * 412 * #include <ti/drivers/AESCMAC.h> 413 * #include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h> 414 * 415 * ... 416 * 417 * AESCMAC_Params params; 418 * AESCMAC_Handle handle; 419 * CryptoKey cryptoKey; 420 * int_fast16_t signResult; 421 * 422 * // For example purposes only. 423 * // Test vector derived from RFC 3602 Case #2 424 * uint8_t plaintext[32] = {0x56, 0x2F, 0x15, 0x9A, 0x69, 0x0C, 0x3B, 0x2F, 425 * 0xD5, 0xBA, 0xB0, 0x62, 0x56, 0x23, 0x61, 0x57, 426 * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 427 * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; 428 * uint8_t mac[16]; 429 * uint8_t keyingMaterial[16] = {0xC2, 0x86, 0x69, 0x6D, 0x88, 0x7C, 0x9A, 0xA0, 430 * 0x61, 0x1B, 0xBB, 0x3E, 0x20, 0x25, 0xA4, 0x5A}; 431 * 432 * // The MAC should equal the following after the operation: 433 * // 0x75, 0x86, 0x60, 0x2D, 0x25, 0x3C, 0xFF, 0xF9, 434 * // 0x1B, 0x82, 0x66, 0xBE, 0xA6, 0xD6, 0x1A, 0xB1 435 * 436 * AESCMAC_Params_init(¶ms); 437 * params.operationalMode = AESCMAC_OPMODE_CBCMAC; 438 * 439 * handle = AESCMAC_open(0, ¶ms); 440 * 441 * if (handle == NULL) { 442 * // handle error 443 * } 444 * 445 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 446 * 447 * AESCMAC_Operation operation; 448 * AESCMAC_Operation_init(&operation); // Optional as all struct members will be set before use. 449 * 450 * operation.input = plaintext; 451 * operation.inputLength = sizeof(plaintext); 452 * operation.mac = mac; 453 * operation.macLength = sizeof(mac); 454 * 455 * signResult = AESCMAC_oneStepSign(handle, &operation, &cryptoKey); 456 * 457 * if (signResult == AESCMAC_STATUS_SUCCESS) { 458 * // signature is available in mac[] buffer. 459 * } 460 * else { 461 * // handle error 462 * } 463 * 464 * AESCMAC_close(handle); 465 * 466 * @endcode 467 * 468 * 469 * ### Multi-step AES CBC-MAC verify with plaintext CryptoKey in polling return mode # 470 * @code 471 * 472 * #include <ti/drivers/AESCMAC.h> 473 * #include <ti/drivers/types/cryptoKey/CryptoKey_Plaintext.h> 474 * 475 * #define AES_BLOCK_SIZE 16 // bytes 476 * ... 477 * 478 * AESCMAC_Params params; 479 * AESCMAC_Handle handle; 480 * CryptoKey cryptoKey; 481 * int_fast16_t retVal; 482 * 483 * // For example purposes only. 484 * // Test vector derived from RFC 3602 Case #2 485 * uint8_t plaintext[32] = {0x56, 0x2F, 0x15, 0x9A, 0x69, 0x0C, 0x3B, 0x2F, 486 * 0xD5, 0xBA, 0xB0, 0x62, 0x56, 0x23, 0x61, 0x57, 487 * 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 488 * 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; 489 * uint8_t mac[16] = {0x75, 0x86, 0x60, 0x2D, 0x25, 0x3C, 0xFF, 0xF9, 490 * 0x1B, 0x82, 0x66, 0xBE, 0xA6, 0xD6, 0x1A, 0xB1} 491 * uint8_t keyingMaterial[16] = {0xC2, 0x86, 0x69, 0x6D, 0x88, 0x7C, 0x9A, 0xA0, 492 * 0x61, 0x1B, 0xBB, 0x3E, 0x20, 0x25, 0xA4, 0x5A}; 493 * 494 * AESCMAC_Params_init(¶ms) 495 * params.returnBehavior = AESCMAC_RETURN_BEHAVIOR_POLLING; 496 * params.operationalMode = AESCMAC_OPMODE_CBCMAC; 497 * 498 * handle = AESCMAC_open(0, ¶ms); 499 * 500 * if (handle == NULL) { 501 * // handle error 502 * } 503 * 504 * CryptoKeyPlaintext_initKey(&cryptoKey, keyingMaterial, sizeof(keyingMaterial)); 505 * 506 * AESCMAC_Operation operation; 507 * AESCMAC_Operation_init(&operation); // Optional as all struct members will be set before use. 508 * 509 * retVal = AESCMAC_setupVerify(handle, &cryptoKey); 510 * 511 * if (retVal != AESCMAC_STATUS_SUCCESS) { 512 * // handle error 513 * } 514 * 515 * operation.input = plaintext; 516 * operation.inputLength = AES_BLOCK_SIZE; // Must be a non-zero multiple of the block size (16-bytes) unless 517 * finalizing. 518 * // Note: MAC pointer only needs to be set when finalizing operation. 519 * 520 * retVal = AESCMAC_addData(handle, &operation); 521 * 522 * if (retVal != AESCMAC_STATUS_SUCCESS) { 523 * // handle error 524 * } 525 * 526 * operation.input = plaintext + AES_BLOCK_SIZE; 527 * operation.inputLength = AES_BLOCK_SIZE; 528 * operation.mac = mac; 529 * operation.macLength = sizeof(mac); 530 * 531 * retVal = AESCMAC_finalize(handle, &operation); 532 * 533 * // retVal should be AESCMAC_STATUS_SUCCESS to indicate that the signature 534 * // verification passed. 535 * 536 * if (retVal == AESCMAC_STATUS_MAC_INVALID) { 537 * // handle invalid MAC 538 * } 539 * else if (retVal != AESCMAC_STATUS_SUCCESS) { 540 * // handle error 541 * } 542 * 543 * AESCMAC_close(handle); 544 * 545 * @endcode 546 */ 547 548 #ifndef ti_drivers_AESCMAC__include 549 #define ti_drivers_AESCMAC__include 550 551 #include <stdbool.h> 552 #include <stddef.h> 553 #include <stdint.h> 554 555 #include <ti/drivers/AESCommon.h> 556 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h> 557 558 #ifdef __cplusplus 559 extern "C" { 560 #endif 561 562 /*! 563 * Common CMAC status code reservation offset. 564 * CMAC driver implementations should offset status codes with 565 * #AESCMAC_STATUS_RESERVED growing negatively. 566 * 567 * Example implementation specific status codes: 568 * @code 569 * #define AESCMACXYZ_STATUS_ERROR0 AESCMAC_STATUS_RESERVED - 0 570 * #define AESCMACXYZ_STATUS_ERROR1 AESCMAC_STATUS_RESERVED - 1 571 * #define AESCMACXYZ_STATUS_ERROR2 AESCMAC_STATUS_RESERVED - 2 572 * @endcode 573 */ 574 #define AESCMAC_STATUS_RESERVED AES_STATUS_RESERVED 575 576 /*! 577 * @brief Successful status code. 578 * 579 * Functions return #AESCMAC_STATUS_SUCCESS if the function was executed 580 * successfully. 581 */ 582 #define AESCMAC_STATUS_SUCCESS AES_STATUS_SUCCESS 583 584 /*! 585 * @brief Generic error status code. 586 * 587 * Functions return #AESCMAC_STATUS_ERROR if the function was not executed 588 * successfully and no more pertinent error code could be returned. 589 */ 590 #define AESCMAC_STATUS_ERROR AES_STATUS_ERROR 591 592 /*! 593 * @brief An error status code returned if the hardware or software resource 594 * is currently unavailable. 595 * 596 * CMAC driver implementations may have hardware or software limitations on how 597 * many clients can simultaneously perform operations. This status code is returned 598 * if the mutual exclusion mechanism signals that an operation cannot currently be performed. 599 */ 600 #define AESCMAC_STATUS_RESOURCE_UNAVAILABLE AES_STATUS_RESOURCE_UNAVAILABLE 601 602 /*! 603 * @brief The MAC verification failed. 604 * 605 * Functions return #AESCMAC_STATUS_MAC_INVALID if the MAC computed 606 * for the provided (key, message) pair did not match the MAC provided. 607 */ 608 #define AESCMAC_STATUS_MAC_INVALID AES_STATUS_MAC_INVALID 609 610 /*! 611 * @brief The ongoing operation was canceled. 612 */ 613 #define AESCMAC_STATUS_CANCELED AES_STATUS_CANCELED 614 615 /*! 616 * @brief The operation requested is not supported either by the target hardware 617 * or the driver implementation. 618 */ 619 #define AESCMAC_STATUS_FEATURE_NOT_SUPPORTED AES_STATUS_FEATURE_NOT_SUPPORTED 620 621 /*! 622 * @brief The operation tried to load a key from the keystore using an invalid key ID. 623 */ 624 #define AESCMAC_STATUS_KEYSTORE_INVALID_ID AES_STATUS_KEYSTORE_INVALID_ID 625 626 /*! 627 * @brief The key store module returned a generic error. See key store documentation 628 * for additional details. 629 */ 630 #define AESCMAC_STATUS_KEYSTORE_GENERIC_ERROR AES_STATUS_KEYSTORE_GENERIC_ERROR 631 632 /*! 633 * @brief The operation does not support non-word-aligned input. 634 * 635 * AESCMAC driver implementations may have restrictions on the alignment of 636 * input data due to performance limitations of the hardware. 637 */ 638 #define AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED AES_STATUS_UNALIGNED_IO_NOT_SUPPORTED 639 640 /*! 641 * @brief CMAC Global configuration 642 * 643 * The #AESCMAC_Config structure contains a set of pointers used to characterize 644 * the CMAC driver implementation. 645 * 646 * This structure needs to be defined before calling #AESCMAC_init() and it must 647 * not be changed thereafter. 648 * 649 * @sa #AESCMAC_init() 650 */ 651 typedef AESCommon_Config AESCMAC_Config; 652 653 /*! 654 * @brief A handle that is returned from an #AESCMAC_open() call. 655 */ 656 typedef AESCMAC_Config *AESCMAC_Handle; 657 658 /*! 659 * @brief The return behavior of AESCMAC functions 660 * 661 * Not all AESCMAC operations exhibit the specified return behavior. Functions that do not 662 * require significant computation and cannot offload that computation to a background thread 663 * behave like regular functions. Which functions exhibit the specified return behavior is not 664 * implementation dependent. Specifically, a software-backed implementation run on the same 665 * CPU as the application will emulate the return behavior while not actually offloading 666 * the computation to the background thread. 667 * 668 * AESCMAC functions exhibiting the specified return behavior have restrictions on the 669 * context from which they may be called. 670 * 671 * | | Task | Hwi | Swi | 672 * |---------------------------------|-------|-------|-------| 673 * |AESCMAC_RETURN_BEHAVIOR_CALLBACK | X | X | X | 674 * |AESCMAC_RETURN_BEHAVIOR_BLOCKING | X | | | 675 * |AESCMAC_RETURN_BEHAVIOR_POLLING | X | X | X | 676 * 677 */ 678 typedef enum 679 { 680 AESCMAC_RETURN_BEHAVIOR_CALLBACK = AES_RETURN_BEHAVIOR_CALLBACK, 681 /*!< The function call will return immediately while the 682 * MAC operation goes on in the background. The registered 683 * callback function is called after the operation completes. 684 * The context the callback function is called (task, HWI, SWI) 685 * is implementation-dependent. 686 */ 687 AESCMAC_RETURN_BEHAVIOR_BLOCKING = AES_RETURN_BEHAVIOR_BLOCKING, 688 /*!< The function call will block while the MAC operation goes 689 * on in the background. MAC operation results are available 690 * after the function returns. 691 */ 692 AESCMAC_RETURN_BEHAVIOR_POLLING = AES_RETURN_BEHAVIOR_POLLING, 693 /*!< The function call will continuously poll a flag while MAC 694 * operation goes on in the background. MAC operation results 695 * are available after the function returns. 696 */ 697 } AESCMAC_ReturnBehavior; 698 699 /*! 700 * @brief Defines the operation modes for the AESCMAC driver. 701 * 702 * By default, the driver will use CMAC to sign and verify messages. 703 * To use CBC-MAC instead of CMAC, set the operationalMode in 704 * #AESCMAC_Params accordingly before calling #AESCMAC_open or 705 * #AESCMAC_construct. The operational mode persists throughout 706 * the existance of the driver instance. 707 */ 708 typedef enum 709 { 710 AESCMAC_OPMODE_CMAC = 1, /*!< CMAC operational mode */ 711 AESCMAC_OPMODE_CBCMAC = 2, /*!< CBC-MAC operational mode */ 712 } AESCMAC_OperationalMode; 713 714 /*! 715 * @brief Struct containing the parameters required for signing or verifying a message. 716 */ 717 typedef struct 718 { 719 uint8_t *input; /*!< - Sign: Pointer to the input message to 720 * be authenticated. 721 * - Verify: Pointer to the input message to be 722 * verified. 723 */ 724 uint8_t *mac; /*!< - Sign: Pointer to the output buffer to write 725 * the generated MAC. Buffer size must be 726 * at least equal to @a macLength. 727 * - Verify: Pointer to the input MAC to be 728 * used for verification. 729 */ 730 size_t inputLength; /*!< Length of the input message in bytes. 731 * May be zero for CMAC but must be non-zero for CBC-MAC. 732 * See function descriptions for further restrictions. 733 * Max length supported may be limited depending on the return behavior. 734 */ 735 size_t macLength; /*!< Length of the MAC in bytes. 736 * Must be <= 16. A length of < 8 is not recommended and 737 * should severely restrict MAC recomputation attempts. 738 * See appendix A of NIST SP800-38b for more information. 739 */ 740 } AESCMAC_Operation; 741 742 /*! 743 * @brief Mask for the operation code. 744 */ 745 #define AESCMAC_OP_CODE_MASK 0x0F /* bits 0-3 */ 746 747 /*! 748 * @brief Enum for the operation codes supported by the driver. 749 */ 750 typedef enum 751 { 752 AESCMAC_OP_CODE_ONE_STEP = 0, 753 AESCMAC_OP_CODE_SEGMENTED, 754 AESCMAC_OP_CODE_FINALIZE 755 } AESCMAC_OperationCode; 756 757 /*! 758 * @brief Flag indicating a sign operation. If this bit is not set, then it 759 * is a verify operation. 760 */ 761 #define AESCMAC_OP_FLAG_SIGN 0x10 /* bit 4 */ 762 763 /*! 764 * @brief Mask for all valid operation flags. 765 */ 766 #define AESCMAC_OP_FLAGS_MASK (AESCMAC_OP_FLAG_SIGN | AESCMAC_OP_FLAG_VERIFY) 767 768 /*! 769 * @brief Enum for the operation types supported by the driver. 770 */ 771 typedef enum 772 { 773 AESCMAC_OP_TYPE_SIGN = AESCMAC_OP_CODE_ONE_STEP | AESCMAC_OP_FLAG_SIGN, 774 AESCMAC_OP_TYPE_VERIFY = AESCMAC_OP_CODE_ONE_STEP, 775 AESCMAC_OP_TYPE_SEGMENTED_SIGN = AESCMAC_OP_CODE_SEGMENTED | AESCMAC_OP_FLAG_SIGN, 776 AESCMAC_OP_TYPE_SEGMENTED_VERIFY = AESCMAC_OP_CODE_SEGMENTED, 777 AESCMAC_OP_TYPE_FINALIZE_SIGN = AESCMAC_OP_CODE_FINALIZE | AESCMAC_OP_FLAG_SIGN, 778 AESCMAC_OP_TYPE_FINALIZE_VERIFY = AESCMAC_OP_CODE_FINALIZE 779 } AESCMAC_OperationType; 780 781 /*! 782 * @brief The definition of a callback function used by the AESCMAC driver 783 * when used in ::AESCMAC_RETURN_BEHAVIOR_CALLBACK 784 * 785 * @param handle Handle of the client that started the AESCMAC operation. 786 * 787 * @param returnValue The result of the AESCMAC operation. May contain an error code. 788 * Informs the application of why the callback function was 789 * called. 790 * 791 * @param operation Pointer to an operation struct. 792 * 793 * @param operationType Indicates which operation the callback refers to. 794 */ 795 typedef void (*AESCMAC_CallbackFxn)(AESCMAC_Handle handle, 796 int_fast16_t returnValue, 797 AESCMAC_Operation *operation, 798 AESCMAC_OperationType operationType); 799 800 /*! 801 * @brief AESCMAC Parameters 802 * 803 * CMAC Parameters are used to with the #AESCMAC_open() or #AESCMAC_construct() call. 804 * Default values for these parameters are set using #AESCMAC_Params_init(). 805 * 806 * @sa #AESCMAC_Params_init() 807 */ 808 typedef struct 809 { 810 AESCMAC_ReturnBehavior returnBehavior; /*!< Blocking, callback, or polling return behavior */ 811 AESCMAC_OperationalMode operationalMode; /*!< CMAC or CBC-MAC operational mode */ 812 AESCMAC_CallbackFxn callbackFxn; /*!< Callback function pointer */ 813 uint32_t timeout; /*!< Timeout before the driver returns an error in 814 * ::AESCMAC_RETURN_BEHAVIOR_BLOCKING 815 */ 816 void *custom; /*!< Custom argument used by driver 817 * implementation 818 */ 819 } AESCMAC_Params; 820 821 /*! 822 * @brief Default #AESCMAC_Params structure 823 * 824 * @sa #AESCMAC_Params_init() 825 */ 826 extern const AESCMAC_Params AESCMAC_defaultParams; 827 828 /*! 829 * @brief Initializes the CMAC module. 830 * 831 * @pre The AESCMAC_config structure must exist and be persistent before this 832 * function can be called. This function must also be called before 833 * any other CMAC driver APIs. This function call does not modify any 834 * peripheral registers. 835 */ 836 void AESCMAC_init(void); 837 838 /*! 839 * @brief Initializes the #AESCMAC_Params struct to its defaults 840 * 841 * @param [in] params Pointer to #AESCMAC_Params structure for 842 * initialization 843 * 844 * Defaults values are: 845 * returnBehavior = AESCMAC_RETURN_BEHAVIOR_BLOCKING 846 * operationalMode = AESCMAC_OPMODE_CMAC 847 * callbackFxn = NULL 848 * timeout = SemaphoreP_WAIT_FOREVER 849 * custom = NULL 850 */ 851 void AESCMAC_Params_init(AESCMAC_Params *params); 852 853 /*! 854 * @brief Initializes an #AESCMAC_Operation struct to its defaults 855 * 856 * @param [in] operation Pointer to an #AESCMAC_Operation structure for 857 * initialization 858 * 859 * Defaults values are all zeros. 860 */ 861 void AESCMAC_Operation_init(AESCMAC_Operation *operation); 862 863 /*! 864 * @brief Opens a given AESCMAC peripheral. 865 * 866 * @note #AESCMAC_Params @a operationalMode may be set to enable CBC-MAC 867 * mode but the default is CMAC mode 868 * 869 * @pre AESCMAC driver has been initialized using #AESCMAC_init() 870 * 871 * @param [in] index Logical peripheral number for the CMAC indexed into 872 * the AESCMAC_config table 873 * 874 * @param [in] params Pointer to a parameter block, if NULL it will use 875 * default values 876 * 877 * @return An #AESCMAC_Handle on success or a NULL on an error or if it has 878 * been opened already. 879 * 880 * @sa #AESCMAC_init() 881 * @sa #AESCMAC_close() 882 */ 883 AESCMAC_Handle AESCMAC_open(uint_least8_t index, const AESCMAC_Params *params); 884 885 /*! 886 * @brief Closes a AESCMAC peripheral specified by the CMAC handle 887 * 888 * @pre #AESCMAC_open() or #AESCMAC_construct() 889 * 890 * @param handle AESCMAC handle 891 * 892 * @sa #AESCMAC_open() 893 * @sa #AESCMAC_construct() 894 */ 895 void AESCMAC_close(AESCMAC_Handle handle); 896 897 /*! 898 * @brief Prepares a segmented AESCMAC sign operation 899 * 900 * This function sets up a segmented AESCMAC sign operation. 901 * After a segmented operation is setup, it must be completed 902 * with #AESCMAC_finalize or cancelled with #AESCMAC_cancelOperation 903 * before another operation can be started. 904 * 905 * @pre #AESCMAC_open() or #AESCMAC_construct() 906 * 907 * @param [in] handle AESCMAC handle 908 * 909 * @param [in] key Pointer to a previously initialized CryptoKey. 910 * 911 * @retval #AESCMAC_STATUS_SUCCESS The operation succeeded. Segmented 912 * data may now be added. 913 * @retval #AESCMAC_STATUS_ERROR The operation failed. 914 * 915 * @post #AESCMAC_addData() or #AESCMAC_finalize() 916 * 917 * @sa #AESCMAC_setupVerify() 918 */ 919 int_fast16_t AESCMAC_setupSign(AESCMAC_Handle handle, const CryptoKey *key); 920 921 /*! 922 * @brief Prepares a segmented AESCMAC verify operation 923 * 924 * This function sets up a segmented AESCMAC verify operation. 925 * After a segmented operation is setup, it must be completed 926 * with #AESCMAC_finalize or cancelled with #AESCMAC_cancelOperation 927 * before another operation can be started. 928 * 929 * @pre #AESCMAC_open() or #AESCMAC_construct() 930 * 931 * @param [in] handle AESCMAC handle 932 * 933 * @param [in] key Pointer to a previously initialized CryptoKey. 934 * 935 * @retval #AESCMAC_STATUS_SUCCESS The operation succeeded. Segmented 936 * data may now be added. 937 * @retval #AESCMAC_STATUS_ERROR The operation failed. 938 * 939 * @post #AESCMAC_addData() or #AESCMAC_finalize() 940 * 941 * @sa #AESCMAC_setupSign() 942 */ 943 int_fast16_t AESCMAC_setupVerify(AESCMAC_Handle handle, const CryptoKey *key); 944 945 /*! 946 * @brief Adds data to the current segmented operation 947 * 948 * The @a inputLength must be a non-zero multiple of the block size (16-bytes). 949 * #AESCMAC_addData() may be called an arbitrary number of times before 950 * finishing the operation with #AESCMAC_finalize(). 951 * 952 * This function blocks until the final MAC been computed. 953 * It returns immediately when ::AESCMAC_RETURN_BEHAVIOR_CALLBACK is set. 954 * 955 * @note None of the buffers provided as arguments may be altered by the application 956 * during an ongoing operation. Doing so can yield corrupted plaintext. 957 * 958 * @pre #AESCMAC_setupSign() or #AESCMAC_setupVerify() 959 * 960 * @param [in] handle AESCMAC handle 961 * 962 * @param [in] operation Pointer to CMAC operation structure() 963 * 964 * @retval #AESCMAC_STATUS_SUCCESS The operation succeeded. 965 * @retval #AESCMAC_STATUS_ERROR The operation failed. 966 * @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE The required hardware 967 * resource was not available. 968 * Try again later. 969 * @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input buffer was not word-aligned. 970 * 971 * @post #AESCMAC_addData() or #AESCMAC_finalize() 972 */ 973 int_fast16_t AESCMAC_addData(AESCMAC_Handle handle, AESCMAC_Operation *operation); 974 975 /*! 976 * @brief Finalizes the current segmented operation 977 * 978 * For sign operations: 979 * This function computes and writes back the final MAC @a mac of length 980 * @a macLength. 981 * 982 * For verify operations: 983 * This function uses the provided MAC @a mac to authenticate an input message. 984 * The return value indicates whether the authentication was successful. 985 * 986 * @note Finalizing without additional input data is not supported. 987 * If finalization is attempted with @a inputLength of zero, 988 * #AESCMAC_STATUS_ERROR will be returned and the caller must either 989 * retry finalization with data or terminate the segmented operation 990 * by calling #AESCMAC_cancelOperation. 991 * 992 * @note None of the buffers provided as arguments may be altered by the application 993 * during an ongoing operation. Doing so can yield corrupted plaintext. 994 * 995 * @pre #AESCMAC_addData() or #AESCMAC_setupSign() or #AESCMAC_setupVerify() 996 * 997 * @param [in] handle AESCMAC handle 998 * 999 * @param [in] operation Pointer to CMAC operation structure() 1000 * 1001 * @retval #AESCMAC_STATUS_SUCCESS In ::AESCMAC_RETURN_BEHAVIOR_BLOCKING and 1002 * ::AESCMAC_RETURN_BEHAVIOR_POLLING, this means the MAC 1003 * was generated successfully. In ::AESCMAC_RETURN_BEHAVIOR_CALLBACK, 1004 * this means the operation started successfully. 1005 * @retval #AESCMAC_STATUS_ERROR The operation failed. 1006 * @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE The required hardware 1007 * resource was not available. 1008 * Try again later. 1009 * @retval #AESCMAC_STATUS_MAC_INVALID The provided MAC did not match the generated MAC. 1010 * This return value is only valid for verify operations. 1011 * @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input buffer was not word-aligned. 1012 */ 1013 int_fast16_t AESCMAC_finalize(AESCMAC_Handle handle, AESCMAC_Operation *operation); 1014 1015 /*! 1016 * @brief Performs a AESCMAC signature in one call 1017 * 1018 * This function uses the provided key to authenticate an input message. 1019 * The resulting output is a message authentication code. 1020 * 1021 * @note None of the buffers provided as arguments may be altered by the application 1022 * during an ongoing operation. Doing so can yield corrupted plaintext. 1023 * 1024 * @pre #AESCMAC_open() or #AESCMAC_construct() 1025 * 1026 * @param [in] handle AESCMAC handle 1027 * 1028 * @param [in] operation Pointer to AESCMAC operation structure 1029 * 1030 * @param [in] key Pointer to a previously initialized CryptoKey 1031 * 1032 * @retval #AESCMAC_STATUS_SUCCESS In ::AESCMAC_RETURN_BEHAVIOR_BLOCKING and 1033 * ::AESCMAC_RETURN_BEHAVIOR_POLLING, this means the MAC 1034 * was generated successfully. In ::AESCMAC_RETURN_BEHAVIOR_CALLBACK, 1035 * this means the operation started successfully. 1036 * @retval #AESCMAC_STATUS_ERROR The operation failed. 1037 * @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE The required hardware 1038 * resource was not available. 1039 * Try again later. 1040 * @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input buffer was not word-aligned. 1041 * 1042 * @sa #AESCMAC_oneStepVerify() 1043 */ 1044 int_fast16_t AESCMAC_oneStepSign(AESCMAC_Handle handle, AESCMAC_Operation *operation, CryptoKey *key); 1045 1046 /*! 1047 * @brief Performs a AESCMAC verification in one call 1048 * 1049 * This function verifies that the provided message authentication code 1050 * matches the one generated by the provided key and input message. 1051 * 1052 * @note None of the buffers provided as arguments may be altered by the application 1053 * during an ongoing operation. Doing so can yield corrupted plaintext. 1054 * 1055 * @pre #AESCMAC_open() or #AESCMAC_construct() 1056 * 1057 * @param [in] handle AESCMAC handle 1058 * 1059 * @param [in] operation Pointer to AESCMAC operation structure 1060 * 1061 * @param [in] key Pointer to a previously initialized CryptoKey 1062 * 1063 * @retval #AESCMAC_STATUS_SUCCESS In ::AESCMAC_RETURN_BEHAVIOR_BLOCKING and 1064 * ::AESCMAC_RETURN_BEHAVIOR_POLLING, this means the MAC 1065 * was verified successfully. In ::AESCMAC_RETURN_BEHAVIOR_CALLBACK, 1066 * this means the operation started successfully. 1067 * @retval #AESCMAC_STATUS_ERROR The operation failed. 1068 * @retval #AESCMAC_STATUS_RESOURCE_UNAVAILABLE The required hardware 1069 * resource was not available. 1070 * Try again later. 1071 * @retval #AESCMAC_STATUS_MAC_INVALID The provided MAC did not match the generated MAC. 1072 * This return value is only valid for verify operations. 1073 * @retval #AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED The input buffer was not word-aligned. 1074 * 1075 * @sa AESCMAC_oneStepSign() 1076 */ 1077 int_fast16_t AESCMAC_oneStepVerify(AESCMAC_Handle handle, AESCMAC_Operation *operation, CryptoKey *key); 1078 1079 /*! 1080 * @brief Cancels an ongoing AESCMAC operation. 1081 * 1082 * Asynchronously cancels an AESCMAC operation. Only available when using 1083 * AESCMAC_RETURN_BEHAVIOR_CALLBACK. 1084 * The operation will terminate as though an error occurred. The 1085 * return status code of the operation will be AESCMAC_STATUS_CANCELED. 1086 * 1087 * @note Only the same thread that started an operation is permitted to cancel it. 1088 * This function cannot be be called from an interrupt context or callback. 1089 * 1090 * @param [in] handle Handle of the operation to cancel 1091 * 1092 * @retval #AESCMAC_STATUS_SUCCESS The operation was canceled or the operation had already completed. 1093 */ 1094 int_fast16_t AESCMAC_cancelOperation(AESCMAC_Handle handle); 1095 1096 /** 1097 * @brief Constructs a new AESCMAC object 1098 * 1099 * Unlike #AESCMAC_open(), #AESCMAC_construct() does not require the hwAttrs and 1100 * object to be allocated in a #AESCMAC_Config array that is indexed into. 1101 * Instead, the #AESCMAC_Config, hwAttrs, and object can be allocated at any 1102 * location. This allows for relatively simple run-time allocation of temporary 1103 * driver instances on the stack or the heap. 1104 * The drawback is that this makes it more difficult to write device-agnostic 1105 * code. If you use an ifdef with DeviceFamily, you can choose the correct 1106 * object and hwAttrs to allocate. That compilation unit will be tied to the 1107 * device it was compiled for at this point. To change devices, recompilation 1108 * of the application with a different DeviceFamily setting is necessary. 1109 * 1110 * @note #AESCMAC_Params @a operationalMode may be set to 1111 * enable CBC-MAC mode but the default is CMAC mode 1112 * 1113 * @pre The object struct @c config points to must be zeroed out prior to 1114 * calling this function. Otherwise, unexpected behavior may ensue. 1115 * 1116 * @param [in] config #AESCMAC_Config describing the location of the object and hwAttrs. 1117 * 1118 * @param [in] params #AESCMAC_Params to configure the driver instance. 1119 * 1120 * @return Returns a #AESCMAC_Handle on success or NULL on failure. 1121 */ 1122 AESCMAC_Handle AESCMAC_construct(AESCMAC_Config *config, const AESCMAC_Params *params); 1123 1124 #ifdef __cplusplus 1125 } 1126 #endif 1127 1128 #endif /* ti_drivers_AESCMAC__include */ 1129