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