mimxrt1040_crypto_hash.c
Go to the documentation of this file.
1 /**
2  * @file mimxrt1040_crypto_hash.c
3  * @brief i.MX RT1040 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 "fsl_device_registers.h"
36 #include "fsl_dcp.h"
37 #include "core/crypto.h"
40 #include "hash/hash_algorithms.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (MIMXRT1040_CRYPTO_HASH_SUPPORT == ENABLED)
45 
46 //IAR EWARM compiler?
47 #if defined(__ICCARM__)
48 
49 //DCP buffer
50 #pragma data_alignment = 16
51 #pragma location = MIMXRT1040_DCP_RAM_SECTION
52 static uint8_t dcpBuffer[MIMXRT1040_DCP_BUFFER_SIZE];
53 
54 //DCP hash context
55 #pragma data_alignment = 16
56 #pragma location = MIMXRT1040_DCP_RAM_SECTION
57 static dcp_hash_ctx_t dcpHashContext;
58 
59 //ARM or GCC compiler?
60 #else
61 
62 //DCP buffer
63 static uint8_t dcpBuffer[MIMXRT1040_DCP_BUFFER_SIZE]
64  __attribute__((aligned(16), __section__(MIMXRT1040_DCP_RAM_SECTION)));
65 
66 //DCP hash context
67 static dcp_hash_ctx_t dcpHashContext
68  __attribute__((aligned(16), __section__(MIMXRT1040_DCP_RAM_SECTION)));
69 
70 #endif
71 
72 #if (SHA1_SUPPORT == ENABLED)
73 
74 /**
75  * @brief Digest a message using SHA-1
76  * @param[in] data Pointer to the message being hashed
77  * @param[in] length Length of the message
78  * @param[out] digest Pointer to the calculated digest
79  * @return Error code
80  **/
81 
82 error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
83 {
84  size_t n;
85  status_t status;
86  dcp_handle_t dcpHandle;
87 
88  //Set DCP parameters
89  dcpHandle.channel = kDCP_Channel0;
90  dcpHandle.keySlot = kDCP_KeySlot0;
91  dcpHandle.swapConfig = kDCP_NoSwap;
92 
93  //Acquire exclusive access to the DCP module
95 
96  //Initialize hash computation
97  status = DCP_HASH_Init(DCP, &dcpHandle, &dcpHashContext, kDCP_Sha1);
98 
99  //Digest the message
100  while(length > 0 && status == kStatus_Success)
101  {
102  //Limit the number of data to process at a time
104  //Copy the data to the buffer
105  osMemcpy(dcpBuffer, data, n);
106 
107  //Update hash value
108  status = DCP_HASH_Update(DCP, &dcpHashContext, dcpBuffer, n);
109 
110  //Advance the data pointer
111  data = (uint8_t *) data + n;
112  //Remaining bytes to process
113  length -= n;
114  }
115 
116  //Check status code
117  if(status == kStatus_Success)
118  {
119  //Specify the size of the output buffer
121  //Finalize hash computation
122  status = DCP_HASH_Finish(DCP, &dcpHashContext, digest, &n);
123  }
124 
125  //Release exclusive access to the DCP module
127 
128  //Return status code
129  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
130 }
131 
132 
133 /**
134  * @brief Initialize SHA-1 message digest context
135  * @param[in] context Pointer to the SHA-1 context to initialize
136  **/
137 
138 void sha1Init(Sha1Context *context)
139 {
140  dcp_handle_t *dcpHandle;
141 
142  //Point to the DCP handle
143  dcpHandle = &context->dcpHandle;
144 
145  //Set DCP parameters
146  dcpHandle->channel = kDCP_Channel0;
147  dcpHandle->keySlot = kDCP_KeySlot0;
148  dcpHandle->swapConfig = kDCP_NoSwap;
149 
150  //Acquire exclusive access to the DCP module
152 
153  //Initialize hash computation
154  DCP_HASH_Init(DCP, dcpHandle, &dcpHashContext, kDCP_Sha1);
155  //Save hash context
156  context->dcpContext = dcpHashContext;
157 
158  //Release exclusive access to the DCP module
160 }
161 
162 
163 /**
164  * @brief Update the SHA-1 context with a portion of the message being hashed
165  * @param[in] context Pointer to the SHA-1 context
166  * @param[in] data Pointer to the buffer being hashed
167  * @param[in] length Length of the buffer
168  **/
169 
170 void sha1Update(Sha1Context *context, const void *data, size_t length)
171 {
172  size_t n;
173 
174  //Acquire exclusive access to the DCP module
176 
177  //Restore hash context
178  dcpHashContext = context->dcpContext;
179 
180  //Digest the message
181  while(length > 0)
182  {
183  //Limit the number of data to process at a time
185  //Copy the data to the buffer
186  osMemcpy(dcpBuffer, data, n);
187 
188  //Update hash value
189  DCP_HASH_Update(DCP, &dcpHashContext, dcpBuffer, n);
190 
191  //Advance the data pointer
192  data = (uint8_t *) data + n;
193  //Remaining bytes to process
194  length -= n;
195  }
196 
197  //Save hash context
198  context->dcpContext = dcpHashContext;
199 
200  //Release exclusive access to the DCP module
202 }
203 
204 
205 /**
206  * @brief Finish the SHA-1 message digest
207  * @param[in] context Pointer to the SHA-1 context
208  * @param[out] digest Calculated digest (optional parameter)
209  **/
210 
211 void sha1Final(Sha1Context *context, uint8_t *digest)
212 {
213  size_t n;
214 
215  //Specify the size of the output buffer
217 
218  //Acquire exclusive access to the DCP module
220 
221  //Restore hash context
222  dcpHashContext = context->dcpContext;
223  //Finalize hash computation
224  DCP_HASH_Finish(DCP, &dcpHashContext, context->digest, &n);
225 
226  //Release exclusive access to the DCP module
228 
229  //Copy the resulting digest
230  if(digest != NULL)
231  {
232  osMemcpy(digest, context->digest, SHA1_DIGEST_SIZE);
233  }
234 }
235 
236 #endif
237 #if (SHA256_SUPPORT == ENABLED)
238 
239 /**
240  * @brief Digest a message using SHA-256
241  * @param[in] data Pointer to the message being hashed
242  * @param[in] length Length of the message
243  * @param[out] digest Pointer to the calculated digest
244  * @return Error code
245  **/
246 
247 error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
248 {
249  size_t n;
250  status_t status;
251  dcp_handle_t dcpHandle;
252 
253  //Set DCP parameters
254  dcpHandle.channel = kDCP_Channel0;
255  dcpHandle.keySlot = kDCP_KeySlot0;
256  dcpHandle.swapConfig = kDCP_NoSwap;
257 
258  //Acquire exclusive access to the DCP module
260 
261  //Initialize hash computation
262  status = DCP_HASH_Init(DCP, &dcpHandle, &dcpHashContext, kDCP_Sha256);
263 
264  //Digest the message
265  while(length > 0 && status == kStatus_Success)
266  {
267  //Limit the number of data to process at a time
269  //Copy the data to the buffer
270  osMemcpy(dcpBuffer, data, n);
271 
272  //Update hash value
273  status = DCP_HASH_Update(DCP, &dcpHashContext, dcpBuffer, n);
274 
275  //Advance the data pointer
276  data = (uint8_t *) data + n;
277  //Remaining bytes to process
278  length -= n;
279  }
280 
281  //Check status code
282  if(status == kStatus_Success)
283  {
284  //Specify the size of the output buffer
286  //Finalize hash computation
287  status = DCP_HASH_Finish(DCP, &dcpHashContext, digest, &n);
288  }
289 
290  //Release exclusive access to the DCP module
292 
293  //Return status code
294  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
295 }
296 
297 
298 /**
299  * @brief Initialize SHA-256 message digest context
300  * @param[in] context Pointer to the SHA-256 context to initialize
301  **/
302 
303 void sha256Init(Sha256Context *context)
304 {
305  dcp_handle_t *dcpHandle;
306 
307  //Point to the DCP handle
308  dcpHandle = &context->dcpHandle;
309 
310  //Set DCP parameters
311  dcpHandle->channel = kDCP_Channel0;
312  dcpHandle->keySlot = kDCP_KeySlot0;
313  dcpHandle->swapConfig = kDCP_NoSwap;
314 
315  //Acquire exclusive access to the DCP module
317 
318  //Initialize hash computation
319  DCP_HASH_Init(DCP, dcpHandle, &dcpHashContext, kDCP_Sha256);
320  //Save hash context
321  context->dcpContext = dcpHashContext;
322 
323  //Release exclusive access to the DCP module
325 }
326 
327 
328 /**
329  * @brief Update the SHA-256 context with a portion of the message being hashed
330  * @param[in] context Pointer to the SHA-256 context
331  * @param[in] data Pointer to the buffer being hashed
332  * @param[in] length Length of the buffer
333  **/
334 
335 void sha256Update(Sha256Context *context, const void *data, size_t length)
336 {
337  size_t n;
338 
339  //Acquire exclusive access to the DCP module
341 
342  //Restore hash context
343  dcpHashContext = context->dcpContext;
344 
345  //Digest the message
346  while(length > 0)
347  {
348  //Limit the number of data to process at a time
350  //Copy the data to the buffer
351  osMemcpy(dcpBuffer, data, n);
352 
353  //Update hash value
354  DCP_HASH_Update(DCP, &dcpHashContext, dcpBuffer, n);
355 
356  //Advance the data pointer
357  data = (uint8_t *) data + n;
358  //Remaining bytes to process
359  length -= n;
360  }
361 
362  //Save hash context
363  context->dcpContext = dcpHashContext;
364 
365  //Release exclusive access to the DCP module
367 }
368 
369 
370 /**
371  * @brief Finish the SHA-256 message digest
372  * @param[in] context Pointer to the SHA-256 context
373  * @param[out] digest Calculated digest (optional parameter)
374  **/
375 
376 void sha256Final(Sha256Context *context, uint8_t *digest)
377 {
378  size_t n;
379 
380  //Specify the size of the output buffer
382 
383  //Acquire exclusive access to the DCP module
385 
386  //Restore hash context
387  dcpHashContext = context->dcpContext;
388  //Finalize hash computation
389  DCP_HASH_Finish(DCP, &dcpHashContext, context->digest, &n);
390 
391  //Release exclusive access to the DCP module
393 
394  //Copy the resulting digest
395  if(digest != NULL)
396  {
397  osMemcpy(digest, context->digest, SHA256_DIGEST_SIZE);
398  }
399 }
400 
401 #endif
402 #endif
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
i.MX RT1040 hash hardware accelerator
#define MIMXRT1040_DCP_RAM_SECTION
SHA-256 algorithm context.
Definition: sha256.h:62
OsMutex mimxrt1040CryptoMutex
uint8_t data[]
Definition: ethernet.h:222
#define MIMXRT1040_DCP_BUFFER_SIZE
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
General definitions for cryptographic algorithms.
void sha256Init(Sha256Context *context)
Initialize SHA-256 message digest context.
uint8_t length
Definition: tcp.h:368
#define MIN(a, b)
Definition: os_port.h:63
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
Collection of hash algorithms.
uint8_t digest[32]
Definition: sha256.h:66
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
uint8_t n
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
error_t sha256Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-256.
SHA-1 algorithm context.
Definition: sha1.h:62
void sha256Update(Sha256Context *context, const void *data, size_t length)
Update the SHA-256 context with a portion of the message being hashed.
void sha256Final(Sha256Context *context, uint8_t *digest)
Finish the SHA-256 message digest.
i.MX RT1040 hardware cryptographic accelerator (DCP)
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
uint8_t digest[20]
Definition: sha1.h:66
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.