/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/security/xyssl-0.9/library/aes.c

Go to the documentation of this file.
00001 /*
00002  *  FIPS-197 compliant AES implementation
00003  *
00004  *  Copyright (C) 2006-2007  Christophe Devine
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 /*
00021  *  The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
00022  *
00023  *  http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
00024  *  http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
00025  */
00026 
00027 #include "xyssl/config.h"
00028 
00029 #if defined(XYSSL_AES_C)
00030 
00031 #include "xyssl/aes.h"
00032 #include "xyssl/padlock.h"
00033 
00034 #include <string.h>
00035 
00036 /*
00037  * 32-bit integer manipulation macros (little endian)
00038  */
00039 #ifndef GET_ULONG_LE
00040 #define GET_ULONG_LE(n,b,i)                             \
00041 {                                                       \
00042     (n) = ( (unsigned long) (b)[(i)    ]       )        \
00043         | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
00044         | ( (unsigned long) (b)[(i) + 2] << 16 )        \
00045         | ( (unsigned long) (b)[(i) + 3] << 24 );       \
00046 }
00047 #endif
00048 
00049 #ifndef PUT_ULONG_LE
00050 #define PUT_ULONG_LE(n,b,i)                             \
00051 {                                                       \
00052     (b)[(i)    ] = (unsigned char) ( (n)       );       \
00053     (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
00054     (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
00055     (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
00056 }
00057 #endif
00058 
00059 #if defined(XYSSL_AES_ROM_TABLES)
00060 /*
00061  * Forward S-box
00062  */
00063 static const unsigned char FSb[256] =
00064 {
00065     0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
00066     0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
00067     0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
00068     0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
00069     0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
00070     0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
00071     0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
00072     0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
00073     0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
00074     0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
00075     0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
00076     0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
00077     0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
00078     0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
00079     0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
00080     0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
00081     0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
00082     0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
00083     0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
00084     0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
00085     0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
00086     0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
00087     0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
00088     0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
00089     0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
00090     0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
00091     0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
00092     0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
00093     0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
00094     0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
00095     0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
00096     0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
00097 };
00098 
00099 /*
00100  * Forward tables
00101  */
00102 #define FT \
00103 \
00104     V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
00105     V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
00106     V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
00107     V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
00108     V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
00109     V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
00110     V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
00111     V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
00112     V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
00113     V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
00114     V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
00115     V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
00116     V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
00117     V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
00118     V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
00119     V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
00120     V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
00121     V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
00122     V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
00123     V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
00124     V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
00125     V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
00126     V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
00127     V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
00128     V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
00129     V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
00130     V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
00131     V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
00132     V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
00133     V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
00134     V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
00135     V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
00136     V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
00137     V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
00138     V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
00139     V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
00140     V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
00141     V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
00142     V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
00143     V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
00144     V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
00145     V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
00146     V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
00147     V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
00148     V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
00149     V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
00150     V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
00151     V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
00152     V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
00153     V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
00154     V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
00155     V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
00156     V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
00157     V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
00158     V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
00159     V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
00160     V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
00161     V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
00162     V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
00163     V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
00164     V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
00165     V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
00166     V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
00167     V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
00168 
00169 #define V(a,b,c,d) 0x##a##b##c##d
00170 static const unsigned long FT0[256] = { FT };
00171 #undef V
00172 
00173 #define V(a,b,c,d) 0x##b##c##d##a
00174 static const unsigned long FT1[256] = { FT };
00175 #undef V
00176 
00177 #define V(a,b,c,d) 0x##c##d##a##b
00178 static const unsigned long FT2[256] = { FT };
00179 #undef V
00180 
00181 #define V(a,b,c,d) 0x##d##a##b##c
00182 static const unsigned long FT3[256] = { FT };
00183 #undef V
00184 
00185 #undef FT
00186 
00187 /*
00188  * Reverse S-box
00189  */
00190 static const unsigned char RSb[256] =
00191 {
00192     0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
00193     0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
00194     0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
00195     0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
00196     0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
00197     0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
00198     0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
00199     0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
00200     0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
00201     0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
00202     0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
00203     0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
00204     0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
00205     0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
00206     0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
00207     0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
00208     0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
00209     0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
00210     0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
00211     0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
00212     0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
00213     0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
00214     0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
00215     0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
00216     0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
00217     0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
00218     0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
00219     0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
00220     0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
00221     0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
00222     0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
00223     0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
00224 };
00225 
00226 /*
00227  * Reverse tables
00228  */
00229 #define RT \
00230 \
00231     V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
00232     V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
00233     V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
00234     V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
00235     V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
00236     V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
00237     V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
00238     V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
00239     V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
00240     V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
00241     V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
00242     V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
00243     V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
00244     V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
00245     V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
00246     V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
00247     V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
00248     V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
00249     V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
00250     V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
00251     V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
00252     V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
00253     V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
00254     V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
00255     V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
00256     V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
00257     V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
00258     V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
00259     V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
00260     V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
00261     V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
00262     V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
00263     V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
00264     V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
00265     V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
00266     V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
00267     V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
00268     V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
00269     V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
00270     V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
00271     V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
00272     V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
00273     V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
00274     V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
00275     V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
00276     V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
00277     V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
00278     V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
00279     V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
00280     V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
00281     V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
00282     V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
00283     V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
00284     V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
00285     V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
00286     V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
00287     V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
00288     V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
00289     V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
00290     V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
00291     V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
00292     V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
00293     V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
00294     V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
00295 
00296 #define V(a,b,c,d) 0x##a##b##c##d
00297 static const unsigned long RT0[256] = { RT };
00298 #undef V
00299 
00300 #define V(a,b,c,d) 0x##b##c##d##a
00301 static const unsigned long RT1[256] = { RT };
00302 #undef V
00303 
00304 #define V(a,b,c,d) 0x##c##d##a##b
00305 static const unsigned long RT2[256] = { RT };
00306 #undef V
00307 
00308 #define V(a,b,c,d) 0x##d##a##b##c
00309 static const unsigned long RT3[256] = { RT };
00310 #undef V
00311 
00312 #undef RT
00313 
00314 /*
00315  * Round constants
00316  */
00317 static const unsigned long RCON[10] =
00318 {
00319     0x00000001, 0x00000002, 0x00000004, 0x00000008,
00320     0x00000010, 0x00000020, 0x00000040, 0x00000080,
00321     0x0000001B, 0x00000036
00322 };
00323 
00324 #else
00325 
00326 /*
00327  * Forward S-box & tables
00328  */
00329 static unsigned char FSb[256];
00330 static unsigned long FT0[256]; 
00331 static unsigned long FT1[256]; 
00332 static unsigned long FT2[256]; 
00333 static unsigned long FT3[256]; 
00334 
00335 /*
00336  * Reverse S-box & tables
00337  */
00338 static unsigned char RSb[256];
00339 static unsigned long RT0[256];
00340 static unsigned long RT1[256];
00341 static unsigned long RT2[256];
00342 static unsigned long RT3[256];
00343 
00344 /*
00345  * Round constants
00346  */
00347 static unsigned long RCON[10];
00348 
00349 /*
00350  * Tables generation code
00351  */
00352 #define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
00353 #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
00354 #define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
00355 
00356 static int aes_init_done = 0;
00357 
00358 static void aes_gen_tables( void )
00359 {
00360     int i, x, y, z;
00361     int pow[256];
00362     int log[256];
00363 
00364     /*
00365      * compute pow and log tables over GF(2^8)
00366      */
00367     for( i = 0, x = 1; i < 256; i++ )
00368     {
00369         pow[i] = x;
00370         log[x] = i;
00371         x = ( x ^ XTIME( x ) ) & 0xFF;
00372     }
00373 
00374     /*
00375      * calculate the round constants
00376      */
00377     for( i = 0, x = 1; i < 10; i++ )
00378     {
00379         RCON[i] = (unsigned long) x;
00380         x = XTIME( x ) & 0xFF;
00381     }
00382 
00383     /*
00384      * generate the forward and reverse S-boxes
00385      */
00386     FSb[0x00] = 0x63;
00387     RSb[0x63] = 0x00;
00388 
00389     for( i = 1; i < 256; i++ )
00390     {
00391         x = pow[255 - log[i]];
00392 
00393         y  = x; y = ( (y << 1) | (y >> 7) ) & 0xFF;
00394         x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
00395         x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
00396         x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
00397         x ^= y ^ 0x63;
00398 
00399         FSb[i] = (unsigned char) x;
00400         RSb[x] = (unsigned char) i;
00401     }
00402 
00403     /*
00404      * generate the forward and reverse tables
00405      */
00406     for( i = 0; i < 256; i++ )
00407     {
00408         x = FSb[i];
00409         y = XTIME( x ) & 0xFF;
00410         z =  ( y ^ x ) & 0xFF;
00411 
00412         FT0[i] = ( (unsigned long) y       ) ^
00413                  ( (unsigned long) x <<  8 ) ^
00414                  ( (unsigned long) x << 16 ) ^
00415                  ( (unsigned long) z << 24 );
00416 
00417         FT1[i] = ROTL8( FT0[i] );
00418         FT2[i] = ROTL8( FT1[i] );
00419         FT3[i] = ROTL8( FT2[i] );
00420 
00421         x = RSb[i];
00422 
00423         RT0[i] = ( (unsigned long) MUL( 0x0E, x )       ) ^
00424                  ( (unsigned long) MUL( 0x09, x ) <<  8 ) ^
00425                  ( (unsigned long) MUL( 0x0D, x ) << 16 ) ^
00426                  ( (unsigned long) MUL( 0x0B, x ) << 24 );
00427 
00428         RT1[i] = ROTL8( RT0[i] );
00429         RT2[i] = ROTL8( RT1[i] );
00430         RT3[i] = ROTL8( RT2[i] );
00431     }
00432 }
00433 
00434 #endif
00435 
00436 /*
00437  * AES key schedule (encryption)
00438  */
00439 void aes_setkey_enc( aes_context *ctx, unsigned char *key, int keysize )
00440 {
00441     int i;
00442     unsigned long *RK;
00443 
00444 #if !defined(XYSSL_AES_ROM_TABLES)
00445     if( aes_init_done == 0 )
00446     {
00447         aes_gen_tables();
00448         aes_init_done = 1;
00449     }
00450 #endif
00451 
00452     switch( keysize )
00453     {
00454         case 128: ctx->nr = 10; break;
00455         case 192: ctx->nr = 12; break;
00456         case 256: ctx->nr = 14; break;
00457         default : return;
00458     }
00459 
00460 #if defined(PADLOCK_ALIGN16)
00461     ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
00462 #else
00463     ctx->rk = RK = ctx->buf;
00464 #endif
00465 
00466     for( i = 0; i < (keysize >> 5); i++ )
00467     {
00468         GET_ULONG_LE( RK[i], key, i << 2 );
00469     }
00470 
00471     switch( ctx->nr )
00472     {
00473         case 10:
00474 
00475             for( i = 0; i < 10; i++, RK += 4 )
00476             {
00477                 RK[4]  = RK[0] ^ RCON[i] ^
00478                     ( FSb[ ( RK[3] >>  8 ) & 0xFF ]       ) ^
00479                     ( FSb[ ( RK[3] >> 16 ) & 0xFF ] <<  8 ) ^
00480                     ( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
00481                     ( FSb[ ( RK[3]       ) & 0xFF ] << 24 );
00482 
00483                 RK[5]  = RK[1] ^ RK[4];
00484                 RK[6]  = RK[2] ^ RK[5];
00485                 RK[7]  = RK[3] ^ RK[6];
00486             }
00487             break;
00488 
00489         case 12:
00490 
00491             for( i = 0; i < 8; i++, RK += 6 )
00492             {
00493                 RK[6]  = RK[0] ^ RCON[i] ^
00494                     ( FSb[ ( RK[5] >>  8 ) & 0xFF ]       ) ^
00495                     ( FSb[ ( RK[5] >> 16 ) & 0xFF ] <<  8 ) ^
00496                     ( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
00497                     ( FSb[ ( RK[5]       ) & 0xFF ] << 24 );
00498 
00499                 RK[7]  = RK[1] ^ RK[6];
00500                 RK[8]  = RK[2] ^ RK[7];
00501                 RK[9]  = RK[3] ^ RK[8];
00502                 RK[10] = RK[4] ^ RK[9];
00503                 RK[11] = RK[5] ^ RK[10];
00504             }
00505             break;
00506 
00507         case 14:
00508 
00509             for( i = 0; i < 7; i++, RK += 8 )
00510             {
00511                 RK[8]  = RK[0] ^ RCON[i] ^
00512                     ( FSb[ ( RK[7] >>  8 ) & 0xFF ]       ) ^
00513                     ( FSb[ ( RK[7] >> 16 ) & 0xFF ] <<  8 ) ^
00514                     ( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
00515                     ( FSb[ ( RK[7]       ) & 0xFF ] << 24 );
00516 
00517                 RK[9]  = RK[1] ^ RK[8];
00518                 RK[10] = RK[2] ^ RK[9];
00519                 RK[11] = RK[3] ^ RK[10];
00520 
00521                 RK[12] = RK[4] ^
00522                     ( FSb[ ( RK[11]       ) & 0xFF ]       ) ^
00523                     ( FSb[ ( RK[11] >>  8 ) & 0xFF ] <<  8 ) ^
00524                     ( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
00525                     ( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
00526 
00527                 RK[13] = RK[5] ^ RK[12];
00528                 RK[14] = RK[6] ^ RK[13];
00529                 RK[15] = RK[7] ^ RK[14];
00530             }
00531             break;
00532 
00533         default:
00534 
00535             break;
00536     }
00537 }
00538 
00539 /*
00540  * AES key schedule (decryption)
00541  */
00542 void aes_setkey_dec( aes_context *ctx, unsigned char *key, int keysize )
00543 {
00544     int i, j;
00545     aes_context cty;
00546     unsigned long *RK;
00547     unsigned long *SK;
00548 
00549     switch( keysize )
00550     {
00551         case 128: ctx->nr = 10; break;
00552         case 192: ctx->nr = 12; break;
00553         case 256: ctx->nr = 14; break;
00554         default : return;
00555     }
00556 
00557 #if defined(PADLOCK_ALIGN16)
00558     ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
00559 #else
00560     ctx->rk = RK = ctx->buf;
00561 #endif
00562 
00563     aes_setkey_enc( &cty, key, keysize );
00564     SK = cty.rk + cty.nr * 4;
00565 
00566     *RK++ = *SK++;
00567     *RK++ = *SK++;
00568     *RK++ = *SK++;
00569     *RK++ = *SK++;
00570 
00571     for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
00572     {
00573         for( j = 0; j < 4; j++, SK++ )
00574         {
00575             *RK++ = RT0[ FSb[ ( *SK       ) & 0xFF ] ] ^
00576                     RT1[ FSb[ ( *SK >>  8 ) & 0xFF ] ] ^
00577                     RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
00578                     RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
00579         }
00580     }
00581 
00582     *RK++ = *SK++;
00583     *RK++ = *SK++;
00584     *RK++ = *SK++;
00585     *RK++ = *SK++;
00586 
00587     memset( &cty, 0, sizeof( aes_context ) );
00588 }
00589 
00590 #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)     \
00591 {                                               \
00592     X0 = *RK++ ^ FT0[ ( Y0       ) & 0xFF ] ^   \
00593                  FT1[ ( Y1 >>  8 ) & 0xFF ] ^   \
00594                  FT2[ ( Y2 >> 16 ) & 0xFF ] ^   \
00595                  FT3[ ( Y3 >> 24 ) & 0xFF ];    \
00596                                                 \
00597     X1 = *RK++ ^ FT0[ ( Y1       ) & 0xFF ] ^   \
00598                  FT1[ ( Y2 >>  8 ) & 0xFF ] ^   \
00599                  FT2[ ( Y3 >> 16 ) & 0xFF ] ^   \
00600                  FT3[ ( Y0 >> 24 ) & 0xFF ];    \
00601                                                 \
00602     X2 = *RK++ ^ FT0[ ( Y2       ) & 0xFF ] ^   \
00603                  FT1[ ( Y3 >>  8 ) & 0xFF ] ^   \
00604                  FT2[ ( Y0 >> 16 ) & 0xFF ] ^   \
00605                  FT3[ ( Y1 >> 24 ) & 0xFF ];    \
00606                                                 \
00607     X3 = *RK++ ^ FT0[ ( Y3       ) & 0xFF ] ^   \
00608                  FT1[ ( Y0 >>  8 ) & 0xFF ] ^   \
00609                  FT2[ ( Y1 >> 16 ) & 0xFF ] ^   \
00610                  FT3[ ( Y2 >> 24 ) & 0xFF ];    \
00611 }
00612 
00613 #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)     \
00614 {                                               \
00615     X0 = *RK++ ^ RT0[ ( Y0       ) & 0xFF ] ^   \
00616                  RT1[ ( Y3 >>  8 ) & 0xFF ] ^   \
00617                  RT2[ ( Y2 >> 16 ) & 0xFF ] ^   \
00618                  RT3[ ( Y1 >> 24 ) & 0xFF ];    \
00619                                                 \
00620     X1 = *RK++ ^ RT0[ ( Y1       ) & 0xFF ] ^   \
00621                  RT1[ ( Y0 >>  8 ) & 0xFF ] ^   \
00622                  RT2[ ( Y3 >> 16 ) & 0xFF ] ^   \
00623                  RT3[ ( Y2 >> 24 ) & 0xFF ];    \
00624                                                 \
00625     X2 = *RK++ ^ RT0[ ( Y2       ) & 0xFF ] ^   \
00626                  RT1[ ( Y1 >>  8 ) & 0xFF ] ^   \
00627                  RT2[ ( Y0 >> 16 ) & 0xFF ] ^   \
00628                  RT3[ ( Y3 >> 24 ) & 0xFF ];    \
00629                                                 \
00630     X3 = *RK++ ^ RT0[ ( Y3       ) & 0xFF ] ^   \
00631                  RT1[ ( Y2 >>  8 ) & 0xFF ] ^   \
00632                  RT2[ ( Y1 >> 16 ) & 0xFF ] ^   \
00633                  RT3[ ( Y0 >> 24 ) & 0xFF ];    \
00634 }
00635 
00636 /*
00637  * AES-ECB block encryption/decryption
00638  */
00639 void aes_crypt_ecb( aes_context *ctx,
00640                     int mode,
00641                     unsigned char input[16],
00642                     unsigned char output[16] )
00643 {
00644     int i;
00645     unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
00646 
00647 #if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
00648     if( padlock_supports( PADLOCK_ACE ) )
00649     {
00650         if( padlock_xcryptecb( ctx, mode, input, output ) == 0 )
00651             return;
00652     }
00653 #endif
00654 
00655     RK = ctx->rk;
00656 
00657     GET_ULONG_LE( X0, input,  0 ); X0 ^= *RK++;
00658     GET_ULONG_LE( X1, input,  4 ); X1 ^= *RK++;
00659     GET_ULONG_LE( X2, input,  8 ); X2 ^= *RK++;
00660     GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++;
00661 
00662     if( mode == AES_DECRYPT )
00663     {
00664         for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
00665         {
00666             AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
00667             AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
00668         }
00669 
00670         AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
00671 
00672         X0 = *RK++ ^ ( RSb[ ( Y0       ) & 0xFF ]       ) ^
00673                      ( RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
00674                      ( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
00675                      ( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
00676 
00677         X1 = *RK++ ^ ( RSb[ ( Y1       ) & 0xFF ]       ) ^
00678                      ( RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
00679                      ( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
00680                      ( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
00681 
00682         X2 = *RK++ ^ ( RSb[ ( Y2       ) & 0xFF ]       ) ^
00683                      ( RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
00684                      ( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
00685                      ( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
00686 
00687         X3 = *RK++ ^ ( RSb[ ( Y3       ) & 0xFF ]       ) ^
00688                      ( RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
00689                      ( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
00690                      ( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
00691     }
00692     else /* AES_ENCRYPT */
00693     {
00694         for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
00695         {
00696             AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
00697             AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
00698         }
00699 
00700         AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
00701 
00702         X0 = *RK++ ^ ( FSb[ ( Y0       ) & 0xFF ]       ) ^
00703                      ( FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
00704                      ( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
00705                      ( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
00706 
00707         X1 = *RK++ ^ ( FSb[ ( Y1       ) & 0xFF ]       ) ^
00708                      ( FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
00709                      ( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
00710                      ( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
00711 
00712         X2 = *RK++ ^ ( FSb[ ( Y2       ) & 0xFF ]       ) ^
00713                      ( FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
00714                      ( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
00715                      ( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
00716 
00717         X3 = *RK++ ^ ( FSb[ ( Y3       ) & 0xFF ]       ) ^
00718                      ( FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
00719                      ( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
00720                      ( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
00721     }
00722 
00723     PUT_ULONG_LE( X0, output,  0 );
00724     PUT_ULONG_LE( X1, output,  4 );
00725     PUT_ULONG_LE( X2, output,  8 );
00726     PUT_ULONG_LE( X3, output, 12 );
00727 }
00728 
00729 /*
00730  * AES-CBC buffer encryption/decryption
00731  */
00732 void aes_crypt_cbc( aes_context *ctx,
00733                     int mode,
00734                     int length,
00735                     unsigned char iv[16],
00736                     unsigned char *input,
00737                     unsigned char *output )
00738 {
00739     int i;
00740     unsigned char temp[16];
00741 
00742 #if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
00743     if( padlock_supports( PADLOCK_ACE ) )
00744     {
00745         if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
00746             return;
00747     }
00748 #endif
00749 
00750     if( mode == AES_DECRYPT )
00751     {
00752         while( length > 0 )
00753         {
00754             memcpy( temp, input, 16 );
00755             aes_crypt_ecb( ctx, mode, input, output );
00756 
00757             for( i = 0; i < 16; i++ )
00758                 output[i] = (unsigned char)( output[i] ^ iv[i] );
00759 
00760             memcpy( iv, temp, 16 );
00761 
00762             input  += 16;
00763             output += 16;
00764             length -= 16;
00765         }
00766     }
00767     else
00768     {
00769         while( length > 0 )
00770         {
00771             for( i = 0; i < 16; i++ )
00772                 output[i] = (unsigned char)( input[i] ^ iv[i] );
00773 
00774             aes_crypt_ecb( ctx, mode, output, output );
00775             memcpy( iv, output, 16 );
00776 
00777             input  += 16;
00778             output += 16;
00779             length -= 16;
00780         }
00781     }
00782 }
00783 
00784 /*
00785  * AES-CFB buffer encryption/decryption
00786  */
00787 void aes_crypt_cfb( aes_context *ctx,
00788                     int mode,
00789                     int length,
00790                     int *iv_off,
00791                     unsigned char iv[16],
00792                     unsigned char *input,
00793                     unsigned char *output )
00794 {
00795     int c, n = *iv_off;
00796 
00797     if( mode == AES_DECRYPT )
00798     {
00799         while( length-- )
00800         {
00801             if( n == 0 )
00802                 aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
00803 
00804             c = *input++;
00805             *output++ = (unsigned char)( c ^ iv[n] );
00806             iv[n] = (unsigned char) c;
00807 
00808             n = (n + 1) & 0x0F;
00809         }
00810     }
00811     else
00812     {
00813         while( length-- )
00814         {
00815             if( n == 0 )
00816                 aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
00817 
00818             iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
00819 
00820             n = (n + 1) & 0x0F;
00821         }
00822     }
00823 
00824     *iv_off = n;
00825 }
00826 
00827 #if defined(XYSSL_SELF_TEST)
00828 
00829 #include <stdio.h>
00830 
00831 /*
00832  * AES test vectors from:
00833  *
00834  * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
00835  */
00836 static const unsigned char aes_test_ecb_dec[3][16] =
00837 {
00838     { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
00839       0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
00840     { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
00841       0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
00842     { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
00843       0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
00844 };
00845 
00846 static const unsigned char aes_test_ecb_enc[3][16] =
00847 {
00848     { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
00849       0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
00850     { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
00851       0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
00852     { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
00853       0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
00854 };
00855 
00856 static const unsigned char aes_test_cbc_dec[3][16] =
00857 {
00858     { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
00859       0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
00860     { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
00861       0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
00862     { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
00863       0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
00864 };
00865 
00866 static const unsigned char aes_test_cbc_enc[3][16] =
00867 {
00868     { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
00869       0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
00870     { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
00871       0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
00872     { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
00873       0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
00874 };
00875 
00876 /*
00877  * AES-CFB test vectors (generated on 2008-02-12)
00878  */
00879 static const unsigned char aes_test_cfb_dec[3][16] =
00880 {
00881     { 0xBA, 0x75, 0x0C, 0xC9, 0x77, 0xF8, 0xD4, 0xE1,
00882       0x3E, 0x0F, 0xB5, 0x46, 0x2E, 0xA6, 0x33, 0xF6 },
00883     { 0xDB, 0x40, 0x4A, 0x98, 0x7B, 0xAA, 0xA3, 0xF3,
00884       0x92, 0x35, 0xAD, 0x58, 0x09, 0x9B, 0xFF, 0x6E },
00885     { 0xA8, 0x17, 0x41, 0x0E, 0x76, 0x71, 0x60, 0xE5,
00886       0xFD, 0x37, 0xC5, 0x43, 0xCC, 0xC8, 0xD6, 0xDA }
00887 };
00888 
00889 static const unsigned char aes_test_cfb_enc[3][16] =
00890 {
00891     { 0x45, 0x62, 0xC5, 0xA1, 0xF9, 0x10, 0x8F, 0xE0,
00892       0x87, 0x24, 0x25, 0x68, 0xB5, 0x12, 0xF3, 0x8B },
00893     { 0xB8, 0xD4, 0xD5, 0x09, 0xF5, 0xEE, 0x08, 0x38,
00894       0x48, 0x9B, 0x9D, 0xAD, 0x11, 0xB4, 0x2E, 0xD2 },
00895     { 0xE9, 0x10, 0x80, 0xDA, 0xEE, 0x2D, 0x81, 0xD9,
00896       0x41, 0x78, 0x91, 0xD5, 0x98, 0x78, 0xE1, 0xFA }
00897 };
00898 
00899 /*
00900  * Checkup routine
00901  */
00902 int aes_self_test( int verbose )
00903 {
00904     int i, j, u, v, offset;
00905     unsigned char key[32];
00906     unsigned char buf[16];
00907     unsigned char prv[16];
00908     unsigned char iv[16];
00909     aes_context ctx;
00910 
00911     memset( key, 0, 32 );
00912 
00913     /*
00914      * ECB mode
00915      */
00916     for( i = 0; i < 6; i++ )
00917     {
00918         u = i >> 1;
00919         v = i  & 1;
00920 
00921         if( verbose != 0 )
00922             printf( "  AES-ECB-%3d (%s): ", 128 + u * 64,
00923                     ( v == AES_DECRYPT ) ? "dec" : "enc" );
00924 
00925         memset( buf, 0, 16 );
00926 
00927         if( v == AES_DECRYPT )
00928         {
00929             aes_setkey_dec( &ctx, key, 128 + u * 64 );
00930 
00931             for( j = 0; j < 10000; j++ )
00932                 aes_crypt_ecb( &ctx, v, buf, buf );
00933 
00934             if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
00935             {
00936                 if( verbose != 0 )
00937                     printf( "failed\n" );
00938 
00939                 return( 1 );
00940             }
00941         }
00942         else
00943         {
00944             aes_setkey_enc( &ctx, key, 128 + u * 64 );
00945 
00946             for( j = 0; j < 10000; j++ )
00947                 aes_crypt_ecb( &ctx, v, buf, buf );
00948 
00949             if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 )
00950             {
00951                 if( verbose != 0 )
00952                     printf( "failed\n" );
00953 
00954                 return( 1 );
00955             }
00956         }
00957 
00958         if( verbose != 0 )
00959             printf( "passed\n" );
00960     }
00961 
00962     if( verbose != 0 )
00963         printf( "\n" );
00964 
00965     /*
00966      * CBC mode
00967      */
00968     for( i = 0; i < 6; i++ )
00969     {
00970         u = i >> 1;
00971         v = i  & 1;
00972 
00973         if( verbose != 0 )
00974             printf( "  AES-CBC-%3d (%s): ", 128 + u * 64,
00975                     ( v == AES_DECRYPT ) ? "dec" : "enc" );
00976 
00977         memset( iv , 0, 16 );
00978         memset( prv, 0, 16 );
00979         memset( buf, 0, 16 );
00980 
00981         if( v == AES_DECRYPT )
00982         {
00983             aes_setkey_dec( &ctx, key, 128 + u * 64 );
00984 
00985             for( j = 0; j < 10000; j++ )
00986                 aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
00987 
00988             if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
00989             {
00990                 if( verbose != 0 )
00991                     printf( "failed\n" );
00992 
00993                 return( 1 );
00994             }
00995         }
00996         else
00997         {
00998             aes_setkey_enc( &ctx, key, 128 + u * 64 );
00999 
01000             for( j = 0; j < 10000; j++ )
01001             {
01002                 unsigned char tmp[16];
01003 
01004                 aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
01005 
01006                 memcpy( tmp, prv, 16 );
01007                 memcpy( prv, buf, 16 );
01008                 memcpy( buf, tmp, 16 );
01009             }
01010 
01011             if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 )
01012             {
01013                 if( verbose != 0 )
01014                     printf( "failed\n" );
01015 
01016                 return( 1 );
01017             }
01018         }
01019 
01020         if( verbose != 0 )
01021             printf( "passed\n" );
01022     }
01023 
01024     if( verbose != 0 )
01025         printf( "\n" );
01026 
01027     /*
01028      * CFB mode
01029      */
01030     for( i = 0; i < 6; i++ )
01031     {
01032         u = i >> 1;
01033         v = i  & 1;
01034 
01035         if( verbose != 0 )
01036             printf( "  AES-CFB-%3d (%s): ", 128 + u * 64,
01037                     ( v == AES_DECRYPT ) ? "dec" : "enc" );
01038 
01039         memset( iv , 0, 16 );
01040         memset( buf, 0, 16 );
01041         offset = 0;
01042 
01043         if( v == AES_DECRYPT )
01044         {
01045             aes_setkey_dec( &ctx, key, 128 + u * 64 );
01046 
01047             for( j = 0; j < 10000; j++ )
01048                 aes_crypt_cfb( &ctx, v, 16, &offset, iv, buf, buf );
01049 
01050             if( memcmp( buf, aes_test_cfb_dec[u], 16 ) != 0 )
01051             {
01052                 if( verbose != 0 )
01053                     printf( "failed\n" );
01054 
01055                 return( 1 );
01056             }
01057         }
01058         else
01059         {
01060             aes_setkey_enc( &ctx, key, 128 + u * 64 );
01061 
01062             for( j = 0; j < 10000; j++ )
01063                 aes_crypt_cfb( &ctx, v, 16, &offset, iv, buf, buf );
01064 
01065             if( memcmp( buf, aes_test_cfb_enc[u], 16 ) != 0 )
01066             {
01067                 if( verbose != 0 )
01068                     printf( "failed\n" );
01069 
01070                 return( 1 );
01071             }
01072         }
01073 
01074         if( verbose != 0 )
01075             printf( "passed\n" );
01076     }
01077 
01078 
01079     if( verbose != 0 )
01080         printf( "\n" );
01081 
01082     return( 0 );
01083 }
01084 
01085 #endif
01086 
01087 #endif

Generated on Fri Jul 11 17:59:46 2008 for Mobile-C by  doxygen 1.5.4