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