]>
git.saurik.com Git - apple/xnu.git/blob - bsd/crypto/aes/i386/MakeData.c
12 /* In comments below, {n} designates the Galois field element represented by
13 the byte n. See notes about Galois field multiplication in ReadMe.txt.
15 So 3+5 is addition of ordinary integers, and 3+5 == 8, while {3}+{5} is
16 addition in the field, and {3} + {5} = {3 XOR 5} = {6}.)
20 // Define constants for languages.
21 typedef enum { C
, IntelAssembly
} Language
;
24 /* LogBase3[i] will contain the base-three logarithm of i in the 256-element
25 Galois field defined by AES. That is, {3}**LogBase3[i] == {3}**i.
27 static Byte LogBase3
[256];
29 /* AntilogBase3[i] will contain {3}**i in the 256-element Galois field defined
30 by AES. It contains extra elements so that the antilog of a+b can be found
31 by looking up a+b directly, without having to reduce modulo the period, for
34 (254 is the greatest value we encounter. Each a or b we use is the
35 base-three logarithm of some element. As a primitive root, the powers of
36 three cycle through all non-zero elements of the field, of which there are
37 255, so the exponents cover 0 to 254 before the powers repeat.)
39 static Byte AntilogBase3
[254+254+1];
42 static void InitializeLogTables(void)
44 // log({1}) is zero, so start {p} (power) at {1} and l (logarithm) at 0.
49 // Record table entries.
53 /* Observe that {2}*{p} is {p << 1 ^ (a & 0x80 ? 0x1b : 0)}, per notes
54 in ReadMe.txt. We produce {3}*{p}:
58 = {1}*{p} + {p << 1 ^ (a & 0x80 ? 0x1b : 0)}
59 = {p ^ p << 1 ^ (p & 0x80 ? 0x1b : 0)}.
61 p
^= p
<< 1 ^ (p
& 0x80 ? 0x1b : 0);
64 } while (p
!= 1); // Stop when we have gone around completely.
66 /* The antilogarithms are periodic with a period of 255, and we want to
67 look up elements as high as 254+254 (the largest that a sum of two
68 logarithms could be), so we replicate the table beyond the first
71 for (l
= 255; l
< 254+254; ++l
)
72 AntilogBase3
[l
] = AntilogBase3
[l
-255];
76 /* MultiplyByte(Byte b, Byte c) returns {b}*{c}. It requires tables that must
77 be initialized before this routine is used.
79 static Byte
MultiplyByte(Byte b
, Byte c
)
81 // Calculate product by adding logarithms, but avoid logarithms of zero.
82 return b
== 0 || c
== 0 ? 0 : AntilogBase3
[LogBase3
[b
] + LogBase3
[c
]];
86 // Return {0} if {b} is {0} and the multiplicative inverse of {b} otherwise.
87 static Byte
InverseByte(Byte b
)
89 return b
== 0 ? 0 : AntilogBase3
[255 - LogBase3
[b
]];
93 // Perform AES' SubBytes operation on a single byte.
94 static Byte
SubByte(Byte b
)
96 unsigned int r
= InverseByte(b
);
98 // Duplicate r as a proxy for a rotate operation.
101 // Apply the standard's affine transformation.
102 return r
^ r
>>4 ^ r
>>5 ^ r
>>6 ^ r
>>7 ^ 0x63;
106 // Define and populate tables for the SubBytes and InvSubBytes operations.
107 static Byte SubBytesTable
[256];
108 static Byte InvSubBytesTable
[256];
111 static void InitializeSubBytesTable(void)
113 for (int i
= 0; i
< 256; ++i
)
114 SubBytesTable
[i
] = SubByte((Byte
) i
);
118 static void InitializeInvSubBytesTable(void)
120 for (int i
= 0; i
< 256; ++i
)
121 InvSubBytesTable
[SubByte((Byte
) i
)] = i
;
125 /* Print tables for SubBytes function providing the output byte embedded in
126 various places in a word, so that the table entries can be used with
127 fewer byte manipulations.
129 static void PrintSubBytesWordTable(Language language
)
135 "// SubBytes embedded in words tables.\n"
136 "const Word AESSubBytesWordTable[4][256] =\n"
138 for (int j
= 0; j
< 4; ++j
)
141 for (int i
= 0; i
< 256; ++i
)
142 printf("\t\t0x%08x,\n", SubBytesTable
[i
] << j
*8);
150 "// SubBytes embedded in words tables.\n"
151 "\t.globl\t_AESSubBytesWordTable\n"
152 "\t.private_extern\t_AESSubBytesWordTable\n"
154 "_AESSubBytesWordTable:\n");
155 for (int j
= 0; j
< 4; ++j
)
157 printf("\t// Table %d.\n", j
);
158 for (int i
= 0; i
< 256; ++i
)
159 printf("\t.long\t0x%08x\n", SubBytesTable
[i
] << j
*8);
166 /* Print tables for InvSubBytes function providing the output byte embedded in
167 various places in a word, so that the table entries can be used with
168 fewer byte manipulations.
170 static void PrintInvSubBytesWordTable(Language language
)
176 "// InvSubBytes embedded in words tables.\n"
177 "const Word AESInvSubBytesWordTable[4][256] =\n"
179 for (int j
= 0; j
< 4; ++j
)
182 for (int i
= 0; i
< 256; ++i
)
183 printf("\t\t0x%08x,\n", InvSubBytesTable
[i
] << j
*8);
191 "// InvSubBytes embedded in words tables.\n"
192 "\t.globl\t_AESInvSubBytesWordTable\n"
193 "\t.private_extern\t_AESInvSubBytesWordTable\n"
195 "_AESInvSubBytesWordTable:\n");
196 for (int j
= 0; j
< 4; ++j
)
198 printf("\t// Table %d.\n", j
);
199 for (int i
= 0; i
< 256; ++i
)
200 printf("\t.long\t0x%08x\n", InvSubBytesTable
[i
] << j
*8);
207 // Print the round constants.
208 static void PrintRcon(Language language
)
210 union { Byte c
[4]; Word w
; } t
= { { 1, 0, 0, 0 } };
216 "// Round constants.\n"
217 "const Byte AESRcon[] =\n"
219 "\t0,\t// Not used, included for indexing simplicity.\n");
220 for (int i
= 1; i
< MaxRcon
; ++i
)
222 printf("\t0x%02x,\n", t
.w
);
223 t
.c
[0] = MultiplyByte(0x2, t
.c
[0]);
230 "// Round constants.\n"
231 "\t.globl\t_AESRcon\n"
232 "\t.private_extern\t_AESRcon\n"
234 "\t.byte\t0\t// Not used, included for indexing simplicity.\n");
235 for (int i
= 1; i
< MaxRcon
; ++i
)
237 printf("\t.byte\t0x%02x\n", t
.w
);
238 t
.c
[0] = MultiplyByte(0x2, t
.c
[0]);
245 // Print tables for the InvMixColumn operation.
246 static void PrintInvMixColumnTable(Language language
)
250 for (int i
= 0; i
< 256; ++i
)
252 union { Byte b
[4]; Word w
; } c
;
254 Byte s9
= MultiplyByte(0x9, i
);
255 Byte sb
= MultiplyByte(0xb, i
);
256 Byte sd
= MultiplyByte(0xd, i
);
257 Byte se
= MultiplyByte(0xe, i
);
288 "// Tables for InvMixColumn.\n"
289 "const Word AESInvMixColumnTable[4][256] =\n"
291 for (int i
= 0; i
< 4; ++i
)
294 for (int j
= 0; j
< 256; ++j
)
295 printf("\t\t0x%08x,\n", T
[i
][j
]);
303 "// Tables for InvMixColumn.\n"
304 "\t.globl\t_AESInvMixColumnTable\n"
305 "\t.private_extern\t_AESInvMixColumnTable\n"
307 "_AESInvMixColumnTable:\n");
308 for (int i
= 0; i
< 4; ++i
)
310 printf("\t// Table %d.\n", i
);
311 for (int j
= 0; j
< 256; ++j
)
312 printf("\t.long\t0x%08x\n", T
[i
][j
]);
319 /* Print the tables defined AES Proposal: Rijndael, amended, 9/04/2003,
320 section 5.2.1. These combine the MixColumn and SubBytes operations.
322 static void PrintEncryptTable(Language language
)
326 for (int i
= 0; i
< 256; ++i
)
328 union { Byte b
[4]; Word w
; } c
;
330 Byte s1
= SubBytesTable
[i
];
331 Byte s2
= MultiplyByte(0x2, s1
);
363 "// Tables for main encryption iterations.\n"
364 "const Word AESEncryptTable[4][256] =\n"
366 for (int i
= 0; i
< 4; ++i
)
369 for (int j
= 0; j
< 256; ++j
)
370 printf("\t\t0x%08x,\n", T
[i
][j
]);
378 "// Tables for main encryption iterations.\n"
379 "\t.globl\t_AESEncryptTable\n"
380 "\t.private_extern\t_AESEncryptTable\n"
382 "_AESEncryptTable:\n");
383 for (int i
= 0; i
< 4; ++i
)
385 printf("\t// Table %d.\n", i
);
386 for (int j
= 0; j
< 256; ++j
)
387 printf("\t.long\t0x%08x\n", T
[i
][j
]);
394 /* Print the inverse tables. These correspond to the tables above, but for
395 decyrption. These combine the InvSubBytes and InvMixColumn operations.
397 static void PrintDecryptTable(Language language
)
401 for (int i
= 0; i
< 256; ++i
)
403 union { Byte b
[4]; Word w
; } c
;
405 Byte si
= InvSubBytesTable
[i
];
407 Byte s9
= MultiplyByte(0x9, si
);
408 Byte sb
= MultiplyByte(0xb, si
);
409 Byte sd
= MultiplyByte(0xd, si
);
410 Byte se
= MultiplyByte(0xe, si
);
441 "// Tables for main decryption iterations.\n"
442 "const Word AESDecryptTable[4][256] =\n"
444 for (int i
= 0; i
< 4; ++i
)
447 for (int j
= 0; j
< 256; ++j
)
448 printf("\t\t0x%08x,\n", T
[i
][j
]);
456 "// Tables for main decryption iterations.\n"
457 "\t.globl\t_AESDecryptTable\n"
458 "\t.private_extern\t_AESDecryptTable\n"
460 "_AESDecryptTable:\n");
461 for (int i
= 0; i
< 4; ++i
)
463 printf("\t// Table %d.\n", i
);
464 for (int j
= 0; j
< 256; ++j
)
465 printf("\t.long\t0x%08x\n", T
[i
][j
]);
472 static void Usage(const char *ProgramName
)
475 "%s: This program must have exactly one argument, \"C\" to generate\n"
476 "C or \"Intel\" to generate GCC i386/x86_64 assembly.\n", ProgramName
);
481 int main(int argc
, char *argv
[])
488 // Figure out which language to generate, C or Intel assembly.
489 if (0 == strcmp(argv
[1], "C"))
491 else if (0 == strcmp(argv
[1], "Intel"))
492 language
= IntelAssembly
;
496 printf("// This file was generated by " __FILE__
".\n");
499 printf("\n\n#include \"AES.h\"\n");
501 if (language
== IntelAssembly
)
502 printf("\n\n\t.const\n");
504 InitializeLogTables();
505 InitializeSubBytesTable();
506 InitializeInvSubBytesTable();
509 PrintInvMixColumnTable(language
);
510 PrintEncryptTable(language
);
511 PrintDecryptTable(language
);
512 PrintSubBytesWordTable(language
);
513 PrintInvSubBytesWordTable(language
);