1 /***************************************************************************//**
2 * \file cy_crypto_core_sha_v1.c
3 * \version 2.120
4 *
5 * \brief
6 * This file provides the source code to the API for the SHA 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_sha_v1.h"
33
34 #if defined(CY_CRYPTO_CFG_HW_V1_ENABLE)
35
36 #if defined(__cplusplus)
37 extern "C" {
38 #endif
39
40 #if (CPUSS_CRYPTO_SHA == 1) && defined(CY_CRYPTO_CFG_SHA_C)
41
42 #include "cy_crypto_core_hw_v1.h"
43 #include "cy_crypto_core_mem_v1.h"
44 #include "cy_syslib.h"
45
46 typedef enum
47 {
48 #if (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED)
49 CY_CRYPTO_V1_SHA_CTL_MODE_SHA1 = 0U,
50 #endif /*(CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED) */
51
52 #if (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
53 CY_CRYPTO_V1_SHA_CTL_MODE_SHA256 = 1U,
54 #endif /* (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED) */
55
56 #if (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
57 CY_CRYPTO_V1_SHA_CTL_MODE_SHA512 = 2U,
58 #endif /* (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED) */
59 } cy_en_crypto_v1_sha_hw_mode_t;
60
61
62 /*******************************************************************************
63 * Function Name: Cy_Crypto_Core_V1_Sha_ProcessBlock
64 ****************************************************************************//**
65 *
66 * Performs the SHA calculation on one block.
67 * All addresses must be 4-Byte aligned!
68 *
69 * \param base
70 * The pointer to the CRYPTO instance.
71 *
72 * \param hashState
73 * The pointer to a Hash State.
74 *
75 * \param block
76 * The pointer to the block whose Hash is being computed.
77 *
78 *******************************************************************************/
Cy_Crypto_Core_V1_Sha_ProcessBlock(CRYPTO_Type * base,cy_stc_crypto_sha_state_t * hashState,uint8_t const * block)79 void Cy_Crypto_Core_V1_Sha_ProcessBlock(CRYPTO_Type *base,
80 cy_stc_crypto_sha_state_t *hashState, uint8_t const *block)
81 {
82 /* Set the SHA mode */
83 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3','This piece of code is written for CRYPTO_V1_Type and will not execute for CRYPTO_V2_Type');
84 REG_CRYPTO_SHA_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_SHA_CTL_MODE, (uint32_t)hashState->modeHw));
85
86 Cy_Crypto_SetReg4Instr(base,
87 (uint32_t)block,
88 (uint32_t)hashState->hash, /* Initial hash */
89 (uint32_t)hashState->roundMem,
90 (uint32_t)hashState->hash); /* Digest */
91
92 /* Issue the SHA instruction */
93 Cy_Crypto_Run4ParamInstr(base,
94 CY_CRYPTO_V1_SHA_OPC,
95 CY_CRYPTO_RSRC0_SHIFT,
96 CY_CRYPTO_RSRC4_SHIFT,
97 CY_CRYPTO_RSRC8_SHIFT,
98 CY_CRYPTO_RSRC12_SHIFT);
99
100 /* Wait until the SHA instruction is complete */
101 while(0uL != _FLD2VAL(CRYPTO_STATUS_SHA_BUSY, REG_CRYPTO_STATUS(base)))
102 {
103 }
104 }
105
106 /*******************************************************************************
107 * Function Name: Cy_Crypto_Core_V1_Sha_Init
108 ****************************************************************************//**
109 *
110 * The function to initialize SHA operation.
111 *
112 * \param base
113 * The pointer to the CRYPTO instance.
114 *
115 * \param hashState
116 * The pointer to a Hash State.
117 *
118 * \param mode
119 * One of these: CY_CRYPTO_SHA256, CY_CRYPTO_SHA1, CY_CRYPTO_SHA256_224,
120 * CY_CRYPTO_SHA512, CY_CRYPTO_SHA384, CY_CRYPTO_SHA512_224, CY_CRYPTO_SHA512_256
121 *
122 * \param shaBuffers
123 * The pointer to the memory buffers storage, see \ref cy_stc_crypto_v1_sha_buffers_t
124 *
125 * \return
126 * \ref cy_en_crypto_status_t
127 *
128 *******************************************************************************/
Cy_Crypto_Core_V1_Sha_Init(CRYPTO_Type * base,cy_stc_crypto_sha_state_t * hashState,cy_en_crypto_sha_mode_t mode,void * shaBuffers)129 cy_en_crypto_status_t Cy_Crypto_Core_V1_Sha_Init(CRYPTO_Type *base,
130 cy_stc_crypto_sha_state_t *hashState,
131 cy_en_crypto_sha_mode_t mode,
132 void *shaBuffers)
133 {
134 cy_en_crypto_status_t tmpResult = CY_CRYPTO_SUCCESS;
135
136 (void)base; /* Suppress warning */
137
138 /* Initialization vectors for different modes of the SHA algorithm */
139 #if (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED)
140 static const uint32_t sha1InitHash[] =
141 {
142 0x67452301uL, 0xEFCDAB89uL, 0x98BADCFEuL, 0x10325476uL,
143 0xC3D2E1F0uL
144 };
145 #endif /* (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED) */
146
147 #if (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
148 static const uint32_t sha224InitHash[] =
149 {
150 0xC1059ED8uL, 0x367CD507uL, 0x3070DD17uL, 0xF70E5939uL,
151 0xFFC00B31uL, 0x68581511uL, 0x64F98FA7uL, 0xBEFA4FA4uL
152 };
153
154 static const uint32_t sha256InitHash[] =
155 {
156 0x6A09E667uL, 0xBB67AE85uL, 0x3C6EF372uL, 0xA54FF53AuL,
157 0x510E527FuL, 0x9B05688CuL, 0x1F83D9ABuL, 0x5BE0CD19uL
158 };
159 #endif /* (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED) */
160
161 #if (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
162 static const uint32_t sha512_224InitHash[] =
163 {
164 0x8C3D37C8uL, 0x19544DA2uL, 0x73E19966uL, 0x89DCD4D6uL,
165 0x1DFAB7AEuL, 0x32FF9C82uL, 0x679DD514uL, 0x582F9FCFuL,
166 0x0F6D2B69uL, 0x7BD44DA8uL, 0x77E36F73uL, 0x04C48942uL,
167 0x3F9D85A8uL, 0x6A1D36C8uL, 0x1112E6ADuL, 0x91D692A1uL
168 };
169
170 static const uint32_t sha512_256InitHash[] =
171 {
172 0x22312194uL, 0xFC2BF72CuL, 0x9F555FA3uL, 0xC84C64C2uL,
173 0x2393B86BuL, 0x6F53B151uL, 0x96387719uL, 0x5940EABDuL,
174 0x96283EE2uL, 0xA88EFFE3uL, 0xBE5E1E25uL, 0x53863992uL,
175 0x2B0199FCuL, 0x2C85B8AAuL, 0x0EB72DDCuL, 0x81C52CA2uL
176 };
177
178 static const uint32_t sha384InitHash[] =
179 {
180 0xCBBB9D5DuL, 0xC1059ED8uL, 0x629A292AuL, 0x367CD507uL,
181 0x9159015AuL, 0x3070DD17uL, 0x152FECD8uL, 0xF70E5939uL,
182 0x67332667uL, 0xFFC00B31uL, 0x8EB44A87uL, 0x68581511uL,
183 0xDB0C2E0DuL, 0x64F98FA7uL, 0x47B5481DuL, 0xBEFA4FA4uL
184 };
185
186 static const uint32_t sha512InitHash[] =
187 {
188 0x6A09E667uL, 0xF3BCC908uL, 0xBB67AE85uL, 0x84CAA73BuL,
189 0x3C6EF372uL, 0xFE94F82BuL, 0xA54FF53AuL, 0x5F1D36F1uL,
190 0x510E527FuL, 0xADE682D1uL, 0x9B05688CuL, 0x2B3E6C1FuL,
191 0x1F83D9ABuL, 0xFB41BD6BuL, 0x5BE0CD19uL, 0x137E2179uL
192 };
193 #endif /* (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED) */
194
195 CY_ASSERT_L1((shaBuffers != NULL) && (hashState != NULL));
196
197 switch (mode)
198 {
199 #if (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED)
200 case CY_CRYPTO_MODE_SHA1:
201 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha1_buffers_t*)shaBuffers)->block;
202 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha1_buffers_t*)shaBuffers)->hash;
203 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha1_buffers_t*)shaBuffers)->roundMem;
204
205 hashState->mode = (uint32_t)mode;
206 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA1;
207 hashState->initialHash = (const uint8_t*)sha1InitHash;
208 hashState->blockSize = CY_CRYPTO_SHA1_BLOCK_SIZE;
209 hashState->hashSize = CY_CRYPTO_SHA1_HASH_SIZE;
210 hashState->digestSize = CY_CRYPTO_SHA1_DIGEST_SIZE;
211 hashState->roundMemSize = CY_CRYPTO_SHA1_ROUND_MEM_SIZE;
212 break;
213 #endif /* (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED) */
214
215 #if (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
216 case CY_CRYPTO_MODE_SHA224:
217 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha256_buffers_t*)shaBuffers)->block;
218 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha256_buffers_t*)shaBuffers)->hash;
219 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha256_buffers_t*)shaBuffers)->roundMem;
220
221 hashState->mode = (uint32_t)mode;
222 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA256;
223 hashState->initialHash = (const uint8_t*)sha224InitHash;
224 hashState->blockSize = CY_CRYPTO_SHA256_BLOCK_SIZE;
225 hashState->hashSize = CY_CRYPTO_SHA256_HASH_SIZE;
226 hashState->digestSize = CY_CRYPTO_SHA224_DIGEST_SIZE;
227 hashState->roundMemSize = CY_CRYPTO_SHA256_ROUND_MEM_SIZE;
228 break;
229
230 case CY_CRYPTO_MODE_SHA256:
231 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha256_buffers_t*)shaBuffers)->block;
232 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha256_buffers_t*)shaBuffers)->hash;
233 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha256_buffers_t*)shaBuffers)->roundMem;
234
235 hashState->mode = (uint32_t)mode;
236 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA256;
237 hashState->initialHash = (const uint8_t*)sha256InitHash;
238 hashState->blockSize = CY_CRYPTO_SHA256_BLOCK_SIZE;
239 hashState->hashSize = CY_CRYPTO_SHA256_HASH_SIZE;
240 hashState->digestSize = CY_CRYPTO_SHA256_DIGEST_SIZE;
241 hashState->roundMemSize = CY_CRYPTO_SHA256_ROUND_MEM_SIZE;
242 break;
243 #endif /* (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED) */
244
245 #if (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
246
247 case CY_CRYPTO_MODE_SHA384:
248 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->block;
249 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->hash;
250 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->roundMem;
251
252 hashState->mode = (uint32_t)mode;
253 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA512;
254 hashState->initialHash = (const uint8_t*)sha384InitHash;
255 hashState->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
256 hashState->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
257 hashState->digestSize = CY_CRYPTO_SHA384_DIGEST_SIZE;
258 hashState->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
259 break;
260
261 case CY_CRYPTO_MODE_SHA512:
262 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->block;
263 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->hash;
264 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->roundMem;
265
266 hashState->mode = (uint32_t)mode;
267 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA512;
268 hashState->initialHash = (const uint8_t*)sha512InitHash;
269 hashState->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
270 hashState->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
271 hashState->digestSize = CY_CRYPTO_SHA512_DIGEST_SIZE;
272 hashState->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
273 break;
274
275 case CY_CRYPTO_MODE_SHA512_224:
276 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->block;
277 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->hash;
278 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->roundMem;
279
280 hashState->mode = (uint32_t)mode;
281 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA512;
282 hashState->initialHash = (const uint8_t*)sha512_224InitHash;
283 hashState->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
284 hashState->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
285 hashState->digestSize = CY_CRYPTO_SHA512_224_DIGEST_SIZE;
286 hashState->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
287 break;
288
289 case CY_CRYPTO_MODE_SHA512_256:
290 hashState->block = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->block;
291 hashState->hash = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->hash;
292 hashState->roundMem = (uint8_t*)((cy_stc_crypto_v1_sha512_buffers_t*)shaBuffers)->roundMem;
293
294 hashState->mode = (uint32_t)mode;
295 hashState->modeHw = (uint32_t)CY_CRYPTO_V1_SHA_CTL_MODE_SHA512;
296 hashState->initialHash = (const uint8_t*)sha512_256InitHash;
297 hashState->blockSize = CY_CRYPTO_SHA512_BLOCK_SIZE;
298 hashState->hashSize = CY_CRYPTO_SHA512_HASH_SIZE;
299 hashState->digestSize = CY_CRYPTO_SHA512_256_DIGEST_SIZE;
300 hashState->roundMemSize = CY_CRYPTO_SHA512_ROUND_MEM_SIZE;
301 break;
302 #endif /* (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED) */
303
304 default:
305 tmpResult = CY_CRYPTO_BAD_PARAMS;
306 break;
307 }
308
309 return (tmpResult);
310 }
311
312 /*******************************************************************************
313 * Function Name: Cy_Crypto_Core_V1_Sha_Start
314 ****************************************************************************//**
315 *
316 * Initializes the initial hash vector.
317 *
318 * \param base
319 * The pointer to the CRYPTO instance.
320 *
321 * \param hashState
322 * The pointer to the SHA context.
323 *
324 * \return
325 * \ref cy_en_crypto_status_t
326 *
327 *******************************************************************************/
Cy_Crypto_Core_V1_Sha_Start(CRYPTO_Type * base,cy_stc_crypto_sha_state_t * hashState)328 cy_en_crypto_status_t Cy_Crypto_Core_V1_Sha_Start(CRYPTO_Type *base, cy_stc_crypto_sha_state_t *hashState)
329 {
330 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
331
332 if (hashState != NULL)
333 {
334 hashState->blockIdx = 0U;
335 hashState->messageSize = 0U;
336
337 if (hashState->hashSize != 0U)
338 {
339 Cy_Crypto_Core_V1_MemCpy(base, (void*)hashState->hash, (void const*)hashState->initialHash, (uint16_t)hashState->hashSize);
340
341 tmpResult = CY_CRYPTO_SUCCESS;
342 }
343 }
344
345 return (tmpResult);
346 }
347
348 /*******************************************************************************
349 * Function Name: Cy_Crypto_Core_V1_Sha_Update
350 ****************************************************************************//**
351 *
352 * Performs the SHA calculation on one message.
353 *
354 * \param base
355 * The pointer to the CRYPTO instance.
356 *
357 * \param hashState
358 * The pointer to the SHA context.
359 *
360 * \param message
361 * The pointer to the message whose Hash is being computed.
362 *
363 * \param messageSize
364 * The size of the message whose Hash is being computed.
365 *
366 * \return
367 * \ref cy_en_crypto_status_t
368 *
369 * \note
370 * This function can be called several times only with message lengths dividable
371 * by the block size. Only the last call to the function can process a message with
372 * a not-dividable size.
373 *
374 *******************************************************************************/
Cy_Crypto_Core_V1_Sha_Update(CRYPTO_Type * base,cy_stc_crypto_sha_state_t * hashState,uint8_t const * message,uint32_t messageSize)375 cy_en_crypto_status_t Cy_Crypto_Core_V1_Sha_Update(CRYPTO_Type *base,
376 cy_stc_crypto_sha_state_t *hashState,
377 uint8_t const *message,
378 uint32_t messageSize)
379 {
380 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
381
382 if(messageSize == 0UL)
383 {
384 return CY_CRYPTO_SUCCESS;
385 }
386
387 if ((hashState != NULL) && (message != NULL))
388 {
389 if (hashState->blockSize != 0U)
390 {
391
392 hashState->messageSize += messageSize;
393
394 uint32_t hashBlockIdx = hashState->blockIdx;
395 uint32_t hashBlockSize = hashState->blockSize;
396
397 /* Processing the fully filled blocks with remaining buffer data */
398 while ((hashBlockIdx + messageSize) >= hashBlockSize)
399 {
400 uint32_t tempBlockSize = hashBlockSize - hashBlockIdx;
401
402 Cy_Crypto_Core_V1_MemCpy(base, (void *)((uint32_t)hashState->block + hashBlockIdx), (void const*)message, (uint16_t)tempBlockSize);
403
404 Cy_Crypto_Core_V1_Sha_ProcessBlock(base, hashState, hashState->block);
405
406 messageSize -= tempBlockSize;
407 message += tempBlockSize;
408
409 hashBlockIdx = 0U;
410 }
411
412 /* The remaining block will be calculated in the Finish function. */
413 hashState->blockIdx = hashBlockIdx + messageSize;
414
415 /* Copy the end of the message to the block */
416 if (messageSize != 0U)
417 {
418 Cy_Crypto_Core_V1_MemCpy(base, (void *)((uint32_t)hashState->block + hashBlockIdx), (void const*)message, (uint16_t)messageSize);
419 }
420
421
422 tmpResult = CY_CRYPTO_SUCCESS;
423 }
424 }
425
426 return (tmpResult);
427 }
428
429 /*******************************************************************************
430 * Function Name: Cy_Crypto_Core_V1_Sha_Finish
431 ****************************************************************************//**
432 *
433 * Completes the SHA calculation.
434 *
435 * \param base
436 * The pointer to the CRYPTO instance.
437 *
438 * \param hashState
439 * The pointer to the SHA context.
440 *
441 * \param digest
442 * The pointer to the calculated hash digest.
443 *
444 * \return
445 * \ref cy_en_crypto_status_t
446 *
447 *******************************************************************************/
Cy_Crypto_Core_V1_Sha_Finish(CRYPTO_Type * base,cy_stc_crypto_sha_state_t * hashState,uint8_t * digest)448 cy_en_crypto_status_t Cy_Crypto_Core_V1_Sha_Finish(CRYPTO_Type *base,
449 cy_stc_crypto_sha_state_t *hashState,
450 uint8_t *digest)
451 {
452 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
453
454 if ((hashState != NULL) && (digest != NULL))
455 {
456 uint8_t *hashPtr = hashState->hash;
457 uint8_t *blockPtr = hashState->block;
458 uint32_t hashBlockSize = hashState->blockSize;
459 uint32_t hashBlockIdx = hashState->blockIdx;
460 uint64_t finalMessageSizeInBits = (uint64_t)hashState->messageSize * 8U;
461 uint32_t padSize;
462
463 if (CY_CRYPTO_SHA512_BLOCK_SIZE == hashBlockSize)
464 {
465 padSize = CY_CRYPTO_SHA512_PAD_SIZE; /* Pad size = 112 */
466 }
467 else
468 {
469 padSize = CY_CRYPTO_SHA256_PAD_SIZE; /* Pad size = 56 */
470 }
471
472 /* Append 1 bit to the end of the message */
473 blockPtr[hashBlockIdx] = 0x80U;
474
475 /* Clear the rest of the block */
476 Cy_Crypto_Core_V1_MemSet(base, (void* )&blockPtr[hashBlockIdx + 1U], 0x00U, (uint16_t)(hashBlockSize - hashBlockIdx - 1U));
477
478 if (hashBlockIdx >= padSize)
479 {
480 /* Here we need one additional last block to calculate SHA, prepare it: */
481 Cy_Crypto_Core_V1_Sha_ProcessBlock(base, hashState, (uint8_t*)blockPtr);
482
483 /* Clear the last block */
484 Cy_Crypto_Core_V1_MemSet(base, (void*)blockPtr, 0x00u, (uint16_t)hashBlockSize);
485 }
486
487 blockPtr[hashBlockSize - 8U] = (uint8_t)((finalMessageSizeInBits) >> 56U);
488 blockPtr[hashBlockSize - 7U] = (uint8_t)((finalMessageSizeInBits) >> 48U);
489 blockPtr[hashBlockSize - 6U] = (uint8_t)((finalMessageSizeInBits) >> 40U);
490 blockPtr[hashBlockSize - 5U] = (uint8_t)((finalMessageSizeInBits) >> 32U);
491 blockPtr[hashBlockSize - 4U] = (uint8_t)((finalMessageSizeInBits) >> 24U);
492 blockPtr[hashBlockSize - 3U] = (uint8_t)((finalMessageSizeInBits) >> 16U);
493 blockPtr[hashBlockSize - 2U] = (uint8_t)((finalMessageSizeInBits) >> 8U);
494 blockPtr[hashBlockSize - 1U] = (uint8_t)(finalMessageSizeInBits);
495
496 /* Process the last block */
497 Cy_Crypto_Core_V1_Sha_ProcessBlock(base, hashState, (uint8_t*)blockPtr);
498
499 /* Invert endians of the hash and copy it to digest, re-use the padSize variable */
500 padSize = (uint32_t)(hashState->digestSize / 4U);
501
502 for(; padSize != 0U; padSize--)
503 {
504 *(digest) = *(hashPtr+3);
505 *(digest+1) = *(hashPtr+2);
506 *(digest+2) = *(hashPtr+1);
507 *(digest+3) = *(hashPtr);
508
509 digest += 4U;
510 hashPtr += 4U;
511 }
512
513 tmpResult = CY_CRYPTO_SUCCESS;
514 }
515
516 return (tmpResult);
517 }
518
519 /*******************************************************************************
520 * Function Name: Cy_Crypto_Core_V1_Sha_Free
521 ****************************************************************************//**
522 *
523 * Clears the used memory buffers.
524 *
525 * \param base
526 * The pointer to the CRYPTO instance.
527 *
528 * \param hashState
529 * The pointer to the SHA context.
530 *
531 * \return
532 * \ref cy_en_crypto_status_t
533 *
534 *******************************************************************************/
Cy_Crypto_Core_V1_Sha_Free(CRYPTO_Type * base,cy_stc_crypto_sha_state_t * hashState)535 cy_en_crypto_status_t Cy_Crypto_Core_V1_Sha_Free(CRYPTO_Type *base, cy_stc_crypto_sha_state_t *hashState)
536 {
537 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
538
539 if (hashState != NULL)
540 {
541 /* Clears the memory buffer. */
542 Cy_Crypto_Core_V1_MemSet(base, (void*)hashState->block, 0x00U, (uint16_t)hashState->blockSize);
543 Cy_Crypto_Core_V1_MemSet(base, (void*)hashState->hash, 0x00U, (uint16_t)hashState->hashSize);
544 Cy_Crypto_Core_V1_MemSet(base, (void*)hashState->roundMem, 0x00U, (uint16_t)hashState->roundMemSize);
545
546 tmpResult = CY_CRYPTO_SUCCESS;
547 }
548
549 return (tmpResult);
550 }
551
552
553 /*******************************************************************************
554 * Function Name: Cy_Crypto_Core_V1_Sha
555 ****************************************************************************//**
556 *
557 * Performs the SHA Hash function.
558 *
559 * \param base
560 * The pointer to the CRYPTO instance.
561 *
562 * \param mode
563 * \ref cy_en_crypto_sha_mode_t
564 *
565 * \param message
566 * The pointer to a message whose hash value is being computed.
567 *
568 * \param messageSize
569 * The size of a message.
570 *
571 * \param digest
572 * The pointer to the hash digest.
573 *
574 * \return
575 * \ref cy_en_crypto_status_t
576 *
577 *******************************************************************************/
Cy_Crypto_Core_V1_Sha(CRYPTO_Type * base,uint8_t const * message,uint32_t messageSize,uint8_t * digest,cy_en_crypto_sha_mode_t mode)578 cy_en_crypto_status_t Cy_Crypto_Core_V1_Sha(CRYPTO_Type *base,
579 uint8_t const *message,
580 uint32_t messageSize,
581 uint8_t *digest,
582 cy_en_crypto_sha_mode_t mode)
583 {
584 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
585
586 void *shaBuffers = (void *)Cy_Crypto_Core_GetVuMemoryAddress(base);
587 cy_stc_crypto_sha_state_t myHashState = { 0 };
588
589 tmpResult = Cy_Crypto_Core_V1_Sha_Init (base, &myHashState, mode, shaBuffers);
590
591 if (CY_CRYPTO_SUCCESS == tmpResult)
592 {
593 tmpResult = Cy_Crypto_Core_V1_Sha_Start (base, &myHashState);
594 }
595 if (CY_CRYPTO_SUCCESS == tmpResult)
596 {
597 tmpResult = Cy_Crypto_Core_V1_Sha_Update (base, &myHashState, message, messageSize);
598 }
599 if (CY_CRYPTO_SUCCESS == tmpResult)
600 {
601 tmpResult = Cy_Crypto_Core_V1_Sha_Finish (base, &myHashState, digest);
602 }
603 if (CY_CRYPTO_SUCCESS == tmpResult)
604 {
605 tmpResult = Cy_Crypto_Core_V1_Sha_Free (base, &myHashState);
606 }
607
608 return (tmpResult);
609 }
610
611 #endif /* (CPUSS_CRYPTO_SHA == 1) && defined(CY_CRYPTO_CFG_SHA_C) */
612
613 #if defined(__cplusplus)
614 }
615 #endif
616
617 #endif /* defined(CY_CRYPTO_CFG_HW_V1_ENABLE) */
618
619 #endif /* defined(CY_IP_MXCRYPTO) */
620
621
622 /* [] END OF FILE */
623