external/boringssl: Sync to ba8f1864c15ec938ce0851f416663511c89f454a.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/b1cbe1979008debd0541621584b00e010d9935dd..ba8f1864c15ec938ce0851f416663511c89f454a
Test: BoringSSL CTS Presubmits
Change-Id: I58da2508fd608988d3d14d7219a104da7ed0f4b7
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 7a87d55..a126718 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-b1cbe1979008debd0541621584b00e010d9935dd
+ba8f1864c15ec938ce0851f416663511c89f454a
diff --git a/ios-arm/crypto/fipsmodule/aes-armv4.S b/ios-arm/crypto/fipsmodule/aes-armv4.S
index 2e6c7ef..516c89b 100644
--- a/ios-arm/crypto/fipsmodule/aes-armv4.S
+++ b/ios-arm/crypto/fipsmodule/aes-armv4.S
@@ -171,7 +171,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ _asm_AES_encrypt
#else
- adr r3,_asm_AES_encrypt
+ adr r3,.
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
@@ -426,7 +426,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ _asm_AES_set_encrypt_key
#else
- adr r3,_asm_AES_set_encrypt_key
+ adr r3,.
#endif
teq r0,#0
#ifdef __thumb2__
@@ -956,7 +956,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ _asm_AES_decrypt
#else
- adr r3,_asm_AES_decrypt
+ adr r3,.
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
diff --git a/ios-arm/crypto/fipsmodule/bsaes-armv7.S b/ios-arm/crypto/fipsmodule/bsaes-armv7.S
index 1cf914c..5e2ebf0 100644
--- a/ios-arm/crypto/fipsmodule/bsaes-armv7.S
+++ b/ios-arm/crypto/fipsmodule/bsaes-armv7.S
@@ -91,7 +91,7 @@
#endif
.align 4
_bsaes_decrypt8:
- adr r6,_bsaes_decrypt8
+ adr r6,.
vldmia r4!, {q9} @ round 0 key
#ifdef __APPLE__
adr r6,LM0ISR
@@ -584,7 +584,7 @@
#endif
.align 4
_bsaes_encrypt8:
- adr r6,_bsaes_encrypt8
+ adr r6,.
vldmia r4!, {q9} @ round 0 key
#ifdef __APPLE__
adr r6,LM0SR
@@ -1021,7 +1021,7 @@
#endif
.align 4
_bsaes_key_convert:
- adr r6,_bsaes_key_convert
+ adr r6,.
vld1.8 {q7}, [r4]! @ load round 0 key
#ifdef __APPLE__
adr r6,LM0
diff --git a/linux-arm/crypto/fipsmodule/aes-armv4.S b/linux-arm/crypto/fipsmodule/aes-armv4.S
index f11bc7e..d401fc7 100644
--- a/linux-arm/crypto/fipsmodule/aes-armv4.S
+++ b/linux-arm/crypto/fipsmodule/aes-armv4.S
@@ -170,7 +170,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ asm_AES_encrypt
#else
- adr r3,asm_AES_encrypt
+ adr r3,.
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
@@ -421,7 +421,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ asm_AES_set_encrypt_key
#else
- adr r3,asm_AES_set_encrypt_key
+ adr r3,.
#endif
teq r0,#0
#ifdef __thumb2__
@@ -945,7 +945,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ asm_AES_decrypt
#else
- adr r3,asm_AES_decrypt
+ adr r3,.
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
diff --git a/linux-arm/crypto/fipsmodule/bsaes-armv7.S b/linux-arm/crypto/fipsmodule/bsaes-armv7.S
index 0b1a9f7..f9c6de7 100644
--- a/linux-arm/crypto/fipsmodule/bsaes-armv7.S
+++ b/linux-arm/crypto/fipsmodule/bsaes-armv7.S
@@ -90,7 +90,7 @@
.type _bsaes_decrypt8,%function
.align 4
_bsaes_decrypt8:
- adr r6,_bsaes_decrypt8
+ adr r6,.
vldmia r4!, {q9} @ round 0 key
#ifdef __APPLE__
adr r6,.LM0ISR
@@ -581,7 +581,7 @@
.type _bsaes_encrypt8,%function
.align 4
_bsaes_encrypt8:
- adr r6,_bsaes_encrypt8
+ adr r6,.
vldmia r4!, {q9} @ round 0 key
#ifdef __APPLE__
adr r6,.LM0SR
@@ -1016,7 +1016,7 @@
.type _bsaes_key_convert,%function
.align 4
_bsaes_key_convert:
- adr r6,_bsaes_key_convert
+ adr r6,.
vld1.8 {q7}, [r4]! @ load round 0 key
#ifdef __APPLE__
adr r6,.LM0
diff --git a/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S b/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
index 62c6cd6..e7b4c48 100644
--- a/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
+++ b/linux-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
@@ -4,6 +4,7 @@
.type _aesni_ctr32_ghash_6x,@function
.align 32
_aesni_ctr32_ghash_6x:
+.cfi_startproc
vmovdqu 32(%r11),%xmm2
subq $6,%rdx
vpxor %xmm4,%xmm4,%xmm4
@@ -328,12 +329,14 @@
vpxor %xmm4,%xmm8,%xmm8
.byte 0xf3,0xc3
+.cfi_endproc
.size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x
.globl aesni_gcm_decrypt
.hidden aesni_gcm_decrypt
.type aesni_gcm_decrypt,@function
.align 32
aesni_gcm_decrypt:
+.cfi_startproc
xorq %r10,%r10
@@ -342,12 +345,19 @@
jb .Lgcm_dec_abort
leaq (%rsp),%rax
+.cfi_def_cfa_register %rax
pushq %rbx
+.cfi_offset %rbx,-16
pushq %rbp
+.cfi_offset %rbp,-24
pushq %r12
+.cfi_offset %r12,-32
pushq %r13
+.cfi_offset %r13,-40
pushq %r14
+.cfi_offset %r14,-48
pushq %r15
+.cfi_offset %r15,-56
vzeroupper
vmovdqu (%r8),%xmm1
@@ -417,19 +427,28 @@
vzeroupper
movq -48(%rax),%r15
+.cfi_restore %r15
movq -40(%rax),%r14
+.cfi_restore %r14
movq -32(%rax),%r13
+.cfi_restore %r13
movq -24(%rax),%r12
+.cfi_restore %r12
movq -16(%rax),%rbp
+.cfi_restore %rbp
movq -8(%rax),%rbx
+.cfi_restore %rbx
leaq (%rax),%rsp
+.cfi_def_cfa_register %rsp
.Lgcm_dec_abort:
movq %r10,%rax
.byte 0xf3,0xc3
+.cfi_endproc
.size aesni_gcm_decrypt,.-aesni_gcm_decrypt
.type _aesni_ctr32_6x,@function
.align 32
_aesni_ctr32_6x:
+.cfi_startproc
vmovdqu 0-128(%rcx),%xmm4
vmovdqu 32(%r11),%xmm2
leaq -1(%rbp),%r13
@@ -516,6 +535,7 @@
vpshufb %xmm0,%xmm1,%xmm1
vpxor %xmm4,%xmm14,%xmm14
jmp .Loop_ctr32
+.cfi_endproc
.size _aesni_ctr32_6x,.-_aesni_ctr32_6x
.globl aesni_gcm_encrypt
@@ -523,6 +543,7 @@
.type aesni_gcm_encrypt,@function
.align 32
aesni_gcm_encrypt:
+.cfi_startproc
xorq %r10,%r10
@@ -532,12 +553,19 @@
jb .Lgcm_enc_abort
leaq (%rsp),%rax
+.cfi_def_cfa_register %rax
pushq %rbx
+.cfi_offset %rbx,-16
pushq %rbp
+.cfi_offset %rbp,-24
pushq %r12
+.cfi_offset %r12,-32
pushq %r13
+.cfi_offset %r13,-40
pushq %r14
+.cfi_offset %r14,-48
pushq %r15
+.cfi_offset %r15,-56
vzeroupper
vmovdqu (%r8),%xmm1
@@ -772,15 +800,23 @@
vzeroupper
movq -48(%rax),%r15
+.cfi_restore %r15
movq -40(%rax),%r14
+.cfi_restore %r14
movq -32(%rax),%r13
+.cfi_restore %r13
movq -24(%rax),%r12
+.cfi_restore %r12
movq -16(%rax),%rbp
+.cfi_restore %rbp
movq -8(%rax),%rbx
+.cfi_restore %rbx
leaq (%rax),%rsp
+.cfi_def_cfa_register %rsp
.Lgcm_enc_abort:
movq %r10,%rax
.byte 0xf3,0xc3
+.cfi_endproc
.size aesni_gcm_encrypt,.-aesni_gcm_encrypt
.align 64
.Lbswap_mask:
diff --git a/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S b/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
index f185d0c..2513904 100644
--- a/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
+++ b/mac-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.S
@@ -4,6 +4,7 @@
.p2align 5
_aesni_ctr32_ghash_6x:
+
vmovdqu 32(%r11),%xmm2
subq $6,%rdx
vpxor %xmm4,%xmm4,%xmm4
@@ -329,11 +330,13 @@
.byte 0xf3,0xc3
+
.globl _aesni_gcm_decrypt
.private_extern _aesni_gcm_decrypt
.p2align 5
_aesni_gcm_decrypt:
+
xorq %r10,%r10
@@ -342,12 +345,19 @@
jb L$gcm_dec_abort
leaq (%rsp),%rax
+
pushq %rbx
+
pushq %rbp
+
pushq %r12
+
pushq %r13
+
pushq %r14
+
pushq %r15
+
vzeroupper
vmovdqu (%r8),%xmm1
@@ -417,19 +427,28 @@
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
+
L$gcm_dec_abort:
movq %r10,%rax
.byte 0xf3,0xc3
+
.p2align 5
_aesni_ctr32_6x:
+
vmovdqu 0-128(%rcx),%xmm4
vmovdqu 32(%r11),%xmm2
leaq -1(%rbp),%r13
@@ -518,11 +537,13 @@
jmp L$oop_ctr32
+
.globl _aesni_gcm_encrypt
.private_extern _aesni_gcm_encrypt
.p2align 5
_aesni_gcm_encrypt:
+
xorq %r10,%r10
@@ -532,12 +553,19 @@
jb L$gcm_enc_abort
leaq (%rsp),%rax
+
pushq %rbx
+
pushq %rbp
+
pushq %r12
+
pushq %r13
+
pushq %r14
+
pushq %r15
+
vzeroupper
vmovdqu (%r8),%xmm1
@@ -772,16 +800,24 @@
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
+
L$gcm_enc_abort:
movq %r10,%rax
.byte 0xf3,0xc3
+
.p2align 6
L$bswap_mask:
.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
diff --git a/src/crypto/asn1/a_i2d_fp.c b/src/crypto/asn1/a_i2d_fp.c
index 486207e..7b76d0c 100644
--- a/src/crypto/asn1/a_i2d_fp.c
+++ b/src/crypto/asn1/a_i2d_fp.c
@@ -81,6 +81,9 @@
int i, j = 0, n, ret = 1;
n = i2d(x, NULL);
+ if (n <= 0)
+ return 0;
+
b = (char *)OPENSSL_malloc(n);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
diff --git a/src/crypto/fipsmodule/aes/asm/aes-armv4.pl b/src/crypto/fipsmodule/aes/asm/aes-armv4.pl
index 06f009c..c34d3dc 100644
--- a/src/crypto/fipsmodule/aes/asm/aes-armv4.pl
+++ b/src/crypto/fipsmodule/aes/asm/aes-armv4.pl
@@ -200,7 +200,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ asm_AES_encrypt
#else
- adr r3,asm_AES_encrypt
+ adr r3,.
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
@@ -450,7 +450,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ asm_AES_set_encrypt_key
#else
- adr r3,asm_AES_set_encrypt_key
+ adr r3,.
#endif
teq r0,#0
#ifdef __thumb2__
@@ -976,7 +976,7 @@
#ifndef __thumb2__
sub r3,pc,#8 @ asm_AES_decrypt
#else
- adr r3,asm_AES_decrypt
+ adr r3,.
#endif
stmdb sp!,{r1,r4-r12,lr}
#ifdef __APPLE__
diff --git a/src/crypto/fipsmodule/aes/asm/bsaes-armv7.pl b/src/crypto/fipsmodule/aes/asm/bsaes-armv7.pl
index 895a269..1ff890a 100644
--- a/src/crypto/fipsmodule/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/fipsmodule/aes/asm/bsaes-armv7.pl
@@ -744,7 +744,7 @@
.type _bsaes_decrypt8,%function
.align 4
_bsaes_decrypt8:
- adr $const,_bsaes_decrypt8
+ adr $const,.
vldmia $key!, {@XMM[9]} @ round 0 key
#ifdef __APPLE__
adr $const,.LM0ISR
@@ -843,7 +843,7 @@
.type _bsaes_encrypt8,%function
.align 4
_bsaes_encrypt8:
- adr $const,_bsaes_encrypt8
+ adr $const,.
vldmia $key!, {@XMM[9]} @ round 0 key
#ifdef __APPLE__
adr $const,.LM0SR
@@ -951,7 +951,7 @@
.type _bsaes_key_convert,%function
.align 4
_bsaes_key_convert:
- adr $const,_bsaes_key_convert
+ adr $const,.
vld1.8 {@XMM[7]}, [$inp]! @ load round 0 key
#ifdef __APPLE__
adr $const,.LM0
diff --git a/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c b/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c
index bfd770f..bcf12eb 100644
--- a/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c
+++ b/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c
@@ -280,7 +280,7 @@
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
-void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
+void bn_mul_comba8(BN_ULONG r[16], BN_ULONG a[8], BN_ULONG b[8]) {
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -382,7 +382,7 @@
r[15] = c1;
}
-void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
+void bn_mul_comba4(BN_ULONG r[8], BN_ULONG a[4], BN_ULONG b[4]) {
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -420,7 +420,7 @@
r[7] = c2;
}
-void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
+void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) {
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -494,7 +494,7 @@
r[15] = c1;
}
-void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
+void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) {
BN_ULONG c1, c2, c3;
c1 = 0;
diff --git a/src/crypto/fipsmodule/bn/div.c b/src/crypto/fipsmodule/bn/div.c
index 0b8b9b9..c92eab3 100644
--- a/src/crypto/fipsmodule/bn/div.c
+++ b/src/crypto/fipsmodule/bn/div.c
@@ -178,28 +178,33 @@
#endif
}
-// BN_div computes dv := num / divisor, rounding towards
-// zero, and sets up rm such that dv*divisor + rm = num holds.
+// BN_div computes "quotient := numerator / divisor", rounding towards zero,
+// and sets up |rem| such that "quotient * divisor + rem = numerator" holds.
+//
// Thus:
-// dv->neg == num->neg ^ divisor->neg (unless the result is zero)
-// rm->neg == num->neg (unless the remainder is zero)
-// If 'dv' or 'rm' is NULL, the respective value is not returned.
+//
+// quotient->neg == numerator->neg ^ divisor->neg
+// (unless the result is zero)
+// rem->neg == numerator->neg
+// (unless the remainder is zero)
+//
+// If |quotient| or |rem| is NULL, the respective value is not returned.
//
// This was specifically designed to contain fewer branches that may leak
// sensitive information; see "New Branch Prediction Vulnerabilities in OpenSSL
// and Necessary Software Countermeasures" by Onur Acıçmez, Shay Gueron, and
// Jean-Pierre Seifert.
-int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
- BN_CTX *ctx) {
- int norm_shift, i, loop;
- BIGNUM *tmp, wnum, *snum, *sdiv, *res;
+int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
+ const BIGNUM *divisor, BN_CTX *ctx) {
+ int norm_shift, loop;
+ BIGNUM wnum;
BN_ULONG *resp, *wnump;
BN_ULONG d0, d1;
int num_n, div_n;
// Invalid zero-padding would have particularly bad consequences
// so don't just rely on bn_check_top() here
- if ((num->top > 0 && num->d[num->top - 1] == 0) ||
+ if ((numerator->top > 0 && numerator->d[numerator->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
return 0;
@@ -211,26 +216,27 @@
}
BN_CTX_start(ctx);
- tmp = BN_CTX_get(ctx);
- snum = BN_CTX_get(ctx);
- sdiv = BN_CTX_get(ctx);
- if (dv == NULL) {
+ BIGNUM *tmp = BN_CTX_get(ctx);
+ BIGNUM *snum = BN_CTX_get(ctx);
+ BIGNUM *sdiv = BN_CTX_get(ctx);
+ BIGNUM *res = NULL;
+ if (quotient == NULL) {
res = BN_CTX_get(ctx);
} else {
- res = dv;
+ res = quotient;
}
- if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL) {
+ if (sdiv == NULL || res == NULL) {
goto err;
}
// First we normalise the numbers
- norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
- if (!(BN_lshift(sdiv, divisor, norm_shift))) {
+ norm_shift = BN_BITS2 - (BN_num_bits(divisor) % BN_BITS2);
+ if (!BN_lshift(sdiv, divisor, norm_shift)) {
goto err;
}
sdiv->neg = 0;
norm_shift += BN_BITS2;
- if (!(BN_lshift(snum, num, norm_shift))) {
+ if (!BN_lshift(snum, numerator, norm_shift)) {
goto err;
}
snum->neg = 0;
@@ -242,7 +248,7 @@
if (!bn_wexpand(snum, sdiv->top + 2)) {
goto err;
}
- for (i = snum->top; i < sdiv->top + 2; i++) {
+ for (int i = snum->top; i < sdiv->top + 2; i++) {
snum->d[i] = 0;
}
snum->top = sdiv->top + 2;
@@ -275,15 +281,15 @@
wnump = &(snum->d[num_n - 1]);
// Setup to 'res'
- res->neg = (num->neg ^ divisor->neg);
- if (!bn_wexpand(res, (loop + 1))) {
+ res->neg = (numerator->neg ^ divisor->neg);
+ if (!bn_wexpand(res, loop + 1)) {
goto err;
}
res->top = loop - 1;
resp = &(res->d[loop - 1]);
// space for temp
- if (!bn_wexpand(tmp, (div_n + 1))) {
+ if (!bn_wexpand(tmp, div_n + 1)) {
goto err;
}
@@ -295,11 +301,11 @@
resp--;
}
- for (i = 0; i < loop - 1; i++, wnump--, resp--) {
+ for (int i = 0; i < loop - 1; i++, wnump--, resp--) {
BN_ULONG q, l0;
// the first part of the loop uses the top two words of snum and sdiv to
// calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv
- BN_ULONG n0, n1, rem = 0;
+ BN_ULONG n0, n1, rm = 0;
n0 = wnump[0];
n1 = wnump[-1];
@@ -307,18 +313,18 @@
q = BN_MASK2;
} else {
// n0 < d0
- bn_div_rem_words(&q, &rem, n0, n1, d0);
+ bn_div_rem_words(&q, &rm, n0, n1, d0);
#ifdef BN_ULLONG
BN_ULLONG t2 = (BN_ULLONG)d1 * q;
for (;;) {
- if (t2 <= ((((BN_ULLONG)rem) << BN_BITS2) | wnump[-2])) {
+ if (t2 <= ((((BN_ULLONG)rm) << BN_BITS2) | wnump[-2])) {
break;
}
q--;
- rem += d0;
- if (rem < d0) {
- break; // don't let rem overflow
+ rm += d0;
+ if (rm < d0) {
+ break; // don't let rm overflow
}
t2 -= d1;
}
@@ -326,13 +332,14 @@
BN_ULONG t2l, t2h;
BN_UMULT_LOHI(t2l, t2h, d1, q);
for (;;) {
- if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) {
+ if (t2h < rm ||
+ (t2h == rm && t2l <= wnump[-2])) {
break;
}
q--;
- rem += d0;
- if (rem < d0) {
- break; // don't let rem overflow
+ rm += d0;
+ if (rm < d0) {
+ break; // don't let rm overflow
}
if (t2l < d1) {
t2h--;
@@ -363,18 +370,21 @@
// store part of the result
*resp = q;
}
+
bn_correct_top(snum);
- if (rm != NULL) {
- // Keep a copy of the neg flag in num because if rm==num
- // BN_rshift() will overwrite it.
- int neg = num->neg;
- if (!BN_rshift(rm, snum, norm_shift)) {
+
+ if (rem != NULL) {
+ // Keep a copy of the neg flag in numerator because if |rem| == |numerator|
+ // |BN_rshift| will overwrite it.
+ int neg = numerator->neg;
+ if (!BN_rshift(rem, snum, norm_shift)) {
goto err;
}
- if (!BN_is_zero(rm)) {
- rm->neg = neg;
+ if (!BN_is_zero(rem)) {
+ rem->neg = neg;
}
}
+
bn_correct_top(res);
BN_CTX_end(ctx);
return 1;
diff --git a/src/crypto/fipsmodule/bn/exponentiation.c b/src/crypto/fipsmodule/bn/exponentiation.c
index e2dfb34..2d40e8f 100644
--- a/src/crypto/fipsmodule/bn/exponentiation.c
+++ b/src/crypto/fipsmodule/bn/exponentiation.c
@@ -188,9 +188,6 @@
return ret;
}
-// maximum precomputation table size for *variable* sliding windows
-#define TABLE_SIZE 32
-
typedef struct bn_recp_ctx_st {
BIGNUM N; // the divisor
BIGNUM Nr; // the reciprocal
@@ -393,8 +390,8 @@
return ret;
}
-// BN_window_bits_for_exponent_size -- macro for sliding window mod_exp
-// functions
+// BN_window_bits_for_exponent_size returns sliding window size for mod_exp with
+// a |b| bit exponent.
//
// For window size 'w' (w >= 2) and a random 'b' bits exponent, the number of
// multiplications is a constant plus on average
@@ -416,11 +413,26 @@
//
// (with draws in between). Very small exponents are often selected
// with low Hamming weight, so we use w = 1 for b <= 23.
-#define BN_window_bits_for_exponent_size(b) \
- ((b) > 671 ? 6 : \
- (b) > 239 ? 5 : \
- (b) > 79 ? 4 : \
- (b) > 23 ? 3 : 1)
+static int BN_window_bits_for_exponent_size(int b) {
+ if (b > 671) {
+ return 6;
+ }
+ if (b > 239) {
+ return 5;
+ }
+ if (b > 79) {
+ return 4;
+ }
+ if (b > 23) {
+ return 3;
+ }
+ return 1;
+}
+
+// TABLE_SIZE is the maximum precomputation table size for *variable* sliding
+// windows. This must be 2^(max_window - 1), where max_window is the largest
+// value returned from |BN_window_bits_for_exponent_size|.
+#define TABLE_SIZE 32
static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx) {
@@ -501,7 +513,7 @@
int wvalue; // The 'value' of the window
int wend; // The bottom bit of the window
- if (BN_is_bit_set(p, wstart) == 0) {
+ if (!BN_is_bit_set(p, wstart)) {
if (!start) {
if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) {
goto err;
@@ -573,19 +585,11 @@
int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) {
- int i, j, bits, ret = 0, wstart, window;
- int start = 1;
- BIGNUM *d, *r;
- const BIGNUM *aa;
- // Table of variables obtained from 'ctx'
- BIGNUM *val[TABLE_SIZE];
- BN_MONT_CTX *new_mont = NULL;
-
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
- bits = BN_num_bits(p);
+ int bits = BN_num_bits(p);
if (bits == 0) {
// x**0 mod 1 is still zero.
if (BN_is_one(m)) {
@@ -595,9 +599,13 @@
return BN_one(rr);
}
+ int ret = 0;
+ BIGNUM *val[TABLE_SIZE];
+ BN_MONT_CTX *new_mont = NULL;
+
BN_CTX_start(ctx);
- d = BN_CTX_get(ctx);
- r = BN_CTX_get(ctx);
+ BIGNUM *d = BN_CTX_get(ctx);
+ BIGNUM *r = BN_CTX_get(ctx);
val[0] = BN_CTX_get(ctx);
if (!d || !r || !val[0]) {
goto err;
@@ -612,6 +620,7 @@
mont = new_mont;
}
+ const BIGNUM *aa;
if (a->neg || BN_ucmp(a, m) >= 0) {
if (!BN_nnmod(val[0], a, m, ctx)) {
goto err;
@@ -626,53 +635,52 @@
ret = 1;
goto err;
}
- if (!BN_to_montgomery(val[0], aa, mont, ctx)) {
- goto err; // 1
- }
- window = BN_window_bits_for_exponent_size(bits);
+ // We exponentiate by looking at sliding windows of the exponent and
+ // precomputing powers of |aa|. Windows may be shifted so they always end on a
+ // set bit, so only precompute odd powers. We compute val[i] = aa^(2*i + 1)
+ // for i = 0 to 2^(window-1), all in Montgomery form.
+ int window = BN_window_bits_for_exponent_size(bits);
+ if (!BN_to_montgomery(val[0], aa, mont, ctx)) {
+ goto err;
+ }
if (window > 1) {
if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) {
- goto err; // 2
+ goto err;
}
- j = 1 << (window - 1);
- for (i = 1; i < j; i++) {
- if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ for (int i = 1; i < 1 << (window - 1); i++) {
+ val[i] = BN_CTX_get(ctx);
+ if (val[i] == NULL ||
!BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) {
goto err;
}
}
}
- start = 1; // This is used to avoid multiplication etc
- // when there is only the value '1' in the
- // buffer.
- wstart = bits - 1; // The top bit of the window
-
- j = m->top; // borrow j
- if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
- if (!bn_wexpand(r, j)) {
+ // Set |r| to one in Montgomery form. If the high bit of |m| is set, |m| is
+ // close to R and we subtract rather than perform Montgomery reduction.
+ if (m->d[m->top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+ if (!bn_wexpand(r, m->top)) {
goto err;
}
- // 2^(top*BN_BITS2) - m
+ // r = 2^(top*BN_BITS2) - m
r->d[0] = 0 - m->d[0];
- for (i = 1; i < j; i++) {
+ for (int i = 1; i < m->top; i++) {
r->d[i] = ~m->d[i];
}
- r->top = j;
- // Upper words will be zero if the corresponding words of 'm'
- // were 0xfff[...], so decrement r->top accordingly.
+ r->top = m->top;
+ // The upper words will be zero if the corresponding words of |m| were
+ // 0xfff[...], so call |bn_correct_top|.
bn_correct_top(r);
} else if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) {
goto err;
}
+ int r_is_one = 1;
+ int wstart = bits - 1; // The top bit of the window.
for (;;) {
- int wvalue; // The 'value' of the window
- int wend; // The bottom bit of the window
-
- if (BN_is_bit_set(p, wstart) == 0) {
- if (!start && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
+ if (!BN_is_bit_set(p, wstart)) {
+ if (!r_is_one && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
goto err;
}
if (wstart == 0) {
@@ -682,44 +690,37 @@
continue;
}
- // We now have wstart on a 'set' bit, we now need to work out how bit a
- // window to do. To do this we need to scan forward until the last set bit
- // before the end of the window
- wvalue = 1;
- wend = 0;
- for (i = 1; i < window; i++) {
- if (wstart - i < 0) {
- break;
- }
+ // We now have wstart on a set bit. Find the largest window we can use.
+ int wvalue = 1;
+ int wsize = 0;
+ for (int i = 1; i < window && i <= wstart; i++) {
if (BN_is_bit_set(p, wstart - i)) {
- wvalue <<= (i - wend);
+ wvalue <<= (i - wsize);
wvalue |= 1;
- wend = i;
+ wsize = i;
}
}
- // wend is the size of the current window
- j = wend + 1;
- // add the 'bytes above'
- if (!start) {
- for (i = 0; i < j; i++) {
+ // Shift |r| to the end of the window.
+ if (!r_is_one) {
+ for (int i = 0; i < wsize + 1; i++) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
goto err;
}
}
}
- // wvalue will be an odd number < 2^window
+ assert(wvalue & 1);
+ assert(wvalue < (1 << window));
if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) {
goto err;
}
- // move the 'window' down further
- wstart -= wend + 1;
- start = 0;
- if (wstart < 0) {
+ r_is_one = 0;
+ if (wstart == wsize) {
break;
}
+ wstart -= wsize + 1;
}
if (!BN_from_montgomery(rr, r, mont, ctx)) {
diff --git a/src/crypto/fipsmodule/bn/generic.c b/src/crypto/fipsmodule/bn/generic.c
index 11c377c..44e0f2c 100644
--- a/src/crypto/fipsmodule/bn/generic.c
+++ b/src/crypto/fipsmodule/bn/generic.c
@@ -458,7 +458,7 @@
#endif // !BN_ULLONG
-void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
+void bn_mul_comba8(BN_ULONG r[16], BN_ULONG a[8], BN_ULONG b[8]) {
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -560,7 +560,7 @@
r[15] = c1;
}
-void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
+void bn_mul_comba4(BN_ULONG r[8], BN_ULONG a[4], BN_ULONG b[4]) {
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -598,7 +598,7 @@
r[7] = c2;
}
-void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
+void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) {
BN_ULONG c1, c2, c3;
c1 = 0;
@@ -672,7 +672,7 @@
r[15] = c1;
}
-void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
+void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) {
BN_ULONG c1, c2, c3;
c1 = 0;
diff --git a/src/crypto/fipsmodule/bn/internal.h b/src/crypto/fipsmodule/bn/internal.h
index b1e0b0d..acc0ac8 100644
--- a/src/crypto/fipsmodule/bn/internal.h
+++ b/src/crypto/fipsmodule/bn/internal.h
@@ -142,41 +142,39 @@
#if !defined(_MSC_VER)
// MSVC doesn't support two-word integers on 64-bit.
-#define BN_ULLONG uint128_t
+#define BN_ULLONG uint128_t
#endif
-#define BN_BITS2 64
-#define BN_BYTES 8
-#define BN_BITS4 32
-#define BN_MASK2 (0xffffffffffffffffUL)
-#define BN_MASK2l (0xffffffffUL)
-#define BN_MASK2h (0xffffffff00000000UL)
-#define BN_MASK2h1 (0xffffffff80000000UL)
+#define BN_BITS2 64
+#define BN_BYTES 8
+#define BN_BITS4 32
+#define BN_MASK2 (0xffffffffffffffffUL)
+#define BN_MASK2l (0xffffffffUL)
+#define BN_MASK2h (0xffffffff00000000UL)
+#define BN_MASK2h1 (0xffffffff80000000UL)
#define BN_MONT_CTX_N0_LIMBS 1
-#define BN_TBIT (0x8000000000000000UL)
-#define BN_DEC_CONV (10000000000000000000UL)
-#define BN_DEC_NUM 19
+#define BN_DEC_CONV (10000000000000000000UL)
+#define BN_DEC_NUM 19
#define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo))
#elif defined(OPENSSL_32_BIT)
-#define BN_ULLONG uint64_t
-#define BN_BITS2 32
-#define BN_BYTES 4
-#define BN_BITS4 16
-#define BN_MASK2 (0xffffffffUL)
-#define BN_MASK2l (0xffffUL)
-#define BN_MASK2h1 (0xffff8000UL)
-#define BN_MASK2h (0xffff0000UL)
+#define BN_ULLONG uint64_t
+#define BN_BITS2 32
+#define BN_BYTES 4
+#define BN_BITS4 16
+#define BN_MASK2 (0xffffffffUL)
+#define BN_MASK2l (0xffffUL)
+#define BN_MASK2h1 (0xffff8000UL)
+#define BN_MASK2h (0xffff0000UL)
// On some 32-bit platforms, Montgomery multiplication is done using 64-bit
// arithmetic with SIMD instructions. On such platforms, |BN_MONT_CTX::n0|
// needs to be two words long. Only certain 32-bit platforms actually make use
// of n0[1] and shorter R value would suffice for the others. However,
// currently only the assembly files know which is which.
#define BN_MONT_CTX_N0_LIMBS 2
-#define BN_TBIT (0x80000000UL)
-#define BN_DEC_CONV (1000000000UL)
-#define BN_DEC_NUM 9
+#define BN_DEC_CONV (1000000000UL)
+#define BN_DEC_NUM 9
#define TOBN(hi, lo) (lo), (hi)
#else
@@ -212,16 +210,50 @@
// least significant word first.
int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num);
-BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
-BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
-void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
-BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
-BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+// bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places
+// the result in |rp|. |ap| and |rp| must both be |num| words long. It returns
+// the carry word of the operation. |ap| and |rp| may be equal but otherwise may
+// not alias.
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w);
-void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
-void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
-void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
-void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
+// bn_mul_words multiples |ap| by |w| and places the result in |rp|. |ap| and
+// |rp| must both be |num| words long. It returns the carry word of the
+// operation. |ap| and |rp| may be equal but otherwise may not alias.
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+
+// bn_sqr_words sets |rp[2*i]| and |rp[2*i+1]| to |ap[i]|'s square, for all |i|
+// up to |num|. |ap| is an array of |num| words and |rp| an array of |2*num|
+// words. |ap| and |rp| may not alias.
+//
+// This gives the contribution of the |ap[i]*ap[i]| terms when squaring |ap|.
+void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+
+// bn_add_words adds |ap| to |bp| and places the result in |rp|, each of which
+// are |num| words long. It returns the carry bit, which is one if the operation
+// overflowed and zero otherwise. Any pair of |ap|, |bp|, and |rp| may be equal
+// to each other but otherwise may not alias.
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ int num);
+
+// bn_sub_words subtracts |bp| from |ap| and places the result in |rp|. It
+// returns the borrow bit, which is one if the computation underflowed and zero
+// otherwise. Any pair of |ap|, |bp|, and |rp| may be equal to each other but
+// otherwise may not alias.
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ int num);
+
+// bn_mul_comba4 sets |r| to the product of |a| and |b|.
+void bn_mul_comba4(BN_ULONG r[8], BN_ULONG a[4], BN_ULONG b[4]);
+
+// bn_mul_comba8 sets |r| to the product of |a| and |b|.
+void bn_mul_comba8(BN_ULONG r[16], BN_ULONG a[8], BN_ULONG b[8]);
+
+// bn_sqr_comba8 sets |r| to |a|^2.
+void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[4]);
+
+// bn_sqr_comba4 sets |r| to |a|^2.
+void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]);
// bn_cmp_words returns a value less than, equal to or greater than zero if
// the, length |n|, array |a| is less than, equal to or greater than |b|.
diff --git a/src/crypto/fipsmodule/bn/montgomery.c b/src/crypto/fipsmodule/bn/montgomery.c
index 5219187..caa2513 100644
--- a/src/crypto/fipsmodule/bn/montgomery.c
+++ b/src/crypto/fipsmodule/bn/montgomery.c
@@ -207,14 +207,13 @@
mont->n0[1] = 0;
#endif
- // Save RR = R**2 (mod N). R is the smallest power of 2**BN_BITS such that R
+ // Save RR = R**2 (mod N). R is the smallest power of 2**BN_BITS2 such that R
// > mod. Even though the assembly on some 32-bit platforms works with 64-bit
// values, using |BN_BITS2| here, rather than |BN_MONT_CTX_N0_LIMBS *
// BN_BITS2|, is correct because R**2 will still be a multiple of the latter
// as |BN_MONT_CTX_N0_LIMBS| is either one or two.
//
- // XXX: This is not constant time with respect to |mont->N|, but it should
- // be.
+ // XXX: This is not constant time with respect to |mont->N|, but it should be.
unsigned lgBigR = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
if (!bn_mod_exp_base_2_vartime(&mont->RR, lgBigR * 2, &mont->N)) {
return 0;
diff --git a/src/crypto/fipsmodule/bn/mul.c b/src/crypto/fipsmodule/bn/mul.c
index b6f3ff1..65f3c2b 100644
--- a/src/crypto/fipsmodule/bn/mul.c
+++ b/src/crypto/fipsmodule/bn/mul.c
@@ -659,37 +659,37 @@
}
// tmp must have 2*n words
-static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp) {
- int i, j, max;
- const BN_ULONG *ap;
- BN_ULONG *rp;
-
- max = n * 2;
- ap = a;
- rp = r;
+static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n,
+ BN_ULONG *tmp) {
+ int max = n * 2;
+ const BN_ULONG *ap = a;
+ BN_ULONG *rp = r;
rp[0] = rp[max - 1] = 0;
rp++;
- j = n;
+ int j = n;
+ // Compute the contribution of a[i] * a[j] for all i < j.
if (--j > 0) {
ap++;
rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
rp += 2;
}
- for (i = n - 2; i > 0; i--) {
+ for (int i = n - 2; i > 0; i--) {
j--;
ap++;
rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
rp += 2;
}
+ // The final result fits in |max| words, so none of the following operations
+ // will overflow.
+
+ // Double |r|, giving the contribution of a[i] * a[j] for all i != j.
bn_add_words(r, r, r, max);
- // There will not be a carry
-
+ // Add in the contribution of a[i] * a[i] for all i.
bn_sqr_words(tmp, a, n);
-
bn_add_words(r, r, tmp, max);
}
@@ -702,7 +702,8 @@
// a[0]*b[0]
// a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
// a[1]*b[1]
-static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t) {
+static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2,
+ BN_ULONG *t) {
int n = n2 / 2;
int zero, c1;
BN_ULONG ln, lo, *p;
diff --git a/src/crypto/fipsmodule/bn/shift.c b/src/crypto/fipsmodule/bn/shift.c
index 64afa78..d4528e6 100644
--- a/src/crypto/fipsmodule/bn/shift.c
+++ b/src/crypto/fipsmodule/bn/shift.c
@@ -122,7 +122,7 @@
for (i = 0; i < a->top; i++) {
t = *(ap++);
*(rp++) = (t << 1) | c;
- c = (t & BN_TBIT) ? 1 : 0;
+ c = t >> (BN_BITS2 - 1);
}
if (c) {
*rp = 1;
@@ -209,14 +209,14 @@
}
rp = r->d;
t = ap[--i];
- c = (t & 1) ? BN_TBIT : 0;
+ c = t << (BN_BITS2 - 1);
if (t >>= 1) {
rp[i] = t;
}
while (i > 0) {
t = ap[--i];
rp[i] = (t >> 1) | c;
- c = (t & 1) ? BN_TBIT : 0;
+ c = t << (BN_BITS2 - 1);
}
r->top = j;
diff --git a/src/crypto/fipsmodule/ecdsa/ecdsa.c b/src/crypto/fipsmodule/ecdsa/ecdsa.c
index dfa3b67..0e2adb6 100644
--- a/src/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/src/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -160,7 +160,7 @@
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
goto err;
}
- // calculate tmp1 = inv(S) mod order
+ // tmp = inv(s) mod order
int no_inverse;
if (!BN_mod_inverse_odd(u2, &no_inverse, sig->s, order, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
@@ -174,7 +174,7 @@
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
- // u2 = r * w mod q
+ // u2 = r * tmp mod order
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
@@ -267,13 +267,11 @@
goto err;
}
} else if (digest_len > 0) {
- do {
- if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
- digest, digest_len, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
- goto err;
- }
- } while (BN_is_zero(k));
+ if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey),
+ digest, digest_len, ctx)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
+ goto err;
+ }
} else if (!BN_rand_range_ex(k, 1, order)) {
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
diff --git a/src/crypto/fipsmodule/ecdsa/ecdsa_test.cc b/src/crypto/fipsmodule/ecdsa/ecdsa_test.cc
index de4bc48..837b95d 100644
--- a/src/crypto/fipsmodule/ecdsa/ecdsa_test.cc
+++ b/src/crypto/fipsmodule/ecdsa/ecdsa_test.cc
@@ -67,17 +67,17 @@
#include "../../test/file_test.h"
-enum Api {
- kEncodedApi,
- kRawApi,
+enum API {
+ kEncodedAPI,
+ kRawAPI,
};
// VerifyECDSASig checks that verifying |ecdsa_sig| gives |expected_result|.
-static void VerifyECDSASig(Api api, const uint8_t *digest, size_t digest_len,
+static void VerifyECDSASig(API api, const uint8_t *digest, size_t digest_len,
const ECDSA_SIG *ecdsa_sig, EC_KEY *eckey,
int expected_result) {
switch (api) {
- case kEncodedApi: {
+ case kEncodedAPI: {
uint8_t *der;
size_t der_len;
ASSERT_TRUE(ECDSA_SIG_to_bytes(&der, &der_len, ecdsa_sig));
@@ -87,7 +87,7 @@
break;
}
- case kRawApi:
+ case kRawAPI:
EXPECT_EQ(expected_result,
ECDSA_do_verify(digest, digest_len, ecdsa_sig, eckey));
break;
@@ -100,7 +100,7 @@
// TestTamperedSig verifies that signature verification fails when a valid
// signature is tampered with. |ecdsa_sig| must be a valid signature, which will
// be modified.
-static void TestTamperedSig(Api api, const uint8_t *digest,
+static void TestTamperedSig(API api, const uint8_t *digest,
size_t digest_len, ECDSA_SIG *ecdsa_sig,
EC_KEY *eckey, const BIGNUM *order) {
SCOPED_TRACE(api);
@@ -206,7 +206,7 @@
bssl::UniquePtr<ECDSA_SIG> ecdsa_sig(
ECDSA_SIG_from_bytes(signature.data(), signature.size()));
ASSERT_TRUE(ecdsa_sig);
- TestTamperedSig(kEncodedApi, digest, 20, ecdsa_sig.get(), eckey.get(),
+ TestTamperedSig(kEncodedAPI, digest, 20, ecdsa_sig.get(), eckey.get(),
order);
// Test ECDSA_SIG signing and verification.
@@ -228,7 +228,7 @@
ERR_clear_error();
// Verify a tampered signature.
- TestTamperedSig(kRawApi, digest, 20, ecdsa_sig.get(), eckey.get(), order);
+ TestTamperedSig(kRawAPI, digest, 20, ecdsa_sig.get(), eckey.get(), order);
}
}
diff --git a/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl b/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl
index dd6657b..3d0600f 100644
--- a/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl
+++ b/src/crypto/fipsmodule/modes/asm/aesni-gcm-x86_64.pl
@@ -86,6 +86,7 @@
.type _aesni_ctr32_ghash_6x,\@abi-omnipotent
.align 32
_aesni_ctr32_ghash_6x:
+.cfi_startproc
vmovdqu 0x20($const),$T2 # borrow $T2, .Lone_msb
sub \$6,$len
vpxor $Z0,$Z0,$Z0 # $Z0 = 0
@@ -410,6 +411,7 @@
vpxor $Z0,$Xi,$Xi # modulo-scheduled
ret
+.cfi_endproc
.size _aesni_ctr32_ghash_6x,.-_aesni_ctr32_ghash_6x
___
######################################################################
@@ -422,6 +424,7 @@
.type aesni_gcm_decrypt,\@function,6
.align 32
aesni_gcm_decrypt:
+.cfi_startproc
xor $ret,$ret
# We call |_aesni_ctr32_ghash_6x|, which requires at least 96 (0x60)
@@ -430,12 +433,19 @@
jb .Lgcm_dec_abort
lea (%rsp),%rax # save stack pointer
+.cfi_def_cfa_register %rax
push %rbx
+.cfi_push %rbx
push %rbp
+.cfi_push %rbp
push %r12
+.cfi_push %r12
push %r13
+.cfi_push %r13
push %r14
+.cfi_push %r14
push %r15
+.cfi_push %r15
___
$code.=<<___ if ($win64);
lea -0xa8(%rsp),%rsp
@@ -535,15 +545,23 @@
___
$code.=<<___;
mov -48(%rax),%r15
+.cfi_restore %r15
mov -40(%rax),%r14
+.cfi_restore %r14
mov -32(%rax),%r13
+.cfi_restore %r13
mov -24(%rax),%r12
+.cfi_restore %r12
mov -16(%rax),%rbp
+.cfi_restore %rbp
mov -8(%rax),%rbx
+.cfi_restore %rbx
lea (%rax),%rsp # restore %rsp
+.cfi_def_cfa_register %rsp
.Lgcm_dec_abort:
mov $ret,%rax # return value
ret
+.cfi_endproc
.size aesni_gcm_decrypt,.-aesni_gcm_decrypt
___
@@ -551,6 +569,7 @@
.type _aesni_ctr32_6x,\@abi-omnipotent
.align 32
_aesni_ctr32_6x:
+.cfi_startproc
vmovdqu 0x00-0x80($key),$Z0 # borrow $Z0 for $rndkey
vmovdqu 0x20($const),$T2 # borrow $T2, .Lone_msb
lea -1($rounds),%r13
@@ -637,12 +656,14 @@
vpshufb $Ii,$T1,$T1 # next counter value
vpxor $Z0,$inout5,$inout5
jmp .Loop_ctr32
+.cfi_endproc
.size _aesni_ctr32_6x,.-_aesni_ctr32_6x
.globl aesni_gcm_encrypt
.type aesni_gcm_encrypt,\@function,6
.align 32
aesni_gcm_encrypt:
+.cfi_startproc
xor $ret,$ret
# We call |_aesni_ctr32_6x| twice, each call consuming 96 bytes of
@@ -652,12 +673,19 @@
jb .Lgcm_enc_abort
lea (%rsp),%rax # save stack pointer
+.cfi_def_cfa_register %rax
push %rbx
+.cfi_push %rbx
push %rbp
+.cfi_push %rbp
push %r12
+.cfi_push %r12
push %r13
+.cfi_push %r13
push %r14
+.cfi_push %r14
push %r15
+.cfi_push %r15
___
$code.=<<___ if ($win64);
lea -0xa8(%rsp),%rsp
@@ -929,15 +957,23 @@
___
$code.=<<___;
mov -48(%rax),%r15
+.cfi_restore %r15
mov -40(%rax),%r14
+.cfi_restore %r14
mov -32(%rax),%r13
+.cfi_restore %r13
mov -24(%rax),%r12
+.cfi_restore %r12
mov -16(%rax),%rbp
+.cfi_restore %rbp
mov -8(%rax),%rbx
+.cfi_restore %rbx
lea (%rax),%rsp # restore %rsp
+.cfi_def_cfa_register %rsp
.Lgcm_enc_abort:
mov $ret,%rax # return value
ret
+.cfi_endproc
.size aesni_gcm_encrypt,.-aesni_gcm_encrypt
___
diff --git a/src/crypto/fipsmodule/modes/cbc.c b/src/crypto/fipsmodule/modes/cbc.c
index 4b3bdb8..db9f024 100644
--- a/src/crypto/fipsmodule/modes/cbc.c
+++ b/src/crypto/fipsmodule/modes/cbc.c
@@ -62,7 +62,8 @@
assert(len == 0 || (in != NULL && out != NULL));
if (STRICT_ALIGNMENT &&
- ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) !=
+ 0) {
while (len >= 16) {
for (n = 0; n < 16; ++n) {
out[n] = in[n] ^ iv[n];
@@ -76,7 +77,7 @@
} 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);
+ store_word_le(out + n, load_word_le(in + n) ^ load_word_le(iv + n));
}
(*block)(out, out, key);
iv = out;
@@ -129,7 +130,8 @@
const uint8_t *iv = ivec;
if (STRICT_ALIGNMENT &&
- ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) !=
+ 0) {
while (len >= 16) {
(*block)(in, out, key);
for (n = 0; n < 16; ++n) {
@@ -142,11 +144,9 @@
}
} 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];
+ for (n = 0; n < 16; n += sizeof(size_t)) {
+ store_word_le(out + n, load_word_le(out + n) ^ load_word_le(iv + n));
}
iv = in;
len -= 16;
@@ -160,7 +160,8 @@
// directly to |out| would overwrite a ciphertext block before it is used as
// the next block's IV. Decrypt to a temporary block instead.
if (STRICT_ALIGNMENT &&
- ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) !=
+ 0) {
uint8_t c;
while (len >= 16) {
(*block)(in, tmp.c, key);
@@ -175,14 +176,12 @@
}
} 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;
+ for (n = 0; n < 16; n += sizeof(size_t)) {
+ size_t c = load_word_le(in + n);
+ store_word_le(out + n,
+ tmp.t[n / sizeof(size_t)] ^ load_word_le(ivec + n));
+ store_word_le(ivec + n, c);
}
len -= 16;
in += 16;
diff --git a/src/crypto/fipsmodule/modes/cfb.c b/src/crypto/fipsmodule/modes/cfb.c
index 2775d19..e1b0a80 100644
--- a/src/crypto/fipsmodule/modes/cfb.c
+++ b/src/crypto/fipsmodule/modes/cfb.c
@@ -72,7 +72,8 @@
n = (n + 1) % 16;
}
#if STRICT_ALIGNMENT
- if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ if (((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) !=
+ 0) {
while (l < len) {
if (n == 0) {
(*block)(ivec, ivec, key);
@@ -88,7 +89,9 @@
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);
+ size_t tmp = load_word_le(ivec + n) ^ load_word_le(in + n);
+ store_word_le(ivec + n, tmp);
+ store_word_le(out + n, tmp);
}
len -= 16;
out += 16;
@@ -112,9 +115,11 @@
--len;
n = (n + 1) % 16;
}
- if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+ if (STRICT_ALIGNMENT &&
+ ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) !=
+ 0) {
while (l < len) {
- unsigned char c;
+ uint8_t c;
if (n == 0) {
(*block)(ivec, ivec, key);
}
@@ -129,9 +134,9 @@
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;
+ size_t t = load_word_le(in + n);
+ store_word_le(out + n, load_word_le(ivec + n) ^ t);
+ store_word_le(ivec + n, t);
}
len -= 16;
out += 16;
@@ -227,4 +232,3 @@
cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block);
}
}
-
diff --git a/src/crypto/fipsmodule/modes/ctr.c b/src/crypto/fipsmodule/modes/ctr.c
index 5a97cf6..63907b4 100644
--- a/src/crypto/fipsmodule/modes/ctr.c
+++ b/src/crypto/fipsmodule/modes/ctr.c
@@ -100,7 +100,8 @@
}
#if STRICT_ALIGNMENT
- if (((size_t)in | (size_t)out | (size_t)ecount_buf) % sizeof(size_t) != 0) {
+ if (((uintptr_t)in | (uintptr_t)out |
+ (uintptr_t)ecount_buf) % sizeof(size_t) != 0) {
size_t l = 0;
while (l < len) {
if (n == 0) {
@@ -121,8 +122,8 @@
(*block)(ivec, ecount_buf, key);
ctr128_inc(ivec);
for (n = 0; n < 16; n += sizeof(size_t)) {
- *(size_t *)(out + n) = *(const size_t *)(in + n) ^
- *(const size_t *)(ecount_buf + n);
+ store_word_le(out + n,
+ load_word_le(in + n) ^ load_word_le(ecount_buf + n));
}
len -= 16;
out += 16;
diff --git a/src/crypto/fipsmodule/modes/gcm.c b/src/crypto/fipsmodule/modes/gcm.c
index bb5be54..05cd18d 100644
--- a/src/crypto/fipsmodule/modes/gcm.c
+++ b/src/crypto/fipsmodule/modes/gcm.c
@@ -550,8 +550,7 @@
}
int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
- const unsigned char *in, unsigned char *out,
- size_t len) {
+ const uint8_t *in, uint8_t *out, size_t len) {
unsigned int n, ctr;
uint64_t mlen = ctx->len.u[1];
block128_f block = ctx->block;
@@ -592,7 +591,8 @@
return 1;
}
}
- if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out) % sizeof(size_t) != 0) {
+ if (STRICT_ALIGNMENT &&
+ ((uintptr_t)in | (uintptr_t)out) % sizeof(size_t) != 0) {
for (size_t i = 0; i < len; ++i) {
if (n == 0) {
(*block)(ctx->Yi.c, ctx->EKi.c, key);
@@ -614,14 +614,12 @@
size_t j = GHASH_CHUNK;
while (j) {
- size_t *out_t = (size_t *)out;
- const size_t *in_t = (const size_t *)in;
-
(*block)(ctx->Yi.c, ctx->EKi.c, key);
++ctr;
ctx->Yi.d[3] = CRYPTO_bswap4(ctr);
- for (size_t i = 0; i < 16 / sizeof(size_t); ++i) {
- out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ for (size_t i = 0; i < 16; i += sizeof(size_t)) {
+ store_word_le(out + i,
+ load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]);
}
out += 16;
in += 16;
@@ -633,14 +631,12 @@
size_t len_blocks = len & kSizeTWithoutLower4Bits;
if (len_blocks != 0) {
while (len >= 16) {
- size_t *out_t = (size_t *)out;
- const size_t *in_t = (const size_t *)in;
-
(*block)(ctx->Yi.c, ctx->EKi.c, key);
++ctr;
ctx->Yi.d[3] = CRYPTO_bswap4(ctr);
- for (size_t i = 0; i < 16 / sizeof(size_t); ++i) {
- out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ for (size_t i = 0; i < 16; i += sizeof(size_t)) {
+ store_word_le(out + i,
+ load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]);
}
out += 16;
in += 16;
@@ -650,14 +646,13 @@
}
#else
while (len >= 16) {
- size_t *out_t = (size_t *)out;
- const size_t *in_t = (const size_t *)in;
-
(*block)(ctx->Yi.c, ctx->EKi.c, key);
++ctr;
ctx->Yi.d[3] = CRYPTO_bswap4(ctr);
- for (size_t i = 0; i < 16 / sizeof(size_t); ++i) {
- ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ for (size_t i = 0; i < 16; i += sizeof(size_t)) {
+ size_t tmp = load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)];
+ store_word_le(out + i, tmp);
+ ctx->Xi.t[i / sizeof(size_t)] ^= tmp;
}
GCM_MUL(ctx, Xi);
out += 16;
@@ -724,7 +719,8 @@
return 1;
}
}
- if (STRICT_ALIGNMENT && ((size_t)in | (size_t)out) % sizeof(size_t) != 0) {
+ if (STRICT_ALIGNMENT &&
+ ((uintptr_t)in | (uintptr_t)out) % sizeof(size_t) != 0) {
for (size_t i = 0; i < len; ++i) {
uint8_t c;
if (n == 0) {
@@ -750,14 +746,12 @@
GHASH(ctx, in, GHASH_CHUNK);
while (j) {
- size_t *out_t = (size_t *)out;
- const size_t *in_t = (const size_t *)in;
-
(*block)(ctx->Yi.c, ctx->EKi.c, key);
++ctr;
ctx->Yi.d[3] = CRYPTO_bswap4(ctr);
- for (size_t i = 0; i < 16 / sizeof(size_t); ++i) {
- out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ for (size_t i = 0; i < 16; i += sizeof(size_t)) {
+ store_word_le(out + i,
+ load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]);
}
out += 16;
in += 16;
@@ -769,14 +763,12 @@
if (len_blocks != 0) {
GHASH(ctx, in, len_blocks);
while (len >= 16) {
- size_t *out_t = (size_t *)out;
- const size_t *in_t = (const size_t *)in;
-
(*block)(ctx->Yi.c, ctx->EKi.c, key);
++ctr;
ctx->Yi.d[3] = CRYPTO_bswap4(ctr);
- for (size_t i = 0; i < 16 / sizeof(size_t); ++i) {
- out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+ for (size_t i = 0; i < 16; i += sizeof(size_t)) {
+ store_word_le(out + i,
+ load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]);
}
out += 16;
in += 16;
@@ -785,16 +777,13 @@
}
#else
while (len >= 16) {
- size_t *out_t = (size_t *)out;
- const size_t *in_t = (const size_t *)in;
-
(*block)(ctx->Yi.c, ctx->EKi.c, key);
++ctr;
ctx->Yi.d[3] = CRYPTO_bswap4(ctr);
- for (size_t i = 0; i < 16 / sizeof(size_t); ++i) {
- size_t c = in_t[i];
- out_t[i] = c ^ ctx->EKi.t[i];
- ctx->Xi.t[i] ^= c;
+ for (size_t i = 0; i < 16; i += sizeof(size_t)) {
+ size_t c = load_word_le(in + i);
+ store_word_le(out + i, c ^ ctx->EKi.t[i / sizeof(size_t)]);
+ ctx->Xi.t[i / sizeof(size_t)] ^= c;
}
GCM_MUL(ctx, Xi);
out += 16;
diff --git a/src/crypto/fipsmodule/modes/internal.h b/src/crypto/fipsmodule/modes/internal.h
index 6a5ff99..f6ee8f4 100644
--- a/src/crypto/fipsmodule/modes/internal.h
+++ b/src/crypto/fipsmodule/modes/internal.h
@@ -109,6 +109,16 @@
OPENSSL_memcpy(out, &v, sizeof(v));
}
+static inline size_t load_word_le(const void *in) {
+ size_t v;
+ OPENSSL_memcpy(&v, in, sizeof(v));
+ return v;
+}
+
+static inline void store_word_le(void *out, size_t v) {
+ OPENSSL_memcpy(out, &v, sizeof(v));
+}
+
// block128_f is the type of a 128-bit, block cipher.
typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16],
const void *key);
diff --git a/src/crypto/poly1305/poly1305_vec.c b/src/crypto/poly1305/poly1305_vec.c
index 80eaa36..480d9e5 100644
--- a/src/crypto/poly1305/poly1305_vec.c
+++ b/src/crypto/poly1305/poly1305_vec.c
@@ -85,57 +85,6 @@
return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
}
-// copy 0-63 bytes
-static inline void
-poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes) {
- size_t offset = src - dst;
- if (bytes & 32) {
- _mm_storeu_si128((xmmi *)(dst + 0),
- _mm_loadu_si128((const xmmi *)(dst + offset + 0)));
- _mm_storeu_si128((xmmi *)(dst + 16),
- _mm_loadu_si128((const xmmi *)(dst + offset + 16)));
- dst += 32;
- }
- if (bytes & 16) {
- _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((const xmmi *)(dst + offset)));
- dst += 16;
- }
- if (bytes & 8) {
- *(uint64_t *)dst = *(const uint64_t *)(dst + offset);
- dst += 8;
- }
- if (bytes & 4) {
- *(uint32_t *)dst = *(const uint32_t *)(dst + offset);
- dst += 4;
- }
- if (bytes & 2) {
- *(uint16_t *)dst = *(uint16_t *)(dst + offset);
- dst += 2;
- }
- if (bytes & 1) {
- *(uint8_t *)dst = *(uint8_t *)(dst + offset);
- }
-}
-
-// zero 0-15 bytes
-static inline void poly1305_block_zero(uint8_t *dst, size_t bytes) {
- if (bytes & 8) {
- *(uint64_t *)dst = 0;
- dst += 8;
- }
- if (bytes & 4) {
- *(uint32_t *)dst = 0;
- dst += 4;
- }
- if (bytes & 2) {
- *(uint16_t *)dst = 0;
- dst += 2;
- }
- if (bytes & 1) {
- *(uint8_t *)dst = 0;
- }
-}
-
static inline size_t poly1305_min(size_t a, size_t b) {
return (a < b) ? a : b;
}
@@ -721,7 +670,7 @@
bytes -= 32;
} else {
want = poly1305_min(32 - st->leftover, bytes);
- poly1305_block_copy(st->buffer + st->leftover, m, want);
+ OPENSSL_memcpy(st->buffer + st->leftover, m, want);
bytes -= want;
m += want;
st->leftover += want;
@@ -737,7 +686,7 @@
// handle leftover
if (st->leftover) {
want = poly1305_min(64 - st->leftover, bytes);
- poly1305_block_copy(st->buffer + st->leftover, m, want);
+ OPENSSL_memcpy(st->buffer + st->leftover, m, want);
bytes -= want;
m += want;
st->leftover += want;
@@ -757,7 +706,7 @@
}
if (bytes) {
- poly1305_block_copy(st->buffer + st->leftover, m, bytes);
+ OPENSSL_memcpy(st->buffer + st->leftover, m, bytes);
st->leftover += bytes;
}
}
@@ -833,7 +782,7 @@
}
m[leftover++] = 1;
- poly1305_block_zero(m + leftover, 16 - leftover);
+ OPENSSL_memset(m + leftover, 0, 16 - leftover);
leftover = 16;
t0 = U8TO64_LE(m + 0);
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 3540a25..8c36ad5 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -593,6 +593,7 @@
#define TLS1_3_DRAFT_VERSION 0x7f12
#define TLS1_3_DRAFT21_VERSION 0x7f15
+#define TLS1_3_DRAFT22_VERSION 0x7e04
#define TLS1_3_EXPERIMENT_VERSION 0x7e01
#define TLS1_3_EXPERIMENT2_VERSION 0x7e02
#define TLS1_3_EXPERIMENT3_VERSION 0x7e03
@@ -3255,6 +3256,7 @@
tls13_experiment2 = 2,
tls13_experiment3 = 3,
tls13_draft21 = 4,
+ tls13_draft22 = 5,
};
// SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the
diff --git a/src/ssl/handshake.cc b/src/ssl/handshake.cc
index ed11484..3b446a8 100644
--- a/src/ssl/handshake.cc
+++ b/src/ssl/handshake.cc
@@ -127,6 +127,7 @@
scts_requested(false),
needs_psk_binder(false),
received_hello_retry_request(false),
+ sent_hello_retry_request(false),
received_custom_extension(false),
handshake_finalized(false),
accept_psk_mode(false),
diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc
index f907939..583aceb 100644
--- a/src/ssl/handshake_client.cc
+++ b/src/ssl/handshake_client.cc
@@ -500,6 +500,12 @@
return ssl_hs_ok;
}
+ ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->session->ssl_version);
+ if (ssl_is_draft22(ssl->session->ssl_version) &&
+ !ssl->method->add_change_cipher_spec(ssl)) {
+ return ssl_hs_error;
+ }
+
if (!tls13_init_early_key_schedule(hs, ssl->session->master_key,
ssl->session->master_key_length) ||
!tls13_derive_early_secrets(hs) ||
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 55bece9..6c14383 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -396,6 +396,10 @@
// variant.
bool ssl_is_draft21(uint16_t version);
+// ssl_is_draft22 returns whether the version corresponds to a draft22 TLS 1.3
+// variant.
+bool ssl_is_draft22(uint16_t version);
+
// ssl_is_resumption_experiment returns whether the version corresponds to a
// TLS 1.3 resumption experiment.
bool ssl_is_resumption_experiment(uint16_t version);
@@ -1004,6 +1008,8 @@
// Channel ID, are all enabled.
#define SSL_MAX_HANDSHAKE_FLIGHT 7
+extern const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE];
+
// ssl_max_handshake_message_len returns the maximum number of bytes permitted
// in a handshake message for |ssl|.
size_t ssl_max_handshake_message_len(const SSL *ssl);
@@ -1438,6 +1444,7 @@
bool needs_psk_binder:1;
bool received_hello_retry_request:1;
+ bool sent_hello_retry_request:1;
bool received_custom_extension:1;
diff --git a/src/ssl/ssl_versions.cc b/src/ssl/ssl_versions.cc
index 1f30b41..15b0294 100644
--- a/src/ssl/ssl_versions.cc
+++ b/src/ssl/ssl_versions.cc
@@ -36,6 +36,7 @@
case TLS1_3_DRAFT_VERSION:
case TLS1_3_DRAFT21_VERSION:
+ case TLS1_3_DRAFT22_VERSION:
case TLS1_3_EXPERIMENT_VERSION:
case TLS1_3_EXPERIMENT2_VERSION:
case TLS1_3_EXPERIMENT3_VERSION:
@@ -60,6 +61,7 @@
// decreasing preference.
static const uint16_t kTLSVersions[] = {
+ TLS1_3_DRAFT22_VERSION,
TLS1_3_EXPERIMENT3_VERSION,
TLS1_3_EXPERIMENT2_VERSION,
TLS1_3_EXPERIMENT_VERSION,
@@ -109,6 +111,7 @@
switch (version) {
case TLS1_3_DRAFT_VERSION:
case TLS1_3_DRAFT21_VERSION:
+ case TLS1_3_DRAFT22_VERSION:
case TLS1_3_EXPERIMENT_VERSION:
case TLS1_3_EXPERIMENT2_VERSION:
case TLS1_3_EXPERIMENT3_VERSION:
@@ -142,6 +145,7 @@
// Report TLS 1.3 draft versions as TLS 1.3 in the public API.
case TLS1_3_DRAFT_VERSION:
case TLS1_3_DRAFT21_VERSION:
+ case TLS1_3_DRAFT22_VERSION:
case TLS1_3_EXPERIMENT_VERSION:
case TLS1_3_EXPERIMENT2_VERSION:
case TLS1_3_EXPERIMENT3_VERSION:
@@ -157,6 +161,7 @@
static bool api_version_to_wire(uint16_t *out, uint16_t version) {
if (version == TLS1_3_DRAFT_VERSION ||
version == TLS1_3_DRAFT21_VERSION ||
+ version == TLS1_3_DRAFT22_VERSION ||
version == TLS1_3_EXPERIMENT_VERSION ||
version == TLS1_3_EXPERIMENT2_VERSION ||
version == TLS1_3_EXPERIMENT3_VERSION) {
@@ -324,6 +329,8 @@
version == TLS1_3_EXPERIMENT3_VERSION) ||
(ssl->tls13_variant == tls13_draft21 &&
version == TLS1_3_DRAFT21_VERSION) ||
+ (ssl->tls13_variant == tls13_draft22 &&
+ version == TLS1_3_DRAFT22_VERSION) ||
(ssl->tls13_variant == tls13_default &&
version == TLS1_3_DRAFT_VERSION)) {
return true;
@@ -331,13 +338,15 @@
// The server, when not configured at |tls13_default|, should additionally
// enable all variants, except draft-21 which is implemented solely for QUIC
- // interop testing and will not be deployed. Currently, this is to implement
- // the draft-18 vs. experiments field trials. In the future, this will be to
- // transition cleanly to a future draft-22 which hopefully includes the
- // deployability fixes.
+ // interop testing and will not be deployed, and draft-22 which will be
+ // enabled once the draft is finalized and ready to be deployed in Chrome.
+ // Currently, this is to implement the draft-18 vs. experiments field trials.
+ // In the future, this will be to transition cleanly to a final draft-22
+ // which hopefully includes the deployability fixes.
if (ssl->server &&
ssl->tls13_variant != tls13_default &&
- version != TLS1_3_DRAFT21_VERSION) {
+ version != TLS1_3_DRAFT21_VERSION &&
+ version != TLS1_3_DRAFT22_VERSION) {
return true;
}
@@ -389,28 +398,35 @@
}
bool ssl_is_draft21(uint16_t version) {
- return version == TLS1_3_DRAFT21_VERSION;
+ return version == TLS1_3_DRAFT21_VERSION || version == TLS1_3_DRAFT22_VERSION;
+}
+
+bool ssl_is_draft22(uint16_t version) {
+ return version == TLS1_3_DRAFT22_VERSION;
}
bool ssl_is_resumption_experiment(uint16_t version) {
return version == TLS1_3_EXPERIMENT_VERSION ||
version == TLS1_3_EXPERIMENT2_VERSION ||
- version == TLS1_3_EXPERIMENT3_VERSION;
+ version == TLS1_3_EXPERIMENT3_VERSION ||
+ version == TLS1_3_DRAFT22_VERSION;
}
bool ssl_is_resumption_variant(enum tls13_variant_t variant) {
return variant == tls13_experiment || variant == tls13_experiment2 ||
- variant == tls13_experiment3;
+ variant == tls13_experiment3 || variant == tls13_draft22;
}
bool ssl_is_resumption_client_ccs_experiment(uint16_t version) {
return version == TLS1_3_EXPERIMENT_VERSION ||
- version == TLS1_3_EXPERIMENT2_VERSION;
+ version == TLS1_3_EXPERIMENT2_VERSION ||
+ version == TLS1_3_DRAFT22_VERSION;
}
bool ssl_is_resumption_record_version_experiment(uint16_t version) {
return version == TLS1_3_EXPERIMENT2_VERSION ||
- version == TLS1_3_EXPERIMENT3_VERSION;
+ version == TLS1_3_EXPERIMENT3_VERSION ||
+ version == TLS1_3_DRAFT22_VERSION;
}
} // namespace bssl
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 9e0deef..4564b0f 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -38,6 +38,7 @@
tls13ExperimentVersion = 0x7e01
tls13Experiment2Version = 0x7e02
tls13Experiment3Version = 0x7e03
+ tls13Draft22Version = 0x7e04
)
const (
@@ -46,10 +47,12 @@
TLS13Experiment2 = 2
TLS13Experiment3 = 3
TLS13Draft21 = 4
+ TLS13Draft22 = 5
)
var allTLSWireVersions = []uint16{
tls13DraftVersion,
+ tls13Draft22Version,
tls13Draft21Version,
tls13Experiment3Version,
tls13Experiment2Version,
@@ -148,6 +151,12 @@
scsvRenegotiation uint16 = 0x00ff
)
+var tls13HelloRetryRequest = []uint8{
+ 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c,
+ 0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb,
+ 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
+}
+
// CurveID is the type of a TLS identifier for an elliptic curve. See
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
type CurveID uint16
@@ -619,6 +628,10 @@
// messages.
FragmentAcrossChangeCipherSpec bool
+ // SendExtraChangeCipherSpec causes the implementation to send extra
+ // ChangeCipherSpec messages.
+ SendExtraChangeCipherSpec int
+
// SendUnencryptedFinished, if true, causes the Finished message to be
// send unencrypted before ChangeCipherSpec rather than after it.
SendUnencryptedFinished bool
@@ -1605,7 +1618,7 @@
switch vers {
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
return vers, true
- case tls13DraftVersion, tls13Draft21Version, tls13ExperimentVersion, tls13Experiment2Version, tls13Experiment3Version:
+ case tls13DraftVersion, tls13Draft22Version, tls13Draft21Version, tls13ExperimentVersion, tls13Experiment2Version, tls13Experiment3Version:
return VersionTLS13, true
}
}
@@ -1614,19 +1627,27 @@
}
func isDraft21(vers uint16) bool {
- return vers == tls13Draft21Version
+ return vers == tls13Draft21Version || vers == tls13Draft22Version
+}
+
+func isDraft22(vers uint16) bool {
+ return vers == tls13Draft22Version
}
func isResumptionExperiment(vers uint16) bool {
- return vers == tls13ExperimentVersion || vers == tls13Experiment2Version || vers == tls13Experiment3Version
+ return vers == tls13ExperimentVersion || vers == tls13Experiment2Version || vers == tls13Experiment3Version || vers == tls13Draft22Version
}
func isResumptionClientCCSExperiment(vers uint16) bool {
- return vers == tls13ExperimentVersion || vers == tls13Experiment2Version
+ return vers == tls13ExperimentVersion || vers == tls13Experiment2Version || vers == tls13Draft22Version
}
func isResumptionRecordVersionExperiment(vers uint16) bool {
- return vers == tls13Experiment2Version || vers == tls13Experiment3Version
+ return vers == tls13Experiment2Version || vers == tls13Experiment3Version || vers == tls13Draft22Version
+}
+
+func isResumptionRecordVersionVariant(variant int) bool {
+ return variant == TLS13Experiment2 || variant == TLS13Experiment3 || variant == TLS13Draft22
}
// isSupportedVersion checks if the specified wire version is acceptable. If so,
@@ -1636,6 +1657,7 @@
if (c.TLS13Variant != TLS13Experiment && wireVers == tls13ExperimentVersion) ||
(c.TLS13Variant != TLS13Experiment2 && wireVers == tls13Experiment2Version) ||
(c.TLS13Variant != TLS13Experiment3 && wireVers == tls13Experiment3Version) ||
+ (c.TLS13Variant != TLS13Draft22 && wireVers == tls13Draft22Version) ||
(c.TLS13Variant != TLS13Draft21 && wireVers == tls13Draft21Version) ||
(c.TLS13Variant != TLS13Default && wireVers == tls13DraftVersion) {
return 0, false
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index 6a2c59c..5359462 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -39,6 +39,7 @@
vers uint16 // TLS version
haveVers bool // version has been negotiated
config *Config // configuration passed to constructor
+ hadHelloRetryRequest bool
handshakeComplete bool
skipEarlyData bool // On a server, indicates that the client is sending early data that must be skipped over.
didResume bool // whether this connection was a session resumption
@@ -1152,7 +1153,6 @@
}
if isResumptionRecordVersionExperiment(c.wireVersion) || isResumptionRecordVersionExperiment(c.out.wireVersion) {
vers = VersionTLS12
- } else {
}
if c.config.Bugs.SendRecordVersion != 0 {
@@ -1322,6 +1322,14 @@
// so pass in a fresh copy that won't be overwritten.
data = append([]byte(nil), data...)
+ if data[0] == typeServerHello && len(data) >= 38 {
+ vers := uint16(data[4])<<8 | uint16(data[5])
+ if vers == VersionTLS12 && bytes.Equal(data[6:38], tls13HelloRetryRequest) {
+ m = new(helloRetryRequestMsg)
+ m.(*helloRetryRequestMsg).isServerHello = true
+ }
+ }
+
if !m.unmarshal(data) {
return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
}
@@ -1936,7 +1944,7 @@
payload[0] = byte(recordTypeApplicationData)
payload[1] = 3
payload[2] = 1
- if c.config.TLS13Variant == TLS13Experiment2 || c.config.TLS13Variant == TLS13Experiment3 {
+ if isResumptionRecordVersionVariant(c.config.TLS13Variant) {
payload[1] = 3
payload[2] = 3
}
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index ba34647..7c8dbb5 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -419,6 +419,12 @@
earlyLabel = earlyTrafficLabelDraft21
}
+ if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(session.wireVersion) {
+ c.wireVersion = session.wireVersion
+ c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ c.wireVersion = 0
+ }
+
earlyTrafficSecret := finishedHash.deriveSecret(earlyLabel)
c.useOutTrafficSecret(session.wireVersion, pskCipherSuite, earlyTrafficSecret)
for _, earlyData := range c.config.Bugs.SendEarlyData {
@@ -482,6 +488,13 @@
helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
var secondHelloBytes []byte
if haveHelloRetryRequest {
+ c.hadHelloRetryRequest = true
+ if isDraft22(c.wireVersion) {
+ if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
+ return err
+ }
+ }
+
c.out.resetCipher()
if len(helloRetryRequest.cookie) > 0 {
hello.tls13Cookie = helloRetryRequest.cookie
@@ -761,7 +774,7 @@
hs.finishedHash.addEntropy(zeroSecret)
}
- if isResumptionExperiment(c.wireVersion) {
+ if isResumptionExperiment(c.wireVersion) && !c.hadHelloRetryRequest {
if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
return err
}
@@ -979,7 +992,11 @@
}
}
- if isResumptionClientCCSExperiment(c.wireVersion) {
+ if !c.config.Bugs.SkipChangeCipherSpec && isResumptionClientCCSExperiment(c.wireVersion) && !hs.hello.hasEarlyData {
+ c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ }
+
+ for i := 0; i < c.config.Bugs.SendExtraChangeCipherSpec; i++ {
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
}
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index aa6b463..d5e3951 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -1406,6 +1406,8 @@
type helloRetryRequestMsg struct {
raw []byte
vers uint16
+ isServerHello bool
+ sessionId []byte
cipherSuite uint16
hasSelectedGroup bool
selectedGroup CurveID
@@ -1420,11 +1422,25 @@
}
retryRequestMsg := newByteBuilder()
- retryRequestMsg.addU8(typeHelloRetryRequest)
+ if isDraft22(m.vers) {
+ retryRequestMsg.addU8(typeServerHello)
+ } else {
+ retryRequestMsg.addU8(typeHelloRetryRequest)
+ }
retryRequest := retryRequestMsg.addU24LengthPrefixed()
- retryRequest.addU16(m.vers)
- if isDraft21(m.vers) {
+
+ if isDraft22(m.vers) {
+ retryRequest.addU16(VersionTLS12)
+ retryRequest.addBytes(tls13HelloRetryRequest)
+ sessionId := retryRequest.addU8LengthPrefixed()
+ sessionId.addBytes(m.sessionId)
retryRequest.addU16(m.cipherSuite)
+ retryRequest.addU8(0)
+ } else {
+ retryRequest.addU16(m.vers)
+ if isDraft21(m.vers) {
+ retryRequest.addU16(m.cipherSuite)
+ }
}
extensions := retryRequest.addU16LengthPrefixed()
@@ -1434,6 +1450,11 @@
}
for i := 0; i < count; i++ {
+ if isDraft22(m.vers) {
+ extensions.addU16(extensionSupportedVersions)
+ extensions.addU16(2) // Length
+ extensions.addU16(m.vers)
+ }
if m.hasSelectedGroup {
extensions.addU16(extensionKeyShare)
extensions.addU16(2) // length
@@ -1461,9 +1482,25 @@
}
m.vers = uint16(data[4])<<8 | uint16(data[5])
data = data[6:]
- if isDraft21(m.vers) {
+ if m.isServerHello {
+ if len(data) < 33 {
+ return false
+ }
+ data = data[32:] // Random
+ sessionIdLen := int(data[0])
+ if sessionIdLen > 32 || len(data) < 1+sessionIdLen+3 {
+ return false
+ }
+ m.sessionId = data[1 : 1+sessionIdLen]
+ data = data[1+sessionIdLen:]
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
data = data[2:]
+ data = data[1:] // Compression Method
+ } else {
+ if isDraft21(m.vers) {
+ m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
+ data = data[2:]
+ }
}
extLen := int(data[0])<<8 | int(data[1])
data = data[2:]
@@ -1482,6 +1519,11 @@
}
switch extension {
+ case extensionSupportedVersions:
+ if length != 2 || !m.isServerHello {
+ return false
+ }
+ m.vers = uint16(data[0])<<8 | uint16(data[1])
case extensionKeyShare:
if length != 2 {
return false
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index dd6f48f..2513a00 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -526,6 +526,7 @@
}
helloRetryRequest := &helloRetryRequestMsg{
vers: c.wireVersion,
+ sessionId: hs.clientHello.sessionId,
cipherSuite: cipherSuite,
duplicateExtensions: config.Bugs.DuplicateHelloRetryRequestExtensions,
}
@@ -587,6 +588,10 @@
c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
c.flushHandshake()
+ if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(c.wireVersion) {
+ c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ }
+
if hs.clientHello.hasEarlyData {
c.skipEarlyData = true
}
@@ -686,6 +691,12 @@
earlyLabel = earlyTrafficLabelDraft21
}
+ if isDraft22(c.wireVersion) {
+ if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
+ return err
+ }
+ }
+
earlyTrafficSecret := hs.finishedHash.deriveSecret(earlyLabel)
if err := c.useInTrafficSecret(c.wireVersion, hs.suite, earlyTrafficSecret); err != nil {
return err
@@ -782,7 +793,11 @@
}
c.flushHandshake()
- if isResumptionExperiment(c.wireVersion) {
+ if !c.config.Bugs.SkipChangeCipherSpec && isResumptionExperiment(c.wireVersion) && !sendHelloRetryRequest {
+ c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ }
+
+ for i := 0; i < c.config.Bugs.SendExtraChangeCipherSpec; i++ {
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
}
@@ -982,7 +997,7 @@
}
}
- if isResumptionClientCCSExperiment(c.wireVersion) && !c.skipEarlyData {
+ if isResumptionClientCCSExperiment(c.wireVersion) && !c.skipEarlyData && !encryptedExtensions.extensions.hasEarlyData {
if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
return err
}
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index ce50fa8..57bc20c 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -1312,6 +1312,13 @@
tls13Variant: TLS13Draft21,
},
{
+ name: "TLS13Draft22",
+ version: VersionTLS13,
+ excludeFlag: "-no-tls13",
+ versionWire: tls13Draft22Version,
+ tls13Variant: TLS13Draft22,
+ },
+ {
name: "TLS13Experiment",
version: VersionTLS13,
excludeFlag: "-no-tls13",
@@ -4160,6 +4167,37 @@
})
tests = append(tests, testCase{
+ name: "TLS13Draft22-HelloRetryRequest-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ // P-384 requires a HelloRetryRequest against BoringSSL's default
+ // configuration. Assert this with ExpectMissingKeyShare.
+ CurvePreferences: []CurveID{CurveP384},
+ Bugs: ProtocolBugs{
+ ExpectMissingKeyShare: true,
+ },
+ },
+ tls13Variant: TLS13Draft22,
+ // Cover HelloRetryRequest during an ECDHE-PSK resumption.
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "TLS13Draft22-HelloRetryRequest-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ // Require a HelloRetryRequest for every curve.
+ DefaultCurves: []CurveID{},
+ },
+ tls13Variant: TLS13Draft22,
+ // Cover HelloRetryRequest during an ECDHE-PSK resumption.
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
testType: clientTest,
name: "TLS13-EarlyData-TooMuchData-Client",
config: Config{
@@ -5177,7 +5215,7 @@
if expectedVersion == VersionTLS13 && runnerVers.tls13Variant != shimVers.tls13Variant {
expectedClientVersion = VersionTLS12
expectedServerVersion = VersionTLS12
- if shimVers.tls13Variant != TLS13Default && runnerVers.tls13Variant != TLS13Draft21 {
+ if shimVers.tls13Variant != TLS13Default && runnerVers.tls13Variant != TLS13Draft21 && runnerVers.tls13Variant != TLS13Draft22 {
expectedServerVersion = VersionTLS13
}
}
@@ -5196,7 +5234,7 @@
serverVers := expectedServerVersion
if expectedServerVersion >= VersionTLS13 {
serverVers = VersionTLS10
- if runnerVers.tls13Variant == TLS13Experiment2 || runnerVers.tls13Variant == TLS13Experiment3 {
+ if runnerVers.tls13Variant == TLS13Experiment2 || runnerVers.tls13Variant == TLS13Experiment3 || runnerVers.tls13Variant == TLS13Draft22 {
serverVers = VersionTLS12
}
}
@@ -11734,6 +11772,58 @@
expectedError: ":UNEXPECTED_EXTENSION:",
})
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13Draft22-SkipChangeCipherSpec-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ tls13Variant: TLS13Draft22,
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TLS13Draft22-SkipChangeCipherSpec-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ tls13Variant: TLS13Draft22,
+ })
+
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13Draft22-TooManyChangeCipherSpec-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendExtraChangeCipherSpec: 33,
+ },
+ },
+ tls13Variant: TLS13Draft22,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TLS13Draft22-TooManyChangeCipherSpec-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendExtraChangeCipherSpec: 33,
+ },
+ },
+ tls13Variant: TLS13Draft22,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
+ })
+
fooString := "foo"
barString := "bar"
diff --git a/src/ssl/tls13_both.cc b/src/ssl/tls13_both.cc
index 5796bf4..57acbcb 100644
--- a/src/ssl/tls13_both.cc
+++ b/src/ssl/tls13_both.cc
@@ -37,6 +37,12 @@
// without being able to return application data.
static const uint8_t kMaxKeyUpdates = 32;
+const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE] = {
+ 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c,
+ 0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb,
+ 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
+};
+
bool tls13_get_cert_verify_signature_input(
SSL_HANDSHAKE *hs, Array<uint8_t> *out,
enum ssl_cert_verify_context_t cert_verify_context) {
diff --git a/src/ssl/tls13_client.cc b/src/ssl/tls13_client.cc
index 9c09309..0013e61 100644
--- a/src/ssl/tls13_client.cc
+++ b/src/ssl/tls13_client.cc
@@ -36,7 +36,6 @@
state_read_hello_retry_request = 0,
state_send_second_client_hello,
state_read_server_hello,
- state_process_change_cipher_spec,
state_read_encrypted_extensions,
state_read_certificate_request,
state_read_server_certificate,
@@ -57,23 +56,52 @@
if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_read_message;
}
- if (msg.type != SSL3_MT_HELLO_RETRY_REQUEST) {
- hs->tls13_state = state_read_server_hello;
- return ssl_hs_ok;
- }
- CBS body = msg.body, extensions;
- uint16_t server_version, cipher_suite = 0;
- if (!CBS_get_u16(&body, &server_version) ||
- (ssl_is_draft21(ssl->version) &&
- !CBS_get_u16(&body, &cipher_suite)) ||
- !CBS_get_u16_length_prefixed(&body, &extensions) ||
- // HelloRetryRequest may not be empty.
- CBS_len(&extensions) == 0 ||
- CBS_len(&body) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return ssl_hs_error;
+ CBS extensions;
+ uint16_t cipher_suite = 0;
+ if (ssl_is_draft22(ssl->version)) {
+ if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) {
+ return ssl_hs_error;
+ }
+
+ CBS body = msg.body, server_random, session_id;
+ uint16_t server_version;
+ if (!CBS_get_u16(&body, &server_version) ||
+ !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) ||
+ !CBS_get_u8_length_prefixed(&body, &session_id) ||
+ !CBS_get_u16(&body, &cipher_suite) ||
+ !CBS_skip(&body, 1) ||
+ !CBS_get_u16_length_prefixed(&body, &extensions) ||
+ CBS_len(&extensions) == 0 ||
+ CBS_len(&body) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+
+ if (!CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) {
+ hs->tls13_state = state_read_server_hello;
+ return ssl_hs_ok;
+ }
+ } else {
+ if (msg.type != SSL3_MT_HELLO_RETRY_REQUEST) {
+ hs->tls13_state = state_read_server_hello;
+ return ssl_hs_ok;
+ }
+
+ CBS body = msg.body;
+ uint16_t server_version;
+ if (!CBS_get_u16(&body, &server_version) ||
+ (ssl_is_draft21(ssl->version) &&
+ !CBS_get_u16(&body, &cipher_suite)) ||
+ !CBS_get_u16_length_prefixed(&body, &extensions) ||
+ // HelloRetryRequest may not be empty.
+ CBS_len(&extensions) == 0 ||
+ CBS_len(&body) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
}
if (ssl_is_draft21(ssl->version)) {
@@ -96,11 +124,13 @@
}
- bool have_cookie, have_key_share;
- CBS cookie, key_share;
+ bool have_cookie, have_key_share, have_supported_versions;
+ CBS cookie, key_share, supported_versions;
const SSL_EXTENSION_TYPE ext_types[] = {
{TLSEXT_TYPE_key_share, &have_key_share, &key_share},
{TLSEXT_TYPE_cookie, &have_cookie, &cookie},
+ {TLSEXT_TYPE_supported_versions, &have_supported_versions,
+ &supported_versions},
};
uint8_t alert = SSL_AD_DECODE_ERROR;
@@ -111,6 +141,11 @@
return ssl_hs_error;
}
+ if (!ssl_is_draft22(ssl->version) && have_supported_versions) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ return ssl_hs_error;
+ }
if (have_cookie) {
CBS cookie_value;
if (!CBS_get_u16_length_prefixed(&cookie, &cookie_value) ||
@@ -359,20 +394,8 @@
if (!tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size()) ||
!ssl_hash_message(hs, msg) ||
- !tls13_derive_handshake_secrets(hs)) {
- return ssl_hs_error;
- }
-
- ssl->method->next_message(ssl);
- hs->tls13_state = state_process_change_cipher_spec;
- return ssl_is_resumption_experiment(ssl->version)
- ? ssl_hs_read_change_cipher_spec
- : ssl_hs_ok;
-}
-
-static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
+ !tls13_derive_handshake_secrets(hs) ||
+ !tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
hs->hash_len)) {
return ssl_hs_error;
}
@@ -388,6 +411,7 @@
}
}
+ ssl->method->next_message(ssl);
hs->tls13_state = state_read_encrypted_extensions;
return ssl_hs_ok;
}
@@ -642,9 +666,7 @@
}
if (hs->early_data_offered) {
- if ((ssl_is_resumption_client_ccs_experiment(ssl->version) &&
- !ssl->method->add_change_cipher_spec(ssl)) ||
- !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
+ if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
hs->hash_len)) {
return ssl_hs_error;
}
@@ -767,9 +789,6 @@
case state_read_server_hello:
ret = do_read_server_hello(hs);
break;
- case state_process_change_cipher_spec:
- ret = do_process_change_cipher_spec(hs);
- break;
case state_read_encrypted_extensions:
ret = do_read_encrypted_extensions(hs);
break;
@@ -824,8 +843,6 @@
return "TLS 1.3 client send_second_client_hello";
case state_read_server_hello:
return "TLS 1.3 client read_server_hello";
- case state_process_change_cipher_spec:
- return "TLS 1.3 client process_change_cipher_spec";
case state_read_encrypted_extensions:
return "TLS 1.3 client read_encrypted_extensions";
case state_read_certificate_request:
diff --git a/src/ssl/tls13_server.cc b/src/ssl/tls13_server.cc
index 9afd0d4..1040ace 100644
--- a/src/ssl/tls13_server.cc
+++ b/src/ssl/tls13_server.cc
@@ -47,7 +47,6 @@
state_send_server_certificate_verify,
state_send_server_finished,
state_read_second_client_flight,
- state_process_change_cipher_spec,
state_process_end_of_early_data,
state_read_client_certificate,
state_read_client_certificate_verify,
@@ -490,23 +489,55 @@
static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- ScopedCBB cbb;
- CBB body, extensions;
- uint16_t group_id;
- if (!ssl->method->init_message(ssl, cbb.get(), &body,
- SSL3_MT_HELLO_RETRY_REQUEST) ||
- !CBB_add_u16(&body, ssl->version) ||
- (ssl_is_draft21(ssl->version) &&
- !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher))) ||
- !tls1_get_shared_group(hs, &group_id) ||
- !CBB_add_u16_length_prefixed(&body, &extensions) ||
- !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
- !CBB_add_u16(&extensions, 2 /* length */) ||
- !CBB_add_u16(&extensions, group_id) ||
- !ssl_add_message_cbb(ssl, cbb.get())) {
- return ssl_hs_error;
+
+
+ if (ssl_is_draft22(ssl->version)) {
+ ScopedCBB cbb;
+ CBB body, session_id, extensions;
+ uint16_t group_id;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
+ SSL3_MT_SERVER_HELLO) ||
+ !CBB_add_u16(&body, TLS1_2_VERSION) ||
+ !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) ||
+ !CBB_add_u8_length_prefixed(&body, &session_id) ||
+ !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) ||
+ !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
+ !CBB_add_u8(&body, 0 /* no compression */) ||
+ !tls1_get_shared_group(hs, &group_id) ||
+ !CBB_add_u16_length_prefixed(&body, &extensions) ||
+ !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) ||
+ !CBB_add_u16(&extensions, 2 /* length */) ||
+ !CBB_add_u16(&extensions, ssl->version) ||
+ !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
+ !CBB_add_u16(&extensions, 2 /* length */) ||
+ !CBB_add_u16(&extensions, group_id) ||
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ return ssl_hs_error;
+ }
+
+ if (!ssl->method->add_change_cipher_spec(ssl)) {
+ return ssl_hs_error;
+ }
+ } else {
+ ScopedCBB cbb;
+ CBB body, extensions;
+ uint16_t group_id;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
+ SSL3_MT_HELLO_RETRY_REQUEST) ||
+ !CBB_add_u16(&body, ssl->version) ||
+ (ssl_is_draft21(ssl->version) &&
+ !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher))) ||
+ !tls1_get_shared_group(hs, &group_id) ||
+ !CBB_add_u16_length_prefixed(&body, &extensions) ||
+ !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
+ !CBB_add_u16(&extensions, 2 /* length */) ||
+ !CBB_add_u16(&extensions, group_id) ||
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ return ssl_hs_error;
+ }
}
+ hs->sent_hello_retry_request = true;
hs->tls13_state = state_read_second_client_hello;
return ssl_hs_flush;
}
@@ -576,6 +607,7 @@
}
if (ssl_is_resumption_experiment(ssl->version) &&
+ (!ssl_is_draft22(ssl->version) || !hs->sent_hello_retry_request) &&
!ssl->method->add_change_cipher_spec(ssl)) {
return ssl_hs_error;
}
@@ -756,46 +788,35 @@
hs->can_early_write = true;
hs->can_early_read = true;
hs->in_early_data = true;
- hs->tls13_state = state_process_end_of_early_data;
- return ssl_hs_read_end_of_early_data;
}
hs->tls13_state = state_process_end_of_early_data;
- return ssl_hs_ok;
+ return ssl->early_data_accepted ? ssl_hs_read_end_of_early_data : ssl_hs_ok;
}
static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- hs->tls13_state = state_process_change_cipher_spec;
if (hs->early_data_offered) {
// If early data was not accepted, the EndOfEarlyData and ChangeCipherSpec
// message will be in the discarded early data.
- if (!hs->ssl->early_data_accepted) {
- return ssl_hs_ok;
- }
- if (ssl_is_draft21(ssl->version)) {
- SSLMessage msg;
- if (!ssl->method->get_message(ssl, &msg)) {
- return ssl_hs_read_message;
- }
+ if (hs->ssl->early_data_accepted) {
+ if (ssl_is_draft21(ssl->version)) {
+ SSLMessage msg;
+ if (!ssl->method->get_message(ssl, &msg)) {
+ return ssl_hs_read_message;
+ }
- if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) {
- return ssl_hs_error;
+ if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) {
+ return ssl_hs_error;
+ }
+ if (CBS_len(&msg.body) != 0) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+ ssl->method->next_message(ssl);
}
- if (CBS_len(&msg.body) != 0) {
- ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- return ssl_hs_error;
- }
- ssl->method->next_message(ssl);
}
}
- return ssl_is_resumption_client_ccs_experiment(hs->ssl->version)
- ? ssl_hs_read_change_cipher_spec
- : ssl_hs_ok;
-}
-
-static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
hs->hash_len)) {
return ssl_hs_error;
@@ -973,9 +994,6 @@
case state_process_end_of_early_data:
ret = do_process_end_of_early_data(hs);
break;
- case state_process_change_cipher_spec:
- ret = do_process_change_cipher_spec(hs);
- break;
case state_read_client_certificate:
ret = do_read_client_certificate(hs);
break;
@@ -1028,8 +1046,6 @@
return "TLS 1.3 server send_server_finished";
case state_read_second_client_flight:
return "TLS 1.3 server read_second_client_flight";
- case state_process_change_cipher_spec:
- return "TLS 1.3 server process_change_cipher_spec";
case state_process_end_of_early_data:
return "TLS 1.3 server process_end_of_early_data";
case state_read_client_certificate:
diff --git a/src/ssl/tls_record.cc b/src/ssl/tls_record.cc
index a062012..7e8e968 100644
--- a/src/ssl/tls_record.cc
+++ b/src/ssl/tls_record.cc
@@ -247,6 +247,21 @@
*out_consumed = in.size() - CBS_len(&cbs);
+ if (ssl->s3->have_version &&
+ ssl_is_resumption_experiment(ssl->version) &&
+ SSL_in_init(ssl) &&
+ type == SSL3_RT_CHANGE_CIPHER_SPEC &&
+ ciphertext_len == 1 &&
+ CBS_data(&body)[0] == 1) {
+ ssl->s3->empty_record_count++;
+ if (ssl->s3->empty_record_count > kMaxEmptyRecords) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
+ *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
+ return ssl_open_record_error;
+ }
+ return ssl_open_record_discard;
+ }
+
// Skip early data received when expecting a second ClientHello if we rejected
// 0RTT.
if (ssl->s3->skip_early_data &&
diff --git a/src/third_party/android-cmake/METADATA b/src/third_party/android-cmake/METADATA
index 0ba6817..bddb4d3 100644
--- a/src/third_party/android-cmake/METADATA
+++ b/src/third_party/android-cmake/METADATA
@@ -5,7 +5,7 @@
third_party {
url {
- type: HOMEPAGE
+ type: GIT
value: "https://github.com/taka-no-me/android-cmake/"
}
version: "556cc14296c226f753a3778d99d8b60778b7df4f"
diff --git a/src/third_party/fiat/METADATA b/src/third_party/fiat/METADATA
index bae0285..8158c30 100644
--- a/src/third_party/fiat/METADATA
+++ b/src/third_party/fiat/METADATA
@@ -1,10 +1,10 @@
name: "fiat"
description:
- "Fiat-Crypto: Synthesizing Correct-by-Construction Code for Cryptographic Primitives".
+ "Fiat-Crypto: Synthesizing Correct-by-Construction Code for Cryptographic Primitives."
third_party {
url {
- type: HOMEPAGE
+ type: GIT
value: "https://github.com/mit-plv/fiat-crypto"
}
version: "6c4d4afb26de639718fcac39094353ca7feec365"
diff --git a/src/tool/client.cc b/src/tool/client.cc
index 873cea0..57e1b6e 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -121,7 +121,8 @@
"verification is required.",
},
{
- "-early-data", kOptionalArgument, "Allow early data",
+ "-early-data", kOptionalArgument, "Enable early data. The argument to "
+ "this flag is the early data to send.",
},
{
"-tls13-variant", kOptionalArgument,
@@ -339,6 +340,10 @@
*out = tls13_experiment3;
return true;
}
+ if (in == "draft22") {
+ *out = tls13_draft22;
+ return true;
+ }
return false;
}
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 1a80678..55f2059 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -284,8 +284,9 @@
BIO_printf(bio, " SCT list: %s\n", sct_list_len > 0 ? "yes" : "no");
}
- BIO_printf(bio, " Early data: %s\n",
- SSL_early_data_accepted(ssl) ? "yes" : "no");
+ BIO_printf(
+ bio, " Early data: %s\n",
+ (SSL_early_data_accepted(ssl) || SSL_in_early_data(ssl)) ? "yes" : "no");
// Print the server cert subject and issuer names.
bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
diff --git a/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm b/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm
index 741a9e4..63bcd48 100644
--- a/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm
+++ b/win-x86_64/crypto/fipsmodule/aesni-gcm-x86_64.asm
@@ -8,6 +8,7 @@
ALIGN 32
_aesni_ctr32_ghash_6x:
+
vmovdqu xmm2,XMMWORD[32+r11]
sub rdx,6
vpxor xmm4,xmm4,xmm4
@@ -333,6 +334,7 @@
DB 0F3h,0C3h ;repret
+
global aesni_gcm_decrypt
ALIGN 32
@@ -349,6 +351,7 @@
mov r9,QWORD[48+rsp]
+
xor r10,r10
@@ -357,12 +360,19 @@
jb NEAR $L$gcm_dec_abort
lea rax,[rsp]
+
push rbx
+
push rbp
+
push r12
+
push r13
+
push r14
+
push r15
+
lea rsp,[((-168))+rsp]
movaps XMMWORD[(-216)+rax],xmm6
movaps XMMWORD[(-200)+rax],xmm7
@@ -454,21 +464,30 @@
movaps xmm14,XMMWORD[((-88))+rax]
movaps xmm15,XMMWORD[((-72))+rax]
mov r15,QWORD[((-48))+rax]
+
mov r14,QWORD[((-40))+rax]
+
mov r13,QWORD[((-32))+rax]
+
mov r12,QWORD[((-24))+rax]
+
mov rbp,QWORD[((-16))+rax]
+
mov rbx,QWORD[((-8))+rax]
+
lea rsp,[rax]
+
$L$gcm_dec_abort:
mov rax,r10
mov rdi,QWORD[8+rsp] ;WIN64 epilogue
mov rsi,QWORD[16+rsp]
DB 0F3h,0C3h ;repret
+
$L$SEH_end_aesni_gcm_decrypt:
ALIGN 32
_aesni_ctr32_6x:
+
vmovdqu xmm4,XMMWORD[((0-128))+rcx]
vmovdqu xmm2,XMMWORD[32+r11]
lea r13,[((-1))+rbp]
@@ -557,6 +576,7 @@
jmp NEAR $L$oop_ctr32
+
global aesni_gcm_encrypt
ALIGN 32
@@ -573,6 +593,7 @@
mov r9,QWORD[48+rsp]
+
xor r10,r10
@@ -582,12 +603,19 @@
jb NEAR $L$gcm_enc_abort
lea rax,[rsp]
+
push rbx
+
push rbp
+
push r12
+
push r13
+
push r14
+
push r15
+
lea rsp,[((-168))+rsp]
movaps XMMWORD[(-216)+rax],xmm6
movaps XMMWORD[(-200)+rax],xmm7
@@ -844,17 +872,25 @@
movaps xmm14,XMMWORD[((-88))+rax]
movaps xmm15,XMMWORD[((-72))+rax]
mov r15,QWORD[((-48))+rax]
+
mov r14,QWORD[((-40))+rax]
+
mov r13,QWORD[((-32))+rax]
+
mov r12,QWORD[((-24))+rax]
+
mov rbp,QWORD[((-16))+rax]
+
mov rbx,QWORD[((-8))+rax]
+
lea rsp,[rax]
+
$L$gcm_enc_abort:
mov rax,r10
mov rdi,QWORD[8+rsp] ;WIN64 epilogue
mov rsi,QWORD[16+rsp]
DB 0F3h,0C3h ;repret
+
$L$SEH_end_aesni_gcm_encrypt:
ALIGN 64
$L$bswap_mask: