summaryrefslogtreecommitdiff
path: root/fpcsrc/tests/test/taes1.pp
blob: 5d4578ae3497f9cf2704cfde6b379eb3b03f065a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
{ %CPU=x86_64 }
Program AESTest;
{$INLINE ON}
{$ASMMODE INTEL}
{$MODE DELPHI}

Uses Cpu,SysUtils;

Type
  Word32 = LongWord;
  Word64 = QWord;
  WordPR = Word64;

  PAESKey256 = ^TAESKey256; TAESKey256 = Array [0..3] of Word64;

  PAESOpenedKey = ^TAESOpenedKey; TAESOpenedKey = Packed Record
    EnCryptRoundKeys    : Array [0..14, 0..3] Of Word32;
    Padding0            : Array [0..3] of Word32;
    DeCryptRoundKeys    : Array [0..14, 0..3] Of Word32;
    Padding1            : Array [0..3] of Word32;
  End;

Const
  Test_Key     : Array[0..3] of Word64 = ($0706050403020100, $0f0e0d0c0b0a0908, $1716151413121110, $1f1e1d1c1b1a1918);
  Test_Data    : Array[0..1] of Word64 = (Word64($7766554433221100), Word64($ffeeddccbbaa9988));
  Test_Crypt   : Array[0..1] of Word64 = (Word64($bf456751cab7a28e), Word64($8960494b9049fcea));

Var
  OpenedKey   : TAESOpenedKey;
  Data        : Array [0..1] of Word64;
  Passed      : Boolean;

Procedure OpenKey_AES(Key: PAESKey256; OpenedKey: PAESOpenedKey); Assembler; NoStackFrame;
  Procedure key_expansion; Assembler; NoStackFrame;
  Asm
   MOV RDX, RCX
   PSHUFD XMM2, XMM2, 011111111b; PXOR XMM2, XMM1; MOVD EAX, XMM2; MOV [RCX], EAX; ADD RCX, 4
   PSHUFD XMM1, XMM1, 011100101b; MOVD EBX, XMM1; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   PSHUFD XMM1, XMM1, 011100110b; MOVD EBX, XMM1; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   PSHUFD XMM1, XMM1, 011100111b; MOVD EBX, XMM1; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   MOVDQU XMM4, [RDX]; AESKEYGENASSIST XMM4, XMM4, 0
   PSHUFD XMM4, XMM4, 011100110b; MOVD EAX, XMM4; MOVD EBX, XMM3; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   PSHUFD XMM3, XMM3, 011100101b; MOVD EBX, XMM3; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   PSHUFD XMM3, XMM3, 011100110b; MOVD EBX, XMM3; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   PSHUFD XMM3, XMM3, 011100111b; MOVD EBX, XMM3; XOR EAX, EBX; MOV [RCX], EAX; ADD RCX, 4
   MOVDQU XMM1, [RDX]; ADD RDX, $10; MOVDQU XMM3, [RDX]
  End;
Asm
 PUSH RBX
{$ifndef win64}
 // fix parameter locations
 MOV RDX,RSI
 MOV RCX,RDI 
{$endif win64}
 MOV R8, RDX
 MOVDQU XMM1, [RCX]; MOVDQU XMM3, [RCX+16]
 MOVDQU [RDX], XMM1; MOVDQU [RDX + $10], XMM3
 LEA RCX, [RDX+$20]
 AESKEYGENASSIST XMM2, XMM3, $1;  CALL key_expansion
 AESKEYGENASSIST XMM2, XMM3, $2;  CALL key_expansion
 AESKEYGENASSIST XMM2, XMM3, $4;  CALL key_expansion
 AESKEYGENASSIST XMM2, XMM3, $8;  CALL key_expansion
 AESKEYGENASSIST XMM2, XMM3, $10; CALL key_expansion
 AESKEYGENASSIST XMM2, XMM3, $20; CALL key_expansion
 AESKEYGENASSIST XMM2, XMM3, $40; CALL key_expansion
 MOVDQU XMM0,  [R8+$00]; MOVDQU XMM1,  [R8+$10]; MOVDQU XMM2,  [R8+$20]; MOVDQU XMM3,  [R8+$30]
 MOVDQU XMM4,  [R8+$40]; MOVDQU XMM5,  [R8+$50]; MOVDQU XMM6,  [R8+$60]; MOVDQU XMM7,  [R8+$70]
 MOVDQU XMM8,  [R8+$80]; MOVDQU XMM9,  [R8+$90]; MOVDQU XMM10, [R8+$A0]; MOVDQU XMM11, [R8+$B0]
 MOVDQU XMM12, [R8+$C0]; MOVDQU XMM13, [R8+$D0]; MOVDQU XMM14, [R8+$E0]
 AESIMC XMM1,  XMM1; AESIMC XMM2,  XMM2;  AESIMC XMM3,  XMM3;  AESIMC XMM4,  XMM4
 AESIMC XMM5,  XMM5; AESIMC XMM6,  XMM6;  AESIMC XMM7,  XMM7;  AESIMC XMM8,  XMM8
 AESIMC XMM9,  XMM9; AESIMC XMM10, XMM10; AESIMC XMM11, XMM11; AESIMC XMM12, XMM12
 AESIMC XMM13, XMM13
 MOVDQU [R8+$100], XMM0;  MOVDQU [R8+$110], XMM1;  MOVDQU [R8+$120], XMM2;  MOVDQU [R8+$130], XMM3
 MOVDQU [R8+$140], XMM4;  MOVDQU [R8+$150], XMM5;  MOVDQU [R8+$160], XMM6;  MOVDQU [R8+$170], XMM7
 MOVDQU [R8+$180], XMM8;  MOVDQU [R8+$190], XMM9;  MOVDQU [R8+$1A0], XMM10; MOVDQU [R8+$1B0], XMM11
 MOVDQU [R8+$1C0], XMM12; MOVDQU [R8+$1D0], XMM13; MOVDQU [R8+$1E0], XMM14
 POP RBX
End;

Procedure EnCrypt_AES(InData, OutData: Pointer; DataSize: WordPR; EnCryptRoundKeys: Pointer); Assembler; NoStackFrame;
Asm
{$ifndef win64}
 // fix parameter locations
 MOV R9,RCX
 MOV R8,RDX
 MOV RDX,RSI
 MOV RCX,RDI
{$endif win64}
 // Loading encryption keys
 MOVDQU XMM0, [R9+16*0]
 MOVDQU XMM1, [R9+16*1]
 MOVDQU XMM2, [R9+16*2]
 MOVDQU XMM3, [R9+16*3]
 MOVDQU XMM4, [R9+16*4]
 MOVDQU XMM5, [R9+16*5]
 MOVDQU XMM6, [R9+16*6]
 MOVDQU XMM7, [R9+16*7]
 MOVDQU XMM8, [R9+16*8]
 MOVDQU XMM9, [R9+16*9]
 MOVDQU XMM10, [R9+16*10]
 MOVDQU XMM11, [R9+16*11]
 MOVDQU XMM12, [R9+16*12]
 MOVDQU XMM13, [R9+16*13]
 MOVDQU XMM14, [R9+16*14]
 // Setting the main loop
 XCHG RCX, R8
 SHR RCX, 4
@Loop: MOVDQU XMM15, [R8]; ADD R8, 16
       PXOR XMM15, XMM0
       AESENC XMM15, XMM1
       AESENC XMM15, XMM2
       AESENC XMM15, XMM3
       AESENC XMM15, XMM4
       AESENC XMM15, XMM5
       AESENC XMM15, XMM6
       AESENC XMM15, XMM7
       AESENC XMM15, XMM8
       AESENC XMM15, XMM9
       AESENC XMM15, XMM10
       AESENC XMM15, XMM11
       AESENC XMM15, XMM12
       AESENC XMM15, XMM13
       AESENCLAST XMM15, XMM14
       MOVDQU [RDX], XMM15; ADD RDX, 16
       LOOP @Loop
End;

Procedure DeCrypt_AES(InData, OutData: Pointer; DataSize: WordPR; DeCryptRoundKeys: Pointer); Assembler; NoStackFrame;
Asm
{$ifndef win64}
 // fix parameter locations
 MOV R9,RCX
 MOV R8,RDX
 MOV RDX,RSI
 MOV RCX,RDI  
{$endif win64}
 // Loading decryption keys
 MOVDQU XMM0, [R9+16*0]
 MOVDQU XMM1, [R9+16*1]
 MOVDQU XMM2, [R9+16*2]
 MOVDQU XMM3, [R9+16*3]
 MOVDQU XMM4, [R9+16*4]
 MOVDQU XMM5, [R9+16*5]
 MOVDQU XMM6, [R9+16*6]
 MOVDQU XMM7, [R9+16*7]
 MOVDQU XMM8, [R9+16*8]
 MOVDQU XMM9, [R9+16*9]
 MOVDQU XMM10, [R9+16*10]
 MOVDQU XMM11, [R9+16*11]
 MOVDQU XMM12, [R9+16*12]
 MOVDQU XMM13, [R9+16*13]
 MOVDQU XMM14, [R9+16*14]
 // Setting the main loop
 XCHG RCX, R8
 SHR RCX, 4
@Loop: MOVDQU XMM15, [R8]; ADD R8, 16
       PXOR XMM15, XMM14
       AESDEC XMM15, XMM13
       AESDEC XMM15, XMM12
       AESDEC XMM15, XMM11
       AESDEC XMM15, XMM10
       AESDEC XMM15, XMM9
       AESDEC XMM15, XMM8
       AESDEC XMM15, XMM7
       AESDEC XMM15, XMM6
       AESDEC XMM15, XMM5
       AESDEC XMM15, XMM4
       AESDEC XMM15, XMM3
       AESDEC XMM15, XMM2
       AESDEC XMM15, XMM1
       AESDECLAST XMM15, XMM0
       MOVDQU [RDX], XMM15; ADD RDX, 16
       LOOP @Loop
End;

BEGIN
  if AESSupport then
    begin
      OpenKey_AES(@Test_Key, @OpenedKey);
      EnCrypt_AES(@Test_Data, @Data, 16, @OpenedKey.EnCryptRoundKeys);
      Passed := SysUtils.CompareMem(@Data, @Test_Crypt, 16);
      DeCrypt_AES(@Data, @Data, 16, @OpenedKey.DeCryptRoundKeys);
      Passed := Passed and SysUtils.CompareMem(@Data, @Test_Data, 16);
      If Not Passed Then Halt(1);
      writeln('ok');
    end 
  else
    writeln('CPU has no AES instruction support');
END.