Embedded systems coursework 2.
Fork of Crypto_light by
Embed:
(wiki syntax)
Show/hide line numbers
AES.cpp
00001 #include "AES.h" 00002 #include <string.h> 00003 #include <stdio.h> 00004 #include <stdlib.h> 00005 00006 static const uint8_t sbox[] = 00007 { 00008 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 00009 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 00010 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 00011 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 00012 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 00013 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 00014 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 00015 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 00016 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 00017 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 00018 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 00019 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 00020 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 00021 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 00022 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 00023 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 00024 }; 00025 00026 static const uint8_t inv_s[] = 00027 { 00028 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 00029 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 00030 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 00031 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 00032 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 00033 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 00034 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 00035 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 00036 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 00037 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 00038 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 00039 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 00040 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 00041 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 00042 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 00043 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 00044 }; 00045 00046 00047 static const uint32_t rcon[10]= 00048 { 00049 0x01000000, 0x02000000, 0x04000000, 0x08000000, 00050 0x10000000, 0x20000000, 0x40000000, 0x80000000, 00051 0x1B000000, 0x36000000 00052 }; 00053 00054 AES::AES(const AES_TYPE t, uint8_t *key): 00055 BlockCipher(16,ECB_MODE), 00056 state() 00057 { 00058 switch(t) 00059 { 00060 case AES_128: 00061 nr = 10; 00062 nk = 4; 00063 break; 00064 00065 case AES_192: 00066 nr = 12; 00067 nk = 6; 00068 break; 00069 00070 case AES_256: 00071 nr = 14; 00072 nk = 8; 00073 break; 00074 } 00075 00076 keyExpansion(key); 00077 } 00078 00079 AES::AES(const AES_TYPE t, uint8_t *key, uint8_t *iv): 00080 BlockCipher(16,CBC_MODE, iv), 00081 state() 00082 { 00083 switch(t) 00084 { 00085 case AES_128: 00086 nr = 10; 00087 nk = 4; 00088 break; 00089 00090 case AES_192: 00091 nr = 12; 00092 nk = 6; 00093 break; 00094 00095 case AES_256: 00096 nr = 14; 00097 nk = 8; 00098 break; 00099 } 00100 00101 keyExpansion(key); 00102 } 00103 00104 void AES::keyExpansion(uint8_t *key) 00105 { 00106 uint32_t temp; 00107 int i = 0; 00108 00109 while(i < nk) 00110 { 00111 w[i] = (key[4*i] << 24) + (key[4*i+1] << 16) + (key[4*i+2] << 8) + key[4*i+3]; 00112 i++; 00113 } 00114 i = nk; 00115 while(i < 4*(nr+1)) 00116 { 00117 temp = w[i-1]; 00118 if(i % nk == 0) 00119 { 00120 temp = rotWord(temp); 00121 temp = subWord(temp); 00122 temp ^= rcon[i/nk-1]; 00123 } 00124 else if(nk > 6 && i % nk == 4) 00125 temp = subWord(temp); 00126 w[i] = w[i-nk] ^ temp; 00127 i++; 00128 } 00129 } 00130 00131 uint32_t AES::rotWord(uint32_t w) 00132 { 00133 return (w << 8) + (w >> 24); 00134 } 00135 00136 uint32_t AES::invRotWord(uint32_t w) 00137 { 00138 return (w >> 8) + (w << 24); 00139 } 00140 00141 uint32_t AES::subWord(uint32_t w) 00142 { 00143 uint32_t out = 0; 00144 for(int i = 0; i < 4; ++i) 00145 { 00146 uint8_t temp = (w & 0xFF); 00147 out |= (sbox[temp] << (8*i)); 00148 w = (w >> 8); 00149 } 00150 return out; 00151 } 00152 00153 void AES::subBytes() 00154 { 00155 for(int i = 0; i < 16; ++i) 00156 state[i] = sbox[state[i]]; 00157 } 00158 00159 void AES::invSubBytes() 00160 { 00161 for(int i = 0; i < 16; ++i) 00162 state[i] = inv_s[state[i]]; 00163 } 00164 00165 void AES::shiftRows() 00166 { 00167 for(int r = 0; r < 4; ++r) 00168 { 00169 uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12]; 00170 int i = r; 00171 while(i > 0) 00172 { 00173 temp = rotWord(temp); 00174 --i; 00175 } 00176 state[r] = temp >> 24; 00177 state[r+4] = temp >> 16; 00178 state[r+8] = temp >> 8; 00179 state[r+12] = temp; 00180 } 00181 } 00182 00183 void AES::invShiftRows() 00184 { 00185 for(int r = 0; r < 4; ++r) 00186 { 00187 uint32_t temp = (state[r] << 24) + (state[r+4] << 16) + (state[r+8] << 8) + state[r+12]; 00188 int i = r; 00189 while(i > 0) 00190 { 00191 temp = invRotWord(temp); 00192 --i; 00193 } 00194 state[r] = temp >> 24; 00195 state[r+4] = temp >> 16; 00196 state[r+8] = temp >> 8; 00197 state[r+12] = temp; 00198 } 00199 } 00200 00201 /* Multiply two numbers in the GF(2^8) finite field defined 00202 * by the polynomial x^8 + x^4 + x^3 + x + 1 */ 00203 uint8_t gmul(uint8_t a, uint8_t b) 00204 { 00205 uint8_t p = 0; 00206 uint8_t counter; 00207 uint8_t carry; 00208 for (counter = 0; counter < 8; counter++) { 00209 if (b & 1) 00210 p ^= a; 00211 carry = (a & 0x80); 00212 a <<= 1; 00213 if (carry) 00214 a ^= 0x001B; /* what x^8 is modulo x^8 + x^4 + x^3 + x^2 + 1 */ 00215 b >>= 1; 00216 } 00217 return p; 00218 } 00219 00220 void AES::mul(uint8_t *r) 00221 { 00222 uint8_t tmp[4]; 00223 memcpy(tmp, r, 4); 00224 r[0] = gmul(tmp[0],2) ^ gmul(tmp[1],3) ^ tmp[2] ^ tmp[3]; 00225 r[1] = tmp[0] ^ gmul(tmp[1],2) ^ gmul(tmp[2],3) ^ tmp[3]; 00226 r[2] = tmp[0] ^ tmp[1] ^ gmul(tmp[2],2) ^ gmul(tmp[3],3); 00227 r[3] = gmul(tmp[0],3) ^ tmp[1] ^ tmp[2] ^ gmul(tmp[3],2); 00228 } 00229 00230 void AES::invMul(uint8_t *r) 00231 { 00232 uint8_t tmp[4]; 00233 memcpy(tmp, r, 4); 00234 r[0] = gmul(tmp[0],0x0e) ^ gmul(tmp[1],0x0b) ^ gmul(tmp[2],0x0d) ^ gmul(tmp[3],9); 00235 r[1] = gmul(tmp[0],9) ^ gmul(tmp[1],0x0e) ^ gmul(tmp[2],0x0b) ^ gmul(tmp[3],0x0d); 00236 r[2] = gmul(tmp[0],0x0d) ^ gmul(tmp[1],9) ^ gmul(tmp[2],0x0e) ^ gmul(tmp[3],0x0b); 00237 r[3] = gmul(tmp[0],0x0b) ^ gmul(tmp[1],0x0d) ^ gmul(tmp[2],9) ^ gmul(tmp[3],0x0e); 00238 } 00239 00240 void AES::mixColumns() 00241 { 00242 for(int c = 0; c < 4; ++c) 00243 mul(&state[4*c]); 00244 } 00245 00246 void AES::invMixColumns() 00247 { 00248 for(int c = 0; c < 4; ++c) 00249 invMul(&state[4*c]); 00250 } 00251 00252 void AES::addRoundKey(int round) 00253 { 00254 for(int c = 0; c < 4; ++c) 00255 { 00256 uint32_t temp = (state[4*c] << 24) + (state[4*c+1] << 16) + (state[4*c+2] << 8) + state[4*c+3]; 00257 temp ^= w[round*4+c]; 00258 state[4*c] = temp >> 24; 00259 state[4*c+1] = temp >> 16; 00260 state[4*c+2] = temp >> 8; 00261 state[4*c+3] = temp; 00262 } 00263 } 00264 00265 void AES::decryptBlock(uint8_t *out, uint8_t *in) 00266 { 00267 memcpy(state,in,16); 00268 00269 addRoundKey(nr); 00270 00271 for(int round = nr-1; round > 0; --round) 00272 { 00273 invShiftRows(); 00274 invSubBytes(); 00275 addRoundKey(round); 00276 invMixColumns(); 00277 } 00278 invShiftRows(); 00279 invSubBytes(); 00280 addRoundKey(0); 00281 00282 memcpy(out, state, 16); 00283 } 00284 00285 void AES::encryptBlock(uint8_t *out, uint8_t *in) 00286 { 00287 memcpy(state,in,16); 00288 00289 addRoundKey(0); 00290 00291 for(int round = 1; round < nr; ++round) 00292 { 00293 subBytes(); 00294 shiftRows(); 00295 mixColumns(); 00296 addRoundKey(round); 00297 } 00298 subBytes(); 00299 shiftRows(); 00300 addRoundKey(nr); 00301 00302 memcpy(out, state, 16); 00303 }
Generated on Wed Jul 20 2022 22:55:43 by 1.7.2