~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to none/tests/amd64/aes.c

  • Committer: Benjamin Kerensa
  • Date: 2012-11-21 23:57:58 UTC
  • mfrom: (1.1.16)
  • Revision ID: bkerensa@ubuntu.com-20121121235758-bd1rv5uc5vzov2p6
Merge from debian unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include <string.h>
 
3
#include <stdio.h>
 
4
#include <assert.h>
 
5
 
 
6
typedef  unsigned int   UInt;
 
7
typedef  signed int     Int;
 
8
typedef  unsigned char  UChar;
 
9
typedef  unsigned long long int ULong;
 
10
typedef  UChar          Bool;
 
11
#define False ((Bool)0)
 
12
#define True  ((Bool)1)
 
13
 
 
14
//typedef  unsigned char  V128[16];
 
15
typedef
 
16
   union {
 
17
      UChar uChar[16];
 
18
      UInt  uInt[4];
 
19
   }
 
20
   V128;
 
21
 
 
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); }
 
26
   else assert(0);
 
27
}
 
28
 
 
29
static void expand ( V128* dst, char* summary )
 
30
{
 
31
   Int i;
 
32
   assert( strlen(summary) == 32 );
 
33
   for (i = 0; i < 16; i++) {
 
34
      UChar xx = 0;
 
35
      UChar x = summary[31-2*i];
 
36
      UChar yy = 0;
 
37
      UChar y = summary[31-2*i-1];
 
38
      xx = fromhex (x);
 
39
      yy = fromhex (y);
 
40
 
 
41
      assert(xx < 16);
 
42
      assert(yy < 16);
 
43
      xx = (yy << 4) | xx;
 
44
      assert(xx < 256);
 
45
      dst->uChar[i] = xx;
 
46
   }
 
47
}
 
48
 
 
49
static int tohex (int nib)
 
50
{
 
51
   if (nib < 10)
 
52
      return '0' + nib;
 
53
   else
 
54
      return 'a' + nib - 10;
 
55
}
 
56
static void unexpand ( V128* dst, char* summary )
 
57
{
 
58
   Int i;
 
59
   for (i = 0; i < 16; i++) {
 
60
      *summary++ = tohex((dst->uChar[i] >> 4) & 0xf);
 
61
      *summary++ = tohex(dst->uChar[i] & 0xf);
 
62
   }
 
63
   *summary = 0;
 
64
}
 
65
 
 
66
static void AESDEC(char *s_argL, char *s_argR, char *s_exp)
 
67
{
 
68
   /*
 
69
     ; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key).
 
70
     ; The result is delivered in xmm1.
 
71
   */
 
72
   V128 argL, argR;
 
73
   V128 res;
 
74
   char s_res[33];
 
75
   V128 exp;
 
76
   expand(&argL, s_argL);
 
77
   expand(&argR, s_argR);
 
78
   __asm__ __volatile__(
 
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"
 
85
      : /*out*/ "=m"(res)
 
86
      : "m"/*in*/(argL), "m"/*in*/(argR)
 
87
      : /*trash*/ "xmm1", "xmm2"
 
88
   );
 
89
 
 
90
   if (strlen(s_exp) > 0) {
 
91
      expand(&exp,  s_exp);
 
92
      assert (0 == memcmp(&res, &exp, 16));
 
93
   }
 
94
   unexpand (&res, s_res);
 
95
   printf ("aesdec %s %s result %s\n", s_argL, s_argR, s_res);
 
96
}
 
97
 
 
98
static void AESDECLAST(char *s_argL, char *s_argR, char *s_exp)
 
99
{
 
100
   /*
 
101
     ; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key).
 
102
     ; The result is delivered in xmm1.
 
103
   */
 
104
   V128 argL, argR;
 
105
   V128 res;
 
106
   char s_res[33];
 
107
   V128 exp;
 
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"
 
117
      : /*out*/ "=m"(res)
 
118
      : "m"/*in*/(argL), "m"/*in*/(argR)
 
119
      : /*trash*/ "xmm1", "xmm2"
 
120
   );
 
121
 
 
122
   if (strlen(s_exp) > 0) {
 
123
      expand(&exp,  s_exp);
 
124
      assert (0 == memcmp(&res, &exp, 16));
 
125
   }
 
126
   unexpand (&res, s_res);
 
127
   printf ("aesdeclast %s %s result %s\n", s_argL, s_argR, s_res);
 
128
}
 
129
 
 
130
static void AESENC(char *s_argL, char *s_argR, char *s_exp)
 
131
{
 
132
   /*
 
133
     ; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key).
 
134
     ; The result is delivered in xmm1.
 
135
   */
 
136
   V128 argL, argR;
 
137
   V128 res;
 
138
   char s_res[33];
 
139
   V128 exp;
 
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"
 
149
      : /*out*/ "=m"(res)
 
150
      : "m"/*in*/(argL), "m"/*in*/(argR)
 
151
      : /*trash*/ "xmm1", "xmm2"
 
152
   );
 
153
 
 
154
   if (strlen(s_exp) > 0) {
 
155
      expand(&exp,  s_exp);
 
156
      assert (0 == memcmp(&res, &exp, 16));
 
157
   }
 
158
   unexpand (&res, s_res);
 
159
   printf ("aesenc %s %s result %s\n", s_argL, s_argR, s_res);
 
160
}
 
161
 
 
162
static void AESENCLAST(char *s_argL, char *s_argR, char *s_exp)
 
163
{
 
164
   /*
 
165
     ; xmm1 and xmm2 hold two 128-bit inputs (xmm1 = State; xmm2 = Round key)
 
166
     ; The result delivered in xmm1
 
167
   */
 
168
   V128 argL, argR;
 
169
   V128 res;
 
170
   char s_res[33];
 
171
   V128 exp;
 
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"
 
181
      : /*out*/ "=m"(res)
 
182
      : "m"/*in*/(argL), "m"/*in*/(argR)
 
183
      : /*trash*/ "xmm1", "xmm2"
 
184
   );
 
185
 
 
186
   if (strlen(s_exp) > 0) {
 
187
      expand(&exp,  s_exp);
 
188
      assert (0 == memcmp(&res, &exp, 16));
 
189
   }
 
190
   unexpand (&res, s_res);
 
191
   printf ("aesenclast %s %s result %s\n", s_argL, s_argR, s_res);
 
192
}
 
193
 
 
194
static void AESIMC(char *s_argR, char *s_exp)
 
195
{
 
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 */
 
199
 
 
200
   V128 argR;
 
201
   V128 res;
 
202
   char s_res[33];
 
203
   V128 exp;
 
204
   expand(&argR, s_argR);
 
205
 
 
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"
 
211
      : /*out*/ "=m"(res)
 
212
      : "m"/*in*/(argR)
 
213
      : /*trash*/ "xmm5"
 
214
   );
 
215
 
 
216
   if (strlen(s_exp) > 0) {
 
217
      expand(&exp,  s_exp);
 
218
      assert (0 == memcmp(&res, &exp, 16));
 
219
   }
 
220
   unexpand (&res, s_res);
 
221
   printf ("aesimc %s result %s\n", s_argR, s_res);
 
222
}
 
223
 
 
224
static void AESKEYGENASSIST(int imm, char* s_argL, char* s_exp)
 
225
{
 
226
   /*
 
227
     ; xmm2 holds a 128-bit input; imm8 holds the RCON value
 
228
     ; result delivered in xmm1
 
229
   */
 
230
 
 
231
   V128 argL;
 
232
   V128 res;
 
233
   char s_res[33];
 
234
   V128 exp;
 
235
   expand(&argL, s_argL);
 
236
   if (imm == 1)
 
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"
 
243
         : /*out*/ "=m"(res)
 
244
         : "m"/*in*/(argL)
 
245
         : /*trash*/ "xmm1", "xmm2"
 
246
      );
 
247
   else if (imm == 2)
 
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"
 
254
         : /*out*/ "=m"(res)
 
255
         : "m"/*in*/(argL)
 
256
         : /*trash*/ "xmm1", "xmm2"
 
257
      );
 
258
   else if (imm == 8)
 
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"
 
265
         : /*out*/ "=m"(res)
 
266
         : "m"/*in*/(argL)
 
267
         : /*trash*/ "xmm1", "xmm2"
 
268
      );
 
269
   else assert (0);
 
270
 
 
271
   if (strlen(s_exp) > 0) {
 
272
      expand(&exp,  s_exp);
 
273
      assert (0 == memcmp(&res, &exp, 16));
 
274
   }
 
275
   unexpand (&res, s_res);
 
276
   printf ("aeskeygenassist %d %s result %s\n", imm, s_argL, s_res);
 
277
}
 
278
 
 
279
typedef struct Aes_Args {
 
280
   char* argL;
 
281
   char* argR;
 
282
   int imm; // only for aeskeygenassist
 
283
} Aes_Args;
 
284
 
 
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",
 
290
    8},
 
291
   {"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
 
292
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 
293
    8},
 
294
   {"3243f6a8885a308d313198a2e0370734",
 
295
    "2b7e151628aed2a6abf7158809cf4f3c",
 
296
    2},
 
297
   {"193de3bea0f4e22b9ac68d2ae9f84808",
 
298
    "d42711aee0bf98f1b8b45de51e415230",
 
299
    2},
 
300
   {"d4bf5d30e0b452aeb84111f11e2798e5",
 
301
    "046681e5e0cb199a48f8d37a2806264c",
 
302
    1},
 
303
   {"a0fafe1788542cb123a339392a6c7605",
 
304
    "a49c7ff2689f352b6b5bea43026a5049",
 
305
    1},
 
306
   {"49ded28945db96f17f39871a7702533b",
 
307
    "49db873b453953897f02d2f177de961a",
 
308
    8},
 
309
   {"584dcaf11b4b5aacdbe7caa81b6bb0e5",
 
310
    "f2c295f27a96b9435935807a7359f67f",
 
311
    8},
 
312
   {"aa8f5f0361dde3ef82d24ad26832469a",
 
313
    "ac73cf7befc111df13b5d6b545235ab8",
 
314
    2},
 
315
   {"acc1d6b8efb55a7b1323cfdf457311b5",
 
316
    "75ec0993200b633353c0cf7cbb25d0dc",
 
317
    2},
 
318
   {"e9317db5cb322c723d2e895faf090794",
 
319
    "d014f9a8c9ee2589e13f0cc8b6630ca6",
 
320
    1},
 
321
   {NULL,
 
322
    NULL,
 
323
    0}
 
324
};
 
325
 
 
326
int main ( void )
 
327
{
 
328
   int i;
 
329
 
 
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)
 
333
          Rev. 3.0
 
334
          by Shay Gueron */
 
335
   AESKEYGENASSIST(1,
 
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
 
351
      seems wrong.
 
352
      The below fails both under Valgrind and natively.
 
353
      AESIMC("48692853686179295b477565726f6e5d",
 
354
             "627a6f6644b109c82b18330a81c3b3e5");
 
355
      So we use the example given for the InvMixColums 
 
356
      transformation. */
 
357
   AESIMC("8dcab9dc035006bc8f57161e00cafd8d",
 
358
          "d635a667928b5eaeeec9cc3bc55f5777");
 
359
 
 
360
 
 
361
   /* and now a bunch of other calls. The below are verified
 
362
      using the aes.stdout.exp (produced by a native run). */
 
363
   
 
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, "");
 
371
   }
 
372
   return 0;
 
373
}