1 /***************************************************************************//**
2 * \file cy_crypto_core_hmac_v2.c
3 * \version 2.120
4 *
5 * \brief
6 * This file provides the source code to the API for the HMAC method
7 * in the Crypto block driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include "cy_device.h"
29
30 #if defined(CY_IP_MXCRYPTO)
31
32 #include "cy_crypto_core_hmac_v2.h"
33
34 #if defined(CY_CRYPTO_CFG_HW_V2_ENABLE)
35
36 #if defined(__cplusplus)
37 extern "C" {
38 #endif
39
40 #if (CPUSS_CRYPTO_SHA == 1) && defined(CY_CRYPTO_CFG_HMAC_C)
41
42 #include "cy_crypto_core_sha_v2.h"
43 #include "cy_crypto_core_mem_v2.h"
44 #include "cy_syslib.h"
45
46 /*****************************************************************************
47 * Cy_Crypto_Core_V2_Hmac_Init
48 ******************************************************************************
49 *
50 * The function to initialize the HMAC operation.
51 *
52 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameters hmacState and hmacBuffer must align and end in 32 byte boundary.
53 *
54 * \param base
55 * The pointer to the CRYPTO instance.
56 *
57 * \param hmacState
58 * The pointer to the cy_stc_crypto_hmac_state_t structure that stores all
59 * internal state for mxcrypto driver.
60 *
61 * \param mode
62 * The hash mode for HMAC.
63 *
64 * \param hmacBuffer
65 * The pointer to the cy_stc_crypto_v2_hmac_buffers_t structure that stores all
66 * buffers for HMAC operation.
67 *
68 * \return
69 * cy_en_crypto_status_t
70 *
71 *******************************************************************************/
72
Cy_Crypto_Core_V2_Hmac_Init(CRYPTO_Type * base,cy_stc_crypto_hmac_state_t * hmacState,cy_en_crypto_sha_mode_t mode,cy_stc_crypto_v2_hmac_buffers_t * hmacBuffer)73 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hmac_Init(CRYPTO_Type *base, cy_stc_crypto_hmac_state_t *hmacState, cy_en_crypto_sha_mode_t mode, cy_stc_crypto_v2_hmac_buffers_t *hmacBuffer)
74 {
75
76
77 /* Input parameters verification */
78 if ((NULL == base) || (NULL == hmacState) || (NULL == hmacBuffer))
79 {
80 return CY_CRYPTO_BAD_PARAMS;
81 }
82
83 hmacState->ipad = hmacBuffer->ipad;
84 hmacState->opad = hmacBuffer->opad;
85 hmacState->m0Key = hmacBuffer->m0Key;
86 hmacState->sha_buffer = &hmacBuffer->shaBuffers;
87
88
89 return Cy_Crypto_Core_V2_Sha_Init(base, &hmacState->hashState, mode, hmacState->sha_buffer);
90
91 }
92
93
94
95 /*******************************************************************************
96 * Cy_Crypto_Core_V2_Hmac_Start
97 ******************************************************************************
98 *
99 * Initializes the initial Hash vector.
100 *
101 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameters key & hmacState (m0Key) must align and end in 32 byte boundary.
102 *
103 * \param base
104 * The pointer to the CRYPTO instance.
105 *
106 * \param hmacState
107 * The pointer to the cy_stc_crypto_hmac_state_t structure that stores all
108 * internal state for mxcrypto driver.
109 *
110 * \param key
111 * The pointer to the HMAC key.
112 *
113 * \param keyLength
114 * The size of the input key
115 *
116 * \return
117 * cy_en_crypto_status_t
118 *
119 *******************************************************************************/
120
Cy_Crypto_Core_V2_Hmac_Start(CRYPTO_Type * base,cy_stc_crypto_hmac_state_t * hmacState,uint8_t const * key,uint32_t keyLength)121 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hmac_Start(CRYPTO_Type *base, cy_stc_crypto_hmac_state_t *hmacState,
122 uint8_t const *key,
123 uint32_t keyLength
124 )
125
126 {
127
128 uint32_t i = 0uL;
129 uint32_t blockSizeTmp;
130 uint32_t digestSizeTmp;
131 uint8_t *ipadRemap;
132 uint8_t *opadRemap;
133 uint8_t *m0KeyRemap;
134 cy_en_crypto_status_t status = CY_CRYPTO_SUCCESS;
135 uint8_t *ipadPtr;
136 uint8_t *opadPtr;
137 uint8_t *m0KeyPtr;
138
139 /* Input parameters verification */
140 if ((NULL == base) || (NULL == hmacState) || ((NULL == key) && (0UL != keyLength)) )
141 {
142 return CY_CRYPTO_BAD_PARAMS;
143 }
144
145 blockSizeTmp = hmacState->hashState.blockSize;
146 digestSizeTmp = hmacState->hashState.digestSize;
147 ipadRemap = (uint8_t*)CY_REMAP_ADDRESS_FOR_CRYPTO(hmacState->ipad);
148 opadRemap = (uint8_t*)CY_REMAP_ADDRESS_FOR_CRYPTO(hmacState->opad);
149 m0KeyRemap = (uint8_t*)CY_REMAP_ADDRESS_FOR_CRYPTO(hmacState->m0Key);
150
151 ipadPtr = hmacState->ipad;
152 opadPtr = hmacState->opad;
153 m0KeyPtr = hmacState->m0Key;
154
155 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
156 /* Flush the cache */
157 SCB_CleanDCache_by_Addr((volatile void *)key,(int32_t)keyLength);
158 #endif
159 Cy_Crypto_Core_V2_MemSet(base, m0KeyRemap, 0x00u, (uint16_t)blockSizeTmp);
160 Cy_Crypto_Core_V2_MemSet(base, ipadRemap, 0x00u, (uint16_t)blockSizeTmp);
161 Cy_Crypto_Core_V2_MemSet(base, opadRemap, 0x00u, (uint16_t)blockSizeTmp);
162
163 /* Steps 1-3 according to FIPS 198-1 */
164 if (keyLength > blockSizeTmp)
165 {
166 /* The key is larger than the block size. Do a hash on the key. */
167 status = Cy_Crypto_Core_V2_Sha_Start (base, &hmacState->hashState);
168
169 if (CY_CRYPTO_SUCCESS == status)
170 {
171 status = Cy_Crypto_Core_V2_Sha_Update (base, &hmacState->hashState, key, keyLength);
172 }
173 if (CY_CRYPTO_SUCCESS == status)
174 {
175 status = Cy_Crypto_Core_V2_Sha_Finish (base, &hmacState->hashState, m0KeyRemap);
176 }
177
178 /* Append zeros */
179 Cy_Crypto_Core_V2_MemSet(base, (m0KeyRemap + digestSizeTmp), 0x00u, (uint16_t)(blockSizeTmp - digestSizeTmp));
180 }
181 else if (keyLength < blockSizeTmp)
182 {
183 /* If the key is shorter than the block, append zeros */
184 Cy_Crypto_Core_V2_MemCpy(base, m0KeyRemap, key, (uint16_t)keyLength);
185 Cy_Crypto_Core_V2_MemSet(base, m0KeyRemap + keyLength, 0x00u, (uint16_t)(blockSizeTmp - keyLength));
186 }
187 else
188 {
189 Cy_Crypto_Core_V2_MemCpy(base, m0KeyRemap, key, (uint16_t)keyLength);
190 }
191 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
192 SCB_InvalidateDCache_by_Addr(hmacState->m0Key, (int32_t)blockSizeTmp);
193 #endif
194
195 if (CY_CRYPTO_SUCCESS == status)
196 {
197 /* Steps 4 and 7 according to FIPS 198-1 */
198 while (i < blockSizeTmp)
199 {
200 ipadPtr[i] = CY_CRYPTO_HMAC_IPAD ^ m0KeyPtr[i];
201 opadPtr[i] = CY_CRYPTO_HMAC_0PAD ^ m0KeyPtr[i];
202 i++;
203 }
204
205 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
206 SCB_CleanDCache_by_Addr((volatile void *)hmacState->ipad,(int32_t)CY_CRYPTO_HMAC_MAX_PAD_SIZE);
207 SCB_CleanDCache_by_Addr((volatile void *)hmacState->opad,(int32_t)CY_CRYPTO_HMAC_MAX_PAD_SIZE);
208 #endif
209
210
211 /* Step 6 according to FIPS 198-1 */
212 status = Cy_Crypto_Core_V2_Sha_Start (base, &hmacState->hashState);
213
214 if (CY_CRYPTO_SUCCESS == status)
215 {
216 status = Cy_Crypto_Core_V2_Sha_Update(base, &hmacState->hashState, ipadRemap, blockSizeTmp);
217 }
218
219 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
220 SCB_InvalidateDCache_by_Addr((volatile void *)hmacState->ipad,(int32_t)CY_CRYPTO_HMAC_MAX_PAD_SIZE);
221 SCB_InvalidateDCache_by_Addr((volatile void *)hmacState->opad,(int32_t)CY_CRYPTO_HMAC_MAX_PAD_SIZE);
222 #endif
223 }
224
225 return status;
226
227 }
228
229
230 /*******************************************************************************
231 * Cy_Crypto_Core_V2_Hmac_Update
232 ******************************************************************************
233 *
234 * Performs the multipart hmac operation.
235 *
236 * \param base
237 * The pointer to the CRYPTO instance.
238 *
239 * \param hmacState
240 * The pointer to the cy_stc_crypto_hmac_state_t structure that stores all
241 * internal state for mxcrypto driver.
242 *
243 * \param message
244 * The pointer to the message.
245 *
246 * \param messageSize
247 * The size of the message
248 *
249 * \return
250 * cy_en_crypto_status_t
251 *
252 *******************************************************************************/
253
Cy_Crypto_Core_V2_Hmac_Update(CRYPTO_Type * base,cy_stc_crypto_hmac_state_t * hmacState,uint8_t const * message,uint32_t messageSize)254 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hmac_Update(CRYPTO_Type *base, cy_stc_crypto_hmac_state_t *hmacState,
255 uint8_t const *message,
256 uint32_t messageSize
257 )
258 {
259
260 if (0UL == messageSize)
261 {
262 return CY_CRYPTO_SUCCESS;
263 }
264
265 /* Input parameters verification */
266 if ((NULL == base) || (NULL == hmacState) || (NULL == message))
267 {
268 return CY_CRYPTO_BAD_PARAMS;
269 }
270
271 return Cy_Crypto_Core_V2_Sha_Update(base, &hmacState->hashState, message, messageSize);
272
273 }
274
275
276
277 /*******************************************************************************
278 * Cy_Crypto_Core_V2_Hmac_Finish
279 ******************************************************************************
280 *
281 * Finishes the hmac operation.
282 *
283 * \param base
284 * The pointer to the CRYPTO instance.
285 *
286 * \param hmacState
287 * The pointer to the cy_stc_crypto_hmac_state_t structure that stores all
288 * internal state for mxcrypto driver.
289 *
290 * \param hmac
291 * The pointer to store the hmac value.
292 *
293 * \return
294 * cy_en_crypto_status_t
295 *
296 *******************************************************************************/
297
Cy_Crypto_Core_V2_Hmac_Finish(CRYPTO_Type * base,cy_stc_crypto_hmac_state_t * hmacState,uint8_t * hmac)298 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hmac_Finish(CRYPTO_Type *base, cy_stc_crypto_hmac_state_t *hmacState,
299 uint8_t *hmac)
300
301 {
302 uint32_t blockSizeTmp;
303 uint32_t digestSizeTmp;
304 uint8_t *ipadPtrTmp;
305 uint8_t *opadPtrTmp;
306 cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
307
308 /* Input parameters verification */
309 if ((NULL == base) || (NULL == hmacState) || (NULL == hmac))
310 {
311 return status;
312 }
313
314 blockSizeTmp = hmacState->hashState.blockSize;
315 digestSizeTmp = hmacState->hashState.digestSize;
316 ipadPtrTmp = (uint8_t*)hmacState->ipad;
317 opadPtrTmp = (uint8_t*)hmacState->opad;
318
319 status = Cy_Crypto_Core_V2_Sha_Finish(base, &hmacState->hashState, ipadPtrTmp);
320
321 /* Here is the ready part of HASH: Hash((Key^ipad)||text) */
322
323 if (CY_CRYPTO_SUCCESS == status)
324 {
325 /* Steps 8, 9 according to FIPS 198-1 */
326 status = Cy_Crypto_Core_V2_Sha_Start(base, &hmacState->hashState);
327
328 if (CY_CRYPTO_SUCCESS == status)
329 {
330 status = Cy_Crypto_Core_V2_Sha_Update(base, &hmacState->hashState, opadPtrTmp, blockSizeTmp);
331 }
332
333 /* Append HASH from Step 6 */
334 if (CY_CRYPTO_SUCCESS == status)
335 {
336 status = Cy_Crypto_Core_V2_Sha_Update(base, &hmacState->hashState, ipadPtrTmp, digestSizeTmp);
337 }
338
339 if (CY_CRYPTO_SUCCESS == status)
340 {
341 status = Cy_Crypto_Core_V2_Sha_Finish(base, &hmacState->hashState, hmac);
342 }
343
344 if (CY_CRYPTO_SUCCESS == status)
345 {
346 status = Cy_Crypto_Core_V2_Sha_Free(base, &hmacState->hashState);
347 }
348 }
349
350 return status;
351
352 }
353
354
355 /*******************************************************************************
356 * Cy_Crypto_Core_V2_Hmac_Free
357 ******************************************************************************
358 *
359 * Frees the internally stored buffers in hmac context.
360 *
361 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameters hmacState must align and end in 32 byte boundary.
362 *
363 * \param base
364 * The pointer to the CRYPTO instance.
365 *
366 * \param hmacState
367 * The pointer to the cy_stc_crypto_hmac_state_t structure that stores all
368 * internal state for mxcrypto driver.
369 *
370 *
371 * \return
372 * cy_en_crypto_status_t
373 *
374 *******************************************************************************/
Cy_Crypto_Core_V2_Hmac_Free(CRYPTO_Type * base,cy_stc_crypto_hmac_state_t * hmacState)375 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hmac_Free(CRYPTO_Type *base, cy_stc_crypto_hmac_state_t *hmacState)
376 {
377 /* Input parameters verification */
378 if ( (NULL != base) && (NULL != hmacState))
379 {
380 /* Clear the memory buffer. */
381
382 if (NULL != hmacState->ipad)
383 {
384 Cy_Crypto_Core_V2_MemSet(base, hmacState->ipad, 0u, CY_CRYPTO_HMAC_MAX_PAD_SIZE);
385 }
386
387 if (NULL != hmacState->opad)
388 {
389 Cy_Crypto_Core_V2_MemSet(base, hmacState->opad, 0u, CY_CRYPTO_HMAC_MAX_PAD_SIZE);
390 }
391
392 if (NULL != hmacState->m0Key)
393 {
394 Cy_Crypto_Core_V2_MemSet(base, hmacState->m0Key, 0u, CY_CRYPTO_SHA_MAX_BLOCK_SIZE);
395 }
396
397 Cy_Crypto_Core_V2_MemSet(base, hmacState, 0u, ((uint16_t)sizeof(cy_stc_crypto_hmac_state_t)));
398 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
399 SCB_InvalidateDCache_by_Addr(hmacState->ipad, (int32_t)CY_CRYPTO_HMAC_MAX_PAD_SIZE);
400 SCB_InvalidateDCache_by_Addr(hmacState->opad, (int32_t)CY_CRYPTO_HMAC_MAX_PAD_SIZE);
401 SCB_InvalidateDCache_by_Addr(hmacState->m0Key, (int32_t)CY_CRYPTO_SHA_MAX_BLOCK_SIZE);
402 SCB_InvalidateDCache_by_Addr(hmacState, (int32_t)sizeof(cy_stc_crypto_hmac_state_t));
403 #endif
404
405 }
406
407
408 return CY_CRYPTO_SUCCESS;
409
410 }
411
412 /*******************************************************************************
413 * Function Name: Cy_Crypto_Core_V2_Hmac
414 ****************************************************************************//**
415 *
416 * Performs HMAC calculation.
417 *
418 * For CAT1A and CAT1C devices with DCache disabled, hmac must be 4-byte aligned.
419 *
420 * \param base
421 * The pointer to the CRYPTO instance.
422 *
423 * \param hmac
424 * The pointer to the calculated HMAC.
425 *
426 * \param message
427 * The pointer to a message whose hash value is being computed.
428 *
429 * \param messageSize
430 * The size of a message.
431 *
432 * \param key
433 * The pointer to the key.
434 *
435 * \param keyLength
436 * The length of the key.
437 *
438 * \param mode
439 * \ref cy_en_crypto_sha_mode_t
440 *
441 * \return
442 * \ref cy_en_crypto_status_t
443 *
444 *******************************************************************************/
Cy_Crypto_Core_V2_Hmac(CRYPTO_Type * base,uint8_t * hmac,uint8_t const * message,uint32_t messageSize,uint8_t const * key,uint32_t keyLength,cy_en_crypto_sha_mode_t mode)445 cy_en_crypto_status_t Cy_Crypto_Core_V2_Hmac(CRYPTO_Type *base,
446 uint8_t *hmac,
447 uint8_t const *message,
448 uint32_t messageSize,
449 uint8_t const *key,
450 uint32_t keyLength,
451 cy_en_crypto_sha_mode_t mode)
452 {
453 cy_en_crypto_status_t status = CY_CRYPTO_BAD_PARAMS;
454 /* Allocating internal variables into the RAM */
455 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
456 CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static cy_stc_crypto_hmac_state_t hmacState;
457 CY_ALIGN(__SCB_DCACHE_LINE_SIZE) static cy_stc_crypto_v2_hmac_buffers_t hmacBuffer;
458 #else
459 cy_stc_crypto_hmac_state_t hmacState = {0};
460 cy_stc_crypto_v2_hmac_buffers_t hmacBuffer = {0};
461 #endif
462
463 /* Input parameters verification */
464 if ((NULL == base) || (NULL == hmac) || ((NULL == message) && (0UL != messageSize))
465 ||((NULL == key) && (0UL != keyLength)))
466 {
467 return status;
468 }
469
470 Cy_Crypto_Core_V2_MemSet(base, (void*)&hmacState, 0x00U, (uint16_t)sizeof(cy_stc_crypto_hmac_state_t));
471 Cy_Crypto_Core_V2_MemSet(base, (void*)&hmacBuffer, 0x00U, (uint16_t)sizeof(cy_stc_crypto_v2_hmac_buffers_t));
472
473 status = Cy_Crypto_Core_V2_Hmac_Init(base, &hmacState, mode, &hmacBuffer);
474
475 if (CY_CRYPTO_SUCCESS == status)
476 {
477 status = Cy_Crypto_Core_V2_Hmac_Start(base, &hmacState, key, keyLength);
478 }
479
480 if (CY_CRYPTO_SUCCESS == status)
481 {
482 status = Cy_Crypto_Core_V2_Hmac_Update(base, &hmacState, message, messageSize);
483 }
484
485 if (CY_CRYPTO_SUCCESS == status)
486 {
487 status = Cy_Crypto_Core_V2_Hmac_Finish(base, &hmacState, hmac);
488 }
489
490 if (CY_CRYPTO_SUCCESS == status)
491 {
492 status = Cy_Crypto_Core_V2_Hmac_Free(base, &hmacState);
493 }
494
495 return (status);
496 }
497
498 #endif /* (CPUSS_CRYPTO_SHA == 1) && defined(CY_CRYPTO_CFG_HMAC_C) */
499
500 #if defined(__cplusplus)
501 }
502 #endif
503
504 #endif /* defined(CY_CRYPTO_CFG_HW_V2_ENABLE) */
505
506 #endif /* defined(CY_IP_MXCRYPTO) */
507
508
509 /* [] END OF FILE */
510