Home | History | Annotate | Download | only in tables
      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 int
    202 main(void) {
    203   int i;
    204 
    205   aes_init_sbox();
    206   aes_compute_inv_tables();
    207 
    208 #if TABLES_32BIT
    209   printf("uint32_t U0 = {");
    210   for (i=0; i < 256; i++) {
    211     if ((i % 4) == 0)
    212       printf("\n");
    213     printf("0x%0x, ", U0[i]);
    214   }
    215   printf("\n}\n");
    216 
    217  printf("uint32_t U1 = {");
    218   for (i=0; i < 256; i++) {
    219     if ((i % 4) == 0)
    220       printf("\n");
    221     printf("0x%x, ", U1[i]);
    222   }
    223   printf("\n}\n");
    224 
    225  printf("uint32_t U2 = {");
    226   for (i=0; i < 256; i++) {
    227     if ((i % 4) == 0)
    228       printf("\n");
    229     printf("0x%x, ", U2[i]);
    230   }
    231   printf("\n}\n");
    232 
    233  printf("uint32_t U3 = {");
    234   for (i=0; i < 256; i++) {
    235     if ((i % 4) == 0)
    236       printf("\n");
    237     printf("0x%x, ", U3[i]);
    238   }
    239   printf("\n}\n");
    240 
    241  printf("uint32_t U4 = {");
    242  for (i=0; i < 256; i++) {
    243     if ((i % 4) == 0)
    244       printf("\n");
    245     printf("0x%x, ", U4[i]);
    246   }
    247   printf("\n}\n");
    248 
    249 #else
    250 
    251   printf("uint32_t U0 = {");
    252   for (i=0; i < 256; i++) {
    253     if ((i % 4) == 0)
    254       printf("\n");
    255     printf("0x%lx, ", U0[i]);
    256   }
    257   printf("\n}\n");
    258 
    259  printf("uint32_t U1 = {");
    260   for (i=0; i < 256; i++) {
    261     if ((i % 4) == 0)
    262       printf("\n");
    263     printf("0x%lx, ", U1[i]);
    264   }
    265   printf("\n}\n");
    266 
    267  printf("uint32_t U2 = {");
    268   for (i=0; i < 256; i++) {
    269     if ((i % 4) == 0)
    270       printf("\n");
    271     printf("0x%lx, ", U2[i]);
    272   }
    273   printf("\n}\n");
    274 
    275  printf("uint32_t U3 = {");
    276   for (i=0; i < 256; i++) {
    277     if ((i % 4) == 0)
    278       printf("\n");
    279     printf("0x%lx, ", U3[i]);
    280   }
    281   printf("\n}\n");
    282 
    283  printf("uint32_t U4 = {");
    284  for (i=0; i < 256; i++) {
    285     if ((i % 4) == 0)
    286       printf("\n");
    287     printf("0x%lx, ", U4[i]);
    288   }
    289   printf("\n}\n");
    290 
    291 
    292 #endif /* TABLES_32BIT */
    293 
    294 
    295 #if AES_INVERSE_TEST
    296   /*
    297    * test that aes_encrypt and aes_decrypt are actually
    298    * inverses of each other
    299    */
    300 
    301   printf("aes inverse test: ");
    302   if (aes_test_inverse() == err_status_ok)
    303     printf("passed\n");
    304   else {
    305     printf("failed\n");
    306     exit(1);
    307   }
    308 #endif
    309 
    310   return 0;
    311 }
    312 
    313 #if AES_INVERSE_TEST
    314 
    315 err_status_t
    316 aes_test_inverse(void) {
    317   v128_t x, y;
    318   aes_expanded_key_t expanded_key, decrypt_key;
    319   uint8_t plaintext[16] = {
    320     0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    321     0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
    322   };
    323   uint8_t key[16] = {
    324     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    325     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    326   };
    327   v128_t k;
    328   v128_set_to_zero(&x);
    329 
    330   v128_copy_octet_string(&k, key);
    331   v128_copy_octet_string(&x, plaintext);
    332   aes_expand_encryption_key(k, expanded_key);
    333   aes_expand_decryption_key(k, decrypt_key);
    334   aes_encrypt(&x, expanded_key);
    335   aes_decrypt(&x, decrypt_key);
    336 
    337   /* compare to expected value then report */
    338   v128_copy_octet_string(&y, plaintext);
    339 
    340   if (v128_is_eq(&x, &y))
    341     return err_status_ok;
    342   return err_status_algo_fail;
    343 
    344 }
    345 
    346 #endif
    347