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
, "");