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