1 /*
2 * Copyright (c) 2021-2024, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <string.h>
36
37 #include <ti/drivers/aescmac/AESCMACLPF3.h>
38
39 #include <ti/drivers/AESCMAC.h>
40 #include <ti/drivers/AESCommon.h>
41 #include <ti/drivers/aesecb/AESECBLPF3.h>
42 #include <ti/drivers/cryptoutils/aes/AESCommonLPF3.h>
43 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
44 #include <ti/drivers/cryptoutils/sharedresources/CryptoResourceLPF3.h>
45 #include <ti/drivers/cryptoutils/utils/CryptoUtils.h>
46 #include <ti/drivers/dma/UDMALPF3.h>
47
48 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
49 #include <ti/drivers/cryptoutils/hsm/HSMLPF3.h>
50 #include <third_party/hsmddk/include/Kit/EIP130/TokenHelper/incl/eip130_asset_policy.h>
51 #include <third_party/hsmddk/include/Kit/EIP130/TokenHelper/incl/eip130_token_result.h>
52 #endif
53
54 #include <ti/drivers/dpl/DebugP.h>
55 #include <ti/drivers/dpl/HwiP.h>
56 #include <ti/drivers/dpl/SemaphoreP.h>
57
58 #include <ti/devices/DeviceFamily.h>
59 #include DeviceFamily_constructPath(driverlib/aes.h)
60 #include DeviceFamily_constructPath(inc/hw_aes.h)
61 #include DeviceFamily_constructPath(inc/hw_ints.h)
62
63 /**
64 * The threshold at which blocking and callback mode transfers will utilize DMA.
65 * For data lengths below this threshold, polling CPU R/W will be used instead
66 * of DMA. With task switching and interrupt overhead, it is inefficient to
67 * utilize DMA for shorter length operations.
68 * The threshold value must be a multiple of AES_BLOCK_SIZE.
69 */
70 #define AESCMACLPF3_DMA_SIZE_THRESHOLD (1U * AES_BLOCK_SIZE)
71
72 #define AESCMAC_CONST_RB ((uint8_t)0x87U)
73 #define AESCMAC_MSB_CHECK ((uint8_t)0x80U)
74 #define AESCMAC_PADDING ((uint8_t)0x80U)
75
76 typedef enum
77 {
78 AESCMAC_SUBKEY1,
79 AESCMAC_SUBKEY2
80 } AESCMAC_SUBKEY_NUM;
81
82 /* Forward declarations */
83 static void AESCMACLPF3_deriveSubKey(uint8_t *buffer);
84 static void AESCMACLPF3_generateSubKey(AESCMAC_SUBKEY_NUM subKeyNum, uint32_t subKey[AES_BLOCK_SIZE_WORDS]);
85 static void AESCMACLPF3_getResult(AESCMACLPF3_Object *object);
86 static inline void AESCMACLPF3_prepareFinalInputBlock(AESCMACLPF3_Object *object, size_t *transactionLength);
87 static int_fast16_t AESCMACLPF3_setupSegmentedOperation(AESCMACLPF3_Object *object, const CryptoKey *key);
88 static int_fast16_t AESCMACLPF3_oneStepOperation(AESCMAC_Handle handle,
89 AESCMAC_Operation *operation,
90 const CryptoKey *key,
91 AESCMAC_OperationType operationType);
92 static int_fast16_t AESCMACLPF3_startOperation(AESCMAC_Handle handle);
93 static inline int_fast16_t AESCMACLPF3_waitForResult(AESCMAC_Handle handle);
94 static inline void AESCMACLPF3_xorBlock(uint32_t *block1_dst, const uint32_t *block2);
95
96 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
97 static int_fast16_t AESCMACLPF3HSM_oneStepOperation(AESCMAC_Handle handle,
98 AESCMAC_Operation *operation,
99 const CryptoKey *key,
100 AESCMAC_OperationType operationType);
101 static int_fast16_t AESCMACLPF3HSM_SegmentedOperation(AESCMAC_Handle handle, AESCMAC_Operation *operation);
102
103 static int_fast16_t AESCMACLPF3HSM_finalize(AESCMAC_Handle handle, AESCMAC_Operation *operation);
104
105 static int_fast16_t AESCMACLPF3HSM_processOneStepAndFinalizeOperation(AESCMAC_Handle handle);
106 static int_fast16_t AESCMACLPF3HSM_processSegmentedOperation(AESCMAC_Handle handle);
107
108 static int_fast16_t AESCMACLPF3HSM_createAndLoadKeyAssetID(AESCMAC_Handle handle);
109 static int_fast16_t AESCMACLPF3HSM_CreateTempAssetID(AESCMAC_Handle handle);
110 static int_fast16_t AESCMACLPF3HSM_freeAssets(AESCMAC_Handle handle);
111 static int_fast16_t AESCMACLPF3HSM_freeAssetID(AESCMAC_Handle handle, uint32_t AssetID);
112 #endif
113
114 /*
115 * ======== AESCMACLPF3_getObject ========
116 */
AESCMACLPF3_getObject(AESCMAC_Handle handle)117 static inline AESCMACLPF3_Object *AESCMACLPF3_getObject(AESCMAC_Handle handle)
118 {
119 AESCMACLPF3_Object *object = (AESCMACLPF3_Object *)handle->object;
120 DebugP_assert(object);
121
122 return object;
123 }
124
125 /*
126 * ======== AESCMACLPF3_hwiFxn ========
127 */
AESCMACLPF3_hwiFxn(uintptr_t arg0)128 static void AESCMACLPF3_hwiFxn(uintptr_t arg0)
129 {
130 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
131 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
132
133 /*
134 * Only the input channel A interrupt is enabled.
135 */
136 uint32_t intStatus = AESGetMaskedInterruptStatus();
137
138 /* Disable DMA, clear interupts, and release power constraint */
139 AESCommonLPF3_cleanupHwi(&object->common);
140
141 if ((intStatus & (uint32_t)AES_MIS_CHADONE_M) != (uint32_t)0U)
142 {
143 UDMALPF3_clearInterrupt(AESCommonLPF3_DMA_CHA_BITMASK);
144
145 AESCMACLPF3_getResult(object);
146
147 /* Clear operation in-progress if one-step or finalize operation */
148 if (object->operationType != AESCMAC_OP_TYPE_SEGMENTED_SIGN &&
149 object->operationType != AESCMAC_OP_TYPE_SEGMENTED_VERIFY)
150 {
151 AESCommonLPF3_clearOperationInProgress(&object->common);
152 }
153
154 /* Cleanup and release crypto resource lock */
155 AESCommonLPF3_cleanup(&object->common);
156
157 if (object->common.returnBehavior == AES_RETURN_BEHAVIOR_BLOCKING)
158 {
159 /* Unblock the pending task to signal that the operation is complete */
160 SemaphoreP_post(&CryptoResourceLPF3_operationSemaphore);
161 }
162 else
163 {
164 /* Call the callback function provided by the application */
165 object->callbackFxn((AESCMAC_Handle)handle,
166 object->common.returnStatus,
167 object->operation,
168 object->operationType);
169 }
170 }
171 }
172
173 /*
174 * ======== AESCMAC_init ========
175 */
AESCMAC_init(void)176 void AESCMAC_init(void)
177 {
178 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
179 HSMLPF3_constructRTOSObjects();
180 #endif
181 AESCommonLPF3_init();
182 }
183
184 /*
185 * ======== AESCMAC_construct ========
186 */
AESCMAC_construct(AESCMAC_Config * config,const AESCMAC_Params * params)187 AESCMAC_Handle AESCMAC_construct(AESCMAC_Config *config, const AESCMAC_Params *params)
188 {
189 DebugP_assert(config);
190
191 int_fast16_t status;
192 AESCMAC_Handle handle = config;
193 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
194
195 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
196 /* Initialize and boot HSM */
197 if (HSMLPF3_init() != HSMLPF3_STATUS_SUCCESS)
198 {
199 /* Upon HSM Boot failure, the AES-CCM Driver stores the failure status in the object
200 * This is done so that users of the AES-CCM Driver do not get a NULL handle and still can use
201 * the driver in LAES mode.
202 */
203 object->hsmStatus = HSMLPF3_STATUS_ERROR;
204 }
205 else
206 {
207 object->hsmStatus = HSMLPF3_STATUS_SUCCESS;
208 }
209
210 object->segmentedOperationInProgress = false;
211 #endif
212
213 /* If params are NULL, use defaults */
214 if (params == NULL)
215 {
216 params = &AESCMAC_defaultParams;
217 }
218
219 DebugP_assert((params->returnBehavior != AES_RETURN_BEHAVIOR_CALLBACK) || (params->callbackFxn != NULL));
220
221 object->operationalMode = params->operationalMode;
222 object->callbackFxn = params->callbackFxn;
223 object->threadSafe = true;
224
225 status = AESCommonLPF3_construct(&object->common, (AES_ReturnBehavior)params->returnBehavior, params->timeout);
226
227 if (status != AES_STATUS_SUCCESS)
228 {
229 handle = NULL;
230 }
231
232 return handle;
233 }
234
235 /*
236 * ======== AESCMACLPF3_readTag ========
237 */
AESCMACLPF3_readTag(uint32_t tagOut[AES_TAG_LENGTH_BYTES/4U])238 void AESCMACLPF3_readTag(uint32_t tagOut[AES_TAG_LENGTH_BYTES / 4U])
239 {
240 /* Wait until the operation is done */
241 while (AESGetStatus() != (uint32_t)AES_STA_STATE_IDLE) {}
242
243 AESReadTag32(&tagOut[0]);
244 }
245
246 /*
247 * ======== AESCMACLPF3_getResult ========
248 */
AESCMACLPF3_getResult(AESCMACLPF3_Object * object)249 static void AESCMACLPF3_getResult(AESCMACLPF3_Object *object)
250 {
251 AESCMAC_Operation *operation = object->operation;
252 uint8_t opcode = (object->operationType & AESCMAC_OP_CODE_MASK);
253
254 if (object->common.returnStatus == AESCMAC_STATUS_SUCCESS)
255 {
256 if (object->common.key.encoding == CryptoKey_PLAINTEXT || object->common.key.encoding == CryptoKey_KEYSTORE)
257 {
258 /* If One-step or Finalize operation, process the final input block */
259 if (opcode != AESCMAC_OP_CODE_SEGMENTED)
260 {
261 AESWriteBUF32(&object->finalInputBlock[0]);
262 }
263
264 AESCMACLPF3_readTag((uint32_t *)&object->intermediateTag[0]);
265 }
266 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
267 else if (object->common.key.encoding == CryptoKey_PLAINTEXT_HSM)
268 {
269 /* Do nothing as HSM does not rely on AES engine */
270 }
271 #endif
272
273 /* If One-step or Finalize operation, verify or copy the MAC */
274 if (opcode != AESCMAC_OP_CODE_SEGMENTED)
275 {
276 if (object->operationType & AESCMAC_OP_FLAG_SIGN)
277 {
278 (void)memcpy((void *)operation->mac, (void *)&object->intermediateTag[0], operation->macLength);
279 }
280 else
281 {
282 /* Constant time comparison of output tag versus provided MAC */
283 if (!CryptoUtils_buffersMatch(&object->intermediateTag[0], operation->mac, operation->macLength))
284 {
285 object->common.returnStatus = AESCMAC_STATUS_MAC_INVALID;
286 }
287 }
288 }
289 }
290 }
291
292 /*
293 * ======== AESCMACLPF3_startOperation ========
294 */
AESCMACLPF3_startOperation(AESCMAC_Handle handle)295 static int_fast16_t AESCMACLPF3_startOperation(AESCMAC_Handle handle)
296 {
297 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
298 AESCMAC_Operation *operation = object->operation;
299
300 /* Input pointer cannot be NULL if input length is non-zero */
301 DebugP_assert((operation->inputLength == 0U) || operation->input);
302
303 uint8_t opcode = (object->operationType & AESCMAC_OP_CODE_MASK);
304
305 /*
306 * MAC pointer cannot be NULL if performing a one-step operation or
307 * finalizing a segmented operation
308 */
309 DebugP_assert((opcode == AESCMAC_OP_CODE_SEGMENTED) || (operation->mac));
310
311 AESCMAC_OperationType operationType;
312 int_fast16_t status = AESCMAC_STATUS_ERROR;
313 size_t transactionLength = operation->inputLength;
314
315 /* Load key */
316 AESCommonLPF3_loadKey(&object->common.key);
317
318 /*
319 * If One-step or Finalization operation, prepare the final
320 * input block and adjust the transaction length accordingly.
321 */
322 if (opcode != AESCMAC_OP_CODE_SEGMENTED)
323 {
324 AESCMACLPF3_prepareFinalInputBlock(object, &transactionLength);
325 }
326
327 AESSetAUTOCFG(AESCMACLPF3_DEFAULT_AUTOCFG);
328
329 /*
330 * Set IV to intermediate tag (initialized to zero at the start
331 * of a new operation).
332 */
333 AESWriteIV32((uint32_t *)&object->intermediateTag[0]);
334
335 if (transactionLength == 0U)
336 {
337 /*
338 * If transaction length is zero, only the final input block
339 * of data remains to be processed for CMAC. Call AESCMAC_getResult()
340 * to process the last block, obtain the result, and store status of
341 * the operation in object->returnStatus.
342 */
343 AESCMACLPF3_getResult(object);
344
345 /*
346 * Save the object's data to provide to callback in case it
347 * is overwritten during by the start of a new operation
348 * after the operationInProgress flag is cleared or access
349 * semaphore is posted.
350 */
351 status = object->common.returnStatus;
352 operationType = object->operationType;
353
354 AESCommonLPF3_clearOperationInProgress(&object->common);
355
356 /*
357 * Handle clean up of the operation and post access semaphore to allow
358 * callback to chain operations.
359 */
360 AESCommonLPF3_cleanup(&(object->common));
361
362 if (object->common.returnBehavior == AES_RETURN_BEHAVIOR_CALLBACK)
363 {
364 /* Call the callback function provided by the application */
365 object->callbackFxn(handle, status, operation, operationType);
366
367 /* Always return success in callback mode */
368 status = AESCMAC_STATUS_SUCCESS;
369 }
370 }
371 else
372 {
373 if ((object->common.returnBehavior == AES_RETURN_BEHAVIOR_POLLING) ||
374 (transactionLength < AESCMACLPF3_DMA_SIZE_THRESHOLD))
375 {
376 /*
377 * Process all data. Transaction length is updated in
378 * AESCMACLPF3_prepareFinalInputBlock() to be the truncated
379 * message length (which excludes the final block).
380 */
381 AESCMACLPF3_processBlocks(operation->input, transactionLength);
382 }
383 else
384 {
385 /*
386 * We need to set the HWI function and priority since the same physical
387 * interrupt is shared by multiple drivers and they all need to coexist.
388 * Whenever a driver starts an operation, it registers its HWI callback
389 * with the OS.
390 */
391 AESCMACLPF3_HWAttrs const *hwAttrs = handle->hwAttrs;
392 AESCommonLPF3_setupHwi(AESCMACLPF3_hwiFxn, (uintptr_t)handle, hwAttrs->intPriority);
393
394 /* Clear BUSHALT when using DMA */
395 AESClearAUTOCFGBusHalt();
396
397 /* Setup DMA configuration and set power constraint */
398 AESCommonLPF3_setupDMA(&object->common, AESCMACLPF3_DMA_CONFIG);
399
400 AESCommonLPF3_configInputDMA(operation->input, transactionLength);
401
402 /* Enable interrupt upon input DMA done */
403 AESSetIMASK((uint32_t)AES_IMASK_CHADONE_M);
404
405 /* Manually trigger the DMA to start the ECB operation */
406 AESSetTrigger((uint32_t)AES_TRG_DMACHA);
407 }
408
409 status = AESCMACLPF3_waitForResult(handle);
410 }
411
412 return status;
413 }
414
415 /*
416 * ======== AESCMACLPF3_processBlocks ========
417 */
AESCMACLPF3_processBlocks(const uint8_t * input,size_t transactionLength)418 void AESCMACLPF3_processBlocks(const uint8_t *input, size_t transactionLength)
419 {
420 #if (AESCommonLPF3_UNALIGNED_IO_SUPPORT_ENABLE == 0)
421 AESProcessAlignedBlocksCMAC((const uint32_t *)input, (uint32_t)AES_GET_NUM_BLOCKS(transactionLength));
422 #else
423 size_t bytesProcessed = 0;
424 size_t transactionLengthDoubleBlocks = transactionLength & AES_DOUBLE_BLOCK_SIZE_MULTIPLE_MASK;
425 size_t transactionLengthSingleBlocks = transactionLength & (size_t)~AES_DOUBLE_BLOCK_SIZE_MULTIPLE_MASK;
426
427 /*
428 * The code below has additional optimizations for word-aligned input data
429 * to support lower latency AES-CCM operations for BLE stack.
430 */
431 if (IS_WORD_ALIGNED(input))
432 {
433 AESProcessAlignedBlocksCMAC((const uint32_t *)input, (uint32_t)AES_GET_NUM_BLOCKS(transactionLength));
434 }
435 else
436 {
437 while (bytesProcessed < transactionLengthDoubleBlocks)
438 {
439 AESWriteBUF(&input[bytesProcessed]);
440 bytesProcessed += AES_BLOCK_SIZE;
441
442 AESWriteBUF(&input[bytesProcessed]);
443 bytesProcessed += AES_BLOCK_SIZE;
444 }
445
446 /* Process any remaining single block */
447 if (transactionLengthSingleBlocks != 0U)
448 {
449 AESWriteBUF(&input[bytesProcessed]);
450 }
451 }
452 #endif
453 }
454
455 /*
456 * ======== AESCMACLPF3_xorBlock ========
457 * XOR's two 16-byte blocks, storing the result in block1_dst.
458 */
AESCMACLPF3_xorBlock(uint32_t * block1_dst,const uint32_t * block2)459 static inline void AESCMACLPF3_xorBlock(uint32_t *block1_dst, const uint32_t *block2)
460 {
461 uint_fast8_t i;
462
463 for (i = (uint_fast8_t)0U; i < (uint_fast8_t)AES_BLOCK_SIZE_WORDS; i++)
464 {
465 block1_dst[i] = block1_dst[i] ^ block2[i];
466 }
467 }
468
469 /*
470 * ======== AESCMACLPF3_prepareFinalInputBlock ========
471 */
AESCMACLPF3_prepareFinalInputBlock(AESCMACLPF3_Object * object,size_t * transactionLength)472 static inline void AESCMACLPF3_prepareFinalInputBlock(AESCMACLPF3_Object *object, size_t *transactionLength)
473 {
474 AESCMAC_Operation *operation = object->operation;
475 size_t finalInputLength = 0U;
476 size_t truncatedInputLength = 0U;
477 uint32_t subKey[AES_BLOCK_SIZE_WORDS];
478
479 /* Copy last partial or full block of input into local buffer */
480 CryptoUtils_memset((void *)&object->finalInputBlock[0],
481 sizeof(object->finalInputBlock),
482 (uint8_t)0U,
483 sizeof(object->finalInputBlock));
484
485 if (operation->inputLength != 0U)
486 {
487 finalInputLength = AES_NON_BLOCK_SIZE_MULTIPLE_LENGTH(operation->inputLength);
488
489 if (finalInputLength == 0U)
490 {
491 finalInputLength = AES_BLOCK_SIZE;
492 }
493
494 truncatedInputLength = operation->inputLength - finalInputLength;
495
496 (void)memcpy(object->finalInputBlock, &operation->input[truncatedInputLength], finalInputLength);
497 }
498
499 /* CMAC requires the final block to be XOR'd with a subkey */
500 if (object->operationalMode == AESCMAC_OPMODE_CMAC)
501 {
502 /* Check if input message length is a positive block multiple */
503 if ((operation->inputLength != 0U) && (finalInputLength == AES_BLOCK_SIZE))
504 {
505 /* Generate subkey1 */
506 AESCMACLPF3_generateSubKey(AESCMAC_SUBKEY1, subKey);
507 }
508 else
509 {
510 /* Generate subkey2 */
511 AESCMACLPF3_generateSubKey(AESCMAC_SUBKEY2, subKey);
512
513 /* Set padding byte if partial block */
514 ((uint8_t *)&object->finalInputBlock[0])[finalInputLength] = AESCMAC_PADDING;
515 }
516
517 /* XOR final block with subkey */
518 AESCMACLPF3_xorBlock(object->finalInputBlock, subKey);
519 }
520
521 *transactionLength = truncatedInputLength;
522 }
523
524 /*
525 * ======== AESCMACLPF3_oneStepOperation ========
526 */
AESCMACLPF3_oneStepOperation(AESCMAC_Handle handle,AESCMAC_Operation * operation,const CryptoKey * key,AESCMAC_OperationType operationType)527 static int_fast16_t AESCMACLPF3_oneStepOperation(AESCMAC_Handle handle,
528 AESCMAC_Operation *operation,
529 const CryptoKey *key,
530 AESCMAC_OperationType operationType)
531 {
532 DebugP_assert(handle);
533 DebugP_assert(operation);
534 DebugP_assert(key);
535 /* No need to assert operationType since we control it within the driver */
536
537 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
538
539 /* CBC-MAC is not permitted for zero length messages */
540 if ((object->operationalMode == AESCMAC_OPMODE_CBCMAC) && (operation->inputLength == 0U))
541 {
542 return AESCMAC_STATUS_ERROR;
543 }
544
545 #if (AESCommonLPF3_UNALIGNED_IO_SUPPORT_ENABLE == 0)
546 /* Check word-alignment of input pointer */
547 if (!IS_WORD_ALIGNED(operation->input))
548 {
549 return AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED;
550 }
551 #endif
552
553 if (operation->macLength > sizeof(object->intermediateTag))
554 {
555 return AESCMAC_STATUS_ERROR;
556 }
557
558 /*
559 * Check that there is no operation already in progress for this driver
560 * instance.
561 */
562 int_fast16_t status = AESCommonLPF3_setOperationInProgress(&object->common);
563
564 if (status != AESCMAC_STATUS_SUCCESS)
565 {
566 return status;
567 }
568
569 if (object->threadSafe)
570 {
571 if (!CryptoResourceLPF3_acquireLock(object->common.semaphoreTimeout))
572 {
573 AESCommonLPF3_clearOperationInProgress(&object->common);
574 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
575 }
576
577 object->common.cryptoResourceLocked = true;
578 }
579
580 object->operation = operation;
581 object->operationType = operationType;
582 /* We will only change the returnStatus if there is an error or cancellation */
583 object->common.returnStatus = AESCMAC_STATUS_SUCCESS;
584 /* Make internal copy of crypto key */
585 object->common.key = *key;
586
587 /* Zero the intermediate tag because it will be used as the IV */
588 CryptoUtils_memset((void *)&object->intermediateTag[0],
589 sizeof(object->intermediateTag),
590 (uint8_t)0U,
591 sizeof(object->intermediateTag));
592
593 if (object->common.key.encoding == CryptoKey_PLAINTEXT || object->common.key.encoding == CryptoKey_KEYSTORE)
594 {
595 status = AESCMACLPF3_startOperation(handle);
596 }
597 else
598 {
599 status = AESCMAC_STATUS_ERROR;
600 }
601
602 if ((status != AESCMAC_STATUS_SUCCESS) && (object->common.cryptoResourceLocked))
603 {
604 CryptoResourceLPF3_releaseLock();
605 object->common.cryptoResourceLocked = false;
606 AESCommonLPF3_clearOperationInProgress(&object->common);
607 }
608
609 return status;
610 }
611
612 /*
613 * ======== AESCMACLPF3_waitForResult ========
614 */
AESCMACLPF3_waitForResult(AESCMAC_Handle handle)615 static inline int_fast16_t AESCMACLPF3_waitForResult(AESCMAC_Handle handle)
616 {
617 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
618 int_fast16_t status = AESCMAC_STATUS_ERROR;
619 uint8_t opcode = (object->operationType & AESCMAC_OP_CODE_MASK);
620
621 if ((object->common.returnBehavior == AES_RETURN_BEHAVIOR_POLLING) ||
622 (object->operation->inputLength < AESCMACLPF3_DMA_SIZE_THRESHOLD))
623 {
624 AESCMACLPF3_getResult(object);
625
626 /*
627 * Save the object's returnStatus before clearing operationInProgress or
628 * posting the access semaphore in case it is overwritten.
629 */
630 status = object->common.returnStatus;
631
632 /* Mark operation as no longer in progress if one-step or final operation */
633 if (opcode != AESCMAC_OP_CODE_SEGMENTED)
634 {
635 AESCommonLPF3_clearOperationInProgress(&object->common);
636 }
637
638 AESCommonLPF3_cleanup(&(object->common));
639
640 if (object->common.returnBehavior == AES_RETURN_BEHAVIOR_CALLBACK)
641 {
642 object->callbackFxn(handle, status, object->operation, object->operationType);
643
644 /* Always return success in callback mode */
645 status = AESCMAC_STATUS_SUCCESS;
646 }
647 }
648 else if (object->common.returnBehavior == AES_RETURN_BEHAVIOR_BLOCKING)
649 {
650 (void)SemaphoreP_pend((SemaphoreP_Handle)&CryptoResourceLPF3_operationSemaphore,
651 (uint32_t)SemaphoreP_WAIT_FOREVER);
652
653 status = object->common.returnStatus;
654 }
655 else /* AES_RETURN_BEHAVIOR_CALLBACK */
656 {
657 /* AESCMAC_STATUS_SUCCESS is always returned in callback mode */
658 status = AESCMAC_STATUS_SUCCESS;
659 }
660
661 return status;
662 }
663
664 /*
665 * ======== AESCMAC_oneStepSign ========
666 */
AESCMAC_oneStepSign(AESCMAC_Handle handle,AESCMAC_Operation * operation,CryptoKey * key)667 int_fast16_t AESCMAC_oneStepSign(AESCMAC_Handle handle, AESCMAC_Operation *operation, CryptoKey *key)
668 {
669 int_fast16_t status;
670
671 if (key->encoding == CryptoKey_PLAINTEXT || key->encoding == CryptoKey_KEYSTORE)
672 {
673 status = AESCMACLPF3_oneStepOperation(handle, operation, key, AESCMAC_OP_TYPE_SIGN);
674 }
675 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
676 else if (key->encoding == CryptoKey_PLAINTEXT_HSM)
677 {
678 status = AESCMACLPF3HSM_oneStepOperation(handle, operation, key, AESCMAC_OP_TYPE_SIGN);
679 }
680 #endif
681 else
682 {
683 status = AESCMAC_STATUS_ERROR;
684 }
685 return status;
686 }
687
688 /*
689 * ======== AESCMAC_oneStepVerify ========
690 */
AESCMAC_oneStepVerify(AESCMAC_Handle handle,AESCMAC_Operation * operation,CryptoKey * key)691 int_fast16_t AESCMAC_oneStepVerify(AESCMAC_Handle handle, AESCMAC_Operation *operation, CryptoKey *key)
692 {
693 int_fast16_t status;
694
695 if (key->encoding == CryptoKey_PLAINTEXT || key->encoding == CryptoKey_KEYSTORE)
696 {
697 status = AESCMACLPF3_oneStepOperation(handle, operation, key, AESCMAC_OP_TYPE_VERIFY);
698 }
699 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
700 else if (key->encoding == CryptoKey_PLAINTEXT_HSM)
701 {
702 status = AESCMACLPF3HSM_oneStepOperation(handle, operation, key, AESCMAC_OP_TYPE_VERIFY);
703 }
704 #endif
705 else
706 {
707 status = AESCMAC_STATUS_ERROR;
708 }
709 return status;
710 }
711
712 /*
713 * ======== AESCMACLPF3_setupSegmentedOperation ========
714 */
AESCMACLPF3_setupSegmentedOperation(AESCMACLPF3_Object * object,const CryptoKey * key)715 static int_fast16_t AESCMACLPF3_setupSegmentedOperation(AESCMACLPF3_Object *object, const CryptoKey *key)
716 {
717 DebugP_assert(key);
718
719 int_fast16_t status = AESCMAC_STATUS_SUCCESS;
720
721 /*
722 * Key material pointer and length are not asserted until adding or
723 * finalizing data.
724 */
725 if (key->encoding == CryptoKey_PLAINTEXT)
726 {
727 /* When using the AES driver with the LAES engine */
728 status = AESCommonLPF3_setupSegmentedOperation(&object->common, key);
729 }
730 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
731 else if (key->encoding == CryptoKey_PLAINTEXT_HSM)
732 {
733 /* A segmented operation may have been started but not finalized yet */
734 if (object->segmentedOperationInProgress)
735 {
736 return AESCMAC_STATUS_ERROR;
737 }
738
739 /* Make internal copy of crypto key */
740 object->common.key = *key;
741
742 /* returnStatus is only changed in the case of an error or cancellation */
743 object->common.returnStatus = AES_STATUS_SUCCESS;
744
745 object->segmentedOperationInProgress = true;
746 }
747 #endif
748 else
749 {
750 status = AESCMAC_STATUS_ERROR;
751 }
752
753 if (status == AESCMAC_STATUS_SUCCESS)
754 {
755 /*
756 * Initialize operation pointer to NULL in case AESCBC_cancelOperation
757 * is called after AESCMAC_setupXXXX and callback should be skipped.
758 */
759 object->operation = NULL;
760
761 /* Zero the intermediate tag because it will be used as the IV */
762 CryptoUtils_memset((void *)&object->intermediateTag[0],
763 sizeof(object->intermediateTag),
764 (uint8_t)0U,
765 sizeof(object->intermediateTag));
766 }
767
768 return status;
769 }
770
771 /*
772 * ======== AESCMAC_setupSign ========
773 */
AESCMAC_setupSign(AESCMAC_Handle handle,const CryptoKey * key)774 int_fast16_t AESCMAC_setupSign(AESCMAC_Handle handle, const CryptoKey *key)
775 {
776 DebugP_assert(handle);
777
778 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
779
780 int_fast16_t status = AESCMACLPF3_setupSegmentedOperation(object, key);
781
782 if (status == AESCMAC_STATUS_SUCCESS)
783 {
784 object->operationType = AESCMAC_OP_TYPE_SEGMENTED_SIGN;
785 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
786 if (key->encoding == CryptoKey_PLAINTEXT_HSM)
787 {
788 /* If the HSM IP and/or HSMSAL failed to boot then we cannot perform any HSM-related operation */
789 if (object->hsmStatus == AESCMAC_STATUS_ERROR)
790 {
791 return AESCMAC_STATUS_ERROR;
792 }
793 status = AESCMACLPF3HSM_createAndLoadKeyAssetID(handle);
794 }
795 #endif
796 }
797
798 return status;
799 }
800
801 /*
802 * ======== AESCMAC_setupVerify ========
803 */
AESCMAC_setupVerify(AESCMAC_Handle handle,const CryptoKey * key)804 int_fast16_t AESCMAC_setupVerify(AESCMAC_Handle handle, const CryptoKey *key)
805 {
806 DebugP_assert(handle);
807
808 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
809
810 int_fast16_t status = AESCMACLPF3_setupSegmentedOperation(object, key);
811
812 if (status == AESCMAC_STATUS_SUCCESS)
813 {
814 object->operationType = AESCMAC_OP_TYPE_SEGMENTED_VERIFY;
815 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
816 if (key->encoding == CryptoKey_PLAINTEXT_HSM)
817 {
818 /* If the HSM IP and/or HSMSAL failed to boot then we cannot perform any HSM-related operation */
819 if (object->hsmStatus == AESCMAC_STATUS_ERROR)
820 {
821 return AESCMAC_STATUS_ERROR;
822 }
823 status = AESCMACLPF3HSM_createAndLoadKeyAssetID(handle);
824 }
825 #endif
826 }
827
828 return status;
829 }
830
831 /*
832 * ======== AESCMAC_addData ========
833 */
AESCMAC_addData(AESCMAC_Handle handle,AESCMAC_Operation * operation)834 int_fast16_t AESCMAC_addData(AESCMAC_Handle handle, AESCMAC_Operation *operation)
835 {
836 DebugP_assert(handle);
837 DebugP_assert(operation);
838
839 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
840 int_fast16_t status = AESCMAC_STATUS_ERROR;
841
842 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
843 if (object->common.key.encoding == CryptoKey_PLAINTEXT_HSM)
844 {
845 return AESCMACLPF3HSM_SegmentedOperation(handle, operation);
846 }
847 #endif
848
849 /* Assert the segmented operation was setup */
850 DebugP_assert((object->operationType == AESCMAC_OP_TYPE_SEGMENTED_SIGN) ||
851 (object->operationType == AESCMAC_OP_TYPE_SEGMENTED_VERIFY));
852
853 /* Check for previous failure or cancellation of segmented operation */
854 if (object->common.returnStatus != AESCMAC_STATUS_SUCCESS)
855 {
856 /* Return the status of the previous call.
857 * The callback function will not be executed.
858 */
859 return object->common.returnStatus;
860 }
861
862 #if (AESCommonLPF3_UNALIGNED_IO_SUPPORT_ENABLE == 0)
863 /* Check word-alignment of input pointer */
864 if (!IS_WORD_ALIGNED(operation->input))
865 {
866 return AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED;
867 }
868 #endif
869
870 /* Verify the input length is non-zero and a multiple of the block size */
871 if ((operation->inputLength == 0U) || (AES_NON_BLOCK_SIZE_MULTIPLE_LENGTH(operation->inputLength) > 0U))
872 {
873 return AESCMAC_STATUS_ERROR;
874 }
875
876 if (object->threadSafe)
877 {
878 if (!CryptoResourceLPF3_acquireLock(object->common.semaphoreTimeout))
879 {
880 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
881 }
882
883 object->common.cryptoResourceLocked = true;
884 }
885
886 object->operation = operation;
887 if (object->common.key.encoding == CryptoKey_PLAINTEXT || object->common.key.encoding == CryptoKey_KEYSTORE)
888 {
889 status = AESCMACLPF3_startOperation(handle);
890 }
891 else
892 {
893 status = AESCMAC_STATUS_ERROR;
894 }
895
896 if ((status != AESCMAC_STATUS_SUCCESS) && (object->common.cryptoResourceLocked))
897 {
898 CryptoResourceLPF3_releaseLock();
899 object->common.cryptoResourceLocked = false;
900 }
901
902 return status;
903 }
904
905 /* Perform ECB encryption on a block of zeros */
AESCMACLPF3_encryptZeroBlockECB(uint32_t output[AES_BLOCK_SIZE_WORDS])906 static inline void AESCMACLPF3_encryptZeroBlockECB(uint32_t output[AES_BLOCK_SIZE_WORDS])
907 {
908 const uint32_t zeroBlock[AES_BLOCK_SIZE_WORDS] = {0};
909
910 AESSetAUTOCFG(AESEBCLPF3_SINGLE_BLOCK_AUTOCFG);
911
912 /* Write block of zeros to input */
913 AESWriteBUF32(&zeroBlock[0]);
914
915 /* Wait until the operation is done */
916 while (AESGetStatus() != (uint32_t)AES_STA_STATE_IDLE) {}
917
918 /* Read output */
919 AESReadTXT32(&output[0]);
920 }
921
922 /*
923 * ======== AESCMACLPF3_generateSubKey ========
924 * Generate AES CMAC subkey based on
925 * https://tools.ietf.org/html/rfc4493#section-2.3
926 */
AESCMACLPF3_generateSubKey(AESCMAC_SUBKEY_NUM subKeyNum,uint32_t subKey[AES_BLOCK_SIZE_WORDS])927 static void AESCMACLPF3_generateSubKey(AESCMAC_SUBKEY_NUM subKeyNum, uint32_t subKey[AES_BLOCK_SIZE_WORDS])
928 {
929 /* Perform ECB encryption on the block of zeros using CPU R/W */
930 AESCMACLPF3_encryptZeroBlockECB(&subKey[0]);
931
932 /*
933 * At this point, subKey buffer only has the ciphertext
934 * generated by encrypting a block of 0's.
935 * Derive SubKey1.
936 */
937 AESCMACLPF3_deriveSubKey((uint8_t *)&subKey[0]);
938
939 if (subKeyNum == AESCMAC_SUBKEY2)
940 {
941 /* At this point, subKey buffer contains SubKey1. Derive SubKey2. */
942 AESCMACLPF3_deriveSubKey((uint8_t *)&subKey[0]);
943 }
944 }
945
946 /*
947 * ======== AESCMACLPF3_deriveSubKey ========
948 */
AESCMACLPF3_deriveSubKey(uint8_t * buffer)949 static void AESCMACLPF3_deriveSubKey(uint8_t *buffer)
950 {
951 uint_fast8_t i;
952 uint8_t xorMask = (uint8_t)0U;
953
954 if ((buffer[0] & AESCMAC_MSB_CHECK) != (uint8_t)0U)
955 {
956 xorMask = AESCMAC_CONST_RB;
957 }
958
959 for (i = (uint_fast8_t)0U; i < (uint_fast8_t)AES_BLOCK_SIZE; i += (uint_fast8_t)1U)
960 {
961 if (i != (uint_fast8_t)0U)
962 {
963 buffer[i - (uint_fast8_t)1U] += (buffer[i] >> 7U);
964 }
965
966 buffer[i] = buffer[i] << 1U;
967 }
968
969 buffer[AES_BLOCK_SIZE - 1U] ^= xorMask;
970 }
971
972 /*
973 * ======== AESCMAC_finalize ========
974 */
AESCMAC_finalize(AESCMAC_Handle handle,AESCMAC_Operation * operation)975 int_fast16_t AESCMAC_finalize(AESCMAC_Handle handle, AESCMAC_Operation *operation)
976 {
977 DebugP_assert(handle);
978 DebugP_assert(operation);
979
980 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
981 int_fast16_t status = AESCMAC_STATUS_ERROR;
982
983 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
984 if (object->common.key.encoding == CryptoKey_PLAINTEXT_HSM)
985 {
986 return AESCMACLPF3HSM_finalize(handle, operation);
987 }
988 #endif
989
990 /* Assert the segmented operation was setup */
991 DebugP_assert((object->operationType == AESCMAC_OP_TYPE_SEGMENTED_SIGN) ||
992 (object->operationType == AESCMAC_OP_TYPE_SEGMENTED_VERIFY));
993
994 /* Check for previous failure or cancellation of segmented operation */
995 if (object->common.returnStatus != AESCMAC_STATUS_SUCCESS)
996 {
997 /*
998 * Return the failure status of previous call.
999 * The callback will not be called.
1000 */
1001 return object->common.returnStatus;
1002 }
1003
1004 #if (AESCommonLPF3_UNALIGNED_IO_SUPPORT_ENABLE == 0)
1005 /* Check word-alignment of input pointer */
1006 if (!IS_WORD_ALIGNED(operation->input))
1007 {
1008 return AESCMAC_STATUS_UNALIGNED_IO_NOT_SUPPORTED;
1009 }
1010 #endif
1011
1012 if (operation->macLength > sizeof(object->intermediateTag))
1013 {
1014 return AESCMAC_STATUS_ERROR;
1015 }
1016
1017 if (operation->inputLength == 0U)
1018 {
1019 /*
1020 * Finalizing an operation without providing data to process is not
1021 * supported. Return an error.
1022 */
1023 return AESCMAC_STATUS_ERROR;
1024 }
1025
1026 /* Try and obtain access to the crypto module */
1027 if (object->threadSafe)
1028 {
1029 if (!CryptoResourceLPF3_acquireLock(object->common.semaphoreTimeout))
1030 {
1031 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1032 }
1033
1034 object->common.cryptoResourceLocked = true;
1035 }
1036
1037 if (object->operationType == AESCMAC_OP_TYPE_SEGMENTED_SIGN)
1038 {
1039 object->operationType = AESCMAC_OP_TYPE_FINALIZE_SIGN;
1040 }
1041 else
1042 {
1043 object->operationType = AESCMAC_OP_TYPE_FINALIZE_VERIFY;
1044 }
1045
1046 object->operation = operation;
1047 if (object->common.key.encoding == CryptoKey_PLAINTEXT || object->common.key.encoding == CryptoKey_KEYSTORE)
1048 {
1049 status = AESCMACLPF3_startOperation(handle);
1050 }
1051 else
1052 {
1053 status = AESCMAC_STATUS_ERROR;
1054 }
1055
1056 if ((status != AESCMAC_STATUS_SUCCESS) && (object->common.cryptoResourceLocked))
1057 {
1058 CryptoResourceLPF3_releaseLock();
1059 object->common.cryptoResourceLocked = false;
1060 }
1061
1062 return status;
1063 }
1064
1065 /*
1066 * ======== AESCMAC_close ========
1067 */
AESCMAC_close(AESCMAC_Handle handle)1068 void AESCMAC_close(AESCMAC_Handle handle)
1069 {
1070 DebugP_assert(handle);
1071
1072 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1073
1074 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
1075 if (object->common.key.encoding == CryptoKey_PLAINTEXT_HSM &&
1076 AESCMACLPF3HSM_freeAssets(handle) != AESCMAC_STATUS_SUCCESS)
1077 {
1078 /* empty */
1079 }
1080 #endif
1081
1082 AESCommonLPF3_close(&object->common);
1083 }
1084
1085 /*
1086 * ======== AESCMAC_cancelOperation ========
1087 */
AESCMAC_cancelOperation(AESCMAC_Handle handle)1088 int_fast16_t AESCMAC_cancelOperation(AESCMAC_Handle handle)
1089 {
1090 DebugP_assert(handle);
1091
1092 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1093
1094 uintptr_t interruptKey = HwiP_disable();
1095
1096 /* Return success if there is no active operation to cancel.
1097 * Do not execute the callback as it would have been executed already
1098 * when the operation completed.
1099 */
1100
1101 /* If the operation is in _HSM mode, then the driver does not rely on 'object->common' metadata
1102 * and instead relies on HSM metadata. The check below insures that.
1103 */
1104 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
1105 if (((object->common.key.encoding & CRYPTOKEY_HSM) == 0U) && (!object->common.operationInProgress))
1106 #else
1107 if (!object->common.operationInProgress)
1108 #endif
1109 {
1110 HwiP_restore(interruptKey);
1111 return AESCMAC_STATUS_SUCCESS;
1112 }
1113
1114 HwiP_restore(interruptKey);
1115
1116 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
1117 /* Since the HSM cannot cancel an in-progress token, we must wait for the result to allow for
1118 * subsequent token submissions to succeed.
1119 */
1120 (void)HSMLPF3_cancelOperation();
1121
1122 object->segmentedOperationInProgress = false;
1123
1124 if ((object->common.key.encoding == CryptoKey_PLAINTEXT_HSM) &&
1125 (AESCMACLPF3HSM_freeAssets(handle) != AESCMAC_STATUS_SUCCESS))
1126 {
1127 return AESCMAC_STATUS_ERROR;
1128 }
1129 #endif
1130
1131 /* Cancel DMA for input channel A only, clear operation in-progress,
1132 * and release crypto resource if locked.
1133 */
1134 AESCommonLPF3_cancelOperation(&object->common, false);
1135
1136 /* Operation pointer could be NULL if a segmented operation was setup
1137 * but neither AESCMAC_addData or AESCMAC_finalize was called.
1138 */
1139 if ((object->common.returnBehavior == AES_RETURN_BEHAVIOR_CALLBACK) && (object->operation != NULL))
1140 {
1141 /* Call the callback function provided by the application */
1142 object->callbackFxn(handle, AESCMAC_STATUS_CANCELED, object->operation, object->operationType);
1143 }
1144
1145 return AESCMAC_STATUS_SUCCESS;
1146 }
1147
1148 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
1149
1150 /*
1151 * ======== AESCMACLPF3HSM_oneStepOperation ========
1152 */
AESCMACLPF3HSM_oneStepOperation(AESCMAC_Handle handle,AESCMAC_Operation * operation,const CryptoKey * key,AESCMAC_OperationType operationType)1153 static int_fast16_t AESCMACLPF3HSM_oneStepOperation(AESCMAC_Handle handle,
1154 AESCMAC_Operation *operation,
1155 const CryptoKey *key,
1156 AESCMAC_OperationType operationType)
1157 {
1158 DebugP_assert(handle);
1159 DebugP_assert(operation);
1160 DebugP_assert(key);
1161 /* No need to assert operationType since we control it within the driver */
1162 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1163 int_fast16_t status = AESCMAC_STATUS_SUCCESS;
1164
1165 /* If the HSM IP and/or HSMSAL failed to boot then we cannot perform any HSM-related operation */
1166 if (object->hsmStatus == HSMLPF3_STATUS_ERROR)
1167 {
1168 return HSMLPF3_STATUS_ERROR;
1169 }
1170
1171 /* CBC-MAC is not permitted for zero length messages */
1172 if ((object->operationalMode == AESCMAC_OPMODE_CBCMAC) && (operation->inputLength == 0U))
1173 {
1174 return AESCMAC_STATUS_ERROR;
1175 }
1176
1177 if (operation->macLength > sizeof(object->intermediateTag))
1178 {
1179 return AESCMAC_STATUS_ERROR;
1180 }
1181
1182 /* A segmented operation may have been started but not finalized yet */
1183 if (object->segmentedOperationInProgress)
1184 {
1185 return AESCMAC_STATUS_ERROR;
1186 }
1187
1188 object->operation = operation;
1189 object->operationType = operationType;
1190 /* We will only change the returnStatus if there is an error or cancellation */
1191 object->common.returnStatus = AESCMAC_STATUS_SUCCESS;
1192 /* Make internal copy of crypto key */
1193 object->common.key = *key;
1194
1195 /* Zero the intermediate tag because it will be used as the IV */
1196 CryptoUtils_memset((void *)&object->intermediateTag[0],
1197 sizeof(object->intermediateTag),
1198 (uint8_t)0U,
1199 sizeof(object->intermediateTag));
1200
1201 if (object->common.key.encoding == CryptoKey_PLAINTEXT_HSM)
1202 {
1203 status = AESCMACLPF3HSM_createAndLoadKeyAssetID(handle);
1204
1205 if (status == AESCMAC_STATUS_SUCCESS)
1206 {
1207 status = AESCMACLPF3HSM_processOneStepAndFinalizeOperation(handle);
1208 }
1209 }
1210 else
1211 {
1212 status = AESCMAC_STATUS_ERROR;
1213 }
1214
1215 return status;
1216 }
1217
1218 /*
1219 * ======== AESCMACLPF3HSM_finalize ========
1220 */
AESCMACLPF3HSM_finalize(AESCMAC_Handle handle,AESCMAC_Operation * operation)1221 static int_fast16_t AESCMACLPF3HSM_finalize(AESCMAC_Handle handle, AESCMAC_Operation *operation)
1222 {
1223 DebugP_assert(handle);
1224 DebugP_assert(operation);
1225
1226 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1227 int_fast16_t status = AESCMAC_STATUS_ERROR;
1228
1229 if (object->hsmStatus == HSMLPF3_STATUS_ERROR)
1230 {
1231 return HSMLPF3_STATUS_ERROR;
1232 }
1233
1234 /* Assert the segmented operation was setup */
1235 DebugP_assert((object->operationType == AESCMAC_OP_TYPE_SEGMENTED_SIGN) ||
1236 (object->operationType == AESCMAC_OP_TYPE_SEGMENTED_VERIFY));
1237
1238 /* Check for previous failure or cancellation of segmented operation */
1239 if (object->common.returnStatus != AESCMAC_STATUS_SUCCESS)
1240 {
1241 /* Return the status of the previous call.
1242 * The callback function will not be executed.
1243 */
1244 return object->common.returnStatus;
1245 }
1246
1247 if (operation->inputLength == 0U)
1248 {
1249 /*
1250 * Finalizing an operation without providing data to process is not
1251 * supported. Return an error.
1252 */
1253 return AESCMAC_STATUS_ERROR;
1254 }
1255
1256 object->operation = operation;
1257
1258 if (object->operationType & AESCMAC_OP_FLAG_SIGN)
1259 {
1260 object->operationType = AESCMAC_OP_TYPE_FINALIZE_SIGN;
1261 }
1262 else
1263 {
1264 object->operationType = AESCMAC_OP_TYPE_FINALIZE_VERIFY;
1265 }
1266
1267 status = AESCMACLPF3HSM_processOneStepAndFinalizeOperation(handle);
1268
1269 return status;
1270 }
1271
1272 /*
1273 * ======== AESCMACLPF3HSM_CreateKeyAssetPostProcessing ========
1274 */
AESCMACLPF3HSM_CreateKeyAssetPostProcessing(uintptr_t arg0)1275 static inline void AESCMACLPF3HSM_CreateKeyAssetPostProcessing(uintptr_t arg0)
1276 {
1277 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
1278 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1279 int_fast16_t status = AESCMAC_STATUS_ERROR;
1280 int32_t physicalResult = HSMLPF3_getResultCode();
1281 int8_t tokenResult = physicalResult & HSMLPF3_RETVAL_MASK;
1282
1283 if (tokenResult == EIP130TOKEN_RESULT_SUCCESS)
1284 {
1285 object->keyAssetID = HSMLPF3_getResultAssetID();
1286 status = AESCMAC_STATUS_SUCCESS;
1287 }
1288
1289 object->common.returnStatus = status;
1290
1291 HSMLPF3_releaseLock();
1292
1293 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1294 }
1295
1296 /*
1297 * ======== AESCMACLPF3HSM_createKeyAssetID ========
1298 */
AESCMACLPF3HSM_createKeyAsset(AESCMAC_Handle handle)1299 static int_fast16_t AESCMACLPF3HSM_createKeyAsset(AESCMAC_Handle handle)
1300 {
1301 int_fast16_t status = AESCMAC_STATUS_ERROR;
1302 int_fast16_t hsmRetval = HSMLPF3_STATUS_ERROR;
1303 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1304 uint64_t assetPolicy = 0U;
1305
1306 if (!HSMLPF3_acquireLock(SemaphoreP_NO_WAIT, (uintptr_t)handle))
1307 {
1308 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1309 }
1310
1311 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
1312
1313 /* Operation (Lower 16-bits + general Operation) + Direction + Mode */
1314 assetPolicy = EIP130_ASSET_POLICY_SYM_BASE | EIP130_ASSET_POLICY_SCUIMACCIPHER | EIP130_ASSET_POLICY_SCACAES |
1315 EIP130_ASSET_POLICY_SCDIRENCGEN;
1316
1317 if (object->operationalMode == AESCMAC_OPMODE_CMAC)
1318 {
1319 assetPolicy |= EIP130_ASSET_POLICY_SCMCMCMAC;
1320 }
1321 else
1322 {
1323 assetPolicy |= EIP130_ASSET_POLICY_SCMCMCBCMAC;
1324 }
1325
1326 HSMLPF3_constructCreateAssetToken(assetPolicy, (uint32_t)object->common.key.u.plaintext.keyLength);
1327
1328 hsmRetval = HSMLPF3_submitToken(HSMLPF3_RETURN_BEHAVIOR_POLLING,
1329 AESCMACLPF3HSM_CreateKeyAssetPostProcessing,
1330 (uintptr_t)handle);
1331 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1332 {
1333 hsmRetval = HSMLPF3_waitForResult();
1334
1335 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1336 {
1337 status = object->common.returnStatus;
1338 }
1339 }
1340
1341 if (hsmRetval != HSMLPF3_STATUS_SUCCESS)
1342 {
1343 HSMLPF3_releaseLock();
1344
1345 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1346 }
1347
1348 return status;
1349 }
1350
1351 /*
1352 * ======== AESCMACLPF3HSM_LoadKeyAssetPostProcessing ========
1353 */
AESCMACLPF3HSM_LoadKeyAssetPostProcessing(uintptr_t arg0)1354 static inline void AESCMACLPF3HSM_LoadKeyAssetPostProcessing(uintptr_t arg0)
1355 {
1356 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
1357 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1358 int_fast16_t status = AESCMAC_STATUS_ERROR;
1359 int32_t physicalResult = HSMLPF3_getResultCode();
1360 int8_t tokenResult = physicalResult & HSMLPF3_RETVAL_MASK;
1361
1362 if (tokenResult == EIP130TOKEN_RESULT_SUCCESS)
1363 {
1364 status = AESCMAC_STATUS_SUCCESS;
1365 }
1366
1367 object->hsmStatus = status;
1368
1369 HSMLPF3_releaseLock();
1370
1371 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1372 }
1373
1374 /*
1375 * ======== AESCMACLPF3HSM_createKeyAssetID ========
1376 */
AESCMACLPF3HSM_LoadKeyAsset(AESCMAC_Handle handle)1377 static int_fast16_t AESCMACLPF3HSM_LoadKeyAsset(AESCMAC_Handle handle)
1378 {
1379 int_fast16_t status = AESCMAC_STATUS_ERROR;
1380 int_fast16_t hsmRetval = HSMLPF3_STATUS_ERROR;
1381 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1382
1383 if (!HSMLPF3_acquireLock(SemaphoreP_NO_WAIT, (uintptr_t)handle))
1384 {
1385 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1386 }
1387
1388 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
1389
1390 HSMLPF3_constructLoadPlaintextAssetToken(object->common.key.u.plaintext.keyMaterial,
1391 object->common.key.u.plaintext.keyLength,
1392 object->keyAssetID);
1393
1394 hsmRetval = HSMLPF3_submitToken(HSMLPF3_RETURN_BEHAVIOR_POLLING,
1395 AESCMACLPF3HSM_LoadKeyAssetPostProcessing,
1396 (uintptr_t)handle);
1397 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1398 {
1399 hsmRetval = HSMLPF3_waitForResult();
1400
1401 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1402 {
1403 status = object->common.returnStatus;
1404 }
1405 }
1406
1407 if (hsmRetval != HSMLPF3_STATUS_SUCCESS)
1408 {
1409 HSMLPF3_releaseLock();
1410
1411 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1412 }
1413
1414 return status;
1415 }
1416
1417 /*
1418 * ======== AESCMACLPF3HSM_createAndLoadKeyAssetID ========
1419 */
AESCMACLPF3HSM_createAndLoadKeyAssetID(AESCMAC_Handle handle)1420 static int_fast16_t AESCMACLPF3HSM_createAndLoadKeyAssetID(AESCMAC_Handle handle)
1421 {
1422 int_fast16_t status = AESCMAC_STATUS_ERROR;
1423
1424 status = AESCMACLPF3HSM_createKeyAsset(handle);
1425 if (status == AESCMAC_STATUS_SUCCESS)
1426 {
1427 status = AESCMACLPF3HSM_LoadKeyAsset(handle);
1428 }
1429
1430 return status;
1431 }
1432
1433 /*
1434 * ======== AESCMACLPF3HSM_CreateTempAssetPostProcessing ========
1435 */
AESCMACLPF3HSM_CreateTempAssetPostProcessing(uintptr_t arg0)1436 static inline void AESCMACLPF3HSM_CreateTempAssetPostProcessing(uintptr_t arg0)
1437 {
1438 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
1439 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1440 int_fast16_t status = AESCMAC_STATUS_ERROR;
1441 int32_t physicalResult = HSMLPF3_getResultCode();
1442 int8_t tokenResult = physicalResult & HSMLPF3_RETVAL_MASK;
1443
1444 if (tokenResult == EIP130TOKEN_RESULT_SUCCESS)
1445 {
1446 object->tempAssetID = HSMLPF3_getResultAssetID();
1447 status = AESCMAC_STATUS_SUCCESS;
1448 }
1449
1450 object->common.returnStatus = status;
1451
1452 HSMLPF3_releaseLock();
1453
1454 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1455 }
1456
AESCMACLPF3HSM_CreateTempAssetID(AESCMAC_Handle handle)1457 static int_fast16_t AESCMACLPF3HSM_CreateTempAssetID(AESCMAC_Handle handle)
1458 {
1459 int_fast16_t status = AESCMAC_STATUS_ERROR;
1460 int_fast16_t hsmRetval = HSMLPF3_STATUS_ERROR;
1461 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1462 uint64_t assetPolicy = 0U;
1463
1464 if (!HSMLPF3_acquireLock(SemaphoreP_NO_WAIT, (uintptr_t)handle))
1465 {
1466 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1467 }
1468
1469 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
1470
1471 /* Operation (Lower 16-bits + general Operation) + Direction + Mode */
1472 assetPolicy = EIP130_ASSET_POLICY_SYM_TEMP | EIP130_ASSET_POLICY_SCUIMACCIPHER | EIP130_ASSET_POLICY_SCACAES |
1473 EIP130_ASSET_POLICY_SCDIRENCGEN;
1474
1475 if (object->operationalMode == AESCMAC_OPMODE_CMAC)
1476 {
1477 assetPolicy |= EIP130_ASSET_POLICY_SCMCMCMAC;
1478 }
1479 else
1480 {
1481 assetPolicy |= EIP130_ASSET_POLICY_SCMCMCBCMAC;
1482 }
1483
1484 HSMLPF3_constructCreateAssetToken(assetPolicy, AES_BLOCK_SIZE);
1485
1486 hsmRetval = HSMLPF3_submitToken(HSMLPF3_RETURN_BEHAVIOR_POLLING,
1487 AESCMACLPF3HSM_CreateTempAssetPostProcessing,
1488 (uintptr_t)handle);
1489 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1490 {
1491 hsmRetval = HSMLPF3_waitForResult();
1492
1493 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1494 {
1495 status = object->common.returnStatus;
1496 }
1497 }
1498
1499 if (hsmRetval != HSMLPF3_STATUS_SUCCESS)
1500 {
1501 HSMLPF3_releaseLock();
1502
1503 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1504 }
1505
1506 return status;
1507 }
1508
1509 /*
1510 * ======== AESCMACLPF3HSM_oneStepAndFinalizePostProcessing ========
1511 */
AESCMACLPF3HSM_oneStepAndFinalizePostProcessing(uintptr_t arg0)1512 static inline void AESCMACLPF3HSM_oneStepAndFinalizePostProcessing(uintptr_t arg0)
1513 {
1514 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
1515 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1516 AESCMAC_Operation *operation = object->operation;
1517 int32_t physicalResult = HSMLPF3_getResultCode();
1518 int8_t tokenResult = physicalResult & HSMLPF3_RETVAL_MASK;
1519
1520 if (tokenResult == EIP130TOKEN_RESULT_SUCCESS)
1521 {
1522 HSMLPF3_getAESCMACSignMac((void *)&object->intermediateTag[0], operation->macLength);
1523
1524 object->common.returnStatus = AESCMAC_STATUS_SUCCESS;
1525
1526 AESCMACLPF3_getResult(object);
1527 }
1528 else
1529 {
1530 object->common.returnStatus = AESCMAC_STATUS_ERROR;
1531 }
1532
1533 HSMLPF3_releaseLock();
1534
1535 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1536
1537 if (AESCMACLPF3HSM_freeAssets(handle) == AESCMAC_STATUS_ERROR)
1538 {
1539 object->common.returnStatus = AESCMAC_STATUS_ERROR;
1540 }
1541
1542 object->segmentedOperationInProgress = false;
1543
1544 if (object->common.returnBehavior == AES_RETURN_BEHAVIOR_CALLBACK)
1545 {
1546 object->callbackFxn(handle, object->common.returnStatus, object->operation, object->operationType);
1547 }
1548 }
1549
1550 /*
1551 * ======== AESCMACLPF3HSM_processOneStepAndFinalizeOperation ========
1552 */
AESCMACLPF3HSM_processOneStepAndFinalizeOperation(AESCMAC_Handle handle)1553 static int_fast16_t AESCMACLPF3HSM_processOneStepAndFinalizeOperation(AESCMAC_Handle handle)
1554 {
1555 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1556 int_fast16_t status = AESCMAC_STATUS_ERROR;
1557 int_fast16_t hsmRetval = HSMLPF3_STATUS_ERROR;
1558
1559 if (!HSMLPF3_acquireLock(SemaphoreP_NO_WAIT, (uintptr_t)handle))
1560 {
1561 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1562 }
1563
1564 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
1565
1566 HSMLPF3_constructAESCMACOneStepPhysicalToken(object);
1567
1568 hsmRetval = HSMLPF3_submitToken((HSMLPF3_ReturnBehavior)object->common.returnBehavior,
1569 AESCMACLPF3HSM_oneStepAndFinalizePostProcessing,
1570 (uintptr_t)handle);
1571
1572 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1573 {
1574 hsmRetval = HSMLPF3_waitForResult();
1575
1576 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1577 {
1578 status = object->common.returnStatus;
1579 }
1580 }
1581
1582 if (hsmRetval != HSMLPF3_STATUS_SUCCESS)
1583 {
1584 HSMLPF3_releaseLock();
1585
1586 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1587 }
1588
1589 return status;
1590 }
1591
1592 /*
1593 * ======== AESCMACLPF3HSM_freeAssets ========
1594 */
AESCMACLPF3HSM_freeAssets(AESCMAC_Handle handle)1595 static int_fast16_t AESCMACLPF3HSM_freeAssets(AESCMAC_Handle handle)
1596 {
1597 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1598 int_fast16_t status = AESCMAC_STATUS_ERROR;
1599
1600 object->common.cryptoResourceLocked = true;
1601
1602 if (object->keyAssetID != 0U)
1603 {
1604 status = AESCMACLPF3HSM_freeAssetID(handle, object->keyAssetID);
1605 if (status != AESCMAC_STATUS_ERROR)
1606 {
1607 object->keyAssetID = 0U;
1608 }
1609 }
1610
1611 if (object->tempAssetID != 0)
1612 {
1613 status = AESCMACLPF3HSM_freeAssetID(handle, object->tempAssetID);
1614 if (status != AESCMAC_STATUS_ERROR)
1615 {
1616 object->tempAssetID = 0U;
1617 }
1618 }
1619
1620 object->common.cryptoResourceLocked = false;
1621
1622 return status;
1623 }
1624
1625 /*
1626 * ======== AESCMACLPF3HSM_FreeAssetPostProcessing ========
1627 */
AESCMACLPF3HSM_FreeAssetPostProcessing(uintptr_t arg0)1628 static inline void AESCMACLPF3HSM_FreeAssetPostProcessing(uintptr_t arg0)
1629 {
1630 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
1631 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1632 int_fast16_t status = AESCMAC_STATUS_ERROR;
1633 int32_t physicalResult = HSMLPF3_getResultCode();
1634 int8_t tokenResult = physicalResult & HSMLPF3_RETVAL_MASK;
1635
1636 if (tokenResult == EIP130TOKEN_RESULT_SUCCESS)
1637 {
1638 status = AESCMAC_STATUS_SUCCESS;
1639 }
1640
1641 if (status == AESCMAC_STATUS_ERROR)
1642 {
1643 object->common.returnStatus = status;
1644 }
1645
1646 if ((HSMLPF3_ReturnBehavior)object->common.returnBehavior == HSMLPF3_RETURN_BEHAVIOR_POLLING)
1647 {
1648 HSMLPF3_releaseLock();
1649
1650 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1651 }
1652
1653 if (status == AESCMAC_STATUS_ERROR && object->common.returnBehavior == AES_RETURN_BEHAVIOR_CALLBACK)
1654 {
1655 object->callbackFxn(handle, object->common.returnStatus, object->operation, object->operationType);
1656 }
1657 }
1658
1659 /*
1660 * ======== AESCMACLPF3HSM_freeAssetID ========
1661 */
AESCMACLPF3HSM_freeAssetID(AESCMAC_Handle handle,uint32_t AssetID)1662 static int_fast16_t AESCMACLPF3HSM_freeAssetID(AESCMAC_Handle handle, uint32_t AssetID)
1663 {
1664 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1665 int_fast16_t status = AESCMAC_STATUS_SUCCESS;
1666 int_fast16_t hsmRetval = HSMLPF3_STATUS_ERROR;
1667
1668 if ((HSMLPF3_ReturnBehavior)object->common.returnBehavior == HSMLPF3_RETURN_BEHAVIOR_POLLING)
1669 {
1670 if (!HSMLPF3_acquireLock(SemaphoreP_NO_WAIT, (uintptr_t)handle))
1671 {
1672 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1673 }
1674
1675 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
1676 }
1677
1678 HSMLPF3_constructDeleteAssetToken(AssetID);
1679
1680 hsmRetval = HSMLPF3_submitToken(HSMLPF3_RETURN_BEHAVIOR_POLLING,
1681 AESCMACLPF3HSM_FreeAssetPostProcessing,
1682 (uintptr_t)handle);
1683 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1684 {
1685 hsmRetval = HSMLPF3_waitForResult();
1686
1687 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1688 {
1689 status = object->common.returnStatus;
1690 }
1691 }
1692
1693 if (((HSMLPF3_ReturnBehavior)object->common.returnBehavior == HSMLPF3_RETURN_BEHAVIOR_POLLING) &&
1694 (hsmRetval != HSMLPF3_STATUS_SUCCESS))
1695 {
1696 HSMLPF3_releaseLock();
1697
1698 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1699 }
1700
1701 return status;
1702 }
1703
1704 /*
1705 * ======== AESCMACLPF3HSM_SegmentedOperation ========
1706 */
AESCMACLPF3HSM_SegmentedOperation(AESCMAC_Handle handle,AESCMAC_Operation * operation)1707 static int_fast16_t AESCMACLPF3HSM_SegmentedOperation(AESCMAC_Handle handle, AESCMAC_Operation *operation)
1708 {
1709 DebugP_assert(handle);
1710 DebugP_assert(operation);
1711
1712 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1713 int_fast16_t status = AESCMAC_STATUS_ERROR;
1714
1715 /* If the HSM IP and/or HSMSAL failed to boot then we cannot perform any HSM-related operation */
1716 if (object->hsmStatus == AESCMAC_STATUS_ERROR)
1717 {
1718 return AESCMAC_STATUS_ERROR;
1719 }
1720
1721 /* Assert the segmented operation was setup */
1722 DebugP_assert((object->operationType == AESCMAC_OP_TYPE_SEGMENTED_SIGN) ||
1723 (object->operationType == AESCMAC_OP_TYPE_SEGMENTED_VERIFY));
1724
1725 /* Check for previous failure or cancellation of segmented operation */
1726 if (object->common.returnStatus != AESCMAC_STATUS_SUCCESS)
1727 {
1728 /* Return the status of the previous call.
1729 * The callback function will not be executed.
1730 */
1731 return object->common.returnStatus;
1732 }
1733
1734 if ((operation->inputLength == 0U) || (AES_NON_BLOCK_SIZE_MULTIPLE_LENGTH(operation->inputLength) > 0U))
1735 {
1736 return AESCMAC_STATUS_ERROR;
1737 }
1738
1739 object->operation = operation;
1740
1741 status = AESCMACLPF3HSM_processSegmentedOperation(handle);
1742
1743 return status;
1744 }
1745
1746 /*
1747 * ======== AESCMACLPF3HSM_segmentedPostProcessing ========
1748 */
AESCMACLPF3HSM_segmentedPostProcessing(uintptr_t arg0)1749 static inline void AESCMACLPF3HSM_segmentedPostProcessing(uintptr_t arg0)
1750 {
1751 AESCMAC_Handle handle = (AESCMAC_Handle)arg0;
1752 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1753 int_fast16_t status = AESCMAC_STATUS_ERROR;
1754 int32_t physicalResult = HSMLPF3_getResultCode();
1755
1756 if (physicalResult == EIP130TOKEN_RESULT_SUCCESS)
1757 {
1758 status = AESCMAC_STATUS_SUCCESS;
1759 }
1760
1761 object->common.returnStatus = status;
1762
1763 HSMLPF3_releaseLock();
1764
1765 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1766
1767 if (object->common.returnBehavior == AES_RETURN_BEHAVIOR_CALLBACK)
1768 {
1769 object->callbackFxn(handle, object->common.returnStatus, object->operation, object->operationType);
1770 }
1771 }
1772
AESCMACLPF3HSM_processSegmentedOperation(AESCMAC_Handle handle)1773 static int_fast16_t AESCMACLPF3HSM_processSegmentedOperation(AESCMAC_Handle handle)
1774 {
1775 AESCMACLPF3_Object *object = AESCMACLPF3_getObject(handle);
1776 int_fast16_t status = AESCMAC_STATUS_SUCCESS;
1777 int_fast16_t hsmRetval = HSMLPF3_STATUS_ERROR;
1778 bool isInitWithDefault = true;
1779
1780 if (!HSMLPF3_acquireLock(SemaphoreP_NO_WAIT, (uintptr_t)handle))
1781 {
1782 return AESCMAC_STATUS_RESOURCE_UNAVAILABLE;
1783 }
1784
1785 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
1786
1787 if (object->tempAssetID == 0U)
1788 {
1789 HSMLPF3_releaseLock();
1790 status = AESCMACLPF3HSM_CreateTempAssetID(handle);
1791 }
1792 else
1793 {
1794 isInitWithDefault = false;
1795 }
1796
1797 HSMLPF3_constructAESCMACUpdatePhysicalToken(object, isInitWithDefault);
1798
1799 hsmRetval = HSMLPF3_submitToken((HSMLPF3_ReturnBehavior)object->common.returnBehavior,
1800 AESCMACLPF3HSM_segmentedPostProcessing,
1801 (uintptr_t)handle);
1802
1803 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1804 {
1805 hsmRetval = HSMLPF3_waitForResult();
1806
1807 if (hsmRetval == HSMLPF3_STATUS_SUCCESS)
1808 {
1809 status = object->common.returnStatus;
1810 }
1811 }
1812
1813 if (hsmRetval != HSMLPF3_STATUS_SUCCESS)
1814 {
1815 HSMLPF3_releaseLock();
1816
1817 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
1818 }
1819
1820 return status;
1821 }
1822
1823 #endif