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