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

hal/nrf24lu1p/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: 230 $
00012  */
00013 
00022 #include "nrf24lu1p.h"
00023 #include <stdint.h>
00024 #include "hal_aes.h"
00025 
00026 
00027 #define AES_BUF_SIZE                16
00028 
00029 //-----------------------------------------------------------------------------
00030 // AES register masks
00031 //-----------------------------------------------------------------------------
00032 
00033 #define AESCS_MODE_MASK             0x1C
00034 #define AESCS_GO_MASK               0x01
00035 
00036 #define AESCS_E_D_MASK              0x02
00037 #define AESCS_E_D_BIT_POS           1
00038 #define DECRYPT                     1
00039 #define ENCRYPT                     0
00040 
00041 #define AESIA1_KIN_MASK             0xf0
00042 #define AESIA1_KIN_B0_POS           4
00043 
00044 #define AESIA1_IV_MASK              0x0f
00045 #define AESIA1_IV_B0_POS            0
00046 
00047 #define AESIA2_DI_MASK              0xf0
00048 #define AESIA2_DI_B0_POS            4
00049 
00050 #define AESIA2_DO_MASK              0x0f
00051 #define AESIA2_DO_B0_POS            0
00052 
00053 //-----------------------------------------------------------------------------
00054 // AES substitution table (used by aes_get_dec_key() only)
00055 //-----------------------------------------------------------------------------
00056 
00057 static code const uint8_t S[256] = {
00058  99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118,
00059 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
00060 183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21,
00061   4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117,
00062   9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132,
00063  83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207,
00064 208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168,
00065  81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210,
00066 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115,
00067  96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219,
00068 224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121,
00069 231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8,
00070 186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138,
00071 112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158,
00072 225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223,
00073 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22,
00074 };
00075 
00076 //-----------------------------------------------------------------------------
00077 // Internal function prototypes
00078 //-----------------------------------------------------------------------------
00079 
00080 void aes_set_mode(uint8_t mode);
00081 void aes_select_e_d(uint8_t operation);
00082 void aes_go();
00083 uint8_t aes_busy();
00084 
00085 void aes_data_write_buf(uint8_t *buf, uint8_t indirect_start_address, uint8_t length);
00086 void aes_data_read_buf(uint8_t *buf, uint8_t indirect_start_address, uint8_t length);
00087 void aes_keyin_write_buf(const uint8_t *buf, uint8_t indirect_address, uint8_t length);
00088 void aes_initvect_write_buf(const uint8_t *buf, uint8_t indirect_start_address, uint8_t length);
00089 
00090 //-----------------------------------------------------------------------------
00091 // Function implementations
00092 //-----------------------------------------------------------------------------
00093 
00094 void hal_aes_setup(bool decrypt, aes_modes_t mode, uint8_t *keyin, uint8_t *ivin)
00095 {
00096    if(keyin != NULL)
00097    {
00098       aes_keyin_write_buf(keyin, 0, AES_BUF_SIZE);
00099    }
00100 
00101    if(ivin)
00102    {
00103       aes_initvect_write_buf(ivin, 0, AES_BUF_SIZE);
00104       aes_set_mode(ECB);            // Dummy change of mode in order to load init-vector
00105       aes_set_mode(CBC);
00106    }
00107 
00108    if(decrypt)
00109    {
00110      AESCS=(AESCS & ~AESCS_E_D_MASK) | DECRYPT<<AESCS_E_D_BIT_POS;
00111    }
00112    else
00113    {
00114      AESCS=(AESCS & ~AESCS_E_D_MASK) | ENCRYPT<<AESCS_E_D_BIT_POS;
00115    }
00116 
00117    aes_set_mode(mode);
00118 }
00119 
00120 void hal_aes_crypt(uint8_t *dest_buf, uint8_t *src_buf)
00121 {
00122    aes_data_write_buf(src_buf, 0, AES_BUF_SIZE);
00123    aes_go();
00124    while(aes_busy());
00125    aes_data_read_buf(dest_buf, 0, AES_BUF_SIZE);
00126 }
00127 
00128 void hal_aes_get_dec_key(uint8_t *output_dec_key, uint8_t *input_enc_key)
00129 {
00130    uint8_t index, loop, rcon_int; //lint -esym(644, rcon_int) "variable may not have been initialized"
00131    for(index=0; index<16; index++)
00132    {
00133       output_dec_key[index]=input_enc_key[index];
00134    }
00135    for(loop=0; loop<10; loop++)
00136    {
00137       if(loop==0)
00138       {
00139          rcon_int=1;
00140       }
00141       else
00142       {
00143          rcon_int=((rcon_int & 0x80) ? (rcon_int<<1) ^ 0x1b : rcon_int<<1); // xtime operation
00144       }
00145 
00146       output_dec_key[0]^=S[output_dec_key[13]];
00147       output_dec_key[1]^=S[output_dec_key[14]];
00148       output_dec_key[2]^=S[output_dec_key[15]];
00149       output_dec_key[3]^=S[output_dec_key[12]];
00150       output_dec_key[0] ^= rcon_int;
00151 
00152       for(index=0; index < 12; index++)
00153       {
00154          output_dec_key[index+4]^=output_dec_key[index];
00155       }
00156    }
00157 }
00158 
00159 void aes_set_mode(uint8_t mode)
00160 {
00161    AESCS=(AESCS & ~AESCS_MODE_MASK) | mode<<2;
00162 }
00163 
00164 void aes_select_e_d(uint8_t operation)
00165 {
00166 
00167    AESCS=(AESCS & ~AESCS_E_D_MASK) | operation<<1;
00168 }
00169 
00170 void aes_go()
00171 {
00172    AESCS=AESCS | AESCS_GO_MASK;
00173 }
00174 
00175 uint8_t aes_busy()
00176 {
00177    return AESCS & AESCS_GO_MASK;
00178 }
00179 
00180 void aes_data_write_buf(uint8_t *buf, uint8_t indirect_start_address, uint8_t length)
00181 {
00182    int8_t index;
00183    AESIA2= (AESIA2 & ~AESIA2_DI_MASK) | (indirect_start_address << AESIA2_DI_B0_POS);
00184    for(index=length-1; index>=0; index--)
00185    {
00186       AESD=buf[index];
00187    }
00188 }
00189 
00190 void aes_data_read_buf(uint8_t *buf, uint8_t indirect_start_address, uint8_t length)
00191 {
00192    int8_t index;
00193    AESIA2= (AESIA2 & ~AESIA2_DO_MASK) | (indirect_start_address << AESIA2_DO_B0_POS);
00194    for(index=length-1; index>=0; index--)
00195    {
00196       buf[index]=AESD;
00197    }
00198 }
00199 
00200 void aes_keyin_write_buf(const uint8_t *buf, uint8_t indirect_start_address, uint8_t length)
00201 {
00202    int8_t index;
00203    AESIA1= (AESIA1 & ~AESIA1_KIN_MASK) | (indirect_start_address << AESIA1_KIN_B0_POS);
00204    for(index=length-1; index>=0; index--)
00205    {
00206       AESKIN=buf[index];
00207    }
00208 }
00209 
00210 void aes_initvect_write_buf(const uint8_t *buf, uint8_t indirect_start_address, uint8_t length)
00211 {
00212    int8_t index;
00213    AESIA1= (AESIA1 & ~AESIA1_IV_MASK) | (indirect_start_address << AESIA1_IV_B0_POS);
00214    for(index=length-1; index>=0; index--)
00215    {
00216       AESIV=buf[index];
00217    }
00218 }
00219 

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