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