1 /***************************************************************************//**
2 * \file cy_cryptolite_sha256.c
3 * \version 2.50
4 *
5 * \brief
6 * Provides API implementation of the Cryptolite SHA256 PDL driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation.
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26
27 #include "cy_device.h"
28
29 #if defined (CY_IP_MXCRYPTOLITE)
30
31 #include "cy_cryptolite_sha256.h"
32 #include "cy_cryptolite_utils.h"
33
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37
38 #if (CRYPTOLITE_SHA_PRESENT == 1)
39 #if defined(CY_CRYPTOLITE_CFG_SHA_C) && defined(CY_CRYPTOLITE_CFG_SHA2_256_ENABLED)
40
41 /*Initial Hash*/
42 static const uint32_t sha256InitHash[] =
43 {
44 0x6A09E667uL, 0xBB67AE85uL, 0x3C6EF372uL, 0xA54FF53AuL,
45 0x510E527FuL, 0x9B05688CuL, 0x1F83D9ABuL, 0x5BE0CD19uL
46 };
47
48 /*****************************************************************************
49 * Cy_Cryptolite_Sha256_Process (for internal use)
50 ******************************************************************************
51 *
52 * The function starts the hash calculation, blocks until finished.
53 *
54 * base
55 * The pointer to the Cryptolite instance.
56 *
57 * cfContext
58 * The pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
59 * internal variables for Cryptolite driver.
60 *
61 * return
62 * cy_en_cryptolite_status_t
63 *
64 *******************************************************************************/
Cy_Cryptolite_Sha256_Process(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_sha256_t * cfContext)65 static cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Process(CRYPTOLITE_Type *base,
66 cy_stc_cryptolite_context_sha256_t *cfContext)
67 {
68 if((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
69 {
70 return CY_CRYPTOLITE_HW_BUSY;
71 }
72
73 /*write to SHA DESCR REG starts process
74 IP will block another write to SHA DESCR REG until its busy
75 We poll for busy state and check for error before posting next
76 descriptor */
77
78 /*start message schedule*/
79 REG_CRYPTOLITE_SHA_DESCR(base) = (uint32_t)&(cfContext->message_schedule_struct);
80 while((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL){};
81 if((REG_CRYPTOLITE_SHA_INTR_ERROR(base) & CRYPTOLITE_INTR_ERROR_BUS_ERROR_Msk) != 0UL)
82 {
83 REG_CRYPTOLITE_SHA_INTR_ERROR(base) = CRYPTOLITE_INTR_ERROR_BUS_ERROR_Msk;
84 return CY_CRYPTOLITE_BUS_ERROR;
85 }
86
87 /*start process*/
88 REG_CRYPTOLITE_SHA_DESCR(base) = (uint32_t)&(cfContext->message_process_struct);
89 while((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL){};
90 if((REG_CRYPTOLITE_SHA_INTR_ERROR(base) & CRYPTOLITE_INTR_ERROR_BUS_ERROR_Msk) != 0UL)
91 {
92 REG_CRYPTOLITE_SHA_INTR_ERROR(base) = CRYPTOLITE_INTR_ERROR_BUS_ERROR_Msk;
93 return CY_CRYPTOLITE_BUS_ERROR;
94 }
95
96 return CY_CRYPTOLITE_SUCCESS;
97 }
98
99 /*****************************************************************************
100 * Cy_Cryptolite_Sha256_Process_aligned (for internal use)
101 ******************************************************************************
102 *
103 * The function starts the hash calculation for 4 byte aligned data blocks
104 * until finished.
105 *
106 * base
107 * The pointer to the Cryptolite instance.
108 *
109 * cfContext
110 * The pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
111 * internal variables for Cryptolite driver.
112 *
113 * message
114 * The pointer to the message whose Hash is being computed.
115 *
116 * messageSize
117 * The pointer to size of the message whose Hash is being computed.
118 * returns the remaining message size after process
119 *
120 * return
121 * cy_en_cryptolite_status_t
122 *
123 *******************************************************************************/
Cy_Cryptolite_Sha256_Process_aligned(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_sha256_t * cfContext,uint8_t const * message,uint32_t * messageSize)124 static cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Process_aligned(CRYPTOLITE_Type *base,
125 cy_stc_cryptolite_context_sha256_t *cfContext,
126 uint8_t const *message,
127 uint32_t *messageSize)
128 {
129 cy_en_cryptolite_status_t err;
130
131 /*point descriptor to message buffer*/
132 cfContext->message_schedule_struct.data1 = (uint32_t)message;
133
134 while(*messageSize >= CY_CRYPTOLITE_SHA256_BLOCK_SIZE)
135 {
136 err = Cy_Cryptolite_Sha256_Process(base, cfContext);
137 if(CY_CRYPTOLITE_SUCCESS != err)
138 {
139 cfContext->message_schedule_struct.data1 = (uint32_t)cfContext->message;
140 return err;
141 }
142 *messageSize-=CY_CRYPTOLITE_SHA256_BLOCK_SIZE;
143 cfContext->messageSize+= CY_CRYPTOLITE_SHA256_BLOCK_SIZE;
144 cfContext->message_schedule_struct.data1+= CY_CRYPTOLITE_SHA256_BLOCK_SIZE;
145 }
146 /*restore descriptor to context buffer*/
147 cfContext->message_schedule_struct.data1 = (uint32_t)cfContext->message;
148
149 return CY_CRYPTOLITE_SUCCESS;
150 }
151
152 /*****************************************************************************
153 * Cy_Cryptolite_Sha256_Init
154 ******************************************************************************
155 *
156 * The function to initialize the SHA256 operation.
157 *
158 * base
159 * The pointer to the Cryptolite instance.
160 *
161 * cfContext
162 * The pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
163 * internal variables for Cryptolite driver.
164 *
165 * return
166 * cy_en_cryptolite_status_t
167 *
168 *******************************************************************************/
Cy_Cryptolite_Sha256_Init(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_sha256_t * cfContext)169 cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Init(CRYPTOLITE_Type *base,
170 cy_stc_cryptolite_context_sha256_t *cfContext)
171 {
172 /* Input parameters verification */
173 if ((NULL == base) || (NULL == cfContext))
174 {
175 return CY_CRYPTOLITE_BAD_PARAMS;
176 }
177
178 cfContext->message = (uint8_t*)cfContext->msgblock;
179 cfContext->message_schedule_struct.data0 = (uint32_t)CY_CRYPTOLITE_MSG_SCH_CTLWD;
180 cfContext->message_schedule_struct.data1 = (uint32_t)cfContext->message;
181 cfContext->message_schedule_struct.data2 = (uint32_t)cfContext->message_schedule;
182
183 cfContext->message_process_struct.data0 = (uint32_t)CY_CRYPTOLITE_PROCESS_CTLWD;
184 cfContext->message_process_struct.data1 = (uint32_t)cfContext->hash;
185 cfContext->message_process_struct.data2 = (uint32_t)cfContext->message_schedule;
186
187 return (CY_CRYPTOLITE_SUCCESS);
188 }
189
190 /*******************************************************************************
191 * Cy_Cryptolite_Sha256_Start
192 ******************************************************************************
193 *
194 * Initializes the initial Hash vector.
195 *
196 * base
197 * The pointer to the CRYPTOLITE instance.
198 *
199 * cfContext
200 * The pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
201 * internal variables for Cryptolite driver.
202 *
203 * return
204 * cy_en_cryptolite_status_t
205 *
206 *******************************************************************************/
Cy_Cryptolite_Sha256_Start(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_sha256_t * cfContext)207 cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Start(CRYPTOLITE_Type *base,
208 cy_stc_cryptolite_context_sha256_t *cfContext)
209 {
210 uint32_t i;
211 /* Input parameters verification */
212 if ((NULL == base) || (NULL == cfContext))
213 {
214 return CY_CRYPTOLITE_BAD_PARAMS;
215 }
216
217 /*check if IP is busy*/
218 if ((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
219 {
220 return CY_CRYPTOLITE_HW_BUSY;
221 }
222
223 cfContext->msgIdx = 0U;
224 cfContext->messageSize = 0U;
225
226 /*copy initial hash*/
227 for (i=0U; i < CY_CRYPTOLITE_SHA256_HASH_SIZE/4U; i++)
228 {
229 cfContext->hash[i] = sha256InitHash[i];
230 }
231
232 return CY_CRYPTOLITE_SUCCESS;
233 }
234
235
236 /*******************************************************************************
237 * Cy_Cryptolite_Sha256_Update
238 ********************************************************************************
239 *
240 * Performs the SHA256 calculation on one message.
241 *
242 * base
243 * The pointer to the CRYPTOLITE instance.
244 *
245 * cfContext
246 * The pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
247 * internal variables for Cryptolite driver.
248 *
249 * message
250 * The pointer to the message whose Hash is being computed.
251 *
252 * messageSize
253 * The size of the message whose Hash is being computed.
254 *
255 * return
256 * cy_en_cryptolite_status_t
257 *
258 *******************************************************************************/
Cy_Cryptolite_Sha256_Update(CRYPTOLITE_Type * base,uint8_t const * message,uint32_t messageSize,cy_stc_cryptolite_context_sha256_t * cfContext)259 cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Update(CRYPTOLITE_Type *base,
260 uint8_t const *message,
261 uint32_t messageSize,
262 cy_stc_cryptolite_context_sha256_t *cfContext)
263 {
264 cy_en_cryptolite_status_t err = CY_CRYPTOLITE_BAD_PARAMS;
265 uint32_t readIdx = 0U;
266 uint32_t msg_add = (uint32)message;
267 uint32_t lmessageSize;
268 uint8_t *messageRemap;
269
270 if (0UL == messageSize)
271 {
272 return CY_CRYPTOLITE_SUCCESS;
273 }
274
275 /* Input parameters verification */
276 if ((NULL == base) || (NULL == cfContext) || (NULL == message))
277 {
278 return err;
279 }
280
281 /*check if IP is busy*/
282 if ((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
283 {
284 return CY_CRYPTOLITE_HW_BUSY;
285 }
286
287 messageRemap = (uint8_t *)CY_REMAP_ADDRESS_CRYPTOLITE(message);
288 lmessageSize = messageSize;
289
290 /*Check for 4 byte aligned buffer and process*/
291 if((msg_add & 0x3UL) == 0UL)
292 {
293 /*Check for fragmented message and size*/
294 if (cfContext->msgIdx == 0UL && messageSize >= CY_CRYPTOLITE_SHA256_BLOCK_SIZE)
295 {
296 err = Cy_Cryptolite_Sha256_Process_aligned(base, cfContext, messageRemap, &lmessageSize);
297 if(CY_CRYPTOLITE_SUCCESS != err)
298 {
299 return err;
300 }
301 readIdx = messageSize - lmessageSize;
302 }
303 }
304
305 while((cfContext->msgIdx + lmessageSize) >= CY_CRYPTOLITE_SHA256_BLOCK_SIZE)
306 {
307 uint32_t tocopy = CY_CRYPTOLITE_SHA256_BLOCK_SIZE - cfContext->msgIdx;
308
309 err = Cy_Cryptolite_Memcpy(base, &cfContext->message[cfContext->msgIdx], (uint8_t *)&messageRemap[readIdx], tocopy);
310
311 if(CY_CRYPTOLITE_SUCCESS != err)
312 {
313 return err;
314 }
315 readIdx += tocopy;
316 cfContext->msgIdx += tocopy;
317
318 /* calculate message schedule and process */
319 err = Cy_Cryptolite_Sha256_Process(base, cfContext);
320 if(CY_CRYPTOLITE_SUCCESS != err)
321 {
322 return err;
323 }
324 lmessageSize-= tocopy;
325 cfContext->messageSize+= CY_CRYPTOLITE_SHA256_BLOCK_SIZE;
326 cfContext->msgIdx = 0U;
327 }
328
329 err = Cy_Cryptolite_Memcpy(base, &cfContext->message[cfContext->msgIdx], (uint8_t *)&messageRemap[readIdx], lmessageSize);
330
331 if(CY_CRYPTOLITE_SUCCESS != err)
332 {
333 return err;
334 }
335 cfContext->msgIdx += lmessageSize;
336
337 return CY_CRYPTOLITE_SUCCESS;
338 }
339
340 /*******************************************************************************
341 * Cy_Cryptolite_Sha256_Finish
342 ******************************************************************************
343 *
344 * Completes the SHA256 calculation.
345 *
346 * base
347 * The pointer to the CRYPTOLITE instance.
348 *
349 * cfContext
350 * the pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
351 * internal variables for Cryptolite driver.
352 *
353 * digest
354 * The pointer to the calculated Hash digest.
355 *
356 * return
357 * cy_en_cryptolite_status_t
358 *
359 *******************************************************************************/
Cy_Cryptolite_Sha256_Finish(CRYPTOLITE_Type * base,uint8_t * digest,cy_stc_cryptolite_context_sha256_t * cfContext)360 cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Finish(CRYPTOLITE_Type *base,
361 uint8_t *digest,
362 cy_stc_cryptolite_context_sha256_t *cfContext)
363 {
364 cy_en_cryptolite_status_t err = CY_CRYPTOLITE_BAD_PARAMS;
365 uint8_t *hashptr;
366 uint32_t idx;
367 uint64_t totalMessageSizeInBits;
368
369 /* Input parameters verification */
370 if ((NULL == base) || (NULL == cfContext) || (NULL == digest))
371 {
372 return err;
373 }
374
375 /*check if IP is busy*/
376 if ((REG_CRYPTOLITE_STATUS(base) & CRYPTOLITE_STATUS_BUSY_Msk) != 0UL)
377 {
378 return CY_CRYPTOLITE_HW_BUSY;
379 }
380
381 totalMessageSizeInBits = (cfContext->messageSize + (uint64_t)(cfContext->msgIdx)) * 8U;
382 /*Append one bit to end and clear rest of block*/
383 cfContext->message[cfContext->msgIdx] = 0x80U;
384 idx = cfContext->msgIdx + 1U;
385
386 for ( ; idx < CY_CRYPTOLITE_SHA256_BLOCK_SIZE; idx++ )
387 {
388 cfContext->message[idx] = 0U;
389 }
390
391 /*if message size is more than pad size process the block*/
392 if (cfContext->msgIdx >= CY_CRYPTOLITE_SHA256_PAD_SIZE)
393 {
394 err = Cy_Cryptolite_Sha256_Process(base, cfContext);
395 if(CY_CRYPTOLITE_SUCCESS != err)
396 {
397 return err;
398 }
399 /*clear the message block to finish*/
400 for ( idx = 0; idx < CY_CRYPTOLITE_SHA256_PAD_SIZE; idx++ )
401 {
402 cfContext->message[idx] = 0U;
403 }
404 }
405
406 /*append total message size in bits from 57 to 64 bytes */
407 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 1UL] = (uint8_t)totalMessageSizeInBits;
408 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 2UL] = (uint8_t)(totalMessageSizeInBits >> 8);
409 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 3UL] = (uint8_t)(totalMessageSizeInBits >> 16);
410 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 4UL] = (uint8_t)(totalMessageSizeInBits >> 24);
411 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 5UL] = (uint8_t)(totalMessageSizeInBits >> 32);
412 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 6UL] = (uint8_t)(totalMessageSizeInBits >> 40);
413 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 7UL] = (uint8_t)(totalMessageSizeInBits >> 48);
414 cfContext->message[CY_CRYPTOLITE_SHA256_BLOCK_SIZE - 8UL] = (uint8_t)(totalMessageSizeInBits >> 56);
415
416 /*Process the last block*/
417 err = Cy_Cryptolite_Sha256_Process(base, cfContext);
418 if(CY_CRYPTOLITE_SUCCESS != err)
419 {
420 return err;
421 }
422
423 /* This implementation uses little endian ordering and SHA uses big endian,
424 reverse all the bytes in 32bit word when copying the final output hash.*/
425 idx = (uint32_t)(CY_CRYPTOLITE_SHA256_HASH_SIZE / 4UL);
426 hashptr = (uint8_t*)cfContext->hash;
427
428 for( ; idx != 0U; idx--)
429 {
430 *(digest) = *(hashptr+3);
431 *(digest+1) = *(hashptr+2);
432 *(digest+2) = *(hashptr+1);
433 *(digest+3) = *(hashptr);
434
435 digest += 4U;
436 hashptr += 4U;
437 }
438
439 return CY_CRYPTOLITE_SUCCESS;
440 }
441
442 /*******************************************************************************
443 * Cy_Cryptolite_Sha256_Free
444 ******************************************************************************
445 *
446 * Clears the used memory and context data.
447 *
448 * base
449 * The pointer to the CRYPTOLITE instance.
450 *
451 * cfContext
452 * the pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
453 * internal variables for Cryptolite driver.
454 *
455 * return
456 * cy_en_cryptolite_status_t
457 *
458 *******************************************************************************/
Cy_Cryptolite_Sha256_Free(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_sha256_t * cfContext)459 cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Free(CRYPTOLITE_Type *base,
460 cy_stc_cryptolite_context_sha256_t *cfContext)
461 {
462 uint32_t idx;
463 (void)base;
464
465 /* Input parameters verification */
466 if (NULL != cfContext)
467 {
468 /* Clear the context memory */
469 for ( idx = 0; idx < CY_CRYPTOLITE_SHA256_BLOCK_SIZE; idx++ )
470 {
471 cfContext->message_schedule[idx] = 0U;
472 }
473
474 for ( idx = 0; idx < (CY_CRYPTOLITE_SHA256_BLOCK_SIZE / 4u) + 1u ; idx++ )
475 {
476 cfContext->msgblock[idx] = 0U;
477 }
478
479 for ( idx = 0; idx < CY_CRYPTOLITE_SHA256_HASH_SIZE/4U ; idx++ )
480 {
481 cfContext->hash[idx] = 0U;
482 }
483 }
484
485 return CY_CRYPTOLITE_SUCCESS;
486 }
487
488 /*******************************************************************************
489 * Cy_Cryptolite_Sha256_Run
490 ******************************************************************************
491 *
492 * This function performs the SHA256 Hash function.
493 * Provide the required parameters and the pointer
494 * to the context structure when making this function call.
495 * It is independent of the previous Crypto state because it already contains
496 * preparation, calculation, and finalization steps.
497 *
498 * base
499 * The pointer to the CRYPTOLITE instance.
500 *
501 * cfContext
502 * the pointer to the cy_stc_cryptolite_context_sha256_t structure that stores all
503 * internal variables for Cryptolite driver.
504 *
505 * message
506 * The pointer to a message whose hash value is being computed.
507 *
508 * messageSize
509 * The size of a message in bytes.
510 *
511 * digest
512 * The pointer to the hash digest.
513 *
514 * return
515 * cy_en_cryptolite_status_t
516 *
517 *******************************************************************************/
Cy_Cryptolite_Sha256_Run(CRYPTOLITE_Type * base,uint8_t const * message,uint32_t messageSize,uint8_t * digest,cy_stc_cryptolite_context_sha256_t * cfContext)518 cy_en_cryptolite_status_t Cy_Cryptolite_Sha256_Run(CRYPTOLITE_Type *base,
519 uint8_t const *message,
520 uint32_t messageSize,
521 uint8_t *digest,
522 cy_stc_cryptolite_context_sha256_t *cfContext)
523 {
524 cy_en_cryptolite_status_t err = CY_CRYPTOLITE_BAD_PARAMS;
525 /* Input parameters verification */
526 if ((NULL == base) || (NULL == cfContext) || (NULL == digest) || ((NULL == message) && (0UL != messageSize)))
527 {
528 return err;
529 }
530
531 err = Cy_Cryptolite_Sha256_Init (base, cfContext);
532
533 if (CY_CRYPTOLITE_SUCCESS == err)
534 {
535 err = Cy_Cryptolite_Sha256_Start (base, cfContext);
536 }
537 if (CY_CRYPTOLITE_SUCCESS == err)
538 {
539 err = Cy_Cryptolite_Sha256_Update (base, message, messageSize, cfContext);
540 }
541 if (CY_CRYPTOLITE_SUCCESS == err)
542 {
543 err = Cy_Cryptolite_Sha256_Finish (base, digest, cfContext);
544 }
545 if (CY_CRYPTOLITE_SUCCESS == err)
546 {
547 err = Cy_Cryptolite_Sha256_Free (base, cfContext);
548 }
549
550 return (err);
551 }
552
553 #endif
554 #endif
555
556 #if defined(__cplusplus)
557 }
558 #endif
559
560
561 #endif /* CY_IP_MXCRYPTOLITE */
562
563
564 /* [] END OF FILE */
565