• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 *     http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16#include "hitls_build.h"
17#if defined(HITLS_CRYPTO_AES) && defined(HITLS_CRYPTO_GCM)
18
19.text
20
21/*
22 * MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, void *key
23 * ctx  %rdi
24 * in   %rsi
25 * out  %rdx
26 * len  %rcx
27 * key  %r8
28 * The %r12 register is shared with AES_GCM_EncryptBlockAsm. Pay attention to its use.
29 */
30.type   AES_GCM_Encrypt96BlockAsm, @function
31.balign 16
32AES_GCM_Encrypt96BlockAsm:
33.cfi_startproc
34    push %rbp
35    mov %rsp, %rbp
36    vmovdqu (%rdi), %xmm0                       // iv
37    lea -2(%r9d), %r13d
38    addl $0x6000000, %r12d                      // ctr inc
39    vmovdqu -0x80(%r8), %xmm6                   // key0
40    leaq -0x70(%r8), %r10
41    jc .Lm96_enc_ctr_carry
42    vmovdqa 0x20(%r11), %xmm7
43    movl %r12d, 12(%rdi)                        // out iv
44    vpaddb %xmm7, %xmm0, %xmm1                  // g_oneLow
45    vpxor %xmm6, %xmm0, %xmm0
46    vpaddb %xmm7, %xmm1, %xmm2
47    vpxor %xmm6, %xmm1, %xmm1
48    vpaddb %xmm7, %xmm2, %xmm3
49    vpxor %xmm6, %xmm2, %xmm2
50    vpaddb %xmm7, %xmm3, %xmm4
51    vpxor %xmm6, %xmm3, %xmm3
52    vpaddb %xmm7, %xmm4, %xmm5
53    vpxor %xmm6, %xmm4, %xmm4
54    vpxor %xmm6, %xmm5, %xmm5
55    vmovdqu (%r10), %xmm6                       // key1
56.balign 16
57.Lm96_enc_aes:
58    vaesenc %xmm6, %xmm0, %xmm0
59    vaesenc %xmm6, %xmm1, %xmm1
60    vaesenc %xmm6, %xmm2, %xmm2
61    vaesenc %xmm6, %xmm3, %xmm3
62    vaesenc %xmm6, %xmm4, %xmm4
63    leaq 0x10(%r10), %r10
64    vaesenc %xmm6, %xmm5, %xmm5
65    vmovdqu (%r10), %xmm6                       // key2-9/11/13
66    decl %r13d
67    jnz .Lm96_enc_aes
68    vaesenc %xmm6, %xmm0, %xmm0
69    vmovdqu 0x10(%r10), %xmm10                   // key10/12/14
70    sub $112, %rsp
71    vaesenc %xmm6, %xmm1, %xmm1
72    vpxor (%rsi), %xmm10, %xmm8                  // last key xor plaintext
73    and $-16, %rsp
74    vaesenc %xmm6, %xmm2, %xmm2
75    vpxor 0x10(%rsi), %xmm10, %xmm7
76    vaesenc %xmm6, %xmm3, %xmm3
77    vpxor 0x20(%rsi), %xmm10, %xmm9
78    vaesenc %xmm6, %xmm4, %xmm4
79    vpxor 0x30(%rsi), %xmm10, %xmm11
80    vaesenc %xmm6, %xmm5, %xmm5
81    vpxor 0x40(%rsi), %xmm10, %xmm12
82    vaesenclast %xmm8, %xmm0, %xmm0
83    vpxor 0x50(%rsi), %xmm10, %xmm13
84    vmovdqa (%r11), %xmm15                      // g_byteSwapMask
85    vaesenclast %xmm7, %xmm1, %xmm1
86    vmovdqu %xmm0, (%rdx)                       // out ciphertext
87    vpxor 16(%rdi), %xmm0, %xmm0               // Do it in advance. input for ghash operation
88    vmovdqa 0x20(%r11), %xmm6
89    vpshufb %xmm15, %xmm0, %xmm8
90    vmovdqu (%rdi), %xmm0                       // iv
91    vaesenclast %xmm9, %xmm2, %xmm2
92    vmovdqa %xmm8, (%rsp)
93    vmovdqu -0x80(%r8), %xmm7
94    vmovdqu %xmm1, 0x10(%rdx)
95    vpshufb %xmm15, %xmm1, %xmm9
96    vpaddb %xmm6, %xmm0, %xmm1                  // g_oneLow
97    vpxor %xmm7, %xmm0, %xmm0                   // key 0
98    vaesenclast %xmm11, %xmm3, %xmm3
99    vmovdqa %xmm9, 0x10(%rsp)
100    vmovdqu %xmm2, 0x20(%rdx)
101    vpshufb %xmm15, %xmm2, %xmm11
102    vpaddb %xmm6, %xmm1, %xmm2
103    vpxor %xmm7, %xmm1, %xmm1
104    vaesenclast %xmm12, %xmm4, %xmm4
105    vmovdqa %xmm11, 0x20(%rsp)
106    vmovdqu %xmm3, 0x30(%rdx)
107    vpshufb %xmm15, %xmm3, %xmm12
108    vpaddb %xmm6, %xmm2, %xmm3
109    vpxor %xmm7, %xmm2, %xmm2
110    vaesenclast %xmm13, %xmm5, %xmm5
111    vmovdqa %xmm12, 0x30(%rsp)
112    vmovdqu %xmm4, 0x40(%rdx)
113    vpshufb %xmm15, %xmm4, %xmm13
114    vpaddb %xmm6, %xmm3, %xmm4
115    vpxor %xmm7, %xmm3, %xmm3
116    leaq 0x60(%rsi), %rsi
117    vmovdqu %xmm5, 0x50(%rdx)
118    vpshufb %xmm15, %xmm5, %xmm14
119    vpaddb %xmm6, %xmm4, %xmm5
120    vmovdqa %xmm13, 0x40(%rsp)
121    vmovdqa %xmm14, 0x50(%rsp)
122    cmpl $12, %ecx                              // If the remaining length is less than 12,
123                                                // the loop is not performed.
124
125    jb .Lm96_inner_out
126    addl $0x6000000, %r12d
127    jc .Lm96_inner_ctr_carry
128.balign 16
129.Lm96_inner_loop:
130    vmovdqu -0x70(%r8), %xmm6                   // rk0
131    // function stitch second 6x-blocks encryption and ghash of first 6x-blocks.
132    vaesenc %xmm6, %xmm0, %xmm0                 // encryption of the 'inout0' of second 6x-blocks.
133    vmovdqu 0x20+0x70(%rdi), %xmm11             // H^6
134    vmovdqa (%rsp), %xmm10                      // xmm10 = inout0, the first encrypted 6x-blocks
135    vaesenc %xmm6, %xmm1, %xmm1
136    movl %r12d, 12(%rdi)                        // out iv
137    vmovdqu 0x20+0x80(%rdi), %xmm12             // xmm12 = (H^5.h + H^5.l, H^6.h + H^6.l)
138    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm15    // Karatsuba Multiply. xmm15 = H^6.h·inout0.h,  where '·' represent multiply in GF(2^128) of GHASH.
139    vaesenc %xmm6, %xmm2, %xmm2
140    vpxor %xmm7, %xmm4, %xmm4
141    vpxor %xmm7, %xmm5, %xmm5
142    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm14    // xmm14 = H^6.l·inout0.l
143    vaesenc %xmm6, %xmm3, %xmm3
144    vpunpckhqdq %xmm10, %xmm10, %xmm13          // xmm13= (inout0.h, inout0.h)
145    leaq 0x10(%r8), %r10
146    vpxor %xmm10, %xmm13, %xmm13                // xmm13 = (inout0.h + inout0.l, inout0.h + inout0.h)
147    vmovdqu 0x20+0x60(%rdi), %xmm11             // H^5
148    vpclmulqdq $0x10, %xmm12, %xmm13, %xmm13    // xmm13 = (H^6.h + H^6.l)·(inout0.h + inout0.l)
149    vaesenc %xmm6, %xmm4, %xmm4
150    vmovdqa 0x10(%rsp), %xmm10                  // xmm10 = inout1
151    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm8     // xmm8 = H^5.h·inout1.h
152    vaesenc %xmm6, %xmm5, %xmm5
153    vmovdqu -0x60(%r8), %xmm7                   // rk1
154    vpxor %xmm8, %xmm15, %xmm15                 // xmm15 += xmm8
155    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm11    // xmm11 = H^5.l·inout1.l
156    vaesenc %xmm7, %xmm0, %xmm0
157    vpunpckhqdq %xmm10, %xmm10, %xmm8           // xmm8 = (inout1.h, inout1.h)
158    vpxor %xmm11, %xmm14, %xmm14                // xmm14 += xmm11
159    vpxor %xmm10, %xmm8, %xmm8                  // xmm8 = (inout1.h + inout1.l, inout1.h + inout1.h)
160    vmovdqu 0x20+0x40(%rdi), %xmm11             // xmm11 = H^4
161    vpclmulqdq $0x00, %xmm12, %xmm8, %xmm9      // xmm9 = (H^5.h + H^5.l)·(inout1.h + inout1.l)
162    vaesenc %xmm7, %xmm1, %xmm1
163    vmovdqa 0x20(%rsp), %xmm10                  // xmm10 = inout2
164    vpxor %xmm9, %xmm13, %xmm13                 // xmm13 += xmm9
165
166    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm8     // xmm8 = H^4.h·inout2.h
167    vaesenc %xmm7, %xmm2, %xmm2
168    vmovdqu 0x20+0x50(%rdi), %xmm12             // xmm12 = (H^3.h + H^3.l, H^4.h + H^4.l)
169    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm9     // xmm9 = H^4.l·inout2.l
170    vaesenc %xmm7, %xmm3, %xmm3
171    vpxor %xmm8, %xmm15, %xmm15                 // xmm15 += xmm8
172    vpxor %xmm9, %xmm14, %xmm14                 // xmm14 += xmm9
173    vpunpckhqdq %xmm10, %xmm10, %xmm6           // xmm6 = (inout2.h, inout2.h)
174    vaesenc %xmm7, %xmm4, %xmm4
175    vpxor %xmm10, %xmm6, %xmm6                  // xmm6 = (inout2.h + inout2.l, inout2.h + inout2.h)
176    vmovdqu 0x20+0x30(%rdi), %xmm11             // xmm11 = H^3
177    vpclmulqdq $0x10, %xmm12, %xmm6, %xmm8      // xmm8 = (H^4.h + H^4.l)·(inout2.h + inout2.h)
178    vaesenc %xmm7, %xmm5, %xmm5
179    vmovdqa 0x30(%rsp), %xmm10                  // xmm10 = inout3
180    vmovdqu -0x50(%r8), %xmm6                   // rk2
181
182    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm9     // xmm9 = H^3.h·inout3.h
183    vaesenc %xmm6, %xmm0, %xmm0
184    vpxor %xmm8, %xmm13, %xmm13                 // xmm13 += xmm8
185    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm7     // xmm7 = H^3.l·inout3.l
186    vaesenc %xmm6, %xmm1, %xmm1
187    vpxor %xmm9, %xmm15, %xmm15                 // xmm15 += xmm9
188    vpunpckhqdq %xmm10, %xmm10, %xmm8           // xmm8 = (inout3.h, inout3,h)
189    vaesenc %xmm6, %xmm2, %xmm2
190    vpxor %xmm10, %xmm8, %xmm8                  // xmm8 = (inout3.h + inout3.l, inout3.h + inout3.h)
191    vpxor %xmm7, %xmm14, %xmm14                 // xmm14 += xmm7
192    vpclmulqdq $0x00, %xmm12, %xmm8, %xmm9      // xmm9 = (H^3.h + H^3.l)·(inout3.h + inout3.l)
193    vaesenc %xmm6, %xmm3, %xmm3
194    vmovdqa 0x40(%rsp), %xmm10                  // xmm10 = inout4
195    vmovdqu 0x20+0x10(%rdi), %xmm11             // xmm11 = H^2
196    vaesenc %xmm6, %xmm4, %xmm4
197    vpxor %xmm9, %xmm13, %xmm13                 // xmm13 += xmm9
198    vaesenc %xmm6, %xmm5, %xmm5
199    vmovdqu -0x40(%r8), %xmm7                   // rk3
200
201    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm8     // xmm8 = H^2.h·inout4.h
202    vaesenc %xmm7, %xmm0, %xmm0
203    vmovdqu 0x20+0x20(%rdi), %xmm12             // xmm12 = (H^1.h + H^1.l, H^2.h + H^2.l)
204    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm9     // xmm9 = H^2.h·inout4.h
205    vaesenc %xmm7, %xmm1, %xmm1
206    vpunpckhqdq %xmm10, %xmm10, %xmm6           // xmm6 = (inout4.h, inout4.h)
207    vpxor %xmm8, %xmm15, %xmm15                 // xmm15 += xmm8
208    vaesenc %xmm7, %xmm2, %xmm2
209    vpxor %xmm10, %xmm6, %xmm6                  // xmm6 = (inout4.h + inout4.l, inout4.h + inout4.h)
210    vpxor %xmm9, %xmm14, %xmm14                 // xmm14 += xmm9
211    vpclmulqdq $0x10, %xmm12, %xmm6, %xmm8      // xmm8 = (H^2.h + H^2.l)·(inout4.h + inout4.l)
212    vaesenc %xmm7, %xmm3, %xmm3
213    vmovdqa 0x50(%rsp), %xmm10                  // xmm10 = inout5
214    vmovdqu 0x20(%rdi), %xmm11                  // xmm11 = H^1
215    vaesenc %xmm7, %xmm4, %xmm4
216    vpxor %xmm8, %xmm13, %xmm13                 // xmm13 += xmm8
217    vmovdqu -0x30(%r8), %xmm6                   // rk4
218    vaesenc %xmm7, %xmm5, %xmm5
219
220    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm9     // xmm9 = H^1.h·inout5.h
221    vaesenc %xmm6, %xmm0, %xmm0
222    vpunpckhqdq %xmm10, %xmm10, %xmm7           // xmm7 = (inout5.h, inout5.h)
223    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm8     // xmm8 = H^1.l·inout5.l
224    vaesenc %xmm6, %xmm1, %xmm1
225    vpxor %xmm10, %xmm7, %xmm7                  // xmm7 = (inout5.h + inout5.l, inout5.h + inout5.h)
226    vpxor %xmm9, %xmm15, %xmm15                 // xmm15 += xmm9
227    vpclmulqdq $0x00, %xmm12, %xmm7, %xmm12     // xmm12 = (H^1.h + H^1.l)·(inout5.h + inout5.l), that's all the (l+h)·(l+h)
228    vaesenc %xmm6, %xmm2, %xmm2
229    vpxor %xmm12, %xmm13, %xmm13                // xmm13 += xmm12
230    vpxor %xmm8, %xmm14, %xmm14                 // xmm14 += xmm8
231    vaesenc %xmm6, %xmm3, %xmm3
232    vpxor %xmm15, %xmm13, %xmm13                // Karatsuba, middle coefficient + higher coefficient
233    vpxor %xmm14, %xmm13, %xmm13                // Karatsuba, middle coefficient + lower coefficient
234    vpslldq $8, %xmm13, %xmm9                   // xmm9 = (0, xmm13.l)
235    vaesenc %xmm6, %xmm4, %xmm4
236    vpxor %xmm9, %xmm14, %xmm14                 // xmm14 is the lower 128-bits of ghash of first 6x-blocks
237    vaesenc %xmm6, %xmm5, %xmm5
238
239    // montgomery reduction method from https://link.springer.com/chapter/10.1007/978-3-031-34671-2_30
240    // T = [D:C:B:A]. here, xmm14 = [B:A], xmm15 = [D:C]
241    // WA = W·A, U = C + A + WA.h, V = B + WA.l
242    vmovdqu -0x20(%r8), %xmm7                   // rk5
243    vpalignr $8, %xmm14, %xmm14, %xmm9          // xmm9 = [A:B]
244    vaesenc %xmm7, %xmm0, %xmm0
245    vmovdqu 0x30(%r11), %xmm12                  // poly
246    vaesenc %xmm7, %xmm1, %xmm1
247    vpsrldq $8, %xmm13, %xmm8                   // xmm8 = (xmm13.h, 0)
248    vpxor %xmm8, %xmm15, %xmm15                 // xmm15 is the higher 128-bits of ghash of first 6x-blocks
249    vaesenc %xmm7, %xmm2, %xmm2
250    vpclmulqdq $0x10, %xmm12, %xmm14, %xmm14    // xmm14 = W·A, where W = 0xC200000000000000.
251    vaesenc %xmm7, %xmm3, %xmm3
252    vmovdqu -0x10(%r8), %xmm6                   // rk6
253    vpxor %xmm9, %xmm14, %xmm14                 // xmm14 = W·A + [A:B] = [A+WA.h:B+WA.l] = [U':V], where U' = A + WA.h
254    vaesenc %xmm7, %xmm4, %xmm4
255    vpalignr $8, %xmm14, %xmm14, %xmm8          // xmm8 = [V:U']
256    vpclmulqdq $0x10, %xmm12, %xmm14, %xmm14    // xmm14 = W·V
257    vaesenc %xmm7, %xmm5, %xmm5
258    vpxor %xmm8, %xmm15, %xmm15                 // xmm15 = [D+V:C+U']
259    vpxor %xmm14, %xmm15, %xmm15                // xmm15 = [D+V:C+U'] +  W·V = [D+V+WV.h:C+U'+WV.l] = [D+V+WV.h:U+WV.l] = [D+V:U+WV]
260                                                // reduction finished.
261    vaesenc %xmm6, %xmm0, %xmm0
262    vaesenc %xmm6, %xmm1, %xmm1
263    vaesenc %xmm6, %xmm2, %xmm2
264    vaesenc %xmm6, %xmm3, %xmm3
265    vaesenc %xmm6, %xmm4, %xmm4
266    vaesenc %xmm6, %xmm5, %xmm5
267
268    vmovdqu 0x00(%r8), %xmm7                   // rk7
269    vaesenc %xmm7, %xmm0, %xmm0
270    vaesenc %xmm7, %xmm1, %xmm1
271    vmovdqa %xmm15, %xmm10
272    vaesenc %xmm7, %xmm2, %xmm2
273    vaesenc %xmm7, %xmm3, %xmm3
274    vaesenc %xmm7, %xmm4, %xmm4
275    cmpl $12, %r9d
276    vaesenc %xmm7, %xmm5, %xmm5
277
278    vmovdqu (%r10), %xmm6
279    vmovdqu 0x10(%r10), %xmm11
280    jb .Lm96_inner_ending
281
282    vaesenc %xmm6, %xmm0, %xmm0                 // key 10
283    vaesenc %xmm6, %xmm1, %xmm1
284    vaesenc %xmm6, %xmm2, %xmm2
285    vaesenc %xmm6, %xmm3, %xmm3
286    vaesenc %xmm6, %xmm4, %xmm4
287    vaesenc %xmm6, %xmm5, %xmm5
288
289    vaesenc %xmm11, %xmm0, %xmm0                 // key 11
290    vaesenc %xmm11, %xmm1, %xmm1
291    vaesenc %xmm11, %xmm2, %xmm2
292    vaesenc %xmm11, %xmm3, %xmm3
293    leaq 0x20(%r10), %r10
294    vaesenc %xmm11, %xmm4, %xmm4
295    vmovdqu (%r10), %xmm6
296    vaesenc %xmm11, %xmm5, %xmm5
297    vmovdqu 0x10(%r10), %xmm11
298
299    je .Lm96_inner_ending
300
301    vaesenc %xmm6, %xmm0, %xmm0                 // key 12
302    vaesenc %xmm6, %xmm1, %xmm1
303    vaesenc %xmm6, %xmm2, %xmm2
304    vaesenc %xmm6, %xmm3, %xmm3
305    vaesenc %xmm6, %xmm4, %xmm4
306    vaesenc %xmm6, %xmm5, %xmm5
307
308    vaesenc %xmm11, %xmm0, %xmm0                 // key 13
309    vaesenc %xmm11, %xmm1, %xmm1
310    vaesenc %xmm11, %xmm2, %xmm2
311    vaesenc %xmm11, %xmm3, %xmm3
312    leaq 0x20(%r10), %r10
313    vaesenc %xmm11, %xmm4, %xmm4
314    vmovdqu (%r10), %xmm6
315    vaesenc %xmm11, %xmm5, %xmm5
316    vmovdqu 0x10(%r10), %xmm11
317
318    jmp .Lm96_inner_ending
319.balign 16
320.Lm96_inner_ctr_carry:
321    vmovdqu (%rdi), %xmm0                       // iv
322    bswap %r12d
323    vmovdqa (%r11), %xmm15
324    addl $0x100, %r12d                          // add carry bit
325    vmovdqa 0x10(%r11), %xmm14                   // lone_high
326    vpshufb %xmm15, %xmm0, %xmm0
327    vmovdqu -0x80(%r8), %xmm7
328    vpaddd %xmm14, %xmm0, %xmm1
329    vpshufb %xmm15, %xmm0, %xmm0
330    vpaddd %xmm14, %xmm1, %xmm2
331    vpxor %xmm7, %xmm0, %xmm0                   // key 0
332    vpshufb %xmm15, %xmm1, %xmm1
333    vpaddd %xmm14, %xmm2, %xmm3
334    vpxor %xmm7, %xmm1, %xmm1
335    vpshufb %xmm15, %xmm2, %xmm2
336    vpaddd %xmm14, %xmm3, %xmm4
337    vpxor %xmm7, %xmm2, %xmm2
338    vpshufb %xmm15, %xmm3, %xmm3
339    vpaddd %xmm14, %xmm4, %xmm5
340    vpxor %xmm7, %xmm3, %xmm3
341    vpshufb %xmm15, %xmm4, %xmm4
342    bswap %r12d
343    vpshufb %xmm15, %xmm5, %xmm5
344    jmp .Lm96_inner_loop
345.balign 16
346.Lm96_inner_ending:
347    vaesenc %xmm6, %xmm0, %xmm0                 // key 9
348    vpxor (%rsi), %xmm11, %xmm13                  // last key xor plaintext
349    vpxor %xmm14, %xmm12, %xmm12
350    vaesenc %xmm6, %xmm1, %xmm1
351    vpxor 0x10(%rsi), %xmm11, %xmm8
352    vaesenclast %xmm13, %xmm0, %xmm0             // key 10/12/14
353    vmovdqa (%r11), %xmm15
354    leaq 0x60(%rdx), %rdx
355    vaesenc %xmm6, %xmm2, %xmm2
356    vpxor 0x20(%rsi), %xmm11, %xmm9
357    sub $6, %ecx
358    vaesenclast %xmm8, %xmm1, %xmm1
359    vmovdqu %xmm0, (%rdx)                       // out result text
360    vaesenc %xmm6, %xmm3, %xmm3
361    vpshufb %xmm15, %xmm0, %xmm0
362    vmovdqa 0x20(%r11), %xmm12
363    vpxor %xmm10, %xmm0, %xmm0                  // Do it in advance. input for ghash operation
364    vpxor 0x30(%rsi), %xmm11, %xmm8
365    vmovdqa %xmm0, (%rsp)
366    vaesenclast %xmm9, %xmm2, %xmm2
367    vmovdqu -0x80(%r8), %xmm7
368    vmovdqu %xmm1, 0x10(%rdx)
369    vmovdqu (%rdi), %xmm0                       // iv
370    vpshufb %xmm15, %xmm1, %xmm1
371    vaesenc %xmm6, %xmm4, %xmm4
372    vmovdqa %xmm1, 0x10(%rsp)
373    vpaddb %xmm12, %xmm0, %xmm1                  // g_oneLow
374    vaesenc %xmm6, %xmm5, %xmm5
375    vpxor %xmm7, %xmm0, %xmm0                   // key 0
376    vmovdqu %xmm2, 0x20(%rdx)
377    vpxor 0x40(%rsi), %xmm11, %xmm9
378    vpshufb %xmm15, %xmm2, %xmm2
379    vaesenclast %xmm8, %xmm3, %xmm3
380    vmovdqa %xmm2, 0x20(%rsp)
381    vpaddb %xmm12, %xmm1, %xmm2
382    vpxor %xmm7, %xmm1, %xmm1
383    vpxor 0x50(%rsi), %xmm11, %xmm8
384    vmovdqu %xmm3, 0x30(%rdx)
385    vpshufb %xmm15, %xmm3, %xmm3
386    vaesenclast %xmm9, %xmm4, %xmm4
387    vmovdqa %xmm3, 0x30(%rsp)
388    vpaddb %xmm12, %xmm2, %xmm3
389    vpxor %xmm7, %xmm2, %xmm2
390    leaq 0x60(%rsi), %rsi
391    vmovdqu %xmm4, 0x40(%rdx)
392    vpshufb %xmm15, %xmm4, %xmm4
393    vaesenclast %xmm8, %xmm5, %xmm5
394    vmovdqa %xmm4, 0x40(%rsp)
395    vpaddb %xmm12, %xmm3, %xmm4
396    vpxor %xmm7, %xmm3, %xmm3
397    vmovdqu %xmm5, 0x50(%rdx)
398    vpshufb %xmm15, %xmm5, %xmm5
399    cmpl $12, %ecx                              // If the remaining length is greater than or equal to 12,
400                                                // the loop continues.
401    vmovdqa %xmm5, 0x50(%rsp)
402    vpaddb %xmm12, %xmm4, %xmm5
403    jb .Lm96_inner_out
404    addl $0x6000000, %r12d
405    jc .Lm96_inner_ctr_carry
406    jmp .Lm96_inner_loop
407.balign 16
408.Lm96_enc_ctr_carry:
409    vmovdqa (%r11), %xmm15
410    bswap %r12d
411    vmovdqa 0x10(%r11), %xmm14
412    vpshufb %xmm15, %xmm0, %xmm0
413    addl $0x100, %r12d                          // add carry bit
414    vpaddd %xmm14, %xmm0, %xmm1                 // g_oneHigh
415    vpshufb %xmm15, %xmm0, %xmm0
416    vpaddd %xmm14, %xmm1, %xmm2
417    vpxor %xmm6, %xmm0, %xmm0
418    vpshufb %xmm15, %xmm1, %xmm1
419    vpaddd %xmm14, %xmm2, %xmm3
420    vpxor %xmm6, %xmm1, %xmm1
421    vpshufb %xmm15, %xmm2, %xmm2
422    vpaddd %xmm14, %xmm3, %xmm4
423    vpxor %xmm6, %xmm2, %xmm2
424    vpshufb %xmm15, %xmm3, %xmm3
425    vpaddd %xmm14, %xmm4, %xmm5
426    vpxor %xmm6, %xmm3, %xmm3
427    vpshufb %xmm15, %xmm4, %xmm4
428    bswap %r12d
429    vpshufb %xmm15, %xmm5, %xmm5
430    vpxor %xmm6, %xmm4, %xmm4
431    movl %r12d, 12(%rdi)                        // out iv
432    vpxor %xmm6, %xmm5, %xmm5
433    vmovdqu (%r10), %xmm6                       // key1
434    jmp .Lm96_enc_aes
435.balign 16
436.Lm96_inner_out:
437// +++++++++++++++++ ghash process +++++++++++++++++++++++++++++++++
438    vmovdqu 0x20+0x70(%rdi), %xmm11            // hash key h^6
439    vmovdqa (%rsp), %xmm10
440    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm9    // Karatsuba Multiply
441    vmovdqu 0x20+0x80(%rdi), %xmm12            // hash key h^5_6
442    vpxor 0x08(%rsp), %xmm10, %xmm13
443    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm7
444    vmovdqu 0x20+0x60(%rdi), %xmm11            // hash key h^5
445    vmovdqa 0x10(%rsp), %xmm10
446    vpclmulqdq $0x10, %xmm12, %xmm13, %xmm8
447
448    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14   // Karatsuba Multiply
449    vmovdqu 0x20+0x50(%rdi), %xmm6             // hash key h^3_4
450    vpxor 0x18(%rsp), %xmm10, %xmm13
451    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
452    vmovdqu 0x20+0x40(%rdi), %xmm11             // hash key h^4
453    vpxor %xmm14, %xmm9, %xmm9
454    vpclmulqdq $0x00, %xmm12, %xmm13, %xmm13
455    vpxor %xmm10, %xmm7, %xmm7
456    vmovdqa 0x20(%rsp), %xmm10
457    vpxor %xmm13, %xmm8, %xmm8
458
459    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
460    vpxor 0x28(%rsp), %xmm10, %xmm13
461    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
462    vmovdqu 0x20+0x30(%rdi), %xmm11             // hash key h^3
463    vpxor %xmm14, %xmm9, %xmm9
464    vpclmulqdq $0x10, %xmm6, %xmm13, %xmm13
465    vpxor %xmm10, %xmm7, %xmm7
466    vmovdqa 0x30(%rsp), %xmm10
467    vpxor %xmm13, %xmm8, %xmm8
468
469    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
470    vmovdqu 0x20+0x20(%rdi), %xmm12             // hash key h^1_2
471    vpxor 0x38(%rsp), %xmm10, %xmm13
472    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
473    vmovdqu 0x20+0x10(%rdi), %xmm11             // hash key h^2
474    vpxor %xmm14, %xmm9, %xmm9
475    vpclmulqdq $0x00, %xmm6, %xmm13, %xmm13
476    vpxor %xmm10, %xmm7, %xmm7
477    vmovdqa 0x40(%rsp), %xmm10
478    vpxor %xmm13, %xmm8, %xmm8
479
480    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
481    vpxor 0x48(%rsp), %xmm10, %xmm13
482    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
483    vmovdqu 0x20(%rdi), %xmm11                  // hash key h^1
484    vpxor %xmm14, %xmm9, %xmm9
485    vpclmulqdq $0x10, %xmm12, %xmm13, %xmm13
486    vpxor %xmm10, %xmm7, %xmm7
487    vmovdqa 0x50(%rsp), %xmm10
488    vpxor %xmm13, %xmm8, %xmm8
489
490    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
491    vpxor 0x58(%rsp), %xmm10, %xmm13
492    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
493    vpxor %xmm14, %xmm9, %xmm14
494    vpclmulqdq $0x00, %xmm12, %xmm13, %xmm13
495    vpxor %xmm10, %xmm7, %xmm10
496    vpxor %xmm13, %xmm8, %xmm13
497
498    vpxor %xmm10, %xmm14, %xmm11
499    vpxor %xmm11, %xmm13, %xmm13
500
501    vpslldq $8, %xmm13, %xmm11
502    vmovdqa 0x30(%r11), %xmm15                  // g_poly
503    vpsrldq $8, %xmm13, %xmm13
504    vpxor %xmm11, %xmm10, %xmm10
505    vpxor %xmm13, %xmm14, %xmm14
506
507    vpalignr $8, %xmm10, %xmm10, %xmm12         // 1st phase of reduction
508    vpclmulqdq $0x10, %xmm15, %xmm10, %xmm10
509    sub $6, %ecx
510    vpxor %xmm12, %xmm10, %xmm10
511
512    vpalignr $8, %xmm10, %xmm10, %xmm12         // 2nd phase of reduction
513    vpclmulqdq $0x10, %xmm15, %xmm10, %xmm10
514    vpxor %xmm14, %xmm12, %xmm12
515    leaq 0x60(%rdx), %rdx
516    vpxor %xmm12, %xmm10, %xmm10
517
518    vpxor %xmm0, %xmm0, %xmm0
519    vpshufb (%r11), %xmm10, %xmm10
520// ------------------- ghash complete ---------------------------------
521    vmovdqa %xmm0, (%rsp)
522    vmovdqu %xmm10, 16(%rdi)                     // out ghash
523    vmovdqa %xmm0, 0x10(%rsp)
524    vmovdqa %xmm0, 0x20(%rsp)
525    vmovdqa %xmm0, 0x30(%rsp)
526    vmovdqa %xmm0, 0x40(%rsp)
527    vmovdqa %xmm0, 0x50(%rsp)
528    mov %rbp, %rsp
529    pop %rbp
530    ret
531.cfi_endproc
532.size   AES_GCM_Encrypt96BlockAsm, .-AES_GCM_Encrypt96BlockAsm
533
534/*
535 * MODES_GCM_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, void *key
536 * ctx  %rdi
537 * in   %rsi
538 * out  %rdx
539 * len  %rcx
540 * key  %r8
541 */
542.type   AES_GCM_Decrypt96BlockAsm, @function
543.balign  32
544AES_GCM_Decrypt96BlockAsm:
545.cfi_startproc
546    push %rbp
547    push %r12
548    push %r13
549    push %r14
550    mov %rsp, %rbp
551    sub $112, %rsp
552    vmovdqu (%rsi), %xmm0                       // in0
553    vmovdqa (%r11), %xmm6
554    and $-16, %rsp
555    vpshufb %xmm6, %xmm0, %xmm0
556    vmovdqu 0x10(%rsi), %xmm1                   // in1
557    vmovdqa %xmm0, (%rsp)
558    vpshufb %xmm6, %xmm1, %xmm1
559    vmovdqu 0x20(%rsi), %xmm2                   // in2
560    vmovdqa %xmm1, 0x10(%rsp)
561    vpshufb %xmm6, %xmm2, %xmm2
562    vmovdqu 0x30(%rsi), %xmm3                   // in3
563    vmovdqa %xmm2, 0x20(%rsp)
564    vpshufb %xmm6, %xmm3, %xmm3
565    vmovdqu 0x40(%rsi), %xmm4                   // in4
566    vmovdqa %xmm3, 0x30(%rsp)
567    vpshufb %xmm6, %xmm4, %xmm4
568    vmovdqu 0x50(%rsi), %xmm5                   // in5
569    vmovdqa %xmm4, 0x40(%rsp)
570    vpshufb %xmm6, %xmm5, %xmm5
571    vmovdqu 16(%rdi), %xmm10                    // ghash
572    vmovdqa %xmm5, 0x50(%rsp)
573    vpshufb %xmm6, %xmm10, %xmm10
574.balign 16
575.Lm96_dec_loop:
576    mov 12(%rdi), %r10d                         // counter  r10d(32bit)
577    vmovdqu (%rdi), %xmm0                       // iv
578    addl $0x6000000, %r10d                      // ctr inc
579    jc .Lm96_dec_ctr_carry
580    vmovdqa 0x20(%r11), %xmm6
581    vmovdqu (%r8), %xmm7
582    vpaddb %xmm6, %xmm0, %xmm1                  // g_oneLow
583    vpxor %xmm7, %xmm0, %xmm0                   // key 0
584    vpaddb %xmm6, %xmm1, %xmm2
585    vpxor %xmm7, %xmm1, %xmm1
586    vpaddb %xmm6, %xmm2, %xmm3
587    vpxor %xmm7, %xmm2, %xmm2
588    vpaddb %xmm6, %xmm3, %xmm4
589    vpxor %xmm7, %xmm3, %xmm3
590    vpaddb %xmm6, %xmm4, %xmm5
591    vmovdqu 0x10(%r8), %xmm6
592
593.Lm96_dec_aes_cipher:
594    vaesenc %xmm6, %xmm0, %xmm0                 // key 1
595    xor %r14, %r14
596    cmp $12, %ecx
597    mov %r10d, 12(%rdi)                         // out iv
598    setae %r14b
599    vaesenc %xmm6, %xmm1, %xmm1
600    vpxor %xmm7, %xmm4, %xmm4
601    neg %r14
602    lea 0x90(%r8), %r10
603// +++++++++++++++++ ghash process +++++++++++++++++++++++++++++++++
604    vmovdqu 0x20+0x70(%rdi), %xmm11             // hash key h^6
605    and $0x60, %r14
606    vpxor %xmm7, %xmm5, %xmm5
607    vmovdqu 0x20+0x80(%rdi), %xmm12             // hash key h^5_6
608    lea (%rsi, %r14), %r14
609    vaesenc %xmm6, %xmm2, %xmm2
610    vpxor (%rsp), %xmm10, %xmm10                // xor ghash
611
612    vaesenc %xmm6, %xmm3, %xmm3
613    vpalignr $8, %xmm10, %xmm10, %xmm13
614    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm15    // Karatsuba Multiply
615    vpxor %xmm10, %xmm13, %xmm13
616    vaesenc %xmm6, %xmm4, %xmm4
617    movbe (%r14), %r12
618    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm7
619    movbe 0x08(%r14), %r13
620    vaesenc %xmm6, %xmm5, %xmm5
621    vmovdqu 0x20(%r8), %xmm6
622    mov %r13, (%rsp)
623    vpclmulqdq $0x10, %xmm12, %xmm13, %xmm8
624    vmovdqu 0x20+0x60(%rdi), %xmm11             // hash key h^5
625    mov %r12, 0x08(%rsp)
626    vaesenc %xmm6, %xmm0, %xmm0                 // key 2
627    vmovdqa 0x10(%rsp), %xmm10
628    vaesenc %xmm6, %xmm1, %xmm1
629    vpxor 0x18(%rsp), %xmm10, %xmm13
630    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
631
632    movbe 0x10(%r14), %r12
633    vaesenc %xmm6, %xmm2, %xmm2
634    vpxor %xmm14, %xmm15, %xmm15
635    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
636    movbe 0x18(%r14), %r13
637    vaesenc %xmm6, %xmm3, %xmm3
638    mov %r13, 0x10(%rsp)
639    vmovdqu 0x20+0x40(%rdi), %xmm11             // hash key h^4
640    vpclmulqdq $0x00, %xmm12, %xmm13, %xmm13
641    mov %r12, 0x18(%rsp)
642    vpxor %xmm10, %xmm7, %xmm7
643    vaesenc %xmm6, %xmm4, %xmm4
644    vpxor %xmm13, %xmm8, %xmm8
645    vmovdqu 0x20+0x50(%rdi), %xmm12             // hash key h^3_4
646    vaesenc %xmm6, %xmm5, %xmm5
647    vmovdqu 0x30(%r8), %xmm6
648    vmovdqa 0x20(%rsp), %xmm10
649
650    vaesenc %xmm6, %xmm0, %xmm0                 // key 3
651    vpxor 0x28(%rsp), %xmm10, %xmm13
652    movbe 0x20(%r14), %r12
653    vaesenc %xmm6, %xmm1, %xmm1
654    movbe 0x28(%r14), %r13
655    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
656    mov %r13, 0x20(%rsp)
657    vaesenc %xmm6, %xmm2, %xmm2
658    vpxor %xmm14, %xmm15, %xmm15
659    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
660    mov %r12, 0x28(%rsp)
661    vmovdqu 0x20+0x30(%rdi), %xmm11             // hash key h^3
662    vaesenc %xmm6, %xmm3, %xmm3
663    vpxor %xmm10, %xmm7, %xmm7
664
665    vpclmulqdq $0x10, %xmm12, %xmm13, %xmm13
666    vmovdqa 0x30(%rsp), %xmm10
667    vaesenc %xmm6, %xmm4, %xmm4
668    vpxor %xmm13, %xmm8, %xmm8
669    vaesenc %xmm6, %xmm5, %xmm5
670    vmovdqu 0x40(%r8), %xmm6
671    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
672
673    vpxor 0x38(%rsp), %xmm10, %xmm13
674    vaesenc %xmm6, %xmm0, %xmm0                 // key 4
675    movbe 0x30(%r14), %r12
676    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
677    vpxor %xmm14, %xmm15, %xmm15
678    vaesenc %xmm6, %xmm1, %xmm1
679    movbe 0x38(%r14), %r13
680    vpxor %xmm10, %xmm7, %xmm7
681    vpclmulqdq $0x00, %xmm12, %xmm13, %xmm13
682    mov %r13, 0x30(%rsp)
683    vpxor %xmm13, %xmm8, %xmm8
684    vaesenc %xmm6, %xmm2, %xmm2
685    mov %r12, 0x38(%rsp)
686    vaesenc %xmm6, %xmm3, %xmm3
687    vmovdqu 0x20+0x10(%rdi), %xmm11             // hash key h^2
688    vaesenc %xmm6, %xmm4, %xmm4
689    vmovdqu 0x20+0x20(%rdi), %xmm12             // hash key h^1_2
690    vaesenc %xmm6, %xmm5, %xmm5
691    vmovdqu 0x50(%r8), %xmm6
692
693    vmovdqa 0x40(%rsp), %xmm10
694    vaesenc %xmm6, %xmm0, %xmm0                 // key 5
695    vpxor 0x48(%rsp), %xmm10, %xmm13
696    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
697    movbe 0x40(%r14), %r12
698    vaesenc %xmm6, %xmm1, %xmm1
699    movbe 0x48(%r14), %r13
700    vpxor %xmm14, %xmm15, %xmm15
701    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
702    mov %r13, 0x40(%rsp)
703    vaesenc %xmm6, %xmm2, %xmm2
704    vpxor %xmm10, %xmm7, %xmm7
705    vpclmulqdq $0x10, %xmm12, %xmm13, %xmm13
706    mov %r12, 0x48(%rsp)
707    vpxor %xmm13, %xmm8, %xmm8
708    vaesenc %xmm6, %xmm3, %xmm3
709    vmovdqu 0x20(%rdi), %xmm11                  // hash key h^1
710    vaesenc %xmm6, %xmm4, %xmm4
711    vmovdqa 0x50(%rsp), %xmm10
712    vaesenc %xmm6, %xmm5, %xmm5
713    vmovdqu 0x60(%r8), %xmm6
714
715    vaesenc %xmm6, %xmm0, %xmm0                 // key 6
716    vpxor 0x58(%rsp), %xmm10, %xmm13
717    vpclmulqdq $0x11, %xmm11, %xmm10, %xmm14    // Karatsuba Multiply
718    movbe 0x50(%r14), %r12
719    vaesenc %xmm6, %xmm1, %xmm1
720    vpxor %xmm14, %xmm15, %xmm14
721    vpclmulqdq $0x00, %xmm11, %xmm10, %xmm10
722    movbe 0x58(%r14), %r13
723    vaesenc %xmm6, %xmm2, %xmm2
724    mov %r13, 0x50(%rsp)
725    vpclmulqdq $0x00, %xmm12, %xmm13, %xmm13
726    mov %r12, 0x58(%rsp)
727    vpxor %xmm10, %xmm7, %xmm10
728    vaesenc %xmm6, %xmm3, %xmm3
729    vpxor %xmm13, %xmm8, %xmm13
730    vaesenc %xmm6, %xmm4, %xmm4
731    vpxor %xmm10, %xmm14, %xmm11
732    vaesenc %xmm6, %xmm5, %xmm5
733
734    vmovdqu 0x70(%r8), %xmm6
735    vpxor %xmm11, %xmm13, %xmm13
736    vaesenc %xmm6, %xmm0, %xmm0                 // key 7
737    vpslldq $8, %xmm13, %xmm11
738    vaesenc %xmm6, %xmm1, %xmm1
739    vpsrldq $8, %xmm13, %xmm13
740    vaesenc %xmm6, %xmm2, %xmm2
741    vpxor %xmm13, %xmm14, %xmm14
742    vaesenc %xmm6, %xmm3, %xmm3
743    vpxor %xmm11, %xmm10, %xmm10
744    vaesenc %xmm6, %xmm4, %xmm4
745    vmovdqa 0x30(%r11), %xmm13                  // g_poly
746    vaesenc %xmm6, %xmm5, %xmm5
747
748    vmovdqu 0x80(%r8), %xmm6
749    vpalignr $8, %xmm10, %xmm10, %xmm12         // 1st phase of reduction
750    vaesenc %xmm6, %xmm0, %xmm0                 // key 8
751    vpclmulqdq $0x10, %xmm13, %xmm10, %xmm10
752    vaesenc %xmm6, %xmm1, %xmm1
753    vpxor %xmm12, %xmm10, %xmm10
754    vaesenc %xmm6, %xmm2, %xmm2
755    vpalignr $8, %xmm10, %xmm10, %xmm12         // 2nd phase of reduction
756    vaesenc %xmm6, %xmm3, %xmm3
757    vpclmulqdq $0x10, %xmm13, %xmm10, %xmm10
758    vpxor %xmm14, %xmm12, %xmm12
759    vaesenc %xmm6, %xmm4, %xmm4
760    vpxor %xmm12, %xmm10, %xmm10
761    vmovdqu 0x10(%r10), %xmm7
762    vaesenc %xmm6, %xmm5, %xmm5
763    vmovdqu (%r10), %xmm6
764// ------------------- ghash complete ---------------------------------
765    cmp $12, %r9d
766
767    jb .Lm96_dec_ending
768
769    vaesenc %xmm6, %xmm0, %xmm0                 // key 9
770    vaesenc %xmm6, %xmm1, %xmm1
771    vaesenc %xmm6, %xmm2, %xmm2
772    vaesenc %xmm6, %xmm3, %xmm3
773    vaesenc %xmm6, %xmm4, %xmm4
774    vaesenc %xmm6, %xmm5, %xmm5
775
776    vaesenc %xmm7, %xmm0, %xmm0                 // key 10
777    vaesenc %xmm7, %xmm1, %xmm1
778    vaesenc %xmm7, %xmm2, %xmm2
779    vaesenc %xmm7, %xmm3, %xmm3
780    lea 0x20(%r10), %r10
781    vaesenc %xmm7, %xmm4, %xmm4
782    vmovdqu (%r10), %xmm6
783    vaesenc %xmm7, %xmm5, %xmm5
784    vmovdqu 0x10(%r10), %xmm7
785
786    je .Lm96_dec_ending
787
788    vaesenc %xmm6, %xmm0, %xmm0                 // key 11
789    vaesenc %xmm6, %xmm1, %xmm1
790    vaesenc %xmm6, %xmm2, %xmm2
791    vaesenc %xmm6, %xmm3, %xmm3
792    vaesenc %xmm6, %xmm4, %xmm4
793    vaesenc %xmm6, %xmm5, %xmm5
794
795    vaesenc %xmm7, %xmm0, %xmm0                 // key 12
796    vaesenc %xmm7, %xmm1, %xmm1
797    vaesenc %xmm7, %xmm2, %xmm2
798    vaesenc %xmm7, %xmm3, %xmm3
799    lea 0x20(%r10), %r10
800    vaesenc %xmm7, %xmm4, %xmm4
801    vmovdqu (%r10), %xmm6
802    vaesenc %xmm7, %xmm5, %xmm5
803    vmovdqu 0x10(%r10), %xmm7
804
805    jmp .Lm96_dec_ending
806.balign 16
807.Lm96_dec_ctr_carry:
808    vmovdqa (%r11), %xmm8
809    vmovdqu (%r8), %xmm7
810    bswap %r10d
811    vpshufb %xmm8, %xmm0, %xmm0
812    vmovdqa 0x10(%r11), %xmm6
813    addl $0x100, %r10d                          // add carry bit
814    vpaddd %xmm6, %xmm0, %xmm1
815    vpshufb %xmm8, %xmm0, %xmm0
816    vpaddd %xmm6, %xmm1, %xmm2
817    vpxor %xmm7, %xmm0, %xmm0                   // key 0
818    vpshufb %xmm8, %xmm1, %xmm1
819    vpaddd %xmm6, %xmm2, %xmm3
820    vpxor %xmm7, %xmm1, %xmm1
821    vpshufb %xmm8, %xmm2, %xmm2
822    vpaddd %xmm6, %xmm3, %xmm4
823    vpxor %xmm7, %xmm2, %xmm2
824    vpshufb %xmm8, %xmm3, %xmm3
825    vpaddd %xmm6, %xmm4, %xmm5
826    vpxor %xmm7, %xmm3, %xmm3
827    vpshufb %xmm8, %xmm4, %xmm4
828    bswap %r10d
829    vpshufb %xmm8, %xmm5, %xmm5
830    vmovdqu 0x10(%r8), %xmm6
831    jmp .Lm96_dec_aes_cipher
832.balign 16
833.Lm96_dec_ending:
834    vaesenc %xmm6, %xmm0, %xmm0
835    sub $6, %ecx
836    vpxor (%rsi), %xmm7, %xmm8                 // last key xor plaintext
837    vaesenc %xmm6, %xmm1, %xmm1
838    vpxor 0x10(%rsi), %xmm7, %xmm9                 // last key xor plaintext
839    vaesenc %xmm6, %xmm2, %xmm2
840    vpxor 0x20(%rsi), %xmm7, %xmm11                 // last key xor plaintext
841    vaesenc %xmm6, %xmm3, %xmm3
842    vpxor 0x30(%rsi), %xmm7, %xmm12                 // last key xor plaintext
843    vaesenc %xmm6, %xmm4, %xmm4
844    vpxor 0x40(%rsi), %xmm7, %xmm13                 // last key xor plaintext
845    vaesenc %xmm6, %xmm5, %xmm5
846    vpxor 0x50(%rsi), %xmm7, %xmm14                 // last key xor plaintext
847    vaesenclast %xmm8, %xmm0, %xmm0             // last key
848    lea 0x60(%rsi), %rsi
849    vaesenclast %xmm9, %xmm1, %xmm1
850    vmovdqu %xmm0, (%rdx)                       // out result text
851    vaesenclast %xmm11, %xmm2, %xmm2
852    vmovdqu %xmm1, 0x10(%rdx)
853    vaesenclast %xmm12, %xmm3, %xmm3
854    vmovdqu %xmm2, 0x20(%rdx)
855    vaesenclast %xmm13, %xmm4, %xmm4
856    vmovdqu %xmm3, 0x30(%rdx)
857    vaesenclast %xmm14, %xmm5, %xmm5
858    vmovdqu %xmm4, 0x40(%rdx)
859    cmp $6, %ecx
860    vmovdqu %xmm5, 0x50(%rdx)
861    lea 0x60(%rdx), %rdx
862    jae .Lm96_dec_loop
863
864    vpxor %xmm0, %xmm0, %xmm0
865    vpshufb (%r11), %xmm10, %xmm10
866    vmovdqa %xmm0, (%rsp)
867    vmovdqa %xmm0, 0x10(%rsp)
868    vmovdqa %xmm0, 0x20(%rsp)
869    vmovdqa %xmm0, 0x30(%rsp)
870    vmovdqa %xmm0, 0x40(%rsp)
871    vmovdqa %xmm0, 0x50(%rsp)
872    mov %rbp, %rsp
873    vmovdqu %xmm10, 16(%rdi)                    // out ghash
874    pop %r14
875    pop %r13
876    pop %r12
877    pop %rbp
878    ret
879.cfi_endproc
880.size   AES_GCM_Decrypt96BlockAsm, .-AES_GCM_Decrypt96BlockAsm
881#endif
882