6
typedef unsigned int UInt;
7
typedef signed int Int;
8
typedef unsigned char UChar;
9
typedef unsigned long long int ULong;
11
#define False ((Bool)0)
12
#define True ((Bool)1)
14
//typedef unsigned char V128[16];
22
static UChar fromhex(char x) {
23
if (x >= '0' && x <= '9') { return(x - '0'); }
24
else if (x >= 'A' && x <= 'F') { return(x - 'A' + 10); }
25
else if (x >= 'a' && x <= 'f') { return(x - 'a' + 10); }
29
static void expand ( V128* dst, char* summary )
32
assert( strlen(summary) == 32 );
33
for (i = 0; i < 16; i++) {
35
UChar x = summary[31-2*i];
37
UChar y = summary[31-2*i-1];
49
static int tohex (int nib)
54
return 'a' + nib - 10;
56
static void unexpand ( V128* dst, char* summary )
59
for (i = 0; i < 16; i++) {
60
*summary++ = tohex((dst->uChar[i] >> 4) & 0xf);
61
*summary++ = tohex(dst->uChar[i] & 0xf);
66
static void AESDEC(char *s_argL, char *s_argR, char *s_exp)
69
; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key).
70
; The result is delivered in xmm1.
76
expand(&argL, s_argL);
77
expand(&argR, s_argR);
79
"subq $1024, %%rsp" "\n\t"
80
"movdqu %1, %%xmm1" "\n\t"
81
"movdqu %2, %%xmm2" "\n\t"
82
"aesdec %%xmm2, %%xmm1" "\n\t"
83
"movdqu %%xmm1, %0" "\n\t"
84
"addq $1024, %%rsp" "\n\t"
86
: "m"/*in*/(argL), "m"/*in*/(argR)
87
: /*trash*/ "xmm1", "xmm2"
90
if (strlen(s_exp) > 0) {
92
assert (0 == memcmp(&res, &exp, 16));
94
unexpand (&res, s_res);
95
printf ("aesdec %s %s result %s\n", s_argL, s_argR, s_res);
98
static void AESDECLAST(char *s_argL, char *s_argR, char *s_exp)
101
; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key).
102
; The result is delivered in xmm1.
108
expand(&argL, s_argL);
109
expand(&argR, s_argR);
110
__asm__ __volatile__(
111
"subq $1024, %%rsp" "\n\t"
112
"movdqu %1, %%xmm1" "\n\t"
113
"movdqu %2, %%xmm2" "\n\t"
114
"aesdeclast %%xmm2, %%xmm1" "\n\t"
115
"movdqu %%xmm1, %0" "\n\t"
116
"addq $1024, %%rsp" "\n\t"
118
: "m"/*in*/(argL), "m"/*in*/(argR)
119
: /*trash*/ "xmm1", "xmm2"
122
if (strlen(s_exp) > 0) {
124
assert (0 == memcmp(&res, &exp, 16));
126
unexpand (&res, s_res);
127
printf ("aesdeclast %s %s result %s\n", s_argL, s_argR, s_res);
130
static void AESENC(char *s_argL, char *s_argR, char *s_exp)
133
; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key).
134
; The result is delivered in xmm1.
140
expand(&argL, s_argL);
141
expand(&argR, s_argR);
142
__asm__ __volatile__(
143
"subq $1024, %%rsp" "\n\t"
144
"movdqu %1, %%xmm1" "\n\t"
145
"movdqu %2, %%xmm2" "\n\t"
146
"aesenc %%xmm2, %%xmm1" "\n\t"
147
"movdqu %%xmm1, %0" "\n\t"
148
"addq $1024, %%rsp" "\n\t"
150
: "m"/*in*/(argL), "m"/*in*/(argR)
151
: /*trash*/ "xmm1", "xmm2"
154
if (strlen(s_exp) > 0) {
156
assert (0 == memcmp(&res, &exp, 16));
158
unexpand (&res, s_res);
159
printf ("aesenc %s %s result %s\n", s_argL, s_argR, s_res);
162
static void AESENCLAST(char *s_argL, char *s_argR, char *s_exp)
165
; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key)
166
; The result delivered in xmm1
172
expand(&argL, s_argL);
173
expand(&argR, s_argR);
174
__asm__ __volatile__(
175
"subq $1024, %%rsp" "\n\t"
176
"movdqu %1, %%xmm1" "\n\t"
177
"movdqu %2, %%xmm2" "\n\t"
178
"aesenclast %%xmm2, %%xmm1" "\n\t"
179
"movdqu %%xmm1, %0" "\n\t"
180
"addq $1024, %%rsp" "\n\t"
182
: "m"/*in*/(argL), "m"/*in*/(argR)
183
: /*trash*/ "xmm1", "xmm2"
186
if (strlen(s_exp) > 0) {
188
assert (0 == memcmp(&res, &exp, 16));
190
unexpand (&res, s_res);
191
printf ("aesenclast %s %s result %s\n", s_argL, s_argR, s_res);
194
static void AESIMC(char *s_argR, char *s_exp)
196
/* We test another way to pass input and get results */
197
/* ; argR hold one 128-bit inputs (argR = Round key)
198
; result delivered in xmm5 */
204
expand(&argR, s_argR);
206
__asm__ __volatile__(
207
"subq $1024, %%rsp" "\n\t"
208
"aesimc %1, %%xmm5" "\n\t"
209
"movdqu %%xmm5, %0" "\n\t"
210
"addq $1024, %%rsp" "\n\t"
216
if (strlen(s_exp) > 0) {
218
assert (0 == memcmp(&res, &exp, 16));
220
unexpand (&res, s_res);
221
printf ("aesimc %s result %s\n", s_argR, s_res);
224
static void AESKEYGENASSIST(int imm, char* s_argL, char* s_exp)
227
; xmm2 holds a 128-bit input; imm8 holds the RCON value
228
; result delivered in xmm1
235
expand(&argL, s_argL);
237
__asm__ __volatile__(
238
"subq $1024, %%rsp" "\n\t"
239
"movdqu %1, %%xmm2" "\n\t"
240
"aeskeygenassist $1,%%xmm2, %%xmm1" "\n\t"
241
"movdqu %%xmm1, %0" "\n\t"
242
"addq $1024, %%rsp" "\n\t"
245
: /*trash*/ "xmm1", "xmm2"
248
__asm__ __volatile__(
249
"subq $1024, %%rsp" "\n\t"
250
"movdqu %1, %%xmm2" "\n\t"
251
"aeskeygenassist $2,%%xmm2, %%xmm1" "\n\t"
252
"movdqu %%xmm1, %0" "\n\t"
253
"addq $1024, %%rsp" "\n\t"
256
: /*trash*/ "xmm1", "xmm2"
259
__asm__ __volatile__(
260
"subq $1024, %%rsp" "\n\t"
261
"movdqu %1, %%xmm2" "\n\t"
262
"aeskeygenassist $8,%%xmm2, %%xmm1" "\n\t"
263
"movdqu %%xmm1, %0" "\n\t"
264
"addq $1024, %%rsp" "\n\t"
267
: /*trash*/ "xmm1", "xmm2"
271
if (strlen(s_exp) > 0) {
273
assert (0 == memcmp(&res, &exp, 16));
275
unexpand (&res, s_res);
276
printf ("aeskeygenassist %d %s result %s\n", imm, s_argL, s_res);
279
typedef struct Aes_Args {
282
int imm; // only for aeskeygenassist
285
/* Just a bunch of various data to compare a native run
286
with a run under Valgrind. */
287
static const Aes_Args aes_args[] = {
288
{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
289
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
291
{"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
292
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
294
{"3243f6a8885a308d313198a2e0370734",
295
"2b7e151628aed2a6abf7158809cf4f3c",
297
{"193de3bea0f4e22b9ac68d2ae9f84808",
298
"d42711aee0bf98f1b8b45de51e415230",
300
{"d4bf5d30e0b452aeb84111f11e2798e5",
301
"046681e5e0cb199a48f8d37a2806264c",
303
{"a0fafe1788542cb123a339392a6c7605",
304
"a49c7ff2689f352b6b5bea43026a5049",
306
{"49ded28945db96f17f39871a7702533b",
307
"49db873b453953897f02d2f177de961a",
309
{"584dcaf11b4b5aacdbe7caa81b6bb0e5",
310
"f2c295f27a96b9435935807a7359f67f",
312
{"aa8f5f0361dde3ef82d24ad26832469a",
313
"ac73cf7befc111df13b5d6b545235ab8",
315
{"acc1d6b8efb55a7b1323cfdf457311b5",
316
"75ec0993200b633353c0cf7cbb25d0dc",
318
{"e9317db5cb322c723d2e895faf090794",
319
"d014f9a8c9ee2589e13f0cc8b6630ca6",
330
/* test the various instructions, using the examples provided
331
in "White Paper Intel Advanced Encryption Standard AES
332
instruction set" January 2010 (26/1/2010)
336
"3c4fcf098815f7aba6d2ae2816157e2b",
337
"01eb848beb848a013424b5e524b5e434");
338
AESENC("7b5b54657374566563746f725d53475d",
339
"48692853686179295b477565726f6e5d",
340
"a8311c2f9fdba3c58b104b58ded7e595");
341
AESENCLAST("7b5b54657374566563746f725d53475d",
342
"48692853686179295b477565726f6e5d",
343
"c7fb881e938c5964177ec42553fdc611");
344
AESDEC("7b5b54657374566563746f725d53475d",
345
"48692853686179295b477565726f6e5d",
346
"138ac342faea2787b58eb95eb730392a");
347
AESDECLAST("7b5b54657374566563746f725d53475d",
348
"48692853686179295b477565726f6e5d",
349
"c5a391ef6b317f95d410637b72a593d0");
350
/* ??? the AESIMC example given in the Intel White paper
352
The below fails both under Valgrind and natively.
353
AESIMC("48692853686179295b477565726f6e5d",
354
"627a6f6644b109c82b18330a81c3b3e5");
355
So we use the example given for the InvMixColums
357
AESIMC("8dcab9dc035006bc8f57161e00cafd8d",
358
"d635a667928b5eaeeec9cc3bc55f5777");
361
/* and now a bunch of other calls. The below are verified
362
using the aes.stdout.exp (produced by a native run). */
364
for (i = 0; aes_args[i].argL != NULL; i++) {
365
AESKEYGENASSIST(aes_args[i].imm, aes_args[i].argL, "");
366
AESENC(aes_args[i].argL, aes_args[i].argR, "");
367
AESENCLAST(aes_args[i].argL, aes_args[i].argR, "");
368
AESDEC(aes_args[i].argL, aes_args[i].argR, "");
369
AESDECLAST(aes_args[i].argL, aes_args[i].argR, "");
370
AESIMC(aes_args[i].argL, "");