ra8_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file ra8_crypto_cipher.c
3  * @brief RA8 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 (RA8_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 RSIP7 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 RSIP7 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 RSIP7 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 RSIP7 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 RSIP7 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 dummy;
759  uint32_t temp[4];
760  uint32_t block[4];
761  uint32_t authTag[4];
762  AesContext *aesContext;
763 
764  //Make sure the GCM context is valid
765  if(context == NULL)
767 
768  //Check whether the length of the IV is 96 bits
769  if(ivLen != 12)
770  return ERROR_INVALID_LENGTH;
771 
772  //Check the length of the authentication tag
773  if(tLen < 4 || tLen > 16)
774  return ERROR_INVALID_LENGTH;
775 
776  //Point to the AES context
777  aesContext = (AesContext *) context->cipherContext;
778 
779  //Set key type
780  keyType = 0;
781  //Dummy parameter
782  dummy = 0;
783 
784  //When the length of the IV is 96 bits, the padding string is appended to
785  //the IV to form the pre-counter block
786  temp[0] = LOAD32LE(iv);
787  temp[1] = LOAD32LE(iv + 4);
788  temp[2] = LOAD32LE(iv + 8);
789  temp[3] = BETOH32(1);
790 
791  //Acquire exclusive access to the RSIP7 module
793 
794  //Initialize GCM encryption
795  if(aesContext->nr == 10)
796  {
797  status = HW_SCE_Aes128GcmEncryptInitSub(&keyType, &dummy, &dummy,
798  aesContext->ek, temp, &dummy);
799  }
800  else if(aesContext->nr == 12)
801  {
802  status = HW_SCE_Aes192GcmEncryptInitSub(aesContext->ek, temp);
803  }
804  else if(aesContext->nr == 14)
805  {
806  status = HW_SCE_Aes256GcmEncryptInitSub(&keyType, aesContext->ek, temp);
807  }
808  else
809  {
810  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
811  }
812 
813  //Check status code
814  if(status == FSP_SUCCESS)
815  {
816  //Point to the beginning of the additional authenticated data
817  i = 0;
818 
819  //Process additional authenticated data
820  if(aLen >= AES_BLOCK_SIZE)
821  {
822  //Process complete blocks only
823  n = aLen - (aLen % AES_BLOCK_SIZE);
824 
825  //Write complete blocks
826  if(aesContext->nr == 10)
827  {
828  HW_SCE_Aes128GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
829  }
830  else if(aesContext->nr == 12)
831  {
832  HW_SCE_Aes192GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
833  }
834  else
835  {
836  HW_SCE_Aes256GcmEncryptUpdateAADSub((uint32_t *) a, n / 4);
837  }
838 
839  //Advance data pointer
840  i += n;
841  }
842 
843  //Process final block of additional authenticated data
844  if(i < aLen)
845  {
846  //Copy the partial block
848  osMemcpy(block, a + i, aLen - i);
849 
850  //Write block
851  if(aesContext->nr == 10)
852  {
853  HW_SCE_Aes128GcmEncryptUpdateAADSub(block, 1);
854  }
855  else if(aesContext->nr == 12)
856  {
857  HW_SCE_Aes192GcmEncryptUpdateAADSub(block, 1);
858  }
859  else
860  {
861  HW_SCE_Aes256GcmEncryptUpdateAADSub(block, 1);
862  }
863  }
864 
865  //Transition to from AAD phase to data phase
866  if(aesContext->nr == 10)
867  {
868  HW_SCE_Aes128GcmEncryptUpdateTransitionSub();
869  }
870  else if(aesContext->nr == 12)
871  {
872  HW_SCE_Aes192GcmEncryptUpdateTransitionSub();
873  }
874  else
875  {
876  HW_SCE_Aes256GcmEncryptUpdateTransitionSub();
877  }
878 
879  //Point to the beginning of the payload data
880  i = 0;
881 
882  //Process payload data
883  if(length >= AES_BLOCK_SIZE)
884  {
885  //Process complete blocks only
886  n = length - (length % AES_BLOCK_SIZE);
887 
888  //Encrypt complete blocks
889  if(aesContext->nr == 10)
890  {
891  HW_SCE_Aes128GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
892  n / 4);
893  }
894  else if(aesContext->nr == 12)
895  {
896  HW_SCE_Aes192GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
897  n / 4);
898  }
899  else
900  {
901  HW_SCE_Aes256GcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
902  n / 4);
903  }
904 
905  //Advance data pointer
906  i += n;
907  }
908 
909  //Process final block of payload data
910  if(i < length)
911  {
912  //Copy the partial input block
914  osMemcpy(block, p + i, length - i);
915  }
916 
917  //64-bit representation of the length of the payload data
918  m = length * 8;
919  temp[0] = htobe32(m >> 32);
920  temp[1] = htobe32(m);
921 
922  //64-bit representation of the length of the additional data
923  m = aLen * 8;
924  temp[2] = htobe32(m >> 32);
925  temp[3] = htobe32(m);
926 
927  //Generate authentication tag
928  if(aesContext->nr == 10)
929  {
930  status = HW_SCE_Aes128GcmEncryptFinalSub(block, temp, temp + 2,
931  block, authTag);
932  }
933  else if(aesContext->nr == 12)
934  {
935  status = HW_SCE_Aes192GcmEncryptFinalSub(block, temp, temp + 2,
936  block, authTag);
937  }
938  else if(aesContext->nr == 14)
939  {
940  status = HW_SCE_Aes256GcmEncryptFinalSub(block, temp, temp + 2,
941  block, authTag);
942  }
943  else
944  {
945  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
946  }
947  }
948 
949  //Check status code
950  if(status == FSP_SUCCESS)
951  {
952  //Copy the partial output block
953  osMemcpy(c + i, block, length - i);
954  //Copy the resulting authentication tag
955  osMemcpy(t, authTag, tLen);
956  }
957 
958  //Release exclusive access to the RSIP7 module
960 
961  //Return status code
962  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
963 }
964 
965 
966 /**
967  * @brief Authenticated decryption using GCM
968  * @param[in] context Pointer to the GCM context
969  * @param[in] iv Initialization vector
970  * @param[in] ivLen Length of the initialization vector
971  * @param[in] a Additional authenticated data
972  * @param[in] aLen Length of the additional data
973  * @param[in] c Ciphertext to be decrypted
974  * @param[out] p Plaintext resulting from the decryption
975  * @param[in] length Total number of data bytes to be decrypted
976  * @param[in] t Authentication tag
977  * @param[in] tLen Length of the authentication tag
978  * @return Error code
979  **/
980 
981 error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
982  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
983  uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
984 {
985  fsp_err_t status;
986  size_t i;
987  size_t n;
988  uint64_t m;
989  uint32_t keyType;
990  uint32_t dummy;
991  uint32_t temp[5];
992  uint32_t block[4];
993  uint32_t authTag[4];
994  AesContext *aesContext;
995 
996  //Make sure the GCM context is valid
997  if(context == NULL)
999 
1000  //Check whether the length of the IV is 96 bits
1001  if(ivLen != 12)
1002  return ERROR_INVALID_LENGTH;
1003 
1004  //Check the length of the authentication tag
1005  if(tLen < 4 || tLen > 16)
1006  return ERROR_INVALID_LENGTH;
1007 
1008  //Point to the AES context
1009  aesContext = (AesContext *) context->cipherContext;
1010 
1011  //Set key type
1012  keyType = 0;
1013  //Dummy parameter
1014  dummy = 0;
1015 
1016  //When the length of the IV is 96 bits, the padding string is appended to
1017  //the IV to form the pre-counter block
1018  temp[0] = LOAD32LE(iv);
1019  temp[1] = LOAD32LE(iv + 4);
1020  temp[2] = LOAD32LE(iv + 8);
1021  temp[3] = BETOH32(1);
1022 
1023  //Acquire exclusive access to the RSIP7 module
1025 
1026  //Initialize GCM decryption
1027  if(aesContext->nr == 10)
1028  {
1029  status = HW_SCE_Aes128GcmDecryptInitSub(&keyType, &dummy, &dummy,
1030  aesContext->ek, temp, &dummy);
1031  }
1032  else if(aesContext->nr == 12)
1033  {
1034  status = HW_SCE_Aes192GcmDecryptInitSub(aesContext->ek, temp);
1035  }
1036  else if(aesContext->nr == 14)
1037  {
1038  status = HW_SCE_Aes256GcmDecryptInitSub(&keyType, aesContext->ek, temp);
1039  }
1040  else
1041  {
1042  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1043  }
1044 
1045  //Check status code
1046  if(status == FSP_SUCCESS)
1047  {
1048  //Point to the beginning of the additional authenticated data
1049  i = 0;
1050 
1051  //Process additional authenticated data
1052  if(aLen >= AES_BLOCK_SIZE)
1053  {
1054  //Process complete blocks only
1055  n = aLen - (aLen % AES_BLOCK_SIZE);
1056 
1057  //Write complete blocks
1058  if(aesContext->nr == 10)
1059  {
1060  HW_SCE_Aes128GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1061  }
1062  else if(aesContext->nr == 12)
1063  {
1064  HW_SCE_Aes192GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1065  }
1066  else
1067  {
1068  HW_SCE_Aes256GcmDecryptUpdateAADSub((uint32_t *) a, n / 4);
1069  }
1070 
1071  //Advance data pointer
1072  i += n;
1073  }
1074 
1075  //Process final block of additional authenticated data
1076  if(i < aLen)
1077  {
1078  //Copy the partial block
1080  osMemcpy(block, a + i, aLen - i);
1081 
1082  //Write block
1083  if(aesContext->nr == 10)
1084  {
1085  HW_SCE_Aes128GcmDecryptUpdateAADSub(block, 1);
1086  }
1087  else if(aesContext->nr == 12)
1088  {
1089  HW_SCE_Aes192GcmDecryptUpdateAADSub(block, 1);
1090  }
1091  else
1092  {
1093  HW_SCE_Aes256GcmDecryptUpdateAADSub(block, 1);
1094  }
1095  }
1096 
1097  //Transition to from AAD phase to data phase
1098  if(aesContext->nr == 10)
1099  {
1100  HW_SCE_Aes128GcmDecryptUpdateTransitionSub();
1101  }
1102  else if(aesContext->nr == 12)
1103  {
1104  HW_SCE_Aes192GcmDecryptUpdateTransitionSub();
1105  }
1106  else
1107  {
1108  HW_SCE_Aes256GcmDecryptUpdateTransitionSub();
1109  }
1110 
1111  //Point to the beginning of the payload data
1112  i = 0;
1113 
1114  //Process payload data
1115  if(length >= AES_BLOCK_SIZE)
1116  {
1117  //Process complete blocks only
1118  n = length - (length % AES_BLOCK_SIZE);
1119 
1120  //Decrypt complete blocks
1121  if(aesContext->nr == 10)
1122  {
1123  HW_SCE_Aes128GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1124  n / 4);
1125  }
1126  else if(aesContext->nr == 12)
1127  {
1128  HW_SCE_Aes192GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1129  n / 4);
1130  }
1131  else
1132  {
1133  HW_SCE_Aes256GcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1134  n / 4);
1135  }
1136 
1137  //Advance data pointer
1138  i += n;
1139  }
1140 
1141  //Process final block of payload data
1142  if(i < length)
1143  {
1144  //Copy the partial input block
1146  osMemcpy(block, c + i, length - i);
1147  }
1148 
1149  //64-bit representation of the length of the payload data
1150  m = length * 8;
1151  temp[0] = htobe32(m >> 32);
1152  temp[1] = htobe32(m);
1153 
1154  //64-bit representation of the length of the additional data
1155  m = aLen * 8;
1156  temp[2] = htobe32(m >> 32);
1157  temp[3] = htobe32(m);
1158 
1159  //32-bit representation of the length of the authentication tag
1160  temp[4] = htobe32(tLen);
1161 
1162  //Pad the authentication tag
1163  osMemset(authTag, 0, sizeof(authTag));
1164  osMemcpy(authTag, t, tLen);
1165 
1166  //Verify authentication tag
1167  if(aesContext->nr == 10)
1168  {
1169  status = HW_SCE_Aes128GcmDecryptFinalSub(block, temp, temp + 2,
1170  authTag, temp + 4, block);
1171  }
1172  else if(aesContext->nr == 12)
1173  {
1174  status = HW_SCE_Aes192GcmDecryptFinalSub(block, temp, temp + 2,
1175  authTag, temp + 4, block);
1176  }
1177  else if(aesContext->nr == 14)
1178  {
1179  status = HW_SCE_Aes256GcmDecryptFinalSub(block, temp, temp + 2,
1180  authTag, temp + 4, block);
1181  }
1182  else
1183  {
1184  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1185  }
1186  }
1187 
1188  //Check status code
1189  if(status == FSP_SUCCESS)
1190  {
1191  //Copy the partial output block
1192  osMemcpy(p + i, block, length - i);
1193  }
1194 
1195  //Release exclusive access to the RSIP7 module
1197 
1198  //Return status code
1199  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1200 }
1201 
1202 #endif
1203 #if (CCM_SUPPORT == ENABLED)
1204 
1205 /**
1206  * @brief Authenticated encryption using CCM
1207  * @param[in] cipher Cipher algorithm
1208  * @param[in] context Cipher algorithm context
1209  * @param[in] n Nonce
1210  * @param[in] nLen Length of the nonce
1211  * @param[in] a Additional authenticated data
1212  * @param[in] aLen Length of the additional data
1213  * @param[in] p Plaintext to be encrypted
1214  * @param[out] c Ciphertext resulting from the encryption
1215  * @param[in] length Total number of data bytes to be encrypted
1216  * @param[out] t MAC resulting from the encryption process
1217  * @param[in] tLen Length of the MAC
1218  * @return Error code
1219  **/
1220 
1221 error_t ccmEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1222  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c,
1223  size_t length, uint8_t *t, size_t tLen)
1224 {
1225  error_t error;
1226  fsp_err_t status;
1227  size_t m;
1228  uint32_t keyType;
1229  uint32_t dataType;
1230  uint32_t command;
1231  uint32_t textLen;
1232  uint32_t headerLen;
1233  uint32_t seqNum;
1234  uint32_t block[4];
1235  uint32_t authTag[4];
1236  uint8_t header[64];
1237  AesContext *aesContext;
1238 
1239  //The RSIP7 module only supports AES cipher algorithm
1240  if(cipher != AES_CIPHER_ALGO)
1241  return ERROR_INVALID_PARAMETER;
1242 
1243  //Make sure the cipher context is valid
1244  if(context == NULL)
1245  return ERROR_INVALID_PARAMETER;
1246 
1247  //Check the length of the additional data
1248  if(aLen > (sizeof(header) - 18))
1249  return ERROR_INVALID_LENGTH;
1250 
1251  //Point to the AES context
1252  aesContext = (AesContext *) context;
1253 
1254  //Initialize parameters
1255  keyType = 0;
1256  dataType = 0;
1257  command = 0;
1258  textLen = htobe32(length);
1259  seqNum = 0;
1260 
1261  //Clear header
1262  osMemset(header, 0, sizeof(header));
1263 
1264  //Format first block B(0)
1265  error = ccmFormatBlock0(length, n, nLen, aLen, tLen, header);
1266  //Invalid parameters?
1267  if(error)
1268  return error;
1269 
1270  //Size of the first block (B0)
1271  headerLen = AES_BLOCK_SIZE;
1272 
1273  //Any additional data?
1274  if(aLen > 0)
1275  {
1276  //The length is encoded as 2 octets
1277  STORE16BE(aLen, header + headerLen);
1278  //Concatenate the associated data A
1279  osMemcpy(header + headerLen + 2, a, aLen);
1280  //Adjust the size of the header
1281  headerLen += 2 + aLen;
1282  }
1283 
1284  //Format initial counter value CTR(0)
1285  ccmFormatCounter0(n, nLen, (uint8_t *) block);
1286 
1287  //Acquire exclusive access to the RSIP7 module
1289 
1290  //Initialize CCM encryption
1291  if(aesContext->nr == 10)
1292  {
1293  status = HW_SCE_Aes128CcmEncryptInitSubGeneral(&keyType, &dataType,
1294  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1295  &seqNum, (headerLen + 3) / 4);
1296  }
1297  else if(aesContext->nr == 12)
1298  {
1299  status = HW_SCE_Aes192CcmEncryptInitSubGeneral(&keyType, &dataType,
1300  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1301  &seqNum, (headerLen + 3) / 4);
1302  }
1303  else if(aesContext->nr == 14)
1304  {
1305  status = HW_SCE_Aes256CcmEncryptInitSubGeneral(&keyType, &dataType,
1306  &command, &textLen, aesContext->ek, block, (uint32_t *) header,
1307  &seqNum, (headerLen + 3) / 4);
1308  }
1309  else
1310  {
1311  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1312  }
1313 
1314  //Check status code
1315  if(status == FSP_SUCCESS)
1316  {
1317  //Process payload data
1318  if(length >= AES_BLOCK_SIZE)
1319  {
1320  //Process complete blocks only
1321  m = length - (length % AES_BLOCK_SIZE);
1322 
1323  //Encrypt complete blocks
1324  if(aesContext->nr == 10)
1325  {
1326  HW_SCE_Aes128CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1327  m / 4);
1328  }
1329  else if(aesContext->nr == 12)
1330  {
1331  HW_SCE_Aes192CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1332  m / 4);
1333  }
1334  else
1335  {
1336  HW_SCE_Aes256CcmEncryptUpdateSub((uint32_t *) p, (uint32_t *) c,
1337  m / 4);
1338  }
1339 
1340  //Advance data pointer
1341  length -= m;
1342  p += m;
1343  c += m;
1344  }
1345 
1346  //Process final block of payload data
1347  if(length > 0)
1348  {
1349  //Copy the partial input block
1351  osMemcpy(block, p, length);
1352  }
1353 
1354  //Generate authentication tag
1355  if(aesContext->nr == 10)
1356  {
1357  status = HW_SCE_Aes128CcmEncryptFinalSubGeneral(block, &textLen,
1358  block, authTag);
1359  }
1360  else if(aesContext->nr == 12)
1361  {
1362  status = HW_SCE_Aes192CcmEncryptFinalSub(block, &textLen, block,
1363  authTag);
1364  }
1365  else if(aesContext->nr == 14)
1366  {
1367  status = HW_SCE_Aes256CcmEncryptFinalSub(block, &textLen, block,
1368  authTag);
1369  }
1370  else
1371  {
1372  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1373  }
1374  }
1375 
1376  //Check status code
1377  if(status == FSP_SUCCESS)
1378  {
1379  //Copy the partial output block
1380  osMemcpy(c, block, length);
1381  //Copy the resulting authentication tag
1382  osMemcpy(t, authTag, tLen);
1383  }
1384 
1385  //Release exclusive access to the RSIP7 module
1387 
1388  //Return status code
1389  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1390 }
1391 
1392 
1393 /**
1394  * @brief Authenticated decryption using CCM
1395  * @param[in] cipher Cipher algorithm
1396  * @param[in] context Cipher algorithm context
1397  * @param[in] n Nonce
1398  * @param[in] nLen Length of the nonce
1399  * @param[in] a Additional authenticated data
1400  * @param[in] aLen Length of the additional data
1401  * @param[in] c Ciphertext to be decrypted
1402  * @param[out] p Plaintext resulting from the decryption
1403  * @param[in] length Total number of data bytes to be decrypted
1404  * @param[in] t MAC to be verified
1405  * @param[in] tLen Length of the MAC
1406  * @return Error code
1407  **/
1408 
1409 error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n,
1410  size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p,
1411  size_t length, const uint8_t *t, size_t tLen)
1412 {
1413  error_t error;
1414  fsp_err_t status;
1415  size_t m;
1416  uint32_t keyType;
1417  uint32_t dataType;
1418  uint32_t command;
1419  uint32_t textLen;
1420  uint32_t authTagLen;
1421  uint32_t headerLen;
1422  uint32_t seqNum;
1423  uint32_t block[4];
1424  uint32_t authTag[4];
1425  uint8_t header[64];
1426  AesContext *aesContext;
1427 
1428  //The RSIP7 module only supports AES cipher algorithm
1429  if(cipher != AES_CIPHER_ALGO)
1430  return ERROR_INVALID_PARAMETER;
1431 
1432  //Make sure the cipher context is valid
1433  if(context == NULL)
1434  return ERROR_INVALID_PARAMETER;
1435 
1436  //Check the length of the additional data
1437  if(aLen > (sizeof(header) - 18))
1438  return ERROR_INVALID_LENGTH;
1439 
1440  //Point to the AES context
1441  aesContext = (AesContext *) context;
1442 
1443  //Initialize parameters
1444  keyType = 0;
1445  dataType = 0;
1446  command = 0;
1447  textLen = htobe32(length);
1448  authTagLen = htobe32(tLen);
1449  seqNum = 0;
1450 
1451  //Clear header
1452  osMemset(header, 0, sizeof(header));
1453 
1454  //Format first block B(0)
1455  error = ccmFormatBlock0(length, n, nLen, aLen, tLen, header);
1456  //Invalid parameters?
1457  if(error)
1458  return error;
1459 
1460  //Size of the first block (B0)
1461  headerLen = AES_BLOCK_SIZE;
1462 
1463  //Any additional data?
1464  if(aLen > 0)
1465  {
1466  //The length is encoded as 2 octets
1467  STORE16BE(aLen, header + headerLen);
1468  //Concatenate the associated data A
1469  osMemcpy(header + headerLen + 2, a, aLen);
1470  //Adjust the size of the header
1471  headerLen += 2 + aLen;
1472  }
1473 
1474  //Format initial counter value CTR(0)
1475  ccmFormatCounter0(n, nLen, (uint8_t *) block);
1476 
1477  //Acquire exclusive access to the RSIP7 module
1479 
1480  //Initialize CCM decryption
1481  if(aesContext->nr == 10)
1482  {
1483  status = HW_SCE_Aes128CcmDecryptInitSubGeneral(&keyType, &dataType,
1484  &command, &textLen, &authTagLen, aesContext->ek, block,
1485  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1486  }
1487  else if(aesContext->nr == 12)
1488  {
1489  status = HW_SCE_Aes192CcmDecryptInitSubGeneral(&keyType, &dataType,
1490  &command, &textLen, &authTagLen, aesContext->ek, block,
1491  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1492  }
1493  else if(aesContext->nr == 14)
1494  {
1495  status = HW_SCE_Aes256CcmDecryptInitSubGeneral(&keyType, &dataType,
1496  &command, &textLen, &authTagLen, aesContext->ek, block,
1497  (uint32_t *) header, &seqNum, (headerLen + 3) / 4);
1498  }
1499  else
1500  {
1501  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1502  }
1503 
1504  //Check status code
1505  if(status == FSP_SUCCESS)
1506  {
1507  //Process payload data
1508  if(length >= AES_BLOCK_SIZE)
1509  {
1510  //Process complete blocks only
1511  m = length - (length % AES_BLOCK_SIZE);
1512 
1513  //Decrypt complete blocks
1514  if(aesContext->nr == 10)
1515  {
1516  HW_SCE_Aes128CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1517  m / 4);
1518  }
1519  else if(aesContext->nr == 12)
1520  {
1521  HW_SCE_Aes192CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1522  m / 4);
1523  }
1524  else
1525  {
1526  HW_SCE_Aes256CcmDecryptUpdateSub((uint32_t *) c, (uint32_t *) p,
1527  m / 4);
1528  }
1529 
1530  //Advance data pointer
1531  length -= m;
1532  c += m;
1533  p += m;
1534  }
1535 
1536  //Process final block of payload data
1537  if(length > 0)
1538  {
1539  //Copy the partial input block
1541  osMemcpy(block, c, length);
1542  }
1543 
1544  //Pad the authentication tag
1545  osMemset(authTag, 0, sizeof(authTag));
1546  osMemcpy(authTag, t, tLen);
1547 
1548  //Verify authentication tag
1549  if(aesContext->nr == 10)
1550  {
1551  status = HW_SCE_Aes128CcmDecryptFinalSubGeneral(block, &textLen,
1552  authTag, &authTagLen, block);
1553  }
1554  else if(aesContext->nr == 12)
1555  {
1556  status = HW_SCE_Aes192CcmDecryptFinalSub(block, &textLen,
1557  authTag, &authTagLen, block);
1558  }
1559  else if(aesContext->nr == 14)
1560  {
1561  status = HW_SCE_Aes256CcmDecryptFinalSub(block, &textLen,
1562  authTag, &authTagLen, block);
1563  }
1564  else
1565  {
1566  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
1567  }
1568  }
1569 
1570  //Check status code
1571  if(status == FSP_SUCCESS)
1572  {
1573  //Copy the partial output block
1574  osMemcpy(p, block, length);
1575  }
1576 
1577  //Release exclusive access to the RSIP7 module
1579 
1580  //Return status code
1581  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1582 }
1583 
1584 #endif
1585 #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 ra8CryptoMutex
Definition: ra8_crypto.c:41
RA8 hardware cryptographic accelerator (RSIP7)
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.
RA8 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