mimxrt1180_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file mimxrt1180_crypto_cipher.c
3  * @brief i.MX RT1180 cipher 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.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 "ele_crypto.h"
37 #include "core/crypto.h"
42 #include "aead/aead_algorithms.h"
43 #include "debug.h"
44 
45 //Check crypto library configuration
46 #if (MIMXRT1180_CRYPTO_CIPHER_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
47 
48 //ELE input buffer
49 SDK_ALIGN(static uint8_t eleBufferIn[MIMXRT1180_ELE_BUFFER_SIZE], 16);
50 //ELE output buffer
51 SDK_ALIGN(static uint8_t eleBufferOut[MIMXRT1180_ELE_BUFFER_SIZE], 16);
52 //ELE initialization vector
53 SDK_ALIGN(static uint8_t eleInitVector[16], 16);
54 
55 #if (ECB_SUPPORT == ENABLED)
56 
57 /**
58  * @brief ECB encryption
59  * @param[in] cipher Cipher algorithm
60  * @param[in] context Cipher algorithm context
61  * @param[in] p Plaintext to be encrypted
62  * @param[out] c Ciphertext resulting from the encryption
63  * @param[in] length Total number of data bytes to be encrypted
64  * @return Error code
65  **/
66 
67 error_t ecbEncrypt(const CipherAlgo *cipher, void *context,
68  const uint8_t *p, uint8_t *c, size_t length)
69 {
70  status_t status;
71  ele_generic_cipher_t genericCipher;
72 
73  //Initialize status code
74  status = kStatus_Success;
75 
76  //AES cipher algorithm?
77  if(cipher == AES_CIPHER_ALGO)
78  {
79  //Check the length of the payload
80  if(length == 0)
81  {
82  //No data to process
83  }
84  else if((length % AES_BLOCK_SIZE) == 0)
85  {
86  size_t i;
87  size_t n;
88  size_t keySize;
89  AesContext *aesContext;
90 
91  //Point to the AES context
92  aesContext = (AesContext *) context;
93 
94  //Get the length of the key
95  if(aesContext->nr == 10)
96  {
97  //10 rounds are required for 128-bit key
98  keySize = 16;
99  }
100  else if(aesContext->nr == 12)
101  {
102  //12 rounds are required for 192-bit key
103  keySize = 24;
104  }
105  else if(aesContext->nr == 14)
106  {
107  //14 rounds are required for 256-bit key
108  keySize = 32;
109  }
110  else
111  {
112  //Invalid key length
113  status = kStatus_Fail;
114  }
115 
116  //Check status code
117  if(status == kStatus_Success)
118  {
119  //Acquire exclusive access to the ELE module
121 
122  //Perform AES-ECB encryption
123  for(i = 0; i < length && status == kStatus_Success; i += n)
124  {
125  //Limit the number of data to process at a time
127  //Copy the plaintext to the buffer
128  osMemcpy(eleBufferIn, p + i, n);
129 
130  //Set cipher parameters
131  genericCipher.data = (uint32_t) eleBufferIn;
132  genericCipher.output = (uint32_t) eleBufferOut;
133  genericCipher.size = n;
134  genericCipher.key = (uint32_t) aesContext->ek;
135  genericCipher.key_size = keySize;
136  genericCipher.iv = NULL;
137  genericCipher.iv_size = 0;
138  genericCipher.algo = kAES_ECB;
139  genericCipher.mode = kEncrypt;
140 
141  //Encrypt data
142  status = ELE_GenericCipher(MU_APPS_S3MUA, &genericCipher);
143 
144  //Check status code
145  if(status == kStatus_Success)
146  {
147  //Copy the resulting ciphertext
148  osMemcpy(c + i, eleBufferOut, n);
149  }
150  }
151 
152  //Release exclusive access to the ELE module
154  }
155  }
156  else
157  {
158  //The length of the payload must be a multiple of the block size
159  status = kStatus_InvalidArgument;
160  }
161  }
162  //Unknown cipher algorithm?
163  else
164  {
165  //ECB mode operates in a block-by-block fashion
166  while(length >= cipher->blockSize)
167  {
168  //Encrypt current block
169  cipher->encryptBlock(context, p, c);
170 
171  //Next block
172  p += cipher->blockSize;
173  c += cipher->blockSize;
174  length -= cipher->blockSize;
175  }
176 
177  //The length of the payload must be a multiple of the block size
178  if(length != 0)
179  {
180  status = kStatus_InvalidArgument;
181  }
182  }
183 
184  //Return status code
185  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
186 }
187 
188 
189 /**
190  * @brief ECB decryption
191  * @param[in] cipher Cipher algorithm
192  * @param[in] context Cipher algorithm context
193  * @param[in] c Ciphertext to be decrypted
194  * @param[out] p Plaintext resulting from the decryption
195  * @param[in] length Total number of data bytes to be decrypted
196  * @return Error code
197  **/
198 
199 error_t ecbDecrypt(const CipherAlgo *cipher, void *context,
200  const uint8_t *c, uint8_t *p, size_t length)
201 {
202  status_t status;
203  ele_generic_cipher_t genericCipher;
204 
205  //Initialize status code
206  status = kStatus_Success;
207 
208  //AES cipher algorithm?
209  if(cipher == AES_CIPHER_ALGO)
210  {
211  //Check the length of the payload
212  if(length == 0)
213  {
214  //No data to process
215  }
216  else if((length % AES_BLOCK_SIZE) == 0)
217  {
218  size_t i;
219  size_t n;
220  size_t keySize;
221  AesContext *aesContext;
222 
223  //Point to the AES context
224  aesContext = (AesContext *) context;
225 
226  //Get the length of the key
227  if(aesContext->nr == 10)
228  {
229  //10 rounds are required for 128-bit key
230  keySize = 16;
231  }
232  else if(aesContext->nr == 12)
233  {
234  //12 rounds are required for 192-bit key
235  keySize = 24;
236  }
237  else if(aesContext->nr == 14)
238  {
239  //14 rounds are required for 256-bit key
240  keySize = 32;
241  }
242  else
243  {
244  //Invalid key length
245  status = kStatus_Fail;
246  }
247 
248  //Check status code
249  if(status == kStatus_Success)
250  {
251  //Acquire exclusive access to the ELE module
253 
254  //Perform AES-ECB decryption
255  for(i = 0; i < length && status == kStatus_Success; i += n)
256  {
257  //Limit the number of data to process at a time
259  //Copy the ciphertext to the buffer
260  osMemcpy(eleBufferIn, c + i, n);
261 
262  //Set cipher parameters
263  genericCipher.data = (uint32_t) eleBufferIn;
264  genericCipher.output = (uint32_t) eleBufferOut;
265  genericCipher.size = n;
266  genericCipher.key = (uint32_t) aesContext->ek;
267  genericCipher.key_size = keySize;
268  genericCipher.iv = NULL;
269  genericCipher.iv_size = 0;
270  genericCipher.algo = kAES_ECB;
271  genericCipher.mode = kDecrypt;
272 
273  //Decrypt data
274  status = ELE_GenericCipher(MU_APPS_S3MUA, &genericCipher);
275 
276  //Check status code
277  if(status == kStatus_Success)
278  {
279  //Copy the resulting plaintext
280  osMemcpy(p + i, eleBufferOut, n);
281  }
282  }
283  }
284 
285  //Release exclusive access to the ELE module
287  }
288  else
289  {
290  //The length of the payload must be a multiple of the block size
291  status = kStatus_InvalidArgument;
292  }
293  }
294  //Unknown cipher algorithm?
295  else
296  {
297  //ECB mode operates in a block-by-block fashion
298  while(length >= cipher->blockSize)
299  {
300  //Decrypt current block
301  cipher->decryptBlock(context, c, p);
302 
303  //Next block
304  c += cipher->blockSize;
305  p += cipher->blockSize;
306  length -= cipher->blockSize;
307  }
308 
309  //The length of the payload must be a multiple of the block size
310  if(length != 0)
311  {
312  status = kStatus_InvalidArgument;
313  }
314  }
315 
316  //Return status code
317  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
318 }
319 
320 #endif
321 #if (CBC_SUPPORT == ENABLED)
322 
323 /**
324  * @brief CBC encryption
325  * @param[in] cipher Cipher algorithm
326  * @param[in] context Cipher algorithm context
327  * @param[in,out] iv Initialization vector
328  * @param[in] p Plaintext to be encrypted
329  * @param[out] c Ciphertext resulting from the encryption
330  * @param[in] length Total number of data bytes to be encrypted
331  * @return Error code
332  **/
333 
334 error_t cbcEncrypt(const CipherAlgo *cipher, void *context,
335  uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
336 {
337  status_t status;
338  ele_generic_cipher_t genericCipher;
339 
340  //Initialize status code
341  status = kStatus_Success;
342 
343  //AES cipher algorithm?
344  if(cipher == AES_CIPHER_ALGO)
345  {
346  //Check the length of the payload
347  if(length == 0)
348  {
349  //No data to process
350  }
351  else if((length % AES_BLOCK_SIZE) == 0)
352  {
353  size_t i;
354  size_t n;
355  size_t keySize;
356  AesContext *aesContext;
357 
358  //Point to the AES context
359  aesContext = (AesContext *) context;
360 
361  //Get the length of the key
362  if(aesContext->nr == 10)
363  {
364  //10 rounds are required for 128-bit key
365  keySize = 16;
366  }
367  else if(aesContext->nr == 12)
368  {
369  //12 rounds are required for 192-bit key
370  keySize = 24;
371  }
372  else if(aesContext->nr == 14)
373  {
374  //14 rounds are required for 256-bit key
375  keySize = 32;
376  }
377  else
378  {
379  //Invalid key length
380  status = kStatus_Fail;
381  }
382 
383  //Check status code
384  if(status == kStatus_Success)
385  {
386  //Acquire exclusive access to the ELE module
388 
389  //Perform AES-CBC encryption
390  for(i = 0; i < length && status == kStatus_Success; i += n)
391  {
392  //Limit the number of data to process at a time
394  //Copy the plaintext to the buffer
395  osMemcpy(eleBufferIn, p + i, n);
396 
397  //Set cipher parameters
398  genericCipher.data = (uint32_t) eleBufferIn;
399  genericCipher.output = (uint32_t) eleBufferOut;
400  genericCipher.size = n;
401  genericCipher.key = (uint32_t) aesContext->ek;
402  genericCipher.key_size = keySize;
403  genericCipher.iv = (uint32_t) iv;
404  genericCipher.iv_size = AES_BLOCK_SIZE;
405  genericCipher.algo = kAES_CBC;
406  genericCipher.mode = kEncrypt;
407 
408  //Encrypt data
409  status = ELE_GenericCipher(MU_APPS_S3MUA, &genericCipher);
410 
411  //Check status code
412  if(status == kStatus_Success)
413  {
414  //Copy the resulting ciphertext
415  osMemcpy(c + i, eleBufferOut, n);
416  //Update the value of the initialization vector
417  osMemcpy(iv, eleBufferOut + n - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
418  }
419  }
420  }
421 
422  //Release exclusive access to the ELE module
424  }
425  else
426  {
427  //The length of the payload must be a multiple of the block size
428  status = kStatus_InvalidArgument;
429  }
430  }
431  //Unknown cipher algorithm?
432  else
433  {
434  size_t i;
435 
436  //CBC mode operates in a block-by-block fashion
437  while(length >= cipher->blockSize)
438  {
439  //XOR input block with IV contents
440  for(i = 0; i < cipher->blockSize; i++)
441  {
442  c[i] = p[i] ^ iv[i];
443  }
444 
445  //Encrypt the current block based upon the output of the previous
446  //encryption
447  cipher->encryptBlock(context, c, c);
448 
449  //Update IV with output block contents
450  osMemcpy(iv, c, cipher->blockSize);
451 
452  //Next block
453  p += cipher->blockSize;
454  c += cipher->blockSize;
455  length -= cipher->blockSize;
456  }
457 
458  //The length of the payload must be a multiple of the block size
459  if(length != 0)
460  {
461  status = kStatus_InvalidArgument;
462  }
463  }
464 
465  //Return status code
466  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
467 }
468 
469 
470 /**
471  * @brief CBC decryption
472  * @param[in] cipher Cipher algorithm
473  * @param[in] context Cipher algorithm context
474  * @param[in,out] iv Initialization vector
475  * @param[in] c Ciphertext to be decrypted
476  * @param[out] p Plaintext resulting from the decryption
477  * @param[in] length Total number of data bytes to be decrypted
478  * @return Error code
479  **/
480 
481 error_t cbcDecrypt(const CipherAlgo *cipher, void *context,
482  uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
483 {
484  status_t status;
485  ele_generic_cipher_t genericCipher;
486 
487  //Initialize status code
488  status = kStatus_Success;
489 
490  //AES cipher algorithm?
491  if(cipher == AES_CIPHER_ALGO)
492  {
493  //Check the length of the payload
494  if(length == 0)
495  {
496  //No data to process
497  }
498  else if((length % AES_BLOCK_SIZE) == 0)
499  {
500  size_t i;
501  size_t n;
502  size_t keySize;
503  AesContext *aesContext;
504  uint8_t block[AES_BLOCK_SIZE];
505 
506  //Point to the AES context
507  aesContext = (AesContext *) context;
508 
509  //Get the length of the key
510  if(aesContext->nr == 10)
511  {
512  //10 rounds are required for 128-bit key
513  keySize = 16;
514  }
515  else if(aesContext->nr == 12)
516  {
517  //12 rounds are required for 192-bit key
518  keySize = 24;
519  }
520  else if(aesContext->nr == 14)
521  {
522  //14 rounds are required for 256-bit key
523  keySize = 32;
524  }
525  else
526  {
527  //Invalid key length
528  status = kStatus_Fail;
529  }
530 
531  //Check status code
532  if(status == kStatus_Success)
533  {
534  //Acquire exclusive access to the ELE module
536 
537  //Perform AES-CBC decryption
538  for(i = 0; i < length && status == kStatus_Success; i += n)
539  {
540  //Limit the number of data to process at a time
542  //Copy the ciphertext to the buffer
543  osMemcpy(eleBufferIn, c + i, n);
544  //Save the last input block
545  osMemcpy(block, eleBufferIn + n - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
546 
547  //Set cipher parameters
548  genericCipher.data = (uint32_t) eleBufferIn;
549  genericCipher.output = (uint32_t) eleBufferOut;
550  genericCipher.size = n;
551  genericCipher.key = (uint32_t) aesContext->ek;
552  genericCipher.key_size = keySize;
553  genericCipher.iv = (uint32_t) iv;
554  genericCipher.iv_size = AES_BLOCK_SIZE;
555  genericCipher.algo = kAES_CBC;
556  genericCipher.mode = kDecrypt;
557 
558  //Decrypt data
559  status = ELE_GenericCipher(MU_APPS_S3MUA, &genericCipher);
560 
561  //Check status code
562  if(status == kStatus_Success)
563  {
564  //Copy the resulting plaintext
565  osMemcpy(p + i, eleBufferOut, n);
566  //Update the value of the initialization vector
568  }
569  }
570  }
571 
572  //Release exclusive access to the ELE module
574  }
575  else
576  {
577  //The length of the payload must be a multiple of the block size
578  status = kStatus_InvalidArgument;
579  }
580  }
581  //Unknown cipher algorithm?
582  else
583  {
584  size_t i;
585  uint8_t t[16];
586 
587  //CBC mode operates in a block-by-block fashion
588  while(length >= cipher->blockSize)
589  {
590  //Save input block
591  osMemcpy(t, c, cipher->blockSize);
592 
593  //Decrypt the current block
594  cipher->decryptBlock(context, c, p);
595 
596  //XOR output block with IV contents
597  for(i = 0; i < cipher->blockSize; i++)
598  {
599  p[i] ^= iv[i];
600  }
601 
602  //Update IV with input block contents
603  osMemcpy(iv, t, cipher->blockSize);
604 
605  //Next block
606  c += cipher->blockSize;
607  p += cipher->blockSize;
608  length -= cipher->blockSize;
609  }
610 
611  //The length of the payload must be a multiple of the block size
612  if(length != 0)
613  {
614  status = kStatus_InvalidArgument;
615  }
616  }
617 
618  //Return status code
619  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
620 }
621 
622 #endif
623 #if (CTR_SUPPORT == ENABLED)
624 
625 /**
626  * @brief CTR encryption
627  * @param[in] cipher Cipher algorithm
628  * @param[in] context Cipher algorithm context
629  * @param[in] m Size in bits of the specific part of the block to be incremented
630  * @param[in,out] t Initial counter block
631  * @param[in] p Plaintext to be encrypted
632  * @param[out] c Ciphertext resulting from the encryption
633  * @param[in] length Total number of data bytes to be encrypted
634  * @return Error code
635  **/
636 
637 error_t ctrEncrypt(const CipherAlgo *cipher, void *context, uint_t m,
638  uint8_t *t, const uint8_t *p, uint8_t *c, size_t length)
639 {
640  status_t status;
641  ele_generic_cipher_t genericCipher;
642 
643  //Initialize status code
644  status = kStatus_Success;
645 
646  //Check the value of the parameter
647  if((m % 8) == 0 && m <= (cipher->blockSize * 8))
648  {
649  //Determine the size, in bytes, of the specific part of the block to be
650  //incremented
651  m = m / 8;
652 
653  //AES cipher algorithm?
654  if(cipher == AES_CIPHER_ALGO)
655  {
656  size_t i;
657  size_t k;
658  size_t n;
659  size_t keySize;
660  AesContext *aesContext;
661 
662  //Point to the AES context
663  aesContext = (AesContext *) context;
664 
665  //Get the length of the key
666  if(aesContext->nr == 10)
667  {
668  //10 rounds are required for 128-bit key
669  keySize = 16;
670  }
671  else if(aesContext->nr == 12)
672  {
673  //12 rounds are required for 192-bit key
674  keySize = 24;
675  }
676  else if(aesContext->nr == 14)
677  {
678  //14 rounds are required for 256-bit key
679  keySize = 32;
680  }
681  else
682  {
683  //Invalid key length
684  status = kStatus_Fail;
685  }
686 
687  //Check status code
688  if(status == kStatus_Success)
689  {
690  //Acquire exclusive access to the ELE module
692 
693  //Perform AES-CTR encryption
694  for(i = 0; i < length && status == kStatus_Success; i += n)
695  {
696  //Limit the number of data to process at a time
697  k = 256 - t[AES_BLOCK_SIZE - 1];
698  n = k * AES_BLOCK_SIZE;
699  n = MIN(n, length - i);
701  k = (n + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
702 
703  //Copy the plaintext to the buffer
704  osMemcpy(eleBufferIn, p + i, n);
705  //Copy the counter block
706  osMemcpy(eleInitVector, t, AES_BLOCK_SIZE);
707 
708  //Set cipher parameters
709  genericCipher.data = (uint32_t) eleBufferIn;
710  genericCipher.output = (uint32_t) eleBufferOut;
711  genericCipher.size = k * AES_BLOCK_SIZE;
712  genericCipher.key = (uint32_t) aesContext->ek;
713  genericCipher.key_size = keySize;
714  genericCipher.iv = (uint32_t) eleInitVector;
715  genericCipher.iv_size = AES_BLOCK_SIZE;
716  genericCipher.algo = kAES_CTR;
717  genericCipher.mode = kEncrypt;
718 
719  //Encrypt data
720  status = ELE_GenericCipher(MU_APPS_S3MUA, &genericCipher);
721 
722  //Check status code
723  if(status == kStatus_Success)
724  {
725  //Copy the resulting ciphertext
726  osMemcpy(c + i, eleBufferOut, n);
727  //Update the value of the counter block
729  }
730  }
731  }
732 
733  //Release exclusive access to the ELE module
735  }
736  //Unknown cipher algorithm?
737  else
738  {
739  size_t i;
740  size_t n;
741  uint8_t o[16];
742 
743  //Process plaintext
744  while(length > 0)
745  {
746  //CTR mode operates in a block-by-block fashion
747  n = MIN(length, cipher->blockSize);
748 
749  //Compute O(j) = CIPH(T(j))
750  cipher->encryptBlock(context, t, o);
751 
752  //Compute C(j) = P(j) XOR T(j)
753  for(i = 0; i < n; i++)
754  {
755  c[i] = p[i] ^ o[i];
756  }
757 
758  //Standard incrementing function
759  ctrIncBlock(t, 1, cipher->blockSize, m);
760 
761  //Next block
762  p += n;
763  c += n;
764  length -= n;
765  }
766  }
767  }
768  else
769  {
770  //The value of the parameter is not valid
771  status = kStatus_InvalidArgument;
772  }
773 
774  //Return status code
775  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
776 }
777 
778 #endif
779 #if (GCM_SUPPORT == ENABLED)
780 
781 /**
782  * @brief Initialize GCM context
783  * @param[in] context Pointer to the GCM context
784  * @param[in] cipherAlgo Cipher algorithm
785  * @param[in] cipherContext Pointer to the cipher algorithm context
786  * @return Error code
787  **/
788 
789 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
790  void *cipherContext)
791 {
792  //Check parameters
793  if(context == NULL || cipherContext == NULL)
795 
796  //The CRYP module only supports AES cipher algorithm
797  if(cipherAlgo != AES_CIPHER_ALGO)
799 
800  //Save cipher algorithm context
801  context->cipherAlgo = cipherAlgo;
802  context->cipherContext = cipherContext;
803 
804  //Successful initialization
805  return NO_ERROR;
806 }
807 
808 
809 /**
810  * @brief Authenticated encryption using GCM
811  * @param[in] context Pointer to the GCM context
812  * @param[in] iv Initialization vector
813  * @param[in] ivLen Length of the initialization vector
814  * @param[in] a Additional authenticated data
815  * @param[in] aLen Length of the additional data
816  * @param[in] p Plaintext to be encrypted
817  * @param[out] c Ciphertext resulting from the encryption
818  * @param[in] length Total number of data bytes to be encrypted
819  * @param[out] t Authentication tag
820  * @param[in] tLen Length of the authentication tag
821  * @return Error code
822  **/
823 
824 error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
825  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
826  uint8_t *c, size_t length, uint8_t *t, size_t tLen)
827 {
828  status_t status;
829  size_t keySize;
830  AesContext *aesContext;
831  ele_generic_aead_t genericAead;
832 
833  //Make sure the GCM context is valid
834  if(context == NULL)
836 
837  //Check the length of the authentication tag
838  if(tLen < 4 || tLen > 16)
839  return ERROR_INVALID_LENGTH;
840 
841  //Initialize status code
842  status = kStatus_Success;
843 
844  //Point to the AES context
845  aesContext = (AesContext *) context->cipherContext;
846 
847  //Get the length of the key
848  if(aesContext->nr == 10)
849  {
850  //10 rounds are required for 128-bit key
851  keySize = 16;
852  }
853  else if(aesContext->nr == 12)
854  {
855  //12 rounds are required for 192-bit key
856  keySize = 24;
857  }
858  else if(aesContext->nr == 14)
859  {
860  //14 rounds are required for 256-bit key
861  keySize = 32;
862  }
863  else
864  {
865  //Invalid key length
866  status = kStatus_Fail;
867  }
868 
869  //Check status code
870  if(status == kStatus_Success)
871  {
872  //Acquire exclusive access to the ELE module
874 
875  //Set cipher parameters
876  genericAead.data = (uint32_t) p;
877  genericAead.output = (uint32_t) c;
878  genericAead.size = length;
879  genericAead.key = (uint32_t) aesContext->ek;
880  genericAead.key_size = keySize;
881  genericAead.iv = (uint32_t) iv;
882  genericAead.iv_size = ivLen;
883  genericAead.aad = (uint32_t) a;
884  genericAead.aad_size = aLen;
885  genericAead.tag = (uint32_t) t;
886  genericAead.tag_size = tLen;
887  genericAead.algo = kAES_GCM;
888  genericAead.mode = kEncrypt;
889 
890  //Perform AES-GCM encryption
891  status = ELE_GenericAead(MU_APPS_S3MUA, &genericAead);
892 
893  //Release exclusive access to the ELE module
895  }
896 
897  //Return status code
898  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
899 }
900 
901 
902 /**
903  * @brief Authenticated decryption using GCM
904  * @param[in] context Pointer to the GCM context
905  * @param[in] iv Initialization vector
906  * @param[in] ivLen Length of the initialization vector
907  * @param[in] a Additional authenticated data
908  * @param[in] aLen Length of the additional data
909  * @param[in] c Ciphertext to be decrypted
910  * @param[out] p Plaintext resulting from the decryption
911  * @param[in] length Total number of data bytes to be decrypted
912  * @param[in] t Authentication tag
913  * @param[in] tLen Length of the authentication tag
914  * @return Error code
915  **/
916 
917 error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
918  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
919  uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
920 {
921  status_t status;
922  size_t keySize;
923  AesContext *aesContext;
924  ele_generic_aead_t genericAead;
925 
926  //Make sure the GCM context is valid
927  if(context == NULL)
929 
930  //Check the length of the authentication tag
931  if(tLen < 4 || tLen > 16)
932  return ERROR_INVALID_LENGTH;
933 
934  //Initialize status code
935  status = kStatus_Success;
936 
937  //Point to the AES context
938  aesContext = (AesContext *) context->cipherContext;
939 
940  //Get the length of the key
941  if(aesContext->nr == 10)
942  {
943  //10 rounds are required for 128-bit key
944  keySize = 16;
945  }
946  else if(aesContext->nr == 12)
947  {
948  //12 rounds are required for 192-bit key
949  keySize = 24;
950  }
951  else if(aesContext->nr == 14)
952  {
953  //14 rounds are required for 256-bit key
954  keySize = 32;
955  }
956  else
957  {
958  //Invalid key length
959  status = kStatus_Fail;
960  }
961 
962  //Check status code
963  if(status == kStatus_Success)
964  {
965  //Acquire exclusive access to the ELE module
967 
968  //Set cipher parameters
969  genericAead.data = (uint32_t) c;
970  genericAead.output = (uint32_t) p;
971  genericAead.size = length;
972  genericAead.key = (uint32_t) aesContext->ek;
973  genericAead.key_size = keySize;
974  genericAead.iv = (uint32_t) iv;
975  genericAead.iv_size = ivLen;
976  genericAead.aad = (uint32_t) a;
977  genericAead.aad_size = aLen;
978  genericAead.tag = (uint32_t) t;
979  genericAead.tag_size = tLen;
980  genericAead.algo = kAES_GCM;
981  genericAead.mode = kDecrypt;
982 
983  //Perform AES-GCM decryption
984  status = ELE_GenericAead(MU_APPS_S3MUA, &genericAead);
985 
986  //Release exclusive access to the ELE module
988  }
989 
990  //Return status code
991  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
992 }
993 
994 #endif
995 #if (CCM_SUPPORT == ENABLED)
996 
997 /**
998  * @brief Authenticated encryption using CCM
999  * @param[in] cipher Cipher algorithm
1000  * @param[in] context Cipher algorithm context
1001  * @param[in] n Nonce
1002  * @param[in] nLen Length of the nonce
1003  * @param[in] a Additional authenticated data
1004  * @param[in] aLen Length of the additional data
1005  * @param[in] p Plaintext to be encrypted
1006  * @param[out] c Ciphertext resulting from the encryption
1007  * @param[in] length Total number of data bytes to be encrypted
1008  * @param[out] t MAC resulting from the encryption process
1009  * @param[in] tLen Length of the MAC
1010  * @return Error code
1011  **/
1012 
1013 error_t ccmEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1014  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c,
1015  size_t length, uint8_t *t, size_t tLen)
1016 {
1017  status_t status;
1018  size_t keySize;
1019  AesContext *aesContext;
1020  ele_generic_aead_t genericAead;
1021 
1022  //Make sure the GCM context is valid
1023  if(context == NULL)
1024  return ERROR_INVALID_PARAMETER;
1025 
1026  //Check the length of the authentication tag
1027  if(tLen < 4 || tLen > 16)
1028  return ERROR_INVALID_LENGTH;
1029 
1030  //Initialize status code
1031  status = kStatus_Success;
1032 
1033  //Point to the AES context
1034  aesContext = (AesContext *) context;
1035 
1036  //Get the length of the key
1037  if(aesContext->nr == 10)
1038  {
1039  //10 rounds are required for 128-bit key
1040  keySize = 16;
1041  }
1042  else if(aesContext->nr == 12)
1043  {
1044  //12 rounds are required for 192-bit key
1045  keySize = 24;
1046  }
1047  else if(aesContext->nr == 14)
1048  {
1049  //14 rounds are required for 256-bit key
1050  keySize = 32;
1051  }
1052  else
1053  {
1054  //Invalid key length
1055  status = kStatus_Fail;
1056  }
1057 
1058  //Check status code
1059  if(status == kStatus_Success)
1060  {
1061  //Acquire exclusive access to the ELE module
1063 
1064  //Set cipher parameters
1065  genericAead.data = (uint32_t) p;
1066  genericAead.output = (uint32_t) c;
1067  genericAead.size = length;
1068  genericAead.key = (uint32_t) aesContext->ek;
1069  genericAead.key_size = keySize;
1070  genericAead.iv = (uint32_t) n;
1071  genericAead.iv_size = nLen;
1072  genericAead.aad = (uint32_t) a;
1073  genericAead.aad_size = aLen;
1074  genericAead.tag = (uint32_t) t;
1075  genericAead.tag_size = tLen;
1076  genericAead.algo = kAES_CCM;
1077  genericAead.mode = kEncrypt;
1078 
1079  //Perform AES-CCM encryption
1080  status = ELE_GenericAead(MU_APPS_S3MUA, &genericAead);
1081 
1082  //Release exclusive access to the ELE module
1084  }
1085 
1086  //Return status code
1087  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
1088 }
1089 
1090 
1091 /**
1092  * @brief Authenticated decryption using CCM
1093  * @param[in] cipher Cipher algorithm
1094  * @param[in] context Cipher algorithm context
1095  * @param[in] n Nonce
1096  * @param[in] nLen Length of the nonce
1097  * @param[in] a Additional authenticated data
1098  * @param[in] aLen Length of the additional data
1099  * @param[in] c Ciphertext to be decrypted
1100  * @param[out] p Plaintext resulting from the decryption
1101  * @param[in] length Total number of data bytes to be decrypted
1102  * @param[in] t MAC to be verified
1103  * @param[in] tLen Length of the MAC
1104  * @return Error code
1105  **/
1106 
1107 error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1108  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p,
1109  size_t length, const uint8_t *t, size_t tLen)
1110 {
1111  status_t status;
1112  size_t keySize;
1113  AesContext *aesContext;
1114  ele_generic_aead_t genericAead;
1115 
1116  //Make sure the GCM context is valid
1117  if(context == NULL)
1118  return ERROR_INVALID_PARAMETER;
1119 
1120  //Check the length of the authentication tag
1121  if(tLen < 4 || tLen > 16)
1122  return ERROR_INVALID_LENGTH;
1123 
1124  //Initialize status code
1125  status = kStatus_Success;
1126 
1127  //Point to the AES context
1128  aesContext = (AesContext *) context;
1129 
1130  //Get the length of the key
1131  if(aesContext->nr == 10)
1132  {
1133  //10 rounds are required for 128-bit key
1134  keySize = 16;
1135  }
1136  else if(aesContext->nr == 12)
1137  {
1138  //12 rounds are required for 192-bit key
1139  keySize = 24;
1140  }
1141  else if(aesContext->nr == 14)
1142  {
1143  //14 rounds are required for 256-bit key
1144  keySize = 32;
1145  }
1146  else
1147  {
1148  //Invalid key length
1149  status = kStatus_Fail;
1150  }
1151 
1152  //Check status code
1153  if(status == kStatus_Success)
1154  {
1155  //Acquire exclusive access to the ELE module
1157 
1158  //Set cipher parameters
1159  genericAead.data = (uint32_t) c;
1160  genericAead.output = (uint32_t) p;
1161  genericAead.size = length;
1162  genericAead.key = (uint32_t) aesContext->ek;
1163  genericAead.key_size = keySize;
1164  genericAead.iv = (uint32_t) n;
1165  genericAead.iv_size = nLen;
1166  genericAead.aad = (uint32_t) a;
1167  genericAead.aad_size = aLen;
1168  genericAead.tag = (uint32_t) t;
1169  genericAead.tag_size = tLen;
1170  genericAead.algo = kAES_CCM;
1171  genericAead.mode = kDecrypt;
1172 
1173  //Perform AES-CCM decryption
1174  status = ELE_GenericAead(MU_APPS_S3MUA, &genericAead);
1175 
1176  //Release exclusive access to the ELE module
1178  }
1179 
1180  //Return status code
1181  return (status == kStatus_Success) ? NO_ERROR : ERROR_FAILURE;
1182 }
1183 
1184 #endif
1185 #endif
uint16_t block
Definition: tftp_common.h:115
uint8_t a
Definition: ndp.h:411
error_t ctrEncrypt(const CipherAlgo *cipher, void *context, uint_t m, uint8_t *t, const uint8_t *p, uint8_t *c, size_t length)
CTR encryption.
CipherAlgoDecryptBlock decryptBlock
Definition: crypto.h:1173
uint8_t p
Definition: ndp.h:300
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t o
Collection of AEAD algorithms.
#define MIMXRT1180_ELE_BUFFER_SIZE
size_t blockSize
Definition: crypto.h:1168
error_t cbcDecrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
CBC decryption.
error_t ecbDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *c, uint8_t *p, size_t length)
ECB decryption.
CipherAlgoEncryptBlock encryptBlock
Definition: crypto.h:1172
AES algorithm context.
Definition: aes.h:58
#define AES_BLOCK_SIZE
Definition: aes.h:43
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t
Error codes.
Definition: error.h:43
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
error_t ccmEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Authenticated encryption using CCM.
error_t ecbEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *p, uint8_t *c, size_t length)
ECB encryption.
SDK_ALIGN(static uint8_t eleBufferIn[MIMXRT1180_ELE_BUFFER_SIZE], 16)
uint8_t iv[]
Definition: ike.h:1659
Block cipher modes of operation.
error_t gcmEncrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Authenticated encryption using GCM.
OsMutex mimxrt1180CryptoMutex
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: gcm.h:65
uint8_t length
Definition: tcp.h:375
#define MIN(a, b)
Definition: os_port.h:63
error_t cbcEncrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
CBC encryption.
uint_t nr
Definition: aes.h:59
i.MX RT1180 cipher hardware accelerator
GCM context.
Definition: gcm.h:64
uint8_t m
Definition: ndp.h:304
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.
i.MX RT1180 hardware cryptographic accelerator (ELE)
error_t gcmDecrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using GCM.
Common interface for encryption algorithms.
Definition: crypto.h:1164
#define AES_CIPHER_ALGO
Definition: aes.h:45
error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using CCM.
uint32_t ek[60]
Definition: aes.h:60
unsigned int uint_t
Definition: compiler_port.h:57
void * cipherContext
Cipher algorithm context.
Definition: gcm.h:66
void ctrIncBlock(uint8_t *ctr, uint32_t inc, size_t blockSize, size_t m)
Increment counter block.
Definition: ctr.c:138
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
Debugging facilities.