s5d9_crypto_hash.c
Go to the documentation of this file.
1 /**
2  * @file s5d9_crypto_hash.c
3  * @brief Synergy S5D9 hash hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "hw_sce_hash_private.h"
36 #include "core/crypto.h"
39 #include "hash/hash_algorithms.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (S5D9_CRYPTO_HASH_SUPPORT == ENABLED)
44 
45 //Padding string
46 static const uint8_t padding[64] =
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 };
53 
54 
55 #if (MD5_SUPPORT == ENABLED)
56 
57 /**
58  * @brief Initialize MD5 message digest context
59  * @param[in] context Pointer to the MD5 context to initialize
60  **/
61 
62 void md5Init(Md5Context *context)
63 {
64  //Set initial hash value
65  context->h[0] = BETOH32(0x67452301);
66  context->h[1] = BETOH32(0xEFCDAB89);
67  context->h[2] = BETOH32(0x98BADCFE);
68  context->h[3] = BETOH32(0x10325476);
69 
70  //Number of bytes in the buffer
71  context->size = 0;
72  //Total length of the message
73  context->totalSize = 0;
74 }
75 
76 
77 /**
78  * @brief Update the MD5 context with a portion of the message being hashed
79  * @param[in] context Pointer to the MD5 context
80  * @param[in] data Pointer to the buffer being hashed
81  * @param[in] length Length of the buffer
82  **/
83 
84 void md5Update(Md5Context *context, const void *data, size_t length)
85 {
86  size_t n;
87 
88  //Acquire exclusive access to the SCE7 module
90 
91  //Process the incoming data
92  while(length > 0)
93  {
94  //Check whether some data is pending in the buffer
95  if(context->size == 0 && length >= 64)
96  {
97  //The length must be a multiple of 64 bytes
98  n = length - (length % 64);
99 
100  //Update hash value
101  HW_SCE_MD5_MessageDigestGeneration(context->h, data, n / 4,
102  context->h);
103 
104  //Update the MD5 context
105  context->totalSize += n;
106  //Advance the data pointer
107  data = (uint8_t *) data + n;
108  //Remaining bytes to process
109  length -= n;
110  }
111  else
112  {
113  //The buffer can hold at most 64 bytes
114  n = MIN(length, 64 - context->size);
115 
116  //Copy the data to the buffer
117  osMemcpy(context->buffer + context->size, data, n);
118 
119  //Update the MD5 context
120  context->size += n;
121  context->totalSize += n;
122  //Advance the data pointer
123  data = (uint8_t *) data + n;
124  //Remaining bytes to process
125  length -= n;
126 
127  //Check whether the buffer is full
128  if(context->size == 64)
129  {
130  //Update hash value
131  HW_SCE_MD5_MessageDigestGeneration(context->h, context->x, 16,
132  context->h);
133 
134  //Empty the buffer
135  context->size = 0;
136  }
137  }
138  }
139 
140  //Release exclusive access to the SCE7 module
142 }
143 
144 
145 /**
146  * @brief Finish the MD5 message digest
147  * @param[in] context Pointer to the MD5 context
148  * @param[out] digest Calculated digest (optional parameter)
149  **/
150 
151 void md5Final(Md5Context *context, uint8_t *digest)
152 {
153  uint_t i;
154  size_t paddingSize;
155  uint64_t totalSize;
156 
157  //Length of the original message (before padding)
158  totalSize = context->totalSize * 8;
159 
160  //Pad the message so that its length is congruent to 56 modulo 64
161  if(context->size < 56)
162  {
163  paddingSize = 56 - context->size;
164  }
165  else
166  {
167  paddingSize = 64 + 56 - context->size;
168  }
169 
170  //Append padding
171  md5Update(context, padding, paddingSize);
172 
173  //Append the length of the original message
174  context->x[14] = htole32((uint32_t) totalSize);
175  context->x[15] = htole32((uint32_t) (totalSize >> 32));
176 
177  //Calculate the message digest
178  md5ProcessBlock(context);
179 
180  //Convert from host byte order to big-endian byte order
181  for(i = 0; i < 4; i++)
182  {
183  context->h[i] = htobe32(context->h[i]);
184  }
185 
186  //Copy the resulting digest
187  if(digest != NULL)
188  {
189  osMemcpy(digest, context->digest, MD5_DIGEST_SIZE);
190  }
191 }
192 
193 
194 /**
195  * @brief Finish the MD5 message digest (no padding added)
196  * @param[in] context Pointer to the MD5 context
197  * @param[out] digest Calculated digest
198  **/
199 
200 void md5FinalRaw(Md5Context *context, uint8_t *digest)
201 {
202  uint_t i;
203 
204  //Convert from host byte order to big-endian byte order
205  for(i = 0; i < 4; i++)
206  {
207  context->h[i] = htobe32(context->h[i]);
208  }
209 
210  //Copy the resulting digest
211  osMemcpy(digest, context->digest, MD5_DIGEST_SIZE);
212 
213  //Convert from big-endian byte order to host byte order
214  for(i = 0; i < 4; i++)
215  {
216  context->h[i] = betoh32(context->h[i]);
217  }
218 }
219 
220 
221 /**
222  * @brief Process message in 16-word blocks
223  * @param[in] context Pointer to the MD5 context
224  **/
225 
227 {
228  //Acquire exclusive access to the SCE7 module
230  //Accelerate MD5 inner compression loop
231  HW_SCE_MD5_MessageDigestGeneration(context->h, context->x, 16, context->h);
232  //Release exclusive access to the SCE7 module
234 }
235 
236 #endif
237 #if (SHA1_SUPPORT == ENABLED)
238 
239 /**
240  * @brief Initialize SHA-1 message digest context
241  * @param[in] context Pointer to the SHA-1 context to initialize
242  **/
243 
244 void sha1Init(Sha1Context *context)
245 {
246  //Set initial hash value
247  context->h[0] = BETOH32(0x67452301);
248  context->h[1] = BETOH32(0xEFCDAB89);
249  context->h[2] = BETOH32(0x98BADCFE);
250  context->h[3] = BETOH32(0x10325476);
251  context->h[4] = BETOH32(0xC3D2E1F0);
252 
253  //Number of bytes in the buffer
254  context->size = 0;
255  //Total length of the message
256  context->totalSize = 0;
257 }
258 
259 
260 /**
261  * @brief Update the SHA-1 context with a portion of the message being hashed
262  * @param[in] context Pointer to the SHA-1 context
263  * @param[in] data Pointer to the buffer being hashed
264  * @param[in] length Length of the buffer
265  **/
266 
267 void sha1Update(Sha1Context *context, const void *data, size_t length)
268 {
269  size_t n;
270 
271  //Acquire exclusive access to the SCE7 module
273 
274  //Process the incoming data
275  while(length > 0)
276  {
277  //Check whether some data is pending in the buffer
278  if(context->size == 0 && length >= 64)
279  {
280  //The length must be a multiple of 64 bytes
281  n = length - (length % 64);
282 
283  //Update hash value
284  HW_SCE_SHA1_UpdateHash(data, n / 4, context->h);
285 
286  //Update the SHA-1 context
287  context->totalSize += n;
288  //Advance the data pointer
289  data = (uint8_t *) data + n;
290  //Remaining bytes to process
291  length -= n;
292  }
293  else
294  {
295  //The buffer can hold at most 64 bytes
296  n = MIN(length, 64 - context->size);
297 
298  //Copy the data to the buffer
299  osMemcpy(context->buffer + context->size, data, n);
300 
301  //Update the SHA-1 context
302  context->size += n;
303  context->totalSize += n;
304  //Advance the data pointer
305  data = (uint8_t *) data + n;
306  //Remaining bytes to process
307  length -= n;
308 
309  //Check whether the buffer is full
310  if(context->size == 64)
311  {
312  //Update hash value
313  HW_SCE_SHA1_UpdateHash(context->w, 16, context->h);
314 
315  //Empty the buffer
316  context->size = 0;
317  }
318  }
319  }
320 
321  //Release exclusive access to the SCE7 module
323 }
324 
325 
326 /**
327  * @brief Finish the SHA-1 message digest
328  * @param[in] context Pointer to the SHA-1 context
329  * @param[out] digest Calculated digest (optional parameter)
330  **/
331 
332 void sha1Final(Sha1Context *context, uint8_t *digest)
333 {
334  size_t paddingSize;
335  uint64_t totalSize;
336 
337  //Length of the original message (before padding)
338  totalSize = context->totalSize * 8;
339 
340  //Pad the message so that its length is congruent to 56 modulo 64
341  if(context->size < 56)
342  {
343  paddingSize = 56 - context->size;
344  }
345  else
346  {
347  paddingSize = 64 + 56 - context->size;
348  }
349 
350  //Append padding
351  sha1Update(context, padding, paddingSize);
352 
353  //Append the length of the original message
354  context->w[14] = htobe32((uint32_t) (totalSize >> 32));
355  context->w[15] = htobe32((uint32_t) totalSize);
356 
357  //Calculate the message digest
358  sha1ProcessBlock(context);
359 
360  //Copy the resulting digest
361  if(digest != NULL)
362  {
363  osMemcpy(digest, context->digest, SHA1_DIGEST_SIZE);
364  }
365 }
366 
367 
368 /**
369  * @brief Finish the SHA-1 message digest (no padding added)
370  * @param[in] context Pointer to the SHA-1 context
371  * @param[out] digest Calculated digest
372  **/
373 
374 void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
375 {
376  //Copy the resulting digest
377  osMemcpy(digest, context->digest, SHA1_DIGEST_SIZE);
378 }
379 
380 
381 /**
382  * @brief Process message in 16-word blocks
383  * @param[in] context Pointer to the SHA-1 context
384  **/
385 
387 {
388  //Acquire exclusive access to the SCE7 module
390  //Accelerate SHA-1 inner compression loop
391  HW_SCE_SHA1_UpdateHash(context->w, 16, context->h);
392  //Release exclusive access to the SCE7 module
394 }
395 
396 #endif
397 #if (SHA224_SUPPORT == ENABLED)
398 
399 /**
400  * @brief Initialize SHA-224 message digest context
401  * @param[in] context Pointer to the SHA-224 context to initialize
402  **/
403 
404 void sha224Init(Sha224Context *context)
405 {
406  //Set initial hash value
407  context->h[0] = BETOH32(0xC1059ED8);
408  context->h[1] = BETOH32(0x367CD507);
409  context->h[2] = BETOH32(0x3070DD17);
410  context->h[3] = BETOH32(0xF70E5939);
411  context->h[4] = BETOH32(0xFFC00B31);
412  context->h[5] = BETOH32(0x68581511);
413  context->h[6] = BETOH32(0x64F98FA7);
414  context->h[7] = BETOH32(0xBEFA4FA4);
415 
416  //Number of bytes in the buffer
417  context->size = 0;
418  //Total length of the message
419  context->totalSize = 0;
420 }
421 
422 #endif
423 #if (SHA256_SUPPORT == ENABLED)
424 
425 /**
426  * @brief Initialize SHA-256 message digest context
427  * @param[in] context Pointer to the SHA-256 context to initialize
428  **/
429 
430 void sha256Init(Sha256Context *context)
431 {
432  //Set initial hash value
433  context->h[0] = BETOH32(0x6A09E667);
434  context->h[1] = BETOH32(0xBB67AE85);
435  context->h[2] = BETOH32(0x3C6EF372);
436  context->h[3] = BETOH32(0xA54FF53A);
437  context->h[4] = BETOH32(0x510E527F);
438  context->h[5] = BETOH32(0x9B05688C);
439  context->h[6] = BETOH32(0x1F83D9AB);
440  context->h[7] = BETOH32(0x5BE0CD19);
441 
442  //Number of bytes in the buffer
443  context->size = 0;
444  //Total length of the message
445  context->totalSize = 0;
446 }
447 
448 
449 /**
450  * @brief Update the SHA-256 context with a portion of the message being hashed
451  * @param[in] context Pointer to the SHA-256 context
452  * @param[in] data Pointer to the buffer being hashed
453  * @param[in] length Length of the buffer
454  **/
455 
456 void sha256Update(Sha256Context *context, const void *data, size_t length)
457 {
458  size_t n;
459 
460  //Acquire exclusive access to the SCE7 module
462 
463  //Process the incoming data
464  while(length > 0)
465  {
466  //Check whether some data is pending in the buffer
467  if(context->size == 0 && length >= 64)
468  {
469  //The length must be a multiple of 64 bytes
470  n = length - (length % 64);
471 
472  //Update hash value
473  HW_SCE_SHA256_UpdateHash(data, n / 4, context->h);
474 
475  //Update the SHA-256 context
476  context->totalSize += n;
477  //Advance the data pointer
478  data = (uint8_t *) data + n;
479  //Remaining bytes to process
480  length -= n;
481  }
482  else
483  {
484  //The buffer can hold at most 64 bytes
485  n = MIN(length, 64 - context->size);
486 
487  //Copy the data to the buffer
488  osMemcpy(context->buffer + context->size, data, n);
489 
490  //Update the SHA-256 context
491  context->size += n;
492  context->totalSize += n;
493  //Advance the data pointer
494  data = (uint8_t *) data + n;
495  //Remaining bytes to process
496  length -= n;
497 
498  //Check whether the buffer is full
499  if(context->size == 64)
500  {
501  //Update hash value
502  HW_SCE_SHA256_UpdateHash(context->w, 16, context->h);
503 
504  //Empty the buffer
505  context->size = 0;
506  }
507  }
508  }
509 
510  //Release exclusive access to the SCE7 module
512 }
513 
514 
515 /**
516  * @brief Finish the SHA-256 message digest
517  * @param[in] context Pointer to the SHA-256 context
518  * @param[out] digest Calculated digest (optional parameter)
519  **/
520 
521 void sha256Final(Sha256Context *context, uint8_t *digest)
522 {
523  size_t paddingSize;
524  uint64_t totalSize;
525 
526  //Length of the original message (before padding)
527  totalSize = context->totalSize * 8;
528 
529  //Pad the message so that its length is congruent to 56 modulo 64
530  if(context->size < 56)
531  {
532  paddingSize = 56 - context->size;
533  }
534  else
535  {
536  paddingSize = 64 + 56 - context->size;
537  }
538 
539  //Append padding
540  sha256Update(context, padding, paddingSize);
541 
542  //Append the length of the original message
543  context->w[14] = htobe32((uint32_t) (totalSize >> 32));
544  context->w[15] = htobe32((uint32_t) totalSize);
545 
546  //Calculate the message digest
547  sha256ProcessBlock(context);
548 
549  //Copy the resulting digest
550  if(digest != NULL)
551  {
552  osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
553  }
554 }
555 
556 
557 /**
558  * @brief Finish the SHA-256 message digest (no padding added)
559  * @param[in] context Pointer to the SHA-256 context
560  * @param[out] digest Calculated digest
561  **/
562 
563 void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
564 {
565  //Copy the resulting digest
566  osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
567 }
568 
569 
570 /**
571  * @brief Process message in 16-word blocks
572  * @param[in] context Pointer to the SHA-256 context
573  **/
574 
576 {
577  //Acquire exclusive access to the SCE7 module
579  //Accelerate SHA-256 inner compression loop
580  HW_SCE_SHA256_UpdateHash(context->w, 16, context->h);
581  //Release exclusive access to the SCE7 module
583 }
584 
585 #endif
586 #endif
#define betoh32(value)
Definition: cpu_endian.h:454
Synergy S5D9 hash hardware accelerator.
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
uint8_t digest[16]
Definition: md5.h:66
SHA-256 algorithm context.
Definition: sha256.h:62
void sha1ProcessBlock(Sha1Context *context)
Process message in 16-word blocks.
void md5ProcessBlock(Md5Context *context)
Process message in 16-word blocks.
uint8_t data[]
Definition: ethernet.h:222
size_t size
Definition: sha256.h:73
void sha256ProcessBlock(Sha256Context *context)
Process message in 16-word blocks.
uint32_t h[8]
Definition: sha256.h:65
#define BETOH32(value)
Definition: cpu_endian.h:451
void sha1FinalRaw(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest (no padding added)
void sha224Init(Sha224Context *context)
Initialize SHA-224 message digest context.
uint64_t totalSize
Definition: sha1.h:74
uint32_t x[16]
Definition: md5.h:70
uint8_t buffer[64]
Definition: md5.h:71
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
uint32_t w[16]
Definition: sha256.h:70
#define htole32(value)
Definition: cpu_endian.h:430
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 context with a portion of the message being hashed.
uint32_t h[5]
Definition: sha1.h:65
General definitions for cryptographic algorithms.
MD5 algorithm context.
Definition: md5.h:62
uint8_t length
Definition: tcp.h:368
uint8_t buffer[64]
Definition: sha256.h:71
void sha256Update(Sha256Context *context, const void *data, size_t length)
Update the SHA-256 context with a portion of the message being hashed.
#define MIN(a, b)
Definition: os_port.h:63
uint64_t totalSize
Definition: md5.h:74
#define MD5_DIGEST_SIZE
Definition: md5.h:45
void md5FinalRaw(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest (no padding added)
Collection of hash algorithms.
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
#define htobe32(value)
Definition: cpu_endian.h:446
uint8_t digest[32]
Definition: sha256.h:66
void sha256FinalRaw(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest (no padding added)
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
uint8_t n
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
size_t size
Definition: sha1.h:73
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
size_t size
Definition: md5.h:73
uint32_t w[16]
Definition: sha1.h:70
SHA-1 algorithm context.
Definition: sha1.h:62
void sha256Init(Sha256Context *context)
Initialize SHA-256 message digest context.
uint8_t buffer[64]
Definition: sha1.h:71
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
uint64_t totalSize
Definition: sha256.h:74
unsigned int uint_t
Definition: compiler_port.h:50
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
OsMutex s5d9CryptoMutex
Definition: s5d9_crypto.c:41
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
uint32_t h[4]
Definition: md5.h:65
void sha256Final(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest.
uint8_t digest[20]
Definition: sha1.h:66
Debugging facilities.
Synergy S5D9 hardware cryptographic accelerator (SCE7)