]> git.saurik.com Git - apple/xnu.git/blob - bsd/crypto/aes/i386/aes_crypt_hw.s
xnu-1699.32.7.tar.gz
[apple/xnu.git] / bsd / crypto / aes / i386 / aes_crypt_hw.s
1 /* This files defines _aes_encrypt_hw and _aes_decrypt_hw --- Intel Westmere HW AES-based implementation
2 of _aes_encrypt and _aes_decrypt.
3
4 These 2 functions SHOULD BE entried ONLY after the AES HW is verified to be available.
5 They SHOULD NOT be called without AES HW detection. It might cause xnu to crash.
6
7 The AES HW is detected 1st thing in
8 _aes_encrypt (EncryptDecrypt.s)
9 _aes_decrypt (EncryptDecrypt.s)
10 and, if AES HW is detected, branch without link (ie, jump) to the functions here.
11
12 The implementation here follows the examples in an Intel White Paper
13 "Intel Advanced Encryption Standard (AES) Instruction Set" Rev.2 01
14
15 Note: Rev. 03 Final 2010 01 26 is available. Looks like some code change from Rev.2 01
16
17 cclee 3-13-10
18 */
19
20 .text
21 .align 4,0x90
22 .globl _aes_encrypt_hw
23 _aes_encrypt_hw:
24
25 #if defined __i386__
26 movl 4(%esp), %eax // in
27 movl 12(%esp), %edx // ctx
28 movl 8(%esp), %ecx // out
29
30 #define LOCAL_SIZE (12+16+16) // 16-byte align (-4 for return address) + 16 (xmm0) + 16 (xmm1)
31 #define in %eax
32 #define ctx %edx
33 #define out %ecx
34 #define r13 %esp
35
36 #else // x86_64
37
38 #define LOCAL_SIZE (8+16+16) // 16-byte align (-8 for return address) + 16 (xmm0) + 16 (xmm1)
39 #define in %rdi
40 #define ctx %rdx
41 #define out %rsi
42 #define r13 %rsp
43
44 #endif // i386 or x86_64
45
46 #ifdef KERNEL
47 sub $LOCAL_SIZE, r13
48 movaps %xmm0, (r13)
49 #endif
50 movups (in), %xmm0
51
52 // key length identification
53 movl 240(ctx), %eax // key length
54 cmp $160, %eax
55 je L_AES_128
56 cmp $192, %eax
57 je L_AES_192
58 cmp $224, %eax
59 je L_AES_256
60 mov $-1, %eax // return ERROR
61 #ifdef KERNEL
62 movaps (r13), %xmm0
63 add $LOCAL_SIZE, r13
64 #endif
65 ret
66
67 L_AES_128:
68 testb $15, %dl // check whether expanded key is 16-byte aligned
69 jne 0f // if not 16-byte aligned, aesenc xmm, m128 won't work
70 pxor (ctx), %xmm0
71 aesenc 16(ctx), %xmm0
72 aesenc 32(ctx), %xmm0
73 aesenc 48(ctx), %xmm0
74 aesenc 64(ctx), %xmm0
75 aesenc 80(ctx), %xmm0
76 aesenc 96(ctx), %xmm0
77 aesenc 112(ctx), %xmm0
78 aesenc 128(ctx), %xmm0
79 aesenc 144(ctx), %xmm0
80 aesenclast 160(ctx), %xmm0
81 xorl %eax, %eax
82 movups %xmm0, (out)
83 #ifdef KERNEL
84 movaps (r13), %xmm0
85 add $LOCAL_SIZE, r13
86 #endif
87 ret
88 0: // special case expanded key is not 16-byte aligned
89 #ifdef KERNEL
90 movaps %xmm1, 16(r13) // save xmm1 into stack
91 #endif
92 movups (ctx), %xmm1
93 pxor %xmm1, %xmm0
94 movups 16(ctx), %xmm1
95 aesenc %xmm1, %xmm0
96 movups 32(ctx), %xmm1
97 aesenc %xmm1, %xmm0
98 movups 48(ctx), %xmm1
99 aesenc %xmm1, %xmm0
100 movups 64(ctx), %xmm1
101 aesenc %xmm1, %xmm0
102 movups 80(ctx), %xmm1
103 aesenc %xmm1, %xmm0
104 movups 96(ctx), %xmm1
105 aesenc %xmm1, %xmm0
106 movups 112(ctx), %xmm1
107 aesenc %xmm1, %xmm0
108 movups 128(ctx), %xmm1
109 aesenc %xmm1, %xmm0
110 movups 144(ctx), %xmm1
111 aesenc %xmm1, %xmm0
112 movups 160(ctx), %xmm1
113 aesenclast %xmm1, %xmm0
114 xorl %eax, %eax
115 movups %xmm0, (out)
116 #ifdef KERNEL
117 movaps (r13), %xmm0
118 movaps 16(r13), %xmm1
119 add $LOCAL_SIZE, r13
120 #endif
121 ret
122
123 L_AES_192:
124 testb $15, %dl // check whether expanded key is 16-byte aligned
125 jne 0f // if not 16-byte aligned, aesenc xmm, m128 won't work
126 pxor (ctx), %xmm0
127 aesenc 16(ctx), %xmm0
128 aesenc 32(ctx), %xmm0
129 aesenc 48(ctx), %xmm0
130 aesenc 64(ctx), %xmm0
131 aesenc 80(ctx), %xmm0
132 aesenc 96(ctx), %xmm0
133 aesenc 112(ctx), %xmm0
134 aesenc 128(ctx), %xmm0
135 aesenc 144(ctx), %xmm0
136 aesenc 160(ctx), %xmm0
137 aesenc 176(ctx), %xmm0
138 aesenclast 192(ctx), %xmm0
139 xorl %eax, %eax
140 movups %xmm0, (out)
141 #ifdef KERNEL
142 movaps (r13), %xmm0
143 add $LOCAL_SIZE, r13
144 #endif
145 ret
146 0: // special case expanded key is not 16-byte aligned
147 #ifdef KERNEL
148 movaps %xmm1, 16(r13) // save xmm1 into stack
149 #endif
150 movups (ctx), %xmm1
151 pxor %xmm1, %xmm0
152 movups 16(ctx), %xmm1
153 aesenc %xmm1, %xmm0
154 movups 32(ctx), %xmm1
155 aesenc %xmm1, %xmm0
156 movups 48(ctx), %xmm1
157 aesenc %xmm1, %xmm0
158 movups 64(ctx), %xmm1
159 aesenc %xmm1, %xmm0
160 movups 80(ctx), %xmm1
161 aesenc %xmm1, %xmm0
162 movups 96(ctx), %xmm1
163 aesenc %xmm1, %xmm0
164 movups 112(ctx), %xmm1
165 aesenc %xmm1, %xmm0
166 movups 128(ctx), %xmm1
167 aesenc %xmm1, %xmm0
168 movups 144(ctx), %xmm1
169 aesenc %xmm1, %xmm0
170 movups 160(ctx), %xmm1
171 aesenc %xmm1, %xmm0
172 movups 176(ctx), %xmm1
173 aesenc %xmm1, %xmm0
174 movups 192(ctx), %xmm1
175 aesenclast %xmm1, %xmm0
176 xorl %eax, %eax
177 movups %xmm0, (out)
178 #ifdef KERNEL
179 movaps (r13), %xmm0
180 movaps 16(r13), %xmm1
181 add $LOCAL_SIZE, r13
182 #endif
183 ret
184
185 L_AES_256:
186 testb $15, %dl // check whether expanded key is 16-byte aligned
187 jne 0f // if not 16-byte aligned, aesenc xmm, m128 won't work
188 pxor (ctx), %xmm0
189 aesenc 16(ctx), %xmm0
190 aesenc 32(ctx), %xmm0
191 aesenc 48(ctx), %xmm0
192 aesenc 64(ctx), %xmm0
193 aesenc 80(ctx), %xmm0
194 aesenc 96(ctx), %xmm0
195 aesenc 112(ctx), %xmm0
196 aesenc 128(ctx), %xmm0
197 aesenc 144(ctx), %xmm0
198 aesenc 160(ctx), %xmm0
199 aesenc 176(ctx), %xmm0
200 aesenc 192(ctx), %xmm0
201 aesenc 208(ctx), %xmm0
202 aesenclast 224(ctx), %xmm0
203 xorl %eax, %eax
204 movups %xmm0, (out)
205 #ifdef KERNEL
206 movaps (r13), %xmm0
207 add $LOCAL_SIZE, r13
208 #endif
209 ret
210 0: // special case expanded key is not 16-byte aligned
211 #ifdef KERNEL
212 movaps %xmm1, 16(r13) // save xmm1 into stack
213 #endif
214 movups (ctx), %xmm1
215 pxor %xmm1, %xmm0
216 movups 16(ctx), %xmm1
217 aesenc %xmm1, %xmm0
218 movups 32(ctx), %xmm1
219 aesenc %xmm1, %xmm0
220 movups 48(ctx), %xmm1
221 aesenc %xmm1, %xmm0
222 movups 64(ctx), %xmm1
223 aesenc %xmm1, %xmm0
224 movups 80(ctx), %xmm1
225 aesenc %xmm1, %xmm0
226 movups 96(ctx), %xmm1
227 aesenc %xmm1, %xmm0
228 movups 112(ctx), %xmm1
229 aesenc %xmm1, %xmm0
230 movups 128(ctx), %xmm1
231 aesenc %xmm1, %xmm0
232 movups 144(ctx), %xmm1
233 aesenc %xmm1, %xmm0
234 movups 160(ctx), %xmm1
235 aesenc %xmm1, %xmm0
236 movups 176(ctx), %xmm1
237 aesenc %xmm1, %xmm0
238 movups 192(ctx), %xmm1
239 aesenc %xmm1, %xmm0
240 movups 208(ctx), %xmm1
241 aesenc %xmm1, %xmm0
242 movups 224(ctx), %xmm1
243 aesenclast %xmm1, %xmm0
244 xorl %eax, %eax
245 movups %xmm0, (out)
246 #ifdef KERNEL
247 movaps (r13), %xmm0
248 movaps 16(r13), %xmm1
249 add $LOCAL_SIZE, r13
250 #endif
251 ret
252
253
254 .text
255 .align 4,0x90
256 .globl _aes_decrypt_hw
257 _aes_decrypt_hw:
258
259 #if defined __i386__
260 movl 4(%esp), %eax // in
261 movl 12(%esp), %edx // ctx
262 movl 8(%esp), %ecx // out
263
264 #endif
265
266 #ifdef KERNEL
267 sub $LOCAL_SIZE, r13
268 movaps %xmm0, (r13)
269 #endif
270 movups (in), %xmm0
271
272 // key length identification
273 movl 240(ctx), %eax // key length
274 cmp $160, %eax
275 je 0f // AES-128
276 cmp $192, %eax
277 je 1f // AES-192
278 cmp $224, %eax
279 je 2f // AES-256
280 mov $-1, %eax // return ERROR
281 #ifdef KERNEL
282 movaps (r13), %xmm0
283 add $LOCAL_SIZE, r13
284 #endif
285 ret
286
287 0: // AES-128
288 testb $15, %dl // check whether expanded key is 16-byte aligned
289 jne 9f // if not 16-byte aligned, aesenc xmm, m128 won't work
290 pxor 160(ctx), %xmm0
291 aesdec 144(ctx), %xmm0
292 aesdec 128(ctx), %xmm0
293 aesdec 112(ctx), %xmm0
294 aesdec 96(ctx), %xmm0
295 aesdec 80(ctx), %xmm0
296 aesdec 64(ctx), %xmm0
297 aesdec 48(ctx), %xmm0
298 aesdec 32(ctx), %xmm0
299 aesdec 16(ctx), %xmm0
300 aesdeclast (ctx), %xmm0
301 xorl %eax, %eax
302 movups %xmm0, (out)
303 #ifdef KERNEL
304 movaps (r13), %xmm0
305 add $LOCAL_SIZE, r13
306 #endif
307 ret
308 9: // AES-128 Decrypt : special case expanded key is not 16-byte aligned
309 #ifdef KERNEL
310 movaps %xmm1, 16(r13) // save xmm1 into stack
311 #endif
312 movups 160(ctx), %xmm1
313 pxor %xmm1, %xmm0
314 movups 144(ctx), %xmm1
315 aesdec %xmm1, %xmm0
316 movups 128(ctx), %xmm1
317 aesdec %xmm1, %xmm0
318 movups 112(ctx), %xmm1
319 aesdec %xmm1, %xmm0
320 movups 96(ctx), %xmm1
321 aesdec %xmm1, %xmm0
322 movups 80(ctx), %xmm1
323 aesdec %xmm1, %xmm0
324 movups 64(ctx), %xmm1
325 aesdec %xmm1, %xmm0
326 movups 48(ctx), %xmm1
327 aesdec %xmm1, %xmm0
328 movups 32(ctx), %xmm1
329 aesdec %xmm1, %xmm0
330 movups 16(ctx), %xmm1
331 aesdec %xmm1, %xmm0
332 movups (ctx), %xmm1
333 aesdeclast %xmm1, %xmm0
334 xorl %eax, %eax
335 movups %xmm0, (out)
336 #ifdef KERNEL
337 movaps (r13), %xmm0
338 movaps 16(r13), %xmm1
339 add $LOCAL_SIZE, r13
340 #endif
341 ret
342
343 1: // AES-192
344 testb $15, %dl // check whether expanded key is 16-byte aligned
345 jne 9f // if not 16-byte aligned, aesenc xmm, m128 won't work
346 pxor 192(ctx), %xmm0
347 aesdec 176(ctx), %xmm0
348 aesdec 160(ctx), %xmm0
349 aesdec 144(ctx), %xmm0
350 aesdec 128(ctx), %xmm0
351 aesdec 112(ctx), %xmm0
352 aesdec 96(ctx), %xmm0
353 aesdec 80(ctx), %xmm0
354 aesdec 64(ctx), %xmm0
355 aesdec 48(ctx), %xmm0
356 aesdec 32(ctx), %xmm0
357 aesdec 16(ctx), %xmm0
358 aesdeclast (ctx), %xmm0
359 xorl %eax, %eax
360 movups %xmm0, (out)
361 #ifdef KERNEL
362 movaps (r13), %xmm0
363 add $LOCAL_SIZE, r13
364 #endif
365 ret
366 9: // AES-192 Decrypt : special case expanded key is not 16-byte aligned
367 #ifdef KERNEL
368 movaps %xmm1, 16(r13) // save xmm1 into stack
369 #endif
370 movups 192(ctx), %xmm1
371 pxor %xmm1, %xmm0
372 movups 176(ctx), %xmm1
373 aesdec %xmm1, %xmm0
374 movups 160(ctx), %xmm1
375 aesdec %xmm1, %xmm0
376 movups 144(ctx), %xmm1
377 aesdec %xmm1, %xmm0
378 movups 128(ctx), %xmm1
379 aesdec %xmm1, %xmm0
380 movups 112(ctx), %xmm1
381 aesdec %xmm1, %xmm0
382 movups 96(ctx), %xmm1
383 aesdec %xmm1, %xmm0
384 movups 80(ctx), %xmm1
385 aesdec %xmm1, %xmm0
386 movups 64(ctx), %xmm1
387 aesdec %xmm1, %xmm0
388 movups 48(ctx), %xmm1
389 aesdec %xmm1, %xmm0
390 movups 32(ctx), %xmm1
391 aesdec %xmm1, %xmm0
392 movups 16(ctx), %xmm1
393 aesdec %xmm1, %xmm0
394 movups (ctx), %xmm1
395 aesdeclast %xmm1, %xmm0
396 xorl %eax, %eax
397 movups %xmm0, (out)
398 #ifdef KERNEL
399 movaps (r13), %xmm0
400 movaps 16(r13), %xmm1
401 add $LOCAL_SIZE, r13
402 #endif
403 ret
404
405 2: // AES-256
406 testb $15, %dl // check whether expanded key is 16-byte aligned
407 jne 9f // if not 16-byte aligned, aesenc xmm, m128 won't work
408 pxor 224(ctx), %xmm0
409 aesdec 208(ctx), %xmm0
410 aesdec 192(ctx), %xmm0
411 aesdec 176(ctx), %xmm0
412 aesdec 160(ctx), %xmm0
413 aesdec 144(ctx), %xmm0
414 aesdec 128(ctx), %xmm0
415 aesdec 112(ctx), %xmm0
416 aesdec 96(ctx), %xmm0
417 aesdec 80(ctx), %xmm0
418 aesdec 64(ctx), %xmm0
419 aesdec 48(ctx), %xmm0
420 aesdec 32(ctx), %xmm0
421 aesdec 16(ctx), %xmm0
422 aesdeclast (ctx), %xmm0
423 xorl %eax, %eax
424 movups %xmm0, (out)
425 #ifdef KERNEL
426 movaps (r13), %xmm0
427 add $LOCAL_SIZE, r13
428 #endif
429 ret
430 9: // AES-256 Decrypt : special case expanded key is not 16-byte aligned
431 #ifdef KERNEL
432 movaps %xmm1, 16(r13) // save xmm1 into stack
433 #endif
434 movups 224(ctx), %xmm1
435 pxor %xmm1, %xmm0
436 movups 208(ctx), %xmm1
437 aesdec %xmm1, %xmm0
438 movups 192(ctx), %xmm1
439 aesdec %xmm1, %xmm0
440 movups 176(ctx), %xmm1
441 aesdec %xmm1, %xmm0
442 movups 160(ctx), %xmm1
443 aesdec %xmm1, %xmm0
444 movups 144(ctx), %xmm1
445 aesdec %xmm1, %xmm0
446 movups 128(ctx), %xmm1
447 aesdec %xmm1, %xmm0
448 movups 112(ctx), %xmm1
449 aesdec %xmm1, %xmm0
450 movups 96(ctx), %xmm1
451 aesdec %xmm1, %xmm0
452 movups 80(ctx), %xmm1
453 aesdec %xmm1, %xmm0
454 movups 64(ctx), %xmm1
455 aesdec %xmm1, %xmm0
456 movups 48(ctx), %xmm1
457 aesdec %xmm1, %xmm0
458 movups 32(ctx), %xmm1
459 aesdec %xmm1, %xmm0
460 movups 16(ctx), %xmm1
461 aesdec %xmm1, %xmm0
462 movups (ctx), %xmm1
463 aesdeclast %xmm1, %xmm0
464 xorl %eax, %eax
465 movups %xmm0, (out)
466 #ifdef KERNEL
467 movaps (r13), %xmm0
468 movaps 16(r13), %xmm1
469 add $LOCAL_SIZE, r13
470 #endif
471 ret
472