00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <string.h>
00026 #include "crypto.h"
00027
00028
00029 #ifndef CONFIG_SSL_SKELETON_MODE
00030
00031 #define rot1(x) (((x) << 24) | ((x) >> 8))
00032 #define rot2(x) (((x) << 16) | ((x) >> 16))
00033 #define rot3(x) (((x) << 8) | ((x) >> 24))
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define mt 0x80808080
00047 #define ml 0x7f7f7f7f
00048 #define mh 0xfefefefe
00049 #define mm 0x1b1b1b1b
00050 #define mul2(x,t) ((t)=((x)&mt), \
00051 ((((x)+(x))&mh)^(((t)-((t)>>7))&mm)))
00052
00053 #define inv_mix_col(x,f2,f4,f8,f9) (\
00054 (f2)=mul2(x,f2), \
00055 (f4)=mul2(f2,f4), \
00056 (f8)=mul2(f4,f8), \
00057 (f9)=(x)^(f8), \
00058 (f8)=((f2)^(f4)^(f8)), \
00059 (f2)^=(f9), \
00060 (f4)^=(f9), \
00061 (f8)^=rot3(f2), \
00062 (f8)^=rot2(f4), \
00063 (f8)^rot1(f9))
00064
00065
00066 #define n2l(c,l) l=ntohl(*c); c++
00067 #define l2n(l,c) *c++=htonl(l)
00068
00069
00070
00071
00072 static const uint8_t aes_sbox[256] =
00073 {
00074 0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,
00075 0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
00076 0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,
00077 0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
00078 0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,
00079 0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
00080 0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,
00081 0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
00082 0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,
00083 0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
00084 0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,
00085 0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
00086 0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,
00087 0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
00088 0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,
00089 0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
00090 0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,
00091 0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
00092 0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,
00093 0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
00094 0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,
00095 0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
00096 0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,
00097 0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
00098 0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,
00099 0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
00100 0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,
00101 0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
00102 0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,
00103 0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
00104 0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,
00105 0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16,
00106 };
00107
00108
00109
00110
00111 static const uint8_t aes_isbox[256] =
00112 {
00113 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
00114 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
00115 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
00116 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
00117 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
00118 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
00119 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
00120 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
00121 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
00122 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
00123 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
00124 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
00125 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
00126 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
00127 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
00128 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
00129 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
00130 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
00131 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
00132 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
00133 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
00134 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
00135 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
00136 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
00137 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
00138 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
00139 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
00140 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
00141 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
00142 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
00143 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
00144 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
00145 };
00146
00147 static const unsigned char Rcon[30]=
00148 {
00149 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
00150 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f,
00151 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4,
00152 0xb3,0x7d,0xfa,0xef,0xc5,0x91,
00153 };
00154
00155
00156
00157 static unsigned char AES_xtime(uint32_t x)
00158 {
00159 return x = (x&0x80) ? (x<<1)^0x1b : x<<1;
00160 }
00161
00162
00163
00164
00165 void AES_set_key(AES_CTX *ctx, const uint8_t *key,
00166 const uint8_t *iv, AES_MODE mode)
00167 {
00168 int i, ii;
00169 uint32_t *W, tmp, tmp2;
00170 const unsigned char *ip;
00171 int words;
00172
00173 switch (mode)
00174 {
00175 case AES_MODE_128:
00176 i = 10;
00177 words = 4;
00178 break;
00179
00180 case AES_MODE_256:
00181 i = 14;
00182 words = 8;
00183 break;
00184
00185 default:
00186 return;
00187 }
00188
00189 ctx->rounds = i;
00190 ctx->key_size = words;
00191 W = ctx->ks;
00192 for (i = 0; i < words; i+=2)
00193 {
00194 W[i+0]= ((uint32_t)key[ 0]<<24)|
00195 ((uint32_t)key[ 1]<<16)|
00196 ((uint32_t)key[ 2]<< 8)|
00197 ((uint32_t)key[ 3] );
00198 W[i+1]= ((uint32_t)key[ 4]<<24)|
00199 ((uint32_t)key[ 5]<<16)|
00200 ((uint32_t)key[ 6]<< 8)|
00201 ((uint32_t)key[ 7] );
00202 key += 8;
00203 }
00204
00205 ip = Rcon;
00206 ii = 4 * (ctx->rounds+1);
00207 for (i = words; i<ii; i++)
00208 {
00209 tmp = W[i-1];
00210
00211 if ((i % words) == 0)
00212 {
00213 tmp2 =(uint32_t)aes_sbox[(tmp )&0xff]<< 8;
00214 tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<<16;
00215 tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24;
00216 tmp2|=(uint32_t)aes_sbox[(tmp>>24) ];
00217 tmp=tmp2^(((unsigned int)*ip)<<24);
00218 ip++;
00219 }
00220
00221 if ((words == 8) && ((i % words) == 4))
00222 {
00223 tmp2 =(uint32_t)aes_sbox[(tmp )&0xff] ;
00224 tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8;
00225 tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16;
00226 tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]<<24;
00227 tmp=tmp2;
00228 }
00229
00230 W[i]=W[i-words]^tmp;
00231 }
00232
00233
00234 memcpy(ctx->iv, iv, 16);
00235 }
00236
00237
00238
00239
00240 void AES_convert_key(AES_CTX *ctx)
00241 {
00242 int i;
00243 uint32_t *k,w,t1,t2,t3,t4;
00244
00245 k = ctx->ks;
00246 k += 4;
00247
00248 for (i=ctx->rounds*4; i>4; i--)
00249 {
00250 w= *k;
00251 w = inv_mix_col(w,t1,t2,t3,t4);
00252 *k++ =w;
00253 }
00254 }
00255
00256 #if 0
00257
00258
00259
00260 void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
00261 {
00262 uint32_t tin0, tin1, tin2, tin3;
00263 uint32_t tout0, tout1, tout2, tout3;
00264 uint32_t tin[4];
00265 uint32_t *iv = (uint32_t *)ctx->iv;
00266 uint32_t *msg_32 = (uint32_t *)msg;
00267 uint32_t *out_32 = (uint32_t *)out;
00268
00269 n2l(iv, tout0);
00270 n2l(iv, tout1);
00271 n2l(iv, tout2);
00272 n2l(iv, tout3);
00273 iv -= 4;
00274
00275 for (length -= 16; length >= 0; length -= 16)
00276 {
00277 n2l(msg_32, tin0);
00278 n2l(msg_32, tin1);
00279 n2l(msg_32, tin2);
00280 n2l(msg_32, tin3);
00281 tin[0] = tin0^tout0;
00282 tin[1] = tin1^tout1;
00283 tin[2] = tin2^tout2;
00284 tin[3] = tin3^tout3;
00285
00286 AES_encrypt(ctx, tin);
00287
00288 tout0 = tin[0];
00289 l2n(tout0, out_32);
00290 tout1 = tin[1];
00291 l2n(tout1, out_32);
00292 tout2 = tin[2];
00293 l2n(tout2, out_32);
00294 tout3 = tin[3];
00295 l2n(tout3, out_32);
00296 }
00297
00298 l2n(tout0, iv);
00299 l2n(tout1, iv);
00300 l2n(tout2, iv);
00301 l2n(tout3, iv);
00302 }
00303
00304
00305
00306
00307 void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
00308 {
00309 uint32_t tin0, tin1, tin2, tin3;
00310 uint32_t xor0,xor1,xor2,xor3;
00311 uint32_t tout0,tout1,tout2,tout3;
00312 uint32_t data[4];
00313 uint32_t *iv = (uint32_t *)ctx->iv;
00314 uint32_t *msg_32 = (uint32_t *)msg;
00315 uint32_t *out_32 = (uint32_t *)out;
00316
00317 n2l(iv ,xor0);
00318 n2l(iv, xor1);
00319 n2l(iv, xor2);
00320 n2l(iv, xor3);
00321 iv -= 4;
00322
00323 for (length-=16; length >= 0; length -= 16)
00324 {
00325 n2l(msg_32, tin0);
00326 n2l(msg_32, tin1);
00327 n2l(msg_32, tin2);
00328 n2l(msg_32, tin3);
00329
00330 data[0] = tin0;
00331 data[1] = tin1;
00332 data[2] = tin2;
00333 data[3] = tin3;
00334
00335 AES_decrypt(ctx, data);
00336
00337 tout0 = data[0]^xor0;
00338 tout1 = data[1]^xor1;
00339 tout2 = data[2]^xor2;
00340 tout3 = data[3]^xor3;
00341
00342 xor0 = tin0;
00343 xor1 = tin1;
00344 xor2 = tin2;
00345 xor3 = tin3;
00346
00347 l2n(tout0, out_32);
00348 l2n(tout1, out_32);
00349 l2n(tout2, out_32);
00350 l2n(tout3, out_32);
00351 }
00352
00353 l2n(xor0, iv);
00354 l2n(xor1, iv);
00355 l2n(xor2, iv);
00356 l2n(xor3, iv);
00357 }
00358 #endif
00359
00360
00361
00362
00363 void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
00364 {
00365
00366
00367
00368 uint32_t tmp[4];
00369 uint32_t tmp1, old_a0, a0, a1, a2, a3, row;
00370 int curr_rnd;
00371 int rounds = ctx->rounds;
00372 const uint32_t *k = ctx->ks;
00373
00374
00375 for (row = 0; row < 4; row++)
00376 {
00377 data[row] ^= *(k++);
00378 }
00379
00380
00381 for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
00382 {
00383
00384 for (row = 0; row < 4; row++)
00385 {
00386 a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF];
00387 a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF];
00388 a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF];
00389 a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF];
00390
00391
00392 if (curr_rnd < (rounds - 1))
00393 {
00394 tmp1 = a0 ^ a1 ^ a2 ^ a3;
00395 old_a0 = a0;
00396
00397 a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
00398 a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
00399 a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
00400 a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);
00401
00402 }
00403
00404 tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3);
00405 }
00406
00407
00408
00409 for (row = 0; row < 4; row++)
00410 {
00411 data[row] = tmp[row] ^ *(k++);
00412 }
00413 }
00414 }
00415
00416
00417
00418
00419 void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
00420 {
00421 uint32_t tmp[4];
00422 uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6;
00423 uint32_t a0, a1, a2, a3, row;
00424 int curr_rnd;
00425 int rounds = ctx->rounds;
00426 uint32_t *k = (uint32_t*)ctx->ks + ((rounds+1)*4);
00427
00428
00429 for (row=4; row > 0;row--)
00430 {
00431 data[row-1] ^= *(--k);
00432 }
00433
00434
00435 for (curr_rnd=0; curr_rnd < rounds; curr_rnd++)
00436 {
00437
00438 for (row = 4; row > 0; row--)
00439 {
00440 a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF];
00441 a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF];
00442 a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF];
00443 a3 = aes_isbox[(data[row%4])&0xFF];
00444
00445
00446 if (curr_rnd<(rounds-1))
00447 {
00448
00449
00450
00451 xt0 = AES_xtime(a0^a1);
00452 xt1 = AES_xtime(a1^a2);
00453 xt2 = AES_xtime(a2^a3);
00454 xt3 = AES_xtime(a3^a0);
00455 xt4 = AES_xtime(xt0^xt1);
00456 xt5 = AES_xtime(xt1^xt2);
00457 xt6 = AES_xtime(xt4^xt5);
00458
00459 xt0 ^= a1^a2^a3^xt4^xt6;
00460 xt1 ^= a0^a2^a3^xt5^xt6;
00461 xt2 ^= a0^a1^a3^xt4^xt6;
00462 xt3 ^= a0^a1^a2^xt5^xt6;
00463 tmp[row-1] = ((xt0<<24)|(xt1<<16)|(xt2<<8)|xt3);
00464 }
00465 else
00466 tmp[row-1] = ((a0<<24)|(a1<<16)|(a2<<8)|a3);
00467 }
00468
00469 for (row = 4; row > 0; row--)
00470 {
00471 data[row-1] = tmp[row-1] ^ *(--k);
00472 }
00473 }
00474 }
00475
00476 #endif