Update pre9
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the OpenSSL license (the "License"). You may not use
|
||||
# this file except in compliance with the License. You can obtain a copy
|
||||
@@ -28,33 +28,32 @@
|
||||
#
|
||||
# Performance in cycles per byte out of large buffer.
|
||||
#
|
||||
# IALU/gcc 4.8(i) 1xSSSE3/SSE2 4xSSSE3 NxAVX(v)
|
||||
# IALU/gcc 4.8(i) 1x/2xSSSE3(ii) 4xSSSE3 NxAVX(v)
|
||||
#
|
||||
# P4 9.48/+99% -/22.7(ii) -
|
||||
# Core2 7.83/+55% 7.90/8.08 4.35
|
||||
# Westmere 7.19/+50% 5.60/6.70 3.00
|
||||
# Sandy Bridge 8.31/+42% 5.45/6.76 2.72
|
||||
# Ivy Bridge 6.71/+46% 5.40/6.49 2.41
|
||||
# Haswell 5.92/+43% 5.20/6.45 2.42 1.23
|
||||
# Skylake[-X] 5.87/+39% 4.70/- 2.31 1.19[0.80(vi)]
|
||||
# Silvermont 12.0/+33% 7.75/7.40 7.03(iii)
|
||||
# Knights L 11.7/- - 9.60(iii) 0.80
|
||||
# Goldmont 10.6/+17% 5.10/- 3.28
|
||||
# Sledgehammer 7.28/+52% -/14.2(ii) -
|
||||
# Bulldozer 9.66/+28% 9.85/11.1 3.06(iv)
|
||||
# Ryzen 5.96/+50% 5.19/- 2.40 2.09
|
||||
# VIA Nano 10.5/+46% 6.72/8.60 6.05
|
||||
# P4 9.48/+99% - -
|
||||
# Core2 7.83/+55% 7.90/5.76 4.35
|
||||
# Westmere 7.19/+50% 5.60/4.50 3.00
|
||||
# Sandy Bridge 8.31/+42% 5.45/4.00 2.72
|
||||
# Ivy Bridge 6.71/+46% 5.40/? 2.41
|
||||
# Haswell 5.92/+43% 5.20/3.45 2.42 1.23
|
||||
# Skylake[-X] 5.87/+39% 4.70/3.22 2.31 1.19[0.80(vi)]
|
||||
# Silvermont 12.0/+33% 7.75/6.90 7.03(iii)
|
||||
# Knights L 11.7/- ? 9.60(iii) 0.80
|
||||
# Goldmont 10.6/+17% 5.10/3.52 3.28
|
||||
# Sledgehammer 7.28/+52% - -
|
||||
# Bulldozer 9.66/+28% 9.85/5.35(iv) 3.06(iv)
|
||||
# Ryzen 5.96/+50% 5.19/3.00 2.40 2.09
|
||||
# VIA Nano 10.5/+46% 6.72/6.88 6.05
|
||||
#
|
||||
# (i) compared to older gcc 3.x one can observe >2x improvement on
|
||||
# most platforms;
|
||||
# (ii) as it can be seen, SSE2 performance is too low on legacy
|
||||
# processors; NxSSE2 results are naturally better, but not
|
||||
# impressively better than IALU ones, which is why you won't
|
||||
# find SSE2 code below;
|
||||
# (ii) 2xSSSE3 is code path optimized specifically for 128 bytes used
|
||||
# by chacha20_poly1305_tls_cipher, results are EVP-free;
|
||||
# (iii) this is not optimal result for Atom because of MSROM
|
||||
# limitations, SSE2 can do better, but gain is considered too
|
||||
# low to justify the [maintenance] effort;
|
||||
# (iv) Bulldozer actually executes 4xXOP code path that delivers 2.20;
|
||||
# (iv) Bulldozer actually executes 4xXOP code path that delivers 2.20
|
||||
# and 4.85 for 128-byte inputs;
|
||||
# (v) 8xAVX2, 8xAVX512VL or 16xAVX512F, whichever best applicable;
|
||||
# (vi) even though Skylake-X can execute AVX512F code and deliver 0.57
|
||||
# cpb in single thread, the corresponding capability is suppressed;
|
||||
@@ -489,6 +488,7 @@ $code.=<<___ if ($avx);
|
||||
___
|
||||
$code.=<<___;
|
||||
cmp \$128,$len # we might throw away some data,
|
||||
je .LChaCha20_128
|
||||
ja .LChaCha20_4x # but overall it won't be slower
|
||||
|
||||
.Ldo_sse3_after_all:
|
||||
@@ -605,6 +605,172 @@ $code.=<<___;
|
||||
___
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# SSSE3 code path that handles 128-byte inputs
|
||||
{
|
||||
my ($a,$b,$c,$d,$t,$t1,$rot16,$rot24)=map("%xmm$_",(8,9,2..7));
|
||||
my ($a1,$b1,$c1,$d1)=map("%xmm$_",(10,11,0,1));
|
||||
|
||||
sub SSSE3ROUND_2x {
|
||||
&paddd ($a,$b);
|
||||
&pxor ($d,$a);
|
||||
&paddd ($a1,$b1);
|
||||
&pxor ($d1,$a1);
|
||||
&pshufb ($d,$rot16);
|
||||
&pshufb($d1,$rot16);
|
||||
|
||||
&paddd ($c,$d);
|
||||
&paddd ($c1,$d1);
|
||||
&pxor ($b,$c);
|
||||
&pxor ($b1,$c1);
|
||||
&movdqa ($t,$b);
|
||||
&psrld ($b,20);
|
||||
&movdqa($t1,$b1);
|
||||
&pslld ($t,12);
|
||||
&psrld ($b1,20);
|
||||
&por ($b,$t);
|
||||
&pslld ($t1,12);
|
||||
&por ($b1,$t1);
|
||||
|
||||
&paddd ($a,$b);
|
||||
&pxor ($d,$a);
|
||||
&paddd ($a1,$b1);
|
||||
&pxor ($d1,$a1);
|
||||
&pshufb ($d,$rot24);
|
||||
&pshufb($d1,$rot24);
|
||||
|
||||
&paddd ($c,$d);
|
||||
&paddd ($c1,$d1);
|
||||
&pxor ($b,$c);
|
||||
&pxor ($b1,$c1);
|
||||
&movdqa ($t,$b);
|
||||
&psrld ($b,25);
|
||||
&movdqa($t1,$b1);
|
||||
&pslld ($t,7);
|
||||
&psrld ($b1,25);
|
||||
&por ($b,$t);
|
||||
&pslld ($t1,7);
|
||||
&por ($b1,$t1);
|
||||
}
|
||||
|
||||
my $xframe = $win64 ? 0x68 : 8;
|
||||
|
||||
$code.=<<___;
|
||||
.type ChaCha20_128,\@function,5
|
||||
.align 32
|
||||
ChaCha20_128:
|
||||
.cfi_startproc
|
||||
.LChaCha20_128:
|
||||
mov %rsp,%r9 # frame pointer
|
||||
.cfi_def_cfa_register %r9
|
||||
sub \$64+$xframe,%rsp
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps %xmm6,-0x68(%r9)
|
||||
movaps %xmm7,-0x58(%r9)
|
||||
movaps %xmm8,-0x48(%r9)
|
||||
movaps %xmm9,-0x38(%r9)
|
||||
movaps %xmm10,-0x28(%r9)
|
||||
movaps %xmm11,-0x18(%r9)
|
||||
.L128_body:
|
||||
___
|
||||
$code.=<<___;
|
||||
movdqa .Lsigma(%rip),$a
|
||||
movdqu ($key),$b
|
||||
movdqu 16($key),$c
|
||||
movdqu ($counter),$d
|
||||
movdqa .Lone(%rip),$d1
|
||||
movdqa .Lrot16(%rip),$rot16
|
||||
movdqa .Lrot24(%rip),$rot24
|
||||
|
||||
movdqa $a,$a1
|
||||
movdqa $a,0x00(%rsp)
|
||||
movdqa $b,$b1
|
||||
movdqa $b,0x10(%rsp)
|
||||
movdqa $c,$c1
|
||||
movdqa $c,0x20(%rsp)
|
||||
paddd $d,$d1
|
||||
movdqa $d,0x30(%rsp)
|
||||
mov \$10,$counter # reuse $counter
|
||||
jmp .Loop_128
|
||||
|
||||
.align 32
|
||||
.Loop_128:
|
||||
___
|
||||
&SSSE3ROUND_2x();
|
||||
&pshufd ($c,$c,0b01001110);
|
||||
&pshufd ($b,$b,0b00111001);
|
||||
&pshufd ($d,$d,0b10010011);
|
||||
&pshufd ($c1,$c1,0b01001110);
|
||||
&pshufd ($b1,$b1,0b00111001);
|
||||
&pshufd ($d1,$d1,0b10010011);
|
||||
|
||||
&SSSE3ROUND_2x();
|
||||
&pshufd ($c,$c,0b01001110);
|
||||
&pshufd ($b,$b,0b10010011);
|
||||
&pshufd ($d,$d,0b00111001);
|
||||
&pshufd ($c1,$c1,0b01001110);
|
||||
&pshufd ($b1,$b1,0b10010011);
|
||||
&pshufd ($d1,$d1,0b00111001);
|
||||
|
||||
&dec ($counter);
|
||||
&jnz (".Loop_128");
|
||||
|
||||
$code.=<<___;
|
||||
paddd 0x00(%rsp),$a
|
||||
paddd 0x10(%rsp),$b
|
||||
paddd 0x20(%rsp),$c
|
||||
paddd 0x30(%rsp),$d
|
||||
paddd .Lone(%rip),$d1
|
||||
paddd 0x00(%rsp),$a1
|
||||
paddd 0x10(%rsp),$b1
|
||||
paddd 0x20(%rsp),$c1
|
||||
paddd 0x30(%rsp),$d1
|
||||
|
||||
movdqu 0x00($inp),$t
|
||||
movdqu 0x10($inp),$t1
|
||||
pxor $t,$a # xor with input
|
||||
movdqu 0x20($inp),$t
|
||||
pxor $t1,$b
|
||||
movdqu 0x30($inp),$t1
|
||||
pxor $t,$c
|
||||
movdqu 0x40($inp),$t
|
||||
pxor $t1,$d
|
||||
movdqu 0x50($inp),$t1
|
||||
pxor $t,$a1
|
||||
movdqu 0x60($inp),$t
|
||||
pxor $t1,$b1
|
||||
movdqu 0x70($inp),$t1
|
||||
pxor $t,$c1
|
||||
pxor $t1,$d1
|
||||
|
||||
movdqu $a,0x00($out) # write output
|
||||
movdqu $b,0x10($out)
|
||||
movdqu $c,0x20($out)
|
||||
movdqu $d,0x30($out)
|
||||
movdqu $a1,0x40($out)
|
||||
movdqu $b1,0x50($out)
|
||||
movdqu $c1,0x60($out)
|
||||
movdqu $d1,0x70($out)
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps -0x68(%r9),%xmm6
|
||||
movaps -0x58(%r9),%xmm7
|
||||
movaps -0x48(%r9),%xmm8
|
||||
movaps -0x38(%r9),%xmm9
|
||||
movaps -0x28(%r9),%xmm10
|
||||
movaps -0x18(%r9),%xmm11
|
||||
___
|
||||
$code.=<<___;
|
||||
lea (%r9),%rsp
|
||||
.cfi_def_cfa_register %rsp
|
||||
.L128_epilogue:
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size ChaCha20_128,.-ChaCha20_128
|
||||
___
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# SSSE3 code path that handles longer messages.
|
||||
{
|
||||
@@ -3674,9 +3840,9 @@ se_handler:
|
||||
ret
|
||||
.size se_handler,.-se_handler
|
||||
|
||||
.type ssse3_handler,\@abi-omnipotent
|
||||
.type simd_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ssse3_handler:
|
||||
simd_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
@@ -3702,57 +3868,20 @@ ssse3_handler:
|
||||
mov 192($context),%rax # pull context->R9
|
||||
|
||||
mov 4(%r11),%r10d # HandlerData[1]
|
||||
mov 8(%r11),%ecx # HandlerData[2]
|
||||
lea (%rsi,%r10),%r10 # epilogue label
|
||||
cmp %r10,%rbx # context->Rip>=epilogue label
|
||||
jae .Lcommon_seh_tail
|
||||
|
||||
lea -0x28(%rax),%rsi
|
||||
neg %rcx
|
||||
lea -8(%rax,%rcx),%rsi
|
||||
lea 512($context),%rdi # &context.Xmm6
|
||||
mov \$4,%ecx
|
||||
neg %ecx
|
||||
shr \$3,%ecx
|
||||
.long 0xa548f3fc # cld; rep movsq
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ssse3_handler,.-ssse3_handler
|
||||
|
||||
.type full_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
full_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
push %rbp
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
pushfq
|
||||
sub \$64,%rsp
|
||||
|
||||
mov 120($context),%rax # pull context->Rax
|
||||
mov 248($context),%rbx # pull context->Rip
|
||||
|
||||
mov 8($disp),%rsi # disp->ImageBase
|
||||
mov 56($disp),%r11 # disp->HandlerData
|
||||
|
||||
mov 0(%r11),%r10d # HandlerData[0]
|
||||
lea (%rsi,%r10),%r10 # prologue label
|
||||
cmp %r10,%rbx # context->Rip<prologue label
|
||||
jb .Lcommon_seh_tail
|
||||
|
||||
mov 192($context),%rax # pull context->R9
|
||||
|
||||
mov 4(%r11),%r10d # HandlerData[1]
|
||||
lea (%rsi,%r10),%r10 # epilogue label
|
||||
cmp %r10,%rbx # context->Rip>=epilogue label
|
||||
jae .Lcommon_seh_tail
|
||||
|
||||
lea -0xa8(%rax),%rsi
|
||||
lea 512($context),%rdi # &context.Xmm6
|
||||
mov \$20,%ecx
|
||||
.long 0xa548f3fc # cld; rep movsq
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size full_handler,.-full_handler
|
||||
.size simd_handler,.-simd_handler
|
||||
|
||||
.section .pdata
|
||||
.align 4
|
||||
@@ -3764,6 +3893,10 @@ full_handler:
|
||||
.rva .LSEH_end_ChaCha20_ssse3
|
||||
.rva .LSEH_info_ChaCha20_ssse3
|
||||
|
||||
.rva .LSEH_begin_ChaCha20_128
|
||||
.rva .LSEH_end_ChaCha20_128
|
||||
.rva .LSEH_info_ChaCha20_128
|
||||
|
||||
.rva .LSEH_begin_ChaCha20_4x
|
||||
.rva .LSEH_end_ChaCha20_4x
|
||||
.rva .LSEH_info_ChaCha20_4x
|
||||
@@ -3804,46 +3937,60 @@ $code.=<<___;
|
||||
|
||||
.LSEH_info_ChaCha20_ssse3:
|
||||
.byte 9,0,0,0
|
||||
.rva ssse3_handler
|
||||
.rva simd_handler
|
||||
.rva .Lssse3_body,.Lssse3_epilogue
|
||||
.long 0x20,0
|
||||
|
||||
.LSEH_info_ChaCha20_128:
|
||||
.byte 9,0,0,0
|
||||
.rva simd_handler
|
||||
.rva .L128_body,.L128_epilogue
|
||||
.long 0x60,0
|
||||
|
||||
.LSEH_info_ChaCha20_4x:
|
||||
.byte 9,0,0,0
|
||||
.rva full_handler
|
||||
.rva simd_handler
|
||||
.rva .L4x_body,.L4x_epilogue
|
||||
.long 0xa0,0
|
||||
___
|
||||
$code.=<<___ if ($avx);
|
||||
.LSEH_info_ChaCha20_4xop:
|
||||
.byte 9,0,0,0
|
||||
.rva full_handler
|
||||
.rva simd_handler
|
||||
.rva .L4xop_body,.L4xop_epilogue # HandlerData[]
|
||||
.long 0xa0,0
|
||||
___
|
||||
$code.=<<___ if ($avx>1);
|
||||
.LSEH_info_ChaCha20_8x:
|
||||
.byte 9,0,0,0
|
||||
.rva full_handler
|
||||
.rva simd_handler
|
||||
.rva .L8x_body,.L8x_epilogue # HandlerData[]
|
||||
.long 0xa0,0
|
||||
___
|
||||
$code.=<<___ if ($avx>2);
|
||||
.LSEH_info_ChaCha20_avx512:
|
||||
.byte 9,0,0,0
|
||||
.rva ssse3_handler
|
||||
.rva simd_handler
|
||||
.rva .Lavx512_body,.Lavx512_epilogue # HandlerData[]
|
||||
.long 0x20,0
|
||||
|
||||
.LSEH_info_ChaCha20_avx512vl:
|
||||
.byte 9,0,0,0
|
||||
.rva ssse3_handler
|
||||
.rva simd_handler
|
||||
.rva .Lavx512vl_body,.Lavx512vl_epilogue # HandlerData[]
|
||||
.long 0x20,0
|
||||
|
||||
.LSEH_info_ChaCha20_16x:
|
||||
.byte 9,0,0,0
|
||||
.rva full_handler
|
||||
.rva simd_handler
|
||||
.rva .L16x_body,.L16x_epilogue # HandlerData[]
|
||||
.long 0xa0,0
|
||||
|
||||
.LSEH_info_ChaCha20_8xvl:
|
||||
.byte 9,0,0,0
|
||||
.rva full_handler
|
||||
.rva simd_handler
|
||||
.rva .L8xvl_body,.L8xvl_epilogue # HandlerData[]
|
||||
.long 0xa0,0
|
||||
___
|
||||
}
|
||||
|
||||
|
||||
@@ -292,10 +292,13 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
for (*result = 0; conf->meth->is_number(conf, *str);) {
|
||||
*result = (*result) * 10 + conf->meth->to_int(conf, *str);
|
||||
str++;
|
||||
}
|
||||
if (conf == NULL)
|
||||
*result = strtol(str, &str, 10);
|
||||
else
|
||||
for (*result = 0; conf->meth->is_number(conf, *str);) {
|
||||
*result = (*result) * 10 + conf->meth->to_int(conf, *str);
|
||||
str++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
+24
-22
@@ -389,30 +389,32 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Handle the common cases where the scalar is secret, enforcing a constant
|
||||
* time scalar multiplication algorithm.
|
||||
*/
|
||||
if ((scalar != NULL) && (num == 0)) {
|
||||
if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GeneratorPoint: this
|
||||
* codepath is reached most prominently by (ephemeral) key generation
|
||||
* of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH
|
||||
* keygen/first half), where the scalar is always secret. This is why
|
||||
* we ignore if BN_FLG_CONSTTIME is actually set and we always call the
|
||||
* constant time version.
|
||||
* Handle the common cases where the scalar is secret, enforcing a constant
|
||||
* time scalar multiplication algorithm.
|
||||
*/
|
||||
return ec_mul_consttime(group, r, scalar, NULL, ctx);
|
||||
}
|
||||
if ((scalar == NULL) && (num == 1)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GenericPoint: this codepath
|
||||
* is reached most prominently by the second half of ECDH, where the
|
||||
* secret scalar is multiplied by the peer's public point. To protect
|
||||
* the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and
|
||||
* we always call the constant time version.
|
||||
*/
|
||||
return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
|
||||
if ((scalar != NULL) && (num == 0)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GeneratorPoint: this
|
||||
* codepath is reached most prominently by (ephemeral) key generation
|
||||
* of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH
|
||||
* keygen/first half), where the scalar is always secret. This is why
|
||||
* we ignore if BN_FLG_CONSTTIME is actually set and we always call the
|
||||
* constant time version.
|
||||
*/
|
||||
return ec_mul_consttime(group, r, scalar, NULL, ctx);
|
||||
}
|
||||
if ((scalar == NULL) && (num == 1)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GenericPoint: this codepath
|
||||
* is reached most prominently by the second half of ECDH, where the
|
||||
* secret scalar is multiplied by the peer's public point. To protect
|
||||
* the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and
|
||||
* we always call the constant time version.
|
||||
*/
|
||||
return ec_mul_consttime(group, r, scalars[0], points[0], ctx);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
|
||||
@@ -150,6 +150,7 @@ typedef struct {
|
||||
EVP_CHACHA_KEY key;
|
||||
unsigned int nonce[12/4];
|
||||
unsigned char tag[POLY1305_BLOCK_SIZE];
|
||||
unsigned char tls_aad[POLY1305_BLOCK_SIZE];
|
||||
struct { uint64_t aad, text; } len;
|
||||
int aad, mac_inited, tag_len, nonce_len;
|
||||
size_t tls_payload_length;
|
||||
@@ -179,7 +180,8 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
|
||||
|
||||
/* pad on the left */
|
||||
if (actx->nonce_len <= CHACHA_CTR_SIZE)
|
||||
memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len);
|
||||
memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv,
|
||||
actx->nonce_len);
|
||||
|
||||
chacha_init_key(ctx, inkey, temp, enc);
|
||||
|
||||
@@ -193,23 +195,158 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 };
|
||||
|
||||
static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
size_t i, tail, tohash_len, plen = actx->tls_payload_length;
|
||||
unsigned char *buf, *tohash, *ctr, storage[2 * CHACHA_BLK_SIZE + 32];
|
||||
|
||||
if (len != plen + POLY1305_BLOCK_SIZE)
|
||||
return -1;
|
||||
|
||||
buf = storage + ((0 - (size_t)storage) & 15); /* align */
|
||||
ctr = buf + CHACHA_BLK_SIZE;
|
||||
tohash = buf + CHACHA_BLK_SIZE - POLY1305_BLOCK_SIZE;
|
||||
|
||||
if (plen <= CHACHA_BLK_SIZE) {
|
||||
actx->key.counter[0] = 0;
|
||||
ChaCha20_ctr32(buf, zero, 2 * CHACHA_BLK_SIZE, actx->key.key.d,
|
||||
actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||
actx->key.partial_len = 0;
|
||||
memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE);
|
||||
tohash_len = POLY1305_BLOCK_SIZE;
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->len.text = plen;
|
||||
|
||||
if (ctx->encrypt) {
|
||||
for (i = 0; i < plen; i++) {
|
||||
out[i] = ctr[i] ^= in[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < plen; i++) {
|
||||
unsigned char c = in[i];
|
||||
out[i] = ctr[i] ^ c;
|
||||
ctr[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
in += i;
|
||||
out += i;
|
||||
|
||||
tail = (0 - i) & (POLY1305_BLOCK_SIZE - 1);
|
||||
memset(ctr + i, 0, tail);
|
||||
ctr += i + tail;
|
||||
tohash_len += i + tail;
|
||||
} else {
|
||||
actx->key.counter[0] = 0;
|
||||
ChaCha20_ctr32(buf, zero, CHACHA_BLK_SIZE, actx->key.key.d,
|
||||
actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), buf);
|
||||
actx->key.counter[0] = 1;
|
||||
actx->key.partial_len = 0;
|
||||
Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad, POLY1305_BLOCK_SIZE);
|
||||
tohash = ctr;
|
||||
tohash_len = 0;
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->len.text = plen;
|
||||
|
||||
if (ctx->encrypt) {
|
||||
ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter);
|
||||
Poly1305_Update(POLY1305_ctx(actx), out, plen);
|
||||
} else {
|
||||
Poly1305_Update(POLY1305_ctx(actx), in, plen);
|
||||
ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter);
|
||||
}
|
||||
|
||||
in += plen;
|
||||
out += plen;
|
||||
tail = (0 - plen) & (POLY1305_BLOCK_SIZE - 1);
|
||||
Poly1305_Update(POLY1305_ctx(actx), zero, tail);
|
||||
}
|
||||
|
||||
{
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = { 1 };
|
||||
|
||||
if (is_endian.little) {
|
||||
memcpy(ctr, (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
|
||||
} else {
|
||||
ctr[0] = (unsigned char)(actx->len.aad);
|
||||
ctr[1] = (unsigned char)(actx->len.aad>>8);
|
||||
ctr[2] = (unsigned char)(actx->len.aad>>16);
|
||||
ctr[3] = (unsigned char)(actx->len.aad>>24);
|
||||
ctr[4] = (unsigned char)(actx->len.aad>>32);
|
||||
ctr[5] = (unsigned char)(actx->len.aad>>40);
|
||||
ctr[6] = (unsigned char)(actx->len.aad>>48);
|
||||
ctr[7] = (unsigned char)(actx->len.aad>>56);
|
||||
|
||||
ctr[8] = (unsigned char)(actx->len.text);
|
||||
ctr[9] = (unsigned char)(actx->len.text>>8);
|
||||
ctr[10] = (unsigned char)(actx->len.text>>16);
|
||||
ctr[11] = (unsigned char)(actx->len.text>>24);
|
||||
ctr[12] = (unsigned char)(actx->len.text>>32);
|
||||
ctr[13] = (unsigned char)(actx->len.text>>40);
|
||||
ctr[14] = (unsigned char)(actx->len.text>>48);
|
||||
ctr[15] = (unsigned char)(actx->len.text>>56);
|
||||
}
|
||||
tohash_len += POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
Poly1305_Update(POLY1305_ctx(actx), tohash, tohash_len);
|
||||
OPENSSL_cleanse(buf, 2 * CHACHA_BLK_SIZE);
|
||||
Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
|
||||
: tohash);
|
||||
|
||||
actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
|
||||
|
||||
if (ctx->encrypt) {
|
||||
memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
|
||||
} else {
|
||||
if (CRYPTO_memcmp(tohash, in, POLY1305_BLOCK_SIZE)) {
|
||||
memset(out - (len - POLY1305_BLOCK_SIZE), 0,
|
||||
len - POLY1305_BLOCK_SIZE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
# else
|
||||
static const unsigned char zero[CHACHA_BLK_SIZE] = { 0 };
|
||||
# endif
|
||||
|
||||
static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
|
||||
size_t rem, plen = actx->tls_payload_length;
|
||||
static const unsigned char zero[POLY1305_BLOCK_SIZE] = { 0 };
|
||||
|
||||
if (!actx->mac_inited) {
|
||||
# if !defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL)
|
||||
return chacha20_poly1305_tls_cipher(ctx, out, in, len);
|
||||
# endif
|
||||
actx->key.counter[0] = 0;
|
||||
memset(actx->key.buf, 0, sizeof(actx->key.buf));
|
||||
ChaCha20_ctr32(actx->key.buf, actx->key.buf, CHACHA_BLK_SIZE,
|
||||
ChaCha20_ctr32(actx->key.buf, zero, CHACHA_BLK_SIZE,
|
||||
actx->key.key.d, actx->key.counter);
|
||||
Poly1305_Init(POLY1305_ctx(actx), actx->key.buf);
|
||||
actx->key.counter[0] = 1;
|
||||
actx->key.partial_len = 0;
|
||||
actx->len.aad = actx->len.text = 0;
|
||||
actx->mac_inited = 1;
|
||||
if (plen != NO_TLS_PAYLOAD_LENGTH) {
|
||||
Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad,
|
||||
EVP_AEAD_TLS1_AAD_LEN);
|
||||
actx->len.aad = EVP_AEAD_TLS1_AAD_LEN;
|
||||
actx->aad = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (in) { /* aad or text */
|
||||
@@ -341,6 +478,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||
actx->tag_len = 0;
|
||||
actx->nonce_len = 12;
|
||||
actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
|
||||
memset(actx->tls_aad, 0, POLY1305_BLOCK_SIZE);
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_COPY:
|
||||
@@ -393,18 +531,18 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||
return 0;
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned char *aad = ptr, temp[POLY1305_BLOCK_SIZE];
|
||||
unsigned char *aad = ptr;
|
||||
|
||||
memcpy(actx->tls_aad, ptr, EVP_AEAD_TLS1_AAD_LEN);
|
||||
len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 |
|
||||
aad[EVP_AEAD_TLS1_AAD_LEN - 1];
|
||||
aad = actx->tls_aad;
|
||||
if (!ctx->encrypt) {
|
||||
if (len < POLY1305_BLOCK_SIZE)
|
||||
return 0;
|
||||
len -= POLY1305_BLOCK_SIZE; /* discount attached tag */
|
||||
memcpy(temp, aad, EVP_AEAD_TLS1_AAD_LEN - 2);
|
||||
aad = temp;
|
||||
temp[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8);
|
||||
temp[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len;
|
||||
aad[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8);
|
||||
aad[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len;
|
||||
}
|
||||
actx->tls_payload_length = len;
|
||||
|
||||
@@ -415,7 +553,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||
actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad);
|
||||
actx->key.counter[3] = actx->nonce[2] ^ CHACHA_U8TOU32(aad+4);
|
||||
actx->mac_inited = 0;
|
||||
chacha20_poly1305_cipher(ctx, NULL, aad, EVP_AEAD_TLS1_AAD_LEN);
|
||||
|
||||
return POLY1305_BLOCK_SIZE; /* tag length */
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,8 @@ $code=<<___;
|
||||
.text
|
||||
#if defined(__thumb2__) || defined(__clang__)
|
||||
.syntax unified
|
||||
#define ldrplb ldrbpl
|
||||
#define ldrneb ldrbne
|
||||
#endif
|
||||
#if defined(__thumb2__)
|
||||
.thumb
|
||||
@@ -152,11 +154,6 @@ $code=<<___;
|
||||
.code 32
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#define ldrplb ldrbpl
|
||||
#define ldrneb ldrbne
|
||||
#endif
|
||||
|
||||
.type rem_4bit,%object
|
||||
.align 5
|
||||
rem_4bit:
|
||||
|
||||
@@ -488,6 +488,7 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
|
||||
char *dekinfostart, c;
|
||||
|
||||
cipher->cipher = NULL;
|
||||
memset(cipher->iv, 0, sizeof(cipher->iv));
|
||||
if ((header == NULL) || (*header == '\0') || (*header == '\n'))
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -877,7 +877,7 @@ my %globals;
|
||||
$var=~s/^(0b[0-1]+)/oct($1)/eig;
|
||||
$var=~s/^0x([0-9a-f]+)/0$1h/ig if ($masm);
|
||||
if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva"))
|
||||
{ $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
|
||||
{ $var=~s/^([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; }
|
||||
$var;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
#include "e_os.h"
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
@@ -335,7 +335,6 @@ ___
|
||||
}
|
||||
{
|
||||
$code.=<<___;
|
||||
.globl KeccakF1600
|
||||
.type KeccakF1600,\@function
|
||||
.align 32
|
||||
KeccakF1600:
|
||||
|
||||
@@ -344,7 +344,6 @@ $code.=<<___;
|
||||
ret
|
||||
.size __KeccakF1600,.-__KeccakF1600
|
||||
|
||||
.globl KeccakF1600
|
||||
.type KeccakF1600,\@abi-omnipotent
|
||||
.align 32
|
||||
KeccakF1600:
|
||||
|
||||
Reference in New Issue
Block a user