]>
Commit | Line | Data |
---|---|---|
2a014536 | 1 | /* |
94f03c9a | 2 | * Copyright (c) 2011-2014, Intel Corporation |
2a014536 BH |
3 | * Authors: Fenghua Yu <fenghua.yu@intel.com>, |
4 | * H. Peter Anvin <hpa@linux.intel.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms and conditions of the GNU General Public License, | |
8 | * version 2, as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | * more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along with | |
16 | * this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | * | |
19 | */ | |
20 | ||
795666e6 PA |
21 | #if defined(__i386__) || defined(__x86_64__) |
22 | ||
2a014536 BH |
23 | #define ENTRY(x) \ |
24 | .balign 64 ; \ | |
25 | .globl x ; \ | |
26 | x: | |
27 | ||
28 | #define ENDPROC(x) \ | |
29 | .size x, .-x ; \ | |
30 | .type x, @function | |
31 | ||
32 | #define RDRAND_RETRY_LIMIT 10 | |
33 | ||
795666e6 | 34 | #ifdef __x86_64__ |
2a014536 BH |
35 | |
36 | ENTRY(x86_rdrand_nlong) | |
37 | 1: | |
38 | mov $RDRAND_RETRY_LIMIT, %eax | |
39 | 2: | |
40 | .byte 0x48,0x0f,0xc7,0xf2 /* rdrand %rdx */ | |
41 | jnc 3f | |
42 | mov %rdx, (%rdi) | |
43 | add $8, %rdi | |
44 | sub $1, %esi | |
45 | jnz 1b | |
46 | ret | |
47 | 3: | |
48 | sub $1, %eax | |
49 | rep;nop | |
50 | jnz 2b | |
51 | ret | |
52 | ENDPROC(x86_rdrand_nlong) | |
53 | ||
54 | #define SETPTR(var,ptr) leaq var(%rip),ptr | |
55 | #define PTR0 %rdi | |
56 | #define PTR1 %rsi | |
57 | #define PTR2 %rcx | |
58 | #define NPTR2 1 /* %rcx = %r1, only 0-7 valid here */ | |
59 | ||
60 | #elif defined(__i386__) | |
61 | ||
62 | ENTRY(x86_rdrand_nlong) | |
63 | push %ebp | |
64 | mov %esp, %ebp | |
65 | push %edi | |
66 | movl 8(%ebp), %ecx | |
67 | movl 12(%ebp), %edx | |
68 | 1: | |
69 | mov $RDRAND_RETRY_LIMIT, %eax | |
70 | 2: | |
71 | .byte 0x0f,0xc7,0xf7 /* rdrand %edi */ | |
72 | jnc 3f | |
73 | mov %edi, (%ecx) | |
74 | add $4, %ecx | |
75 | sub $1, %edx | |
76 | jnz 2b | |
77 | pop %edi | |
78 | pop %ebp | |
79 | ret | |
80 | 3: | |
81 | sub $1, %eax | |
82 | rep;nop | |
83 | jnz 2b | |
84 | pop %edi | |
85 | pop %ebp | |
86 | ret | |
87 | ENDPROC(x86_rdrand_nlong) | |
88 | ||
89 | #define SETPTR(var,ptr) movl $(var),ptr | |
90 | #define PTR0 %eax | |
91 | #define PTR1 %edx | |
92 | #define PTR2 %ecx | |
93 | #define NPTR2 1 /* %rcx = %r1 */ | |
94 | ||
95 | #endif | |
96 | ||
2a014536 | 97 | ENTRY(x86_aes_mangle) |
795666e6 | 98 | #ifdef __i386__ |
2a014536 BH |
99 | push %ebp |
100 | mov %esp, %ebp | |
101 | movl 8(%ebp), %eax | |
102 | movl 12(%ebp), %edx | |
103 | #endif | |
104 | ||
105 | SETPTR(aes_round_keys, PTR2) | |
106 | ||
107 | movdqa (0*16)(PTR0), %xmm0 | |
108 | movdqa (1*16)(PTR0), %xmm1 | |
109 | movdqa (2*16)(PTR0), %xmm2 | |
110 | movdqa (3*16)(PTR0), %xmm3 | |
111 | movdqa (4*16)(PTR0), %xmm4 | |
112 | movdqa (5*16)(PTR0), %xmm5 | |
113 | movdqa (6*16)(PTR0), %xmm6 | |
114 | movdqa (7*16)(PTR0), %xmm7 | |
115 | ||
116 | pxor (0*16)(PTR1), %xmm0 | |
117 | pxor (1*16)(PTR1), %xmm1 | |
118 | pxor (2*16)(PTR1), %xmm2 | |
119 | pxor (3*16)(PTR1), %xmm3 | |
120 | pxor (4*16)(PTR1), %xmm4 | |
121 | pxor (5*16)(PTR1), %xmm5 | |
122 | pxor (6*16)(PTR1), %xmm6 | |
123 | pxor (7*16)(PTR1), %xmm7 | |
124 | ||
c851f481 | 125 | offset = 0 |
2a014536 | 126 | .rept 10 |
c851f481 PA |
127 | #ifdef __x86_64__ |
128 | movdqa offset(PTR2), %xmm8 | |
129 | offset = offset + 16 | |
130 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xc0 /* aesenc %xmm8, %xmm0 */ | |
131 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */ | |
132 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xd0 /* aesenc %xmm8, %xmm2 */ | |
133 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xd8 /* aesenc %xmm8, %xmm3 */ | |
134 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xe0 /* aesenc %xmm8, %xmm4 */ | |
135 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xe8 /* aesenc %xmm8, %xmm5 */ | |
136 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xf0 /* aesenc %xmm8, %xmm6 */ | |
137 | .byte 0x66,0x41,0x0f,0x38,0xdc,0xf8 /* aesenc %xmm8, %xmm7 */ | |
138 | #else | |
2a014536 BH |
139 | .byte 0x66,0x0f,0x38,0xdc,0x00+NPTR2 /* aesenc (PTR2), %xmm0 */ |
140 | .byte 0x66,0x0f,0x38,0xdc,0x08+NPTR2 /* aesenc (PTR2), %xmm1 */ | |
141 | .byte 0x66,0x0f,0x38,0xdc,0x10+NPTR2 /* aesenc (PTR2), %xmm2 */ | |
142 | .byte 0x66,0x0f,0x38,0xdc,0x18+NPTR2 /* aesenc (PTR2), %xmm3 */ | |
143 | .byte 0x66,0x0f,0x38,0xdc,0x20+NPTR2 /* aesenc (PTR2), %xmm4 */ | |
144 | .byte 0x66,0x0f,0x38,0xdc,0x28+NPTR2 /* aesenc (PTR2), %xmm5 */ | |
145 | .byte 0x66,0x0f,0x38,0xdc,0x30+NPTR2 /* aesenc (PTR2), %xmm6 */ | |
146 | .byte 0x66,0x0f,0x38,0xdc,0x38+NPTR2 /* aesenc (PTR2), %xmm7 */ | |
147 | add $16, PTR2 | |
c851f481 | 148 | #endif |
2a014536 BH |
149 | .endr |
150 | ||
c851f481 PA |
151 | #ifdef __x86_64__ |
152 | movdqa offset(PTR2), %xmm8 | |
153 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xc0 /* aesenclast %xmm8, %xmm0 */ | |
154 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xc8 /* aesenclast %xmm8, %xmm1 */ | |
155 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xd0 /* aesenclast %xmm8, %xmm2 */ | |
156 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xd8 /* aesenclast %xmm8, %xmm3 */ | |
157 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xe0 /* aesenclast %xmm8, %xmm4 */ | |
158 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xe8 /* aesenclast %xmm8, %xmm5 */ | |
159 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xf0 /* aesenclast %xmm8, %xmm6 */ | |
160 | .byte 0x66,0x41,0x0f,0x38,0xdd,0xf8 /* aesenclast %xmm8, %xmm7 */ | |
161 | #else | |
2a014536 BH |
162 | .byte 0x66,0x0f,0x38,0xdd,0x00+NPTR2 /* aesenclast (PTR2), %xmm0 */ |
163 | .byte 0x66,0x0f,0x38,0xdd,0x08+NPTR2 /* aesenclast (PTR2), %xmm1 */ | |
164 | .byte 0x66,0x0f,0x38,0xdd,0x10+NPTR2 /* aesenclast (PTR2), %xmm2 */ | |
165 | .byte 0x66,0x0f,0x38,0xdd,0x18+NPTR2 /* aesenclast (PTR2), %xmm3 */ | |
166 | .byte 0x66,0x0f,0x38,0xdd,0x20+NPTR2 /* aesenclast (PTR2), %xmm4 */ | |
167 | .byte 0x66,0x0f,0x38,0xdd,0x28+NPTR2 /* aesenclast (PTR2), %xmm5 */ | |
168 | .byte 0x66,0x0f,0x38,0xdd,0x30+NPTR2 /* aesenclast (PTR2), %xmm6 */ | |
169 | .byte 0x66,0x0f,0x38,0xdd,0x38+NPTR2 /* aesenclast (PTR2), %xmm7 */ | |
c851f481 | 170 | #endif |
2a014536 BH |
171 | |
172 | movdqa %xmm0, (0*16)(PTR0) | |
173 | movdqa %xmm1, (1*16)(PTR0) | |
174 | movdqa %xmm2, (2*16)(PTR0) | |
175 | movdqa %xmm3, (3*16)(PTR0) | |
176 | movdqa %xmm4, (4*16)(PTR0) | |
177 | movdqa %xmm5, (5*16)(PTR0) | |
178 | movdqa %xmm6, (6*16)(PTR0) | |
179 | movdqa %xmm7, (7*16)(PTR0) | |
180 | ||
181 | movdqa %xmm0, (0*16)(PTR1) | |
182 | movdqa %xmm1, (1*16)(PTR1) | |
183 | movdqa %xmm2, (2*16)(PTR1) | |
184 | movdqa %xmm3, (3*16)(PTR1) | |
185 | movdqa %xmm4, (4*16)(PTR1) | |
186 | movdqa %xmm5, (5*16)(PTR1) | |
187 | movdqa %xmm6, (6*16)(PTR1) | |
188 | movdqa %xmm7, (7*16)(PTR1) | |
189 | ||
795666e6 | 190 | #ifdef __i386__ |
2a014536 BH |
191 | pop %ebp |
192 | #endif | |
193 | ret | |
194 | ENDPROC(x86_aes_mangle) | |
2a014536 | 195 | |
94f03c9a PA |
196 | /* aeskeygenassist $imm,%xmm0,%xmm1 */ |
197 | #define AESKEYGENASSIST(imm) .byte 0x66,0x0f,0x3a,0xdf,0xc8,imm | |
198 | ||
199 | ENTRY(x86_aes_expand_key) | |
795666e6 | 200 | #ifdef __i386__ |
94f03c9a PA |
201 | push %ebp |
202 | mov %esp, %ebp | |
203 | movl 8(%ebp), %eax | |
204 | #endif | |
205 | ||
206 | SETPTR(aes_round_keys, PTR1) | |
207 | movdqu (PTR0), %xmm0 | |
208 | movdqa %xmm0, (PTR1) /* First slot = the plain key */ | |
209 | add $16, PTR1 | |
210 | ||
211 | AESKEYGENASSIST(0x01) | |
212 | call 1f | |
213 | AESKEYGENASSIST(0x02) | |
214 | call 1f | |
215 | AESKEYGENASSIST(0x04) | |
216 | call 1f | |
217 | AESKEYGENASSIST(0x08) | |
218 | call 1f | |
219 | AESKEYGENASSIST(0x10) | |
220 | call 1f | |
221 | AESKEYGENASSIST(0x20) | |
222 | call 1f | |
223 | AESKEYGENASSIST(0x40) | |
224 | call 1f | |
225 | AESKEYGENASSIST(0x80) | |
226 | call 1f | |
227 | AESKEYGENASSIST(0x1b) | |
228 | call 1f | |
229 | AESKEYGENASSIST(0x36) | |
230 | call 1f | |
231 | ||
795666e6 | 232 | #ifdef __i386__ |
94f03c9a PA |
233 | pop %ebp |
234 | #endif | |
235 | ret | |
2a014536 | 236 | |
94f03c9a PA |
237 | 1: |
238 | pshufd $0xff, %xmm1, %xmm1 | |
239 | movdqa %xmm0, %xmm2 | |
240 | pslldq $4, %xmm2 | |
241 | pxor %xmm2, %xmm0 | |
242 | pslldq $4, %xmm2 | |
243 | pxor %xmm2, %xmm0 | |
244 | pslldq $4, %xmm2 | |
245 | pxor %xmm2, %xmm0 | |
246 | pxor %xmm1, %xmm0 | |
247 | movdqa %xmm0, (PTR1) | |
248 | add $16, PTR1 | |
249 | ret | |
250 | ||
251 | ENDPROC(x86_aes_expand_key) | |
252 | ||
253 | .bss | |
254 | .balign 64 | |
255 | aes_round_keys: | |
256 | .space 11*16 | |
257 | .size aes_round_keys, .-aes_round_keys | |
795666e6 | 258 | |
2a014536 | 259 | #endif /* i386 or x86_64 */ |
b8579105 PA |
260 | |
261 | /* | |
262 | * This is necessary to keep the whole executable | |
263 | * from needing a writable stack. | |
264 | */ | |
265 | .section .note.GNU-stack,"",%progbits |