sama5d2_crypto_cipher.c
Go to the documentation of this file.
1 /**
2  * @file sama5d2_crypto_cipher.c
3  * @brief SAMA5D2 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 "chip.h"
36 #include "core/crypto.h"
41 #include "aead/aead_algorithms.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (SAMA5D2_CRYPTO_CIPHER_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Encrypt/decrypt a 16-byte block using DES algorithm
50  * @param[in] input Input block to be encrypted/decrypted
51  * @param[out] output Resulting block
52  **/
53 
54 void desProcessDataBlock(const uint8_t *input, uint8_t *output)
55 {
56  uint32_t *p;
57 
58  //Write input block
59  p = (uint32_t *) input;
60  TDES->TDES_IDATAR[0] = p[0];
61  TDES->TDES_IDATAR[1] = p[1];
62 
63  //Start encryption/decryption
64  TDES->TDES_CR = TDES_CR_START;
65 
66  //When processing completes, the DATRDY flag is raised
67  while((TDES->TDES_ISR & TDES_ISR_DATRDY) == 0)
68  {
69  }
70 
71  //Read output block
72  p = (uint32_t *) output;
73  p[0] = TDES->TDES_ODATAR[0];
74  p[1] = TDES->TDES_ODATAR[1];
75 }
76 
77 
78 #if (DES_SUPPORT == ENABLED)
79 
80 /**
81  * @brief Perform DES encryption or decryption
82  * @param[in] context DES algorithm context
83  * @param[in,out] iv Initialization vector
84  * @param[in] input Data to be encrypted/decrypted
85  * @param[out] output Data resulting from the encryption/decryption process
86  * @param[in] length Total number of data bytes to be processed
87  * @param[in] mode Operation mode
88  **/
89 
90 void desProcessData(DesContext *context, uint8_t *iv, const uint8_t *input,
91  uint8_t *output, size_t length, uint32_t mode)
92 {
93  uint32_t *p;
94 
95  //Acquire exclusive access to the TDES module
97 
98  //Perform software reset
99  TDES->TDES_CR = TDES_CR_SWRST;
100 
101  //Set operation mode
102  TDES->TDES_MR = TDES_MR_SMOD_MANUAL_START | TDES_MR_TDESMOD(0) | mode;
103 
104  //Set encryption key
105  TDES->TDES_KEY1WR[0] = context->ks[0];
106  TDES->TDES_KEY1WR[1] = context->ks[1];
107 
108  //Valid initialization vector?
109  if(iv != NULL)
110  {
111  //Set initialization vector
112  p = (uint32_t *) iv;
113  TDES->TDES_IVR[0] = p[0];
114  TDES->TDES_IVR[1] = p[1];
115  }
116 
117  //Process data
118  while(length >= DES_BLOCK_SIZE)
119  {
120  //The data is encrypted block by block
121  desProcessDataBlock(input, output);
122 
123  //Next block
124  input += DES_BLOCK_SIZE;
125  output += DES_BLOCK_SIZE;
127  }
128 
129  //Process final block of data
130  if(length > 0)
131  {
132  uint8_t buffer[DES_BLOCK_SIZE];
133 
134  //Copy input data
135  osMemset(buffer, 0, DES_BLOCK_SIZE);
136  osMemcpy(buffer, input, length);
137 
138  //Encrypt the final block of data
139  desProcessDataBlock(buffer, buffer);
140 
141  //Copy output data
142  osMemcpy(output, buffer, length);
143  }
144 
145  //Release exclusive access to the TDES module
147 }
148 
149 
150 /**
151  * @brief Initialize a DES context using the supplied key
152  * @param[in] context Pointer to the DES context to initialize
153  * @param[in] key Pointer to the key
154  * @param[in] keyLen Length of the key (must be set to 8)
155  * @return Error code
156  **/
157 
158 error_t desInit(DesContext *context, const uint8_t *key, size_t keyLen)
159 {
160  //Check parameters
161  if(context == NULL || key == NULL)
163 
164  //Invalid key length?
165  if(keyLen != 8)
167 
168  //Copy the key
169  osMemcpy(context->ks, key, keyLen);
170 
171  //No error to report
172  return NO_ERROR;
173 }
174 
175 
176 /**
177  * @brief Encrypt a 8-byte block using DES algorithm
178  * @param[in] context Pointer to the DES context
179  * @param[in] input Plaintext block to encrypt
180  * @param[out] output Ciphertext block resulting from encryption
181  **/
182 
183 void desEncryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
184 {
185  //Perform DES encryption
186  desProcessData(context, NULL, input, output, DES_BLOCK_SIZE,
187  TDES_MR_CIPHER | TDES_MR_OPMOD_ECB);
188 }
189 
190 
191 /**
192  * @brief Decrypt a 8-byte block using DES algorithm
193  * @param[in] context Pointer to the DES context
194  * @param[in] input Ciphertext block to decrypt
195  * @param[out] output Plaintext block resulting from decryption
196  **/
197 
198 void desDecryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
199 {
200  //Perform DES decryption
201  desProcessData(context, NULL, input, output, DES_BLOCK_SIZE,
202  TDES_MR_OPMOD_ECB);
203 }
204 
205 #endif
206 #if (DES3_SUPPORT == ENABLED)
207 
208 /**
209  * @brief Perform Triple DES encryption or decryption
210  * @param[in] context DES algorithm context
211  * @param[in,out] iv Initialization vector
212  * @param[in] input Data to be encrypted/decrypted
213  * @param[out] output Data resulting from the encryption/decryption process
214  * @param[in] length Total number of data bytes to be processed
215  * @param[in] mode Operation mode
216  **/
217 
218 void des3ProcessData(Des3Context *context, uint8_t *iv, const uint8_t *input,
219  uint8_t *output, size_t length, uint32_t mode)
220 {
221  uint32_t *p;
222 
223  //Acquire exclusive access to the TDES module
225 
226  //Perform software reset
227  TDES->TDES_CR = TDES_CR_SWRST;
228 
229  //Set operation mode
230  TDES->TDES_MR = TDES_MR_SMOD_MANUAL_START | TDES_MR_TDESMOD(1) | mode;
231 
232  //Set encryption key
233  TDES->TDES_KEY1WR[0] = context->k1.ks[0];
234  TDES->TDES_KEY1WR[1] = context->k1.ks[1];
235  TDES->TDES_KEY2WR[0] = context->k2.ks[0];
236  TDES->TDES_KEY2WR[1] = context->k2.ks[1];
237  TDES->TDES_KEY3WR[0] = context->k3.ks[0];
238  TDES->TDES_KEY3WR[1] = context->k3.ks[1];
239 
240  //Valid initialization vector?
241  if(iv != NULL)
242  {
243  //Set initialization vector
244  p = (uint32_t *) iv;
245  TDES->TDES_IVR[0] = p[0];
246  TDES->TDES_IVR[1] = p[1];
247  }
248 
249  //Process data
250  while(length >= DES3_BLOCK_SIZE)
251  {
252  //The data is encrypted block by block
253  desProcessDataBlock(input, output);
254 
255  //Next block
256  input += DES3_BLOCK_SIZE;
257  output += DES3_BLOCK_SIZE;
259  }
260 
261  //Process final block of data
262  if(length > 0)
263  {
264  uint8_t buffer[DES3_BLOCK_SIZE];
265 
266  //Copy input data
267  osMemset(buffer, 0, DES3_BLOCK_SIZE);
268  osMemcpy(buffer, input, length);
269 
270  //Encrypt the final block of data
271  desProcessDataBlock(buffer, buffer);
272 
273  //Copy output data
274  osMemcpy(output, buffer, length);
275  }
276 
277  //Release exclusive access to the TDES module
279 }
280 
281 
282 /**
283  * @brief Initialize a Triple DES context using the supplied key
284  * @param[in] context Pointer to the Triple DES context to initialize
285  * @param[in] key Pointer to the key
286  * @param[in] keyLen Length of the key
287  * @return Error code
288  **/
289 
290 error_t des3Init(Des3Context *context, const uint8_t *key, size_t keyLen)
291 {
292  //Check parameters
293  if(context == NULL || key == NULL)
295 
296  //Check key length
297  if(keyLen == 8)
298  {
299  //This option provides backward compatibility with DES, because the
300  //first and second DES operations cancel out
301  osMemcpy(context->k1.ks, key, 8);
302  osMemcpy(context->k2.ks, key, 8);
303  osMemcpy(context->k3.ks, key, 8);
304  }
305  else if(keyLen == 16)
306  {
307  //If the key length is 128 bits including parity, the first 8 bytes of the
308  //encoding represent the key used for the two outer DES operations, and
309  //the second 8 bytes represent the key used for the inner DES operation
310  osMemcpy(context->k1.ks, key, 8);
311  osMemcpy(context->k2.ks, key + 8, 8);
312  osMemcpy(context->k3.ks, key, 8);
313  }
314  else if(keyLen == 24)
315  {
316  //If the key length is 192 bits including parity, then 3 independent DES
317  //keys are represented, in the order in which they are used for encryption
318  osMemcpy(context->k1.ks, key, 8);
319  osMemcpy(context->k2.ks, key + 8, 8);
320  osMemcpy(context->k3.ks, key + 16, 8);
321  }
322  else
323  {
324  //The length of the key is not valid
326  }
327 
328  //No error to report
329  return NO_ERROR;
330 }
331 
332 
333 /**
334  * @brief Encrypt a 8-byte block using Triple DES algorithm
335  * @param[in] context Pointer to the Triple DES context
336  * @param[in] input Plaintext block to encrypt
337  * @param[out] output Ciphertext block resulting from encryption
338  **/
339 
340 void des3EncryptBlock(Des3Context *context, const uint8_t *input, uint8_t *output)
341 {
342  //Perform Triple DES encryption
343  des3ProcessData(context, NULL, input, output, DES3_BLOCK_SIZE,
344  TDES_MR_CIPHER | TDES_MR_OPMOD_ECB);
345 }
346 
347 
348 /**
349  * @brief Decrypt a 8-byte block using Triple DES algorithm
350  * @param[in] context Pointer to the Triple DES context
351  * @param[in] input Ciphertext block to decrypt
352  * @param[out] output Plaintext block resulting from decryption
353  **/
354 
355 void des3DecryptBlock(Des3Context *context, const uint8_t *input, uint8_t *output)
356 {
357  //Perform Triple DES decryption
358  des3ProcessData(context, NULL, input, output, DES3_BLOCK_SIZE,
359  TDES_MR_OPMOD_ECB);
360 }
361 
362 #endif
363 #if (XTEA_SUPPORT == ENABLED)
364 
365 /**
366  * @brief Encrypt/decrypt a 16-byte block using XTEA algorithm
367  * @param[in] input Input block to be encrypted/decrypted
368  * @param[out] output Resulting block
369  **/
370 
371 void xteaProcessDataBlock(const uint8_t *input, uint8_t *output)
372 {
373  uint32_t *p;
374 
375  //Write input block
376  p = (uint32_t *) input;
377  TDES->TDES_IDATAR[1] = p[0];
378  TDES->TDES_IDATAR[0] = p[1];
379 
380  //Start encryption/decryption
381  TDES->TDES_CR = TDES_CR_START;
382 
383  //When processing completes, the DATRDY flag is raised
384  while((TDES->TDES_ISR & TDES_ISR_DATRDY) == 0)
385  {
386  }
387 
388  //Read output block
389  p = (uint32_t *) output;
390  p[0] = TDES->TDES_ODATAR[1];
391  p[1] = TDES->TDES_ODATAR[0];
392 }
393 
394 
395 /**
396  * @brief Perform XTEA encryption or decryption
397  * @param[in] context XTEA algorithm context
398  * @param[in,out] iv Initialization vector
399  * @param[in] input Data to be encrypted/decrypted
400  * @param[out] output Data resulting from the encryption/decryption process
401  * @param[in] length Total number of data bytes to be processed
402  * @param[in] mode Operation mode
403  **/
404 
405 void xteaProcessData(XteaContext *context, uint8_t *iv, const uint8_t *input,
406  uint8_t *output, size_t length, uint32_t mode)
407 {
408  uint32_t *p;
409 
410  //Acquire exclusive access to the TDES module
412 
413  //Perform software reset
414  TDES->TDES_CR = TDES_CR_SWRST;
415 
416  //Set operation mode
417  TDES->TDES_MR = TDES_MR_SMOD_MANUAL_START | TDES_MR_TDESMOD(2) | mode;
418 
419  //The number of rounds of XTEA is defined in the TDES_XTEA_RNDR register
420  TDES->TDES_XTEA_RNDR = XTEA_NB_ROUNDS - 1;
421 
422  //Set encryption key
423  TDES->TDES_KEY2WR[1] = context->k[0];
424  TDES->TDES_KEY2WR[0] = context->k[1];
425  TDES->TDES_KEY1WR[1] = context->k[2];
426  TDES->TDES_KEY1WR[0] = context->k[3];
427 
428  //Valid initialization vector?
429  if(iv != NULL)
430  {
431  //Set initialization vector
432  p = (uint32_t *) iv;
433  TDES->TDES_IVR[1] = p[0];
434  TDES->TDES_IVR[0] = p[1];
435  }
436 
437  //Process data
438  while(length >= XTEA_BLOCK_SIZE)
439  {
440  //The data is encrypted block by block
441  xteaProcessDataBlock(input, output);
442 
443  //Next block
444  input += XTEA_BLOCK_SIZE;
445  output += XTEA_BLOCK_SIZE;
447  }
448 
449  //Process final block of data
450  if(length > 0)
451  {
452  uint8_t buffer[XTEA_BLOCK_SIZE];
453 
454  //Copy input data
455  osMemset(buffer, 0, XTEA_BLOCK_SIZE);
456  osMemcpy(buffer, input, length);
457 
458  //Encrypt the final block of data
459  xteaProcessDataBlock(buffer, buffer);
460 
461  //Copy output data
462  osMemcpy(output, buffer, length);
463  }
464 
465  //Release exclusive access to the TDES module
467 }
468 
469 
470 /**
471  * @brief Initialize a XTEA context using the supplied key
472  * @param[in] context Pointer to the XTEA context to initialize
473  * @param[in] key Pointer to the key
474  * @param[in] keyLen Length of the key (must be set to 16)
475  * @return Error code
476  **/
477 
478 error_t xteaInit(XteaContext *context, const uint8_t *key, size_t keyLen)
479 {
480  //Check parameters
481  if(context == NULL || key == NULL)
483 
484  //Invalid key length?
485  if(keyLen != 16)
487 
488  //Copy the key
489  osMemcpy(context->k, key, keyLen);
490 
491  //No error to report
492  return NO_ERROR;
493 }
494 
495 
496 /**
497  * @brief Encrypt a 8-byte block using XTEA algorithm
498  * @param[in] context Pointer to the XTEA context
499  * @param[in] input Plaintext block to encrypt
500  * @param[out] output Ciphertext block resulting from encryption
501  **/
502 
503 void xteaEncryptBlock(XteaContext *context, const uint8_t *input, uint8_t *output)
504 {
505  //Perform XTEA encryption
506  xteaProcessData(context, NULL, input, output, XTEA_BLOCK_SIZE,
507  TDES_MR_CIPHER | TDES_MR_OPMOD_ECB);
508 }
509 
510 
511 /**
512  * @brief Decrypt a 8-byte block using XTEA algorithm
513  * @param[in] context Pointer to the XTEA context
514  * @param[in] input Ciphertext block to decrypt
515  * @param[out] output Plaintext block resulting from decryption
516  **/
517 
518 void xteaDecryptBlock(XteaContext *context, const uint8_t *input, uint8_t *output)
519 {
520  //Perform XTEA decryption
521  xteaProcessData(context, NULL, input, output, XTEA_BLOCK_SIZE,
522  TDES_MR_OPMOD_ECB);
523 }
524 
525 #endif
526 #if (AES_SUPPORT == ENABLED)
527 
528 /**
529  * @brief Load AES key
530  * @param[in] context AES algorithm context
531  **/
532 
533 void aesLoadKey(AesContext *context)
534 {
535  uint32_t temp;
536 
537  //Read mode register
538  temp = AES->AES_MR & ~AES_MR_KEYSIZE_Msk;
539 
540  //Check the length of the key
541  if(context->nr == 10)
542  {
543  //10 rounds are required for 128-bit key
544  AES->AES_MR = temp | AES_MR_KEYSIZE_AES128;
545 
546  //Set the 128-bit encryption key
547  AES->AES_KEYWR[0] = context->ek[0];
548  AES->AES_KEYWR[1] = context->ek[1];
549  AES->AES_KEYWR[2] = context->ek[2];
550  AES->AES_KEYWR[3] = context->ek[3];
551  }
552  else if(context->nr == 12)
553  {
554  //12 rounds are required for 192-bit key
555  AES->AES_MR = temp | AES_MR_KEYSIZE_AES192;
556 
557  //Set the 192-bit encryption key
558  AES->AES_KEYWR[0] = context->ek[0];
559  AES->AES_KEYWR[1] = context->ek[1];
560  AES->AES_KEYWR[2] = context->ek[2];
561  AES->AES_KEYWR[3] = context->ek[3];
562  AES->AES_KEYWR[4] = context->ek[4];
563  AES->AES_KEYWR[5] = context->ek[5];
564  }
565  else
566  {
567  //14 rounds are required for 256-bit key
568  AES->AES_MR = temp | AES_MR_KEYSIZE_AES256;
569 
570  //Set the 256-bit encryption key
571  AES->AES_KEYWR[0] = context->ek[0];
572  AES->AES_KEYWR[1] = context->ek[1];
573  AES->AES_KEYWR[2] = context->ek[2];
574  AES->AES_KEYWR[3] = context->ek[3];
575  AES->AES_KEYWR[4] = context->ek[4];
576  AES->AES_KEYWR[5] = context->ek[5];
577  AES->AES_KEYWR[6] = context->ek[6];
578  AES->AES_KEYWR[7] = context->ek[7];
579  }
580 }
581 
582 
583 /**
584  * @brief Encrypt/decrypt a 16-byte block using AES algorithm
585  * @param[in] input Input block to be encrypted/decrypted
586  * @param[out] output Resulting block
587  **/
588 
589 void aesProcessDataBlock(const uint8_t *input, uint8_t *output)
590 {
591  uint32_t *p;
592 
593  //Write input block
594  p = (uint32_t *) input;
595  AES->AES_IDATAR[0] = p[0];
596  AES->AES_IDATAR[1] = p[1];
597  AES->AES_IDATAR[2] = p[2];
598  AES->AES_IDATAR[3] = p[3];
599 
600  //Start encryption/decryption
601  AES->AES_CR = AES_CR_START;
602 
603  //When processing completes, the DATRDY flag is raised
604  while((AES->AES_ISR & AES_ISR_DATRDY) == 0)
605  {
606  }
607 
608  //Read output block
609  p = (uint32_t *) output;
610  p[0] = AES->AES_ODATAR[0];
611  p[1] = AES->AES_ODATAR[1];
612  p[2] = AES->AES_ODATAR[2];
613  p[3] = AES->AES_ODATAR[3];
614 }
615 
616 
617 /**
618  * @brief Perform AES encryption or decryption
619  * @param[in] context AES algorithm context
620  * @param[in] iv Initialization vector
621  * @param[in] input Data to be encrypted/decrypted
622  * @param[out] output Data resulting from the encryption/decryption process
623  * @param[in] length Total number of data bytes to be processed
624  * @param[in] mode Operation mode
625  **/
626 
627 void aesProcessData(AesContext *context, uint8_t *iv, const uint8_t *input,
628  uint8_t *output, size_t length, uint32_t mode)
629 {
630  uint32_t *p;
631 
632  //Acquire exclusive access to the AES module
634 
635  //Perform software reset
636  AES->AES_CR = AES_CR_SWRST;
637 
638  //Set operation mode
639  AES->AES_MR = AES_MR_SMOD_MANUAL_START | mode;
640  //Set encryption key
641  aesLoadKey(context);
642 
643  //Valid initialization vector?
644  if(iv != NULL)
645  {
646  //Set initialization vector
647  p = (uint32_t *) iv;
648  AES->AES_IVR[0] = p[0];
649  AES->AES_IVR[1] = p[1];
650  AES->AES_IVR[2] = p[2];
651  AES->AES_IVR[3] = p[3];
652  }
653 
654  //Process data
655  while(length >= AES_BLOCK_SIZE)
656  {
657  //The data is encrypted block by block
658  aesProcessDataBlock(input, output);
659 
660  //Next block
661  input += AES_BLOCK_SIZE;
662  output += AES_BLOCK_SIZE;
664  }
665 
666  //Process final block of data
667  if(length > 0)
668  {
669  uint8_t buffer[AES_BLOCK_SIZE];
670 
671  //Copy input data
672  osMemset(buffer, 0, AES_BLOCK_SIZE);
673  osMemcpy(buffer, input, length);
674 
675  //Encrypt the final block of data
676  aesProcessDataBlock(buffer, buffer);
677 
678  //Copy output data
679  osMemcpy(output, buffer, length);
680  }
681 
682  //Release exclusive access to the AES module
684 }
685 
686 
687 /**
688  * @brief Key expansion
689  * @param[in] context Pointer to the AES context to initialize
690  * @param[in] key Pointer to the key
691  * @param[in] keyLen Length of the key
692  * @return Error code
693  **/
694 
695 error_t aesInit(AesContext *context, const uint8_t *key, size_t keyLen)
696 {
697  //Check parameters
698  if(context == NULL || key == NULL)
700 
701  //Check the length of the key
702  if(keyLen == 16)
703  {
704  //10 rounds are required for 128-bit key
705  context->nr = 10;
706  }
707  else if(keyLen == 24)
708  {
709  //12 rounds are required for 192-bit key
710  context->nr = 12;
711  }
712  else if(keyLen == 32)
713  {
714  //14 rounds are required for 256-bit key
715  context->nr = 14;
716  }
717  else
718  {
719  //Report an error
721  }
722 
723  //Copy the original key
724  osMemcpy(context->ek, key, keyLen);
725 
726  //No error to report
727  return NO_ERROR;
728 }
729 
730 
731 /**
732  * @brief Encrypt a 16-byte block using AES algorithm
733  * @param[in] context Pointer to the AES context
734  * @param[in] input Plaintext block to encrypt
735  * @param[out] output Ciphertext block resulting from encryption
736  **/
737 
738 void aesEncryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
739 {
740  //Perform AES encryption
741  aesProcessData(context, NULL, input, output, AES_BLOCK_SIZE, AES_MR_CIPHER |
742  AES_MR_OPMOD_ECB);
743 }
744 
745 
746 /**
747  * @brief Decrypt a 16-byte block using AES algorithm
748  * @param[in] context Pointer to the AES context
749  * @param[in] input Ciphertext block to decrypt
750  * @param[out] output Plaintext block resulting from decryption
751  **/
752 
753 void aesDecryptBlock(AesContext *context, const uint8_t *input, uint8_t *output)
754 {
755  //Perform AES decryption
756  aesProcessData(context, NULL, input, output, AES_BLOCK_SIZE,
757  AES_MR_OPMOD_ECB);
758 }
759 
760 #endif
761 #if (ECB_SUPPORT == ENABLED)
762 
763 /**
764  * @brief ECB encryption
765  * @param[in] cipher Cipher algorithm
766  * @param[in] context Cipher algorithm context
767  * @param[in] p Plaintext to be encrypted
768  * @param[out] c Ciphertext resulting from the encryption
769  * @param[in] length Total number of data bytes to be encrypted
770  * @return Error code
771  **/
772 
773 error_t ecbEncrypt(const CipherAlgo *cipher, void *context,
774  const uint8_t *p, uint8_t *c, size_t length)
775 {
776  error_t error;
777 
778  //Initialize status code
779  error = NO_ERROR;
780 
781 #if (DES_SUPPORT == ENABLED)
782  //DES cipher algorithm?
783  if(cipher == DES_CIPHER_ALGO)
784  {
785  //Check the length of the payload
786  if(length == 0)
787  {
788  //No data to process
789  }
790  else if((length % DES_BLOCK_SIZE) == 0)
791  {
792  //Encrypt payload data
793  desProcessData(context, NULL, p, c, length, TDES_MR_CIPHER |
794  TDES_MR_OPMOD_ECB);
795  }
796  else
797  {
798  //The length of the payload must be a multiple of the block size
799  error = ERROR_INVALID_LENGTH;
800  }
801  }
802  else
803 #endif
804 #if (DES3_SUPPORT == ENABLED)
805  //Triple DES cipher algorithm?
806  if(cipher == DES3_CIPHER_ALGO)
807  {
808  //Check the length of the payload
809  if(length == 0)
810  {
811  //No data to process
812  }
813  else if((length % DES3_BLOCK_SIZE) == 0)
814  {
815  //Encrypt payload data
816  des3ProcessData(context, NULL, p, c, length, TDES_MR_CIPHER |
817  TDES_MR_OPMOD_ECB);
818  }
819  else
820  {
821  //The length of the payload must be a multiple of the block size
822  error = ERROR_INVALID_LENGTH;
823  }
824  }
825  else
826 #endif
827 #if (XTEA_SUPPORT == ENABLED)
828  //XTEA cipher algorithm?
829  if(cipher == XTEA_CIPHER_ALGO)
830  {
831  //Check the length of the payload
832  if(length == 0)
833  {
834  //No data to process
835  }
836  else if((length % XTEA_BLOCK_SIZE) == 0)
837  {
838  //Encrypt payload data
839  xteaProcessData(context, NULL, p, c, length, TDES_MR_CIPHER |
840  TDES_MR_OPMOD_ECB);
841  }
842  else
843  {
844  //The length of the payload must be a multiple of the block size
845  error = ERROR_INVALID_LENGTH;
846  }
847  }
848  else
849 #endif
850 #if (AES_SUPPORT == ENABLED)
851  //AES cipher algorithm?
852  if(cipher == AES_CIPHER_ALGO)
853  {
854  //Check the length of the payload
855  if(length == 0)
856  {
857  //No data to process
858  }
859  else if((length % AES_BLOCK_SIZE) == 0)
860  {
861  //Encrypt payload data
862  aesProcessData(context, NULL, p, c, length, AES_MR_CIPHER |
863  AES_MR_OPMOD_ECB);
864  }
865  else
866  {
867  //The length of the payload must be a multiple of the block size
868  error = ERROR_INVALID_LENGTH;
869  }
870  }
871  else
872 #endif
873  //Unknown cipher algorithm?
874  {
875  //ECB mode operates in a block-by-block fashion
876  while(length >= cipher->blockSize)
877  {
878  //Encrypt current block
879  cipher->encryptBlock(context, p, c);
880 
881  //Next block
882  p += cipher->blockSize;
883  c += cipher->blockSize;
884  length -= cipher->blockSize;
885  }
886 
887  //The length of the payload must be a multiple of the block size
888  if(length != 0)
889  {
890  error = ERROR_INVALID_LENGTH;
891  }
892  }
893 
894  //Return status code
895  return error;
896 }
897 
898 
899 /**
900  * @brief ECB decryption
901  * @param[in] cipher Cipher algorithm
902  * @param[in] context Cipher algorithm context
903  * @param[in] c Ciphertext to be decrypted
904  * @param[out] p Plaintext resulting from the decryption
905  * @param[in] length Total number of data bytes to be decrypted
906  * @return Error code
907  **/
908 
909 error_t ecbDecrypt(const CipherAlgo *cipher, void *context,
910  const uint8_t *c, uint8_t *p, size_t length)
911 {
912  error_t error;
913 
914  //Initialize status code
915  error = NO_ERROR;
916 
917 #if (DES_SUPPORT == ENABLED)
918  //DES cipher algorithm?
919  if(cipher == DES_CIPHER_ALGO)
920  {
921  //Check the length of the payload
922  if(length == 0)
923  {
924  //No data to process
925  }
926  else if((length % DES_BLOCK_SIZE) == 0)
927  {
928  //Decrypt payload data
929  desProcessData(context, NULL, c, p, length, TDES_MR_OPMOD_ECB);
930  }
931  else
932  {
933  //The length of the payload must be a multiple of the block size
934  error = ERROR_INVALID_LENGTH;
935  }
936  }
937  else
938 #endif
939 #if (DES3_SUPPORT == ENABLED)
940  //Triple DES cipher algorithm?
941  if(cipher == DES3_CIPHER_ALGO)
942  {
943  //Check the length of the payload
944  if(length == 0)
945  {
946  //No data to process
947  }
948  else if((length % DES3_BLOCK_SIZE) == 0)
949  {
950  //Decrypt payload data
951  des3ProcessData(context, NULL, c, p, length, TDES_MR_OPMOD_ECB);
952  }
953  else
954  {
955  //The length of the payload must be a multiple of the block size
956  error = ERROR_INVALID_LENGTH;
957  }
958  }
959  else
960 #endif
961 #if (XTEA_SUPPORT == ENABLED)
962  //XTEA cipher algorithm?
963  if(cipher == XTEA_CIPHER_ALGO)
964  {
965  //Check the length of the payload
966  if(length == 0)
967  {
968  //No data to process
969  }
970  else if((length % XTEA_BLOCK_SIZE) == 0)
971  {
972  //Decrypt payload data
973  xteaProcessData(context, NULL, c, p, length, TDES_MR_OPMOD_ECB);
974  }
975  else
976  {
977  //The length of the payload must be a multiple of the block size
978  error = ERROR_INVALID_LENGTH;
979  }
980  }
981  else
982 #endif
983 #if (AES_SUPPORT == ENABLED)
984  //AES cipher algorithm?
985  if(cipher == AES_CIPHER_ALGO)
986  {
987  //Check the length of the payload
988  if(length == 0)
989  {
990  //No data to process
991  }
992  else if((length % AES_BLOCK_SIZE) == 0)
993  {
994  //Decrypt payload data
995  aesProcessData(context, NULL, c, p, length, AES_MR_OPMOD_ECB);
996  }
997  else
998  {
999  //The length of the payload must be a multiple of the block size
1000  error = ERROR_INVALID_LENGTH;
1001  }
1002  }
1003  else
1004 #endif
1005  //Unknown cipher algorithm?
1006  {
1007  //ECB mode operates in a block-by-block fashion
1008  while(length >= cipher->blockSize)
1009  {
1010  //Decrypt current block
1011  cipher->decryptBlock(context, c, p);
1012 
1013  //Next block
1014  c += cipher->blockSize;
1015  p += cipher->blockSize;
1016  length -= cipher->blockSize;
1017  }
1018 
1019  //The length of the payload must be a multiple of the block size
1020  if(length != 0)
1021  {
1022  error = ERROR_INVALID_LENGTH;
1023  }
1024  }
1025 
1026  //Return status code
1027  return error;
1028 }
1029 
1030 #endif
1031 #if (CBC_SUPPORT == ENABLED)
1032 
1033 /**
1034  * @brief CBC encryption
1035  * @param[in] cipher Cipher algorithm
1036  * @param[in] context Cipher algorithm context
1037  * @param[in,out] iv Initialization vector
1038  * @param[in] p Plaintext to be encrypted
1039  * @param[out] c Ciphertext resulting from the encryption
1040  * @param[in] length Total number of data bytes to be encrypted
1041  * @return Error code
1042  **/
1043 
1044 error_t cbcEncrypt(const CipherAlgo *cipher, void *context,
1045  uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
1046 {
1047  error_t error;
1048 
1049  //Initialize status code
1050  error = NO_ERROR;
1051 
1052 #if (DES_SUPPORT == ENABLED)
1053  //DES cipher algorithm?
1054  if(cipher == DES_CIPHER_ALGO)
1055  {
1056  //Check the length of the payload
1057  if(length == 0)
1058  {
1059  //No data to process
1060  }
1061  else if((length % DES_BLOCK_SIZE) == 0)
1062  {
1063  //Encrypt payload data
1064  desProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1065  TDES_MR_OPMOD_CBC);
1066 
1067  //Update the value of the initialization vector
1069  }
1070  else
1071  {
1072  //The length of the payload must be a multiple of the block size
1073  error = ERROR_INVALID_LENGTH;
1074  }
1075  }
1076  else
1077 #endif
1078 #if (DES3_SUPPORT == ENABLED)
1079  //Triple DES cipher algorithm?
1080  if(cipher == DES3_CIPHER_ALGO)
1081  {
1082  //Check the length of the payload
1083  if(length == 0)
1084  {
1085  //No data to process
1086  }
1087  else if((length % DES3_BLOCK_SIZE) == 0)
1088  {
1089  //Encrypt payload data
1090  des3ProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1091  TDES_MR_OPMOD_CBC);
1092 
1093  //Update the value of the initialization vector
1095  }
1096  else
1097  {
1098  //The length of the payload must be a multiple of the block size
1099  error = ERROR_INVALID_LENGTH;
1100  }
1101  }
1102  else
1103 #endif
1104 #if (XTEA_SUPPORT == ENABLED)
1105  //XTEA cipher algorithm?
1106  if(cipher == XTEA_CIPHER_ALGO)
1107  {
1108  //Check the length of the payload
1109  if(length == 0)
1110  {
1111  //No data to process
1112  }
1113  else if((length % XTEA_BLOCK_SIZE) == 0)
1114  {
1115  //Encrypt payload data
1116  xteaProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1117  TDES_MR_OPMOD_CBC);
1118 
1119  //Update the value of the initialization vector
1121  }
1122  else
1123  {
1124  //The length of the payload must be a multiple of the block size
1125  error = ERROR_INVALID_LENGTH;
1126  }
1127  }
1128  else
1129 #endif
1130 #if (AES_SUPPORT == ENABLED)
1131  //AES cipher algorithm?
1132  if(cipher == AES_CIPHER_ALGO)
1133  {
1134  //Check the length of the payload
1135  if(length == 0)
1136  {
1137  //No data to process
1138  }
1139  else if((length % AES_BLOCK_SIZE) == 0)
1140  {
1141  //Encrypt payload data
1142  aesProcessData(context, iv, p, c, length, AES_MR_CIPHER |
1143  AES_MR_OPMOD_CBC);
1144 
1145  //Update the value of the initialization vector
1147  }
1148  else
1149  {
1150  //The length of the payload must be a multiple of the block size
1151  error = ERROR_INVALID_LENGTH;
1152  }
1153  }
1154  else
1155 #endif
1156  //Unknown cipher algorithm?
1157  {
1158  size_t i;
1159 
1160  //CBC mode operates in a block-by-block fashion
1161  while(length >= cipher->blockSize)
1162  {
1163  //XOR input block with IV contents
1164  for(i = 0; i < cipher->blockSize; i++)
1165  {
1166  c[i] = p[i] ^ iv[i];
1167  }
1168 
1169  //Encrypt the current block based upon the output of the previous
1170  //encryption
1171  cipher->encryptBlock(context, c, c);
1172 
1173  //Update IV with output block contents
1174  osMemcpy(iv, c, cipher->blockSize);
1175 
1176  //Next block
1177  p += cipher->blockSize;
1178  c += cipher->blockSize;
1179  length -= cipher->blockSize;
1180  }
1181 
1182  //The length of the payload must be a multiple of the block size
1183  if(length != 0)
1184  {
1185  error = ERROR_INVALID_LENGTH;
1186  }
1187  }
1188 
1189  //Return status code
1190  return error;
1191 }
1192 
1193 
1194 /**
1195  * @brief CBC decryption
1196  * @param[in] cipher Cipher algorithm
1197  * @param[in] context Cipher algorithm context
1198  * @param[in,out] iv Initialization vector
1199  * @param[in] c Ciphertext to be decrypted
1200  * @param[out] p Plaintext resulting from the decryption
1201  * @param[in] length Total number of data bytes to be decrypted
1202  * @return Error code
1203  **/
1204 
1205 error_t cbcDecrypt(const CipherAlgo *cipher, void *context,
1206  uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
1207 {
1208  error_t error;
1209 
1210  //Initialize status code
1211  error = NO_ERROR;
1212 
1213 #if (DES_SUPPORT == ENABLED)
1214  //DES cipher algorithm?
1215  if(cipher == DES_CIPHER_ALGO)
1216  {
1217  //Check the length of the payload
1218  if(length == 0)
1219  {
1220  //No data to process
1221  }
1222  else if((length % DES_BLOCK_SIZE) == 0)
1223  {
1224  uint8_t block[DES_BLOCK_SIZE];
1225 
1226  //Save the last input block
1228 
1229  //Decrypt payload data
1230  desProcessData(context, iv, c, p, length, TDES_MR_OPMOD_CBC);
1231 
1232  //Update the value of the initialization vector
1234  }
1235  else
1236  {
1237  //The length of the payload must be a multiple of the block size
1238  error = ERROR_INVALID_LENGTH;
1239  }
1240  }
1241  else
1242 #endif
1243 #if (DES3_SUPPORT == ENABLED)
1244  //Triple DES cipher algorithm?
1245  if(cipher == DES3_CIPHER_ALGO)
1246  {
1247  //Check the length of the payload
1248  if(length == 0)
1249  {
1250  //No data to process
1251  }
1252  else if((length % DES3_BLOCK_SIZE) == 0)
1253  {
1254  uint8_t block[DES3_BLOCK_SIZE];
1255 
1256  //Save the last input block
1258 
1259  //Decrypt payload data
1260  des3ProcessData(context, iv, c, p, length, TDES_MR_OPMOD_CBC);
1261 
1262  //Update the value of the initialization vector
1264  }
1265  else
1266  {
1267  //The length of the payload must be a multiple of the block size
1268  error = ERROR_INVALID_LENGTH;
1269  }
1270  }
1271  else
1272 #endif
1273 #if (XTEA_SUPPORT == ENABLED)
1274  //XTEA cipher algorithm?
1275  if(cipher == XTEA_CIPHER_ALGO)
1276  {
1277  //Check the length of the payload
1278  if(length == 0)
1279  {
1280  //No data to process
1281  }
1282  else if((length % XTEA_BLOCK_SIZE) == 0)
1283  {
1284  uint8_t block[XTEA_BLOCK_SIZE];
1285 
1286  //Save the last input block
1288 
1289  //Decrypt payload data
1290  xteaProcessData(context, iv, c, p, length, TDES_MR_OPMOD_CBC);
1291 
1292  //Update the value of the initialization vector
1294  }
1295  else
1296  {
1297  //The length of the payload must be a multiple of the block size
1298  error = ERROR_INVALID_LENGTH;
1299  }
1300  }
1301  else
1302 #endif
1303 #if (AES_SUPPORT == ENABLED)
1304  //AES cipher algorithm?
1305  if(cipher == AES_CIPHER_ALGO)
1306  {
1307  //Check the length of the payload
1308  if(length == 0)
1309  {
1310  //No data to process
1311  }
1312  else if((length % AES_BLOCK_SIZE) == 0)
1313  {
1314  uint8_t block[AES_BLOCK_SIZE];
1315 
1316  //Save the last input block
1318 
1319  //Decrypt payload data
1320  aesProcessData(context, iv, c, p, length, AES_MR_OPMOD_CBC);
1321 
1322  //Update the value of the initialization vector
1324  }
1325  else
1326  {
1327  //The length of the payload must be a multiple of the block size
1328  error = ERROR_INVALID_LENGTH;
1329  }
1330  }
1331  else
1332 #endif
1333  //Unknown cipher algorithm?
1334  {
1335  size_t i;
1336  uint8_t t[16];
1337 
1338  //CBC mode operates in a block-by-block fashion
1339  while(length >= cipher->blockSize)
1340  {
1341  //Save input block
1342  osMemcpy(t, c, cipher->blockSize);
1343 
1344  //Decrypt the current block
1345  cipher->decryptBlock(context, c, p);
1346 
1347  //XOR output block with IV contents
1348  for(i = 0; i < cipher->blockSize; i++)
1349  {
1350  p[i] ^= iv[i];
1351  }
1352 
1353  //Update IV with input block contents
1354  osMemcpy(iv, t, cipher->blockSize);
1355 
1356  //Next block
1357  c += cipher->blockSize;
1358  p += cipher->blockSize;
1359  length -= cipher->blockSize;
1360  }
1361 
1362  //The length of the payload must be a multiple of the block size
1363  if(length != 0)
1364  {
1365  error = ERROR_INVALID_LENGTH;
1366  }
1367  }
1368 
1369  //Return status code
1370  return error;
1371 }
1372 
1373 #endif
1374 #if (CFB_SUPPORT == ENABLED)
1375 
1376 /**
1377  * @brief CFB encryption
1378  * @param[in] cipher Cipher algorithm
1379  * @param[in] context Cipher algorithm context
1380  * @param[in] s Size of the plaintext and ciphertext segments
1381  * @param[in,out] iv Initialization vector
1382  * @param[in] p Plaintext to be encrypted
1383  * @param[out] c Ciphertext resulting from the encryption
1384  * @param[in] length Total number of data bytes to be encrypted
1385  * @return Error code
1386  **/
1387 
1388 error_t cfbEncrypt(const CipherAlgo *cipher, void *context, uint_t s,
1389  uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
1390 {
1391  error_t error;
1392 
1393  //Initialize status code
1394  error = NO_ERROR;
1395 
1396 #if (DES_SUPPORT == ENABLED)
1397  //DES cipher algorithm?
1398  if(cipher == DES_CIPHER_ALGO)
1399  {
1400  //Check the value of the parameter
1401  if(s == (DES_BLOCK_SIZE * 8))
1402  {
1403  //Check the length of the payload
1404  if(length > 0)
1405  {
1406  //Encrypt payload data
1407  desProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1408  TDES_MR_OPMOD_CFB | TDES_MR_CFBS_SIZE_64BIT);
1409  }
1410  else
1411  {
1412  //No data to process
1413  }
1414  }
1415  else
1416  {
1417  //The value of the parameter is not valid
1418  error = ERROR_INVALID_PARAMETER;
1419  }
1420  }
1421  else
1422 #endif
1423 #if (DES3_SUPPORT == ENABLED)
1424  //Triple DES cipher algorithm?
1425  if(cipher == DES3_CIPHER_ALGO)
1426  {
1427  //Check the value of the parameter
1428  if(s == (DES3_BLOCK_SIZE * 8))
1429  {
1430  //Check the length of the payload
1431  if(length > 0)
1432  {
1433  //Encrypt payload data
1434  des3ProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1435  TDES_MR_OPMOD_CFB | TDES_MR_CFBS_SIZE_64BIT);
1436  }
1437  else
1438  {
1439  //No data to process
1440  }
1441  }
1442  else
1443  {
1444  //The value of the parameter is not valid
1445  error = ERROR_INVALID_PARAMETER;
1446  }
1447  }
1448  else
1449 #endif
1450 #if (XTEA_SUPPORT == ENABLED)
1451  //XTEA cipher algorithm?
1452  if(cipher == XTEA_CIPHER_ALGO)
1453  {
1454  //Check the value of the parameter
1455  if(s == (XTEA_BLOCK_SIZE * 8))
1456  {
1457  //Check the length of the payload
1458  if(length > 0)
1459  {
1460  //Encrypt payload data
1461  xteaProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1462  TDES_MR_OPMOD_CFB | TDES_MR_CFBS_SIZE_64BIT);
1463  }
1464  else
1465  {
1466  //No data to process
1467  }
1468  }
1469  else
1470  {
1471  //The value of the parameter is not valid
1472  error = ERROR_INVALID_PARAMETER;
1473  }
1474  }
1475  else
1476 #endif
1477 #if (AES_SUPPORT == ENABLED)
1478  //AES cipher algorithm?
1479  if(cipher == AES_CIPHER_ALGO)
1480  {
1481  //Check the value of the parameter
1482  if(s == (AES_BLOCK_SIZE * 8))
1483  {
1484  //Check the length of the payload
1485  if(length > 0)
1486  {
1487  //Encrypt payload data
1488  aesProcessData(context, iv, p, c, length, AES_MR_CIPHER |
1489  AES_MR_OPMOD_CFB | AES_MR_CFBS_SIZE_128BIT);
1490  }
1491  else
1492  {
1493  //No data to process
1494  }
1495  }
1496  else
1497  {
1498  //The value of the parameter is not valid
1499  error = ERROR_INVALID_PARAMETER;
1500  }
1501  }
1502  else
1503 #endif
1504  //Unknown cipher algorithm?
1505  {
1506  //Check the value of the parameter
1507  if((s % 8) == 0 && s >= 1 && s <= (cipher->blockSize * 8))
1508  {
1509  size_t i;
1510  size_t n;
1511  uint8_t o[16];
1512 
1513  //Determine the size, in bytes, of the plaintext and ciphertext segments
1514  s = s / 8;
1515 
1516  //Process each plaintext segment
1517  while(length > 0)
1518  {
1519  //Compute the number of bytes to process at a time
1520  n = MIN(length, s);
1521 
1522  //Compute O(j) = CIPH(I(j))
1523  cipher->encryptBlock(context, iv, o);
1524 
1525  //Compute C(j) = P(j) XOR MSB(O(j))
1526  for(i = 0; i < n; i++)
1527  {
1528  c[i] = p[i] ^ o[i];
1529  }
1530 
1531  //Compute I(j+1) = LSB(I(j)) | C(j)
1532  osMemmove(iv, iv + s, cipher->blockSize - s);
1533  osMemcpy(iv + cipher->blockSize - s, c, s);
1534 
1535  //Next block
1536  p += n;
1537  c += n;
1538  length -= n;
1539  }
1540  }
1541  else
1542  {
1543  //The value of the parameter is not valid
1544  error = ERROR_INVALID_PARAMETER;
1545  }
1546  }
1547 
1548  //Return status code
1549  return error;
1550 }
1551 
1552 
1553 /**
1554  * @brief CFB decryption
1555  * @param[in] cipher Cipher algorithm
1556  * @param[in] context Cipher algorithm context
1557  * @param[in] s Size of the plaintext and ciphertext segments
1558  * @param[in,out] iv Initialization vector
1559  * @param[in] c Ciphertext to be decrypted
1560  * @param[out] p Plaintext resulting from the decryption
1561  * @param[in] length Total number of data bytes to be decrypted
1562  * @return Error code
1563  **/
1564 
1565 error_t cfbDecrypt(const CipherAlgo *cipher, void *context, uint_t s,
1566  uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
1567 {
1568  error_t error;
1569 
1570  //Initialize status code
1571  error = NO_ERROR;
1572 
1573 #if (DES_SUPPORT == ENABLED)
1574  //DES cipher algorithm?
1575  if(cipher == DES_CIPHER_ALGO)
1576  {
1577  //Check the value of the parameter
1578  if(s == (DES_BLOCK_SIZE * 8))
1579  {
1580  //Check the length of the payload
1581  if(length > 0)
1582  {
1583  //Decrypt payload data
1584  desProcessData(context, iv, c, p, length, TDES_MR_OPMOD_CFB |
1585  TDES_MR_CFBS_SIZE_64BIT);
1586  }
1587  else
1588  {
1589  //No data to process
1590  }
1591  }
1592  else
1593  {
1594  //The value of the parameter is not valid
1595  error = ERROR_INVALID_PARAMETER;
1596  }
1597  }
1598  else
1599 #endif
1600 #if (DES3_SUPPORT == ENABLED)
1601  //Triple DES cipher algorithm?
1602  if(cipher == DES3_CIPHER_ALGO)
1603  {
1604  //Check the value of the parameter
1605  if(s == (DES3_BLOCK_SIZE * 8))
1606  {
1607  //Check the length of the payload
1608  if(length > 0)
1609  {
1610  //Decrypt payload data
1611  des3ProcessData(context, iv, c, p, length, TDES_MR_OPMOD_CFB |
1612  TDES_MR_CFBS_SIZE_64BIT);
1613  }
1614  else
1615  {
1616  //No data to process
1617  }
1618  }
1619  else
1620  {
1621  //The value of the parameter is not valid
1622  error = ERROR_INVALID_PARAMETER;
1623  }
1624  }
1625  else
1626 #endif
1627 #if (XTEA_SUPPORT == ENABLED)
1628  //XTEA cipher algorithm?
1629  if(cipher == XTEA_CIPHER_ALGO)
1630  {
1631  //Check the value of the parameter
1632  if(s == (XTEA_BLOCK_SIZE * 8))
1633  {
1634  //Check the length of the payload
1635  if(length > 0)
1636  {
1637  //Decrypt payload data
1638  xteaProcessData(context, iv, c, p, length, TDES_MR_OPMOD_CFB |
1639  TDES_MR_CFBS_SIZE_64BIT);
1640  }
1641  else
1642  {
1643  //No data to process
1644  }
1645  }
1646  else
1647  {
1648  //The value of the parameter is not valid
1649  error = ERROR_INVALID_PARAMETER;
1650  }
1651  }
1652  else
1653 #endif
1654 #if (AES_SUPPORT == ENABLED)
1655  //AES cipher algorithm?
1656  if(cipher == AES_CIPHER_ALGO)
1657  {
1658  //Check the value of the parameter
1659  if(s == (AES_BLOCK_SIZE * 8))
1660  {
1661  //Check the length of the payload
1662  if(length > 0)
1663  {
1664  //Decrypt payload data
1665  aesProcessData(context, iv, c, p, length, AES_MR_OPMOD_CFB |
1666  AES_MR_CFBS_SIZE_128BIT);
1667  }
1668  else
1669  {
1670  //No data to process
1671  }
1672  }
1673  else
1674  {
1675  //The value of the parameter is not valid
1676  error = ERROR_INVALID_PARAMETER;
1677  }
1678  }
1679  else
1680 #endif
1681  //Unknown cipher algorithm?
1682  {
1683  //Check the value of the parameter
1684  if((s % 8) == 0 && s >= 1 && s <= (cipher->blockSize * 8))
1685  {
1686  size_t i;
1687  size_t n;
1688  uint8_t o[16];
1689 
1690  //Determine the size, in bytes, of the plaintext and ciphertext segments
1691  s = s / 8;
1692 
1693  //Process each ciphertext segment
1694  while(length > 0)
1695  {
1696  //Compute the number of bytes to process at a time
1697  n = MIN(length, s);
1698 
1699  //Compute O(j) = CIPH(I(j))
1700  cipher->encryptBlock(context, iv, o);
1701 
1702  //Compute I(j+1) = LSB(I(j)) | C(j)
1703  osMemmove(iv, iv + s, cipher->blockSize - s);
1704  osMemcpy(iv + cipher->blockSize - s, c, s);
1705 
1706  //Compute P(j) = C(j) XOR MSB(O(j))
1707  for(i = 0; i < n; i++)
1708  {
1709  p[i] = c[i] ^ o[i];
1710  }
1711 
1712  //Next block
1713  c += n;
1714  p += n;
1715  length -= n;
1716  }
1717  }
1718  else
1719  {
1720  //The value of the parameter is not valid
1721  error = ERROR_INVALID_PARAMETER;
1722  }
1723  }
1724 
1725  //Return status code
1726  return error;
1727 }
1728 
1729 #endif
1730 #if (OFB_SUPPORT == ENABLED)
1731 
1732 /**
1733  * @brief OFB encryption
1734  * @param[in] cipher Cipher algorithm
1735  * @param[in] context Cipher algorithm context
1736  * @param[in] s Size of the plaintext and ciphertext segments
1737  * @param[in,out] iv Initialization vector
1738  * @param[in] p Plaintext to be encrypted
1739  * @param[out] c Ciphertext resulting from the encryption
1740  * @param[in] length Total number of data bytes to be encrypted
1741  * @return Error code
1742  **/
1743 
1744 error_t ofbEncrypt(const CipherAlgo *cipher, void *context, uint_t s,
1745  uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
1746 {
1747  error_t error;
1748 
1749  //Initialize status code
1750  error = NO_ERROR;
1751 
1752 #if (DES_SUPPORT == ENABLED)
1753  //DES cipher algorithm?
1754  if(cipher == DES_CIPHER_ALGO)
1755  {
1756  //Check the value of the parameter
1757  if(s == (DES_BLOCK_SIZE * 8))
1758  {
1759  //Check the length of the payload
1760  if(length > 0)
1761  {
1762  //Encrypt payload data
1763  desProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1764  TDES_MR_OPMOD_OFB);
1765  }
1766  else
1767  {
1768  //No data to process
1769  }
1770  }
1771  else
1772  {
1773  //The value of the parameter is not valid
1774  error = ERROR_INVALID_PARAMETER;
1775  }
1776  }
1777  else
1778 #endif
1779 #if (DES3_SUPPORT == ENABLED)
1780  //Triple DES cipher algorithm?
1781  if(cipher == DES3_CIPHER_ALGO)
1782  {
1783  //Check the value of the parameter
1784  if(s == (DES3_BLOCK_SIZE * 8))
1785  {
1786  //Check the length of the payload
1787  if(length > 0)
1788  {
1789  //Encrypt payload data
1790  des3ProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1791  TDES_MR_OPMOD_OFB);
1792  }
1793  else
1794  {
1795  //No data to process
1796  }
1797  }
1798  else
1799  {
1800  //The value of the parameter is not valid
1801  error = ERROR_INVALID_PARAMETER;
1802  }
1803  }
1804  else
1805 #endif
1806 #if (XTEA_SUPPORT == ENABLED)
1807  //XTEA cipher algorithm?
1808  if(cipher == XTEA_CIPHER_ALGO)
1809  {
1810  //Check the value of the parameter
1811  if(s == (XTEA_BLOCK_SIZE * 8))
1812  {
1813  //Check the length of the payload
1814  if(length > 0)
1815  {
1816  //Encrypt payload data
1817  xteaProcessData(context, iv, p, c, length, TDES_MR_CIPHER |
1818  TDES_MR_OPMOD_OFB);
1819  }
1820  else
1821  {
1822  //No data to process
1823  }
1824  }
1825  else
1826  {
1827  //The value of the parameter is not valid
1828  error = ERROR_INVALID_PARAMETER;
1829  }
1830  }
1831  else
1832 #endif
1833 #if (AES_SUPPORT == ENABLED)
1834  //AES cipher algorithm?
1835  if(cipher == AES_CIPHER_ALGO)
1836  {
1837  //Check the value of the parameter
1838  if(s == (AES_BLOCK_SIZE * 8))
1839  {
1840  //Check the length of the payload
1841  if(length > 0)
1842  {
1843  //Encrypt payload data
1844  aesProcessData(context, iv, p, c, length, AES_MR_CIPHER |
1845  AES_MR_OPMOD_OFB);
1846  }
1847  else
1848  {
1849  //No data to process
1850  }
1851  }
1852  else
1853  {
1854  //The value of the parameter is not valid
1855  error = ERROR_INVALID_PARAMETER;
1856  }
1857  }
1858  else
1859 #endif
1860  //Unknown cipher algorithm?
1861  {
1862  //Check the value of the parameter
1863  if((s % 8) == 0 && s >= 1 && s <= (cipher->blockSize * 8))
1864  {
1865  size_t i;
1866  size_t n;
1867  uint8_t o[16];
1868 
1869  //Determine the size, in bytes, of the plaintext and ciphertext segments
1870  s = s / 8;
1871 
1872  //Process each plaintext segment
1873  while(length > 0)
1874  {
1875  //Compute the number of bytes to process at a time
1876  n = MIN(length, s);
1877 
1878  //Compute O(j) = CIPH(I(j))
1879  cipher->encryptBlock(context, iv, o);
1880 
1881  //Compute C(j) = P(j) XOR MSB(O(j))
1882  for(i = 0; i < n; i++)
1883  {
1884  c[i] = p[i] ^ o[i];
1885  }
1886 
1887  //Compute I(j+1) = LSB(I(j)) | O(j)
1888  osMemmove(iv, iv + s, cipher->blockSize - s);
1889  osMemcpy(iv + cipher->blockSize - s, o, s);
1890 
1891  //Next block
1892  p += n;
1893  c += n;
1894  length -= n;
1895  }
1896  }
1897  else
1898  {
1899  //The value of the parameter is not valid
1900  error = ERROR_INVALID_PARAMETER;
1901  }
1902  }
1903 
1904  //Return status code
1905  return error;
1906 }
1907 
1908 #endif
1909 #if (GCM_SUPPORT == ENABLED && AES_SUPPORT == ENABLED)
1910 
1911 /**
1912  * @brief Update GHASH value
1913  * @param[in] data Input block of data
1914  **/
1915 
1916 void gcmUpdateGhash(const uint8_t *data)
1917 {
1918  uint32_t *p;
1919 
1920  //Write data block
1921  p = (uint32_t *) data;
1922  AES->AES_IDATAR[0] = p[0];
1923  AES->AES_IDATAR[1] = p[1];
1924  AES->AES_IDATAR[2] = p[2];
1925  AES->AES_IDATAR[3] = p[3];
1926 
1927  //Process data
1928  AES->AES_CR = AES_CR_START;
1929 
1930  //The DATRDY bit indicates when the data have been processed. However, no
1931  //output data are generated when processing AAD
1932  while((AES->AES_ISR & AES_ISR_DATRDY) == 0)
1933  {
1934  }
1935 }
1936 
1937 
1938 /**
1939  * @brief Perform AES-GCM encryption or decryption
1940  * @param[in] context AES algorithm context
1941  * @param[in] iv Initialization vector
1942  * @param[in] a Additional authenticated data
1943  * @param[in] aLen Length of the additional data
1944  * @param[in] input Data to be encrypted/decrypted
1945  * @param[out] output Data resulting from the encryption/decryption process
1946  * @param[in] length Total number of data bytes to be processed
1947  * @param[out] t Authentication tag
1948  * @param[in] mode Operation mode
1949  **/
1950 
1951 void gcmProcessData(AesContext *context, const uint8_t *iv,
1952  const uint8_t *a, size_t aLen, const uint8_t *input, uint8_t *output,
1953  size_t length, uint8_t *t, uint32_t mode)
1954 {
1955  uint32_t temp;
1956  uint8_t buffer[16];
1957 
1958  //Acquire exclusive access to the AES module
1960 
1961  //Perform software reset
1962  AES->AES_CR = AES_CR_SWRST;
1963 
1964  //Check parameters
1965  if(aLen > 0 || length > 0)
1966  {
1967  //Select GCM operation mode
1968  AES->AES_MR |= AES_MR_SMOD_MANUAL_START | AES_MR_OPMOD_GCM |
1969  AES_MR_GTAGEN | mode;
1970 
1971  //Whenever a new key is written to the hardware, the hash subkey is
1972  //automatically generated. The hash subkey generation must be complete
1973  //before doing any other action
1974  aesLoadKey(context);
1975 
1976  //The DATRDY bit of the AES_ISR indicates when the subkey generation is
1977  //complete
1978  while((AES->AES_ISR & AES_ISR_DATRDY) == 0)
1979  {
1980  }
1981 
1982  //When the length of the IV is 96 bits, the padding string is appended to
1983  //the IV to form the pre-counter block
1984  AES->AES_IVR[0] = LOAD32LE(iv);
1985  AES->AES_IVR[1] = LOAD32LE(iv + 4);
1986  AES->AES_IVR[2] = LOAD32LE(iv + 8);
1987  AES->AES_IVR[3] = BETOH32(2);
1988 
1989  //Set AADLEN field in AES_AADLENR and CLEN field in AES_CLENR
1990  AES->AES_AADLENR = aLen;
1991  AES->AES_CLENR = length;
1992 
1993  //Process additional authenticated data
1994  while(aLen > 16)
1995  {
1996  //Additional authenticated data is written block by block
1997  gcmUpdateGhash(a);
1998 
1999  //Next block
2000  a += 16;
2001  aLen -= 16;
2002  }
2003 
2004  //Process final block of additional authenticated data
2005  if(aLen > 0)
2006  {
2007  //Copy partial block
2008  osMemset(buffer, 0, 16);
2009  osMemcpy(buffer, a, aLen);
2010 
2011  //Write the resulting block
2012  gcmUpdateGhash(buffer);
2013  }
2014 
2015  //Process data
2016  while(length >= AES_BLOCK_SIZE)
2017  {
2018  //The data is encrypted block by block
2019  aesProcessDataBlock(input, output);
2020 
2021  //Next block
2022  input += AES_BLOCK_SIZE;
2023  output += AES_BLOCK_SIZE;
2025  }
2026 
2027  //Process final block of data
2028  if(length > 0)
2029  {
2030  //Copy input data
2031  osMemset(buffer, 0, AES_BLOCK_SIZE);
2032  osMemcpy(buffer, input, length);
2033 
2034  //Encrypt the final block of data
2035  aesProcessDataBlock(buffer, buffer);
2036 
2037  //Copy output data
2038  osMemcpy(output, buffer, length);
2039  }
2040 
2041  //Wait for TAGRDY to be set
2042  while((AES->AES_ISR & AES_ISR_TAGRDY) == 0)
2043  {
2044  }
2045 
2046  //Read the value from AES_TAGR registers to obtain the authentication tag
2047  //of the message
2048  temp = AES->AES_TAGR[0];
2049  STORE32LE(temp, t);
2050  temp = AES->AES_TAGR[1];
2051  STORE32LE(temp, t + 4);
2052  temp = AES->AES_TAGR[2];
2053  STORE32LE(temp, t + 8);
2054  temp = AES->AES_TAGR[3];
2055  STORE32LE(temp, t + 12);
2056  }
2057  else
2058  {
2059  //Select CTR operation mode
2060  AES->AES_MR |= AES_MR_SMOD_MANUAL_START | AES_MR_OPMOD_CTR |
2061  AES_MR_CIPHER;
2062 
2063  //Set encryption key
2064  aesLoadKey(context);
2065 
2066  //When the length of the IV is 96 bits, the padding string is appended to
2067  //the IV to form the pre-counter block
2068  AES->AES_IVR[0] = LOAD32LE(iv);
2069  AES->AES_IVR[1] = LOAD32LE(iv + 4);
2070  AES->AES_IVR[2] = LOAD32LE(iv + 8);
2071  AES->AES_IVR[3] = BETOH32(1);
2072 
2073  //Clear data block
2074  osMemset(buffer, 0, AES_BLOCK_SIZE);
2075 
2076  //Generate authentication tag
2077  aesProcessDataBlock(buffer, t);
2078  }
2079 
2080  //Release exclusive access to the AES module
2082 }
2083 
2084 
2085 /**
2086  * @brief Initialize GCM context
2087  * @param[in] context Pointer to the GCM context
2088  * @param[in] cipherAlgo Cipher algorithm
2089  * @param[in] cipherContext Pointer to the cipher algorithm context
2090  * @return Error code
2091  **/
2092 
2093 error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo,
2094  void *cipherContext)
2095 {
2096  //Check parameters
2097  if(context == NULL || cipherContext == NULL)
2098  return ERROR_INVALID_PARAMETER;
2099 
2100  //The CRYP module only supports AES cipher algorithm
2101  if(cipherAlgo != AES_CIPHER_ALGO)
2102  return ERROR_INVALID_PARAMETER;
2103 
2104  //Save cipher algorithm context
2105  context->cipherAlgo = cipherAlgo;
2106  context->cipherContext = cipherContext;
2107 
2108  //Successful initialization
2109  return NO_ERROR;
2110 }
2111 
2112 
2113 /**
2114  * @brief Authenticated encryption using GCM
2115  * @param[in] context Pointer to the GCM context
2116  * @param[in] iv Initialization vector
2117  * @param[in] ivLen Length of the initialization vector
2118  * @param[in] a Additional authenticated data
2119  * @param[in] aLen Length of the additional data
2120  * @param[in] p Plaintext to be encrypted
2121  * @param[out] c Ciphertext resulting from the encryption
2122  * @param[in] length Total number of data bytes to be encrypted
2123  * @param[out] t Authentication tag
2124  * @param[in] tLen Length of the authentication tag
2125  * @return Error code
2126  **/
2127 
2128 error_t gcmEncrypt(GcmContext *context, const uint8_t *iv,
2129  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p,
2130  uint8_t *c, size_t length, uint8_t *t, size_t tLen)
2131 {
2132  uint8_t authTag[16];
2133 
2134  //Make sure the GCM context is valid
2135  if(context == NULL)
2136  return ERROR_INVALID_PARAMETER;
2137 
2138  //Check whether the length of the IV is 96 bits
2139  if(ivLen != 12)
2140  return ERROR_INVALID_LENGTH;
2141 
2142  //Check the length of the authentication tag
2143  if(tLen < 4 || tLen > 16)
2144  return ERROR_INVALID_LENGTH;
2145 
2146  //Perform AES-GCM encryption
2147  gcmProcessData(context->cipherContext, iv, a, aLen, p, c, length,
2148  authTag, AES_MR_CIPHER);
2149 
2150  //Copy the resulting authentication tag
2151  osMemcpy(t, authTag, tLen);
2152 
2153  //Successful processing
2154  return NO_ERROR;
2155 }
2156 
2157 
2158 /**
2159  * @brief Authenticated decryption using GCM
2160  * @param[in] context Pointer to the GCM context
2161  * @param[in] iv Initialization vector
2162  * @param[in] ivLen Length of the initialization vector
2163  * @param[in] a Additional authenticated data
2164  * @param[in] aLen Length of the additional data
2165  * @param[in] c Ciphertext to be decrypted
2166  * @param[out] p Plaintext resulting from the decryption
2167  * @param[in] length Total number of data bytes to be decrypted
2168  * @param[in] t Authentication tag
2169  * @param[in] tLen Length of the authentication tag
2170  * @return Error code
2171  **/
2172 
2173 error_t gcmDecrypt(GcmContext *context, const uint8_t *iv,
2174  size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c,
2175  uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
2176 {
2177  size_t i;
2178  uint8_t mask;
2179  uint8_t authTag[16];
2180 
2181  //Make sure the GCM context is valid
2182  if(context == NULL)
2183  return ERROR_INVALID_PARAMETER;
2184 
2185  //Check whether the length of the IV is 96 bits
2186  if(ivLen != 12)
2187  return ERROR_INVALID_LENGTH;
2188 
2189  //Check the length of the authentication tag
2190  if(tLen < 4 || tLen > 16)
2191  return ERROR_INVALID_LENGTH;
2192 
2193  //Perform AES-GCM decryption
2194  gcmProcessData(context->cipherContext, iv, a, aLen, c, p, length,
2195  authTag, 0);
2196 
2197  //The calculated tag is bitwise compared to the received tag
2198  for(mask = 0, i = 0; i < tLen; i++)
2199  {
2200  mask |= authTag[i] ^ t[i];
2201  }
2202 
2203  //The message is authenticated if and only if the tags match
2204  return (mask == 0) ? NO_ERROR : ERROR_FAILURE;
2205 }
2206 
2207 #endif
2208 #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
#define BETOH32(value)
Definition: cpu_endian.h:451
#define LOAD32LE(p)
Definition: cpu_endian.h:203
#define STORE32LE(a, p)
Definition: cpu_endian.h:279
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_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 data[]
Definition: ethernet.h:222
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 s
Definition: ndp.h:345
uint8_t p
Definition: ndp.h:300
uint8_t a
Definition: ndp.h:411
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemmove(dest, src, length)
Definition: os_port.h:147
#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 sama5d2CryptoMutex
SAMA5D2 hardware cryptographic accelerator.
void des3ProcessData(Des3Context *context, uint8_t *iv, const uint8_t *input, uint8_t *output, size_t length, uint32_t mode)
Perform Triple DES encryption or decryption.
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.
void xteaProcessData(XteaContext *context, uint8_t *iv, const uint8_t *input, uint8_t *output, size_t length, uint32_t mode)
Perform XTEA encryption or decryption.
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.
void aesLoadKey(AesContext *context)
Load AES key.
void xteaProcessDataBlock(const uint8_t *input, uint8_t *output)
Encrypt/decrypt a 16-byte block using XTEA algorithm.
void desDecryptBlock(DesContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 8-byte block using DES algorithm.
void xteaDecryptBlock(XteaContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 8-byte block using XTEA algorithm.
void desProcessDataBlock(const uint8_t *input, uint8_t *output)
Encrypt/decrypt a 16-byte block using DES algorithm.
void aesProcessData(AesContext *context, uint8_t *iv, const uint8_t *input, uint8_t *output, size_t length, uint32_t mode)
Perform AES encryption or decryption.
void gcmProcessData(AesContext *context, const uint8_t *iv, const uint8_t *a, size_t aLen, const uint8_t *input, uint8_t *output, size_t length, uint8_t *t, uint32_t mode)
Perform AES-GCM encryption or decryption.
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 xteaEncryptBlock(XteaContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 8-byte block using XTEA algorithm.
error_t cfbDecrypt(const CipherAlgo *cipher, void *context, uint_t s, uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
CFB decryption.
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.
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.
void desProcessData(DesContext *context, uint8_t *iv, const uint8_t *input, uint8_t *output, size_t length, uint32_t mode)
Perform DES encryption or decryption.
error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
error_t cfbEncrypt(const CipherAlgo *cipher, void *context, uint_t s, uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
CFB encryption.
void aesProcessDataBlock(const uint8_t *input, uint8_t *output)
Encrypt/decrypt a 16-byte block using AES algorithm.
error_t xteaInit(XteaContext *context, const uint8_t *key, size_t keyLen)
Initialize a XTEA context using the supplied key.
void gcmUpdateGhash(const uint8_t *data)
Update GHASH value.
error_t ofbEncrypt(const CipherAlgo *cipher, void *context, uint_t s, uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
OFB 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.
SAMA5D2 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
Triple DES algorithm context.
Definition: des3.h:59
DesContext k2
Definition: des3.h:61
DesContext k3
Definition: des3.h:62
DesContext k1
Definition: des3.h:60
DES algorithm context.
Definition: des.h:58
uint32_t ks[32]
Definition: des.h:59
GCM context.
Definition: gcm.h:64
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: gcm.h:65
void * cipherContext
Cipher algorithm context.
Definition: gcm.h:66
XTEA algorithm context.
Definition: xtea.h:60
uint32_t k[4]
Definition: xtea.h:61
uint8_t length
Definition: tcp.h:368
uint16_t block
Definition: tftp_common.h:115
uint8_t mask
Definition: web_socket.h:319
#define XTEA_BLOCK_SIZE
Definition: xtea.h:43
#define XTEA_CIPHER_ALGO
Definition: xtea.h:47
#define XTEA_NB_ROUNDS
Definition: xtea.h:45