Changeset 8a64320e in mainline for uspace/lib/crypto/aes.c
- Timestamp:
- 2015-04-23T23:40:14Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dcba819
- Parents:
- 09044cb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/crypto/aes.c
r09044cb r8a64320e 28 28 29 29 /** @file aes.c 30 * 30 * 31 31 * Implementation of AES-128 symmetric cipher cryptographic algorithm. 32 * 32 * 33 33 * Based on FIPS 197. 34 34 */ … … 37 37 #include <errno.h> 38 38 #include <mem.h> 39 40 39 #include "crypto.h" 41 40 42 41 /* Number of elements in rows/columns in AES arrays. */ 43 #define ELEMS 442 #define ELEMS 4 44 43 45 44 /* Number of elements (words) in cipher. */ 46 #define CIPHER_ELEMS 445 #define CIPHER_ELEMS 4 47 46 48 47 /* Length of AES block. */ 49 #define BLOCK_LEN 1648 #define BLOCK_LEN 16 50 49 51 50 /* Number of iterations in AES algorithm. */ 52 #define ROUNDS 10 53 54 /* 55 * Irreducible polynomial used in AES algorithm. 56 * 51 #define ROUNDS 10 52 53 /** Irreducible polynomial used in AES algorithm. 54 * 57 55 * NOTE: x^8 + x^4 + x^3 + x + 1. 58 */ 59 #define AES_IP 0x1B 60 61 /* Precomputed values for AES sub_byte transformation. */ 56 * 57 */ 58 #define AES_IP 0x1b 59 60 /** Precomputed values for AES sub_byte transformation. */ 62 61 static const uint8_t sbox[BLOCK_LEN][BLOCK_LEN] = { 63 62 { 64 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 63 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 65 64 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 66 65 }, 67 66 { 68 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 67 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 69 68 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 70 69 }, … … 74 73 }, 75 74 { 76 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 75 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 77 76 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 78 77 }, 79 78 { 80 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 79 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 81 80 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 82 81 }, 83 82 { 84 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 83 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 85 84 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf 86 85 }, 87 86 { 88 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 87 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 89 88 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 90 89 }, 91 90 { 92 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 91 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 93 92 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 94 93 }, 95 94 { 96 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 95 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 97 96 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 98 97 }, 99 98 { 100 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 99 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 101 100 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb 102 101 }, 103 102 { 104 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 103 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 105 104 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 106 105 }, 107 106 { 108 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 107 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 109 108 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 110 109 }, 111 110 { 112 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 111 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 113 112 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a 114 113 }, 115 114 { 116 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 115 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 117 116 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e 118 117 }, 119 118 { 120 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 119 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 121 120 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf 122 121 }, 123 122 { 124 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 123 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 125 124 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 126 125 } 127 126 }; 128 127 129 /* Precomputed values for AES inv_sub_byte transformation. */128 /** Precomputed values for AES inv_sub_byte transformation. */ 130 129 static uint8_t inv_sbox[BLOCK_LEN][BLOCK_LEN] = { 131 130 { 132 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 131 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 133 132 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb 134 133 }, 135 134 { 136 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 135 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 137 136 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb 138 137 }, 139 138 { 140 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 139 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 141 140 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e 142 141 }, 143 142 { 144 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 143 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 145 144 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 146 145 }, 147 146 { 148 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 147 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 149 148 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 150 149 }, 151 150 { 152 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 151 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 153 152 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 154 153 }, 155 154 { 156 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 155 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 157 156 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 158 157 }, 159 158 { 160 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 159 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 161 160 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b 162 161 }, 163 162 { 164 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 163 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 165 164 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 166 165 }, 167 166 { 168 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 167 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 169 168 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e 170 169 }, 171 170 { 172 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 171 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 173 172 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b 174 173 }, 175 174 { 176 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 175 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 177 176 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 178 177 }, 179 178 { 180 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 179 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 181 180 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f 182 181 }, 183 182 { 184 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 183 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 185 184 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef 186 185 }, 187 186 { 188 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 187 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 189 188 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 190 189 }, 191 190 { 192 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 191 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 193 192 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 194 193 } 195 194 }; 196 195 197 /* Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */196 /** Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */ 198 197 static const uint32_t r_con_array[] = { 199 0x01000000, 0x02000000, 0x04000000, 0x08000000,198 0x01000000, 0x02000000, 0x04000000, 0x08000000, 200 199 0x10000000, 0x20000000, 0x40000000, 0x80000000, 201 0x1 B000000, 0x36000000200 0x1b000000, 0x36000000 202 201 }; 203 202 204 /** 205 * Perform substitution transformation on given byte. 206 * 203 /** Perform substitution transformation on given byte. 204 * 207 205 * @param byte Input byte. 208 * @param inv Flag indicating whether to use inverse table.209 * 206 * @param inv Flag indicating whether to use inverse table. 207 * 210 208 * @return Substituted value. 209 * 211 210 */ 212 211 static uint8_t sub_byte(uint8_t byte, bool inv) … … 215 214 uint8_t j = byte & 0xF; 216 215 217 if (!inv) {216 if (!inv) 218 217 return sbox[i][j]; 219 } else { 220 return inv_sbox[i][j]; 221 } 222 } 223 224 /** 225 * Perform substitution transformation on state table. 226 * 218 219 return inv_sbox[i][j]; 220 } 221 222 /** Perform substitution transformation on state table. 223 * 227 224 * @param state State table to be modified. 228 * @param inv Flag indicating whether to use inverse table. 225 * @param inv Flag indicating whether to use inverse table. 226 * 229 227 */ 230 228 static void sub_bytes(uint8_t state[ELEMS][ELEMS], bool inv) … … 232 230 uint8_t val; 233 231 234 for (size_t i = 0; i < ELEMS; i++) {235 for (size_t j = 0; j < ELEMS; j++) {232 for (size_t i = 0; i < ELEMS; i++) { 233 for (size_t j = 0; j < ELEMS; j++) { 236 234 val = state[i][j]; 237 235 state[i][j] = sub_byte(val, inv); … … 240 238 } 241 239 242 /** 243 * Perform shift rows transformation on state table. 244 * 240 /** Perform shift rows transformation on state table. 241 * 245 242 * @param state State table to be modified. 243 * 246 244 */ 247 245 static void shift_rows(uint8_t state[ELEMS][ELEMS]) … … 249 247 uint8_t temp[ELEMS]; 250 248 251 for (size_t i = 1; i < ELEMS; i++) {249 for (size_t i = 1; i < ELEMS; i++) { 252 250 memcpy(temp, state[i], i); 253 251 memcpy(state[i], state[i] + i, ELEMS - i); … … 256 254 } 257 255 258 /** 259 * Perform inverted shift rows transformation on state table. 260 * 256 /** Perform inverted shift rows transformation on state table. 257 * 261 258 * @param state State table to be modified. 259 * 262 260 */ 263 261 static void inv_shift_rows(uint8_t state[ELEMS][ELEMS]) … … 265 263 uint8_t temp[ELEMS]; 266 264 267 for (size_t i = 1; i < ELEMS; i++) {265 for (size_t i = 1; i < ELEMS; i++) { 268 266 memcpy(temp, state[i], ELEMS - i); 269 267 memcpy(state[i], state[i] + ELEMS - i, i); … … 272 270 } 273 271 274 /** 275 * Multiplication in GF(2^8). 276 * 272 /** Multiplication in GF(2^8). 273 * 277 274 * @param x First factor. 278 275 * @param y Second factor. 279 * 276 * 280 277 * @return Multiplication of given factors in GF(2^8). 281 */ 282 static uint8_t galois_mult(uint8_t x, uint8_t y) { 283 uint8_t result = 0; 284 uint8_t F_bitH; 285 286 for(size_t i = 0; i < 8; i++) { 287 if (y & 1) 278 * 279 */ 280 static uint8_t galois_mult(uint8_t x, uint8_t y) 281 { 282 uint8_t result = 0; 283 uint8_t f_bith; 284 285 for (size_t i = 0; i < 8; i++) { 286 if (y & 1) 288 287 result ^= x; 289 F_bitH = (x & 0x80); 290 x <<= 1; 291 if (F_bitH) 292 x ^= AES_IP; 293 y >>= 1; 294 } 295 296 return result; 297 } 298 299 /** 300 * Perform mix columns transformation on state table. 301 * 288 289 f_bith = (x & 0x80); 290 x <<= 1; 291 292 if (f_bith) 293 x ^= AES_IP; 294 295 y >>= 1; 296 } 297 298 return result; 299 } 300 301 /** Perform mix columns transformation on state table. 302 * 302 303 * @param state State table to be modified. 304 * 303 305 */ 304 306 static void mix_columns(uint8_t state[ELEMS][ELEMS]) … … 307 309 memcpy(orig_state, state, BLOCK_LEN); 308 310 309 for(size_t j = 0; j < ELEMS; j++) { 310 state[0][j] = 311 galois_mult(0x2, orig_state[0][j]) ^ 312 galois_mult(0x3, orig_state[1][j]) ^ 313 orig_state[2][j] ^ 314 orig_state[3][j]; 315 state[1][j] = 316 orig_state[0][j] ^ 317 galois_mult(0x2, orig_state[1][j]) ^ 318 galois_mult(0x3, orig_state[2][j]) ^ 319 orig_state[3][j]; 320 state[2][j] = 321 orig_state[0][j] ^ 322 orig_state[1][j] ^ 323 galois_mult(0x2, orig_state[2][j]) ^ 324 galois_mult(0x3, orig_state[3][j]); 325 state[3][j] = 326 galois_mult(0x3, orig_state[0][j]) ^ 327 orig_state[1][j] ^ 328 orig_state[2][j] ^ 329 galois_mult(0x2, orig_state[3][j]); 330 } 331 } 332 333 /** 334 * Perform inverted mix columns transformation on state table. 335 * 311 for (size_t j = 0; j < ELEMS; j++) { 312 state[0][j] = 313 galois_mult(0x2, orig_state[0][j]) ^ 314 galois_mult(0x3, orig_state[1][j]) ^ 315 orig_state[2][j] ^ 316 orig_state[3][j]; 317 state[1][j] = 318 orig_state[0][j] ^ 319 galois_mult(0x2, orig_state[1][j]) ^ 320 galois_mult(0x3, orig_state[2][j]) ^ 321 orig_state[3][j]; 322 state[2][j] = 323 orig_state[0][j] ^ 324 orig_state[1][j] ^ 325 galois_mult(0x2, orig_state[2][j]) ^ 326 galois_mult(0x3, orig_state[3][j]); 327 state[3][j] = 328 galois_mult(0x3, orig_state[0][j]) ^ 329 orig_state[1][j] ^ 330 orig_state[2][j] ^ 331 galois_mult(0x2, orig_state[3][j]); 332 } 333 } 334 335 /** Perform inverted mix columns transformation on state table. 336 * 336 337 * @param state State table to be modified. 338 * 337 339 */ 338 340 static void inv_mix_columns(uint8_t state[ELEMS][ELEMS]) … … 341 343 memcpy(orig_state, state, BLOCK_LEN); 342 344 343 for(size_t j = 0; j < ELEMS; j++) { 344 state[0][j] = 345 galois_mult(0x0E, orig_state[0][j]) ^ 346 galois_mult(0x0B, orig_state[1][j]) ^ 347 galois_mult(0x0D, orig_state[2][j]) ^ 348 galois_mult(0x09, orig_state[3][j]); 349 state[1][j] = 350 galois_mult(0x09, orig_state[0][j]) ^ 351 galois_mult(0x0E, orig_state[1][j]) ^ 352 galois_mult(0x0B, orig_state[2][j]) ^ 353 galois_mult(0x0D, orig_state[3][j]); 354 state[2][j] = 355 galois_mult(0x0D, orig_state[0][j]) ^ 356 galois_mult(0x09, orig_state[1][j]) ^ 357 galois_mult(0x0E, orig_state[2][j]) ^ 358 galois_mult(0x0B, orig_state[3][j]); 359 state[3][j] = 360 galois_mult(0x0B, orig_state[0][j]) ^ 361 galois_mult(0x0D, orig_state[1][j]) ^ 362 galois_mult(0x09, orig_state[2][j]) ^ 363 galois_mult(0x0E, orig_state[3][j]); 364 } 365 } 366 367 /** 368 * Perform round key transformation on state table. 369 * 370 * @param state State table to be modified. 345 for (size_t j = 0; j < ELEMS; j++) { 346 state[0][j] = 347 galois_mult(0x0e, orig_state[0][j]) ^ 348 galois_mult(0x0b, orig_state[1][j]) ^ 349 galois_mult(0x0d, orig_state[2][j]) ^ 350 galois_mult(0x09, orig_state[3][j]); 351 state[1][j] = 352 galois_mult(0x09, orig_state[0][j]) ^ 353 galois_mult(0x0e, orig_state[1][j]) ^ 354 galois_mult(0x0b, orig_state[2][j]) ^ 355 galois_mult(0x0d, orig_state[3][j]); 356 state[2][j] = 357 galois_mult(0x0d, orig_state[0][j]) ^ 358 galois_mult(0x09, orig_state[1][j]) ^ 359 galois_mult(0x0e, orig_state[2][j]) ^ 360 galois_mult(0x0b, orig_state[3][j]); 361 state[3][j] = 362 galois_mult(0x0b, orig_state[0][j]) ^ 363 galois_mult(0x0d, orig_state[1][j]) ^ 364 galois_mult(0x09, orig_state[2][j]) ^ 365 galois_mult(0x0e, orig_state[3][j]); 366 } 367 } 368 369 /** Perform round key transformation on state table. 370 * 371 * @param state State table to be modified. 371 372 * @param round_key Round key to be applied on state table. 373 * 372 374 */ 373 375 static void add_round_key(uint8_t state[ELEMS][ELEMS], uint32_t *round_key) … … 375 377 uint8_t byte_round; 376 378 uint8_t shift; 377 uint32_t mask = 0x FF;378 379 for (size_t j = 0; j < ELEMS; j++) {380 for (size_t i = 0; i < ELEMS; i++) {381 shift = 24 - 8 *i;379 uint32_t mask = 0xff; 380 381 for (size_t j = 0; j < ELEMS; j++) { 382 for (size_t i = 0; i < ELEMS; i++) { 383 shift = 24 - 8 * i; 382 384 byte_round = (round_key[j] & (mask << shift)) >> shift; 383 385 state[i][j] = state[i][j] ^ byte_round; … … 386 388 } 387 389 388 /** 389 * Perform substitution transformation on given word. 390 * 390 /** Perform substitution transformation on given word. 391 * 391 392 * @param byte Input word. 392 * 393 * 393 394 * @return Substituted word. 395 * 394 396 */ 395 397 static uint32_t sub_word(uint32_t word) … … 398 400 uint8_t *start = (uint8_t *) &temp; 399 401 400 for(size_t i = 0; i < 4; i++) { 401 *(start+i) = sub_byte(*(start+i), false); 402 } 402 for (size_t i = 0; i < 4; i++) 403 *(start + i) = sub_byte(*(start + i), false); 403 404 404 405 return temp; 405 406 } 406 407 407 /** 408 * Perform left rotation by one byte on given word. 409 * 408 /** Perform left rotation by one byte on given word. 409 * 410 410 * @param byte Input word. 411 * 411 * 412 412 * @return Rotated word. 413 * 413 414 */ 414 415 static uint32_t rot_word(uint32_t word) … … 417 418 } 418 419 419 /** 420 * Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 420 /** Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 423 423 * @param key_exp Result key expansion. 424 * 424 425 */ 425 426 static void key_expansion(uint8_t *key, uint32_t *key_exp) … … 427 428 uint32_t temp; 428 429 429 for (size_t i = 0; i < CIPHER_ELEMS; i++) {430 key_exp[i] = 431 (key[4*i] << 24) +432 (key[4*i+1] << 16) +433 (key[4*i+2] << 8) +434 (key[4*i+3]);435 } 436 437 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) {438 temp = key_exp[i -1];439 440 if ((i % CIPHER_ELEMS) == 0) {441 temp = sub_word(rot_word(temp)) ^ 442 r_con_array[i/CIPHER_ELEMS - 1];430 for (size_t i = 0; i < CIPHER_ELEMS; i++) { 431 key_exp[i] = 432 (key[4 * i] << 24) + 433 (key[4 * i + 1] << 16) + 434 (key[4 * i + 2] << 8) + 435 (key[4 * i + 3]); 436 } 437 438 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) { 439 temp = key_exp[i - 1]; 440 441 if ((i % CIPHER_ELEMS) == 0) { 442 temp = sub_word(rot_word(temp)) ^ 443 r_con_array[i / CIPHER_ELEMS - 1]; 443 444 } 444 445 … … 447 448 } 448 449 449 /** 450 * AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 450 /** AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 454 454 * @param output Encrypted data sequence. 455 * 456 * @return EINVAL when input or key not specified, ENOMEM when pointer for 457 * output is not allocated, otherwise EOK. 455 * 456 * @return EINVAL when input or key not specified, 457 * ENOMEM when pointer for output is not allocated, 458 * otherwise EOK. 459 * 458 460 */ 459 461 int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output) 460 462 { 461 if (!key || !input)463 if ((!key) || (!input)) 462 464 return EINVAL; 463 465 464 if (!output)466 if (!output) 465 467 return ENOMEM; 466 468 467 469 /* Create key expansion. */ 468 uint32_t key_exp[ELEMS * (ROUNDS +1)];470 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 469 471 key_expansion(key, key_exp); 470 472 471 473 /* Copy input into state array. */ 472 474 uint8_t state[ELEMS][ELEMS]; 473 for(size_t i = 0; i < ELEMS; i++) { 474 for(size_t j = 0; j < ELEMS; j++) { 475 state[i][j] = input[i + ELEMS*j]; 476 } 475 for (size_t i = 0; i < ELEMS; i++) { 476 for (size_t j = 0; j < ELEMS; j++) 477 state[i][j] = input[i + ELEMS * j]; 477 478 } 478 479 … … 480 481 add_round_key(state, key_exp); 481 482 482 for (size_t k = 1; k <= ROUNDS; k++) {483 for (size_t k = 1; k <= ROUNDS; k++) { 483 484 sub_bytes(state, false); 484 485 shift_rows(state); 485 if(k < ROUNDS) 486 487 if (k < ROUNDS) 486 488 mix_columns(state); 487 add_round_key(state, key_exp + k*ELEMS); 489 490 add_round_key(state, key_exp + k * ELEMS); 488 491 } 489 492 490 493 /* Copy state array into output. */ 491 for(size_t i = 0; i < ELEMS; i++) { 492 for(size_t j = 0; j < ELEMS; j++) { 493 output[i + j*ELEMS] = state[i][j]; 494 } 494 for (size_t i = 0; i < ELEMS; i++) { 495 for (size_t j = 0; j < ELEMS; j++) 496 output[i + j * ELEMS] = state[i][j]; 495 497 } 496 498 … … 498 500 } 499 501 500 /** 501 * AES-128 decryption algorithm. 502 * 503 * @param key Input key. 504 * @param input Input data sequence to be decrypted. 502 /** AES-128 decryption algorithm. 503 * 504 * @param key Input key. 505 * @param input Input data sequence to be decrypted. 505 506 * @param output Decrypted data sequence. 506 * 507 * @return EINVAL when input or key not specified, ENOMEM when pointer for 508 * output is not allocated, otherwise EOK. 507 * 508 * @return EINVAL when input or key not specified, 509 * ENOMEM when pointer for output is not allocated, 510 * otherwise EOK. 511 * 509 512 */ 510 513 int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output) 511 514 { 512 if (!key || !input)515 if ((!key) || (!input)) 513 516 return EINVAL; 514 517 515 if (!output)518 if (!output) 516 519 return ENOMEM; 517 520 518 521 /* Create key expansion. */ 519 uint32_t key_exp[ELEMS * (ROUNDS +1)];522 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 520 523 key_expansion(key, key_exp); 521 524 522 525 /* Copy input into state array. */ 523 526 uint8_t state[ELEMS][ELEMS]; 524 for(size_t i = 0; i < ELEMS; i++) { 525 for(size_t j = 0; j < ELEMS; j++) { 526 state[i][j] = input[i + ELEMS*j]; 527 } 527 for (size_t i = 0; i < ELEMS; i++) { 528 for (size_t j = 0; j < ELEMS; j++) 529 state[i][j] = input[i + ELEMS * j]; 528 530 } 529 531 530 532 /* Processing loop. */ 531 add_round_key(state, key_exp + ROUNDS *ELEMS);532 533 for (int k = ROUNDS - 1; k >= 0; k--) {533 add_round_key(state, key_exp + ROUNDS * ELEMS); 534 535 for (int k = ROUNDS - 1; k >= 0; k--) { 534 536 inv_shift_rows(state); 535 537 sub_bytes(state, true); 536 add_round_key(state, key_exp + k*ELEMS); 537 if(k > 0) 538 add_round_key(state, key_exp + k * ELEMS); 539 540 if (k > 0) 538 541 inv_mix_columns(state); 539 542 } 540 543 541 544 /* Copy state array into output. */ 542 for(size_t i = 0; i < ELEMS; i++) { 543 for(size_t j = 0; j < ELEMS; j++) { 544 output[i + j*ELEMS] = state[i][j]; 545 } 545 for (size_t i = 0; i < ELEMS; i++) { 546 for (size_t j = 0; j < ELEMS; j++) 547 output[i + j * ELEMS] = state[i][j]; 546 548 } 547 549
Note:
See TracChangeset
for help on using the changeset viewer.