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