]> git.saurik.com Git - apple/xnu.git/blame_incremental - bsd/crypto/aes/i386/aes_modes_hw.s
xnu-1699.32.7.tar.gz
[apple/xnu.git] / bsd / crypto / aes / i386 / aes_modes_hw.s
... / ...
CommitLineData
1/*\r
2 ---------------------------------------------------------------------------\r
3 Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.\r
4\r
5 LICENSE TERMS\r
6\r
7 The free distribution and use of this software in both source and binary\r
8 form is allowed (with or without changes) provided that:\r
9\r
10 1. distributions of this source code include the above copyright\r
11 notice, this list of conditions and the following disclaimer;\r
12\r
13 2. distributions in binary form include the above copyright\r
14 notice, this list of conditions and the following disclaimer\r
15 in the documentation and/or other associated materials;\r
16\r
17 3. the copyright holder's name is not used to endorse products\r
18 built using this software without specific written permission.\r
19\r
20 ALTERNATIVELY, provided that this notice is retained in full, this product\r
21 may be distributed under the terms of the GNU General Public License (GPL),\r
22 in which case the provisions of the GPL apply INSTEAD OF those given above.\r
23\r
24 DISCLAIMER\r
25\r
26 This software is provided 'as is' with no explicit or implied warranties\r
27 in respect of its properties, including, but not limited to, correctness\r
28 and/or fitness for purpose.\r
29 ---------------------------------------------------------------------------\r
30 Issue 31/01/2006\r
31\r
32 These subroutines implement multiple block AES modes for ECB, CBC, CFB,\r
33 OFB and CTR encryption, The code provides support for the VIA Advanced \r
34 Cryptography Engine (ACE).\r
35\r
36 NOTE: In the following subroutines, the AES contexts (ctx) must be\r
37 16 byte aligned if VIA ACE is being used\r
38*/\r
39\r
40\r
41/* ---------------------------------------------------------------------------------------------------------------- \r
42\r
43 aes_encrypt_cbc function (see aes_modes.c or aes_modes_asm.s) :\r
44\r
45 For simplicity, I am assuming all variables are in 128-bit data type.\r
46\r
47 aes_rval aes_encrypt_cbc(const __m128 *ibuf, __m128 *iv, int num_blk, __m128 *obuf, const aes_encrypt_ctx *ctx)\r
48 {\r
49 while(num_blk--) {\r
50 *iv ^= *ibuf++;\r
51 aes_encrypt(iv, iv, ctx);\r
52 *obuf++ = *iv;\r
53 }\r
54 return 0;\r
55 }\r
56\r
57 The following is an implementation of this function using Intel AESNI.\r
58 This function _aes_encrypt_cbc_hw SHOULD NOT be called directly. \r
59 Developer should still call _aes_encrypt_cbc (in aes_modes_asm.s) which will poll cpu_capabilities and branch\r
60 to this aesni-based function should it detecs that aesni is available.\r
61 Blindly call this function SURELY will cause a CRASH on systems with no aesni support. \r
62\r
63 Note that each block starts with *iv, which is the output of the previous block. Therefore, the cbc blocks\r
64 are serially chained. This prevents us from arranging several blocks for encryption in parallel.\r
65\r
66 ----------------------------------------------------------------------------------------------------------------*/\r
67\r
68 .text\r
69 .align 4,0x90\r
70 .globl _aes_encrypt_cbc_hw\r
71_aes_encrypt_cbc_hw:\r
72\r
73 // push/save registers for local use\r
74#if defined __i386__\r
75\r
76 push %ebp\r
77 movl %esp, %ebp\r
78 push %ebx\r
79 push %edi\r
80\r
81 #define sp %esp\r
82\r
83#else // __x86_64__\r
84\r
85 push %rbp\r
86 mov %rsp, %rbp\r
87 push %rbx\r
88 push %r13\r
89 push %r14\r
90 push %r15\r
91\r
92 #define sp %rsp\r
93\r
94#endif\r
95\r
96 // if this is kernel code, need to save used xmm registers\r
97#ifdef KERNEL\r
98\r
99#if defined __i386__\r
100 sub $(8*16), %esp // for possible xmm0-xmm7 save/restore\r
101#else\r
102 sub $(16*16), %rsp // xmm0-xmm15 save/restore \r
103#endif\r
104\r
105 movaps %xmm0, (sp)\r
106 movaps %xmm1, 16(sp)\r
107 movaps %xmm2, 32(sp)\r
108 movaps %xmm3, 48(sp)\r
109 movaps %xmm4, 64(sp)\r
110 movaps %xmm5, 80(sp)\r
111 movaps %xmm6, 96(sp)\r
112 movaps %xmm7, 112(sp)\r
113#if defined __x86_64__\r
114 movaps %xmm8, 16*8(sp)\r
115 movaps %xmm9, 16*9(sp)\r
116 movaps %xmm10, 16*10(sp)\r
117 movaps %xmm11, 16*11(sp)\r
118 movaps %xmm12, 16*12(sp)\r
119 movaps %xmm13, 16*13(sp)\r
120 movaps %xmm14, 16*14(sp)\r
121 movaps %xmm15, 16*15(sp)\r
122#endif // __x86_64__\r
123\r
124#endif // KERNEL\r
125\r
126 #define iv %xmm0\r
127\r
128#ifdef __i386__\r
129\r
130 mov 12(%ebp), %eax // in_iv\r
131 mov 24(%ebp), %edx // ctx\r
132 movups (%eax), iv // iv = in_iv \r
133 mov 8(%ebp), %ebx // ibuf\r
134 mov 16(%ebp), %ecx // num_blk\r
135 mov 20(%ebp), %edi // obuf\r
136\r
137 #define ibuf %ebx\r
138 #define obuf %edi\r
139 #define num_blk %ecx \r
140 #define ctx %edx\r
141\r
142#else\r
143\r
144 mov %rdi, %rbx // ibuf\r
145 movups (%rsi), iv // iv = in_iv\r
146 mov %rdx, %r13 // num_blk\r
147 mov %rcx, %r14 // obuf\r
148 mov %r8, %r15 // ctx \r
149\r
150 #define ibuf %rbx\r
151 #define num_blk %r13d\r
152 #define obuf %r14 \r
153 #define ctx %r15\r
154\r
155#endif\r
156\r
157 mov 240(ctx), %eax // aes length\r
158 cmp $160, %eax // aes-128 encrypt ?\r
159 je L_encrypt_128\r
160 cmp $192, %eax // aes-192 encrypt ?\r
161 je L_encrypt_192\r
162 cmp $224, %eax // aes-256 encrypt ?\r
163 je L_encrypt_256\r
164 mov $-1, %eax // return error\r
165 jmp L_error \r
166\r
167 //\r
168 // aes-128 encrypt_cbc operation, up to L_HW_cbc_done\r
169 //\r
170\r
171L_encrypt_128:\r
172\r
173 cmp $1, num_blk // check number of block\r
174 jl L_HW_cbc_done // should it be less than 1, nothing to do\r
175\r
176 movups (ctx), %xmm2 // key0\r
177 movups 16(ctx), %xmm3 // key1\r
178 movups 32(ctx), %xmm4 // key2\r
179 movups 48(ctx), %xmm5 // key3\r
180 movups 64(ctx), %xmm6 // key4\r
181 movups 80(ctx), %xmm7 // key5\r
182#if defined __x86_64__\r
183 movups 96(ctx), %xmm8 // key6\r
184 movups 112(ctx), %xmm9 // key7\r
185 movups 128(ctx), %xmm10 // key8\r
186 movups 144(ctx), %xmm11 // key9\r
187 movups 160(ctx), %xmm12 // keyA\r
188#endif\r
189\r
190 // while (num_blk--) {\r
191 // *iv ^= *ibuf++;\r
192 // aes_encrypt(iv, iv, ctx);\r
193 // *obuf++ = *iv;\r
194 // }\r
1950:\r
196 movups (ibuf), %xmm1 // *ibuf\r
197 pxor %xmm2, iv // 1st instruction inside aes_encrypt\r
198 pxor %xmm1, iv // *iv ^= *ibuf\r
199\r
200 // finishing up the rest of aes_encrypt\r
201 aesenc %xmm3, iv\r
202 aesenc %xmm4, iv\r
203 aesenc %xmm5, iv\r
204 aesenc %xmm6, iv\r
205 aesenc %xmm7, iv\r
206#if defined __x86_64__\r
207 aesenc %xmm8, iv\r
208 aesenc %xmm9, iv\r
209 aesenc %xmm10, iv\r
210 aesenc %xmm11, iv\r
211 aesenclast %xmm12, iv\r
212#else\r
213 movups 96(ctx), %xmm1 // key6\r
214 aesenc %xmm1, iv\r
215 movups 112(ctx), %xmm1 // key7\r
216 aesenc %xmm1, iv\r
217 movups 128(ctx), %xmm1 // key8\r
218 aesenc %xmm1, iv\r
219 movups 144(ctx), %xmm1 // key9\r
220 aesenc %xmm1, iv\r
221 movups 160(ctx), %xmm1 // keyA\r
222 aesenclast %xmm1, iv\r
223#endif\r
224\r
225 movups iv, (obuf) // *obuf = *iv;\r
226 add $16, obuf // obuf++;\r
227 add $16, ibuf // ibuf++;\r
228 sub $1, num_blk // num_blk --\r
229 jg 0b // if num_blk > 0, repeat the loop\r
230\r
231 // the following will be branched to from all other cases (encrypt/decrypt 128/192/256)\r
232\r
233L_HW_cbc_done:\r
234\r
235 xor %eax, %eax // to return CRYPT_OK\r
236\r
237L_error:\r
238\r
239 // if kernel, restore xmm registers\r
240#ifdef KERNEL \r
241 movaps 0(sp), %xmm0\r
242 movaps 16(sp), %xmm1\r
243 movaps 32(sp), %xmm2\r
244 movaps 48(sp), %xmm3\r
245 movaps 64(sp), %xmm4\r
246 movaps 80(sp), %xmm5\r
247 movaps 96(sp), %xmm6\r
248 movaps 112(sp), %xmm7\r
249#if defined __x86_64__\r
250 movaps 16*8(sp), %xmm8\r
251 movaps 16*9(sp), %xmm9\r
252 movaps 16*10(sp), %xmm10\r
253 movaps 16*11(sp), %xmm11\r
254 movaps 16*12(sp), %xmm12\r
255 movaps 16*13(sp), %xmm13\r
256 movaps 16*14(sp), %xmm14\r
257 movaps 16*15(sp), %xmm15\r
258#endif // __x86_64__\r
259#endif // KERNEL\r
260\r
261 // release used stack memory, restore used callee-saved registers, and return \r
262#if defined __i386__\r
263#ifdef KERNEL\r
264 add $(8*16), %esp\r
265#endif\r
266 pop %edi\r
267 pop %ebx\r
268#else\r
269#ifdef KERNEL\r
270 add $(16*16), %rsp \r
271#endif\r
272 pop %r15\r
273 pop %r14\r
274 pop %r13\r
275 pop %rbx\r
276#endif\r
277 leave\r
278 ret\r
279\r
280 //\r
281 // aes-192 encrypt_cbc operation, after completion, branch to L_HW_cbc_done\r
282 //\r
283\r
284L_encrypt_192:\r
285\r
286 cmp $1, num_blk // check number of block\r
287 jl L_HW_cbc_done // should it be less than 1, nothing to do\r
288\r
289 movups (ctx), %xmm2 // key0\r
290 movups 16(ctx), %xmm3 // key1\r
291 movups 32(ctx), %xmm4 // key2\r
292 movups 48(ctx), %xmm5 // key3\r
293 movups 64(ctx), %xmm6 // key4\r
294 movups 80(ctx), %xmm7 // key5\r
295#if defined __x86_64__\r
296 movups 96(ctx), %xmm8 // key6\r
297 movups 112(ctx), %xmm9 // key7\r
298 movups 128(ctx), %xmm10 // key8\r
299 movups 144(ctx), %xmm11 // key9\r
300 movups 160(ctx), %xmm12 // keyA\r
301 movups 176(ctx), %xmm13 // keyB\r
302 movups 192(ctx), %xmm14 // keyC\r
303#endif\r
304 \r
305 // while (num_blk--) {\r
306 // *iv ^= *ibuf++;\r
307 // aes_encrypt(iv, iv, ctx);\r
308 // *obuf++ = *iv;\r
309 // }\r
3100:\r
311 movups (ibuf), %xmm1 // *ibuf\r
312 pxor %xmm1, iv // *iv ^= ibuf\r
313\r
314 // aes_encrypt(iv, iv, ctx);\r
315\r
316 pxor %xmm2, iv\r
317 aesenc %xmm3, iv\r
318 aesenc %xmm4, iv\r
319 aesenc %xmm5, iv\r
320 aesenc %xmm6, iv\r
321 aesenc %xmm7, iv\r
322#if defined __x86_64__\r
323 aesenc %xmm8, iv\r
324 aesenc %xmm9, iv\r
325 aesenc %xmm10, iv\r
326 aesenc %xmm11, iv\r
327 aesenc %xmm12, iv\r
328 aesenc %xmm13, iv\r
329 aesenclast %xmm14, iv\r
330#else\r
331 movups 96(ctx), %xmm1\r
332 aesenc %xmm1, iv\r
333 movups 112(ctx), %xmm1\r
334 aesenc %xmm1, iv\r
335 movups 128(ctx), %xmm1\r
336 aesenc %xmm1, iv\r
337 movups 144(ctx), %xmm1\r
338 aesenc %xmm1, iv\r
339 movups 160(ctx), %xmm1\r
340 aesenc %xmm1, iv\r
341 movups 176(ctx), %xmm1\r
342 aesenc %xmm1, iv\r
343 movups 192(ctx), %xmm1\r
344 aesenclast %xmm1, iv\r
345#endif\r
346\r
347 movups iv, (obuf) // *obuf = *iv;\r
348 add $16, ibuf // ibuf++\r
349 add $16, obuf // obuf++\r
350\r
351 sub $1, num_blk // num_blk --\r
352 jg 0b // if num_blk > 0, repeat the loop\r
353\r
354 jmp L_HW_cbc_done // share with the common exit code\r
355\r
356 //\r
357 // aes-256 encrypt_cbc operation, after completion, branch to L_HW_cbc_done\r
358 //\r
359\r
360L_encrypt_256:\r
361\r
362 cmp $1, num_blk // check number of block\r
363 jl L_HW_cbc_done // should it be less than 1, nothing to do\r
364\r
365 movups (ctx), %xmm2 // key0\r
366 movups 16(ctx), %xmm3 // key1\r
367 movups 32(ctx), %xmm4 // key2\r
368 movups 48(ctx), %xmm5 // key3\r
369 movups 64(ctx), %xmm6 // key4\r
370 movups 80(ctx), %xmm7 // key5\r
371#if defined __x86_64__\r
372 movups 96(ctx), %xmm8 // key6\r
373 movups 112(ctx), %xmm9 // key7\r
374 movups 128(ctx), %xmm10 // key8\r
375 movups 144(ctx), %xmm11 // key9\r
376 movups 160(ctx), %xmm12 // keyA\r
377 movups 176(ctx), %xmm13 // keyB\r
378 movups 192(ctx), %xmm14 // keyC\r
379 movups 208(ctx), %xmm15 // keyD\r
380 // movups 224(ctx), %xmm1 // keyE\r
381#endif\r
382\r
383 // while (num_blk--) {\r
384 // *iv ^= *ibuf++;\r
385 // aes_encrypt(iv, iv, ctx);\r
386 // *obuf++ = *iv;\r
387 // }\r
3880:\r
389 movups (ibuf), %xmm1 // *ibuf\r
390 pxor %xmm1, iv // *iv ^= ibuf\r
391 \r
392 // aes_encrypt(iv, iv, ctx);\r
393 pxor %xmm2, iv\r
394 aesenc %xmm3, iv\r
395 aesenc %xmm4, iv\r
396 aesenc %xmm5, iv\r
397 aesenc %xmm6, iv\r
398 aesenc %xmm7, iv\r
399#if defined __x86_64__\r
400 movups 224(ctx), %xmm1 // keyE\r
401 aesenc %xmm8, iv\r
402 aesenc %xmm9, iv\r
403 aesenc %xmm10, iv\r
404 aesenc %xmm11, iv\r
405 aesenc %xmm12, iv\r
406 aesenc %xmm13, iv\r
407 aesenc %xmm14, iv\r
408 aesenc %xmm15, iv\r
409 aesenclast %xmm1, iv\r
410#else\r
411 movups 96(ctx), %xmm1 // key6\r
412 aesenc %xmm1, iv\r
413 movups 112(ctx), %xmm1 // key7\r
414 aesenc %xmm1, iv\r
415 movups 128(ctx), %xmm1 // key8\r
416 aesenc %xmm1, iv\r
417 movups 144(ctx), %xmm1 // key9\r
418 aesenc %xmm1, iv\r
419 movups 160(ctx), %xmm1 // keyA\r
420 aesenc %xmm1, iv\r
421 movups 176(ctx), %xmm1 // keyB\r
422 aesenc %xmm1, iv\r
423 movups 192(ctx), %xmm1 // keyC\r
424 aesenc %xmm1, iv\r
425 movups 208(ctx), %xmm1 // keyD\r
426 aesenc %xmm1, iv\r
427 movups 224(ctx), %xmm1 // keyE\r
428 aesenclast %xmm1, iv\r
429#endif\r
430\r
431 movups iv, (obuf) // *obuf = *iv;\r
432 add $16, ibuf // ibuf++\r
433 add $16, obuf // obuf++\r
434\r
435 sub $1, num_blk // num_blk --\r
436 jg 0b // if num_blk > 0, repeat the loop\r
437\r
438 jmp L_HW_cbc_done // share with the common exit code\r
439\r
440\r
441\r
442 //\r
443 // --------- END of aes_encrypt_cbc_hw -------------------\r
444 //\r
445\r
446\r
447/* ---------------------------------------------------------------------------------------------------------------- \r
448\r
449 aes_decrypt_cbc function (see aes_modes.c or aes_modes_asm.s) :\r
450\r
451 For simplicity, I am assuming all variables are in 128-bit data type.\r
452\r
453 aes_rval aes_decrypt_cbc(const __m128 *ibuf, __m128 *iv, int num_blk, __m128 *obuf, const aes_decrypt_ctx *ctx)\r
454 {\r
455 while(num_blk--) {\r
456 aes_decrypt(ibuf, obuf, ctx);\r
457 *obuf++ ^= *iv;\r
458 *iv = *ibuf++;\r
459 }\r
460 return 0;\r
461 }\r
462\r
463 The following is an implementation of this function using Intel AESNI.\r
464 This function _aes_decrypt_cbc_hw SHOULD NOT be called directly. \r
465 Developer should still call _aes_decrypt_cbc (in aes_modes_asm.s) which will poll cpu_capabilities and branch\r
466 to this aesni-based function should it detecs that aesni is available.\r
467 Blindly call this function SURELY will cause a CRASH on systems with no aesni support. \r
468\r
469 Note that the decryption operation is not related over blocks.\r
470 This gives opportunity of arranging aes_decrypt operations in parallel to speed up code.\r
471 This is equivalent to what has been described in the Intel AES Instruction Set White Paper (Rev. 2.0 page 53-55)\r
472 The following assembly code exploits this idea to achieve ~ 1.4 speed up in aes_decrypt_cbc.\r
473\r
474 Example C code for packing 4 blocks in an iteration is shown as follows:\r
475\r
476 while ((num_blk-=4)>=0) {\r
477\r
478 // the following 4 functions can be interleaved to exploit parallelism\r
479 aes_decrypt(ibuf, obuf, ctx);\r
480 aes_decrypt(ibuf+1, obuf+1, ctx);\r
481 aes_decrypt(ibuf+2, obuf+2, ctx);\r
482 aes_decrypt(ibuf+3, obuf+3, ctx);\r
483\r
484 obuf[0] ^= *iv; obuf[1] ^= ibuf[1]; obuf[2] ^= ibuf[1]; obuf[3] ^= ibuf[2];\r
485 *iv = ibuf[3]; ibuf += 4; obuf += 4;\r
486 }\r
487 num_blk+=4;\r
488\r
489 ----------------------------------------------------------------------------------------------------------------*/\r
490\r
491 .text\r
492 .align 4,0x90\r
493 .globl _aes_decrypt_cbc_hw\r
494_aes_decrypt_cbc_hw:\r
495\r
496 // push/save registers for local use\r
497#if defined __i386__\r
498\r
499 push %ebp\r
500 movl %esp, %ebp\r
501 push %ebx // ibuf\r
502 push %edi // obuf\r
503\r
504 #define sp %esp\r
505\r
506#else // __x86_64__\r
507\r
508 push %rbp\r
509 mov %rsp, %rbp\r
510 push %rbx\r
511 push %r13\r
512 push %r14\r
513 push %r15\r
514\r
515 #define sp %rsp\r
516\r
517#endif\r
518\r
519\r
520 // if kernel, allocate stack space to save xmm registers\r
521#ifdef KERNEL\r
522#if defined __i386__\r
523 sub $(8*16), %esp\r
524#else\r
525 sub $(16*16), %rsp\r
526#endif\r
527 movaps %xmm0, (sp)\r
528 movaps %xmm1, 16(sp)\r
529 movaps %xmm2, 32(sp)\r
530 movaps %xmm3, 48(sp)\r
531 movaps %xmm4, 64(sp)\r
532 movaps %xmm5, 80(sp)\r
533 movaps %xmm6, 96(sp)\r
534 movaps %xmm7, 112(sp)\r
535#if defined __x86_64__\r
536 movaps %xmm8, 16*8(sp)\r
537 movaps %xmm9, 16*9(sp)\r
538 movaps %xmm10, 16*10(sp)\r
539 movaps %xmm11, 16*11(sp)\r
540 movaps %xmm12, 16*12(sp)\r
541 movaps %xmm13, 16*13(sp)\r
542 movaps %xmm14, 16*14(sp)\r
543 movaps %xmm15, 16*15(sp)\r
544#endif // __x86_64__\r
545#endif\r
546\r
547 #undef iv\r
548 #define iv %xmm0\r
549\r
550#if defined __i386__\r
551 mov 12(%ebp), %eax // in_iv\r
552 mov 24(%ebp), %edx // ctx\r
553 movups (%eax), iv // iv = in_iv \r
554 mov 8(%ebp), %ebx // ibuf\r
555 mov 16(%ebp), %ecx // num_blk\r
556 mov 20(%ebp), %edi // obuf\r
557\r
558 #define ibuf %ebx\r
559 #define obuf %edi\r
560 #define num_blk %ecx \r
561 #define ctx %edx\r
562\r
563#else // __x86_64__, rdi/rsi/rdx/rcx/r8\r
564\r
565 mov %rdi, %rbx // ibuf\r
566 movups (%rsi), iv // iv = in_iv\r
567 mov %rdx, %r13 // num_blk\r
568 mov %rcx, %r14 // obuf\r
569 mov %r8, %r15 // ctx \r
570\r
571 #define ibuf %rbx\r
572 #define num_blk %r13d\r
573 #define obuf %r14 \r
574 #define ctx %r15\r
575\r
576#endif\r
577\r
578 mov 240(ctx), %eax // aes length\r
579 cmp $160, %eax // aes-128 decrypt\r
580 je L_decrypt_128\r
581 cmp $192, %eax // aes-192 decrypt\r
582 je L_decrypt_192\r
583 cmp $224, %eax // aes-256 decrypt\r
584 je L_decrypt_256\r
585\r
586 mov $-1, %eax // wrong aes length, to return -1\r
587 jmp L_error // early exit due to wrong aes length\r
588\r
589\r
590 //\r
591 // aes-128 decrypt_cbc operation, after completion, branch to L_HW_cbc_done\r
592 //\r
593\r
594L_decrypt_128:\r
595\r
596 cmp $1, num_blk\r
597 jl L_HW_cbc_done // if num_blk < 1, early return\r
598\r
599 // aes-128 decrypt expanded keys\r
600 movups 160(ctx), %xmm3\r
601 movups 144(ctx), %xmm4\r
602 movups 128(ctx), %xmm5\r
603 movups 112(ctx), %xmm6\r
604 movups 96(ctx), %xmm7\r
605#if defined __x86_64__\r
606 movups 80(ctx), %xmm8\r
607 movups 64(ctx), %xmm9\r
608 movups 48(ctx), %xmm10\r
609 movups 32(ctx), %xmm11\r
610 movups 16(ctx), %xmm12\r
611 movups 0(ctx), %xmm13\r
612#endif\r
613\r
614 // performs 4 block decryption in an iteration to exploit decrypt in parallel\r
615\r
616 // while ((num_blk-=4)>=0) {\r
617 // aes_decrypt(ibuf, obuf, ctx);\r
618 // aes_decrypt(ibuf+1, obuf+1, ctx);\r
619 // aes_decrypt(ibuf+2, obuf+2, ctx);\r
620 // aes_decrypt(ibuf+3, obuf+3, ctx);\r
621 // obuf[0] ^= *iv; obuf[1] ^= ibuf[1]; obuf[2] ^= ibuf[1]; obuf[3] ^= ibuf[2];\r
622 // *iv = ibuf[3]; ibuf += 4; obuf += 4;\r
623 // }\r
624\r
625 sub $4, num_blk // pre decrement num_blk by 4\r
626 jl 9f // if num_blk < 4, skip the per-4-blocks processing code\r
627\r
6280:\r
629\r
630\r
631#if defined __x86_64__\r
632\r
633 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
634 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
635 movups 32(ibuf), %xmm14 // tmp = 3rd ibuf\r
636 movups 48(ibuf), %xmm15 // tmp = 4th ibuf\r
637\r
638 // for x86_64, the expanded keys are already stored in xmm3-xmm13\r
639\r
640 // aes-128 decrypt round 0 per 4 blocks\r
641 pxor %xmm3, %xmm1\r
642 pxor %xmm3, %xmm2\r
643 pxor %xmm3, %xmm14\r
644 pxor %xmm3, %xmm15\r
645\r
646 // aes-128 decrypt round 1 per 4 blocks\r
647 aesdec %xmm4, %xmm1\r
648 aesdec %xmm4, %xmm2\r
649 aesdec %xmm4, %xmm14\r
650 aesdec %xmm4, %xmm15\r
651\r
652 // aes-128 decrypt round 2 per 4 blocks\r
653 aesdec %xmm5, %xmm1\r
654 aesdec %xmm5, %xmm2\r
655 aesdec %xmm5, %xmm14\r
656 aesdec %xmm5, %xmm15\r
657\r
658 // aes-128 decrypt round 3 per 4 blocks\r
659 aesdec %xmm6, %xmm1\r
660 aesdec %xmm6, %xmm2\r
661 aesdec %xmm6, %xmm14\r
662 aesdec %xmm6, %xmm15\r
663\r
664 // aes-128 decrypt round 4 per 4 blocks\r
665 aesdec %xmm7, %xmm1\r
666 aesdec %xmm7, %xmm2\r
667 aesdec %xmm7, %xmm14\r
668 aesdec %xmm7, %xmm15\r
669\r
670 // aes-128 decrypt round 5 per 4 blocks\r
671 aesdec %xmm8, %xmm1\r
672 aesdec %xmm8, %xmm2\r
673 aesdec %xmm8, %xmm14\r
674 aesdec %xmm8, %xmm15\r
675\r
676 // aes-128 decrypt round 6 per 4 blocks\r
677 aesdec %xmm9, %xmm1\r
678 aesdec %xmm9, %xmm2\r
679 aesdec %xmm9, %xmm14\r
680 aesdec %xmm9, %xmm15\r
681\r
682 // aes-128 decrypt round 7 per 4 blocks\r
683 aesdec %xmm10, %xmm1\r
684 aesdec %xmm10, %xmm2\r
685 aesdec %xmm10, %xmm14\r
686 aesdec %xmm10, %xmm15\r
687\r
688 // aes-128 decrypt round 8 per 4 blocks\r
689 aesdec %xmm11, %xmm1\r
690 aesdec %xmm11, %xmm2\r
691 aesdec %xmm11, %xmm14\r
692 aesdec %xmm11, %xmm15\r
693\r
694 // aes-128 decrypt round 9 per 4 blocks\r
695 aesdec %xmm12, %xmm1\r
696 aesdec %xmm12, %xmm2\r
697 aesdec %xmm12, %xmm14\r
698 aesdec %xmm12, %xmm15\r
699\r
700 // aes-128 decrypt round 10 (last) per 4 blocks\r
701 aesdeclast %xmm13, %xmm1\r
702 aesdeclast %xmm13, %xmm2\r
703 aesdeclast %xmm13, %xmm14\r
704 aesdeclast %xmm13, %xmm15\r
705\r
706 pxor iv, %xmm1 // obuf[0] ^= *iv; \r
707 movups (ibuf), iv // ibuf[0]\r
708 pxor iv, %xmm2 // obuf[1] ^= ibuf[0]; \r
709 movups 16(ibuf), iv // ibuf[1]\r
710 pxor iv, %xmm14 // obuf[2] ^= ibuf[1]; \r
711 movups 32(ibuf), iv // ibuf[2] \r
712 pxor iv, %xmm15 // obuf[3] ^= obuf[2]; \r
713 movups 48(ibuf), iv // *iv = ibuf[3]\r
714\r
715 movups %xmm1, (obuf) // write 1st obuf\r
716 movups %xmm2, 16(obuf) // write 2nd obuf\r
717 movups %xmm14, 32(obuf) // write 3rd obuf\r
718 movups %xmm15, 48(obuf) // write 4th obuf\r
719\r
720\r
721#else\r
722\r
723 // aes_decrypt_cbc per 4 blocks using aes-128 for i386\r
724 // xmm1/xmm2/xmm4/xmm5 used for obuf per block\r
725 // xmm3 = key0\r
726 // xmm0 = iv\r
727 // xmm6/xmm7 dynamically load with other expanded keys\r
728\r
729 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
730 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
731 movups 32(ibuf), %xmm4 // tmp = 3rd ibuf\r
732 movups 48(ibuf), %xmm5 // tmp = 4th ibuf\r
733\r
734 // aes_decrypt\r
735 // for i386, sequentially load expanded keys into xmm6/xmm7\r
736\r
737 movups 144(ctx), %xmm6 // key1\r
738\r
739 // aes-128 decrypt round 0 per 4 blocks\r
740 pxor %xmm3, %xmm1\r
741 pxor %xmm3, %xmm2\r
742 pxor %xmm3, %xmm4\r
743 pxor %xmm3, %xmm5\r
744\r
745 movups 128(ctx), %xmm7 // key2\r
746\r
747 // aes-128 decrypt round 1 per 4 blocks\r
748 aesdec %xmm6, %xmm1\r
749 aesdec %xmm6, %xmm2\r
750 aesdec %xmm6, %xmm4\r
751 aesdec %xmm6, %xmm5\r
752\r
753 movups 112(ctx), %xmm6 // key3\r
754\r
755 // aes-128 decrypt round 2 per 4 blocks\r
756 aesdec %xmm7, %xmm1\r
757 aesdec %xmm7, %xmm2\r
758 aesdec %xmm7, %xmm4\r
759 aesdec %xmm7, %xmm5\r
760\r
761 movups 96(ctx), %xmm7 // key4\r
762\r
763 // aes-128 decrypt round 3 per 4 blocks\r
764 aesdec %xmm6, %xmm1\r
765 aesdec %xmm6, %xmm2\r
766 aesdec %xmm6, %xmm4\r
767 aesdec %xmm6, %xmm5\r
768\r
769 movups 80(ctx), %xmm6 // key5\r
770\r
771 // aes-128 decrypt round 4 per 4 blocks\r
772 aesdec %xmm7, %xmm1\r
773 aesdec %xmm7, %xmm2\r
774 aesdec %xmm7, %xmm4\r
775 aesdec %xmm7, %xmm5\r
776\r
777 movups 64(ctx), %xmm7 // key6\r
778\r
779 // aes-128 decrypt round 5 per 4 blocks\r
780 aesdec %xmm6, %xmm1\r
781 aesdec %xmm6, %xmm2\r
782 aesdec %xmm6, %xmm4\r
783 aesdec %xmm6, %xmm5\r
784\r
785 movups 48(ctx), %xmm6 // key7\r
786\r
787 // aes-128 decrypt round 6 per 4 blocks\r
788 aesdec %xmm7, %xmm1\r
789 aesdec %xmm7, %xmm2\r
790 aesdec %xmm7, %xmm4\r
791 aesdec %xmm7, %xmm5\r
792\r
793 movups 32(ctx), %xmm7 // key8\r
794\r
795 // aes-128 decrypt round 7 per 4 blocks\r
796 aesdec %xmm6, %xmm1\r
797 aesdec %xmm6, %xmm2\r
798 aesdec %xmm6, %xmm4\r
799 aesdec %xmm6, %xmm5\r
800\r
801 movups 16(ctx), %xmm6 // key9\r
802\r
803 // aes-128 decrypt round 8 per 4 blocks\r
804 aesdec %xmm7, %xmm1\r
805 aesdec %xmm7, %xmm2\r
806 aesdec %xmm7, %xmm4\r
807 aesdec %xmm7, %xmm5\r
808\r
809 movups 0(ctx), %xmm7 // keyA\r
810\r
811 // aes-128 decrypt round 9 per 4 blocks\r
812 aesdec %xmm6, %xmm1\r
813 aesdec %xmm6, %xmm2\r
814 aesdec %xmm6, %xmm4\r
815 aesdec %xmm6, %xmm5\r
816\r
817 // aes-128 decrypt round 10 (last) per 4 blocks\r
818 aesdeclast %xmm7, %xmm1\r
819 aesdeclast %xmm7, %xmm2\r
820 aesdeclast %xmm7, %xmm4\r
821 aesdeclast %xmm7, %xmm5\r
822\r
823 pxor iv, %xmm1 // 1st obuf ^= iv; \r
824 movups (ibuf), iv // 1st memcpy(iv, tmp, AES_BLOCK_SIZE);\r
825 pxor iv, %xmm2 // 2nd obuf ^= iv; \r
826 movups 16(ibuf), iv // 2nd memcpy(iv, tmp, AES_BLOCK_SIZE);\r
827 pxor iv, %xmm4 // 3rd obuf ^= iv; \r
828 movups 32(ibuf), iv // 3rd memcpy(iv, tmp, AES_BLOCK_SIZE);\r
829 pxor iv, %xmm5 // 4th obuf ^= iv; \r
830 movups 48(ibuf), iv // 4th memcpy(iv, tmp, AES_BLOCK_SIZE);\r
831\r
832 movups %xmm1, (obuf) // write 1st obuf\r
833 movups %xmm2, 16(obuf) // write 2nd obuf\r
834 movups %xmm4, 32(obuf) // write 3rd obuf\r
835 movups %xmm5, 48(obuf) // write 4th obuf\r
836#endif\r
837\r
838 add $64, ibuf // ibuf += 4; \r
839 add $64, obuf // obuf += 4; \r
840\r
841 sub $4, num_blk // num_blk -= 4\r
842 jge 0b // if num_blk > 0, repeat the loop\r
843\r
8449: add $4, num_blk // post incremtn num_blk by 4\r
845 je L_HW_cbc_done // if num_blk == 0, no need for forthur processing code\r
846\r
847#if defined __i386__\r
848 // updated as they might be needed as expanded keys in the remaining\r
849 movups 144(ctx), %xmm4\r
850 movups 128(ctx), %xmm5\r
851 movups 112(ctx), %xmm6\r
852 movups 96(ctx), %xmm7\r
853#endif\r
854\r
855 test $2, num_blk // check whether num_blk has 2 blocks\r
856 je 9f // if num_blk & 2 == 0, skip the per-pair processing code\r
857\r
858 // do the remaining 2 blocks together\r
859\r
860 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
861 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
862\r
863 // aes_decrypt\r
864 pxor %xmm3, %xmm1\r
865 pxor %xmm3, %xmm2\r
866 aesdec %xmm4, %xmm1\r
867 aesdec %xmm4, %xmm2\r
868 aesdec %xmm5, %xmm1\r
869 aesdec %xmm5, %xmm2\r
870 aesdec %xmm6, %xmm1\r
871 aesdec %xmm6, %xmm2\r
872#if defined __x86_64__\r
873 aesdec %xmm7, %xmm1\r
874 aesdec %xmm7, %xmm2\r
875 aesdec %xmm8, %xmm1\r
876 aesdec %xmm8, %xmm2\r
877 aesdec %xmm9, %xmm1\r
878 aesdec %xmm9, %xmm2\r
879 aesdec %xmm10, %xmm1\r
880 aesdec %xmm10, %xmm2\r
881 aesdec %xmm11, %xmm1\r
882 aesdec %xmm11, %xmm2\r
883 aesdec %xmm12, %xmm1\r
884 aesdec %xmm12, %xmm2\r
885 aesdeclast %xmm13, %xmm1\r
886 aesdeclast %xmm13, %xmm2\r
887#else\r
888 movups 80(ctx), %xmm6\r
889 aesdec %xmm7, %xmm1\r
890 aesdec %xmm7, %xmm2\r
891 movups 64(ctx), %xmm7\r
892 aesdec %xmm6, %xmm1\r
893 aesdec %xmm6, %xmm2\r
894 movups 48(ctx), %xmm6\r
895 aesdec %xmm7, %xmm1\r
896 aesdec %xmm7, %xmm2\r
897 movups 32(ctx), %xmm7\r
898 aesdec %xmm6, %xmm1\r
899 aesdec %xmm6, %xmm2\r
900 movups 16(ctx), %xmm6\r
901 aesdec %xmm7, %xmm1\r
902 aesdec %xmm7, %xmm2\r
903 movups 0(ctx), %xmm7\r
904 aesdec %xmm6, %xmm1\r
905 aesdec %xmm6, %xmm2\r
906 aesdeclast %xmm7, %xmm1\r
907 aesdeclast %xmm7, %xmm2\r
908 movups 112(ctx), %xmm6\r
909 movups 96(ctx), %xmm7\r
910#endif\r
911\r
912 pxor iv, %xmm1 // obuf[0] ^= *iv; \r
913 movups (ibuf), iv // ibuf[0]\r
914 pxor iv, %xmm2 // obuf[1] ^= ibuf[0]\r
915 movups 16(ibuf), iv // *iv = ibuf[1]\r
916\r
917 movups %xmm1, (obuf) // write obuf[0]\r
918 movups %xmm2, 16(obuf) // write obuf[1]\r
919\r
920 add $32, ibuf // ibuf += 2\r
921 add $32, obuf // obuf += 2\r
922\r
9239:\r
924 test $1, num_blk // check whether num_blk has residual 1 block\r
925 je L_HW_cbc_done // if num_blk == 0, no need for residual processing code\r
926 \r
927 movups (ibuf), %xmm2 // tmp = ibuf\r
928 // aes_decrypt\r
929 pxor %xmm3, %xmm2\r
930 aesdec %xmm4, %xmm2\r
931 aesdec %xmm5, %xmm2\r
932 aesdec %xmm6, %xmm2\r
933 aesdec %xmm7, %xmm2\r
934#if defined __x86_64__\r
935 aesdec %xmm8, %xmm2\r
936 aesdec %xmm9, %xmm2\r
937 aesdec %xmm10, %xmm2\r
938 aesdec %xmm11, %xmm2\r
939 aesdec %xmm12, %xmm2\r
940 aesdeclast %xmm13, %xmm2\r
941#else\r
942 movups 80(ctx), %xmm1\r
943 aesdec %xmm1, %xmm2\r
944 movups 64(ctx), %xmm1\r
945 aesdec %xmm1, %xmm2\r
946 movups 48(ctx), %xmm1\r
947 aesdec %xmm1, %xmm2\r
948 movups 32(ctx), %xmm1\r
949 aesdec %xmm1, %xmm2\r
950 movups 16(ctx), %xmm1\r
951 aesdec %xmm1, %xmm2\r
952 movups (ctx), %xmm1\r
953 aesdeclast %xmm1, %xmm2\r
954#endif\r
955\r
956 pxor iv, %xmm2 // *obuf ^= *iv; \r
957 movups (ibuf), iv // *iv = *ibuf;\r
958 movups %xmm2, (obuf) // write *obuf\r
959\r
960 jmp L_HW_cbc_done\r
961\r
962 //\r
963 // aes-192 decrypt_cbc operation, after completion, branch to L_HW_cbc_done\r
964 //\r
965\r
966L_decrypt_192:\r
967\r
968 cmp $1, num_blk\r
969 jl L_HW_cbc_done // if num_blk < 1, early return\r
970\r
971 // aes-192 decryp expanded keys\r
972 movups 192(ctx), %xmm3\r
973 movups 176(ctx), %xmm4\r
974 movups 160(ctx), %xmm5\r
975 movups 144(ctx), %xmm6\r
976 movups 128(ctx), %xmm7\r
977#if defined __x86_64__\r
978 movups 112(ctx), %xmm8\r
979 movups 96(ctx), %xmm9\r
980 movups 80(ctx), %xmm10\r
981 movups 64(ctx), %xmm11\r
982 movups 48(ctx), %xmm12\r
983 movups 32(ctx), %xmm13\r
984 movups 16(ctx), %xmm14\r
985 movups (ctx), %xmm15\r
986#endif\r
987\r
988 // performs 4 block decryption in an iteration to exploit decrypt in parallel\r
989\r
990 // while ((num_blk-=4)>=0) {\r
991 // aes_decrypt(ibuf, obuf, ctx);\r
992 // aes_decrypt(ibuf+1, obuf+1, ctx);\r
993 // aes_decrypt(ibuf+2, obuf+2, ctx);\r
994 // aes_decrypt(ibuf+3, obuf+3, ctx);\r
995 // obuf[0] ^= *iv; obuf[1] ^= ibuf[1]; obuf[2] ^= ibuf[1]; obuf[3] ^= ibuf[2];\r
996 // *iv = ibuf[3]; ibuf += 4; obuf += 4;\r
997 // }\r
998\r
999 sub $4, num_blk // pre decrement num_blk by 4\r
1000 jl 9f // if num_blk < 4, skip the per-4-blocks processing code\r
10010:\r
1002\r
1003#if defined __x86_64__\r
1004\r
1005 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
1006 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
1007 movups 32(ibuf), %xmm14 // tmp = 3rd ibuf\r
1008 movups 48(ibuf), %xmm15 // tmp = 4th ibuf\r
1009\r
1010 // aes_decrypt, for x86_64, the expanded keys are already stored in xmm3-xmm13\r
1011 // use %xmm12/%xmm13 ts dynamic keys in the middle, restored afterwards\r
1012\r
1013 // round 0 for 4 blocks\r
1014 pxor %xmm3, %xmm1\r
1015 pxor %xmm3, %xmm2\r
1016 pxor %xmm3, %xmm14\r
1017 pxor %xmm3, %xmm15\r
1018\r
1019 // round 1 for 4 blocks\r
1020 aesdec %xmm4, %xmm1\r
1021 aesdec %xmm4, %xmm2\r
1022 aesdec %xmm4, %xmm14\r
1023 aesdec %xmm4, %xmm15\r
1024\r
1025 // round 2 for 4 blocks\r
1026 aesdec %xmm5, %xmm1\r
1027 aesdec %xmm5, %xmm2\r
1028 aesdec %xmm5, %xmm14\r
1029 aesdec %xmm5, %xmm15\r
1030\r
1031 // round 3 for 4 blocks\r
1032 aesdec %xmm6, %xmm1\r
1033 aesdec %xmm6, %xmm2\r
1034 aesdec %xmm6, %xmm14\r
1035 aesdec %xmm6, %xmm15\r
1036\r
1037 // round 4 for 4 blocks\r
1038 aesdec %xmm7, %xmm1\r
1039 aesdec %xmm7, %xmm2\r
1040 aesdec %xmm7, %xmm14\r
1041 aesdec %xmm7, %xmm15\r
1042\r
1043 // round 5 for 4 blocks\r
1044 aesdec %xmm8, %xmm1\r
1045 aesdec %xmm8, %xmm2\r
1046 aesdec %xmm8, %xmm14\r
1047 aesdec %xmm8, %xmm15\r
1048\r
1049 // round 6 for 4 blocks\r
1050 aesdec %xmm9, %xmm1\r
1051 aesdec %xmm9, %xmm2\r
1052 aesdec %xmm9, %xmm14\r
1053 aesdec %xmm9, %xmm15\r
1054\r
1055 // round 7 for 4 blocks\r
1056 aesdec %xmm10, %xmm1\r
1057 aesdec %xmm10, %xmm2\r
1058 aesdec %xmm10, %xmm14\r
1059 aesdec %xmm10, %xmm15\r
1060\r
1061 // round 8 for 4 blocks\r
1062 aesdec %xmm11, %xmm1\r
1063 aesdec %xmm11, %xmm2\r
1064 aesdec %xmm11, %xmm14\r
1065 aesdec %xmm11, %xmm15\r
1066\r
1067 // round 9 for 4 blocks\r
1068 aesdec %xmm12, %xmm1\r
1069 aesdec %xmm12, %xmm2\r
1070 aesdec %xmm12, %xmm14\r
1071 aesdec %xmm12, %xmm15\r
1072\r
1073 movups 16(ctx), %xmm12\r
1074\r
1075 // round A for 4 blocks\r
1076 aesdec %xmm13, %xmm1\r
1077 aesdec %xmm13, %xmm2\r
1078 aesdec %xmm13, %xmm14\r
1079 aesdec %xmm13, %xmm15\r
1080\r
1081 movups (ctx), %xmm13\r
1082\r
1083 // round B for 4 blocks\r
1084 aesdec %xmm12, %xmm1\r
1085 aesdec %xmm12, %xmm2\r
1086 aesdec %xmm12, %xmm14\r
1087 aesdec %xmm12, %xmm15\r
1088\r
1089 movups 48(ctx), %xmm12 // restore %xmm12 to its original key\r
1090\r
1091 // round C (last) for 4 blocks\r
1092 aesdeclast %xmm13, %xmm1\r
1093 aesdeclast %xmm13, %xmm2\r
1094 aesdeclast %xmm13, %xmm14\r
1095 aesdeclast %xmm13, %xmm15\r
1096\r
1097 movups 32(ctx), %xmm13 // restore %xmm13 to its original key\r
1098\r
1099 pxor iv, %xmm1 // obuf[0] ^= *iv; \r
1100 movups (ibuf), iv // ibuf[0]\r
1101 pxor iv, %xmm2 // obuf[1] ^= ibuf[0] \r
1102 movups 16(ibuf), iv // ibuf[1]\r
1103 pxor iv, %xmm14 // obuf[2] ^= ibuf[1] \r
1104 movups 32(ibuf), iv // ibuf[2] \r
1105 pxor iv, %xmm15 // obuf[3] ^= ibuf[2] \r
1106 movups 48(ibuf), iv // *iv = ibuf[3] \r
1107\r
1108 movups %xmm1, (obuf) // write 1st obuf\r
1109 movups %xmm2, 16(obuf) // write 2nd obuf\r
1110 movups %xmm14, 32(obuf) // write 3rd obuf\r
1111 movups %xmm15, 48(obuf) // write 4th obuf\r
1112\r
1113 add $64, ibuf // ibuf += 4; \r
1114 add $64, obuf // obuf += 4; \r
1115\r
1116 sub $4, num_blk // num_blk -= 4\r
1117 jge 0b // if num_blk > 0, repeat the loop\r
1118\r
11199: add $4, num_blk // post incremtn num_blk by 4\r
1120 je L_HW_cbc_done // if num_blk == 0, prepare to return \r
1121\r
1122 movups 16(ctx), %xmm14 // restore %xmm14 to its key\r
1123 movups (ctx), %xmm15 // restore %xmm15 to its key\r
1124\r
1125#else\r
1126\r
1127 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
1128 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
1129 movups 32(ibuf), %xmm4 // tmp = 3rd ibuf\r
1130 movups 48(ibuf), %xmm5 // tmp = 4th ibuf\r
1131\r
1132 // aes_decrypt\r
1133 // for i386, sequentially load expanded keys into xmm6/xmm7\r
1134 movups 176(ctx), %xmm6\r
1135 pxor %xmm3, %xmm1\r
1136 pxor %xmm3, %xmm2\r
1137 pxor %xmm3, %xmm4\r
1138 pxor %xmm3, %xmm5\r
1139\r
1140 movups 160(ctx), %xmm7\r
1141 aesdec %xmm6, %xmm1\r
1142 aesdec %xmm6, %xmm2\r
1143 aesdec %xmm6, %xmm4\r
1144 aesdec %xmm6, %xmm5\r
1145\r
1146 movups 144(ctx), %xmm6\r
1147 aesdec %xmm7, %xmm1\r
1148 aesdec %xmm7, %xmm2\r
1149 aesdec %xmm7, %xmm4\r
1150 aesdec %xmm7, %xmm5\r
1151\r
1152 movups 128(ctx), %xmm7\r
1153 aesdec %xmm6, %xmm1\r
1154 aesdec %xmm6, %xmm2\r
1155 aesdec %xmm6, %xmm4\r
1156 aesdec %xmm6, %xmm5\r
1157\r
1158 movups 112(ctx), %xmm6\r
1159 aesdec %xmm7, %xmm1\r
1160 aesdec %xmm7, %xmm2\r
1161 aesdec %xmm7, %xmm4\r
1162 aesdec %xmm7, %xmm5\r
1163\r
1164 movups 96(ctx), %xmm7\r
1165 aesdec %xmm6, %xmm1\r
1166 aesdec %xmm6, %xmm2\r
1167 aesdec %xmm6, %xmm4\r
1168 aesdec %xmm6, %xmm5\r
1169\r
1170 movups 80(ctx), %xmm6\r
1171 aesdec %xmm7, %xmm1\r
1172 aesdec %xmm7, %xmm2\r
1173 aesdec %xmm7, %xmm4\r
1174 aesdec %xmm7, %xmm5\r
1175\r
1176 movups 64(ctx), %xmm7\r
1177 aesdec %xmm6, %xmm1\r
1178 aesdec %xmm6, %xmm2\r
1179 aesdec %xmm6, %xmm4\r
1180 aesdec %xmm6, %xmm5\r
1181\r
1182 movups 48(ctx), %xmm6\r
1183 aesdec %xmm7, %xmm1\r
1184 aesdec %xmm7, %xmm2\r
1185 aesdec %xmm7, %xmm4\r
1186 aesdec %xmm7, %xmm5\r
1187\r
1188 movups 32(ctx), %xmm7\r
1189 aesdec %xmm6, %xmm1\r
1190 aesdec %xmm6, %xmm2\r
1191 aesdec %xmm6, %xmm4\r
1192 aesdec %xmm6, %xmm5\r
1193\r
1194 movups 16(ctx), %xmm6\r
1195 aesdec %xmm7, %xmm1\r
1196 aesdec %xmm7, %xmm2\r
1197 aesdec %xmm7, %xmm4\r
1198 aesdec %xmm7, %xmm5\r
1199\r
1200 movups 0(ctx), %xmm7\r
1201 aesdec %xmm6, %xmm1\r
1202 aesdec %xmm6, %xmm2\r
1203 aesdec %xmm6, %xmm4\r
1204 aesdec %xmm6, %xmm5\r
1205\r
1206 aesdeclast %xmm7, %xmm1\r
1207 aesdeclast %xmm7, %xmm2\r
1208 aesdeclast %xmm7, %xmm4\r
1209 aesdeclast %xmm7, %xmm5\r
1210\r
1211 pxor iv, %xmm1 // 1st obuf ^= iv; \r
1212 movups (ibuf), iv // 1st memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1213 pxor iv, %xmm2 // 2nd obuf ^= iv; \r
1214 movups 16(ibuf), iv // 2nd memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1215 pxor iv, %xmm4 // 3rd obuf ^= iv; \r
1216 movups 32(ibuf), iv // 3rd memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1217 pxor iv, %xmm5 // 4th obuf ^= iv; \r
1218 movups 48(ibuf), iv // 4th memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1219 movups %xmm1, (obuf) // write 1st obuf\r
1220 movups %xmm2, 16(obuf) // write 2nd obuf\r
1221 movups %xmm4, 32(obuf) // write 3rd obuf\r
1222 movups %xmm5, 48(obuf) // write 4th obuf\r
1223\r
1224 add $64, ibuf // ibuf += AES_BLOCK_SIZE * 4; \r
1225 add $64, obuf // obuf += AES_BLOCK_SIZE * 4; \r
1226\r
1227 sub $4, num_blk // num_blk -= 4\r
1228 jge 0b // if num_blk > 0, repeat the loop\r
1229\r
1230\r
12319: add $4, num_blk // post incremtn num_blk by 4\r
1232 je L_HW_cbc_done // if num_blk == 0, no need for forthur processing code\r
1233\r
1234 movups 176(ctx), %xmm4\r
1235 movups 160(ctx), %xmm5\r
1236 movups 144(ctx), %xmm6\r
1237 movups 128(ctx), %xmm7\r
1238\r
1239#endif\r
1240\r
1241 // per-block aes_decrypt_cbc loop\r
1242\r
12430:\r
1244 movups (ibuf), %xmm2 // tmp = ibuf\r
1245\r
1246 // aes_decrypt\r
1247 pxor %xmm3, %xmm2\r
1248 aesdec %xmm4, %xmm2\r
1249 aesdec %xmm5, %xmm2\r
1250 aesdec %xmm6, %xmm2\r
1251 aesdec %xmm7, %xmm2\r
1252#if defined __x86_64__\r
1253 aesdec %xmm8, %xmm2\r
1254 aesdec %xmm9, %xmm2\r
1255 aesdec %xmm10, %xmm2\r
1256 aesdec %xmm11, %xmm2\r
1257 aesdec %xmm12, %xmm2\r
1258 aesdec %xmm13, %xmm2\r
1259 aesdec %xmm14, %xmm2\r
1260 aesdeclast %xmm15, %xmm2\r
1261#else\r
1262 movups 112(ctx), %xmm1\r
1263 aesdec %xmm1, %xmm2\r
1264 movups 96(ctx), %xmm1\r
1265 aesdec %xmm1, %xmm2\r
1266 movups 80(ctx), %xmm1\r
1267 aesdec %xmm1, %xmm2\r
1268 movups 64(ctx), %xmm1\r
1269 aesdec %xmm1, %xmm2\r
1270 movups 48(ctx), %xmm1\r
1271 aesdec %xmm1, %xmm2\r
1272 movups 32(ctx), %xmm1\r
1273 aesdec %xmm1, %xmm2\r
1274 movups 16(ctx), %xmm1\r
1275 aesdec %xmm1, %xmm2\r
1276 movups (ctx), %xmm1\r
1277 aesdeclast %xmm1, %xmm2\r
1278#endif\r
1279\r
1280 pxor iv, %xmm2 // obuf ^= iv; \r
1281 movups (ibuf), iv // memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1282\r
1283 movups %xmm2, (obuf) // write obuf\r
1284\r
1285 add $16, ibuf // ibuf += AES_BLOCK_SIZE; \r
1286 add $16, obuf // obuf += AES_BLOCK_SIZE; \r
1287 sub $1, num_blk // num_blk --\r
1288 jg 0b // if num_blk > 0, repeat the loop\r
1289\r
1290 jmp L_HW_cbc_done\r
1291\r
1292 //\r
1293 // aes-256 decrypt_cbc operation, after completion, branch to L_HW_cbc_done\r
1294 //\r
1295\r
1296L_decrypt_256:\r
1297\r
1298 cmp $1, num_blk\r
1299 jl L_HW_cbc_done \r
1300\r
1301 movups 224(ctx), %xmm3\r
1302 movups 208(ctx), %xmm4\r
1303 movups 192(ctx), %xmm5\r
1304 movups 176(ctx), %xmm6\r
1305 movups 160(ctx), %xmm7\r
1306#if defined __x86_64__\r
1307 movups 144(ctx), %xmm8\r
1308 movups 128(ctx), %xmm9\r
1309 movups 112(ctx), %xmm10\r
1310 movups 96(ctx), %xmm11\r
1311 movups 80(ctx), %xmm12\r
1312 movups 64(ctx), %xmm13\r
1313 movups 48(ctx), %xmm14\r
1314 movups 32(ctx), %xmm15\r
1315// movups 16(ctx), %xmm14\r
1316// movups (ctx), %xmm15\r
1317#endif\r
1318\r
1319#if defined __x86_64__\r
1320\r
1321 sub $4, num_blk // pre decrement num_blk by 4\r
1322 jl 9f // if num_blk < 4, skip the per-4-blocks processing code\r
13230:\r
1324 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
1325 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
1326 movups 32(ibuf), %xmm14 // tmp = 3rd ibuf\r
1327 movups 48(ibuf), %xmm15 // tmp = 4th ibuf\r
1328\r
1329 // aes_decrypt, for x86_64, the expanded keys are already stored in xmm3-xmm13\r
1330 pxor %xmm3, %xmm1\r
1331 pxor %xmm3, %xmm2\r
1332 pxor %xmm3, %xmm14\r
1333 pxor %xmm3, %xmm15\r
1334\r
1335 aesdec %xmm4, %xmm1\r
1336 aesdec %xmm4, %xmm2\r
1337 aesdec %xmm4, %xmm14\r
1338 aesdec %xmm4, %xmm15\r
1339\r
1340 aesdec %xmm5, %xmm1\r
1341 aesdec %xmm5, %xmm2\r
1342 aesdec %xmm5, %xmm14\r
1343 aesdec %xmm5, %xmm15\r
1344\r
1345 aesdec %xmm6, %xmm1\r
1346 aesdec %xmm6, %xmm2\r
1347 aesdec %xmm6, %xmm14\r
1348 aesdec %xmm6, %xmm15\r
1349\r
1350 aesdec %xmm7, %xmm1\r
1351 aesdec %xmm7, %xmm2\r
1352 aesdec %xmm7, %xmm14\r
1353 aesdec %xmm7, %xmm15\r
1354\r
1355 aesdec %xmm8, %xmm1\r
1356 aesdec %xmm8, %xmm2\r
1357 aesdec %xmm8, %xmm14\r
1358 aesdec %xmm8, %xmm15\r
1359\r
1360 aesdec %xmm9, %xmm1\r
1361 aesdec %xmm9, %xmm2\r
1362 aesdec %xmm9, %xmm14\r
1363 aesdec %xmm9, %xmm15\r
1364\r
1365 aesdec %xmm10, %xmm1\r
1366 aesdec %xmm10, %xmm2\r
1367 aesdec %xmm10, %xmm14\r
1368 aesdec %xmm10, %xmm15\r
1369\r
1370 aesdec %xmm11, %xmm1\r
1371 aesdec %xmm11, %xmm2\r
1372 aesdec %xmm11, %xmm14\r
1373 aesdec %xmm11, %xmm15\r
1374\r
1375 aesdec %xmm12, %xmm1\r
1376 aesdec %xmm12, %xmm2\r
1377 aesdec %xmm12, %xmm14\r
1378 aesdec %xmm12, %xmm15\r
1379 movups 48(ctx), %xmm12\r
1380\r
1381 aesdec %xmm13, %xmm1\r
1382 aesdec %xmm13, %xmm2\r
1383 aesdec %xmm13, %xmm14\r
1384 aesdec %xmm13, %xmm15\r
1385 movups 32(ctx), %xmm13\r
1386\r
1387 aesdec %xmm12, %xmm1\r
1388 aesdec %xmm12, %xmm2\r
1389 aesdec %xmm12, %xmm14\r
1390 aesdec %xmm12, %xmm15\r
1391 movups 16(ctx), %xmm12\r
1392\r
1393 aesdec %xmm13, %xmm1\r
1394 aesdec %xmm13, %xmm2\r
1395 aesdec %xmm13, %xmm14\r
1396 aesdec %xmm13, %xmm15\r
1397 movups (ctx), %xmm13\r
1398\r
1399 aesdec %xmm12, %xmm1\r
1400 aesdec %xmm12, %xmm2\r
1401 aesdec %xmm12, %xmm14\r
1402 aesdec %xmm12, %xmm15\r
1403 movups 80(ctx), %xmm12\r
1404\r
1405 aesdeclast %xmm13, %xmm1\r
1406 aesdeclast %xmm13, %xmm2\r
1407 aesdeclast %xmm13, %xmm14\r
1408 aesdeclast %xmm13, %xmm15\r
1409 movups 64(ctx), %xmm13\r
1410\r
1411 pxor iv, %xmm1 // obuf ^= iv; \r
1412 movups (ibuf), iv // memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1413 pxor iv, %xmm2 // obuf ^= iv; \r
1414 movups 16(ibuf), iv // memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1415 pxor iv, %xmm14 // obuf ^= iv; \r
1416 movups 32(ibuf), iv // memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1417 pxor iv, %xmm15 // obuf ^= iv; \r
1418 movups 48(ibuf), iv // memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1419\r
1420 movups %xmm1, (obuf) // write 1st obuf\r
1421 movups %xmm2, 16(obuf) // write 2nd obuf\r
1422 movups %xmm14, 32(obuf) // write 3rd obuf\r
1423 movups %xmm15, 48(obuf) // write 4th obuf\r
1424\r
1425 add $64, ibuf // ibuf += AES_BLOCK_SIZE*4; \r
1426 add $64, obuf // obuf += AES_BLOCK_SIZE*4; \r
1427\r
1428 sub $4, num_blk // num_blk -= 4\r
1429 jge 0b // if num_blk > 0, repeat the loop\r
1430\r
14319: add $4, num_blk // post incremtn num_blk by 4\r
1432 je L_HW_cbc_done // if num_blk == 0, no need for forthur processing code\r
1433\r
1434 movups 48(ctx), %xmm14\r
1435 movups 32(ctx), %xmm15\r
1436\r
1437#else\r
1438\r
1439 sub $4, num_blk // pre decrement num_blk by 4\r
1440 jl 9f // if num_blk < 4, skip the per-pair processing code\r
14410:\r
1442 movups (ibuf), %xmm1 // tmp = 1st ibuf\r
1443 movups 16(ibuf), %xmm2 // tmp = 2nd ibuf\r
1444 movups 32(ibuf), %xmm4 // tmp = 3rd ibuf\r
1445 movups 48(ibuf), %xmm5 // tmp = 4th ibuf\r
1446\r
1447 // aes_decrypt\r
1448 // for i386, sequentially load expanded keys into xmm6/xmm7\r
1449 movups 208(ctx), %xmm6\r
1450 pxor %xmm3, %xmm1\r
1451 pxor %xmm3, %xmm2\r
1452 pxor %xmm3, %xmm4\r
1453 pxor %xmm3, %xmm5\r
1454\r
1455 movups 192(ctx), %xmm7\r
1456 aesdec %xmm6, %xmm1\r
1457 aesdec %xmm6, %xmm2\r
1458 aesdec %xmm6, %xmm4\r
1459 aesdec %xmm6, %xmm5\r
1460\r
1461 movups 176(ctx), %xmm6\r
1462 aesdec %xmm7, %xmm1\r
1463 aesdec %xmm7, %xmm2\r
1464 aesdec %xmm7, %xmm4\r
1465 aesdec %xmm7, %xmm5\r
1466\r
1467 movups 160(ctx), %xmm7\r
1468 aesdec %xmm6, %xmm1\r
1469 aesdec %xmm6, %xmm2\r
1470 aesdec %xmm6, %xmm4\r
1471 aesdec %xmm6, %xmm5\r
1472\r
1473 movups 144(ctx), %xmm6\r
1474 aesdec %xmm7, %xmm1\r
1475 aesdec %xmm7, %xmm2\r
1476 aesdec %xmm7, %xmm4\r
1477 aesdec %xmm7, %xmm5\r
1478\r
1479 movups 128(ctx), %xmm7\r
1480 aesdec %xmm6, %xmm1\r
1481 aesdec %xmm6, %xmm2\r
1482 aesdec %xmm6, %xmm4\r
1483 aesdec %xmm6, %xmm5\r
1484\r
1485 movups 112(ctx), %xmm6\r
1486 aesdec %xmm7, %xmm1\r
1487 aesdec %xmm7, %xmm2\r
1488 aesdec %xmm7, %xmm4\r
1489 aesdec %xmm7, %xmm5\r
1490\r
1491 movups 96(ctx), %xmm7\r
1492 aesdec %xmm6, %xmm1\r
1493 aesdec %xmm6, %xmm2\r
1494 aesdec %xmm6, %xmm4\r
1495 aesdec %xmm6, %xmm5\r
1496\r
1497 movups 80(ctx), %xmm6\r
1498 aesdec %xmm7, %xmm1\r
1499 aesdec %xmm7, %xmm2\r
1500 aesdec %xmm7, %xmm4\r
1501 aesdec %xmm7, %xmm5\r
1502\r
1503 movups 64(ctx), %xmm7\r
1504 aesdec %xmm6, %xmm1\r
1505 aesdec %xmm6, %xmm2\r
1506 aesdec %xmm6, %xmm4\r
1507 aesdec %xmm6, %xmm5\r
1508\r
1509 movups 48(ctx), %xmm6\r
1510 aesdec %xmm7, %xmm1\r
1511 aesdec %xmm7, %xmm2\r
1512 aesdec %xmm7, %xmm4\r
1513 aesdec %xmm7, %xmm5\r
1514\r
1515 movups 32(ctx), %xmm7\r
1516 aesdec %xmm6, %xmm1\r
1517 aesdec %xmm6, %xmm2\r
1518 aesdec %xmm6, %xmm4\r
1519 aesdec %xmm6, %xmm5\r
1520\r
1521 movups 16(ctx), %xmm6\r
1522 aesdec %xmm7, %xmm1\r
1523 aesdec %xmm7, %xmm2\r
1524 aesdec %xmm7, %xmm4\r
1525 aesdec %xmm7, %xmm5\r
1526\r
1527 movups 0(ctx), %xmm7\r
1528 aesdec %xmm6, %xmm1\r
1529 aesdec %xmm6, %xmm2\r
1530 aesdec %xmm6, %xmm4\r
1531 aesdec %xmm6, %xmm5\r
1532\r
1533 aesdeclast %xmm7, %xmm1\r
1534 aesdeclast %xmm7, %xmm2\r
1535 aesdeclast %xmm7, %xmm4\r
1536 aesdeclast %xmm7, %xmm5\r
1537\r
1538 pxor iv, %xmm1 // 1st obuf ^= iv; \r
1539 movups (ibuf), iv // 1st memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1540 pxor iv, %xmm2 // 2nd obuf ^= iv; \r
1541 movups 16(ibuf), iv // 2nd memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1542 pxor iv, %xmm4 // 3rd obuf ^= iv; \r
1543 movups 32(ibuf), iv // 3rd memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1544 pxor iv, %xmm5 // 4th obuf ^= iv; \r
1545 movups 48(ibuf), iv // 4th memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1546 movups %xmm1, (obuf) // write 1st obuf\r
1547 movups %xmm2, 16(obuf) // write 2nd obuf\r
1548 movups %xmm4, 32(obuf) // write 3rd obuf\r
1549 movups %xmm5, 48(obuf) // write 4th obuf\r
1550\r
1551 add $64, ibuf // ibuf += AES_BLOCK_SIZE * 4; \r
1552 add $64, obuf // obuf += AES_BLOCK_SIZE * 4; \r
1553\r
1554 sub $4, num_blk // num_blk -= 4\r
1555 jge 0b // if num_blk > 0, repeat the loop\r
1556\r
1557\r
15589: add $4, num_blk // post incremtn num_blk by 4\r
1559 je L_HW_cbc_done // if num_blk == 0, no need for forthur processing code\r
1560\r
1561 movups 208(ctx), %xmm4\r
1562 movups 192(ctx), %xmm5\r
1563 movups 176(ctx), %xmm6\r
1564 movups 160(ctx), %xmm7\r
1565\r
1566#endif\r
1567\r
15680:\r
1569 movups (ibuf), %xmm2 // tmp = ibuf\r
1570\r
1571 // aes_decrypt\r
1572 pxor %xmm3, %xmm2\r
1573 aesdec %xmm4, %xmm2\r
1574 aesdec %xmm5, %xmm2\r
1575 aesdec %xmm6, %xmm2\r
1576 aesdec %xmm7, %xmm2\r
1577#if defined __x86_64__\r
1578 aesdec %xmm8, %xmm2\r
1579 aesdec %xmm9, %xmm2\r
1580 aesdec %xmm10, %xmm2\r
1581 aesdec %xmm11, %xmm2\r
1582 aesdec %xmm12, %xmm2\r
1583 aesdec %xmm13, %xmm2\r
1584 aesdec %xmm14, %xmm2\r
1585 aesdec %xmm15, %xmm2\r
1586#else\r
1587 movups 144(ctx), %xmm1\r
1588 aesdec %xmm1, %xmm2\r
1589 movups 128(ctx), %xmm1\r
1590 aesdec %xmm1, %xmm2\r
1591 movups 112(ctx), %xmm1\r
1592 aesdec %xmm1, %xmm2\r
1593 movups 96(ctx), %xmm1\r
1594 aesdec %xmm1, %xmm2\r
1595 movups 80(ctx), %xmm1\r
1596 aesdec %xmm1, %xmm2\r
1597 movups 64(ctx), %xmm1\r
1598 aesdec %xmm1, %xmm2\r
1599 movups 48(ctx), %xmm1\r
1600 aesdec %xmm1, %xmm2\r
1601 movups 32(ctx), %xmm1\r
1602 aesdec %xmm1, %xmm2\r
1603#endif\r
1604 movups 16(ctx), %xmm1\r
1605 aesdec %xmm1, %xmm2\r
1606 movups (ctx), %xmm1\r
1607 aesdeclast %xmm1, %xmm2\r
1608\r
1609 pxor iv, %xmm2 // obuf ^= iv; \r
1610 movups (ibuf), iv // memcpy(iv, tmp, AES_BLOCK_SIZE);\r
1611\r
1612 movups %xmm2, (obuf) // write obuf\r
1613\r
1614 add $16, ibuf // ibuf += AES_BLOCK_SIZE; \r
1615 add $16, obuf // obuf += AES_BLOCK_SIZE; \r
1616 sub $1, num_blk // num_blk --\r
1617 jg 0b // if num_blk > 0, repeat the loop\r
1618\r
1619 jmp L_HW_cbc_done\r
1620\r
1621 //\r
1622 // --------- END of aes_decrypt_cbc_hw -------------------\r
1623 //\r