1########################################################################
2# Copyright (c) 2013, Intel Corporation
3#
4# This software is available to you under a choice of one of two
5# licenses.  You may choose to be licensed under the terms of the GNU
6# General Public License (GPL) Version 2, available from the file
7# COPYING in the main directory of this source tree, or the
8# OpenIB.org BSD license below:
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are
12# met:
13#
14# * Redistributions of source code must retain the above copyright
15#   notice, this list of conditions and the following disclaimer.
16#
17# * Redistributions in binary form must reproduce the above copyright
18#   notice, this list of conditions and the following disclaimer in the
19#   documentation and/or other materials provided with the
20#   distribution.
21#
22# * Neither the name of the Intel Corporation nor the names of its
23#   contributors may be used to endorse or promote products derived from
24#   this software without specific prior written permission.
25#
26#
27# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
28# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
31# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES# LOSS OF USE, DATA, OR
34# PROFITS# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38########################################################################
39##
40## Authors:
41##	Erdinc Ozturk <erdinc.ozturk@intel.com>
42##	Vinodh Gopal <vinodh.gopal@intel.com>
43##	James Guilford <james.guilford@intel.com>
44##	Tim Chen <tim.c.chen@linux.intel.com>
45##
46## References:
47##       This code was derived and highly optimized from the code described in paper:
48##               Vinodh Gopal et. al. Optimized Galois-Counter-Mode Implementation
49##			on Intel Architecture Processors. August, 2010
50##       The details of the implementation is explained in:
51##               Erdinc Ozturk et. al. Enabling High-Performance Galois-Counter-Mode
52##			on Intel Architecture Processors. October, 2012.
53##
54## Assumptions:
55##
56##
57##
58## iv:
59##       0                   1                   2                   3
60##       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
61##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62##       |                             Salt  (From the SA)               |
63##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64##       |                     Initialization Vector                     |
65##       |         (This is the sequence number from IPSec header)       |
66##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67##       |                              0x1                              |
68##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69##
70##
71##
72## AAD:
73##       AAD padded to 128 bits with 0
74##       for example, assume AAD is a u32 vector
75##
76##       if AAD is 8 bytes:
77##       AAD[3] = {A0, A1}#
78##       padded AAD in xmm register = {A1 A0 0 0}
79##
80##       0                   1                   2                   3
81##       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
82##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83##       |                               SPI (A1)                        |
84##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85##       |                     32-bit Sequence Number (A0)               |
86##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87##       |                              0x0                              |
88##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89##
90##                                       AAD Format with 32-bit Sequence Number
91##
92##       if AAD is 12 bytes:
93##       AAD[3] = {A0, A1, A2}#
94##       padded AAD in xmm register = {A2 A1 A0 0}
95##
96##       0                   1                   2                   3
97##       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
98##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99##       |                               SPI (A2)                        |
100##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101##       |                 64-bit Extended Sequence Number {A1,A0}       |
102##       |                                                               |
103##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104##       |                              0x0                              |
105##       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106##
107##        AAD Format with 64-bit Extended Sequence Number
108##
109##
110## aadLen:
111##       from the definition of the spec, aadLen can only be 8 or 12 bytes.
112##	 The code additionally supports aadLen of length 16 bytes.
113##
114## TLen:
115##       from the definition of the spec, TLen can only be 8, 12 or 16 bytes.
116##
117## poly = x^128 + x^127 + x^126 + x^121 + 1
118## throughout the code, one tab and two tab indentations are used. one tab is
119## for GHASH part, two tabs is for AES part.
120##
121
122#include <linux/linkage.h>
123
124# constants in mergeable sections, linker can reorder and merge
125.section	.rodata.cst16.POLY, "aM", @progbits, 16
126.align 16
127POLY:            .octa     0xC2000000000000000000000000000001
128
129.section	.rodata.cst16.POLY2, "aM", @progbits, 16
130.align 16
131POLY2:           .octa     0xC20000000000000000000001C2000000
132
133.section	.rodata.cst16.TWOONE, "aM", @progbits, 16
134.align 16
135TWOONE:          .octa     0x00000001000000000000000000000001
136
137.section	.rodata.cst16.SHUF_MASK, "aM", @progbits, 16
138.align 16
139SHUF_MASK:       .octa     0x000102030405060708090A0B0C0D0E0F
140
141.section	.rodata.cst16.ONE, "aM", @progbits, 16
142.align 16
143ONE:             .octa     0x00000000000000000000000000000001
144
145.section	.rodata.cst16.ONEf, "aM", @progbits, 16
146.align 16
147ONEf:            .octa     0x01000000000000000000000000000000
148
149# order of these constants should not change.
150# more specifically, ALL_F should follow SHIFT_MASK, and zero should follow ALL_F
151.section	.rodata, "a", @progbits
152.align 16
153SHIFT_MASK:      .octa     0x0f0e0d0c0b0a09080706050403020100
154ALL_F:           .octa     0xffffffffffffffffffffffffffffffff
155                 .octa     0x00000000000000000000000000000000
156
157.text
158
159
160#define AadHash 16*0
161#define AadLen 16*1
162#define InLen (16*1)+8
163#define PBlockEncKey 16*2
164#define OrigIV 16*3
165#define CurCount 16*4
166#define PBlockLen 16*5
167
168HashKey        = 16*6   # store HashKey <<1 mod poly here
169HashKey_2      = 16*7   # store HashKey^2 <<1 mod poly here
170HashKey_3      = 16*8   # store HashKey^3 <<1 mod poly here
171HashKey_4      = 16*9   # store HashKey^4 <<1 mod poly here
172HashKey_5      = 16*10   # store HashKey^5 <<1 mod poly here
173HashKey_6      = 16*11   # store HashKey^6 <<1 mod poly here
174HashKey_7      = 16*12   # store HashKey^7 <<1 mod poly here
175HashKey_8      = 16*13   # store HashKey^8 <<1 mod poly here
176HashKey_k      = 16*14   # store XOR of HashKey <<1 mod poly here (for Karatsuba purposes)
177HashKey_2_k    = 16*15   # store XOR of HashKey^2 <<1 mod poly here (for Karatsuba purposes)
178HashKey_3_k    = 16*16   # store XOR of HashKey^3 <<1 mod poly here (for Karatsuba purposes)
179HashKey_4_k    = 16*17   # store XOR of HashKey^4 <<1 mod poly here (for Karatsuba purposes)
180HashKey_5_k    = 16*18   # store XOR of HashKey^5 <<1 mod poly here (for Karatsuba purposes)
181HashKey_6_k    = 16*19   # store XOR of HashKey^6 <<1 mod poly here (for Karatsuba purposes)
182HashKey_7_k    = 16*20   # store XOR of HashKey^7 <<1 mod poly here (for Karatsuba purposes)
183HashKey_8_k    = 16*21   # store XOR of HashKey^8 <<1 mod poly here (for Karatsuba purposes)
184
185#define arg1 %rdi
186#define arg2 %rsi
187#define arg3 %rdx
188#define arg4 %rcx
189#define arg5 %r8
190#define arg6 %r9
191#define keysize 2*15*16(arg1)
192
193i = 0
194j = 0
195
196out_order = 0
197in_order = 1
198DEC = 0
199ENC = 1
200
201.macro define_reg r n
202reg_\r = %xmm\n
203.endm
204
205.macro setreg
206.altmacro
207define_reg i %i
208define_reg j %j
209.noaltmacro
210.endm
211
212TMP1 =   16*0    # Temporary storage for AAD
213TMP2 =   16*1    # Temporary storage for AES State 2 (State 1 is stored in an XMM register)
214TMP3 =   16*2    # Temporary storage for AES State 3
215TMP4 =   16*3    # Temporary storage for AES State 4
216TMP5 =   16*4    # Temporary storage for AES State 5
217TMP6 =   16*5    # Temporary storage for AES State 6
218TMP7 =   16*6    # Temporary storage for AES State 7
219TMP8 =   16*7    # Temporary storage for AES State 8
220
221VARIABLE_OFFSET = 16*8
222
223################################
224# Utility Macros
225################################
226
227.macro FUNC_SAVE
228        push    %r12
229        push    %r13
230        push    %r15
231
232	push	%rbp
233	mov	%rsp, %rbp
234
235        sub     $VARIABLE_OFFSET, %rsp
236        and     $~63, %rsp                    # align rsp to 64 bytes
237.endm
238
239.macro FUNC_RESTORE
240        mov     %rbp, %rsp
241	pop	%rbp
242
243        pop     %r15
244        pop     %r13
245        pop     %r12
246.endm
247
248# Encryption of a single block
249.macro ENCRYPT_SINGLE_BLOCK REP XMM0
250                vpxor    (arg1), \XMM0, \XMM0
251               i = 1
252               setreg
253.rep \REP
254                vaesenc  16*i(arg1), \XMM0, \XMM0
255               i = (i+1)
256               setreg
257.endr
258                vaesenclast 16*i(arg1), \XMM0, \XMM0
259.endm
260
261# combined for GCM encrypt and decrypt functions
262# clobbering all xmm registers
263# clobbering r10, r11, r12, r13, r15, rax
264.macro  GCM_ENC_DEC INITIAL_BLOCKS GHASH_8_ENCRYPT_8_PARALLEL GHASH_LAST_8 GHASH_MUL ENC_DEC REP
265        vmovdqu AadHash(arg2), %xmm8
266        vmovdqu  HashKey(arg2), %xmm13      # xmm13 = HashKey
267        add arg5, InLen(arg2)
268
269        # initialize the data pointer offset as zero
270        xor     %r11d, %r11d
271
272        PARTIAL_BLOCK \GHASH_MUL, arg3, arg4, arg5, %r11, %xmm8, \ENC_DEC
273        sub %r11, arg5
274
275        mov     arg5, %r13                  # save the number of bytes of plaintext/ciphertext
276        and     $-16, %r13                  # r13 = r13 - (r13 mod 16)
277
278        mov     %r13, %r12
279        shr     $4, %r12
280        and     $7, %r12
281        jz      .L_initial_num_blocks_is_0\@
282
283        cmp     $7, %r12
284        je      .L_initial_num_blocks_is_7\@
285        cmp     $6, %r12
286        je      .L_initial_num_blocks_is_6\@
287        cmp     $5, %r12
288        je      .L_initial_num_blocks_is_5\@
289        cmp     $4, %r12
290        je      .L_initial_num_blocks_is_4\@
291        cmp     $3, %r12
292        je      .L_initial_num_blocks_is_3\@
293        cmp     $2, %r12
294        je      .L_initial_num_blocks_is_2\@
295
296        jmp     .L_initial_num_blocks_is_1\@
297
298.L_initial_num_blocks_is_7\@:
299        \INITIAL_BLOCKS  \REP, 7, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
300        sub     $16*7, %r13
301        jmp     .L_initial_blocks_encrypted\@
302
303.L_initial_num_blocks_is_6\@:
304        \INITIAL_BLOCKS  \REP, 6, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
305        sub     $16*6, %r13
306        jmp     .L_initial_blocks_encrypted\@
307
308.L_initial_num_blocks_is_5\@:
309        \INITIAL_BLOCKS  \REP, 5, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
310        sub     $16*5, %r13
311        jmp     .L_initial_blocks_encrypted\@
312
313.L_initial_num_blocks_is_4\@:
314        \INITIAL_BLOCKS  \REP, 4, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
315        sub     $16*4, %r13
316        jmp     .L_initial_blocks_encrypted\@
317
318.L_initial_num_blocks_is_3\@:
319        \INITIAL_BLOCKS  \REP, 3, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
320        sub     $16*3, %r13
321        jmp     .L_initial_blocks_encrypted\@
322
323.L_initial_num_blocks_is_2\@:
324        \INITIAL_BLOCKS  \REP, 2, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
325        sub     $16*2, %r13
326        jmp     .L_initial_blocks_encrypted\@
327
328.L_initial_num_blocks_is_1\@:
329        \INITIAL_BLOCKS  \REP, 1, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
330        sub     $16*1, %r13
331        jmp     .L_initial_blocks_encrypted\@
332
333.L_initial_num_blocks_is_0\@:
334        \INITIAL_BLOCKS  \REP, 0, %xmm12, %xmm13, %xmm14, %xmm15, %xmm11, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm10, %xmm0, \ENC_DEC
335
336
337.L_initial_blocks_encrypted\@:
338        test    %r13, %r13
339        je      .L_zero_cipher_left\@
340
341        sub     $128, %r13
342        je      .L_eight_cipher_left\@
343
344
345
346
347        vmovd   %xmm9, %r15d
348        and     $255, %r15d
349        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
350
351
352.L_encrypt_by_8_new\@:
353        cmp     $(255-8), %r15d
354        jg      .L_encrypt_by_8\@
355
356
357
358        add     $8, %r15b
359        \GHASH_8_ENCRYPT_8_PARALLEL      \REP, %xmm0, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm15, out_order, \ENC_DEC
360        add     $128, %r11
361        sub     $128, %r13
362        jne     .L_encrypt_by_8_new\@
363
364        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
365        jmp     .L_eight_cipher_left\@
366
367.L_encrypt_by_8\@:
368        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
369        add     $8, %r15b
370        \GHASH_8_ENCRYPT_8_PARALLEL      \REP, %xmm0, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm9, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm15, in_order, \ENC_DEC
371        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
372        add     $128, %r11
373        sub     $128, %r13
374        jne     .L_encrypt_by_8_new\@
375
376        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
377
378
379
380
381.L_eight_cipher_left\@:
382        \GHASH_LAST_8    %xmm0, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8
383
384
385.L_zero_cipher_left\@:
386        vmovdqu %xmm14, AadHash(arg2)
387        vmovdqu %xmm9, CurCount(arg2)
388
389        # check for 0 length
390        mov     arg5, %r13
391        and     $15, %r13                            # r13 = (arg5 mod 16)
392
393        je      .L_multiple_of_16_bytes\@
394
395        # handle the last <16 Byte block separately
396
397        mov %r13, PBlockLen(arg2)
398
399        vpaddd  ONE(%rip), %xmm9, %xmm9              # INCR CNT to get Yn
400        vmovdqu %xmm9, CurCount(arg2)
401        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
402
403        ENCRYPT_SINGLE_BLOCK    \REP, %xmm9                # E(K, Yn)
404        vmovdqu %xmm9, PBlockEncKey(arg2)
405
406        cmp $16, arg5
407        jge .L_large_enough_update\@
408
409        lea (arg4,%r11,1), %r10
410        mov %r13, %r12
411
412        READ_PARTIAL_BLOCK %r10 %r12 %xmm1
413
414        lea     SHIFT_MASK+16(%rip), %r12
415        sub     %r13, %r12                           # adjust the shuffle mask pointer to be
416						     # able to shift 16-r13 bytes (r13 is the
417	# number of bytes in plaintext mod 16)
418
419        jmp .L_final_ghash_mul\@
420
421.L_large_enough_update\@:
422        sub $16, %r11
423        add %r13, %r11
424
425        # receive the last <16 Byte block
426        vmovdqu	(arg4, %r11, 1), %xmm1
427
428        sub	%r13, %r11
429        add	$16, %r11
430
431        lea	SHIFT_MASK+16(%rip), %r12
432        # adjust the shuffle mask pointer to be able to shift 16-r13 bytes
433        # (r13 is the number of bytes in plaintext mod 16)
434        sub	%r13, %r12
435        # get the appropriate shuffle mask
436        vmovdqu	(%r12), %xmm2
437        # shift right 16-r13 bytes
438        vpshufb  %xmm2, %xmm1, %xmm1
439
440.L_final_ghash_mul\@:
441        .if  \ENC_DEC ==  DEC
442        vmovdqa %xmm1, %xmm2
443        vpxor   %xmm1, %xmm9, %xmm9                  # Plaintext XOR E(K, Yn)
444        vmovdqu ALL_F-SHIFT_MASK(%r12), %xmm1        # get the appropriate mask to
445						     # mask out top 16-r13 bytes of xmm9
446        vpand   %xmm1, %xmm9, %xmm9                  # mask out top 16-r13 bytes of xmm9
447        vpand   %xmm1, %xmm2, %xmm2
448        vpshufb SHUF_MASK(%rip), %xmm2, %xmm2
449        vpxor   %xmm2, %xmm14, %xmm14
450
451        vmovdqu %xmm14, AadHash(arg2)
452        .else
453        vpxor   %xmm1, %xmm9, %xmm9                  # Plaintext XOR E(K, Yn)
454        vmovdqu ALL_F-SHIFT_MASK(%r12), %xmm1        # get the appropriate mask to
455						     # mask out top 16-r13 bytes of xmm9
456        vpand   %xmm1, %xmm9, %xmm9                  # mask out top 16-r13 bytes of xmm9
457        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9
458        vpxor   %xmm9, %xmm14, %xmm14
459
460        vmovdqu %xmm14, AadHash(arg2)
461        vpshufb SHUF_MASK(%rip), %xmm9, %xmm9        # shuffle xmm9 back to output as ciphertext
462        .endif
463
464
465        #############################
466        # output r13 Bytes
467        vmovq   %xmm9, %rax
468        cmp     $8, %r13
469        jle     .L_less_than_8_bytes_left\@
470
471        mov     %rax, (arg3 , %r11)
472        add     $8, %r11
473        vpsrldq $8, %xmm9, %xmm9
474        vmovq   %xmm9, %rax
475        sub     $8, %r13
476
477.L_less_than_8_bytes_left\@:
478        movb    %al, (arg3 , %r11)
479        add     $1, %r11
480        shr     $8, %rax
481        sub     $1, %r13
482        jne     .L_less_than_8_bytes_left\@
483        #############################
484
485.L_multiple_of_16_bytes\@:
486.endm
487
488
489# GCM_COMPLETE Finishes update of tag of last partial block
490# Output: Authorization Tag (AUTH_TAG)
491# Clobbers rax, r10-r12, and xmm0, xmm1, xmm5-xmm15
492.macro GCM_COMPLETE GHASH_MUL REP AUTH_TAG AUTH_TAG_LEN
493        vmovdqu AadHash(arg2), %xmm14
494        vmovdqu HashKey(arg2), %xmm13
495
496        mov PBlockLen(arg2), %r12
497        test %r12, %r12
498        je .L_partial_done\@
499
500	#GHASH computation for the last <16 Byte block
501        \GHASH_MUL       %xmm14, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
502
503.L_partial_done\@:
504        mov AadLen(arg2), %r12                          # r12 = aadLen (number of bytes)
505        shl     $3, %r12                             # convert into number of bits
506        vmovd   %r12d, %xmm15                        # len(A) in xmm15
507
508        mov InLen(arg2), %r12
509        shl     $3, %r12                        # len(C) in bits  (*128)
510        vmovq   %r12, %xmm1
511        vpslldq $8, %xmm15, %xmm15                   # xmm15 = len(A)|| 0x0000000000000000
512        vpxor   %xmm1, %xmm15, %xmm15                # xmm15 = len(A)||len(C)
513
514        vpxor   %xmm15, %xmm14, %xmm14
515        \GHASH_MUL       %xmm14, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6    # final GHASH computation
516        vpshufb SHUF_MASK(%rip), %xmm14, %xmm14      # perform a 16Byte swap
517
518        vmovdqu OrigIV(arg2), %xmm9
519
520        ENCRYPT_SINGLE_BLOCK    \REP, %xmm9                # E(K, Y0)
521
522        vpxor   %xmm14, %xmm9, %xmm9
523
524
525
526.L_return_T\@:
527        mov     \AUTH_TAG, %r10              # r10 = authTag
528        mov     \AUTH_TAG_LEN, %r11              # r11 = auth_tag_len
529
530        cmp     $16, %r11
531        je      .L_T_16\@
532
533        cmp     $8, %r11
534        jl      .L_T_4\@
535
536.L_T_8\@:
537        vmovq   %xmm9, %rax
538        mov     %rax, (%r10)
539        add     $8, %r10
540        sub     $8, %r11
541        vpsrldq $8, %xmm9, %xmm9
542        test    %r11, %r11
543        je     .L_return_T_done\@
544.L_T_4\@:
545        vmovd   %xmm9, %eax
546        mov     %eax, (%r10)
547        add     $4, %r10
548        sub     $4, %r11
549        vpsrldq     $4, %xmm9, %xmm9
550        test    %r11, %r11
551        je     .L_return_T_done\@
552.L_T_123\@:
553        vmovd     %xmm9, %eax
554        cmp     $2, %r11
555        jl     .L_T_1\@
556        mov     %ax, (%r10)
557        cmp     $2, %r11
558        je     .L_return_T_done\@
559        add     $2, %r10
560        sar     $16, %eax
561.L_T_1\@:
562        mov     %al, (%r10)
563        jmp     .L_return_T_done\@
564
565.L_T_16\@:
566        vmovdqu %xmm9, (%r10)
567
568.L_return_T_done\@:
569.endm
570
571.macro CALC_AAD_HASH GHASH_MUL AAD AADLEN T1 T2 T3 T4 T5 T6 T7 T8
572
573	mov     \AAD, %r10                      # r10 = AAD
574	mov     \AADLEN, %r12                      # r12 = aadLen
575
576
577	mov     %r12, %r11
578
579	vpxor   \T8, \T8, \T8
580	vpxor   \T7, \T7, \T7
581	cmp     $16, %r11
582	jl      .L_get_AAD_rest8\@
583.L_get_AAD_blocks\@:
584	vmovdqu (%r10), \T7
585	vpshufb SHUF_MASK(%rip), \T7, \T7
586	vpxor   \T7, \T8, \T8
587	\GHASH_MUL       \T8, \T2, \T1, \T3, \T4, \T5, \T6
588	add     $16, %r10
589	sub     $16, %r12
590	sub     $16, %r11
591	cmp     $16, %r11
592	jge     .L_get_AAD_blocks\@
593	vmovdqu \T8, \T7
594	test    %r11, %r11
595	je      .L_get_AAD_done\@
596
597	vpxor   \T7, \T7, \T7
598
599	/* read the last <16B of AAD. since we have at least 4B of
600	data right after the AAD (the ICV, and maybe some CT), we can
601	read 4B/8B blocks safely, and then get rid of the extra stuff */
602.L_get_AAD_rest8\@:
603	cmp     $4, %r11
604	jle     .L_get_AAD_rest4\@
605	movq    (%r10), \T1
606	add     $8, %r10
607	sub     $8, %r11
608	vpslldq $8, \T1, \T1
609	vpsrldq $8, \T7, \T7
610	vpxor   \T1, \T7, \T7
611	jmp     .L_get_AAD_rest8\@
612.L_get_AAD_rest4\@:
613	test    %r11, %r11
614	jle     .L_get_AAD_rest0\@
615	mov     (%r10), %eax
616	movq    %rax, \T1
617	add     $4, %r10
618	sub     $4, %r11
619	vpslldq $12, \T1, \T1
620	vpsrldq $4, \T7, \T7
621	vpxor   \T1, \T7, \T7
622.L_get_AAD_rest0\@:
623	/* finalize: shift out the extra bytes we read, and align
624	left. since pslldq can only shift by an immediate, we use
625	vpshufb and a pair of shuffle masks */
626	leaq	ALL_F(%rip), %r11
627	subq	%r12, %r11
628	vmovdqu	16(%r11), \T1
629	andq	$~3, %r11
630	vpshufb (%r11), \T7, \T7
631	vpand	\T1, \T7, \T7
632.L_get_AAD_rest_final\@:
633	vpshufb SHUF_MASK(%rip), \T7, \T7
634	vpxor   \T8, \T7, \T7
635	\GHASH_MUL       \T7, \T2, \T1, \T3, \T4, \T5, \T6
636
637.L_get_AAD_done\@:
638        vmovdqu \T7, AadHash(arg2)
639.endm
640
641.macro INIT GHASH_MUL PRECOMPUTE
642        mov arg6, %r11
643        mov %r11, AadLen(arg2) # ctx_data.aad_length = aad_length
644        xor %r11d, %r11d
645        mov %r11, InLen(arg2) # ctx_data.in_length = 0
646
647        mov %r11, PBlockLen(arg2) # ctx_data.partial_block_length = 0
648        mov %r11, PBlockEncKey(arg2) # ctx_data.partial_block_enc_key = 0
649        mov arg3, %rax
650        movdqu (%rax), %xmm0
651        movdqu %xmm0, OrigIV(arg2) # ctx_data.orig_IV = iv
652
653        vpshufb SHUF_MASK(%rip), %xmm0, %xmm0
654        movdqu %xmm0, CurCount(arg2) # ctx_data.current_counter = iv
655
656        vmovdqu  (arg4), %xmm6              # xmm6 = HashKey
657
658        vpshufb  SHUF_MASK(%rip), %xmm6, %xmm6
659        ###############  PRECOMPUTATION of HashKey<<1 mod poly from the HashKey
660        vmovdqa  %xmm6, %xmm2
661        vpsllq   $1, %xmm6, %xmm6
662        vpsrlq   $63, %xmm2, %xmm2
663        vmovdqa  %xmm2, %xmm1
664        vpslldq  $8, %xmm2, %xmm2
665        vpsrldq  $8, %xmm1, %xmm1
666        vpor     %xmm2, %xmm6, %xmm6
667        #reduction
668        vpshufd  $0b00100100, %xmm1, %xmm2
669        vpcmpeqd TWOONE(%rip), %xmm2, %xmm2
670        vpand    POLY(%rip), %xmm2, %xmm2
671        vpxor    %xmm2, %xmm6, %xmm6        # xmm6 holds the HashKey<<1 mod poly
672        #######################################################################
673        vmovdqu  %xmm6, HashKey(arg2)       # store HashKey<<1 mod poly
674
675        CALC_AAD_HASH \GHASH_MUL, arg5, arg6, %xmm2, %xmm6, %xmm3, %xmm4, %xmm5, %xmm7, %xmm1, %xmm0
676
677        \PRECOMPUTE  %xmm6, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5
678.endm
679
680
681# Reads DLEN bytes starting at DPTR and stores in XMMDst
682# where 0 < DLEN < 16
683# Clobbers %rax, DLEN
684.macro READ_PARTIAL_BLOCK DPTR DLEN XMMDst
685        vpxor \XMMDst, \XMMDst, \XMMDst
686
687        cmp $8, \DLEN
688        jl .L_read_lt8_\@
689        mov (\DPTR), %rax
690        vpinsrq $0, %rax, \XMMDst, \XMMDst
691        sub $8, \DLEN
692        jz .L_done_read_partial_block_\@
693        xor %eax, %eax
694.L_read_next_byte_\@:
695        shl $8, %rax
696        mov 7(\DPTR, \DLEN, 1), %al
697        dec \DLEN
698        jnz .L_read_next_byte_\@
699        vpinsrq $1, %rax, \XMMDst, \XMMDst
700        jmp .L_done_read_partial_block_\@
701.L_read_lt8_\@:
702        xor %eax, %eax
703.L_read_next_byte_lt8_\@:
704        shl $8, %rax
705        mov -1(\DPTR, \DLEN, 1), %al
706        dec \DLEN
707        jnz .L_read_next_byte_lt8_\@
708        vpinsrq $0, %rax, \XMMDst, \XMMDst
709.L_done_read_partial_block_\@:
710.endm
711
712# PARTIAL_BLOCK: Handles encryption/decryption and the tag partial blocks
713# between update calls.
714# Requires the input data be at least 1 byte long due to READ_PARTIAL_BLOCK
715# Outputs encrypted bytes, and updates hash and partial info in gcm_data_context
716# Clobbers rax, r10, r12, r13, xmm0-6, xmm9-13
717.macro PARTIAL_BLOCK GHASH_MUL CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \
718        AAD_HASH ENC_DEC
719        mov 	PBlockLen(arg2), %r13
720        test	%r13, %r13
721        je	.L_partial_block_done_\@	# Leave Macro if no partial blocks
722        # Read in input data without over reading
723        cmp	$16, \PLAIN_CYPH_LEN
724        jl	.L_fewer_than_16_bytes_\@
725        vmovdqu	(\PLAIN_CYPH_IN), %xmm1	# If more than 16 bytes, just fill xmm
726        jmp	.L_data_read_\@
727
728.L_fewer_than_16_bytes_\@:
729        lea	(\PLAIN_CYPH_IN, \DATA_OFFSET, 1), %r10
730        mov	\PLAIN_CYPH_LEN, %r12
731        READ_PARTIAL_BLOCK %r10 %r12 %xmm1
732
733        mov PBlockLen(arg2), %r13
734
735.L_data_read_\@:				# Finished reading in data
736
737        vmovdqu	PBlockEncKey(arg2), %xmm9
738        vmovdqu	HashKey(arg2), %xmm13
739
740        lea	SHIFT_MASK(%rip), %r12
741
742        # adjust the shuffle mask pointer to be able to shift r13 bytes
743        # r16-r13 is the number of bytes in plaintext mod 16)
744        add	%r13, %r12
745        vmovdqu	(%r12), %xmm2		# get the appropriate shuffle mask
746        vpshufb %xmm2, %xmm9, %xmm9		# shift right r13 bytes
747
748.if  \ENC_DEC ==  DEC
749        vmovdqa	%xmm1, %xmm3
750        pxor	%xmm1, %xmm9		# Ciphertext XOR E(K, Yn)
751
752        mov	\PLAIN_CYPH_LEN, %r10
753        add	%r13, %r10
754        # Set r10 to be the amount of data left in CYPH_PLAIN_IN after filling
755        sub	$16, %r10
756        # Determine if partial block is not being filled and
757        # shift mask accordingly
758        jge	.L_no_extra_mask_1_\@
759        sub	%r10, %r12
760.L_no_extra_mask_1_\@:
761
762        vmovdqu	ALL_F-SHIFT_MASK(%r12), %xmm1
763        # get the appropriate mask to mask out bottom r13 bytes of xmm9
764        vpand	%xmm1, %xmm9, %xmm9		# mask out bottom r13 bytes of xmm9
765
766        vpand	%xmm1, %xmm3, %xmm3
767        vmovdqa	SHUF_MASK(%rip), %xmm10
768        vpshufb	%xmm10, %xmm3, %xmm3
769        vpshufb	%xmm2, %xmm3, %xmm3
770        vpxor	%xmm3, \AAD_HASH, \AAD_HASH
771
772        test	%r10, %r10
773        jl	.L_partial_incomplete_1_\@
774
775        # GHASH computation for the last <16 Byte block
776        \GHASH_MUL \AAD_HASH, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
777        xor	%eax,%eax
778
779        mov	%rax, PBlockLen(arg2)
780        jmp	.L_dec_done_\@
781.L_partial_incomplete_1_\@:
782        add	\PLAIN_CYPH_LEN, PBlockLen(arg2)
783.L_dec_done_\@:
784        vmovdqu	\AAD_HASH, AadHash(arg2)
785.else
786        vpxor	%xmm1, %xmm9, %xmm9			# Plaintext XOR E(K, Yn)
787
788        mov	\PLAIN_CYPH_LEN, %r10
789        add	%r13, %r10
790        # Set r10 to be the amount of data left in CYPH_PLAIN_IN after filling
791        sub	$16, %r10
792        # Determine if partial block is not being filled and
793        # shift mask accordingly
794        jge	.L_no_extra_mask_2_\@
795        sub	%r10, %r12
796.L_no_extra_mask_2_\@:
797
798        vmovdqu	ALL_F-SHIFT_MASK(%r12), %xmm1
799        # get the appropriate mask to mask out bottom r13 bytes of xmm9
800        vpand	%xmm1, %xmm9, %xmm9
801
802        vmovdqa	SHUF_MASK(%rip), %xmm1
803        vpshufb %xmm1, %xmm9, %xmm9
804        vpshufb %xmm2, %xmm9, %xmm9
805        vpxor	%xmm9, \AAD_HASH, \AAD_HASH
806
807        test	%r10, %r10
808        jl	.L_partial_incomplete_2_\@
809
810        # GHASH computation for the last <16 Byte block
811        \GHASH_MUL \AAD_HASH, %xmm13, %xmm0, %xmm10, %xmm11, %xmm5, %xmm6
812        xor	%eax,%eax
813
814        mov	%rax, PBlockLen(arg2)
815        jmp	.L_encode_done_\@
816.L_partial_incomplete_2_\@:
817        add	\PLAIN_CYPH_LEN, PBlockLen(arg2)
818.L_encode_done_\@:
819        vmovdqu	\AAD_HASH, AadHash(arg2)
820
821        vmovdqa	SHUF_MASK(%rip), %xmm10
822        # shuffle xmm9 back to output as ciphertext
823        vpshufb	%xmm10, %xmm9, %xmm9
824        vpshufb	%xmm2, %xmm9, %xmm9
825.endif
826        # output encrypted Bytes
827        test	%r10, %r10
828        jl	.L_partial_fill_\@
829        mov	%r13, %r12
830        mov	$16, %r13
831        # Set r13 to be the number of bytes to write out
832        sub	%r12, %r13
833        jmp	.L_count_set_\@
834.L_partial_fill_\@:
835        mov	\PLAIN_CYPH_LEN, %r13
836.L_count_set_\@:
837        vmovdqa	%xmm9, %xmm0
838        vmovq	%xmm0, %rax
839        cmp	$8, %r13
840        jle	.L_less_than_8_bytes_left_\@
841
842        mov	%rax, (\CYPH_PLAIN_OUT, \DATA_OFFSET, 1)
843        add	$8, \DATA_OFFSET
844        psrldq	$8, %xmm0
845        vmovq	%xmm0, %rax
846        sub	$8, %r13
847.L_less_than_8_bytes_left_\@:
848        movb	%al, (\CYPH_PLAIN_OUT, \DATA_OFFSET, 1)
849        add	$1, \DATA_OFFSET
850        shr	$8, %rax
851        sub	$1, %r13
852        jne	.L_less_than_8_bytes_left_\@
853.L_partial_block_done_\@:
854.endm # PARTIAL_BLOCK
855
856###############################################################################
857# GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0)
858# Input: A and B (128-bits each, bit-reflected)
859# Output: C = A*B*x mod poly, (i.e. >>1 )
860# To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input
861# GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly.
862###############################################################################
863.macro  GHASH_MUL_AVX GH HK T1 T2 T3 T4 T5
864
865        vpshufd         $0b01001110, \GH, \T2
866        vpshufd         $0b01001110, \HK, \T3
867        vpxor           \GH     , \T2, \T2      # T2 = (a1+a0)
868        vpxor           \HK     , \T3, \T3      # T3 = (b1+b0)
869
870        vpclmulqdq      $0x11, \HK, \GH, \T1    # T1 = a1*b1
871        vpclmulqdq      $0x00, \HK, \GH, \GH    # GH = a0*b0
872        vpclmulqdq      $0x00, \T3, \T2, \T2    # T2 = (a1+a0)*(b1+b0)
873        vpxor           \GH, \T2,\T2
874        vpxor           \T1, \T2,\T2            # T2 = a0*b1+a1*b0
875
876        vpslldq         $8, \T2,\T3             # shift-L T3 2 DWs
877        vpsrldq         $8, \T2,\T2             # shift-R T2 2 DWs
878        vpxor           \T3, \GH, \GH
879        vpxor           \T2, \T1, \T1           # <T1:GH> = GH x HK
880
881        #first phase of the reduction
882        vpslld  $31, \GH, \T2                   # packed right shifting << 31
883        vpslld  $30, \GH, \T3                   # packed right shifting shift << 30
884        vpslld  $25, \GH, \T4                   # packed right shifting shift << 25
885
886        vpxor   \T3, \T2, \T2                   # xor the shifted versions
887        vpxor   \T4, \T2, \T2
888
889        vpsrldq $4, \T2, \T5                    # shift-R T5 1 DW
890
891        vpslldq $12, \T2, \T2                   # shift-L T2 3 DWs
892        vpxor   \T2, \GH, \GH                   # first phase of the reduction complete
893
894        #second phase of the reduction
895
896        vpsrld  $1,\GH, \T2                     # packed left shifting >> 1
897        vpsrld  $2,\GH, \T3                     # packed left shifting >> 2
898        vpsrld  $7,\GH, \T4                     # packed left shifting >> 7
899        vpxor   \T3, \T2, \T2                   # xor the shifted versions
900        vpxor   \T4, \T2, \T2
901
902        vpxor   \T5, \T2, \T2
903        vpxor   \T2, \GH, \GH
904        vpxor   \T1, \GH, \GH                   # the result is in GH
905
906
907.endm
908
909.macro PRECOMPUTE_AVX HK T1 T2 T3 T4 T5 T6
910
911        # Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
912        vmovdqa  \HK, \T5
913
914        vpshufd  $0b01001110, \T5, \T1
915        vpxor    \T5, \T1, \T1
916        vmovdqu  \T1, HashKey_k(arg2)
917
918        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^2<<1 mod poly
919        vmovdqu  \T5, HashKey_2(arg2)                    #  [HashKey_2] = HashKey^2<<1 mod poly
920        vpshufd  $0b01001110, \T5, \T1
921        vpxor    \T5, \T1, \T1
922        vmovdqu  \T1, HashKey_2_k(arg2)
923
924        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^3<<1 mod poly
925        vmovdqu  \T5, HashKey_3(arg2)
926        vpshufd  $0b01001110, \T5, \T1
927        vpxor    \T5, \T1, \T1
928        vmovdqu  \T1, HashKey_3_k(arg2)
929
930        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^4<<1 mod poly
931        vmovdqu  \T5, HashKey_4(arg2)
932        vpshufd  $0b01001110, \T5, \T1
933        vpxor    \T5, \T1, \T1
934        vmovdqu  \T1, HashKey_4_k(arg2)
935
936        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^5<<1 mod poly
937        vmovdqu  \T5, HashKey_5(arg2)
938        vpshufd  $0b01001110, \T5, \T1
939        vpxor    \T5, \T1, \T1
940        vmovdqu  \T1, HashKey_5_k(arg2)
941
942        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^6<<1 mod poly
943        vmovdqu  \T5, HashKey_6(arg2)
944        vpshufd  $0b01001110, \T5, \T1
945        vpxor    \T5, \T1, \T1
946        vmovdqu  \T1, HashKey_6_k(arg2)
947
948        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^7<<1 mod poly
949        vmovdqu  \T5, HashKey_7(arg2)
950        vpshufd  $0b01001110, \T5, \T1
951        vpxor    \T5, \T1, \T1
952        vmovdqu  \T1, HashKey_7_k(arg2)
953
954        GHASH_MUL_AVX \T5, \HK, \T1, \T3, \T4, \T6, \T2  #  T5 = HashKey^8<<1 mod poly
955        vmovdqu  \T5, HashKey_8(arg2)
956        vpshufd  $0b01001110, \T5, \T1
957        vpxor    \T5, \T1, \T1
958        vmovdqu  \T1, HashKey_8_k(arg2)
959
960.endm
961
962## if a = number of total plaintext bytes
963## b = floor(a/16)
964## num_initial_blocks = b mod 4#
965## encrypt the initial num_initial_blocks blocks and apply ghash on the ciphertext
966## r10, r11, r12, rax are clobbered
967## arg1, arg2, arg3, arg4 are used as pointers only, not modified
968
969.macro INITIAL_BLOCKS_AVX REP num_initial_blocks T1 T2 T3 T4 T5 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T6 T_key ENC_DEC
970	i = (8-\num_initial_blocks)
971	setreg
972        vmovdqu AadHash(arg2), reg_i
973
974	# start AES for num_initial_blocks blocks
975	vmovdqu CurCount(arg2), \CTR
976
977	i = (9-\num_initial_blocks)
978	setreg
979.rep \num_initial_blocks
980                vpaddd  ONE(%rip), \CTR, \CTR		# INCR Y0
981                vmovdqa \CTR, reg_i
982                vpshufb SHUF_MASK(%rip), reg_i, reg_i   # perform a 16Byte swap
983	i = (i+1)
984	setreg
985.endr
986
987	vmovdqa  (arg1), \T_key
988	i = (9-\num_initial_blocks)
989	setreg
990.rep \num_initial_blocks
991                vpxor   \T_key, reg_i, reg_i
992	i = (i+1)
993	setreg
994.endr
995
996       j = 1
997       setreg
998.rep \REP
999       vmovdqa  16*j(arg1), \T_key
1000	i = (9-\num_initial_blocks)
1001	setreg
1002.rep \num_initial_blocks
1003        vaesenc \T_key, reg_i, reg_i
1004	i = (i+1)
1005	setreg
1006.endr
1007
1008       j = (j+1)
1009       setreg
1010.endr
1011
1012	vmovdqa  16*j(arg1), \T_key
1013	i = (9-\num_initial_blocks)
1014	setreg
1015.rep \num_initial_blocks
1016        vaesenclast      \T_key, reg_i, reg_i
1017	i = (i+1)
1018	setreg
1019.endr
1020
1021	i = (9-\num_initial_blocks)
1022	setreg
1023.rep \num_initial_blocks
1024                vmovdqu (arg4, %r11), \T1
1025                vpxor   \T1, reg_i, reg_i
1026                vmovdqu reg_i, (arg3 , %r11)           # write back ciphertext for num_initial_blocks blocks
1027                add     $16, %r11
1028.if  \ENC_DEC == DEC
1029                vmovdqa \T1, reg_i
1030.endif
1031                vpshufb SHUF_MASK(%rip), reg_i, reg_i  # prepare ciphertext for GHASH computations
1032	i = (i+1)
1033	setreg
1034.endr
1035
1036
1037	i = (8-\num_initial_blocks)
1038	j = (9-\num_initial_blocks)
1039	setreg
1040
1041.rep \num_initial_blocks
1042        vpxor    reg_i, reg_j, reg_j
1043        GHASH_MUL_AVX       reg_j, \T2, \T1, \T3, \T4, \T5, \T6 # apply GHASH on num_initial_blocks blocks
1044	i = (i+1)
1045	j = (j+1)
1046	setreg
1047.endr
1048        # XMM8 has the combined result here
1049
1050        vmovdqa  \XMM8, TMP1(%rsp)
1051        vmovdqa  \XMM8, \T3
1052
1053        cmp     $128, %r13
1054        jl      .L_initial_blocks_done\@                  # no need for precomputed constants
1055
1056###############################################################################
1057# Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
1058                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1059                vmovdqa  \CTR, \XMM1
1060                vpshufb  SHUF_MASK(%rip), \XMM1, \XMM1  # perform a 16Byte swap
1061
1062                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1063                vmovdqa  \CTR, \XMM2
1064                vpshufb  SHUF_MASK(%rip), \XMM2, \XMM2  # perform a 16Byte swap
1065
1066                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1067                vmovdqa  \CTR, \XMM3
1068                vpshufb  SHUF_MASK(%rip), \XMM3, \XMM3  # perform a 16Byte swap
1069
1070                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1071                vmovdqa  \CTR, \XMM4
1072                vpshufb  SHUF_MASK(%rip), \XMM4, \XMM4  # perform a 16Byte swap
1073
1074                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1075                vmovdqa  \CTR, \XMM5
1076                vpshufb  SHUF_MASK(%rip), \XMM5, \XMM5  # perform a 16Byte swap
1077
1078                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1079                vmovdqa  \CTR, \XMM6
1080                vpshufb  SHUF_MASK(%rip), \XMM6, \XMM6  # perform a 16Byte swap
1081
1082                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1083                vmovdqa  \CTR, \XMM7
1084                vpshufb  SHUF_MASK(%rip), \XMM7, \XMM7  # perform a 16Byte swap
1085
1086                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
1087                vmovdqa  \CTR, \XMM8
1088                vpshufb  SHUF_MASK(%rip), \XMM8, \XMM8  # perform a 16Byte swap
1089
1090                vmovdqa  (arg1), \T_key
1091                vpxor    \T_key, \XMM1, \XMM1
1092                vpxor    \T_key, \XMM2, \XMM2
1093                vpxor    \T_key, \XMM3, \XMM3
1094                vpxor    \T_key, \XMM4, \XMM4
1095                vpxor    \T_key, \XMM5, \XMM5
1096                vpxor    \T_key, \XMM6, \XMM6
1097                vpxor    \T_key, \XMM7, \XMM7
1098                vpxor    \T_key, \XMM8, \XMM8
1099
1100               i = 1
1101               setreg
1102.rep    \REP       # do REP rounds
1103                vmovdqa  16*i(arg1), \T_key
1104                vaesenc  \T_key, \XMM1, \XMM1
1105                vaesenc  \T_key, \XMM2, \XMM2
1106                vaesenc  \T_key, \XMM3, \XMM3
1107                vaesenc  \T_key, \XMM4, \XMM4
1108                vaesenc  \T_key, \XMM5, \XMM5
1109                vaesenc  \T_key, \XMM6, \XMM6
1110                vaesenc  \T_key, \XMM7, \XMM7
1111                vaesenc  \T_key, \XMM8, \XMM8
1112               i = (i+1)
1113               setreg
1114.endr
1115
1116                vmovdqa  16*i(arg1), \T_key
1117                vaesenclast  \T_key, \XMM1, \XMM1
1118                vaesenclast  \T_key, \XMM2, \XMM2
1119                vaesenclast  \T_key, \XMM3, \XMM3
1120                vaesenclast  \T_key, \XMM4, \XMM4
1121                vaesenclast  \T_key, \XMM5, \XMM5
1122                vaesenclast  \T_key, \XMM6, \XMM6
1123                vaesenclast  \T_key, \XMM7, \XMM7
1124                vaesenclast  \T_key, \XMM8, \XMM8
1125
1126                vmovdqu  (arg4, %r11), \T1
1127                vpxor    \T1, \XMM1, \XMM1
1128                vmovdqu  \XMM1, (arg3 , %r11)
1129                .if   \ENC_DEC == DEC
1130                vmovdqa  \T1, \XMM1
1131                .endif
1132
1133                vmovdqu  16*1(arg4, %r11), \T1
1134                vpxor    \T1, \XMM2, \XMM2
1135                vmovdqu  \XMM2, 16*1(arg3 , %r11)
1136                .if   \ENC_DEC == DEC
1137                vmovdqa  \T1, \XMM2
1138                .endif
1139
1140                vmovdqu  16*2(arg4, %r11), \T1
1141                vpxor    \T1, \XMM3, \XMM3
1142                vmovdqu  \XMM3, 16*2(arg3 , %r11)
1143                .if   \ENC_DEC == DEC
1144                vmovdqa  \T1, \XMM3
1145                .endif
1146
1147                vmovdqu  16*3(arg4, %r11), \T1
1148                vpxor    \T1, \XMM4, \XMM4
1149                vmovdqu  \XMM4, 16*3(arg3 , %r11)
1150                .if   \ENC_DEC == DEC
1151                vmovdqa  \T1, \XMM4
1152                .endif
1153
1154                vmovdqu  16*4(arg4, %r11), \T1
1155                vpxor    \T1, \XMM5, \XMM5
1156                vmovdqu  \XMM5, 16*4(arg3 , %r11)
1157                .if   \ENC_DEC == DEC
1158                vmovdqa  \T1, \XMM5
1159                .endif
1160
1161                vmovdqu  16*5(arg4, %r11), \T1
1162                vpxor    \T1, \XMM6, \XMM6
1163                vmovdqu  \XMM6, 16*5(arg3 , %r11)
1164                .if   \ENC_DEC == DEC
1165                vmovdqa  \T1, \XMM6
1166                .endif
1167
1168                vmovdqu  16*6(arg4, %r11), \T1
1169                vpxor    \T1, \XMM7, \XMM7
1170                vmovdqu  \XMM7, 16*6(arg3 , %r11)
1171                .if   \ENC_DEC == DEC
1172                vmovdqa  \T1, \XMM7
1173                .endif
1174
1175                vmovdqu  16*7(arg4, %r11), \T1
1176                vpxor    \T1, \XMM8, \XMM8
1177                vmovdqu  \XMM8, 16*7(arg3 , %r11)
1178                .if   \ENC_DEC == DEC
1179                vmovdqa  \T1, \XMM8
1180                .endif
1181
1182                add     $128, %r11
1183
1184                vpshufb  SHUF_MASK(%rip), \XMM1, \XMM1     # perform a 16Byte swap
1185                vpxor    TMP1(%rsp), \XMM1, \XMM1          # combine GHASHed value with the corresponding ciphertext
1186                vpshufb  SHUF_MASK(%rip), \XMM2, \XMM2     # perform a 16Byte swap
1187                vpshufb  SHUF_MASK(%rip), \XMM3, \XMM3     # perform a 16Byte swap
1188                vpshufb  SHUF_MASK(%rip), \XMM4, \XMM4     # perform a 16Byte swap
1189                vpshufb  SHUF_MASK(%rip), \XMM5, \XMM5     # perform a 16Byte swap
1190                vpshufb  SHUF_MASK(%rip), \XMM6, \XMM6     # perform a 16Byte swap
1191                vpshufb  SHUF_MASK(%rip), \XMM7, \XMM7     # perform a 16Byte swap
1192                vpshufb  SHUF_MASK(%rip), \XMM8, \XMM8     # perform a 16Byte swap
1193
1194###############################################################################
1195
1196.L_initial_blocks_done\@:
1197
1198.endm
1199
1200# encrypt 8 blocks at a time
1201# ghash the 8 previously encrypted ciphertext blocks
1202# arg1, arg2, arg3, arg4 are used as pointers only, not modified
1203# r11 is the data offset value
1204.macro GHASH_8_ENCRYPT_8_PARALLEL_AVX REP T1 T2 T3 T4 T5 T6 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T7 loop_idx ENC_DEC
1205
1206        vmovdqa \XMM1, \T2
1207        vmovdqa \XMM2, TMP2(%rsp)
1208        vmovdqa \XMM3, TMP3(%rsp)
1209        vmovdqa \XMM4, TMP4(%rsp)
1210        vmovdqa \XMM5, TMP5(%rsp)
1211        vmovdqa \XMM6, TMP6(%rsp)
1212        vmovdqa \XMM7, TMP7(%rsp)
1213        vmovdqa \XMM8, TMP8(%rsp)
1214
1215.if \loop_idx == in_order
1216                vpaddd  ONE(%rip), \CTR, \XMM1           # INCR CNT
1217                vpaddd  ONE(%rip), \XMM1, \XMM2
1218                vpaddd  ONE(%rip), \XMM2, \XMM3
1219                vpaddd  ONE(%rip), \XMM3, \XMM4
1220                vpaddd  ONE(%rip), \XMM4, \XMM5
1221                vpaddd  ONE(%rip), \XMM5, \XMM6
1222                vpaddd  ONE(%rip), \XMM6, \XMM7
1223                vpaddd  ONE(%rip), \XMM7, \XMM8
1224                vmovdqa \XMM8, \CTR
1225
1226                vpshufb SHUF_MASK(%rip), \XMM1, \XMM1    # perform a 16Byte swap
1227                vpshufb SHUF_MASK(%rip), \XMM2, \XMM2    # perform a 16Byte swap
1228                vpshufb SHUF_MASK(%rip), \XMM3, \XMM3    # perform a 16Byte swap
1229                vpshufb SHUF_MASK(%rip), \XMM4, \XMM4    # perform a 16Byte swap
1230                vpshufb SHUF_MASK(%rip), \XMM5, \XMM5    # perform a 16Byte swap
1231                vpshufb SHUF_MASK(%rip), \XMM6, \XMM6    # perform a 16Byte swap
1232                vpshufb SHUF_MASK(%rip), \XMM7, \XMM7    # perform a 16Byte swap
1233                vpshufb SHUF_MASK(%rip), \XMM8, \XMM8    # perform a 16Byte swap
1234.else
1235                vpaddd  ONEf(%rip), \CTR, \XMM1           # INCR CNT
1236                vpaddd  ONEf(%rip), \XMM1, \XMM2
1237                vpaddd  ONEf(%rip), \XMM2, \XMM3
1238                vpaddd  ONEf(%rip), \XMM3, \XMM4
1239                vpaddd  ONEf(%rip), \XMM4, \XMM5
1240                vpaddd  ONEf(%rip), \XMM5, \XMM6
1241                vpaddd  ONEf(%rip), \XMM6, \XMM7
1242                vpaddd  ONEf(%rip), \XMM7, \XMM8
1243                vmovdqa \XMM8, \CTR
1244.endif
1245
1246
1247        #######################################################################
1248
1249                vmovdqu (arg1), \T1
1250                vpxor   \T1, \XMM1, \XMM1
1251                vpxor   \T1, \XMM2, \XMM2
1252                vpxor   \T1, \XMM3, \XMM3
1253                vpxor   \T1, \XMM4, \XMM4
1254                vpxor   \T1, \XMM5, \XMM5
1255                vpxor   \T1, \XMM6, \XMM6
1256                vpxor   \T1, \XMM7, \XMM7
1257                vpxor   \T1, \XMM8, \XMM8
1258
1259        #######################################################################
1260
1261
1262
1263
1264
1265                vmovdqu 16*1(arg1), \T1
1266                vaesenc \T1, \XMM1, \XMM1
1267                vaesenc \T1, \XMM2, \XMM2
1268                vaesenc \T1, \XMM3, \XMM3
1269                vaesenc \T1, \XMM4, \XMM4
1270                vaesenc \T1, \XMM5, \XMM5
1271                vaesenc \T1, \XMM6, \XMM6
1272                vaesenc \T1, \XMM7, \XMM7
1273                vaesenc \T1, \XMM8, \XMM8
1274
1275                vmovdqu 16*2(arg1), \T1
1276                vaesenc \T1, \XMM1, \XMM1
1277                vaesenc \T1, \XMM2, \XMM2
1278                vaesenc \T1, \XMM3, \XMM3
1279                vaesenc \T1, \XMM4, \XMM4
1280                vaesenc \T1, \XMM5, \XMM5
1281                vaesenc \T1, \XMM6, \XMM6
1282                vaesenc \T1, \XMM7, \XMM7
1283                vaesenc \T1, \XMM8, \XMM8
1284
1285
1286        #######################################################################
1287
1288        vmovdqu         HashKey_8(arg2), \T5
1289        vpclmulqdq      $0x11, \T5, \T2, \T4             # T4 = a1*b1
1290        vpclmulqdq      $0x00, \T5, \T2, \T7             # T7 = a0*b0
1291
1292        vpshufd         $0b01001110, \T2, \T6
1293        vpxor           \T2, \T6, \T6
1294
1295        vmovdqu         HashKey_8_k(arg2), \T5
1296        vpclmulqdq      $0x00, \T5, \T6, \T6
1297
1298                vmovdqu 16*3(arg1), \T1
1299                vaesenc \T1, \XMM1, \XMM1
1300                vaesenc \T1, \XMM2, \XMM2
1301                vaesenc \T1, \XMM3, \XMM3
1302                vaesenc \T1, \XMM4, \XMM4
1303                vaesenc \T1, \XMM5, \XMM5
1304                vaesenc \T1, \XMM6, \XMM6
1305                vaesenc \T1, \XMM7, \XMM7
1306                vaesenc \T1, \XMM8, \XMM8
1307
1308        vmovdqa         TMP2(%rsp), \T1
1309        vmovdqu         HashKey_7(arg2), \T5
1310        vpclmulqdq      $0x11, \T5, \T1, \T3
1311        vpxor           \T3, \T4, \T4
1312        vpclmulqdq      $0x00, \T5, \T1, \T3
1313        vpxor           \T3, \T7, \T7
1314
1315        vpshufd         $0b01001110, \T1, \T3
1316        vpxor           \T1, \T3, \T3
1317        vmovdqu         HashKey_7_k(arg2), \T5
1318        vpclmulqdq      $0x10, \T5, \T3, \T3
1319        vpxor           \T3, \T6, \T6
1320
1321                vmovdqu 16*4(arg1), \T1
1322                vaesenc \T1, \XMM1, \XMM1
1323                vaesenc \T1, \XMM2, \XMM2
1324                vaesenc \T1, \XMM3, \XMM3
1325                vaesenc \T1, \XMM4, \XMM4
1326                vaesenc \T1, \XMM5, \XMM5
1327                vaesenc \T1, \XMM6, \XMM6
1328                vaesenc \T1, \XMM7, \XMM7
1329                vaesenc \T1, \XMM8, \XMM8
1330
1331        #######################################################################
1332
1333        vmovdqa         TMP3(%rsp), \T1
1334        vmovdqu         HashKey_6(arg2), \T5
1335        vpclmulqdq      $0x11, \T5, \T1, \T3
1336        vpxor           \T3, \T4, \T4
1337        vpclmulqdq      $0x00, \T5, \T1, \T3
1338        vpxor           \T3, \T7, \T7
1339
1340        vpshufd         $0b01001110, \T1, \T3
1341        vpxor           \T1, \T3, \T3
1342        vmovdqu         HashKey_6_k(arg2), \T5
1343        vpclmulqdq      $0x10, \T5, \T3, \T3
1344        vpxor           \T3, \T6, \T6
1345
1346                vmovdqu 16*5(arg1), \T1
1347                vaesenc \T1, \XMM1, \XMM1
1348                vaesenc \T1, \XMM2, \XMM2
1349                vaesenc \T1, \XMM3, \XMM3
1350                vaesenc \T1, \XMM4, \XMM4
1351                vaesenc \T1, \XMM5, \XMM5
1352                vaesenc \T1, \XMM6, \XMM6
1353                vaesenc \T1, \XMM7, \XMM7
1354                vaesenc \T1, \XMM8, \XMM8
1355
1356        vmovdqa         TMP4(%rsp), \T1
1357        vmovdqu         HashKey_5(arg2), \T5
1358        vpclmulqdq      $0x11, \T5, \T1, \T3
1359        vpxor           \T3, \T4, \T4
1360        vpclmulqdq      $0x00, \T5, \T1, \T3
1361        vpxor           \T3, \T7, \T7
1362
1363        vpshufd         $0b01001110, \T1, \T3
1364        vpxor           \T1, \T3, \T3
1365        vmovdqu         HashKey_5_k(arg2), \T5
1366        vpclmulqdq      $0x10, \T5, \T3, \T3
1367        vpxor           \T3, \T6, \T6
1368
1369                vmovdqu 16*6(arg1), \T1
1370                vaesenc \T1, \XMM1, \XMM1
1371                vaesenc \T1, \XMM2, \XMM2
1372                vaesenc \T1, \XMM3, \XMM3
1373                vaesenc \T1, \XMM4, \XMM4
1374                vaesenc \T1, \XMM5, \XMM5
1375                vaesenc \T1, \XMM6, \XMM6
1376                vaesenc \T1, \XMM7, \XMM7
1377                vaesenc \T1, \XMM8, \XMM8
1378
1379
1380        vmovdqa         TMP5(%rsp), \T1
1381        vmovdqu         HashKey_4(arg2), \T5
1382        vpclmulqdq      $0x11, \T5, \T1, \T3
1383        vpxor           \T3, \T4, \T4
1384        vpclmulqdq      $0x00, \T5, \T1, \T3
1385        vpxor           \T3, \T7, \T7
1386
1387        vpshufd         $0b01001110, \T1, \T3
1388        vpxor           \T1, \T3, \T3
1389        vmovdqu         HashKey_4_k(arg2), \T5
1390        vpclmulqdq      $0x10, \T5, \T3, \T3
1391        vpxor           \T3, \T6, \T6
1392
1393                vmovdqu 16*7(arg1), \T1
1394                vaesenc \T1, \XMM1, \XMM1
1395                vaesenc \T1, \XMM2, \XMM2
1396                vaesenc \T1, \XMM3, \XMM3
1397                vaesenc \T1, \XMM4, \XMM4
1398                vaesenc \T1, \XMM5, \XMM5
1399                vaesenc \T1, \XMM6, \XMM6
1400                vaesenc \T1, \XMM7, \XMM7
1401                vaesenc \T1, \XMM8, \XMM8
1402
1403        vmovdqa         TMP6(%rsp), \T1
1404        vmovdqu         HashKey_3(arg2), \T5
1405        vpclmulqdq      $0x11, \T5, \T1, \T3
1406        vpxor           \T3, \T4, \T4
1407        vpclmulqdq      $0x00, \T5, \T1, \T3
1408        vpxor           \T3, \T7, \T7
1409
1410        vpshufd         $0b01001110, \T1, \T3
1411        vpxor           \T1, \T3, \T3
1412        vmovdqu         HashKey_3_k(arg2), \T5
1413        vpclmulqdq      $0x10, \T5, \T3, \T3
1414        vpxor           \T3, \T6, \T6
1415
1416
1417                vmovdqu 16*8(arg1), \T1
1418                vaesenc \T1, \XMM1, \XMM1
1419                vaesenc \T1, \XMM2, \XMM2
1420                vaesenc \T1, \XMM3, \XMM3
1421                vaesenc \T1, \XMM4, \XMM4
1422                vaesenc \T1, \XMM5, \XMM5
1423                vaesenc \T1, \XMM6, \XMM6
1424                vaesenc \T1, \XMM7, \XMM7
1425                vaesenc \T1, \XMM8, \XMM8
1426
1427        vmovdqa         TMP7(%rsp), \T1
1428        vmovdqu         HashKey_2(arg2), \T5
1429        vpclmulqdq      $0x11, \T5, \T1, \T3
1430        vpxor           \T3, \T4, \T4
1431        vpclmulqdq      $0x00, \T5, \T1, \T3
1432        vpxor           \T3, \T7, \T7
1433
1434        vpshufd         $0b01001110, \T1, \T3
1435        vpxor           \T1, \T3, \T3
1436        vmovdqu         HashKey_2_k(arg2), \T5
1437        vpclmulqdq      $0x10, \T5, \T3, \T3
1438        vpxor           \T3, \T6, \T6
1439
1440        #######################################################################
1441
1442                vmovdqu 16*9(arg1), \T5
1443                vaesenc \T5, \XMM1, \XMM1
1444                vaesenc \T5, \XMM2, \XMM2
1445                vaesenc \T5, \XMM3, \XMM3
1446                vaesenc \T5, \XMM4, \XMM4
1447                vaesenc \T5, \XMM5, \XMM5
1448                vaesenc \T5, \XMM6, \XMM6
1449                vaesenc \T5, \XMM7, \XMM7
1450                vaesenc \T5, \XMM8, \XMM8
1451
1452        vmovdqa         TMP8(%rsp), \T1
1453        vmovdqu         HashKey(arg2), \T5
1454        vpclmulqdq      $0x11, \T5, \T1, \T3
1455        vpxor           \T3, \T4, \T4
1456        vpclmulqdq      $0x00, \T5, \T1, \T3
1457        vpxor           \T3, \T7, \T7
1458
1459        vpshufd         $0b01001110, \T1, \T3
1460        vpxor           \T1, \T3, \T3
1461        vmovdqu         HashKey_k(arg2), \T5
1462        vpclmulqdq      $0x10, \T5, \T3, \T3
1463        vpxor           \T3, \T6, \T6
1464
1465        vpxor           \T4, \T6, \T6
1466        vpxor           \T7, \T6, \T6
1467
1468                vmovdqu 16*10(arg1), \T5
1469
1470        i = 11
1471        setreg
1472.rep (\REP-9)
1473
1474        vaesenc \T5, \XMM1, \XMM1
1475        vaesenc \T5, \XMM2, \XMM2
1476        vaesenc \T5, \XMM3, \XMM3
1477        vaesenc \T5, \XMM4, \XMM4
1478        vaesenc \T5, \XMM5, \XMM5
1479        vaesenc \T5, \XMM6, \XMM6
1480        vaesenc \T5, \XMM7, \XMM7
1481        vaesenc \T5, \XMM8, \XMM8
1482
1483        vmovdqu 16*i(arg1), \T5
1484        i = i + 1
1485        setreg
1486.endr
1487
1488	i = 0
1489	j = 1
1490	setreg
1491.rep 8
1492		vpxor	16*i(arg4, %r11), \T5, \T2
1493                .if \ENC_DEC == ENC
1494                vaesenclast     \T2, reg_j, reg_j
1495                .else
1496                vaesenclast     \T2, reg_j, \T3
1497                vmovdqu 16*i(arg4, %r11), reg_j
1498                vmovdqu \T3, 16*i(arg3, %r11)
1499                .endif
1500	i = (i+1)
1501	j = (j+1)
1502	setreg
1503.endr
1504	#######################################################################
1505
1506
1507	vpslldq	$8, \T6, \T3				# shift-L T3 2 DWs
1508	vpsrldq	$8, \T6, \T6				# shift-R T2 2 DWs
1509	vpxor	\T3, \T7, \T7
1510	vpxor	\T4, \T6, \T6				# accumulate the results in T6:T7
1511
1512
1513
1514	#######################################################################
1515	#first phase of the reduction
1516	#######################################################################
1517        vpslld  $31, \T7, \T2                           # packed right shifting << 31
1518        vpslld  $30, \T7, \T3                           # packed right shifting shift << 30
1519        vpslld  $25, \T7, \T4                           # packed right shifting shift << 25
1520
1521        vpxor   \T3, \T2, \T2                           # xor the shifted versions
1522        vpxor   \T4, \T2, \T2
1523
1524        vpsrldq $4, \T2, \T1                            # shift-R T1 1 DW
1525
1526        vpslldq $12, \T2, \T2                           # shift-L T2 3 DWs
1527        vpxor   \T2, \T7, \T7                           # first phase of the reduction complete
1528	#######################################################################
1529                .if \ENC_DEC == ENC
1530		vmovdqu	 \XMM1,	16*0(arg3,%r11)		# Write to the Ciphertext buffer
1531		vmovdqu	 \XMM2,	16*1(arg3,%r11)		# Write to the Ciphertext buffer
1532		vmovdqu	 \XMM3,	16*2(arg3,%r11)		# Write to the Ciphertext buffer
1533		vmovdqu	 \XMM4,	16*3(arg3,%r11)		# Write to the Ciphertext buffer
1534		vmovdqu	 \XMM5,	16*4(arg3,%r11)		# Write to the Ciphertext buffer
1535		vmovdqu	 \XMM6,	16*5(arg3,%r11)		# Write to the Ciphertext buffer
1536		vmovdqu	 \XMM7,	16*6(arg3,%r11)		# Write to the Ciphertext buffer
1537		vmovdqu	 \XMM8,	16*7(arg3,%r11)		# Write to the Ciphertext buffer
1538                .endif
1539
1540	#######################################################################
1541	#second phase of the reduction
1542        vpsrld  $1, \T7, \T2                            # packed left shifting >> 1
1543        vpsrld  $2, \T7, \T3                            # packed left shifting >> 2
1544        vpsrld  $7, \T7, \T4                            # packed left shifting >> 7
1545        vpxor   \T3, \T2, \T2                           # xor the shifted versions
1546        vpxor   \T4, \T2, \T2
1547
1548        vpxor   \T1, \T2, \T2
1549        vpxor   \T2, \T7, \T7
1550        vpxor   \T7, \T6, \T6                           # the result is in T6
1551	#######################################################################
1552
1553		vpshufb	SHUF_MASK(%rip), \XMM1, \XMM1	# perform a 16Byte swap
1554		vpshufb	SHUF_MASK(%rip), \XMM2, \XMM2	# perform a 16Byte swap
1555		vpshufb	SHUF_MASK(%rip), \XMM3, \XMM3	# perform a 16Byte swap
1556		vpshufb	SHUF_MASK(%rip), \XMM4, \XMM4	# perform a 16Byte swap
1557		vpshufb	SHUF_MASK(%rip), \XMM5, \XMM5	# perform a 16Byte swap
1558		vpshufb	SHUF_MASK(%rip), \XMM6, \XMM6	# perform a 16Byte swap
1559		vpshufb	SHUF_MASK(%rip), \XMM7, \XMM7	# perform a 16Byte swap
1560		vpshufb	SHUF_MASK(%rip), \XMM8, \XMM8	# perform a 16Byte swap
1561
1562
1563	vpxor	\T6, \XMM1, \XMM1
1564
1565
1566
1567.endm
1568
1569
1570# GHASH the last 4 ciphertext blocks.
1571.macro  GHASH_LAST_8_AVX T1 T2 T3 T4 T5 T6 T7 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8
1572
1573        ## Karatsuba Method
1574
1575
1576        vpshufd         $0b01001110, \XMM1, \T2
1577        vpxor           \XMM1, \T2, \T2
1578        vmovdqu         HashKey_8(arg2), \T5
1579        vpclmulqdq      $0x11, \T5, \XMM1, \T6
1580        vpclmulqdq      $0x00, \T5, \XMM1, \T7
1581
1582        vmovdqu         HashKey_8_k(arg2), \T3
1583        vpclmulqdq      $0x00, \T3, \T2, \XMM1
1584
1585        ######################
1586
1587        vpshufd         $0b01001110, \XMM2, \T2
1588        vpxor           \XMM2, \T2, \T2
1589        vmovdqu         HashKey_7(arg2), \T5
1590        vpclmulqdq      $0x11, \T5, \XMM2, \T4
1591        vpxor           \T4, \T6, \T6
1592
1593        vpclmulqdq      $0x00, \T5, \XMM2, \T4
1594        vpxor           \T4, \T7, \T7
1595
1596        vmovdqu         HashKey_7_k(arg2), \T3
1597        vpclmulqdq      $0x00, \T3, \T2, \T2
1598        vpxor           \T2, \XMM1, \XMM1
1599
1600        ######################
1601
1602        vpshufd         $0b01001110, \XMM3, \T2
1603        vpxor           \XMM3, \T2, \T2
1604        vmovdqu         HashKey_6(arg2), \T5
1605        vpclmulqdq      $0x11, \T5, \XMM3, \T4
1606        vpxor           \T4, \T6, \T6
1607
1608        vpclmulqdq      $0x00, \T5, \XMM3, \T4
1609        vpxor           \T4, \T7, \T7
1610
1611        vmovdqu         HashKey_6_k(arg2), \T3
1612        vpclmulqdq      $0x00, \T3, \T2, \T2
1613        vpxor           \T2, \XMM1, \XMM1
1614
1615        ######################
1616
1617        vpshufd         $0b01001110, \XMM4, \T2
1618        vpxor           \XMM4, \T2, \T2
1619        vmovdqu         HashKey_5(arg2), \T5
1620        vpclmulqdq      $0x11, \T5, \XMM4, \T4
1621        vpxor           \T4, \T6, \T6
1622
1623        vpclmulqdq      $0x00, \T5, \XMM4, \T4
1624        vpxor           \T4, \T7, \T7
1625
1626        vmovdqu         HashKey_5_k(arg2), \T3
1627        vpclmulqdq      $0x00, \T3, \T2, \T2
1628        vpxor           \T2, \XMM1, \XMM1
1629
1630        ######################
1631
1632        vpshufd         $0b01001110, \XMM5, \T2
1633        vpxor           \XMM5, \T2, \T2
1634        vmovdqu         HashKey_4(arg2), \T5
1635        vpclmulqdq      $0x11, \T5, \XMM5, \T4
1636        vpxor           \T4, \T6, \T6
1637
1638        vpclmulqdq      $0x00, \T5, \XMM5, \T4
1639        vpxor           \T4, \T7, \T7
1640
1641        vmovdqu         HashKey_4_k(arg2), \T3
1642        vpclmulqdq      $0x00, \T3, \T2, \T2
1643        vpxor           \T2, \XMM1, \XMM1
1644
1645        ######################
1646
1647        vpshufd         $0b01001110, \XMM6, \T2
1648        vpxor           \XMM6, \T2, \T2
1649        vmovdqu         HashKey_3(arg2), \T5
1650        vpclmulqdq      $0x11, \T5, \XMM6, \T4
1651        vpxor           \T4, \T6, \T6
1652
1653        vpclmulqdq      $0x00, \T5, \XMM6, \T4
1654        vpxor           \T4, \T7, \T7
1655
1656        vmovdqu         HashKey_3_k(arg2), \T3
1657        vpclmulqdq      $0x00, \T3, \T2, \T2
1658        vpxor           \T2, \XMM1, \XMM1
1659
1660        ######################
1661
1662        vpshufd         $0b01001110, \XMM7, \T2
1663        vpxor           \XMM7, \T2, \T2
1664        vmovdqu         HashKey_2(arg2), \T5
1665        vpclmulqdq      $0x11, \T5, \XMM7, \T4
1666        vpxor           \T4, \T6, \T6
1667
1668        vpclmulqdq      $0x00, \T5, \XMM7, \T4
1669        vpxor           \T4, \T7, \T7
1670
1671        vmovdqu         HashKey_2_k(arg2), \T3
1672        vpclmulqdq      $0x00, \T3, \T2, \T2
1673        vpxor           \T2, \XMM1, \XMM1
1674
1675        ######################
1676
1677        vpshufd         $0b01001110, \XMM8, \T2
1678        vpxor           \XMM8, \T2, \T2
1679        vmovdqu         HashKey(arg2), \T5
1680        vpclmulqdq      $0x11, \T5, \XMM8, \T4
1681        vpxor           \T4, \T6, \T6
1682
1683        vpclmulqdq      $0x00, \T5, \XMM8, \T4
1684        vpxor           \T4, \T7, \T7
1685
1686        vmovdqu         HashKey_k(arg2), \T3
1687        vpclmulqdq      $0x00, \T3, \T2, \T2
1688
1689        vpxor           \T2, \XMM1, \XMM1
1690        vpxor           \T6, \XMM1, \XMM1
1691        vpxor           \T7, \XMM1, \T2
1692
1693
1694
1695
1696        vpslldq $8, \T2, \T4
1697        vpsrldq $8, \T2, \T2
1698
1699        vpxor   \T4, \T7, \T7
1700        vpxor   \T2, \T6, \T6   # <T6:T7> holds the result of
1701				# the accumulated carry-less multiplications
1702
1703        #######################################################################
1704        #first phase of the reduction
1705        vpslld  $31, \T7, \T2   # packed right shifting << 31
1706        vpslld  $30, \T7, \T3   # packed right shifting shift << 30
1707        vpslld  $25, \T7, \T4   # packed right shifting shift << 25
1708
1709        vpxor   \T3, \T2, \T2   # xor the shifted versions
1710        vpxor   \T4, \T2, \T2
1711
1712        vpsrldq $4, \T2, \T1    # shift-R T1 1 DW
1713
1714        vpslldq $12, \T2, \T2   # shift-L T2 3 DWs
1715        vpxor   \T2, \T7, \T7   # first phase of the reduction complete
1716        #######################################################################
1717
1718
1719        #second phase of the reduction
1720        vpsrld  $1, \T7, \T2    # packed left shifting >> 1
1721        vpsrld  $2, \T7, \T3    # packed left shifting >> 2
1722        vpsrld  $7, \T7, \T4    # packed left shifting >> 7
1723        vpxor   \T3, \T2, \T2   # xor the shifted versions
1724        vpxor   \T4, \T2, \T2
1725
1726        vpxor   \T1, \T2, \T2
1727        vpxor   \T2, \T7, \T7
1728        vpxor   \T7, \T6, \T6   # the result is in T6
1729
1730.endm
1731
1732#############################################################
1733#void   aesni_gcm_precomp_avx_gen2
1734#        (gcm_data     *my_ctx_data,
1735#         gcm_context_data *data,
1736#        u8     *hash_subkey# /* H, the Hash sub key input. Data starts on a 16-byte boundary. */
1737#        u8      *iv, /* Pre-counter block j0: 4 byte salt
1738#			(from Security Association) concatenated with 8 byte
1739#			Initialisation Vector (from IPSec ESP Payload)
1740#			concatenated with 0x00000001. 16-byte aligned pointer. */
1741#        const   u8 *aad, /* Additional Authentication Data (AAD)*/
1742#        u64     aad_len) /* Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 Bytes */
1743#############################################################
1744SYM_FUNC_START(aesni_gcm_init_avx_gen2)
1745        FUNC_SAVE
1746        INIT GHASH_MUL_AVX, PRECOMPUTE_AVX
1747        FUNC_RESTORE
1748        RET
1749SYM_FUNC_END(aesni_gcm_init_avx_gen2)
1750
1751###############################################################################
1752#void   aesni_gcm_enc_update_avx_gen2(
1753#        gcm_data        *my_ctx_data,     /* aligned to 16 Bytes */
1754#        gcm_context_data *data,
1755#        u8      *out, /* Ciphertext output. Encrypt in-place is allowed.  */
1756#        const   u8 *in, /* Plaintext input */
1757#        u64     plaintext_len) /* Length of data in Bytes for encryption. */
1758###############################################################################
1759SYM_FUNC_START(aesni_gcm_enc_update_avx_gen2)
1760        FUNC_SAVE
1761        mov     keysize, %eax
1762        cmp     $32, %eax
1763        je      key_256_enc_update
1764        cmp     $16, %eax
1765        je      key_128_enc_update
1766        # must be 192
1767        GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, ENC, 11
1768        FUNC_RESTORE
1769        RET
1770key_128_enc_update:
1771        GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, ENC, 9
1772        FUNC_RESTORE
1773        RET
1774key_256_enc_update:
1775        GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, ENC, 13
1776        FUNC_RESTORE
1777        RET
1778SYM_FUNC_END(aesni_gcm_enc_update_avx_gen2)
1779
1780###############################################################################
1781#void   aesni_gcm_dec_update_avx_gen2(
1782#        gcm_data        *my_ctx_data,     /* aligned to 16 Bytes */
1783#        gcm_context_data *data,
1784#        u8      *out, /* Plaintext output. Decrypt in-place is allowed.  */
1785#        const   u8 *in, /* Ciphertext input */
1786#        u64     plaintext_len) /* Length of data in Bytes for encryption. */
1787###############################################################################
1788SYM_FUNC_START(aesni_gcm_dec_update_avx_gen2)
1789        FUNC_SAVE
1790        mov     keysize,%eax
1791        cmp     $32, %eax
1792        je      key_256_dec_update
1793        cmp     $16, %eax
1794        je      key_128_dec_update
1795        # must be 192
1796        GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, DEC, 11
1797        FUNC_RESTORE
1798        RET
1799key_128_dec_update:
1800        GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, DEC, 9
1801        FUNC_RESTORE
1802        RET
1803key_256_dec_update:
1804        GCM_ENC_DEC INITIAL_BLOCKS_AVX, GHASH_8_ENCRYPT_8_PARALLEL_AVX, GHASH_LAST_8_AVX, GHASH_MUL_AVX, DEC, 13
1805        FUNC_RESTORE
1806        RET
1807SYM_FUNC_END(aesni_gcm_dec_update_avx_gen2)
1808
1809###############################################################################
1810#void   aesni_gcm_finalize_avx_gen2(
1811#        gcm_data        *my_ctx_data,     /* aligned to 16 Bytes */
1812#        gcm_context_data *data,
1813#        u8      *auth_tag, /* Authenticated Tag output. */
1814#        u64     auth_tag_len)# /* Authenticated Tag Length in bytes.
1815#				Valid values are 16 (most likely), 12 or 8. */
1816###############################################################################
1817SYM_FUNC_START(aesni_gcm_finalize_avx_gen2)
1818        FUNC_SAVE
1819        mov	keysize,%eax
1820        cmp     $32, %eax
1821        je      key_256_finalize
1822        cmp     $16, %eax
1823        je      key_128_finalize
1824        # must be 192
1825        GCM_COMPLETE GHASH_MUL_AVX, 11, arg3, arg4
1826        FUNC_RESTORE
1827        RET
1828key_128_finalize:
1829        GCM_COMPLETE GHASH_MUL_AVX, 9, arg3, arg4
1830        FUNC_RESTORE
1831        RET
1832key_256_finalize:
1833        GCM_COMPLETE GHASH_MUL_AVX, 13, arg3, arg4
1834        FUNC_RESTORE
1835        RET
1836SYM_FUNC_END(aesni_gcm_finalize_avx_gen2)
1837
1838###############################################################################
1839# GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0)
1840# Input: A and B (128-bits each, bit-reflected)
1841# Output: C = A*B*x mod poly, (i.e. >>1 )
1842# To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input
1843# GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly.
1844###############################################################################
1845.macro  GHASH_MUL_AVX2 GH HK T1 T2 T3 T4 T5
1846
1847        vpclmulqdq      $0x11,\HK,\GH,\T1      # T1 = a1*b1
1848        vpclmulqdq      $0x00,\HK,\GH,\T2      # T2 = a0*b0
1849        vpclmulqdq      $0x01,\HK,\GH,\T3      # T3 = a1*b0
1850        vpclmulqdq      $0x10,\HK,\GH,\GH      # GH = a0*b1
1851        vpxor           \T3, \GH, \GH
1852
1853
1854        vpsrldq         $8 , \GH, \T3          # shift-R GH 2 DWs
1855        vpslldq         $8 , \GH, \GH          # shift-L GH 2 DWs
1856
1857        vpxor           \T3, \T1, \T1
1858        vpxor           \T2, \GH, \GH
1859
1860        #######################################################################
1861        #first phase of the reduction
1862        vmovdqa         POLY2(%rip), \T3
1863
1864        vpclmulqdq      $0x01, \GH, \T3, \T2
1865        vpslldq         $8, \T2, \T2           # shift-L T2 2 DWs
1866
1867        vpxor           \T2, \GH, \GH          # first phase of the reduction complete
1868        #######################################################################
1869        #second phase of the reduction
1870        vpclmulqdq      $0x00, \GH, \T3, \T2
1871        vpsrldq         $4, \T2, \T2           # shift-R T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
1872
1873        vpclmulqdq      $0x10, \GH, \T3, \GH
1874        vpslldq         $4, \GH, \GH           # shift-L GH 1 DW (Shift-L 1-DW to obtain result with no shifts)
1875
1876        vpxor           \T2, \GH, \GH          # second phase of the reduction complete
1877        #######################################################################
1878        vpxor           \T1, \GH, \GH          # the result is in GH
1879
1880
1881.endm
1882
1883.macro PRECOMPUTE_AVX2 HK T1 T2 T3 T4 T5 T6
1884
1885        # Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
1886        vmovdqa  \HK, \T5
1887        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^2<<1 mod poly
1888        vmovdqu  \T5, HashKey_2(arg2)                       #  [HashKey_2] = HashKey^2<<1 mod poly
1889
1890        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^3<<1 mod poly
1891        vmovdqu  \T5, HashKey_3(arg2)
1892
1893        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^4<<1 mod poly
1894        vmovdqu  \T5, HashKey_4(arg2)
1895
1896        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^5<<1 mod poly
1897        vmovdqu  \T5, HashKey_5(arg2)
1898
1899        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^6<<1 mod poly
1900        vmovdqu  \T5, HashKey_6(arg2)
1901
1902        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^7<<1 mod poly
1903        vmovdqu  \T5, HashKey_7(arg2)
1904
1905        GHASH_MUL_AVX2 \T5, \HK, \T1, \T3, \T4, \T6, \T2    #  T5 = HashKey^8<<1 mod poly
1906        vmovdqu  \T5, HashKey_8(arg2)
1907
1908.endm
1909
1910## if a = number of total plaintext bytes
1911## b = floor(a/16)
1912## num_initial_blocks = b mod 4#
1913## encrypt the initial num_initial_blocks blocks and apply ghash on the ciphertext
1914## r10, r11, r12, rax are clobbered
1915## arg1, arg2, arg3, arg4 are used as pointers only, not modified
1916
1917.macro INITIAL_BLOCKS_AVX2 REP num_initial_blocks T1 T2 T3 T4 T5 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T6 T_key ENC_DEC VER
1918	i = (8-\num_initial_blocks)
1919	setreg
1920	vmovdqu AadHash(arg2), reg_i
1921
1922	# start AES for num_initial_blocks blocks
1923	vmovdqu CurCount(arg2), \CTR
1924
1925	i = (9-\num_initial_blocks)
1926	setreg
1927.rep \num_initial_blocks
1928                vpaddd  ONE(%rip), \CTR, \CTR   # INCR Y0
1929                vmovdqa \CTR, reg_i
1930                vpshufb SHUF_MASK(%rip), reg_i, reg_i     # perform a 16Byte swap
1931	i = (i+1)
1932	setreg
1933.endr
1934
1935	vmovdqa  (arg1), \T_key
1936	i = (9-\num_initial_blocks)
1937	setreg
1938.rep \num_initial_blocks
1939                vpxor   \T_key, reg_i, reg_i
1940	i = (i+1)
1941	setreg
1942.endr
1943
1944	j = 1
1945	setreg
1946.rep \REP
1947	vmovdqa  16*j(arg1), \T_key
1948	i = (9-\num_initial_blocks)
1949	setreg
1950.rep \num_initial_blocks
1951        vaesenc \T_key, reg_i, reg_i
1952	i = (i+1)
1953	setreg
1954.endr
1955
1956	j = (j+1)
1957	setreg
1958.endr
1959
1960
1961	vmovdqa  16*j(arg1), \T_key
1962	i = (9-\num_initial_blocks)
1963	setreg
1964.rep \num_initial_blocks
1965        vaesenclast      \T_key, reg_i, reg_i
1966	i = (i+1)
1967	setreg
1968.endr
1969
1970	i = (9-\num_initial_blocks)
1971	setreg
1972.rep \num_initial_blocks
1973                vmovdqu (arg4, %r11), \T1
1974                vpxor   \T1, reg_i, reg_i
1975                vmovdqu reg_i, (arg3 , %r11)           # write back ciphertext for
1976						       # num_initial_blocks blocks
1977                add     $16, %r11
1978.if  \ENC_DEC == DEC
1979                vmovdqa \T1, reg_i
1980.endif
1981                vpshufb SHUF_MASK(%rip), reg_i, reg_i  # prepare ciphertext for GHASH computations
1982	i = (i+1)
1983	setreg
1984.endr
1985
1986
1987	i = (8-\num_initial_blocks)
1988	j = (9-\num_initial_blocks)
1989	setreg
1990
1991.rep \num_initial_blocks
1992        vpxor    reg_i, reg_j, reg_j
1993        GHASH_MUL_AVX2       reg_j, \T2, \T1, \T3, \T4, \T5, \T6  # apply GHASH on num_initial_blocks blocks
1994	i = (i+1)
1995	j = (j+1)
1996	setreg
1997.endr
1998        # XMM8 has the combined result here
1999
2000        vmovdqa  \XMM8, TMP1(%rsp)
2001        vmovdqa  \XMM8, \T3
2002
2003        cmp     $128, %r13
2004        jl      .L_initial_blocks_done\@                  # no need for precomputed constants
2005
2006###############################################################################
2007# Haskey_i_k holds XORed values of the low and high parts of the Haskey_i
2008                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2009                vmovdqa  \CTR, \XMM1
2010                vpshufb  SHUF_MASK(%rip), \XMM1, \XMM1  # perform a 16Byte swap
2011
2012                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2013                vmovdqa  \CTR, \XMM2
2014                vpshufb  SHUF_MASK(%rip), \XMM2, \XMM2  # perform a 16Byte swap
2015
2016                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2017                vmovdqa  \CTR, \XMM3
2018                vpshufb  SHUF_MASK(%rip), \XMM3, \XMM3  # perform a 16Byte swap
2019
2020                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2021                vmovdqa  \CTR, \XMM4
2022                vpshufb  SHUF_MASK(%rip), \XMM4, \XMM4  # perform a 16Byte swap
2023
2024                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2025                vmovdqa  \CTR, \XMM5
2026                vpshufb  SHUF_MASK(%rip), \XMM5, \XMM5  # perform a 16Byte swap
2027
2028                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2029                vmovdqa  \CTR, \XMM6
2030                vpshufb  SHUF_MASK(%rip), \XMM6, \XMM6  # perform a 16Byte swap
2031
2032                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2033                vmovdqa  \CTR, \XMM7
2034                vpshufb  SHUF_MASK(%rip), \XMM7, \XMM7  # perform a 16Byte swap
2035
2036                vpaddd   ONE(%rip), \CTR, \CTR          # INCR Y0
2037                vmovdqa  \CTR, \XMM8
2038                vpshufb  SHUF_MASK(%rip), \XMM8, \XMM8  # perform a 16Byte swap
2039
2040                vmovdqa  (arg1), \T_key
2041                vpxor    \T_key, \XMM1, \XMM1
2042                vpxor    \T_key, \XMM2, \XMM2
2043                vpxor    \T_key, \XMM3, \XMM3
2044                vpxor    \T_key, \XMM4, \XMM4
2045                vpxor    \T_key, \XMM5, \XMM5
2046                vpxor    \T_key, \XMM6, \XMM6
2047                vpxor    \T_key, \XMM7, \XMM7
2048                vpxor    \T_key, \XMM8, \XMM8
2049
2050		i = 1
2051		setreg
2052.rep    \REP       # do REP rounds
2053                vmovdqa  16*i(arg1), \T_key
2054                vaesenc  \T_key, \XMM1, \XMM1
2055                vaesenc  \T_key, \XMM2, \XMM2
2056                vaesenc  \T_key, \XMM3, \XMM3
2057                vaesenc  \T_key, \XMM4, \XMM4
2058                vaesenc  \T_key, \XMM5, \XMM5
2059                vaesenc  \T_key, \XMM6, \XMM6
2060                vaesenc  \T_key, \XMM7, \XMM7
2061                vaesenc  \T_key, \XMM8, \XMM8
2062		i = (i+1)
2063		setreg
2064.endr
2065
2066
2067                vmovdqa  16*i(arg1), \T_key
2068                vaesenclast  \T_key, \XMM1, \XMM1
2069                vaesenclast  \T_key, \XMM2, \XMM2
2070                vaesenclast  \T_key, \XMM3, \XMM3
2071                vaesenclast  \T_key, \XMM4, \XMM4
2072                vaesenclast  \T_key, \XMM5, \XMM5
2073                vaesenclast  \T_key, \XMM6, \XMM6
2074                vaesenclast  \T_key, \XMM7, \XMM7
2075                vaesenclast  \T_key, \XMM8, \XMM8
2076
2077                vmovdqu  (arg4, %r11), \T1
2078                vpxor    \T1, \XMM1, \XMM1
2079                vmovdqu  \XMM1, (arg3 , %r11)
2080                .if   \ENC_DEC == DEC
2081                vmovdqa  \T1, \XMM1
2082                .endif
2083
2084                vmovdqu  16*1(arg4, %r11), \T1
2085                vpxor    \T1, \XMM2, \XMM2
2086                vmovdqu  \XMM2, 16*1(arg3 , %r11)
2087                .if   \ENC_DEC == DEC
2088                vmovdqa  \T1, \XMM2
2089                .endif
2090
2091                vmovdqu  16*2(arg4, %r11), \T1
2092                vpxor    \T1, \XMM3, \XMM3
2093                vmovdqu  \XMM3, 16*2(arg3 , %r11)
2094                .if   \ENC_DEC == DEC
2095                vmovdqa  \T1, \XMM3
2096                .endif
2097
2098                vmovdqu  16*3(arg4, %r11), \T1
2099                vpxor    \T1, \XMM4, \XMM4
2100                vmovdqu  \XMM4, 16*3(arg3 , %r11)
2101                .if   \ENC_DEC == DEC
2102                vmovdqa  \T1, \XMM4
2103                .endif
2104
2105                vmovdqu  16*4(arg4, %r11), \T1
2106                vpxor    \T1, \XMM5, \XMM5
2107                vmovdqu  \XMM5, 16*4(arg3 , %r11)
2108                .if   \ENC_DEC == DEC
2109                vmovdqa  \T1, \XMM5
2110                .endif
2111
2112                vmovdqu  16*5(arg4, %r11), \T1
2113                vpxor    \T1, \XMM6, \XMM6
2114                vmovdqu  \XMM6, 16*5(arg3 , %r11)
2115                .if   \ENC_DEC == DEC
2116                vmovdqa  \T1, \XMM6
2117                .endif
2118
2119                vmovdqu  16*6(arg4, %r11), \T1
2120                vpxor    \T1, \XMM7, \XMM7
2121                vmovdqu  \XMM7, 16*6(arg3 , %r11)
2122                .if   \ENC_DEC == DEC
2123                vmovdqa  \T1, \XMM7
2124                .endif
2125
2126                vmovdqu  16*7(arg4, %r11), \T1
2127                vpxor    \T1, \XMM8, \XMM8
2128                vmovdqu  \XMM8, 16*7(arg3 , %r11)
2129                .if   \ENC_DEC == DEC
2130                vmovdqa  \T1, \XMM8
2131                .endif
2132
2133                add     $128, %r11
2134
2135                vpshufb  SHUF_MASK(%rip), \XMM1, \XMM1     # perform a 16Byte swap
2136                vpxor    TMP1(%rsp), \XMM1, \XMM1          # combine GHASHed value with
2137							   # the corresponding ciphertext
2138                vpshufb  SHUF_MASK(%rip), \XMM2, \XMM2     # perform a 16Byte swap
2139                vpshufb  SHUF_MASK(%rip), \XMM3, \XMM3     # perform a 16Byte swap
2140                vpshufb  SHUF_MASK(%rip), \XMM4, \XMM4     # perform a 16Byte swap
2141                vpshufb  SHUF_MASK(%rip), \XMM5, \XMM5     # perform a 16Byte swap
2142                vpshufb  SHUF_MASK(%rip), \XMM6, \XMM6     # perform a 16Byte swap
2143                vpshufb  SHUF_MASK(%rip), \XMM7, \XMM7     # perform a 16Byte swap
2144                vpshufb  SHUF_MASK(%rip), \XMM8, \XMM8     # perform a 16Byte swap
2145
2146###############################################################################
2147
2148.L_initial_blocks_done\@:
2149
2150
2151.endm
2152
2153
2154
2155# encrypt 8 blocks at a time
2156# ghash the 8 previously encrypted ciphertext blocks
2157# arg1, arg2, arg3, arg4 are used as pointers only, not modified
2158# r11 is the data offset value
2159.macro GHASH_8_ENCRYPT_8_PARALLEL_AVX2 REP T1 T2 T3 T4 T5 T6 CTR XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 T7 loop_idx ENC_DEC
2160
2161        vmovdqa \XMM1, \T2
2162        vmovdqa \XMM2, TMP2(%rsp)
2163        vmovdqa \XMM3, TMP3(%rsp)
2164        vmovdqa \XMM4, TMP4(%rsp)
2165        vmovdqa \XMM5, TMP5(%rsp)
2166        vmovdqa \XMM6, TMP6(%rsp)
2167        vmovdqa \XMM7, TMP7(%rsp)
2168        vmovdqa \XMM8, TMP8(%rsp)
2169
2170.if \loop_idx == in_order
2171                vpaddd  ONE(%rip), \CTR, \XMM1            # INCR CNT
2172                vpaddd  ONE(%rip), \XMM1, \XMM2
2173                vpaddd  ONE(%rip), \XMM2, \XMM3
2174                vpaddd  ONE(%rip), \XMM3, \XMM4
2175                vpaddd  ONE(%rip), \XMM4, \XMM5
2176                vpaddd  ONE(%rip), \XMM5, \XMM6
2177                vpaddd  ONE(%rip), \XMM6, \XMM7
2178                vpaddd  ONE(%rip), \XMM7, \XMM8
2179                vmovdqa \XMM8, \CTR
2180
2181                vpshufb SHUF_MASK(%rip), \XMM1, \XMM1     # perform a 16Byte swap
2182                vpshufb SHUF_MASK(%rip), \XMM2, \XMM2     # perform a 16Byte swap
2183                vpshufb SHUF_MASK(%rip), \XMM3, \XMM3     # perform a 16Byte swap
2184                vpshufb SHUF_MASK(%rip), \XMM4, \XMM4     # perform a 16Byte swap
2185                vpshufb SHUF_MASK(%rip), \XMM5, \XMM5     # perform a 16Byte swap
2186                vpshufb SHUF_MASK(%rip), \XMM6, \XMM6     # perform a 16Byte swap
2187                vpshufb SHUF_MASK(%rip), \XMM7, \XMM7     # perform a 16Byte swap
2188                vpshufb SHUF_MASK(%rip), \XMM8, \XMM8     # perform a 16Byte swap
2189.else
2190                vpaddd  ONEf(%rip), \CTR, \XMM1            # INCR CNT
2191                vpaddd  ONEf(%rip), \XMM1, \XMM2
2192                vpaddd  ONEf(%rip), \XMM2, \XMM3
2193                vpaddd  ONEf(%rip), \XMM3, \XMM4
2194                vpaddd  ONEf(%rip), \XMM4, \XMM5
2195                vpaddd  ONEf(%rip), \XMM5, \XMM6
2196                vpaddd  ONEf(%rip), \XMM6, \XMM7
2197                vpaddd  ONEf(%rip), \XMM7, \XMM8
2198                vmovdqa \XMM8, \CTR
2199.endif
2200
2201
2202        #######################################################################
2203
2204                vmovdqu (arg1), \T1
2205                vpxor   \T1, \XMM1, \XMM1
2206                vpxor   \T1, \XMM2, \XMM2
2207                vpxor   \T1, \XMM3, \XMM3
2208                vpxor   \T1, \XMM4, \XMM4
2209                vpxor   \T1, \XMM5, \XMM5
2210                vpxor   \T1, \XMM6, \XMM6
2211                vpxor   \T1, \XMM7, \XMM7
2212                vpxor   \T1, \XMM8, \XMM8
2213
2214        #######################################################################
2215
2216
2217
2218
2219
2220                vmovdqu 16*1(arg1), \T1
2221                vaesenc \T1, \XMM1, \XMM1
2222                vaesenc \T1, \XMM2, \XMM2
2223                vaesenc \T1, \XMM3, \XMM3
2224                vaesenc \T1, \XMM4, \XMM4
2225                vaesenc \T1, \XMM5, \XMM5
2226                vaesenc \T1, \XMM6, \XMM6
2227                vaesenc \T1, \XMM7, \XMM7
2228                vaesenc \T1, \XMM8, \XMM8
2229
2230                vmovdqu 16*2(arg1), \T1
2231                vaesenc \T1, \XMM1, \XMM1
2232                vaesenc \T1, \XMM2, \XMM2
2233                vaesenc \T1, \XMM3, \XMM3
2234                vaesenc \T1, \XMM4, \XMM4
2235                vaesenc \T1, \XMM5, \XMM5
2236                vaesenc \T1, \XMM6, \XMM6
2237                vaesenc \T1, \XMM7, \XMM7
2238                vaesenc \T1, \XMM8, \XMM8
2239
2240
2241        #######################################################################
2242
2243        vmovdqu         HashKey_8(arg2), \T5
2244        vpclmulqdq      $0x11, \T5, \T2, \T4              # T4 = a1*b1
2245        vpclmulqdq      $0x00, \T5, \T2, \T7              # T7 = a0*b0
2246        vpclmulqdq      $0x01, \T5, \T2, \T6              # T6 = a1*b0
2247        vpclmulqdq      $0x10, \T5, \T2, \T5              # T5 = a0*b1
2248        vpxor           \T5, \T6, \T6
2249
2250                vmovdqu 16*3(arg1), \T1
2251                vaesenc \T1, \XMM1, \XMM1
2252                vaesenc \T1, \XMM2, \XMM2
2253                vaesenc \T1, \XMM3, \XMM3
2254                vaesenc \T1, \XMM4, \XMM4
2255                vaesenc \T1, \XMM5, \XMM5
2256                vaesenc \T1, \XMM6, \XMM6
2257                vaesenc \T1, \XMM7, \XMM7
2258                vaesenc \T1, \XMM8, \XMM8
2259
2260        vmovdqa         TMP2(%rsp), \T1
2261        vmovdqu         HashKey_7(arg2), \T5
2262        vpclmulqdq      $0x11, \T5, \T1, \T3
2263        vpxor           \T3, \T4, \T4
2264
2265        vpclmulqdq      $0x00, \T5, \T1, \T3
2266        vpxor           \T3, \T7, \T7
2267
2268        vpclmulqdq      $0x01, \T5, \T1, \T3
2269        vpxor           \T3, \T6, \T6
2270
2271        vpclmulqdq      $0x10, \T5, \T1, \T3
2272        vpxor           \T3, \T6, \T6
2273
2274                vmovdqu 16*4(arg1), \T1
2275                vaesenc \T1, \XMM1, \XMM1
2276                vaesenc \T1, \XMM2, \XMM2
2277                vaesenc \T1, \XMM3, \XMM3
2278                vaesenc \T1, \XMM4, \XMM4
2279                vaesenc \T1, \XMM5, \XMM5
2280                vaesenc \T1, \XMM6, \XMM6
2281                vaesenc \T1, \XMM7, \XMM7
2282                vaesenc \T1, \XMM8, \XMM8
2283
2284        #######################################################################
2285
2286        vmovdqa         TMP3(%rsp), \T1
2287        vmovdqu         HashKey_6(arg2), \T5
2288        vpclmulqdq      $0x11, \T5, \T1, \T3
2289        vpxor           \T3, \T4, \T4
2290
2291        vpclmulqdq      $0x00, \T5, \T1, \T3
2292        vpxor           \T3, \T7, \T7
2293
2294        vpclmulqdq      $0x01, \T5, \T1, \T3
2295        vpxor           \T3, \T6, \T6
2296
2297        vpclmulqdq      $0x10, \T5, \T1, \T3
2298        vpxor           \T3, \T6, \T6
2299
2300                vmovdqu 16*5(arg1), \T1
2301                vaesenc \T1, \XMM1, \XMM1
2302                vaesenc \T1, \XMM2, \XMM2
2303                vaesenc \T1, \XMM3, \XMM3
2304                vaesenc \T1, \XMM4, \XMM4
2305                vaesenc \T1, \XMM5, \XMM5
2306                vaesenc \T1, \XMM6, \XMM6
2307                vaesenc \T1, \XMM7, \XMM7
2308                vaesenc \T1, \XMM8, \XMM8
2309
2310        vmovdqa         TMP4(%rsp), \T1
2311        vmovdqu         HashKey_5(arg2), \T5
2312        vpclmulqdq      $0x11, \T5, \T1, \T3
2313        vpxor           \T3, \T4, \T4
2314
2315        vpclmulqdq      $0x00, \T5, \T1, \T3
2316        vpxor           \T3, \T7, \T7
2317
2318        vpclmulqdq      $0x01, \T5, \T1, \T3
2319        vpxor           \T3, \T6, \T6
2320
2321        vpclmulqdq      $0x10, \T5, \T1, \T3
2322        vpxor           \T3, \T6, \T6
2323
2324                vmovdqu 16*6(arg1), \T1
2325                vaesenc \T1, \XMM1, \XMM1
2326                vaesenc \T1, \XMM2, \XMM2
2327                vaesenc \T1, \XMM3, \XMM3
2328                vaesenc \T1, \XMM4, \XMM4
2329                vaesenc \T1, \XMM5, \XMM5
2330                vaesenc \T1, \XMM6, \XMM6
2331                vaesenc \T1, \XMM7, \XMM7
2332                vaesenc \T1, \XMM8, \XMM8
2333
2334
2335        vmovdqa         TMP5(%rsp), \T1
2336        vmovdqu         HashKey_4(arg2), \T5
2337        vpclmulqdq      $0x11, \T5, \T1, \T3
2338        vpxor           \T3, \T4, \T4
2339
2340        vpclmulqdq      $0x00, \T5, \T1, \T3
2341        vpxor           \T3, \T7, \T7
2342
2343        vpclmulqdq      $0x01, \T5, \T1, \T3
2344        vpxor           \T3, \T6, \T6
2345
2346        vpclmulqdq      $0x10, \T5, \T1, \T3
2347        vpxor           \T3, \T6, \T6
2348
2349                vmovdqu 16*7(arg1), \T1
2350                vaesenc \T1, \XMM1, \XMM1
2351                vaesenc \T1, \XMM2, \XMM2
2352                vaesenc \T1, \XMM3, \XMM3
2353                vaesenc \T1, \XMM4, \XMM4
2354                vaesenc \T1, \XMM5, \XMM5
2355                vaesenc \T1, \XMM6, \XMM6
2356                vaesenc \T1, \XMM7, \XMM7
2357                vaesenc \T1, \XMM8, \XMM8
2358
2359        vmovdqa         TMP6(%rsp), \T1
2360        vmovdqu         HashKey_3(arg2), \T5
2361        vpclmulqdq      $0x11, \T5, \T1, \T3
2362        vpxor           \T3, \T4, \T4
2363
2364        vpclmulqdq      $0x00, \T5, \T1, \T3
2365        vpxor           \T3, \T7, \T7
2366
2367        vpclmulqdq      $0x01, \T5, \T1, \T3
2368        vpxor           \T3, \T6, \T6
2369
2370        vpclmulqdq      $0x10, \T5, \T1, \T3
2371        vpxor           \T3, \T6, \T6
2372
2373                vmovdqu 16*8(arg1), \T1
2374                vaesenc \T1, \XMM1, \XMM1
2375                vaesenc \T1, \XMM2, \XMM2
2376                vaesenc \T1, \XMM3, \XMM3
2377                vaesenc \T1, \XMM4, \XMM4
2378                vaesenc \T1, \XMM5, \XMM5
2379                vaesenc \T1, \XMM6, \XMM6
2380                vaesenc \T1, \XMM7, \XMM7
2381                vaesenc \T1, \XMM8, \XMM8
2382
2383        vmovdqa         TMP7(%rsp), \T1
2384        vmovdqu         HashKey_2(arg2), \T5
2385        vpclmulqdq      $0x11, \T5, \T1, \T3
2386        vpxor           \T3, \T4, \T4
2387
2388        vpclmulqdq      $0x00, \T5, \T1, \T3
2389        vpxor           \T3, \T7, \T7
2390
2391        vpclmulqdq      $0x01, \T5, \T1, \T3
2392        vpxor           \T3, \T6, \T6
2393
2394        vpclmulqdq      $0x10, \T5, \T1, \T3
2395        vpxor           \T3, \T6, \T6
2396
2397
2398        #######################################################################
2399
2400                vmovdqu 16*9(arg1), \T5
2401                vaesenc \T5, \XMM1, \XMM1
2402                vaesenc \T5, \XMM2, \XMM2
2403                vaesenc \T5, \XMM3, \XMM3
2404                vaesenc \T5, \XMM4, \XMM4
2405                vaesenc \T5, \XMM5, \XMM5
2406                vaesenc \T5, \XMM6, \XMM6
2407                vaesenc \T5, \XMM7, \XMM7
2408                vaesenc \T5, \XMM8, \XMM8
2409
2410        vmovdqa         TMP8(%rsp), \T1
2411        vmovdqu         HashKey(arg2), \T5
2412
2413        vpclmulqdq      $0x00, \T5, \T1, \T3
2414        vpxor           \T3, \T7, \T7
2415
2416        vpclmulqdq      $0x01, \T5, \T1, \T3
2417        vpxor           \T3, \T6, \T6
2418
2419        vpclmulqdq      $0x10, \T5, \T1, \T3
2420        vpxor           \T3, \T6, \T6
2421
2422        vpclmulqdq      $0x11, \T5, \T1, \T3
2423        vpxor           \T3, \T4, \T1
2424
2425
2426                vmovdqu 16*10(arg1), \T5
2427
2428        i = 11
2429        setreg
2430.rep (\REP-9)
2431        vaesenc \T5, \XMM1, \XMM1
2432        vaesenc \T5, \XMM2, \XMM2
2433        vaesenc \T5, \XMM3, \XMM3
2434        vaesenc \T5, \XMM4, \XMM4
2435        vaesenc \T5, \XMM5, \XMM5
2436        vaesenc \T5, \XMM6, \XMM6
2437        vaesenc \T5, \XMM7, \XMM7
2438        vaesenc \T5, \XMM8, \XMM8
2439
2440        vmovdqu 16*i(arg1), \T5
2441        i = i + 1
2442        setreg
2443.endr
2444
2445	i = 0
2446	j = 1
2447	setreg
2448.rep 8
2449		vpxor	16*i(arg4, %r11), \T5, \T2
2450                .if \ENC_DEC == ENC
2451                vaesenclast     \T2, reg_j, reg_j
2452                .else
2453                vaesenclast     \T2, reg_j, \T3
2454                vmovdqu 16*i(arg4, %r11), reg_j
2455                vmovdqu \T3, 16*i(arg3, %r11)
2456                .endif
2457	i = (i+1)
2458	j = (j+1)
2459	setreg
2460.endr
2461	#######################################################################
2462
2463
2464	vpslldq	$8, \T6, \T3				# shift-L T3 2 DWs
2465	vpsrldq	$8, \T6, \T6				# shift-R T2 2 DWs
2466	vpxor	\T3, \T7, \T7
2467	vpxor	\T6, \T1, \T1				# accumulate the results in T1:T7
2468
2469
2470
2471	#######################################################################
2472	#first phase of the reduction
2473	vmovdqa         POLY2(%rip), \T3
2474
2475	vpclmulqdq	$0x01, \T7, \T3, \T2
2476	vpslldq		$8, \T2, \T2			# shift-L xmm2 2 DWs
2477
2478	vpxor		\T2, \T7, \T7			# first phase of the reduction complete
2479	#######################################################################
2480                .if \ENC_DEC == ENC
2481		vmovdqu	 \XMM1,	16*0(arg3,%r11)		# Write to the Ciphertext buffer
2482		vmovdqu	 \XMM2,	16*1(arg3,%r11)		# Write to the Ciphertext buffer
2483		vmovdqu	 \XMM3,	16*2(arg3,%r11)		# Write to the Ciphertext buffer
2484		vmovdqu	 \XMM4,	16*3(arg3,%r11)		# Write to the Ciphertext buffer
2485		vmovdqu	 \XMM5,	16*4(arg3,%r11)		# Write to the Ciphertext buffer
2486		vmovdqu	 \XMM6,	16*5(arg3,%r11)		# Write to the Ciphertext buffer
2487		vmovdqu	 \XMM7,	16*6(arg3,%r11)		# Write to the Ciphertext buffer
2488		vmovdqu	 \XMM8,	16*7(arg3,%r11)		# Write to the Ciphertext buffer
2489                .endif
2490
2491	#######################################################################
2492	#second phase of the reduction
2493	vpclmulqdq	$0x00, \T7, \T3, \T2
2494	vpsrldq		$4, \T2, \T2			# shift-R xmm2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
2495
2496	vpclmulqdq	$0x10, \T7, \T3, \T4
2497	vpslldq		$4, \T4, \T4			# shift-L xmm0 1 DW (Shift-L 1-DW to obtain result with no shifts)
2498
2499	vpxor		\T2, \T4, \T4			# second phase of the reduction complete
2500	#######################################################################
2501	vpxor		\T4, \T1, \T1			# the result is in T1
2502
2503		vpshufb	SHUF_MASK(%rip), \XMM1, \XMM1	# perform a 16Byte swap
2504		vpshufb	SHUF_MASK(%rip), \XMM2, \XMM2	# perform a 16Byte swap
2505		vpshufb	SHUF_MASK(%rip), \XMM3, \XMM3	# perform a 16Byte swap
2506		vpshufb	SHUF_MASK(%rip), \XMM4, \XMM4	# perform a 16Byte swap
2507		vpshufb	SHUF_MASK(%rip), \XMM5, \XMM5	# perform a 16Byte swap
2508		vpshufb	SHUF_MASK(%rip), \XMM6, \XMM6	# perform a 16Byte swap
2509		vpshufb	SHUF_MASK(%rip), \XMM7, \XMM7	# perform a 16Byte swap
2510		vpshufb	SHUF_MASK(%rip), \XMM8, \XMM8	# perform a 16Byte swap
2511
2512
2513	vpxor	\T1, \XMM1, \XMM1
2514
2515
2516
2517.endm
2518
2519
2520# GHASH the last 4 ciphertext blocks.
2521.macro  GHASH_LAST_8_AVX2 T1 T2 T3 T4 T5 T6 T7 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8
2522
2523        ## Karatsuba Method
2524
2525        vmovdqu         HashKey_8(arg2), \T5
2526
2527        vpshufd         $0b01001110, \XMM1, \T2
2528        vpshufd         $0b01001110, \T5, \T3
2529        vpxor           \XMM1, \T2, \T2
2530        vpxor           \T5, \T3, \T3
2531
2532        vpclmulqdq      $0x11, \T5, \XMM1, \T6
2533        vpclmulqdq      $0x00, \T5, \XMM1, \T7
2534
2535        vpclmulqdq      $0x00, \T3, \T2, \XMM1
2536
2537        ######################
2538
2539        vmovdqu         HashKey_7(arg2), \T5
2540        vpshufd         $0b01001110, \XMM2, \T2
2541        vpshufd         $0b01001110, \T5, \T3
2542        vpxor           \XMM2, \T2, \T2
2543        vpxor           \T5, \T3, \T3
2544
2545        vpclmulqdq      $0x11, \T5, \XMM2, \T4
2546        vpxor           \T4, \T6, \T6
2547
2548        vpclmulqdq      $0x00, \T5, \XMM2, \T4
2549        vpxor           \T4, \T7, \T7
2550
2551        vpclmulqdq      $0x00, \T3, \T2, \T2
2552
2553        vpxor           \T2, \XMM1, \XMM1
2554
2555        ######################
2556
2557        vmovdqu         HashKey_6(arg2), \T5
2558        vpshufd         $0b01001110, \XMM3, \T2
2559        vpshufd         $0b01001110, \T5, \T3
2560        vpxor           \XMM3, \T2, \T2
2561        vpxor           \T5, \T3, \T3
2562
2563        vpclmulqdq      $0x11, \T5, \XMM3, \T4
2564        vpxor           \T4, \T6, \T6
2565
2566        vpclmulqdq      $0x00, \T5, \XMM3, \T4
2567        vpxor           \T4, \T7, \T7
2568
2569        vpclmulqdq      $0x00, \T3, \T2, \T2
2570
2571        vpxor           \T2, \XMM1, \XMM1
2572
2573        ######################
2574
2575        vmovdqu         HashKey_5(arg2), \T5
2576        vpshufd         $0b01001110, \XMM4, \T2
2577        vpshufd         $0b01001110, \T5, \T3
2578        vpxor           \XMM4, \T2, \T2
2579        vpxor           \T5, \T3, \T3
2580
2581        vpclmulqdq      $0x11, \T5, \XMM4, \T4
2582        vpxor           \T4, \T6, \T6
2583
2584        vpclmulqdq      $0x00, \T5, \XMM4, \T4
2585        vpxor           \T4, \T7, \T7
2586
2587        vpclmulqdq      $0x00, \T3, \T2, \T2
2588
2589        vpxor           \T2, \XMM1, \XMM1
2590
2591        ######################
2592
2593        vmovdqu         HashKey_4(arg2), \T5
2594        vpshufd         $0b01001110, \XMM5, \T2
2595        vpshufd         $0b01001110, \T5, \T3
2596        vpxor           \XMM5, \T2, \T2
2597        vpxor           \T5, \T3, \T3
2598
2599        vpclmulqdq      $0x11, \T5, \XMM5, \T4
2600        vpxor           \T4, \T6, \T6
2601
2602        vpclmulqdq      $0x00, \T5, \XMM5, \T4
2603        vpxor           \T4, \T7, \T7
2604
2605        vpclmulqdq      $0x00, \T3, \T2, \T2
2606
2607        vpxor           \T2, \XMM1, \XMM1
2608
2609        ######################
2610
2611        vmovdqu         HashKey_3(arg2), \T5
2612        vpshufd         $0b01001110, \XMM6, \T2
2613        vpshufd         $0b01001110, \T5, \T3
2614        vpxor           \XMM6, \T2, \T2
2615        vpxor           \T5, \T3, \T3
2616
2617        vpclmulqdq      $0x11, \T5, \XMM6, \T4
2618        vpxor           \T4, \T6, \T6
2619
2620        vpclmulqdq      $0x00, \T5, \XMM6, \T4
2621        vpxor           \T4, \T7, \T7
2622
2623        vpclmulqdq      $0x00, \T3, \T2, \T2
2624
2625        vpxor           \T2, \XMM1, \XMM1
2626
2627        ######################
2628
2629        vmovdqu         HashKey_2(arg2), \T5
2630        vpshufd         $0b01001110, \XMM7, \T2
2631        vpshufd         $0b01001110, \T5, \T3
2632        vpxor           \XMM7, \T2, \T2
2633        vpxor           \T5, \T3, \T3
2634
2635        vpclmulqdq      $0x11, \T5, \XMM7, \T4
2636        vpxor           \T4, \T6, \T6
2637
2638        vpclmulqdq      $0x00, \T5, \XMM7, \T4
2639        vpxor           \T4, \T7, \T7
2640
2641        vpclmulqdq      $0x00, \T3, \T2, \T2
2642
2643        vpxor           \T2, \XMM1, \XMM1
2644
2645        ######################
2646
2647        vmovdqu         HashKey(arg2), \T5
2648        vpshufd         $0b01001110, \XMM8, \T2
2649        vpshufd         $0b01001110, \T5, \T3
2650        vpxor           \XMM8, \T2, \T2
2651        vpxor           \T5, \T3, \T3
2652
2653        vpclmulqdq      $0x11, \T5, \XMM8, \T4
2654        vpxor           \T4, \T6, \T6
2655
2656        vpclmulqdq      $0x00, \T5, \XMM8, \T4
2657        vpxor           \T4, \T7, \T7
2658
2659        vpclmulqdq      $0x00, \T3, \T2, \T2
2660
2661        vpxor           \T2, \XMM1, \XMM1
2662        vpxor           \T6, \XMM1, \XMM1
2663        vpxor           \T7, \XMM1, \T2
2664
2665
2666
2667
2668        vpslldq $8, \T2, \T4
2669        vpsrldq $8, \T2, \T2
2670
2671        vpxor   \T4, \T7, \T7
2672        vpxor   \T2, \T6, \T6                      # <T6:T7> holds the result of the
2673						   # accumulated carry-less multiplications
2674
2675        #######################################################################
2676        #first phase of the reduction
2677        vmovdqa         POLY2(%rip), \T3
2678
2679        vpclmulqdq      $0x01, \T7, \T3, \T2
2680        vpslldq         $8, \T2, \T2               # shift-L xmm2 2 DWs
2681
2682        vpxor           \T2, \T7, \T7              # first phase of the reduction complete
2683        #######################################################################
2684
2685
2686        #second phase of the reduction
2687        vpclmulqdq      $0x00, \T7, \T3, \T2
2688        vpsrldq         $4, \T2, \T2               # shift-R T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
2689
2690        vpclmulqdq      $0x10, \T7, \T3, \T4
2691        vpslldq         $4, \T4, \T4               # shift-L T4 1 DW (Shift-L 1-DW to obtain result with no shifts)
2692
2693        vpxor           \T2, \T4, \T4              # second phase of the reduction complete
2694        #######################################################################
2695        vpxor           \T4, \T6, \T6              # the result is in T6
2696.endm
2697
2698
2699
2700#############################################################
2701#void   aesni_gcm_init_avx_gen4
2702#        (gcm_data     *my_ctx_data,
2703#         gcm_context_data *data,
2704#        u8      *iv, /* Pre-counter block j0: 4 byte salt
2705#			(from Security Association) concatenated with 8 byte
2706#			Initialisation Vector (from IPSec ESP Payload)
2707#			concatenated with 0x00000001. 16-byte aligned pointer. */
2708#        u8     *hash_subkey# /* H, the Hash sub key input. Data starts on a 16-byte boundary. */
2709#        const   u8 *aad, /* Additional Authentication Data (AAD)*/
2710#        u64     aad_len) /* Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 Bytes */
2711#############################################################
2712SYM_FUNC_START(aesni_gcm_init_avx_gen4)
2713        FUNC_SAVE
2714        INIT GHASH_MUL_AVX2, PRECOMPUTE_AVX2
2715        FUNC_RESTORE
2716        RET
2717SYM_FUNC_END(aesni_gcm_init_avx_gen4)
2718
2719###############################################################################
2720#void   aesni_gcm_enc_avx_gen4(
2721#        gcm_data        *my_ctx_data,     /* aligned to 16 Bytes */
2722#        gcm_context_data *data,
2723#        u8      *out, /* Ciphertext output. Encrypt in-place is allowed.  */
2724#        const   u8 *in, /* Plaintext input */
2725#        u64     plaintext_len) /* Length of data in Bytes for encryption. */
2726###############################################################################
2727SYM_FUNC_START(aesni_gcm_enc_update_avx_gen4)
2728        FUNC_SAVE
2729        mov     keysize,%eax
2730        cmp     $32, %eax
2731        je      key_256_enc_update4
2732        cmp     $16, %eax
2733        je      key_128_enc_update4
2734        # must be 192
2735        GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, ENC, 11
2736        FUNC_RESTORE
2737	RET
2738key_128_enc_update4:
2739        GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, ENC, 9
2740        FUNC_RESTORE
2741	RET
2742key_256_enc_update4:
2743        GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, ENC, 13
2744        FUNC_RESTORE
2745	RET
2746SYM_FUNC_END(aesni_gcm_enc_update_avx_gen4)
2747
2748###############################################################################
2749#void   aesni_gcm_dec_update_avx_gen4(
2750#        gcm_data        *my_ctx_data,     /* aligned to 16 Bytes */
2751#        gcm_context_data *data,
2752#        u8      *out, /* Plaintext output. Decrypt in-place is allowed.  */
2753#        const   u8 *in, /* Ciphertext input */
2754#        u64     plaintext_len) /* Length of data in Bytes for encryption. */
2755###############################################################################
2756SYM_FUNC_START(aesni_gcm_dec_update_avx_gen4)
2757        FUNC_SAVE
2758        mov     keysize,%eax
2759        cmp     $32, %eax
2760        je      key_256_dec_update4
2761        cmp     $16, %eax
2762        je      key_128_dec_update4
2763        # must be 192
2764        GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, DEC, 11
2765        FUNC_RESTORE
2766        RET
2767key_128_dec_update4:
2768        GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, DEC, 9
2769        FUNC_RESTORE
2770        RET
2771key_256_dec_update4:
2772        GCM_ENC_DEC INITIAL_BLOCKS_AVX2, GHASH_8_ENCRYPT_8_PARALLEL_AVX2, GHASH_LAST_8_AVX2, GHASH_MUL_AVX2, DEC, 13
2773        FUNC_RESTORE
2774        RET
2775SYM_FUNC_END(aesni_gcm_dec_update_avx_gen4)
2776
2777###############################################################################
2778#void   aesni_gcm_finalize_avx_gen4(
2779#        gcm_data        *my_ctx_data,     /* aligned to 16 Bytes */
2780#        gcm_context_data *data,
2781#        u8      *auth_tag, /* Authenticated Tag output. */
2782#        u64     auth_tag_len)# /* Authenticated Tag Length in bytes.
2783#                              Valid values are 16 (most likely), 12 or 8. */
2784###############################################################################
2785SYM_FUNC_START(aesni_gcm_finalize_avx_gen4)
2786        FUNC_SAVE
2787        mov	keysize,%eax
2788        cmp     $32, %eax
2789        je      key_256_finalize4
2790        cmp     $16, %eax
2791        je      key_128_finalize4
2792        # must be 192
2793        GCM_COMPLETE GHASH_MUL_AVX2, 11, arg3, arg4
2794        FUNC_RESTORE
2795        RET
2796key_128_finalize4:
2797        GCM_COMPLETE GHASH_MUL_AVX2, 9, arg3, arg4
2798        FUNC_RESTORE
2799        RET
2800key_256_finalize4:
2801        GCM_COMPLETE GHASH_MUL_AVX2, 13, arg3, arg4
2802        FUNC_RESTORE
2803        RET
2804SYM_FUNC_END(aesni_gcm_finalize_avx_gen4)
2805