blob: 17e44e6183eca1f1d43a80bdac3e6a8cad9daf21 [file]
; This file is generated from a similarly-named Perl script in the BoringSSL
; source tree. Do not edit by hand.
%ifidn __OUTPUT_FORMAT__, win64
default rel
%define XMMWORD
%define YMMWORD
%define ZMMWORD
%define _CET_ENDBR
%ifdef BORINGSSL_PREFIX
%include "boringssl_prefix_symbols_internal_x86_64_win_asm.inc"
%endif
section .rdata rdata align=8
ALIGN 64
aes_gcm_avx512_constants:
; A shuffle mask that reflects the bytes of 16-byte blocks
$L$bswap_mask:
DQ 0x08090a0b0c0d0e0f,0x0001020304050607
; This is the GHASH reducing polynomial without its constant term, i.e.
; x^128 + x^7 + x^2 + x, represented using the backwards mapping
; between bits and polynomial coefficients.
;
; Alternatively, it can be interpreted as the naturally-ordered
; representation of the polynomial x^127 + x^126 + x^121 + 1, i.e. the
; "reversed" GHASH reducing polynomial without its x^128 term.
$L$gfpoly:
DQ 1,0xc200000000000000
; Same as above, but with the (1 << 64) bit set.
$L$gfpoly_and_internal_carrybit:
DQ 1,0xc200000000000001
; Values needed to prepare the initial vector of counter blocks.
$L$ctr_pattern:
DQ 0,0
DQ 1,0
DQ 2,0
DQ 3,0
; The number of AES blocks per vector, as a 128-bit value.
$L$inc_4blocks:
DQ 4,0
section .text code align=64
global gcm_init_vpclmulqdq_avx512
ALIGN 32
gcm_init_vpclmulqdq_avx512:
_CET_ENDBR
; Get pointer to lowest set of key powers (located at end of array).
lea r8,[((256-64))+rcx]
; Load the byte-reflected hash subkey. BoringSSL provides it in
; byte-reflected form except the two halves are in the wrong order.
vpshufd xmm3,XMMWORD[rdx],0x4e
; Finish preprocessing the first key power, H^1. Since this GHASH
; implementation operates directly on values with the backwards bit
; order specified by the GCM standard, it's necessary to preprocess the
; raw key as follows. First, reflect its bytes. Second, multiply it
; by x^-1 mod x^128 + x^7 + x^2 + x + 1 (if using the backwards
; interpretation of polynomial coefficients), which can also be
; interpreted as multiplication by x mod x^128 + x^127 + x^126 + x^121
; + 1 using the alternative, natural interpretation of polynomial
; coefficients. For details, see the comment above _ghash_mul.
;
; Either way, for the multiplication the concrete operation performed
; is a left shift of the 128-bit value by 1 bit, then an XOR with (0xc2
; << 120) | 1 if a 1 bit was carried out. However, there's no 128-bit
; wide shift instruction, so instead double each of the two 64-bit
; halves and incorporate the internal carry bit into the value XOR'd.
vpshufd xmm0,xmm3,0xd3
vpsrad xmm0,xmm0,31
vpaddq xmm3,xmm3,xmm3
; H_CUR_XMM ^= TMP0_XMM & gfpoly_and_internal_carrybit
vpternlogd xmm3,xmm0,XMMWORD[$L$gfpoly_and_internal_carrybit],0x78
; Load the gfpoly constant.
vbroadcasti32x4 zmm5,ZMMWORD[$L$gfpoly]
; Square H^1 to get H^2.
;
; Note that as with H^1, all higher key powers also need an extra
; factor of x^-1 (or x using the natural interpretation). Nothing
; special needs to be done to make this happen, though: H^1 * H^1 would
; end up with two factors of x^-1, but the multiplication consumes one.
; So the product H^2 ends up with the desired one factor of x^-1.
vpclmulqdq xmm0,xmm3,xmm3,0x00 ; LO = a_L * a_L
vpclmulqdq xmm4,xmm3,xmm3,0x11 ; HI = a_H * a_H
vpclmulqdq xmm1,xmm5,xmm0,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpshufd xmm0,xmm0,0x4e ; Swap halves of LO
vpxor xmm1,xmm1,xmm0 ; Fold LO into MI
vpclmulqdq xmm0,xmm5,xmm1,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpshufd xmm1,xmm1,0x4e ; Swap halves of MI
vpternlogd xmm4,xmm1,xmm0,0x96 ; Fold MI into HI
; Create H_CUR_YMM = [H^2, H^1] and H_INC_YMM = [H^2, H^2].
vinserti128 ymm3,ymm4,xmm3,1
vinserti128 ymm4,ymm4,xmm4,1
; Create H_CUR = [H^4, H^3, H^2, H^1] and H_INC = [H^4, H^4, H^4, H^4].
vpclmulqdq ymm0,ymm3,ymm4,0x00 ; LO = a_L * b_L
vpclmulqdq ymm1,ymm3,ymm4,0x01 ; MI_0 = a_L * b_H
vpclmulqdq ymm2,ymm3,ymm4,0x10 ; MI_1 = a_H * b_L
vpxord ymm1,ymm1,ymm2 ; MI = MI_0 + MI_1
vpclmulqdq ymm2,ymm5,ymm0,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpshufd ymm0,ymm0,0x4e ; Swap halves of LO
vpternlogd ymm1,ymm0,ymm2,0x96 ; Fold LO into MI
vpclmulqdq ymm4,ymm3,ymm4,0x11 ; HI = a_H * b_H
vpclmulqdq ymm0,ymm5,ymm1,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpshufd ymm1,ymm1,0x4e ; Swap halves of MI
vpternlogd ymm4,ymm1,ymm0,0x96 ; Fold MI into HI
vinserti64x4 zmm3,zmm4,ymm3,1
vshufi64x2 zmm4,zmm4,zmm4,0
; Store the lowest set of key powers.
vmovdqu8 ZMMWORD[r8],zmm3
; Compute and store the remaining key powers.
; Repeatedly multiply [H^(i+3), H^(i+2), H^(i+1), H^i] by
; [H^4, H^4, H^4, H^4] to get [H^(i+7), H^(i+6), H^(i+5), H^(i+4)].
mov eax,3
$L$precompute_next:
sub r8,64
vpclmulqdq zmm0,zmm3,zmm4,0x00 ; LO = a_L * b_L
vpclmulqdq zmm1,zmm3,zmm4,0x01 ; MI_0 = a_L * b_H
vpclmulqdq zmm2,zmm3,zmm4,0x10 ; MI_1 = a_H * b_L
vpxord zmm1,zmm1,zmm2 ; MI = MI_0 + MI_1
vpclmulqdq zmm2,zmm5,zmm0,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpshufd zmm0,zmm0,0x4e ; Swap halves of LO
vpternlogd zmm1,zmm0,zmm2,0x96 ; Fold LO into MI
vpclmulqdq zmm3,zmm3,zmm4,0x11 ; HI = a_H * b_H
vpclmulqdq zmm0,zmm5,zmm1,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpshufd zmm1,zmm1,0x4e ; Swap halves of MI
vpternlogd zmm3,zmm1,zmm0,0x96 ; Fold MI into HI
vmovdqu8 ZMMWORD[r8],zmm3
dec eax
jnz NEAR $L$precompute_next
vzeroupper ; This is needed after using ymm or zmm registers.
ret
global gcm_gmult_vpclmulqdq_avx512
ALIGN 32
gcm_gmult_vpclmulqdq_avx512:
$L$SEH_begin_gcm_gmult_vpclmulqdq_avx512_1:
_CET_ENDBR
sub rsp,24
$L$SEH_prologue_gcm_gmult_vpclmulqdq_avx512_2:
vmovdqa XMMWORD[rsp],xmm6
$L$SEH_prologue_gcm_gmult_vpclmulqdq_avx512_3:
$L$SEH_endprologue_gcm_gmult_vpclmulqdq_avx512_4:
vmovdqu xmm0,XMMWORD[rcx]
vmovdqu xmm1,XMMWORD[$L$bswap_mask]
vmovdqu xmm2,XMMWORD[((256-16))+rdx]
vmovdqu xmm3,XMMWORD[$L$gfpoly]
vpshufb xmm0,xmm0,xmm1
vpclmulqdq xmm4,xmm0,xmm2,0x00 ; LO = a_L * b_L
vpclmulqdq xmm5,xmm0,xmm2,0x01 ; MI_0 = a_L * b_H
vpclmulqdq xmm6,xmm0,xmm2,0x10 ; MI_1 = a_H * b_L
vpxord xmm5,xmm5,xmm6 ; MI = MI_0 + MI_1
vpclmulqdq xmm6,xmm3,xmm4,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpshufd xmm4,xmm4,0x4e ; Swap halves of LO
vpternlogd xmm5,xmm4,xmm6,0x96 ; Fold LO into MI
vpclmulqdq xmm0,xmm0,xmm2,0x11 ; HI = a_H * b_H
vpclmulqdq xmm4,xmm3,xmm5,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpshufd xmm5,xmm5,0x4e ; Swap halves of MI
vpternlogd xmm0,xmm5,xmm4,0x96 ; Fold MI into HI
vpshufb xmm0,xmm0,xmm1
vmovdqu XMMWORD[rcx],xmm0
; No need for vzeroupper, since only xmm registers were used.
vmovdqa xmm6,XMMWORD[rsp]
add rsp,24
ret
$L$SEH_end_gcm_gmult_vpclmulqdq_avx512_5:
global gcm_ghash_vpclmulqdq_avx512
ALIGN 32
gcm_ghash_vpclmulqdq_avx512:
$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1:
_CET_ENDBR
sub rsp,136
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_2:
vmovdqa XMMWORD[rsp],xmm6
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_3:
vmovdqa XMMWORD[16+rsp],xmm7
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_4:
vmovdqa XMMWORD[32+rsp],xmm8
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_5:
vmovdqa XMMWORD[48+rsp],xmm9
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_6:
vmovdqa XMMWORD[64+rsp],xmm10
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_7:
vmovdqa XMMWORD[80+rsp],xmm11
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_8:
vmovdqa XMMWORD[96+rsp],xmm12
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_9:
vmovdqa XMMWORD[112+rsp],xmm13
$L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_10:
$L$SEH_endprologue_gcm_ghash_vpclmulqdq_avx512_11:
; Load the bswap_mask and gfpoly constants. Since AADLEN is usually small,
; usually only 128-bit vectors will be used. So as an optimization, don't
; broadcast these constants to all 128-bit lanes quite yet.
vmovdqu xmm4,XMMWORD[$L$bswap_mask]
vmovdqu xmm10,XMMWORD[$L$gfpoly]
; Load the GHASH accumulator.
vmovdqu xmm5,XMMWORD[rcx]
vpshufb xmm5,xmm5,xmm4
; Optimize for AADLEN < 64 by checking for AADLEN < 64 before AADLEN < 256.
cmp r9,64
jb NEAR $L$aad_blockbyblock
; AADLEN >= 64, so we'll operate on full vectors. Broadcast bswap_mask and
; gfpoly to all 128-bit lanes.
vshufi64x2 zmm4,zmm4,zmm4,0
vshufi64x2 zmm10,zmm10,zmm10,0
; Load the lowest set of key powers.
vmovdqu8 zmm9,ZMMWORD[((256-64))+rdx]
cmp r9,256
jb NEAR $L$aad_loop_1x
; AADLEN >= 256. Load the higher key powers.
vmovdqu8 zmm6,ZMMWORD[((256-256))+rdx]
vmovdqu8 zmm7,ZMMWORD[((256-192))+rdx]
vmovdqu8 zmm8,ZMMWORD[((256-128))+rdx]
; Update GHASH with 256 bytes of AAD at a time.
$L$aad_loop_4x:
vmovdqu8 zmm0,ZMMWORD[r8]
vmovdqu8 zmm1,ZMMWORD[64+r8]
vmovdqu8 zmm2,ZMMWORD[128+r8]
vmovdqu8 zmm3,ZMMWORD[192+r8]
vpshufb zmm0,zmm0,zmm4
vpxord zmm0,zmm0,zmm5
vpshufb zmm1,zmm1,zmm4
vpshufb zmm2,zmm2,zmm4
vpshufb zmm3,zmm3,zmm4
vpclmulqdq zmm5,zmm0,zmm6,0x00 ; LO_0
vpclmulqdq zmm11,zmm1,zmm7,0x00 ; LO_1
vpclmulqdq zmm12,zmm2,zmm8,0x00 ; LO_2
vpxord zmm5,zmm5,zmm11 ; sum(LO_{1,0})
vpclmulqdq zmm13,zmm3,zmm9,0x00 ; LO_3
vpternlogd zmm5,zmm12,zmm13,0x96 ; LO = sum(LO_{3,2,1,0})
vpclmulqdq zmm11,zmm0,zmm6,0x01 ; MI_0
vpclmulqdq zmm12,zmm1,zmm7,0x01 ; MI_1
vpclmulqdq zmm13,zmm2,zmm8,0x01 ; MI_2
vpternlogd zmm11,zmm12,zmm13,0x96 ; sum(MI_{2,1,0})
vpclmulqdq zmm12,zmm3,zmm9,0x01 ; MI_3
vpclmulqdq zmm13,zmm0,zmm6,0x10 ; MI_4
vpternlogd zmm11,zmm12,zmm13,0x96 ; sum(MI_{4,3,2,1,0})
vpclmulqdq zmm12,zmm1,zmm7,0x10 ; MI_5
vpclmulqdq zmm13,zmm2,zmm8,0x10 ; MI_6
vpternlogd zmm11,zmm12,zmm13,0x96 ; sum(MI_{6,5,4,3,2,1,0})
vpclmulqdq zmm13,zmm10,zmm5,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpclmulqdq zmm12,zmm3,zmm9,0x10 ; MI_7
vpxord zmm11,zmm11,zmm12 ; MI = sum(MI_{7,6,5,4,3,2,1,0})
vpshufd zmm5,zmm5,0x4e ; Swap halves of LO
vpclmulqdq zmm0,zmm0,zmm6,0x11 ; HI_0
vpclmulqdq zmm1,zmm1,zmm7,0x11 ; HI_1
vpclmulqdq zmm2,zmm2,zmm8,0x11 ; HI_2
vpternlogd zmm11,zmm5,zmm13,0x96 ; Fold LO into MI
vpclmulqdq zmm3,zmm3,zmm9,0x11 ; HI_3
vpternlogd zmm0,zmm1,zmm2,0x96 ; sum(HI_{2,1,0})
vpclmulqdq zmm12,zmm10,zmm11,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpxord zmm5,zmm0,zmm3 ; HI = sum(HI_{3,2,1,0})
vpshufd zmm11,zmm11,0x4e ; Swap halves of MI
vpternlogd zmm5,zmm11,zmm12,0x96 ; Fold MI into HI
vextracti32x4 xmm0,zmm5,1
vextracti32x4 xmm1,zmm5,2
vextracti32x4 xmm2,zmm5,3
vpxord xmm5,xmm5,xmm0
vpternlogd xmm5,xmm2,xmm1,0x96
add r8,256
sub r9,256
cmp r9,256
jae NEAR $L$aad_loop_4x
; Update GHASH with 64 bytes of AAD at a time.
cmp r9,64
jb NEAR $L$aad_large_done
$L$aad_loop_1x:
vmovdqu8 zmm0,ZMMWORD[r8]
vpshufb zmm0,zmm0,zmm4
vpxord zmm5,zmm5,zmm0
vpclmulqdq zmm0,zmm5,zmm9,0x00 ; LO = a_L * b_L
vpclmulqdq zmm1,zmm5,zmm9,0x01 ; MI_0 = a_L * b_H
vpclmulqdq zmm2,zmm5,zmm9,0x10 ; MI_1 = a_H * b_L
vpxord zmm1,zmm1,zmm2 ; MI = MI_0 + MI_1
vpclmulqdq zmm2,zmm10,zmm0,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpshufd zmm0,zmm0,0x4e ; Swap halves of LO
vpternlogd zmm1,zmm0,zmm2,0x96 ; Fold LO into MI
vpclmulqdq zmm5,zmm5,zmm9,0x11 ; HI = a_H * b_H
vpclmulqdq zmm0,zmm10,zmm1,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpshufd zmm1,zmm1,0x4e ; Swap halves of MI
vpternlogd zmm5,zmm1,zmm0,0x96 ; Fold MI into HI
vextracti32x4 xmm0,zmm5,1
vextracti32x4 xmm1,zmm5,2
vextracti32x4 xmm2,zmm5,3
vpxord xmm5,xmm5,xmm0
vpternlogd xmm5,xmm2,xmm1,0x96
add r8,64
sub r9,64
cmp r9,64
jae NEAR $L$aad_loop_1x
$L$aad_large_done:
; GHASH the remaining data 16 bytes at a time, using xmm registers only.
$L$aad_blockbyblock:
test r9,r9
jz NEAR $L$aad_done
vmovdqu xmm9,XMMWORD[((256-16))+rdx]
$L$aad_loop_blockbyblock:
vmovdqu xmm0,XMMWORD[r8]
vpshufb xmm0,xmm0,xmm4
vpxor xmm5,xmm5,xmm0
vpclmulqdq xmm0,xmm5,xmm9,0x00 ; LO = a_L * b_L
vpclmulqdq xmm1,xmm5,xmm9,0x01 ; MI_0 = a_L * b_H
vpclmulqdq xmm2,xmm5,xmm9,0x10 ; MI_1 = a_H * b_L
vpxord xmm1,xmm1,xmm2 ; MI = MI_0 + MI_1
vpclmulqdq xmm2,xmm10,xmm0,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpshufd xmm0,xmm0,0x4e ; Swap halves of LO
vpternlogd xmm1,xmm0,xmm2,0x96 ; Fold LO into MI
vpclmulqdq xmm5,xmm5,xmm9,0x11 ; HI = a_H * b_H
vpclmulqdq xmm0,xmm10,xmm1,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpshufd xmm1,xmm1,0x4e ; Swap halves of MI
vpternlogd xmm5,xmm1,xmm0,0x96 ; Fold MI into HI
add r8,16
sub r9,16
jnz NEAR $L$aad_loop_blockbyblock
$L$aad_done:
; Store the updated GHASH accumulator back to memory.
vpshufb xmm5,xmm5,xmm4
vmovdqu XMMWORD[rcx],xmm5
vzeroupper ; This is needed after using ymm or zmm registers.
vmovdqa xmm6,XMMWORD[rsp]
vmovdqa xmm7,XMMWORD[16+rsp]
vmovdqa xmm8,XMMWORD[32+rsp]
vmovdqa xmm9,XMMWORD[48+rsp]
vmovdqa xmm10,XMMWORD[64+rsp]
vmovdqa xmm11,XMMWORD[80+rsp]
vmovdqa xmm12,XMMWORD[96+rsp]
vmovdqa xmm13,XMMWORD[112+rsp]
add rsp,136
ret
$L$SEH_end_gcm_ghash_vpclmulqdq_avx512_12:
global aes_gcm_enc_update_vaes_avx512
ALIGN 32
aes_gcm_enc_update_vaes_avx512:
$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1:
_CET_ENDBR
push rsi
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_2:
push rdi
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_3:
push r12
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_4:
mov rsi,QWORD[64+rsp] ; arg5
mov rdi,QWORD[72+rsp] ; arg6
mov r12,QWORD[80+rsp] ; arg7
sub rsp,160
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_5:
vmovdqa XMMWORD[rsp],xmm6
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_6:
vmovdqa XMMWORD[16+rsp],xmm7
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_7:
vmovdqa XMMWORD[32+rsp],xmm8
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_8:
vmovdqa XMMWORD[48+rsp],xmm9
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_9:
vmovdqa XMMWORD[64+rsp],xmm10
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_10:
vmovdqa XMMWORD[80+rsp],xmm11
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_11:
vmovdqa XMMWORD[96+rsp],xmm12
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_12:
vmovdqa XMMWORD[112+rsp],xmm13
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_13:
vmovdqa XMMWORD[128+rsp],xmm14
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_14:
vmovdqa XMMWORD[144+rsp],xmm15
$L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_15:
$L$SEH_endprologue_aes_gcm_enc_update_vaes_avx512_16:
%ifdef BORINGSSL_DISPATCH_TEST
EXTERN BORINGSSL_function_hit
mov BYTE[((BORINGSSL_function_hit+7))],1
%endif
; Load some constants.
vbroadcasti32x4 zmm8,ZMMWORD[$L$bswap_mask]
vbroadcasti32x4 zmm31,ZMMWORD[$L$gfpoly]
; Load the GHASH accumulator and the starting counter.
; BoringSSL passes these values in big endian format.
vmovdqu xmm10,XMMWORD[r12]
vpshufb xmm10,xmm10,xmm8
vbroadcasti32x4 zmm12,ZMMWORD[rsi]
vpshufb zmm12,zmm12,zmm8
; Load the AES key length in bytes. BoringSSL stores number of rounds
; minus 1, so convert using: AESKEYLEN = 4 * aeskey->rounds - 20.
mov r10d,DWORD[240+r9]
lea r10d,[((-20))+r10*4]
; Make RNDKEYLAST_PTR point to the last AES round key. This is the
; round key with index 10, 12, or 14 for AES-128, AES-192, or AES-256
; respectively. Then load the zero-th and last round keys.
lea r11,[96+r10*4+r9]
vbroadcasti32x4 zmm13,ZMMWORD[r9]
vbroadcasti32x4 zmm14,ZMMWORD[r11]
; Finish initializing LE_CTR by adding [0, 1, 2, 3] to its low words.
vpaddd zmm12,zmm12,ZMMWORD[$L$ctr_pattern]
; Load 4 into all 128-bit lanes of LE_CTR_INC.
vbroadcasti32x4 zmm11,ZMMWORD[$L$inc_4blocks]
; If there are at least 256 bytes of data, then continue into the loop
; that processes 256 bytes of data at a time. Otherwise skip it.
cmp r8,256
jb NEAR $L$crypt_loop_4x_done__func1
; Load powers of the hash key.
vmovdqu8 zmm27,ZMMWORD[((256-256))+rdi]
vmovdqu8 zmm28,ZMMWORD[((256-192))+rdi]
vmovdqu8 zmm29,ZMMWORD[((256-128))+rdi]
vmovdqu8 zmm30,ZMMWORD[((256-64))+rdi]
; Encrypt the first 4 vectors of plaintext blocks. Leave the resulting
; ciphertext in GHASHDATA[0-3] for GHASH.
; Increment le_ctr four times to generate four vectors of little-endian
; counter blocks, swap each to big-endian, and store them in aesdata[0-3].
vpshufb zmm0,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm1,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm2,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm3,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
; AES "round zero": XOR in the zero-th round key.
vpxord zmm0,zmm0,zmm13
vpxord zmm1,zmm1,zmm13
vpxord zmm2,zmm2,zmm13
vpxord zmm3,zmm3,zmm13
lea rax,[16+r9]
$L$vaesenc_loop_first_4_vecs__func1:
vbroadcasti32x4 zmm9,ZMMWORD[rax]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
add rax,16
cmp r11,rax
jne NEAR $L$vaesenc_loop_first_4_vecs__func1
vpxord zmm4,zmm14,ZMMWORD[rcx]
vpxord zmm5,zmm14,ZMMWORD[64+rcx]
vpxord zmm6,zmm14,ZMMWORD[128+rcx]
vpxord zmm7,zmm14,ZMMWORD[192+rcx]
vaesenclast zmm4,zmm0,zmm4
vaesenclast zmm5,zmm1,zmm5
vaesenclast zmm6,zmm2,zmm6
vaesenclast zmm7,zmm3,zmm7
vmovdqu8 ZMMWORD[rdx],zmm4
vmovdqu8 ZMMWORD[64+rdx],zmm5
vmovdqu8 ZMMWORD[128+rdx],zmm6
vmovdqu8 ZMMWORD[192+rdx],zmm7
add rcx,256
add rdx,256
sub r8,256
cmp r8,256
jb NEAR $L$ghash_last_ciphertext_4x__func1
; Cache as many additional AES round keys as possible.
vbroadcasti32x4 zmm15,ZMMWORD[((-144))+r11]
vbroadcasti32x4 zmm16,ZMMWORD[((-128))+r11]
vbroadcasti32x4 zmm17,ZMMWORD[((-112))+r11]
vbroadcasti32x4 zmm18,ZMMWORD[((-96))+r11]
vbroadcasti32x4 zmm19,ZMMWORD[((-80))+r11]
vbroadcasti32x4 zmm20,ZMMWORD[((-64))+r11]
vbroadcasti32x4 zmm21,ZMMWORD[((-48))+r11]
vbroadcasti32x4 zmm22,ZMMWORD[((-32))+r11]
vbroadcasti32x4 zmm23,ZMMWORD[((-16))+r11]
$L$crypt_loop_4x__func1:
; Start the AES encryption of the counter blocks.
; Increment le_ctr four times to generate four vectors of little-endian
; counter blocks, swap each to big-endian, and store them in aesdata[0-3].
vpshufb zmm0,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm1,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm2,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm3,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
; AES "round zero": XOR in the zero-th round key.
vpxord zmm0,zmm0,zmm13
vpxord zmm1,zmm1,zmm13
vpxord zmm2,zmm2,zmm13
vpxord zmm3,zmm3,zmm13
cmp r10d,24
jl NEAR $L$aes128__func1
je NEAR $L$aes192__func1
; AES-256
vbroadcasti32x4 zmm9,ZMMWORD[((-208))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
vbroadcasti32x4 zmm9,ZMMWORD[((-192))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
$L$aes192__func1:
vbroadcasti32x4 zmm9,ZMMWORD[((-176))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
vbroadcasti32x4 zmm9,ZMMWORD[((-160))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
$L$aes128__func1:
; Prefetch the source data 512 bytes ahead into the L1 data cache, to
; improve performance when the hardware prefetcher is disabled. Assumes the
; L1 data cache line size is 64 bytes (de facto standard on x86_64).
prefetcht0 [((512+0))+rcx]
prefetcht0 [((512+64))+rcx]
prefetcht0 [((512+128))+rcx]
prefetcht0 [((512+192))+rcx]
; Finish the AES encryption of the counter blocks in AESDATA[0-3],
; interleaved with the GHASH update of the ciphertext blocks in
; GHASHDATA[0-3].
vpshufb zmm4,zmm4,zmm8
vpxord zmm4,zmm4,zmm10
vpshufb zmm5,zmm5,zmm8
vpshufb zmm6,zmm6,zmm8
vaesenc zmm0,zmm0,zmm15
vaesenc zmm1,zmm1,zmm15
vaesenc zmm2,zmm2,zmm15
vaesenc zmm3,zmm3,zmm15
vpshufb zmm7,zmm7,zmm8
vpclmulqdq zmm10,zmm4,zmm27,0x00 ; LO_0
vpclmulqdq zmm24,zmm5,zmm28,0x00 ; LO_1
vpclmulqdq zmm25,zmm6,zmm29,0x00 ; LO_2
vaesenc zmm0,zmm0,zmm16
vaesenc zmm1,zmm1,zmm16
vaesenc zmm2,zmm2,zmm16
vaesenc zmm3,zmm3,zmm16
vpxord zmm10,zmm10,zmm24 ; sum(LO_{1,0})
vpclmulqdq zmm26,zmm7,zmm30,0x00 ; LO_3
vpternlogd zmm10,zmm25,zmm26,0x96 ; LO = sum(LO_{3,2,1,0})
vpclmulqdq zmm24,zmm4,zmm27,0x01 ; MI_0
vaesenc zmm0,zmm0,zmm17
vaesenc zmm1,zmm1,zmm17
vaesenc zmm2,zmm2,zmm17
vaesenc zmm3,zmm3,zmm17
vpclmulqdq zmm25,zmm5,zmm28,0x01 ; MI_1
vpclmulqdq zmm26,zmm6,zmm29,0x01 ; MI_2
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{2,1,0})
vpclmulqdq zmm25,zmm7,zmm30,0x01 ; MI_3
vaesenc zmm0,zmm0,zmm18
vaesenc zmm1,zmm1,zmm18
vaesenc zmm2,zmm2,zmm18
vaesenc zmm3,zmm3,zmm18
vpclmulqdq zmm26,zmm4,zmm27,0x10 ; MI_4
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{4,3,2,1,0})
vpclmulqdq zmm25,zmm5,zmm28,0x10 ; MI_5
vpclmulqdq zmm26,zmm6,zmm29,0x10 ; MI_6
vaesenc zmm0,zmm0,zmm19
vaesenc zmm1,zmm1,zmm19
vaesenc zmm2,zmm2,zmm19
vaesenc zmm3,zmm3,zmm19
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{6,5,4,3,2,1,0})
vpclmulqdq zmm26,zmm31,zmm10,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpclmulqdq zmm25,zmm7,zmm30,0x10 ; MI_7
vpxord zmm24,zmm24,zmm25 ; MI = sum(MI_{7,6,5,4,3,2,1,0})
vaesenc zmm0,zmm0,zmm20
vaesenc zmm1,zmm1,zmm20
vaesenc zmm2,zmm2,zmm20
vaesenc zmm3,zmm3,zmm20
vpshufd zmm10,zmm10,0x4e ; Swap halves of LO
vpclmulqdq zmm4,zmm4,zmm27,0x11 ; HI_0
vpclmulqdq zmm5,zmm5,zmm28,0x11 ; HI_1
vpclmulqdq zmm6,zmm6,zmm29,0x11 ; HI_2
vaesenc zmm0,zmm0,zmm21
vaesenc zmm1,zmm1,zmm21
vaesenc zmm2,zmm2,zmm21
vaesenc zmm3,zmm3,zmm21
vpternlogd zmm24,zmm10,zmm26,0x96 ; Fold LO into MI
vpclmulqdq zmm7,zmm7,zmm30,0x11 ; HI_3
vpternlogd zmm4,zmm5,zmm6,0x96 ; sum(HI_{2,1,0})
vpclmulqdq zmm25,zmm31,zmm24,0x01 ; MI_L*(x^63 + x^62 + x^57)
vaesenc zmm0,zmm0,zmm22
vaesenc zmm1,zmm1,zmm22
vaesenc zmm2,zmm2,zmm22
vaesenc zmm3,zmm3,zmm22
vpxord zmm10,zmm4,zmm7 ; HI = sum(HI_{3,2,1,0})
vpshufd zmm24,zmm24,0x4e ; Swap halves of MI
vpternlogd zmm10,zmm24,zmm25,0x96 ; Fold MI into HI
vaesenc zmm0,zmm0,zmm23
vaesenc zmm1,zmm1,zmm23
vaesenc zmm2,zmm2,zmm23
vaesenc zmm3,zmm3,zmm23
vextracti32x4 xmm4,zmm10,1
vextracti32x4 xmm5,zmm10,2
vextracti32x4 xmm6,zmm10,3
vpxord xmm10,xmm10,xmm4
vpternlogd xmm10,xmm6,xmm5,0x96
vpxord zmm4,zmm14,ZMMWORD[rcx]
vpxord zmm5,zmm14,ZMMWORD[64+rcx]
vpxord zmm6,zmm14,ZMMWORD[128+rcx]
vpxord zmm7,zmm14,ZMMWORD[192+rcx]
vaesenclast zmm4,zmm0,zmm4
vaesenclast zmm5,zmm1,zmm5
vaesenclast zmm6,zmm2,zmm6
vaesenclast zmm7,zmm3,zmm7
vmovdqu8 ZMMWORD[rdx],zmm4
vmovdqu8 ZMMWORD[64+rdx],zmm5
vmovdqu8 ZMMWORD[128+rdx],zmm6
vmovdqu8 ZMMWORD[192+rdx],zmm7
add rcx,256
add rdx,256
sub r8,256
cmp r8,256
jae NEAR $L$crypt_loop_4x__func1
$L$ghash_last_ciphertext_4x__func1:
vpshufb zmm4,zmm4,zmm8
vpxord zmm4,zmm4,zmm10
vpshufb zmm5,zmm5,zmm8
vpshufb zmm6,zmm6,zmm8
vpshufb zmm7,zmm7,zmm8
vpclmulqdq zmm10,zmm4,zmm27,0x00 ; LO_0
vpclmulqdq zmm24,zmm5,zmm28,0x00 ; LO_1
vpclmulqdq zmm25,zmm6,zmm29,0x00 ; LO_2
vpxord zmm10,zmm10,zmm24 ; sum(LO_{1,0})
vpclmulqdq zmm26,zmm7,zmm30,0x00 ; LO_3
vpternlogd zmm10,zmm25,zmm26,0x96 ; LO = sum(LO_{3,2,1,0})
vpclmulqdq zmm24,zmm4,zmm27,0x01 ; MI_0
vpclmulqdq zmm25,zmm5,zmm28,0x01 ; MI_1
vpclmulqdq zmm26,zmm6,zmm29,0x01 ; MI_2
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{2,1,0})
vpclmulqdq zmm25,zmm7,zmm30,0x01 ; MI_3
vpclmulqdq zmm26,zmm4,zmm27,0x10 ; MI_4
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{4,3,2,1,0})
vpclmulqdq zmm25,zmm5,zmm28,0x10 ; MI_5
vpclmulqdq zmm26,zmm6,zmm29,0x10 ; MI_6
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{6,5,4,3,2,1,0})
vpclmulqdq zmm26,zmm31,zmm10,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpclmulqdq zmm25,zmm7,zmm30,0x10 ; MI_7
vpxord zmm24,zmm24,zmm25 ; MI = sum(MI_{7,6,5,4,3,2,1,0})
vpshufd zmm10,zmm10,0x4e ; Swap halves of LO
vpclmulqdq zmm4,zmm4,zmm27,0x11 ; HI_0
vpclmulqdq zmm5,zmm5,zmm28,0x11 ; HI_1
vpclmulqdq zmm6,zmm6,zmm29,0x11 ; HI_2
vpternlogd zmm24,zmm10,zmm26,0x96 ; Fold LO into MI
vpclmulqdq zmm7,zmm7,zmm30,0x11 ; HI_3
vpternlogd zmm4,zmm5,zmm6,0x96 ; sum(HI_{2,1,0})
vpclmulqdq zmm25,zmm31,zmm24,0x01 ; MI_L*(x^63 + x^62 + x^57)
vpxord zmm10,zmm4,zmm7 ; HI = sum(HI_{3,2,1,0})
vpshufd zmm24,zmm24,0x4e ; Swap halves of MI
vpternlogd zmm10,zmm24,zmm25,0x96 ; Fold MI into HI
vextracti32x4 xmm4,zmm10,1
vextracti32x4 xmm5,zmm10,2
vextracti32x4 xmm6,zmm10,3
vpxord xmm10,xmm10,xmm4
vpternlogd xmm10,xmm6,xmm5,0x96
$L$crypt_loop_4x_done__func1:
; Check whether any data remains.
test r8,r8
jz NEAR $L$done__func1
; The data length isn't a multiple of 256 bytes. Process the remaining
; data of length 1 <= DATALEN < 256, up to one 64-byte vector at a time.
; Going one vector at a time may seem inefficient compared to having
; separate code paths for each possible number of vectors remaining.
; However, using a loop keeps the code size down, and it performs
; surprising well; modern CPUs will start executing the next iteration
; before the previous one finishes and also predict the number of loop
; iterations. For a similar reason, we roll up the AES rounds.
;
; On the last iteration, the remaining length may be less than 64 bytes.
; Handle this using masking.
;
; Since there are enough key powers available for all remaining data,
; there is no need to do a GHASH reduction after each iteration.
; Instead, multiply each remaining block by its own key power, and only
; do a GHASH reduction at the very end.
; Make POWERS_PTR point to the key powers [H^N, H^(N-1), ...] where N
; is the number of blocks that remain.
mov rax,r8
neg rax
and rax,-16 ; -round_up(DATALEN, 16)
lea rsi,[256+rax*1+rdi]
vpxor xmm4,xmm4,xmm4
vpxor xmm5,xmm5,xmm5
vpxor xmm6,xmm6,xmm6
cmp r8,64
jb NEAR $L$partial_vec__func1
$L$crypt_loop_1x__func1:
; Process a full 64-byte vector.
; Encrypt a vector of counter blocks.
vpshufb zmm0,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpxord zmm0,zmm0,zmm13
lea rax,[16+r9]
$L$vaesenc_loop_tail_full_vec__func1:
vbroadcasti32x4 zmm9,ZMMWORD[rax]
vaesenc zmm0,zmm0,zmm9
add rax,16
cmp r11,rax
jne NEAR $L$vaesenc_loop_tail_full_vec__func1
vaesenclast zmm0,zmm0,zmm14
; XOR the data with the vector of keystream blocks.
vmovdqu8 zmm1,ZMMWORD[rcx]
vpxord zmm0,zmm0,zmm1
vmovdqu8 ZMMWORD[rdx],zmm0
; Update GHASH with the ciphertext blocks, without reducing.
vmovdqu8 zmm30,ZMMWORD[rsi]
vpshufb zmm0,zmm0,zmm8
vpxord zmm0,zmm0,zmm10
vpclmulqdq zmm7,zmm0,zmm30,0x00 ; a_L * b_L
vpclmulqdq zmm1,zmm0,zmm30,0x01 ; a_L * b_H
vpclmulqdq zmm2,zmm0,zmm30,0x10 ; a_H * b_L
vpclmulqdq zmm3,zmm0,zmm30,0x11 ; a_H * b_H
vpxord zmm4,zmm4,zmm7
vpternlogd zmm5,zmm1,zmm2,0x96
vpxord zmm6,zmm6,zmm3
vpxor xmm10,xmm10,xmm10
add rsi,64
add rcx,64
add rdx,64
sub r8,64
cmp r8,64
jae NEAR $L$crypt_loop_1x__func1
test r8,r8
jz NEAR $L$reduce__func1
$L$partial_vec__func1:
; Process a partial vector of length 1 <= DATALEN < 64.
; Set the data mask %k1 to DATALEN 1's.
; Set the key powers mask %k2 to round_up(DATALEN, 16) 1's.
mov rax,-1
bzhi rax,rax,r8
kmovq k1,rax
add r8,15
and r8,-16
mov rax,-1
bzhi rax,rax,r8
kmovq k2,rax
; Encrypt one last vector of counter blocks. This does not need to be
; masked. The counter does not need to be incremented here.
vpshufb zmm0,zmm12,zmm8
vpxord zmm0,zmm0,zmm13
lea rax,[16+r9]
$L$vaesenc_loop_tail_partialvec__func1:
vbroadcasti32x4 zmm9,ZMMWORD[rax]
vaesenc zmm0,zmm0,zmm9
add rax,16
cmp r11,rax
jne NEAR $L$vaesenc_loop_tail_partialvec__func1
vaesenclast zmm0,zmm0,zmm14
; XOR the data with the appropriate number of keystream bytes.
vmovdqu8 zmm1{k1}{z},[rcx]
vpxord zmm0,zmm0,zmm1
vmovdqu8 ZMMWORD[rdx]{k1},zmm0
; Update GHASH with the ciphertext block(s), without reducing.
;
; In the case of DATALEN < 64, the ciphertext is zero-padded to 64
; bytes. (If decrypting, it's done by the above masked load. If
; encrypting, it's done by the below masked register-to-register move.)
; Note that if DATALEN <= 48, there will be additional padding beyond
; the padding of the last block specified by GHASH itself; i.e., there
; may be whole block(s) that get processed by the GHASH multiplication
; and reduction instructions but should not actually be included in the
; GHASH. However, any such blocks are all-zeroes, and the values that
; they're multiplied with are also all-zeroes. Therefore they just add
; 0 * 0 = 0 to the final GHASH result, which makes no difference.
vmovdqu8 zmm30{k2}{z},[rsi]
vmovdqu8 zmm1{k1}{z},zmm0
vpshufb zmm0,zmm1,zmm8
vpxord zmm0,zmm0,zmm10
vpclmulqdq zmm7,zmm0,zmm30,0x00 ; a_L * b_L
vpclmulqdq zmm1,zmm0,zmm30,0x01 ; a_L * b_H
vpclmulqdq zmm2,zmm0,zmm30,0x10 ; a_H * b_L
vpclmulqdq zmm3,zmm0,zmm30,0x11 ; a_H * b_H
vpxord zmm4,zmm4,zmm7
vpternlogd zmm5,zmm1,zmm2,0x96
vpxord zmm6,zmm6,zmm3
$L$reduce__func1:
; Finally, do the GHASH reduction.
vpclmulqdq zmm0,zmm31,zmm4,0x01
vpshufd zmm4,zmm4,0x4e
vpternlogd zmm5,zmm4,zmm0,0x96
vpclmulqdq zmm0,zmm31,zmm5,0x01
vpshufd zmm5,zmm5,0x4e
vpternlogd zmm6,zmm5,zmm0,0x96
vextracti32x4 xmm0,zmm6,1
vextracti32x4 xmm1,zmm6,2
vextracti32x4 xmm2,zmm6,3
vpxord xmm10,xmm6,xmm0
vpternlogd xmm10,xmm2,xmm1,0x96
$L$done__func1:
; Store the updated GHASH accumulator back to memory.
vpshufb xmm10,xmm10,xmm8
vmovdqu XMMWORD[r12],xmm10
vzeroupper ; This is needed after using ymm or zmm registers.
vmovdqa xmm6,XMMWORD[rsp]
vmovdqa xmm7,XMMWORD[16+rsp]
vmovdqa xmm8,XMMWORD[32+rsp]
vmovdqa xmm9,XMMWORD[48+rsp]
vmovdqa xmm10,XMMWORD[64+rsp]
vmovdqa xmm11,XMMWORD[80+rsp]
vmovdqa xmm12,XMMWORD[96+rsp]
vmovdqa xmm13,XMMWORD[112+rsp]
vmovdqa xmm14,XMMWORD[128+rsp]
vmovdqa xmm15,XMMWORD[144+rsp]
add rsp,160
pop r12
pop rdi
pop rsi
ret
$L$SEH_end_aes_gcm_enc_update_vaes_avx512_17:
global aes_gcm_dec_update_vaes_avx512
ALIGN 32
aes_gcm_dec_update_vaes_avx512:
$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1:
_CET_ENDBR
push rsi
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_2:
push rdi
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_3:
push r12
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_4:
mov rsi,QWORD[64+rsp] ; arg5
mov rdi,QWORD[72+rsp] ; arg6
mov r12,QWORD[80+rsp] ; arg7
sub rsp,160
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_5:
vmovdqa XMMWORD[rsp],xmm6
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_6:
vmovdqa XMMWORD[16+rsp],xmm7
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_7:
vmovdqa XMMWORD[32+rsp],xmm8
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_8:
vmovdqa XMMWORD[48+rsp],xmm9
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_9:
vmovdqa XMMWORD[64+rsp],xmm10
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_10:
vmovdqa XMMWORD[80+rsp],xmm11
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_11:
vmovdqa XMMWORD[96+rsp],xmm12
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_12:
vmovdqa XMMWORD[112+rsp],xmm13
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_13:
vmovdqa XMMWORD[128+rsp],xmm14
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_14:
vmovdqa XMMWORD[144+rsp],xmm15
$L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_15:
$L$SEH_endprologue_aes_gcm_dec_update_vaes_avx512_16:
; Load some constants.
vbroadcasti32x4 zmm8,ZMMWORD[$L$bswap_mask]
vbroadcasti32x4 zmm31,ZMMWORD[$L$gfpoly]
; Load the GHASH accumulator and the starting counter.
; BoringSSL passes these values in big endian format.
vmovdqu xmm10,XMMWORD[r12]
vpshufb xmm10,xmm10,xmm8
vbroadcasti32x4 zmm12,ZMMWORD[rsi]
vpshufb zmm12,zmm12,zmm8
; Load the AES key length in bytes. BoringSSL stores number of rounds
; minus 1, so convert using: AESKEYLEN = 4 * aeskey->rounds - 20.
mov r10d,DWORD[240+r9]
lea r10d,[((-20))+r10*4]
; Make RNDKEYLAST_PTR point to the last AES round key. This is the
; round key with index 10, 12, or 14 for AES-128, AES-192, or AES-256
; respectively. Then load the zero-th and last round keys.
lea r11,[96+r10*4+r9]
vbroadcasti32x4 zmm13,ZMMWORD[r9]
vbroadcasti32x4 zmm14,ZMMWORD[r11]
; Finish initializing LE_CTR by adding [0, 1, 2, 3] to its low words.
vpaddd zmm12,zmm12,ZMMWORD[$L$ctr_pattern]
; Load 4 into all 128-bit lanes of LE_CTR_INC.
vbroadcasti32x4 zmm11,ZMMWORD[$L$inc_4blocks]
; If there are at least 256 bytes of data, then continue into the loop
; that processes 256 bytes of data at a time. Otherwise skip it.
cmp r8,256
jb NEAR $L$crypt_loop_4x_done__func2
; Load powers of the hash key.
vmovdqu8 zmm27,ZMMWORD[((256-256))+rdi]
vmovdqu8 zmm28,ZMMWORD[((256-192))+rdi]
vmovdqu8 zmm29,ZMMWORD[((256-128))+rdi]
vmovdqu8 zmm30,ZMMWORD[((256-64))+rdi]
; Cache as many additional AES round keys as possible.
vbroadcasti32x4 zmm15,ZMMWORD[((-144))+r11]
vbroadcasti32x4 zmm16,ZMMWORD[((-128))+r11]
vbroadcasti32x4 zmm17,ZMMWORD[((-112))+r11]
vbroadcasti32x4 zmm18,ZMMWORD[((-96))+r11]
vbroadcasti32x4 zmm19,ZMMWORD[((-80))+r11]
vbroadcasti32x4 zmm20,ZMMWORD[((-64))+r11]
vbroadcasti32x4 zmm21,ZMMWORD[((-48))+r11]
vbroadcasti32x4 zmm22,ZMMWORD[((-32))+r11]
vbroadcasti32x4 zmm23,ZMMWORD[((-16))+r11]
$L$crypt_loop_4x__func2:
vmovdqu8 zmm4,ZMMWORD[rcx]
vmovdqu8 zmm5,ZMMWORD[64+rcx]
vmovdqu8 zmm6,ZMMWORD[128+rcx]
vmovdqu8 zmm7,ZMMWORD[192+rcx]
; Start the AES encryption of the counter blocks.
; Increment le_ctr four times to generate four vectors of little-endian
; counter blocks, swap each to big-endian, and store them in aesdata[0-3].
vpshufb zmm0,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm1,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm2,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpshufb zmm3,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
; AES "round zero": XOR in the zero-th round key.
vpxord zmm0,zmm0,zmm13
vpxord zmm1,zmm1,zmm13
vpxord zmm2,zmm2,zmm13
vpxord zmm3,zmm3,zmm13
cmp r10d,24
jl NEAR $L$aes128__func2
je NEAR $L$aes192__func2
; AES-256
vbroadcasti32x4 zmm9,ZMMWORD[((-208))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
vbroadcasti32x4 zmm9,ZMMWORD[((-192))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
$L$aes192__func2:
vbroadcasti32x4 zmm9,ZMMWORD[((-176))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
vbroadcasti32x4 zmm9,ZMMWORD[((-160))+r11]
vaesenc zmm0,zmm0,zmm9
vaesenc zmm1,zmm1,zmm9
vaesenc zmm2,zmm2,zmm9
vaesenc zmm3,zmm3,zmm9
$L$aes128__func2:
; Prefetch the source data 512 bytes ahead into the L1 data cache, to
; improve performance when the hardware prefetcher is disabled. Assumes the
; L1 data cache line size is 64 bytes (de facto standard on x86_64).
prefetcht0 [((512+0))+rcx]
prefetcht0 [((512+64))+rcx]
prefetcht0 [((512+128))+rcx]
prefetcht0 [((512+192))+rcx]
; Finish the AES encryption of the counter blocks in AESDATA[0-3],
; interleaved with the GHASH update of the ciphertext blocks in
; GHASHDATA[0-3].
vpshufb zmm4,zmm4,zmm8
vpxord zmm4,zmm4,zmm10
vpshufb zmm5,zmm5,zmm8
vpshufb zmm6,zmm6,zmm8
vaesenc zmm0,zmm0,zmm15
vaesenc zmm1,zmm1,zmm15
vaesenc zmm2,zmm2,zmm15
vaesenc zmm3,zmm3,zmm15
vpshufb zmm7,zmm7,zmm8
vpclmulqdq zmm10,zmm4,zmm27,0x00 ; LO_0
vpclmulqdq zmm24,zmm5,zmm28,0x00 ; LO_1
vpclmulqdq zmm25,zmm6,zmm29,0x00 ; LO_2
vaesenc zmm0,zmm0,zmm16
vaesenc zmm1,zmm1,zmm16
vaesenc zmm2,zmm2,zmm16
vaesenc zmm3,zmm3,zmm16
vpxord zmm10,zmm10,zmm24 ; sum(LO_{1,0})
vpclmulqdq zmm26,zmm7,zmm30,0x00 ; LO_3
vpternlogd zmm10,zmm25,zmm26,0x96 ; LO = sum(LO_{3,2,1,0})
vpclmulqdq zmm24,zmm4,zmm27,0x01 ; MI_0
vaesenc zmm0,zmm0,zmm17
vaesenc zmm1,zmm1,zmm17
vaesenc zmm2,zmm2,zmm17
vaesenc zmm3,zmm3,zmm17
vpclmulqdq zmm25,zmm5,zmm28,0x01 ; MI_1
vpclmulqdq zmm26,zmm6,zmm29,0x01 ; MI_2
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{2,1,0})
vpclmulqdq zmm25,zmm7,zmm30,0x01 ; MI_3
vaesenc zmm0,zmm0,zmm18
vaesenc zmm1,zmm1,zmm18
vaesenc zmm2,zmm2,zmm18
vaesenc zmm3,zmm3,zmm18
vpclmulqdq zmm26,zmm4,zmm27,0x10 ; MI_4
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{4,3,2,1,0})
vpclmulqdq zmm25,zmm5,zmm28,0x10 ; MI_5
vpclmulqdq zmm26,zmm6,zmm29,0x10 ; MI_6
vaesenc zmm0,zmm0,zmm19
vaesenc zmm1,zmm1,zmm19
vaesenc zmm2,zmm2,zmm19
vaesenc zmm3,zmm3,zmm19
vpternlogd zmm24,zmm25,zmm26,0x96 ; sum(MI_{6,5,4,3,2,1,0})
vpclmulqdq zmm26,zmm31,zmm10,0x01 ; LO_L*(x^63 + x^62 + x^57)
vpclmulqdq zmm25,zmm7,zmm30,0x10 ; MI_7
vpxord zmm24,zmm24,zmm25 ; MI = sum(MI_{7,6,5,4,3,2,1,0})
vaesenc zmm0,zmm0,zmm20
vaesenc zmm1,zmm1,zmm20
vaesenc zmm2,zmm2,zmm20
vaesenc zmm3,zmm3,zmm20
vpshufd zmm10,zmm10,0x4e ; Swap halves of LO
vpclmulqdq zmm4,zmm4,zmm27,0x11 ; HI_0
vpclmulqdq zmm5,zmm5,zmm28,0x11 ; HI_1
vpclmulqdq zmm6,zmm6,zmm29,0x11 ; HI_2
vaesenc zmm0,zmm0,zmm21
vaesenc zmm1,zmm1,zmm21
vaesenc zmm2,zmm2,zmm21
vaesenc zmm3,zmm3,zmm21
vpternlogd zmm24,zmm10,zmm26,0x96 ; Fold LO into MI
vpclmulqdq zmm7,zmm7,zmm30,0x11 ; HI_3
vpternlogd zmm4,zmm5,zmm6,0x96 ; sum(HI_{2,1,0})
vpclmulqdq zmm25,zmm31,zmm24,0x01 ; MI_L*(x^63 + x^62 + x^57)
vaesenc zmm0,zmm0,zmm22
vaesenc zmm1,zmm1,zmm22
vaesenc zmm2,zmm2,zmm22
vaesenc zmm3,zmm3,zmm22
vpxord zmm10,zmm4,zmm7 ; HI = sum(HI_{3,2,1,0})
vpshufd zmm24,zmm24,0x4e ; Swap halves of MI
vpternlogd zmm10,zmm24,zmm25,0x96 ; Fold MI into HI
vaesenc zmm0,zmm0,zmm23
vaesenc zmm1,zmm1,zmm23
vaesenc zmm2,zmm2,zmm23
vaesenc zmm3,zmm3,zmm23
vextracti32x4 xmm4,zmm10,1
vextracti32x4 xmm5,zmm10,2
vextracti32x4 xmm6,zmm10,3
vpxord xmm10,xmm10,xmm4
vpternlogd xmm10,xmm6,xmm5,0x96
vpxord zmm4,zmm14,ZMMWORD[rcx]
vpxord zmm5,zmm14,ZMMWORD[64+rcx]
vpxord zmm6,zmm14,ZMMWORD[128+rcx]
vpxord zmm7,zmm14,ZMMWORD[192+rcx]
vaesenclast zmm4,zmm0,zmm4
vaesenclast zmm5,zmm1,zmm5
vaesenclast zmm6,zmm2,zmm6
vaesenclast zmm7,zmm3,zmm7
vmovdqu8 ZMMWORD[rdx],zmm4
vmovdqu8 ZMMWORD[64+rdx],zmm5
vmovdqu8 ZMMWORD[128+rdx],zmm6
vmovdqu8 ZMMWORD[192+rdx],zmm7
add rcx,256
add rdx,256
sub r8,256
cmp r8,256
jae NEAR $L$crypt_loop_4x__func2
$L$crypt_loop_4x_done__func2:
; Check whether any data remains.
test r8,r8
jz NEAR $L$done__func2
; The data length isn't a multiple of 256 bytes. Process the remaining
; data of length 1 <= DATALEN < 256, up to one 64-byte vector at a time.
; Going one vector at a time may seem inefficient compared to having
; separate code paths for each possible number of vectors remaining.
; However, using a loop keeps the code size down, and it performs
; surprising well; modern CPUs will start executing the next iteration
; before the previous one finishes and also predict the number of loop
; iterations. For a similar reason, we roll up the AES rounds.
;
; On the last iteration, the remaining length may be less than 64 bytes.
; Handle this using masking.
;
; Since there are enough key powers available for all remaining data,
; there is no need to do a GHASH reduction after each iteration.
; Instead, multiply each remaining block by its own key power, and only
; do a GHASH reduction at the very end.
; Make POWERS_PTR point to the key powers [H^N, H^(N-1), ...] where N
; is the number of blocks that remain.
mov rax,r8
neg rax
and rax,-16 ; -round_up(DATALEN, 16)
lea rsi,[256+rax*1+rdi]
vpxor xmm4,xmm4,xmm4
vpxor xmm5,xmm5,xmm5
vpxor xmm6,xmm6,xmm6
cmp r8,64
jb NEAR $L$partial_vec__func2
$L$crypt_loop_1x__func2:
; Process a full 64-byte vector.
; Encrypt a vector of counter blocks.
vpshufb zmm0,zmm12,zmm8
vpaddd zmm12,zmm12,zmm11
vpxord zmm0,zmm0,zmm13
lea rax,[16+r9]
$L$vaesenc_loop_tail_full_vec__func2:
vbroadcasti32x4 zmm9,ZMMWORD[rax]
vaesenc zmm0,zmm0,zmm9
add rax,16
cmp r11,rax
jne NEAR $L$vaesenc_loop_tail_full_vec__func2
vaesenclast zmm0,zmm0,zmm14
; XOR the data with the vector of keystream blocks.
vmovdqu8 zmm1,ZMMWORD[rcx]
vpxord zmm0,zmm0,zmm1
vmovdqu8 ZMMWORD[rdx],zmm0
; Update GHASH with the ciphertext blocks, without reducing.
vmovdqu8 zmm30,ZMMWORD[rsi]
vpshufb zmm0,zmm1,zmm8
vpxord zmm0,zmm0,zmm10
vpclmulqdq zmm7,zmm0,zmm30,0x00 ; a_L * b_L
vpclmulqdq zmm1,zmm0,zmm30,0x01 ; a_L * b_H
vpclmulqdq zmm2,zmm0,zmm30,0x10 ; a_H * b_L
vpclmulqdq zmm3,zmm0,zmm30,0x11 ; a_H * b_H
vpxord zmm4,zmm4,zmm7
vpternlogd zmm5,zmm1,zmm2,0x96
vpxord zmm6,zmm6,zmm3
vpxor xmm10,xmm10,xmm10
add rsi,64
add rcx,64
add rdx,64
sub r8,64
cmp r8,64
jae NEAR $L$crypt_loop_1x__func2
test r8,r8
jz NEAR $L$reduce__func2
$L$partial_vec__func2:
; Process a partial vector of length 1 <= DATALEN < 64.
; Set the data mask %k1 to DATALEN 1's.
; Set the key powers mask %k2 to round_up(DATALEN, 16) 1's.
mov rax,-1
bzhi rax,rax,r8
kmovq k1,rax
add r8,15
and r8,-16
mov rax,-1
bzhi rax,rax,r8
kmovq k2,rax
; Encrypt one last vector of counter blocks. This does not need to be
; masked. The counter does not need to be incremented here.
vpshufb zmm0,zmm12,zmm8
vpxord zmm0,zmm0,zmm13
lea rax,[16+r9]
$L$vaesenc_loop_tail_partialvec__func2:
vbroadcasti32x4 zmm9,ZMMWORD[rax]
vaesenc zmm0,zmm0,zmm9
add rax,16
cmp r11,rax
jne NEAR $L$vaesenc_loop_tail_partialvec__func2
vaesenclast zmm0,zmm0,zmm14
; XOR the data with the appropriate number of keystream bytes.
vmovdqu8 zmm1{k1}{z},[rcx]
vpxord zmm0,zmm0,zmm1
vmovdqu8 ZMMWORD[rdx]{k1},zmm0
; Update GHASH with the ciphertext block(s), without reducing.
;
; In the case of DATALEN < 64, the ciphertext is zero-padded to 64
; bytes. (If decrypting, it's done by the above masked load. If
; encrypting, it's done by the below masked register-to-register move.)
; Note that if DATALEN <= 48, there will be additional padding beyond
; the padding of the last block specified by GHASH itself; i.e., there
; may be whole block(s) that get processed by the GHASH multiplication
; and reduction instructions but should not actually be included in the
; GHASH. However, any such blocks are all-zeroes, and the values that
; they're multiplied with are also all-zeroes. Therefore they just add
; 0 * 0 = 0 to the final GHASH result, which makes no difference.
vmovdqu8 zmm30{k2}{z},[rsi]
vpshufb zmm0,zmm1,zmm8
vpxord zmm0,zmm0,zmm10
vpclmulqdq zmm7,zmm0,zmm30,0x00 ; a_L * b_L
vpclmulqdq zmm1,zmm0,zmm30,0x01 ; a_L * b_H
vpclmulqdq zmm2,zmm0,zmm30,0x10 ; a_H * b_L
vpclmulqdq zmm3,zmm0,zmm30,0x11 ; a_H * b_H
vpxord zmm4,zmm4,zmm7
vpternlogd zmm5,zmm1,zmm2,0x96
vpxord zmm6,zmm6,zmm3
$L$reduce__func2:
; Finally, do the GHASH reduction.
vpclmulqdq zmm0,zmm31,zmm4,0x01
vpshufd zmm4,zmm4,0x4e
vpternlogd zmm5,zmm4,zmm0,0x96
vpclmulqdq zmm0,zmm31,zmm5,0x01
vpshufd zmm5,zmm5,0x4e
vpternlogd zmm6,zmm5,zmm0,0x96
vextracti32x4 xmm0,zmm6,1
vextracti32x4 xmm1,zmm6,2
vextracti32x4 xmm2,zmm6,3
vpxord xmm10,xmm6,xmm0
vpternlogd xmm10,xmm2,xmm1,0x96
$L$done__func2:
; Store the updated GHASH accumulator back to memory.
vpshufb xmm10,xmm10,xmm8
vmovdqu XMMWORD[r12],xmm10
vzeroupper ; This is needed after using ymm or zmm registers.
vmovdqa xmm6,XMMWORD[rsp]
vmovdqa xmm7,XMMWORD[16+rsp]
vmovdqa xmm8,XMMWORD[32+rsp]
vmovdqa xmm9,XMMWORD[48+rsp]
vmovdqa xmm10,XMMWORD[64+rsp]
vmovdqa xmm11,XMMWORD[80+rsp]
vmovdqa xmm12,XMMWORD[96+rsp]
vmovdqa xmm13,XMMWORD[112+rsp]
vmovdqa xmm14,XMMWORD[128+rsp]
vmovdqa xmm15,XMMWORD[144+rsp]
add rsp,160
pop r12
pop rdi
pop rsi
ret
$L$SEH_end_aes_gcm_dec_update_vaes_avx512_17:
section .pdata rdata align=4
ALIGN 4
DD $L$SEH_begin_gcm_gmult_vpclmulqdq_avx512_1 wrt ..imagebase
DD $L$SEH_end_gcm_gmult_vpclmulqdq_avx512_5 wrt ..imagebase
DD $L$SEH_info_gcm_gmult_vpclmulqdq_avx512_0 wrt ..imagebase
DD $L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1 wrt ..imagebase
DD $L$SEH_end_gcm_ghash_vpclmulqdq_avx512_12 wrt ..imagebase
DD $L$SEH_info_gcm_ghash_vpclmulqdq_avx512_0 wrt ..imagebase
DD $L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1 wrt ..imagebase
DD $L$SEH_end_aes_gcm_enc_update_vaes_avx512_17 wrt ..imagebase
DD $L$SEH_info_aes_gcm_enc_update_vaes_avx512_0 wrt ..imagebase
DD $L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1 wrt ..imagebase
DD $L$SEH_end_aes_gcm_dec_update_vaes_avx512_17 wrt ..imagebase
DD $L$SEH_info_aes_gcm_dec_update_vaes_avx512_0 wrt ..imagebase
section .xdata rdata align=8
ALIGN 4
$L$SEH_info_gcm_gmult_vpclmulqdq_avx512_0:
DB 1 ; version 1, no flags
DB $L$SEH_endprologue_gcm_gmult_vpclmulqdq_avx512_4-$L$SEH_begin_gcm_gmult_vpclmulqdq_avx512_1
DB 3
DB 0
DB $L$SEH_prologue_gcm_gmult_vpclmulqdq_avx512_3-$L$SEH_begin_gcm_gmult_vpclmulqdq_avx512_1
DB 104
DW 0
DB $L$SEH_prologue_gcm_gmult_vpclmulqdq_avx512_2-$L$SEH_begin_gcm_gmult_vpclmulqdq_avx512_1
DB 34
DW 0
$L$SEH_info_gcm_ghash_vpclmulqdq_avx512_0:
DB 1 ; version 1, no flags
DB $L$SEH_endprologue_gcm_ghash_vpclmulqdq_avx512_11-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 18
DB 0
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_10-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 216
DW 7
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_9-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 200
DW 6
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_8-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 184
DW 5
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_7-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 168
DW 4
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_6-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 152
DW 3
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_5-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 136
DW 2
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_4-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 120
DW 1
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_3-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 104
DW 0
DB $L$SEH_prologue_gcm_ghash_vpclmulqdq_avx512_2-$L$SEH_begin_gcm_ghash_vpclmulqdq_avx512_1
DB 1
DW 17
$L$SEH_info_aes_gcm_enc_update_vaes_avx512_0:
DB 1 ; version 1, no flags
DB $L$SEH_endprologue_aes_gcm_enc_update_vaes_avx512_16-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 25
DB 0
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_15-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 248
DW 9
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_14-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 232
DW 8
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_13-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 216
DW 7
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_12-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 200
DW 6
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_11-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 184
DW 5
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_10-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 168
DW 4
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_9-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 152
DW 3
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_8-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 136
DW 2
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_7-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 120
DW 1
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_6-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 104
DW 0
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_5-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 1
DW 20
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_4-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 192
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_3-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 112
DB $L$SEH_prologue_aes_gcm_enc_update_vaes_avx512_2-$L$SEH_begin_aes_gcm_enc_update_vaes_avx512_1
DB 96
DW 0
$L$SEH_info_aes_gcm_dec_update_vaes_avx512_0:
DB 1 ; version 1, no flags
DB $L$SEH_endprologue_aes_gcm_dec_update_vaes_avx512_16-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 25
DB 0
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_15-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 248
DW 9
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_14-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 232
DW 8
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_13-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 216
DW 7
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_12-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 200
DW 6
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_11-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 184
DW 5
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_10-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 168
DW 4
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_9-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 152
DW 3
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_8-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 136
DW 2
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_7-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 120
DW 1
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_6-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 104
DW 0
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_5-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 1
DW 20
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_4-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 192
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_3-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 112
DB $L$SEH_prologue_aes_gcm_dec_update_vaes_avx512_2-$L$SEH_begin_aes_gcm_dec_update_vaes_avx512_1
DB 96
DW 0
%else
; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738
ret
%endif