1 /***************************************************************************//**
2 * \file cy_crypto_core_cmac_v2.c
3 * \version 2.120
4 *
5 * \brief
6 *  This file provides the source code to the API for the CMAC method
7 *  in the Crypto block driver.
8 *
9 *  Implementation is done in accordance with information from this weblink:
10 *  nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38b.pdf
11 *
12 ********************************************************************************
13 * \copyright
14 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
15 * an affiliate of Cypress Semiconductor Corporation.
16 * SPDX-License-Identifier: Apache-2.0
17 *
18 * Licensed under the Apache License, Version 2.0 (the "License");
19 * you may not use this file except in compliance with the License.
20 * You may obtain a copy of the License at
21 *
22 *    http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Unless required by applicable law or agreed to in writing, software
25 * distributed under the License is distributed on an "AS IS" BASIS,
26 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27 * See the License for the specific language governing permissions and
28 * limitations under the License.
29 *******************************************************************************/
30 
31 #include "cy_device.h"
32 
33 #if defined(CY_IP_MXCRYPTO)
34 
35 #include "cy_crypto_core_cmac_v2.h"
36 
37 #if defined(CY_CRYPTO_CFG_HW_V2_ENABLE)
38 
39 #if defined(__cplusplus)
40 extern "C" {
41 #endif
42 
43 #if (CPUSS_CRYPTO_AES == 1) && defined(CY_CRYPTO_CFG_CMAC_C)
44 
45 #include "cy_crypto_core_aes_v2.h"
46 #include "cy_crypto_core_hw_v2.h"
47 #include "cy_syslib.h"
48 #include "cy_crypto_core_mem_v2.h"
49 /* The bit string used to generate sub-keys */
50 #define CY_CRYPTO_CMAC_RB  (0x87u)
51 
52 static void Cy_Crypto_Core_V2_Cmac_CalcSubKey(uint8_t *srcDstPtr);
53 
54 /*******************************************************************************
55 * Function Name: Cy_Crypto_Core_V2_Cmac_CalcSubKey
56 ****************************************************************************//**
57 *
58 * Calculates the sub-key for the CMAC algorithm
59 * according to the NIST publication 800-38B, page 7.
60 *
61 * \param srcDstPtr
62 * The pointer to the source data for sub-key calculation, see 800-38B.
63 *
64 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac_CalcSubKey(uint8_t * srcDstPtr)65 static void Cy_Crypto_Core_V2_Cmac_CalcSubKey(uint8_t *srcDstPtr)
66 {
67     int32_t i;
68     uint32_t c;
69     uint32_t msb = 0UL;
70 
71     for (i = (int32_t)((int32_t)CY_CRYPTO_AES_BLOCK_SIZE - 1); i >= 0; i--)
72     {
73         c = (uint32_t)srcDstPtr[i];
74         c = (c << 1U) | msb;
75         srcDstPtr[i] = (uint8_t) c;
76         msb = (c >> 8U) & 1UL;
77     }
78 
79     if (0UL != msb)
80     {
81         /* Just one byte is valuable, the rest are zeros */
82         srcDstPtr[(uint8_t)(CY_CRYPTO_AES_BLOCK_SIZE - 1U)] ^= CY_CRYPTO_CMAC_RB;
83     }
84 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
85     /* Flush the cache */
86     SCB_CleanDCache_by_Addr((volatile void *)srcDstPtr,(int32_t)CY_CRYPTO_AES_BLOCK_SIZE);
87 #endif
88 }
89 
90 /*******************************************************************************
91 * Function Name: Cy_Crypto_Core_V2_Cmac_Init
92 ****************************************************************************//**
93 *
94 * The function for initialization of CMAC operation.
95 *
96 * \param cmacState
97 * The pointer to the structure which stores the CMAC context.
98 *
99 * \param buffer
100 * The pointer to the cmac buffer.
101 *
102 * \return
103 * \ref cy_en_crypto_status_t
104 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac_Init(CRYPTO_Type * base,cy_stc_crypto_v2_cmac_state_t * cmacState,cy_stc_crypto_v2_cmac_buffers_t * buffer)105 cy_en_crypto_status_t Cy_Crypto_Core_V2_Cmac_Init(CRYPTO_Type *base, cy_stc_crypto_v2_cmac_state_t* cmacState, cy_stc_crypto_v2_cmac_buffers_t* buffer)
106 {
107     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
108     cy_stc_crypto_v2_cmac_buffers_t *bufferRemap;
109     cy_stc_crypto_v2_cmac_state_t *cmacStateRemap;
110 
111     if( (NULL != cmacState) && (NULL != buffer))
112     {
113         bufferRemap = (cy_stc_crypto_v2_cmac_buffers_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(buffer);
114         cmacStateRemap = (cy_stc_crypto_v2_cmac_state_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState);
115 
116         Cy_Crypto_Core_V2_MemSet(base, cmacStateRemap, 0U, (uint16_t)sizeof(cy_stc_crypto_v2_cmac_state_t));
117         Cy_Crypto_Core_V2_MemSet(base, bufferRemap, 0U, (uint16_t)sizeof(cy_stc_crypto_v2_cmac_buffers_t));
118 
119         cmacState->k = buffer->k;
120         cmacState->temp = buffer->temp;
121         cmacState->aesState.buffers = &buffer->aesBuffersData;
122         tmpResult = CY_CRYPTO_SUCCESS;
123     }
124 
125     return tmpResult;
126 }
127 
128 
129 
130 /*******************************************************************************
131 * Function Name: Cy_Crypto_Core_V2_Cmac_Start
132 ****************************************************************************//**
133 *
134 * Starts CMAC calculation.
135 *
136 * \param base
137 * The pointer to the CRYPTO instance.
138 *
139 * \param cmacState
140 * The pointer to the structure which stores the CMAC context.
141 *
142 * \param aesKey
143 * The pointer to the cmac key.
144 *
145 * \param keyLength
146 * \ref cy_en_crypto_aes_key_length_t
147 *
148 * \return
149 * \ref cy_en_crypto_status_t
150 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac_Start(CRYPTO_Type * base,cy_stc_crypto_v2_cmac_state_t * cmacState,uint8_t const * aesKey,cy_en_crypto_aes_key_length_t keyLength)151 cy_en_crypto_status_t Cy_Crypto_Core_V2_Cmac_Start(CRYPTO_Type *base, cy_stc_crypto_v2_cmac_state_t *cmacState,
152                                                    uint8_t const *aesKey, cy_en_crypto_aes_key_length_t keyLength)
153 {
154 
155     cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
156     uint8_t *kRemap;
157 
158     kRemap =  (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->k);
159 
160     status = Cy_Crypto_Core_V2_Aes_Init(base, aesKey, keyLength, &cmacState->aesState, cmacState->aesState.buffers);
161 
162     if(status != CY_CRYPTO_SUCCESS)
163     {
164         return status;
165     }
166 
167     Cy_Crypto_Core_V2_Aes_LoadEncKey(base, &cmacState->aesState);
168 
169     /* Calculate the K1 sub-key */
170     Cy_Crypto_Core_V2_BlockXor(base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_BLOCK0,
171                                      CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_AES_BLOCK_SIZE);
172     Cy_Crypto_Core_V2_RunAes(base);
173     Cy_Crypto_Core_V2_FFStart (base, CY_CRYPTO_V2_RB_FF_STORE, kRemap, CY_CRYPTO_AES_BLOCK_SIZE);
174     Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_FF_STORE, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_AES_BLOCK_SIZE);
175     Cy_Crypto_Core_V2_Sync(base);
176 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
177     SCB_InvalidateDCache_by_Addr(cmacState->k, (int32_t)CY_CRYPTO_AES_BLOCK_SIZE);
178 #endif
179     Cy_Crypto_Core_V2_Cmac_CalcSubKey(cmacState->k);
180 
181     return status;
182 }
183 
184 
185 /*******************************************************************************
186 * Function Name: Cy_Crypto_Core_V2_Cmac_Update
187 ****************************************************************************//**
188 *
189 * Performs cmac update for multi stage operation.
190 *
191 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameter message must align and end in 32 byte boundary.
192 *
193 * \param base
194 * The pointer to the CRYPTO instance.
195 *
196 * \param cmacState
197 * The pointer to the structure which stores the CMAC context.
198 *
199 * \param message
200 * The pointer to the message whose CMAC is being computed.
201 *
202 * \param messageSize
203 * The size of the message whose CMAC is being computed.
204 *
205 * \return
206 * \ref cy_en_crypto_status_t
207 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac_Update(CRYPTO_Type * base,cy_stc_crypto_v2_cmac_state_t * cmacState,uint8_t const * message,uint32_t messageSize)208 cy_en_crypto_status_t Cy_Crypto_Core_V2_Cmac_Update(CRYPTO_Type *base,
209                                                     cy_stc_crypto_v2_cmac_state_t *cmacState,
210                                                     uint8_t const *message,
211                                                     uint32_t  messageSize)
212 {
213     uint32_t count = 0u;
214     uint32_t cnt=0u;
215     cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
216     uint8_t *tempRemap;
217     cy_stc_crypto_aes_buffers_t  *bufferRemap;
218     uint8_t *messageRemap;
219 
220 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
221     /* Flush the cache */
222     SCB_CleanDCache_by_Addr((volatile void *)message,(int32_t)messageSize);
223 #endif
224 
225     if(messageSize == 0u)
226     {
227         return CY_CRYPTO_SUCCESS;
228     }
229 
230     tempRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->temp);
231     bufferRemap = (cy_stc_crypto_aes_buffers_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->aesState.buffers);
232 
233     messageRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(message);
234 
235     if(cmacState->aesState.unProcessedBytes > 0u && messageSize > CY_CRYPTO_AES_BLOCK_SIZE-cmacState->aesState.unProcessedBytes)
236     {
237         Cy_Crypto_Core_V2_MemCpy(base, (void*)&bufferRemap->unProcessedData[cmacState->aesState.unProcessedBytes], (void*)messageRemap, (uint16_t)(CY_CRYPTO_AES_BLOCK_SIZE-cmacState->aesState.unProcessedBytes));
238 
239         Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, tempRemap, CY_CRYPTO_AES_BLOCK_SIZE);
240         Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_AES_BLOCK_SIZE);
241         Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, bufferRemap->unProcessedData, CY_CRYPTO_AES_BLOCK_SIZE);
242         Cy_Crypto_Core_V2_BlockXor(base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_AES_BLOCK_SIZE);
243 
244         Cy_Crypto_Core_V2_FFStart   (base, CY_CRYPTO_V2_RB_FF_STORE, tempRemap, CY_CRYPTO_AES_BLOCK_SIZE);
245         Cy_Crypto_Core_V2_BlockMov  (base, CY_CRYPTO_V2_RB_FF_STORE, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_AES_BLOCK_SIZE);
246 
247         status = Cy_Crypto_Core_V2_Aes_Ecb(base, cmacState->aesState.dirMode, tempRemap, (void*)tempRemap, &cmacState->aesState);
248 
249         if(CY_CRYPTO_SUCCESS != status)
250         {
251             return status;
252         }
253 
254         messageSize -= CY_CRYPTO_AES_BLOCK_SIZE-cmacState->aesState.unProcessedBytes;
255         messageRemap+= CY_CRYPTO_AES_BLOCK_SIZE-cmacState->aesState.unProcessedBytes;
256         cmacState->aesState.unProcessedBytes = 0u;
257     }
258 
259     cnt = (uint32_t)((messageSize + CY_CRYPTO_AES_BLOCK_SIZE -1u) / CY_CRYPTO_AES_BLOCK_SIZE);
260 
261     if(cnt > 1u)
262     {
263         --cnt;
264         count =  cnt*CY_CRYPTO_AES_BLOCK_SIZE;
265 
266         Cy_Crypto_Core_V2_Aes_LoadEncKey(base, &cmacState->aesState);
267         Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, tempRemap, CY_CRYPTO_AES_BLOCK_SIZE);
268         Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_AES_BLOCK_SIZE);
269 
270         Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, messageRemap, count);
271 
272         while (count > 0u)
273         {
274             Cy_Crypto_Core_V2_BlockXor(base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_FF_LOAD0,
275                                             CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_AES_BLOCK_SIZE);
276             Cy_Crypto_Core_V2_RunAes(base);
277             count -= CY_CRYPTO_AES_BLOCK_SIZE;
278         }
279 
280         Cy_Crypto_Core_V2_FFStart   (base, CY_CRYPTO_V2_RB_FF_STORE, tempRemap, CY_CRYPTO_AES_BLOCK_SIZE);
281         Cy_Crypto_Core_V2_BlockMov  (base, CY_CRYPTO_V2_RB_FF_STORE, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_AES_BLOCK_SIZE);
282 
283         messageSize -= cnt*CY_CRYPTO_AES_BLOCK_SIZE;
284         messageRemap += cnt*CY_CRYPTO_AES_BLOCK_SIZE;
285     }
286 
287     if(messageSize > 0u)
288     {
289         Cy_Crypto_Core_V2_MemCpy(base, (void*)&bufferRemap->unProcessedData[cmacState->aesState.unProcessedBytes], (void*)messageRemap, (uint16_t)messageSize);
290         cmacState->aesState.unProcessedBytes += messageSize;
291     }
292 
293     return CY_CRYPTO_SUCCESS;
294 }
295 
296 
297 
298 /*******************************************************************************
299 * Function Name: Cy_Crypto_Core_V2_Cmac_Finish
300 ****************************************************************************//**
301 *
302 * Completes CMAC calculation.
303 *
304 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameter cmac must align and end in 32 byte boundary.
305 *
306 * \param cmacState
307 * The pointer to the structure which stores the CMAC context.
308 *
309 * \param base
310 * The pointer to the CRYPTO instance.
311 *
312 * \param cmac
313 * The pointer to the computed CMAC value.
314 *
315 * \return
316 * \ref cy_en_crypto_status_t
317 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac_Finish(CRYPTO_Type * base,cy_stc_crypto_v2_cmac_state_t * cmacState,uint8_t * cmac)318 cy_en_crypto_status_t Cy_Crypto_Core_V2_Cmac_Finish(CRYPTO_Type *base, cy_stc_crypto_v2_cmac_state_t *cmacState, uint8_t* cmac)
319 {
320 
321 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
322     CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static const uint8_t p_padding[16] =
323     {
324         0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
325         0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u
326     };
327 #else
328     uint8_t const p_padding[16] =
329     {
330         0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
331         0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u
332     };
333 #endif
334 
335     uint8_t *tempRemap;
336     uint8_t  *kRemap;
337     uint8_t *cmacRemap;
338     cy_stc_crypto_aes_buffers_t * bufferRemap;
339 
340     cmacRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmac);
341     tempRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->temp);
342     kRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->k);
343     bufferRemap = (cy_stc_crypto_aes_buffers_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->aesState.buffers);
344 
345 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
346         /* Flush the cache */
347         SCB_CleanDCache_by_Addr((volatile void *)p_padding,(int32_t)CY_CRYPTO_AES_BLOCK_SIZE);
348 #endif
349 
350     Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, tempRemap, CY_CRYPTO_AES_BLOCK_SIZE);
351     Cy_Crypto_Core_V2_BlockMov(base, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_V2_RB_FF_LOAD0, CY_CRYPTO_AES_BLOCK_SIZE);
352 
353     Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, bufferRemap->unProcessedData, cmacState->aesState.unProcessedBytes);
354 
355     if(cmacState->aesState.unProcessedBytes < CY_CRYPTO_AES_BLOCK_SIZE)
356     {
357         Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, (const uint8_t*)CY_REMAP_ADDRESS_FOR_CRYPTO(p_padding), CY_CRYPTO_AES_BLOCK_SIZE - cmacState->aesState.unProcessedBytes);
358         Cy_Crypto_Core_V2_Cmac_CalcSubKey(cmacState->k);        /* calculate "k2" */
359     }
360 
361     Cy_Crypto_Core_V2_BlockXor  (base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_FF_LOAD0,
362                                     CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_AES_BLOCK_SIZE);
363 
364     Cy_Crypto_Core_V2_FFContinue(base, CY_CRYPTO_V2_RB_FF_LOAD0, kRemap, CY_CRYPTO_AES_BLOCK_SIZE);
365     Cy_Crypto_Core_V2_BlockXor  (base, CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_V2_RB_FF_LOAD0,
366                                        CY_CRYPTO_V2_RB_BLOCK0, CY_CRYPTO_AES_BLOCK_SIZE);
367     Cy_Crypto_Core_V2_RunAes(base);
368 
369     Cy_Crypto_Core_V2_FFStart   (base, CY_CRYPTO_V2_RB_FF_STORE, cmacRemap, CY_CRYPTO_AES_BLOCK_SIZE);
370     Cy_Crypto_Core_V2_BlockMov  (base, CY_CRYPTO_V2_RB_FF_STORE, CY_CRYPTO_V2_RB_BLOCK1, CY_CRYPTO_AES_BLOCK_SIZE);
371     Cy_Crypto_Core_V2_Sync(base);
372 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
373     SCB_InvalidateDCache_by_Addr(cmac, (int32_t)CY_CRYPTO_AES_BLOCK_SIZE);
374 #endif
375 
376     return (CY_CRYPTO_SUCCESS);
377 }
378 
379 
380 
381 /*******************************************************************************
382 * Function Name: Cy_Crypto_Core_V2_Cmac_Free
383 ****************************************************************************//**
384 *
385 *
386 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameter cmac must align and end in 32 byte boundary.
387 *
388 * \param base
389 * The pointer to the CRYPTO instance.
390 *
391 * \param cmacState
392 * The pointer to the structure which stores the CMAC context.
393 *
394 * \return
395 * \ref cy_en_crypto_status_t
396 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac_Free(CRYPTO_Type * base,cy_stc_crypto_v2_cmac_state_t * cmacState)397 cy_en_crypto_status_t Cy_Crypto_Core_V2_Cmac_Free(CRYPTO_Type *base,
398                                 cy_stc_crypto_v2_cmac_state_t *cmacState
399                                 )
400 
401 
402 {
403     uint8_t *tempRemap;
404     uint8_t  *kRemap;
405     cy_stc_crypto_aes_buffers_t  *bufferRemap;
406 
407     if( (NULL != base) && (NULL != cmacState))
408     {
409         bufferRemap = (cy_stc_crypto_aes_buffers_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->aesState.buffers);
410         tempRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->k);
411         kRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(cmacState->k);
412 
413         if(bufferRemap  != NULL)
414         {
415             Cy_Crypto_Core_V2_MemSet(base, bufferRemap, 0U, (uint16_t)sizeof(cy_stc_crypto_aes_buffers_t));
416         }
417 
418         if(kRemap != NULL)
419         {
420             Cy_Crypto_Core_V2_MemSet(base, kRemap, 0U, CY_CRYPTO_AES_BLOCK_SIZE);
421         }
422 
423         if(tempRemap  != NULL)
424         {
425             Cy_Crypto_Core_V2_MemSet(base, tempRemap, 0U, CY_CRYPTO_AES_BLOCK_SIZE);
426         }
427 
428         Cy_Crypto_Core_V2_MemSet(base, cmacState, 0U, (uint16_t)sizeof(cy_stc_crypto_v2_cmac_state_t));
429     }
430 
431     return CY_CRYPTO_SUCCESS;
432 }
433 
434 
435 /*******************************************************************************
436 * Function Name: Cy_Crypto_Core_V2_Cmac
437 ****************************************************************************//**
438 *
439 * Performs CMAC(Cipher-based Message Authentication Code) operation
440 * on a message to produce message authentication code using AES.
441 *
442 * For CAT1A and CAT1C devices with DCache disabled, message & key must be 4-Byte aligned.
443 *
444 * \param base
445 * The pointer to the CRYPTO instance.
446 *
447 * \param message
448 * The pointer to a source plain text.
449 *
450 * \param messageSize
451 * The size of a source plain text.
452 *
453 * \param key
454 * The pointer to the encryption key.
455 *
456 * \param keyLength
457 * \ref cy_en_crypto_aes_key_length_t
458 *
459 * \param cmac
460 * The pointer to the calculated CMAC.
461 *
462 * \param aesState
463 * The pointer to the AES state structure allocated by the user. The user
464 * must not modify anything in this structure.
465 *
466 * \return
467 * \ref cy_en_crypto_status_t
468 *
469 *******************************************************************************/
Cy_Crypto_Core_V2_Cmac(CRYPTO_Type * base,uint8_t const * message,uint32_t messageSize,uint8_t const * key,cy_en_crypto_aes_key_length_t keyLength,uint8_t * cmac,cy_stc_crypto_aes_state_t * aesState)470 cy_en_crypto_status_t Cy_Crypto_Core_V2_Cmac(CRYPTO_Type *base,
471                                           uint8_t const *message,
472                                           uint32_t messageSize,
473                                           uint8_t const *key,
474                                           cy_en_crypto_aes_key_length_t keyLength,
475                                           uint8_t *cmac,
476                                           cy_stc_crypto_aes_state_t *aesState)
477 {
478     (void)aesState;
479 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
480     /* Allocate space for the structure which stores the CMAC context */
481     CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static cy_stc_crypto_v2_cmac_buffers_t  cmacBuffersData;
482     CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static cy_stc_crypto_v2_cmac_state_t  cmacStateLoc = {{CY_CRYPTO_KEY_AES_128, NULL,0u,0u,0u,CY_CRYPTO_ENCRYPT}, NULL, NULL};
483 
484 #else
485     /* Allocate space for the structure which stores the CMAC context */
486     cy_stc_crypto_v2_cmac_buffers_t  cmacBuffersData = {0u};
487     cy_stc_crypto_v2_cmac_state_t  cmacStateLoc = {{CY_CRYPTO_KEY_AES_128, NULL,0u,0u,0u,CY_CRYPTO_ENCRYPT}, NULL, NULL};
488 
489 #endif
490 
491 
492     cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
493 
494     Cy_Crypto_Core_V2_MemSet(base, CY_REMAP_ADDRESS_FOR_CRYPTO(&cmacBuffersData), 0, (uint16_t)sizeof(cy_stc_crypto_v2_cmac_buffers_t));
495     Cy_Crypto_Core_V2_MemSet(base, CY_REMAP_ADDRESS_FOR_CRYPTO(&cmacStateLoc), 0, (uint16_t)sizeof(cy_stc_crypto_v2_cmac_state_t));
496 
497     status = Cy_Crypto_Core_V2_Cmac_Init  (base, &cmacStateLoc, &cmacBuffersData);
498 
499     if(CY_CRYPTO_SUCCESS == status)
500     {
501         status = Cy_Crypto_Core_V2_Cmac_Start (base, &cmacStateLoc, key, keyLength);
502     }
503 
504     if(CY_CRYPTO_SUCCESS == status)
505     {
506         status = Cy_Crypto_Core_V2_Cmac_Update(base, &cmacStateLoc,  message, messageSize);
507     }
508 
509     if(CY_CRYPTO_SUCCESS == status)
510     {
511         status = Cy_Crypto_Core_V2_Cmac_Finish(base, &cmacStateLoc, cmac);
512     }
513 
514     return (CY_CRYPTO_SUCCESS);
515 }
516 
517 #endif /* (CPUSS_CRYPTO_AES == 1) && defined(CY_CRYPTO_CFG_CMAC_C) */
518 
519 #if defined(__cplusplus)
520 }
521 #endif
522 
523 #endif /* defined(CY_CRYPTO_CFG_HW_V2_ENABLE) */
524 
525 #endif /* defined(CY_IP_MXCRYPTO) */
526 
527 
528 /* [] END OF FILE */
529