tm4c129_crypto_hash.c
Go to the documentation of this file.
1 /**
2  * @file tm4c129_crypto_hash.c
3  * @brief Tiva TM4C129 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 <stdint.h>
36 #include <stdbool.h>
37 #include "inc/hw_types.h"
38 #include "inc/hw_memmap.h"
39 #include "inc/hw_shamd5.h"
40 #include "core/crypto.h"
43 #include "hash/hash_algorithms.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (TM4C129_CRYPTO_HASH_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Reset SHA/MD5 module
52  **/
53 
54 void hashReset(void)
55 {
56  uint32_t temp;
57 
58  //Perform software reset
59  SHAMD5_SYSCONFIG_R |= SHAMD5_SYSCONFIG_SOFTRESET;
60 
61  //Wait for the reset to complete
62  while((SHAMD5_SYSSTATUS_R & SHAMD5_SYSSTATUS_RESETDONE) == 0)
63  {
64  }
65 
66  //Force idle mode
67  temp = SHAMD5_SYSCONFIG_R & ~SHAMD5_SYSCONFIG_SIDLE_M;
68  SHAMD5_SYSCONFIG_R = temp | SHAMD5_SYSCONFIG_SIDLE_FORCE;
69 }
70 
71 
72 /**
73  * @brief Update hash value
74  * @param[in] data Pointer to the input buffer
75  * @param[in] length Length of the input buffer
76  * @param[out] h Resulting hash value
77  * @param[in] hLen Length of the hash value, in words
78  **/
79 
80 void hashProcessData(const uint8_t *data, size_t length, uint32_t *h,
81  size_t hLen)
82 {
83  size_t i;
84 
85  //Specify the length
87 
88  //Digest input data
89  while(length >= 64)
90  {
91  //Wait for the SHA/MD5 engine to be ready to accept data
92  while((SHAMD5_IRQSTATUS_R & SHAMD5_IRQSTATUS_INPUT_READY) == 0)
93  {
94  }
95 
96  //Write 64-byte block
113 
114  //Advance data pointer
115  data += 64;
116  length -= 64;
117  }
118 
119  //Process final block
120  if(length > 0)
121  {
122  //Wait for the SHA/MD5 engine to be ready to accept data
123  while((SHAMD5_IRQSTATUS_R & SHAMD5_IRQSTATUS_INPUT_READY) == 0)
124  {
125  }
126 
127  //Write final block
128  for(i = 0; i < length; i += 4)
129  {
130  //Write 32-bit word
131  HWREG(SHAMD5_BASE + SHAMD5_O_DATA_0_IN + i) = LOAD32LE(data);
132  //Advance data pointer
133  data += 4;
134  }
135  }
136 
137  //Wait for the output to be ready
138  while((SHAMD5_IRQSTATUS_R & SHAMD5_IRQSTATUS_OUTPUT_READY) == 0)
139  {
140  }
141 
142  //Read the resulting output value
143  for(i = 0; i < hLen; i++)
144  {
145  h[i] = HWREG(SHAMD5_BASE + SHAMD5_O_IDIGEST_A + i * 4);
146  }
147 }
148 
149 
150 #if (MD5_SUPPORT == ENABLED)
151 
152 /**
153  * @brief Digest a message using MD5
154  * @param[in] data Pointer to the message being hashed
155  * @param[in] length Length of the message
156  * @param[out] digest Pointer to the calculated digest
157  * @return Error code
158  **/
159 
160 error_t md5Compute(const void *data, size_t length, uint8_t *digest)
161 {
162  uint_t i;
163  uint32_t h[4];
164 
165  //Acquire exclusive access to the SHA/MD5 module
167 
168  //Reset the SHA/MD5 module before use
169  hashReset();
170 
171  //Configure the SHA/MD5 module
172  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_MD5 | SHAMD5_MODE_ALGO_CONSTANT |
173  SHAMD5_MODE_CLOSE_HASH;
174 
175  //Digest the message
177 
178  //Release exclusive access to the SHA/MD5 module
180 
181  //Copy the resulting digest
182  for(i = 0; i < (MD5_DIGEST_SIZE / 4); i++)
183  {
184  STORE32LE(h[i], digest + i * 4);
185  }
186 
187  //Sucessful processing
188  return NO_ERROR;
189 }
190 
191 
192 /**
193  * @brief Initialize MD5 message digest context
194  * @param[in] context Pointer to the MD5 context to initialize
195  **/
196 
197 void md5Init(Md5Context *context)
198 {
199  //Set initial hash value
200  context->h[0] = 0x67452301;
201  context->h[1] = 0xEFCDAB89;
202  context->h[2] = 0x98BADCFE;
203  context->h[3] = 0x10325476;
204 
205  //Number of bytes in the buffer
206  context->size = 0;
207  //Total length of the message
208  context->totalSize = 0;
209 }
210 
211 
212 /**
213  * @brief Update the MD5 context with a portion of the message being hashed
214  * @param[in] context Pointer to the MD5 context
215  * @param[in] data Pointer to the buffer being hashed
216  * @param[in] length Length of the buffer
217  **/
218 
219 void md5Update(Md5Context *context, const void *data, size_t length)
220 {
221  size_t n;
222 
223  //Acquire exclusive access to the SHA/MD5 module
225 
226  //Reset the SHA/MD5 module before use
227  hashReset();
228 
229  //Configure the SHA/MD5 module
230  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_MD5;
231 
232  //Restore hash context
233  SHAMD5_IDIGEST_A_R = context->h[0];
234  SHAMD5_IDIGEST_B_R = context->h[1];
235  SHAMD5_IDIGEST_C_R = context->h[2];
236  SHAMD5_IDIGEST_D_R = context->h[3];
237 
238  //Restore the value of the SHA_DIGEST_COUNT register
239  SHAMD5_DIGEST_COUNT_R = context->totalSize;
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(data, n, context->h, MD5_DIGEST_SIZE / 4);
252 
253  //Advance the data pointer
254  data = (uint8_t *) data + n;
255  //Remaining bytes to process
256  length -= n;
257  }
258  else
259  {
260  //The buffer can hold at most 64 bytes
261  n = MIN(length, 64 - context->size);
262 
263  //Copy the data to the buffer
264  osMemcpy(context->buffer + context->size, data, n);
265 
266  //Update the MD5 context
267  context->size += n;
268  //Advance the data pointer
269  data = (uint8_t *) data + n;
270  //Remaining bytes to process
271  length -= n;
272 
273  //Check whether the buffer is full
274  if(context->size == 64)
275  {
276  //Update hash value
277  hashProcessData(context->buffer, context->size, context->h,
278  MD5_DIGEST_SIZE / 4);
279 
280  //Empty the buffer
281  context->size = 0;
282  }
283  }
284  }
285 
286  //Save the value of the SHA_DIGEST_COUNT register
287  context->totalSize = SHAMD5_DIGEST_COUNT_R;
288 
289  //Release exclusive access to the SHA/MD5 module
291 }
292 
293 
294 /**
295  * @brief Finish the MD5 message digest
296  * @param[in] context Pointer to the MD5 context
297  * @param[out] digest Calculated digest
298  **/
299 
300 void md5Final(Md5Context *context, uint8_t *digest)
301 {
302  uint_t i;
303 
304  //Acquire exclusive access to the SHA/MD5 module
306 
307  //Reset the SHA/MD5 module before use
308  hashReset();
309 
310  //Configure the SHA/MD5 module
311  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_MD5 | SHAMD5_MODE_CLOSE_HASH;
312 
313  //Restore hash context
314  SHAMD5_IDIGEST_A_R = context->h[0];
315  SHAMD5_IDIGEST_B_R = context->h[1];
316  SHAMD5_IDIGEST_C_R = context->h[2];
317  SHAMD5_IDIGEST_D_R = context->h[3];
318 
319  //Restore the value of the SHA_DIGEST_COUNT register
320  SHAMD5_DIGEST_COUNT_R = context->totalSize;
321 
322  //Finish digest calculation
323  hashProcessData(context->buffer, context->size, context->h,
324  MD5_DIGEST_SIZE / 4);
325 
326  //Release exclusive access to the SHA/MD5 module
328 
329  //Copy the resulting digest
330  for(i = 0; i < (MD5_DIGEST_SIZE / 4); i++)
331  {
332  STORE32LE(context->h[i], digest + i * 4);
333  }
334 }
335 
336 
337 /**
338  * @brief Finish the MD5 message digest (no padding added)
339  * @param[in] context Pointer to the MD5 context
340  * @param[out] digest Calculated digest
341  **/
342 
343 void md5FinalRaw(Md5Context *context, uint8_t *digest)
344 {
345  uint_t i;
346 
347  //Copy the resulting digest
348  for(i = 0; i < (MD5_DIGEST_SIZE / 4); i++)
349  {
350  STORE32LE(context->h[i], digest + i * 4);
351  }
352 }
353 
354 #endif
355 #if (SHA1_SUPPORT == ENABLED)
356 
357 /**
358  * @brief Digest a message using SHA-1
359  * @param[in] data Pointer to the message being hashed
360  * @param[in] length Length of the message
361  * @param[out] digest Pointer to the calculated digest
362  * @return Error code
363  **/
364 
365 error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
366 {
367  uint_t i;
368  uint32_t h[5];
369 
370  //Acquire exclusive access to the SHA/MD5 module
372 
373  //Reset the SHA/MD5 module before use
374  hashReset();
375 
376  //Configure the SHA/MD5 module
377  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA1 | SHAMD5_MODE_ALGO_CONSTANT |
378  SHAMD5_MODE_CLOSE_HASH;
379 
380  //Digest the message
382 
383  //Release exclusive access to the SHA/MD5 module
385 
386  //Copy the resulting digest
387  for(i = 0; i < (SHA1_DIGEST_SIZE / 4); i++)
388  {
389  STORE32LE(h[i], digest + i * 4);
390  }
391 
392  //Sucessful processing
393  return NO_ERROR;
394 }
395 
396 
397 /**
398  * @brief Initialize SHA-1 message digest context
399  * @param[in] context Pointer to the SHA-1 context to initialize
400  **/
401 
402 void sha1Init(Sha1Context *context)
403 {
404  //Set initial hash value
405  context->h[0] = BETOH32(0x67452301);
406  context->h[1] = BETOH32(0xEFCDAB89);
407  context->h[2] = BETOH32(0x98BADCFE);
408  context->h[3] = BETOH32(0x10325476);
409  context->h[4] = BETOH32(0xC3D2E1F0);
410 
411  //Number of bytes in the buffer
412  context->size = 0;
413  //Total length of the message
414  context->totalSize = 0;
415 }
416 
417 
418 /**
419  * @brief Update the SHA-1 context with a portion of the message being hashed
420  * @param[in] context Pointer to the SHA-1 context
421  * @param[in] data Pointer to the buffer being hashed
422  * @param[in] length Length of the buffer
423  **/
424 
425 void sha1Update(Sha1Context *context, const void *data, size_t length)
426 {
427  size_t n;
428 
429  //Acquire exclusive access to the SHA/MD5 module
431 
432  //Reset the SHA/MD5 module before use
433  hashReset();
434 
435  //Configure the SHA/MD5 module
436  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA1;
437 
438  //Restore hash context
439  SHAMD5_IDIGEST_A_R = context->h[0];
440  SHAMD5_IDIGEST_B_R = context->h[1];
441  SHAMD5_IDIGEST_C_R = context->h[2];
442  SHAMD5_IDIGEST_D_R = context->h[3];
443  SHAMD5_IDIGEST_E_R = context->h[4];
444 
445  //Restore the value of the SHA_DIGEST_COUNT register
446  SHAMD5_DIGEST_COUNT_R = context->totalSize;
447 
448  //Process the incoming data
449  while(length > 0)
450  {
451  //Check whether some data is pending in the buffer
452  if(context->size == 0 && length >= 64)
453  {
454  //The length must be a multiple of 64 bytes
455  n = length - (length % 64);
456 
457  //Update hash value
458  hashProcessData(data, n, context->h, SHA1_DIGEST_SIZE / 4);
459 
460  //Advance the data pointer
461  data = (uint8_t *) data + n;
462  //Remaining bytes to process
463  length -= n;
464  }
465  else
466  {
467  //The buffer can hold at most 64 bytes
468  n = MIN(length, 64 - context->size);
469 
470  //Copy the data to the buffer
471  osMemcpy(context->buffer + context->size, data, n);
472 
473  //Update the SHA-1 context
474  context->size += n;
475  //Advance the data pointer
476  data = (uint8_t *) data + n;
477  //Remaining bytes to process
478  length -= n;
479 
480  //Check whether the buffer is full
481  if(context->size == 64)
482  {
483  //Update hash value
484  hashProcessData(context->buffer, context->size, context->h,
485  SHA1_DIGEST_SIZE / 4);
486 
487  //Empty the buffer
488  context->size = 0;
489  }
490  }
491  }
492 
493  //Save the value of the SHA_DIGEST_COUNT register
494  context->totalSize = SHAMD5_DIGEST_COUNT_R;
495 
496  //Release exclusive access to the SHA/MD5 module
498 }
499 
500 
501 /**
502  * @brief Finish the SHA-1 message digest
503  * @param[in] context Pointer to the SHA-1 context
504  * @param[out] digest Calculated digest
505  **/
506 
507 void sha1Final(Sha1Context *context, uint8_t *digest)
508 {
509  uint_t i;
510 
511  //Acquire exclusive access to the SHA/MD5 module
513 
514  //Reset the SHA/MD5 module before use
515  hashReset();
516 
517  //Configure the SHA/MD5 module
518  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA1 | SHAMD5_MODE_CLOSE_HASH;
519 
520  //Restore hash context
521  SHAMD5_IDIGEST_A_R = context->h[0];
522  SHAMD5_IDIGEST_B_R = context->h[1];
523  SHAMD5_IDIGEST_C_R = context->h[2];
524  SHAMD5_IDIGEST_D_R = context->h[3];
525  SHAMD5_IDIGEST_E_R = context->h[4];
526 
527  //Restore the value of the SHA_DIGEST_COUNT register
528  SHAMD5_DIGEST_COUNT_R = context->totalSize;
529 
530  //Finish digest calculation
531  hashProcessData(context->buffer, context->size, context->h,
532  SHA1_DIGEST_SIZE / 4);
533 
534  //Release exclusive access to the SHA/MD5 module
536 
537  //Copy the resulting digest
538  for(i = 0; i < (SHA1_DIGEST_SIZE / 4); i++)
539  {
540  STORE32LE(context->h[i], digest + i * 4);
541  }
542 }
543 
544 
545 /**
546  * @brief Finish the SHA-1 message digest (no padding added)
547  * @param[in] context Pointer to the SHA-1 context
548  * @param[out] digest Calculated digest
549  **/
550 
551 void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
552 {
553  uint_t i;
554 
555  //Copy the resulting digest
556  for(i = 0; i < (SHA1_DIGEST_SIZE / 4); i++)
557  {
558  STORE32LE(context->h[i], digest + i * 4);
559  }
560 }
561 
562 #endif
563 #if (SHA224_SUPPORT == ENABLED)
564 
565 /**
566  * @brief Digest a message using SHA-224
567  * @param[in] data Pointer to the message being hashed
568  * @param[in] length Length of the message
569  * @param[out] digest Pointer to the calculated digest
570  * @return Error code
571  **/
572 
573 error_t sha224Compute(const void *data, size_t length, uint8_t *digest)
574 {
575  uint_t i;
576  uint32_t h[7];
577 
578  //Acquire exclusive access to the SHA/MD5 module
580 
581  //Reset the SHA/MD5 module before use
582  hashReset();
583 
584  //Configure the SHA/MD5 module
585  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA224 | SHAMD5_MODE_ALGO_CONSTANT |
586  SHAMD5_MODE_CLOSE_HASH;
587 
588  //Digest the message
590 
591  //Release exclusive access to the SHA/MD5 module
593 
594  //Copy the resulting digest
595  for(i = 0; i < (SHA224_DIGEST_SIZE / 4); i++)
596  {
597  STORE32LE(h[i], digest + i * 4);
598  }
599 
600  //Sucessful processing
601  return NO_ERROR;
602 }
603 
604 
605 /**
606  * @brief Initialize SHA-224 message digest context
607  * @param[in] context Pointer to the SHA-224 context to initialize
608  **/
609 
610 void sha224Init(Sha224Context *context)
611 {
612  //Set initial hash value
613  context->h[0] = BETOH32(0xC1059ED8);
614  context->h[1] = BETOH32(0x367CD507);
615  context->h[2] = BETOH32(0x3070DD17);
616  context->h[3] = BETOH32(0xF70E5939);
617  context->h[4] = BETOH32(0xFFC00B31);
618  context->h[5] = BETOH32(0x68581511);
619  context->h[6] = BETOH32(0x64F98FA7);
620  context->h[7] = BETOH32(0xBEFA4FA4);
621 
622  //Number of bytes in the buffer
623  context->size = 0;
624  //Total length of the message
625  context->totalSize = 0;
626 }
627 
628 
629 /**
630  * @brief Finish the SHA-224 message digest
631  * @param[in] context Pointer to the SHA-224 context
632  * @param[out] digest Calculated digest
633  **/
634 
635 void sha224Final(Sha224Context *context, uint8_t *digest)
636 {
637  uint_t i;
638 
639  //Acquire exclusive access to the SHA/MD5 module
641 
642  //Reset the SHA/MD5 module before use
643  hashReset();
644 
645  //Configure the SHA/MD5 module
646  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA224 | SHAMD5_MODE_CLOSE_HASH;
647 
648  //Restore hash context
649  SHAMD5_IDIGEST_A_R = context->h[0];
650  SHAMD5_IDIGEST_B_R = context->h[1];
651  SHAMD5_IDIGEST_C_R = context->h[2];
652  SHAMD5_IDIGEST_D_R = context->h[3];
653  SHAMD5_IDIGEST_E_R = context->h[4];
654  SHAMD5_IDIGEST_F_R = context->h[5];
655  SHAMD5_IDIGEST_G_R = context->h[6];
656  SHAMD5_IDIGEST_H_R = context->h[7];
657 
658  //Restore the value of the SHA_DIGEST_COUNT register
659  SHAMD5_DIGEST_COUNT_R = context->totalSize;
660 
661  //Finish digest calculation
662  hashProcessData(context->buffer, context->size, context->h,
663  SHA224_DIGEST_SIZE / 4);
664 
665  //Release exclusive access to the SHA/MD5 module
667 
668  //Copy the resulting digest
669  for(i = 0; i < (SHA224_DIGEST_SIZE / 4); i++)
670  {
671  STORE32LE(context->h[i], digest + i * 4);
672  }
673 }
674 
675 #endif
676 #if (SHA256_SUPPORT == ENABLED)
677 
678 /**
679  * @brief Digest a message using SHA-256
680  * @param[in] data Pointer to the message being hashed
681  * @param[in] length Length of the message
682  * @param[out] digest Pointer to the calculated digest
683  * @return Error code
684  **/
685 
686 error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
687 {
688  uint_t i;
689  uint32_t h[8];
690 
691  //Acquire exclusive access to the SHA/MD5 module
693 
694  //Reset the SHA/MD5 module before use
695  hashReset();
696 
697  //Configure the SHA/MD5 module
698  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA256 | SHAMD5_MODE_ALGO_CONSTANT |
699  SHAMD5_MODE_CLOSE_HASH;
700 
701  //Digest the message
703 
704  //Release exclusive access to the SHA/MD5 module
706 
707  //Copy the resulting digest
708  for(i = 0; i < (SHA256_DIGEST_SIZE / 4); i++)
709  {
710  STORE32LE(h[i], digest + i * 4);
711  }
712 
713  //Sucessful processing
714  return NO_ERROR;
715 }
716 
717 
718 /**
719  * @brief Initialize SHA-256 message digest context
720  * @param[in] context Pointer to the SHA-256 context to initialize
721  **/
722 
723 void sha256Init(Sha256Context *context)
724 {
725  //Set initial hash value
726  context->h[0] = BETOH32(0x6A09E667);
727  context->h[1] = BETOH32(0xBB67AE85);
728  context->h[2] = BETOH32(0x3C6EF372);
729  context->h[3] = BETOH32(0xA54FF53A);
730  context->h[4] = BETOH32(0x510E527F);
731  context->h[5] = BETOH32(0x9B05688C);
732  context->h[6] = BETOH32(0x1F83D9AB);
733  context->h[7] = BETOH32(0x5BE0CD19);
734 
735  //Number of bytes in the buffer
736  context->size = 0;
737  //Total length of the message
738  context->totalSize = 0;
739 }
740 
741 
742 /**
743  * @brief Update the SHA-256 context with a portion of the message being hashed
744  * @param[in] context Pointer to the SHA-256 context
745  * @param[in] data Pointer to the buffer being hashed
746  * @param[in] length Length of the buffer
747  **/
748 
749 void sha256Update(Sha256Context *context, const void *data, size_t length)
750 {
751  size_t n;
752 
753  //Acquire exclusive access to the SHA/MD5 module
755 
756  //Reset the SHA/MD5 module before use
757  hashReset();
758 
759  //Configure the SHA/MD5 module
760  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA256;
761 
762  //Restore hash context
763  SHAMD5_IDIGEST_A_R = context->h[0];
764  SHAMD5_IDIGEST_B_R = context->h[1];
765  SHAMD5_IDIGEST_C_R = context->h[2];
766  SHAMD5_IDIGEST_D_R = context->h[3];
767  SHAMD5_IDIGEST_E_R = context->h[4];
768  SHAMD5_IDIGEST_F_R = context->h[5];
769  SHAMD5_IDIGEST_G_R = context->h[6];
770  SHAMD5_IDIGEST_H_R = context->h[7];
771 
772  //Restore the value of the SHA_DIGEST_COUNT register
773  SHAMD5_DIGEST_COUNT_R = context->totalSize;
774 
775  //Process the incoming data
776  while(length > 0)
777  {
778  //Check whether some data is pending in the buffer
779  if(context->size == 0 && length >= 64)
780  {
781  //The length must be a multiple of 64 bytes
782  n = length - (length % 64);
783 
784  //Update hash value
785  hashProcessData(data, n, context->h, SHA256_DIGEST_SIZE / 4);
786 
787  //Advance the data pointer
788  data = (uint8_t *) data + n;
789  //Remaining bytes to process
790  length -= n;
791  }
792  else
793  {
794  //The buffer can hold at most 64 bytes
795  n = MIN(length, 64 - context->size);
796 
797  //Copy the data to the buffer
798  osMemcpy(context->buffer + context->size, data, n);
799 
800  //Update the SHA-256 context
801  context->size += n;
802  //Advance the data pointer
803  data = (uint8_t *) data + n;
804  //Remaining bytes to process
805  length -= n;
806 
807  //Check whether the buffer is full
808  if(context->size == 64)
809  {
810  //Update hash value
811  hashProcessData(context->buffer, context->size, context->h,
812  SHA256_DIGEST_SIZE / 4);
813 
814  //Empty the buffer
815  context->size = 0;
816  }
817  }
818  }
819 
820  //Save the value of the SHA_DIGEST_COUNT register
821  context->totalSize = SHAMD5_DIGEST_COUNT_R;
822 
823  //Release exclusive access to the SHA/MD5 module
825 }
826 
827 
828 /**
829  * @brief Finish the SHA-256 message digest
830  * @param[in] context Pointer to the SHA-256 context
831  * @param[out] digest Calculated digest
832  **/
833 
834 void sha256Final(Sha256Context *context, uint8_t *digest)
835 {
836  uint_t i;
837 
838  //Acquire exclusive access to the SHA/MD5 module
840 
841  //Reset the SHA/MD5 module before use
842  hashReset();
843 
844  //Configure the SHA/MD5 module
845  SHAMD5_MODE_R = SHAMD5_MODE_ALGO_SHA256 | SHAMD5_MODE_CLOSE_HASH;
846 
847  //Restore hash context
848  SHAMD5_IDIGEST_A_R = context->h[0];
849  SHAMD5_IDIGEST_B_R = context->h[1];
850  SHAMD5_IDIGEST_C_R = context->h[2];
851  SHAMD5_IDIGEST_D_R = context->h[3];
852  SHAMD5_IDIGEST_E_R = context->h[4];
853  SHAMD5_IDIGEST_F_R = context->h[5];
854  SHAMD5_IDIGEST_G_R = context->h[6];
855  SHAMD5_IDIGEST_H_R = context->h[7];
856 
857  //Restore the value of the SHA_DIGEST_COUNT register
858  SHAMD5_DIGEST_COUNT_R = context->totalSize;
859 
860  //Finish digest calculation
861  hashProcessData(context->buffer, context->size, context->h,
862  SHA256_DIGEST_SIZE / 4);
863 
864  //Release exclusive access to the SHA/MD5 module
866 
867  //Copy the resulting digest
868  for(i = 0; i < (SHA256_DIGEST_SIZE / 4); i++)
869  {
870  STORE32LE(context->h[i], digest + i * 4);
871  }
872 }
873 
874 
875 /**
876  * @brief Finish the SHA-256 message digest (no padding added)
877  * @param[in] context Pointer to the SHA-256 context
878  * @param[out] digest Calculated digest
879  **/
880 
881 void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
882 {
883  uint_t i;
884 
885  //Copy the resulting digest
886  for(i = 0; i < (SHA256_DIGEST_SIZE / 4); i++)
887  {
888  STORE32LE(context->h[i], digest + i * 4);
889  }
890 }
891 
892 #endif
893 #endif
void hashProcessData(const uint8_t *data, size_t length, uint32_t *h, size_t hLen)
Update hash value.
#define SHAMD5_DATA_5_IN_R
#define SHAMD5_DATA_10_IN_R
Tiva TM4C129 hardware cryptographic accelerator.
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
#define SHAMD5_SYSCONFIG_R
SHA-256 algorithm context.
Definition: sha256.h:62
#define SHAMD5_SYSSTATUS_R
#define SHAMD5_IDIGEST_C_R
void sha224Init(Sha224Context *context)
Initialize SHA-224 message digest context.
uint8_t data[]
Definition: ethernet.h:222
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
size_t size
Definition: sha256.h:69
#define SHA224_DIGEST_SIZE
Definition: sha224.h:41
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 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)
uint32_t h[8]
Definition: sha256.h:63
void sha256Final(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest.
error_t sha224Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-224.
#define BETOH32(value)
Definition: cpu_endian.h:451
#define SHAMD5_IDIGEST_A_R
void md5FinalRaw(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest (no padding added)
#define SHAMD5_DATA_11_IN_R
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
#define SHAMD5_DATA_13_IN_R
#define SHAMD5_DATA_3_IN_R
uint64_t totalSize
Definition: sha1.h:70
#define SHAMD5_LENGTH_R
#define SHAMD5_DATA_6_IN_R
#define SHAMD5_IDIGEST_F_R
uint8_t buffer[64]
Definition: md5.h:67
uint8_t h
Definition: ndp.h:302
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
void sha256Update(Sha256Context *context, const void *data, size_t length)
Update the SHA-256 context with a portion of the message being hashed.
error_t
Error codes.
Definition: error.h:43
#define SHAMD5_IDIGEST_G_R
#define SHAMD5_DATA_12_IN_R
#define SHAMD5_IRQSTATUS_R
#define SHAMD5_IDIGEST_B_R
#define SHAMD5_DATA_4_IN_R
uint32_t h[5]
Definition: sha1.h:63
General definitions for cryptographic algorithms.
#define SHAMD5_DATA_2_IN_R
void sha224Final(Sha224Context *context, uint8_t *digest)
Finish the SHA-224 message digest.
MD5 algorithm context.
Definition: md5.h:62
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
Tiva TM4C129 hash hardware accelerator.
uint8_t length
Definition: tcp.h:375
uint8_t buffer[64]
Definition: sha256.h:67
#define MIN(a, b)
Definition: os_port.h:63
#define SHAMD5_DATA_1_IN_R
uint64_t totalSize
Definition: md5.h:70
#define SHAMD5_IDIGEST_E_R
#define MD5_DIGEST_SIZE
Definition: md5.h:45
OsMutex tm4c129CryptoMutex
Collection of hash algorithms.
#define SHAMD5_IDIGEST_D_R
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
#define SHAMD5_DATA_8_IN_R
uint8_t n
#define SHAMD5_IDIGEST_H_R
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define SHAMD5_MODE_R
size_t size
Definition: sha1.h:69
error_t md5Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using MD5.
size_t size
Definition: md5.h:69
#define SHAMD5_DATA_15_IN_R
#define SHAMD5_DATA_14_IN_R
SHA-1 algorithm context.
Definition: sha1.h:62
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
#define SHAMD5_DATA_0_IN_R
uint8_t buffer[64]
Definition: sha1.h:67
void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest (no padding added)
#define LOAD32LE(p)
Definition: cpu_endian.h:203
uint64_t totalSize
Definition: sha256.h:70
unsigned int uint_t
Definition: compiler_port.h:57
#define SHAMD5_DIGEST_COUNT_R
#define SHAMD5_DATA_9_IN_R
#define SHAMD5_DATA_7_IN_R
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
void sha256Init(Sha256Context *context)
Initialize SHA-256 message digest context.
uint32_t h[4]
Definition: md5.h:63
error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-256.
@ NO_ERROR
Success.
Definition: error.h:44
void hashReset(void)
Reset SHA/MD5 module.
Debugging facilities.