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