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.0
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  //AES cipher algorithm?
608  if(cipher == AES_CIPHER_ALGO)
609  {
610  //Check the value of the parameter
611  if(m == (AES_BLOCK_SIZE * 8))
612  {
613  //Check the length of the payload
614  if(length > 0)
615  {
616  size_t i;
617  size_t j;
618  uint16_t temp;
619 
620  //Encrypt payload data
621  error = aesProcessData(context, t, p, c, length,
622  SCE_AES_IN_DATA_CMD_CTR_ENCRYPTION_DECRYPTION);
623 
624  //Update counter value
625  for(i = 0; i < length; i += AES_BLOCK_SIZE)
626  {
627  //Standard incrementing function
628  for(temp = 1, j = 1; j <= AES_BLOCK_SIZE; j++)
629  {
630  //Increment the current byte and propagate the carry
631  temp += t[AES_BLOCK_SIZE - j];
632  t[AES_BLOCK_SIZE - j] = temp & 0xFF;
633  temp >>= 8;
634  }
635  }
636  }
637  else
638  {
639  //No data to process
640  }
641  }
642  else
643  {
644  //The value of the parameter is not valid
645  error = ERROR_INVALID_PARAMETER;
646  }
647  }
648  else
649  {
650  //Check the value of the parameter
651  if((m % 8) == 0 && m <= (cipher->blockSize * 8))
652  {
653  size_t i;
654  size_t n;
655  uint16_t temp;
656  uint8_t o[16];
657 
658  //Determine the size, in bytes, of the specific part of the block
659  //to be incremented
660  m = m / 8;
661 
662  //Process plaintext
663  while(length > 0)
664  {
665  //CTR mode operates in a block-by-block fashion
666  n = MIN(length, cipher->blockSize);
667 
668  //Compute O(j) = CIPH(T(j))
669  cipher->encryptBlock(context, t, o);
670 
671  //Compute C(j) = P(j) XOR T(j)
672  for(i = 0; i < n; i++)
673  {
674  c[i] = p[i] ^ o[i];
675  }
676 
677  //Standard incrementing function
678  for(temp = 1, i = 1; i <= m; i++)
679  {
680  //Increment the current byte and propagate the carry
681  temp += t[cipher->blockSize - i];
682  t[cipher->blockSize - i] = temp & 0xFF;
683  temp >>= 8;
684  }
685 
686  //Next block
687  p += n;
688  c += n;
689  length -= n;
690  }
691  }
692  else
693  {
694  //The value of the parameter is not valid
695  error = ERROR_INVALID_PARAMETER;
696  }
697  }
698 
699  //Return status code
700  return error;
701 }
702 
703 #endif
704 #if (GCM_SUPPORT == ENABLED)
705 
706 /**
707  * @brief Initialize GCM context
708  * @param[in] context Pointer to the GCM context
709  * @param[in] cipherAlgo Cipher algorithm
710  * @param[in] cipherContext Pointer to the cipher algorithm context
711  * @return Error code
712  **/
713 
714 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
715  void *cipherContext)
716 {
717  //Check parameters
718  if(context == NULL || cipherContext == NULL)
720 
721  //The SCE module only supports AES cipher algorithm
722  if(cipherAlgo != AES_CIPHER_ALGO)
724 
725  //Save cipher algorithm context
726  context->cipherAlgo = cipherAlgo;
727  context->cipherContext = cipherContext;
728 
729  //Successful initialization
730  return NO_ERROR;
731 }
732 
733 
734 /**
735  * @brief Authenticated encryption using GCM
736  * @param[in] context Pointer to the GCM context
737  * @param[in] iv Initialization vector
738  * @param[in] ivLen Length of the initialization vector
739  * @param[in] a Additional authenticated data
740  * @param[in] aLen Length of the additional data
741  * @param[in] p Plaintext to be encrypted
742  * @param[out] c Ciphertext resulting from the encryption
743  * @param[in] length Total number of data bytes to be encrypted
744  * @param[out] t Authentication tag
745  * @param[in] tLen Length of the authentication tag
746  * @return Error code
747  **/
748 
749 error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
750  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
751  uint8_t *c, size_t length, uint8_t *t, size_t tLen)
752 {
753  fsp_err_t status;
754  size_t i;
755  size_t n;
756  uint64_t m;
757  uint32_t keyType;
758  uint32_t temp[4];
759  uint32_t block[4];
760  uint32_t authTag[4];
761  AesContext *aesContext;
762 
763  //Make sure the GCM context is valid
764  if(context == NULL)
766 
767  //Check whether the length of the IV is 96 bits
768  if(ivLen != 12)
769  return ERROR_INVALID_LENGTH;
770 
771  //Check the length of the authentication tag
772  if(tLen < 4 || tLen > 16)
773  return ERROR_INVALID_LENGTH;
774 
775  //Point to the AES context
776  aesContext = (AesContext *) context->cipherContext;
777 
778  //Set key type
779  keyType = 0;
780 
781  //When the length of the IV is 96 bits, the padding string is appended to
782  //the IV to form the pre-counter block
783  temp[0] = LOAD32LE(iv);
784  temp[1] = LOAD32LE(iv + 4);
785  temp[2] = LOAD32LE(iv + 8);
786  temp[3] = BETOH32(1);
787 
788  //Acquire exclusive access to the SCE module
790 
791  //Initialize GCM encryption
792  if(aesContext->nr == 10)
793  {
794  status = HW_SCE_Aes128GcmEncryptInitSub(&keyType, aesContext->ek, temp);
795  }
796  else if(aesContext->nr == 12)
797  {
798  status = HW_SCE_Aes192GcmEncryptInitSub(aesContext->ek, temp);
799  }
800  else if(aesContext->nr == 14)
801  {
802  status = HW_SCE_Aes256GcmEncryptInitSub(&keyType, aesContext->ek, temp);
803  }
804  else
805  {
806  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
807  }
808 
809  //Check status code
810  if(status == FSP_SUCCESS)
811  {
812  //Point to the beginning of the additional authenticated data
813  i = 0;
814 
815  //Process additional authenticated data
816  if(aLen >= AES_BLOCK_SIZE)
817  {
818  //Process complete blocks only
819  n = aLen - (aLen % AES_BLOCK_SIZE);
820 
821  //Write complete blocks
822  if(aesContext->nr == 10)
823  {
824  HW_SCE_Aes128GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
825  }
826  else if(aesContext->nr == 12)
827  {
828  HW_SCE_Aes192GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
829  }
830  else
831  {
832  HW_SCE_Aes256GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
833  }
834 
835  //Advance data pointer
836  i += n;
837  }
838 
839  //Process final block of additional authenticated data
840  if(i < aLen)
841  {
842  //Copy the partial block
844  osMemcpy(block, a + i, aLen - i);
845 
846  //Write block
847  if(aesContext->nr == 10)
848  {
849  HW_SCE_Aes128GcmEncryptUpdateAADSub(block, 1);
850  }
851  else if(aesContext->nr == 12)
852  {
853  HW_SCE_Aes192GcmEncryptUpdateAADSub(block, 1);
854  }
855  else
856  {
857  HW_SCE_Aes256GcmEncryptUpdateAADSub(block, 1);
858  }
859  }
860 
861  //Transition to from AAD phase to data phase
862  if(aesContext->nr == 10)
863  {
864  HW_SCE_Aes128GcmEncryptUpdateTransitionSub();
865  }
866  else if(aesContext->nr == 12)
867  {
868  HW_SCE_Aes192GcmEncryptUpdateTransitionSub();
869  }
870  else
871  {
872  HW_SCE_Aes256GcmEncryptUpdateTransitionSub();
873  }
874 
875  //Point to the beginning of the payload data
876  i = 0;
877 
878  //Process payload data
879  if(length >= AES_BLOCK_SIZE)
880  {
881  //Process complete blocks only
882  n = length - (length % AES_BLOCK_SIZE);
883 
884  //Encrypt complete blocks
885  if(aesContext->nr == 10)
886  {
887  HW_SCE_Aes128GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
888  n / 4);
889  }
890  else if(aesContext->nr == 12)
891  {
892  HW_SCE_Aes192GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
893  n / 4);
894  }
895  else
896  {
897  HW_SCE_Aes256GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
898  n / 4);
899  }
900 
901  //Advance data pointer
902  i += n;
903  }
904 
905  //Process final block of payload data
906  if(i < length)
907  {
908  //Copy the partial input block
910  osMemcpy(block, p + i, length - i);
911  }
912 
913  //64-bit representation of the length of the payload data
914  m = length * 8;
915  temp[0] = htobe32(m >> 32);
916  temp[1] = htobe32(m);
917 
918  //64-bit representation of the length of the additional data
919  m = aLen * 8;
920  temp[2] = htobe32(m >> 32);
921  temp[3] = htobe32(m);
922 
923  //Generate authentication tag
924  if(aesContext->nr == 10)
925  {
926  status = HW_SCE_Aes128GcmEncryptFinalSub(block, temp, temp + 2,
927  block, authTag);
928  }
929  else if(aesContext->nr == 12)
930  {
931  status = HW_SCE_Aes192GcmEncryptFinalSub(block, temp, temp + 2,
932  block, authTag);
933  }
934  else if(aesContext->nr == 14)
935  {
936  status = HW_SCE_Aes256GcmEncryptFinalSub(block, temp, temp + 2,
937  block, authTag);
938  }
939  else
940  {
941  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
942  }
943  }
944 
945  //Check status code
946  if(status == FSP_SUCCESS)
947  {
948  //Copy the partial output block
949  osMemcpy(c + i, block, length - i);
950  //Copy the resulting authentication tag
951  osMemcpy(t, authTag, tLen);
952  }
953 
954  //Release exclusive access to the SCE module
956 
957  //Return status code
958  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
959 }
960 
961 
962 /**
963  * @brief Authenticated decryption using GCM
964  * @param[in] context Pointer to the GCM context
965  * @param[in] iv Initialization vector
966  * @param[in] ivLen Length of the initialization vector
967  * @param[in] a Additional authenticated data
968  * @param[in] aLen Length of the additional data
969  * @param[in] c Ciphertext to be decrypted
970  * @param[out] p Plaintext resulting from the decryption
971  * @param[in] length Total number of data bytes to be decrypted
972  * @param[in] t Authentication tag
973  * @param[in] tLen Length of the authentication tag
974  * @return Error code
975  **/
976 
977 error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
978  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
979  uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
980 {
981  fsp_err_t status;
982  size_t i;
983  size_t n;
984  uint64_t m;
985  uint32_t keyType;
986  uint32_t temp[5];
987  uint32_t block[4];
988  uint32_t authTag[4];
989  AesContext *aesContext;
990 
991  //Make sure the GCM context is valid
992  if(context == NULL)
994 
995  //Check whether the length of the IV is 96 bits
996  if(ivLen != 12)
997  return ERROR_INVALID_LENGTH;
998 
999  //Check the length of the authentication tag
1000  if(tLen < 4 || tLen > 16)
1001  return ERROR_INVALID_LENGTH;
1002 
1003  //Point to the AES context
1004  aesContext = (AesContext *) context->cipherContext;
1005 
1006  //Set key type
1007  keyType = 0;
1008 
1009  //When the length of the IV is 96 bits, the padding string is appended to
1010  //the IV to form the pre-counter block
1011  temp[0] = LOAD32LE(iv);
1012  temp[1] = LOAD32LE(iv + 4);
1013  temp[2] = LOAD32LE(iv + 8);
1014  temp[3] = BETOH32(1);
1015 
1016  //Acquire exclusive access to the SCE module
1018 
1019  //Initialize GCM decryption
1020  if(aesContext->nr == 10)
1021  {
1022  status = HW_SCE_Aes128GcmDecryptInitSub(&keyType, aesContext->ek, temp);
1023  }
1024  else if(aesContext->nr == 12)
1025  {
1026  status = HW_SCE_Aes192GcmDecryptInitSub(aesContext->ek, temp);
1027  }
1028  else if(aesContext->nr == 14)
1029  {
1030  status = HW_SCE_Aes256GcmDecryptInitSub(&keyType, aesContext->ek, temp);
1031  }
1032  else
1033  {
1034  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1035  }
1036 
1037  //Check status code
1038  if(status == FSP_SUCCESS)
1039  {
1040  //Point to the beginning of the additional authenticated data
1041  i = 0;
1042 
1043  //Process additional authenticated data
1044  if(aLen >= AES_BLOCK_SIZE)
1045  {
1046  //Process complete blocks only
1047  n = aLen - (aLen % AES_BLOCK_SIZE);
1048 
1049  //Write complete blocks
1050  if(aesContext->nr == 10)
1051  {
1052  HW_SCE_Aes128GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1053  }
1054  else if(aesContext->nr == 12)
1055  {
1056  HW_SCE_Aes192GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1057  }
1058  else
1059  {
1060  HW_SCE_Aes256GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1061  }
1062 
1063  //Advance data pointer
1064  i += n;
1065  }
1066 
1067  //Process final block of additional authenticated data
1068  if(i < aLen)
1069  {
1070  //Copy the partial block
1072  osMemcpy(block, a + i, aLen - i);
1073 
1074  //Write block
1075  if(aesContext->nr == 10)
1076  {
1077  HW_SCE_Aes128GcmDecryptUpdateAADSub(block, 1);
1078  }
1079  else if(aesContext->nr == 12)
1080  {
1081  HW_SCE_Aes192GcmDecryptUpdateAADSub(block, 1);
1082  }
1083  else
1084  {
1085  HW_SCE_Aes256GcmDecryptUpdateAADSub(block, 1);
1086  }
1087  }
1088 
1089  //Transition to from AAD phase to data phase
1090  if(aesContext->nr == 10)
1091  {
1092  HW_SCE_Aes128GcmDecryptUpdateTransitionSub();
1093  }
1094  else if(aesContext->nr == 12)
1095  {
1096  HW_SCE_Aes192GcmDecryptUpdateTransitionSub();
1097  }
1098  else
1099  {
1100  HW_SCE_Aes256GcmDecryptUpdateTransitionSub();
1101  }
1102 
1103  //Point to the beginning of the payload data
1104  i = 0;
1105 
1106  //Process payload data
1107  if(length >= AES_BLOCK_SIZE)
1108  {
1109  //Process complete blocks only
1110  n = length - (length % AES_BLOCK_SIZE);
1111 
1112  //Decrypt complete blocks
1113  if(aesContext->nr == 10)
1114  {
1115  HW_SCE_Aes128GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1116  n / 4);
1117  }
1118  else if(aesContext->nr == 12)
1119  {
1120  HW_SCE_Aes192GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1121  n / 4);
1122  }
1123  else
1124  {
1125  HW_SCE_Aes256GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1126  n / 4);
1127  }
1128 
1129  //Advance data pointer
1130  i += n;
1131  }
1132 
1133  //Process final block of payload data
1134  if(i < length)
1135  {
1136  //Copy the partial input block
1138  osMemcpy(block, c + i, length - i);
1139  }
1140 
1141  //64-bit representation of the length of the payload data
1142  m = length * 8;
1143  temp[0] = htobe32(m >> 32);
1144  temp[1] = htobe32(m);
1145 
1146  //64-bit representation of the length of the additional data
1147  m = aLen * 8;
1148  temp[2] = htobe32(m >> 32);
1149  temp[3] = htobe32(m);
1150 
1151  //32-bit representation of the length of the authentication tag
1152  temp[4] = htobe32(tLen);
1153 
1154  //Pad the authentication tag
1155  osMemset(authTag, 0, sizeof(authTag));
1156  osMemcpy(authTag, t, tLen);
1157 
1158  //Verify authentication tag
1159  if(aesContext->nr == 10)
1160  {
1161  status = HW_SCE_Aes128GcmDecryptFinalSub(block, temp, temp + 2,
1162  authTag, temp + 4, block);
1163  }
1164  else if(aesContext->nr == 12)
1165  {
1166  status = HW_SCE_Aes192GcmDecryptFinalSub(block, temp, temp + 2,
1167  authTag, temp + 4, block);
1168  }
1169  else if(aesContext->nr == 14)
1170  {
1171  status = HW_SCE_Aes256GcmDecryptFinalSub(block, temp, temp + 2,
1172  authTag, temp + 4, block);
1173  }
1174  else
1175  {
1176  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1177  }
1178  }
1179 
1180  //Check status code
1181  if(status == FSP_SUCCESS)
1182  {
1183  //Copy the partial output block
1184  osMemcpy(p + i, block, length - i);
1185  }
1186 
1187  //Release exclusive access to the SCE module
1189 
1190  //Return status code
1191  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1192 }
1193 
1194 #endif
1195 #if (CCM_SUPPORT == ENABLED)
1196 
1197 /**
1198  * @brief Authenticated encryption using CCM
1199  * @param[in] cipher Cipher algorithm
1200  * @param[in] context Cipher algorithm context
1201  * @param[in] n Nonce
1202  * @param[in] nLen Length of the nonce
1203  * @param[in] a Additional authenticated data
1204  * @param[in] aLen Length of the additional data
1205  * @param[in] p Plaintext to be encrypted
1206  * @param[out] c Ciphertext resulting from the encryption
1207  * @param[in] length Total number of data bytes to be encrypted
1208  * @param[out] t MAC resulting from the encryption process
1209  * @param[in] tLen Length of the MAC
1210  * @return Error code
1211  **/
1212 
1213 error_t ccmEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1214  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c,
1215  size_t length, uint8_t *t, size_t tLen)
1216 {
1217  error_t error;
1218  fsp_err_t status;
1219  size_t m;
1220  uint32_t keyType;
1221  uint32_t dataType;
1222  uint32_t command;
1223  uint32_t textLen;
1224  uint32_t headerLen;
1225  uint32_t seqNum;
1226  uint32_t block[4];
1227  uint32_t authTag[4];
1228  uint8_t header[64];
1229  AesContext *aesContext;
1230 
1231  //The SCE module only supports AES cipher algorithm
1232  if(cipher != AES_CIPHER_ALGO)
1233  return ERROR_INVALID_PARAMETER;
1234 
1235  //Make sure the cipher context is valid
1236  if(context == NULL)
1237  return ERROR_INVALID_PARAMETER;
1238 
1239  //Check the length of the additional data
1240  if(aLen > (sizeof(header) - 18))
1241  return ERROR_INVALID_LENGTH;
1242 
1243  //Point to the AES context
1244  aesContext = (AesContext *) context;
1245 
1246  //Initialize parameters
1247  keyType = 0;
1248  dataType = 0;
1249  command = 0;
1250  textLen = htobe32(length);
1251  seqNum = 0;
1252 
1253  //Clear header
1254  osMemset(header, 0, sizeof(header));
1255 
1256  //Format first block B(0)
1257  error = ccmFormatBlock0(length, n, nLen, aLen, tLen, header);
1258  //Invalid parameters?
1259  if(error)
1260  return error;
1261 
1262  //Size of the first block (B0)
1263  headerLen = AES_BLOCK_SIZE;
1264 
1265  //Any additional data?
1266  if(aLen > 0)
1267  {
1268  //The length is encoded as 2 octets
1269  STORE16BE(aLen, header + headerLen);
1270  //Concatenate the associated data A
1271  osMemcpy(header + headerLen + 2, a, aLen);
1272  //Adjust the size of the header
1273  headerLen += 2 + aLen;
1274  }
1275 
1276  //Format initial counter value CTR(0)
1277  ccmFormatCounter0(n, nLen, (uint8_t *) block);
1278 
1279  //Acquire exclusive access to the SCE module
1281 
1282  //Initialize CCM encryption
1283  if(aesContext->nr == 10)
1284  {
1285  status = HW_SCE_Aes128CcmEncryptInitSubGeneral(&keyType, &dataType,
1286  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1287  &seqNum, (headerLen + 3) / 4);
1288  }
1289  else if(aesContext->nr == 12)
1290  {
1291  status = HW_SCE_Aes192CcmEncryptInitSubGeneral(&keyType, &dataType,
1292  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1293  &seqNum, (headerLen + 3) / 4);
1294  }
1295  else if(aesContext->nr == 14)
1296  {
1297  status = HW_SCE_Aes256CcmEncryptInitSubGeneral(&keyType, &dataType,
1298  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1299  &seqNum, (headerLen + 3) / 4);
1300  }
1301  else
1302  {
1303  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1304  }
1305 
1306  //Check status code
1307  if(status == FSP_SUCCESS)
1308  {
1309  //Process payload data
1310  if(length >= AES_BLOCK_SIZE)
1311  {
1312  //Process complete blocks only
1313  m = length - (length % AES_BLOCK_SIZE);
1314 
1315  //Encrypt complete blocks
1316  if(aesContext->nr == 10)
1317  {
1318  HW_SCE_Aes128CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1319  m / 4);
1320  }
1321  else if(aesContext->nr == 12)
1322  {
1323  HW_SCE_Aes192CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1324  m / 4);
1325  }
1326  else
1327  {
1328  HW_SCE_Aes256CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1329  m / 4);
1330  }
1331 
1332  //Advance data pointer
1333  length -= m;
1334  p += m;
1335  c += m;
1336  }
1337 
1338  //Process final block of payload data
1339  if(length > 0)
1340  {
1341  //Copy the partial input block
1343  osMemcpy(block, p, length);
1344  }
1345 
1346  //Generate authentication tag
1347  if(aesContext->nr == 10)
1348  {
1349  status = HW_SCE_Aes128CcmEncryptFinalSubGeneral(block, &textLen,
1350  block, authTag);
1351  }
1352  else if(aesContext->nr == 12)
1353  {
1354  status = HW_SCE_Aes192CcmEncryptFinalSub(block, &textLen, block,
1355  authTag);
1356  }
1357  else if(aesContext->nr == 14)
1358  {
1359  status = HW_SCE_Aes256CcmEncryptFinalSub(block, &textLen, block,
1360  authTag);
1361  }
1362  else
1363  {
1364  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1365  }
1366  }
1367 
1368  //Check status code
1369  if(status == FSP_SUCCESS)
1370  {
1371  //Copy the partial output block
1372  osMemcpy(c, block, length);
1373  //Copy the resulting authentication tag
1374  osMemcpy(t, authTag, tLen);
1375  }
1376 
1377  //Release exclusive access to the SCE module
1379 
1380  //Return status code
1381  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1382 }
1383 
1384 
1385 /**
1386  * @brief Authenticated decryption using CCM
1387  * @param[in] cipher Cipher algorithm
1388  * @param[in] context Cipher algorithm context
1389  * @param[in] n Nonce
1390  * @param[in] nLen Length of the nonce
1391  * @param[in] a Additional authenticated data
1392  * @param[in] aLen Length of the additional data
1393  * @param[in] c Ciphertext to be decrypted
1394  * @param[out] p Plaintext resulting from the decryption
1395  * @param[in] length Total number of data bytes to be decrypted
1396  * @param[in] t MAC to be verified
1397  * @param[in] tLen Length of the MAC
1398  * @return Error code
1399  **/
1400 
1401 error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1402  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p,
1403  size_t length, const uint8_t *t, size_t tLen)
1404 {
1405  error_t error;
1406  fsp_err_t status;
1407  size_t m;
1408  uint32_t keyType;
1409  uint32_t dataType;
1410  uint32_t command;
1411  uint32_t textLen;
1412  uint32_t authTagLen;
1413  uint32_t headerLen;
1414  uint32_t seqNum;
1415  uint32_t block[4];
1416  uint32_t authTag[4];
1417  uint8_t header[64];
1418  AesContext *aesContext;
1419 
1420  //The SCE module only supports AES cipher algorithm
1421  if(cipher != AES_CIPHER_ALGO)
1422  return ERROR_INVALID_PARAMETER;
1423 
1424  //Make sure the cipher context is valid
1425  if(context == NULL)
1426  return ERROR_INVALID_PARAMETER;
1427 
1428  //Check the length of the additional data
1429  if(aLen > (sizeof(header) - 18))
1430  return ERROR_INVALID_LENGTH;
1431 
1432  //Point to the AES context
1433  aesContext = (AesContext *) context;
1434 
1435  //Initialize parameters
1436  keyType = 0;
1437  dataType = 0;
1438  command = 0;
1439  textLen = htobe32(length);
1440  authTagLen = htobe32(tLen);
1441  seqNum = 0;
1442 
1443  //Clear header
1444  osMemset(header, 0, sizeof(header));
1445 
1446  //Format first block B(0)
1447  error = ccmFormatBlock0(length, n, nLen, aLen, tLen, header);
1448  //Invalid parameters?
1449  if(error)
1450  return error;
1451 
1452  //Size of the first block (B0)
1453  headerLen = AES_BLOCK_SIZE;
1454 
1455  //Any additional data?
1456  if(aLen > 0)
1457  {
1458  //The length is encoded as 2 octets
1459  STORE16BE(aLen, header + headerLen);
1460  //Concatenate the associated data A
1461  osMemcpy(header + headerLen + 2, a, aLen);
1462  //Adjust the size of the header
1463  headerLen += 2 + aLen;
1464  }
1465 
1466  //Format initial counter value CTR(0)
1467  ccmFormatCounter0(n, nLen, (uint8_t *) block);
1468 
1469  //Acquire exclusive access to the SCE module
1471 
1472  //Initialize CCM decryption
1473  if(aesContext->nr == 10)
1474  {
1475  status = HW_SCE_Aes128CcmDecryptInitSubGeneral(&keyType, &dataType,
1476  &command, &textLen, &authTagLen, aesContext->ek, block,
1477  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1478  }
1479  else if(aesContext->nr == 12)
1480  {
1481  status = HW_SCE_Aes192CcmDecryptInitSubGeneral(&keyType, &dataType,
1482  &command, &textLen, &authTagLen, aesContext->ek, block,
1483  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1484  }
1485  else if(aesContext->nr == 14)
1486  {
1487  status = HW_SCE_Aes256CcmDecryptInitSubGeneral(&keyType, &dataType,
1488  &command, &textLen, &authTagLen, aesContext->ek, block,
1489  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1490  }
1491  else
1492  {
1493  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1494  }
1495 
1496  //Check status code
1497  if(status == FSP_SUCCESS)
1498  {
1499  //Process payload data
1500  if(length >= AES_BLOCK_SIZE)
1501  {
1502  //Process complete blocks only
1503  m = length - (length % AES_BLOCK_SIZE);
1504 
1505  //Decrypt complete blocks
1506  if(aesContext->nr == 10)
1507  {
1508  HW_SCE_Aes128CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1509  m / 4);
1510  }
1511  else if(aesContext->nr == 12)
1512  {
1513  HW_SCE_Aes192CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1514  m / 4);
1515  }
1516  else
1517  {
1518  HW_SCE_Aes256CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1519  m / 4);
1520  }
1521 
1522  //Advance data pointer
1523  length -= m;
1524  c += m;
1525  p += m;
1526  }
1527 
1528  //Process final block of payload data
1529  if(length > 0)
1530  {
1531  //Copy the partial input block
1533  osMemcpy(block, c, length);
1534  }
1535 
1536  //Pad the authentication tag
1537  osMemset(authTag, 0, sizeof(authTag));
1538  osMemcpy(authTag, t, tLen);
1539 
1540  //Verify authentication tag
1541  if(aesContext->nr == 10)
1542  {
1543  status = HW_SCE_Aes128CcmDecryptFinalSubGeneral(block, &textLen,
1544  authTag, &authTagLen, block);
1545  }
1546  else if(aesContext->nr == 12)
1547  {
1548  status = HW_SCE_Aes192CcmDecryptFinalSub(block, &textLen,
1549  authTag, &authTagLen, block);
1550  }
1551  else if(aesContext->nr == 14)
1552  {
1553  status = HW_SCE_Aes256CcmDecryptFinalSub(block, &textLen,
1554  authTag, &authTagLen, block);
1555  }
1556  else
1557  {
1558  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1559  }
1560  }
1561 
1562  //Check status code
1563  if(status == FSP_SUCCESS)
1564  {
1565  //Copy the partial output block
1566  osMemcpy(p, block, length);
1567  }
1568 
1569  //Release exclusive access to the SCE module
1571 
1572  //Return status code
1573  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1574 }
1575 
1576 #endif
1577 #endif
#define AES_CIPHER_ALGO
Definition: aes.h:45
#define AES_BLOCK_SIZE
Definition: aes.h:43
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
void ccmFormatCounter0(const uint8_t *n, size_t nLen, uint8_t *ctr)
Format initial counter value CTR(0)
Definition: ccm.c:418
Collection of AEAD algorithms.
Block cipher modes of operation.
unsigned int uint_t
Definition: compiler_port.h:50
#define BETOH32(value)
Definition: cpu_endian.h:451
#define LOAD32LE(p)
Definition: cpu_endian.h:203
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
#define htobe32(value)
Definition: cpu_endian.h:446
General definitions for cryptographic algorithms.
Debugging facilities.
uint8_t n
uint8_t o
error_t
Error codes.
Definition: error.h:43
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t iv[]
Definition: ike.h:1502
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t c
Definition: ndp.h:514
uint8_t p
Definition: ndp.h:300
uint8_t m
Definition: ndp.h:304
uint8_t a
Definition: ndp.h:411
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
OsMutex ra6CryptoMutex
Definition: ra6_crypto.c:41
RA6 hardware cryptographic accelerator (SCE7 / SCE9)
error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
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.
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 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 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_t cbcEncrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
CBC encryption.
error_t cbcDecrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
CBC decryption.
void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using AES algorithm.
void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using AES algorithm.
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.
error_t ecbEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *p, uint8_t *c, size_t length)
ECB encryption.
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.
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
error_t ecbDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *c, uint8_t *p, size_t length)
ECB decryption.
RA6 cipher hardware accelerator.
AES algorithm context.
Definition: aes.h:58
uint_t nr
Definition: aes.h:59
uint32_t ek[60]
Definition: aes.h:60
Common interface for encryption algorithms.
Definition: crypto.h:1036
CipherAlgoEncryptBlock encryptBlock
Definition: crypto.h:1044
CipherAlgoDecryptBlock decryptBlock
Definition: crypto.h:1045
size_t blockSize
Definition: crypto.h:1040
GCM context.
Definition: gcm.h:64
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: gcm.h:65
void * cipherContext
Cipher algorithm context.
Definition: gcm.h:66
uint8_t length
Definition: tcp.h:368
uint32_t seqNum
Definition: tcp.h:341
uint16_t block
Definition: tftp_common.h:115