original files of m241
This commit is contained in:
@@ -0,0 +1,753 @@
|
||||
.text
|
||||
|
||||
.type _aesni_ctr32_ghash_6x,@function
|
||||
.align 32
|
||||
_aesni_ctr32_ghash_6x:
|
||||
vmovdqu 32(%r11),%xmm2
|
||||
subq $6,%rdx
|
||||
vpxor %xmm4,%xmm4,%xmm4
|
||||
vmovdqu 0-128(%rcx),%xmm15
|
||||
vpaddb %xmm2,%xmm1,%xmm10
|
||||
vpaddb %xmm2,%xmm10,%xmm11
|
||||
vpaddb %xmm2,%xmm11,%xmm12
|
||||
vpaddb %xmm2,%xmm12,%xmm13
|
||||
vpaddb %xmm2,%xmm13,%xmm14
|
||||
vpxor %xmm15,%xmm1,%xmm9
|
||||
vmovdqu %xmm4,16+8(%rsp)
|
||||
jmp .Loop6x
|
||||
|
||||
.align 32
|
||||
.Loop6x:
|
||||
addl $100663296,%ebx
|
||||
jc .Lhandle_ctr32
|
||||
vmovdqu 0-32(%r9),%xmm3
|
||||
vpaddb %xmm2,%xmm14,%xmm1
|
||||
vpxor %xmm15,%xmm10,%xmm10
|
||||
vpxor %xmm15,%xmm11,%xmm11
|
||||
|
||||
.Lresume_ctr32:
|
||||
vmovdqu %xmm1,(%r8)
|
||||
vpclmulqdq $0x10,%xmm3,%xmm7,%xmm5
|
||||
vpxor %xmm15,%xmm12,%xmm12
|
||||
vmovups 16-128(%rcx),%xmm2
|
||||
vpclmulqdq $0x01,%xmm3,%xmm7,%xmm6
|
||||
xorq %r12,%r12
|
||||
cmpq %r14,%r15
|
||||
|
||||
vaesenc %xmm2,%xmm9,%xmm9
|
||||
vmovdqu 48+8(%rsp),%xmm0
|
||||
vpxor %xmm15,%xmm13,%xmm13
|
||||
vpclmulqdq $0x00,%xmm3,%xmm7,%xmm1
|
||||
vaesenc %xmm2,%xmm10,%xmm10
|
||||
vpxor %xmm15,%xmm14,%xmm14
|
||||
setnc %r12b
|
||||
vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7
|
||||
vaesenc %xmm2,%xmm11,%xmm11
|
||||
vmovdqu 16-32(%r9),%xmm3
|
||||
negq %r12
|
||||
vaesenc %xmm2,%xmm12,%xmm12
|
||||
vpxor %xmm5,%xmm6,%xmm6
|
||||
vpclmulqdq $0x00,%xmm3,%xmm0,%xmm5
|
||||
vpxor %xmm4,%xmm8,%xmm8
|
||||
vaesenc %xmm2,%xmm13,%xmm13
|
||||
vpxor %xmm5,%xmm1,%xmm4
|
||||
andq $0x60,%r12
|
||||
vmovups 32-128(%rcx),%xmm15
|
||||
vpclmulqdq $0x10,%xmm3,%xmm0,%xmm1
|
||||
vaesenc %xmm2,%xmm14,%xmm14
|
||||
|
||||
vpclmulqdq $0x01,%xmm3,%xmm0,%xmm2
|
||||
leaq (%r14,%r12,1),%r14
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor 16+8(%rsp),%xmm8,%xmm8
|
||||
vpclmulqdq $0x11,%xmm3,%xmm0,%xmm3
|
||||
vmovdqu 64+8(%rsp),%xmm0
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
movbeq 88(%r14),%r13
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
movbeq 80(%r14),%r12
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
movq %r13,32+8(%rsp)
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
movq %r12,40+8(%rsp)
|
||||
vmovdqu 48-32(%r9),%xmm5
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vmovups 48-128(%rcx),%xmm15
|
||||
vpxor %xmm1,%xmm6,%xmm6
|
||||
vpclmulqdq $0x00,%xmm5,%xmm0,%xmm1
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor %xmm2,%xmm6,%xmm6
|
||||
vpclmulqdq $0x10,%xmm5,%xmm0,%xmm2
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vpxor %xmm3,%xmm7,%xmm7
|
||||
vpclmulqdq $0x01,%xmm5,%xmm0,%xmm3
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
vpclmulqdq $0x11,%xmm5,%xmm0,%xmm5
|
||||
vmovdqu 80+8(%rsp),%xmm0
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vpxor %xmm1,%xmm4,%xmm4
|
||||
vmovdqu 64-32(%r9),%xmm1
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vmovups 64-128(%rcx),%xmm15
|
||||
vpxor %xmm2,%xmm6,%xmm6
|
||||
vpclmulqdq $0x00,%xmm1,%xmm0,%xmm2
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor %xmm3,%xmm6,%xmm6
|
||||
vpclmulqdq $0x10,%xmm1,%xmm0,%xmm3
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
movbeq 72(%r14),%r13
|
||||
vpxor %xmm5,%xmm7,%xmm7
|
||||
vpclmulqdq $0x01,%xmm1,%xmm0,%xmm5
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
movbeq 64(%r14),%r12
|
||||
vpclmulqdq $0x11,%xmm1,%xmm0,%xmm1
|
||||
vmovdqu 96+8(%rsp),%xmm0
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
movq %r13,48+8(%rsp)
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
movq %r12,56+8(%rsp)
|
||||
vpxor %xmm2,%xmm4,%xmm4
|
||||
vmovdqu 96-32(%r9),%xmm2
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vmovups 80-128(%rcx),%xmm15
|
||||
vpxor %xmm3,%xmm6,%xmm6
|
||||
vpclmulqdq $0x00,%xmm2,%xmm0,%xmm3
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor %xmm5,%xmm6,%xmm6
|
||||
vpclmulqdq $0x10,%xmm2,%xmm0,%xmm5
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
movbeq 56(%r14),%r13
|
||||
vpxor %xmm1,%xmm7,%xmm7
|
||||
vpclmulqdq $0x01,%xmm2,%xmm0,%xmm1
|
||||
vpxor 112+8(%rsp),%xmm8,%xmm8
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
movbeq 48(%r14),%r12
|
||||
vpclmulqdq $0x11,%xmm2,%xmm0,%xmm2
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
movq %r13,64+8(%rsp)
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
movq %r12,72+8(%rsp)
|
||||
vpxor %xmm3,%xmm4,%xmm4
|
||||
vmovdqu 112-32(%r9),%xmm3
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vmovups 96-128(%rcx),%xmm15
|
||||
vpxor %xmm5,%xmm6,%xmm6
|
||||
vpclmulqdq $0x10,%xmm3,%xmm8,%xmm5
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor %xmm1,%xmm6,%xmm6
|
||||
vpclmulqdq $0x01,%xmm3,%xmm8,%xmm1
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
movbeq 40(%r14),%r13
|
||||
vpxor %xmm2,%xmm7,%xmm7
|
||||
vpclmulqdq $0x00,%xmm3,%xmm8,%xmm2
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
movbeq 32(%r14),%r12
|
||||
vpclmulqdq $0x11,%xmm3,%xmm8,%xmm8
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
movq %r13,80+8(%rsp)
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
movq %r12,88+8(%rsp)
|
||||
vpxor %xmm5,%xmm6,%xmm6
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
vpxor %xmm1,%xmm6,%xmm6
|
||||
|
||||
vmovups 112-128(%rcx),%xmm15
|
||||
vpslldq $8,%xmm6,%xmm5
|
||||
vpxor %xmm2,%xmm4,%xmm4
|
||||
vmovdqu 16(%r11),%xmm3
|
||||
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor %xmm8,%xmm7,%xmm7
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vpxor %xmm5,%xmm4,%xmm4
|
||||
movbeq 24(%r14),%r13
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
movbeq 16(%r14),%r12
|
||||
vpalignr $8,%xmm4,%xmm4,%xmm0
|
||||
vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4
|
||||
movq %r13,96+8(%rsp)
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
movq %r12,104+8(%rsp)
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vmovups 128-128(%rcx),%xmm1
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vaesenc %xmm1,%xmm9,%xmm9
|
||||
vmovups 144-128(%rcx),%xmm15
|
||||
vaesenc %xmm1,%xmm10,%xmm10
|
||||
vpsrldq $8,%xmm6,%xmm6
|
||||
vaesenc %xmm1,%xmm11,%xmm11
|
||||
vpxor %xmm6,%xmm7,%xmm7
|
||||
vaesenc %xmm1,%xmm12,%xmm12
|
||||
vpxor %xmm0,%xmm4,%xmm4
|
||||
movbeq 8(%r14),%r13
|
||||
vaesenc %xmm1,%xmm13,%xmm13
|
||||
movbeq 0(%r14),%r12
|
||||
vaesenc %xmm1,%xmm14,%xmm14
|
||||
vmovups 160-128(%rcx),%xmm1
|
||||
cmpl $11,%ebp
|
||||
jb .Lenc_tail
|
||||
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vaesenc %xmm1,%xmm9,%xmm9
|
||||
vaesenc %xmm1,%xmm10,%xmm10
|
||||
vaesenc %xmm1,%xmm11,%xmm11
|
||||
vaesenc %xmm1,%xmm12,%xmm12
|
||||
vaesenc %xmm1,%xmm13,%xmm13
|
||||
vmovups 176-128(%rcx),%xmm15
|
||||
vaesenc %xmm1,%xmm14,%xmm14
|
||||
vmovups 192-128(%rcx),%xmm1
|
||||
je .Lenc_tail
|
||||
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
|
||||
vaesenc %xmm1,%xmm9,%xmm9
|
||||
vaesenc %xmm1,%xmm10,%xmm10
|
||||
vaesenc %xmm1,%xmm11,%xmm11
|
||||
vaesenc %xmm1,%xmm12,%xmm12
|
||||
vaesenc %xmm1,%xmm13,%xmm13
|
||||
vmovups 208-128(%rcx),%xmm15
|
||||
vaesenc %xmm1,%xmm14,%xmm14
|
||||
vmovups 224-128(%rcx),%xmm1
|
||||
jmp .Lenc_tail
|
||||
|
||||
.align 32
|
||||
.Lhandle_ctr32:
|
||||
vmovdqu (%r11),%xmm0
|
||||
vpshufb %xmm0,%xmm1,%xmm6
|
||||
vmovdqu 48(%r11),%xmm5
|
||||
vpaddd 64(%r11),%xmm6,%xmm10
|
||||
vpaddd %xmm5,%xmm6,%xmm11
|
||||
vmovdqu 0-32(%r9),%xmm3
|
||||
vpaddd %xmm5,%xmm10,%xmm12
|
||||
vpshufb %xmm0,%xmm10,%xmm10
|
||||
vpaddd %xmm5,%xmm11,%xmm13
|
||||
vpshufb %xmm0,%xmm11,%xmm11
|
||||
vpxor %xmm15,%xmm10,%xmm10
|
||||
vpaddd %xmm5,%xmm12,%xmm14
|
||||
vpshufb %xmm0,%xmm12,%xmm12
|
||||
vpxor %xmm15,%xmm11,%xmm11
|
||||
vpaddd %xmm5,%xmm13,%xmm1
|
||||
vpshufb %xmm0,%xmm13,%xmm13
|
||||
vpshufb %xmm0,%xmm14,%xmm14
|
||||
vpshufb %xmm0,%xmm1,%xmm1
|
||||
jmp .Lresume_ctr32
|
||||
|
||||
.align 32
|
||||
.Lenc_tail:
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vmovdqu %xmm7,16+8(%rsp)
|
||||
vpalignr $8,%xmm4,%xmm4,%xmm8
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vpclmulqdq $0x10,%xmm3,%xmm4,%xmm4
|
||||
vpxor 0(%rdi),%xmm1,%xmm2
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
vpxor 16(%rdi),%xmm1,%xmm0
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
vpxor 32(%rdi),%xmm1,%xmm5
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vpxor 48(%rdi),%xmm1,%xmm6
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
vpxor 64(%rdi),%xmm1,%xmm7
|
||||
vpxor 80(%rdi),%xmm1,%xmm3
|
||||
vmovdqu (%r8),%xmm1
|
||||
|
||||
vaesenclast %xmm2,%xmm9,%xmm9
|
||||
vmovdqu 32(%r11),%xmm2
|
||||
vaesenclast %xmm0,%xmm10,%xmm10
|
||||
vpaddb %xmm2,%xmm1,%xmm0
|
||||
movq %r13,112+8(%rsp)
|
||||
leaq 96(%rdi),%rdi
|
||||
vaesenclast %xmm5,%xmm11,%xmm11
|
||||
vpaddb %xmm2,%xmm0,%xmm5
|
||||
movq %r12,120+8(%rsp)
|
||||
leaq 96(%rsi),%rsi
|
||||
vmovdqu 0-128(%rcx),%xmm15
|
||||
vaesenclast %xmm6,%xmm12,%xmm12
|
||||
vpaddb %xmm2,%xmm5,%xmm6
|
||||
vaesenclast %xmm7,%xmm13,%xmm13
|
||||
vpaddb %xmm2,%xmm6,%xmm7
|
||||
vaesenclast %xmm3,%xmm14,%xmm14
|
||||
vpaddb %xmm2,%xmm7,%xmm3
|
||||
|
||||
addq $0x60,%r10
|
||||
subq $0x6,%rdx
|
||||
jc .L6x_done
|
||||
|
||||
vmovups %xmm9,-96(%rsi)
|
||||
vpxor %xmm15,%xmm1,%xmm9
|
||||
vmovups %xmm10,-80(%rsi)
|
||||
vmovdqa %xmm0,%xmm10
|
||||
vmovups %xmm11,-64(%rsi)
|
||||
vmovdqa %xmm5,%xmm11
|
||||
vmovups %xmm12,-48(%rsi)
|
||||
vmovdqa %xmm6,%xmm12
|
||||
vmovups %xmm13,-32(%rsi)
|
||||
vmovdqa %xmm7,%xmm13
|
||||
vmovups %xmm14,-16(%rsi)
|
||||
vmovdqa %xmm3,%xmm14
|
||||
vmovdqu 32+8(%rsp),%xmm7
|
||||
jmp .Loop6x
|
||||
|
||||
.L6x_done:
|
||||
vpxor 16+8(%rsp),%xmm8,%xmm8
|
||||
vpxor %xmm4,%xmm8,%xmm8
|
||||
|
||||
.byte 0xf3,0xc3
|
||||
.size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x
|
||||
.globl aesni_gcm_decrypt
|
||||
.type aesni_gcm_decrypt,@function
|
||||
.align 32
|
||||
aesni_gcm_decrypt:
|
||||
xorq %r10,%r10
|
||||
cmpq $0x60,%rdx
|
||||
jb .Lgcm_dec_abort
|
||||
|
||||
leaq (%rsp),%rax
|
||||
pushq %rbx
|
||||
pushq %rbp
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
vzeroupper
|
||||
|
||||
vmovdqu (%r8),%xmm1
|
||||
addq $-128,%rsp
|
||||
movl 12(%r8),%ebx
|
||||
leaq .Lbswap_mask(%rip),%r11
|
||||
leaq -128(%rcx),%r14
|
||||
movq $0xf80,%r15
|
||||
vmovdqu (%r9),%xmm8
|
||||
andq $-128,%rsp
|
||||
vmovdqu (%r11),%xmm0
|
||||
leaq 128(%rcx),%rcx
|
||||
leaq 32+32(%r9),%r9
|
||||
movl 240-128(%rcx),%ebp
|
||||
vpshufb %xmm0,%xmm8,%xmm8
|
||||
|
||||
andq %r15,%r14
|
||||
andq %rsp,%r15
|
||||
subq %r14,%r15
|
||||
jc .Ldec_no_key_aliasing
|
||||
cmpq $768,%r15
|
||||
jnc .Ldec_no_key_aliasing
|
||||
subq %r15,%rsp
|
||||
.Ldec_no_key_aliasing:
|
||||
|
||||
vmovdqu 80(%rdi),%xmm7
|
||||
leaq (%rdi),%r14
|
||||
vmovdqu 64(%rdi),%xmm4
|
||||
leaq -192(%rdi,%rdx,1),%r15
|
||||
vmovdqu 48(%rdi),%xmm5
|
||||
shrq $4,%rdx
|
||||
xorq %r10,%r10
|
||||
vmovdqu 32(%rdi),%xmm6
|
||||
vpshufb %xmm0,%xmm7,%xmm7
|
||||
vmovdqu 16(%rdi),%xmm2
|
||||
vpshufb %xmm0,%xmm4,%xmm4
|
||||
vmovdqu (%rdi),%xmm3
|
||||
vpshufb %xmm0,%xmm5,%xmm5
|
||||
vmovdqu %xmm4,48(%rsp)
|
||||
vpshufb %xmm0,%xmm6,%xmm6
|
||||
vmovdqu %xmm5,64(%rsp)
|
||||
vpshufb %xmm0,%xmm2,%xmm2
|
||||
vmovdqu %xmm6,80(%rsp)
|
||||
vpshufb %xmm0,%xmm3,%xmm3
|
||||
vmovdqu %xmm2,96(%rsp)
|
||||
vmovdqu %xmm3,112(%rsp)
|
||||
|
||||
call _aesni_ctr32_ghash_6x
|
||||
|
||||
vmovups %xmm9,-96(%rsi)
|
||||
vmovups %xmm10,-80(%rsi)
|
||||
vmovups %xmm11,-64(%rsi)
|
||||
vmovups %xmm12,-48(%rsi)
|
||||
vmovups %xmm13,-32(%rsi)
|
||||
vmovups %xmm14,-16(%rsi)
|
||||
|
||||
vpshufb (%r11),%xmm8,%xmm8
|
||||
vmovdqu %xmm8,-64(%r9)
|
||||
|
||||
vzeroupper
|
||||
movq -48(%rax),%r15
|
||||
movq -40(%rax),%r14
|
||||
movq -32(%rax),%r13
|
||||
movq -24(%rax),%r12
|
||||
movq -16(%rax),%rbp
|
||||
movq -8(%rax),%rbx
|
||||
leaq (%rax),%rsp
|
||||
.Lgcm_dec_abort:
|
||||
movq %r10,%rax
|
||||
.byte 0xf3,0xc3
|
||||
.size aesni_gcm_decrypt,.-aesni_gcm_decrypt
|
||||
.type _aesni_ctr32_6x,@function
|
||||
.align 32
|
||||
_aesni_ctr32_6x:
|
||||
vmovdqu 0-128(%rcx),%xmm4
|
||||
vmovdqu 32(%r11),%xmm2
|
||||
leaq -1(%rbp),%r13
|
||||
vmovups 16-128(%rcx),%xmm15
|
||||
leaq 32-128(%rcx),%r12
|
||||
vpxor %xmm4,%xmm1,%xmm9
|
||||
addl $100663296,%ebx
|
||||
jc .Lhandle_ctr32_2
|
||||
vpaddb %xmm2,%xmm1,%xmm10
|
||||
vpaddb %xmm2,%xmm10,%xmm11
|
||||
vpxor %xmm4,%xmm10,%xmm10
|
||||
vpaddb %xmm2,%xmm11,%xmm12
|
||||
vpxor %xmm4,%xmm11,%xmm11
|
||||
vpaddb %xmm2,%xmm12,%xmm13
|
||||
vpxor %xmm4,%xmm12,%xmm12
|
||||
vpaddb %xmm2,%xmm13,%xmm14
|
||||
vpxor %xmm4,%xmm13,%xmm13
|
||||
vpaddb %xmm2,%xmm14,%xmm1
|
||||
vpxor %xmm4,%xmm14,%xmm14
|
||||
jmp .Loop_ctr32
|
||||
|
||||
.align 16
|
||||
.Loop_ctr32:
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
vmovups (%r12),%xmm15
|
||||
leaq 16(%r12),%r12
|
||||
decl %r13d
|
||||
jnz .Loop_ctr32
|
||||
|
||||
vmovdqu (%r12),%xmm3
|
||||
vaesenc %xmm15,%xmm9,%xmm9
|
||||
vpxor 0(%rdi),%xmm3,%xmm4
|
||||
vaesenc %xmm15,%xmm10,%xmm10
|
||||
vpxor 16(%rdi),%xmm3,%xmm5
|
||||
vaesenc %xmm15,%xmm11,%xmm11
|
||||
vpxor 32(%rdi),%xmm3,%xmm6
|
||||
vaesenc %xmm15,%xmm12,%xmm12
|
||||
vpxor 48(%rdi),%xmm3,%xmm8
|
||||
vaesenc %xmm15,%xmm13,%xmm13
|
||||
vpxor 64(%rdi),%xmm3,%xmm2
|
||||
vaesenc %xmm15,%xmm14,%xmm14
|
||||
vpxor 80(%rdi),%xmm3,%xmm3
|
||||
leaq 96(%rdi),%rdi
|
||||
|
||||
vaesenclast %xmm4,%xmm9,%xmm9
|
||||
vaesenclast %xmm5,%xmm10,%xmm10
|
||||
vaesenclast %xmm6,%xmm11,%xmm11
|
||||
vaesenclast %xmm8,%xmm12,%xmm12
|
||||
vaesenclast %xmm2,%xmm13,%xmm13
|
||||
vaesenclast %xmm3,%xmm14,%xmm14
|
||||
vmovups %xmm9,0(%rsi)
|
||||
vmovups %xmm10,16(%rsi)
|
||||
vmovups %xmm11,32(%rsi)
|
||||
vmovups %xmm12,48(%rsi)
|
||||
vmovups %xmm13,64(%rsi)
|
||||
vmovups %xmm14,80(%rsi)
|
||||
leaq 96(%rsi),%rsi
|
||||
|
||||
.byte 0xf3,0xc3
|
||||
.align 32
|
||||
.Lhandle_ctr32_2:
|
||||
vpshufb %xmm0,%xmm1,%xmm6
|
||||
vmovdqu 48(%r11),%xmm5
|
||||
vpaddd 64(%r11),%xmm6,%xmm10
|
||||
vpaddd %xmm5,%xmm6,%xmm11
|
||||
vpaddd %xmm5,%xmm10,%xmm12
|
||||
vpshufb %xmm0,%xmm10,%xmm10
|
||||
vpaddd %xmm5,%xmm11,%xmm13
|
||||
vpshufb %xmm0,%xmm11,%xmm11
|
||||
vpxor %xmm4,%xmm10,%xmm10
|
||||
vpaddd %xmm5,%xmm12,%xmm14
|
||||
vpshufb %xmm0,%xmm12,%xmm12
|
||||
vpxor %xmm4,%xmm11,%xmm11
|
||||
vpaddd %xmm5,%xmm13,%xmm1
|
||||
vpshufb %xmm0,%xmm13,%xmm13
|
||||
vpxor %xmm4,%xmm12,%xmm12
|
||||
vpshufb %xmm0,%xmm14,%xmm14
|
||||
vpxor %xmm4,%xmm13,%xmm13
|
||||
vpshufb %xmm0,%xmm1,%xmm1
|
||||
vpxor %xmm4,%xmm14,%xmm14
|
||||
jmp .Loop_ctr32
|
||||
.size _aesni_ctr32_6x,.-_aesni_ctr32_6x
|
||||
|
||||
.globl aesni_gcm_encrypt
|
||||
.type aesni_gcm_encrypt,@function
|
||||
.align 32
|
||||
aesni_gcm_encrypt:
|
||||
xorq %r10,%r10
|
||||
cmpq $288,%rdx
|
||||
jb .Lgcm_enc_abort
|
||||
|
||||
leaq (%rsp),%rax
|
||||
pushq %rbx
|
||||
pushq %rbp
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
vzeroupper
|
||||
|
||||
vmovdqu (%r8),%xmm1
|
||||
addq $-128,%rsp
|
||||
movl 12(%r8),%ebx
|
||||
leaq .Lbswap_mask(%rip),%r11
|
||||
leaq -128(%rcx),%r14
|
||||
movq $0xf80,%r15
|
||||
leaq 128(%rcx),%rcx
|
||||
vmovdqu (%r11),%xmm0
|
||||
andq $-128,%rsp
|
||||
movl 240-128(%rcx),%ebp
|
||||
|
||||
andq %r15,%r14
|
||||
andq %rsp,%r15
|
||||
subq %r14,%r15
|
||||
jc .Lenc_no_key_aliasing
|
||||
cmpq $768,%r15
|
||||
jnc .Lenc_no_key_aliasing
|
||||
subq %r15,%rsp
|
||||
.Lenc_no_key_aliasing:
|
||||
|
||||
leaq (%rsi),%r14
|
||||
leaq -192(%rsi,%rdx,1),%r15
|
||||
shrq $4,%rdx
|
||||
|
||||
call _aesni_ctr32_6x
|
||||
vpshufb %xmm0,%xmm9,%xmm8
|
||||
vpshufb %xmm0,%xmm10,%xmm2
|
||||
vmovdqu %xmm8,112(%rsp)
|
||||
vpshufb %xmm0,%xmm11,%xmm4
|
||||
vmovdqu %xmm2,96(%rsp)
|
||||
vpshufb %xmm0,%xmm12,%xmm5
|
||||
vmovdqu %xmm4,80(%rsp)
|
||||
vpshufb %xmm0,%xmm13,%xmm6
|
||||
vmovdqu %xmm5,64(%rsp)
|
||||
vpshufb %xmm0,%xmm14,%xmm7
|
||||
vmovdqu %xmm6,48(%rsp)
|
||||
|
||||
call _aesni_ctr32_6x
|
||||
|
||||
vmovdqu (%r9),%xmm8
|
||||
leaq 32+32(%r9),%r9
|
||||
subq $12,%rdx
|
||||
movq $192,%r10
|
||||
vpshufb %xmm0,%xmm8,%xmm8
|
||||
|
||||
call _aesni_ctr32_ghash_6x
|
||||
vmovdqu 32(%rsp),%xmm7
|
||||
vmovdqu (%r11),%xmm0
|
||||
vmovdqu 0-32(%r9),%xmm3
|
||||
vpunpckhqdq %xmm7,%xmm7,%xmm1
|
||||
vmovdqu 32-32(%r9),%xmm15
|
||||
vmovups %xmm9,-96(%rsi)
|
||||
vpshufb %xmm0,%xmm9,%xmm9
|
||||
vpxor %xmm7,%xmm1,%xmm1
|
||||
vmovups %xmm10,-80(%rsi)
|
||||
vpshufb %xmm0,%xmm10,%xmm10
|
||||
vmovups %xmm11,-64(%rsi)
|
||||
vpshufb %xmm0,%xmm11,%xmm11
|
||||
vmovups %xmm12,-48(%rsi)
|
||||
vpshufb %xmm0,%xmm12,%xmm12
|
||||
vmovups %xmm13,-32(%rsi)
|
||||
vpshufb %xmm0,%xmm13,%xmm13
|
||||
vmovups %xmm14,-16(%rsi)
|
||||
vpshufb %xmm0,%xmm14,%xmm14
|
||||
vmovdqu %xmm9,16(%rsp)
|
||||
vmovdqu 48(%rsp),%xmm6
|
||||
vmovdqu 16-32(%r9),%xmm0
|
||||
vpunpckhqdq %xmm6,%xmm6,%xmm2
|
||||
vpclmulqdq $0x00,%xmm3,%xmm7,%xmm5
|
||||
vpxor %xmm6,%xmm2,%xmm2
|
||||
vpclmulqdq $0x11,%xmm3,%xmm7,%xmm7
|
||||
vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1
|
||||
|
||||
vmovdqu 64(%rsp),%xmm9
|
||||
vpclmulqdq $0x00,%xmm0,%xmm6,%xmm4
|
||||
vmovdqu 48-32(%r9),%xmm3
|
||||
vpxor %xmm5,%xmm4,%xmm4
|
||||
vpunpckhqdq %xmm9,%xmm9,%xmm5
|
||||
vpclmulqdq $0x11,%xmm0,%xmm6,%xmm6
|
||||
vpxor %xmm9,%xmm5,%xmm5
|
||||
vpxor %xmm7,%xmm6,%xmm6
|
||||
vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2
|
||||
vmovdqu 80-32(%r9),%xmm15
|
||||
vpxor %xmm1,%xmm2,%xmm2
|
||||
|
||||
vmovdqu 80(%rsp),%xmm1
|
||||
vpclmulqdq $0x00,%xmm3,%xmm9,%xmm7
|
||||
vmovdqu 64-32(%r9),%xmm0
|
||||
vpxor %xmm4,%xmm7,%xmm7
|
||||
vpunpckhqdq %xmm1,%xmm1,%xmm4
|
||||
vpclmulqdq $0x11,%xmm3,%xmm9,%xmm9
|
||||
vpxor %xmm1,%xmm4,%xmm4
|
||||
vpxor %xmm6,%xmm9,%xmm9
|
||||
vpclmulqdq $0x00,%xmm15,%xmm5,%xmm5
|
||||
vpxor %xmm2,%xmm5,%xmm5
|
||||
|
||||
vmovdqu 96(%rsp),%xmm2
|
||||
vpclmulqdq $0x00,%xmm0,%xmm1,%xmm6
|
||||
vmovdqu 96-32(%r9),%xmm3
|
||||
vpxor %xmm7,%xmm6,%xmm6
|
||||
vpunpckhqdq %xmm2,%xmm2,%xmm7
|
||||
vpclmulqdq $0x11,%xmm0,%xmm1,%xmm1
|
||||
vpxor %xmm2,%xmm7,%xmm7
|
||||
vpxor %xmm9,%xmm1,%xmm1
|
||||
vpclmulqdq $0x10,%xmm15,%xmm4,%xmm4
|
||||
vmovdqu 128-32(%r9),%xmm15
|
||||
vpxor %xmm5,%xmm4,%xmm4
|
||||
|
||||
vpxor 112(%rsp),%xmm8,%xmm8
|
||||
vpclmulqdq $0x00,%xmm3,%xmm2,%xmm5
|
||||
vmovdqu 112-32(%r9),%xmm0
|
||||
vpunpckhqdq %xmm8,%xmm8,%xmm9
|
||||
vpxor %xmm6,%xmm5,%xmm5
|
||||
vpclmulqdq $0x11,%xmm3,%xmm2,%xmm2
|
||||
vpxor %xmm8,%xmm9,%xmm9
|
||||
vpxor %xmm1,%xmm2,%xmm2
|
||||
vpclmulqdq $0x00,%xmm15,%xmm7,%xmm7
|
||||
vpxor %xmm4,%xmm7,%xmm4
|
||||
|
||||
vpclmulqdq $0x00,%xmm0,%xmm8,%xmm6
|
||||
vmovdqu 0-32(%r9),%xmm3
|
||||
vpunpckhqdq %xmm14,%xmm14,%xmm1
|
||||
vpclmulqdq $0x11,%xmm0,%xmm8,%xmm8
|
||||
vpxor %xmm14,%xmm1,%xmm1
|
||||
vpxor %xmm5,%xmm6,%xmm5
|
||||
vpclmulqdq $0x10,%xmm15,%xmm9,%xmm9
|
||||
vmovdqu 32-32(%r9),%xmm15
|
||||
vpxor %xmm2,%xmm8,%xmm7
|
||||
vpxor %xmm4,%xmm9,%xmm6
|
||||
|
||||
vmovdqu 16-32(%r9),%xmm0
|
||||
vpxor %xmm5,%xmm7,%xmm9
|
||||
vpclmulqdq $0x00,%xmm3,%xmm14,%xmm4
|
||||
vpxor %xmm9,%xmm6,%xmm6
|
||||
vpunpckhqdq %xmm13,%xmm13,%xmm2
|
||||
vpclmulqdq $0x11,%xmm3,%xmm14,%xmm14
|
||||
vpxor %xmm13,%xmm2,%xmm2
|
||||
vpslldq $8,%xmm6,%xmm9
|
||||
vpclmulqdq $0x00,%xmm15,%xmm1,%xmm1
|
||||
vpxor %xmm9,%xmm5,%xmm8
|
||||
vpsrldq $8,%xmm6,%xmm6
|
||||
vpxor %xmm6,%xmm7,%xmm7
|
||||
|
||||
vpclmulqdq $0x00,%xmm0,%xmm13,%xmm5
|
||||
vmovdqu 48-32(%r9),%xmm3
|
||||
vpxor %xmm4,%xmm5,%xmm5
|
||||
vpunpckhqdq %xmm12,%xmm12,%xmm9
|
||||
vpclmulqdq $0x11,%xmm0,%xmm13,%xmm13
|
||||
vpxor %xmm12,%xmm9,%xmm9
|
||||
vpxor %xmm14,%xmm13,%xmm13
|
||||
vpalignr $8,%xmm8,%xmm8,%xmm14
|
||||
vpclmulqdq $0x10,%xmm15,%xmm2,%xmm2
|
||||
vmovdqu 80-32(%r9),%xmm15
|
||||
vpxor %xmm1,%xmm2,%xmm2
|
||||
|
||||
vpclmulqdq $0x00,%xmm3,%xmm12,%xmm4
|
||||
vmovdqu 64-32(%r9),%xmm0
|
||||
vpxor %xmm5,%xmm4,%xmm4
|
||||
vpunpckhqdq %xmm11,%xmm11,%xmm1
|
||||
vpclmulqdq $0x11,%xmm3,%xmm12,%xmm12
|
||||
vpxor %xmm11,%xmm1,%xmm1
|
||||
vpxor %xmm13,%xmm12,%xmm12
|
||||
vxorps 16(%rsp),%xmm7,%xmm7
|
||||
vpclmulqdq $0x00,%xmm15,%xmm9,%xmm9
|
||||
vpxor %xmm2,%xmm9,%xmm9
|
||||
|
||||
vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8
|
||||
vxorps %xmm14,%xmm8,%xmm8
|
||||
|
||||
vpclmulqdq $0x00,%xmm0,%xmm11,%xmm5
|
||||
vmovdqu 96-32(%r9),%xmm3
|
||||
vpxor %xmm4,%xmm5,%xmm5
|
||||
vpunpckhqdq %xmm10,%xmm10,%xmm2
|
||||
vpclmulqdq $0x11,%xmm0,%xmm11,%xmm11
|
||||
vpxor %xmm10,%xmm2,%xmm2
|
||||
vpalignr $8,%xmm8,%xmm8,%xmm14
|
||||
vpxor %xmm12,%xmm11,%xmm11
|
||||
vpclmulqdq $0x10,%xmm15,%xmm1,%xmm1
|
||||
vmovdqu 128-32(%r9),%xmm15
|
||||
vpxor %xmm9,%xmm1,%xmm1
|
||||
|
||||
vxorps %xmm7,%xmm14,%xmm14
|
||||
vpclmulqdq $0x10,16(%r11),%xmm8,%xmm8
|
||||
vxorps %xmm14,%xmm8,%xmm8
|
||||
|
||||
vpclmulqdq $0x00,%xmm3,%xmm10,%xmm4
|
||||
vmovdqu 112-32(%r9),%xmm0
|
||||
vpxor %xmm5,%xmm4,%xmm4
|
||||
vpunpckhqdq %xmm8,%xmm8,%xmm9
|
||||
vpclmulqdq $0x11,%xmm3,%xmm10,%xmm10
|
||||
vpxor %xmm8,%xmm9,%xmm9
|
||||
vpxor %xmm11,%xmm10,%xmm10
|
||||
vpclmulqdq $0x00,%xmm15,%xmm2,%xmm2
|
||||
vpxor %xmm1,%xmm2,%xmm2
|
||||
|
||||
vpclmulqdq $0x00,%xmm0,%xmm8,%xmm5
|
||||
vpclmulqdq $0x11,%xmm0,%xmm8,%xmm7
|
||||
vpxor %xmm4,%xmm5,%xmm5
|
||||
vpclmulqdq $0x10,%xmm15,%xmm9,%xmm6
|
||||
vpxor %xmm10,%xmm7,%xmm7
|
||||
vpxor %xmm2,%xmm6,%xmm6
|
||||
|
||||
vpxor %xmm5,%xmm7,%xmm4
|
||||
vpxor %xmm4,%xmm6,%xmm6
|
||||
vpslldq $8,%xmm6,%xmm1
|
||||
vmovdqu 16(%r11),%xmm3
|
||||
vpsrldq $8,%xmm6,%xmm6
|
||||
vpxor %xmm1,%xmm5,%xmm8
|
||||
vpxor %xmm6,%xmm7,%xmm7
|
||||
|
||||
vpalignr $8,%xmm8,%xmm8,%xmm2
|
||||
vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8
|
||||
vpxor %xmm2,%xmm8,%xmm8
|
||||
|
||||
vpalignr $8,%xmm8,%xmm8,%xmm2
|
||||
vpclmulqdq $0x10,%xmm3,%xmm8,%xmm8
|
||||
vpxor %xmm7,%xmm2,%xmm2
|
||||
vpxor %xmm2,%xmm8,%xmm8
|
||||
vpshufb (%r11),%xmm8,%xmm8
|
||||
vmovdqu %xmm8,-64(%r9)
|
||||
|
||||
vzeroupper
|
||||
movq -48(%rax),%r15
|
||||
movq -40(%rax),%r14
|
||||
movq -32(%rax),%r13
|
||||
movq -24(%rax),%r12
|
||||
movq -16(%rax),%rbp
|
||||
movq -8(%rax),%rbx
|
||||
leaq (%rax),%rsp
|
||||
.Lgcm_enc_abort:
|
||||
movq %r10,%rax
|
||||
.byte 0xf3,0xc3
|
||||
.size aesni_gcm_encrypt,.-aesni_gcm_encrypt
|
||||
.align 64
|
||||
.Lbswap_mask:
|
||||
.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
|
||||
.Lpoly:
|
||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2
|
||||
.Lone_msb:
|
||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
|
||||
.Ltwo_lsb:
|
||||
.byte 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.Lone_lsb:
|
||||
.byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.byte 65,69,83,45,78,73,32,71,67,77,32,109,111,100,117,108,101,32,102,111,114,32,120,56,54,95,54,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
|
||||
.align 64
|
||||
@@ -0,0 +1,208 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC)
|
||||
# define STRICT_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], block128_f block)
|
||||
{
|
||||
size_t n;
|
||||
const unsigned char *iv = ivec;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (STRICT_ALIGNMENT &&
|
||||
((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
|
||||
while (len >= 16) {
|
||||
for (n = 0; n < 16; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
(*block) (out, out, key);
|
||||
iv = out;
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
} else {
|
||||
while (len >= 16) {
|
||||
for (n = 0; n < 16; n += sizeof(size_t))
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(in + n) ^ *(size_t *)(iv + n);
|
||||
(*block) (out, out, key);
|
||||
iv = out;
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (len) {
|
||||
for (n = 0; n < 16 && n < len; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
for (; n < 16; ++n)
|
||||
out[n] = iv[n];
|
||||
(*block) (out, out, key);
|
||||
iv = out;
|
||||
if (len <= 16)
|
||||
break;
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
memcpy(ivec, iv, 16);
|
||||
}
|
||||
|
||||
void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], block128_f block)
|
||||
{
|
||||
size_t n;
|
||||
union {
|
||||
size_t t[16 / sizeof(size_t)];
|
||||
unsigned char c[16];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (in != out) {
|
||||
const unsigned char *iv = ivec;
|
||||
|
||||
if (STRICT_ALIGNMENT &&
|
||||
((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
|
||||
while (len >= 16) {
|
||||
(*block) (in, out, key);
|
||||
for (n = 0; n < 16; ++n)
|
||||
out[n] ^= iv[n];
|
||||
iv = in;
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
} else if (16 % sizeof(size_t) == 0) { /* always true */
|
||||
while (len >= 16) {
|
||||
size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv;
|
||||
|
||||
(*block) (in, out, key);
|
||||
for (n = 0; n < 16 / sizeof(size_t); n++)
|
||||
out_t[n] ^= iv_t[n];
|
||||
iv = in;
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
memcpy(ivec, iv, 16);
|
||||
} else {
|
||||
if (STRICT_ALIGNMENT &&
|
||||
((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
|
||||
unsigned char c;
|
||||
while (len >= 16) {
|
||||
(*block) (in, tmp.c, key);
|
||||
for (n = 0; n < 16; ++n) {
|
||||
c = in[n];
|
||||
out[n] = tmp.c[n] ^ ivec[n];
|
||||
ivec[n] = c;
|
||||
}
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
} else if (16 % sizeof(size_t) == 0) { /* always true */
|
||||
while (len >= 16) {
|
||||
size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec;
|
||||
const size_t *in_t = (const size_t *)in;
|
||||
|
||||
(*block) (in, tmp.c, key);
|
||||
for (n = 0; n < 16 / sizeof(size_t); n++) {
|
||||
c = in_t[n];
|
||||
out_t[n] = tmp.t[n] ^ ivec_t[n];
|
||||
ivec_t[n] = c;
|
||||
}
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while (len) {
|
||||
unsigned char c;
|
||||
(*block) (in, tmp.c, key);
|
||||
for (n = 0; n < 16 && n < len; ++n) {
|
||||
c = in[n];
|
||||
out[n] = tmp.c[n] ^ ivec[n];
|
||||
ivec[n] = c;
|
||||
}
|
||||
if (len <= 16) {
|
||||
for (; n < 16; ++n)
|
||||
ivec[n] = in[n];
|
||||
break;
|
||||
}
|
||||
len -= 16;
|
||||
in += 16;
|
||||
out += 16;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,480 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2011 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* First you setup M and L parameters and pass the key schedule. This is
|
||||
* called once per session setup...
|
||||
*/
|
||||
void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
|
||||
unsigned int M, unsigned int L, void *key,
|
||||
block128_f block)
|
||||
{
|
||||
memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
|
||||
ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
|
||||
ctx->blocks = 0;
|
||||
ctx->block = block;
|
||||
ctx->key = key;
|
||||
}
|
||||
|
||||
/* !!! Following interfaces are to be called *once* per packet !!! */
|
||||
|
||||
/* Then you setup per-message nonce and pass the length of the message */
|
||||
int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
|
||||
const unsigned char *nonce, size_t nlen, size_t mlen)
|
||||
{
|
||||
unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
|
||||
|
||||
if (nlen < (14 - L))
|
||||
return -1; /* nonce is too short */
|
||||
|
||||
if (sizeof(mlen) == 8 && L >= 3) {
|
||||
ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
|
||||
ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
|
||||
ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
|
||||
ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
|
||||
} else
|
||||
ctx->nonce.u[1] = 0;
|
||||
|
||||
ctx->nonce.c[12] = (u8)(mlen >> 24);
|
||||
ctx->nonce.c[13] = (u8)(mlen >> 16);
|
||||
ctx->nonce.c[14] = (u8)(mlen >> 8);
|
||||
ctx->nonce.c[15] = (u8)mlen;
|
||||
|
||||
ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */
|
||||
memcpy(&ctx->nonce.c[1], nonce, 14 - L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Then you pass additional authentication data, this is optional */
|
||||
void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
|
||||
const unsigned char *aad, size_t alen)
|
||||
{
|
||||
unsigned int i;
|
||||
block128_f block = ctx->block;
|
||||
|
||||
if (alen == 0)
|
||||
return;
|
||||
|
||||
ctx->nonce.c[0] |= 0x40; /* set Adata flag */
|
||||
(*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
|
||||
|
||||
if (alen < (0x10000 - 0x100)) {
|
||||
ctx->cmac.c[0] ^= (u8)(alen >> 8);
|
||||
ctx->cmac.c[1] ^= (u8)alen;
|
||||
i = 2;
|
||||
} else if (sizeof(alen) == 8
|
||||
&& alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
|
||||
ctx->cmac.c[0] ^= 0xFF;
|
||||
ctx->cmac.c[1] ^= 0xFF;
|
||||
ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
|
||||
ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
|
||||
ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
|
||||
ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
|
||||
ctx->cmac.c[6] ^= (u8)(alen >> 24);
|
||||
ctx->cmac.c[7] ^= (u8)(alen >> 16);
|
||||
ctx->cmac.c[8] ^= (u8)(alen >> 8);
|
||||
ctx->cmac.c[9] ^= (u8)alen;
|
||||
i = 10;
|
||||
} else {
|
||||
ctx->cmac.c[0] ^= 0xFF;
|
||||
ctx->cmac.c[1] ^= 0xFE;
|
||||
ctx->cmac.c[2] ^= (u8)(alen >> 24);
|
||||
ctx->cmac.c[3] ^= (u8)(alen >> 16);
|
||||
ctx->cmac.c[4] ^= (u8)(alen >> 8);
|
||||
ctx->cmac.c[5] ^= (u8)alen;
|
||||
i = 6;
|
||||
}
|
||||
|
||||
do {
|
||||
for (; i < 16 && alen; ++i, ++aad, --alen)
|
||||
ctx->cmac.c[i] ^= *aad;
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
|
||||
i = 0;
|
||||
} while (alen);
|
||||
}
|
||||
|
||||
/* Finally you encrypt or decrypt the message */
|
||||
|
||||
/*
|
||||
* counter part of nonce may not be larger than L*8 bits, L is not larger
|
||||
* than 8, therefore 64-bit counter...
|
||||
*/
|
||||
static void ctr64_inc(unsigned char *counter)
|
||||
{
|
||||
unsigned int n = 8;
|
||||
u8 c;
|
||||
|
||||
counter += 8;
|
||||
do {
|
||||
--n;
|
||||
c = counter[n];
|
||||
++c;
|
||||
counter[n] = c;
|
||||
if (c)
|
||||
return;
|
||||
} while (n);
|
||||
}
|
||||
|
||||
int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
|
||||
const unsigned char *inp, unsigned char *out,
|
||||
size_t len)
|
||||
{
|
||||
size_t n;
|
||||
unsigned int i, L;
|
||||
unsigned char flags0 = ctx->nonce.c[0];
|
||||
block128_f block = ctx->block;
|
||||
void *key = ctx->key;
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} scratch;
|
||||
|
||||
if (!(flags0 & 0x40))
|
||||
(*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
|
||||
|
||||
ctx->nonce.c[0] = L = flags0 & 7;
|
||||
for (n = 0, i = 15 - L; i < 15; ++i) {
|
||||
n |= ctx->nonce.c[i];
|
||||
ctx->nonce.c[i] = 0;
|
||||
n <<= 8;
|
||||
}
|
||||
n |= ctx->nonce.c[15]; /* reconstructed length */
|
||||
ctx->nonce.c[15] = 1;
|
||||
|
||||
if (n != len)
|
||||
return -1; /* length mismatch */
|
||||
|
||||
ctx->blocks += ((len + 15) >> 3) | 1;
|
||||
if (ctx->blocks > (U64(1) << 61))
|
||||
return -2; /* too much data */
|
||||
|
||||
while (len >= 16) {
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} temp;
|
||||
|
||||
memcpy(temp.c, inp, 16);
|
||||
ctx->cmac.u[0] ^= temp.u[0];
|
||||
ctx->cmac.u[1] ^= temp.u[1];
|
||||
#else
|
||||
ctx->cmac.u[0] ^= ((u64 *)inp)[0];
|
||||
ctx->cmac.u[1] ^= ((u64 *)inp)[1];
|
||||
#endif
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
ctr64_inc(ctx->nonce.c);
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
temp.u[0] ^= scratch.u[0];
|
||||
temp.u[1] ^= scratch.u[1];
|
||||
memcpy(out, temp.c, 16);
|
||||
#else
|
||||
((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
|
||||
((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
|
||||
#endif
|
||||
inp += 16;
|
||||
out += 16;
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
for (i = 0; i < len; ++i)
|
||||
ctx->cmac.c[i] ^= inp[i];
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
for (i = 0; i < len; ++i)
|
||||
out[i] = scratch.c[i] ^ inp[i];
|
||||
}
|
||||
|
||||
for (i = 15 - L; i < 16; ++i)
|
||||
ctx->nonce.c[i] = 0;
|
||||
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
ctx->cmac.u[0] ^= scratch.u[0];
|
||||
ctx->cmac.u[1] ^= scratch.u[1];
|
||||
|
||||
ctx->nonce.c[0] = flags0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
|
||||
const unsigned char *inp, unsigned char *out,
|
||||
size_t len)
|
||||
{
|
||||
size_t n;
|
||||
unsigned int i, L;
|
||||
unsigned char flags0 = ctx->nonce.c[0];
|
||||
block128_f block = ctx->block;
|
||||
void *key = ctx->key;
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} scratch;
|
||||
|
||||
if (!(flags0 & 0x40))
|
||||
(*block) (ctx->nonce.c, ctx->cmac.c, key);
|
||||
|
||||
ctx->nonce.c[0] = L = flags0 & 7;
|
||||
for (n = 0, i = 15 - L; i < 15; ++i) {
|
||||
n |= ctx->nonce.c[i];
|
||||
ctx->nonce.c[i] = 0;
|
||||
n <<= 8;
|
||||
}
|
||||
n |= ctx->nonce.c[15]; /* reconstructed length */
|
||||
ctx->nonce.c[15] = 1;
|
||||
|
||||
if (n != len)
|
||||
return -1;
|
||||
|
||||
while (len >= 16) {
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} temp;
|
||||
#endif
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
ctr64_inc(ctx->nonce.c);
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
memcpy(temp.c, inp, 16);
|
||||
ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
|
||||
ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
|
||||
memcpy(out, scratch.c, 16);
|
||||
#else
|
||||
ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
|
||||
ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
|
||||
#endif
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
|
||||
inp += 16;
|
||||
out += 16;
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
for (i = 0; i < len; ++i)
|
||||
ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
}
|
||||
|
||||
for (i = 15 - L; i < 16; ++i)
|
||||
ctx->nonce.c[i] = 0;
|
||||
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
ctx->cmac.u[0] ^= scratch.u[0];
|
||||
ctx->cmac.u[1] ^= scratch.u[1];
|
||||
|
||||
ctx->nonce.c[0] = flags0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ctr64_add(unsigned char *counter, size_t inc)
|
||||
{
|
||||
size_t n = 8, val = 0;
|
||||
|
||||
counter += 8;
|
||||
do {
|
||||
--n;
|
||||
val += counter[n] + (inc & 0xff);
|
||||
counter[n] = (unsigned char)val;
|
||||
val >>= 8; /* carry bit */
|
||||
inc >>= 8;
|
||||
} while (n && (inc || val));
|
||||
}
|
||||
|
||||
int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
|
||||
const unsigned char *inp, unsigned char *out,
|
||||
size_t len, ccm128_f stream)
|
||||
{
|
||||
size_t n;
|
||||
unsigned int i, L;
|
||||
unsigned char flags0 = ctx->nonce.c[0];
|
||||
block128_f block = ctx->block;
|
||||
void *key = ctx->key;
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} scratch;
|
||||
|
||||
if (!(flags0 & 0x40))
|
||||
(*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
|
||||
|
||||
ctx->nonce.c[0] = L = flags0 & 7;
|
||||
for (n = 0, i = 15 - L; i < 15; ++i) {
|
||||
n |= ctx->nonce.c[i];
|
||||
ctx->nonce.c[i] = 0;
|
||||
n <<= 8;
|
||||
}
|
||||
n |= ctx->nonce.c[15]; /* reconstructed length */
|
||||
ctx->nonce.c[15] = 1;
|
||||
|
||||
if (n != len)
|
||||
return -1; /* length mismatch */
|
||||
|
||||
ctx->blocks += ((len + 15) >> 3) | 1;
|
||||
if (ctx->blocks > (U64(1) << 61))
|
||||
return -2; /* too much data */
|
||||
|
||||
if ((n = len / 16)) {
|
||||
(*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
|
||||
n *= 16;
|
||||
inp += n;
|
||||
out += n;
|
||||
len -= n;
|
||||
if (len)
|
||||
ctr64_add(ctx->nonce.c, n / 16);
|
||||
}
|
||||
|
||||
if (len) {
|
||||
for (i = 0; i < len; ++i)
|
||||
ctx->cmac.c[i] ^= inp[i];
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
for (i = 0; i < len; ++i)
|
||||
out[i] = scratch.c[i] ^ inp[i];
|
||||
}
|
||||
|
||||
for (i = 15 - L; i < 16; ++i)
|
||||
ctx->nonce.c[i] = 0;
|
||||
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
ctx->cmac.u[0] ^= scratch.u[0];
|
||||
ctx->cmac.u[1] ^= scratch.u[1];
|
||||
|
||||
ctx->nonce.c[0] = flags0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
|
||||
const unsigned char *inp, unsigned char *out,
|
||||
size_t len, ccm128_f stream)
|
||||
{
|
||||
size_t n;
|
||||
unsigned int i, L;
|
||||
unsigned char flags0 = ctx->nonce.c[0];
|
||||
block128_f block = ctx->block;
|
||||
void *key = ctx->key;
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} scratch;
|
||||
|
||||
if (!(flags0 & 0x40))
|
||||
(*block) (ctx->nonce.c, ctx->cmac.c, key);
|
||||
|
||||
ctx->nonce.c[0] = L = flags0 & 7;
|
||||
for (n = 0, i = 15 - L; i < 15; ++i) {
|
||||
n |= ctx->nonce.c[i];
|
||||
ctx->nonce.c[i] = 0;
|
||||
n <<= 8;
|
||||
}
|
||||
n |= ctx->nonce.c[15]; /* reconstructed length */
|
||||
ctx->nonce.c[15] = 1;
|
||||
|
||||
if (n != len)
|
||||
return -1;
|
||||
|
||||
if ((n = len / 16)) {
|
||||
(*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
|
||||
n *= 16;
|
||||
inp += n;
|
||||
out += n;
|
||||
len -= n;
|
||||
if (len)
|
||||
ctr64_add(ctx->nonce.c, n / 16);
|
||||
}
|
||||
|
||||
if (len) {
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
for (i = 0; i < len; ++i)
|
||||
ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
|
||||
(*block) (ctx->cmac.c, ctx->cmac.c, key);
|
||||
}
|
||||
|
||||
for (i = 15 - L; i < 16; ++i)
|
||||
ctx->nonce.c[i] = 0;
|
||||
|
||||
(*block) (ctx->nonce.c, scratch.c, key);
|
||||
ctx->cmac.u[0] ^= scratch.u[0];
|
||||
ctx->cmac.u[1] ^= scratch.u[1];
|
||||
|
||||
ctx->nonce.c[0] = flags0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
|
||||
{
|
||||
unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
|
||||
|
||||
M *= 2;
|
||||
M += 2;
|
||||
if (len < M)
|
||||
return 0;
|
||||
memcpy(tag, ctx->cmac.c, M);
|
||||
return M;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* The input and output encrypted as though 128bit cfb mode is being used.
|
||||
* The extra state information to record how much of the 128bit block we have
|
||||
* used is contained in *num;
|
||||
*/
|
||||
void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], int *num,
|
||||
int enc, block128_f block)
|
||||
{
|
||||
unsigned int n;
|
||||
size_t l = 0;
|
||||
|
||||
assert(in && out && key && ivec && num);
|
||||
|
||||
n = *num;
|
||||
|
||||
if (enc) {
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (16 % sizeof(size_t) == 0) { /* always true actually */
|
||||
do {
|
||||
while (n && len) {
|
||||
*(out++) = ivec[n] ^= *(in++);
|
||||
--len;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
# if defined(STRICT_ALIGNMENT)
|
||||
if (((size_t)in | (size_t)out | (size_t)ivec) %
|
||||
sizeof(size_t) != 0)
|
||||
break;
|
||||
# endif
|
||||
while (len >= 16) {
|
||||
(*block) (ivec, ivec, key);
|
||||
for (; n < 16; n += sizeof(size_t)) {
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(ivec + n) ^= *(size_t *)(in + n);
|
||||
}
|
||||
len -= 16;
|
||||
out += 16;
|
||||
in += 16;
|
||||
n = 0;
|
||||
}
|
||||
if (len) {
|
||||
(*block) (ivec, ivec, key);
|
||||
while (len--) {
|
||||
out[n] = ivec[n] ^= in[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
*num = n;
|
||||
return;
|
||||
} while (0);
|
||||
}
|
||||
/* the rest would be commonly eliminated by x86* compiler */
|
||||
#endif
|
||||
while (l < len) {
|
||||
if (n == 0) {
|
||||
(*block) (ivec, ivec, key);
|
||||
}
|
||||
out[l] = ivec[n] ^= in[l];
|
||||
++l;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
*num = n;
|
||||
} else {
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (16 % sizeof(size_t) == 0) { /* always true actually */
|
||||
do {
|
||||
while (n && len) {
|
||||
unsigned char c;
|
||||
*(out++) = ivec[n] ^ (c = *(in++));
|
||||
ivec[n] = c;
|
||||
--len;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
# if defined(STRICT_ALIGNMENT)
|
||||
if (((size_t)in | (size_t)out | (size_t)ivec) %
|
||||
sizeof(size_t) != 0)
|
||||
break;
|
||||
# endif
|
||||
while (len >= 16) {
|
||||
(*block) (ivec, ivec, key);
|
||||
for (; n < 16; n += sizeof(size_t)) {
|
||||
size_t t = *(size_t *)(in + n);
|
||||
*(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t;
|
||||
*(size_t *)(ivec + n) = t;
|
||||
}
|
||||
len -= 16;
|
||||
out += 16;
|
||||
in += 16;
|
||||
n = 0;
|
||||
}
|
||||
if (len) {
|
||||
(*block) (ivec, ivec, key);
|
||||
while (len--) {
|
||||
unsigned char c;
|
||||
out[n] = ivec[n] ^ (c = in[n]);
|
||||
ivec[n] = c;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
*num = n;
|
||||
return;
|
||||
} while (0);
|
||||
}
|
||||
/* the rest would be commonly eliminated by x86* compiler */
|
||||
#endif
|
||||
while (l < len) {
|
||||
unsigned char c;
|
||||
if (n == 0) {
|
||||
(*block) (ivec, ivec, key);
|
||||
}
|
||||
out[l] = ivec[n] ^ (c = in[l]);
|
||||
ivec[n] = c;
|
||||
++l;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
*num = n;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This expects a single block of size nbits for both in and out. Note that
|
||||
* it corrupts any extra bits in the last byte of out
|
||||
*/
|
||||
static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out,
|
||||
int nbits, const void *key,
|
||||
unsigned char ivec[16], int enc,
|
||||
block128_f block)
|
||||
{
|
||||
int n, rem, num;
|
||||
unsigned char ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't
|
||||
* use) one byte off the end */
|
||||
|
||||
if (nbits <= 0 || nbits > 128)
|
||||
return;
|
||||
|
||||
/* fill in the first half of the new IV with the current IV */
|
||||
memcpy(ovec, ivec, 16);
|
||||
/* construct the new IV */
|
||||
(*block) (ivec, ivec, key);
|
||||
num = (nbits + 7) / 8;
|
||||
if (enc) /* encrypt the input */
|
||||
for (n = 0; n < num; ++n)
|
||||
out[n] = (ovec[16 + n] = in[n] ^ ivec[n]);
|
||||
else /* decrypt the input */
|
||||
for (n = 0; n < num; ++n)
|
||||
out[n] = (ovec[16 + n] = in[n]) ^ ivec[n];
|
||||
/* shift ovec left... */
|
||||
rem = nbits % 8;
|
||||
num = nbits / 8;
|
||||
if (rem == 0)
|
||||
memcpy(ivec, ovec + num, 16);
|
||||
else
|
||||
for (n = 0; n < 16; ++n)
|
||||
ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem);
|
||||
|
||||
/* it is not necessary to cleanse ovec, since the IV is not secret */
|
||||
}
|
||||
|
||||
/* N.B. This expects the input to be packed, MS bit first */
|
||||
void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t bits, const void *key,
|
||||
unsigned char ivec[16], int *num,
|
||||
int enc, block128_f block)
|
||||
{
|
||||
size_t n;
|
||||
unsigned char c[1], d[1];
|
||||
|
||||
assert(in && out && key && ivec && num);
|
||||
assert(*num == 0);
|
||||
|
||||
for (n = 0; n < bits; ++n) {
|
||||
c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
|
||||
cfbr_encrypt_block(c, d, 1, key, ivec, enc, block);
|
||||
out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) |
|
||||
((d[0] & 0x80) >> (unsigned int)(n % 8));
|
||||
}
|
||||
}
|
||||
|
||||
void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const void *key,
|
||||
unsigned char ivec[16], int *num,
|
||||
int enc, block128_f block)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
assert(in && out && key && ivec && num);
|
||||
assert(*num == 0);
|
||||
|
||||
for (n = 0; n < length; ++n)
|
||||
cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block);
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* NOTE: the IV/counter CTR mode is big-endian. The code itself is
|
||||
* endian-neutral.
|
||||
*/
|
||||
|
||||
/* increment counter (128-bit int) by 1 */
|
||||
static void ctr128_inc(unsigned char *counter)
|
||||
{
|
||||
u32 n = 16, c = 1;
|
||||
|
||||
do {
|
||||
--n;
|
||||
c += counter[n];
|
||||
counter[n] = (u8)c;
|
||||
c >>= 8;
|
||||
} while (n);
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
static void ctr128_inc_aligned(unsigned char *counter)
|
||||
{
|
||||
size_t *data, c, d, n;
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = {
|
||||
1
|
||||
};
|
||||
|
||||
if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
|
||||
ctr128_inc(counter);
|
||||
return;
|
||||
}
|
||||
|
||||
data = (size_t *)counter;
|
||||
c = 1;
|
||||
n = 16 / sizeof(size_t);
|
||||
do {
|
||||
--n;
|
||||
d = data[n] += c;
|
||||
/* did addition carry? */
|
||||
c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
|
||||
} while (n);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The input encrypted as though 128bit counter mode is being used. The
|
||||
* extra state information to record how much of the 128bit block we have
|
||||
* used is contained in *num, and the encrypted counter is kept in
|
||||
* ecount_buf. Both *num and ecount_buf must be initialised with zeros
|
||||
* before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
|
||||
* that the counter is in the x lower bits of the IV (ivec), and that the
|
||||
* application has full control over overflow and the rest of the IV. This
|
||||
* implementation takes NO responsability for checking that the counter
|
||||
* doesn't overflow into the rest of the IV when incremented.
|
||||
*/
|
||||
void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16],
|
||||
unsigned char ecount_buf[16], unsigned int *num,
|
||||
block128_f block)
|
||||
{
|
||||
unsigned int n;
|
||||
size_t l = 0;
|
||||
|
||||
assert(in && out && key && ecount_buf && num);
|
||||
assert(*num < 16);
|
||||
|
||||
n = *num;
|
||||
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (16 % sizeof(size_t) == 0) { /* always true actually */
|
||||
do {
|
||||
while (n && len) {
|
||||
*(out++) = *(in++) ^ ecount_buf[n];
|
||||
--len;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
|
||||
# if defined(STRICT_ALIGNMENT)
|
||||
if (((size_t)in | (size_t)out | (size_t)ecount_buf)
|
||||
% sizeof(size_t) != 0)
|
||||
break;
|
||||
# endif
|
||||
while (len >= 16) {
|
||||
(*block) (ivec, ecount_buf, key);
|
||||
ctr128_inc_aligned(ivec);
|
||||
for (n = 0; n < 16; n += sizeof(size_t))
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
|
||||
len -= 16;
|
||||
out += 16;
|
||||
in += 16;
|
||||
n = 0;
|
||||
}
|
||||
if (len) {
|
||||
(*block) (ivec, ecount_buf, key);
|
||||
ctr128_inc_aligned(ivec);
|
||||
while (len--) {
|
||||
out[n] = in[n] ^ ecount_buf[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
*num = n;
|
||||
return;
|
||||
} while (0);
|
||||
}
|
||||
/* the rest would be commonly eliminated by x86* compiler */
|
||||
#endif
|
||||
while (l < len) {
|
||||
if (n == 0) {
|
||||
(*block) (ivec, ecount_buf, key);
|
||||
ctr128_inc(ivec);
|
||||
}
|
||||
out[l] = in[l] ^ ecount_buf[n];
|
||||
++l;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
|
||||
*num = n;
|
||||
}
|
||||
|
||||
/* increment upper 96 bits of 128-bit counter by 1 */
|
||||
static void ctr96_inc(unsigned char *counter)
|
||||
{
|
||||
u32 n = 12, c = 1;
|
||||
|
||||
do {
|
||||
--n;
|
||||
c += counter[n];
|
||||
counter[n] = (u8)c;
|
||||
c >>= 8;
|
||||
} while (n);
|
||||
}
|
||||
|
||||
void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16],
|
||||
unsigned char ecount_buf[16],
|
||||
unsigned int *num, ctr128_f func)
|
||||
{
|
||||
unsigned int n, ctr32;
|
||||
|
||||
assert(in && out && key && ecount_buf && num);
|
||||
assert(*num < 16);
|
||||
|
||||
n = *num;
|
||||
|
||||
while (n && len) {
|
||||
*(out++) = *(in++) ^ ecount_buf[n];
|
||||
--len;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
|
||||
ctr32 = GETU32(ivec + 12);
|
||||
while (len >= 16) {
|
||||
size_t blocks = len / 16;
|
||||
/*
|
||||
* 1<<28 is just a not-so-small yet not-so-large number...
|
||||
* Below condition is practically never met, but it has to
|
||||
* be checked for code correctness.
|
||||
*/
|
||||
if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
|
||||
blocks = (1U << 28);
|
||||
/*
|
||||
* As (*func) operates on 32-bit counter, caller
|
||||
* has to handle overflow. 'if' below detects the
|
||||
* overflow, which is then handled by limiting the
|
||||
* amount of blocks to the exact overflow point...
|
||||
*/
|
||||
ctr32 += (u32)blocks;
|
||||
if (ctr32 < blocks) {
|
||||
blocks -= ctr32;
|
||||
ctr32 = 0;
|
||||
}
|
||||
(*func) (in, out, blocks, key, ivec);
|
||||
/* (*ctr) does not update ivec, caller does: */
|
||||
PUTU32(ivec + 12, ctr32);
|
||||
/* ... overflow was detected, propogate carry. */
|
||||
if (ctr32 == 0)
|
||||
ctr96_inc(ivec);
|
||||
blocks *= 16;
|
||||
len -= blocks;
|
||||
out += blocks;
|
||||
in += blocks;
|
||||
}
|
||||
if (len) {
|
||||
memset(ecount_buf, 0, 16);
|
||||
(*func) (ecount_buf, ecount_buf, 1, key, ivec);
|
||||
++ctr32;
|
||||
PUTU32(ivec + 12, ctr32);
|
||||
if (ctr32 == 0)
|
||||
ctr96_inc(ivec);
|
||||
while (len--) {
|
||||
out[n] = in[n] ^ ecount_buf[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
*num = n;
|
||||
}
|
||||
@@ -0,0 +1,545 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Rights for redistribution and usage in source and binary
|
||||
* forms are granted according to the OpenSSL license.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Trouble with Ciphertext Stealing, CTS, mode is that there is no
|
||||
* common official specification, but couple of cipher/application
|
||||
* specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
|
||||
* Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
|
||||
* deviates from mentioned RFCs. Most notably it allows input to be
|
||||
* of block length and it doesn't flip the order of the last two
|
||||
* blocks. CTS is being discussed even in ECB context, but it's not
|
||||
* adopted for any known application. This implementation provides
|
||||
* two interfaces: one compliant with above mentioned RFCs and one
|
||||
* compliant with the NIST proposal, both extending CBC mode.
|
||||
*/
|
||||
|
||||
size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
const void *key, unsigned char ivec[16],
|
||||
block128_f block)
|
||||
{
|
||||
size_t residue, n;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len <= 16)
|
||||
return 0;
|
||||
|
||||
if ((residue = len % 16) == 0)
|
||||
residue = 16;
|
||||
|
||||
len -= residue;
|
||||
|
||||
CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
|
||||
|
||||
in += len;
|
||||
out += len;
|
||||
|
||||
for (n = 0; n < residue; ++n)
|
||||
ivec[n] ^= in[n];
|
||||
(*block) (ivec, ivec, key);
|
||||
memcpy(out, out - 16, residue);
|
||||
memcpy(out - 16, ivec, 16);
|
||||
|
||||
return len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
const void *key,
|
||||
unsigned char ivec[16],
|
||||
block128_f block)
|
||||
{
|
||||
size_t residue, n;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len < 16)
|
||||
return 0;
|
||||
|
||||
residue = len % 16;
|
||||
|
||||
len -= residue;
|
||||
|
||||
CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
|
||||
|
||||
if (residue == 0)
|
||||
return len;
|
||||
|
||||
in += len;
|
||||
out += len;
|
||||
|
||||
for (n = 0; n < residue; ++n)
|
||||
ivec[n] ^= in[n];
|
||||
(*block) (ivec, ivec, key);
|
||||
memcpy(out - 16 + residue, ivec, 16);
|
||||
|
||||
return len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], cbc128_f cbc)
|
||||
{
|
||||
size_t residue;
|
||||
union {
|
||||
size_t align;
|
||||
unsigned char c[16];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len <= 16)
|
||||
return 0;
|
||||
|
||||
if ((residue = len % 16) == 0)
|
||||
residue = 16;
|
||||
|
||||
len -= residue;
|
||||
|
||||
(*cbc) (in, out, len, key, ivec, 1);
|
||||
|
||||
in += len;
|
||||
out += len;
|
||||
|
||||
#if defined(CBC_HANDLES_TRUNCATED_IO)
|
||||
memcpy(tmp.c, out - 16, 16);
|
||||
(*cbc) (in, out - 16, residue, key, ivec, 1);
|
||||
memcpy(out, tmp.c, residue);
|
||||
#else
|
||||
memset(tmp.c, 0, sizeof(tmp));
|
||||
memcpy(tmp.c, in, residue);
|
||||
memcpy(out, out - 16, residue);
|
||||
(*cbc) (tmp.c, out - 16, 16, key, ivec, 1);
|
||||
#endif
|
||||
return len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], cbc128_f cbc)
|
||||
{
|
||||
size_t residue;
|
||||
union {
|
||||
size_t align;
|
||||
unsigned char c[16];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len < 16)
|
||||
return 0;
|
||||
|
||||
residue = len % 16;
|
||||
|
||||
len -= residue;
|
||||
|
||||
(*cbc) (in, out, len, key, ivec, 1);
|
||||
|
||||
if (residue == 0)
|
||||
return len;
|
||||
|
||||
in += len;
|
||||
out += len;
|
||||
|
||||
#if defined(CBC_HANDLES_TRUNCATED_IO)
|
||||
(*cbc) (in, out - 16 + residue, residue, key, ivec, 1);
|
||||
#else
|
||||
memset(tmp.c, 0, sizeof(tmp));
|
||||
memcpy(tmp.c, in, residue);
|
||||
(*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1);
|
||||
#endif
|
||||
return len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
const void *key, unsigned char ivec[16],
|
||||
block128_f block)
|
||||
{
|
||||
size_t residue, n;
|
||||
union {
|
||||
size_t align;
|
||||
unsigned char c[32];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len <= 16)
|
||||
return 0;
|
||||
|
||||
if ((residue = len % 16) == 0)
|
||||
residue = 16;
|
||||
|
||||
len -= 16 + residue;
|
||||
|
||||
if (len) {
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
|
||||
in += len;
|
||||
out += len;
|
||||
}
|
||||
|
||||
(*block) (in, tmp.c + 16, key);
|
||||
|
||||
memcpy(tmp.c, tmp.c + 16, 16);
|
||||
memcpy(tmp.c, in + 16, residue);
|
||||
(*block) (tmp.c, tmp.c, key);
|
||||
|
||||
for (n = 0; n < 16; ++n) {
|
||||
unsigned char c = in[n];
|
||||
out[n] = tmp.c[n] ^ ivec[n];
|
||||
ivec[n] = c;
|
||||
}
|
||||
for (residue += 16; n < residue; ++n)
|
||||
out[n] = tmp.c[n] ^ in[n];
|
||||
|
||||
return 16 + len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
const void *key,
|
||||
unsigned char ivec[16],
|
||||
block128_f block)
|
||||
{
|
||||
size_t residue, n;
|
||||
union {
|
||||
size_t align;
|
||||
unsigned char c[32];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len < 16)
|
||||
return 0;
|
||||
|
||||
residue = len % 16;
|
||||
|
||||
if (residue == 0) {
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
|
||||
return len;
|
||||
}
|
||||
|
||||
len -= 16 + residue;
|
||||
|
||||
if (len) {
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
|
||||
in += len;
|
||||
out += len;
|
||||
}
|
||||
|
||||
(*block) (in + residue, tmp.c + 16, key);
|
||||
|
||||
memcpy(tmp.c, tmp.c + 16, 16);
|
||||
memcpy(tmp.c, in, residue);
|
||||
(*block) (tmp.c, tmp.c, key);
|
||||
|
||||
for (n = 0; n < 16; ++n) {
|
||||
unsigned char c = in[n];
|
||||
out[n] = tmp.c[n] ^ ivec[n];
|
||||
ivec[n] = in[n + residue];
|
||||
tmp.c[n] = c;
|
||||
}
|
||||
for (residue += 16; n < residue; ++n)
|
||||
out[n] = tmp.c[n] ^ tmp.c[n - 16];
|
||||
|
||||
return 16 + len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], cbc128_f cbc)
|
||||
{
|
||||
size_t residue;
|
||||
union {
|
||||
size_t align;
|
||||
unsigned char c[32];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len <= 16)
|
||||
return 0;
|
||||
|
||||
if ((residue = len % 16) == 0)
|
||||
residue = 16;
|
||||
|
||||
len -= 16 + residue;
|
||||
|
||||
if (len) {
|
||||
(*cbc) (in, out, len, key, ivec, 0);
|
||||
in += len;
|
||||
out += len;
|
||||
}
|
||||
|
||||
memset(tmp.c, 0, sizeof(tmp));
|
||||
/*
|
||||
* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
|
||||
*/
|
||||
(*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0);
|
||||
|
||||
memcpy(tmp.c, in + 16, residue);
|
||||
#if defined(CBC_HANDLES_TRUNCATED_IO)
|
||||
(*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
|
||||
#else
|
||||
(*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
|
||||
memcpy(out, tmp.c, 16 + residue);
|
||||
#endif
|
||||
return 16 + len + residue;
|
||||
}
|
||||
|
||||
size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], cbc128_f cbc)
|
||||
{
|
||||
size_t residue;
|
||||
union {
|
||||
size_t align;
|
||||
unsigned char c[32];
|
||||
} tmp;
|
||||
|
||||
assert(in && out && key && ivec);
|
||||
|
||||
if (len < 16)
|
||||
return 0;
|
||||
|
||||
residue = len % 16;
|
||||
|
||||
if (residue == 0) {
|
||||
(*cbc) (in, out, len, key, ivec, 0);
|
||||
return len;
|
||||
}
|
||||
|
||||
len -= 16 + residue;
|
||||
|
||||
if (len) {
|
||||
(*cbc) (in, out, len, key, ivec, 0);
|
||||
in += len;
|
||||
out += len;
|
||||
}
|
||||
|
||||
memset(tmp.c, 0, sizeof(tmp));
|
||||
/*
|
||||
* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
|
||||
*/
|
||||
(*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0);
|
||||
|
||||
memcpy(tmp.c, in, residue);
|
||||
#if defined(CBC_HANDLES_TRUNCATED_IO)
|
||||
(*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
|
||||
#else
|
||||
(*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
|
||||
memcpy(out, tmp.c, 16 + residue);
|
||||
#endif
|
||||
return 16 + len + residue;
|
||||
}
|
||||
|
||||
#if defined(SELFTEST)
|
||||
# include <stdio.h>
|
||||
# include <openssl/aes.h>
|
||||
|
||||
/* test vectors from RFC 3962 */
|
||||
static const unsigned char test_key[16] = "chicken teriyaki";
|
||||
static const unsigned char test_input[64] =
|
||||
"I would like the" " General Gau's C"
|
||||
"hicken, please, " "and wonton soup.";
|
||||
static const unsigned char test_iv[16] =
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static const unsigned char vector_17[17] = {
|
||||
0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4,
|
||||
0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f,
|
||||
0x97
|
||||
};
|
||||
|
||||
static const unsigned char vector_31[31] = {
|
||||
0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1,
|
||||
0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22,
|
||||
0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
|
||||
0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5
|
||||
};
|
||||
|
||||
static const unsigned char vector_32[32] = {
|
||||
0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
|
||||
0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
|
||||
0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
|
||||
0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84
|
||||
};
|
||||
|
||||
static const unsigned char vector_47[47] = {
|
||||
0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
|
||||
0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
|
||||
0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
|
||||
0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e,
|
||||
0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
|
||||
0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
|
||||
};
|
||||
|
||||
static const unsigned char vector_48[48] = {
|
||||
0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
|
||||
0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
|
||||
0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
|
||||
0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8,
|
||||
0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
|
||||
0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8
|
||||
};
|
||||
|
||||
static const unsigned char vector_64[64] = {
|
||||
0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
|
||||
0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
|
||||
0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
|
||||
0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
|
||||
0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5,
|
||||
0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40,
|
||||
0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
|
||||
0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
|
||||
};
|
||||
|
||||
static AES_KEY encks, decks;
|
||||
|
||||
void test_vector(const unsigned char *vector, size_t len)
|
||||
{
|
||||
unsigned char iv[sizeof(test_iv)];
|
||||
unsigned char cleartext[64], ciphertext[64];
|
||||
size_t tail;
|
||||
|
||||
printf("vector_%d\n", len);
|
||||
fflush(stdout);
|
||||
|
||||
if ((tail = len % 16) == 0)
|
||||
tail = 16;
|
||||
tail += 16;
|
||||
|
||||
/* test block-based encryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_cts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
|
||||
(block128_f) AES_encrypt);
|
||||
if (memcmp(ciphertext, vector, len))
|
||||
fprintf(stderr, "output_%d mismatch\n", len), exit(1);
|
||||
if (memcmp(iv, vector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
|
||||
|
||||
/* test block-based decryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
|
||||
(block128_f) AES_decrypt);
|
||||
if (memcmp(cleartext, test_input, len))
|
||||
fprintf(stderr, "input_%d mismatch\n", len), exit(2);
|
||||
if (memcmp(iv, vector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
|
||||
|
||||
/* test streamed encryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_cts128_encrypt(test_input, ciphertext, len, &encks, iv,
|
||||
(cbc128_f) AES_cbc_encrypt);
|
||||
if (memcmp(ciphertext, vector, len))
|
||||
fprintf(stderr, "output_%d mismatch\n", len), exit(3);
|
||||
if (memcmp(iv, vector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
|
||||
|
||||
/* test streamed decryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_cts128_decrypt(ciphertext, cleartext, len, &decks, iv,
|
||||
(cbc128_f) AES_cbc_encrypt);
|
||||
if (memcmp(cleartext, test_input, len))
|
||||
fprintf(stderr, "input_%d mismatch\n", len), exit(4);
|
||||
if (memcmp(iv, vector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
|
||||
}
|
||||
|
||||
void test_nistvector(const unsigned char *vector, size_t len)
|
||||
{
|
||||
unsigned char iv[sizeof(test_iv)];
|
||||
unsigned char cleartext[64], ciphertext[64], nistvector[64];
|
||||
size_t tail;
|
||||
|
||||
printf("nistvector_%d\n", len);
|
||||
fflush(stdout);
|
||||
|
||||
if ((tail = len % 16) == 0)
|
||||
tail = 16;
|
||||
|
||||
len -= 16 + tail;
|
||||
memcpy(nistvector, vector, len);
|
||||
/* flip two last blocks */
|
||||
memcpy(nistvector + len, vector + len + 16, tail);
|
||||
memcpy(nistvector + len + tail, vector + len, 16);
|
||||
len += 16 + tail;
|
||||
tail = 16;
|
||||
|
||||
/* test block-based encryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
|
||||
(block128_f) AES_encrypt);
|
||||
if (memcmp(ciphertext, nistvector, len))
|
||||
fprintf(stderr, "output_%d mismatch\n", len), exit(1);
|
||||
if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
|
||||
|
||||
/* test block-based decryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
|
||||
(block128_f) AES_decrypt);
|
||||
if (memcmp(cleartext, test_input, len))
|
||||
fprintf(stderr, "input_%d mismatch\n", len), exit(2);
|
||||
if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
|
||||
|
||||
/* test streamed encryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv,
|
||||
(cbc128_f) AES_cbc_encrypt);
|
||||
if (memcmp(ciphertext, nistvector, len))
|
||||
fprintf(stderr, "output_%d mismatch\n", len), exit(3);
|
||||
if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
|
||||
|
||||
/* test streamed decryption */
|
||||
memcpy(iv, test_iv, sizeof(test_iv));
|
||||
CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, &decks, iv,
|
||||
(cbc128_f) AES_cbc_encrypt);
|
||||
if (memcmp(cleartext, test_input, len))
|
||||
fprintf(stderr, "input_%d mismatch\n", len), exit(4);
|
||||
if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
|
||||
fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
AES_set_encrypt_key(test_key, 128, &encks);
|
||||
AES_set_decrypt_key(test_key, 128, &decks);
|
||||
|
||||
test_vector(vector_17, sizeof(vector_17));
|
||||
test_vector(vector_31, sizeof(vector_31));
|
||||
test_vector(vector_32, sizeof(vector_32));
|
||||
test_vector(vector_47, sizeof(vector_47));
|
||||
test_vector(vector_48, sizeof(vector_48));
|
||||
test_vector(vector_64, sizeof(vector_64));
|
||||
|
||||
test_nistvector(vector_17, sizeof(vector_17));
|
||||
test_nistvector(vector_31, sizeof(vector_31));
|
||||
test_nistvector(vector_32, sizeof(vector_32));
|
||||
test_nistvector(vector_47, sizeof(vector_47));
|
||||
test_nistvector(vector_48, sizeof(vector_48));
|
||||
test_nistvector(vector_64, sizeof(vector_64));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,528 @@
|
||||
#include "../arm_arch.h"
|
||||
|
||||
.text
|
||||
.code 32
|
||||
|
||||
#ifdef __clang__
|
||||
#define ldrplb ldrbpl
|
||||
#define ldrneb ldrbne
|
||||
#endif
|
||||
|
||||
.type rem_4bit,@object
|
||||
.align 5
|
||||
rem_4bit:
|
||||
.short 0x0000,0x1C20,0x3840,0x2460
|
||||
.short 0x7080,0x6CA0,0x48C0,0x54E0
|
||||
.short 0xE100,0xFD20,0xD940,0xC560
|
||||
.short 0x9180,0x8DA0,0xA9C0,0xB5E0
|
||||
.size rem_4bit,.-rem_4bit
|
||||
|
||||
.type rem_4bit_get,@function
|
||||
rem_4bit_get:
|
||||
sub r2,pc,#8
|
||||
sub r2,r2,#32 @ &rem_4bit
|
||||
b .Lrem_4bit_got
|
||||
nop
|
||||
.size rem_4bit_get,.-rem_4bit_get
|
||||
|
||||
.global gcm_ghash_4bit
|
||||
.type gcm_ghash_4bit,@function
|
||||
gcm_ghash_4bit:
|
||||
sub r12,pc,#8
|
||||
add r3,r2,r3 @ r3 to point at the end
|
||||
stmdb sp!,{r3-r11,lr} @ save r3/end too
|
||||
sub r12,r12,#48 @ &rem_4bit
|
||||
|
||||
ldmia r12,{r4-r11} @ copy rem_4bit ...
|
||||
stmdb sp!,{r4-r11} @ ... to stack
|
||||
|
||||
ldrb r12,[r2,#15]
|
||||
ldrb r14,[r0,#15]
|
||||
.Louter:
|
||||
eor r12,r12,r14
|
||||
and r14,r12,#0xf0
|
||||
and r12,r12,#0x0f
|
||||
mov r3,#14
|
||||
|
||||
add r7,r1,r12,lsl#4
|
||||
ldmia r7,{r4-r7} @ load Htbl[nlo]
|
||||
add r11,r1,r14
|
||||
ldrb r12,[r2,#14]
|
||||
|
||||
and r14,r4,#0xf @ rem
|
||||
ldmia r11,{r8-r11} @ load Htbl[nhi]
|
||||
add r14,r14,r14
|
||||
eor r4,r8,r4,lsr#4
|
||||
ldrh r8,[sp,r14] @ rem_4bit[rem]
|
||||
eor r4,r4,r5,lsl#28
|
||||
ldrb r14,[r0,#14]
|
||||
eor r5,r9,r5,lsr#4
|
||||
eor r5,r5,r6,lsl#28
|
||||
eor r6,r10,r6,lsr#4
|
||||
eor r6,r6,r7,lsl#28
|
||||
eor r7,r11,r7,lsr#4
|
||||
eor r12,r12,r14
|
||||
and r14,r12,#0xf0
|
||||
and r12,r12,#0x0f
|
||||
eor r7,r7,r8,lsl#16
|
||||
|
||||
.Linner:
|
||||
add r11,r1,r12,lsl#4
|
||||
and r12,r4,#0xf @ rem
|
||||
subs r3,r3,#1
|
||||
add r12,r12,r12
|
||||
ldmia r11,{r8-r11} @ load Htbl[nlo]
|
||||
eor r4,r8,r4,lsr#4
|
||||
eor r4,r4,r5,lsl#28
|
||||
eor r5,r9,r5,lsr#4
|
||||
eor r5,r5,r6,lsl#28
|
||||
ldrh r8,[sp,r12] @ rem_4bit[rem]
|
||||
eor r6,r10,r6,lsr#4
|
||||
ldrplb r12,[r2,r3]
|
||||
eor r6,r6,r7,lsl#28
|
||||
eor r7,r11,r7,lsr#4
|
||||
|
||||
add r11,r1,r14
|
||||
and r14,r4,#0xf @ rem
|
||||
eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem]
|
||||
add r14,r14,r14
|
||||
ldmia r11,{r8-r11} @ load Htbl[nhi]
|
||||
eor r4,r8,r4,lsr#4
|
||||
ldrplb r8,[r0,r3]
|
||||
eor r4,r4,r5,lsl#28
|
||||
eor r5,r9,r5,lsr#4
|
||||
ldrh r9,[sp,r14]
|
||||
eor r5,r5,r6,lsl#28
|
||||
eor r6,r10,r6,lsr#4
|
||||
eor r6,r6,r7,lsl#28
|
||||
eorpl r12,r12,r8
|
||||
eor r7,r11,r7,lsr#4
|
||||
andpl r14,r12,#0xf0
|
||||
andpl r12,r12,#0x0f
|
||||
eor r7,r7,r9,lsl#16 @ ^= rem_4bit[rem]
|
||||
bpl .Linner
|
||||
|
||||
ldr r3,[sp,#32] @ re-load r3/end
|
||||
add r2,r2,#16
|
||||
mov r14,r4
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r4,r4
|
||||
str r4,[r0,#12]
|
||||
#elif defined(__ARMEB__)
|
||||
str r4,[r0,#12]
|
||||
#else
|
||||
mov r9,r4,lsr#8
|
||||
strb r4,[r0,#12+3]
|
||||
mov r10,r4,lsr#16
|
||||
strb r9,[r0,#12+2]
|
||||
mov r11,r4,lsr#24
|
||||
strb r10,[r0,#12+1]
|
||||
strb r11,[r0,#12]
|
||||
#endif
|
||||
cmp r2,r3
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r5,r5
|
||||
str r5,[r0,#8]
|
||||
#elif defined(__ARMEB__)
|
||||
str r5,[r0,#8]
|
||||
#else
|
||||
mov r9,r5,lsr#8
|
||||
strb r5,[r0,#8+3]
|
||||
mov r10,r5,lsr#16
|
||||
strb r9,[r0,#8+2]
|
||||
mov r11,r5,lsr#24
|
||||
strb r10,[r0,#8+1]
|
||||
strb r11,[r0,#8]
|
||||
#endif
|
||||
ldrneb r12,[r2,#15]
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r6,r6
|
||||
str r6,[r0,#4]
|
||||
#elif defined(__ARMEB__)
|
||||
str r6,[r0,#4]
|
||||
#else
|
||||
mov r9,r6,lsr#8
|
||||
strb r6,[r0,#4+3]
|
||||
mov r10,r6,lsr#16
|
||||
strb r9,[r0,#4+2]
|
||||
mov r11,r6,lsr#24
|
||||
strb r10,[r0,#4+1]
|
||||
strb r11,[r0,#4]
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r7,r7
|
||||
str r7,[r0,#0]
|
||||
#elif defined(__ARMEB__)
|
||||
str r7,[r0,#0]
|
||||
#else
|
||||
mov r9,r7,lsr#8
|
||||
strb r7,[r0,#0+3]
|
||||
mov r10,r7,lsr#16
|
||||
strb r9,[r0,#0+2]
|
||||
mov r11,r7,lsr#24
|
||||
strb r10,[r0,#0+1]
|
||||
strb r11,[r0,#0]
|
||||
#endif
|
||||
|
||||
bne .Louter
|
||||
|
||||
add sp,sp,#36
|
||||
#if __ARM_ARCH__>=5
|
||||
ldmia sp!,{r4-r11,pc}
|
||||
#else
|
||||
ldmia sp!,{r4-r11,lr}
|
||||
tst lr,#1
|
||||
moveq pc,lr @ be binary compatible with V4, yet
|
||||
.word 0xe12fff1e @ interoperable with Thumb ISA:-)
|
||||
#endif
|
||||
.size gcm_ghash_4bit,.-gcm_ghash_4bit
|
||||
|
||||
.global gcm_gmult_4bit
|
||||
.type gcm_gmult_4bit,@function
|
||||
gcm_gmult_4bit:
|
||||
stmdb sp!,{r4-r11,lr}
|
||||
ldrb r12,[r0,#15]
|
||||
b rem_4bit_get
|
||||
.Lrem_4bit_got:
|
||||
and r14,r12,#0xf0
|
||||
and r12,r12,#0x0f
|
||||
mov r3,#14
|
||||
|
||||
add r7,r1,r12,lsl#4
|
||||
ldmia r7,{r4-r7} @ load Htbl[nlo]
|
||||
ldrb r12,[r0,#14]
|
||||
|
||||
add r11,r1,r14
|
||||
and r14,r4,#0xf @ rem
|
||||
ldmia r11,{r8-r11} @ load Htbl[nhi]
|
||||
add r14,r14,r14
|
||||
eor r4,r8,r4,lsr#4
|
||||
ldrh r8,[r2,r14] @ rem_4bit[rem]
|
||||
eor r4,r4,r5,lsl#28
|
||||
eor r5,r9,r5,lsr#4
|
||||
eor r5,r5,r6,lsl#28
|
||||
eor r6,r10,r6,lsr#4
|
||||
eor r6,r6,r7,lsl#28
|
||||
eor r7,r11,r7,lsr#4
|
||||
and r14,r12,#0xf0
|
||||
eor r7,r7,r8,lsl#16
|
||||
and r12,r12,#0x0f
|
||||
|
||||
.Loop:
|
||||
add r11,r1,r12,lsl#4
|
||||
and r12,r4,#0xf @ rem
|
||||
subs r3,r3,#1
|
||||
add r12,r12,r12
|
||||
ldmia r11,{r8-r11} @ load Htbl[nlo]
|
||||
eor r4,r8,r4,lsr#4
|
||||
eor r4,r4,r5,lsl#28
|
||||
eor r5,r9,r5,lsr#4
|
||||
eor r5,r5,r6,lsl#28
|
||||
ldrh r8,[r2,r12] @ rem_4bit[rem]
|
||||
eor r6,r10,r6,lsr#4
|
||||
ldrplb r12,[r0,r3]
|
||||
eor r6,r6,r7,lsl#28
|
||||
eor r7,r11,r7,lsr#4
|
||||
|
||||
add r11,r1,r14
|
||||
and r14,r4,#0xf @ rem
|
||||
eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem]
|
||||
add r14,r14,r14
|
||||
ldmia r11,{r8-r11} @ load Htbl[nhi]
|
||||
eor r4,r8,r4,lsr#4
|
||||
eor r4,r4,r5,lsl#28
|
||||
eor r5,r9,r5,lsr#4
|
||||
ldrh r8,[r2,r14] @ rem_4bit[rem]
|
||||
eor r5,r5,r6,lsl#28
|
||||
eor r6,r10,r6,lsr#4
|
||||
eor r6,r6,r7,lsl#28
|
||||
eor r7,r11,r7,lsr#4
|
||||
andpl r14,r12,#0xf0
|
||||
andpl r12,r12,#0x0f
|
||||
eor r7,r7,r8,lsl#16 @ ^= rem_4bit[rem]
|
||||
bpl .Loop
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r4,r4
|
||||
str r4,[r0,#12]
|
||||
#elif defined(__ARMEB__)
|
||||
str r4,[r0,#12]
|
||||
#else
|
||||
mov r9,r4,lsr#8
|
||||
strb r4,[r0,#12+3]
|
||||
mov r10,r4,lsr#16
|
||||
strb r9,[r0,#12+2]
|
||||
mov r11,r4,lsr#24
|
||||
strb r10,[r0,#12+1]
|
||||
strb r11,[r0,#12]
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r5,r5
|
||||
str r5,[r0,#8]
|
||||
#elif defined(__ARMEB__)
|
||||
str r5,[r0,#8]
|
||||
#else
|
||||
mov r9,r5,lsr#8
|
||||
strb r5,[r0,#8+3]
|
||||
mov r10,r5,lsr#16
|
||||
strb r9,[r0,#8+2]
|
||||
mov r11,r5,lsr#24
|
||||
strb r10,[r0,#8+1]
|
||||
strb r11,[r0,#8]
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r6,r6
|
||||
str r6,[r0,#4]
|
||||
#elif defined(__ARMEB__)
|
||||
str r6,[r0,#4]
|
||||
#else
|
||||
mov r9,r6,lsr#8
|
||||
strb r6,[r0,#4+3]
|
||||
mov r10,r6,lsr#16
|
||||
strb r9,[r0,#4+2]
|
||||
mov r11,r6,lsr#24
|
||||
strb r10,[r0,#4+1]
|
||||
strb r11,[r0,#4]
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__>=7 && defined(__ARMEL__)
|
||||
rev r7,r7
|
||||
str r7,[r0,#0]
|
||||
#elif defined(__ARMEB__)
|
||||
str r7,[r0,#0]
|
||||
#else
|
||||
mov r9,r7,lsr#8
|
||||
strb r7,[r0,#0+3]
|
||||
mov r10,r7,lsr#16
|
||||
strb r9,[r0,#0+2]
|
||||
mov r11,r7,lsr#24
|
||||
strb r10,[r0,#0+1]
|
||||
strb r11,[r0,#0]
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH__>=5
|
||||
ldmia sp!,{r4-r11,pc}
|
||||
#else
|
||||
ldmia sp!,{r4-r11,lr}
|
||||
tst lr,#1
|
||||
moveq pc,lr @ be binary compatible with V4, yet
|
||||
.word 0xe12fff1e @ interoperable with Thumb ISA:-)
|
||||
#endif
|
||||
.size gcm_gmult_4bit,.-gcm_gmult_4bit
|
||||
#if __ARM_MAX_ARCH__>=7
|
||||
.arch armv7-a
|
||||
.fpu neon
|
||||
|
||||
.global gcm_init_neon
|
||||
.type gcm_init_neon,@function
|
||||
.align 4
|
||||
gcm_init_neon:
|
||||
vld1.64 d7,[r1,:64]! @ load H
|
||||
vmov.i8 q8,#0xe1
|
||||
vld1.64 d6,[r1,:64]
|
||||
vshl.i64 d17,#57
|
||||
vshr.u64 d16,#63 @ t0=0xc2....01
|
||||
vdup.8 q9,d7[7]
|
||||
vshr.u64 d26,d6,#63
|
||||
vshr.s8 q9,#7 @ broadcast carry bit
|
||||
vshl.i64 q3,q3,#1
|
||||
vand q8,q8,q9
|
||||
vorr d7,d26 @ H<<<=1
|
||||
veor q3,q3,q8 @ twisted H
|
||||
vstmia r0,{q3}
|
||||
|
||||
bx lr @ bx lr
|
||||
.size gcm_init_neon,.-gcm_init_neon
|
||||
|
||||
.global gcm_gmult_neon
|
||||
.type gcm_gmult_neon,@function
|
||||
.align 4
|
||||
gcm_gmult_neon:
|
||||
vld1.64 d7,[r0,:64]! @ load Xi
|
||||
vld1.64 d6,[r0,:64]!
|
||||
vmov.i64 d29,#0x0000ffffffffffff
|
||||
vldmia r1,{d26-d27} @ load twisted H
|
||||
vmov.i64 d30,#0x00000000ffffffff
|
||||
#ifdef __ARMEL__
|
||||
vrev64.8 q3,q3
|
||||
#endif
|
||||
vmov.i64 d31,#0x000000000000ffff
|
||||
veor d28,d26,d27 @ Karatsuba pre-processing
|
||||
mov r3,#16
|
||||
b .Lgmult_neon
|
||||
.size gcm_gmult_neon,.-gcm_gmult_neon
|
||||
|
||||
.global gcm_ghash_neon
|
||||
.type gcm_ghash_neon,@function
|
||||
.align 4
|
||||
gcm_ghash_neon:
|
||||
vld1.64 d1,[r0,:64]! @ load Xi
|
||||
vld1.64 d0,[r0,:64]!
|
||||
vmov.i64 d29,#0x0000ffffffffffff
|
||||
vldmia r1,{d26-d27} @ load twisted H
|
||||
vmov.i64 d30,#0x00000000ffffffff
|
||||
#ifdef __ARMEL__
|
||||
vrev64.8 q0,q0
|
||||
#endif
|
||||
vmov.i64 d31,#0x000000000000ffff
|
||||
veor d28,d26,d27 @ Karatsuba pre-processing
|
||||
|
||||
.Loop_neon:
|
||||
vld1.64 d7,[r2]! @ load inp
|
||||
vld1.64 d6,[r2]!
|
||||
#ifdef __ARMEL__
|
||||
vrev64.8 q3,q3
|
||||
#endif
|
||||
veor q3,q0 @ inp^=Xi
|
||||
.Lgmult_neon:
|
||||
vext.8 d16, d26, d26, #1 @ A1
|
||||
vmull.p8 q8, d16, d6 @ F = A1*B
|
||||
vext.8 d0, d6, d6, #1 @ B1
|
||||
vmull.p8 q0, d26, d0 @ E = A*B1
|
||||
vext.8 d18, d26, d26, #2 @ A2
|
||||
vmull.p8 q9, d18, d6 @ H = A2*B
|
||||
vext.8 d22, d6, d6, #2 @ B2
|
||||
vmull.p8 q11, d26, d22 @ G = A*B2
|
||||
vext.8 d20, d26, d26, #3 @ A3
|
||||
veor q8, q8, q0 @ L = E + F
|
||||
vmull.p8 q10, d20, d6 @ J = A3*B
|
||||
vext.8 d0, d6, d6, #3 @ B3
|
||||
veor q9, q9, q11 @ M = G + H
|
||||
vmull.p8 q0, d26, d0 @ I = A*B3
|
||||
veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8
|
||||
vand d17, d17, d29
|
||||
vext.8 d22, d6, d6, #4 @ B4
|
||||
veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16
|
||||
vand d19, d19, d30
|
||||
vmull.p8 q11, d26, d22 @ K = A*B4
|
||||
veor q10, q10, q0 @ N = I + J
|
||||
veor d16, d16, d17
|
||||
veor d18, d18, d19
|
||||
veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24
|
||||
vand d21, d21, d31
|
||||
vext.8 q8, q8, q8, #15
|
||||
veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32
|
||||
vmov.i64 d23, #0
|
||||
vext.8 q9, q9, q9, #14
|
||||
veor d20, d20, d21
|
||||
vmull.p8 q0, d26, d6 @ D = A*B
|
||||
vext.8 q11, q11, q11, #12
|
||||
vext.8 q10, q10, q10, #13
|
||||
veor q8, q8, q9
|
||||
veor q10, q10, q11
|
||||
veor q0, q0, q8
|
||||
veor q0, q0, q10
|
||||
veor d6,d6,d7 @ Karatsuba pre-processing
|
||||
vext.8 d16, d28, d28, #1 @ A1
|
||||
vmull.p8 q8, d16, d6 @ F = A1*B
|
||||
vext.8 d2, d6, d6, #1 @ B1
|
||||
vmull.p8 q1, d28, d2 @ E = A*B1
|
||||
vext.8 d18, d28, d28, #2 @ A2
|
||||
vmull.p8 q9, d18, d6 @ H = A2*B
|
||||
vext.8 d22, d6, d6, #2 @ B2
|
||||
vmull.p8 q11, d28, d22 @ G = A*B2
|
||||
vext.8 d20, d28, d28, #3 @ A3
|
||||
veor q8, q8, q1 @ L = E + F
|
||||
vmull.p8 q10, d20, d6 @ J = A3*B
|
||||
vext.8 d2, d6, d6, #3 @ B3
|
||||
veor q9, q9, q11 @ M = G + H
|
||||
vmull.p8 q1, d28, d2 @ I = A*B3
|
||||
veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8
|
||||
vand d17, d17, d29
|
||||
vext.8 d22, d6, d6, #4 @ B4
|
||||
veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16
|
||||
vand d19, d19, d30
|
||||
vmull.p8 q11, d28, d22 @ K = A*B4
|
||||
veor q10, q10, q1 @ N = I + J
|
||||
veor d16, d16, d17
|
||||
veor d18, d18, d19
|
||||
veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24
|
||||
vand d21, d21, d31
|
||||
vext.8 q8, q8, q8, #15
|
||||
veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32
|
||||
vmov.i64 d23, #0
|
||||
vext.8 q9, q9, q9, #14
|
||||
veor d20, d20, d21
|
||||
vmull.p8 q1, d28, d6 @ D = A*B
|
||||
vext.8 q11, q11, q11, #12
|
||||
vext.8 q10, q10, q10, #13
|
||||
veor q8, q8, q9
|
||||
veor q10, q10, q11
|
||||
veor q1, q1, q8
|
||||
veor q1, q1, q10
|
||||
vext.8 d16, d27, d27, #1 @ A1
|
||||
vmull.p8 q8, d16, d7 @ F = A1*B
|
||||
vext.8 d4, d7, d7, #1 @ B1
|
||||
vmull.p8 q2, d27, d4 @ E = A*B1
|
||||
vext.8 d18, d27, d27, #2 @ A2
|
||||
vmull.p8 q9, d18, d7 @ H = A2*B
|
||||
vext.8 d22, d7, d7, #2 @ B2
|
||||
vmull.p8 q11, d27, d22 @ G = A*B2
|
||||
vext.8 d20, d27, d27, #3 @ A3
|
||||
veor q8, q8, q2 @ L = E + F
|
||||
vmull.p8 q10, d20, d7 @ J = A3*B
|
||||
vext.8 d4, d7, d7, #3 @ B3
|
||||
veor q9, q9, q11 @ M = G + H
|
||||
vmull.p8 q2, d27, d4 @ I = A*B3
|
||||
veor d16, d16, d17 @ t0 = (L) (P0 + P1) << 8
|
||||
vand d17, d17, d29
|
||||
vext.8 d22, d7, d7, #4 @ B4
|
||||
veor d18, d18, d19 @ t1 = (M) (P2 + P3) << 16
|
||||
vand d19, d19, d30
|
||||
vmull.p8 q11, d27, d22 @ K = A*B4
|
||||
veor q10, q10, q2 @ N = I + J
|
||||
veor d16, d16, d17
|
||||
veor d18, d18, d19
|
||||
veor d20, d20, d21 @ t2 = (N) (P4 + P5) << 24
|
||||
vand d21, d21, d31
|
||||
vext.8 q8, q8, q8, #15
|
||||
veor d22, d22, d23 @ t3 = (K) (P6 + P7) << 32
|
||||
vmov.i64 d23, #0
|
||||
vext.8 q9, q9, q9, #14
|
||||
veor d20, d20, d21
|
||||
vmull.p8 q2, d27, d7 @ D = A*B
|
||||
vext.8 q11, q11, q11, #12
|
||||
vext.8 q10, q10, q10, #13
|
||||
veor q8, q8, q9
|
||||
veor q10, q10, q11
|
||||
veor q2, q2, q8
|
||||
veor q2, q2, q10
|
||||
veor q1,q1,q0 @ Karatsuba post-processing
|
||||
veor q1,q1,q2
|
||||
veor d1,d1,d2
|
||||
veor d4,d4,d3 @ Xh|Xl - 256-bit result
|
||||
|
||||
@ equivalent of reduction_avx from ghash-x86_64.pl
|
||||
vshl.i64 q9,q0,#57 @ 1st phase
|
||||
vshl.i64 q10,q0,#62
|
||||
veor q10,q10,q9 @
|
||||
vshl.i64 q9,q0,#63
|
||||
veor q10, q10, q9 @
|
||||
veor d1,d1,d20 @
|
||||
veor d4,d4,d21
|
||||
|
||||
vshr.u64 q10,q0,#1 @ 2nd phase
|
||||
veor q2,q2,q0
|
||||
veor q0,q0,q10 @
|
||||
vshr.u64 q10,q10,#6
|
||||
vshr.u64 q0,q0,#1 @
|
||||
veor q0,q0,q2 @
|
||||
veor q0,q0,q10 @
|
||||
|
||||
subs r3,#16
|
||||
bne .Loop_neon
|
||||
|
||||
#ifdef __ARMEL__
|
||||
vrev64.8 q0,q0
|
||||
#endif
|
||||
sub r0,#16
|
||||
vst1.64 d1,[r0,:64]! @ write out Xi
|
||||
vst1.64 d0,[r0,:64]
|
||||
|
||||
bx lr @ bx lr
|
||||
.size gcm_ghash_neon,.-gcm_ghash_neon
|
||||
#endif
|
||||
.asciz "GHASH for ARMv4/NEON, CRYPTOGAMS by <appro@openssl.org>"
|
||||
.align 2
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
/* modes_asm.s - assembler optimization code for modes */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016-2017 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
06jun17,l_y Support ASM for simpc
|
||||
22aug16,l_y Created for vx7 openssl-1.0.2h update
|
||||
*/
|
||||
|
||||
#define _ASMLANGUAGE
|
||||
#include <vxWorks.h>
|
||||
|
||||
#ifndef _WRS_CONFIG_LP64
|
||||
#include "ghash-x86.s"
|
||||
#else
|
||||
#include "ghash-x86_64.s"
|
||||
#define Lbswap_mask Lbswap_mask_gcm
|
||||
#include "aesni-gcm-x86_64.s"
|
||||
#endif
|
||||
@@ -0,0 +1,143 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2010 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use is governed by OpenSSL license.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <openssl/modes.h>
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
|
||||
typedef __int64 i64;
|
||||
typedef unsigned __int64 u64;
|
||||
# define U64(C) C##UI64
|
||||
#elif defined(__arch64__)
|
||||
typedef long i64;
|
||||
typedef unsigned long u64;
|
||||
# define U64(C) C##UL
|
||||
#else
|
||||
typedef long long i64;
|
||||
typedef unsigned long long u64;
|
||||
# define U64(C) C##ULL
|
||||
#endif
|
||||
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned char u8;
|
||||
|
||||
#define STRICT_ALIGNMENT 1
|
||||
#ifndef PEDANTIC
|
||||
# if defined(__i386) || defined(__i386__) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
|
||||
defined(__aarch64__) || \
|
||||
defined(__s390__) || defined(__s390x__)
|
||||
# undef STRICT_ALIGNMENT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
|
||||
# if defined(__GNUC__) && __GNUC__>=2
|
||||
# if defined(__x86_64) || defined(__x86_64__)
|
||||
# define BSWAP8(x) ({ u64 ret_=(x); \
|
||||
asm ("bswapq %0" \
|
||||
: "+r"(ret_)); ret_; })
|
||||
# define BSWAP4(x) ({ u32 ret_=(x); \
|
||||
asm ("bswapl %0" \
|
||||
: "+r"(ret_)); ret_; })
|
||||
# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
|
||||
# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \
|
||||
asm ("bswapl %0; bswapl %1" \
|
||||
: "+r"(hi_),"+r"(lo_)); \
|
||||
(u64)hi_<<32|lo_; })
|
||||
# define BSWAP4(x) ({ u32 ret_=(x); \
|
||||
asm ("bswapl %0" \
|
||||
: "+r"(ret_)); ret_; })
|
||||
# elif defined(__aarch64__)
|
||||
# define BSWAP8(x) ({ u64 ret_; \
|
||||
asm ("rev %0,%1" \
|
||||
: "=r"(ret_) : "r"(x)); ret_; })
|
||||
# define BSWAP4(x) ({ u32 ret_; \
|
||||
asm ("rev %w0,%w1" \
|
||||
: "=r"(ret_) : "r"(x)); ret_; })
|
||||
# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
|
||||
# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \
|
||||
asm ("rev %0,%0; rev %1,%1" \
|
||||
: "+r"(hi_),"+r"(lo_)); \
|
||||
(u64)hi_<<32|lo_; })
|
||||
# define BSWAP4(x) ({ u32 ret_; \
|
||||
asm ("rev %0,%1" \
|
||||
: "=r"(ret_) : "r"((u32)(x))); \
|
||||
ret_; })
|
||||
# endif
|
||||
# elif defined(_MSC_VER)
|
||||
# if _MSC_VER>=1300
|
||||
# pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
|
||||
# define BSWAP8(x) _byteswap_uint64((u64)(x))
|
||||
# define BSWAP4(x) _byteswap_ulong((u32)(x))
|
||||
# elif defined(_M_IX86)
|
||||
__inline u32 _bswap4(u32 val)
|
||||
{
|
||||
_asm mov eax, val _asm bswap eax}
|
||||
# define BSWAP4(x) _bswap4(x)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
|
||||
# define GETU32(p) BSWAP4(*(const u32 *)(p))
|
||||
# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v)
|
||||
#else
|
||||
# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
|
||||
# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
|
||||
#endif
|
||||
/*- GCM definitions */ typedef struct {
|
||||
u64 hi, lo;
|
||||
} u128;
|
||||
|
||||
#ifdef TABLE_BITS
|
||||
# undef TABLE_BITS
|
||||
#endif
|
||||
/*
|
||||
* Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
|
||||
* never be set to 8 [or 1]. For further information see gcm128.c.
|
||||
*/
|
||||
#define TABLE_BITS 4
|
||||
|
||||
struct gcm128_context {
|
||||
/* Following 6 names follow names in GCM specification */
|
||||
union {
|
||||
u64 u[2];
|
||||
u32 d[4];
|
||||
u8 c[16];
|
||||
size_t t[16 / sizeof(size_t)];
|
||||
} Yi, EKi, EK0, len, Xi, H;
|
||||
/*
|
||||
* Relative position of Xi, H and pre-computed Htable is used in some
|
||||
* assembler modules, i.e. don't change the order!
|
||||
*/
|
||||
#if TABLE_BITS==8
|
||||
u128 Htable[256];
|
||||
#else
|
||||
u128 Htable[16];
|
||||
void (*gmult) (u64 Xi[2], const u128 Htable[16]);
|
||||
void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp,
|
||||
size_t len);
|
||||
#endif
|
||||
unsigned int mres, ares;
|
||||
block128_f block;
|
||||
void *key;
|
||||
};
|
||||
|
||||
struct xts128_context {
|
||||
void *key1, *key2;
|
||||
block128_f block1, block2;
|
||||
};
|
||||
|
||||
struct ccm128_context {
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} nonce, cmac;
|
||||
u64 blocks;
|
||||
block128_f block;
|
||||
void *key;
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* The input and output encrypted as though 128bit ofb mode is being used.
|
||||
* The extra state information to record how much of the 128bit block we have
|
||||
* used is contained in *num;
|
||||
*/
|
||||
void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], int *num, block128_f block)
|
||||
{
|
||||
unsigned int n;
|
||||
size_t l = 0;
|
||||
|
||||
assert(in && out && key && ivec && num);
|
||||
|
||||
n = *num;
|
||||
|
||||
#if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (16 % sizeof(size_t) == 0) { /* always true actually */
|
||||
do {
|
||||
while (n && len) {
|
||||
*(out++) = *(in++) ^ ivec[n];
|
||||
--len;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
# if defined(STRICT_ALIGNMENT)
|
||||
if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) !=
|
||||
0)
|
||||
break;
|
||||
# endif
|
||||
while (len >= 16) {
|
||||
(*block) (ivec, ivec, key);
|
||||
for (; n < 16; n += sizeof(size_t))
|
||||
*(size_t *)(out + n) =
|
||||
*(size_t *)(in + n) ^ *(size_t *)(ivec + n);
|
||||
len -= 16;
|
||||
out += 16;
|
||||
in += 16;
|
||||
n = 0;
|
||||
}
|
||||
if (len) {
|
||||
(*block) (ivec, ivec, key);
|
||||
while (len--) {
|
||||
out[n] = in[n] ^ ivec[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
*num = n;
|
||||
return;
|
||||
} while (0);
|
||||
}
|
||||
/* the rest would be commonly eliminated by x86* compiler */
|
||||
#endif
|
||||
while (l < len) {
|
||||
if (n == 0) {
|
||||
(*block) (ivec, ivec, key);
|
||||
}
|
||||
out[l] = in[l] ^ ivec[n];
|
||||
++l;
|
||||
n = (n + 1) % 16;
|
||||
}
|
||||
|
||||
*num = n;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/* crypto/modes/wrap128.c */
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2013 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/modes.h>
|
||||
|
||||
static const unsigned char default_iv[] = {
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
|
||||
};
|
||||
|
||||
/*
|
||||
* Input size limit: lower than maximum of standards but far larger than
|
||||
* anything that will be used in practice.
|
||||
*/
|
||||
#define CRYPTO128_WRAP_MAX (1UL << 31)
|
||||
|
||||
size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
|
||||
unsigned char *out,
|
||||
const unsigned char *in, size_t inlen,
|
||||
block128_f block)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
size_t i, j, t;
|
||||
if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX))
|
||||
return 0;
|
||||
A = B;
|
||||
t = 1;
|
||||
memmove(out + 8, in, inlen);
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
|
||||
memcpy(A, iv, 8);
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
R = out + 8;
|
||||
for (i = 0; i < inlen; i += 8, t++, R += 8) {
|
||||
memcpy(B + 8, R, 8);
|
||||
block(B, B, key);
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff) {
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
memcpy(out, A, 8);
|
||||
return inlen + 8;
|
||||
}
|
||||
|
||||
size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
|
||||
unsigned char *out,
|
||||
const unsigned char *in, size_t inlen,
|
||||
block128_f block)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
size_t i, j, t;
|
||||
inlen -= 8;
|
||||
if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
|
||||
return 0;
|
||||
A = B;
|
||||
t = 6 * (inlen >> 3);
|
||||
memcpy(A, in, 8);
|
||||
memmove(out, in + 8, inlen);
|
||||
for (j = 0; j < 6; j++) {
|
||||
R = out + inlen - 8;
|
||||
for (i = 0; i < inlen; i += 8, t--, R -= 8) {
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff) {
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(B + 8, R, 8);
|
||||
block(B, B, key);
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
if (memcmp(A, iv, 8)) {
|
||||
OPENSSL_cleanse(out, inlen);
|
||||
return 0;
|
||||
}
|
||||
return inlen;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2011 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "modes_lcl.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef MODES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
|
||||
const unsigned char iv[16],
|
||||
const unsigned char *inp, unsigned char *out,
|
||||
size_t len, int enc)
|
||||
{
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = {
|
||||
1
|
||||
};
|
||||
union {
|
||||
u64 u[2];
|
||||
u32 d[4];
|
||||
u8 c[16];
|
||||
} tweak, scratch;
|
||||
unsigned int i;
|
||||
|
||||
if (len < 16)
|
||||
return -1;
|
||||
|
||||
memcpy(tweak.c, iv, 16);
|
||||
|
||||
(*ctx->block2) (tweak.c, tweak.c, ctx->key2);
|
||||
|
||||
if (!enc && (len % 16))
|
||||
len -= 16;
|
||||
|
||||
while (len >= 16) {
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
memcpy(scratch.c, inp, 16);
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
#else
|
||||
scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0];
|
||||
scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1];
|
||||
#endif
|
||||
(*ctx->block1) (scratch.c, scratch.c, ctx->key1);
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
memcpy(out, scratch.c, 16);
|
||||
#else
|
||||
((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0];
|
||||
((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1];
|
||||
#endif
|
||||
inp += 16;
|
||||
out += 16;
|
||||
len -= 16;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (is_endian.little) {
|
||||
unsigned int carry, res;
|
||||
|
||||
res = 0x87 & (((int)tweak.d[3]) >> 31);
|
||||
carry = (unsigned int)(tweak.u[0] >> 63);
|
||||
tweak.u[0] = (tweak.u[0] << 1) ^ res;
|
||||
tweak.u[1] = (tweak.u[1] << 1) | carry;
|
||||
} else {
|
||||
size_t c;
|
||||
|
||||
for (c = 0, i = 0; i < 16; ++i) {
|
||||
/*
|
||||
* + substitutes for |, because c is 1 bit
|
||||
*/
|
||||
c += ((size_t)tweak.c[i]) << 1;
|
||||
tweak.c[i] = (u8)c;
|
||||
c = c >> 8;
|
||||
}
|
||||
tweak.c[0] ^= (u8)(0x87 & (0 - c));
|
||||
}
|
||||
}
|
||||
if (enc) {
|
||||
for (i = 0; i < len; ++i) {
|
||||
u8 c = inp[i];
|
||||
out[i] = scratch.c[i];
|
||||
scratch.c[i] = c;
|
||||
}
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
(*ctx->block1) (scratch.c, scratch.c, ctx->key1);
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
memcpy(out - 16, scratch.c, 16);
|
||||
} else {
|
||||
union {
|
||||
u64 u[2];
|
||||
u8 c[16];
|
||||
} tweak1;
|
||||
|
||||
if (is_endian.little) {
|
||||
unsigned int carry, res;
|
||||
|
||||
res = 0x87 & (((int)tweak.d[3]) >> 31);
|
||||
carry = (unsigned int)(tweak.u[0] >> 63);
|
||||
tweak1.u[0] = (tweak.u[0] << 1) ^ res;
|
||||
tweak1.u[1] = (tweak.u[1] << 1) | carry;
|
||||
} else {
|
||||
size_t c;
|
||||
|
||||
for (c = 0, i = 0; i < 16; ++i) {
|
||||
/*
|
||||
* + substitutes for |, because c is 1 bit
|
||||
*/
|
||||
c += ((size_t)tweak.c[i]) << 1;
|
||||
tweak1.c[i] = (u8)c;
|
||||
c = c >> 8;
|
||||
}
|
||||
tweak1.c[0] ^= (u8)(0x87 & (0 - c));
|
||||
}
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
memcpy(scratch.c, inp, 16);
|
||||
scratch.u[0] ^= tweak1.u[0];
|
||||
scratch.u[1] ^= tweak1.u[1];
|
||||
#else
|
||||
scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0];
|
||||
scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1];
|
||||
#endif
|
||||
(*ctx->block1) (scratch.c, scratch.c, ctx->key1);
|
||||
scratch.u[0] ^= tweak1.u[0];
|
||||
scratch.u[1] ^= tweak1.u[1];
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
u8 c = inp[16 + i];
|
||||
out[16 + i] = scratch.c[i];
|
||||
scratch.c[i] = c;
|
||||
}
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
(*ctx->block1) (scratch.c, scratch.c, ctx->key1);
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
memcpy(out, scratch.c, 16);
|
||||
#else
|
||||
((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0];
|
||||
((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user