nuc472_crypto_hash.c
Go to the documentation of this file.
1 /**
2  * @file nuc472_crypto_hash.c
3  * @brief NUC472 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 "nuc472_442.h"
36 #include "core/crypto.h"
39 #include "hash/hash_algorithms.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (NUC472_CRYPTO_HASH_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Update hash value
48  * @param[in] data Pointer to the input buffer
49  * @param[in] length Length of the input buffer
50  **/
51 
52 void hashProcessData(const uint8_t *data, size_t length)
53 {
54  size_t i;
55 
56  //Process input data
57  for(i = 0; i < length; i += 4)
58  {
59  //Wait for the DATINREQ bit to be set
60  while((CRPT->SHA_STS & CRPT_SHA_STS_DATINREQ_Msk) == 0)
61  {
62  }
63 
64  //Write one word of data
65  CRPT->SHA_DATIN = __UNALIGNED_UINT32_READ(data + i);
66  }
67 
68  //Wait for the processing to complete
69  while((CRPT->SHA_STS & CRPT_SHA_STS_DATINREQ_Msk) == 0)
70  {
71  }
72 }
73 
74 
75 #if (SHA1_SUPPORT == ENABLED)
76 
77 /**
78  * @brief Digest a message using SHA-1
79  * @param[in] data Pointer to the message being hashed
80  * @param[in] length Length of the message
81  * @param[out] digest Pointer to the calculated digest
82  * @return Error code
83  **/
84 
85 error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
86 {
87  size_t n;
88  uint32_t temp;
89  uint8_t buffer[64];
90 
91  //Acquire exclusive access to the CRYPTO module
93 
94  //Reset CRYPTO controller
95  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
96  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
97 
98  //Select the relevant hash algorithm
99  CRPT->SHA_CTL = CRPT_SHA_CTL_INSWAP_Msk | CRPT_SHA_CTL_OUTSWAP_Msk |
101 
102  //Start SHA engine
103  CRPT->SHA_CTL |= CRPT_SHA_CTL_START_Msk;
104 
105  //Digest the message
106  for(n = length; n >= 64; n -= 64)
107  {
108  //Update hash value
109  hashProcessData(data, 64);
110  //Advance the data pointer
111  data = (uint8_t *) data + 64;
112  }
113 
114  //Copy the partial block, is any
115  osMemset(buffer, 0, 64);
116  osMemcpy(buffer, data, n);
117 
118  //Append the first byte of the padding string
119  buffer[n] = 0x80;
120 
121  //Pad the message so that its length is congruent to 56 modulo 64
122  if(n >= 56)
123  {
124  hashProcessData(buffer, 64);
125  osMemset(buffer, 0, 64);
126  }
127 
128  //Append the length of the original message
129  STORE64BE(length * 8, buffer + 56);
130 
131  //Process the final block
132  hashProcessData(buffer, 64);
133 
134  //Save the resulting hash value
135  temp = CRPT->SHA_DGST0;
136  __UNALIGNED_UINT32_WRITE(digest, temp);
137  temp = CRPT->SHA_DGST1;
138  __UNALIGNED_UINT32_WRITE(digest + 4, temp);
139  temp = CRPT->SHA_DGST2;
140  __UNALIGNED_UINT32_WRITE(digest + 8, temp);
141  temp = CRPT->SHA_DGST3;
142  __UNALIGNED_UINT32_WRITE(digest + 12, temp);
143  temp = CRPT->SHA_DGST4;
144  __UNALIGNED_UINT32_WRITE(digest + 16, temp);
145 
146  //Stop SHA engine
147  CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
148 
149  //Release exclusive access to the CRYPTO module
151 
152  //Sucessful processing
153  return NO_ERROR;
154 }
155 
156 #endif
157 #if (SHA224_SUPPORT == ENABLED)
158 
159 /**
160  * @brief Digest a message using SHA-224
161  * @param[in] data Pointer to the message being hashed
162  * @param[in] length Length of the message
163  * @param[out] digest Pointer to the calculated digest
164  * @return Error code
165  **/
166 
167 error_t sha224Compute(const void *data, size_t length, uint8_t *digest)
168 {
169  size_t n;
170  uint32_t temp;
171  uint8_t buffer[64];
172 
173  //Acquire exclusive access to the CRYPTO module
175 
176  //Reset CRYPTO controller
177  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
178  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
179 
180  //Select the relevant hash algorithm
181  CRPT->SHA_CTL = CRPT_SHA_CTL_INSWAP_Msk | CRPT_SHA_CTL_OUTSWAP_Msk |
183 
184  //Start SHA engine
185  CRPT->SHA_CTL |= CRPT_SHA_CTL_START_Msk;
186 
187  //Digest the message
188  for(n = length; n >= 64; n -= 64)
189  {
190  //Update hash value
191  hashProcessData(data, 64);
192  //Advance the data pointer
193  data = (uint8_t *) data + 64;
194  }
195 
196  //Copy the partial block, is any
197  osMemset(buffer, 0, 64);
198  osMemcpy(buffer, data, n);
199 
200  //Append the first byte of the padding string
201  buffer[n] = 0x80;
202 
203  //Pad the message so that its length is congruent to 56 modulo 64
204  if(n >= 56)
205  {
206  hashProcessData(buffer, 64);
207  osMemset(buffer, 0, 64);
208  }
209 
210  //Append the length of the original message
211  STORE64BE(length * 8, buffer + 56);
212 
213  //Process the final block
214  hashProcessData(buffer, 64);
215 
216  //Save the resulting hash value
217  temp = CRPT->SHA_DGST0;
218  __UNALIGNED_UINT32_WRITE(digest, temp);
219  temp = CRPT->SHA_DGST1;
220  __UNALIGNED_UINT32_WRITE(digest + 4, temp);
221  temp = CRPT->SHA_DGST2;
222  __UNALIGNED_UINT32_WRITE(digest + 8, temp);
223  temp = CRPT->SHA_DGST3;
224  __UNALIGNED_UINT32_WRITE(digest + 12, temp);
225  temp = CRPT->SHA_DGST4;
226  __UNALIGNED_UINT32_WRITE(digest + 16, temp);
227  temp = CRPT->SHA_DGST5;
228  __UNALIGNED_UINT32_WRITE(digest + 20, temp);
229  temp = CRPT->SHA_DGST6;
230  __UNALIGNED_UINT32_WRITE(digest + 24, temp);
231 
232  //Stop SHA engine
233  CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
234 
235  //Release exclusive access to the CRYPTO module
237 
238  //Sucessful processing
239  return NO_ERROR;
240 }
241 
242 #endif
243 #if (SHA256_SUPPORT == ENABLED)
244 
245 /**
246  * @brief Digest a message using SHA-256
247  * @param[in] data Pointer to the message being hashed
248  * @param[in] length Length of the message
249  * @param[out] digest Pointer to the calculated digest
250  * @return Error code
251  **/
252 
253 error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
254 {
255  size_t n;
256  uint32_t temp;
257  uint8_t buffer[64];
258 
259  //Acquire exclusive access to the CRYPTO module
261 
262  //Reset CRYPTO controller
263  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
264  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
265 
266  //Select the relevant hash algorithm
267  CRPT->SHA_CTL = CRPT_SHA_CTL_INSWAP_Msk | CRPT_SHA_CTL_OUTSWAP_Msk |
269 
270  //Start SHA engine
271  CRPT->SHA_CTL |= CRPT_SHA_CTL_START_Msk;
272 
273  //Digest the message
274  for(n = length; n >= 64; n -= 64)
275  {
276  //Update hash value
277  hashProcessData(data, 64);
278  //Advance the data pointer
279  data = (uint8_t *) data + 64;
280  }
281 
282  //Copy the partial block, is any
283  osMemset(buffer, 0, 64);
284  osMemcpy(buffer, data, n);
285 
286  //Append the first byte of the padding string
287  buffer[n] = 0x80;
288 
289  //Pad the message so that its length is congruent to 56 modulo 64
290  if(n >= 56)
291  {
292  hashProcessData(buffer, 64);
293  osMemset(buffer, 0, 64);
294  }
295 
296  //Append the length of the original message
297  STORE64BE(length * 8, buffer + 56);
298 
299  //Process the final block
300  hashProcessData(buffer, 64);
301 
302  //Save the resulting hash value
303  temp = CRPT->SHA_DGST0;
304  __UNALIGNED_UINT32_WRITE(digest, temp);
305  temp = CRPT->SHA_DGST1;
306  __UNALIGNED_UINT32_WRITE(digest + 4, temp);
307  temp = CRPT->SHA_DGST2;
308  __UNALIGNED_UINT32_WRITE(digest + 8, temp);
309  temp = CRPT->SHA_DGST3;
310  __UNALIGNED_UINT32_WRITE(digest + 12, temp);
311  temp = CRPT->SHA_DGST4;
312  __UNALIGNED_UINT32_WRITE(digest + 16, temp);
313  temp = CRPT->SHA_DGST5;
314  __UNALIGNED_UINT32_WRITE(digest + 20, temp);
315  temp = CRPT->SHA_DGST6;
316  __UNALIGNED_UINT32_WRITE(digest + 24, temp);
317  temp = CRPT->SHA_DGST7;
318  __UNALIGNED_UINT32_WRITE(digest + 28, temp);
319 
320  //Stop SHA engine
321  CRPT->SHA_CTL |= CRPT_SHA_CTL_STOP_Msk;
322 
323  //Release exclusive access to the CRYPTO module
325 
326  //Sucessful processing
327  return NO_ERROR;
328 }
329 
330 #endif
331 #endif
#define CRPT_SHA_CTL_OPMODE_SHA1
uint8_t data[]
Definition: ethernet.h:222
void hashProcessData(const uint8_t *data, size_t length)
Update hash value.
#define CRPT_SHA_CTL_OPMODE_SHA256
OsMutex nuc472CryptoMutex
Definition: nuc472_crypto.c:41
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t
Error codes.
Definition: error.h:43
General definitions for cryptographic algorithms.
uint8_t length
Definition: tcp.h:375
Collection of hash algorithms.
#define STORE64BE(a, p)
Definition: cpu_endian.h:322
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.
error_t sha224Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-224.
error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-256.
#define osMemset(p, value, length)
Definition: os_port.h:138
#define CRPT_SHA_CTL_OPMODE_SHA224
NUC472 hash hardware accelerator.
NUC472 hardware cryptographic accelerator.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.