RadioShuttle Lib for the STM32 L4 Heltec Board
Dependents: Turtle_RadioShuttle
aes.c
00001 /* 00002 Downloaded from here: https://github.com/kokke/tiny-AES128-C 00003 This is an implementation of the AES128 algorithm, specifically ECB and CBC mode. 00004 00005 The implementation is verified against the test vectors in: 00006 National Institute of Standards and Technology Special Publication 800-38A 2001 ED 00007 00008 ECB-AES128 00009 ---------- 00010 00011 plain-text: 00012 6bc1bee22e409f96e93d7e117393172a 00013 ae2d8a571e03ac9c9eb76fac45af8e51 00014 30c81c46a35ce411e5fbc1191a0a52ef 00015 f69f2445df4f9b17ad2b417be66c3710 00016 00017 key: 00018 2b7e151628aed2a6abf7158809cf4f3c 00019 00020 resulting cipher 00021 3ad77bb40d7a3660a89ecaf32466ef97 00022 f5d3d58503b9699de785895a96fdbaaf 00023 43b1cd7f598ece23881b00e3ed030688 00024 7b0c785e27e8ad3f8223207104725dd4 00025 00026 00027 NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0) 00028 You should pad the end of the string with zeros if this is not the case. 00029 00030 */ 00031 00032 00033 /*****************************************************************************/ 00034 /* Includes: */ 00035 /*****************************************************************************/ 00036 #include <stdint.h> 00037 #include <string.h> // CBC mode, for memset 00038 #include "aes.h" 00039 00040 /*****************************************************************************/ 00041 /* Defines: */ 00042 /*****************************************************************************/ 00043 // The number of columns comprising a state in AES. This is a constant in AES. Value=4 00044 #define Nb 4 00045 // The number of 32 bit words in a key. 00046 #define Nk 4 00047 00048 // jcallan@github points out that declaring Multiply as a function 00049 // reduces code size considerably with the Keil ARM compiler. 00050 // See this link for more information: https://github.com/kokke/tiny-AES128-C/pull/3 00051 #ifndef MULTIPLY_AS_A_FUNCTION 00052 #define MULTIPLY_AS_A_FUNCTION 1 00053 #endif 00054 00055 /* 00056 * simple re-defines do use the existing code with a context 00057 */ 00058 #define state ctx->state 00059 #define RoundKey ctx->RoundKey 00060 #define Iv ctx->InitialVector 00061 #define KEYLEN AES128_KEYLEN 00062 00063 // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM 00064 // The numbers below can be computed dynamically trading ROM for RAM - 00065 // This can be useful in (embedded) bootloader applications, where ROM is often limited. 00066 static const uint8_t sbox[256] = { 00067 //0 1 2 3 4 5 6 7 8 9 A B C D E F 00068 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 00069 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 00070 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 00071 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 00072 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 00073 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 00074 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 00075 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 00076 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 00077 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 00078 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 00079 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 00080 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 00081 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 00082 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 00083 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; 00084 00085 static const uint8_t rsbox[256] = 00086 { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 00087 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 00088 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 00089 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 00090 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 00091 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 00092 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 00093 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 00094 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 00095 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 00096 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 00097 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 00098 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 00099 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 00100 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 00101 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; 00102 00103 00104 // The round constant word array, Rcon[i], contains the values given by 00105 // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) 00106 // Note that i starts at 1, not 0). 00107 static const uint8_t Rcon[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; 00108 00109 00110 /*****************************************************************************/ 00111 /* Private functions: */ 00112 /*****************************************************************************/ 00113 static uint8_t getSBoxValue(uint8_t num) 00114 { 00115 return sbox[num]; 00116 } 00117 00118 static uint8_t getSBoxInvert(uint8_t num) 00119 { 00120 return rsbox[num]; 00121 } 00122 00123 // This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. 00124 static void KeyExpansion(AES_CTX *ctx, const uint8_t* Key) 00125 { 00126 uint32_t i, j, k; 00127 uint8_t tempa[4]; // Used for the column/row operations 00128 00129 // The first round key is the key itself. 00130 for(i = 0; i < Nk; ++i) 00131 { 00132 RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; 00133 RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; 00134 RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; 00135 RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; 00136 } 00137 00138 // All other round keys are found from the previous round keys. 00139 for(; (i < (Nb * (Nr + 1))); ++i) 00140 { 00141 for(j = 0; j < 4; ++j) 00142 { 00143 tempa[j]=RoundKey[(i-1) * 4 + j]; 00144 } 00145 if (i % Nk == 0) 00146 { 00147 // This function rotates the 4 bytes in a word to the left once. 00148 // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] 00149 00150 // Function RotWord() 00151 { 00152 k = tempa[0]; 00153 tempa[0] = tempa[1]; 00154 tempa[1] = tempa[2]; 00155 tempa[2] = tempa[3]; 00156 tempa[3] = k; 00157 } 00158 00159 // SubWord() is a function that takes a four-byte input word and 00160 // applies the S-box to each of the four bytes to produce an output word. 00161 00162 // Function Subword() 00163 { 00164 tempa[0] = getSBoxValue(tempa[0]); 00165 tempa[1] = getSBoxValue(tempa[1]); 00166 tempa[2] = getSBoxValue(tempa[2]); 00167 tempa[3] = getSBoxValue(tempa[3]); 00168 } 00169 00170 tempa[0] = tempa[0] ^ Rcon[(i/Nk)-1]; 00171 } 00172 else if (Nk > 6 && i % Nk == 4) 00173 { 00174 // Function Subword() 00175 { 00176 tempa[0] = getSBoxValue(tempa[0]); 00177 tempa[1] = getSBoxValue(tempa[1]); 00178 tempa[2] = getSBoxValue(tempa[2]); 00179 tempa[3] = getSBoxValue(tempa[3]); 00180 } 00181 } 00182 RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0]; 00183 RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1]; 00184 RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2]; 00185 RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3]; 00186 } 00187 } 00188 00189 // This function adds the round key to state. 00190 // The round key is added to the state by an XOR function. 00191 static void AddRoundKey(AES_CTX *ctx, uint8_t round) 00192 { 00193 uint8_t i,j; 00194 for(i=0;i<4;++i) 00195 { 00196 for(j = 0; j < 4; ++j) 00197 { 00198 (*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j]; 00199 } 00200 } 00201 } 00202 00203 // The SubBytes Function Substitutes the values in the 00204 // state matrix with values in an S-box. 00205 static void SubBytes(AES_CTX *ctx) 00206 { 00207 uint8_t i, j; 00208 for(i = 0; i < 4; ++i) 00209 { 00210 for(j = 0; j < 4; ++j) 00211 { 00212 (*state)[j][i] = getSBoxValue((*state)[j][i]); 00213 } 00214 } 00215 } 00216 00217 // The ShiftRows() function shifts the rows in the state to the left. 00218 // Each row is shifted with different offset. 00219 // Offset = Row number. So the first row is not shifted. 00220 static void ShiftRows(AES_CTX *ctx) 00221 { 00222 uint8_t temp; 00223 00224 // Rotate first row 1 columns to left 00225 temp = (*state)[0][1]; 00226 (*state)[0][1] = (*state)[1][1]; 00227 (*state)[1][1] = (*state)[2][1]; 00228 (*state)[2][1] = (*state)[3][1]; 00229 (*state)[3][1] = temp; 00230 00231 // Rotate second row 2 columns to left 00232 temp = (*state)[0][2]; 00233 (*state)[0][2] = (*state)[2][2]; 00234 (*state)[2][2] = temp; 00235 00236 temp = (*state)[1][2]; 00237 (*state)[1][2] = (*state)[3][2]; 00238 (*state)[3][2] = temp; 00239 00240 // Rotate third row 3 columns to left 00241 temp = (*state)[0][3]; 00242 (*state)[0][3] = (*state)[3][3]; 00243 (*state)[3][3] = (*state)[2][3]; 00244 (*state)[2][3] = (*state)[1][3]; 00245 (*state)[1][3] = temp; 00246 } 00247 00248 static uint8_t xtime(uint8_t x) 00249 { 00250 return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); 00251 } 00252 00253 // MixColumns function mixes the columns of the state matrix 00254 static void MixColumns(AES_CTX *ctx) 00255 { 00256 uint8_t i; 00257 uint8_t Tmp,Tm,t; 00258 for(i = 0; i < 4; ++i) 00259 { 00260 t = (*state)[i][0]; 00261 Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ; 00262 Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ; 00263 Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ; 00264 Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ; 00265 Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ; 00266 } 00267 } 00268 00269 // Multiply is used to multiply numbers in the field GF(2^8) 00270 #if MULTIPLY_AS_A_FUNCTION 00271 static uint8_t Multiply(uint8_t x, uint8_t y) 00272 { 00273 return (((y & 1) * x) ^ 00274 ((y>>1 & 1) * xtime(x)) ^ 00275 ((y>>2 & 1) * xtime(xtime(x))) ^ 00276 ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ 00277 ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); 00278 } 00279 #else 00280 #define Multiply(x, y) \ 00281 ( ((y & 1) * x) ^ \ 00282 ((y>>1 & 1) * xtime(x)) ^ \ 00283 ((y>>2 & 1) * xtime(xtime(x))) ^ \ 00284 ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ 00285 ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ 00286 00287 #endif 00288 00289 // MixColumns function mixes the columns of the state matrix. 00290 // The method used to multiply may be difficult to understand for the inexperienced. 00291 // Please use the references to gain more information. 00292 static void InvMixColumns(AES_CTX *ctx) 00293 { 00294 int i; 00295 uint8_t a,b,c,d; 00296 for(i=0;i<4;++i) 00297 { 00298 a = (*state)[i][0]; 00299 b = (*state)[i][1]; 00300 c = (*state)[i][2]; 00301 d = (*state)[i][3]; 00302 00303 (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); 00304 (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); 00305 (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); 00306 (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); 00307 } 00308 } 00309 00310 00311 // The SubBytes Function Substitutes the values in the 00312 // state matrix with values in an S-box. 00313 static void InvSubBytes(AES_CTX *ctx) 00314 { 00315 uint8_t i,j; 00316 for(i=0;i<4;++i) 00317 { 00318 for(j=0;j<4;++j) 00319 { 00320 (*state)[j][i] = getSBoxInvert((*state)[j][i]); 00321 } 00322 } 00323 } 00324 00325 static void InvShiftRows(AES_CTX *ctx) 00326 { 00327 uint8_t temp; 00328 00329 // Rotate first row 1 columns to right 00330 temp=(*state)[3][1]; 00331 (*state)[3][1]=(*state)[2][1]; 00332 (*state)[2][1]=(*state)[1][1]; 00333 (*state)[1][1]=(*state)[0][1]; 00334 (*state)[0][1]=temp; 00335 00336 // Rotate second row 2 columns to right 00337 temp=(*state)[0][2]; 00338 (*state)[0][2]=(*state)[2][2]; 00339 (*state)[2][2]=temp; 00340 00341 temp=(*state)[1][2]; 00342 (*state)[1][2]=(*state)[3][2]; 00343 (*state)[3][2]=temp; 00344 00345 // Rotate third row 3 columns to right 00346 temp=(*state)[0][3]; 00347 (*state)[0][3]=(*state)[1][3]; 00348 (*state)[1][3]=(*state)[2][3]; 00349 (*state)[2][3]=(*state)[3][3]; 00350 (*state)[3][3]=temp; 00351 } 00352 00353 00354 // Cipher is the main function that encrypts the PlainText. 00355 static void Cipher(AES_CTX *ctx) 00356 { 00357 uint8_t round = 0; 00358 00359 // Add the First round key to the state before starting the rounds. 00360 AddRoundKey(ctx, 0); 00361 00362 // There will be Nr rounds. 00363 // The first Nr-1 rounds are identical. 00364 // These Nr-1 rounds are executed in the loop below. 00365 for(round = 1; round < Nr; ++round) 00366 { 00367 SubBytes(ctx); 00368 ShiftRows(ctx); 00369 MixColumns(ctx); 00370 AddRoundKey(ctx, round); 00371 } 00372 00373 // The last round is given below. 00374 // The MixColumns function is not here in the last round. 00375 SubBytes(ctx); 00376 ShiftRows(ctx); 00377 AddRoundKey(ctx, Nr); 00378 } 00379 00380 static void InvCipher(AES_CTX *ctx) 00381 { 00382 uint8_t round=0; 00383 00384 // Add the First round key to the state before starting the rounds. 00385 AddRoundKey(ctx, Nr); 00386 00387 // There will be Nr rounds. 00388 // The first Nr-1 rounds are identical. 00389 // These Nr-1 rounds are executed in the loop below. 00390 for(round=Nr-1;round>0;round--) 00391 { 00392 InvShiftRows(ctx); 00393 InvSubBytes(ctx); 00394 AddRoundKey(ctx, round); 00395 InvMixColumns(ctx); 00396 } 00397 00398 // The last round is given below. 00399 // The MixColumns function is not here in the last round. 00400 InvShiftRows(ctx); 00401 InvSubBytes(ctx); 00402 AddRoundKey(ctx, 0); 00403 } 00404 00405 00406 /*****************************************************************************/ 00407 /* Public functions: */ 00408 /*****************************************************************************/ 00409 00410 00411 void AES128_InitContext(AES_CTX *ctx, const uint8_t* key, const uint8_t* initialVector) 00412 { 00413 // The KeyExpansion routine must be called before encryption. 00414 KeyExpansion(ctx, key); 00415 if (initialVector) 00416 memcpy(ctx->InitialVector, initialVector, KEYLEN); 00417 00418 } 00419 #ifdef ECB_MODE 00420 00421 00422 void AES128_ECB_encrypt(AES_CTX *ctx, const uint8_t* input, uint8_t* output) 00423 { 00424 // Copy input to output, and work in-memory on output 00425 memcpy(output, input, KEYLEN); 00426 state = (state_t*)output; 00427 00428 // The next function call encrypts the PlainText with the Key using AES algorithm. 00429 Cipher(ctx); 00430 } 00431 00432 void AES128_ECB_decrypt(AES_CTX *ctx, const uint8_t* input, uint8_t *output) 00433 { 00434 // Copy input to output, and work in-memory on output 00435 memcpy(output, input, KEYLEN); 00436 state = (state_t*)output; 00437 00438 InvCipher(ctx); 00439 } 00440 00441 00442 #endif // ECB_MODE 00443 00444 00445 00446 00447 #ifdef CBC_MODE 00448 00449 00450 static void XorWithIv(AES_CTX *ctx, uint8_t* buf) 00451 { 00452 if (sizeof(int) == 4) { 00453 uint32_t *data = (uint32_t *)buf; 00454 uint32_t *iVec = (uint32_t *)Iv; 00455 00456 *data++ ^= *iVec++; 00457 *data++ ^= *iVec++; 00458 *data++ ^= *iVec++; 00459 *data++ ^= *iVec++; 00460 } else { 00461 uint8_t i; 00462 for(i = 0; i < KEYLEN; ++i) 00463 { 00464 buf[i] ^= Iv[i]; 00465 } 00466 } 00467 } 00468 00469 void AES128_CBC_encrypt_buffer(AES_CTX *ctx, uint8_t* output, const uint8_t* input, uint32_t length) 00470 { 00471 uintptr_t i; 00472 uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */ 00473 00474 00475 for(i = 0; i < length; i += KEYLEN) 00476 { 00477 memcpy(output, input, KEYLEN); 00478 XorWithIv(ctx, output); 00479 state = (state_t*)output; 00480 Cipher(ctx); 00481 memcpy(ctx->InitialVector, output, KEYLEN); 00482 input += KEYLEN; 00483 output += KEYLEN; 00484 } 00485 00486 if(remainders) 00487 { 00488 memcpy(output, input, KEYLEN); 00489 memset(output + remainders, 0, KEYLEN - remainders); /* add 0-padding */ 00490 state = (state_t*)output; 00491 Cipher(ctx); 00492 } 00493 } 00494 00495 void AES128_CBC_decrypt_buffer(AES_CTX *ctx, uint8_t* output, const uint8_t* input, uint32_t length) 00496 { 00497 uintptr_t i; 00498 uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */ 00499 00500 00501 for(i = 0; i < length; i += KEYLEN) 00502 { 00503 memcpy(output, input, KEYLEN); 00504 state = (state_t*)output; 00505 InvCipher(ctx); 00506 XorWithIv(ctx, output); 00507 memcpy(ctx->InitialVector, input, KEYLEN); 00508 input += KEYLEN; 00509 output += KEYLEN; 00510 } 00511 00512 if(remainders) 00513 { 00514 memcpy(output, input, KEYLEN); 00515 memset(output+remainders, 0, KEYLEN - remainders); /* add 0-padding */ 00516 state = (state_t*)output; 00517 InvCipher(ctx); 00518 } 00519 } 00520 00521 00522 #endif // CBC_MODE 00523 00524
Generated on Mon Jul 18 2022 05:09:52 by 1.7.2