em_aes.c

Go to the documentation of this file.
00001 /***************************************************************************/
00034 #include "em_aes.h"
00035 #if defined(AES_COUNT) && (AES_COUNT > 0)
00036 
00037 #include "em_assert.h"
00038 /***************************************************************************/
00043 /***************************************************************************/
00082 /*******************************************************************************
00083  *******************************   DEFINES   ***********************************
00084  ******************************************************************************/
00085 
00088 #define AES_BLOCKSIZE    16
00089 
00092 /*******************************************************************************
00093  **************************   GLOBAL FUNCTIONS   *******************************
00094  ******************************************************************************/
00095 
00096 /***************************************************************************/
00159 void AES_CBC128(uint8_t *out,
00160                 const uint8_t *in,
00161                 unsigned int len,
00162                 const uint8_t *key,
00163                 const uint8_t *iv,
00164                 bool encrypt)
00165 {
00166   int            i;
00167   uint32_t       *_out = (uint32_t *)out;
00168   const uint32_t *_in  = (const uint32_t *)in;
00169   const uint32_t *_key = (const uint32_t *)key;
00170   const uint32_t *_iv  = (const uint32_t *)iv;
00171   /* Need to buffer one block when decrypting in case 'out' replaces 'in' */
00172   uint32_t       prev[4];
00173 
00174   EFM_ASSERT(!(len % AES_BLOCKSIZE));
00175 
00176   /* Number of blocks to process */
00177   len /= AES_BLOCKSIZE;
00178 
00179   #if defined( AES_CTRL_KEYBUFEN )
00180   if (key)
00181   {
00182     /* Load key into high key for key buffer usage */
00183     for (i = 3; i >= 0; i--)
00184     {
00185       AES->KEYHA = __REV(_key[i]);
00186     }
00187   }
00188   #endif
00189 
00190   if (encrypt)
00191   {
00192     /* Enable encryption with auto start using XOR */
00193     #if defined( AES_CTRL_KEYBUFEN )
00194     AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_XORSTART;
00195     #else
00196     AES->CTRL = AES_CTRL_XORSTART;
00197     #endif
00198 
00199     /* Load initialization vector, since writing to DATA, it will */
00200     /* not trigger encryption. */
00201     for (i = 3; i >= 0; i--)
00202     {
00203       AES->DATA = __REV(_iv[i]);
00204     }
00205 
00206     /* Encrypt data */
00207     while (len--)
00208     {
00209       #if !defined( AES_CTRL_KEYBUFEN )
00210       /* Load key */
00211       for (i = 3; i >= 0; i--)
00212       {
00213         AES->KEYLA = __REV(_key[i]);
00214       }
00215       #endif
00216 
00217       /* Load data and trigger encryption */
00218       for (i = 3; i >= 0; i--)
00219       {
00220         AES->XORDATA = __REV(_in[i]);
00221       }
00222       _in += 4;
00223 
00224       /* Wait for completion */
00225       while (AES->STATUS & AES_STATUS_RUNNING)
00226         ;
00227 
00228       /* Save encrypted data */
00229       for (i = 3; i >= 0; i--)
00230       {
00231         _out[i] = __REV(AES->DATA);
00232       }
00233       _out += 4;
00234     }
00235   }
00236   else
00237   {
00238     /* Select decryption mode */
00239     #if defined( AES_CTRL_KEYBUFEN )
00240     AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
00241     #else
00242     AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
00243     #endif
00244 
00245     /* Copy init vector to previous buffer to avoid special handling */
00246     for (i = 0; i < 4; i++)
00247     {
00248       prev[i] = _iv[i];
00249     }
00250 
00251     /* Decrypt data */
00252     while (len--)
00253     {
00254       #if !defined( AES_CTRL_KEYBUFEN )
00255       /* Load key */
00256       for (i = 3; i >= 0; i--)
00257       {
00258         AES->KEYLA = __REV(_key[i]);
00259       }
00260       #endif
00261 
00262       /* Load data and trigger decryption */
00263       for (i = 3; i >= 0; i--)
00264       {
00265         AES->DATA = __REV(_in[i]);
00266       }
00267 
00268       /* Wait for completion */
00269       while (AES->STATUS & AES_STATUS_RUNNING)
00270         ;
00271 
00272       /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
00273       /* (Writing to XORDATA will not trigger encoding, triggering enabled on DATA.) */
00274       for (i = 3; i >= 0; i--)
00275       {
00276         AES->XORDATA = __REV(prev[i]);
00277         prev[i]      = _in[i];
00278       }
00279       _in += 4;
00280 
00281       /* Then fetch decrypted data, we have to do it in a separate loop */
00282       /* due to internal auto-shifting of words */
00283       for (i = 3; i >= 0; i--)
00284       {
00285         _out[i] = __REV(AES->DATA);
00286       }
00287       _out += 4;
00288     }
00289   }
00290 }
00291 
00292 
00293 #if defined( AES_CTRL_AES256 )
00294 /***************************************************************************/
00324 void AES_CBC256(uint8_t *out,
00325                 const uint8_t *in,
00326                 unsigned int len,
00327                 const uint8_t *key,
00328                 const uint8_t *iv,
00329                 bool encrypt)
00330 {
00331   int            i;
00332   int            j;
00333   uint32_t       *_out = (uint32_t *)out;
00334   const uint32_t *_in  = (const uint32_t *)in;
00335   const uint32_t *_key = (const uint32_t *)key;
00336   const uint32_t *_iv  = (const uint32_t *)iv;
00337   /* Need to buffer one block when decrypting in case output replaces input */
00338   uint32_t       prev[4];
00339 
00340   EFM_ASSERT(!(len % AES_BLOCKSIZE));
00341 
00342   /* Number of blocks to process */
00343   len /= AES_BLOCKSIZE;
00344 
00345   if (encrypt)
00346   {
00347     /* Enable encryption with auto start using XOR */
00348     AES->CTRL = AES_CTRL_AES256 | AES_CTRL_XORSTART;
00349 
00350     /* Load initialization vector, since writing to DATA, it will */
00351     /* not trigger encryption. */
00352     for (i = 3; i >= 0; i--)
00353     {
00354       AES->DATA = __REV(_iv[i]);
00355     }
00356 
00357     /* Encrypt data */
00358     while (len--)
00359     {
00360       /* Load key and data and trigger encryption */
00361       for (i = 3, j = 7; i >= 0; i--, j--)
00362       {
00363         AES->KEYLA = __REV(_key[j]);
00364         AES->KEYHA = __REV(_key[i]);
00365         /* Write data last, since will trigger encryption on last iteration */
00366         AES->XORDATA = __REV(_in[i]);
00367       }
00368       _in += 4;
00369 
00370       /* Wait for completion */
00371       while (AES->STATUS & AES_STATUS_RUNNING)
00372         ;
00373 
00374       /* Save encrypted data */
00375       for (i = 3; i >= 0; i--)
00376       {
00377         _out[i] = __REV(AES->DATA);
00378       }
00379       _out += 4;
00380     }
00381   }
00382   else
00383   {
00384     /* Select decryption mode */
00385     AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
00386 
00387     /* Copy init vector to previous buffer to avoid special handling */
00388     for (i = 0; i < 4; i++)
00389     {
00390       prev[i] = _iv[i];
00391     }
00392 
00393     /* Decrypt data */
00394     while (len--)
00395     {
00396       /* Load key and data and trigger decryption */
00397       for (i = 3, j = 7; i >= 0; i--, j--)
00398       {
00399         AES->KEYLA = __REV(_key[j]);
00400         AES->KEYHA = __REV(_key[i]);
00401         /* Write data last, since will trigger encryption on last iteration */
00402         AES->DATA = __REV(_in[i]);
00403       }
00404 
00405       /* Wait for completion */
00406       while (AES->STATUS & AES_STATUS_RUNNING)
00407         ;
00408 
00409       /* In order to avoid additional buffer, we use HW directly for XOR and buffer */
00410       for (i = 3; i >= 0; i--)
00411       {
00412         AES->XORDATA = __REV(prev[i]);
00413         prev[i]      = _in[i];
00414       }
00415       _in += 4;
00416 
00417       /* Then fetch decrypted data, we have to do it in a separate loop */
00418       /* due to internal auto-shifting of words */
00419       for (i = 3; i >= 0; i--)
00420       {
00421         _out[i] = __REV(AES->DATA);
00422       }
00423       _out += 4;
00424     }
00425   }
00426 }
00427 #endif
00428 
00429 
00430 /***************************************************************************/
00488 void AES_CFB128(uint8_t *out,
00489                 const uint8_t *in,
00490                 unsigned int len,
00491                 const uint8_t *key,
00492                 const uint8_t *iv,
00493                 bool encrypt)
00494 {
00495   int            i;
00496   uint32_t       *_out = (uint32_t *)out;
00497   const uint32_t *_in  = (const uint32_t *)in;
00498   const uint32_t *_key = (const uint32_t *)key;
00499   const uint32_t *_iv  = (const uint32_t *)iv;
00500   const uint32_t *data;
00501   uint32_t       tmp[4];
00502 
00503   EFM_ASSERT(!(len % AES_BLOCKSIZE));
00504 
00505   #if defined( AES_CTRL_KEYBUFEN )
00506   AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
00507   #else
00508   AES->CTRL = AES_CTRL_DATASTART;
00509   #endif
00510 
00511   #if defined( AES_CTRL_KEYBUFEN )
00512   /* Load key into high key for key buffer usage */
00513   for (i = 3; i >= 0; i--)
00514   {
00515     AES->KEYHA = __REV(_key[i]);
00516   }
00517   #endif
00518 
00519   /* Encrypt/decrypt data */
00520   data = _iv;
00521   len /= AES_BLOCKSIZE;
00522   while (len--)
00523   {
00524     #if !defined( AES_CTRL_KEYBUFEN )
00525     /* Load key */
00526     for (i = 3; i >= 0; i--)
00527     {
00528       AES->KEYLA = __REV(_key[i]);
00529     }
00530     #endif
00531 
00532     /* Load data and trigger encryption */
00533     for (i = 3; i >= 0; i--)
00534     {
00535       AES->DATA = __REV(data[i]);
00536     }
00537 
00538     /* Do some required processing before waiting for completion */
00539     if (encrypt)
00540     {
00541       data = _out;
00542     }
00543     else
00544     {
00545       /* Must copy current ciphertext block since it may be overwritten */
00546       for (i = 0; i < 4; i++)
00547       {
00548         tmp[i] = _in[i];
00549       }
00550       data = tmp;
00551     }
00552 
00553     /* Wait for completion */
00554     while (AES->STATUS & AES_STATUS_RUNNING)
00555       ;
00556 
00557     /* Save encrypted/decrypted data */
00558     for (i = 3; i >= 0; i--)
00559     {
00560       _out[i] = __REV(AES->DATA) ^ _in[i];
00561     }
00562     _out += 4;
00563     _in  += 4;
00564   }
00565 }
00566 
00567 
00568 #if defined( AES_CTRL_AES256 )
00569 /***************************************************************************/
00597 void AES_CFB256(uint8_t *out,
00598                 const uint8_t *in,
00599                 unsigned int len,
00600                 const uint8_t *key,
00601                 const uint8_t *iv,
00602                 bool encrypt)
00603 {
00604   int            i;
00605   int            j;
00606   uint32_t       *_out = (uint32_t *)out;
00607   const uint32_t *_in  = (const uint32_t *)in;
00608   const uint32_t *_key = (const uint32_t *)key;
00609   const uint32_t *_iv  = (const uint32_t *)iv;
00610   const uint32_t *data;
00611   uint32_t       tmp[4];
00612 
00613   EFM_ASSERT(!(len % AES_BLOCKSIZE));
00614 
00615   /* Select encryption mode */
00616   AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
00617 
00618   /* Encrypt/decrypt data */
00619   data = _iv;
00620   len /= AES_BLOCKSIZE;
00621   while (len--)
00622   {
00623     /* Load key and block to be encrypted/decrypted */
00624     for (i = 3, j = 7; i >= 0; i--, j--)
00625     {
00626       AES->KEYLA = __REV(_key[j]);
00627       AES->KEYHA = __REV(_key[i]);
00628       /* Write data last, since will trigger encryption on last iteration */
00629       AES->DATA = __REV(data[i]);
00630     }
00631 
00632     /* Do some required processing before waiting for completion */
00633     if (encrypt)
00634     {
00635       data = _out;
00636     }
00637     else
00638     {
00639       /* Must copy current ciphertext block since it may be overwritten */
00640       for (i = 0; i < 4; i++)
00641       {
00642         tmp[i] = _in[i];
00643       }
00644       data = tmp;
00645     }
00646 
00647     while (AES->STATUS & AES_STATUS_RUNNING)
00648       ;
00649 
00650     /* Save encrypted/decrypted data */
00651     for (i = 3; i >= 0; i--)
00652     {
00653       _out[i] = __REV(AES->DATA) ^ _in[i];
00654     }
00655     _out += 4;
00656     _in  += 4;
00657   }
00658 }
00659 #endif
00660 
00661 
00662 /***************************************************************************/
00722 void AES_CTR128(uint8_t *out,
00723                 const uint8_t *in,
00724                 unsigned int len,
00725                 const uint8_t *key,
00726                 uint8_t *ctr,
00727                 AES_CtrFuncPtr_TypeDef ctrFunc)
00728 {
00729   int            i;
00730   uint32_t       *_out = (uint32_t *)out;
00731   const uint32_t *_in  = (const uint32_t *)in;
00732   const uint32_t *_key = (const uint32_t *)key;
00733   uint32_t       *_ctr = (uint32_t *)ctr;
00734 
00735   EFM_ASSERT(!(len % AES_BLOCKSIZE));
00736   EFM_ASSERT(ctrFunc);
00737 
00738   #if defined( AES_CTRL_KEYBUFEN )
00739   AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
00740   #else
00741   AES->CTRL = AES_CTRL_DATASTART;
00742   #endif
00743 
00744   #if defined( AES_CTRL_KEYBUFEN )
00745   if (key)
00746   {
00747     /* Load key into high key for key buffer usage */
00748     for (i = 3; i >= 0; i--)
00749     {
00750       AES->KEYHA = __REV(_key[i]);
00751     }
00752   }
00753   #endif
00754 
00755   /* Encrypt/decrypt data */
00756   len /= AES_BLOCKSIZE;
00757   while (len--)
00758   {
00759     #if !defined( AES_CTRL_KEYBUFEN )
00760     /* Load key */
00761     for (i = 3; i >= 0; i--)
00762     {
00763       AES->KEYLA = __REV(_key[i]);
00764     }
00765     #endif
00766 
00767     /* Load ctr to be encrypted/decrypted */
00768     for (i = 3; i >= 0; i--)
00769     {
00770       AES->DATA = __REV(_ctr[i]);
00771     }
00772     /* Increment ctr for next use */
00773     ctrFunc(ctr);
00774 
00775     /* Wait for completion */
00776     while (AES->STATUS & AES_STATUS_RUNNING)
00777       ;
00778 
00779     /* Save encrypted/decrypted data */
00780     for (i = 3; i >= 0; i--)
00781     {
00782       _out[i] = __REV(AES->DATA) ^ _in[i];
00783     }
00784     _out += 4;
00785     _in  += 4;
00786   }
00787 }
00788 
00789 
00790 #if defined( AES_CTRL_AES256 )
00791 /***************************************************************************/
00820 void AES_CTR256(uint8_t *out,
00821                 const uint8_t *in,
00822                 unsigned int len,
00823                 const uint8_t *key,
00824                 uint8_t *ctr,
00825                 AES_CtrFuncPtr_TypeDef ctrFunc)
00826 {
00827   int            i;
00828   int            j;
00829   uint32_t       *_out = (uint32_t *)out;
00830   const uint32_t *_in  = (const uint32_t *)in;
00831   const uint32_t *_key = (const uint32_t *)key;
00832   uint32_t       *_ctr = (uint32_t *)ctr;
00833 
00834   EFM_ASSERT(!(len % AES_BLOCKSIZE));
00835   EFM_ASSERT(ctrFunc);
00836 
00837   /* Select encryption mode, with auto trigger */
00838   AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
00839 
00840   /* Encrypt/decrypt data */
00841   len /= AES_BLOCKSIZE;
00842   while (len--)
00843   {
00844     /* Load key and block to be encrypted/decrypted */
00845     for (i = 3, j = 7; i >= 0; i--, j--)
00846     {
00847       AES->KEYLA = __REV(_key[j]);
00848       AES->KEYHA = __REV(_key[i]);
00849       /* Write data last, since will trigger encryption on last iteration */
00850       AES->DATA = __REV(_ctr[i]);
00851     }
00852     /* Increment ctr for next use */
00853     ctrFunc(ctr);
00854 
00855     /* Wait for completion */
00856     while (AES->STATUS & AES_STATUS_RUNNING)
00857       ;
00858 
00859     /* Save encrypted/decrypted data */
00860     for (i = 3; i >= 0; i--)
00861     {
00862       _out[i] = __REV(AES->DATA) ^ _in[i];
00863     }
00864     _out += 4;
00865     _in  += 4;
00866   }
00867 }
00868 #endif
00869 
00870 
00871 /***************************************************************************/
00885 void AES_CTRUpdate32Bit(uint8_t *ctr)
00886 {
00887   uint32_t *_ctr = (uint32_t *)ctr;
00888 
00889   _ctr[3] = __REV(__REV(_ctr[3]) + 1);
00890 }
00891 
00892 
00893 /***************************************************************************/
00908 void AES_DecryptKey128(uint8_t *out, const uint8_t *in)
00909 {
00910   int            i;
00911   uint32_t       *_out = (uint32_t *)out;
00912   const uint32_t *_in  = (const uint32_t *)in;
00913 
00914   /* Load key */
00915   for (i = 3; i >= 0; i--)
00916   {
00917     AES->KEYLA = __REV(_in[i]);
00918   }
00919 
00920   /* Do dummy encryption to generate decrypt key */
00921   AES->CTRL = 0;
00922   AES_IntClear(AES_IF_DONE);
00923   AES->CMD = AES_CMD_START;
00924 
00925   /* Wait for completion */
00926   while (AES->STATUS & AES_STATUS_RUNNING)
00927     ;
00928 
00929   /* Save decryption key */
00930   for (i = 3; i >= 0; i--)
00931   {
00932     _out[i] = __REV(AES->KEYLA);
00933   }
00934 }
00935 
00936 
00937 #if defined( AES_CTRL_AES256 )
00938 /***************************************************************************/
00953 void AES_DecryptKey256(uint8_t *out, const uint8_t *in)
00954 {
00955   int            i;
00956   int            j;
00957   uint32_t       *_out = (uint32_t *)out;
00958   const uint32_t *_in  = (const uint32_t *)in;
00959 
00960   /* Load key */
00961   for (i = 3, j = 7; i >= 0; i--, j--)
00962   {
00963     AES->KEYLA = __REV(_in[j]);
00964     AES->KEYHA = __REV(_in[i]);
00965   }
00966 
00967   /* Do dummy encryption to generate decrypt key */
00968   AES->CTRL = AES_CTRL_AES256;
00969   AES->CMD  = AES_CMD_START;
00970 
00971   /* Wait for completion */
00972   while (AES->STATUS & AES_STATUS_RUNNING)
00973     ;
00974 
00975   /* Save decryption key */
00976   for (i = 3, j = 7; i >= 0; i--, j--)
00977   {
00978     _out[j] = __REV(AES->KEYLA);
00979     _out[i] = __REV(AES->KEYHA);
00980   }
00981 }
00982 #endif
00983 
00984 
00985 /***************************************************************************/
01036 void AES_ECB128(uint8_t *out,
01037                 const uint8_t *in,
01038                 unsigned int len,
01039                 const uint8_t *key,
01040                 bool encrypt)
01041 {
01042   int            i;
01043   uint32_t       *_out = (uint32_t *)out;
01044   const uint32_t *_in  = (const uint32_t *)in;
01045   const uint32_t *_key = (const uint32_t *)key;
01046 
01047   EFM_ASSERT(!(len % AES_BLOCKSIZE));
01048 
01049   #if defined( AES_CTRL_KEYBUFEN )
01050   /* Load key into high key for key buffer usage */
01051   for (i = 3; i >= 0; i--)
01052   {
01053     AES->KEYHA = __REV(_key[i]);
01054   }
01055   #endif
01056 
01057   if (encrypt)
01058   {
01059     /* Select encryption mode */
01060     #if defined( AES_CTRL_KEYBUFEN )
01061     AES->CTRL = AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
01062     #else
01063     AES->CTRL = AES_CTRL_DATASTART;
01064     #endif
01065   }
01066   else
01067   {
01068     /* Select decryption mode */
01069     #if defined( AES_CTRL_KEYBUFEN )
01070     AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_KEYBUFEN | AES_CTRL_DATASTART;
01071     #else
01072     AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_DATASTART;
01073     #endif
01074   }
01075 
01076   /* Encrypt/decrypt data */
01077   len /= AES_BLOCKSIZE;
01078   while (len--)
01079   {
01080     #if !defined( AES_CTRL_KEYBUFEN )
01081     /* Load key */
01082     for (i = 3; i >= 0; i--)
01083     {
01084       AES->KEYLA = __REV(_key[i]);
01085     }
01086     #endif
01087 
01088     /* Load block to be encrypted/decrypted */
01089     for (i = 3; i >= 0; i--)
01090     {
01091       AES->DATA = __REV(_in[i]);
01092     }
01093     _in += 4;
01094 
01095     /* Wait for completion */
01096     while (AES->STATUS & AES_STATUS_RUNNING)
01097       ;
01098 
01099     /* Save encrypted/decrypted data */
01100     for (i = 3; i >= 0; i--)
01101     {
01102       _out[i] = __REV(AES->DATA);
01103     }
01104     _out += 4;
01105   }
01106 }
01107 
01108 
01109 #if defined( AES_CTRL_AES256 )
01110 /***************************************************************************/
01137 void AES_ECB256(uint8_t *out,
01138                 const uint8_t *in,
01139                 unsigned int len,
01140                 const uint8_t *key,
01141                 bool encrypt)
01142 {
01143   int            i;
01144   int            j;
01145   uint32_t       *_out = (uint32_t *)out;
01146   const uint32_t *_in  = (const uint32_t *)in;
01147   const uint32_t *_key = (const uint32_t *)key;
01148 
01149   EFM_ASSERT(!(len % AES_BLOCKSIZE));
01150 
01151   if (encrypt)
01152   {
01153     /* Select encryption mode */
01154     AES->CTRL = AES_CTRL_AES256 | AES_CTRL_DATASTART;
01155   }
01156   else
01157   {
01158     /* Select decryption mode */
01159     AES->CTRL = AES_CTRL_DECRYPT | AES_CTRL_AES256 | AES_CTRL_DATASTART;
01160   }
01161 
01162   /* Encrypt/decrypt data */
01163   len /= AES_BLOCKSIZE;
01164   while (len--)
01165   {
01166     /* Load key and block to be encrypted/decrypted */
01167     for (i = 3, j = 7; i >= 0; i--, j--)
01168     {
01169       AES->KEYLA = __REV(_key[j]);
01170       AES->KEYHA = __REV(_key[i]);
01171       /* Write data last, since will trigger encryption on last iteration */
01172       AES->DATA = __REV(_in[i]);
01173     }
01174     _in += 4;
01175 
01176     /* Wait for completion */
01177     while (AES->STATUS & AES_STATUS_RUNNING)
01178       ;
01179 
01180     /* Save encrypted/decrypted data */
01181     for (i = 3; i >= 0; i--)
01182     {
01183       _out[i] = __REV(AES->DATA);
01184     }
01185     _out += 4;
01186   }
01187 }
01188 #endif
01189 
01190 
01191 /***************************************************************************/
01248 void AES_OFB128(uint8_t *out,
01249                 const uint8_t *in,
01250                 unsigned int len,
01251                 const uint8_t *key,
01252                 const uint8_t *iv)
01253 {
01254   int            i;
01255   uint32_t       *_out = (uint32_t *)out;
01256   const uint32_t *_in  = (const uint32_t *)in;
01257   const uint32_t *_key = (const uint32_t *)key;
01258   const uint32_t *_iv  = (const uint32_t *)iv;
01259 
01260   EFM_ASSERT(!(len % AES_BLOCKSIZE));
01261 
01262   /* Select encryption mode, trigger explicitly by command */
01263   #if defined( AES_CTRL_KEYBUFEN )
01264   AES->CTRL = AES_CTRL_KEYBUFEN;
01265   #else
01266   AES->CTRL = 0;
01267   #endif
01268 
01269   /* Load key into high key for key buffer usage */
01270   /* Load initialization vector */
01271   for (i = 3; i >= 0; i--)
01272   {
01273     #if defined( AES_CTRL_KEYBUFEN )
01274     AES->KEYHA = __REV(_key[i]);
01275     #endif
01276     AES->DATA  = __REV(_iv[i]);
01277   }
01278 
01279   /* Encrypt/decrypt data */
01280   len /= AES_BLOCKSIZE;
01281   while (len--)
01282   {
01283     #if !defined( AES_CTRL_KEYBUFEN )
01284     /* Load key */
01285     for (i = 3; i >= 0; i--)
01286     {
01287       AES->KEYLA = __REV(_key[i]);
01288     }
01289     #endif
01290 
01291     AES->CMD = AES_CMD_START;
01292 
01293     /* Wait for completion */
01294     while (AES->STATUS & AES_STATUS_RUNNING)
01295       ;
01296 
01297     /* Save encrypted/decrypted data */
01298     for (i = 3; i >= 0; i--)
01299     {
01300       _out[i] = __REV(AES->DATA) ^ _in[i];
01301     }
01302     _out += 4;
01303     _in  += 4;
01304   }
01305 }
01306 
01307 
01308 #if defined( AES_CTRL_AES256 )
01309 /***************************************************************************/
01334 void AES_OFB256(uint8_t *out,
01335                 const uint8_t *in,
01336                 unsigned int len,
01337                 const uint8_t *key,
01338                 const uint8_t *iv)
01339 {
01340   int            i;
01341   int            j;
01342   uint32_t       *_out = (uint32_t *)out;
01343   const uint32_t *_in  = (const uint32_t *)in;
01344   const uint32_t *_key = (const uint32_t *)key;
01345   const uint32_t *_iv  = (const uint32_t *)iv;
01346 
01347   EFM_ASSERT(!(len % AES_BLOCKSIZE));
01348 
01349   /* Select encryption mode, trigger explicitly by command */
01350   AES->CTRL = AES_CTRL_AES256;
01351 
01352   /* Load initialization vector */
01353   for (i = 3; i >= 0; i--)
01354   {
01355     AES->DATA = __REV(_iv[i]);
01356   }
01357 
01358   /* Encrypt/decrypt data */
01359   len /= AES_BLOCKSIZE;
01360   while (len--)
01361   {
01362     /* Load key */
01363     for (i = 3, j = 7; i >= 0; i--, j--)
01364     {
01365       AES->KEYLA = __REV(_key[j]);
01366       AES->KEYHA = __REV(_key[i]);
01367     }
01368 
01369     AES->CMD = AES_CMD_START;
01370 
01371     /* Wait for completion */
01372     while (AES->STATUS & AES_STATUS_RUNNING)
01373       ;
01374 
01375     /* Save encrypted/decrypted data */
01376     for (i = 3; i >= 0; i--)
01377     {
01378       _out[i] = __REV(AES->DATA) ^ _in[i];
01379     }
01380     _out += 4;
01381     _in  += 4;
01382   }
01383 }
01384 #endif
01385 
01386 
01389 #endif /* defined(AES_COUNT) && (AES_COUNT > 0) */