• Main Page
  • Modules
  • Index
  • File List
  • Globals

hal/nrf24le1/hal_aes.c

Go to the documentation of this file.
00001 /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is confidential property of Nordic
00004  * Semiconductor ASA.Terms and conditions of usage are described in detail
00005  * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRENTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  * $LastChangedRevision: 2368 $
00012  */
00013 
00022 //lint -e438
00023 
00024 #include "hal_aes.h"
00025 #include "nrf24le1.h"
00026 
00027 /*----------------------- AES Parameters -------------------------------------*/
00028 static uint8_t xdata cipher_key[16];    //AES key
00029 
00030 //These should be placed in fast RAM
00031 static uint8_t pdata aes_round_key[16]; //AES Round Key
00032 
00033 /*----------------------- AES Encryption Functions ---------------------------*/
00034 static void mix_columns_hw(uint8_t data * aes_state);
00035 static void add_sub_shift(uint8_t data * aes_state);
00036 static void add_key(uint8_t data * aes_state);
00037 static void aes_set_key(const uint8_t * key_bytes);
00038 static void key_upgrade(uint8_t round);
00039 
00040 /*----------------------- AES STATIC values ----------------------------------*/
00041 static uint8_t const code s_box[256] = {
00042  99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118,
00043 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
00044 183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21,
00045   4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117,
00046   9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132,
00047  83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207,
00048 208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168,
00049  81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210,
00050 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115,
00051  96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219,
00052 224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121,
00053 231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8,
00054 186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138,
00055 112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158,
00056 225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223,
00057 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22,
00058 };
00059 
00060 static uint8_t const code rcon[]={
00061 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
00062 
00063 /*----------------------- AES API --------------------------------------------*/
00064 void hal_aes_setup(bool decrypt, aes_modes_t mode, const uint8_t *keyin, const uint8_t *ivin)
00065 {
00066     aes_set_key(keyin);
00067 
00068   //lint -save -e438
00069     // Not used in LE1, included to prevent compile-warnings------ |
00070     decrypt = decrypt;                                          // |
00071     mode = mode;                                                // |
00072     ivin = ivin;                                                // |
00073     //-------------------------------------------------------------|
00074   //lint -restore
00075 }
00076 
00077 #ifdef __ICC8051__
00078  static uint8_t data aes_state[16];      //AES State
00079 #endif  
00080 
00081 void hal_aes_crypt(uint8_t * dest_buf, const uint8_t * src_buf)
00082 {
00083 #ifdef __C51__
00084   uint8_t data aes_state[16];      //AES State
00085 #endif
00086 
00087   uint8_t a;
00088     for(a=0;a<16;a++)
00089     {
00090         aes_state[a] = src_buf[a];
00091     }
00092 
00093   //Start
00094   CCPDATIB = 0x02;  //Set co-prosessor the GF(2^8)*2 (used in mix-colums)
00095   for (a=0;a<9;a++)
00096   {
00097     add_sub_shift(aes_state);
00098     mix_columns_hw(aes_state);
00099     key_upgrade(a);
00100   }
00101 
00102   //FINAL   round
00103   add_sub_shift(aes_state);
00104   key_upgrade(9);
00105   add_key(aes_state);
00106 
00107   //Clean up
00108     for(a=0;a<16;a++)
00109     {
00110         aes_round_key[a]=cipher_key[a]; //Write back cipher-key
00111         dest_buf[a] = aes_state[a];     //Write out encrypted result
00112     }
00113 }
00114 /*----------------------- Private AES Encryption Functions -------------------*/
00115 static void aes_set_key(const uint8_t * key_bytes)
00116 {
00117   uint8_t k;
00118   for (k=0;k<16;k++)
00119   {
00120     cipher_key[k]=aes_round_key[k]=key_bytes[k];
00121   }
00122 }
00123 
00124 static void add_key(uint8_t data * aes_state)
00125 {
00126   aes_state[0]^=aes_round_key[0];
00127   aes_state[1]^=aes_round_key[1];
00128   aes_state[2]^=aes_round_key[2];
00129   aes_state[3]^=aes_round_key[3];
00130   aes_state[4]^=aes_round_key[4];
00131   aes_state[5]^=aes_round_key[5];
00132   aes_state[6]^=aes_round_key[6];
00133   aes_state[7]^=aes_round_key[7];
00134   aes_state[8]^=aes_round_key[8];
00135   aes_state[9]^=aes_round_key[9];
00136   aes_state[10]^=aes_round_key[10];
00137   aes_state[11]^=aes_round_key[11];
00138   aes_state[12]^=aes_round_key[12];
00139   aes_state[13]^=aes_round_key[13];
00140   aes_state[14]^=aes_round_key[14];
00141   aes_state[15]^=aes_round_key[15];
00142 }
00143 
00144 static void key_upgrade(uint8_t round)
00145 {
00146   aes_round_key[0]=s_box[aes_round_key[13]]^aes_round_key[0]^rcon[round+1];
00147   aes_round_key[1]=s_box[aes_round_key[14]]^aes_round_key[1];
00148   aes_round_key[2]=s_box[aes_round_key[15]]^aes_round_key[2];
00149   aes_round_key[3]=s_box[aes_round_key[12]]^aes_round_key[3];
00150 
00151   aes_round_key[4]=aes_round_key[0]^aes_round_key[4];
00152   aes_round_key[5]=aes_round_key[1]^aes_round_key[5];
00153   aes_round_key[6]=aes_round_key[2]^aes_round_key[6];
00154   aes_round_key[7]=aes_round_key[3]^aes_round_key[7];
00155 
00156   aes_round_key[8]=aes_round_key[4]^aes_round_key[8];
00157   aes_round_key[9]=aes_round_key[5]^aes_round_key[9];
00158   aes_round_key[10]=aes_round_key[6]^aes_round_key[10];
00159   aes_round_key[11]=aes_round_key[7]^aes_round_key[11];
00160 
00161   aes_round_key[12]=aes_round_key[8]^aes_round_key[12];
00162   aes_round_key[13]=aes_round_key[9]^aes_round_key[13];
00163   aes_round_key[14]=aes_round_key[10]^aes_round_key[14];
00164   aes_round_key[15]=aes_round_key[11]^aes_round_key[15];
00165 }
00166 
00167 static void add_sub_shift(uint8_t data * aes_state)
00168 {
00169   uint8_t row[2];
00170 
00171   aes_state[0]=s_box[aes_state[0]^aes_round_key[0]];
00172   aes_state[4]=s_box[aes_state[4]^aes_round_key[4]];
00173   aes_state[8]=s_box[aes_state[8]^aes_round_key[8]];
00174   aes_state[12]=s_box[aes_state[12]^aes_round_key[12]];
00175 
00176   row[0]=s_box[aes_state[1]^aes_round_key[1]];
00177   aes_state[1]=s_box[aes_state[5]^aes_round_key[5]];
00178   aes_state[5]=s_box[aes_state[9]^aes_round_key[9]];
00179   aes_state[9]=s_box[aes_state[13]^aes_round_key[13]];
00180   aes_state[13]=row[0];
00181 
00182   row[0]=s_box[aes_state[2]^aes_round_key[2]];
00183   row[1]=s_box[aes_state[6]^aes_round_key[6]];
00184   aes_state[2]=s_box[aes_state[10]^aes_round_key[10]];
00185   aes_state[6]=s_box[aes_state[14]^aes_round_key[14]];
00186   aes_state[10]=row[0];
00187   aes_state[14]=row[1];
00188 
00189   row[0]=s_box[aes_state[15]^aes_round_key[15]];
00190   aes_state[15]=s_box[aes_state[11]^aes_round_key[11]];
00191   aes_state[11]=s_box[aes_state[7]^aes_round_key[7]];
00192   aes_state[7]=s_box[aes_state[3]^aes_round_key[3]];
00193   aes_state[3]=row[0];
00194 }
00195 
00196 static void mix_columns_hw(uint8_t data * aes_state)
00197 {
00198   uint8_t col,r,tmp;
00199   /*
00200   This function operates on the columns of the state. Each column is subject to the
00201   following transform (in vector and matrix notation):
00202   (b0)   (2 3 1 1)   (a0)
00203   (b1) = (1 2 3 1) * (a1)
00204   (b2)   (1 1 2 3)   (a2)
00205   (b3)   (3 1 1 2)   (a3)
00206   Here the vector a is a column of the state before the mix columns operation, and
00207   b is the same column after the operation. We use hardware to perform the
00208   multiplication in GF(2^8).
00209   */
00210 
00211   tmp=aes_state[3+0]^aes_state[2+0]^aes_state[1+0]^aes_state[0];
00212   //tmp = a0 + a1 + a2 + a3 (in modular aritmetic)
00213   col=aes_state[0];
00214 
00215   CCPDATIA = aes_state[0]^aes_state[1+0];
00216   r=CCPDATO;
00217   //r = 2*(a0 + a1)
00218   aes_state[0]= r^tmp^(aes_state[0]);
00219   //b0 = 3a0 + 3a1 + a2 +a3 - a0 = 2a0 +3a1 + a2 + a3
00220 
00221   CCPDATIA = aes_state[1+0]^aes_state[2+0];
00222   r=CCPDATO;
00223   //r = 2*(a1 + a2)
00224   aes_state[1+0]= r^tmp^(aes_state[1+0]);
00225   //b1 = a0 + 3a1 + 3a2 +a3 - a1 = a0 +2a1 + 3a2 + a3
00226 
00227   CCPDATIA = aes_state[2+0]^aes_state[3+0];
00228   r=CCPDATO;
00229   //r = 2*(a2 + a3)
00230   aes_state[2+0]= r^tmp^(aes_state[2+0]);
00231   //b2 = a0 + a1 + 3a2 +3a3 - a2 = a0 +a1 + 2a2 + 3a3
00232 
00233   CCPDATIA = aes_state[3+0]^col;
00234   r=CCPDATO;
00235   //r = 2*(a3 + a0)
00236   aes_state[3+0]= r^tmp^(aes_state[3+0]);
00237   //b3 = 3a0 + a1 + a2 +3a3 - a3 = 3a0 +a1 + a2 + 2a3
00238 
00239 
00240   tmp=aes_state[3+4]^aes_state[2+4]^aes_state[1+4]^aes_state[4];
00241   col=aes_state[4];
00242 
00243   CCPDATIA = aes_state[4]^aes_state[1+4];
00244   r=CCPDATO;
00245   aes_state[4]= r^tmp^(aes_state[4]);
00246 
00247   CCPDATIA = aes_state[1+4]^aes_state[2+4];
00248   r=CCPDATO;
00249   aes_state[1+4]= r^tmp^(aes_state[1+4]);
00250 
00251   CCPDATIA = aes_state[2+4]^aes_state[3+4];
00252   r=CCPDATO;
00253   aes_state[2+4]= r^tmp^(aes_state[2+4]);
00254 
00255   CCPDATIA = aes_state[3+4]^col;
00256   r=CCPDATO;
00257   aes_state[3+4]= r^tmp^(aes_state[3+4]);
00258 
00259 
00260   tmp=aes_state[3+8]^aes_state[2+8]^aes_state[1+8]^aes_state[8];
00261   col=aes_state[8];
00262 
00263   CCPDATIA = aes_state[8]^aes_state[1+8];
00264   r=CCPDATO;
00265   aes_state[8]= r^tmp^(aes_state[8]);
00266 
00267   CCPDATIA = aes_state[1+8]^aes_state[2+8];
00268   r=CCPDATO;
00269   aes_state[1+8]= r^tmp^(aes_state[1+8]);
00270 
00271   CCPDATIA = aes_state[2+8]^aes_state[3+8];
00272   r=CCPDATO;
00273   aes_state[2+8]= r^tmp^(aes_state[2+8]);
00274 
00275   CCPDATIA = aes_state[3+8]^col;
00276   r=CCPDATO;
00277   aes_state[3+8]= r^tmp^(aes_state[3+8]);
00278 
00279 
00280   tmp=aes_state[3+12]^aes_state[2+12]^aes_state[1+12]^aes_state[12];
00281   col=aes_state[12];
00282 
00283   CCPDATIA =aes_state[12]^aes_state[1+12];
00284   r=CCPDATO;
00285   aes_state[12]= r^tmp^(aes_state[12]);
00286 
00287   CCPDATIA = aes_state[1+12]^aes_state[2+12];
00288   r=CCPDATO;
00289   aes_state[1+12]= r^tmp^(aes_state[1+12]);
00290 
00291   CCPDATIA =aes_state[2+12]^aes_state[3+12];
00292   r=CCPDATO;
00293   aes_state[2+12]= r^tmp^(aes_state[2+12]);
00294 
00295   CCPDATIA = aes_state[3+12]^col;
00296   r=CCPDATO;
00297   aes_state[3+12]= r^tmp^(aes_state[3+12]);
00298 }
00299 

Generated on Fri Apr 20 2012 14:11:44 for nRFGo SDK by  doxygen 1.7.2