michael@0: # LICENSE: michael@0: # This submission to NSS is to be made available under the terms of the michael@0: # Mozilla Public License, v. 2.0. You can obtain one at http: michael@0: # //mozilla.org/MPL/2.0/. michael@0: ################################################################################ michael@0: # Copyright(c) 2012, Intel Corp. michael@0: michael@0: .align 16 michael@0: .Lone: michael@0: .quad 1,0 michael@0: .Ltwo: michael@0: .quad 2,0 michael@0: .Lbswap_mask: michael@0: .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 michael@0: .Lshuff_mask: michael@0: .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f michael@0: .Lpoly: michael@0: .quad 0x1, 0xc200000000000000 michael@0: michael@0: michael@0: ################################################################################ michael@0: # Generates the final GCM tag michael@0: # void intel_aes_gcmTAG(uint8_t Htbl[16*16], uint8_t *Tp, uint64_t Mlen, uint64_t Alen, uint8_t* X0, uint8_t* TAG); michael@0: .type intel_aes_gcmTAG,@function michael@0: .globl intel_aes_gcmTAG michael@0: .align 16 michael@0: intel_aes_gcmTAG: michael@0: michael@0: .set Htbl, %rdi michael@0: .set Tp, %rsi michael@0: .set Mlen, %rdx michael@0: .set Alen, %rcx michael@0: .set X0, %r8 michael@0: .set TAG, %r9 michael@0: michael@0: .set T,%xmm0 michael@0: .set TMP0,%xmm1 michael@0: michael@0: vmovdqu (Tp), T michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: vpxor TMP0, TMP0, TMP0 michael@0: shl $3, Mlen michael@0: shl $3, Alen michael@0: vpinsrq $0, Mlen, TMP0, TMP0 michael@0: vpinsrq $1, Alen, TMP0, TMP0 michael@0: vpxor TMP0, T, T michael@0: vmovdqu (Htbl), TMP0 michael@0: call GFMUL michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: vpxor (X0), T, T michael@0: vmovdqu T, (TAG) michael@0: michael@0: ret michael@0: .size intel_aes_gcmTAG, .-intel_aes_gcmTAG michael@0: ################################################################################ michael@0: # Generates the H table michael@0: # void intel_aes_gcmINIT(uint8_t Htbl[16*16], uint8_t *KS, int NR); michael@0: .type intel_aes_gcmINIT,@function michael@0: .globl intel_aes_gcmINIT michael@0: .align 16 michael@0: intel_aes_gcmINIT: michael@0: michael@0: .set Htbl, %rdi michael@0: .set KS, %rsi michael@0: .set NR, %edx michael@0: michael@0: .set T,%xmm0 michael@0: .set TMP0,%xmm1 michael@0: michael@0: CALCULATE_POWERS_OF_H: michael@0: vmovdqu 16*0(KS), T michael@0: vaesenc 16*1(KS), T, T michael@0: vaesenc 16*2(KS), T, T michael@0: vaesenc 16*3(KS), T, T michael@0: vaesenc 16*4(KS), T, T michael@0: vaesenc 16*5(KS), T, T michael@0: vaesenc 16*6(KS), T, T michael@0: vaesenc 16*7(KS), T, T michael@0: vaesenc 16*8(KS), T, T michael@0: vaesenc 16*9(KS), T, T michael@0: vmovdqu 16*10(KS), TMP0 michael@0: cmp $10, NR michael@0: je .LH0done michael@0: vaesenc 16*10(KS), T, T michael@0: vaesenc 16*11(KS), T, T michael@0: vmovdqu 16*12(KS), TMP0 michael@0: cmp $12, NR michael@0: je .LH0done michael@0: vaesenc 16*12(KS), T, T michael@0: vaesenc 16*13(KS), T, T michael@0: vmovdqu 16*14(KS), TMP0 michael@0: michael@0: .LH0done: michael@0: vaesenclast TMP0, T, T michael@0: michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: michael@0: vmovdqu T, TMP0 michael@0: # Calculate H` = GFMUL(H, 2) michael@0: vpsrld $7 , T , %xmm3 michael@0: vmovdqu .Lshuff_mask(%rip), %xmm4 michael@0: vpshufb %xmm4, %xmm3 , %xmm3 michael@0: movq $0xff00 , %rax michael@0: vmovq %rax, %xmm4 michael@0: vpshufb %xmm3, %xmm4 , %xmm4 michael@0: vmovdqu .Lpoly(%rip), %xmm5 michael@0: vpand %xmm4, %xmm5, %xmm5 michael@0: vpsrld $31, T, %xmm3 michael@0: vpslld $1, T, %xmm4 michael@0: vpslldq $4, %xmm3, %xmm3 michael@0: vpxor %xmm3, %xmm4, T #xmm1 holds now p(x)<<1 michael@0: michael@0: #adding p(x)<<1 to xmm5 michael@0: vpxor %xmm5, T , T michael@0: vmovdqu T, TMP0 michael@0: vmovdqu T, (Htbl) # H * 2 michael@0: call GFMUL michael@0: vmovdqu T, 16(Htbl) # H^2 * 2 michael@0: call GFMUL michael@0: vmovdqu T, 32(Htbl) # H^3 * 2 michael@0: call GFMUL michael@0: vmovdqu T, 48(Htbl) # H^4 * 2 michael@0: call GFMUL michael@0: vmovdqu T, 64(Htbl) # H^5 * 2 michael@0: call GFMUL michael@0: vmovdqu T, 80(Htbl) # H^6 * 2 michael@0: call GFMUL michael@0: vmovdqu T, 96(Htbl) # H^7 * 2 michael@0: call GFMUL michael@0: vmovdqu T, 112(Htbl) # H^8 * 2 michael@0: michael@0: # Precalculations for the reduce 4 step michael@0: vpshufd $78, (Htbl), %xmm8 michael@0: vpshufd $78, 16(Htbl), %xmm9 michael@0: vpshufd $78, 32(Htbl), %xmm10 michael@0: vpshufd $78, 48(Htbl), %xmm11 michael@0: vpshufd $78, 64(Htbl), %xmm12 michael@0: vpshufd $78, 80(Htbl), %xmm13 michael@0: vpshufd $78, 96(Htbl), %xmm14 michael@0: vpshufd $78, 112(Htbl), %xmm15 michael@0: michael@0: vpxor (Htbl), %xmm8, %xmm8 michael@0: vpxor 16(Htbl), %xmm9, %xmm9 michael@0: vpxor 32(Htbl), %xmm10, %xmm10 michael@0: vpxor 48(Htbl), %xmm11, %xmm11 michael@0: vpxor 64(Htbl), %xmm12, %xmm12 michael@0: vpxor 80(Htbl), %xmm13, %xmm13 michael@0: vpxor 96(Htbl), %xmm14, %xmm14 michael@0: vpxor 112(Htbl), %xmm15, %xmm15 michael@0: michael@0: vmovdqu %xmm8, 128(Htbl) michael@0: vmovdqu %xmm9, 144(Htbl) michael@0: vmovdqu %xmm10, 160(Htbl) michael@0: vmovdqu %xmm11, 176(Htbl) michael@0: vmovdqu %xmm12, 192(Htbl) michael@0: vmovdqu %xmm13, 208(Htbl) michael@0: vmovdqu %xmm14, 224(Htbl) michael@0: vmovdqu %xmm15, 240(Htbl) michael@0: michael@0: ret michael@0: .size intel_aes_gcmINIT, .-intel_aes_gcmINIT michael@0: ################################################################################ michael@0: # Authenticate only michael@0: # void intel_aes_gcmAAD(uint8_t Htbl[16*16], uint8_t *AAD, uint64_t Alen, uint8_t *Tp); michael@0: michael@0: .globl intel_aes_gcmAAD michael@0: .type intel_aes_gcmAAD,@function michael@0: .align 16 michael@0: intel_aes_gcmAAD: michael@0: michael@0: .set DATA, %xmm0 michael@0: .set T, %xmm1 michael@0: .set BSWAP_MASK, %xmm2 michael@0: .set TMP0, %xmm3 michael@0: .set TMP1, %xmm4 michael@0: .set TMP2, %xmm5 michael@0: .set TMP3, %xmm6 michael@0: .set TMP4, %xmm7 michael@0: .set Xhi, %xmm9 michael@0: michael@0: .set Htbl, %rdi michael@0: .set inp, %rsi michael@0: .set len, %rdx michael@0: .set Tp, %rcx michael@0: michael@0: .set hlp0, %r11 michael@0: michael@0: .macro KARATSUBA_AAD i michael@0: vpclmulqdq $0x00, 16*\i(Htbl), DATA, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: vpclmulqdq $0x11, 16*\i(Htbl), DATA, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpshufd $78, DATA, TMP3 michael@0: vpxor DATA, TMP3, TMP3 michael@0: vpclmulqdq $0x00, 16*(\i+8)(Htbl), TMP3, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: .endm michael@0: michael@0: test len, len michael@0: jnz .LbeginAAD michael@0: ret michael@0: michael@0: .LbeginAAD: michael@0: michael@0: push hlp0 michael@0: vzeroupper michael@0: michael@0: vmovdqa .Lbswap_mask(%rip), BSWAP_MASK michael@0: michael@0: vpxor Xhi, Xhi, Xhi michael@0: michael@0: vmovdqu (Tp),T michael@0: vpshufb BSWAP_MASK,T,T michael@0: michael@0: # we hash 8 block each iteration, if the total amount of blocks is not a multiple of 8, we hash the first n%8 blocks first michael@0: mov len, hlp0 michael@0: and $~-128, hlp0 michael@0: michael@0: jz .Lmod_loop michael@0: michael@0: sub hlp0, len michael@0: sub $16, hlp0 michael@0: michael@0: #hash first prefix block michael@0: vmovdqu (inp), DATA michael@0: vpshufb BSWAP_MASK, DATA, DATA michael@0: vpxor T, DATA, DATA michael@0: michael@0: vpclmulqdq $0x00, (Htbl, hlp0), DATA, TMP0 michael@0: vpclmulqdq $0x11, (Htbl, hlp0), DATA, TMP1 michael@0: vpshufd $78, DATA, TMP2 michael@0: vpxor DATA, TMP2, TMP2 michael@0: vpclmulqdq $0x00, 16*8(Htbl, hlp0), TMP2, TMP2 michael@0: michael@0: lea 16(inp), inp michael@0: test hlp0, hlp0 michael@0: jnz .Lpre_loop michael@0: jmp .Lred1 michael@0: michael@0: #hash remaining prefix bocks (up to 7 total prefix blocks) michael@0: .align 64 michael@0: .Lpre_loop: michael@0: michael@0: sub $16, hlp0 michael@0: michael@0: vmovdqu (inp),DATA # next data block michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: vpclmulqdq $0x00, (Htbl,hlp0), DATA, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: vpclmulqdq $0x11, (Htbl,hlp0), DATA, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpshufd $78, DATA, TMP3 michael@0: vpxor DATA, TMP3, TMP3 michael@0: vpclmulqdq $0x00, 16*8(Htbl,hlp0), TMP3, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: michael@0: test hlp0, hlp0 michael@0: michael@0: lea 16(inp), inp michael@0: michael@0: jnz .Lpre_loop michael@0: michael@0: .Lred1: michael@0: vpxor TMP0, TMP2, TMP2 michael@0: vpxor TMP1, TMP2, TMP2 michael@0: vpsrldq $8, TMP2, TMP3 michael@0: vpslldq $8, TMP2, TMP2 michael@0: michael@0: vpxor TMP3, TMP1, Xhi michael@0: vpxor TMP2, TMP0, T michael@0: michael@0: .align 64 michael@0: .Lmod_loop: michael@0: sub $0x80, len michael@0: jb .Ldone michael@0: michael@0: vmovdqu 16*7(inp),DATA # Ii michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: vpclmulqdq $0x00, (Htbl), DATA, TMP0 michael@0: vpclmulqdq $0x11, (Htbl), DATA, TMP1 michael@0: vpshufd $78, DATA, TMP2 michael@0: vpxor DATA, TMP2, TMP2 michael@0: vpclmulqdq $0x00, 16*8(Htbl), TMP2, TMP2 michael@0: ######################################################### michael@0: vmovdqu 16*6(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: KARATSUBA_AAD 1 michael@0: ######################################################### michael@0: vmovdqu 16*5(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: vpclmulqdq $0x10, .Lpoly(%rip), T, TMP4 #reduction stage 1a michael@0: vpalignr $8, T, T, T michael@0: michael@0: KARATSUBA_AAD 2 michael@0: michael@0: vpxor TMP4, T, T #reduction stage 1b michael@0: ######################################################### michael@0: vmovdqu 16*4(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: KARATSUBA_AAD 3 michael@0: ######################################################### michael@0: vmovdqu 16*3(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: vpclmulqdq $0x10, .Lpoly(%rip), T, TMP4 #reduction stage 2a michael@0: vpalignr $8, T, T, T michael@0: michael@0: KARATSUBA_AAD 4 michael@0: michael@0: vpxor TMP4, T, T #reduction stage 2b michael@0: ######################################################### michael@0: vmovdqu 16*2(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: KARATSUBA_AAD 5 michael@0: michael@0: vpxor Xhi, T, T #reduction finalize michael@0: ######################################################### michael@0: vmovdqu 16*1(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: michael@0: KARATSUBA_AAD 6 michael@0: ######################################################### michael@0: vmovdqu 16*0(inp),DATA michael@0: vpshufb BSWAP_MASK,DATA,DATA michael@0: vpxor T,DATA,DATA michael@0: michael@0: KARATSUBA_AAD 7 michael@0: ######################################################### michael@0: vpxor TMP0, TMP2, TMP2 # karatsuba fixup michael@0: vpxor TMP1, TMP2, TMP2 michael@0: vpsrldq $8, TMP2, TMP3 michael@0: vpslldq $8, TMP2, TMP2 michael@0: michael@0: vpxor TMP3, TMP1, Xhi michael@0: vpxor TMP2, TMP0, T michael@0: michael@0: lea 16*8(inp), inp michael@0: jmp .Lmod_loop michael@0: ######################################################### michael@0: michael@0: .Ldone: michael@0: vpclmulqdq $0x10, .Lpoly(%rip), T, TMP3 michael@0: vpalignr $8, T, T, T michael@0: vpxor TMP3, T, T michael@0: michael@0: vpclmulqdq $0x10, .Lpoly(%rip), T, TMP3 michael@0: vpalignr $8, T, T, T michael@0: vpxor TMP3, T, T michael@0: michael@0: vpxor Xhi, T, T michael@0: michael@0: .Lsave: michael@0: vpshufb BSWAP_MASK,T, T michael@0: vmovdqu T,(Tp) michael@0: vzeroupper michael@0: michael@0: pop hlp0 michael@0: ret michael@0: .size intel_aes_gcmAAD,.-intel_aes_gcmAAD michael@0: michael@0: ################################################################################ michael@0: # Encrypt and Authenticate michael@0: # void intel_aes_gcmENC(uint8_t* PT, uint8_t* CT, void *Gctx,uint64_t len); michael@0: .type intel_aes_gcmENC,@function michael@0: .globl intel_aes_gcmENC michael@0: .align 16 michael@0: intel_aes_gcmENC: michael@0: michael@0: .set PT,%rdi michael@0: .set CT,%rsi michael@0: .set Htbl, %rdx michael@0: .set len, %rcx michael@0: .set KS,%r9 michael@0: .set NR,%r10d michael@0: michael@0: .set Gctx, %rdx michael@0: michael@0: .set T,%xmm0 michael@0: .set TMP0,%xmm1 michael@0: .set TMP1,%xmm2 michael@0: .set TMP2,%xmm3 michael@0: .set TMP3,%xmm4 michael@0: .set TMP4,%xmm5 michael@0: .set TMP5,%xmm6 michael@0: .set CTR0,%xmm7 michael@0: .set CTR1,%xmm8 michael@0: .set CTR2,%xmm9 michael@0: .set CTR3,%xmm10 michael@0: .set CTR4,%xmm11 michael@0: .set CTR5,%xmm12 michael@0: .set CTR6,%xmm13 michael@0: .set CTR7,%xmm14 michael@0: .set CTR,%xmm15 michael@0: michael@0: .macro ROUND i michael@0: vmovdqu \i*16(KS), TMP3 michael@0: vaesenc TMP3, CTR0, CTR0 michael@0: vaesenc TMP3, CTR1, CTR1 michael@0: vaesenc TMP3, CTR2, CTR2 michael@0: vaesenc TMP3, CTR3, CTR3 michael@0: vaesenc TMP3, CTR4, CTR4 michael@0: vaesenc TMP3, CTR5, CTR5 michael@0: vaesenc TMP3, CTR6, CTR6 michael@0: vaesenc TMP3, CTR7, CTR7 michael@0: .endm michael@0: michael@0: .macro ROUNDMUL i michael@0: michael@0: vmovdqu \i*16(%rsp), TMP5 michael@0: vmovdqu \i*16(KS), TMP3 michael@0: michael@0: vaesenc TMP3, CTR0, CTR0 michael@0: vaesenc TMP3, CTR1, CTR1 michael@0: vaesenc TMP3, CTR2, CTR2 michael@0: vaesenc TMP3, CTR3, CTR3 michael@0: michael@0: vpshufd $78, TMP5, TMP4 michael@0: vpxor TMP5, TMP4, TMP4 michael@0: michael@0: vaesenc TMP3, CTR4, CTR4 michael@0: vaesenc TMP3, CTR5, CTR5 michael@0: vaesenc TMP3, CTR6, CTR6 michael@0: vaesenc TMP3, CTR7, CTR7 michael@0: michael@0: vpclmulqdq $0x00, 128+\i*16(Htbl), TMP4, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: vmovdqa \i*16(Htbl), TMP4 michael@0: vpclmulqdq $0x11, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpclmulqdq $0x00, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: michael@0: .endm michael@0: michael@0: .macro KARATSUBA i michael@0: vmovdqu \i*16(%rsp), TMP5 michael@0: michael@0: vpclmulqdq $0x11, 16*\i(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpclmulqdq $0x00, 16*\i(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vpclmulqdq $0x00, 128+\i*16(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: .endm michael@0: michael@0: test len, len michael@0: jnz .Lbegin michael@0: ret michael@0: michael@0: .Lbegin: michael@0: michael@0: vzeroupper michael@0: push %rbp michael@0: push %rbx michael@0: michael@0: movq %rsp, %rbp michael@0: sub $128, %rsp michael@0: andq $-16, %rsp michael@0: michael@0: vmovdqu 288(Gctx), CTR michael@0: vmovdqu 272(Gctx), T michael@0: mov 304(Gctx), KS michael@0: mov 4(KS), NR michael@0: lea 48(KS), KS michael@0: michael@0: vpshufb .Lbswap_mask(%rip), CTR, CTR michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: michael@0: cmp $128, len michael@0: jb .LDataSingles michael@0: michael@0: # Encrypt the first eight blocks michael@0: sub $128, len michael@0: vmovdqa CTR, CTR0 michael@0: vpaddd .Lone(%rip), CTR0, CTR1 michael@0: vpaddd .Ltwo(%rip), CTR0, CTR2 michael@0: vpaddd .Lone(%rip), CTR2, CTR3 michael@0: vpaddd .Ltwo(%rip), CTR2, CTR4 michael@0: vpaddd .Lone(%rip), CTR4, CTR5 michael@0: vpaddd .Ltwo(%rip), CTR4, CTR6 michael@0: vpaddd .Lone(%rip), CTR6, CTR7 michael@0: vpaddd .Ltwo(%rip), CTR6, CTR michael@0: michael@0: vpshufb .Lbswap_mask(%rip), CTR0, CTR0 michael@0: vpshufb .Lbswap_mask(%rip), CTR1, CTR1 michael@0: vpshufb .Lbswap_mask(%rip), CTR2, CTR2 michael@0: vpshufb .Lbswap_mask(%rip), CTR3, CTR3 michael@0: vpshufb .Lbswap_mask(%rip), CTR4, CTR4 michael@0: vpshufb .Lbswap_mask(%rip), CTR5, CTR5 michael@0: vpshufb .Lbswap_mask(%rip), CTR6, CTR6 michael@0: vpshufb .Lbswap_mask(%rip), CTR7, CTR7 michael@0: michael@0: vpxor (KS), CTR0, CTR0 michael@0: vpxor (KS), CTR1, CTR1 michael@0: vpxor (KS), CTR2, CTR2 michael@0: vpxor (KS), CTR3, CTR3 michael@0: vpxor (KS), CTR4, CTR4 michael@0: vpxor (KS), CTR5, CTR5 michael@0: vpxor (KS), CTR6, CTR6 michael@0: vpxor (KS), CTR7, CTR7 michael@0: michael@0: ROUND 1 michael@0: ROUND 2 michael@0: ROUND 3 michael@0: ROUND 4 michael@0: ROUND 5 michael@0: ROUND 6 michael@0: ROUND 7 michael@0: ROUND 8 michael@0: ROUND 9 michael@0: michael@0: vmovdqu 160(KS), TMP5 michael@0: cmp $12, NR michael@0: jb .LLast1 michael@0: michael@0: ROUND 10 michael@0: ROUND 11 michael@0: michael@0: vmovdqu 192(KS), TMP5 michael@0: cmp $14, NR michael@0: jb .LLast1 michael@0: michael@0: ROUND 12 michael@0: ROUND 13 michael@0: michael@0: vmovdqu 224(KS), TMP5 michael@0: michael@0: .LLast1: michael@0: michael@0: vpxor (PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR0, CTR0 michael@0: vpxor 16(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR1, CTR1 michael@0: vpxor 32(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR2, CTR2 michael@0: vpxor 48(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR3, CTR3 michael@0: vpxor 64(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR4, CTR4 michael@0: vpxor 80(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR5, CTR5 michael@0: vpxor 96(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR6, CTR6 michael@0: vpxor 112(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR7, CTR7 michael@0: michael@0: vmovdqu .Lbswap_mask(%rip), TMP3 michael@0: michael@0: vmovdqu CTR0, (CT) michael@0: vpshufb TMP3, CTR0, CTR0 michael@0: vmovdqu CTR1, 16(CT) michael@0: vpshufb TMP3, CTR1, CTR1 michael@0: vmovdqu CTR2, 32(CT) michael@0: vpshufb TMP3, CTR2, CTR2 michael@0: vmovdqu CTR3, 48(CT) michael@0: vpshufb TMP3, CTR3, CTR3 michael@0: vmovdqu CTR4, 64(CT) michael@0: vpshufb TMP3, CTR4, CTR4 michael@0: vmovdqu CTR5, 80(CT) michael@0: vpshufb TMP3, CTR5, CTR5 michael@0: vmovdqu CTR6, 96(CT) michael@0: vpshufb TMP3, CTR6, CTR6 michael@0: vmovdqu CTR7, 112(CT) michael@0: vpshufb TMP3, CTR7, CTR7 michael@0: michael@0: lea 128(CT), CT michael@0: lea 128(PT), PT michael@0: jmp .LDataOctets michael@0: michael@0: # Encrypt 8 blocks each time while hashing previous 8 blocks michael@0: .align 64 michael@0: .LDataOctets: michael@0: cmp $128, len michael@0: jb .LEndOctets michael@0: sub $128, len michael@0: michael@0: vmovdqa CTR7, TMP5 michael@0: vmovdqa CTR6, 1*16(%rsp) michael@0: vmovdqa CTR5, 2*16(%rsp) michael@0: vmovdqa CTR4, 3*16(%rsp) michael@0: vmovdqa CTR3, 4*16(%rsp) michael@0: vmovdqa CTR2, 5*16(%rsp) michael@0: vmovdqa CTR1, 6*16(%rsp) michael@0: vmovdqa CTR0, 7*16(%rsp) michael@0: michael@0: vmovdqa CTR, CTR0 michael@0: vpaddd .Lone(%rip), CTR0, CTR1 michael@0: vpaddd .Ltwo(%rip), CTR0, CTR2 michael@0: vpaddd .Lone(%rip), CTR2, CTR3 michael@0: vpaddd .Ltwo(%rip), CTR2, CTR4 michael@0: vpaddd .Lone(%rip), CTR4, CTR5 michael@0: vpaddd .Ltwo(%rip), CTR4, CTR6 michael@0: vpaddd .Lone(%rip), CTR6, CTR7 michael@0: vpaddd .Ltwo(%rip), CTR6, CTR michael@0: michael@0: vmovdqu (KS), TMP4 michael@0: vpshufb TMP3, CTR0, CTR0 michael@0: vpxor TMP4, CTR0, CTR0 michael@0: vpshufb TMP3, CTR1, CTR1 michael@0: vpxor TMP4, CTR1, CTR1 michael@0: vpshufb TMP3, CTR2, CTR2 michael@0: vpxor TMP4, CTR2, CTR2 michael@0: vpshufb TMP3, CTR3, CTR3 michael@0: vpxor TMP4, CTR3, CTR3 michael@0: vpshufb TMP3, CTR4, CTR4 michael@0: vpxor TMP4, CTR4, CTR4 michael@0: vpshufb TMP3, CTR5, CTR5 michael@0: vpxor TMP4, CTR5, CTR5 michael@0: vpshufb TMP3, CTR6, CTR6 michael@0: vpxor TMP4, CTR6, CTR6 michael@0: vpshufb TMP3, CTR7, CTR7 michael@0: vpxor TMP4, CTR7, CTR7 michael@0: michael@0: vmovdqu 16*0(Htbl), TMP3 michael@0: vpclmulqdq $0x11, TMP3, TMP5, TMP1 michael@0: vpclmulqdq $0x00, TMP3, TMP5, TMP2 michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vmovdqu 128+0*16(Htbl), TMP3 michael@0: vpclmulqdq $0x00, TMP3, TMP5, TMP0 michael@0: michael@0: ROUNDMUL 1 michael@0: michael@0: ROUNDMUL 2 michael@0: michael@0: ROUNDMUL 3 michael@0: michael@0: ROUNDMUL 4 michael@0: michael@0: ROUNDMUL 5 michael@0: michael@0: ROUNDMUL 6 michael@0: michael@0: vpxor 7*16(%rsp), T, TMP5 michael@0: vmovdqu 7*16(KS), TMP3 michael@0: michael@0: vaesenc TMP3, CTR0, CTR0 michael@0: vaesenc TMP3, CTR1, CTR1 michael@0: vaesenc TMP3, CTR2, CTR2 michael@0: vaesenc TMP3, CTR3, CTR3 michael@0: michael@0: vpshufd $78, TMP5, TMP4 michael@0: vpxor TMP5, TMP4, TMP4 michael@0: michael@0: vaesenc TMP3, CTR4, CTR4 michael@0: vaesenc TMP3, CTR5, CTR5 michael@0: vaesenc TMP3, CTR6, CTR6 michael@0: vaesenc TMP3, CTR7, CTR7 michael@0: michael@0: vpclmulqdq $0x11, 7*16(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpclmulqdq $0x00, 7*16(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: vpclmulqdq $0x00, 128+7*16(Htbl), TMP4, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: michael@0: ROUND 8 michael@0: vmovdqa .Lpoly(%rip), TMP5 michael@0: michael@0: vpxor TMP1, TMP0, TMP0 michael@0: vpxor TMP2, TMP0, TMP0 michael@0: vpsrldq $8, TMP0, TMP3 michael@0: vpxor TMP3, TMP1, TMP4 michael@0: vpslldq $8, TMP0, TMP3 michael@0: vpxor TMP3, TMP2, T michael@0: michael@0: vpclmulqdq $0x10, TMP5, T, TMP1 michael@0: vpalignr $8, T, T, T michael@0: vpxor T, TMP1, T michael@0: michael@0: ROUND 9 michael@0: michael@0: vpclmulqdq $0x10, TMP5, T, TMP1 michael@0: vpalignr $8, T, T, T michael@0: vpxor T, TMP1, T michael@0: michael@0: vmovdqu 160(KS), TMP5 michael@0: cmp $10, NR michael@0: jbe .LLast2 michael@0: michael@0: ROUND 10 michael@0: ROUND 11 michael@0: michael@0: vmovdqu 192(KS), TMP5 michael@0: cmp $12, NR michael@0: jbe .LLast2 michael@0: michael@0: ROUND 12 michael@0: ROUND 13 michael@0: michael@0: vmovdqu 224(KS), TMP5 michael@0: michael@0: .LLast2: michael@0: michael@0: vpxor (PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR0, CTR0 michael@0: vpxor 16(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR1, CTR1 michael@0: vpxor 32(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR2, CTR2 michael@0: vpxor 48(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR3, CTR3 michael@0: vpxor 64(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR4, CTR4 michael@0: vpxor 80(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR5, CTR5 michael@0: vpxor 96(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR6, CTR6 michael@0: vpxor 112(PT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR7, CTR7 michael@0: michael@0: vmovdqu .Lbswap_mask(%rip), TMP3 michael@0: michael@0: vmovdqu CTR0, (CT) michael@0: vpshufb TMP3, CTR0, CTR0 michael@0: vmovdqu CTR1, 16(CT) michael@0: vpshufb TMP3, CTR1, CTR1 michael@0: vmovdqu CTR2, 32(CT) michael@0: vpshufb TMP3, CTR2, CTR2 michael@0: vmovdqu CTR3, 48(CT) michael@0: vpshufb TMP3, CTR3, CTR3 michael@0: vmovdqu CTR4, 64(CT) michael@0: vpshufb TMP3, CTR4, CTR4 michael@0: vmovdqu CTR5, 80(CT) michael@0: vpshufb TMP3, CTR5, CTR5 michael@0: vmovdqu CTR6, 96(CT) michael@0: vpshufb TMP3, CTR6, CTR6 michael@0: vmovdqu CTR7,112(CT) michael@0: vpshufb TMP3, CTR7, CTR7 michael@0: michael@0: vpxor TMP4, T, T michael@0: michael@0: lea 128(CT), CT michael@0: lea 128(PT), PT michael@0: jmp .LDataOctets michael@0: michael@0: .LEndOctets: michael@0: michael@0: vmovdqa CTR7, TMP5 michael@0: vmovdqa CTR6, 1*16(%rsp) michael@0: vmovdqa CTR5, 2*16(%rsp) michael@0: vmovdqa CTR4, 3*16(%rsp) michael@0: vmovdqa CTR3, 4*16(%rsp) michael@0: vmovdqa CTR2, 5*16(%rsp) michael@0: vmovdqa CTR1, 6*16(%rsp) michael@0: vmovdqa CTR0, 7*16(%rsp) michael@0: michael@0: vmovdqu 16*0(Htbl), TMP3 michael@0: vpclmulqdq $0x11, TMP3, TMP5, TMP1 michael@0: vpclmulqdq $0x00, TMP3, TMP5, TMP2 michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vmovdqu 128+0*16(Htbl), TMP3 michael@0: vpclmulqdq $0x00, TMP3, TMP5, TMP0 michael@0: michael@0: KARATSUBA 1 michael@0: KARATSUBA 2 michael@0: KARATSUBA 3 michael@0: KARATSUBA 4 michael@0: KARATSUBA 5 michael@0: KARATSUBA 6 michael@0: michael@0: vmovdqu 7*16(%rsp), TMP5 michael@0: vpxor T, TMP5, TMP5 michael@0: vmovdqu 16*7(Htbl), TMP4 michael@0: vpclmulqdq $0x11, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpclmulqdq $0x00, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vmovdqu 128+7*16(Htbl), TMP4 michael@0: vpclmulqdq $0x00, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: michael@0: vpxor TMP1, TMP0, TMP0 michael@0: vpxor TMP2, TMP0, TMP0 michael@0: michael@0: vpsrldq $8, TMP0, TMP3 michael@0: vpxor TMP3, TMP1, TMP4 michael@0: vpslldq $8, TMP0, TMP3 michael@0: vpxor TMP3, TMP2, T michael@0: michael@0: vmovdqa .Lpoly(%rip), TMP2 michael@0: michael@0: vpalignr $8, T, T, TMP1 michael@0: vpclmulqdq $0x10, TMP2, T, T michael@0: vpxor T, TMP1, T michael@0: michael@0: vpalignr $8, T, T, TMP1 michael@0: vpclmulqdq $0x10, TMP2, T, T michael@0: vpxor T, TMP1, T michael@0: michael@0: vpxor TMP4, T, T michael@0: michael@0: #Here we encrypt any remaining whole block michael@0: .LDataSingles: michael@0: michael@0: cmp $16, len michael@0: jb .LDataTail michael@0: sub $16, len michael@0: michael@0: vpshufb .Lbswap_mask(%rip), CTR, TMP1 michael@0: vpaddd .Lone(%rip), CTR, CTR michael@0: michael@0: vpxor (KS), TMP1, TMP1 michael@0: vaesenc 16*1(KS), TMP1, TMP1 michael@0: vaesenc 16*2(KS), TMP1, TMP1 michael@0: vaesenc 16*3(KS), TMP1, TMP1 michael@0: vaesenc 16*4(KS), TMP1, TMP1 michael@0: vaesenc 16*5(KS), TMP1, TMP1 michael@0: vaesenc 16*6(KS), TMP1, TMP1 michael@0: vaesenc 16*7(KS), TMP1, TMP1 michael@0: vaesenc 16*8(KS), TMP1, TMP1 michael@0: vaesenc 16*9(KS), TMP1, TMP1 michael@0: vmovdqu 16*10(KS), TMP2 michael@0: cmp $10, NR michael@0: je .LLast3 michael@0: vaesenc 16*10(KS), TMP1, TMP1 michael@0: vaesenc 16*11(KS), TMP1, TMP1 michael@0: vmovdqu 16*12(KS), TMP2 michael@0: cmp $12, NR michael@0: je .LLast3 michael@0: vaesenc 16*12(KS), TMP1, TMP1 michael@0: vaesenc 16*13(KS), TMP1, TMP1 michael@0: vmovdqu 16*14(KS), TMP2 michael@0: michael@0: .LLast3: michael@0: vaesenclast TMP2, TMP1, TMP1 michael@0: michael@0: vpxor (PT), TMP1, TMP1 michael@0: vmovdqu TMP1, (CT) michael@0: addq $16, CT michael@0: addq $16, PT michael@0: michael@0: vpshufb .Lbswap_mask(%rip), TMP1, TMP1 michael@0: vpxor TMP1, T, T michael@0: vmovdqu (Htbl), TMP0 michael@0: call GFMUL michael@0: michael@0: jmp .LDataSingles michael@0: michael@0: #Here we encypt the final partial block, if there is one michael@0: .LDataTail: michael@0: michael@0: test len, len michael@0: jz DATA_END michael@0: # First prepare the counter block michael@0: vpshufb .Lbswap_mask(%rip), CTR, TMP1 michael@0: vpaddd .Lone(%rip), CTR, CTR michael@0: michael@0: vpxor (KS), TMP1, TMP1 michael@0: vaesenc 16*1(KS), TMP1, TMP1 michael@0: vaesenc 16*2(KS), TMP1, TMP1 michael@0: vaesenc 16*3(KS), TMP1, TMP1 michael@0: vaesenc 16*4(KS), TMP1, TMP1 michael@0: vaesenc 16*5(KS), TMP1, TMP1 michael@0: vaesenc 16*6(KS), TMP1, TMP1 michael@0: vaesenc 16*7(KS), TMP1, TMP1 michael@0: vaesenc 16*8(KS), TMP1, TMP1 michael@0: vaesenc 16*9(KS), TMP1, TMP1 michael@0: vmovdqu 16*10(KS), TMP2 michael@0: cmp $10, NR michael@0: je .LLast4 michael@0: vaesenc 16*10(KS), TMP1, TMP1 michael@0: vaesenc 16*11(KS), TMP1, TMP1 michael@0: vmovdqu 16*12(KS), TMP2 michael@0: cmp $12, NR michael@0: je .LLast4 michael@0: vaesenc 16*12(KS), TMP1, TMP1 michael@0: vaesenc 16*13(KS), TMP1, TMP1 michael@0: vmovdqu 16*14(KS), TMP2 michael@0: michael@0: .LLast4: michael@0: vaesenclast TMP2, TMP1, TMP1 michael@0: #Zero a temp location michael@0: vpxor TMP2, TMP2, TMP2 michael@0: vmovdqa TMP2, (%rsp) michael@0: michael@0: # Copy the required bytes only (could probably use rep movsb) michael@0: xor KS, KS michael@0: .LEncCpy: michael@0: cmp KS, len michael@0: je .LEncCpyEnd michael@0: movb (PT, KS, 1), %r8b michael@0: movb %r8b, (%rsp, KS, 1) michael@0: inc KS michael@0: jmp .LEncCpy michael@0: .LEncCpyEnd: michael@0: # Xor with the counter block michael@0: vpxor (%rsp), TMP1, TMP0 michael@0: # Again, store at temp location michael@0: vmovdqa TMP0, (%rsp) michael@0: # Copy only the required bytes to CT, and zero the rest for the hash michael@0: xor KS, KS michael@0: .LEncCpy2: michael@0: cmp KS, len michael@0: je .LEncCpy3 michael@0: movb (%rsp, KS, 1), %r8b michael@0: movb %r8b, (CT, KS, 1) michael@0: inc KS michael@0: jmp .LEncCpy2 michael@0: .LEncCpy3: michael@0: cmp $16, KS michael@0: je .LEndCpy3 michael@0: movb $0, (%rsp, KS, 1) michael@0: inc KS michael@0: jmp .LEncCpy3 michael@0: .LEndCpy3: michael@0: vmovdqa (%rsp), TMP0 michael@0: michael@0: vpshufb .Lbswap_mask(%rip), TMP0, TMP0 michael@0: vpxor TMP0, T, T michael@0: vmovdqu (Htbl), TMP0 michael@0: call GFMUL michael@0: michael@0: DATA_END: michael@0: michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: vpshufb .Lbswap_mask(%rip), CTR, CTR michael@0: vmovdqu T, 272(Gctx) michael@0: vmovdqu CTR, 288(Gctx) michael@0: michael@0: movq %rbp, %rsp michael@0: michael@0: popq %rbx michael@0: popq %rbp michael@0: ret michael@0: .size intel_aes_gcmENC, .-intel_aes_gcmENC michael@0: michael@0: ######################### michael@0: # Decrypt and Authenticate michael@0: # void intel_aes_gcmDEC(uint8_t* PT, uint8_t* CT, void *Gctx,uint64_t len); michael@0: .type intel_aes_gcmDEC,@function michael@0: .globl intel_aes_gcmDEC michael@0: .align 16 michael@0: intel_aes_gcmDEC: michael@0: # parameter 1: CT # input michael@0: # parameter 2: PT # output michael@0: # parameter 3: %rdx # Gctx michael@0: # parameter 4: %rcx # len michael@0: michael@0: .macro DEC_KARATSUBA i michael@0: vmovdqu (7-\i)*16(CT), TMP5 michael@0: vpshufb .Lbswap_mask(%rip), TMP5, TMP5 michael@0: michael@0: vpclmulqdq $0x11, 16*\i(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpclmulqdq $0x00, 16*\i(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vpclmulqdq $0x00, 128+\i*16(Htbl), TMP5, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: .endm michael@0: michael@0: .set PT,%rsi michael@0: .set CT,%rdi michael@0: .set Htbl, %rdx michael@0: .set len, %rcx michael@0: .set KS,%r9 michael@0: .set NR,%r10d michael@0: michael@0: .set Gctx, %rdx michael@0: michael@0: .set T,%xmm0 michael@0: .set TMP0,%xmm1 michael@0: .set TMP1,%xmm2 michael@0: .set TMP2,%xmm3 michael@0: .set TMP3,%xmm4 michael@0: .set TMP4,%xmm5 michael@0: .set TMP5,%xmm6 michael@0: .set CTR0,%xmm7 michael@0: .set CTR1,%xmm8 michael@0: .set CTR2,%xmm9 michael@0: .set CTR3,%xmm10 michael@0: .set CTR4,%xmm11 michael@0: .set CTR5,%xmm12 michael@0: .set CTR6,%xmm13 michael@0: .set CTR7,%xmm14 michael@0: .set CTR,%xmm15 michael@0: michael@0: test len, len michael@0: jnz .LbeginDec michael@0: ret michael@0: michael@0: .LbeginDec: michael@0: michael@0: pushq %rbp michael@0: pushq %rbx michael@0: movq %rsp, %rbp michael@0: sub $128, %rsp michael@0: andq $-16, %rsp michael@0: vmovdqu 288(Gctx), CTR michael@0: vmovdqu 272(Gctx), T michael@0: mov 304(Gctx), KS michael@0: mov 4(KS), NR michael@0: lea 48(KS), KS michael@0: michael@0: vpshufb .Lbswap_mask(%rip), CTR, CTR michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: michael@0: vmovdqu .Lbswap_mask(%rip), TMP3 michael@0: jmp .LDECOctets michael@0: michael@0: # Decrypt 8 blocks each time while hashing them at the same time michael@0: .align 64 michael@0: .LDECOctets: michael@0: michael@0: cmp $128, len michael@0: jb .LDECSingles michael@0: sub $128, len michael@0: michael@0: vmovdqa CTR, CTR0 michael@0: vpaddd .Lone(%rip), CTR0, CTR1 michael@0: vpaddd .Ltwo(%rip), CTR0, CTR2 michael@0: vpaddd .Lone(%rip), CTR2, CTR3 michael@0: vpaddd .Ltwo(%rip), CTR2, CTR4 michael@0: vpaddd .Lone(%rip), CTR4, CTR5 michael@0: vpaddd .Ltwo(%rip), CTR4, CTR6 michael@0: vpaddd .Lone(%rip), CTR6, CTR7 michael@0: vpaddd .Ltwo(%rip), CTR6, CTR michael@0: michael@0: vpshufb TMP3, CTR0, CTR0 michael@0: vpshufb TMP3, CTR1, CTR1 michael@0: vpshufb TMP3, CTR2, CTR2 michael@0: vpshufb TMP3, CTR3, CTR3 michael@0: vpshufb TMP3, CTR4, CTR4 michael@0: vpshufb TMP3, CTR5, CTR5 michael@0: vpshufb TMP3, CTR6, CTR6 michael@0: vpshufb TMP3, CTR7, CTR7 michael@0: michael@0: vmovdqu (KS), TMP3 michael@0: vpxor TMP3, CTR0, CTR0 michael@0: vpxor TMP3, CTR1, CTR1 michael@0: vpxor TMP3, CTR2, CTR2 michael@0: vpxor TMP3, CTR3, CTR3 michael@0: vpxor TMP3, CTR4, CTR4 michael@0: vpxor TMP3, CTR5, CTR5 michael@0: vpxor TMP3, CTR6, CTR6 michael@0: vpxor TMP3, CTR7, CTR7 michael@0: michael@0: vmovdqu 7*16(CT), TMP5 michael@0: vpshufb .Lbswap_mask(%rip), TMP5, TMP5 michael@0: vmovdqu 16*0(Htbl), TMP3 michael@0: vpclmulqdq $0x11, TMP3, TMP5, TMP1 michael@0: vpclmulqdq $0x00, TMP3, TMP5, TMP2 michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vmovdqu 128+0*16(Htbl), TMP3 michael@0: vpclmulqdq $0x00, TMP3, TMP5, TMP0 michael@0: michael@0: ROUND 1 michael@0: DEC_KARATSUBA 1 michael@0: michael@0: ROUND 2 michael@0: DEC_KARATSUBA 2 michael@0: michael@0: ROUND 3 michael@0: DEC_KARATSUBA 3 michael@0: michael@0: ROUND 4 michael@0: DEC_KARATSUBA 4 michael@0: michael@0: ROUND 5 michael@0: DEC_KARATSUBA 5 michael@0: michael@0: ROUND 6 michael@0: DEC_KARATSUBA 6 michael@0: michael@0: ROUND 7 michael@0: michael@0: vmovdqu 0*16(CT), TMP5 michael@0: vpshufb .Lbswap_mask(%rip), TMP5, TMP5 michael@0: vpxor T, TMP5, TMP5 michael@0: vmovdqu 16*7(Htbl), TMP4 michael@0: michael@0: vpclmulqdq $0x11, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpclmulqdq $0x00, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP2, TMP2 michael@0: michael@0: vpshufd $78, TMP5, TMP3 michael@0: vpxor TMP5, TMP3, TMP5 michael@0: vmovdqu 128+7*16(Htbl), TMP4 michael@0: michael@0: vpclmulqdq $0x00, TMP4, TMP5, TMP3 michael@0: vpxor TMP3, TMP0, TMP0 michael@0: michael@0: ROUND 8 michael@0: michael@0: vpxor TMP1, TMP0, TMP0 michael@0: vpxor TMP2, TMP0, TMP0 michael@0: michael@0: vpsrldq $8, TMP0, TMP3 michael@0: vpxor TMP3, TMP1, TMP4 michael@0: vpslldq $8, TMP0, TMP3 michael@0: vpxor TMP3, TMP2, T michael@0: vmovdqa .Lpoly(%rip), TMP2 michael@0: michael@0: vpalignr $8, T, T, TMP1 michael@0: vpclmulqdq $0x10, TMP2, T, T michael@0: vpxor T, TMP1, T michael@0: michael@0: ROUND 9 michael@0: michael@0: vpalignr $8, T, T, TMP1 michael@0: vpclmulqdq $0x10, TMP2, T, T michael@0: vpxor T, TMP1, T michael@0: michael@0: vmovdqu 160(KS), TMP5 michael@0: cmp $10, NR michael@0: michael@0: jbe .LDECLast1 michael@0: michael@0: ROUND 10 michael@0: ROUND 11 michael@0: michael@0: vmovdqu 192(KS), TMP5 michael@0: cmp $12, NR michael@0: michael@0: jbe .LDECLast1 michael@0: michael@0: ROUND 12 michael@0: ROUND 13 michael@0: michael@0: vmovdqu 224(KS), TMP5 michael@0: michael@0: .LDECLast1: michael@0: michael@0: vpxor (CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR0, CTR0 michael@0: vpxor 16(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR1, CTR1 michael@0: vpxor 32(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR2, CTR2 michael@0: vpxor 48(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR3, CTR3 michael@0: vpxor 64(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR4, CTR4 michael@0: vpxor 80(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR5, CTR5 michael@0: vpxor 96(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR6, CTR6 michael@0: vpxor 112(CT), TMP5, TMP3 michael@0: vaesenclast TMP3, CTR7, CTR7 michael@0: michael@0: vmovdqu .Lbswap_mask(%rip), TMP3 michael@0: michael@0: vmovdqu CTR0, (PT) michael@0: vmovdqu CTR1, 16(PT) michael@0: vmovdqu CTR2, 32(PT) michael@0: vmovdqu CTR3, 48(PT) michael@0: vmovdqu CTR4, 64(PT) michael@0: vmovdqu CTR5, 80(PT) michael@0: vmovdqu CTR6, 96(PT) michael@0: vmovdqu CTR7,112(PT) michael@0: michael@0: vpxor TMP4, T, T michael@0: michael@0: lea 128(CT), CT michael@0: lea 128(PT), PT michael@0: jmp .LDECOctets michael@0: michael@0: #Here we decrypt and hash any remaining whole block michael@0: .LDECSingles: michael@0: michael@0: cmp $16, len michael@0: jb .LDECTail michael@0: sub $16, len michael@0: michael@0: vmovdqu (CT), TMP1 michael@0: vpshufb .Lbswap_mask(%rip), TMP1, TMP1 michael@0: vpxor TMP1, T, T michael@0: vmovdqu (Htbl), TMP0 michael@0: call GFMUL michael@0: michael@0: michael@0: vpshufb .Lbswap_mask(%rip), CTR, TMP1 michael@0: vpaddd .Lone(%rip), CTR, CTR michael@0: michael@0: vpxor (KS), TMP1, TMP1 michael@0: vaesenc 16*1(KS), TMP1, TMP1 michael@0: vaesenc 16*2(KS), TMP1, TMP1 michael@0: vaesenc 16*3(KS), TMP1, TMP1 michael@0: vaesenc 16*4(KS), TMP1, TMP1 michael@0: vaesenc 16*5(KS), TMP1, TMP1 michael@0: vaesenc 16*6(KS), TMP1, TMP1 michael@0: vaesenc 16*7(KS), TMP1, TMP1 michael@0: vaesenc 16*8(KS), TMP1, TMP1 michael@0: vaesenc 16*9(KS), TMP1, TMP1 michael@0: vmovdqu 16*10(KS), TMP2 michael@0: cmp $10, NR michael@0: je .LDECLast2 michael@0: vaesenc 16*10(KS), TMP1, TMP1 michael@0: vaesenc 16*11(KS), TMP1, TMP1 michael@0: vmovdqu 16*12(KS), TMP2 michael@0: cmp $12, NR michael@0: je .LDECLast2 michael@0: vaesenc 16*12(KS), TMP1, TMP1 michael@0: vaesenc 16*13(KS), TMP1, TMP1 michael@0: vmovdqu 16*14(KS), TMP2 michael@0: .LDECLast2: michael@0: vaesenclast TMP2, TMP1, TMP1 michael@0: michael@0: vpxor (CT), TMP1, TMP1 michael@0: vmovdqu TMP1, (PT) michael@0: addq $16, CT michael@0: addq $16, PT michael@0: jmp .LDECSingles michael@0: michael@0: #Here we decrypt the final partial block, if there is one michael@0: .LDECTail: michael@0: test len, len michael@0: jz .LDEC_END michael@0: michael@0: vpshufb .Lbswap_mask(%rip), CTR, TMP1 michael@0: vpaddd .Lone(%rip), CTR, CTR michael@0: michael@0: vpxor (KS), TMP1, TMP1 michael@0: vaesenc 16*1(KS), TMP1, TMP1 michael@0: vaesenc 16*2(KS), TMP1, TMP1 michael@0: vaesenc 16*3(KS), TMP1, TMP1 michael@0: vaesenc 16*4(KS), TMP1, TMP1 michael@0: vaesenc 16*5(KS), TMP1, TMP1 michael@0: vaesenc 16*6(KS), TMP1, TMP1 michael@0: vaesenc 16*7(KS), TMP1, TMP1 michael@0: vaesenc 16*8(KS), TMP1, TMP1 michael@0: vaesenc 16*9(KS), TMP1, TMP1 michael@0: vmovdqu 16*10(KS), TMP2 michael@0: cmp $10, NR michael@0: je .LDECLast3 michael@0: vaesenc 16*10(KS), TMP1, TMP1 michael@0: vaesenc 16*11(KS), TMP1, TMP1 michael@0: vmovdqu 16*12(KS), TMP2 michael@0: cmp $12, NR michael@0: je .LDECLast3 michael@0: vaesenc 16*12(KS), TMP1, TMP1 michael@0: vaesenc 16*13(KS), TMP1, TMP1 michael@0: vmovdqu 16*14(KS), TMP2 michael@0: michael@0: .LDECLast3: michael@0: vaesenclast TMP2, TMP1, TMP1 michael@0: michael@0: vpxor TMP2, TMP2, TMP2 michael@0: vmovdqa TMP2, (%rsp) michael@0: # Copy the required bytes only (could probably use rep movsb) michael@0: xor KS, KS michael@0: .LDecCpy: michael@0: cmp KS, len michael@0: je .LDecCpy2 michael@0: movb (CT, KS, 1), %r8b michael@0: movb %r8b, (%rsp, KS, 1) michael@0: inc KS michael@0: jmp .LDecCpy michael@0: .LDecCpy2: michael@0: cmp $16, KS michael@0: je .LDecCpyEnd michael@0: movb $0, (%rsp, KS, 1) michael@0: inc KS michael@0: jmp .LDecCpy2 michael@0: .LDecCpyEnd: michael@0: # Xor with the counter block michael@0: vmovdqa (%rsp), TMP0 michael@0: vpxor TMP0, TMP1, TMP1 michael@0: # Again, store at temp location michael@0: vmovdqa TMP1, (%rsp) michael@0: # Copy only the required bytes to PT, and zero the rest for the hash michael@0: xor KS, KS michael@0: .LDecCpy3: michael@0: cmp KS, len michael@0: je .LDecCpyEnd3 michael@0: movb (%rsp, KS, 1), %r8b michael@0: movb %r8b, (PT, KS, 1) michael@0: inc KS michael@0: jmp .LDecCpy3 michael@0: .LDecCpyEnd3: michael@0: vpshufb .Lbswap_mask(%rip), TMP0, TMP0 michael@0: vpxor TMP0, T, T michael@0: vmovdqu (Htbl), TMP0 michael@0: call GFMUL michael@0: .LDEC_END: michael@0: michael@0: vpshufb .Lbswap_mask(%rip), T, T michael@0: vpshufb .Lbswap_mask(%rip), CTR, CTR michael@0: vmovdqu T, 272(Gctx) michael@0: vmovdqu CTR, 288(Gctx) michael@0: michael@0: movq %rbp, %rsp michael@0: michael@0: popq %rbx michael@0: popq %rbp michael@0: ret michael@0: .size intel_aes_gcmDEC, .-intel_aes_gcmDEC michael@0: ######################### michael@0: # a = T michael@0: # b = TMP0 - remains unchanged michael@0: # res = T michael@0: # uses also TMP1,TMP2,TMP3,TMP4 michael@0: # __m128i GFMUL(__m128i A, __m128i B); michael@0: .type GFMUL,@function michael@0: .globl GFMUL michael@0: GFMUL: michael@0: vpclmulqdq $0x00, TMP0, T, TMP1 michael@0: vpclmulqdq $0x11, TMP0, T, TMP4 michael@0: michael@0: vpshufd $78, T, TMP2 michael@0: vpshufd $78, TMP0, TMP3 michael@0: vpxor T, TMP2, TMP2 michael@0: vpxor TMP0, TMP3, TMP3 michael@0: michael@0: vpclmulqdq $0x00, TMP3, TMP2, TMP2 michael@0: vpxor TMP1, TMP2, TMP2 michael@0: vpxor TMP4, TMP2, TMP2 michael@0: michael@0: vpslldq $8, TMP2, TMP3 michael@0: vpsrldq $8, TMP2, TMP2 michael@0: michael@0: vpxor TMP3, TMP1, TMP1 michael@0: vpxor TMP2, TMP4, TMP4 michael@0: michael@0: vpclmulqdq $0x10, .Lpoly(%rip), TMP1, TMP2 michael@0: vpshufd $78, TMP1, TMP3 michael@0: vpxor TMP3, TMP2, TMP1 michael@0: michael@0: vpclmulqdq $0x10, .Lpoly(%rip), TMP1, TMP2 michael@0: vpshufd $78, TMP1, TMP3 michael@0: vpxor TMP3, TMP2, TMP1 michael@0: michael@0: vpxor TMP4, TMP1, T michael@0: ret michael@0: .size GFMUL, .-GFMUL michael@0: