ra6_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file ra6_crypto_cipher.c
3  * @brief RA6 cipher 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_private.h"
36 #include "hw_sce_ra_private.h"
37 #include "hw_sce_aes_private.h"
38 #include "core/crypto.h"
43 #include "aead/aead_algorithms.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (RA6_CRYPTO_CIPHER_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Perform AES encryption or decryption
52  * @param[in] context AES algorithm context
53  * @param[in,out] iv Initialization vector
54  * @param[in] input Data to be encrypted/decrypted
55  * @param[out] output Data resulting from the encryption/decryption process
56  * @param[in] length Total number of data bytes to be processed
57  * @param[in] command Operation mode
58  * @return Status code
59  **/
60 
61 error_t aesProcessData(AesContext *context, uint8_t *iv, const uint8_t *input,
62  uint8_t *output, size_t length, uint32_t command)
63 {
64  fsp_err_t status;
65  size_t n;
66  uint32_t keyType;
67  uint32_t block[AES_BLOCK_SIZE / 4];
68 
69  //Set key type
70  keyType = 0;
71  //Set operation mode
72  command = htobe32(command);
73 
74  //Acquire exclusive access to the SCE module
76 
77  //Initialize encryption or decryption operation
78  if(context->nr == 10)
79  {
80  status = HW_SCE_Aes128EncryptDecryptInitSub(&keyType, &command,
81  context->ek, (const uint32_t *) iv);
82  }
83  else if(context->nr == 12)
84  {
85  status = HW_SCE_Aes192EncryptDecryptInitSub(&command,
86  context->ek, (const uint32_t *) iv);
87  }
88  else if(context->nr == 14)
89  {
90  status = HW_SCE_Aes256EncryptDecryptInitSub(&keyType, &command,
91  context->ek, (const uint32_t *) iv);
92  }
93  else
94  {
95  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
96  }
97 
98  //Check status code
99  if(status == FSP_SUCCESS)
100  {
101  //Get the number of bytes in the last block
102  n = length % AES_BLOCK_SIZE;
103 
104  //Process complete blocks only
105  if(context->nr == 10)
106  {
107  HW_SCE_Aes128EncryptDecryptUpdateSub((const uint32_t *) input,
108  (uint32_t *) output, (length - n) / 4);
109  }
110  else if(context->nr == 12)
111  {
112  HW_SCE_Aes192EncryptDecryptUpdateSub((const uint32_t *) input,
113  (uint32_t *) output, (length - n) / 4);
114  }
115  else
116  {
117  HW_SCE_Aes256EncryptDecryptUpdateSub((const uint32_t *) input,
118  (uint32_t *) output, (length - n) / 4);
119  }
120 
121  //The final block requires special processing
122  if(n > 0)
123  {
124  //Copy the input data
126  osMemcpy(block, input + length - n, n);
127 
128  //Process the final block
129  if(context->nr == 10)
130  {
131  HW_SCE_Aes128EncryptDecryptUpdateSub(block, block,
132  AES_BLOCK_SIZE / 4);
133  }
134  else if(context->nr == 12)
135  {
136  HW_SCE_Aes192EncryptDecryptUpdateSub(block, block,
137  AES_BLOCK_SIZE / 4);
138  }
139  else
140  {
141  HW_SCE_Aes256EncryptDecryptUpdateSub(block, block,
142  AES_BLOCK_SIZE / 4);
143  }
144 
145  //Copy the resulting ciphertext
146  osMemcpy(output + length - n, block, n);
147  }
148  }
149 
150  //Check status code
151  if(status == FSP_SUCCESS)
152  {
153  //Finalize encryption or decryption operation
154  if(context->nr == 10)
155  {
156  status = HW_SCE_Aes128EncryptDecryptFinalSub();
157  }
158  else if(context->nr == 12)
159  {
160  status = HW_SCE_Aes192EncryptDecryptFinalSub();
161  }
162  else if(context->nr == 14)
163  {
164  status = HW_SCE_Aes256EncryptDecryptFinalSub();
165  }
166  else
167  {
168  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
169  }
170  }
171 
172  //Check status code
173  if(status != FSP_SUCCESS)
174  {
175  osMemset(output, 0, length);
176  }
177 
178  //Release exclusive access to the SCE module
180 
181  //Return status code
182  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
183 }
184 
185 
186 /**
187  * @brief Key expansion
188  * @param[in] context Pointer to the AES context to initialize
189  * @param[in] key Pointer to the key
190  * @param[in] keyLen Length of the key
191  * @return Error code
192  **/
193 
194 error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
195 {
196  fsp_err_t status;
197 
198  //Check parameters
199  if(context == NULL || key == NULL)
201 
202  //Acquire exclusive access to the SCE module
204 
205  //Check the length of the key
206  if(keyLen == 16)
207  {
208  //10 rounds are required for 128-bit key
209  context->nr = 10;
210 
211  //Install the plaintext key and get the wrapped key
212  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
213  SCE_OEM_CMD_AES128, NULL, NULL, key, context->ek);
214  }
215  else if(keyLen == 24)
216  {
217  //12 rounds are required for 192-bit key
218  context->nr = 12;
219 
220  //Install the plaintext key and get the wrapped key
221  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
222  SCE_OEM_CMD_AES192, NULL, NULL, key, context->ek);
223  }
224  else if(keyLen == 32)
225  {
226  //14 rounds are required for 256-bit key
227  context->nr = 14;
228 
229  //Install the plaintext key and get the wrapped key
230  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
231  SCE_OEM_CMD_AES256, NULL, NULL, key, context->ek);
232  }
233  else
234  {
235  //Invalid key length
236  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
237  }
238 
239  //Release exclusive access to the SCE module
241 
242  //Return status code
243  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
244 }
245 
246 
247 /**
248  * @brief Encrypt a 16-byte block using AES algorithm
249  * @param[in] context Pointer to the AES context
250  * @param[in] input Plaintext block to encrypt
251  * @param[out] output Ciphertext block resulting from encryption
252  **/
253 
254 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
255 {
256  //Perform AES encryption
257  aesProcessData(context, NULL, input, output, AES_BLOCK_SIZE,
258  SCE_AES_IN_DATA_CMD_ECB_ENCRYPTION);
259 }
260 
261 
262 /**
263  * @brief Decrypt a 16-byte block using AES algorithm
264  * @param[in] context Pointer to the AES context
265  * @param[in] input Ciphertext block to decrypt
266  * @param[out] output Plaintext block resulting from decryption
267  **/
268 
269 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
270 {
271  //Perform AES decryption
272  aesProcessData(context, NULL, input, output, AES_BLOCK_SIZE,
273  SCE_AES_IN_DATA_CMD_ECB_DECRYPTION);
274 }
275 
276 
277 #if (ECB_SUPPORT == ENABLED)
278 
279 /**
280  * @brief ECB encryption
281  * @param[in] cipher Cipher algorithm
282  * @param[in] context Cipher algorithm context
283  * @param[in] p Plaintext to be encrypted
284  * @param[out] c Ciphertext resulting from the encryption
285  * @param[in] length Total number of data bytes to be encrypted
286  * @return Error code
287  **/
288 
289 error_t ecbEncrypt(const CipherAlgo *cipher, void *context,
290  const uint8_t *p, uint8_t *c, size_t length)
291 {
292  error_t error;
293 
294  //Initialize status code
295  error = NO_ERROR;
296 
297  //AES cipher algorithm?
298  if(cipher == AES_CIPHER_ALGO)
299  {
300  //Check the length of the payload
301  if(length == 0)
302  {
303  //No data to process
304  }
305  else if((length % AES_BLOCK_SIZE) == 0)
306  {
307  //Encrypt payload data
308  error = aesProcessData(context, NULL, p, c, length,
309  SCE_AES_IN_DATA_CMD_ECB_ENCRYPTION);
310  }
311  else
312  {
313  //The length of the payload must be a multiple of the block size
314  error = ERROR_INVALID_LENGTH;
315  }
316  }
317  else
318  {
319  //ECB mode operates in a block-by-block fashion
320  while(length >= cipher->blockSize)
321  {
322  //Encrypt current block
323  cipher->encryptBlock(context, p, c);
324 
325  //Next block
326  p += cipher->blockSize;
327  c += cipher->blockSize;
328  length -= cipher->blockSize;
329  }
330 
331  //The length of the payload must be a multiple of the block size
332  if(length != 0)
333  {
334  error = ERROR_INVALID_LENGTH;
335  }
336  }
337 
338  //Return status code
339  return error;
340 }
341 
342 
343 /**
344  * @brief ECB decryption
345  * @param[in] cipher Cipher algorithm
346  * @param[in] context Cipher algorithm context
347  * @param[in] c Ciphertext to be decrypted
348  * @param[out] p Plaintext resulting from the decryption
349  * @param[in] length Total number of data bytes to be decrypted
350  * @return Error code
351  **/
352 
353 error_t ecbDecrypt(const CipherAlgo *cipher, void *context,
354  const uint8_t *c, uint8_t *p, size_t length)
355 {
356  error_t error;
357 
358  //Initialize status code
359  error = NO_ERROR;
360 
361  //AES cipher algorithm?
362  if(cipher == AES_CIPHER_ALGO)
363  {
364  //Check the length of the payload
365  if(length == 0)
366  {
367  //No data to process
368  }
369  else if((length % AES_BLOCK_SIZE) == 0)
370  {
371  //Decrypt payload data
372  error = aesProcessData(context, NULL, c, p, length,
373  SCE_AES_IN_DATA_CMD_ECB_DECRYPTION);
374  }
375  else
376  {
377  //The length of the payload must be a multiple of the block size
378  error = ERROR_INVALID_LENGTH;
379  }
380  }
381  else
382  {
383  //ECB mode operates in a block-by-block fashion
384  while(length >= cipher->blockSize)
385  {
386  //Decrypt current block
387  cipher->decryptBlock(context, c, p);
388 
389  //Next block
390  c += cipher->blockSize;
391  p += cipher->blockSize;
392  length -= cipher->blockSize;
393  }
394 
395  //The length of the payload must be a multiple of the block size
396  if(length != 0)
397  {
398  error = ERROR_INVALID_LENGTH;
399  }
400  }
401 
402  //Return status code
403  return error;
404 }
405 
406 #endif
407 #if (CBC_SUPPORT == ENABLED)
408 
409 /**
410  * @brief CBC encryption
411  * @param[in] cipher Cipher algorithm
412  * @param[in] context Cipher algorithm context
413  * @param[in,out] iv Initialization vector
414  * @param[in] p Plaintext to be encrypted
415  * @param[out] c Ciphertext resulting from the encryption
416  * @param[in] length Total number of data bytes to be encrypted
417  * @return Error code
418  **/
419 
420 error_t cbcEncrypt(const CipherAlgo *cipher, void *context,
421  uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
422 {
423  error_t error;
424 
425  //Initialize status code
426  error = NO_ERROR;
427 
428  //AES cipher algorithm?
429  if(cipher == AES_CIPHER_ALGO)
430  {
431  //Check the length of the payload
432  if(length == 0)
433  {
434  //No data to process
435  }
436  else if((length % AES_BLOCK_SIZE) == 0)
437  {
438  //Encrypt payload data
439  error = aesProcessData(context, iv, p, c, length,
440  SCE_AES_IN_DATA_CMD_CBC_ENCRYPTION);
441 
442  //Check status code
443  if(!error)
444  {
445  //Update the value of the initialization vector
447  }
448  }
449  else
450  {
451  //The length of the payload must be a multiple of the block size
452  error = ERROR_INVALID_LENGTH;
453  }
454  }
455  else
456  {
457  size_t i;
458 
459  //CBC mode operates in a block-by-block fashion
460  while(length >= cipher->blockSize)
461  {
462  //XOR input block with IV contents
463  for(i = 0; i < cipher->blockSize; i++)
464  {
465  c[i] = p[i] ^ iv[i];
466  }
467 
468  //Encrypt the current block based upon the output of the previous
469  //encryption
470  cipher->encryptBlock(context, c, c);
471 
472  //Update IV with output block contents
473  osMemcpy(iv, c, cipher->blockSize);
474 
475  //Next block
476  p += cipher->blockSize;
477  c += cipher->blockSize;
478  length -= cipher->blockSize;
479  }
480 
481  //The length of the payload must be a multiple of the block size
482  if(length != 0)
483  {
484  error = ERROR_INVALID_LENGTH;
485  }
486  }
487 
488  //Return status code
489  return error;
490 }
491 
492 
493 /**
494  * @brief CBC decryption
495  * @param[in] cipher Cipher algorithm
496  * @param[in] context Cipher algorithm context
497  * @param[in,out] iv Initialization vector
498  * @param[in] c Ciphertext to be decrypted
499  * @param[out] p Plaintext resulting from the decryption
500  * @param[in] length Total number of data bytes to be decrypted
501  * @return Error code
502  **/
503 
504 error_t cbcDecrypt(const CipherAlgo *cipher, void *context,
505  uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
506 {
507  error_t error;
508 
509  //Initialize status code
510  error = NO_ERROR;
511 
512  //AES cipher algorithm?
513  if(cipher == AES_CIPHER_ALGO)
514  {
515  //Check the length of the payload
516  if(length == 0)
517  {
518  //No data to process
519  }
520  else if((length % AES_BLOCK_SIZE) == 0)
521  {
522  uint8_t block[AES_BLOCK_SIZE];
523 
524  //Save the last input block
526 
527  //Decrypt payload data
528  error = aesProcessData(context, iv, c, p, length,
529  SCE_AES_IN_DATA_CMD_CBC_DECRYPTION);
530 
531  //Check status code
532  if(!error)
533  {
534  //Update the value of the initialization vector
536  }
537  }
538  else
539  {
540  //The length of the payload must be a multiple of the block size
541  error = ERROR_INVALID_LENGTH;
542  }
543  }
544  else
545  {
546  size_t i;
547  uint8_t t[16];
548 
549  //CBC mode operates in a block-by-block fashion
550  while(length >= cipher->blockSize)
551  {
552  //Save input block
553  osMemcpy(t, c, cipher->blockSize);
554 
555  //Decrypt the current block
556  cipher->decryptBlock(context, c, p);
557 
558  //XOR output block with IV contents
559  for(i = 0; i < cipher->blockSize; i++)
560  {
561  p[i] ^= iv[i];
562  }
563 
564  //Update IV with input block contents
565  osMemcpy(iv, t, cipher->blockSize);
566 
567  //Next block
568  c += cipher->blockSize;
569  p += cipher->blockSize;
570  length -= cipher->blockSize;
571  }
572 
573  //The length of the payload must be a multiple of the block size
574  if(length != 0)
575  {
576  error = ERROR_INVALID_LENGTH;
577  }
578  }
579 
580  //Return status code
581  return error;
582 }
583 
584 #endif
585 #if (CTR_SUPPORT == ENABLED)
586 
587 /**
588  * @brief CTR encryption
589  * @param[in] cipher Cipher algorithm
590  * @param[in] context Cipher algorithm context
591  * @param[in] m Size in bits of the specific part of the block to be incremented
592  * @param[in,out] t Initial counter block
593  * @param[in] p Plaintext to be encrypted
594  * @param[out] c Ciphertext resulting from the encryption
595  * @param[in] length Total number of data bytes to be encrypted
596  * @return Error code
597  **/
598 
599 error_t ctrEncrypt(const CipherAlgo *cipher, void *context, uint_t m,
600  uint8_t *t, const uint8_t *p, uint8_t *c, size_t length)
601 {
602  error_t error;
603 
604  //Initialize status code
605  error = NO_ERROR;
606 
607  //Check the value of the parameter
608  if((m % 8) == 0 && m <= (cipher->blockSize * 8))
609  {
610  //Determine the size, in bytes, of the specific part of the block to be
611  //incremented
612  m = m / 8;
613 
614  //AES cipher algorithm?
615  if(cipher == AES_CIPHER_ALGO)
616  {
617  size_t k;
618  size_t n;
619 
620  //Process plaintext
621  while(length > 0 && !error)
622  {
623  //Limit the number of blocks to process at a time
624  k = 256 - t[AES_BLOCK_SIZE - 1];
625  n = MIN(length, k * AES_BLOCK_SIZE);
626  k = (n + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
627 
628  //Encrypt payload data
629  error = aesProcessData(context, t, p, c, n,
630  SCE_AES_IN_DATA_CMD_CTR_ENCRYPTION_DECRYPTION);
631 
632  //Standard incrementing function
634 
635  //Next block
636  p += n;
637  c += n;
638  length -= n;
639  }
640  }
641  else
642  {
643  size_t i;
644  size_t n;
645  uint8_t o[16];
646 
647  //Process plaintext
648  while(length > 0)
649  {
650  //CTR mode operates in a block-by-block fashion
651  n = MIN(length, cipher->blockSize);
652 
653  //Compute O(j) = CIPH(T(j))
654  cipher->encryptBlock(context, t, o);
655 
656  //Compute C(j) = P(j) XOR T(j)
657  for(i = 0; i < n; i++)
658  {
659  c[i] = p[i] ^ o[i];
660  }
661 
662  //Standard incrementing function
663  ctrIncBlock(t, 1, cipher->blockSize, m);
664 
665  //Next block
666  p += n;
667  c += n;
668  length -= n;
669  }
670  }
671  }
672  else
673  {
674  //The value of the parameter is not valid
675  error = ERROR_INVALID_PARAMETER;
676  }
677 
678  //Return status code
679  return error;
680 }
681 
682 #endif
683 #if (GCM_SUPPORT == ENABLED)
684 
685 /**
686  * @brief Initialize GCM context
687  * @param[in] context Pointer to the GCM context
688  * @param[in] cipherAlgo Cipher algorithm
689  * @param[in] cipherContext Pointer to the cipher algorithm context
690  * @return Error code
691  **/
692 
693 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
694  void *cipherContext)
695 {
696  //Check parameters
697  if(context == NULL || cipherContext == NULL)
699 
700  //The SCE module only supports AES cipher algorithm
701  if(cipherAlgo != AES_CIPHER_ALGO)
703 
704  //Save cipher algorithm context
705  context->cipherAlgo = cipherAlgo;
706  context->cipherContext = cipherContext;
707 
708  //Successful initialization
709  return NO_ERROR;
710 }
711 
712 
713 /**
714  * @brief Authenticated encryption using GCM
715  * @param[in] context Pointer to the GCM context
716  * @param[in] iv Initialization vector
717  * @param[in] ivLen Length of the initialization vector
718  * @param[in] a Additional authenticated data
719  * @param[in] aLen Length of the additional data
720  * @param[in] p Plaintext to be encrypted
721  * @param[out] c Ciphertext resulting from the encryption
722  * @param[in] length Total number of data bytes to be encrypted
723  * @param[out] t Authentication tag
724  * @param[in] tLen Length of the authentication tag
725  * @return Error code
726  **/
727 
728 error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
729  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
730  uint8_t *c, size_t length, uint8_t *t, size_t tLen)
731 {
732  fsp_err_t status;
733  size_t i;
734  size_t n;
735  uint64_t m;
736  uint32_t keyType;
737  uint32_t temp[4];
738  uint32_t block[4];
739  uint32_t authTag[4];
740  AesContext *aesContext;
741 
742  //Make sure the GCM context is valid
743  if(context == NULL)
745 
746  //Check whether the length of the IV is 96 bits
747  if(ivLen != 12)
748  return ERROR_INVALID_LENGTH;
749 
750  //Check the length of the authentication tag
751  if(tLen < 4 || tLen > 16)
752  return ERROR_INVALID_LENGTH;
753 
754  //Point to the AES context
755  aesContext = (AesContext *) context->cipherContext;
756 
757  //Set key type
758  keyType = 0;
759 
760  //When the length of the IV is 96 bits, the padding string is appended to
761  //the IV to form the pre-counter block
762  temp[0] = LOAD32LE(iv);
763  temp[1] = LOAD32LE(iv + 4);
764  temp[2] = LOAD32LE(iv + 8);
765  temp[3] = BETOH32(1);
766 
767  //Acquire exclusive access to the SCE module
769 
770  //Initialize GCM encryption
771  if(aesContext->nr == 10)
772  {
773  status = HW_SCE_Aes128GcmEncryptInitSub(&keyType, aesContext->ek, temp);
774  }
775  else if(aesContext->nr == 12)
776  {
777  status = HW_SCE_Aes192GcmEncryptInitSub(aesContext->ek, temp);
778  }
779  else if(aesContext->nr == 14)
780  {
781  status = HW_SCE_Aes256GcmEncryptInitSub(&keyType, aesContext->ek, temp);
782  }
783  else
784  {
785  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
786  }
787 
788  //Check status code
789  if(status == FSP_SUCCESS)
790  {
791  //Point to the beginning of the additional authenticated data
792  i = 0;
793 
794  //Process additional authenticated data
795  if(aLen >= AES_BLOCK_SIZE)
796  {
797  //Process complete blocks only
798  n = aLen - (aLen % AES_BLOCK_SIZE);
799 
800  //Write complete blocks
801  if(aesContext->nr == 10)
802  {
803  HW_SCE_Aes128GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
804  }
805  else if(aesContext->nr == 12)
806  {
807  HW_SCE_Aes192GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
808  }
809  else
810  {
811  HW_SCE_Aes256GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
812  }
813 
814  //Advance data pointer
815  i += n;
816  }
817 
818  //Process final block of additional authenticated data
819  if(i < aLen)
820  {
821  //Copy the partial block
823  osMemcpy(block, a + i, aLen - i);
824 
825  //Write block
826  if(aesContext->nr == 10)
827  {
828  HW_SCE_Aes128GcmEncryptUpdateAADSub(block, 1);
829  }
830  else if(aesContext->nr == 12)
831  {
832  HW_SCE_Aes192GcmEncryptUpdateAADSub(block, 1);
833  }
834  else
835  {
836  HW_SCE_Aes256GcmEncryptUpdateAADSub(block, 1);
837  }
838  }
839 
840  //Transition to from AAD phase to data phase
841  if(aesContext->nr == 10)
842  {
843  HW_SCE_Aes128GcmEncryptUpdateTransitionSub();
844  }
845  else if(aesContext->nr == 12)
846  {
847  HW_SCE_Aes192GcmEncryptUpdateTransitionSub();
848  }
849  else
850  {
851  HW_SCE_Aes256GcmEncryptUpdateTransitionSub();
852  }
853 
854  //Point to the beginning of the payload data
855  i = 0;
856 
857  //Process payload data
858  if(length >= AES_BLOCK_SIZE)
859  {
860  //Process complete blocks only
861  n = length - (length % AES_BLOCK_SIZE);
862 
863  //Encrypt complete blocks
864  if(aesContext->nr == 10)
865  {
866  HW_SCE_Aes128GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
867  n / 4);
868  }
869  else if(aesContext->nr == 12)
870  {
871  HW_SCE_Aes192GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
872  n / 4);
873  }
874  else
875  {
876  HW_SCE_Aes256GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
877  n / 4);
878  }
879 
880  //Advance data pointer
881  i += n;
882  }
883 
884  //Process final block of payload data
885  if(i < length)
886  {
887  //Copy the partial input block
889  osMemcpy(block, p + i, length - i);
890  }
891 
892  //64-bit representation of the length of the payload data
893  m = length * 8;
894  temp[0] = htobe32(m >> 32);
895  temp[1] = htobe32(m);
896 
897  //64-bit representation of the length of the additional data
898  m = aLen * 8;
899  temp[2] = htobe32(m >> 32);
900  temp[3] = htobe32(m);
901 
902  //Generate authentication tag
903  if(aesContext->nr == 10)
904  {
905  status = HW_SCE_Aes128GcmEncryptFinalSub(block, temp, temp + 2,
906  block, authTag);
907  }
908  else if(aesContext->nr == 12)
909  {
910  status = HW_SCE_Aes192GcmEncryptFinalSub(block, temp, temp + 2,
911  block, authTag);
912  }
913  else if(aesContext->nr == 14)
914  {
915  status = HW_SCE_Aes256GcmEncryptFinalSub(block, temp, temp + 2,
916  block, authTag);
917  }
918  else
919  {
920  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
921  }
922  }
923 
924  //Check status code
925  if(status == FSP_SUCCESS)
926  {
927  //Copy the partial output block
928  osMemcpy(c + i, block, length - i);
929  //Copy the resulting authentication tag
930  osMemcpy(t, authTag, tLen);
931  }
932 
933  //Release exclusive access to the SCE module
935 
936  //Return status code
937  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
938 }
939 
940 
941 /**
942  * @brief Authenticated decryption using GCM
943  * @param[in] context Pointer to the GCM context
944  * @param[in] iv Initialization vector
945  * @param[in] ivLen Length of the initialization vector
946  * @param[in] a Additional authenticated data
947  * @param[in] aLen Length of the additional data
948  * @param[in] c Ciphertext to be decrypted
949  * @param[out] p Plaintext resulting from the decryption
950  * @param[in] length Total number of data bytes to be decrypted
951  * @param[in] t Authentication tag
952  * @param[in] tLen Length of the authentication tag
953  * @return Error code
954  **/
955 
956 error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
957  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
958  uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
959 {
960  fsp_err_t status;
961  size_t i;
962  size_t n;
963  uint64_t m;
964  uint32_t keyType;
965  uint32_t temp[5];
966  uint32_t block[4];
967  uint32_t authTag[4];
968  AesContext *aesContext;
969 
970  //Make sure the GCM context is valid
971  if(context == NULL)
973 
974  //Check whether the length of the IV is 96 bits
975  if(ivLen != 12)
976  return ERROR_INVALID_LENGTH;
977 
978  //Check the length of the authentication tag
979  if(tLen < 4 || tLen > 16)
980  return ERROR_INVALID_LENGTH;
981 
982  //Point to the AES context
983  aesContext = (AesContext *) context->cipherContext;
984 
985  //Set key type
986  keyType = 0;
987 
988  //When the length of the IV is 96 bits, the padding string is appended to
989  //the IV to form the pre-counter block
990  temp[0] = LOAD32LE(iv);
991  temp[1] = LOAD32LE(iv + 4);
992  temp[2] = LOAD32LE(iv + 8);
993  temp[3] = BETOH32(1);
994 
995  //Acquire exclusive access to the SCE module
997 
998  //Initialize GCM decryption
999  if(aesContext->nr == 10)
1000  {
1001  status = HW_SCE_Aes128GcmDecryptInitSub(&keyType, aesContext->ek, temp);
1002  }
1003  else if(aesContext->nr == 12)
1004  {
1005  status = HW_SCE_Aes192GcmDecryptInitSub(aesContext->ek, temp);
1006  }
1007  else if(aesContext->nr == 14)
1008  {
1009  status = HW_SCE_Aes256GcmDecryptInitSub(&keyType, aesContext->ek, temp);
1010  }
1011  else
1012  {
1013  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1014  }
1015 
1016  //Check status code
1017  if(status == FSP_SUCCESS)
1018  {
1019  //Point to the beginning of the additional authenticated data
1020  i = 0;
1021 
1022  //Process additional authenticated data
1023  if(aLen >= AES_BLOCK_SIZE)
1024  {
1025  //Process complete blocks only
1026  n = aLen - (aLen % AES_BLOCK_SIZE);
1027 
1028  //Write complete blocks
1029  if(aesContext->nr == 10)
1030  {
1031  HW_SCE_Aes128GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1032  }
1033  else if(aesContext->nr == 12)
1034  {
1035  HW_SCE_Aes192GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1036  }
1037  else
1038  {
1039  HW_SCE_Aes256GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1040  }
1041 
1042  //Advance data pointer
1043  i += n;
1044  }
1045 
1046  //Process final block of additional authenticated data
1047  if(i < aLen)
1048  {
1049  //Copy the partial block
1051  osMemcpy(block, a + i, aLen - i);
1052 
1053  //Write block
1054  if(aesContext->nr == 10)
1055  {
1056  HW_SCE_Aes128GcmDecryptUpdateAADSub(block, 1);
1057  }
1058  else if(aesContext->nr == 12)
1059  {
1060  HW_SCE_Aes192GcmDecryptUpdateAADSub(block, 1);
1061  }
1062  else
1063  {
1064  HW_SCE_Aes256GcmDecryptUpdateAADSub(block, 1);
1065  }
1066  }
1067 
1068  //Transition to from AAD phase to data phase
1069  if(aesContext->nr == 10)
1070  {
1071  HW_SCE_Aes128GcmDecryptUpdateTransitionSub();
1072  }
1073  else if(aesContext->nr == 12)
1074  {
1075  HW_SCE_Aes192GcmDecryptUpdateTransitionSub();
1076  }
1077  else
1078  {
1079  HW_SCE_Aes256GcmDecryptUpdateTransitionSub();
1080  }
1081 
1082  //Point to the beginning of the payload data
1083  i = 0;
1084 
1085  //Process payload data
1086  if(length >= AES_BLOCK_SIZE)
1087  {
1088  //Process complete blocks only
1089  n = length - (length % AES_BLOCK_SIZE);
1090 
1091  //Decrypt complete blocks
1092  if(aesContext->nr == 10)
1093  {
1094  HW_SCE_Aes128GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1095  n / 4);
1096  }
1097  else if(aesContext->nr == 12)
1098  {
1099  HW_SCE_Aes192GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1100  n / 4);
1101  }
1102  else
1103  {
1104  HW_SCE_Aes256GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1105  n / 4);
1106  }
1107 
1108  //Advance data pointer
1109  i += n;
1110  }
1111 
1112  //Process final block of payload data
1113  if(i < length)
1114  {
1115  //Copy the partial input block
1117  osMemcpy(block, c + i, length - i);
1118  }
1119 
1120  //64-bit representation of the length of the payload data
1121  m = length * 8;
1122  temp[0] = htobe32(m >> 32);
1123  temp[1] = htobe32(m);
1124 
1125  //64-bit representation of the length of the additional data
1126  m = aLen * 8;
1127  temp[2] = htobe32(m >> 32);
1128  temp[3] = htobe32(m);
1129 
1130  //32-bit representation of the length of the authentication tag
1131  temp[4] = htobe32(tLen);
1132 
1133  //Pad the authentication tag
1134  osMemset(authTag, 0, sizeof(authTag));
1135  osMemcpy(authTag, t, tLen);
1136 
1137  //Verify authentication tag
1138  if(aesContext->nr == 10)
1139  {
1140  status = HW_SCE_Aes128GcmDecryptFinalSub(block, temp, temp + 2,
1141  authTag, temp + 4, block);
1142  }
1143  else if(aesContext->nr == 12)
1144  {
1145  status = HW_SCE_Aes192GcmDecryptFinalSub(block, temp, temp + 2,
1146  authTag, temp + 4, block);
1147  }
1148  else if(aesContext->nr == 14)
1149  {
1150  status = HW_SCE_Aes256GcmDecryptFinalSub(block, temp, temp + 2,
1151  authTag, temp + 4, block);
1152  }
1153  else
1154  {
1155  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1156  }
1157  }
1158 
1159  //Check status code
1160  if(status == FSP_SUCCESS)
1161  {
1162  //Copy the partial output block
1163  osMemcpy(p + i, block, length - i);
1164  }
1165 
1166  //Release exclusive access to the SCE module
1168 
1169  //Return status code
1170  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1171 }
1172 
1173 #endif
1174 #if (CCM_SUPPORT == ENABLED)
1175 
1176 /**
1177  * @brief Authenticated encryption using CCM
1178  * @param[in] cipher Cipher algorithm
1179  * @param[in] context Cipher algorithm context
1180  * @param[in] n Nonce
1181  * @param[in] nLen Length of the nonce
1182  * @param[in] a Additional authenticated data
1183  * @param[in] aLen Length of the additional data
1184  * @param[in] p Plaintext to be encrypted
1185  * @param[out] c Ciphertext resulting from the encryption
1186  * @param[in] length Total number of data bytes to be encrypted
1187  * @param[out] t MAC resulting from the encryption process
1188  * @param[in] tLen Length of the MAC
1189  * @return Error code
1190  **/
1191 
1192 error_t ccmEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1193  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c,
1194  size_t length, uint8_t *t, size_t tLen)
1195 {
1196  error_t error;
1197  fsp_err_t status;
1198  size_t m;
1199  uint32_t keyType;
1200  uint32_t dataType;
1201  uint32_t command;
1202  uint32_t textLen;
1203  uint32_t headerLen;
1204  uint32_t seqNum;
1205  uint32_t block[4];
1206  uint32_t authTag[4];
1207  uint8_t header[64];
1208  AesContext *aesContext;
1209 
1210  //The SCE module only supports AES cipher algorithm
1211  if(cipher != AES_CIPHER_ALGO)
1212  return ERROR_INVALID_PARAMETER;
1213 
1214  //Make sure the cipher context is valid
1215  if(context == NULL)
1216  return ERROR_INVALID_PARAMETER;
1217 
1218  //Check the length of the additional data
1219  if(aLen > (sizeof(header) - 18))
1220  return ERROR_INVALID_LENGTH;
1221 
1222  //Point to the AES context
1223  aesContext = (AesContext *) context;
1224 
1225  //Initialize parameters
1226  keyType = 0;
1227  dataType = 0;
1228  command = 0;
1229  textLen = htobe32(length);
1230  seqNum = 0;
1231 
1232  //Clear header
1233  osMemset(header, 0, sizeof(header));
1234 
1235  //Format first block B(0)
1236  error = ccmFormatBlock0(length, n, nLen, aLen, tLen, header);
1237  //Invalid parameters?
1238  if(error)
1239  return error;
1240 
1241  //Size of the first block (B0)
1242  headerLen = AES_BLOCK_SIZE;
1243 
1244  //Any additional data?
1245  if(aLen > 0)
1246  {
1247  //The length is encoded as 2 octets
1248  STORE16BE(aLen, header + headerLen);
1249  //Concatenate the associated data A
1250  osMemcpy(header + headerLen + 2, a, aLen);
1251  //Adjust the size of the header
1252  headerLen += 2 + aLen;
1253  }
1254 
1255  //Format initial counter value CTR(0)
1256  ccmFormatCounter0(n, nLen, (uint8_t *) block);
1257 
1258  //Acquire exclusive access to the SCE module
1260 
1261  //Initialize CCM encryption
1262  if(aesContext->nr == 10)
1263  {
1264  status = HW_SCE_Aes128CcmEncryptInitSubGeneral(&keyType, &dataType,
1265  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1266  &seqNum, (headerLen + 3) / 4);
1267  }
1268  else if(aesContext->nr == 12)
1269  {
1270  status = HW_SCE_Aes192CcmEncryptInitSubGeneral(&keyType, &dataType,
1271  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1272  &seqNum, (headerLen + 3) / 4);
1273  }
1274  else if(aesContext->nr == 14)
1275  {
1276  status = HW_SCE_Aes256CcmEncryptInitSubGeneral(&keyType, &dataType,
1277  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1278  &seqNum, (headerLen + 3) / 4);
1279  }
1280  else
1281  {
1282  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1283  }
1284 
1285  //Check status code
1286  if(status == FSP_SUCCESS)
1287  {
1288  //Process payload data
1289  if(length >= AES_BLOCK_SIZE)
1290  {
1291  //Process complete blocks only
1292  m = length - (length % AES_BLOCK_SIZE);
1293 
1294  //Encrypt complete blocks
1295  if(aesContext->nr == 10)
1296  {
1297  HW_SCE_Aes128CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1298  m / 4);
1299  }
1300  else if(aesContext->nr == 12)
1301  {
1302  HW_SCE_Aes192CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1303  m / 4);
1304  }
1305  else
1306  {
1307  HW_SCE_Aes256CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1308  m / 4);
1309  }
1310 
1311  //Advance data pointer
1312  length -= m;
1313  p += m;
1314  c += m;
1315  }
1316 
1317  //Process final block of payload data
1318  if(length > 0)
1319  {
1320  //Copy the partial input block
1322  osMemcpy(block, p, length);
1323  }
1324 
1325  //Generate authentication tag
1326  if(aesContext->nr == 10)
1327  {
1328  status = HW_SCE_Aes128CcmEncryptFinalSubGeneral(block, &textLen,
1329  block, authTag);
1330  }
1331  else if(aesContext->nr == 12)
1332  {
1333  status = HW_SCE_Aes192CcmEncryptFinalSub(block, &textLen, block,
1334  authTag);
1335  }
1336  else if(aesContext->nr == 14)
1337  {
1338  status = HW_SCE_Aes256CcmEncryptFinalSub(block, &textLen, block,
1339  authTag);
1340  }
1341  else
1342  {
1343  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1344  }
1345  }
1346 
1347  //Check status code
1348  if(status == FSP_SUCCESS)
1349  {
1350  //Copy the partial output block
1351  osMemcpy(c, block, length);
1352  //Copy the resulting authentication tag
1353  osMemcpy(t, authTag, tLen);
1354  }
1355 
1356  //Release exclusive access to the SCE module
1358 
1359  //Return status code
1360  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1361 }
1362 
1363 
1364 /**
1365  * @brief Authenticated decryption using CCM
1366  * @param[in] cipher Cipher algorithm
1367  * @param[in] context Cipher algorithm context
1368  * @param[in] n Nonce
1369  * @param[in] nLen Length of the nonce
1370  * @param[in] a Additional authenticated data
1371  * @param[in] aLen Length of the additional data
1372  * @param[in] c Ciphertext to be decrypted
1373  * @param[out] p Plaintext resulting from the decryption
1374  * @param[in] length Total number of data bytes to be decrypted
1375  * @param[in] t MAC to be verified
1376  * @param[in] tLen Length of the MAC
1377  * @return Error code
1378  **/
1379 
1380 error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1381  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p,
1382  size_t length, const uint8_t *t, size_t tLen)
1383 {
1384  error_t error;
1385  fsp_err_t status;
1386  size_t m;
1387  uint32_t keyType;
1388  uint32_t dataType;
1389  uint32_t command;
1390  uint32_t textLen;
1391  uint32_t authTagLen;
1392  uint32_t headerLen;
1393  uint32_t seqNum;
1394  uint32_t block[4];
1395  uint32_t authTag[4];
1396  uint8_t header[64];
1397  AesContext *aesContext;
1398 
1399  //The SCE module only supports AES cipher algorithm
1400  if(cipher != AES_CIPHER_ALGO)
1401  return ERROR_INVALID_PARAMETER;
1402 
1403  //Make sure the cipher context is valid
1404  if(context == NULL)
1405  return ERROR_INVALID_PARAMETER;
1406 
1407  //Check the length of the additional data
1408  if(aLen > (sizeof(header) - 18))
1409  return ERROR_INVALID_LENGTH;
1410 
1411  //Point to the AES context
1412  aesContext = (AesContext *) context;
1413 
1414  //Initialize parameters
1415  keyType = 0;
1416  dataType = 0;
1417  command = 0;
1418  textLen = htobe32(length);
1419  authTagLen = htobe32(tLen);
1420  seqNum = 0;
1421 
1422  //Clear header
1423  osMemset(header, 0, sizeof(header));
1424 
1425  //Format first block B(0)
1426  error = ccmFormatBlock0(length, n, nLen, aLen, tLen, header);
1427  //Invalid parameters?
1428  if(error)
1429  return error;
1430 
1431  //Size of the first block (B0)
1432  headerLen = AES_BLOCK_SIZE;
1433 
1434  //Any additional data?
1435  if(aLen > 0)
1436  {
1437  //The length is encoded as 2 octets
1438  STORE16BE(aLen, header + headerLen);
1439  //Concatenate the associated data A
1440  osMemcpy(header + headerLen + 2, a, aLen);
1441  //Adjust the size of the header
1442  headerLen += 2 + aLen;
1443  }
1444 
1445  //Format initial counter value CTR(0)
1446  ccmFormatCounter0(n, nLen, (uint8_t *) block);
1447 
1448  //Acquire exclusive access to the SCE module
1450 
1451  //Initialize CCM decryption
1452  if(aesContext->nr == 10)
1453  {
1454  status = HW_SCE_Aes128CcmDecryptInitSubGeneral(&keyType, &dataType,
1455  &command, &textLen, &authTagLen, aesContext->ek, block,
1456  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1457  }
1458  else if(aesContext->nr == 12)
1459  {
1460  status = HW_SCE_Aes192CcmDecryptInitSubGeneral(&keyType, &dataType,
1461  &command, &textLen, &authTagLen, aesContext->ek, block,
1462  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1463  }
1464  else if(aesContext->nr == 14)
1465  {
1466  status = HW_SCE_Aes256CcmDecryptInitSubGeneral(&keyType, &dataType,
1467  &command, &textLen, &authTagLen, aesContext->ek, block,
1468  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1469  }
1470  else
1471  {
1472  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1473  }
1474 
1475  //Check status code
1476  if(status == FSP_SUCCESS)
1477  {
1478  //Process payload data
1479  if(length >= AES_BLOCK_SIZE)
1480  {
1481  //Process complete blocks only
1482  m = length - (length % AES_BLOCK_SIZE);
1483 
1484  //Decrypt complete blocks
1485  if(aesContext->nr == 10)
1486  {
1487  HW_SCE_Aes128CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1488  m / 4);
1489  }
1490  else if(aesContext->nr == 12)
1491  {
1492  HW_SCE_Aes192CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1493  m / 4);
1494  }
1495  else
1496  {
1497  HW_SCE_Aes256CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1498  m / 4);
1499  }
1500 
1501  //Advance data pointer
1502  length -= m;
1503  c += m;
1504  p += m;
1505  }
1506 
1507  //Process final block of payload data
1508  if(length > 0)
1509  {
1510  //Copy the partial input block
1512  osMemcpy(block, c, length);
1513  }
1514 
1515  //Pad the authentication tag
1516  osMemset(authTag, 0, sizeof(authTag));
1517  osMemcpy(authTag, t, tLen);
1518 
1519  //Verify authentication tag
1520  if(aesContext->nr == 10)
1521  {
1522  status = HW_SCE_Aes128CcmDecryptFinalSubGeneral(block, &textLen,
1523  authTag, &authTagLen, block);
1524  }
1525  else if(aesContext->nr == 12)
1526  {
1527  status = HW_SCE_Aes192CcmDecryptFinalSub(block, &textLen,
1528  authTag, &authTagLen, block);
1529  }
1530  else if(aesContext->nr == 14)
1531  {
1532  status = HW_SCE_Aes256CcmDecryptFinalSub(block, &textLen,
1533  authTag, &authTagLen, block);
1534  }
1535  else
1536  {
1537  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1538  }
1539  }
1540 
1541  //Check status code
1542  if(status == FSP_SUCCESS)
1543  {
1544  //Copy the partial output block
1545  osMemcpy(p, block, length);
1546  }
1547 
1548  //Release exclusive access to the SCE module
1550 
1551  //Return status code
1552  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1553 }
1554 
1555 #endif
1556 #endif
uint16_t block
Definition: tftp_common.h:115
void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using AES algorithm.
uint8_t a
Definition: ndp.h:411
CipherAlgoDecryptBlock decryptBlock
Definition: crypto.h:1077
uint8_t p
Definition: ndp.h:300
RA6 cipher hardware accelerator.
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t o
Collection of AEAD algorithms.
size_t blockSize
Definition: crypto.h:1072
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.
#define BETOH32(value)
Definition: cpu_endian.h:451
void ccmFormatCounter0(const uint8_t *n, size_t nLen, uint8_t *ctr)
Format initial counter value CTR(0)
Definition: ccm.c:418
CipherAlgoEncryptBlock encryptBlock
Definition: crypto.h:1076
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:141
error_t
Error codes.
Definition: error.h:43
uint32_t seqNum
Definition: tcp.h:341
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.
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
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 ccmFormatBlock0(size_t q, const uint8_t *n, size_t nLen, size_t aLen, size_t tLen, uint8_t *b)
Format first block B(0)
Definition: ccm.c:353
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
uint8_t iv[]
Definition: ike.h:1502
error_t aesProcessData(AesContext *context, uint8_t *iv, const uint8_t *input, uint8_t *output, size_t length, uint32_t command)
Perform AES encryption or decryption.
Block cipher modes of operation.
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: gcm.h:65
uint8_t length
Definition: tcp.h:368
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.
#define MIN(a, b)
Definition: os_port.h:63
RA6 hardware cryptographic accelerator (SCE7 / SCE9)
error_t cbcDecrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
CBC decryption.
OsMutex ra6CryptoMutex
Definition: ra6_crypto.c:41
uint_t nr
Definition: aes.h:59
#define htobe32(value)
Definition: cpu_endian.h:446
void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using AES algorithm.
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.
error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
Common interface for encryption algorithms.
Definition: crypto.h:1068
#define AES_CIPHER_ALGO
Definition: aes.h:45
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.
error_t cbcEncrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
CBC encryption.
#define LOAD32LE(p)
Definition: cpu_endian.h:203
error_t ecbDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *c, uint8_t *p, size_t length)
ECB decryption.
uint32_t ek[60]
Definition: aes.h:60
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:135
error_t ecbEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *p, uint8_t *c, size_t length)
ECB encryption.
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.