#if HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "nettle-types.h" #if 1 # define BYTE_FORMAT "0x%02x" # define BYTE_COLUMNS 8 #else # define BYTE_FORMAT "%3d" # define BYTE_COLUMNS 0x10 #endif #define WORD_FORMAT "0x%08x" #define WORD_COLUMNS 4 uint8_t sbox[0x100]; uint8_t isbox[0x100]; uint8_t gf2_log[0x100]; uint8_t gf2_exp[0x100]; uint32_t dtable[4][0x100]; uint32_t itable[4][0x100]; static unsigned xtime(unsigned x) { assert (x < 0x100); x <<= 1; if (x & 0x100) x ^= 0x11b; assert (x < 0x100); return x; } /* Computes the exponentiatiom and logarithm tables for GF_2, to the * base x+1 (0x03). The unit element is 1 (0x01).*/ static void compute_log(void) { unsigned i = 0; unsigned x = 1; memset(gf2_log, 0, 0x100); for (i = 0; i < 0x100; i++, x = x ^ xtime(x)) { gf2_exp[i] = x; gf2_log[x] = i; } /* Invalid. */ gf2_log[0] = 0; /* The loop above sets gf2_log[1] = 0xff, which is correct, * but gf2_log[1] = 0 is nicer. */ gf2_log[1] = 0; } static unsigned mult(unsigned a, unsigned b) { return (a && b) ? gf2_exp[ (gf2_log[a] + gf2_log[b]) % 255] : 0; } static unsigned invert(unsigned x) { return x ? gf2_exp[0xff - gf2_log[x]] : 0; } static unsigned affine(unsigned x) { return 0xff & (0x63^x^(x>>4)^(x<<4)^(x>>5)^(x<<3)^(x>>6)^(x<<2)^(x>>7)^(x<<1)); } static void compute_sbox(void) { unsigned i; for (i = 0; i<0x100; i++) { sbox[i] = affine(invert(i)); isbox[sbox[i]] = i; } } /* Generate little endian tables, i.e. the first row of the AES state * arrays occupies the least significant byte of the words. * * The sbox values are multiplied with the column of GF2 coefficients * of the polynomial 03 x^3 + x^2 + x + 02. */ static void compute_dtable(void) { unsigned i; for (i = 0; i<0x100; i++) { unsigned s = sbox[i]; unsigned j; uint32_t t =( ( (s ^ xtime(s)) << 24) | (s << 16) | (s << 8) | xtime(s) ); for (j = 0; j<4; j++, t = (t << 8) | (t >> 24)) dtable[j][i] = t; } } /* The inverse sbox values are multiplied with the column of GF2 coefficients * of the polynomial inverse 0b x^3 + 0d x^2 + 09 x + 0e. */ static void compute_itable(void) { unsigned i; for (i = 0; i<0x100; i++) { unsigned s = isbox[i]; unsigned j; uint32_t t = ( (mult(s, 0xb) << 24) | (mult(s, 0xd) << 16) | (mult(s, 0x9) << 8) | (mult(s, 0xe) )); for (j = 0; j<4; j++, t = (t << 8) | (t >> 24)) itable[j][i] = t; } } static void display_byte_table(const char *name, uint8_t *table) { unsigned i, j; printf("uint8_t %s[0x100] =\n{", name); for (i = 0; i<0x100; i+= BYTE_COLUMNS) { printf("\n "); for (j = 0; j