gd32f2xx_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file gd32f2xx_crypto_cipher.c
3  * @brief GD32F2 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 "gd32f20x.h"
36 #include "gd32f20x_cau.h"
37 #include "core/crypto.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (GD32F2XX_CRYPTO_CIPHER_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief CAU module initialization
50  * @return Error code
51  **/
52 
54 {
55  //Enable CAU peripheral clock
56  rcu_periph_clock_enable(RCU_CAU);
57 
58  //Successful processing
59  return NO_ERROR;
60 }
61 
62 
63 #if (DES_SUPPORT == ENABLED)
64 
65 /**
66  * @brief Initialize a DES context using the supplied key
67  * @param[in] context Pointer to the DES context to initialize
68  * @param[in] key Pointer to the key
69  * @param[in] keyLen Length of the key (must be set to 8)
70  * @return Error code
71  **/
72 
73 error_t desInit(DesContext *context, const uint8_t *key, size_t keyLen)
74 {
75  //Check parameters
76  if(context == NULL || key == NULL)
78 
79  //Invalid key length?
80  if(keyLen != 8)
82 
83  //Copy the key
84  osMemcpy(context->ks, key, keyLen);
85 
86  //No error to report
87  return NO_ERROR;
88 }
89 
90 
91 /**
92  * @brief Encrypt a 8-byte block using DES algorithm
93  * @param[in] context Pointer to the DES context
94  * @param[in] input Plaintext block to encrypt
95  * @param[out] output Ciphertext block resulting from encryption
96  **/
97 
98 void desEncryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
99 {
100  cau_text_struct text;
101 
102  //Specify input and output data
103  text.input = (uint8_t *) input;
104  text.output = output;
105  text.in_length = DES_BLOCK_SIZE;
106 
107  //Acquire exclusive access to the CAU module
109  //Perform DES encryption
110  cau_des_ecb(CAU_ENCRYPT, (uint8_t *) context->ks, &text);
111  //Release exclusive access to the CAU module
113 }
114 
115 
116 /**
117  * @brief Decrypt a 8-byte block using DES algorithm
118  * @param[in] context Pointer to the DES context
119  * @param[in] input Ciphertext block to decrypt
120  * @param[out] output Plaintext block resulting from decryption
121  **/
122 
123 void desDecryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
124 {
125  cau_text_struct text;
126 
127  //Specify input and output data
128  text.input = (uint8_t *) input;
129  text.output = output;
130  text.in_length = DES_BLOCK_SIZE;
131 
132  //Acquire exclusive access to the CAU module
134  //Perform DES decryption
135  cau_des_ecb(CAU_DECRYPT, (uint8_t *) context->ks, &text);
136  //Release exclusive access to the CAU module
138 }
139 
140 #endif
141 #if (DES3_SUPPORT == ENABLED)
142 
143 /**
144  * @brief Initialize a Triple DES context using the supplied key
145  * @param[in] context Pointer to the Triple DES context to initialize
146  * @param[in] key Pointer to the key
147  * @param[in] keyLen Length of the key
148  * @return Error code
149  **/
150 
151 error_t des3Init(Des3Context *context, const uint8_t *key, size_t keyLen)
152 {
153  //Check parameters
154  if(context == NULL || key == NULL)
156 
157  //Invalid key length?
158  if(keyLen != 8 && keyLen != 16 && keyLen != 24)
160 
161  //Copy the key
162  osMemcpy(context->k1.ks, key, keyLen);
163 
164  //No error to report
165  return NO_ERROR;
166 }
167 
168 
169 /**
170  * @brief Encrypt a 8-byte block using Triple DES algorithm
171  * @param[in] context Pointer to the Triple DES context
172  * @param[in] input Plaintext block to encrypt
173  * @param[out] output Ciphertext block resulting from encryption
174  **/
175 
176 void des3EncryptBlock(Des3Context *context, const uint8_t *input, uint8_t *output)
177 {
178  cau_text_struct text;
179 
180  //Specify input and output data
181  text.input = (uint8_t *) input;
182  text.output = output;
183  text.in_length = DES3_BLOCK_SIZE;
184 
185  //Acquire exclusive access to the CAU module
187  //Perform 3DES encryption
188  cau_tdes_ecb(CAU_ENCRYPT, (uint8_t *) context->k1.ks, &text);
189  //Release exclusive access to the CAU module
191 }
192 
193 
194 /**
195  * @brief Decrypt a 8-byte block using Triple DES algorithm
196  * @param[in] context Pointer to the Triple DES context
197  * @param[in] input Ciphertext block to decrypt
198  * @param[out] output Plaintext block resulting from decryption
199  **/
200 
201 void des3DecryptBlock(Des3Context *context, const uint8_t *input, uint8_t *output)
202 {
203  cau_text_struct text;
204 
205  //Specify input and output data
206  text.input = (uint8_t *) input;
207  text.output = output;
208  text.in_length = DES3_BLOCK_SIZE;
209 
210  //Acquire exclusive access to the CAU module
212  //Perform 3DES decryption
213  cau_tdes_ecb(CAU_DECRYPT, (uint8_t *) context->k1.ks, &text);
214  //Release exclusive access to the CAU module
216 }
217 
218 #endif
219 #if (AES_SUPPORT == ENABLED)
220 
221 /**
222  * @brief Key expansion
223  * @param[in] context Pointer to the AES context to initialize
224  * @param[in] key Pointer to the key
225  * @param[in] keyLen Length of the key
226  * @return Error code
227  **/
228 
229 error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
230 {
231  //Check parameters
232  if(context == NULL || key == NULL)
234 
235  //Invalid key length?
236  if(keyLen != 16 && keyLen != 24 && keyLen != 32)
238 
239  //Copy the key
240  osMemcpy(context->ek, key, keyLen);
241 
242  //Save the length of the key in bits
243  context->nr = keyLen * 8;
244 
245  //No error to report
246  return NO_ERROR;
247 }
248 
249 
250 /**
251  * @brief Encrypt a 16-byte block using AES algorithm
252  * @param[in] context Pointer to the AES context
253  * @param[in] input Plaintext block to encrypt
254  * @param[out] output Ciphertext block resulting from encryption
255  **/
256 
257 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
258 {
259  cau_text_struct text;
260 
261  //Specify input and output data
262  text.input = (uint8_t *) input;
263  text.output = output;
264  text.in_length = AES_BLOCK_SIZE;
265 
266  //Acquire exclusive access to the CAU module
268  //Perform AES encryption
269  cau_aes_ecb(CAU_ENCRYPT, (uint8_t *) context->ek, context->nr, &text);
270  //Release exclusive access to the CAU module
272 }
273 
274 
275 /**
276  * @brief Decrypt a 16-byte block using AES algorithm
277  * @param[in] context Pointer to the AES context
278  * @param[in] input Ciphertext block to decrypt
279  * @param[out] output Plaintext block resulting from decryption
280  **/
281 
282 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
283 {
284  cau_text_struct text;
285 
286  //Specify input and output data
287  text.input = (uint8_t *) input;
288  text.output = output;
289  text.in_length = AES_BLOCK_SIZE;
290 
291  //Acquire exclusive access to the CAU module
293  //Perform AES decryption
294  cau_aes_ecb(CAU_DECRYPT, (uint8_t *) context->ek, context->nr, &text);
295  //Release exclusive access to the CAU module
297 }
298 
299 #endif
300 #if (ECB_SUPPORT == ENABLED)
301 
302 /**
303  * @brief ECB encryption
304  * @param[in] cipher Cipher algorithm
305  * @param[in] context Cipher algorithm context
306  * @param[in] p Plaintext to be encrypted
307  * @param[out] c Ciphertext resulting from the encryption
308  * @param[in] length Total number of data bytes to be encrypted
309  * @return Error code
310  **/
311 
312 error_t ecbEncrypt(const CipherAlgo *cipher, void *context,
313  const uint8_t *p, uint8_t *c, size_t length)
314 {
315  ErrStatus status;
316  cau_text_struct text;
317 
318  //Initialize status code
319  status = SUCCESS;
320 
321  //Specify input and output data
322  text.input = (uint8_t *) p;
323  text.output = c;
324  text.in_length = length;
325 
326 #if (DES_SUPPORT == ENABLED)
327  //DES cipher algorithm?
328  if(cipher == DES_CIPHER_ALGO)
329  {
330  //Check the length of the payload
331  if(length == 0)
332  {
333  //No data to process
334  }
335  else if((length % DES_BLOCK_SIZE) == 0)
336  {
337  DesContext *desContext;
338 
339  //Point to the DES context
340  desContext = (DesContext *) context;
341 
342  //Acquire exclusive access to the CAU module
344  //Perform DES-ECB encryption
345  status = cau_des_ecb(CAU_ENCRYPT, (uint8_t *) desContext->ks, &text);
346  //Release exclusive access to the CAU module
348  }
349  else
350  {
351  //The length of the payload must be a multiple of the block size
352  status = ERROR;
353  }
354  }
355  else
356 #endif
357 #if (DES3_SUPPORT == ENABLED)
358  //Triple DES cipher algorithm?
359  if(cipher == DES3_CIPHER_ALGO)
360  {
361  //Check the length of the payload
362  if(length == 0)
363  {
364  //No data to process
365  }
366  else if((length % DES3_BLOCK_SIZE) == 0)
367  {
368  Des3Context *des3Context;
369 
370  //Point to the Triple DES context
371  des3Context = (Des3Context *) context;
372 
373  //Acquire exclusive access to the CAU module
375  //Perform 3DES-ECB encryption
376  status = cau_tdes_ecb(CAU_ENCRYPT, (uint8_t *) des3Context->k1.ks, &text);
377  //Release exclusive access to the CAU module
379  }
380  else
381  {
382  //The length of the payload must be a multiple of the block size
383  status = ERROR;
384  }
385  }
386  else
387 #endif
388 #if (AES_SUPPORT == ENABLED)
389  //AES cipher algorithm?
390  if(cipher == AES_CIPHER_ALGO)
391  {
392  //Check the length of the payload
393  if(length == 0)
394  {
395  //No data to process
396  }
397  else if((length % AES_BLOCK_SIZE) == 0)
398  {
399  AesContext *aesContext;
400 
401  //Point to the AES context
402  aesContext = (AesContext *) context;
403 
404  //Acquire exclusive access to the CAU module
406  //Perform AES-ECB encryption
407  status = cau_aes_ecb(CAU_ENCRYPT, (uint8_t *) aesContext->ek,
408  aesContext->nr, &text);
409  //Release exclusive access to the CAU module
411  }
412  else
413  {
414  //The length of the payload must be a multiple of the block size
415  status = ERROR;
416  }
417  }
418  else
419 #endif
420  //Unknown cipher algorithm?
421  {
422  //ECB mode operates in a block-by-block fashion
423  while(length >= cipher->blockSize)
424  {
425  //Encrypt current block
426  cipher->encryptBlock(context, p, c);
427 
428  //Next block
429  p += cipher->blockSize;
430  c += cipher->blockSize;
431  length -= cipher->blockSize;
432  }
433 
434  //The length of the payload must be a multiple of the block size
435  if(length != 0)
436  {
437  status = ERROR;
438  }
439  }
440 
441  //Return status code
442  return (status == SUCCESS) ? NO_ERROR : ERROR_FAILURE;
443 }
444 
445 
446 /**
447  * @brief ECB decryption
448  * @param[in] cipher Cipher algorithm
449  * @param[in] context Cipher algorithm context
450  * @param[in] c Ciphertext to be decrypted
451  * @param[out] p Plaintext resulting from the decryption
452  * @param[in] length Total number of data bytes to be decrypted
453  * @return Error code
454  **/
455 
456 error_t ecbDecrypt(const CipherAlgo *cipher, void *context,
457  const uint8_t *c, uint8_t *p, size_t length)
458 {
459  ErrStatus status;
460  cau_text_struct text;
461 
462  //Initialize status code
463  status = SUCCESS;
464 
465  //Specify input and output data
466  text.input = (uint8_t *) c;
467  text.output = p;
468  text.in_length = length;
469 
470 #if (DES_SUPPORT == ENABLED)
471  //DES cipher algorithm?
472  if(cipher == DES_CIPHER_ALGO)
473  {
474  //Check the length of the payload
475  if(length == 0)
476  {
477  //No data to process
478  }
479  else if((length % DES_BLOCK_SIZE) == 0)
480  {
481  DesContext *desContext;
482 
483  //Point to the DES context
484  desContext = (DesContext *) context;
485 
486  //Acquire exclusive access to the CAU module
488  //Perform DES-ECB decryption
489  status = cau_des_ecb(CAU_DECRYPT, (uint8_t *) desContext->ks, &text);
490  //Release exclusive access to the CAU module
492  }
493  else
494  {
495  //The length of the payload must be a multiple of the block size
496  status = ERROR;
497  }
498  }
499  else
500 #endif
501 #if (DES3_SUPPORT == ENABLED)
502  //Triple DES cipher algorithm?
503  if(cipher == DES3_CIPHER_ALGO)
504  {
505  //Check the length of the payload
506  if(length == 0)
507  {
508  //No data to process
509  }
510  else if((length % DES3_BLOCK_SIZE) == 0)
511  {
512  Des3Context *des3Context;
513 
514  //Point to the Triple DES context
515  des3Context = (Des3Context *) context;
516 
517  //Acquire exclusive access to the CAU module
519  //Perform 3DES-ECB decryption
520  status = cau_tdes_ecb(CAU_DECRYPT, (uint8_t *) des3Context->k1.ks, &text);
521  //Release exclusive access to the CAU module
523  }
524  else
525  {
526  //The length of the payload must be a multiple of the block size
527  status = ERROR;
528  }
529  }
530  else
531 #endif
532 #if (AES_SUPPORT == ENABLED)
533  //AES cipher algorithm?
534  if(cipher == AES_CIPHER_ALGO)
535  {
536  //Check the length of the payload
537  if(length == 0)
538  {
539  //No data to process
540  }
541  else if((length % AES_BLOCK_SIZE) == 0)
542  {
543  AesContext *aesContext;
544 
545  //Point to the AES context
546  aesContext = (AesContext *) context;
547 
548  //Acquire exclusive access to the CAU module
550  //Perform AES-ECB decryption
551  status = cau_aes_ecb(CAU_DECRYPT, (uint8_t *) aesContext->ek,
552  aesContext->nr, &text);
553  //Release exclusive access to the CAU module
555  }
556  else
557  {
558  //The length of the payload must be a multiple of the block size
559  status = ERROR;
560  }
561  }
562  else
563 #endif
564  //Unknown cipher algorithm?
565  {
566  //ECB mode operates in a block-by-block fashion
567  while(length >= cipher->blockSize)
568  {
569  //Decrypt current block
570  cipher->decryptBlock(context, c, p);
571 
572  //Next block
573  c += cipher->blockSize;
574  p += cipher->blockSize;
575  length -= cipher->blockSize;
576  }
577 
578  //The length of the payload must be a multiple of the block size
579  if(length != 0)
580  {
581  status = ERROR;
582  }
583  }
584 
585  //Return status code
586  return (status == SUCCESS) ? NO_ERROR : ERROR_FAILURE;
587 }
588 
589 #endif
590 #if (CBC_SUPPORT == ENABLED)
591 
592 /**
593  * @brief CBC encryption
594  * @param[in] cipher Cipher algorithm
595  * @param[in] context Cipher algorithm context
596  * @param[in,out] iv Initialization vector
597  * @param[in] p Plaintext to be encrypted
598  * @param[out] c Ciphertext resulting from the encryption
599  * @param[in] length Total number of data bytes to be encrypted
600  * @return Error code
601  **/
602 
603 error_t cbcEncrypt(const CipherAlgo *cipher, void *context,
604  uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
605 {
606  ErrStatus status;
607  cau_text_struct text;
608 
609  //Initialize status code
610  status = SUCCESS;
611 
612  //Specify input and output data
613  text.input = (uint8_t *) p;
614  text.output = c;
615  text.in_length = length;
616 
617 #if (DES_SUPPORT == ENABLED)
618  //DES cipher algorithm?
619  if(cipher == DES_CIPHER_ALGO)
620  {
621  //Check the length of the payload
622  if(length == 0)
623  {
624  //No data to process
625  }
626  else if((length % DES_BLOCK_SIZE) == 0)
627  {
628  DesContext *desContext;
629 
630  //Point to the DES context
631  desContext = (DesContext *) context;
632 
633  //Acquire exclusive access to the CAU module
635  //Perform DES-CBC encryption
636  status = cau_des_cbc(CAU_ENCRYPT, (uint8_t *) desContext->ks, iv, &text);
637  //Release exclusive access to the CAU module
639  }
640  else
641  {
642  //The length of the payload must be a multiple of the block size
643  status = ERROR;
644  }
645  }
646  else
647 #endif
648 #if (DES3_SUPPORT == ENABLED)
649  //Triple DES cipher algorithm?
650  if(cipher == DES3_CIPHER_ALGO)
651  {
652  //Check the length of the payload
653  if(length == 0)
654  {
655  //No data to process
656  }
657  else if((length % DES3_BLOCK_SIZE) == 0)
658  {
659  Des3Context *des3Context;
660 
661  //Point to the Triple DES context
662  des3Context = (Des3Context *) context;
663 
664  //Acquire exclusive access to the CAU module
666  //Perform 3DES-ECB encryption
667  status = cau_tdes_cbc(CAU_ENCRYPT, (uint8_t *) des3Context->k1.ks, iv, &text);
668  //Release exclusive access to the CAU module
670  }
671  else
672  {
673  //The length of the payload must be a multiple of the block size
674  status = ERROR;
675  }
676  }
677  else
678 #endif
679 #if (AES_SUPPORT == ENABLED)
680  //AES cipher algorithm?
681  if(cipher == AES_CIPHER_ALGO)
682  {
683  //Check the length of the payload
684  if(length == 0)
685  {
686  //No data to process
687  }
688  else if((length % AES_BLOCK_SIZE) == 0)
689  {
690  AesContext *aesContext;
691 
692  //Point to the AES context
693  aesContext = (AesContext *) context;
694 
695  //Acquire exclusive access to the CAU module
697  //Perform AES-CBC encryption
698  status = cau_aes_cbc(CAU_ENCRYPT, (uint8_t *) aesContext->ek,
699  aesContext->nr, iv, &text);
700  //Release exclusive access to the CAU module
702  }
703  else
704  {
705  //The length of the payload must be a multiple of the block size
706  status = ERROR;
707  }
708  }
709  else
710 #endif
711  //Unknown cipher algorithm?
712  {
713  size_t i;
714 
715  //CBC mode operates in a block-by-block fashion
716  while(length >= cipher->blockSize)
717  {
718  //XOR input block with IV contents
719  for(i = 0; i < cipher->blockSize; i++)
720  {
721  c[i] = p[i] ^ iv[i];
722  }
723 
724  //Encrypt the current block based upon the output of the previous
725  //encryption
726  cipher->encryptBlock(context, c, c);
727 
728  //Update IV with output block contents
729  osMemcpy(iv, c, cipher->blockSize);
730 
731  //Next block
732  p += cipher->blockSize;
733  c += cipher->blockSize;
734  length -= cipher->blockSize;
735  }
736 
737  //The length of the payload must be a multiple of the block size
738  if(length != 0)
739  {
740  status = ERROR;
741  }
742  }
743 
744  //Return status code
745  return (status == SUCCESS) ? NO_ERROR : ERROR_FAILURE;
746 }
747 
748 
749 /**
750  * @brief CBC decryption
751  * @param[in] cipher Cipher algorithm
752  * @param[in] context Cipher algorithm context
753  * @param[in,out] iv Initialization vector
754  * @param[in] c Ciphertext to be decrypted
755  * @param[out] p Plaintext resulting from the decryption
756  * @param[in] length Total number of data bytes to be decrypted
757  * @return Error code
758  **/
759 
760 error_t cbcDecrypt(const CipherAlgo *cipher, void *context,
761  uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
762 {
763  ErrStatus status;
764  cau_text_struct text;
765 
766  //Initialize status code
767  status = SUCCESS;
768 
769  //Specify input and output data
770  text.input = (uint8_t *) c;
771  text.output = p;
772  text.in_length = length;
773 
774 #if (DES_SUPPORT == ENABLED)
775  //DES cipher algorithm?
776  if(cipher == DES_CIPHER_ALGO)
777  {
778  //Check the length of the payload
779  if(length == 0)
780  {
781  //No data to process
782  }
783  else if((length % DES_BLOCK_SIZE) == 0)
784  {
785  DesContext *desContext;
786 
787  //Point to the DES context
788  desContext = (DesContext *) context;
789 
790  //Acquire exclusive access to the CAU module
792  //Perform DES-CBC decryption
793  status = cau_des_cbc(CAU_DECRYPT, (uint8_t *) desContext->ks, iv, &text);
794  //Release exclusive access to the CAU module
796  }
797  else
798  {
799  //The length of the payload must be a multiple of the block size
800  status = ERROR;
801  }
802  }
803  else
804 #endif
805 #if (DES3_SUPPORT == ENABLED)
806  //Triple DES cipher algorithm?
807  if(cipher == DES3_CIPHER_ALGO)
808  {
809  //Check the length of the payload
810  if(length == 0)
811  {
812  //No data to process
813  }
814  else if((length % DES3_BLOCK_SIZE) == 0)
815  {
816  Des3Context *des3Context;
817 
818  //Point to the Triple DES context
819  des3Context = (Des3Context *) context;
820 
821  //Acquire exclusive access to the CAU module
823  //Perform 3DES-ECB decryption
824  status = cau_tdes_cbc(CAU_DECRYPT, (uint8_t *) des3Context->k1.ks, iv, &text);
825  //Release exclusive access to the CAU module
827  }
828  else
829  {
830  //The length of the payload must be a multiple of the block size
831  status = ERROR;
832  }
833  }
834  else
835 #endif
836 #if (AES_SUPPORT == ENABLED)
837  //AES cipher algorithm?
838  if(cipher == AES_CIPHER_ALGO)
839  {
840  //Check the length of the payload
841  if(length == 0)
842  {
843  //No data to process
844  }
845  else if((length % AES_BLOCK_SIZE) == 0)
846  {
847  AesContext *aesContext;
848 
849  //Point to the AES context
850  aesContext = (AesContext *) context;
851 
852  //Acquire exclusive access to the CAU module
854  //Perform AES-CBC decryption
855  status = cau_aes_cbc(CAU_DECRYPT, (uint8_t *) aesContext->ek,
856  aesContext->nr, iv, &text);
857  //Release exclusive access to the CAU module
859  }
860  else
861  {
862  //The length of the payload must be a multiple of the block size
863  status = ERROR;
864  }
865  }
866  else
867 #endif
868  //Unknown cipher algorithm?
869  {
870  size_t i;
871  uint8_t t[16];
872 
873  //CBC mode operates in a block-by-block fashion
874  while(length >= cipher->blockSize)
875  {
876  //Save input block
877  osMemcpy(t, c, cipher->blockSize);
878 
879  //Decrypt the current block
880  cipher->decryptBlock(context, c, p);
881 
882  //XOR output block with IV contents
883  for(i = 0; i < cipher->blockSize; i++)
884  {
885  p[i] ^= iv[i];
886  }
887 
888  //Update IV with input block contents
889  osMemcpy(iv, t, cipher->blockSize);
890 
891  //Next block
892  c += cipher->blockSize;
893  p += cipher->blockSize;
894  length -= cipher->blockSize;
895  }
896 
897  //The length of the payload must be a multiple of the block size
898  if(length != 0)
899  {
900  status = ERROR;
901  }
902  }
903 
904  //Return status code
905  return (status == SUCCESS) ? NO_ERROR : ERROR_FAILURE;
906 }
907 
908 #endif
909 #if (CTR_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
910 
911 /**
912  * @brief CTR encryption
913  * @param[in] cipher Cipher algorithm
914  * @param[in] context Cipher algorithm context
915  * @param[in] m Size in bits of the specific part of the block to be incremented
916  * @param[in,out] t Initial counter block
917  * @param[in] p Plaintext to be encrypted
918  * @param[out] c Ciphertext resulting from the encryption
919  * @param[in] length Total number of data bytes to be encrypted
920  * @return Error code
921  **/
922 
923 error_t ctrEncrypt(const CipherAlgo *cipher, void *context, uint_t m,
924  uint8_t *t, const uint8_t *p, uint8_t *c, size_t length)
925 {
926  ErrStatus status;
927  cau_text_struct text;
928 
929  //Initialize status code
930  status = SUCCESS;
931 
932  //Specify input and output data
933  text.input = (uint8_t *) p;
934  text.output = c;
935  text.in_length = length;
936 
937  //AES cipher algorithm?
938  if(cipher == AES_CIPHER_ALGO)
939  {
940  //Check the value of the parameter
941  if(m == (AES_BLOCK_SIZE * 8))
942  {
943  //Check the length of the payload
944  if(length == 0)
945  {
946  //No data to process
947  }
948  else if((length % AES_BLOCK_SIZE) == 0)
949  {
950  size_t i;
951  size_t j;
952  uint16_t temp;
953  AesContext *aesContext;
954 
955  //Point to the AES context
956  aesContext = (AesContext *) context;
957 
958  //Acquire exclusive access to the CAU module
960  //Perform AES-CTR encryption
961  status = cau_aes_ctr(CAU_ENCRYPT, (uint8_t *) aesContext->ek,
962  aesContext->nr, t, &text);
963  //Release exclusive access to the CAU module
965 
966  //Update counter value
967  for(i = 0; i < length; i += AES_BLOCK_SIZE)
968  {
969  //Standard incrementing function
970  for(temp = 1, j = 1; j <= AES_BLOCK_SIZE; j++)
971  {
972  //Increment the current byte and propagate the carry
973  temp += t[AES_BLOCK_SIZE - j];
974  t[AES_BLOCK_SIZE - j] = temp & 0xFF;
975  temp >>= 8;
976  }
977  }
978  }
979  else
980  {
981  //The length of the payload must be a multiple of the block size
982  status = ERROR;
983  }
984  }
985  else
986  {
987  //The value of the parameter is not valid
988  status = ERROR;
989  }
990  }
991  else
992  {
993  //Check the value of the parameter
994  if((m % 8) == 0 && m <= (cipher->blockSize * 8))
995  {
996  size_t i;
997  size_t n;
998  uint16_t temp;
999  uint8_t o[16];
1000 
1001  //Determine the size, in bytes, of the specific part of the block
1002  //to be incremented
1003  m = m / 8;
1004 
1005  //Process plaintext
1006  while(length > 0)
1007  {
1008  //CTR mode operates in a block-by-block fashion
1009  n = MIN(length, cipher->blockSize);
1010 
1011  //Compute O(j) = CIPH(T(j))
1012  cipher->encryptBlock(context, t, o);
1013 
1014  //Compute C(j) = P(j) XOR T(j)
1015  for(i = 0; i < n; i++)
1016  {
1017  c[i] = p[i] ^ o[i];
1018  }
1019 
1020  //Standard incrementing function
1021  for(temp = 1, i = 1; i <= m; i++)
1022  {
1023  //Increment the current byte and propagate the carry
1024  temp += t[cipher->blockSize - i];
1025  t[cipher->blockSize - i] = temp & 0xFF;
1026  temp >>= 8;
1027  }
1028 
1029  //Next block
1030  p += n;
1031  c += n;
1032  length -= n;
1033  }
1034  }
1035  else
1036  {
1037  //The value of the parameter is not valid
1038  status = ERROR;
1039  }
1040  }
1041 
1042  //Return status code
1043  return (status == SUCCESS) ? NO_ERROR : ERROR_FAILURE;
1044 }
1045 
1046 #endif
1047 #endif
#define AES_CIPHER_ALGO
Definition: aes.h:45
#define AES_BLOCK_SIZE
Definition: aes.h:43
Collection of AEAD algorithms.
Block cipher modes of operation.
unsigned int uint_t
Definition: compiler_port.h:50
General definitions for cryptographic algorithms.
Debugging facilities.
#define DES3_CIPHER_ALGO
Definition: des3.h:46
#define DES3_BLOCK_SIZE
Definition: des3.h:44
#define DES_BLOCK_SIZE
Definition: des.h:43
#define DES_CIPHER_ALGO
Definition: des.h:45
uint8_t n
uint8_t o
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
OsMutex gd32f2xxCryptoMutex
GD32F2 hardware cryptographic accelerator.
void des3DecryptBlock(Des3Context *context, const uint8_t *input, uint8_t *output)
Decrypt a 8-byte block using Triple DES algorithm.
error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
Key expansion.
error_t cauInit(void)
CAU module initialization.
void desDecryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 8-byte block using DES algorithm.
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 des3Init(Des3Context *context, const uint8_t *key, size_t keyLen)
Initialize a Triple DES context using the supplied key.
void des3EncryptBlock(Des3Context *context, const uint8_t *input, uint8_t *output)
Encrypt a 8-byte block using Triple DES algorithm.
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.
void desEncryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 8-byte block using DES algorithm.
error_t ecbEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *p, uint8_t *c, size_t length)
ECB encryption.
error_t desInit(DesContext *context, const uint8_t *key, size_t keyLen)
Initialize a DES context using the supplied key.
error_t ecbDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *c, uint8_t *p, size_t length)
ECB decryption.
GD32F2 cipher hardware accelerator.
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
#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.
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
Triple DES algorithm context.
Definition: des3.h:59
DesContext k1
Definition: des3.h:60
DES algorithm context.
Definition: des.h:58
uint32_t ks[32]
Definition: des.h:59
uint8_t length
Definition: tcp.h:368