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-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.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 (optional parameter)
334  **/
335 
336 void sha1Final(Sha1Context *context, uint8_t *digest)
337 {
338  size_t paddingSize;
339  uint64_t totalSize;
340 
341  //Length of the original message (before padding)
342  totalSize = context->totalSize * 8;
343 
344  //Pad the message so that its length is congruent to 56 modulo 64
345  if(context->size < 56)
346  {
347  paddingSize = 56 - context->size;
348  }
349  else
350  {
351  paddingSize = 64 + 56 - context->size;
352  }
353 
354  //Append padding
355  sha1Update(context, padding, paddingSize);
356 
357  //Append the length of the original message
358  context->w[14] = htobe32((uint32_t) (totalSize >> 32));
359  context->w[15] = htobe32((uint32_t) totalSize);
360 
361  //Calculate the message digest
362  hashProcessData(SHA_MODE_SHA1, context->buffer, 64, context->h);
363 
364  //Copy the resulting digest
365  if(digest != NULL)
366  {
367  osMemcpy(digest, context->digest, SHA1_DIGEST_SIZE);
368  }
369 }
370 
371 
372 /**
373  * @brief Finish the SHA-1 message digest (no padding added)
374  * @param[in] context Pointer to the SHA-1 context
375  * @param[out] digest Calculated digest
376  **/
377 
378 void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
379 {
380  //Copy the resulting digest
381  osMemcpy(digest, context->digest, SHA1_DIGEST_SIZE);
382 }
383 
384 #endif
385 #if (SHA224_SUPPORT == ENABLED)
386 
387 /**
388  * @brief Initialize SHA-224 message digest context
389  * @param[in] context Pointer to the SHA-224 context to initialize
390  **/
391 
392 void sha224Init(Sha224Context *context)
393 {
394  //Set initial hash value
395  context->h[0] = BETOH32(0xC1059ED8);
396  context->h[1] = BETOH32(0x367CD507);
397  context->h[2] = BETOH32(0x3070DD17);
398  context->h[3] = BETOH32(0xF70E5939);
399  context->h[4] = BETOH32(0xFFC00B31);
400  context->h[5] = BETOH32(0x68581511);
401  context->h[6] = BETOH32(0x64F98FA7);
402  context->h[7] = BETOH32(0xBEFA4FA4);
403 
404  //Number of bytes in the buffer
405  context->size = 0;
406  //Total length of the message
407  context->totalSize = 0;
408 }
409 
410 #endif
411 #if (SHA256_SUPPORT == ENABLED)
412 
413 /**
414  * @brief Initialize SHA-256 message digest context
415  * @param[in] context Pointer to the SHA-256 context to initialize
416  **/
417 
418 void sha256Init(Sha256Context *context)
419 {
420  //Set initial hash value
421  context->h[0] = BETOH32(0x6A09E667);
422  context->h[1] = BETOH32(0xBB67AE85);
423  context->h[2] = BETOH32(0x3C6EF372);
424  context->h[3] = BETOH32(0xA54FF53A);
425  context->h[4] = BETOH32(0x510E527F);
426  context->h[5] = BETOH32(0x9B05688C);
427  context->h[6] = BETOH32(0x1F83D9AB);
428  context->h[7] = BETOH32(0x5BE0CD19);
429 
430  //Number of bytes in the buffer
431  context->size = 0;
432  //Total length of the message
433  context->totalSize = 0;
434 }
435 
436 
437 /**
438  * @brief Update the SHA-256 context with a portion of the message being hashed
439  * @param[in] context Pointer to the SHA-256 context
440  * @param[in] data Pointer to the buffer being hashed
441  * @param[in] length Length of the buffer
442  **/
443 
444 void sha256Update(Sha256Context *context, const void *data, size_t length)
445 {
446  size_t n;
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(SHA_MODE_SHA256, data, n, context->h);
459 
460  //Update the SHA-256 context
461  context->totalSize += n;
462  //Advance the data pointer
463  data = (uint8_t *) data + n;
464  //Remaining bytes to process
465  length -= n;
466  }
467  else
468  {
469  //The buffer can hold at most 64 bytes
470  n = MIN(length, 64 - context->size);
471 
472  //Copy the data to the buffer
473  osMemcpy(context->buffer + context->size, data, n);
474 
475  //Update the SHA-256 context
476  context->size += n;
477  context->totalSize += n;
478  //Advance the data pointer
479  data = (uint8_t *) data + n;
480  //Remaining bytes to process
481  length -= n;
482 
483  //Check whether the buffer is full
484  if(context->size == 64)
485  {
486  //Update hash value
487  hashProcessData(SHA_MODE_SHA256, context->buffer, context->size,
488  context->h);
489 
490  //Empty the buffer
491  context->size = 0;
492  }
493  }
494  }
495 }
496 
497 
498 /**
499  * @brief Finish the SHA-256 message digest
500  * @param[in] context Pointer to the SHA-256 context
501  * @param[out] digest Calculated digest (optional parameter)
502  **/
503 
504 void sha256Final(Sha256Context *context, uint8_t *digest)
505 {
506  size_t paddingSize;
507  uint64_t totalSize;
508 
509  //Length of the original message (before padding)
510  totalSize = context->totalSize * 8;
511 
512  //Pad the message so that its length is congruent to 56 modulo 64
513  if(context->size < 56)
514  {
515  paddingSize = 56 - context->size;
516  }
517  else
518  {
519  paddingSize = 64 + 56 - context->size;
520  }
521 
522  //Append padding
523  sha256Update(context, padding, paddingSize);
524 
525  //Append the length of the original message
526  context->w[14] = htobe32((uint32_t) (totalSize >> 32));
527  context->w[15] = htobe32((uint32_t) totalSize);
528 
529  //Calculate the message digest
530  hashProcessData(SHA_MODE_SHA256, context->buffer, 64, context->h);
531 
532  //Copy the resulting digest
533  if(digest != NULL)
534  {
535  osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
536  }
537 }
538 
539 
540 /**
541  * @brief Finish the SHA-256 message digest (no padding added)
542  * @param[in] context Pointer to the SHA-256 context
543  * @param[out] digest Calculated digest
544  **/
545 
546 void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
547 {
548  //Copy the resulting digest
549  osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
550 }
551 
552 #endif
553 #if (SHA384_SUPPORT == ENABLED)
554 
555 /**
556  * @brief Initialize SHA-384 message digest context
557  * @param[in] context Pointer to the SHA-384 context to initialize
558  **/
559 
560 void sha384Init(Sha384Context *context)
561 {
562  //Set initial hash value
563  context->h[0] = BETOH64(0xCBBB9D5DC1059ED8);
564  context->h[1] = BETOH64(0x629A292A367CD507);
565  context->h[2] = BETOH64(0x9159015A3070DD17);
566  context->h[3] = BETOH64(0x152FECD8F70E5939);
567  context->h[4] = BETOH64(0x67332667FFC00B31);
568  context->h[5] = BETOH64(0x8EB44A8768581511);
569  context->h[6] = BETOH64(0xDB0C2E0D64F98FA7);
570  context->h[7] = BETOH64(0x47B5481DBEFA4FA4);
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 Finish the SHA-384 message digest (no padding added)
581  * @param[in] context Pointer to the SHA-384 context
582  * @param[out] digest Calculated digest
583  **/
584 
585 void sha384FinalRaw(Sha384Context *context, uint8_t *digest)
586 {
587  //Copy the resulting digest
588  osMemcpy(digest, context->digest, SHA384_DIGEST_SIZE);
589 }
590 
591 #endif
592 #if (SHA512_SUPPORT == ENABLED)
593 
594 /**
595  * @brief Initialize SHA-512 message digest context
596  * @param[in] context Pointer to the SHA-512 context to initialize
597  **/
598 
599 void sha512Init(Sha512Context *context)
600 {
601  //Set initial hash value
602  context->h[0] = BETOH64(0x6A09E667F3BCC908);
603  context->h[1] = BETOH64(0xBB67AE8584CAA73B);
604  context->h[2] = BETOH64(0x3C6EF372FE94F82B);
605  context->h[3] = BETOH64(0xA54FF53A5F1D36F1);
606  context->h[4] = BETOH64(0x510E527FADE682D1);
607  context->h[5] = BETOH64(0x9B05688C2B3E6C1F);
608  context->h[6] = BETOH64(0x1F83D9ABFB41BD6B);
609  context->h[7] = BETOH64(0x5BE0CD19137E2179);
610 
611  //Number of bytes in the buffer
612  context->size = 0;
613  //Total length of the message
614  context->totalSize = 0;
615 }
616 
617 
618 /**
619  * @brief Update the SHA-512 context with a portion of the message being hashed
620  * @param[in] context Pointer to the SHA-512 context
621  * @param[in] data Pointer to the buffer being hashed
622  * @param[in] length Length of the buffer
623  **/
624 
625 void sha512Update(Sha512Context *context, const void *data, size_t length)
626 {
627  size_t n;
628 
629  //Process the incoming data
630  while(length > 0)
631  {
632  //Check whether some data is pending in the buffer
633  if(context->size == 0 && length >= 128)
634  {
635  //The length must be a multiple of 128 bytes
636  n = length - (length % 128);
637 
638  //Update hash value
639  hashProcessData(SHA_MODE_SHA512, data, n, (uint32_t *) context->h);
640 
641  //Update the SHA-512 context
642  context->totalSize += n;
643  //Advance the data pointer
644  data = (uint8_t *) data + n;
645  //Remaining bytes to process
646  length -= n;
647  }
648  else
649  {
650  //The buffer can hold at most 128 bytes
651  n = MIN(length, 128 - context->size);
652 
653  //Copy the data to the buffer
654  osMemcpy(context->buffer + context->size, data, n);
655 
656  //Update the SHA-512 context
657  context->size += n;
658  context->totalSize += n;
659  //Advance the data pointer
660  data = (uint8_t *) data + n;
661  //Remaining bytes to process
662  length -= n;
663 
664  //Check whether the buffer is full
665  if(context->size == 128)
666  {
667  //Update hash value
668  hashProcessData(SHA_MODE_SHA512, context->buffer, context->size,
669  (uint32_t *) context->h);
670 
671  //Empty the buffer
672  context->size = 0;
673  }
674  }
675  }
676 }
677 
678 
679 /**
680  * @brief Finish the SHA-512 message digest
681  * @param[in] context Pointer to the SHA-512 context
682  * @param[out] digest Calculated digest (optional parameter)
683  **/
684 
685 void sha512Final(Sha512Context *context, uint8_t *digest)
686 {
687  size_t paddingSize;
688  uint64_t totalSize;
689 
690  //Length of the original message (before padding)
691  totalSize = context->totalSize * 8;
692 
693  //Pad the message so that its length is congruent to 112 modulo 128
694  if(context->size < 112)
695  {
696  paddingSize = 112 - context->size;
697  }
698  else
699  {
700  paddingSize = 128 + 112 - context->size;
701  }
702 
703  //Append padding
704  sha512Update(context, padding, paddingSize);
705 
706  //Append the length of the original message
707  context->w[14] = 0;
708  context->w[15] = htobe64(totalSize);
709 
710  //Calculate the message digest
711  hashProcessData(SHA_MODE_SHA512, context->buffer, 128,
712  (uint32_t *) context->h);
713 
714  //Copy the resulting digest
715  if(digest != NULL)
716  {
717  osMemcpy(digest, context->digest, SHA512_DIGEST_SIZE);
718  }
719 }
720 
721 #endif
722 #if (SHA512_224_SUPPORT == ENABLED)
723 
724 /**
725  * @brief Initialize SHA-512/224 message digest context
726  * @param[in] context Pointer to the SHA-512/224 context to initialize
727  **/
728 
730 {
731  //Set initial hash value
732  context->h[0] = BETOH64(0x8C3D37C819544DA2);
733  context->h[1] = BETOH64(0x73E1996689DCD4D6);
734  context->h[2] = BETOH64(0x1DFAB7AE32FF9C82);
735  context->h[3] = BETOH64(0x679DD514582F9FCF);
736  context->h[4] = BETOH64(0x0F6D2B697BD44DA8);
737  context->h[5] = BETOH64(0x77E36F7304C48942);
738  context->h[6] = BETOH64(0x3F9D85A86A1D36C8);
739  context->h[7] = BETOH64(0x1112E6AD91D692A1);
740 
741  //Number of bytes in the buffer
742  context->size = 0;
743  //Total length of the message
744  context->totalSize = 0;
745 }
746 
747 #endif
748 #if (SHA512_384_SUPPORT == ENABLED)
749 
750 /**
751  * @brief Initialize SHA-512/256 message digest context
752  * @param[in] context Pointer to the SHA-512/256 context to initialize
753  **/
754 
756 {
757  //Set initial hash value
758  context->h[0] = BETOH64(0x22312194FC2BF72C);
759  context->h[1] = BETOH64(0x9F555FA3C84C64C2);
760  context->h[2] = BETOH64(0x2393B86B6F53B151);
761  context->h[3] = BETOH64(0x963877195940EABD);
762  context->h[4] = BETOH64(0x96283EE2A88EFFE3);
763  context->h[5] = BETOH64(0xBE5E1E2553863992);
764  context->h[6] = BETOH64(0x2B0199FC2C85B8AA);
765  context->h[7] = BETOH64(0x0EB72DDC81C52CA2);
766 
767  //Number of bytes in the buffer
768  context->size = 0;
769  //Total length of the message
770  context->totalSize = 0;
771 }
772 
773 #endif
774 #endif
#define htobe64(value)
Definition: cpu_endian.h:447
#define BETOH32(value)
Definition: cpu_endian.h:451
#define BETOH64(value)
Definition: cpu_endian.h:452
#define LOAD32LE(p)
Definition: cpu_endian.h:203
#define htobe32(value)
Definition: cpu_endian.h:446
General definitions for cryptographic algorithms.
Debugging facilities.
uint8_t n
#define SHA_MODE_SHA1
#define SHA_MODE_SHA224
#define SHA_MODE_SHA256
ESP32-S3 hardware cryptographic accelerator.
void esp32s3ShaInit(void)
SHA module initialization.
void sha224Init(Sha224Context *context)
Initialize SHA-224 message digest context.
void sha384FinalRaw(Sha384Context *context, uint8_t *digest)
Finish the SHA-384 message digest (no padding added)
void sha512_256Init(Sha512_256Context *context)
Initialize SHA-512/256 message digest context.
void sha512Init(Sha512Context *context)
Initialize SHA-512 message digest context.
void sha512_224Init(Sha512_224Context *context)
Initialize SHA-512/224 message digest context.
void sha384Init(Sha384Context *context)
Initialize SHA-384 message digest context.
void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest (no padding added)
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
void sha512Final(Sha512Context *context, uint8_t *digest)
Finish the SHA-512 message digest.
void sha256Update(Sha256Context *context, const void *data, size_t length)
Update the SHA-256 context with a portion of the message being hashed.
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
void sha256Final(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest.
void sha512Update(Sha512Context *context, const void *data, size_t length)
Update the SHA-512 context with a portion of the message being hashed.
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
void hashProcessData(uint32_t algo, const uint8_t *data, size_t length, uint32_t *h)
Update hash value.
void sha256Init(Sha256Context *context)
Initialize SHA-256 message digest context.
void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest (no padding added)
ESP32-S3 hash hardware accelerator.
#define SHA_MODE_SHA384
#define SHA_MODE_SHA512
uint8_t data[]
Definition: ethernet.h:222
Collection of hash algorithms.
uint8_t h
Definition: ndp.h:302
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
#define SHA384_DIGEST_SIZE
Definition: sha384.h:41
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
SHA-1 algorithm context.
Definition: sha1.h:62
uint8_t digest[20]
Definition: sha1.h:66
uint64_t totalSize
Definition: sha1.h:74
size_t size
Definition: sha1.h:73
uint32_t h[5]
Definition: sha1.h:65
uint8_t buffer[64]
Definition: sha1.h:71
uint32_t w[16]
Definition: sha1.h:70
SHA-256 algorithm context.
Definition: sha256.h:62
uint8_t digest[32]
Definition: sha256.h:66
uint64_t totalSize
Definition: sha256.h:74
size_t size
Definition: sha256.h:73
uint8_t buffer[64]
Definition: sha256.h:71
uint32_t h[8]
Definition: sha256.h:65
uint32_t w[16]
Definition: sha256.h:70
SHA-512 algorithm context.
Definition: sha512.h:62
uint64_t h[8]
Definition: sha512.h:65
uint8_t digest[64]
Definition: sha512.h:66
uint64_t totalSize
Definition: sha512.h:74
size_t size
Definition: sha512.h:73
uint64_t w[16]
Definition: sha512.h:70
uint8_t buffer[128]
Definition: sha512.h:71
uint8_t length
Definition: tcp.h:368