EFM32 Happy Gecko Software Documentation  efm32hg-doc-5.1.2
em_aes.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_aes.h"
34 #if defined(AES_COUNT) && (AES_COUNT > 0)
35 
36 #include "em_assert.h"
37 /***************************************************************************/
42 /***************************************************************************/
47 /*******************************************************************************
48  ******************************* DEFINES ***********************************
49  ******************************************************************************/
50 
53 #define AES_BLOCKSIZE 16
54 
57 /*******************************************************************************
58  ************************** GLOBAL FUNCTIONS *******************************
59  ******************************************************************************/
60 
61 /***************************************************************************/
124 void AES_CBC128(uint8_t *out,
125  const uint8_t *in,
126  unsigned int len,
127  const uint8_t *key,
128  const uint8_t *iv,
129  bool encrypt)
130 {
131  int i;
132  uint32_t *_out = (uint32_t *)out;
133  const uint32_t *_in = (const uint32_t *)in;
134  const uint32_t *_key = (const uint32_t *)key;
135  const uint32_t *_iv = (const uint32_t *)iv;
136  /* Need to buffer one block when decrypting in case 'out' replaces 'in' */
137  uint32_t prev[4];
138 
139  EFM_ASSERT(!(len % AES_BLOCKSIZE));
140 
141  /* Number of blocks to process */
142  len /= AES_BLOCKSIZE;
143 
144  #if defined( AES_CTRL_KEYBUFEN )
145  if (key)
146  {
147  /* Load key into high key for key buffer usage */
148  for (i = 3; i >= 0; i--)
149  {
150  AES->KEYHA = __REV(_key[i]);
151  }
152  }
153  #endif
154 
155  if (encrypt)
156  {
157  /* Enable encryption with auto start using XOR */
158  #if defined( AES_CTRL_KEYBUFEN )
159  AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_XORSTART;
160  #else
161  AES->CTRL = AES_CTRL_XORSTART;
162  #endif
163 
164  /* Load initialization vector, since writing to DATA, it will */
165  /* not trigger encryption. */
166  for (i = 3; i >= 0; i--)
167  {
168  AES->DATA = __REV(_iv[i]);
169  }
170 
171  /* Encrypt data */
172  while (len--)
173  {
174  #if !defined( AES_CTRL_KEYBUFEN )
175  /* Load key */
176  for (i = 3; i >= 0; i--)
177  {
178  AES->KEYLA = __REV(_key[i]);
179  }
180  #endif
181 
182  /* Load data and trigger encryption */
183  for (i = 3; i >= 0; i--)
184  {
185  AES->XORDATA = __REV(_in[i]);
186  }
187  _in += 4;
188 
189  /* Wait for completion */
190  while (AES->STATUS & AES_STATUS_RUNNING)
191  ;
192 
193  /* Save encrypted data */
194  for (i = 3; i >= 0; i--)
195  {
196  _out[i] = __REV(AES->DATA);
197  }
198  _out += 4;
199  }
200  }
201  else
202  {
203  /* Select decryption mode */
204  #if defined( AES_CTRL_KEYBUFEN )
205  AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
206  #else
208  #endif
209 
210  /* Copy init vector to previous buffer to avoid special handling */
211  for (i = 0; i < 4; i++)
212  {
213  prev[i] = _iv[i];
214  }
215 
216  /* Decrypt data */
217  while (len--)
218  {
219  #if !defined( AES_CTRL_KEYBUFEN )
220  /* Load key */
221  for (i = 3; i >= 0; i--)
222  {
223  AES->KEYLA = __REV(_key[i]);
224  }
225  #endif
226 
227  /* Load data and trigger decryption */
228  for (i = 3; i >= 0; i--)
229  {
230  AES->DATA = __REV(_in[i]);
231  }
232 
233  /* Wait for completion */
234  while (AES->STATUS & AES_STATUS_RUNNING)
235  ;
236 
237  /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
238  /* (Writing to XORDATA will not trigger encoding, triggering enabled on DATA.) */
239  for (i = 3; i >= 0; i--)
240  {
241  AES->XORDATA = __REV(prev[i]);
242  prev[i] = _in[i];
243  }
244  _in += 4;
245 
246  /* Then fetch decrypted data, we have to do it in a separate loop */
247  /* due to internal auto-shifting of words */
248  for (i = 3; i >= 0; i--)
249  {
250  _out[i] = __REV(AES->DATA);
251  }
252  _out += 4;
253  }
254  }
255 }
256 
257 
258 #if defined( AES_CTRL_AES256 )
259 /***************************************************************************/
289 void AES_CBC256(uint8_t *out,
290  const uint8_t *in,
291  unsigned int len,
292  const uint8_t *key,
293  const uint8_t *iv,
294  bool encrypt)
295 {
296  int i;
297  int j;
298  uint32_t *_out = (uint32_t *)out;
299  const uint32_t *_in = (const uint32_t *)in;
300  const uint32_t *_key = (const uint32_t *)key;
301  const uint32_t *_iv = (const uint32_t *)iv;
302  /* Need to buffer one block when decrypting in case output replaces input */
303  uint32_t prev[4];
304 
305  EFM_ASSERT(!(len % AES_BLOCKSIZE));
306 
307  /* Number of blocks to process */
308  len /= AES_BLOCKSIZE;
309 
310  if (encrypt)
311  {
312  /* Enable encryption with auto start using XOR */
313  AES->CTRL = AES_CTRL_AES256 | AES_CTRL_XORSTART;
314 
315  /* Load initialization vector, since writing to DATA, it will */
316  /* not trigger encryption. */
317  for (i = 3; i >= 0; i--)
318  {
319  AES->DATA = __REV(_iv[i]);
320  }
321 
322  /* Encrypt data */
323  while (len--)
324  {
325  /* Load key and data and trigger encryption */
326  for (i = 3, j = 7; i >= 0; i--, j--)
327  {
328  AES->KEYLA = __REV(_key[j]);
329  AES->KEYHA = __REV(_key[i]);
330  /* Write data last, since will trigger encryption on last iteration */
331  AES->XORDATA = __REV(_in[i]);
332  }
333  _in += 4;
334 
335  /* Wait for completion */
336  while (AES->STATUS & AES_STATUS_RUNNING)
337  ;
338 
339  /* Save encrypted data */
340  for (i = 3; i >= 0; i--)
341  {
342  _out[i] = __REV(AES->DATA);
343  }
344  _out += 4;
345  }
346  }
347  else
348  {
349  /* Select decryption mode */
350  AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
351 
352  /* Copy init vector to previous buffer to avoid special handling */
353  for (i = 0; i < 4; i++)
354  {
355  prev[i] = _iv[i];
356  }
357 
358  /* Decrypt data */
359  while (len--)
360  {
361  /* Load key and data and trigger decryption */
362  for (i = 3, j = 7; i >= 0; i--, j--)
363  {
364  AES->KEYLA = __REV(_key[j]);
365  AES->KEYHA = __REV(_key[i]);
366  /* Write data last, since will trigger encryption on last iteration */
367  AES->DATA = __REV(_in[i]);
368  }
369 
370  /* Wait for completion */
371  while (AES->STATUS & AES_STATUS_RUNNING)
372  ;
373 
374  /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
375  for (i = 3; i >= 0; i--)
376  {
377  AES->XORDATA = __REV(prev[i]);
378  prev[i] = _in[i];
379  }
380  _in += 4;
381 
382  /* Then fetch decrypted data, we have to do it in a separate loop */
383  /* due to internal auto-shifting of words */
384  for (i = 3; i >= 0; i--)
385  {
386  _out[i] = __REV(AES->DATA);
387  }
388  _out += 4;
389  }
390  }
391 }
392 #endif
393 
394 
395 /***************************************************************************/
453 void AES_CFB128(uint8_t *out,
454  const uint8_t *in,
455  unsigned int len,
456  const uint8_t *key,
457  const uint8_t *iv,
458  bool encrypt)
459 {
460  int i;
461  uint32_t *_out = (uint32_t *)out;
462  const uint32_t *_in = (const uint32_t *)in;
463  const uint32_t *_key = (const uint32_t *)key;
464  const uint32_t *_iv = (const uint32_t *)iv;
465  const uint32_t *data;
466  uint32_t tmp[4];
467 
468  EFM_ASSERT(!(len % AES_BLOCKSIZE));
469 
470  #if defined( AES_CTRL_KEYBUFEN )
471  AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
472  #else
473  AES->CTRL = AES_CTRL_DATASTART;
474  #endif
475 
476  #if defined( AES_CTRL_KEYBUFEN )
477  /* Load key into high key for key buffer usage */
478  for (i = 3; i >= 0; i--)
479  {
480  AES->KEYHA = __REV(_key[i]);
481  }
482  #endif
483 
484  /* Encrypt/decrypt data */
485  data = _iv;
486  len /= AES_BLOCKSIZE;
487  while (len--)
488  {
489  #if !defined( AES_CTRL_KEYBUFEN )
490  /* Load key */
491  for (i = 3; i >= 0; i--)
492  {
493  AES->KEYLA = __REV(_key[i]);
494  }
495  #endif
496 
497  /* Load data and trigger encryption */
498  for (i = 3; i >= 0; i--)
499  {
500  AES->DATA = __REV(data[i]);
501  }
502 
503  /* Do some required processing before waiting for completion */
504  if (encrypt)
505  {
506  data = _out;
507  }
508  else
509  {
510  /* Must copy current ciphertext block since it may be overwritten */
511  for (i = 0; i < 4; i++)
512  {
513  tmp[i] = _in[i];
514  }
515  data = tmp;
516  }
517 
518  /* Wait for completion */
519  while (AES->STATUS & AES_STATUS_RUNNING)
520  ;
521 
522  /* Save encrypted/decrypted data */
523  for (i = 3; i >= 0; i--)
524  {
525  _out[i] = __REV(AES->DATA) ^ _in[i];
526  }
527  _out += 4;
528  _in += 4;
529  }
530 }
531 
532 
533 #if defined( AES_CTRL_AES256 )
534 /***************************************************************************/
562 void AES_CFB256(uint8_t *out,
563  const uint8_t *in,
564  unsigned int len,
565  const uint8_t *key,
566  const uint8_t *iv,
567  bool encrypt)
568 {
569  int i;
570  int j;
571  uint32_t *_out = (uint32_t *)out;
572  const uint32_t *_in = (const uint32_t *)in;
573  const uint32_t *_key = (const uint32_t *)key;
574  const uint32_t *_iv = (const uint32_t *)iv;
575  const uint32_t *data;
576  uint32_t tmp[4];
577 
578  EFM_ASSERT(!(len % AES_BLOCKSIZE));
579 
580  /* Select encryption mode */
581  AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
582 
583  /* Encrypt/decrypt data */
584  data = _iv;
585  len /= AES_BLOCKSIZE;
586  while (len--)
587  {
588  /* Load key and block to be encrypted/decrypted */
589  for (i = 3, j = 7; i >= 0; i--, j--)
590  {
591  AES->KEYLA = __REV(_key[j]);
592  AES->KEYHA = __REV(_key[i]);
593  /* Write data last, since will trigger encryption on last iteration */
594  AES->DATA = __REV(data[i]);
595  }
596 
597  /* Do some required processing before waiting for completion */
598  if (encrypt)
599  {
600  data = _out;
601  }
602  else
603  {
604  /* Must copy current ciphertext block since it may be overwritten */
605  for (i = 0; i < 4; i++)
606  {
607  tmp[i] = _in[i];
608  }
609  data = tmp;
610  }
611 
612  while (AES->STATUS & AES_STATUS_RUNNING)
613  ;
614 
615  /* Save encrypted/decrypted data */
616  for (i = 3; i >= 0; i--)
617  {
618  _out[i] = __REV(AES->DATA) ^ _in[i];
619  }
620  _out += 4;
621  _in += 4;
622  }
623 }
624 #endif
625 
626 
627 /***************************************************************************/
687 void AES_CTR128(uint8_t *out,
688  const uint8_t *in,
689  unsigned int len,
690  const uint8_t *key,
691  uint8_t *ctr,
692  AES_CtrFuncPtr_TypeDef ctrFunc)
693 {
694  int i;
695  uint32_t *_out = (uint32_t *)out;
696  const uint32_t *_in = (const uint32_t *)in;
697  const uint32_t *_key = (const uint32_t *)key;
698  uint32_t *_ctr = (uint32_t *)ctr;
699 
700  EFM_ASSERT(!(len % AES_BLOCKSIZE));
701  EFM_ASSERT(ctrFunc);
702 
703  #if defined( AES_CTRL_KEYBUFEN )
704  AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
705  #else
706  AES->CTRL = AES_CTRL_DATASTART;
707  #endif
708 
709  #if defined( AES_CTRL_KEYBUFEN )
710  if (key)
711  {
712  /* Load key into high key for key buffer usage */
713  for (i = 3; i >= 0; i--)
714  {
715  AES->KEYHA = __REV(_key[i]);
716  }
717  }
718  #endif
719 
720  /* Encrypt/decrypt data */
721  len /= AES_BLOCKSIZE;
722  while (len--)
723  {
724  #if !defined( AES_CTRL_KEYBUFEN )
725  /* Load key */
726  for (i = 3; i >= 0; i--)
727  {
728  AES->KEYLA = __REV(_key[i]);
729  }
730  #endif
731 
732  /* Load ctr to be encrypted/decrypted */
733  for (i = 3; i >= 0; i--)
734  {
735  AES->DATA = __REV(_ctr[i]);
736  }
737  /* Increment ctr for next use */
738  ctrFunc(ctr);
739 
740  /* Wait for completion */
741  while (AES->STATUS & AES_STATUS_RUNNING)
742  ;
743 
744  /* Save encrypted/decrypted data */
745  for (i = 3; i >= 0; i--)
746  {
747  _out[i] = __REV(AES->DATA) ^ _in[i];
748  }
749  _out += 4;
750  _in += 4;
751  }
752 }
753 
754 
755 #if defined( AES_CTRL_AES256 )
756 /***************************************************************************/
785 void AES_CTR256(uint8_t *out,
786  const uint8_t *in,
787  unsigned int len,
788  const uint8_t *key,
789  uint8_t *ctr,
790  AES_CtrFuncPtr_TypeDef ctrFunc)
791 {
792  int i;
793  int j;
794  uint32_t *_out = (uint32_t *)out;
795  const uint32_t *_in = (const uint32_t *)in;
796  const uint32_t *_key = (const uint32_t *)key;
797  uint32_t *_ctr = (uint32_t *)ctr;
798 
799  EFM_ASSERT(!(len % AES_BLOCKSIZE));
800  EFM_ASSERT(ctrFunc);
801 
802  /* Select encryption mode, with auto trigger */
803  AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
804 
805  /* Encrypt/decrypt data */
806  len /= AES_BLOCKSIZE;
807  while (len--)
808  {
809  /* Load key and block to be encrypted/decrypted */
810  for (i = 3, j = 7; i >= 0; i--, j--)
811  {
812  AES->KEYLA = __REV(_key[j]);
813  AES->KEYHA = __REV(_key[i]);
814  /* Write data last, since will trigger encryption on last iteration */
815  AES->DATA = __REV(_ctr[i]);
816  }
817  /* Increment ctr for next use */
818  ctrFunc(ctr);
819 
820  /* Wait for completion */
821  while (AES->STATUS & AES_STATUS_RUNNING)
822  ;
823 
824  /* Save encrypted/decrypted data */
825  for (i = 3; i >= 0; i--)
826  {
827  _out[i] = __REV(AES->DATA) ^ _in[i];
828  }
829  _out += 4;
830  _in += 4;
831  }
832 }
833 #endif
834 
835 
836 /***************************************************************************/
850 void AES_CTRUpdate32Bit(uint8_t *ctr)
851 {
852  uint32_t *_ctr = (uint32_t *)ctr;
853 
854  _ctr[3] = __REV(__REV(_ctr[3]) + 1);
855 }
856 
857 
858 /***************************************************************************/
873 void AES_DecryptKey128(uint8_t *out, const uint8_t *in)
874 {
875  int i;
876  uint32_t *_out = (uint32_t *)out;
877  const uint32_t *_in = (const uint32_t *)in;
878 
879  /* Load key */
880  for (i = 3; i >= 0; i--)
881  {
882  AES->KEYLA = __REV(_in[i]);
883  }
884 
885  /* Do dummy encryption to generate decrypt key */
886  AES->CTRL = 0;
888  AES->CMD = AES_CMD_START;
889 
890  /* Wait for completion */
891  while (AES->STATUS & AES_STATUS_RUNNING)
892  ;
893 
894  /* Save decryption key */
895  for (i = 3; i >= 0; i--)
896  {
897  _out[i] = __REV(AES->KEYLA);
898  }
899 }
900 
901 
902 #if defined( AES_CTRL_AES256 )
903 /***************************************************************************/
918 void AES_DecryptKey256(uint8_t *out, const uint8_t *in)
919 {
920  int i;
921  int j;
922  uint32_t *_out = (uint32_t *)out;
923  const uint32_t *_in = (const uint32_t *)in;
924 
925  /* Load key */
926  for (i = 3, j = 7; i >= 0; i--, j--)
927  {
928  AES->KEYLA = __REV(_in[j]);
929  AES->KEYHA = __REV(_in[i]);
930  }
931 
932  /* Do dummy encryption to generate decrypt key */
933  AES->CTRL = AES_CTRL_AES256;
934  AES->CMD = AES_CMD_START;
935 
936  /* Wait for completion */
937  while (AES->STATUS & AES_STATUS_RUNNING)
938  ;
939 
940  /* Save decryption key */
941  for (i = 3, j = 7; i >= 0; i--, j--)
942  {
943  _out[j] = __REV(AES->KEYLA);
944  _out[i] = __REV(AES->KEYHA);
945  }
946 }
947 #endif
948 
949 
950 /***************************************************************************/
1001 void AES_ECB128(uint8_t *out,
1002  const uint8_t *in,
1003  unsigned int len,
1004  const uint8_t *key,
1005  bool encrypt)
1006 {
1007  int i;
1008  uint32_t *_out = (uint32_t *)out;
1009  const uint32_t *_in = (const uint32_t *)in;
1010  const uint32_t *_key = (const uint32_t *)key;
1011 
1012  EFM_ASSERT(!(len % AES_BLOCKSIZE));
1013 
1014  #if defined( AES_CTRL_KEYBUFEN )
1015  /* Load key into high key for key buffer usage */
1016  for (i = 3; i >= 0; i--)
1017  {
1018  AES->KEYHA = __REV(_key[i]);
1019  }
1020  #endif
1021 
1022  if (encrypt)
1023  {
1024  /* Select encryption mode */
1025  #if defined( AES_CTRL_KEYBUFEN )
1026  AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
1027  #else
1028  AES->CTRL = AES_CTRL_DATASTART;
1029  #endif
1030  }
1031  else
1032  {
1033  /* Select decryption mode */
1034  #if defined( AES_CTRL_KEYBUFEN )
1035  AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
1036  #else
1038  #endif
1039  }
1040 
1041  /* Encrypt/decrypt data */
1042  len /= AES_BLOCKSIZE;
1043  while (len--)
1044  {
1045  #if !defined( AES_CTRL_KEYBUFEN )
1046  /* Load key */
1047  for (i = 3; i >= 0; i--)
1048  {
1049  AES->KEYLA = __REV(_key[i]);
1050  }
1051  #endif
1052 
1053  /* Load block to be encrypted/decrypted */
1054  for (i = 3; i >= 0; i--)
1055  {
1056  AES->DATA = __REV(_in[i]);
1057  }
1058  _in += 4;
1059 
1060  /* Wait for completion */
1061  while (AES->STATUS & AES_STATUS_RUNNING)
1062  ;
1063 
1064  /* Save encrypted/decrypted data */
1065  for (i = 3; i >= 0; i--)
1066  {
1067  _out[i] = __REV(AES->DATA);
1068  }
1069  _out += 4;
1070  }
1071 }
1072 
1073 
1074 #if defined( AES_CTRL_AES256 )
1075 /***************************************************************************/
1102 void AES_ECB256(uint8_t *out,
1103  const uint8_t *in,
1104  unsigned int len,
1105  const uint8_t *key,
1106  bool encrypt)
1107 {
1108  int i;
1109  int j;
1110  uint32_t *_out = (uint32_t *)out;
1111  const uint32_t *_in = (const uint32_t *)in;
1112  const uint32_t *_key = (const uint32_t *)key;
1113 
1114  EFM_ASSERT(!(len % AES_BLOCKSIZE));
1115 
1116  if (encrypt)
1117  {
1118  /* Select encryption mode */
1119  AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
1120  }
1121  else
1122  {
1123  /* Select decryption mode */
1124  AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_AES256 | AES_CTRL_DATASTART;
1125  }
1126 
1127  /* Encrypt/decrypt data */
1128  len /= AES_BLOCKSIZE;
1129  while (len--)
1130  {
1131  /* Load key and block to be encrypted/decrypted */
1132  for (i = 3, j = 7; i >= 0; i--, j--)
1133  {
1134  AES->KEYLA = __REV(_key[j]);
1135  AES->KEYHA = __REV(_key[i]);
1136  /* Write data last, since will trigger encryption on last iteration */
1137  AES->DATA = __REV(_in[i]);
1138  }
1139  _in += 4;
1140 
1141  /* Wait for completion */
1142  while (AES->STATUS & AES_STATUS_RUNNING)
1143  ;
1144 
1145  /* Save encrypted/decrypted data */
1146  for (i = 3; i >= 0; i--)
1147  {
1148  _out[i] = __REV(AES->DATA);
1149  }
1150  _out += 4;
1151  }
1152 }
1153 #endif
1154 
1155 
1156 /***************************************************************************/
1213 void AES_OFB128(uint8_t *out,
1214  const uint8_t *in,
1215  unsigned int len,
1216  const uint8_t *key,
1217  const uint8_t *iv)
1218 {
1219  int i;
1220  uint32_t *_out = (uint32_t *)out;
1221  const uint32_t *_in = (const uint32_t *)in;
1222  const uint32_t *_key = (const uint32_t *)key;
1223  const uint32_t *_iv = (const uint32_t *)iv;
1224 
1225  EFM_ASSERT(!(len % AES_BLOCKSIZE));
1226 
1227  /* Select encryption mode, trigger explicitly by command */
1228  #if defined( AES_CTRL_KEYBUFEN )
1229  AES->CTRL = AES_CTRL_KEYBUFEN;
1230  #else
1231  AES->CTRL = 0;
1232  #endif
1233 
1234  /* Load key into high key for key buffer usage */
1235  /* Load initialization vector */
1236  for (i = 3; i >= 0; i--)
1237  {
1238  #if defined( AES_CTRL_KEYBUFEN )
1239  AES->KEYHA = __REV(_key[i]);
1240  #endif
1241  AES->DATA = __REV(_iv[i]);
1242  }
1243 
1244  /* Encrypt/decrypt data */
1245  len /= AES_BLOCKSIZE;
1246  while (len--)
1247  {
1248  #if !defined( AES_CTRL_KEYBUFEN )
1249  /* Load key */
1250  for (i = 3; i >= 0; i--)
1251  {
1252  AES->KEYLA = __REV(_key[i]);
1253  }
1254  #endif
1255 
1256  AES->CMD = AES_CMD_START;
1257 
1258  /* Wait for completion */
1259  while (AES->STATUS & AES_STATUS_RUNNING)
1260  ;
1261 
1262  /* Save encrypted/decrypted data */
1263  for (i = 3; i >= 0; i--)
1264  {
1265  _out[i] = __REV(AES->DATA) ^ _in[i];
1266  }
1267  _out += 4;
1268  _in += 4;
1269  }
1270 }
1271 
1272 
1273 #if defined( AES_CTRL_AES256 )
1274 /***************************************************************************/
1299 void AES_OFB256(uint8_t *out,
1300  const uint8_t *in,
1301  unsigned int len,
1302  const uint8_t *key,
1303  const uint8_t *iv)
1304 {
1305  int i;
1306  int j;
1307  uint32_t *_out = (uint32_t *)out;
1308  const uint32_t *_in = (const uint32_t *)in;
1309  const uint32_t *_key = (const uint32_t *)key;
1310  const uint32_t *_iv = (const uint32_t *)iv;
1311 
1312  EFM_ASSERT(!(len % AES_BLOCKSIZE));
1313 
1314  /* Select encryption mode, trigger explicitly by command */
1315  AES->CTRL = AES_CTRL_AES256;
1316 
1317  /* Load initialization vector */
1318  for (i = 3; i >= 0; i--)
1319  {
1320  AES->DATA = __REV(_iv[i]);
1321  }
1322 
1323  /* Encrypt/decrypt data */
1324  len /= AES_BLOCKSIZE;
1325  while (len--)
1326  {
1327  /* Load key */
1328  for (i = 3, j = 7; i >= 0; i--, j--)
1329  {
1330  AES->KEYLA = __REV(_key[j]);
1331  AES->KEYHA = __REV(_key[i]);
1332  }
1333 
1334  AES->CMD = AES_CMD_START;
1335 
1336  /* Wait for completion */
1337  while (AES->STATUS & AES_STATUS_RUNNING)
1338  ;
1339 
1340  /* Save encrypted/decrypted data */
1341  for (i = 3; i >= 0; i--)
1342  {
1343  _out[i] = __REV(AES->DATA) ^ _in[i];
1344  }
1345  _out += 4;
1346  _in += 4;
1347  }
1348 }
1349 #endif
1350 
1351 
1354 #endif /* defined(AES_COUNT) && (AES_COUNT > 0) */
#define AES_STATUS_RUNNING
Definition: efm32hg_aes.h:105
void AES_CTRUpdate32Bit(uint8_t *ctr)
Update last 32 bits of 128 bit counter, by incrementing with 1.
Definition: em_aes.c:850
#define AES_CTRL_DECRYPT
Definition: efm32hg_aes.h:67
void AES_DecryptKey128(uint8_t *out, const uint8_t *in)
Generate 128 bit decryption key from 128 bit encryption key. The decryption key is used for some ciph...
Definition: em_aes.c:873
Emlib peripheral API "assert" implementation.
#define AES_CMD_START
Definition: efm32hg_aes.h:91
__STATIC_INLINE void AES_IntClear(uint32_t flags)
Clear one or more pending AES interrupts.
Definition: em_aes.h:200
#define AES
#define AES_CTRL_DATASTART
Definition: efm32hg_aes.h:72
void AES_CTR128(uint8_t *out, const uint8_t *in, unsigned int len, const uint8_t *key, uint8_t *ctr, AES_CtrFuncPtr_TypeDef ctrFunc)
Counter (CTR) cipher mode encryption/decryption, 128 bit key.
Definition: em_aes.c:687
void AES_OFB128(uint8_t *out, const uint8_t *in, unsigned int len, const uint8_t *key, const uint8_t *iv)
Output feedback (OFB) cipher mode encryption/decryption, 128 bit key.
Definition: em_aes.c:1213
#define AES_CTRL_XORSTART
Definition: efm32hg_aes.h:77
void AES_CBC128(uint8_t *out, const uint8_t *in, unsigned int len, const uint8_t *key, const uint8_t *iv, bool encrypt)
Cipher-block chaining (CBC) cipher mode encryption/decryption, 128 bit key.
Definition: em_aes.c:124
void(* AES_CtrFuncPtr_TypeDef)(uint8_t *ctr)
AES counter modification function pointer.
Definition: em_aes.h:116
Advanced encryption standard (AES) accelerator peripheral API.
#define AES_IF_DONE
Definition: efm32hg_aes.h:123
void AES_ECB128(uint8_t *out, const uint8_t *in, unsigned int len, const uint8_t *key, bool encrypt)
Electronic Codebook (ECB) cipher mode encryption/decryption, 128 bit key.
Definition: em_aes.c:1001
void AES_CFB128(uint8_t *out, const uint8_t *in, unsigned int len, const uint8_t *key, const uint8_t *iv, bool encrypt)
Cipher feedback (CFB) cipher mode encryption/decryption, 128 bit key.
Definition: em_aes.c:453