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 #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