1 /* 2 * aes_tables.c 3 * 4 * generate tables for the AES cipher 5 * 6 * David A. McGrew 7 * Cisco Systems, Inc. 8 */ 9 /* 10 * 11 * Copyright(c) 2001-2006 Cisco Systems, Inc. 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 18 * Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * Neither the name of the Cisco Systems, Inc. nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 41 * OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 #include <stdio.h> 46 #include "gf2_8.h" 47 #include "crypto_math.h" 48 49 50 unsigned char aes_sbox[256]; 51 52 unsigned char aes_inv_sbox[256]; 53 54 uint32_t T0[256], T1[256], T2[256], T3[256], T4[256]; 55 56 57 #define AES_INVERSE_TEST 0 /* set to 1 to test forward/backwards aes */ 58 59 /* functions for precomputing AES values */ 60 61 /* 62 * A[] is the 8 x 8 binary matrix (represented as an array of columns, 63 * where each column is an octet) which defines the affine 64 * transformation used in the AES substitution table (Section 65 * 4.2.1 of the spec). 66 */ 67 68 uint8_t A[8] = { 31, 62, 124, 248, 241, 227, 199, 143 }; 69 70 /* 71 * b is the 8 bit vector (represented as an octet) used in the affine 72 * transform described above. 73 */ 74 75 uint8_t b = 99; 76 77 78 void 79 aes_init_sbox(void) { 80 unsigned int i; 81 uint8_t x; 82 83 for (i=0; i < 256; i++) { 84 x = gf2_8_compute_inverse((gf2_8)i); 85 x = A_times_x_plus_b(A, x, b); 86 aes_sbox[i] = x; 87 aes_inv_sbox[x] = i; 88 } 89 } 90 91 void 92 aes_compute_tables(void) { 93 int i; 94 uint32_t x1, x2, x3; 95 v32_t tmp; 96 97 /* initialize substitution table */ 98 aes_init_sbox(); 99 100 /* combine sbox with linear operations to form 8-bit to 32-bit tables */ 101 for (i=0; i < 256; i++) { 102 x1 = aes_sbox[i]; 103 x2 = gf2_8_shift(x1); 104 x3 = x2 ^ x1; 105 106 tmp.v8[0] = x2; 107 tmp.v8[1] = x1; 108 tmp.v8[2] = x1; 109 tmp.v8[3] = x3; 110 T0[i] = tmp.value; 111 112 tmp.v8[0] = x3; 113 tmp.v8[1] = x2; 114 tmp.v8[2] = x1; 115 tmp.v8[3] = x1; 116 T1[i] = tmp.value; 117 118 tmp.v8[0] = x1; 119 tmp.v8[1] = x3; 120 tmp.v8[2] = x2; 121 tmp.v8[3] = x1; 122 T2[i] = tmp.value; 123 124 tmp.v8[0] = x1; 125 tmp.v8[1] = x1; 126 tmp.v8[2] = x3; 127 tmp.v8[3] = x2; 128 T3[i] = tmp.value; 129 130 } 131 } 132 133 134 /* 135 * the tables U0, U1, U2, U3 implement the aes operations invSubBytes, 136 * invMixColumns, and invShiftRows 137 */ 138 139 uint32_t U0[256], U1[256], U2[256], U3[256], U4[256]; 140 141 extern uint8_t aes_inv_sbox[256]; 142 143 void 144 aes_compute_inv_tables(void) { 145 int i; 146 uint8_t x, xe, x9, xd, xb; 147 v32_t tmp; 148 149 /* combine sbox with linear operations to form 8-bit to 32-bit tables */ 150 for (i=0; i < 256; i++) { 151 x = aes_inv_sbox[i]; 152 153 xe = gf2_8_multiply(0x0e, x); 154 x9 = gf2_8_multiply(0x09, x); 155 xd = gf2_8_multiply(0x0d, x); 156 xb = gf2_8_multiply(0x0b, x); 157 158 tmp.v8[0] = xe; 159 tmp.v8[1] = x9; 160 tmp.v8[2] = xd; 161 tmp.v8[3] = xb; 162 U0[i] = tmp.value; 163 164 tmp.v8[0] = xb; 165 tmp.v8[1] = xe; 166 tmp.v8[2] = x9; 167 tmp.v8[3] = xd; 168 U1[i] = tmp.value; 169 170 tmp.v8[0] = xd; 171 tmp.v8[1] = xb; 172 tmp.v8[2] = xe; 173 tmp.v8[3] = x9; 174 U2[i] = tmp.value; 175 176 tmp.v8[0] = x9; 177 tmp.v8[1] = xd; 178 tmp.v8[2] = xb; 179 tmp.v8[3] = xe; 180 U3[i] = tmp.value; 181 182 tmp.v8[0] = tmp.v8[1] = tmp.v8[2] = tmp.v8[3] = x; 183 U4[i] = tmp.value; 184 } 185 } 186 187 188 /* 189 * aes_test_inverse() returns err_status_ok if aes 190 * encryption and decryption are true inverses of each other, and 191 * returns err_status_algo_fail otherwise 192 */ 193 194 #include "err.h" 195 196 err_status_t 197 aes_test_inverse(void); 198 199 #define TABLES_32BIT 1 200 201 #ifndef HIDE_AES_TABLES_MAIN 202 203 int 204 main(void) { 205 int i; 206 207 aes_init_sbox(); 208 aes_compute_inv_tables(); 209 210 #if TABLES_32BIT 211 printf("uint32_t U0 = {"); 212 for (i=0; i < 256; i++) { 213 if ((i % 4) == 0) 214 printf("\n"); 215 printf("0x%0x, ", U0[i]); 216 } 217 printf("\n}\n"); 218 219 printf("uint32_t U1 = {"); 220 for (i=0; i < 256; i++) { 221 if ((i % 4) == 0) 222 printf("\n"); 223 printf("0x%x, ", U1[i]); 224 } 225 printf("\n}\n"); 226 227 printf("uint32_t U2 = {"); 228 for (i=0; i < 256; i++) { 229 if ((i % 4) == 0) 230 printf("\n"); 231 printf("0x%x, ", U2[i]); 232 } 233 printf("\n}\n"); 234 235 printf("uint32_t U3 = {"); 236 for (i=0; i < 256; i++) { 237 if ((i % 4) == 0) 238 printf("\n"); 239 printf("0x%x, ", U3[i]); 240 } 241 printf("\n}\n"); 242 243 printf("uint32_t U4 = {"); 244 for (i=0; i < 256; i++) { 245 if ((i % 4) == 0) 246 printf("\n"); 247 printf("0x%x, ", U4[i]); 248 } 249 printf("\n}\n"); 250 251 #else 252 253 printf("uint32_t U0 = {"); 254 for (i=0; i < 256; i++) { 255 if ((i % 4) == 0) 256 printf("\n"); 257 printf("0x%lx, ", U0[i]); 258 } 259 printf("\n}\n"); 260 261 printf("uint32_t U1 = {"); 262 for (i=0; i < 256; i++) { 263 if ((i % 4) == 0) 264 printf("\n"); 265 printf("0x%lx, ", U1[i]); 266 } 267 printf("\n}\n"); 268 269 printf("uint32_t U2 = {"); 270 for (i=0; i < 256; i++) { 271 if ((i % 4) == 0) 272 printf("\n"); 273 printf("0x%lx, ", U2[i]); 274 } 275 printf("\n}\n"); 276 277 printf("uint32_t U3 = {"); 278 for (i=0; i < 256; i++) { 279 if ((i % 4) == 0) 280 printf("\n"); 281 printf("0x%lx, ", U3[i]); 282 } 283 printf("\n}\n"); 284 285 printf("uint32_t U4 = {"); 286 for (i=0; i < 256; i++) { 287 if ((i % 4) == 0) 288 printf("\n"); 289 printf("0x%lx, ", U4[i]); 290 } 291 printf("\n}\n"); 292 293 294 #endif /* TABLES_32BIT */ 295 296 297 #if AES_INVERSE_TEST 298 /* 299 * test that aes_encrypt and aes_decrypt are actually 300 * inverses of each other 301 */ 302 303 printf("aes inverse test: "); 304 if (aes_test_inverse() == err_status_ok) 305 printf("passed\n"); 306 else { 307 printf("failed\n"); 308 exit(1); 309 } 310 #endif 311 312 return 0; 313 } 314 315 #endif // HIDE_AES_TABLES_MAIN 316 317 #if AES_INVERSE_TEST 318 319 err_status_t 320 aes_test_inverse(void) { 321 v128_t x, y; 322 aes_expanded_key_t expanded_key, decrypt_key; 323 uint8_t plaintext[16] = { 324 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 325 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff 326 }; 327 uint8_t key[16] = { 328 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 329 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 330 }; 331 v128_t k; 332 v128_set_to_zero(&x); 333 334 v128_copy_octet_string(&k, key); 335 v128_copy_octet_string(&x, plaintext); 336 aes_expand_encryption_key(k, expanded_key); 337 aes_expand_decryption_key(k, decrypt_key); 338 aes_encrypt(&x, expanded_key); 339 aes_decrypt(&x, decrypt_key); 340 341 /* compare to expected value then report */ 342 v128_copy_octet_string(&y, plaintext); 343 344 if (v128_is_eq(&x, &y)) 345 return err_status_ok; 346 return err_status_algo_fail; 347 348 } 349 350 #endif 351