sama5d4_crypto_hash.c
Go to the documentation of this file.
1 /**
2  * @file sama5d4_crypto_hash.c
3  * @brief SAMA5D4 hash hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "chip.h"
36 #include "core/crypto.h"
39 #include "hash/hash_algorithms.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (SAMA5D4_CRYPTO_HASH_SUPPORT == ENABLED)
44 
45 //Padding string
46 static const uint8_t padding[128] =
47 {
48  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
56 };
57 
58 
59 /**
60  * @brief Update hash value
61  * @param[in] algo Hash algorithm
62  * @param[in] data Pointer to the input buffer
63  * @param[in] length Length of the input buffer
64  * @param[in,out] h Hash value
65  **/
66 
67 void hashProcessData(uint32_t algo, const uint8_t *data, size_t length,
68  uint32_t *h)
69 {
70  size_t blockSize;
71  uint32_t *p;
72 
73  //Get block size
74  blockSize = (algo == SHA_MR_ALGO_SHA512) ? 128 : 64;
75 
76  //Acquire exclusive access to the SHA module
78 
79  //Perform software reset
80  SHA->SHA_CR = SHA_CR_SWRST;
81 
82  //Select the relevant hash algorithm
83  SHA->SHA_MR = SHA_MR_UIHV | SHA_MR_SMOD_MANUAL_START | algo;
84 
85  //Set the WUIHV bit before loading the initial hash value
86  SHA->SHA_CR = SHA_CR_WUIHV;
87 
88  //Restore initial hash value
89  if(algo == SHA_MR_ALGO_SHA1)
90  {
91  SHA->SHA_IDATAR[0] = HTOBE32(h[0]);
92  SHA->SHA_IDATAR[1] = HTOBE32(h[1]);
93  SHA->SHA_IDATAR[2] = HTOBE32(h[2]);
94  SHA->SHA_IDATAR[3] = HTOBE32(h[3]);
95  SHA->SHA_IDATAR[4] = HTOBE32(h[4]);
96  }
97  else if(algo == SHA_MR_ALGO_SHA256)
98  {
99  SHA->SHA_IDATAR[0] = HTOBE32(h[0]);
100  SHA->SHA_IDATAR[1] = HTOBE32(h[1]);
101  SHA->SHA_IDATAR[2] = HTOBE32(h[2]);
102  SHA->SHA_IDATAR[3] = HTOBE32(h[3]);
103  SHA->SHA_IDATAR[4] = HTOBE32(h[4]);
104  SHA->SHA_IDATAR[5] = HTOBE32(h[5]);
105  SHA->SHA_IDATAR[6] = HTOBE32(h[6]);
106  SHA->SHA_IDATAR[7] = HTOBE32(h[7]);
107  }
108  else
109  {
110  SHA->SHA_IDATAR[0] = HTOBE32(h[1]);
111  SHA->SHA_IDATAR[1] = HTOBE32(h[0]);
112  SHA->SHA_IDATAR[2] = HTOBE32(h[3]);
113  SHA->SHA_IDATAR[3] = HTOBE32(h[2]);
114  SHA->SHA_IDATAR[4] = HTOBE32(h[5]);
115  SHA->SHA_IDATAR[5] = HTOBE32(h[4]);
116  SHA->SHA_IDATAR[6] = HTOBE32(h[7]);
117  SHA->SHA_IDATAR[7] = HTOBE32(h[6]);
118  SHA->SHA_IDATAR[8] = HTOBE32(h[9]);
119  SHA->SHA_IDATAR[9] = HTOBE32(h[8]);
120  SHA->SHA_IDATAR[10] = HTOBE32(h[11]);
121  SHA->SHA_IDATAR[11] = HTOBE32(h[10]);
122  SHA->SHA_IDATAR[12] = HTOBE32(h[13]);
123  SHA->SHA_IDATAR[13] = HTOBE32(h[12]);
124  SHA->SHA_IDATAR[14] = HTOBE32(h[15]);
125  SHA->SHA_IDATAR[15] = HTOBE32(h[14]);
126  }
127 
128  //The FIRST bit indicates that the next block to process is the first one
129  //of the message
130  SHA->SHA_CR = SHA_CR_FIRST;
131 
132  //Input data are processed in a block-by-block fashion
133  while(length >= blockSize)
134  {
135  //Write the block to be processed to the input data registers
136  p = (uint32_t *) data;
137  SHA->SHA_IDATAR[0] = p[0];
138  SHA->SHA_IDATAR[1] = p[1];
139  SHA->SHA_IDATAR[2] = p[2];
140  SHA->SHA_IDATAR[3] = p[3];
141  SHA->SHA_IDATAR[4] = p[4];
142  SHA->SHA_IDATAR[5] = p[5];
143  SHA->SHA_IDATAR[6] = p[6];
144  SHA->SHA_IDATAR[7] = p[7];
145  SHA->SHA_IDATAR[8] = p[8];
146  SHA->SHA_IDATAR[9] = p[9];
147  SHA->SHA_IDATAR[10] = p[10];
148  SHA->SHA_IDATAR[11] = p[11];
149  SHA->SHA_IDATAR[12] = p[12];
150  SHA->SHA_IDATAR[13] = p[13];
151  SHA->SHA_IDATAR[14] = p[14];
152  SHA->SHA_IDATAR[15] = p[15];
153 
154  //SHA-512 algorithm?
155  if(algo == SHA_MR_ALGO_SHA512)
156  {
157  SHA->SHA_IODATAR[0] = p[16];
158  SHA->SHA_IODATAR[1] = p[17];
159  SHA->SHA_IODATAR[2] = p[18];
160  SHA->SHA_IODATAR[3] = p[19];
161  SHA->SHA_IODATAR[4] = p[20];
162  SHA->SHA_IODATAR[5] = p[21];
163  SHA->SHA_IODATAR[6] = p[22];
164  SHA->SHA_IODATAR[7] = p[23];
165  SHA->SHA_IODATAR[8] = p[24];
166  SHA->SHA_IODATAR[9] = p[25];
167  SHA->SHA_IODATAR[10] = p[26];
168  SHA->SHA_IODATAR[11] = p[27];
169  SHA->SHA_IODATAR[12] = p[28];
170  SHA->SHA_IODATAR[13] = p[29];
171  SHA->SHA_IODATAR[14] = p[30];
172  SHA->SHA_IODATAR[15] = p[31];
173  }
174 
175  //Set the START bit to begin the processing
176  SHA->SHA_CR = SHA_CR_START;
177 
178  //When processing completes, the DATRDY flag is raised
179  while((SHA->SHA_ISR & SHA_ISR_DATRDY) == 0)
180  {
181  }
182 
183  //Advance data pointer
184  data += blockSize;
185  length -= blockSize;
186  }
187 
188  //Save intermediate hash value
189  h[0] = SHA->SHA_IODATAR[0];
190  h[1] = SHA->SHA_IODATAR[1];
191  h[2] = SHA->SHA_IODATAR[2];
192  h[3] = SHA->SHA_IODATAR[3];
193  h[4] = SHA->SHA_IODATAR[4];
194 
195  //SHA-256 or SHA-512 algorithm?
196  if(algo == SHA_MR_ALGO_SHA256 || algo == SHA_MR_ALGO_SHA512)
197  {
198  h[5] = SHA->SHA_IODATAR[5];
199  h[6] = SHA->SHA_IODATAR[6];
200  h[7] = SHA->SHA_IODATAR[7];
201  }
202 
203  //SHA-512 algorithm?
204  if(algo == SHA_MR_ALGO_SHA512)
205  {
206  h[8] = SHA->SHA_IODATAR[8];
207  h[9] = SHA->SHA_IODATAR[9];
208  h[10] = SHA->SHA_IODATAR[10];
209  h[11] = SHA->SHA_IODATAR[11];
210  h[12] = SHA->SHA_IODATAR[12];
211  h[13] = SHA->SHA_IODATAR[13];
212  h[14] = SHA->SHA_IODATAR[14];
213  h[15] = SHA->SHA_IODATAR[15];
214  }
215 
216  //Release exclusive access to the SHA module
218 }
219 
220 
221 #if (SHA1_SUPPORT == ENABLED)
222 
223 /**
224  * @brief Initialize SHA-1 message digest context
225  * @param[in] context Pointer to the SHA-1 context to initialize
226  **/
227 
228 void sha1Init(Sha1Context *context)
229 {
230  //Set initial hash value
231  context->h[0] = BETOH32(0x67452301);
232  context->h[1] = BETOH32(0xEFCDAB89);
233  context->h[2] = BETOH32(0x98BADCFE);
234  context->h[3] = BETOH32(0x10325476);
235  context->h[4] = BETOH32(0xC3D2E1F0);
236 
237  //Number of bytes in the buffer
238  context->size = 0;
239  //Total length of the message
240  context->totalSize = 0;
241 }
242 
243 
244 /**
245  * @brief Update the SHA-1 context with a portion of the message being hashed
246  * @param[in] context Pointer to the SHA-1 context
247  * @param[in] data Pointer to the buffer being hashed
248  * @param[in] length Length of the buffer
249  **/
250 
251 void sha1Update(Sha1Context *context, const void *data, size_t length)
252 {
253  size_t n;
254 
255  //Process the incoming data
256  while(length > 0)
257  {
258  //Check whether some data is pending in the buffer
259  if(context->size == 0 && length >= 64)
260  {
261  //The length must be a multiple of 64 bytes
262  n = length - (length % 64);
263 
264  //Update hash value
265  hashProcessData(SHA_MR_ALGO_SHA1, data, n, context->h);
266 
267  //Update the SHA-1 context
268  context->totalSize += n;
269  //Advance the data pointer
270  data = (uint8_t *) data + n;
271  //Remaining bytes to process
272  length -= n;
273  }
274  else
275  {
276  //The buffer can hold at most 64 bytes
277  n = MIN(length, 64 - context->size);
278 
279  //Copy the data to the buffer
280  osMemcpy(context->buffer + context->size, data, n);
281 
282  //Update the SHA-1 context
283  context->size += n;
284  context->totalSize += n;
285  //Advance the data pointer
286  data = (uint8_t *) data + n;
287  //Remaining bytes to process
288  length -= n;
289 
290  //Check whether the buffer is full
291  if(context->size == 64)
292  {
293  //Update hash value
294  hashProcessData(SHA_MR_ALGO_SHA1, context->buffer, context->size,
295  context->h);
296 
297  //Empty the buffer
298  context->size = 0;
299  }
300  }
301  }
302 }
303 
304 
305 /**
306  * @brief Finish the SHA-1 message digest
307  * @param[in] context Pointer to the SHA-1 context
308  * @param[out] digest Calculated digest
309  **/
310 
311 void sha1Final(Sha1Context *context, uint8_t *digest)
312 {
313  uint_t i;
314  size_t paddingSize;
315  uint64_t totalSize;
316 
317  //Length of the original message (before padding)
318  totalSize = context->totalSize * 8;
319 
320  //Pad the message so that its length is congruent to 56 modulo 64
321  if(context->size < 56)
322  {
323  paddingSize = 56 - context->size;
324  }
325  else
326  {
327  paddingSize = 64 + 56 - context->size;
328  }
329 
330  //Append padding
331  sha1Update(context, padding, paddingSize);
332 
333  //Append the length of the original message
334  for(i = 0; i < 8; i++)
335  {
336  context->buffer[63 - i] = totalSize & 0xFF;
337  totalSize >>= 8;
338  }
339 
340  //Calculate the message digest
341  hashProcessData(SHA_MR_ALGO_SHA1, context->buffer, 64, context->h);
342 
343  //Copy the resulting digest
344  for(i = 0; i < (SHA1_DIGEST_SIZE / 4); i++)
345  {
346  STORE32LE(context->h[i], digest + i * 4);
347  }
348 }
349 
350 
351 /**
352  * @brief Finish the SHA-1 message digest (no padding added)
353  * @param[in] context Pointer to the SHA-1 context
354  * @param[out] digest Calculated digest
355  **/
356 
357 void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
358 {
359  uint_t i;
360 
361  //Copy the resulting digest
362  for(i = 0; i < (SHA1_DIGEST_SIZE / 4); i++)
363  {
364  STORE32LE(context->h[i], digest + i * 4);
365  }
366 }
367 
368 #endif
369 #if (SHA224_SUPPORT == ENABLED)
370 
371 /**
372  * @brief Initialize SHA-224 message digest context
373  * @param[in] context Pointer to the SHA-224 context to initialize
374  **/
375 
376 void sha224Init(Sha224Context *context)
377 {
378  //Set initial hash value
379  context->h[0] = BETOH32(0xC1059ED8);
380  context->h[1] = BETOH32(0x367CD507);
381  context->h[2] = BETOH32(0x3070DD17);
382  context->h[3] = BETOH32(0xF70E5939);
383  context->h[4] = BETOH32(0xFFC00B31);
384  context->h[5] = BETOH32(0x68581511);
385  context->h[6] = BETOH32(0x64F98FA7);
386  context->h[7] = BETOH32(0xBEFA4FA4);
387 
388  //Number of bytes in the buffer
389  context->size = 0;
390  //Total length of the message
391  context->totalSize = 0;
392 }
393 
394 #endif
395 #if (SHA256_SUPPORT == ENABLED)
396 
397 /**
398  * @brief Initialize SHA-256 message digest context
399  * @param[in] context Pointer to the SHA-256 context to initialize
400  **/
401 
402 void sha256Init(Sha256Context *context)
403 {
404  //Set initial hash value
405  context->h[0] = BETOH32(0x6A09E667);
406  context->h[1] = BETOH32(0xBB67AE85);
407  context->h[2] = BETOH32(0x3C6EF372);
408  context->h[3] = BETOH32(0xA54FF53A);
409  context->h[4] = BETOH32(0x510E527F);
410  context->h[5] = BETOH32(0x9B05688C);
411  context->h[6] = BETOH32(0x1F83D9AB);
412  context->h[7] = BETOH32(0x5BE0CD19);
413 
414  //Number of bytes in the buffer
415  context->size = 0;
416  //Total length of the message
417  context->totalSize = 0;
418 }
419 
420 
421 /**
422  * @brief Update the SHA-256 context with a portion of the message being hashed
423  * @param[in] context Pointer to the SHA-256 context
424  * @param[in] data Pointer to the buffer being hashed
425  * @param[in] length Length of the buffer
426  **/
427 
428 void sha256Update(Sha256Context *context, const void *data, size_t length)
429 {
430  size_t n;
431 
432  //Process the incoming data
433  while(length > 0)
434  {
435  //Check whether some data is pending in the buffer
436  if(context->size == 0 && length >= 64)
437  {
438  //The length must be a multiple of 64 bytes
439  n = length - (length % 64);
440 
441  //Update hash value
442  hashProcessData(SHA_MR_ALGO_SHA256, data, n, context->h);
443 
444  //Update the SHA-256 context
445  context->totalSize += n;
446  //Advance the data pointer
447  data = (uint8_t *) data + n;
448  //Remaining bytes to process
449  length -= n;
450  }
451  else
452  {
453  //The buffer can hold at most 64 bytes
454  n = MIN(length, 64 - context->size);
455 
456  //Copy the data to the buffer
457  osMemcpy(context->buffer + context->size, data, n);
458 
459  //Update the SHA-256 context
460  context->size += n;
461  context->totalSize += n;
462  //Advance the data pointer
463  data = (uint8_t *) data + n;
464  //Remaining bytes to process
465  length -= n;
466 
467  //Check whether the buffer is full
468  if(context->size == 64)
469  {
470  //Update hash value
471  hashProcessData(SHA_MR_ALGO_SHA256, context->buffer, context->size,
472  context->h);
473 
474  //Empty the buffer
475  context->size = 0;
476  }
477  }
478  }
479 }
480 
481 
482 /**
483  * @brief Finish the SHA-256 message digest
484  * @param[in] context Pointer to the SHA-256 context
485  * @param[out] digest Calculated digest
486  **/
487 
488 void sha256Final(Sha256Context *context, uint8_t *digest)
489 {
490  uint_t i;
491  size_t paddingSize;
492  uint64_t totalSize;
493 
494  //Length of the original message (before padding)
495  totalSize = context->totalSize * 8;
496 
497  //Pad the message so that its length is congruent to 56 modulo 64
498  if(context->size < 56)
499  {
500  paddingSize = 56 - context->size;
501  }
502  else
503  {
504  paddingSize = 64 + 56 - context->size;
505  }
506 
507  //Append padding
508  sha256Update(context, padding, paddingSize);
509 
510  //Append the length of the original message
511  for(i = 0; i < 8; i++)
512  {
513  context->buffer[63 - i] = totalSize & 0xFF;
514  totalSize >>= 8;
515  }
516 
517  //Calculate the message digest
518  hashProcessData(SHA_MR_ALGO_SHA256, context->buffer, 64, context->h);
519 
520  //Copy the resulting digest
521  for(i = 0; i < (SHA256_DIGEST_SIZE / 4); i++)
522  {
523  STORE32LE(context->h[i], digest + i * 4);
524  }
525 }
526 
527 
528 /**
529  * @brief Finish the SHA-256 message digest (no padding added)
530  * @param[in] context Pointer to the SHA-256 context
531  * @param[out] digest Calculated digest
532  **/
533 
534 void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
535 {
536  uint_t i;
537 
538  //Copy the resulting digest
539  for(i = 0; i < (SHA256_DIGEST_SIZE / 4); i++)
540  {
541  STORE32LE(context->h[i], digest + i * 4);
542  }
543 }
544 
545 #endif
546 #if (SHA384_SUPPORT == ENABLED)
547 
548 /**
549  * @brief Initialize SHA-384 message digest context
550  * @param[in] context Pointer to the SHA-384 context to initialize
551  **/
552 
553 void sha384Init(Sha384Context *context)
554 {
555  //Set initial hash value
556  context->h[0] = BETOH64(0xCBBB9D5DC1059ED8);
557  context->h[1] = BETOH64(0x629A292A367CD507);
558  context->h[2] = BETOH64(0x9159015A3070DD17);
559  context->h[3] = BETOH64(0x152FECD8F70E5939);
560  context->h[4] = BETOH64(0x67332667FFC00B31);
561  context->h[5] = BETOH64(0x8EB44A8768581511);
562  context->h[6] = BETOH64(0xDB0C2E0D64F98FA7);
563  context->h[7] = BETOH64(0x47B5481DBEFA4FA4);
564 
565  //Number of bytes in the buffer
566  context->size = 0;
567  //Total length of the message
568  context->totalSize = 0;
569 }
570 
571 
572 /**
573  * @brief Finish the SHA-384 message digest (no padding added)
574  * @param[in] context Pointer to the SHA-384 context
575  * @param[out] digest Calculated digest
576  **/
577 
578 void sha384FinalRaw(Sha384Context *context, uint8_t *digest)
579 {
580  uint_t i;
581 
582  //Copy the resulting digest
583  for(i = 0; i < (SHA384_DIGEST_SIZE / 8); i++)
584  {
585  STORE64LE(context->h[i], digest + i * 8);
586  }
587 }
588 
589 #endif
590 #if (SHA512_SUPPORT == ENABLED)
591 
592 /**
593  * @brief Initialize SHA-512 message digest context
594  * @param[in] context Pointer to the SHA-512 context to initialize
595  **/
596 
597 void sha512Init(Sha512Context *context)
598 {
599  //Set initial hash value
600  context->h[0] = BETOH64(0x6A09E667F3BCC908);
601  context->h[1] = BETOH64(0xBB67AE8584CAA73B);
602  context->h[2] = BETOH64(0x3C6EF372FE94F82B);
603  context->h[3] = BETOH64(0xA54FF53A5F1D36F1);
604  context->h[4] = BETOH64(0x510E527FADE682D1);
605  context->h[5] = BETOH64(0x9B05688C2B3E6C1F);
606  context->h[6] = BETOH64(0x1F83D9ABFB41BD6B);
607  context->h[7] = BETOH64(0x5BE0CD19137E2179);
608 
609  //Number of bytes in the buffer
610  context->size = 0;
611  //Total length of the message
612  context->totalSize = 0;
613 }
614 
615 
616 /**
617  * @brief Update the SHA-512 context with a portion of the message being hashed
618  * @param[in] context Pointer to the SHA-512 context
619  * @param[in] data Pointer to the buffer being hashed
620  * @param[in] length Length of the buffer
621  **/
622 
623 void sha512Update(Sha512Context *context, const void *data, size_t length)
624 {
625  size_t n;
626 
627  //Process the incoming data
628  while(length > 0)
629  {
630  //Check whether some data is pending in the buffer
631  if(context->size == 0 && length >= 128)
632  {
633  //The length must be a multiple of 128 bytes
634  n = length - (length % 128);
635 
636  //Update hash value
637  hashProcessData(SHA_MR_ALGO_SHA512, data, n, (uint32_t *) context->h);
638 
639  //Update the SHA-512 context
640  context->totalSize += n;
641  //Advance the data pointer
642  data = (uint8_t *) data + n;
643  //Remaining bytes to process
644  length -= n;
645  }
646  else
647  {
648  //The buffer can hold at most 128 bytes
649  n = MIN(length, 128 - context->size);
650 
651  //Copy the data to the buffer
652  osMemcpy(context->buffer + context->size, data, n);
653 
654  //Update the SHA-512 context
655  context->size += n;
656  context->totalSize += n;
657  //Advance the data pointer
658  data = (uint8_t *) data + n;
659  //Remaining bytes to process
660  length -= n;
661 
662  //Check whether the buffer is full
663  if(context->size == 128)
664  {
665  //Update hash value
666  hashProcessData(SHA_MR_ALGO_SHA512, context->buffer, context->size,
667  (uint32_t *) context->h);
668 
669  //Empty the buffer
670  context->size = 0;
671  }
672  }
673  }
674 }
675 
676 
677 /**
678  * @brief Finish the SHA-512 message digest
679  * @param[in] context Pointer to the SHA-512 context
680  * @param[out] digest Calculated digest
681  **/
682 
683 void sha512Final(Sha512Context *context, uint8_t *digest)
684 {
685  uint_t i;
686  size_t paddingSize;
687  uint64_t totalSize;
688 
689  //Length of the original message (before padding)
690  totalSize = context->totalSize * 8;
691 
692  //Pad the message so that its length is congruent to 112 modulo 128
693  if(context->size < 112)
694  {
695  paddingSize = 112 - context->size;
696  }
697  else
698  {
699  paddingSize = 128 + 112 - context->size;
700  }
701 
702  //Append padding
703  sha512Update(context, padding, paddingSize);
704 
705  //Append the length of the original message
706  for(i = 0; i < 16; i++)
707  {
708  context->buffer[127 - i] = totalSize & 0xFF;
709  totalSize >>= 8;
710  }
711 
712  //Calculate the message digest
713  hashProcessData(SHA_MR_ALGO_SHA512, context->buffer, 128,
714  (uint32_t *) context->h);
715 
716  //Copy the resulting digest
717  for(i = 0; i < (SHA512_DIGEST_SIZE / 8); i++)
718  {
719  STORE64LE(context->h[i], digest + i * 8);
720  }
721 }
722 
723 #endif
724 #if (SHA512_224_SUPPORT == ENABLED)
725 
726 /**
727  * @brief Initialize SHA-512/224 message digest context
728  * @param[in] context Pointer to the SHA-512/224 context to initialize
729  **/
730 
732 {
733  //Set initial hash value
734  context->h[0] = BETOH64(0x8C3D37C819544DA2);
735  context->h[1] = BETOH64(0x73E1996689DCD4D6);
736  context->h[2] = BETOH64(0x1DFAB7AE32FF9C82);
737  context->h[3] = BETOH64(0x679DD514582F9FCF);
738  context->h[4] = BETOH64(0x0F6D2B697BD44DA8);
739  context->h[5] = BETOH64(0x77E36F7304C48942);
740  context->h[6] = BETOH64(0x3F9D85A86A1D36C8);
741  context->h[7] = BETOH64(0x1112E6AD91D692A1);
742 
743  //Number of bytes in the buffer
744  context->size = 0;
745  //Total length of the message
746  context->totalSize = 0;
747 }
748 
749 #endif
750 #if (SHA512_256_SUPPORT == ENABLED)
751 
752 /**
753  * @brief Initialize SHA-512/256 message digest context
754  * @param[in] context Pointer to the SHA-512/256 context to initialize
755  **/
756 
758 {
759  //Set initial hash value
760  context->h[0] = BETOH64(0x22312194FC2BF72C);
761  context->h[1] = BETOH64(0x9F555FA3C84C64C2);
762  context->h[2] = BETOH64(0x2393B86B6F53B151);
763  context->h[3] = BETOH64(0x963877195940EABD);
764  context->h[4] = BETOH64(0x96283EE2A88EFFE3);
765  context->h[5] = BETOH64(0xBE5E1E2553863992);
766  context->h[6] = BETOH64(0x2B0199FC2C85B8AA);
767  context->h[7] = BETOH64(0x0EB72DDC81C52CA2);
768 
769  //Number of bytes in the buffer
770  context->size = 0;
771  //Total length of the message
772  context->totalSize = 0;
773 }
774 
775 #endif
776 #endif
void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest (no padding added)
void sha512Final(Sha512Context *context, uint8_t *digest)
Finish the SHA-512 message digest.
void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest (no padding added)
SHA-256 algorithm context.
Definition: sha256.h:62
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
uint8_t p
Definition: ndp.h:300
void sha512Init(Sha512Context *context)
Initialize SHA-512 message digest context.
uint8_t data[]
Definition: ethernet.h:224
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
size_t size
Definition: sha256.h:69
SAMA5D4 hardware cryptographic accelerator.
uint32_t h[8]
Definition: sha256.h:63
#define BETOH32(value)
Definition: cpu_endian.h:451
uint64_t totalSize
Definition: sha1.h:70
size_t size
Definition: sha512.h:69
uint8_t h
Definition: ndp.h:302
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
void hashProcessData(uint32_t algo, const uint8_t *data, size_t length, uint32_t *h)
Update hash value.
void sha256Final(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest.
void sha224Init(Sha224Context *context)
Initialize SHA-224 message digest context.
OsMutex sama5d4CryptoMutex
SHA-512 algorithm context.
Definition: sha512.h:62
uint32_t h[5]
Definition: sha1.h:63
General definitions for cryptographic algorithms.
uint8_t buffer[128]
Definition: sha512.h:67
void sha256Update(Sha256Context *context, const void *data, size_t length)
Update the SHA-256 context with a portion of the message being hashed.
uint8_t length
Definition: tcp.h:375
uint8_t buffer[64]
Definition: sha256.h:67
#define MIN(a, b)
Definition: os_port.h:63
void sha512_224Init(Sha512_224Context *context)
Initialize SHA-512/224 message digest context.
#define SHA384_DIGEST_SIZE
Definition: sha384.h:41
void sha384FinalRaw(Sha384Context *context, uint8_t *digest)
Finish the SHA-384 message digest (no padding added)
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
Collection of hash algorithms.
void sha512_256Init(Sha512_256Context *context)
Initialize SHA-512/256 message digest context.
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
uint64_t h[8]
Definition: sha512.h:63
uint8_t n
#define STORE64LE(a, p)
Definition: cpu_endian.h:311
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
#define HTOBE32(value)
Definition: cpu_endian.h:443
size_t size
Definition: sha1.h:69
#define BETOH64(value)
Definition: cpu_endian.h:452
SHA-1 algorithm context.
Definition: sha1.h:62
SAMA5D4 hash hardware accelerator.
uint8_t buffer[64]
Definition: sha1.h:67
uint64_t totalSize
Definition: sha512.h:70
uint64_t totalSize
Definition: sha256.h:70
unsigned int uint_t
Definition: compiler_port.h:57
void sha256Init(Sha256Context *context)
Initialize SHA-256 message digest context.
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
void sha512Update(Sha512Context *context, const void *data, size_t length)
Update the SHA-512 context with a portion of the message being hashed.
Debugging facilities.
void sha384Init(Sha384Context *context)
Initialize SHA-384 message digest context.