external/boringssl: Sync to b2ff2623a88a65fd4db42d3820f3d8c64e8ab180.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/6d50f475e319de153a43e1dba5a1beca95948c63..b2ff2623a88a65fd4db42d3820f3d8c64e8ab180
Change-Id: I649281e093369d99e863b4882a2ff6a5ad8a64d1
Test: ATP's cts/libcore/gce-net (go/gce-net)
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index d7d248e..398c360 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-6d50f475e319de153a43e1dba5a1beca95948c63
+b2ff2623a88a65fd4db42d3820f3d8c64e8ab180
diff --git a/linux-x86_64/crypto/bn/x86_64-mont5.S b/linux-x86_64/crypto/bn/x86_64-mont5.S
index 554df1f..5d7502c 100644
--- a/linux-x86_64/crypto/bn/x86_64-mont5.S
+++ b/linux-x86_64/crypto/bn/x86_64-mont5.S
@@ -1826,6 +1826,7 @@
.align 32
.L8x_tail_done:
+ xorq %rax,%rax
addq (%rdx),%r8
adcq $0,%r9
adcq $0,%r10
@@ -1834,9 +1835,7 @@
adcq $0,%r13
adcq $0,%r14
adcq $0,%r15
-
-
- xorq %rax,%rax
+ adcq $0,%rax
negq %rsi
.L8x_no_tail:
diff --git a/linux-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S b/linux-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S
index 889c535..241d7d0 100644
--- a/linux-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S
+++ b/linux-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S
@@ -61,7 +61,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -74,7 +74,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -108,7 +108,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -121,7 +121,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -140,7 +140,7 @@
adcq %r9,%r11
adcq $0,%r12
- leaq (1*16)(%rcx),%rcx
+ leaq 16(%rcx),%rcx
subq $16,%r8
jmp hash_ad_loop
hash_ad_tail:
@@ -170,7 +170,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -183,7 +183,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -238,7 +238,6 @@
.cfi_offset r13, -40
.cfi_offset r14, -48
.cfi_offset r15, -56
-.cfi_offset %r9, -64
leaq 32(%rsp),%rbp
andq $-32,%rbp
movq %rdx,8+32(%rbp)
@@ -406,7 +405,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movdqa .rol8(%rip),%xmm8
@@ -459,7 +458,7 @@
pslld $32-25,%xmm4
pxor %xmm8,%xmm4
movdqa 80(%rbp),%xmm8
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
.byte 102,15,58,15,255,4
@@ -594,7 +593,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -607,7 +606,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -727,7 +726,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -740,7 +739,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -845,7 +844,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -858,7 +857,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1032,7 +1031,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1045,7 +1044,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1209,7 +1208,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1222,7 +1221,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1253,7 +1252,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1266,7 +1265,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1431,7 +1430,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movdqa %xmm9,80(%rbp)
@@ -1510,7 +1509,7 @@
.byte 102,15,58,15,237,12
.byte 102,69,15,58,15,201,8
.byte 102,69,15,58,15,237,4
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
paddd %xmm6,%xmm2
@@ -1590,7 +1589,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1603,7 +1602,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1742,7 +1741,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1755,7 +1754,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1786,7 +1785,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1799,7 +1798,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2042,7 +2041,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2055,7 +2054,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2120,7 +2119,6 @@
.cfi_offset r13, -40
.cfi_offset r14, -48
.cfi_offset r15, -56
-.cfi_offset %r9, -64
leaq 32(%rsp),%rbp
andq $-32,%rbp
movq %rdx,8+32(%rbp)
@@ -2508,7 +2506,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movdqa .rol8(%rip),%xmm8
@@ -2561,7 +2559,7 @@
pslld $32-25,%xmm4
pxor %xmm8,%xmm4
movdqa 80(%rbp),%xmm8
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
.byte 102,15,58,15,255,4
@@ -2697,7 +2695,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2710,7 +2708,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2843,7 +2841,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2856,7 +2854,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2929,7 +2927,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2942,7 +2940,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3001,7 +2999,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3014,7 +3012,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3087,7 +3085,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3100,7 +3098,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3224,7 +3222,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3237,7 +3235,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3331,7 +3329,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3344,7 +3342,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3485,7 +3483,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3498,7 +3496,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3542,7 +3540,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3555,7 +3553,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3627,7 +3625,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3640,7 +3638,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3670,7 +3668,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3683,7 +3681,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3997,7 +3995,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4010,7 +4008,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4085,7 +4083,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -4103,7 +4101,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
vpxor %ymm9,%ymm5,%ymm5
@@ -4167,7 +4165,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vmovdqa %ymm8,128(%rbp)
@@ -4194,7 +4192,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpalignr $8,%ymm10,%ymm10,%ymm10
vpalignr $12,%ymm14,%ymm14,%ymm14
vpalignr $4,%ymm5,%ymm5,%ymm5
@@ -4274,7 +4272,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -4291,7 +4289,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpaddd %ymm12,%ymm8,%ymm8
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
@@ -4385,7 +4383,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4398,7 +4396,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4450,7 +4448,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4463,7 +4461,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4528,7 +4526,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4541,7 +4539,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4648,7 +4646,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -4657,7 +4655,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4795,7 +4793,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -4804,7 +4802,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4894,7 +4892,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -4903,7 +4901,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4991,7 +4989,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5004,7 +5002,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5102,7 +5100,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5111,7 +5109,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5215,7 +5213,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5228,7 +5226,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5293,7 +5291,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5302,7 +5300,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5375,7 +5373,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5384,7 +5382,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5506,7 +5504,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5515,7 +5513,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5758,7 +5756,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5771,7 +5769,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5799,7 +5797,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5812,7 +5810,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5862,7 +5860,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5875,7 +5873,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -6632,7 +6630,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -6650,7 +6648,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
vpxor %ymm9,%ymm5,%ymm5
@@ -6716,7 +6714,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vmovdqa %ymm8,128(%rbp)
@@ -6743,7 +6741,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpalignr $8,%ymm10,%ymm10,%ymm10
vpalignr $12,%ymm14,%ymm14,%ymm14
vpalignr $4,%ymm5,%ymm5,%ymm5
@@ -6823,7 +6821,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -6840,7 +6838,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpaddd %ymm12,%ymm8,%ymm8
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
@@ -6935,7 +6933,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -6948,7 +6946,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7000,7 +6998,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7013,7 +7011,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7058,7 +7056,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7071,7 +7069,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7099,7 +7097,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7112,7 +7110,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7156,7 +7154,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7169,7 +7167,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7219,7 +7217,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7232,7 +7230,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7279,7 +7277,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7292,7 +7290,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7355,7 +7353,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7368,7 +7366,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7437,7 +7435,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7450,7 +7448,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7516,7 +7514,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7529,7 +7527,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7616,7 +7614,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7629,7 +7627,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7698,7 +7696,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7711,7 +7709,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7777,7 +7775,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7790,7 +7788,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7930,7 +7928,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -7939,7 +7937,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8007,7 +8005,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpaddd %ymm4,%ymm0,%ymm0
@@ -8036,7 +8034,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpslld $32-25,%ymm7,%ymm7
vpxor %ymm8,%ymm7,%ymm7
vpsrld $25,%ymm6,%ymm8
@@ -8141,7 +8139,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpxor %ymm9,%ymm5,%ymm5
@@ -8170,7 +8168,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpalignr $8,%ymm10,%ymm10,%ymm10
vpalignr $4,%ymm14,%ymm14,%ymm14
vpalignr $12,%ymm5,%ymm5,%ymm5
@@ -8590,7 +8588,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8603,7 +8601,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8644,7 +8642,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8657,7 +8655,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8685,7 +8683,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8698,7 +8696,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8746,7 +8744,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8759,7 +8757,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
diff --git a/mac-x86_64/crypto/bn/x86_64-mont5.S b/mac-x86_64/crypto/bn/x86_64-mont5.S
index f3ad8d7..a154cc8 100644
--- a/mac-x86_64/crypto/bn/x86_64-mont5.S
+++ b/mac-x86_64/crypto/bn/x86_64-mont5.S
@@ -1825,6 +1825,7 @@
.p2align 5
L$8x_tail_done:
+ xorq %rax,%rax
addq (%rdx),%r8
adcq $0,%r9
adcq $0,%r10
@@ -1833,9 +1834,7 @@
adcq $0,%r13
adcq $0,%r14
adcq $0,%r15
-
-
- xorq %rax,%rax
+ adcq $0,%rax
negq %rsi
L$8x_no_tail:
diff --git a/mac-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S b/mac-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S
index 20a7838..4e5c0f3 100644
--- a/mac-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S
+++ b/mac-x86_64/crypto/cipher/chacha20_poly1305_x86_64.S
@@ -60,7 +60,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -73,7 +73,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -107,7 +107,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -120,7 +120,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -139,7 +139,7 @@
adcq %r9,%r11
adcq $0,%r12
- leaq (1*16)(%rcx),%rcx
+ leaq 16(%rcx),%rcx
subq $16,%r8
jmp hash_ad_loop
hash_ad_tail:
@@ -169,7 +169,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -182,7 +182,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -237,7 +237,6 @@
.cfi_offset r13, -40
.cfi_offset r14, -48
.cfi_offset r15, -56
-.cfi_offset %r9, -64
leaq 32(%rsp),%rbp
andq $-32,%rbp
movq %rdx,8+32(%rbp)
@@ -405,7 +404,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movdqa .rol8(%rip),%xmm8
@@ -458,7 +457,7 @@
pslld $32-25,%xmm4
pxor %xmm8,%xmm4
movdqa 80(%rbp),%xmm8
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
.byte 102,15,58,15,255,4
@@ -593,7 +592,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -606,7 +605,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -726,7 +725,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -739,7 +738,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -844,7 +843,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -857,7 +856,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1031,7 +1030,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1044,7 +1043,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1208,7 +1207,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1221,7 +1220,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1252,7 +1251,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1265,7 +1264,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1430,7 +1429,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movdqa %xmm9,80(%rbp)
@@ -1509,7 +1508,7 @@
.byte 102,15,58,15,237,12
.byte 102,69,15,58,15,201,8
.byte 102,69,15,58,15,237,4
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
paddd %xmm6,%xmm2
@@ -1589,7 +1588,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1602,7 +1601,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1741,7 +1740,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1754,7 +1753,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -1785,7 +1784,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -1798,7 +1797,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2041,7 +2040,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2054,7 +2053,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2119,7 +2118,6 @@
.cfi_offset r13, -40
.cfi_offset r14, -48
.cfi_offset r15, -56
-.cfi_offset %r9, -64
leaq 32(%rsp),%rbp
andq $-32,%rbp
movq %rdx,8+32(%rbp)
@@ -2507,7 +2505,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movdqa .rol8(%rip),%xmm8
@@ -2560,7 +2558,7 @@
pslld $32-25,%xmm4
pxor %xmm8,%xmm4
movdqa 80(%rbp),%xmm8
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
.byte 102,15,58,15,255,4
@@ -2696,7 +2694,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2709,7 +2707,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2842,7 +2840,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2855,7 +2853,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -2928,7 +2926,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -2941,7 +2939,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3000,7 +2998,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3013,7 +3011,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3086,7 +3084,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3099,7 +3097,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3223,7 +3221,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3236,7 +3234,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3330,7 +3328,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3343,7 +3341,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3484,7 +3482,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3497,7 +3495,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3541,7 +3539,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3554,7 +3552,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3626,7 +3624,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3639,7 +3637,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3669,7 +3667,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -3682,7 +3680,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -3996,7 +3994,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4009,7 +4007,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4084,7 +4082,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -4102,7 +4100,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
vpxor %ymm9,%ymm5,%ymm5
@@ -4166,7 +4164,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vmovdqa %ymm8,128(%rbp)
@@ -4193,7 +4191,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpalignr $8,%ymm10,%ymm10,%ymm10
vpalignr $12,%ymm14,%ymm14,%ymm14
vpalignr $4,%ymm5,%ymm5,%ymm5
@@ -4273,7 +4271,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -4290,7 +4288,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpaddd %ymm12,%ymm8,%ymm8
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
@@ -4384,7 +4382,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4397,7 +4395,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4449,7 +4447,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4462,7 +4460,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4527,7 +4525,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -4540,7 +4538,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4647,7 +4645,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -4656,7 +4654,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4794,7 +4792,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -4803,7 +4801,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4893,7 +4891,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -4902,7 +4900,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -4990,7 +4988,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5003,7 +5001,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5101,7 +5099,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5110,7 +5108,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5214,7 +5212,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5227,7 +5225,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5292,7 +5290,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5301,7 +5299,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5374,7 +5372,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5383,7 +5381,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5505,7 +5503,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -5514,7 +5512,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5757,7 +5755,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5770,7 +5768,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5798,7 +5796,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5811,7 +5809,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -5861,7 +5859,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -5874,7 +5872,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -6631,7 +6629,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -6649,7 +6647,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
vpxor %ymm9,%ymm5,%ymm5
@@ -6715,7 +6713,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vmovdqa %ymm8,128(%rbp)
@@ -6742,7 +6740,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpalignr $8,%ymm10,%ymm10,%ymm10
vpalignr $12,%ymm14,%ymm14,%ymm14
vpalignr $4,%ymm5,%ymm5,%ymm5
@@ -6822,7 +6820,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpshufb %ymm8,%ymm15,%ymm15
@@ -6839,7 +6837,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpaddd %ymm12,%ymm8,%ymm8
vpxor %ymm11,%ymm7,%ymm7
vpxor %ymm10,%ymm6,%ymm6
@@ -6934,7 +6932,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -6947,7 +6945,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -6999,7 +6997,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7012,7 +7010,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7057,7 +7055,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7070,7 +7068,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7098,7 +7096,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7111,7 +7109,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7155,7 +7153,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7168,7 +7166,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7218,7 +7216,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7231,7 +7229,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7278,7 +7276,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7291,7 +7289,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7354,7 +7352,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7367,7 +7365,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7436,7 +7434,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7449,7 +7447,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7515,7 +7513,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7528,7 +7526,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7615,7 +7613,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7628,7 +7626,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7697,7 +7695,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7710,7 +7708,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7776,7 +7774,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -7789,7 +7787,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -7929,7 +7927,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rdx
@@ -7938,7 +7936,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
addq %rax,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8006,7 +8004,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpaddd %ymm4,%ymm0,%ymm0
@@ -8035,7 +8033,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpslld $32-25,%ymm7,%ymm7
vpxor %ymm8,%ymm7,%ymm7
vpsrld $25,%ymm6,%ymm8
@@ -8140,7 +8138,7 @@
movq %rdx,%r15
mulxq %r10,%r13,%r14
mulxq %r11,%rax,%rdx
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
vpxor %ymm9,%ymm5,%ymm5
@@ -8169,7 +8167,7 @@
mulxq %r11,%r11,%r9
adcq %r11,%r15
adcq $0,%r9
- imul %r12,%rdx
+ imulq %r12,%rdx
vpalignr $8,%ymm10,%ymm10,%ymm10
vpalignr $4,%ymm14,%ymm14,%ymm14
vpalignr $12,%ymm5,%ymm5,%ymm5
@@ -8589,7 +8587,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8602,7 +8600,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8643,7 +8641,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8656,7 +8654,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8684,7 +8682,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8697,7 +8695,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
@@ -8745,7 +8743,7 @@
movq %rdx,%r14
movq 0+0(%rbp),%rax
mulq %r11
- imul %r12,%r15
+ imulq %r12,%r15
addq %rax,%r14
adcq %rdx,%r15
movq 8+0(%rbp),%rax
@@ -8758,7 +8756,7 @@
mulq %r11
addq %rax,%r15
adcq $0,%rdx
- imul %r12,%r9
+ imulq %r12,%r9
addq %r10,%r15
adcq %rdx,%r9
movq %r13,%r10
diff --git a/sources.bp b/sources.bp
index 31fd493..99720a5 100644
--- a/sources.bp
+++ b/sources.bp
@@ -56,7 +56,6 @@
"src/crypto/base64/base64.c",
"src/crypto/bio/bio.c",
"src/crypto/bio/bio_mem.c",
- "src/crypto/bio/buffer.c",
"src/crypto/bio/connect.c",
"src/crypto/bio/fd.c",
"src/crypto/bio/file.c",
@@ -398,6 +397,7 @@
cc_defaults {
name: "libssl_sources",
srcs: [
+ "src/ssl/bio_ssl.c",
"src/ssl/custom_extensions.c",
"src/ssl/d1_both.c",
"src/ssl/d1_lib.c",
diff --git a/sources.mk b/sources.mk
index e370f6e..ebea6b9 100644
--- a/sources.mk
+++ b/sources.mk
@@ -54,7 +54,6 @@
src/crypto/base64/base64.c\
src/crypto/bio/bio.c\
src/crypto/bio/bio_mem.c\
- src/crypto/bio/buffer.c\
src/crypto/bio/connect.c\
src/crypto/bio/fd.c\
src/crypto/bio/file.c\
diff --git a/src/crypto/bio/CMakeLists.txt b/src/crypto/bio/CMakeLists.txt
index 7859b58..49b9d76 100644
--- a/src/crypto/bio/CMakeLists.txt
+++ b/src/crypto/bio/CMakeLists.txt
@@ -7,7 +7,6 @@
bio.c
bio_mem.c
- buffer.c
connect.c
fd.c
file.c
diff --git a/src/crypto/bio/bio.c b/src/crypto/bio/bio.c
index 8aad9fb..5cab843 100644
--- a/src/crypto/bio/bio.c
+++ b/src/crypto/bio/bio.c
@@ -608,3 +608,5 @@
void BIO_set_retry_special(BIO *bio) {
bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
}
+
+int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index 24ed5be..1cba8a8 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -189,10 +189,6 @@
return ret;
}
-static int mem_puts(BIO *bp, const char *str) {
- return mem_write(bp, str, strlen(str));
-}
-
static int mem_gets(BIO *bio, char *buf, int size) {
int i, j;
char *p;
@@ -295,8 +291,12 @@
}
static const BIO_METHOD mem_method = {
- BIO_TYPE_MEM, "memory buffer", mem_write, mem_read, mem_puts,
- mem_gets, mem_ctrl, mem_new, mem_free, NULL, };
+ BIO_TYPE_MEM, "memory buffer",
+ mem_write, mem_read,
+ NULL /* puts */, mem_gets,
+ mem_ctrl, mem_new,
+ mem_free, NULL /* callback_ctrl */,
+};
const BIO_METHOD *BIO_s_mem(void) { return &mem_method; }
diff --git a/src/crypto/bio/buffer.c b/src/crypto/bio/buffer.c
deleted file mode 100644
index 6190f29..0000000
--- a/src/crypto/bio/buffer.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.] */
-
-#include <openssl/bio.h>
-
-#include <string.h>
-
-#include <openssl/buf.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
-
-#include "../internal.h"
-
-
-#define DEFAULT_BUFFER_SIZE 4096
-
-typedef struct bio_f_buffer_ctx_struct {
- /* Buffers are setup like this:
- *
- * <---------------------- size ----------------------->
- * +---------------------------------------------------+
- * | consumed | remaining | free space |
- * +---------------------------------------------------+
- * <-- off --><------- len ------->
- */
-
- int ibuf_size; /* how big is the input buffer */
- int obuf_size; /* how big is the output buffer */
-
- char *ibuf; /* the char array */
- int ibuf_len; /* how many bytes are in it */
- int ibuf_off; /* write/read offset */
-
- char *obuf; /* the char array */
- int obuf_len; /* how many bytes are in it */
- int obuf_off; /* write/read offset */
-} BIO_F_BUFFER_CTX;
-
-static int buffer_new(BIO *bio) {
- BIO_F_BUFFER_CTX *ctx;
-
- ctx = OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX));
- if (ctx == NULL) {
- return 0;
- }
- OPENSSL_memset(ctx, 0, sizeof(BIO_F_BUFFER_CTX));
-
- ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
- if (ctx->ibuf == NULL) {
- goto err1;
- }
- ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
- if (ctx->obuf == NULL) {
- goto err2;
- }
- ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
- ctx->obuf_size = DEFAULT_BUFFER_SIZE;
-
- bio->init = 1;
- bio->ptr = (char *)ctx;
- return 1;
-
-err2:
- OPENSSL_free(ctx->ibuf);
-
-err1:
- OPENSSL_free(ctx);
- return 0;
-}
-
-static int buffer_free(BIO *bio) {
- BIO_F_BUFFER_CTX *ctx;
-
- if (bio == NULL || bio->ptr == NULL) {
- return 0;
- }
-
- ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
- OPENSSL_free(ctx->ibuf);
- OPENSSL_free(ctx->obuf);
- OPENSSL_free(bio->ptr);
-
- bio->ptr = NULL;
- bio->init = 0;
- bio->flags = 0;
-
- return 1;
-}
-
-static int buffer_read(BIO *bio, char *out, int outl) {
- int i, num = 0;
- BIO_F_BUFFER_CTX *ctx;
-
- ctx = (BIO_F_BUFFER_CTX *)bio->ptr;
-
- if (ctx == NULL || bio->next_bio == NULL) {
- return 0;
- }
-
- num = 0;
- BIO_clear_retry_flags(bio);
-
- for (;;) {
- i = ctx->ibuf_len;
- /* If there is stuff left over, grab it */
- if (i != 0) {
- if (i > outl) {
- i = outl;
- }
- OPENSSL_memcpy(out, &ctx->ibuf[ctx->ibuf_off], i);
- ctx->ibuf_off += i;
- ctx->ibuf_len -= i;
- num += i;
- if (outl == i) {
- return num;
- }
- outl -= i;
- out += i;
- }
-
- /* We may have done a partial read. Try to do more. We have nothing in the
- * buffer. If we get an error and have read some data, just return it and
- * let them retry to get the error again. Copy direct to parent address
- * space */
- if (outl > ctx->ibuf_size) {
- for (;;) {
- i = BIO_read(bio->next_bio, out, outl);
- if (i <= 0) {
- BIO_copy_next_retry(bio);
- if (i < 0) {
- return (num > 0) ? num : i;
- }
- return num;
- }
- num += i;
- if (outl == i) {
- return num;
- }
- out += i;
- outl -= i;
- }
- }
- /* else */
-
- /* we are going to be doing some buffering */
- i = BIO_read(bio->next_bio, ctx->ibuf, ctx->ibuf_size);
- if (i <= 0) {
- BIO_copy_next_retry(bio);
- if (i < 0) {
- return (num > 0) ? num : i;
- }
- return num;
- }
- ctx->ibuf_off = 0;
- ctx->ibuf_len = i;
- }
-}
-
-static int buffer_write(BIO *b, const char *in, int inl) {
- int i, num = 0;
- BIO_F_BUFFER_CTX *ctx;
-
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
- if (ctx == NULL || b->next_bio == NULL) {
- return 0;
- }
-
- BIO_clear_retry_flags(b);
-
- for (;;) {
- i = ctx->obuf_size - (ctx->obuf_off + ctx->obuf_len);
- /* add to buffer and return */
- if (i >= inl) {
- OPENSSL_memcpy(&ctx->obuf[ctx->obuf_off + ctx->obuf_len], in, inl);
- ctx->obuf_len += inl;
- return num + inl;
- }
- /* else */
- /* stuff already in buffer, so add to it first, then flush */
- if (ctx->obuf_len != 0) {
- if (i > 0) {
- OPENSSL_memcpy(&ctx->obuf[ctx->obuf_off + ctx->obuf_len], in, i);
- in += i;
- inl -= i;
- num += i;
- ctx->obuf_len += i;
- }
-
- /* we now have a full buffer needing flushing */
- for (;;) {
- i = BIO_write(b->next_bio, &ctx->obuf[ctx->obuf_off], ctx->obuf_len);
- if (i <= 0) {
- BIO_copy_next_retry(b);
-
- if (i < 0) {
- return (num > 0) ? num : i;
- }
- return num;
- }
- ctx->obuf_off += i;
- ctx->obuf_len -= i;
- if (ctx->obuf_len == 0) {
- break;
- }
- }
- }
-
- /* we only get here if the buffer has been flushed and we
- * still have stuff to write */
- ctx->obuf_off = 0;
-
- /* we now have inl bytes to write */
- while (inl >= ctx->obuf_size) {
- i = BIO_write(b->next_bio, in, inl);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- if (i < 0) {
- return (num > 0) ? num : i;
- }
- return num;
- }
- num += i;
- in += i;
- inl -= i;
- if (inl == 0) {
- return num;
- }
- }
-
- /* copy the rest into the buffer since we have only a small
- * amount left */
- }
-}
-
-static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
- BIO_F_BUFFER_CTX *ctx;
- long ret = 1;
- char *p1, *p2;
- int r, *ip;
- int ibs, obs;
-
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
-
- switch (cmd) {
- case BIO_CTRL_RESET:
- ctx->ibuf_off = 0;
- ctx->ibuf_len = 0;
- ctx->obuf_off = 0;
- ctx->obuf_len = 0;
- if (b->next_bio == NULL) {
- return 0;
- }
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
-
- case BIO_CTRL_INFO:
- ret = ctx->obuf_len;
- break;
-
- case BIO_CTRL_WPENDING:
- ret = (long)ctx->obuf_len;
- break;
-
- case BIO_CTRL_PENDING:
- ret = (long)ctx->ibuf_len;
- break;
-
- case BIO_C_SET_BUFF_SIZE:
- ip = (int *)ptr;
- if (*ip == 0) {
- ibs = (int)num;
- obs = ctx->obuf_size;
- } else /* if (*ip == 1) */ {
- ibs = ctx->ibuf_size;
- obs = (int)num;
- }
- p1 = ctx->ibuf;
- p2 = ctx->obuf;
- if (ibs > DEFAULT_BUFFER_SIZE && ibs != ctx->ibuf_size) {
- p1 = OPENSSL_malloc(ibs);
- if (p1 == NULL) {
- goto malloc_error;
- }
- }
- if (obs > DEFAULT_BUFFER_SIZE && obs != ctx->obuf_size) {
- p2 = OPENSSL_malloc(obs);
- if (p2 == NULL) {
- if (p1 != ctx->ibuf) {
- OPENSSL_free(p1);
- }
- goto malloc_error;
- }
- }
-
- if (ctx->ibuf != p1) {
- OPENSSL_free(ctx->ibuf);
- ctx->ibuf = p1;
- ctx->ibuf_size = ibs;
- }
- ctx->ibuf_off = 0;
- ctx->ibuf_len = 0;
-
- if (ctx->obuf != p2) {
- OPENSSL_free(ctx->obuf);
- ctx->obuf = p2;
- ctx->obuf_size = obs;
- }
- ctx->obuf_off = 0;
- ctx->obuf_len = 0;
- break;
-
- case BIO_CTRL_FLUSH:
- if (b->next_bio == NULL) {
- return 0;
- }
-
- while (ctx->obuf_len > 0) {
- BIO_clear_retry_flags(b);
- r = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
- ctx->obuf_len);
- BIO_copy_next_retry(b);
- if (r <= 0) {
- return r;
- }
- ctx->obuf_off += r;
- ctx->obuf_len -= r;
- }
-
- ctx->obuf_len = 0;
- ctx->obuf_off = 0;
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- break;
-
- default:
- if (b->next_bio == NULL) {
- return 0;
- }
- BIO_clear_retry_flags(b);
- ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
- BIO_copy_next_retry(b);
- break;
- }
- return ret;
-
-malloc_error:
- OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb fp) {
- long ret = 1;
-
- if (b->next_bio == NULL) {
- return 0;
- }
-
- switch (cmd) {
- default:
- ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
- break;
- }
- return ret;
-}
-
-static int buffer_gets(BIO *b, char *buf, int size) {
- BIO_F_BUFFER_CTX *ctx;
- int num = 0, i, flag;
- char *p;
-
- ctx = (BIO_F_BUFFER_CTX *)b->ptr;
- if (buf == NULL || size <= 0) {
- return 0;
- }
-
- size--; /* reserve space for a '\0' */
- BIO_clear_retry_flags(b);
-
- for (;;) {
- if (ctx->ibuf_len > 0) {
- p = &ctx->ibuf[ctx->ibuf_off];
- flag = 0;
- for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
- *(buf++) = p[i];
- if (p[i] == '\n') {
- flag = 1;
- i++;
- break;
- }
- }
- num += i;
- size -= i;
- ctx->ibuf_len -= i;
- ctx->ibuf_off += i;
- if (flag || size == 0) {
- *buf = '\0';
- return num;
- }
- } else /* read another chunk */
- {
- i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
- if (i <= 0) {
- BIO_copy_next_retry(b);
- *buf = '\0';
- if (i < 0) {
- return (num > 0) ? num : i;
- }
- return num;
- }
- ctx->ibuf_len = i;
- ctx->ibuf_off = 0;
- }
- }
-}
-
-static int buffer_puts(BIO *b, const char *str) {
- return buffer_write(b, str, strlen(str));
-}
-
-static const BIO_METHOD methods_buffer = {
- BIO_TYPE_BUFFER, "buffer", buffer_write, buffer_read,
- buffer_puts, buffer_gets, buffer_ctrl, buffer_new,
- buffer_free, buffer_callback_ctrl,
-};
-
-const BIO_METHOD *BIO_f_buffer(void) { return &methods_buffer; }
-
-int BIO_set_read_buffer_size(BIO *bio, int buffer_size) {
- return BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, buffer_size, 0);
-}
-
-int BIO_set_write_buffer_size(BIO *bio, int buffer_size) {
- return BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, buffer_size, 1);
-}
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index f6cc837..d40dd53 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -468,14 +468,6 @@
break;
case BIO_CTRL_FLUSH:
break;
- case BIO_CTRL_SET_CALLBACK: {
-#if 0 /* FIXME: Should this be used? -- Richard Levitte */
- OPENSSL_PUT_ERROR(BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- ret = -1;
-#else
- ret = 0;
-#endif
- } break;
case BIO_CTRL_GET_CALLBACK: {
int (**fptr)(const BIO *bio, int state, int xret);
fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
@@ -485,7 +477,7 @@
ret = 0;
break;
}
- return (ret);
+ return ret;
}
static long conn_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
@@ -495,9 +487,9 @@
data = (BIO_CONNECT *)bio->ptr;
switch (cmd) {
- case BIO_CTRL_SET_CALLBACK: {
+ case BIO_CTRL_SET_CALLBACK:
data->info_callback = (int (*)(const struct bio_st *, int, int))fp;
- } break;
+ break;
default:
ret = 0;
break;
@@ -505,10 +497,6 @@
return ret;
}
-static int conn_puts(BIO *bp, const char *str) {
- return conn_write(bp, str, strlen(str));
-}
-
BIO *BIO_new_connect(const char *hostname) {
BIO *ret;
@@ -524,8 +512,8 @@
}
static const BIO_METHOD methods_connectp = {
- BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read,
- conn_puts, NULL /* connect_gets, */, conn_ctrl, conn_new,
+ BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read,
+ NULL /* puts */, NULL /* gets */, conn_ctrl, conn_new,
conn_free, conn_callback_ctrl,
};
diff --git a/src/crypto/bio/fd.c b/src/crypto/bio/fd.c
index 13833df..4e9eeac 100644
--- a/src/crypto/bio/fd.c
+++ b/src/crypto/bio/fd.c
@@ -241,10 +241,6 @@
return ret;
}
-static int fd_puts(BIO *bp, const char *str) {
- return fd_write(bp, str, strlen(str));
-}
-
static int fd_gets(BIO *bp, char *buf, int size) {
char *ptr = buf;
char *end = buf + size - 1;
@@ -263,8 +259,9 @@
}
static const BIO_METHOD methods_fdp = {
- BIO_TYPE_FD, "file descriptor", fd_write, fd_read, fd_puts,
- fd_gets, fd_ctrl, fd_new, fd_free, NULL, };
+ BIO_TYPE_FD, "file descriptor", fd_write, fd_read, NULL /* puts */,
+ fd_gets, fd_ctrl, fd_new, fd_free, NULL /* callback_ctrl */,
+};
const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; }
diff --git a/src/crypto/bio/file.c b/src/crypto/bio/file.c
index b903bc2..3580cd1 100644
--- a/src/crypto/bio/file.c
+++ b/src/crypto/bio/file.c
@@ -273,13 +273,13 @@
return ret;
}
-static int file_puts(BIO *bp, const char *str) {
- return file_write(bp, str, strlen(str));
-}
-
static const BIO_METHOD methods_filep = {
- BIO_TYPE_FILE, "FILE pointer", file_write, file_read, file_puts,
- file_gets, file_ctrl, file_new, file_free, NULL, };
+ BIO_TYPE_FILE, "FILE pointer",
+ file_write, file_read,
+ NULL /* puts */, file_gets,
+ file_ctrl, file_new,
+ file_free, NULL /* callback_ctrl */,
+};
const BIO_METHOD *BIO_s_file(void) { return &methods_filep; }
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index e933a1d..8ba382d 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -450,14 +450,10 @@
return ret;
}
-static int bio_puts(BIO *bio, const char *str) {
- return bio_write(bio, str, strlen(str));
-}
static const BIO_METHOD methods_biop = {
- BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
- bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
- bio_free, NULL /* no bio_callback_ctrl */
+ BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */,
+ NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */
};
static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
diff --git a/src/crypto/bio/socket.c b/src/crypto/bio/socket.c
index f70ea92..111761f 100644
--- a/src/crypto/bio/socket.c
+++ b/src/crypto/bio/socket.c
@@ -142,10 +142,6 @@
return ret;
}
-static int sock_puts(BIO *bp, const char *str) {
- return sock_write(bp, str, strlen(str));
-}
-
static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) {
long ret = 1;
int *ip;
@@ -185,8 +181,11 @@
}
static const BIO_METHOD methods_sockp = {
- BIO_TYPE_SOCKET, "socket", sock_write, sock_read, sock_puts,
- NULL /* gets, */, sock_ctrl, sock_new, sock_free, NULL,
+ BIO_TYPE_SOCKET, "socket",
+ sock_write, sock_read,
+ NULL /* puts */, NULL /* gets, */,
+ sock_ctrl, sock_new,
+ sock_free, NULL /* callback_ctrl */,
};
const BIO_METHOD *BIO_s_socket(void) { return &methods_sockp; }
diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl
index 61dd902..61fde2d 100755
--- a/src/crypto/bn/asm/x86_64-mont5.pl
+++ b/src/crypto/bn/asm/x86_64-mont5.pl
@@ -1852,6 +1852,7 @@
.align 32
.L8x_tail_done:
+ xor %rax,%rax
add (%rdx),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
@@ -1859,10 +1860,8 @@
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
- adc \$0,%r15 # can't overflow, because we
- # started with "overhung" part
- # of multiplication
- xor %rax,%rax
+ adc \$0,%r15
+ adc \$0,%rax
neg $carry
.L8x_no_tail:
@@ -3248,6 +3247,7 @@
.align 32
.Lsqrx8x_tail_done:
+ xor %rax,%rax
add 24+8(%rsp),%r8 # can this overflow?
adc \$0,%r9
adc \$0,%r10
@@ -3255,10 +3255,8 @@
adc \$0,%r12
adc \$0,%r13
adc \$0,%r14
- adc \$0,%r15 # can't overflow, because we
- # started with "overhung" part
- # of multiplication
- mov $carry,%rax # xor %rax,%rax
+ adc \$0,%r15
+ adc \$0,%rax
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
.Lsqrx8x_no_tail: # %cf is 0 if jumped here
@@ -3273,7 +3271,7 @@
adc 8*5($tptr),%r13
adc 8*6($tptr),%r14
adc 8*7($tptr),%r15
- adc %rax,%rax # top-most carry
+ adc \$0,%rax # top-most carry
mov 32+8(%rsp),%rbx # n0
mov 8*8($tptr,%rcx),%rdx # modulo-scheduled "%r8"
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index 8f93ad0..a152cdf 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -515,6 +515,54 @@
return true;
}
+static bool TestModSquare(FileTest *t, BN_CTX *ctx) {
+ bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
+ bssl::UniquePtr<BIGNUM> m = GetBIGNUM(t, "M");
+ bssl::UniquePtr<BIGNUM> mod_square = GetBIGNUM(t, "ModSquare");
+ if (!a || !m || !mod_square) {
+ return false;
+ }
+
+ bssl::UniquePtr<BIGNUM> a_copy(BN_new());
+ bssl::UniquePtr<BIGNUM> ret(BN_new());
+ if (!ret || !a_copy ||
+ !BN_mod_mul(ret.get(), a.get(), a.get(), m.get(), ctx) ||
+ !ExpectBIGNUMsEqual(t, "A * A (mod M)", mod_square.get(), ret.get()) ||
+ // Repeat the operation with |a_copy|.
+ !BN_copy(a_copy.get(), a.get()) ||
+ !BN_mod_mul(ret.get(), a.get(), a_copy.get(), m.get(), ctx) ||
+ !ExpectBIGNUMsEqual(t, "A * A_copy (mod M)", mod_square.get(),
+ ret.get())) {
+ return false;
+ }
+
+ if (BN_is_odd(m.get())) {
+ // Reduce |a| and test the Montgomery version.
+ bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
+ bssl::UniquePtr<BIGNUM> a_tmp(BN_new());
+ if (!mont || !a_tmp ||
+ !BN_MONT_CTX_set(mont.get(), m.get(), ctx) ||
+ !BN_nnmod(a_tmp.get(), a.get(), m.get(), ctx) ||
+ !BN_to_montgomery(a_tmp.get(), a_tmp.get(), mont.get(), ctx) ||
+ !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_tmp.get(), mont.get(),
+ ctx) ||
+ !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
+ !ExpectBIGNUMsEqual(t, "A * A (mod M) (Montgomery)",
+ mod_square.get(), ret.get()) ||
+ // Repeat the operation with |a_copy|.
+ !BN_copy(a_copy.get(), a_tmp.get()) ||
+ !BN_mod_mul_montgomery(ret.get(), a_tmp.get(), a_copy.get(), mont.get(),
+ ctx) ||
+ !BN_from_montgomery(ret.get(), ret.get(), mont.get(), ctx) ||
+ !ExpectBIGNUMsEqual(t, "A * A_copy (mod M) (Montgomery)",
+ mod_square.get(), ret.get())) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
static bool TestModExp(FileTest *t, BN_CTX *ctx) {
bssl::UniquePtr<BIGNUM> a = GetBIGNUM(t, "A");
bssl::UniquePtr<BIGNUM> e = GetBIGNUM(t, "E");
@@ -649,6 +697,7 @@
{"Product", TestProduct},
{"Quotient", TestQuotient},
{"ModMul", TestModMul},
+ {"ModSquare", TestModSquare},
{"ModExp", TestModExp},
{"Exp", TestExp},
{"ModSqrt", TestModSqrt},
diff --git a/src/crypto/bn/bn_tests.txt b/src/crypto/bn/bn_tests.txt
index 46c788f..c53eb23 100644
--- a/src/crypto/bn/bn_tests.txt
+++ b/src/crypto/bn/bn_tests.txt
@@ -9888,6 +9888,16 @@
M = d78af684e71db0c39cff4e64fb9db567132cb9c50cc98009feb820b26f2ded9b91b9b5e2b83ae0ae4eb4e0523ca726bfbe969b89fd754f674ce99118c3f2d1c5d81fdc7c54e02b60262b241d53c040e99e45826eca37a804668e690e1afc1ca42c9a15d84d4954425f0b7642fc0bd9d7b24e2618d2dcc9b729d944badacfddaf
+# ModSquare tests.
+#
+# These test vectors satisfy A * A = ModSquare (mod M) and 0 <= ModSquare < M.
+
+# Regression test for CVE-2017-3732.
+ModSquare = fffffffdfffffd01000009000002f6fffdf403000312000402f3fff5f602fe080a0005fdfafffa00010001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000002000002fefffff7fffffd07000109fdfffef3fffdfd06000405ff00fdfbfffe00010001
+A = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff00000000
+M = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff
+
+
# ModExp tests.
#
# These test vectors satisfy A ^ E = ModExp (mod M) and 0 <= ModExp < M.
diff --git a/src/crypto/cipher/asm/chacha20_poly1305_x86_64.pl b/src/crypto/cipher/asm/chacha20_poly1305_x86_64.pl
index c3f3e0b..44590c2 100644
--- a/src/crypto/cipher/asm/chacha20_poly1305_x86_64.pl
+++ b/src/crypto/cipher/asm/chacha20_poly1305_x86_64.pl
@@ -31,7 +31,7 @@
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-open OUT,"| \"$^X\" $xlate $flavour $output";
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
*STDOUT=*OUT;
$avx = 2;
@@ -138,7 +138,7 @@
mov %rdx, $t1
mov 0+$r_store, %rax
mul $acc1
- imul $acc2, $t2
+ imulq $acc2, $t2
add %rax, $t1
adc %rdx, $t2\n";
}
@@ -157,7 +157,7 @@
}
sub poly_stage3 {
-$code.="imul $acc2, $t3
+$code.="imulq $acc2, $t3
add $acc0, $t2
adc %rdx, $t3\n";
}
@@ -389,7 +389,7 @@
jb hash_ad_tail\n";
&poly_add("0($adp)");
&poly_mul(); $code.="
- lea (1*16)($adp), $adp
+ lea 1*16($adp), $adp
sub \$16, $itr2
jmp hash_ad_loop
hash_ad_tail:
@@ -453,7 +453,6 @@
.cfi_offset r13, -40
.cfi_offset r14, -48
.cfi_offset r15, -56
-.cfi_offset $keyp, -64
lea 32(%rsp), %rbp
and \$-32, %rbp
mov %rdx, 8+$len_store
@@ -852,7 +851,6 @@
.cfi_offset r13, -40
.cfi_offset r14, -48
.cfi_offset r15, -56
-.cfi_offset $keyp, -64
lea 32(%rsp), %rbp
and \$-32, %rbp
mov %rdx, 8+$len_store
@@ -1378,7 +1376,7 @@
mov %rdx, $t2
mulx $acc0, $t0, $t1
mulx $acc1, %rax, %rdx
- imul $acc2, $t2
+ imulq $acc2, $t2
add %rax, $t1
adc %rdx, $t2
___
@@ -1392,7 +1390,7 @@
mulx $acc1, $acc1, $t3
adc $acc1, $t2
adc \$0, $t3
- imul $acc2, %rdx
+ imulq $acc2, %rdx
___
}
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index 34d094b..c6e81ab 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -18,6 +18,7 @@
#include <openssl/chacha.h>
#include <openssl/cipher.h>
+#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/poly1305.h>
@@ -35,16 +36,21 @@
#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \
!defined(OPENSSL_WINDOWS)
-static const int kHaveAsm = 1;
+static int asm_capable(void) {
+ const int sse41_capable = (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0;
+ return sse41_capable;
+}
+
// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It
// decrypts |plaintext_len| bytes from |ciphertext| and writes them to
// |out_plaintext|. On entry, |aead_data| must contain the final 48 bytes of
// the initial ChaCha20 block, i.e. the key, followed by four zeros, followed
// by the nonce. On exit, it will contain the calculated tag value, which the
// caller must check.
-void chacha20_poly1305_open(uint8_t *out_plaintext, const uint8_t *ciphertext,
- size_t plaintext_len, const uint8_t *ad,
- size_t ad_len, uint8_t *aead_data);
+extern void chacha20_poly1305_open(uint8_t *out_plaintext,
+ const uint8_t *ciphertext,
+ size_t plaintext_len, const uint8_t *ad,
+ size_t ad_len, uint8_t *aead_data);
// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It
// encrypts |plaintext_len| bytes from |plaintext| and writes them to
@@ -52,11 +58,15 @@
// the initial ChaCha20 block, i.e. the key, followed by four zeros, followed
// by the nonce. On exit, it will contain the calculated tag value, which the
// caller must append to the ciphertext.
-void chacha20_poly1305_seal(uint8_t *out_ciphertext, const uint8_t *plaintext,
- size_t plaintext_len, const uint8_t *ad,
- size_t ad_len, uint8_t *aead_data);
+extern void chacha20_poly1305_seal(uint8_t *out_ciphertext,
+ const uint8_t *plaintext,
+ size_t plaintext_len, const uint8_t *ad,
+ size_t ad_len, uint8_t *aead_data);
#else
-static const int kHaveAsm = 0;
+static int asm_capable(void) {
+ return 0;
+}
+
static void chacha20_poly1305_open(uint8_t *out_plaintext,
const uint8_t *ciphertext,
@@ -181,7 +191,7 @@
alignas(16) uint8_t tag[48];
- if (kHaveAsm) {
+ if (asm_capable()) {
OPENSSL_memcpy(tag, c20_ctx->key, 32);
OPENSSL_memset(tag + 32, 0, 4);
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
@@ -229,7 +239,7 @@
plaintext_len = in_len - c20_ctx->tag_len;
alignas(16) uint8_t tag[48];
- if (kHaveAsm) {
+ if (asm_capable()) {
OPENSSL_memcpy(tag, c20_ctx->key, 32);
OPENSSL_memset(tag + 32, 0, 4);
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
diff --git a/src/crypto/curve25519/asm/x25519-asm-x86_64.S b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
index 531ac16..18041d0 100644
--- a/src/crypto/curve25519/asm/x25519-asm-x86_64.S
+++ b/src/crypto/curve25519/asm/x25519-asm-x86_64.S
@@ -60,17 +60,10 @@
.globl C_ABI(x25519_x86_64_freeze)
HIDDEN C_ABI(x25519_x86_64_freeze)
C_ABI(x25519_x86_64_freeze):
-mov %rsp,%r11
-and $31,%r11
-add $64,%r11
-sub %r11,%rsp
-movq %r11,0(%rsp)
-movq %r12,8(%rsp)
-movq %r13,16(%rsp)
-movq %r14,24(%rsp)
-movq %r15,32(%rsp)
-movq %rbx,40(%rsp)
-movq %rbp,48(%rsp)
+.cfi_startproc
+/* This is a leaf function and uses the redzone for saving registers. */
+movq %r12,-8(%rsp)
+.cfi_rel_offset r12, -8
movq 0(%rdi),%rsi
movq 8(%rdi),%rdx
movq 16(%rdi),%rcx
@@ -128,44 +121,38 @@
movq %rcx,16(%rdi)
movq %r8,24(%rdi)
movq %r9,32(%rdi)
-movq 0(%rsp),%r11
-movq 8(%rsp),%r12
-movq 16(%rsp),%r13
-movq 24(%rsp),%r14
-movq 32(%rsp),%r15
-movq 40(%rsp),%rbx
-movq 48(%rsp),%rbp
-add %r11,%rsp
-mov %rdi,%rax
-mov %rsi,%rdx
+movq -8(%rsp),%r12
ret
+.cfi_endproc
.p2align 5
.globl C_ABI(x25519_x86_64_mul)
HIDDEN C_ABI(x25519_x86_64_mul)
C_ABI(x25519_x86_64_mul):
-mov %rsp,%r11
-and $31,%r11
-add $96,%r11
-sub %r11,%rsp
-movq %r11,0(%rsp)
-movq %r12,8(%rsp)
-movq %r13,16(%rsp)
-movq %r14,24(%rsp)
-movq %r15,32(%rsp)
-movq %rbx,40(%rsp)
-movq %rbp,48(%rsp)
-movq %rdi,56(%rsp)
+.cfi_startproc
+/* This is a leaf function and uses the redzone for saving registers. */
+movq %r12,-8(%rsp)
+.cfi_rel_offset r12, -8
+movq %r13,-16(%rsp)
+.cfi_rel_offset r13, -16
+movq %r14,-24(%rsp)
+.cfi_rel_offset r14, -24
+movq %r15,-32(%rsp)
+.cfi_rel_offset r15, -32
+movq %rbx,-40(%rsp)
+.cfi_rel_offset rbx, -40
+movq %rbp,-48(%rsp)
+.cfi_rel_offset rbp, -48
mov %rdx,%rcx
movq 24(%rsi),%rdx
imulq $19,%rdx,%rax
-movq %rax,64(%rsp)
+movq %rax,-64(%rsp)
mulq 16(%rcx)
mov %rax,%r8
mov %rdx,%r9
movq 32(%rsi),%rdx
imulq $19,%rdx,%rax
-movq %rax,72(%rsp)
+movq %rax,-72(%rsp)
mulq 8(%rcx)
add %rax,%r8
adc %rdx,%r9
@@ -240,11 +227,11 @@
mulq 8(%rcx)
add %rax,%rbx
adc %rdx,%rbp
-movq 64(%rsp),%rax
+movq -64(%rsp),%rax
mulq 24(%rcx)
add %rax,%r10
adc %rdx,%r11
-movq 64(%rsp),%rax
+movq -64(%rsp),%rax
mulq 32(%rcx)
add %rax,%r12
adc %rdx,%r13
@@ -252,15 +239,15 @@
mulq 0(%rcx)
add %rax,%rbx
adc %rdx,%rbp
-movq 72(%rsp),%rax
+movq -72(%rsp),%rax
mulq 16(%rcx)
add %rax,%r10
adc %rdx,%r11
-movq 72(%rsp),%rax
+movq -72(%rsp),%rax
mulq 24(%rcx)
add %rax,%r12
adc %rdx,%r13
-movq 72(%rsp),%rax
+movq -72(%rsp),%rax
mulq 32(%rcx)
add %rax,%r14
adc %rdx,%r15
@@ -307,33 +294,31 @@
movq %r9,16(%rdi)
movq %rax,24(%rdi)
movq %r10,32(%rdi)
-movq 0(%rsp),%r11
-movq 8(%rsp),%r12
-movq 16(%rsp),%r13
-movq 24(%rsp),%r14
-movq 32(%rsp),%r15
-movq 40(%rsp),%rbx
-movq 48(%rsp),%rbp
-add %r11,%rsp
-mov %rdi,%rax
-mov %rsi,%rdx
+movq -8(%rsp),%r12
+movq -16(%rsp),%r13
+movq -24(%rsp),%r14
+movq -32(%rsp),%r15
+movq -40(%rsp),%rbx
+movq -48(%rsp),%rbp
ret
+.cfi_endproc
.p2align 5
.globl C_ABI(x25519_x86_64_square)
HIDDEN C_ABI(x25519_x86_64_square)
C_ABI(x25519_x86_64_square):
-mov %rsp,%r11
-and $31,%r11
-add $64,%r11
-sub %r11,%rsp
-movq %r11,0(%rsp)
-movq %r12,8(%rsp)
-movq %r13,16(%rsp)
-movq %r14,24(%rsp)
-movq %r15,32(%rsp)
-movq %rbx,40(%rsp)
-movq %rbp,48(%rsp)
+.cfi_startproc
+/* This is a leaf function and uses the redzone for saving registers. */
+movq %r12,-8(%rsp)
+.cfi_rel_offset r12, -8
+movq %r13,-16(%rsp)
+.cfi_rel_offset r13, -16
+movq %r14,-24(%rsp)
+.cfi_rel_offset r14, -24
+movq %r15,-32(%rsp)
+.cfi_rel_offset r15, -32
+movq %rbx,-40(%rsp)
+.cfi_rel_offset rbx, -40
movq 0(%rsi),%rax
mulq 0(%rsi)
mov %rax,%rcx
@@ -449,33 +434,33 @@
movq %r9,16(%rdi)
movq %rax,24(%rdi)
movq %r10,32(%rdi)
-movq 0(%rsp),%r11
-movq 8(%rsp),%r12
-movq 16(%rsp),%r13
-movq 24(%rsp),%r14
-movq 32(%rsp),%r15
-movq 40(%rsp),%rbx
-movq 48(%rsp),%rbp
-add %r11,%rsp
-mov %rdi,%rax
-mov %rsi,%rdx
+movq -8(%rsp),%r12
+movq -16(%rsp),%r13
+movq -24(%rsp),%r14
+movq -32(%rsp),%r15
+movq -40(%rsp),%rbx
ret
+.cfi_endproc
.p2align 5
.globl C_ABI(x25519_x86_64_ladderstep)
HIDDEN C_ABI(x25519_x86_64_ladderstep)
C_ABI(x25519_x86_64_ladderstep):
-mov %rsp,%r11
-and $31,%r11
-add $352,%r11
-sub %r11,%rsp
-movq %r11,0(%rsp)
-movq %r12,8(%rsp)
-movq %r13,16(%rsp)
-movq %r14,24(%rsp)
-movq %r15,32(%rsp)
-movq %rbx,40(%rsp)
-movq %rbp,48(%rsp)
+.cfi_startproc
+sub $344,%rsp
+.cfi_adjust_cfa_offset 344
+movq %r12,296(%rsp)
+.cfi_rel_offset r12, 296
+movq %r13,304(%rsp)
+.cfi_rel_offset r13, 304
+movq %r14,312(%rsp)
+.cfi_rel_offset r14, 312
+movq %r15,320(%rsp)
+.cfi_rel_offset r15, 320
+movq %rbx,328(%rsp)
+.cfi_rel_offset rbx, 328
+movq %rbp,336(%rsp)
+.cfi_rel_offset rbp, 336
movq 40(%rdi),%rsi
movq 48(%rdi),%rdx
movq 56(%rdi),%rcx
@@ -501,201 +486,86 @@
subq 96(%rdi),%r11
subq 104(%rdi),%r12
subq 112(%rdi),%r13
-movq %rsi,56(%rsp)
-movq %rdx,64(%rsp)
-movq %rcx,72(%rsp)
-movq %r8,80(%rsp)
-movq %r9,88(%rsp)
-movq %rax,96(%rsp)
-movq %r10,104(%rsp)
-movq %r11,112(%rsp)
-movq %r12,120(%rsp)
-movq %r13,128(%rsp)
-movq 96(%rsp),%rax
-mulq 96(%rsp)
+movq %rsi,0(%rsp)
+movq %rdx,8(%rsp)
+movq %rcx,16(%rsp)
+movq %r8,24(%rsp)
+movq %r9,32(%rsp)
+movq %rax,40(%rsp)
+movq %r10,48(%rsp)
+movq %r11,56(%rsp)
+movq %r12,64(%rsp)
+movq %r13,72(%rsp)
+movq 40(%rsp),%rax
+mulq 40(%rsp)
mov %rax,%rsi
mov %rdx,%rcx
-movq 96(%rsp),%rax
+movq 40(%rsp),%rax
shl $1,%rax
-mulq 104(%rsp)
+mulq 48(%rsp)
mov %rax,%r8
mov %rdx,%r9
-movq 96(%rsp),%rax
+movq 40(%rsp),%rax
shl $1,%rax
-mulq 112(%rsp)
+mulq 56(%rsp)
mov %rax,%r10
mov %rdx,%r11
-movq 96(%rsp),%rax
+movq 40(%rsp),%rax
shl $1,%rax
-mulq 120(%rsp)
+mulq 64(%rsp)
mov %rax,%r12
mov %rdx,%r13
-movq 96(%rsp),%rax
+movq 40(%rsp),%rax
shl $1,%rax
-mulq 128(%rsp)
+mulq 72(%rsp)
mov %rax,%r14
mov %rdx,%r15
-movq 104(%rsp),%rax
-mulq 104(%rsp)
+movq 48(%rsp),%rax
+mulq 48(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 104(%rsp),%rax
+movq 48(%rsp),%rax
shl $1,%rax
-mulq 112(%rsp)
+mulq 56(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 104(%rsp),%rax
+movq 48(%rsp),%rax
shl $1,%rax
-mulq 120(%rsp)
+mulq 64(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 104(%rsp),%rdx
+movq 48(%rsp),%rdx
imulq $38,%rdx,%rax
-mulq 128(%rsp)
+mulq 72(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 112(%rsp),%rax
-mulq 112(%rsp)
-add %rax,%r14
-adc %rdx,%r15
-movq 112(%rsp),%rdx
-imulq $38,%rdx,%rax
-mulq 120(%rsp)
-add %rax,%rsi
-adc %rdx,%rcx
-movq 112(%rsp),%rdx
-imulq $38,%rdx,%rax
-mulq 128(%rsp)
-add %rax,%r8
-adc %rdx,%r9
-movq 120(%rsp),%rdx
-imulq $19,%rdx,%rax
-mulq 120(%rsp)
-add %rax,%r8
-adc %rdx,%r9
-movq 120(%rsp),%rdx
-imulq $38,%rdx,%rax
-mulq 128(%rsp)
-add %rax,%r10
-adc %rdx,%r11
-movq 128(%rsp),%rdx
-imulq $19,%rdx,%rax
-mulq 128(%rsp)
-add %rax,%r12
-adc %rdx,%r13
-movq x25519_x86_64_REDMASK51(%rip),%rdx
-shld $13,%rsi,%rcx
-and %rdx,%rsi
-shld $13,%r8,%r9
-and %rdx,%r8
-add %rcx,%r8
-shld $13,%r10,%r11
-and %rdx,%r10
-add %r9,%r10
-shld $13,%r12,%r13
-and %rdx,%r12
-add %r11,%r12
-shld $13,%r14,%r15
-and %rdx,%r14
-add %r13,%r14
-imulq $19,%r15,%rcx
-add %rcx,%rsi
-mov %rsi,%rcx
-shr $51,%rcx
-add %r8,%rcx
-and %rdx,%rsi
-mov %rcx,%r8
-shr $51,%rcx
-add %r10,%rcx
-and %rdx,%r8
-mov %rcx,%r9
-shr $51,%rcx
-add %r12,%rcx
-and %rdx,%r9
-mov %rcx,%rax
-shr $51,%rcx
-add %r14,%rcx
-and %rdx,%rax
-mov %rcx,%r10
-shr $51,%rcx
-imulq $19,%rcx,%rcx
-add %rcx,%rsi
-and %rdx,%r10
-movq %rsi,136(%rsp)
-movq %r8,144(%rsp)
-movq %r9,152(%rsp)
-movq %rax,160(%rsp)
-movq %r10,168(%rsp)
movq 56(%rsp),%rax
mulq 56(%rsp)
-mov %rax,%rsi
-mov %rdx,%rcx
-movq 56(%rsp),%rax
-shl $1,%rax
-mulq 64(%rsp)
-mov %rax,%r8
-mov %rdx,%r9
-movq 56(%rsp),%rax
-shl $1,%rax
-mulq 72(%rsp)
-mov %rax,%r10
-mov %rdx,%r11
-movq 56(%rsp),%rax
-shl $1,%rax
-mulq 80(%rsp)
-mov %rax,%r12
-mov %rdx,%r13
-movq 56(%rsp),%rax
-shl $1,%rax
-mulq 88(%rsp)
-mov %rax,%r14
-mov %rdx,%r15
-movq 64(%rsp),%rax
-mulq 64(%rsp)
-add %rax,%r10
-adc %rdx,%r11
-movq 64(%rsp),%rax
-shl $1,%rax
-mulq 72(%rsp)
-add %rax,%r12
-adc %rdx,%r13
-movq 64(%rsp),%rax
-shl $1,%rax
-mulq 80(%rsp)
add %rax,%r14
adc %rdx,%r15
+movq 56(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 64(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 56(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 72(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 64(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 64(%rsp)
+add %rax,%r8
+adc %rdx,%r9
movq 64(%rsp),%rdx
imulq $38,%rdx,%rax
-mulq 88(%rsp)
-add %rax,%rsi
-adc %rdx,%rcx
-movq 72(%rsp),%rax
mulq 72(%rsp)
-add %rax,%r14
-adc %rdx,%r15
-movq 72(%rsp),%rdx
-imulq $38,%rdx,%rax
-mulq 80(%rsp)
-add %rax,%rsi
-adc %rdx,%rcx
-movq 72(%rsp),%rdx
-imulq $38,%rdx,%rax
-mulq 88(%rsp)
-add %rax,%r8
-adc %rdx,%r9
-movq 80(%rsp),%rdx
-imulq $19,%rdx,%rax
-mulq 80(%rsp)
-add %rax,%r8
-adc %rdx,%r9
-movq 80(%rsp),%rdx
-imulq $38,%rdx,%rax
-mulq 88(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 88(%rsp),%rdx
+movq 72(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 88(%rsp)
+mulq 72(%rsp)
add %rax,%r12
adc %rdx,%r13
movq x25519_x86_64_REDMASK51(%rip),%rdx
@@ -736,11 +606,126 @@
imulq $19,%rcx,%rcx
add %rcx,%rsi
and %rdx,%r10
-movq %rsi,176(%rsp)
-movq %r8,184(%rsp)
-movq %r9,192(%rsp)
-movq %rax,200(%rsp)
-movq %r10,208(%rsp)
+movq %rsi,80(%rsp)
+movq %r8,88(%rsp)
+movq %r9,96(%rsp)
+movq %rax,104(%rsp)
+movq %r10,112(%rsp)
+movq 0(%rsp),%rax
+mulq 0(%rsp)
+mov %rax,%rsi
+mov %rdx,%rcx
+movq 0(%rsp),%rax
+shl $1,%rax
+mulq 8(%rsp)
+mov %rax,%r8
+mov %rdx,%r9
+movq 0(%rsp),%rax
+shl $1,%rax
+mulq 16(%rsp)
+mov %rax,%r10
+mov %rdx,%r11
+movq 0(%rsp),%rax
+shl $1,%rax
+mulq 24(%rsp)
+mov %rax,%r12
+mov %rdx,%r13
+movq 0(%rsp),%rax
+shl $1,%rax
+mulq 32(%rsp)
+mov %rax,%r14
+mov %rdx,%r15
+movq 8(%rsp),%rax
+mulq 8(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 8(%rsp),%rax
+shl $1,%rax
+mulq 16(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 8(%rsp),%rax
+shl $1,%rax
+mulq 24(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 8(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 32(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 16(%rsp),%rax
+mulq 16(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 16(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 24(%rsp)
+add %rax,%rsi
+adc %rdx,%rcx
+movq 16(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 32(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 24(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 24(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 24(%rsp),%rdx
+imulq $38,%rdx,%rax
+mulq 32(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 32(%rsp),%rdx
+imulq $19,%rdx,%rax
+mulq 32(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq x25519_x86_64_REDMASK51(%rip),%rdx
+shld $13,%rsi,%rcx
+and %rdx,%rsi
+shld $13,%r8,%r9
+and %rdx,%r8
+add %rcx,%r8
+shld $13,%r10,%r11
+and %rdx,%r10
+add %r9,%r10
+shld $13,%r12,%r13
+and %rdx,%r12
+add %r11,%r12
+shld $13,%r14,%r15
+and %rdx,%r14
+add %r13,%r14
+imulq $19,%r15,%rcx
+add %rcx,%rsi
+mov %rsi,%rcx
+shr $51,%rcx
+add %r8,%rcx
+and %rdx,%rsi
+mov %rcx,%r8
+shr $51,%rcx
+add %r10,%rcx
+and %rdx,%r8
+mov %rcx,%r9
+shr $51,%rcx
+add %r12,%rcx
+and %rdx,%r9
+mov %rcx,%rax
+shr $51,%rcx
+add %r14,%rcx
+and %rdx,%rax
+mov %rcx,%r10
+shr $51,%rcx
+imulq $19,%rcx,%rcx
+add %rcx,%rsi
+and %rdx,%r10
+movq %rsi,120(%rsp)
+movq %r8,128(%rsp)
+movq %r9,136(%rsp)
+movq %rax,144(%rsp)
+movq %r10,152(%rsp)
mov %rsi,%rsi
mov %r8,%rdx
mov %r9,%rcx
@@ -751,16 +736,16 @@
add x25519_x86_64_2P1234(%rip),%rcx
add x25519_x86_64_2P1234(%rip),%r8
add x25519_x86_64_2P1234(%rip),%r9
-subq 136(%rsp),%rsi
-subq 144(%rsp),%rdx
-subq 152(%rsp),%rcx
-subq 160(%rsp),%r8
-subq 168(%rsp),%r9
-movq %rsi,216(%rsp)
-movq %rdx,224(%rsp)
-movq %rcx,232(%rsp)
-movq %r8,240(%rsp)
-movq %r9,248(%rsp)
+subq 80(%rsp),%rsi
+subq 88(%rsp),%rdx
+subq 96(%rsp),%rcx
+subq 104(%rsp),%r8
+subq 112(%rsp),%r9
+movq %rsi,160(%rsp)
+movq %rdx,168(%rsp)
+movq %rcx,176(%rsp)
+movq %r8,184(%rsp)
+movq %r9,192(%rsp)
movq 120(%rdi),%rsi
movq 128(%rdi),%rdx
movq 136(%rdi),%rcx
@@ -786,121 +771,121 @@
subq 176(%rdi),%r11
subq 184(%rdi),%r12
subq 192(%rdi),%r13
-movq %rsi,256(%rsp)
-movq %rdx,264(%rsp)
-movq %rcx,272(%rsp)
-movq %r8,280(%rsp)
-movq %r9,288(%rsp)
-movq %rax,296(%rsp)
-movq %r10,304(%rsp)
-movq %r11,312(%rsp)
-movq %r12,320(%rsp)
-movq %r13,328(%rsp)
-movq 280(%rsp),%rsi
+movq %rsi,200(%rsp)
+movq %rdx,208(%rsp)
+movq %rcx,216(%rsp)
+movq %r8,224(%rsp)
+movq %r9,232(%rsp)
+movq %rax,240(%rsp)
+movq %r10,248(%rsp)
+movq %r11,256(%rsp)
+movq %r12,264(%rsp)
+movq %r13,272(%rsp)
+movq 224(%rsp),%rsi
imulq $19,%rsi,%rax
-movq %rax,336(%rsp)
-mulq 112(%rsp)
+movq %rax,280(%rsp)
+mulq 56(%rsp)
mov %rax,%rsi
mov %rdx,%rcx
-movq 288(%rsp),%rdx
+movq 232(%rsp),%rdx
imulq $19,%rdx,%rax
-movq %rax,344(%rsp)
-mulq 104(%rsp)
+movq %rax,288(%rsp)
+mulq 48(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 256(%rsp),%rax
-mulq 96(%rsp)
+movq 200(%rsp),%rax
+mulq 40(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 256(%rsp),%rax
-mulq 104(%rsp)
+movq 200(%rsp),%rax
+mulq 48(%rsp)
mov %rax,%r8
mov %rdx,%r9
-movq 256(%rsp),%rax
-mulq 112(%rsp)
+movq 200(%rsp),%rax
+mulq 56(%rsp)
mov %rax,%r10
mov %rdx,%r11
-movq 256(%rsp),%rax
-mulq 120(%rsp)
+movq 200(%rsp),%rax
+mulq 64(%rsp)
mov %rax,%r12
mov %rdx,%r13
-movq 256(%rsp),%rax
-mulq 128(%rsp)
+movq 200(%rsp),%rax
+mulq 72(%rsp)
mov %rax,%r14
mov %rdx,%r15
-movq 264(%rsp),%rax
-mulq 96(%rsp)
+movq 208(%rsp),%rax
+mulq 40(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 264(%rsp),%rax
-mulq 104(%rsp)
+movq 208(%rsp),%rax
+mulq 48(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 264(%rsp),%rax
-mulq 112(%rsp)
+movq 208(%rsp),%rax
+mulq 56(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 264(%rsp),%rax
-mulq 120(%rsp)
+movq 208(%rsp),%rax
+mulq 64(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 264(%rsp),%rdx
+movq 208(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 128(%rsp)
+mulq 72(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 272(%rsp),%rax
-mulq 96(%rsp)
+movq 216(%rsp),%rax
+mulq 40(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 272(%rsp),%rax
-mulq 104(%rsp)
+movq 216(%rsp),%rax
+mulq 48(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 272(%rsp),%rax
-mulq 112(%rsp)
+movq 216(%rsp),%rax
+mulq 56(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 272(%rsp),%rdx
+movq 216(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 120(%rsp)
+mulq 64(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 272(%rsp),%rdx
+movq 216(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 128(%rsp)
+mulq 72(%rsp)
+add %rax,%r8
+adc %rdx,%r9
+movq 224(%rsp),%rax
+mulq 40(%rsp)
+add %rax,%r12
+adc %rdx,%r13
+movq 224(%rsp),%rax
+mulq 48(%rsp)
+add %rax,%r14
+adc %rdx,%r15
+movq 280(%rsp),%rax
+mulq 64(%rsp)
add %rax,%r8
adc %rdx,%r9
movq 280(%rsp),%rax
-mulq 96(%rsp)
-add %rax,%r12
-adc %rdx,%r13
-movq 280(%rsp),%rax
-mulq 104(%rsp)
+mulq 72(%rsp)
+add %rax,%r10
+adc %rdx,%r11
+movq 232(%rsp),%rax
+mulq 40(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 336(%rsp),%rax
-mulq 120(%rsp)
+movq 288(%rsp),%rax
+mulq 56(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 336(%rsp),%rax
-mulq 128(%rsp)
+movq 288(%rsp),%rax
+mulq 64(%rsp)
add %rax,%r10
adc %rdx,%r11
movq 288(%rsp),%rax
-mulq 96(%rsp)
-add %rax,%r14
-adc %rdx,%r15
-movq 344(%rsp),%rax
-mulq 112(%rsp)
-add %rax,%r8
-adc %rdx,%r9
-movq 344(%rsp),%rax
-mulq 120(%rsp)
-add %rax,%r10
-adc %rdx,%r11
-movq 344(%rsp),%rax
-mulq 128(%rsp)
+mulq 72(%rsp)
add %rax,%r12
adc %rdx,%r13
movq x25519_x86_64_REDMASK51(%rip),%rdx
@@ -941,116 +926,116 @@
imulq $19,%rcx,%rcx
add %rcx,%rsi
and %rdx,%r10
-movq %rsi,96(%rsp)
-movq %r8,104(%rsp)
-movq %r9,112(%rsp)
-movq %rax,120(%rsp)
-movq %r10,128(%rsp)
-movq 320(%rsp),%rsi
+movq %rsi,40(%rsp)
+movq %r8,48(%rsp)
+movq %r9,56(%rsp)
+movq %rax,64(%rsp)
+movq %r10,72(%rsp)
+movq 264(%rsp),%rsi
imulq $19,%rsi,%rax
-movq %rax,256(%rsp)
-mulq 72(%rsp)
+movq %rax,200(%rsp)
+mulq 16(%rsp)
mov %rax,%rsi
mov %rdx,%rcx
-movq 328(%rsp),%rdx
+movq 272(%rsp),%rdx
imulq $19,%rdx,%rax
-movq %rax,264(%rsp)
-mulq 64(%rsp)
+movq %rax,208(%rsp)
+mulq 8(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 296(%rsp),%rax
-mulq 56(%rsp)
+movq 240(%rsp),%rax
+mulq 0(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 296(%rsp),%rax
-mulq 64(%rsp)
+movq 240(%rsp),%rax
+mulq 8(%rsp)
mov %rax,%r8
mov %rdx,%r9
-movq 296(%rsp),%rax
-mulq 72(%rsp)
+movq 240(%rsp),%rax
+mulq 16(%rsp)
mov %rax,%r10
mov %rdx,%r11
-movq 296(%rsp),%rax
-mulq 80(%rsp)
+movq 240(%rsp),%rax
+mulq 24(%rsp)
mov %rax,%r12
mov %rdx,%r13
-movq 296(%rsp),%rax
-mulq 88(%rsp)
+movq 240(%rsp),%rax
+mulq 32(%rsp)
mov %rax,%r14
mov %rdx,%r15
-movq 304(%rsp),%rax
-mulq 56(%rsp)
+movq 248(%rsp),%rax
+mulq 0(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 304(%rsp),%rax
-mulq 64(%rsp)
+movq 248(%rsp),%rax
+mulq 8(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 304(%rsp),%rax
-mulq 72(%rsp)
+movq 248(%rsp),%rax
+mulq 16(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 304(%rsp),%rax
-mulq 80(%rsp)
+movq 248(%rsp),%rax
+mulq 24(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 304(%rsp),%rdx
+movq 248(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 88(%rsp)
+mulq 32(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 312(%rsp),%rax
-mulq 56(%rsp)
+movq 256(%rsp),%rax
+mulq 0(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 312(%rsp),%rax
-mulq 64(%rsp)
+movq 256(%rsp),%rax
+mulq 8(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 312(%rsp),%rax
-mulq 72(%rsp)
+movq 256(%rsp),%rax
+mulq 16(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 312(%rsp),%rdx
+movq 256(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 80(%rsp)
+mulq 24(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 312(%rsp),%rdx
+movq 256(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 88(%rsp)
+mulq 32(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 320(%rsp),%rax
-mulq 56(%rsp)
+movq 264(%rsp),%rax
+mulq 0(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 320(%rsp),%rax
-mulq 64(%rsp)
+movq 264(%rsp),%rax
+mulq 8(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 256(%rsp),%rax
-mulq 80(%rsp)
+movq 200(%rsp),%rax
+mulq 24(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 256(%rsp),%rax
-mulq 88(%rsp)
+movq 200(%rsp),%rax
+mulq 32(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 328(%rsp),%rax
-mulq 56(%rsp)
+movq 272(%rsp),%rax
+mulq 0(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 264(%rsp),%rax
-mulq 72(%rsp)
+movq 208(%rsp),%rax
+mulq 16(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 264(%rsp),%rax
-mulq 80(%rsp)
+movq 208(%rsp),%rax
+mulq 24(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 264(%rsp),%rax
-mulq 88(%rsp)
+movq 208(%rsp),%rax
+mulq 32(%rsp)
add %rax,%r12
adc %rdx,%r13
movq x25519_x86_64_REDMASK51(%rip),%rdx
@@ -1101,16 +1086,16 @@
add x25519_x86_64_2P1234(%rip),%r11
add x25519_x86_64_2P1234(%rip),%r12
add x25519_x86_64_2P1234(%rip),%r13
-addq 96(%rsp),%rsi
-addq 104(%rsp),%r8
-addq 112(%rsp),%r9
-addq 120(%rsp),%rax
-addq 128(%rsp),%r10
-subq 96(%rsp),%rdx
-subq 104(%rsp),%rcx
-subq 112(%rsp),%r11
-subq 120(%rsp),%r12
-subq 128(%rsp),%r13
+addq 40(%rsp),%rsi
+addq 48(%rsp),%r8
+addq 56(%rsp),%r9
+addq 64(%rsp),%rax
+addq 72(%rsp),%r10
+subq 40(%rsp),%rdx
+subq 48(%rsp),%rcx
+subq 56(%rsp),%r11
+subq 64(%rsp),%r12
+subq 72(%rsp),%r13
movq %rsi,120(%rdi)
movq %r8,128(%rdi)
movq %r9,136(%rdi)
@@ -1353,13 +1338,13 @@
movq %r10,192(%rdi)
movq 184(%rdi),%rsi
imulq $19,%rsi,%rax
-movq %rax,56(%rsp)
+movq %rax,0(%rsp)
mulq 16(%rdi)
mov %rax,%rsi
mov %rdx,%rcx
movq 192(%rdi),%rdx
imulq $19,%rdx,%rax
-movq %rax,64(%rsp)
+movq %rax,8(%rsp)
mulq 8(%rdi)
add %rax,%rsi
adc %rdx,%rcx
@@ -1434,11 +1419,11 @@
mulq 8(%rdi)
add %rax,%r14
adc %rdx,%r15
-movq 56(%rsp),%rax
+movq 0(%rsp),%rax
mulq 24(%rdi)
add %rax,%r8
adc %rdx,%r9
-movq 56(%rsp),%rax
+movq 0(%rsp),%rax
mulq 32(%rdi)
add %rax,%r10
adc %rdx,%r11
@@ -1446,15 +1431,15 @@
mulq 0(%rdi)
add %rax,%r14
adc %rdx,%r15
-movq 64(%rsp),%rax
+movq 8(%rsp),%rax
mulq 16(%rdi)
add %rax,%r8
adc %rdx,%r9
-movq 64(%rsp),%rax
+movq 8(%rsp),%rax
mulq 24(%rdi)
add %rax,%r10
adc %rdx,%r11
-movq 64(%rsp),%rax
+movq 8(%rsp),%rax
mulq 32(%rdi)
add %rax,%r12
adc %rdx,%r13
@@ -1501,111 +1486,111 @@
movq %r9,176(%rdi)
movq %rax,184(%rdi)
movq %r10,192(%rdi)
-movq 200(%rsp),%rsi
+movq 144(%rsp),%rsi
imulq $19,%rsi,%rax
-movq %rax,56(%rsp)
-mulq 152(%rsp)
+movq %rax,0(%rsp)
+mulq 96(%rsp)
mov %rax,%rsi
mov %rdx,%rcx
-movq 208(%rsp),%rdx
+movq 152(%rsp),%rdx
imulq $19,%rdx,%rax
-movq %rax,64(%rsp)
-mulq 144(%rsp)
+movq %rax,8(%rsp)
+mulq 88(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 176(%rsp),%rax
-mulq 136(%rsp)
+movq 120(%rsp),%rax
+mulq 80(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 176(%rsp),%rax
-mulq 144(%rsp)
+movq 120(%rsp),%rax
+mulq 88(%rsp)
mov %rax,%r8
mov %rdx,%r9
-movq 176(%rsp),%rax
-mulq 152(%rsp)
+movq 120(%rsp),%rax
+mulq 96(%rsp)
mov %rax,%r10
mov %rdx,%r11
-movq 176(%rsp),%rax
-mulq 160(%rsp)
+movq 120(%rsp),%rax
+mulq 104(%rsp)
mov %rax,%r12
mov %rdx,%r13
-movq 176(%rsp),%rax
-mulq 168(%rsp)
+movq 120(%rsp),%rax
+mulq 112(%rsp)
mov %rax,%r14
mov %rdx,%r15
-movq 184(%rsp),%rax
-mulq 136(%rsp)
+movq 128(%rsp),%rax
+mulq 80(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 184(%rsp),%rax
-mulq 144(%rsp)
+movq 128(%rsp),%rax
+mulq 88(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 184(%rsp),%rax
-mulq 152(%rsp)
+movq 128(%rsp),%rax
+mulq 96(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 184(%rsp),%rax
-mulq 160(%rsp)
+movq 128(%rsp),%rax
+mulq 104(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 184(%rsp),%rdx
+movq 128(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 168(%rsp)
+mulq 112(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 192(%rsp),%rax
-mulq 136(%rsp)
+movq 136(%rsp),%rax
+mulq 80(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 192(%rsp),%rax
-mulq 144(%rsp)
+movq 136(%rsp),%rax
+mulq 88(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 192(%rsp),%rax
-mulq 152(%rsp)
+movq 136(%rsp),%rax
+mulq 96(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 192(%rsp),%rdx
+movq 136(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 160(%rsp)
+mulq 104(%rsp)
add %rax,%rsi
adc %rdx,%rcx
-movq 192(%rsp),%rdx
+movq 136(%rsp),%rdx
imulq $19,%rdx,%rax
-mulq 168(%rsp)
+mulq 112(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 200(%rsp),%rax
-mulq 136(%rsp)
+movq 144(%rsp),%rax
+mulq 80(%rsp)
add %rax,%r12
adc %rdx,%r13
-movq 200(%rsp),%rax
-mulq 144(%rsp)
+movq 144(%rsp),%rax
+mulq 88(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 56(%rsp),%rax
-mulq 160(%rsp)
+movq 0(%rsp),%rax
+mulq 104(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 56(%rsp),%rax
-mulq 168(%rsp)
+movq 0(%rsp),%rax
+mulq 112(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 208(%rsp),%rax
-mulq 136(%rsp)
+movq 152(%rsp),%rax
+mulq 80(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 64(%rsp),%rax
-mulq 152(%rsp)
+movq 8(%rsp),%rax
+mulq 96(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 64(%rsp),%rax
-mulq 160(%rsp)
+movq 8(%rsp),%rax
+mulq 104(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 64(%rsp),%rax
-mulq 168(%rsp)
+movq 8(%rsp),%rax
+mulq 112(%rsp)
add %rax,%r12
adc %rdx,%r13
movq x25519_x86_64_REDMASK51(%rip),%rdx
@@ -1651,37 +1636,37 @@
movq %r9,56(%rdi)
movq %rax,64(%rdi)
movq %r10,72(%rdi)
-movq 216(%rsp),%rax
+movq 160(%rsp),%rax
mulq x25519_x86_64_121666_213(%rip)
shr $13,%rax
mov %rax,%rsi
mov %rdx,%rcx
-movq 224(%rsp),%rax
+movq 168(%rsp),%rax
mulq x25519_x86_64_121666_213(%rip)
shr $13,%rax
add %rax,%rcx
mov %rdx,%r8
-movq 232(%rsp),%rax
+movq 176(%rsp),%rax
mulq x25519_x86_64_121666_213(%rip)
shr $13,%rax
add %rax,%r8
mov %rdx,%r9
-movq 240(%rsp),%rax
+movq 184(%rsp),%rax
mulq x25519_x86_64_121666_213(%rip)
shr $13,%rax
add %rax,%r9
mov %rdx,%r10
-movq 248(%rsp),%rax
+movq 192(%rsp),%rax
mulq x25519_x86_64_121666_213(%rip)
shr $13,%rax
add %rax,%r10
imulq $19,%rdx,%rdx
add %rdx,%rsi
-addq 136(%rsp),%rsi
-addq 144(%rsp),%rcx
-addq 152(%rsp),%r8
-addq 160(%rsp),%r9
-addq 168(%rsp),%r10
+addq 80(%rsp),%rsi
+addq 88(%rsp),%rcx
+addq 96(%rsp),%r8
+addq 104(%rsp),%r9
+addq 112(%rsp),%r10
movq %rsi,80(%rdi)
movq %rcx,88(%rdi)
movq %r8,96(%rdi)
@@ -1689,109 +1674,109 @@
movq %r10,112(%rdi)
movq 104(%rdi),%rsi
imulq $19,%rsi,%rax
-movq %rax,56(%rsp)
-mulq 232(%rsp)
+movq %rax,0(%rsp)
+mulq 176(%rsp)
mov %rax,%rsi
mov %rdx,%rcx
movq 112(%rdi),%rdx
imulq $19,%rdx,%rax
-movq %rax,64(%rsp)
-mulq 224(%rsp)
+movq %rax,8(%rsp)
+mulq 168(%rsp)
add %rax,%rsi
adc %rdx,%rcx
movq 80(%rdi),%rax
-mulq 216(%rsp)
+mulq 160(%rsp)
add %rax,%rsi
adc %rdx,%rcx
movq 80(%rdi),%rax
-mulq 224(%rsp)
+mulq 168(%rsp)
mov %rax,%r8
mov %rdx,%r9
movq 80(%rdi),%rax
-mulq 232(%rsp)
+mulq 176(%rsp)
mov %rax,%r10
mov %rdx,%r11
movq 80(%rdi),%rax
-mulq 240(%rsp)
+mulq 184(%rsp)
mov %rax,%r12
mov %rdx,%r13
movq 80(%rdi),%rax
-mulq 248(%rsp)
+mulq 192(%rsp)
mov %rax,%r14
mov %rdx,%r15
movq 88(%rdi),%rax
-mulq 216(%rsp)
+mulq 160(%rsp)
add %rax,%r8
adc %rdx,%r9
movq 88(%rdi),%rax
-mulq 224(%rsp)
+mulq 168(%rsp)
add %rax,%r10
adc %rdx,%r11
movq 88(%rdi),%rax
-mulq 232(%rsp)
+mulq 176(%rsp)
add %rax,%r12
adc %rdx,%r13
movq 88(%rdi),%rax
-mulq 240(%rsp)
+mulq 184(%rsp)
add %rax,%r14
adc %rdx,%r15
movq 88(%rdi),%rdx
imulq $19,%rdx,%rax
-mulq 248(%rsp)
+mulq 192(%rsp)
add %rax,%rsi
adc %rdx,%rcx
movq 96(%rdi),%rax
-mulq 216(%rsp)
+mulq 160(%rsp)
add %rax,%r10
adc %rdx,%r11
movq 96(%rdi),%rax
-mulq 224(%rsp)
+mulq 168(%rsp)
add %rax,%r12
adc %rdx,%r13
movq 96(%rdi),%rax
-mulq 232(%rsp)
+mulq 176(%rsp)
add %rax,%r14
adc %rdx,%r15
movq 96(%rdi),%rdx
imulq $19,%rdx,%rax
-mulq 240(%rsp)
+mulq 184(%rsp)
add %rax,%rsi
adc %rdx,%rcx
movq 96(%rdi),%rdx
imulq $19,%rdx,%rax
-mulq 248(%rsp)
+mulq 192(%rsp)
add %rax,%r8
adc %rdx,%r9
movq 104(%rdi),%rax
-mulq 216(%rsp)
+mulq 160(%rsp)
add %rax,%r12
adc %rdx,%r13
movq 104(%rdi),%rax
-mulq 224(%rsp)
+mulq 168(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 56(%rsp),%rax
-mulq 240(%rsp)
+movq 0(%rsp),%rax
+mulq 184(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 56(%rsp),%rax
-mulq 248(%rsp)
+movq 0(%rsp),%rax
+mulq 192(%rsp)
add %rax,%r10
adc %rdx,%r11
movq 112(%rdi),%rax
-mulq 216(%rsp)
+mulq 160(%rsp)
add %rax,%r14
adc %rdx,%r15
-movq 64(%rsp),%rax
-mulq 232(%rsp)
+movq 8(%rsp),%rax
+mulq 176(%rsp)
add %rax,%r8
adc %rdx,%r9
-movq 64(%rsp),%rax
-mulq 240(%rsp)
+movq 8(%rsp),%rax
+mulq 184(%rsp)
add %rax,%r10
adc %rdx,%r11
-movq 64(%rsp),%rax
-mulq 248(%rsp)
+movq 8(%rsp),%rax
+mulq 192(%rsp)
add %rax,%r12
adc %rdx,%r13
movq x25519_x86_64_REDMASK51(%rip),%rdx
@@ -1837,26 +1822,22 @@
movq %r9,96(%rdi)
movq %rax,104(%rdi)
movq %r10,112(%rdi)
-movq 0(%rsp),%r11
-movq 8(%rsp),%r12
-movq 16(%rsp),%r13
-movq 24(%rsp),%r14
-movq 32(%rsp),%r15
-movq 40(%rsp),%rbx
-movq 48(%rsp),%rbp
-add %r11,%rsp
-mov %rdi,%rax
-mov %rsi,%rdx
+movq 296(%rsp),%r12
+movq 304(%rsp),%r13
+movq 312(%rsp),%r14
+movq 320(%rsp),%r15
+movq 328(%rsp),%rbx
+movq 336(%rsp),%rbp
+add $344,%rsp
+.cfi_adjust_cfa_offset -344
ret
+.cfi_endproc
.p2align 5
.globl C_ABI(x25519_x86_64_work_cswap)
HIDDEN C_ABI(x25519_x86_64_work_cswap)
C_ABI(x25519_x86_64_work_cswap):
-mov %rsp,%r11
-and $31,%r11
-add $0,%r11
-sub %r11,%rsp
+.cfi_startproc
cmp $1,%rsi
movq 0(%rdi),%rsi
movq 80(%rdi),%rdx
@@ -1928,10 +1909,10 @@
movq %rdx,144(%rdi)
movq %rcx,72(%rdi)
movq %r8,152(%rdi)
-add %r11,%rsp
mov %rdi,%rax
mov %rsi,%rdx
ret
+.cfi_endproc
#endif /* __x86_64__ */
#endif /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index 8cf23bb..905aae9 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -201,6 +201,7 @@
return 0;
}
if (keytype != -1 && ctx->pmeth->pkey_id != keytype) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c
index 3ccd940..23bdcf4 100644
--- a/src/crypto/rand/urandom.c
+++ b/src/crypto/rand/urandom.c
@@ -12,7 +12,9 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE /* needed for syscall() on Linux. */
+#endif
#include <openssl/rand.h>
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index d3cd5b0..15118d2 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -56,6 +56,7 @@
* [including the GNU Public Licence.] */
#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <openssl/asn1t.h>
@@ -151,6 +152,11 @@
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) {
+ if (CRYPTO_BUFFER_len(buf) > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+
X509 *x509 = X509_new();
if (x509 == NULL) {
return NULL;
diff --git a/src/decrepit/CMakeLists.txt b/src/decrepit/CMakeLists.txt
index ee49bc8..223320d 100644
--- a/src/decrepit/CMakeLists.txt
+++ b/src/decrepit/CMakeLists.txt
@@ -1,7 +1,6 @@
include_directories(../include)
add_subdirectory(bio)
-add_subdirectory(biossl)
add_subdirectory(blowfish)
add_subdirectory(cast)
add_subdirectory(des)
@@ -20,7 +19,6 @@
decrepit
$<TARGET_OBJECTS:bio_decrepit>
- $<TARGET_OBJECTS:biossl_decrepit>
$<TARGET_OBJECTS:blowfish>
$<TARGET_OBJECTS:cast>
$<TARGET_OBJECTS:des_decrepit>
diff --git a/src/decrepit/bio/base64_bio.c b/src/decrepit/bio/base64_bio.c
index 85f30ff..eef4e1a 100644
--- a/src/decrepit/bio/base64_bio.c
+++ b/src/decrepit/bio/base64_bio.c
@@ -526,12 +526,8 @@
return ret;
}
-static int b64_puts(BIO *b, const char *str) {
- return b64_write(b, str, strlen(str));
-}
-
static const BIO_METHOD b64_method = {
- BIO_TYPE_BASE64, "base64 encoding", b64_write, b64_read, b64_puts,
+ BIO_TYPE_BASE64, "base64 encoding", b64_write, b64_read, NULL /* puts */,
NULL /* gets */, b64_ctrl, b64_new, b64_free, b64_callback_ctrl,
};
diff --git a/src/decrepit/biossl/CMakeLists.txt b/src/decrepit/biossl/CMakeLists.txt
deleted file mode 100644
index 39fe139..0000000
--- a/src/decrepit/biossl/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-include_directories(../../include)
-
-add_library(
- biossl_decrepit
-
- OBJECT
-
- bio_ssl.c
-)
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index 110629e..6ba1421 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -493,23 +493,6 @@
OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename);
-/* Buffer BIOs.
- *
- * Buffer BIOs are a filter-type BIO, i.e. they are designed to be used in a
- * chain of BIOs. They provide buffering to reduce the number of operations on
- * the underlying BIOs. */
-
-OPENSSL_EXPORT const BIO_METHOD *BIO_f_buffer(void);
-
-/* BIO_set_read_buffer_size sets the size, in bytes, of the read buffer and
- * clears it. It returns one on success and zero on failure. */
-OPENSSL_EXPORT int BIO_set_read_buffer_size(BIO *bio, int buffer_size);
-
-/* BIO_set_write_buffer_size sets the size, in bytes, of the write buffer and
- * clears it. It returns one on success and zero on failure. */
-OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
-
-
/* Socket BIOs.
*
* Socket BIOs behave like file descriptor BIOs but, on Windows systems, wrap
@@ -672,6 +655,9 @@
OPENSSL_EXPORT void BIO_set_retry_special(BIO *bio);
+/* BIO_set_write_buffer_size returns zero. */
+OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
+
/* Private functions */
diff --git a/src/include/openssl/sha.h b/src/include/openssl/sha.h
index 2ddcb62..7c31097 100644
--- a/src/include/openssl/sha.h
+++ b/src/include/openssl/sha.h
@@ -73,10 +73,6 @@
/* SHA_DIGEST_LENGTH is the length of a SHA-1 digest. */
#define SHA_DIGEST_LENGTH 20
-/* TODO(fork): remove */
-#define SHA_LBLOCK 16
-#define SHA_LONG uint32_t
-
/* SHA1_Init initialises |sha| and returns one. */
OPENSSL_EXPORT int SHA1_Init(SHA_CTX *sha);
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 1491a53..3bb5b78 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -1726,19 +1726,36 @@
OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl);
/* SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a
- * session. */
+ * session in TLS 1.2 or earlier. This is how long we are willing to use the
+ * secret to encrypt traffic without fresh key material. */
#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60)
-/* SSL_CTX_set_timeout sets the lifetime, in seconds, of sessions created in
- * |ctx| to |timeout|. */
+/* SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT is the default lifetime, in seconds, of a
+ * session for TLS 1.3 psk_dhe_ke. This is how long we are willing to use the
+ * secret as an authenticator. */
+#define SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT (2 * 24 * 60 * 60)
+
+/* SSL_DEFAULT_SESSION_AUTH_TIMEOUT is the default non-renewable lifetime, in
+ * seconds, of a TLS 1.3 session. This is how long we are willing to trust the
+ * signature in the initial handshake. */
+#define SSL_DEFAULT_SESSION_AUTH_TIMEOUT (7 * 24 * 60 * 60)
+
+/* SSL_CTX_set_timeout sets the lifetime, in seconds, of TLS 1.2 (or earlier)
+ * sessions created in |ctx| to |timeout|. */
OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout);
-/* SSL_CTX_get_timeout returns the lifetime, in seconds, of sessions created in
- * |ctx|. */
+/* SSL_CTX_set_session_psk_dhe_timeout sets the lifetime, in seconds, of TLS 1.3
+ * sessions created in |ctx| to |timeout|. */
+OPENSSL_EXPORT void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx,
+ long timeout);
+
+/* SSL_CTX_get_timeout returns the lifetime, in seconds, of TLS 1.2 (or earlier)
+ * sessions created in |ctx|. */
OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
-/* SSL_set_session_timeout sets the default lifetime, in seconds, of the
- * session created in |ssl| to |timeout|, and returns the old value.
+/* SSL_set_session_timeout sets the default lifetime, in seconds, of a TLS 1.2
+ * (or earlier) session created in |ssl| to |timeout|, and returns the old
+ * value.
*
* By default the value |SSL_DEFAULT_SESSION_TIMEOUT| is used, which can be
* overridden at the context level by calling |SSL_CTX_set_timeout|.
@@ -1746,6 +1763,10 @@
* If |timeout| is zero the newly created session will not be resumable. */
OPENSSL_EXPORT long SSL_set_session_timeout(SSL *ssl, long timeout);
+/* SSL_set_session_psk_dhe_timeout sets the lifetime, in seconds, of TLS 1.3
+ * sessions created in |ssl| to |timeout|. */
+OPENSSL_EXPORT void SSL_set_session_psk_dhe_timeout(SSL *ssl, long timeout);
+
/* SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|.
* It returns one on success and zero on error. The session ID context is an
* application-defined opaque byte string. A session will not be used in a
@@ -2968,6 +2989,10 @@
OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl,
size_t max_send_fragment);
+/* SSL_get_v2clienthello_count returns the total number of V2ClientHellos that
+ * are accepted. */
+OPENSSL_EXPORT uint64_t SSL_get_v2clienthello_count(void);
+
/* ssl_early_callback_ctx (aka |SSL_CLIENT_HELLO|) is passed to certain
* callbacks that are called very early on during the server handshake. At this
* point, much of the SSL* hasn't been filled out and only the ClientHello can
@@ -3646,7 +3671,9 @@
/* BIO_f_ssl returns a |BIO_METHOD| that can wrap an |SSL*| in a |BIO*|. Note
* that this has quite different behaviour from the version in OpenSSL (notably
- * that it doesn't try to auto renegotiate). */
+ * that it doesn't try to auto renegotiate).
+ *
+ * IMPORTANT: if you are not curl, don't use this. */
OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void);
/* BIO_set_ssl sets |ssl| as the underlying connection for |bio|, which must
@@ -3732,9 +3759,14 @@
* non-fatal certificate errors. */
long verify_result;
- /* timeout is the lifetime of the session in seconds, measured from |time|. */
+ /* timeout is the lifetime of the session in seconds, measured from |time|.
+ * This is renewable up to |auth_timeout|. */
long timeout;
+ /* auth_timeout is the non-renewable lifetime of the session in seconds,
+ * measured from |time|. */
+ long auth_timeout;
+
/* time is the time the session was issued, measured in seconds from the UNIX
* epoch. */
long time;
@@ -3868,10 +3900,14 @@
* SSL_accept which cache SSL_SESSIONS. */
int session_cache_mode;
- /* If timeout is not 0, it is the default timeout value set when SSL_new() is
- * called. This has been put in to make life easier to set things up */
+ /* session_timeout is the default lifetime for new sessions in TLS 1.2 and
+ * earlier, in seconds. */
long session_timeout;
+ /* session_psk_dhe_timeout is the default lifetime for new sessions in TLS
+ * 1.3, in seconds. */
+ long session_psk_dhe_timeout;
+
/* If this callback is not null, it will be called each time a session id is
* added to the cache. If this function returns 1, it means that the
* callback will do a SSL_SESSION_free() when it has finished using it.
@@ -4106,17 +4142,6 @@
BIO *rbio; /* used by SSL_read */
BIO *wbio; /* used by SSL_write */
- /* bbio, if non-NULL, is a buffer placed in front of |wbio| to pack handshake
- * messages within one flight into a single |BIO_write|. In this case, |wbio|
- * and |bbio| are equal and the true caller-configured BIO is
- * |bbio->next_bio|.
- *
- * TODO(davidben): This does not work right for DTLS. It assumes the MTU is
- * smaller than the buffer size so that the buffer's internal flushing never
- * kicks in. It also doesn't kick in for DTLS retransmission. Replace this
- * with a better mechanism. */
- BIO *bbio;
-
int (*handshake_func)(SSL_HANDSHAKE *hs);
BUF_MEM *init_buf; /* buffer used during init */
@@ -4126,10 +4151,6 @@
/* init_num is the length of the current handshake message body. */
uint32_t init_num;
- /* init_off, in DTLS, is the number of bytes of the current message that have
- * been written. */
- uint32_t init_off;
-
struct ssl3_state_st *s3; /* SSLv3 variables */
struct dtls1_state_st *d1; /* DTLSv1 variables */
@@ -4249,9 +4270,13 @@
unsigned retain_only_sha256_of_client_certs:1;
/* session_timeout is the default lifetime in seconds of the session
- * created in this connection. */
+ * created in this connection at TLS 1.2 and earlier. */
long session_timeout;
+ /* session_psk_dhe_timeout is the default lifetime in seconds of sessions
+ * created in this connection at TLS 1.3. */
+ long session_psk_dhe_timeout;
+
/* OCSP response to be sent to the client, if requested. */
CRYPTO_BUFFER *ocsp_response;
};
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index e75b70d..84051ff 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -309,7 +309,6 @@
#define SSL3_ST_VERIFY_SERVER_CERT (0x102 | SSL_ST_CONNECT)
/* write to server */
#define SSL3_ST_CW_CLNT_HELLO_A (0x110 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CLNT_HELLO_B (0x111 | SSL_ST_CONNECT)
/* read from server */
#define SSL3_ST_CR_SRVR_HELLO_A (0x120 | SSL_ST_CONNECT)
#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126 | SSL_ST_CONNECT)
@@ -320,19 +319,13 @@
#define SSL3_ST_CR_SRVR_DONE_A (0x160 | SSL_ST_CONNECT)
/* write to server */
#define SSL3_ST_CW_CERT_A (0x170 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CERT_B (0x171 | SSL_ST_CONNECT)
#define SSL3_ST_CW_KEY_EXCH_A (0x180 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_KEY_EXCH_B (0x181 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_VRFY_A (0x190 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_VRFY_B (0x191 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CERT_VRFY_C (0x192 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CHANGE (0x1A0 | SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_A (0x200 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_NEXT_PROTO_B (0x201 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CHANNEL_ID_A (0x220 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_CHANNEL_ID_B (0x221 | SSL_ST_CONNECT)
#define SSL3_ST_CW_FINISHED_A (0x1B0 | SSL_ST_CONNECT)
-#define SSL3_ST_CW_FINISHED_B (0x1B1 | SSL_ST_CONNECT)
/* read from server */
#define SSL3_ST_CR_CHANGE (0x1C0 | SSL_ST_CONNECT)
#define SSL3_ST_CR_FINISHED_A (0x1D0 | SSL_ST_CONNECT)
@@ -351,22 +344,16 @@
#define SSL3_ST_SR_CLNT_HELLO_B (0x111 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_D (0x113 | SSL_ST_ACCEPT)
-#define SSL3_ST_SR_CLNT_HELLO_E (0x114 | SSL_ST_ACCEPT)
/* write to client */
#define SSL3_ST_SW_HELLO_REQ_A (0x120 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_HELLO_REQ_B (0x121 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_HELLO_REQ_C (0x122 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_SRVR_HELLO_A (0x130 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SRVR_HELLO_B (0x131 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_A (0x140 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_CERT_B (0x141 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_KEY_EXCH_A (0x150 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_KEY_EXCH_B (0x151 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_KEY_EXCH_C (0x152 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_REQ_A (0x160 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_CERT_REQ_B (0x161 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_SRVR_DONE_A (0x170 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SRVR_DONE_B (0x171 | SSL_ST_ACCEPT)
/* read from client */
#define SSL3_ST_SR_CERT_A (0x180 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_KEY_EXCH_A (0x190 | SSL_ST_ACCEPT)
@@ -380,13 +367,8 @@
/* write to client */
#define SSL3_ST_SW_CHANGE (0x1D0 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_FINISHED_A (0x1E0 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_FINISHED_B (0x1E1 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_STATUS_A (0x200 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_CERT_STATUS_B (0x201 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SUPPLEMENTAL_DATA_A (0x220 | SSL_ST_ACCEPT)
-#define SSL3_ST_SW_SUPPLEMENTAL_DATA_B (0x221 | SSL_ST_ACCEPT)
#define SSL3_MT_HELLO_REQUEST 0
#define SSL3_MT_CLIENT_HELLO 1
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index 7102769..afc3a39 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -3,6 +3,7 @@
add_library(
ssl
+ bio_ssl.c
custom_extensions.c
handshake_server.c
handshake_client.c
diff --git a/src/decrepit/biossl/bio_ssl.c b/src/ssl/bio_ssl.c
similarity index 93%
rename from src/decrepit/biossl/bio_ssl.c
rename to src/ssl/bio_ssl.c
index f8147c6..ad8f5d8 100644
--- a/src/decrepit/biossl/bio_ssl.c
+++ b/src/ssl/bio_ssl.c
@@ -107,14 +107,14 @@
return 1;
case BIO_CTRL_WPENDING:
- return BIO_ctrl(ssl->wbio, cmd, num, ptr);
+ return BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr);
case BIO_CTRL_PENDING:
return SSL_pending(ssl);
case BIO_CTRL_FLUSH: {
BIO_clear_retry_flags(bio);
- long ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
+ long ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr);
BIO_copy_next_retry(bio);
return ret;
}
@@ -125,7 +125,7 @@
return -1;
default:
- return BIO_ctrl(ssl->rbio, cmd, num, ptr);
+ return BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr);
}
}
@@ -159,7 +159,7 @@
return -1;
default:
- return BIO_callback_ctrl(ssl->rbio, cmd, fp);
+ return BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp);
}
}
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index d3e4a92..48a5c54 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -122,6 +122,7 @@
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
+#include <openssl/type_check.h>
#include <openssl/x509.h>
#include "../crypto/internal.h"
@@ -311,9 +312,9 @@
}
/* Cross-epoch records are discarded, but we may receive out-of-order
- * application data between ChangeCipherSpec and Finished or a ChangeCipherSpec
- * before the appropriate point in the handshake. Those must be silently
- * discarded.
+ * application data between ChangeCipherSpec and Finished or a
+ * ChangeCipherSpec before the appropriate point in the handshake. Those must
+ * be silently discarded.
*
* However, only allow the out-of-order records in the correct epoch.
* Application data must come in the encrypted epoch, and ChangeCipherSpec in
@@ -384,8 +385,8 @@
assert(msg_len > 0);
/* Copy the body into the fragment. */
- OPENSSL_memcpy(frag->data + DTLS1_HM_HEADER_LENGTH + frag_off, CBS_data(&body),
- CBS_len(&body));
+ OPENSSL_memcpy(frag->data + DTLS1_HM_HEADER_LENGTH + frag_off,
+ CBS_data(&body), CBS_len(&body));
dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len);
}
@@ -394,17 +395,11 @@
return 1;
}
-int dtls1_get_message(SSL *ssl, int msg_type,
- enum ssl_hash_message_t hash_message) {
+int dtls1_get_message(SSL *ssl) {
if (ssl->s3->tmp.reuse_message) {
- /* A ssl_dont_hash_message call cannot be combined with reuse_message; the
- * ssl_dont_hash_message would have to have been applied to the previous
- * call. */
- assert(hash_message == ssl_hash_message);
+ /* There must be a current message. */
assert(ssl->init_msg != NULL);
-
ssl->s3->tmp.reuse_message = 0;
- hash_message = ssl_dont_hash_message;
} else {
dtls1_release_current_message(ssl, 0 /* don't free buffer */);
}
@@ -429,15 +424,6 @@
ssl->init_msg = frag->data + DTLS1_HM_HEADER_LENGTH;
ssl->init_num = frag->msg_len;
- if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- return -1;
- }
- if (hash_message == ssl_hash_message && !ssl_hash_current_message(ssl)) {
- return -1;
- }
-
ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, frag->data,
ssl->init_num + DTLS1_HM_HEADER_LENGTH);
return 1;
@@ -507,219 +493,14 @@
/* Sending handshake messages. */
-static void dtls1_update_mtu(SSL *ssl) {
- /* TODO(davidben): What is this code doing and do we need it? */
- if (ssl->d1->mtu < dtls1_min_mtu() &&
- !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
- long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
- if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
- ssl->d1->mtu = (unsigned)mtu;
- } else {
- ssl->d1->mtu = kDefaultMTU;
- BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL);
- }
- }
-
- /* The MTU should be above the minimum now. */
- assert(ssl->d1->mtu >= dtls1_min_mtu());
-}
-
-/* dtls1_max_record_size returns the maximum record body length that may be
- * written without exceeding the MTU. It accounts for any buffering installed on
- * the write BIO. If no record may be written, it returns zero. */
-static size_t dtls1_max_record_size(const SSL *ssl) {
- size_t ret = ssl->d1->mtu;
-
- size_t overhead = SSL_max_seal_overhead(ssl);
- if (ret <= overhead) {
- return 0;
- }
- ret -= overhead;
-
- size_t pending = BIO_wpending(ssl->wbio);
- if (ret <= pending) {
- return 0;
- }
- ret -= pending;
-
- return ret;
-}
-
-static int dtls1_write_change_cipher_spec(SSL *ssl,
- enum dtls1_use_epoch_t use_epoch) {
- dtls1_update_mtu(ssl);
-
- /* During the handshake, wbio is buffered to pack messages together. Flush the
- * buffer if the ChangeCipherSpec would not fit in a packet. */
- if (dtls1_max_record_size(ssl) == 0) {
- int ret = BIO_flush(ssl->wbio);
- if (ret <= 0) {
- ssl->rwstate = SSL_WRITING;
- return ret;
- }
- }
-
- static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
- int ret =
- dtls1_write_record(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
- sizeof(kChangeCipherSpec), use_epoch);
- if (ret <= 0) {
- return ret;
- }
-
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
- kChangeCipherSpec, sizeof(kChangeCipherSpec));
- return 1;
-}
-
-/* dtls1_do_handshake_write writes handshake message |in| using the given epoch,
- * starting |offset| bytes into the message body. It returns one on success. On
- * error, it returns <= 0 and sets |*out_offset| to the number of bytes of body
- * that were successfully written. This may be used to retry the write
- * later. |in| must be a reassembled handshake message with the full DTLS
- * handshake header. */
-static int dtls1_do_handshake_write(SSL *ssl, size_t *out_offset,
- const uint8_t *in, size_t offset,
- size_t len,
- enum dtls1_use_epoch_t use_epoch) {
- dtls1_update_mtu(ssl);
-
- int ret = -1;
- CBB cbb;
- CBB_zero(&cbb);
- /* Allocate a temporary buffer to hold the message fragments to avoid
- * clobbering the message. */
- uint8_t *buf = OPENSSL_malloc(ssl->d1->mtu);
- if (buf == NULL) {
- goto err;
- }
-
- /* Although it may be sent as multiple fragments, a DTLS message must be sent
- * serialized as a single fragment for purposes of |ssl_do_msg_callback| and
- * the handshake hash. */
- CBS cbs, body;
- struct hm_header_st hdr;
- CBS_init(&cbs, in, len);
- if (!dtls1_parse_fragment(&cbs, &hdr, &body) ||
- hdr.frag_off != 0 ||
- hdr.frag_len != CBS_len(&body) ||
- hdr.msg_len != CBS_len(&body) ||
- !CBS_skip(&body, offset) ||
- CBS_len(&cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- do {
- /* During the handshake, wbio is buffered to pack messages together. Flush
- * the buffer if there isn't enough room to make progress. */
- if (dtls1_max_record_size(ssl) < DTLS1_HM_HEADER_LENGTH + 1) {
- int flush_ret = BIO_flush(ssl->wbio);
- if (flush_ret <= 0) {
- ssl->rwstate = SSL_WRITING;
- ret = flush_ret;
- goto err;
- }
- assert(BIO_wpending(ssl->wbio) == 0);
- }
-
- size_t todo = dtls1_max_record_size(ssl);
- if (todo < DTLS1_HM_HEADER_LENGTH + 1) {
- /* To make forward progress, the MTU must, at minimum, fit the handshake
- * header and one byte of handshake body. */
- OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
- goto err;
- }
- todo -= DTLS1_HM_HEADER_LENGTH;
-
- if (todo > CBS_len(&body)) {
- todo = CBS_len(&body);
- }
- if (todo >= (1u << 24)) {
- todo = (1u << 24) - 1;
- }
-
- size_t buf_len;
- if (!CBB_init_fixed(&cbb, buf, ssl->d1->mtu) ||
- !CBB_add_u8(&cbb, hdr.type) ||
- !CBB_add_u24(&cbb, hdr.msg_len) ||
- !CBB_add_u16(&cbb, hdr.seq) ||
- !CBB_add_u24(&cbb, offset) ||
- !CBB_add_u24(&cbb, todo) ||
- !CBB_add_bytes(&cbb, CBS_data(&body), todo) ||
- !CBB_finish(&cbb, NULL, &buf_len)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- int write_ret =
- dtls1_write_record(ssl, SSL3_RT_HANDSHAKE, buf, buf_len, use_epoch);
- if (write_ret <= 0) {
- ret = write_ret;
- goto err;
- }
-
- if (!CBS_skip(&body, todo)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- offset += todo;
- } while (CBS_len(&body) != 0);
-
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, in, len);
-
- ret = 1;
-
-err:
- *out_offset = offset;
- CBB_cleanup(&cbb);
- OPENSSL_free(buf);
- return ret;
-}
-
void dtls_clear_outgoing_messages(SSL *ssl) {
for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) {
OPENSSL_free(ssl->d1->outgoing_messages[i].data);
ssl->d1->outgoing_messages[i].data = NULL;
}
ssl->d1->outgoing_messages_len = 0;
-}
-
-/* dtls1_add_change_cipher_spec adds a ChangeCipherSpec to the current
- * handshake flight. */
-static int dtls1_add_change_cipher_spec(SSL *ssl) {
- if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- DTLS_OUTGOING_MESSAGE *msg =
- &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len];
- msg->data = NULL;
- msg->len = 0;
- msg->epoch = ssl->d1->w_epoch;
- msg->is_ccs = 1;
-
- ssl->d1->outgoing_messages_len++;
- return 1;
-}
-
-static int dtls1_add_message(SSL *ssl, uint8_t *data, size_t len) {
- if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- OPENSSL_free(data);
- return 0;
- }
-
- DTLS_OUTGOING_MESSAGE *msg =
- &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len];
- msg->data = data;
- msg->len = len;
- msg->epoch = ssl->d1->w_epoch;
- msg->is_ccs = 0;
-
- ssl->d1->outgoing_messages_len++;
- return 1;
+ ssl->d1->outgoing_written = 0;
+ ssl->d1->outgoing_offset = 0;
}
int dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
@@ -752,36 +533,91 @@
return 1;
}
-int dtls1_queue_message(SSL *ssl, uint8_t *msg, size_t len) {
- ssl3_update_handshake_hash(ssl, msg, len);
-
- ssl->d1->handshake_write_seq++;
- ssl->init_off = 0;
- return dtls1_add_message(ssl, msg, len);
-}
-
-int dtls1_write_message(SSL *ssl) {
- if (ssl->d1->outgoing_messages_len == 0) {
+/* add_outgoing adds a new handshake message or ChangeCipherSpec to the current
+ * outgoing flight. It returns one on success and zero on error. In both cases,
+ * it takes ownership of |data| and releases it with |OPENSSL_free| when
+ * done. */
+static int add_outgoing(SSL *ssl, int is_ccs, uint8_t *data, size_t len) {
+ OPENSSL_COMPILE_ASSERT(SSL_MAX_HANDSHAKE_FLIGHT <
+ (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)),
+ outgoing_messages_len_is_too_small);
+ if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT) {
+ assert(0);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
+ OPENSSL_free(data);
+ return 0;
}
- const DTLS_OUTGOING_MESSAGE *msg =
- &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len - 1];
- if (msg->is_ccs) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
+ if (!is_ccs) {
+ ssl3_update_handshake_hash(ssl, data, len);
+ ssl->d1->handshake_write_seq++;
}
- size_t offset = ssl->init_off;
- int ret = dtls1_do_handshake_write(ssl, &offset, msg->data, offset, msg->len,
- dtls1_use_current_epoch);
- ssl->init_off = offset;
- return ret;
+ DTLS_OUTGOING_MESSAGE *msg =
+ &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len];
+ msg->data = data;
+ msg->len = len;
+ msg->epoch = ssl->d1->w_epoch;
+ msg->is_ccs = is_ccs;
+
+ ssl->d1->outgoing_messages_len++;
+ return 1;
}
-static int dtls1_retransmit_message(SSL *ssl,
- const DTLS_OUTGOING_MESSAGE *msg) {
+int dtls1_add_message(SSL *ssl, uint8_t *data, size_t len) {
+ return add_outgoing(ssl, 0 /* handshake */, data, len);
+}
+
+int dtls1_add_change_cipher_spec(SSL *ssl) {
+ return add_outgoing(ssl, 1 /* ChangeCipherSpec */, NULL, 0);
+}
+
+int dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc) {
+ /* The |add_alert| path is only used for warning alerts for now, which DTLS
+ * never sends. This will be implemented later once closure alerts are
+ * converted. */
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+}
+
+/* dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above
+ * the minimum. */
+static void dtls1_update_mtu(SSL *ssl) {
+ /* TODO(davidben): No consumer implements |BIO_CTRL_DGRAM_SET_MTU| and the
+ * only |BIO_CTRL_DGRAM_QUERY_MTU| implementation could use
+ * |SSL_set_mtu|. Does this need to be so complex? */
+ if (ssl->d1->mtu < dtls1_min_mtu() &&
+ !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+ if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
+ ssl->d1->mtu = (unsigned)mtu;
+ } else {
+ ssl->d1->mtu = kDefaultMTU;
+ BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL);
+ }
+ }
+
+ /* The MTU should be above the minimum now. */
+ assert(ssl->d1->mtu >= dtls1_min_mtu());
+}
+
+enum seal_result_t {
+ seal_error,
+ seal_no_progress,
+ seal_partial,
+ seal_success,
+};
+
+/* seal_next_message seals |msg|, which must be the next message, to |out|. If
+ * progress was made, it returns |seal_partial| or |seal_success| and sets
+ * |*out_len| to the number of bytes written. */
+static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out,
+ size_t *out_len, size_t max_out,
+ const DTLS_OUTGOING_MESSAGE *msg) {
+ assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len);
+ assert(msg == &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]);
+
/* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
* (negotiated cipher) exist. */
assert(ssl->d1->w_epoch == 0 || ssl->d1->w_epoch == 1);
@@ -790,56 +626,181 @@
if (ssl->d1->w_epoch == 1 && msg->epoch == 0) {
use_epoch = dtls1_use_previous_epoch;
}
+ size_t overhead = dtls_max_seal_overhead(ssl, use_epoch);
+ size_t prefix = dtls_seal_prefix_len(ssl, use_epoch);
- /* TODO(davidben): This cannot handle non-blocking writes. */
- int ret;
if (msg->is_ccs) {
- ret = dtls1_write_change_cipher_spec(ssl, use_epoch);
- } else {
- size_t offset = 0;
- ret = dtls1_do_handshake_write(ssl, &offset, msg->data, offset, msg->len,
- use_epoch);
+ /* Check there is room for the ChangeCipherSpec. */
+ static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
+ if (max_out < sizeof(kChangeCipherSpec) + overhead) {
+ return seal_no_progress;
+ }
+
+ if (!dtls_seal_record(ssl, out, out_len, max_out,
+ SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
+ sizeof(kChangeCipherSpec), use_epoch)) {
+ return seal_error;
+ }
+
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
+ kChangeCipherSpec, sizeof(kChangeCipherSpec));
+ return seal_success;
}
- return ret;
+ /* DTLS messages are serialized as a single fragment in |msg|. */
+ CBS cbs, body;
+ struct hm_header_st hdr;
+ CBS_init(&cbs, msg->data, msg->len);
+ if (!dtls1_parse_fragment(&cbs, &hdr, &body) ||
+ hdr.frag_off != 0 ||
+ hdr.frag_len != CBS_len(&body) ||
+ hdr.msg_len != CBS_len(&body) ||
+ !CBS_skip(&body, ssl->d1->outgoing_offset) ||
+ CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return seal_error;
+ }
+
+ /* Determine how much progress can be made. */
+ if (max_out < DTLS1_HM_HEADER_LENGTH + 1 + overhead || max_out < prefix) {
+ return seal_no_progress;
+ }
+ size_t todo = CBS_len(&body);
+ if (todo > max_out - DTLS1_HM_HEADER_LENGTH - overhead) {
+ todo = max_out - DTLS1_HM_HEADER_LENGTH - overhead;
+ }
+
+ /* Assemble a fragment, to be sealed in-place. */
+ CBB cbb;
+ uint8_t *frag = out + prefix;
+ size_t max_frag = max_out - prefix, frag_len;
+ if (!CBB_init_fixed(&cbb, frag, max_frag) ||
+ !CBB_add_u8(&cbb, hdr.type) ||
+ !CBB_add_u24(&cbb, hdr.msg_len) ||
+ !CBB_add_u16(&cbb, hdr.seq) ||
+ !CBB_add_u24(&cbb, ssl->d1->outgoing_offset) ||
+ !CBB_add_u24(&cbb, todo) ||
+ !CBB_add_bytes(&cbb, CBS_data(&body), todo) ||
+ !CBB_finish(&cbb, NULL, &frag_len)) {
+ CBB_cleanup(&cbb);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return seal_error;
+ }
+
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, frag, frag_len);
+
+ if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE,
+ out + prefix, frag_len, use_epoch)) {
+ return seal_error;
+ }
+
+ if (todo == CBS_len(&body)) {
+ /* The next message is complete. */
+ ssl->d1->outgoing_offset = 0;
+ return seal_success;
+ }
+
+ ssl->d1->outgoing_offset += todo;
+ return seal_partial;
}
-int dtls1_retransmit_outgoing_messages(SSL *ssl) {
- /* Ensure we are packing handshake messages. */
- const int was_buffered = ssl_is_wbio_buffered(ssl);
- assert(was_buffered == SSL_in_init(ssl));
- if (!was_buffered && !ssl_init_wbio_buffer(ssl)) {
- return -1;
+/* seal_next_packet writes as much of the next flight as possible to |out| and
+ * advances |ssl->d1->outgoing_written| and |ssl->d1->outgoing_offset| as
+ * appropriate. */
+static int seal_next_packet(SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out) {
+ int made_progress = 0;
+ size_t total = 0;
+ assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len);
+ for (; ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len;
+ ssl->d1->outgoing_written++) {
+ const DTLS_OUTGOING_MESSAGE *msg =
+ &ssl->d1->outgoing_messages[ssl->d1->outgoing_written];
+ size_t len;
+ enum seal_result_t ret = seal_next_message(ssl, out, &len, max_out, msg);
+ switch (ret) {
+ case seal_error:
+ return 0;
+
+ case seal_no_progress:
+ goto packet_full;
+
+ case seal_partial:
+ case seal_success:
+ out += len;
+ max_out -= len;
+ total += len;
+ made_progress = 1;
+
+ if (ret == seal_partial) {
+ goto packet_full;
+ }
+ break;
+ }
}
- assert(ssl_is_wbio_buffered(ssl));
+
+packet_full:
+ /* The MTU was too small to make any progress. */
+ if (!made_progress) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
+ return 0;
+ }
+
+ *out_len = total;
+ return 1;
+}
+
+int dtls1_flush_flight(SSL *ssl) {
+ dtls1_update_mtu(ssl);
int ret = -1;
- for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) {
- if (dtls1_retransmit_message(ssl, &ssl->d1->outgoing_messages[i]) <= 0) {
+ uint8_t *packet = OPENSSL_malloc(ssl->d1->mtu);
+ if (packet == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len) {
+ uint8_t old_written = ssl->d1->outgoing_written;
+ uint32_t old_offset = ssl->d1->outgoing_offset;
+
+ size_t packet_len;
+ if (!seal_next_packet(ssl, packet, &packet_len, ssl->d1->mtu)) {
+ goto err;
+ }
+
+ int bio_ret = BIO_write(ssl->wbio, packet, packet_len);
+ if (bio_ret <= 0) {
+ /* Retry this packet the next time around. */
+ ssl->d1->outgoing_written = old_written;
+ ssl->d1->outgoing_offset = old_offset;
+ ssl->rwstate = SSL_WRITING;
+ ret = bio_ret;
goto err;
}
}
- ret = BIO_flush(ssl->wbio);
- if (ret <= 0) {
+ if (BIO_flush(ssl->wbio) <= 0) {
ssl->rwstate = SSL_WRITING;
goto err;
}
+ ret = 1;
+
err:
- if (!was_buffered) {
- ssl_free_wbio_buffer(ssl);
- }
+ OPENSSL_free(packet);
return ret;
}
-int dtls1_send_change_cipher_spec(SSL *ssl) {
- int ret = dtls1_write_change_cipher_spec(ssl, dtls1_use_current_epoch);
- if (ret <= 0) {
- return ret;
- }
- dtls1_add_change_cipher_spec(ssl);
- return 1;
+int dtls1_retransmit_outgoing_messages(SSL *ssl) {
+ /* Rewind to the start of the flight and write it again.
+ *
+ * TODO(davidben): This does not allow retransmits to be resumed on
+ * non-blocking write. */
+ ssl->d1->outgoing_written = 0;
+ ssl->d1->outgoing_offset = 0;
+
+ return dtls1_flush_flight(ssl);
}
unsigned int dtls1_min_mtu(void) {
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index c6950d5..27b2763 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -331,7 +331,7 @@
}
}
-int dtls1_write_app_data(SSL *ssl, const void *buf_, int len) {
+int dtls1_write_app_data(SSL *ssl, const uint8_t *buf, int len) {
assert(!SSL_in_init(ssl));
if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
@@ -348,7 +348,7 @@
return 0;
}
- int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, buf_, (size_t)len,
+ int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, buf, (size_t)len,
dtls1_use_current_epoch);
if (ret <= 0) {
return ret;
@@ -364,15 +364,6 @@
* |ssl_write_buffer_flush|. */
assert(!ssl_write_buffer_is_pending(ssl));
- /* If we have an alert to send, lets send it */
- if (ssl->s3->alert_dispatch) {
- int ret = ssl->method->dispatch_alert(ssl);
- if (ret <= 0) {
- return ret;
- }
- /* if it went, fall through and send more stuff */
- }
-
if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
@@ -397,13 +388,12 @@
}
int dtls1_dispatch_alert(SSL *ssl) {
- ssl->s3->alert_dispatch = 0;
int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2,
dtls1_use_current_epoch);
if (ret <= 0) {
- ssl->s3->alert_dispatch = 1;
return ret;
}
+ ssl->s3->alert_dispatch = 0;
/* If the alert is fatal, flush the BIO now. */
if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
diff --git a/src/ssl/dtls_method.c b/src/ssl/dtls_method.c
index 702b3c0..7a35b39 100644
--- a/src/ssl/dtls_method.c
+++ b/src/ssl/dtls_method.c
@@ -99,14 +99,6 @@
return cipher->algorithm_enc != SSL_eNULL;
}
-static int dtls1_flush_flight(SSL *ssl) {
- int ret = BIO_flush(ssl->wbio);
- if (ret <= 0) {
- ssl->rwstate = SSL_WRITING;
- }
- return ret;
-}
-
static void dtls1_expect_flight(SSL *ssl) { dtls1_start_timer(ssl); }
static void dtls1_received_flight(SSL *ssl) { dtls1_stop_timer(ssl); }
@@ -159,9 +151,9 @@
dtls1_supports_cipher,
dtls1_init_message,
dtls1_finish_message,
- dtls1_queue_message,
- dtls1_write_message,
- dtls1_send_change_cipher_spec,
+ dtls1_add_message,
+ dtls1_add_change_cipher_spec,
+ dtls1_add_alert,
dtls1_flush_flight,
dtls1_expect_flight,
dtls1_received_flight,
diff --git a/src/ssl/dtls_record.c b/src/ssl/dtls_record.c
index 35c08b0..879706d 100644
--- a/src/ssl/dtls_record.c
+++ b/src/ssl/dtls_record.c
@@ -249,16 +249,27 @@
return ssl_open_record_success;
}
-size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
- const SSL_AEAD_CTX *aead = ssl->s3->aead_write_ctx;
+static const SSL_AEAD_CTX *get_write_aead(const SSL *ssl,
+ enum dtls1_use_epoch_t use_epoch) {
if (use_epoch == dtls1_use_previous_epoch) {
/* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
* (negotiated cipher) exist. */
assert(ssl->d1->w_epoch == 1);
- aead = NULL;
+ return NULL;
}
- return DTLS1_RT_HEADER_LENGTH + SSL_AEAD_CTX_explicit_nonce_len(aead);
+ return ssl->s3->aead_write_ctx;
+}
+
+size_t dtls_max_seal_overhead(const SSL *ssl,
+ enum dtls1_use_epoch_t use_epoch) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_max_overhead(get_write_aead(ssl, use_epoch));
+}
+
+size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(get_write_aead(ssl, use_epoch));
}
int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
diff --git a/src/ssl/handshake_client.c b/src/ssl/handshake_client.c
index 3389d6c..23a4cff 100644
--- a/src/ssl/handshake_client.c
+++ b/src/ssl/handshake_client.c
@@ -206,17 +206,10 @@
case SSL_ST_CONNECT:
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
-
- if (!ssl_init_wbio_buffer(ssl)) {
- ret = -1;
- goto end;
- }
-
hs->state = SSL3_ST_CW_CLNT_HELLO_A;
break;
case SSL3_ST_CW_CLNT_HELLO_A:
- case SSL3_ST_CW_CLNT_HELLO_B:
ret = ssl3_send_client_hello(hs);
if (ret <= 0) {
goto end;
@@ -326,7 +319,6 @@
break;
case SSL3_ST_CW_CERT_A:
- case SSL3_ST_CW_CERT_B:
if (hs->cert_request) {
ret = ssl3_send_client_certificate(hs);
if (ret <= 0) {
@@ -339,7 +331,6 @@
break;
case SSL3_ST_CW_KEY_EXCH_A:
- case SSL3_ST_CW_KEY_EXCH_B:
ret = ssl3_send_client_key_exchange(hs);
if (ret <= 0) {
goto end;
@@ -349,7 +340,6 @@
case SSL3_ST_CW_CERT_VRFY_A:
case SSL3_ST_CW_CERT_VRFY_B:
- case SSL3_ST_CW_CERT_VRFY_C:
if (hs->cert_request && ssl_has_certificate(ssl)) {
ret = ssl3_send_cert_verify(hs);
if (ret <= 0) {
@@ -362,22 +352,16 @@
break;
case SSL3_ST_CW_CHANGE:
- ret = ssl->method->send_change_cipher_spec(ssl);
- if (ret <= 0) {
- goto end;
- }
-
- hs->state = SSL3_ST_CW_NEXT_PROTO_A;
-
- if (!tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
+ if (!ssl->method->add_change_cipher_spec(ssl) ||
+ !tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
ret = -1;
goto end;
}
+ hs->state = SSL3_ST_CW_NEXT_PROTO_A;
break;
case SSL3_ST_CW_NEXT_PROTO_A:
- case SSL3_ST_CW_NEXT_PROTO_B:
if (hs->next_proto_neg_seen) {
ret = ssl3_send_next_proto(hs);
if (ret <= 0) {
@@ -390,7 +374,6 @@
break;
case SSL3_ST_CW_CHANNEL_ID_A:
- case SSL3_ST_CW_CHANNEL_ID_B:
if (ssl->s3->tlsext_channel_id_valid) {
ret = ssl3_send_channel_id(hs);
if (ret <= 0) {
@@ -403,9 +386,7 @@
break;
case SSL3_ST_CW_FINISHED_A:
- case SSL3_ST_CW_FINISHED_B:
- ret = ssl3_send_finished(hs, SSL3_ST_CW_FINISHED_A,
- SSL3_ST_CW_FINISHED_B);
+ ret = ssl3_send_finished(hs);
if (ret <= 0) {
goto end;
}
@@ -437,8 +418,6 @@
case SSL3_ST_FALSE_START:
hs->state = SSL3_ST_CR_SESSION_TICKET_A;
hs->in_false_start = 1;
-
- ssl_free_wbio_buffer(ssl);
ret = 1;
goto end;
@@ -527,9 +506,6 @@
ssl->s3->new_session = NULL;
}
- /* Remove write buffering now. */
- ssl_free_wbio_buffer(ssl);
-
const int is_initial_handshake = !ssl->s3->initial_handshake_complete;
ssl->s3->initial_handshake_complete = 1;
if (is_initial_handshake) {
@@ -578,11 +554,59 @@
return ret;
}
+/* ssl_get_client_disabled sets |*out_mask_a| and |*out_mask_k| to masks of
+ * disabled algorithms. */
+static void ssl_get_client_disabled(SSL *ssl, uint32_t *out_mask_a,
+ uint32_t *out_mask_k) {
+ int have_rsa = 0, have_ecdsa = 0;
+ *out_mask_a = 0;
+ *out_mask_k = 0;
+
+ /* Now go through all signature algorithms seeing if we support any for RSA or
+ * ECDSA. Do this for all versions not just TLS 1.2. */
+ const uint16_t *sigalgs;
+ size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
+ for (size_t i = 0; i < num_sigalgs; i++) {
+ switch (sigalgs[i]) {
+ case SSL_SIGN_RSA_PSS_SHA512:
+ case SSL_SIGN_RSA_PSS_SHA384:
+ case SSL_SIGN_RSA_PSS_SHA256:
+ case SSL_SIGN_RSA_PKCS1_SHA512:
+ case SSL_SIGN_RSA_PKCS1_SHA384:
+ case SSL_SIGN_RSA_PKCS1_SHA256:
+ case SSL_SIGN_RSA_PKCS1_SHA1:
+ have_rsa = 1;
+ break;
+
+ case SSL_SIGN_ECDSA_SECP521R1_SHA512:
+ case SSL_SIGN_ECDSA_SECP384R1_SHA384:
+ case SSL_SIGN_ECDSA_SECP256R1_SHA256:
+ case SSL_SIGN_ECDSA_SHA1:
+ have_ecdsa = 1;
+ break;
+ }
+ }
+
+ /* Disable auth if we don't include any appropriate signature algorithms. */
+ if (!have_rsa) {
+ *out_mask_a |= SSL_aRSA;
+ }
+ if (!have_ecdsa) {
+ *out_mask_a |= SSL_aECDSA;
+ }
+
+ /* PSK requires a client callback. */
+ if (ssl->psk_client_callback == NULL) {
+ *out_mask_a |= SSL_aPSK;
+ *out_mask_k |= SSL_kPSK;
+ }
+}
+
static int ssl_write_client_cipher_list(SSL *ssl, CBB *out,
uint16_t min_version,
uint16_t max_version) {
- /* Prepare disabled cipher masks. */
- ssl_set_client_disabled(ssl);
+ uint32_t mask_a, mask_k;
+ ssl_get_client_disabled(ssl, &mask_a, &mask_k);
CBB child;
if (!CBB_add_u16_length_prefixed(out, &child)) {
@@ -618,8 +642,8 @@
for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
/* Skip disabled ciphers */
- if ((cipher->algorithm_mkey & ssl->cert->mask_k) ||
- (cipher->algorithm_auth & ssl->cert->mask_a)) {
+ if ((cipher->algorithm_mkey & mask_k) ||
+ (cipher->algorithm_auth & mask_a)) {
continue;
}
if (SSL_CIPHER_get_min_version(cipher) > max_version ||
@@ -713,7 +737,7 @@
goto err;
}
- return ssl->method->queue_message(ssl, msg, len);
+ return ssl->method->add_message(ssl, msg, len);
err:
CBB_cleanup(&cbb);
@@ -722,10 +746,6 @@
static int ssl3_send_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_CW_CLNT_HELLO_B) {
- return ssl->method->write_message(ssl);
- }
-
/* The handshake buffer is reset on every ClientHello. Notably, in DTLS, we
* may send multiple ClientHellos if we receive HelloVerifyRequest. */
if (!ssl3_init_handshake_buffer(ssl)) {
@@ -779,8 +799,7 @@
return -1;
}
- hs->state = SSL3_ST_CW_CLNT_HELLO_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int dtls1_get_hello_verify(SSL_HANDSHAKE *hs) {
@@ -789,7 +808,7 @@
CBS hello_verify_request, cookie;
uint16_t server_version;
- int ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
@@ -800,8 +819,10 @@
return 1;
}
- CBS_init(&hello_verify_request, ssl->init_msg, ssl->init_num);
+ /* The handshake transcript is reset on HelloVerifyRequst, so do not bother
+ * hashing it. */
+ CBS_init(&hello_verify_request, ssl->init_msg, ssl->init_num);
if (!CBS_get_u16(&hello_verify_request, &server_version) ||
!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) ||
CBS_len(&hello_verify_request) != 0) {
@@ -828,13 +849,12 @@
static int ssl3_get_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CERT *ct = ssl->cert;
int al = SSL_AD_INTERNAL_ERROR;
CBS server_hello, server_random, session_id;
uint16_t server_wire_version, cipher_suite;
uint8_t compression_method;
- int ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
uint32_t err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
@@ -896,9 +916,7 @@
ssl_clear_tls13_state(hs);
- if (ssl->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
+ if (!ssl_check_message_type(ssl, SSL3_MT_SERVER_HELLO)) {
return -1;
}
@@ -945,7 +963,9 @@
}
/* The cipher must be allowed in the selected version and enabled. */
- if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) ||
+ uint32_t mask_a, mask_k;
+ ssl_get_client_disabled(ssl, &mask_a, &mask_k);
+ if ((c->algorithm_mkey & mask_k) || (c->algorithm_auth & mask_a) ||
SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) ||
SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl) ||
!sk_SSL_CIPHER_find(SSL_get_ciphers(ssl), NULL, c)) {
@@ -977,8 +997,10 @@
}
ssl->s3->tmp.new_cipher = c;
- /* Now that the cipher is known, initialize the handshake hash. */
- if (!ssl3_init_handshake_hash(ssl)) {
+ /* Now that the cipher is known, initialize the handshake hash and hash the
+ * ServerHello. */
+ if (!ssl3_init_handshake_hash(ssl) ||
+ !ssl_hash_current_message(ssl)) {
goto f_err;
}
@@ -1033,12 +1055,16 @@
static int ssl3_get_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret =
- ssl->method->ssl_get_message(ssl, SSL3_MT_CERTIFICATE, ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
+ !ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
CBS cbs;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
@@ -1077,7 +1103,7 @@
CBS certificate_status, ocsp_response;
uint8_t status_type;
- int ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
@@ -1089,6 +1115,10 @@
return 1;
}
+ if (!ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
CBS_init(&certificate_status, ssl->init_msg, ssl->init_num);
if (!CBS_get_u8(&certificate_status, &status_type) ||
status_type != TLSEXT_STATUSTYPE_ocsp ||
@@ -1130,7 +1160,7 @@
EC_KEY *ecdh = NULL;
EC_POINT *srvr_ecpoint = NULL;
- int ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
@@ -1147,6 +1177,10 @@
return 1;
}
+ if (!ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
/* Retain a copy of the original CBS to compute the signature over. */
CBS server_key_exchange;
CBS_init(&server_key_exchange, ssl->init_msg, ssl->init_num);
@@ -1360,7 +1394,7 @@
static int ssl3_get_certificate_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int msg_ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
+ int msg_ret = ssl->method->ssl_get_message(ssl);
if (msg_ret <= 0) {
return msg_ret;
}
@@ -1373,9 +1407,8 @@
return 1;
}
- if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_REQUEST) ||
+ !ssl_hash_current_message(ssl)) {
return -1;
}
@@ -1428,12 +1461,16 @@
static int ssl3_get_server_hello_done(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = ssl->method->ssl_get_message(ssl, SSL3_MT_SERVER_HELLO_DONE,
- ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_SERVER_HELLO_DONE) ||
+ !ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
/* ServerHelloDone is empty. */
if (ssl->init_num > 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
@@ -1446,11 +1483,6 @@
static int ssl3_send_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_CW_CERT_B) {
- return ssl->method->write_message(ssl);
- }
- assert(hs->state == SSL3_ST_CW_CERT_A);
-
/* Call cert_cb to update the certificate. */
if (ssl->cert->cert_cb) {
int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
@@ -1469,9 +1501,12 @@
/* Without a client certificate, the handshake buffer may be released. */
ssl3_free_handshake_buffer(ssl);
+ /* In SSL 3.0, the Certificate message is replaced with a warning alert. */
if (ssl->version == SSL3_VERSION) {
- /* In SSL 3.0, send no certificate by skipping both messages. */
- ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
+ if (!ssl->method->add_alert(ssl, SSL3_AL_WARNING,
+ SSL_AD_NO_CERTIFICATE)) {
+ return -1;
+ }
return 1;
}
}
@@ -1480,8 +1515,7 @@
!ssl3_output_cert_chain(ssl)) {
return -1;
}
- hs->state = SSL3_ST_CW_CERT_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),
@@ -1489,11 +1523,6 @@
static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_CW_KEY_EXCH_B) {
- return ssl->method->write_message(ssl);
- }
- assert(hs->state == SSL3_ST_CW_KEY_EXCH_A);
-
uint8_t *pms = NULL;
size_t pms_len = 0;
CBB cbb, body;
@@ -1647,10 +1676,9 @@
/* The message must be added to the finished hash before calculating the
* master secret. */
- if (!ssl_complete_message(ssl, &cbb)) {
+ if (!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
- hs->state = SSL3_ST_CW_KEY_EXCH_B;
ssl->s3->new_session->master_key_length =
tls1_generate_master_secret(ssl, ssl->s3->new_session->master_key, pms,
@@ -1663,7 +1691,7 @@
OPENSSL_cleanse(pms, pms_len);
OPENSSL_free(pms);
- return ssl->method->write_message(ssl);
+ return 1;
err:
CBB_cleanup(&cbb);
@@ -1676,10 +1704,6 @@
static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_CW_CERT_VRFY_C) {
- return ssl->method->write_message(ssl);
- }
-
assert(ssl_has_private_key(ssl));
CBB cbb, body, child;
@@ -1765,12 +1789,11 @@
}
if (!CBB_did_write(&child, sig_len) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
- hs->state = SSL3_ST_CW_CERT_VRFY_C;
- return ssl->method->write_message(ssl);
+ return 1;
err:
CBB_cleanup(&cbb);
@@ -1779,12 +1802,6 @@
static int ssl3_send_next_proto(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_CW_NEXT_PROTO_B) {
- return ssl->method->write_message(ssl);
- }
-
- assert(hs->state == SSL3_ST_CW_NEXT_PROTO_A);
-
static const uint8_t kZero[32] = {0};
size_t padding_len = 32 - ((ssl->s3->next_proto_negotiated_len + 2) % 32);
@@ -1795,24 +1812,17 @@
ssl->s3->next_proto_negotiated_len) ||
!CBB_add_u8_length_prefixed(&body, &child) ||
!CBB_add_bytes(&child, kZero, padding_len) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return -1;
}
- hs->state = SSL3_ST_CW_NEXT_PROTO_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int ssl3_send_channel_id(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_CW_CHANNEL_ID_B) {
- return ssl->method->write_message(ssl);
- }
-
- assert(hs->state == SSL3_ST_CW_CHANNEL_ID_A);
-
if (!ssl_do_channel_id_callback(ssl)) {
return -1;
}
@@ -1825,24 +1835,27 @@
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CHANNEL_ID) ||
!tls1_write_channel_id(ssl, &body) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return -1;
}
- hs->state = SSL3_ST_CW_CHANNEL_ID_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int ssl3_get_new_session_ticket(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = ssl->method->ssl_get_message(ssl, SSL3_MT_NEW_SESSION_TICKET,
- ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_NEW_SESSION_TICKET) ||
+ !ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
CBS new_session_ticket, ticket;
uint32_t tlsext_tick_lifetime_hint;
CBS_init(&new_session_ticket, ssl->init_msg, ssl->init_num);
@@ -1877,7 +1890,7 @@
}
/* |tlsext_tick_lifetime_hint| is measured from when the ticket was issued. */
- ssl_session_refresh_time(ssl, session);
+ ssl_session_rebase_time(ssl, session);
if (!CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
diff --git a/src/ssl/handshake_server.c b/src/ssl/handshake_server.c
index a4396f4..7b66cf2 100644
--- a/src/ssl/handshake_server.c
+++ b/src/ssl/handshake_server.c
@@ -185,6 +185,17 @@
static int ssl3_get_channel_id(SSL_HANDSHAKE *hs);
static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs);
+static struct CRYPTO_STATIC_MUTEX g_v2clienthello_lock =
+ CRYPTO_STATIC_MUTEX_INIT;
+static uint64_t g_v2clienthello_count = 0;
+
+uint64_t SSL_get_v2clienthello_count(void) {
+ CRYPTO_STATIC_MUTEX_lock_read(&g_v2clienthello_lock);
+ uint64_t ret = g_v2clienthello_count;
+ CRYPTO_STATIC_MUTEX_unlock_read(&g_v2clienthello_lock);
+ return ret;
+}
+
int ssl3_accept(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
uint32_t alg_a;
@@ -206,13 +217,6 @@
case SSL_ST_ACCEPT:
ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1);
- /* Enable a write buffer. This groups handshake messages within a flight
- * into a single write. */
- if (!ssl_init_wbio_buffer(ssl)) {
- ret = -1;
- goto end;
- }
-
if (!ssl3_init_handshake_buffer(ssl)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
@@ -226,7 +230,6 @@
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
case SSL3_ST_SR_CLNT_HELLO_D:
- case SSL3_ST_SR_CLNT_HELLO_E:
ret = ssl3_get_client_hello(hs);
if (hs->state == SSL_ST_TLS13) {
break;
@@ -239,7 +242,6 @@
break;
case SSL3_ST_SW_SRVR_HELLO_A:
- case SSL3_ST_SW_SRVR_HELLO_B:
ret = ssl3_send_server_hello(hs);
if (ret <= 0) {
goto end;
@@ -252,7 +254,6 @@
break;
case SSL3_ST_SW_CERT_A:
- case SSL3_ST_SW_CERT_B:
if (ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
ret = ssl3_send_server_certificate(hs);
if (ret <= 0) {
@@ -265,7 +266,6 @@
break;
case SSL3_ST_SW_CERT_STATUS_A:
- case SSL3_ST_SW_CERT_STATUS_B:
if (hs->certificate_status_expected) {
ret = ssl3_send_certificate_status(hs);
if (ret <= 0) {
@@ -279,7 +279,6 @@
case SSL3_ST_SW_KEY_EXCH_A:
case SSL3_ST_SW_KEY_EXCH_B:
- case SSL3_ST_SW_KEY_EXCH_C:
alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
/* PSK ciphers send ServerKeyExchange if there is an identity hint. */
@@ -297,7 +296,6 @@
break;
case SSL3_ST_SW_CERT_REQ_A:
- case SSL3_ST_SW_CERT_REQ_B:
if (hs->cert_request) {
ret = ssl3_send_certificate_request(hs);
if (ret <= 0) {
@@ -310,7 +308,6 @@
break;
case SSL3_ST_SW_SRVR_DONE_A:
- case SSL3_ST_SW_SRVR_DONE_B:
ret = ssl3_send_server_hello_done(hs);
if (ret <= 0) {
goto end;
@@ -410,7 +407,6 @@
break;
case SSL3_ST_SW_SESSION_TICKET_A:
- case SSL3_ST_SW_SESSION_TICKET_B:
if (hs->ticket_expected) {
ret = ssl3_send_new_session_ticket(hs);
if (ret <= 0) {
@@ -423,22 +419,17 @@
break;
case SSL3_ST_SW_CHANGE:
- ret = ssl->method->send_change_cipher_spec(ssl);
- if (ret <= 0) {
- goto end;
- }
- hs->state = SSL3_ST_SW_FINISHED_A;
-
- if (!tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
+ if (!ssl->method->add_change_cipher_spec(ssl) ||
+ !tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
ret = -1;
goto end;
}
+
+ hs->state = SSL3_ST_SW_FINISHED_A;
break;
case SSL3_ST_SW_FINISHED_A:
- case SSL3_ST_SW_FINISHED_B:
- ret = ssl3_send_finished(hs, SSL3_ST_SW_FINISHED_A,
- SSL3_ST_SW_FINISHED_B);
+ ret = ssl3_send_finished(hs);
if (ret <= 0) {
goto end;
}
@@ -493,8 +484,11 @@
ssl->s3->new_session = NULL;
}
- /* remove buffering on output */
- ssl_free_wbio_buffer(ssl);
+ if (hs->v2_clienthello) {
+ CRYPTO_STATIC_MUTEX_lock_write(&g_v2clienthello_lock);
+ g_v2clienthello_count++;
+ CRYPTO_STATIC_MUTEX_unlock_write(&g_v2clienthello_lock);
+ }
ssl->s3->initial_handshake_complete = 1;
ssl_update_cache(hs, SSL_SESS_CACHE_SERVER);
@@ -546,6 +540,7 @@
static int negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
+ assert(!ssl->s3->have_version);
uint16_t min_version, max_version;
if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
*out_alert = SSL_AD_PROTOCOL_VERSION;
@@ -703,7 +698,7 @@
uint32_t mask_k = 0;
uint32_t mask_a = 0;
- if (ssl->cert->x509_leaf != NULL && ssl_has_private_key(ssl)) {
+ if (ssl_has_certificate(ssl)) {
int type = ssl_private_key_type(ssl);
if (type == NID_rsaEncryption) {
mask_k |= SSL_kRSA;
@@ -820,12 +815,15 @@
if (hs->state == SSL3_ST_SR_CLNT_HELLO_A) {
/* The first time around, read the ClientHello. */
- int msg_ret = ssl->method->ssl_get_message(ssl, SSL3_MT_CLIENT_HELLO,
- ssl_hash_message);
+ int msg_ret = ssl->method->ssl_get_message(ssl);
if (msg_ret <= 0) {
return msg_ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
+ return -1;
+ }
+
hs->state = SSL3_ST_SR_CLNT_HELLO_B;
}
@@ -855,23 +853,11 @@
/* fallthrough */;
}
}
- hs->state = SSL3_ST_SR_CLNT_HELLO_C;
- }
- /* Negotiate the protocol version if we have not done so yet. */
- if (!ssl->s3->have_version) {
if (!negotiate_version(hs, &al, &client_hello)) {
goto f_err;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- hs->state = SSL_ST_TLS13;
- hs->do_tls13_handshake = tls13_server_handshake;
- return 1;
- }
- }
-
- if (hs->state == SSL3_ST_SR_CLNT_HELLO_C) {
/* Load the client random. */
if (client_hello.random_len != SSL3_RANDOM_SIZE) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -880,11 +866,14 @@
OPENSSL_memcpy(ssl->s3->client_random, client_hello.random,
client_hello.random_len);
- /* Only null compression is supported. */
+ /* Only null compression is supported. TLS 1.3 further requires the peer
+ * advertise no other compression. */
if (OPENSSL_memchr(client_hello.compression_methods, 0,
- client_hello.compression_methods_len) == NULL) {
+ client_hello.compression_methods_len) == NULL ||
+ (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
+ client_hello.compression_methods_len != 1)) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMPRESSION_SPECIFIED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
goto f_err;
}
@@ -894,10 +883,10 @@
goto err;
}
- hs->state = SSL3_ST_SR_CLNT_HELLO_D;
+ hs->state = SSL3_ST_SR_CLNT_HELLO_C;
}
- if (hs->state == SSL3_ST_SR_CLNT_HELLO_D) {
+ if (hs->state == SSL3_ST_SR_CLNT_HELLO_C) {
/* Call |cert_cb| to update server certificates if required. */
if (ssl->cert->cert_cb != NULL) {
int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
@@ -916,6 +905,13 @@
goto err;
}
+ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ /* Jump to the TLS 1.3 state machine. */
+ hs->state = SSL_ST_TLS13;
+ hs->do_tls13_handshake = tls13_server_handshake;
+ return 1;
+ }
+
/* Negotiate the cipher suite. This must be done after |cert_cb| so the
* certificate is finalized. */
ssl->s3->tmp.new_cipher =
@@ -926,10 +922,10 @@
goto f_err;
}
- hs->state = SSL3_ST_SR_CLNT_HELLO_E;
+ hs->state = SSL3_ST_SR_CLNT_HELLO_D;
}
- assert(hs->state == SSL3_ST_SR_CLNT_HELLO_E);
+ assert(hs->state == SSL3_ST_SR_CLNT_HELLO_D);
/* Determine whether we are doing session resumption. */
int tickets_supported = 0, renew_ticket = 0;
@@ -1028,8 +1024,10 @@
goto f_err;
}
- /* Now that all parameters are known, initialize the handshake hash. */
- if (!ssl3_init_handshake_hash(ssl)) {
+ /* Now that all parameters are known, initialize the handshake hash and hash
+ * the ClientHello. */
+ if (!ssl3_init_handshake_hash(ssl) ||
+ !ssl_hash_current_message(ssl)) {
goto f_err;
}
@@ -1052,11 +1050,6 @@
static int ssl3_send_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_SRVR_HELLO_B) {
- return ssl->method->write_message(ssl);
- }
-
- assert(hs->state == SSL3_ST_SW_SRVR_HELLO_A);
/* We only accept ChannelIDs on connections with ECDHE in order to avoid a
* known attack while we fix ChannelID itself. */
@@ -1101,40 +1094,30 @@
!CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
!CBB_add_u8(&body, 0 /* no compression */) ||
!ssl_add_serverhello_tlsext(hs, &body) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return -1;
}
- hs->state = SSL3_ST_SW_SRVR_HELLO_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_CERT_B) {
- return ssl->method->write_message(ssl);
- }
-
if (!ssl_has_certificate(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
- return 0;
+ return -1;
}
if (!ssl3_output_cert_chain(ssl)) {
- return 0;
+ return -1;
}
- hs->state = SSL3_ST_SW_CERT_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int ssl3_send_certificate_status(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_CERT_STATUS_B) {
- return ssl->method->write_message(ssl);
- }
-
CBB cbb, body, ocsp_response;
if (!ssl->method->init_message(ssl, &cbb, &body,
SSL3_MT_CERTIFICATE_STATUS) ||
@@ -1142,22 +1125,17 @@
!CBB_add_u24_length_prefixed(&body, &ocsp_response) ||
!CBB_add_bytes(&ocsp_response, CRYPTO_BUFFER_data(ssl->ocsp_response),
CRYPTO_BUFFER_len(ssl->ocsp_response)) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return -1;
}
- hs->state = SSL3_ST_SW_CERT_STATUS_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_KEY_EXCH_C) {
- return ssl->method->write_message(ssl);
- }
-
CBB cbb, child;
CBB_zero(&cbb);
@@ -1317,7 +1295,7 @@
}
}
- if (!ssl_complete_message(ssl, &cbb)) {
+ if (!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
@@ -1325,8 +1303,7 @@
hs->server_params = NULL;
hs->server_params_len = 0;
- hs->state = SSL3_ST_SW_KEY_EXCH_C;
- return ssl->method->write_message(ssl);
+ return 1;
err:
CBB_cleanup(&cbb);
@@ -1373,10 +1350,6 @@
static int ssl3_send_certificate_request(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_CERT_REQ_B) {
- return ssl->method->write_message(ssl);
- }
-
CBB cbb, body, cert_types, sigalgs_cbb;
if (!ssl->method->init_message(ssl, &cbb, &body,
SSL3_MT_CERTIFICATE_REQUEST) ||
@@ -1400,12 +1373,11 @@
}
if (!ssl_add_client_CA_list(ssl, &body) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
- hs->state = SSL3_ST_SW_CERT_REQ_B;
- return ssl->method->write_message(ssl);
+ return 1;
err:
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1415,27 +1387,22 @@
static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_SRVR_DONE_B) {
- return ssl->method->write_message(ssl);
- }
-
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return -1;
}
- hs->state = SSL3_ST_SW_SRVR_DONE_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
assert(hs->cert_request);
- int msg_ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
+ int msg_ret = ssl->method->ssl_get_message(ssl);
if (msg_ret <= 0) {
return msg_ret;
}
@@ -1463,6 +1430,10 @@
return -1;
}
+ if (!ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
CBS certificate_msg;
CBS_init(&certificate_msg, ssl->init_msg, ssl->init_num);
@@ -1539,11 +1510,15 @@
uint8_t psk[PSK_MAX_PSK_LEN];
if (hs->state == SSL3_ST_SR_KEY_EXCH_A) {
- int ret = ssl->method->ssl_get_message(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE,
- ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+
+ if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE) ||
+ !ssl_hash_current_message(ssl)) {
+ return -1;
+ }
}
CBS_init(&client_key_exchange, ssl->init_msg, ssl->init_num);
@@ -1807,12 +1782,15 @@
return 1;
}
- int msg_ret = ssl->method->ssl_get_message(ssl, SSL3_MT_CERTIFICATE_VERIFY,
- ssl_dont_hash_message);
+ int msg_ret = ssl->method->ssl_get_message(ssl);
if (msg_ret <= 0) {
return msg_ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY)) {
+ return -1;
+ }
+
CBS_init(&certificate_verify, ssl->init_msg, ssl->init_num);
/* Determine the digest type if needbe. */
@@ -1900,12 +1878,16 @@
* sets the next_proto member in s if found */
static int ssl3_get_next_proto(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret =
- ssl->method->ssl_get_message(ssl, SSL3_MT_NEXT_PROTO, ssl_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_NEXT_PROTO) ||
+ !ssl_hash_current_message(ssl)) {
+ return -1;
+ }
+
CBS next_protocol, selected_protocol, padding;
CBS_init(&next_protocol, ssl->init_msg, ssl->init_num);
if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) ||
@@ -1927,13 +1909,13 @@
/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */
static int ssl3_get_channel_id(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int msg_ret = ssl->method->ssl_get_message(ssl, SSL3_MT_CHANNEL_ID,
- ssl_dont_hash_message);
+ int msg_ret = ssl->method->ssl_get_message(ssl);
if (msg_ret <= 0) {
return msg_ret;
}
- if (!tls1_verify_channel_id(ssl) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
+ !tls1_verify_channel_id(ssl) ||
!ssl_hash_current_message(ssl)) {
return -1;
}
@@ -1942,15 +1924,11 @@
static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == SSL3_ST_SW_SESSION_TICKET_B) {
- return ssl->method->write_message(ssl);
- }
-
const SSL_SESSION *session;
SSL_SESSION *session_copy = NULL;
if (ssl->session == NULL) {
/* Fix the timeout to measure from the ticket issuance time. */
- ssl_session_refresh_time(ssl, ssl->s3->new_session);
+ ssl_session_rebase_time(ssl, ssl->s3->new_session);
session = ssl->s3->new_session;
} else {
/* We are renewing an existing session. Duplicate the session to adjust the
@@ -1960,7 +1938,7 @@
return -1;
}
- ssl_session_refresh_time(ssl, session_copy);
+ ssl_session_rebase_time(ssl, session_copy);
session = session_copy;
}
@@ -1970,7 +1948,7 @@
CBB_add_u32(&body, session->timeout) &&
CBB_add_u16_length_prefixed(&body, &ticket) &&
ssl_encrypt_ticket(ssl, &ticket, session) &&
- ssl_complete_message(ssl, &cbb);
+ ssl_add_message_cbb(ssl, &cbb);
SSL_SESSION_free(session_copy);
CBB_cleanup(&cbb);
@@ -1979,6 +1957,5 @@
return -1;
}
- hs->state = SSL3_ST_SW_SESSION_TICKET_B;
- return ssl->method->write_message(ssl);
+ return 1;
}
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index a320e72..544259c 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -273,22 +273,22 @@
uint8_t fixed_nonce_len, variable_nonce_len;
/* variable_nonce_included_in_record is non-zero if the variable nonce
* for a record is included as a prefix before the ciphertext. */
- char variable_nonce_included_in_record;
+ unsigned variable_nonce_included_in_record : 1;
/* random_variable_nonce is non-zero if the variable nonce is
* randomly generated, rather than derived from the sequence
* number. */
- char random_variable_nonce;
+ unsigned random_variable_nonce : 1;
/* omit_length_in_ad is non-zero if the length should be omitted in the
* AEAD's ad parameter. */
- char omit_length_in_ad;
+ unsigned omit_length_in_ad : 1;
/* omit_version_in_ad is non-zero if the version should be omitted
* in the AEAD's ad parameter. */
- char omit_version_in_ad;
+ unsigned omit_version_in_ad : 1;
/* omit_ad is non-zero if the AEAD's ad parameter should be omitted. */
- char omit_ad;
+ unsigned omit_ad : 1;
/* xor_fixed_nonce is non-zero if the fixed nonce should be XOR'd into the
* variable nonce rather than prepended. */
- char xor_fixed_nonce;
+ unsigned xor_fixed_nonce : 1;
} SSL_AEAD_CTX;
/* SSL_AEAD_CTX_new creates a newly-allocated |SSL_AEAD_CTX| using the supplied
@@ -433,6 +433,10 @@
dtls1_use_current_epoch,
};
+/* dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a
+ * record. */
+size_t dtls_max_seal_overhead(const SSL *ssl, enum dtls1_use_epoch_t use_epoch);
+
/* dtls_seal_prefix_len returns the number of bytes of prefix to reserve in
* front of the plaintext when sealing a record in-place. */
size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch);
@@ -769,10 +773,6 @@
CBS *cbs,
CRYPTO_BUFFER_POOL *pool);
-/* ssl_add_cert_to_cbb adds |x509| to |cbb|. It returns one on success and zero
- * on error. */
-int ssl_add_cert_to_cbb(CBB *cbb, X509 *x509);
-
/* ssl_add_cert_chain adds |ssl|'s certificate chain to |cbb| in the format used
* by a TLS Certificate message. If there is no certificate chain, it emits an
* empty certificate list. It returns one on success and zero on error. */
@@ -884,7 +884,6 @@
ssl_hs_error,
ssl_hs_ok,
ssl_hs_read_message,
- ssl_hs_write_message,
ssl_hs_flush,
ssl_hs_flush_and_read_message,
ssl_hs_x509_lookup,
@@ -1053,6 +1052,9 @@
* or received. */
unsigned ticket_expected:1;
+ /* v2_clienthello is one if we received a V2ClientHello. */
+ unsigned v2_clienthello:1;
+
/* client_version is the value sent or received in the ClientHello version. */
uint16_t client_version;
} /* SSL_HANDSHAKE */;
@@ -1062,6 +1064,10 @@
/* ssl_handshake_free releases all memory associated with |hs|. */
void ssl_handshake_free(SSL_HANDSHAKE *hs);
+/* ssl_check_message_type checks if the current message has type |type|. If so
+ * it returns one. Otherwise, it sends an alert and returns zero. */
+int ssl_check_message_type(SSL *ssl, int type);
+
/* tls13_handshake runs the TLS 1.3 handshake. It returns one on success and <=
* 0 on error. */
int tls13_handshake(SSL_HANDSHAKE *hs);
@@ -1075,18 +1081,14 @@
* success and zero on failure. */
int tls13_post_handshake(SSL *ssl);
-/* tls13_check_message_type checks if the current message has type |type|. If so
- * it returns one. Otherwise, it sends an alert and returns zero. */
-int tls13_check_message_type(SSL *ssl, int type);
-
int tls13_process_certificate(SSL_HANDSHAKE *hs, int allow_anonymous);
int tls13_process_certificate_verify(SSL_HANDSHAKE *hs);
int tls13_process_finished(SSL_HANDSHAKE *hs);
-int tls13_prepare_certificate(SSL_HANDSHAKE *hs);
-enum ssl_private_key_result_t tls13_prepare_certificate_verify(
- SSL_HANDSHAKE *hs, int is_first_run);
-int tls13_prepare_finished(SSL_HANDSHAKE *hs);
+int tls13_add_certificate(SSL_HANDSHAKE *hs);
+enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs,
+ int is_first_run);
+int tls13_add_finished(SSL_HANDSHAKE *hs);
int tls13_process_new_session_ticket(SSL *ssl);
int ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t **out_secret,
@@ -1222,28 +1224,36 @@
/* From RFC4492, used in encoding the curve type in ECParameters */
#define NAMED_CURVE_TYPE 3
-enum ssl_hash_message_t {
- ssl_dont_hash_message,
- ssl_hash_message,
-};
-
typedef struct cert_st {
EVP_PKEY *privatekey;
- X509 *x509_leaf;
+
+ /* chain contains the certificate chain, with the leaf at the beginning. The
+ * first element of |chain| may be NULL to indicate that the leaf certificate
+ * has not yet been set.
+ * If |chain| != NULL -> len(chain) >= 1
+ * If |chain[0]| == NULL -> len(chain) >= 2.
+ * |chain[1..]| != NULL */
+ STACK_OF(CRYPTO_BUFFER) *chain;
+
+ /* x509_chain may contain a parsed copy of |chain[1..]|. This is only used as
+ * a cache in order to implement “get0” functions that return a non-owning
+ * pointer to the certificate chain. */
STACK_OF(X509) *x509_chain;
+ /* x509_leaf may contain a parsed copy of the first element of |chain|. This
+ * is only used as a cache in order to implement “get0” functions that return
+ * a non-owning pointer to the certificate chain. */
+ X509 *x509_leaf;
+
+ /* x509_stash contains the last |X509| object append to the chain. This is a
+ * workaround for some third-party code that continue to use an |X509| object
+ * even after passing ownership with an “add0” function. */
+ X509 *x509_stash;
+
/* key_method, if non-NULL, is a set of callbacks to call for private key
* operations. */
const SSL_PRIVATE_KEY_METHOD *key_method;
- /* For clients the following masks are of *disabled* key and auth algorithms
- * based on the current configuration.
- *
- * TODO(davidben): Remove these. They get checked twice: when sending the
- * ClientHello and when processing the ServerHello. */
- uint32_t mask_k;
- uint32_t mask_a;
-
DH *dh_tmp;
DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize);
@@ -1294,12 +1304,10 @@
uint16_t (*version_to_wire)(uint16_t version);
int (*ssl_new)(SSL *ssl);
void (*ssl_free)(SSL *ssl);
- /* ssl_get_message reads the next handshake message. If |msg_type| is not -1,
- * the message must have the specified type. On success, it returns one and
- * sets |ssl->s3->tmp.message_type|, |ssl->init_msg|, and |ssl->init_num|.
- * Otherwise, it returns <= 0. */
- int (*ssl_get_message)(SSL *ssl, int msg_type,
- enum ssl_hash_message_t hash_message);
+ /* ssl_get_message reads the next handshake message. On success, it returns
+ * one and sets |ssl->s3->tmp.message_type|, |ssl->init_msg|, and
+ * |ssl->init_num|. Otherwise, it returns <= 0. */
+ int (*ssl_get_message)(SSL *ssl);
/* get_current_message sets |*out| to the current handshake message. This
* includes the protocol-specific message header. */
void (*get_current_message)(const SSL *ssl, CBS *out);
@@ -1311,11 +1319,11 @@
* and sets |*out_got_handshake| to whether the failure was due to a
* post-handshake handshake message. If so, it fills in the current message as
* in |ssl_get_message|. */
- int (*read_app_data)(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len,
+ int (*read_app_data)(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len,
int peek);
int (*read_change_cipher_spec)(SSL *ssl);
void (*read_close_notify)(SSL *ssl);
- int (*write_app_data)(SSL *ssl, const void *buf_, int len);
+ int (*write_app_data)(SSL *ssl, const uint8_t *buf, int len);
int (*dispatch_alert)(SSL *ssl);
/* supports_cipher returns one if |cipher| is supported by this protocol and
* zero otherwise. */
@@ -1329,16 +1337,17 @@
* release it with |OPENSSL_free| when done. It returns one on success and
* zero on error. */
int (*finish_message)(SSL *ssl, CBB *cbb, uint8_t **out_msg, size_t *out_len);
- /* queue_message queues a handshake message and prepares it to be written. It
- * takes ownership of |msg| and releases it with |OPENSSL_free| when done. It
- * returns one on success and zero on error. */
- int (*queue_message)(SSL *ssl, uint8_t *msg, size_t len);
- /* write_message writes the next message to the transport. It returns one on
- * success and <= 0 on error. */
- int (*write_message)(SSL *ssl);
- /* send_change_cipher_spec sends a ChangeCipherSpec message. */
- int (*send_change_cipher_spec)(SSL *ssl);
- /* flush_flight flushes the current flight to the transport. It returns one on
+ /* add_message adds a handshake message to the pending flight. It returns one
+ * on success and zero on error. In either case, it takes ownership of |msg|
+ * and releases it with |OPENSSL_free| when done. */
+ int (*add_message)(SSL *ssl, uint8_t *msg, size_t len);
+ /* add_change_cipher_spec adds a ChangeCipherSpec record to the pending
+ * flight. It returns one on success and zero on error. */
+ int (*add_change_cipher_spec)(SSL *ssl);
+ /* add_alert adds an alert to the pending flight. It returns one on success
+ * and zero on error. */
+ int (*add_alert)(SSL *ssl, uint8_t level, uint8_t desc);
+ /* flush_flight flushes the pending flight to the transport. It returns one on
* success and <= 0 on error. */
int (*flush_flight)(SSL *ssl);
/* expect_flight is called when the handshake expects a flight of messages from
@@ -1466,6 +1475,10 @@
* and future messages should use the record layer. */
unsigned v2_hello_done:1;
+ /* is_v2_hello is true if the current handshake message was derived from a
+ * V2ClientHello rather than received from the peer directly. */
+ unsigned is_v2_hello:1;
+
/* initial_handshake_complete is true if the initial handshake has
* completed. */
unsigned initial_handshake_complete:1;
@@ -1487,9 +1500,13 @@
uint8_t send_alert[2];
- /* pending_message is the current outgoing handshake message. */
- uint8_t *pending_message;
- uint32_t pending_message_len;
+ /* pending_flight is the pending outgoing flight. This is used to flush each
+ * handshake flight in a single write. */
+ BUF_MEM *pending_flight;
+
+ /* pending_flight_offset is the number of bytes of |pending_flight| which have
+ * been successfully written. */
+ uint32_t pending_flight_offset;
/* aead_read_ctx is the current read cipher state. */
SSL_AEAD_CTX *aead_read_ctx;
@@ -1645,6 +1662,13 @@
DTLS_OUTGOING_MESSAGE outgoing_messages[SSL_MAX_HANDSHAKE_FLIGHT];
uint8_t outgoing_messages_len;
+ /* outgoing_written is the number of outgoing messages that have been
+ * written. */
+ uint8_t outgoing_written;
+ /* outgoing_offset is the number of bytes of the next outgoing message have
+ * been written. */
+ uint32_t outgoing_offset;
+
unsigned int mtu; /* max DTLS packet size */
/* num_timeouts is the number of times the retransmit timer has fired since
@@ -1675,6 +1699,15 @@
CERT *ssl_cert_dup(CERT *cert);
void ssl_cert_clear_certs(CERT *c);
void ssl_cert_free(CERT *c);
+CRYPTO_BUFFER *x509_to_buffer(X509 *x509);
+void ssl_cert_flush_cached_x509_leaf(CERT *cert);
+int ssl_cert_cache_leaf_cert(CERT *cert);
+/* ssl_compare_public_and_private_key returns one if |pubkey| is the public
+ * counterpart to |privkey|. Otherwise it returns zero and pushes a helpful
+ * message on the error queue. */
+int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
+ const EVP_PKEY *privkey);
+int ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey);
int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server);
int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session);
@@ -1720,9 +1753,14 @@
OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session,
int dup_flags);
-/* ssl_session_refresh_time updates |session|'s start time to the current time,
+/* ssl_session_rebase_time updates |session|'s start time to the current time,
* adjusting the timeout so the expiration time is unchanged. */
-void ssl_session_refresh_time(SSL *ssl, SSL_SESSION *session);
+void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session);
+
+/* ssl_session_renew_timeout calls |ssl_session_rebase_time| and renews
+ * |session|'s timeout to |timeout| (measured from the current time). The
+ * renewal is clamped to the session's auth_timeout. */
+void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, long timeout);
void ssl_cipher_preference_list_free(
struct ssl_cipher_preference_list_st *cipher_list);
@@ -1739,10 +1777,8 @@
int ssl_verify_alarm_type(long type);
int ssl3_get_finished(SSL_HANDSHAKE *hs);
-int ssl3_send_change_cipher_spec(SSL *ssl);
int ssl3_send_alert(SSL *ssl, int level, int desc);
-int ssl3_get_message(SSL *ssl, int msg_type,
- enum ssl_hash_message_t hash_message);
+int ssl3_get_message(SSL *ssl);
void ssl3_get_current_message(const SSL *ssl, CBS *out);
void ssl3_release_current_message(SSL *ssl, int free_buffer);
@@ -1753,15 +1789,14 @@
int ssl3_cert_verify_hash(SSL *ssl, const EVP_MD **out_md, uint8_t *out,
size_t *out_len, uint16_t signature_algorithm);
-int ssl3_send_finished(SSL_HANDSHAKE *hs, int a, int b);
+int ssl3_send_finished(SSL_HANDSHAKE *hs);
int ssl3_dispatch_alert(SSL *ssl);
int ssl3_read_app_data(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len,
int peek);
int ssl3_read_change_cipher_spec(SSL *ssl);
void ssl3_read_close_notify(SSL *ssl);
int ssl3_read_handshake_bytes(SSL *ssl, uint8_t *buf, int len);
-int ssl3_write_app_data(SSL *ssl, const void *buf, int len);
-int ssl3_write_bytes(SSL *ssl, int type, const void *buf, int len);
+int ssl3_write_app_data(SSL *ssl, const uint8_t *buf, int len);
int ssl3_output_cert_chain(SSL *ssl);
int ssl3_new(SSL *ssl);
@@ -1771,18 +1806,22 @@
int ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
int ssl3_finish_message(SSL *ssl, CBB *cbb, uint8_t **out_msg, size_t *out_len);
-int ssl3_queue_message(SSL *ssl, uint8_t *msg, size_t len);
-int ssl3_write_message(SSL *ssl);
+int ssl3_add_message(SSL *ssl, uint8_t *msg, size_t len);
+int ssl3_add_change_cipher_spec(SSL *ssl);
+int ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc);
+int ssl3_flush_flight(SSL *ssl);
int dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
int dtls1_finish_message(SSL *ssl, CBB *cbb, uint8_t **out_msg,
size_t *out_len);
-int dtls1_queue_message(SSL *ssl, uint8_t *msg, size_t len);
-int dtls1_write_message(SSL *ssl);
+int dtls1_add_message(SSL *ssl, uint8_t *msg, size_t len);
+int dtls1_add_change_cipher_spec(SSL *ssl);
+int dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc);
+int dtls1_flush_flight(SSL *ssl);
-/* ssl_complete_message calls |finish_message| and |queue_message| on |cbb| to
- * queue the message for writing. */
-int ssl_complete_message(SSL *ssl, CBB *cbb);
+/* ssl_add_message_cbb finishes the handshake message in |cbb| and adds it to
+ * the pending flight. It returns one on success and zero on error. */
+int ssl_add_message_cbb(SSL *ssl, CBB *cbb);
/* ssl_hash_current_message incorporates the current handshake message into the
* handshake hash. It returns one on success and zero on allocation failure. */
@@ -1798,14 +1837,13 @@
int dtls1_read_change_cipher_spec(SSL *ssl);
void dtls1_read_close_notify(SSL *ssl);
-int dtls1_write_app_data(SSL *ssl, const void *buf, int len);
+int dtls1_write_app_data(SSL *ssl, const uint8_t *buf, int len);
/* dtls1_write_record sends a record. It returns one on success and <= 0 on
* error. */
int dtls1_write_record(SSL *ssl, int type, const uint8_t *buf, size_t len,
enum dtls1_use_epoch_t use_epoch);
-int dtls1_send_change_cipher_spec(SSL *ssl);
int dtls1_send_finished(SSL *ssl, int a, int b, const char *sender, int slen);
int dtls1_retransmit_outgoing_messages(SSL *ssl);
void dtls1_clear_record_buffer(SSL *ssl);
@@ -1825,18 +1863,11 @@
int dtls1_connect(SSL *ssl);
void dtls1_free(SSL *ssl);
-int dtls1_get_message(SSL *ssl, int mt, enum ssl_hash_message_t hash_message);
+int dtls1_get_message(SSL *ssl);
void dtls1_get_current_message(const SSL *ssl, CBS *out);
void dtls1_release_current_message(SSL *ssl, int free_buffer);
int dtls1_dispatch_alert(SSL *ssl);
-/* ssl_is_wbio_buffered returns one if |ssl|'s write BIO is buffered and zero
- * otherwise. */
-int ssl_is_wbio_buffered(const SSL *ssl);
-
-int ssl_init_wbio_buffer(SSL *ssl);
-void ssl_free_wbio_buffer(SSL *ssl);
-
int tls1_change_cipher_state(SSL_HANDSHAKE *hs, int which);
int tls1_handshake_digest(SSL *ssl, uint8_t *out, size_t out_len);
int tls1_generate_master_secret(SSL *ssl, uint8_t *out, const uint8_t *premaster,
@@ -1935,8 +1966,6 @@
uint32_t ssl_get_algorithm_prf(const SSL *ssl);
-void ssl_set_client_disabled(SSL *ssl);
-
void ssl_get_current_time(const SSL *ssl, struct timeval *out_clock);
/* ssl_reset_error_state resets state for |SSL_get_error|. */
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 492884f..8d2657f 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -180,33 +180,56 @@
OPENSSL_free(hs);
}
-/* ssl3_do_write sends |ssl->init_buf| in records of type 'type'
- * (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC). It returns 1 on success
- * and <= 0 on error. */
-static int ssl3_do_write(SSL *ssl, int type, const uint8_t *data, size_t len) {
- int ret = ssl3_write_bytes(ssl, type, data, len);
- if (ret <= 0) {
- return ret;
+int ssl_check_message_type(SSL *ssl, int type) {
+ if (ssl->s3->tmp.message_type != type) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
+ ERR_add_error_dataf("got type %d, wanted type %d",
+ ssl->s3->tmp.message_type, type);
+ return 0;
}
- /* ssl3_write_bytes writes the data in its entirety. */
- assert((size_t)ret == len);
- ssl_do_msg_callback(ssl, 1 /* write */, type, data, len);
+ return 1;
+}
+
+static int add_record_to_flight(SSL *ssl, uint8_t type, const uint8_t *in,
+ size_t in_len) {
+ /* We'll never add a flight while in the process of writing it out. */
+ assert(ssl->s3->pending_flight_offset == 0);
+
+ if (ssl->s3->pending_flight == NULL) {
+ ssl->s3->pending_flight = BUF_MEM_new();
+ if (ssl->s3->pending_flight == NULL) {
+ return 0;
+ }
+ }
+
+ size_t max_out = in_len + SSL_max_seal_overhead(ssl);
+ size_t new_cap = ssl->s3->pending_flight->length + max_out;
+ if (max_out < in_len || new_cap < max_out) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+
+ size_t len;
+ if (!BUF_MEM_reserve(ssl->s3->pending_flight, new_cap) ||
+ !tls_seal_record(ssl, (uint8_t *)ssl->s3->pending_flight->data +
+ ssl->s3->pending_flight->length,
+ &len, max_out, type, in, in_len)) {
+ return 0;
+ }
+
+ ssl->s3->pending_flight->length += len;
return 1;
}
int ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
- CBB_zero(cbb);
- if (ssl->s3->pending_message != NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
/* Pick a modest size hint to save most of the |realloc| calls. */
if (!CBB_init(cbb, 64) ||
!CBB_add_u8(cbb, type) ||
!CBB_add_u24_length_prefixed(cbb, body)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(cbb);
return 0;
}
@@ -223,56 +246,113 @@
return 1;
}
-int ssl3_queue_message(SSL *ssl, uint8_t *msg, size_t len) {
- if (ssl->s3->pending_message != NULL ||
- len > 0xffffffffu) {
- OPENSSL_free(msg);
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+int ssl3_add_message(SSL *ssl, uint8_t *msg, size_t len) {
+ /* Add the message to the current flight, splitting into several records if
+ * needed. */
+ int ret = 0;
+ size_t added = 0;
+ do {
+ size_t todo = len - added;
+ if (todo > ssl->max_send_fragment) {
+ todo = ssl->max_send_fragment;
+ }
+
+ if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, msg + added, todo)) {
+ goto err;
+ }
+ added += todo;
+ } while (added < len);
+
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg, len);
+ ssl3_update_handshake_hash(ssl, msg, len);
+ ret = 1;
+
+err:
+ OPENSSL_free(msg);
+ return ret;
+}
+
+int ssl3_add_change_cipher_spec(SSL *ssl) {
+ static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
+
+ if (!add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
+ sizeof(kChangeCipherSpec))) {
return 0;
}
- ssl3_update_handshake_hash(ssl, msg, len);
-
- ssl->s3->pending_message = msg;
- ssl->s3->pending_message_len = (uint32_t)len;
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
+ kChangeCipherSpec, sizeof(kChangeCipherSpec));
return 1;
}
-int ssl_complete_message(SSL *ssl, CBB *cbb) {
+int ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc) {
+ uint8_t alert[2] = {level, desc};
+ if (!add_record_to_flight(ssl, SSL3_RT_ALERT, alert, sizeof(alert))) {
+ return 0;
+ }
+
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, alert, sizeof(alert));
+ ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, ((int)level << 8) | desc);
+ return 1;
+}
+
+int ssl_add_message_cbb(SSL *ssl, CBB *cbb) {
uint8_t *msg;
size_t len;
if (!ssl->method->finish_message(ssl, cbb, &msg, &len) ||
- !ssl->method->queue_message(ssl, msg, len)) {
+ !ssl->method->add_message(ssl, msg, len)) {
return 0;
}
return 1;
}
-int ssl3_write_message(SSL *ssl) {
- if (ssl->s3->pending_message == NULL) {
+int ssl3_flush_flight(SSL *ssl) {
+ if (ssl->s3->pending_flight == NULL) {
+ return 1;
+ }
+
+ if (ssl->s3->pending_flight->length > 0xffffffff ||
+ ssl->s3->pending_flight->length > INT_MAX) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
+ return -1;
}
- int ret = ssl3_do_write(ssl, SSL3_RT_HANDSHAKE, ssl->s3->pending_message,
- ssl->s3->pending_message_len);
- if (ret <= 0) {
- return ret;
+ /* The handshake flight buffer is mutually exclusive with application data.
+ *
+ * TODO(davidben): This will not be true when closure alerts use this. */
+ if (ssl_write_buffer_is_pending(ssl)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
- OPENSSL_free(ssl->s3->pending_message);
- ssl->s3->pending_message = NULL;
- ssl->s3->pending_message_len = 0;
+ /* Write the pending flight. */
+ while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) {
+ int ret = BIO_write(
+ ssl->wbio,
+ ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset,
+ ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset);
+ if (ret <= 0) {
+ ssl->rwstate = SSL_WRITING;
+ return ret;
+ }
+
+ ssl->s3->pending_flight_offset += ret;
+ }
+
+ if (BIO_flush(ssl->wbio) <= 0) {
+ ssl->rwstate = SSL_WRITING;
+ return -1;
+ }
+
+ BUF_MEM_free(ssl->s3->pending_flight);
+ ssl->s3->pending_flight = NULL;
+ ssl->s3->pending_flight_offset = 0;
return 1;
}
-int ssl3_send_finished(SSL_HANDSHAKE *hs, int a, int b) {
+int ssl3_send_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->state == b) {
- return ssl->method->write_message(ssl);
- }
-
uint8_t finished[EVP_MAX_MD_SIZE];
size_t finished_len =
ssl->s3->enc_method->final_finish_mac(ssl, ssl->server, finished);
@@ -307,24 +387,26 @@
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_FINISHED) ||
!CBB_add_bytes(&body, finished, finished_len) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return -1;
}
- hs->state = b;
- return ssl->method->write_message(ssl);
+ return 1;
}
int ssl3_get_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = ssl->method->ssl_get_message(ssl, SSL3_MT_FINISHED,
- ssl_dont_hash_message);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+ if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED)) {
+ return -1;
+ }
+
/* Snapshot the finished hash before incorporating the new message. */
uint8_t finished[EVP_MAX_MD_SIZE];
size_t finished_len =
@@ -365,18 +447,11 @@
return 1;
}
-int ssl3_send_change_cipher_spec(SSL *ssl) {
- static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
-
- return ssl3_do_write(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
- sizeof(kChangeCipherSpec));
-}
-
int ssl3_output_cert_chain(SSL *ssl) {
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) ||
!ssl_add_cert_chain(ssl, &body) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
return 0;
@@ -431,7 +506,7 @@
return 1;
}
-static int read_v2_client_hello(SSL *ssl, int *out_is_v2_client_hello) {
+static int read_v2_client_hello(SSL *ssl) {
/* Read the first 5 bytes, the size of the TLS record header. This is
* sufficient to detect a V2ClientHello and ensures that we never read beyond
* the first record. */
@@ -459,7 +534,6 @@
if ((p[0] & 0x80) == 0 || p[2] != SSL2_MT_CLIENT_HELLO ||
p[3] != SSL3_VERSION_MAJOR) {
/* Not a V2ClientHello. */
- *out_is_v2_client_hello = 0;
return 1;
}
@@ -581,12 +655,13 @@
ssl_read_buffer_consume(ssl, 2 + msg_length);
ssl_read_buffer_discard(ssl);
- *out_is_v2_client_hello = 1;
+ ssl->s3->is_v2_hello = 1;
+ /* This is the first message, so hs must be non-NULL. */
+ ssl->s3->hs->v2_clienthello = 1;
return 1;
}
-int ssl3_get_message(SSL *ssl, int msg_type,
- enum ssl_hash_message_t hash_message) {
+int ssl3_get_message(SSL *ssl) {
again:
/* Re-create the handshake buffer if needed. */
if (ssl->init_buf == NULL) {
@@ -598,28 +673,17 @@
if (ssl->server && !ssl->s3->v2_hello_done) {
/* Bypass the record layer for the first message to handle V2ClientHello. */
- assert(hash_message == ssl_hash_message);
- int is_v2_client_hello = 0;
- int ret = read_v2_client_hello(ssl, &is_v2_client_hello);
+ int ret = read_v2_client_hello(ssl);
if (ret <= 0) {
return ret;
}
- if (is_v2_client_hello) {
- /* V2ClientHello is hashed separately. */
- hash_message = ssl_dont_hash_message;
- }
ssl->s3->v2_hello_done = 1;
}
if (ssl->s3->tmp.reuse_message) {
- /* A ssl_dont_hash_message call cannot be combined with reuse_message; the
- * ssl_dont_hash_message would have to have been applied to the previous
- * call. */
- assert(hash_message == ssl_hash_message);
+ /* There must be a current message. */
assert(ssl->init_msg != NULL);
-
ssl->s3->tmp.reuse_message = 0;
- hash_message = ssl_dont_hash_message;
} else {
ssl3_release_current_message(ssl, 0 /* don't free buffer */);
}
@@ -663,17 +727,6 @@
goto again;
}
- if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- /* Feed this message into MAC computation. */
- if (hash_message == ssl_hash_message && !ssl_hash_current_message(ssl)) {
- return -1;
- }
-
return 1;
}
@@ -682,6 +735,11 @@
}
int ssl_hash_current_message(SSL *ssl) {
+ /* V2ClientHellos are hashed implicitly. */
+ if (ssl->s3->is_v2_hello) {
+ return 1;
+ }
+
CBS cbs;
ssl->method->get_current_message(ssl, &cbs);
return ssl3_update_handshake_hash(ssl, CBS_data(&cbs), CBS_len(&cbs));
@@ -696,6 +754,7 @@
ssl->init_msg = NULL;
ssl->init_num = 0;
ssl->init_buf->length = 0;
+ ssl->s3->is_v2_hello = 0;
}
if (free_buffer) {
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 7039418..3f44629 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -209,7 +209,7 @@
OPENSSL_free(ssl->s3->alpn_selected);
SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
- OPENSSL_free(ssl->s3->pending_message);
+ BUF_MEM_free(ssl->s3->pending_flight);
OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
OPENSSL_free(ssl->s3);
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 9bd9f1f..5d5b7e8 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -188,16 +188,9 @@
return -1;
}
-int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
+int ssl3_write_app_data(SSL *ssl, const uint8_t *buf, int len) {
assert(!SSL_in_init(ssl) || SSL_in_false_start(ssl));
- return ssl3_write_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len);
-}
-
-/* Call this to write data in records of type |type|. It will return <= 0 if
- * not all data has been sent or non-blocking IO. */
-int ssl3_write_bytes(SSL *ssl, int type, const void *buf_, int len) {
- const uint8_t *buf = buf_;
unsigned tot, n, nw;
assert(ssl->s3->wnum <= INT_MAX);
@@ -216,7 +209,7 @@
return -1;
}
- n = (len - tot);
+ n = len - tot;
for (;;) {
/* max contains the maximum number of bytes that we can put into a
* record. */
@@ -227,14 +220,13 @@
nw = n;
}
- int ret = do_ssl3_write(ssl, type, &buf[tot], nw);
+ int ret = do_ssl3_write(ssl, SSL3_RT_APPLICATION_DATA, &buf[tot], nw);
if (ret <= 0) {
ssl->s3->wnum = tot;
return ret;
}
- if (ret == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
- (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
+ if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) {
return tot + ret;
}
@@ -267,13 +259,12 @@
return ssl3_write_pending(ssl, type, buf, len);
}
- /* If we have an alert to send, lets send it */
- if (ssl->s3->alert_dispatch) {
- int ret = ssl->method->dispatch_alert(ssl);
- if (ret <= 0) {
- return ret;
- }
- /* if it went, fall through and send more stuff */
+ /* The handshake flight buffer is mutually exclusive with application data.
+ *
+ * TODO(davidben): This will not be true when closure alerts use this. */
+ if (ssl->s3->pending_flight != NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
@@ -364,7 +355,7 @@
}
/* Parse post-handshake handshake messages. */
- int ret = ssl3_get_message(ssl, -1, ssl_dont_hash_message);
+ int ret = ssl3_get_message(ssl);
if (ret <= 0) {
return ret;
}
@@ -456,10 +447,11 @@
return -1;
}
- if (level == SSL3_AL_FATAL) {
- ssl->s3->send_shutdown = ssl_shutdown_fatal_alert;
- } else if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) {
+ if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) {
ssl->s3->send_shutdown = ssl_shutdown_close_notify;
+ } else {
+ assert(level == SSL3_AL_FATAL);
+ ssl->s3->send_shutdown = ssl_shutdown_fatal_alert;
}
ssl->s3->alert_dispatch = 1;
@@ -476,12 +468,11 @@
}
int ssl3_dispatch_alert(SSL *ssl) {
- ssl->s3->alert_dispatch = 0;
int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
if (ret <= 0) {
- ssl->s3->alert_dispatch = 1;
return ret;
}
+ ssl->s3->alert_dispatch = 0;
/* If the alert is fatal, flush the BIO now. */
if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.c
index c9dfdcc..4c1ee89 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.c
@@ -129,10 +129,11 @@
* isServer [22] BOOLEAN DEFAULT TRUE,
* peerSignatureAlgorithm [23] INTEGER OPTIONAL,
* ticketMaxEarlyData [24] INTEGER OPTIONAL,
+ * authTimeout [25] INTEGER OPTIONAL, -- defaults to timeout
* }
*
* Note: historically this serialization has included other optional
- * fields. Their presense is currently treated as a parse error:
+ * fields. Their presence is currently treated as a parse error:
*
* keyArg [0] IMPLICIT OCTET STRING OPTIONAL,
* pskIdentityHint [7] OCTET STRING OPTIONAL,
@@ -183,6 +184,8 @@
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23;
static const int kTicketMaxEarlyDataTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24;
+static const int kAuthTimeoutTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25;
static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
size_t *out_len, int for_ticket) {
@@ -402,6 +405,13 @@
goto err;
}
+ if (in->timeout != in->auth_timeout &&
+ (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) ||
+ !CBB_add_asn1_uint64(&child, in->auth_timeout))) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
if (!CBB_finish(&cbb, out_data, out_len)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -787,6 +797,8 @@
kPeerSignatureAlgorithmTag, 0) ||
!SSL_SESSION_parse_u32(&session, &ret->ticket_max_early_data,
kTicketMaxEarlyDataTag, 0) ||
+ !SSL_SESSION_parse_long(&session, &ret->auth_timeout, kAuthTimeoutTag,
+ ret->timeout) ||
CBS_len(&session) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 66edf37..6452620 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -152,6 +152,11 @@
return ret;
}
+static CRYPTO_BUFFER *buffer_up_ref(CRYPTO_BUFFER *buffer) {
+ CRYPTO_BUFFER_up_ref(buffer);
+ return buffer;
+}
+
CERT *ssl_cert_dup(CERT *cert) {
CERT *ret = OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
@@ -160,29 +165,16 @@
}
OPENSSL_memset(ret, 0, sizeof(CERT));
- if (cert->x509_leaf != NULL) {
- X509_up_ref(cert->x509_leaf);
- ret->x509_leaf = cert->x509_leaf;
- }
+ ret->chain = sk_CRYPTO_BUFFER_deep_copy(cert->chain, buffer_up_ref,
+ CRYPTO_BUFFER_free);
if (cert->privatekey != NULL) {
EVP_PKEY_up_ref(cert->privatekey);
ret->privatekey = cert->privatekey;
}
- if (cert->x509_chain) {
- ret->x509_chain = X509_chain_up_ref(cert->x509_chain);
- if (!ret->x509_chain) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
-
ret->key_method = cert->key_method;
- ret->mask_k = cert->mask_k;
- ret->mask_a = cert->mask_a;
-
if (cert->dh_tmp != NULL) {
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
if (ret->dh_tmp == NULL) {
@@ -216,18 +208,32 @@
return NULL;
}
+void ssl_cert_flush_cached_x509_leaf(CERT *cert) {
+ X509_free(cert->x509_leaf);
+ cert->x509_leaf = NULL;
+}
+
+static void ssl_cert_flush_cached_x509_chain(CERT *cert) {
+ sk_X509_pop_free(cert->x509_chain, X509_free);
+ cert->x509_chain = NULL;
+}
+
/* Free up and clear all certificates and chains */
void ssl_cert_clear_certs(CERT *cert) {
if (cert == NULL) {
return;
}
- X509_free(cert->x509_leaf);
- cert->x509_leaf = NULL;
+ ssl_cert_flush_cached_x509_leaf(cert);
+ ssl_cert_flush_cached_x509_chain(cert);
+
+ X509_free(cert->x509_stash);
+ cert->x509_stash = NULL;
+
+ sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free);
+ cert->chain = NULL;
EVP_PKEY_free(cert->privatekey);
cert->privatekey = NULL;
- sk_X509_pop_free(cert->x509_chain, X509_free);
- cert->x509_chain = NULL;
cert->key_method = NULL;
}
@@ -245,25 +251,125 @@
OPENSSL_free(c);
}
+/* new_leafless_chain returns a fresh stack of buffers set to {NULL}. */
+static STACK_OF(CRYPTO_BUFFER) *new_leafless_chain(void) {
+ STACK_OF(CRYPTO_BUFFER) *chain = sk_CRYPTO_BUFFER_new_null();
+ if (chain == NULL) {
+ return NULL;
+ }
+
+ if (!sk_CRYPTO_BUFFER_push(chain, NULL)) {
+ sk_CRYPTO_BUFFER_free(chain);
+ return NULL;
+ }
+
+ return chain;
+}
+
+/* x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised
+ * contents of |x509|. */
+CRYPTO_BUFFER *x509_to_buffer(X509 *x509) {
+ uint8_t *buf = NULL;
+ int cert_len = i2d_X509(x509, &buf);
+ if (cert_len <= 0) {
+ return 0;
+ }
+
+ CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(buf, cert_len, NULL);
+ OPENSSL_free(buf);
+
+ return buffer;
+}
+
+/* ssl_cert_set_chain sets elements 1.. of |cert->chain| to the serialised
+ * forms of elements of |chain|. It returns one on success or zero on error, in
+ * which case no change to |cert->chain| is made. It preverses the existing
+ * leaf from |cert->chain|, if any. */
+static int ssl_cert_set_chain(CERT *cert, STACK_OF(X509) *chain) {
+ STACK_OF(CRYPTO_BUFFER) *new_chain = NULL;
+
+ if (cert->chain != NULL) {
+ new_chain = sk_CRYPTO_BUFFER_new_null();
+ if (new_chain == NULL) {
+ return 0;
+ }
+
+ CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain, 0);
+ if (!sk_CRYPTO_BUFFER_push(new_chain, leaf)) {
+ goto err;
+ }
+ /* |leaf| might be NULL if it's a “leafless” chain. */
+ if (leaf != NULL) {
+ CRYPTO_BUFFER_up_ref(leaf);
+ }
+ }
+
+ for (size_t i = 0; i < sk_X509_num(chain); i++) {
+ if (new_chain == NULL) {
+ new_chain = new_leafless_chain();
+ if (new_chain == NULL) {
+ goto err;
+ }
+ }
+
+ CRYPTO_BUFFER *buffer = x509_to_buffer(sk_X509_value(chain, i));
+ if (buffer == NULL ||
+ !sk_CRYPTO_BUFFER_push(new_chain, buffer)) {
+ CRYPTO_BUFFER_free(buffer);
+ goto err;
+ }
+ }
+
+ sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free);
+ cert->chain = new_chain;
+
+ return 1;
+
+err:
+ sk_CRYPTO_BUFFER_pop_free(new_chain, CRYPTO_BUFFER_free);
+ return 0;
+}
+
static int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain) {
- sk_X509_pop_free(cert->x509_chain, X509_free);
- cert->x509_chain = chain;
+ if (!ssl_cert_set_chain(cert, chain)) {
+ return 0;
+ }
+
+ sk_X509_pop_free(chain, X509_free);
+ ssl_cert_flush_cached_x509_chain(cert);
return 1;
}
static int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) {
- STACK_OF(X509) *dchain;
- if (chain == NULL) {
- return ssl_cert_set0_chain(cert, NULL);
- }
-
- dchain = X509_chain_up_ref(chain);
- if (dchain == NULL) {
+ if (!ssl_cert_set_chain(cert, chain)) {
return 0;
}
- if (!ssl_cert_set0_chain(cert, dchain)) {
- sk_X509_pop_free(dchain, X509_free);
+ ssl_cert_flush_cached_x509_chain(cert);
+ return 1;
+}
+
+static int ssl_cert_append_cert(CERT *cert, X509 *x509) {
+ CRYPTO_BUFFER *buffer = x509_to_buffer(x509);
+ if (buffer == NULL) {
+ return 0;
+ }
+
+ if (cert->chain != NULL) {
+ if (!sk_CRYPTO_BUFFER_push(cert->chain, buffer)) {
+ CRYPTO_BUFFER_free(buffer);
+ return 0;
+ }
+
+ return 1;
+ }
+
+ cert->chain = new_leafless_chain();
+ if (cert->chain == NULL ||
+ !sk_CRYPTO_BUFFER_push(cert->chain, buffer)) {
+ CRYPTO_BUFFER_free(buffer);
+ sk_CRYPTO_BUFFER_free(cert->chain);
+ cert->chain = NULL;
return 0;
}
@@ -271,22 +377,22 @@
}
static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) {
- if (cert->x509_chain == NULL) {
- cert->x509_chain = sk_X509_new_null();
- }
- if (cert->x509_chain == NULL || !sk_X509_push(cert->x509_chain, x509)) {
+ if (!ssl_cert_append_cert(cert, x509)) {
return 0;
}
+ X509_free(cert->x509_stash);
+ cert->x509_stash = x509;
+ ssl_cert_flush_cached_x509_chain(cert);
return 1;
}
static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) {
- if (!ssl_cert_add0_chain_cert(cert, x509)) {
+ if (!ssl_cert_append_cert(cert, x509)) {
return 0;
}
- X509_up_ref(x509);
+ ssl_cert_flush_cached_x509_chain(cert);
return 1;
}
@@ -446,7 +552,9 @@
}
int ssl_has_certificate(const SSL *ssl) {
- return ssl->cert->x509_leaf != NULL && ssl_has_private_key(ssl);
+ return ssl->cert->chain != NULL &&
+ sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0) != NULL &&
+ ssl_has_private_key(ssl);
}
STACK_OF(CRYPTO_BUFFER) *ssl_parse_cert_chain(uint8_t *out_alert,
@@ -515,49 +623,33 @@
return NULL;
}
-int ssl_add_cert_to_cbb(CBB *cbb, X509 *x509) {
- int len = i2d_X509(x509, NULL);
- if (len < 0) {
- return 0;
- }
- uint8_t *buf;
- if (!CBB_add_space(cbb, &buf, len)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- if (buf != NULL && i2d_X509(x509, &buf) < 0) {
- return 0;
- }
- return 1;
-}
-
-static int ssl_add_cert_with_length(CBB *cbb, X509 *x509) {
- CBB child;
- return CBB_add_u24_length_prefixed(cbb, &child) &&
- ssl_add_cert_to_cbb(&child, x509) &&
- CBB_flush(cbb);
-}
-
int ssl_add_cert_chain(SSL *ssl, CBB *cbb) {
if (!ssl_has_certificate(ssl)) {
return CBB_add_u24(cbb, 0);
}
- CBB child;
- if (!CBB_add_u24_length_prefixed(cbb, &child) ||
- !ssl_add_cert_with_length(&child, ssl->cert->x509_leaf)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
+ CBB certs;
+ if (!CBB_add_u24_length_prefixed(cbb, &certs)) {
+ goto err;
}
- STACK_OF(X509) *chain = ssl->cert->x509_chain;
- for (size_t i = 0; i < sk_X509_num(chain); i++) {
- if (!ssl_add_cert_with_length(&child, sk_X509_value(chain, i))) {
- return 0;
+ STACK_OF(CRYPTO_BUFFER) *chain = ssl->cert->chain;
+ for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(chain); i++) {
+ CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(chain, i);
+ CBB child;
+ if (!CBB_add_u24_length_prefixed(&certs, &child) ||
+ !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
+ CRYPTO_BUFFER_len(buffer)) ||
+ !CBB_flush(&certs)) {
+ goto err;
}
}
return CBB_flush(cbb);
+
+err:
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
int ssl_auto_chain_if_needed(SSL *ssl) {
@@ -565,30 +657,41 @@
* isn't disabled. */
if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) ||
!ssl_has_certificate(ssl) ||
- ssl->cert->x509_chain != NULL) {
+ ssl->cert->chain == NULL ||
+ sk_CRYPTO_BUFFER_num(ssl->cert->chain) > 1) {
return 1;
}
+ X509 *leaf =
+ X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0));
+ if (!leaf) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
+ return 0;
+ }
+
X509_STORE_CTX ctx;
- if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, ssl->cert->x509_leaf,
- NULL)) {
+ if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, NULL)) {
+ X509_free(leaf);
OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
/* Attempt to build a chain, ignoring the result. */
X509_verify_cert(&ctx);
+ X509_free(leaf);
ERR_clear_error();
- /* Configure the intermediates from any partial chain we managed to build. */
- for (size_t i = 1; i < sk_X509_num(ctx.chain); i++) {
- if (!SSL_add1_chain_cert(ssl, sk_X509_value(ctx.chain, i))) {
- X509_STORE_CTX_cleanup(&ctx);
- return 0;
- }
+ /* Remove the leaf from the generated chain. */
+ X509_free(sk_X509_shift(ctx.chain));
+
+ const int ok = ssl_cert_set_chain(ssl->cert, ctx.chain);
+ X509_STORE_CTX_cleanup(&ctx);
+ if (!ok) {
+ return 0;
}
- X509_STORE_CTX_cleanup(&ctx);
+ ssl_cert_flush_cached_x509_chain(ssl->cert);
+
return 1;
}
@@ -647,6 +750,55 @@
return EVP_parse_public_key(&tbs_cert);
}
+int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
+ const EVP_PKEY *privkey) {
+ int ret = 0;
+
+ switch (EVP_PKEY_cmp(pubkey, privkey)) {
+ case 1:
+ ret = 1;
+ break;
+ case 0:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
+ break;
+ case -1:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
+ break;
+ case -2:
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+ default:
+ assert(0);
+ break;
+ }
+
+ return ret;
+}
+
+int ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey) {
+ if (privkey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+ return 0;
+ }
+
+ if (cert->chain == NULL ||
+ sk_CRYPTO_BUFFER_value(cert->chain, 0) == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
+ return 0;
+ }
+
+ CBS cert_cbs;
+ CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(cert->chain, 0), &cert_cbs);
+ EVP_PKEY *pubkey = ssl_cert_parse_pubkey(&cert_cbs);
+ if (!pubkey) {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+ return 0;
+ }
+
+ const int ok = ssl_compare_public_and_private_key(pubkey, privkey);
+ EVP_PKEY_free(pubkey);
+ return ok;
+}
+
int ssl_cert_check_digital_signature_key_usage(const CBS *in) {
CBS buf = *in;
@@ -891,7 +1043,61 @@
ssl_cert_set_cert_cb(ssl->cert, cb, arg);
}
+/* ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the
+ * first element of |cert->chain|. */
+int ssl_cert_cache_leaf_cert(CERT *cert) {
+ if (cert->x509_leaf != NULL ||
+ cert->chain == NULL) {
+ return 1;
+ }
+
+ CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain, 0);
+ if (!leaf) {
+ return 1;
+ }
+
+ cert->x509_leaf = X509_parse_from_buffer(leaf);
+ return cert->x509_leaf != NULL;
+}
+
+/* ssl_cert_cache_chain_certs fills in |cert->x509_chain| from elements 1.. of
+ * |cert->chain|. */
+static int ssl_cert_cache_chain_certs(CERT *cert) {
+ if (cert->x509_chain != NULL ||
+ cert->chain == NULL ||
+ sk_CRYPTO_BUFFER_num(cert->chain) < 2) {
+ return 1;
+ }
+
+ STACK_OF(X509) *chain = sk_X509_new_null();
+ if (chain == NULL) {
+ return 0;
+ }
+
+ for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) {
+ CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cert->chain, i);
+ X509 *x509 = X509_parse_from_buffer(buffer);
+ if (x509 == NULL ||
+ !sk_X509_push(chain, x509)) {
+ X509_free(x509);
+ goto err;
+ }
+ }
+
+ cert->x509_chain = chain;
+ return 1;
+
+err:
+ sk_X509_pop_free(chain, X509_free);
+ return 0;
+}
+
int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) {
+ if (!ssl_cert_cache_chain_certs(ctx->cert)) {
+ *out_chain = NULL;
+ return 0;
+ }
+
*out_chain = ctx->cert->x509_chain;
return 1;
}
@@ -902,6 +1108,11 @@
}
int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
+ if (!ssl_cert_cache_chain_certs(ssl->cert)) {
+ *out_chain = NULL;
+ return 0;
+ }
+
*out_chain = ssl->cert->x509_chain;
return 1;
}
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index ba1ee8f..851c81f 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -254,8 +254,8 @@
ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
- /* We take the system default */
ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
+ ret->session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT;
ret->references = 1;
@@ -425,22 +425,21 @@
ssl->initial_ctx = ctx;
if (ctx->supported_group_list) {
- ssl->supported_group_list =
- BUF_memdup(ctx->supported_group_list,
- ctx->supported_group_list_len * 2);
+ ssl->supported_group_list = BUF_memdup(ctx->supported_group_list,
+ ctx->supported_group_list_len * 2);
if (!ssl->supported_group_list) {
goto err;
}
ssl->supported_group_list_len = ctx->supported_group_list_len;
}
- if (ssl->ctx->alpn_client_proto_list) {
- ssl->alpn_client_proto_list = BUF_memdup(
- ssl->ctx->alpn_client_proto_list, ssl->ctx->alpn_client_proto_list_len);
+ if (ctx->alpn_client_proto_list) {
+ ssl->alpn_client_proto_list = BUF_memdup(ctx->alpn_client_proto_list,
+ ctx->alpn_client_proto_list_len);
if (ssl->alpn_client_proto_list == NULL) {
goto err;
}
- ssl->alpn_client_proto_list_len = ssl->ctx->alpn_client_proto_list_len;
+ ssl->alpn_client_proto_list_len = ctx->alpn_client_proto_list_len;
}
ssl->method = ctx->method;
@@ -469,16 +468,11 @@
ssl->tlsext_channel_id_private = ctx->tlsext_channel_id_private;
}
- ssl->signed_cert_timestamps_enabled =
- ssl->ctx->signed_cert_timestamps_enabled;
- ssl->ocsp_stapling_enabled = ssl->ctx->ocsp_stapling_enabled;
+ ssl->signed_cert_timestamps_enabled = ctx->signed_cert_timestamps_enabled;
+ ssl->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled;
- ssl->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
-
- /* If the context has a default timeout, use it over the default. */
- if (ctx->session_timeout != 0) {
- ssl->session_timeout = ctx->session_timeout;
- }
+ ssl->session_timeout = ctx->session_timeout;
+ ssl->session_psk_dhe_timeout = ctx->session_psk_dhe_timeout;
/* If the context has an OCSP response, use it. */
if (ctx->ocsp_response != NULL) {
@@ -504,9 +498,6 @@
CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
- ssl_free_wbio_buffer(ssl);
- assert(ssl->bbio == NULL);
-
BIO_free_all(ssl->rbio);
BIO_free_all(ssl->wbio);
@@ -553,18 +544,8 @@
}
void SSL_set0_wbio(SSL *ssl, BIO *wbio) {
- /* If the output buffering BIO is still in place, remove it. */
- if (ssl->bbio != NULL) {
- ssl->wbio = BIO_pop(ssl->wbio);
- }
-
BIO_free_all(ssl->wbio);
ssl->wbio = wbio;
-
- /* Re-attach |bbio| to the new |wbio|. */
- if (ssl->bbio != NULL) {
- ssl->wbio = BIO_push(ssl->bbio, ssl->wbio);
- }
}
void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
@@ -603,14 +584,7 @@
BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
-BIO *SSL_get_wbio(const SSL *ssl) {
- if (ssl->bbio != NULL) {
- /* If |bbio| is active, the true caller-configured BIO is its |next_bio|. */
- assert(ssl->bbio == ssl->wbio);
- return ssl->bbio->next_bio;
- }
- return ssl->wbio;
-}
+BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
void ssl_reset_error_state(SSL *ssl) {
/* Functions which use |SSL_get_error| must reset I/O and error state on
@@ -1292,34 +1266,12 @@
/* Fix this so it checks all the valid key/cert options */
int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
- if (ctx->cert->privatekey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
- return 0;
- }
-
- X509 *x509 = ctx->cert->x509_leaf;
- if (x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
- return 0;
- }
-
- return X509_check_private_key(x509, ctx->cert->privatekey);
+ return ssl_cert_check_private_key(ctx->cert, ctx->cert->privatekey);
}
/* Fix this function so that it takes an optional type parameter */
int SSL_check_private_key(const SSL *ssl) {
- if (ssl->cert->privatekey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
- return 0;
- }
-
- X509 *x509 = ssl->cert->x509_leaf;
- if (x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
- return 0;
- }
-
- return X509_check_private_key(x509, ssl->cert->privatekey);
+ return ssl_cert_check_private_key(ssl->cert, ssl->cert->privatekey);
}
long SSL_get_default_timeout(const SSL *ssl) {
@@ -2023,41 +1975,6 @@
int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; }
-int ssl_is_wbio_buffered(const SSL *ssl) {
- return ssl->bbio != NULL;
-}
-
-int ssl_init_wbio_buffer(SSL *ssl) {
- if (ssl->bbio != NULL) {
- /* Already buffered. */
- assert(ssl->bbio == ssl->wbio);
- return 1;
- }
-
- BIO *bbio = BIO_new(BIO_f_buffer());
- if (bbio == NULL ||
- !BIO_set_read_buffer_size(bbio, 1)) {
- BIO_free(bbio);
- return 0;
- }
-
- ssl->bbio = bbio;
- ssl->wbio = BIO_push(bbio, ssl->wbio);
- return 1;
-}
-
-void ssl_free_wbio_buffer(SSL *ssl) {
- if (ssl->bbio == NULL) {
- return;
- }
-
- assert(ssl->bbio == ssl->wbio);
-
- ssl->wbio = BIO_pop(ssl->wbio);
- BIO_free(ssl->bbio);
- ssl->bbio = NULL;
-}
-
void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
ctx->quiet_shutdown = (mode != 0);
}
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 34d1f86..6ad2b71 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -70,8 +70,8 @@
#include "internal.h"
-static int ssl_set_cert(CERT *c, X509 *x509);
-static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
+static int ssl_set_cert(CERT *cert, CRYPTO_BUFFER *buffer);
+static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey);
static int is_key_type_supported(int key_type) {
return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC;
@@ -82,26 +82,26 @@
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- return ssl_set_cert(ssl->cert, x);
+
+ CRYPTO_BUFFER *buffer = x509_to_buffer(x);
+ if (buffer == NULL) {
+ return 0;
+ }
+
+ const int ok = ssl_set_cert(ssl->cert, buffer);
+ CRYPTO_BUFFER_free(buffer);
+ return ok;
}
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
- if (der_len > LONG_MAX) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(der, der_len, NULL);
+ if (buffer == NULL) {
return 0;
}
- const uint8_t *p = der;
- X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
- if (x509 == NULL || p != der + der_len) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
- X509_free(x509);
- return 0;
- }
-
- int ret = SSL_use_certificate(ssl, x509);
- X509_free(x509);
- return ret;
+ const int ok = ssl_set_cert(ssl->cert, buffer);
+ CRYPTO_BUFFER_free(buffer);
+ return ok;
}
int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
@@ -128,41 +128,35 @@
return ret;
}
-static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) {
+static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
if (!is_key_type_supported(pkey->type)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return 0;
}
- X509 *x509_leaf = c->x509_leaf;
- if (x509_leaf != NULL) {
- /* Sanity-check that the private key and the certificate match, unless the
- * key is opaque (in case of, say, a smartcard). */
- if (!EVP_PKEY_is_opaque(pkey) &&
- !X509_check_private_key(x509_leaf, pkey)) {
- X509_free(c->x509_leaf);
- c->x509_leaf = NULL;
- return 0;
- }
+ if (cert->chain != NULL &&
+ sk_CRYPTO_BUFFER_value(cert->chain, 0) != NULL &&
+ /* Sanity-check that the private key and the certificate match, unless
+ * the key is opaque (in case of, say, a smartcard). */
+ !EVP_PKEY_is_opaque(pkey) &&
+ !ssl_cert_check_private_key(cert, pkey)) {
+ return 0;
}
- EVP_PKEY_free(c->privatekey);
+ EVP_PKEY_free(cert->privatekey);
EVP_PKEY_up_ref(pkey);
- c->privatekey = pkey;
+ cert->privatekey = pkey;
return 1;
}
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
- int ret;
-
if (pkey == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- ret = ssl_set_pkey(ssl->cert, pkey);
- return ret;
+ return ssl_set_pkey(ssl->cert, pkey);
}
int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
@@ -191,77 +185,90 @@
return 0;
}
- return ssl_set_cert(ctx->cert, x);
-}
-
-static int ssl_set_cert(CERT *c, X509 *x) {
- EVP_PKEY *pkey = X509_get_pubkey(x);
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB);
+ CRYPTO_BUFFER *buffer = x509_to_buffer(x);
+ if (buffer == NULL) {
return 0;
}
- if (!is_key_type_supported(pkey->type)) {
+ const int ok = ssl_set_cert(ctx->cert, buffer);
+ CRYPTO_BUFFER_free(buffer);
+ return ok;
+}
+
+static int ssl_set_cert(CERT *cert, CRYPTO_BUFFER *buffer) {
+ CBS cert_cbs;
+ CRYPTO_BUFFER_init_CBS(buffer, &cert_cbs);
+ EVP_PKEY *pubkey = ssl_cert_parse_pubkey(&cert_cbs);
+ if (pubkey == NULL) {
+ return 0;
+ }
+
+ if (!is_key_type_supported(pubkey->type)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
- EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pubkey);
return 0;
}
/* An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
* certificates, so sanity-check the key usage extension. */
- if (pkey->type == EVP_PKEY_EC) {
- /* This call populates extension flags (ex_flags). */
- X509_check_purpose(x, -1, 0);
- if ((x->ex_flags & EXFLAG_KUSAGE) &&
- !(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
- EVP_PKEY_free(pkey);
- return 0;
- }
+ if (pubkey->type == EVP_PKEY_EC &&
+ !ssl_cert_check_digital_signature_key_usage(&cert_cbs)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ EVP_PKEY_free(pubkey);
+ return 0;
}
- if (c->privatekey != NULL) {
+ if (cert->privatekey != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */
- if (!EVP_PKEY_is_opaque(c->privatekey) &&
- !X509_check_private_key(x, c->privatekey)) {
+ if (!EVP_PKEY_is_opaque(cert->privatekey) &&
+ !ssl_compare_public_and_private_key(pubkey, cert->privatekey)) {
/* don't fail for a cert/key mismatch, just free current private key
* (when switching to a different cert & key, first this function should
* be used, then ssl_set_pkey */
- EVP_PKEY_free(c->privatekey);
- c->privatekey = NULL;
+ EVP_PKEY_free(cert->privatekey);
+ cert->privatekey = NULL;
/* clear error queue */
ERR_clear_error();
}
}
- EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pubkey);
- X509_free(c->x509_leaf);
- X509_up_ref(x);
- c->x509_leaf = x;
+ ssl_cert_flush_cached_x509_leaf(cert);
+
+ if (cert->chain != NULL) {
+ CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_value(cert->chain, 0));
+ sk_CRYPTO_BUFFER_set(cert->chain, 0, buffer);
+ CRYPTO_BUFFER_up_ref(buffer);
+ return 1;
+ }
+
+ cert->chain = sk_CRYPTO_BUFFER_new_null();
+ if (cert->chain == NULL) {
+ return 0;
+ }
+
+ if (!sk_CRYPTO_BUFFER_push(cert->chain, buffer)) {
+ sk_CRYPTO_BUFFER_free(cert->chain);
+ cert->chain = NULL;
+ return 0;
+ }
+ CRYPTO_BUFFER_up_ref(buffer);
return 1;
}
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
const uint8_t *der) {
- if (der_len > LONG_MAX) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(der, der_len, NULL);
+ if (buffer == NULL) {
return 0;
}
- const uint8_t *p = der;
- X509 *x509 = d2i_X509(NULL, &p, (long)der_len);
- if (x509 == NULL || p != der + der_len) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
- X509_free(x509);
- return 0;
- }
-
- int ret = SSL_CTX_use_certificate(ctx, x509);
- X509_free(x509);
- return ret;
+ const int ok = ssl_set_cert(ctx->cert, buffer);
+ CRYPTO_BUFFER_free(buffer);
+ return ok;
}
int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
index 7adef1a..5dffc70 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.c
@@ -171,6 +171,7 @@
session->verify_result = X509_V_ERR_INVALID_CALL;
session->references = 1;
session->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
+ session->auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
session->time = (long)time(NULL);
CRYPTO_new_ex_data(&session->ex_data);
return session;
@@ -259,6 +260,7 @@
new_session->peer_signature_algorithm = session->peer_signature_algorithm;
new_session->timeout = session->timeout;
+ new_session->auth_timeout = session->auth_timeout;
new_session->time = session->time;
/* Copy non-authentication connection properties. */
@@ -303,7 +305,7 @@
return 0;
}
-void ssl_session_refresh_time(SSL *ssl, SSL_SESSION *session) {
+void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) {
struct timeval now;
ssl_get_current_time(ssl, &now);
@@ -314,11 +316,12 @@
now.tv_sec < 0) {
session->time = now.tv_sec;
session->timeout = 0;
+ session->auth_timeout = 0;
return;
}
- /* Adjust the session time and timeout. If the session has already expired,
- * clamp the timeout at zero. */
+ /* Adjust the session time and timeouts. If the session has already expired,
+ * clamp the timeouts at zero. */
long delta = now.tv_sec - session->time;
session->time = now.tv_sec;
if (session->timeout < delta) {
@@ -326,6 +329,26 @@
} else {
session->timeout -= delta;
}
+ if (session->auth_timeout < delta) {
+ session->auth_timeout = 0;
+ } else {
+ session->auth_timeout -= delta;
+ }
+}
+
+void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, long timeout) {
+ /* Rebase the timestamp relative to the current time so |timeout| is measured
+ * correctly. */
+ ssl_session_rebase_time(ssl, session);
+
+ if (session->timeout > timeout) {
+ return;
+ }
+
+ session->timeout = timeout;
+ if (session->timeout > session->auth_timeout) {
+ session->timeout = session->auth_timeout;
+ }
}
int SSL_SESSION_up_ref(SSL_SESSION *session) {
@@ -408,6 +431,7 @@
}
session->timeout = timeout;
+ session->auth_timeout = timeout;
return 1;
}
@@ -490,10 +514,21 @@
ssl_get_current_time(ssl, &now);
session->time = now.tv_sec;
- session->timeout = ssl->session_timeout;
+ uint16_t version = ssl3_protocol_version(ssl);
+ if (version >= TLS1_3_VERSION) {
+ /* TLS 1.3 uses tickets as authenticators, so we are willing to use them for
+ * longer. */
+ session->timeout = ssl->session_psk_dhe_timeout;
+ session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
+ } else {
+ /* TLS 1.2 resumption does not incorporate new key material, so we use a
+ * much shorter timeout. */
+ session->timeout = ssl->session_timeout;
+ session->auth_timeout = ssl->session_timeout;
+ }
if (is_server) {
- if (hs->ticket_expected) {
+ if (hs->ticket_expected || version >= TLS1_3_VERSION) {
/* Don't set session IDs for sessions resumed with tickets. This will keep
* them out of the session cache. */
session->session_id_length = 0;
@@ -934,6 +969,11 @@
return 0;
}
+ /* Historically, zero was treated as |SSL_DEFAULT_SESSION_TIMEOUT|. */
+ if (timeout == 0) {
+ timeout = SSL_DEFAULT_SESSION_TIMEOUT;
+ }
+
long old_timeout = ctx->session_timeout;
ctx->session_timeout = timeout;
return old_timeout;
@@ -947,12 +987,20 @@
return ctx->session_timeout;
}
+void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, long timeout) {
+ ctx->session_psk_dhe_timeout = timeout;
+}
+
long SSL_set_session_timeout(SSL *ssl, long timeout) {
long old_timeout = ssl->session_timeout;
ssl->session_timeout = timeout;
return old_timeout;
}
+void SSL_set_session_psk_dhe_timeout(SSL *ssl, long timeout) {
+ ssl->session_psk_dhe_timeout = timeout;
+}
+
typedef struct timeout_param_st {
SSL_CTX *ctx;
long time;
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.c
index d657788..09a43d1 100644
--- a/src/ssl/ssl_stat.c
+++ b/src/ssl/ssl_stat.c
@@ -104,9 +104,6 @@
case SSL3_ST_CW_CLNT_HELLO_A:
return "SSLv3 write client hello A";
- case SSL3_ST_CW_CLNT_HELLO_B:
- return "SSLv3 write client hello B";
-
case SSL3_ST_CR_SRVR_HELLO_A:
return "SSLv3 read server hello A";
@@ -128,15 +125,9 @@
case SSL3_ST_CW_CERT_A:
return "SSLv3 write client certificate A";
- case SSL3_ST_CW_CERT_B:
- return "SSLv3 write client certificate B";
-
case SSL3_ST_CW_KEY_EXCH_A:
return "SSLv3 write client key exchange A";
- case SSL3_ST_CW_KEY_EXCH_B:
- return "SSLv3 write client key exchange B";
-
case SSL3_ST_CW_CERT_VRFY_A:
return "SSLv3 write certificate verify A";
@@ -151,10 +142,6 @@
case SSL3_ST_SW_FINISHED_A:
return "SSLv3 write finished A";
- case SSL3_ST_CW_FINISHED_B:
- case SSL3_ST_SW_FINISHED_B:
- return "SSLv3 write finished B";
-
case SSL3_ST_CR_CHANGE:
case SSL3_ST_SR_CHANGE:
return "SSLv3 read change cipher spec";
@@ -188,39 +175,21 @@
case SSL3_ST_SW_SRVR_HELLO_A:
return "SSLv3 write server hello A";
- case SSL3_ST_SW_SRVR_HELLO_B:
- return "SSLv3 write server hello B";
-
case SSL3_ST_SW_CERT_A:
return "SSLv3 write certificate A";
- case SSL3_ST_SW_CERT_B:
- return "SSLv3 write certificate B";
-
case SSL3_ST_SW_KEY_EXCH_A:
return "SSLv3 write key exchange A";
- case SSL3_ST_SW_KEY_EXCH_B:
- return "SSLv3 write key exchange B";
-
case SSL3_ST_SW_CERT_REQ_A:
return "SSLv3 write certificate request A";
- case SSL3_ST_SW_CERT_REQ_B:
- return "SSLv3 write certificate request B";
-
case SSL3_ST_SW_SESSION_TICKET_A:
return "SSLv3 write session ticket A";
- case SSL3_ST_SW_SESSION_TICKET_B:
- return "SSLv3 write session ticket B";
-
case SSL3_ST_SW_SRVR_DONE_A:
return "SSLv3 write server done A";
- case SSL3_ST_SW_SRVR_DONE_B:
- return "SSLv3 write server done B";
-
case SSL3_ST_SR_CERT_A:
return "SSLv3 read client certificate A";
@@ -261,9 +230,6 @@
case SSL3_ST_CW_CLNT_HELLO_A:
return "3WCH_A";
- case SSL3_ST_CW_CLNT_HELLO_B:
- return "3WCH_B";
-
case SSL3_ST_CR_SRVR_HELLO_A:
return "3RSH_A";
@@ -282,15 +248,9 @@
case SSL3_ST_CW_CERT_A:
return "3WCC_A";
- case SSL3_ST_CW_CERT_B:
- return "3WCC_B";
-
case SSL3_ST_CW_KEY_EXCH_A:
return "3WCKEA";
- case SSL3_ST_CW_KEY_EXCH_B:
- return "3WCKEB";
-
case SSL3_ST_CW_CERT_VRFY_A:
return "3WCV_A";
@@ -305,10 +265,6 @@
case SSL3_ST_CW_FINISHED_A:
return "3WFINA";
- case SSL3_ST_SW_FINISHED_B:
- case SSL3_ST_CW_FINISHED_B:
- return "3WFINB";
-
case SSL3_ST_CR_CHANGE:
case SSL3_ST_SR_CHANGE:
return "3RCCS_";
@@ -338,15 +294,9 @@
case SSL3_ST_SW_SRVR_HELLO_A:
return "3WSH_A";
- case SSL3_ST_SW_SRVR_HELLO_B:
- return "3WSH_B";
-
case SSL3_ST_SW_CERT_A:
return "3WSC_A";
- case SSL3_ST_SW_CERT_B:
- return "3WSC_B";
-
case SSL3_ST_SW_KEY_EXCH_A:
return "3WSKEA";
@@ -356,15 +306,9 @@
case SSL3_ST_SW_CERT_REQ_A:
return "3WCR_A";
- case SSL3_ST_SW_CERT_REQ_B:
- return "3WCR_B";
-
case SSL3_ST_SW_SRVR_DONE_A:
return "3WSD_A";
- case SSL3_ST_SW_SRVR_DONE_B:
- return "3WSD_B";
-
case SSL3_ST_SR_CERT_A:
return "3RCC_A";
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 22a9b7b..aa265c8 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -2154,6 +2154,11 @@
*out_clock = g_current_time;
}
+static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
+ out_clock->tv_sec = 1000;
+ out_clock->tv_usec = 0;
+}
+
static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
int encrypt) {
@@ -2221,9 +2226,15 @@
}
for (bool server_test : std::vector<bool>{false, true}) {
- static const int kStartTime = 1000;
+ static const time_t kStartTime = 1000;
g_current_time.tv_sec = kStartTime;
+ // We are willing to use a longer lifetime for TLS 1.3 sessions as
+ // resumptions still perform ECDHE.
+ const time_t timeout = version == TLS1_3_VERSION
+ ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
+ : SSL_DEFAULT_SESSION_TIMEOUT;
+
bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
if (!server_ctx || !client_ctx ||
@@ -2239,11 +2250,14 @@
SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
- // Both client and server must enforce session timeouts.
+ // Both client and server must enforce session timeouts. We configure the
+ // other side with a frozen clock so it never expires tickets.
if (server_test) {
+ SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
} else {
SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
+ SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
}
// Configure a ticket callback which renews tickets.
@@ -2257,7 +2271,7 @@
}
// Advance the clock just behind the timeout.
- g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT - 1;
+ g_current_time.tv_sec += timeout - 1;
if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
true /* expect session reused */)) {
@@ -2289,7 +2303,8 @@
}
// Renew the session 10 seconds before expiration.
- g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
+ time_t new_start_time = kStartTime + timeout - 10;
+ g_current_time.tv_sec = new_start_time;
bssl::UniquePtr<SSL_SESSION> new_session =
ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
if (!new_session) {
@@ -2319,23 +2334,76 @@
return false;
}
- // The new session is usable just before the old expiration.
- g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
- if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
- new_session.get(),
- true /* expect session reused */)) {
- fprintf(stderr, "Error resuming renewed session.\n");
- return false;
- }
+ if (version == TLS1_3_VERSION) {
+ // Renewal incorporates fresh key material in TLS 1.3, so we extend the
+ // lifetime TLS 1.3.
+ g_current_time.tv_sec = new_start_time + timeout - 1;
+ if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
+ new_session.get(),
+ true /* expect session reused */)) {
+ fprintf(stderr, "Error resuming renewed session.\n");
+ return false;
+ }
- // Renewal does not extend the lifetime, so it is not usable beyond the
- // old expiration.
- g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
- if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
- new_session.get(),
- false /* expect session not reused */)) {
- fprintf(stderr, "Renewed session's lifetime is too long.\n");
- return false;
+ // The new session expires after the new timeout.
+ g_current_time.tv_sec = new_start_time + timeout + 1;
+ if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
+ new_session.get(),
+ false /* expect session ot reused */)) {
+ fprintf(stderr, "Renewed session's lifetime is too long.\n");
+ return false;
+ }
+
+ // Renew the session until it begins just past the auth timeout.
+ time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
+ while (new_start_time < auth_end_time - 1000) {
+ // Get as close as possible to target start time.
+ new_start_time =
+ std::min(auth_end_time - 1000, new_start_time + timeout - 1);
+ g_current_time.tv_sec = new_start_time;
+ new_session = ExpectSessionRenewed(client_ctx.get(), server_ctx.get(),
+ new_session.get());
+ if (!new_session) {
+ fprintf(stderr, "Error renewing session.\n");
+ return false;
+ }
+ }
+
+ // Now the session's lifetime is bound by the auth timeout.
+ g_current_time.tv_sec = auth_end_time - 1;
+ if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
+ new_session.get(),
+ true /* expect session reused */)) {
+ fprintf(stderr, "Error resuming renewed session.\n");
+ return false;
+ }
+
+ g_current_time.tv_sec = auth_end_time + 1;
+ if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
+ new_session.get(),
+ false /* expect session ot reused */)) {
+ fprintf(stderr, "Renewed session's lifetime is too long.\n");
+ return false;
+ }
+ } else {
+ // The new session is usable just before the old expiration.
+ g_current_time.tv_sec = kStartTime + timeout - 1;
+ if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
+ new_session.get(),
+ true /* expect session reused */)) {
+ fprintf(stderr, "Error resuming renewed session.\n");
+ return false;
+ }
+
+ // Renewal does not extend the lifetime, so it is not usable beyond the
+ // old expiration.
+ g_current_time.tv_sec = kStartTime + timeout + 1;
+ if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
+ new_session.get(),
+ false /* expect session not reused */)) {
+ fprintf(stderr, "Renewed session's lifetime is too long.\n");
+ return false;
+ }
}
}
@@ -2348,9 +2416,20 @@
return 1;
}
+static int SetSessionTimeoutCallbackTLS13(SSL *ssl, void *arg) {
+ long timeout = *(long *) arg;
+ SSL_set_session_psk_dhe_timeout(ssl, timeout);
+ return 1;
+}
+
static bool TestSessionTimeoutCertCallback(bool is_dtls,
const SSL_METHOD *method,
uint16_t version) {
+ if (version == TLS1_3_VERSION) {
+ // |SSL_set_session_timeout| only applies to TLS 1.2 style resumption.
+ return true;
+ }
+
static const int kStartTime = 1000;
g_current_time.tv_sec = kStartTime;
@@ -2378,7 +2457,12 @@
SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
long timeout = 25;
- SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
+ if (version == TLS1_3_VERSION) {
+ SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallbackTLS13,
+ &timeout);
+ } else {
+ SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
+ }
bssl::UniquePtr<SSL_SESSION> session =
CreateClientSession(client_ctx.get(), server_ctx.get());
@@ -2428,7 +2512,11 @@
timeout = 25;
g_current_time.tv_sec = kStartTime;
- SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
+ if (version == TLS1_3_VERSION) {
+ SSL_CTX_set_session_psk_dhe_timeout(server_ctx.get(), timeout - 10);
+ } else {
+ SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
+ }
bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session =
CreateClientSession(client_ctx.get(), server_ctx.get());
@@ -3142,6 +3230,61 @@
return true;
}
+TEST(SSLTest, AddChainCertHack) {
+ // Ensure that we don't accidently break the hack that we have in place to
+ // keep curl and serf happy when they use an |X509| even after transfering
+ // ownership.
+
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
+ ASSERT_TRUE(ctx);
+ X509 *cert = GetTestCertificate().release();
+ ASSERT_TRUE(cert);
+ SSL_CTX_add0_chain_cert(ctx.get(), cert);
+
+ // This should not trigger a use-after-free.
+ X509_cmp(cert, cert);
+}
+
+TEST(SSLTest, GetCertificate) {
+ bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
+ ASSERT_TRUE(ctx);
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ ASSERT_TRUE(cert);
+ ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
+ bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
+ ASSERT_TRUE(ssl);
+
+ X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
+ ASSERT_TRUE(cert2);
+ X509 *cert3 = SSL_get_certificate(ssl.get());
+ ASSERT_TRUE(cert3);
+
+ // The old and new certificates must be identical.
+ EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
+ EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
+
+ uint8_t *der = nullptr;
+ long der_len = i2d_X509(cert.get(), &der);
+ ASSERT_LT(0, der_len);
+ bssl::UniquePtr<uint8_t> free_der(der);
+
+ uint8_t *der2 = nullptr;
+ long der2_len = i2d_X509(cert2, &der2);
+ ASSERT_LT(0, der2_len);
+ bssl::UniquePtr<uint8_t> free_der2(der2);
+
+ uint8_t *der3 = nullptr;
+ long der3_len = i2d_X509(cert3, &der3);
+ ASSERT_LT(0, der3_len);
+ bssl::UniquePtr<uint8_t> free_der3(der3);
+
+ // They must also encode identically.
+ ASSERT_EQ(der2_len, der_len);
+ EXPECT_EQ(0, OPENSSL_memcmp(der, der2, static_cast<size_t>(der_len)));
+ ASSERT_EQ(der3_len, der_len);
+ EXPECT_EQ(0, OPENSSL_memcmp(der, der3, static_cast<size_t>(der_len)));
+}
+
// TODO(davidben): Convert this file to GTest properly.
TEST(SSLTest, AllTests) {
if (!TestCipherRules() ||
diff --git a/src/ssl/ssl_x509.c b/src/ssl/ssl_x509.c
index 3fc62b7..5d78deb 100644
--- a/src/ssl/ssl_x509.c
+++ b/src/ssl/ssl_x509.c
@@ -281,20 +281,21 @@
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}
-X509 *SSL_get_certificate(const SSL *ssl) {
- if (ssl->cert != NULL) {
- return ssl->cert->x509_leaf;
+static X509 *ssl_cert_get0_leaf(CERT *cert) {
+ if (cert->x509_leaf == NULL &&
+ !ssl_cert_cache_leaf_cert(cert)) {
+ return NULL;
}
- return NULL;
+ return cert->x509_leaf;
+}
+
+X509 *SSL_get_certificate(const SSL *ssl) {
+ return ssl_cert_get0_leaf(ssl->cert);
}
X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
- if (ctx->cert != NULL) {
- return ctx->cert->x509_leaf;
- }
-
- return NULL;
+ return ssl_cert_get0_leaf(ctx->cert);
}
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index ec5dce0..6fdef45 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -527,56 +527,6 @@
return 0;
}
-/* Get a mask of disabled algorithms: an algorithm is disabled if it isn't
- * supported or doesn't appear in supported signature algorithms. Unlike
- * ssl_cipher_get_disabled this applies to a specific session and not global
- * settings. */
-void ssl_set_client_disabled(SSL *ssl) {
- CERT *c = ssl->cert;
- int have_rsa = 0, have_ecdsa = 0;
- c->mask_a = 0;
- c->mask_k = 0;
-
- /* Now go through all signature algorithms seeing if we support any for RSA or
- * ECDSA. Do this for all versions not just TLS 1.2. */
- const uint16_t *sigalgs;
- size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
- for (size_t i = 0; i < num_sigalgs; i++) {
- switch (sigalgs[i]) {
- case SSL_SIGN_RSA_PSS_SHA512:
- case SSL_SIGN_RSA_PSS_SHA384:
- case SSL_SIGN_RSA_PSS_SHA256:
- case SSL_SIGN_RSA_PKCS1_SHA512:
- case SSL_SIGN_RSA_PKCS1_SHA384:
- case SSL_SIGN_RSA_PKCS1_SHA256:
- case SSL_SIGN_RSA_PKCS1_SHA1:
- have_rsa = 1;
- break;
-
- case SSL_SIGN_ECDSA_SECP521R1_SHA512:
- case SSL_SIGN_ECDSA_SECP384R1_SHA384:
- case SSL_SIGN_ECDSA_SECP256R1_SHA256:
- case SSL_SIGN_ECDSA_SHA1:
- have_ecdsa = 1;
- break;
- }
- }
-
- /* Disable auth if we don't include any appropriate signature algorithms. */
- if (!have_rsa) {
- c->mask_a |= SSL_aRSA;
- }
- if (!have_ecdsa) {
- c->mask_a |= SSL_aECDSA;
- }
-
- /* with PSK there must be client callback set */
- if (!ssl->psk_client_callback) {
- c->mask_a |= SSL_aPSK;
- c->mask_k |= SSL_kPSK;
- }
-}
-
/* tls_extension represents a TLS extension that is handled internally. The
* |init| function is called for each handshake, before any other functions of
* the extension. Then the add and parse callbacks are called as needed.
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 12f0b46..66a71a0 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -1254,6 +1254,17 @@
}
}
+ if (!is_resume) {
+ if (config->expect_session_id && !GetTestState(ssl)->got_new_session) {
+ fprintf(stderr, "session was not cached on the server.\n");
+ return false;
+ }
+ if (config->expect_no_session_id && GetTestState(ssl)->got_new_session) {
+ fprintf(stderr, "session was unexpectedly cached on the server.\n");
+ return false;
+ }
+ }
+
if (config->is_server && !GetTestState(ssl)->early_callback_called) {
fprintf(stderr, "early callback not called\n");
return false;
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 3afd73f..92f3e15 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -1132,6 +1132,19 @@
// data interleaved with the second ClientHello and the client Finished.
InterleaveEarlyData bool
+ // SendHalfRTTData causes a TLS 1.3 server to send the provided
+ // data in application data records before reading the client's
+ // Finished message.
+ SendHalfRTTData [][]byte
+
+ // ExpectHalfRTTData causes a TLS 1.3 client to read application
+ // data after reading the server's Finished message and before
+ // sending any other handshake messages. It checks that the
+ // application data it reads matches what is provided in
+ // ExpectHalfRTTData and errors if the number of records or their
+ // content do not match.
+ ExpectHalfRTTData [][]byte
+
// EmptyEncryptedExtensions, if true, causes the TLS 1.3 server to
// emit an empty EncryptedExtensions block.
EmptyEncryptedExtensions bool
@@ -1257,6 +1270,10 @@
// MaxReceivePlaintext, if non-zero, is the maximum plaintext record
// length accepted from the peer.
MaxReceivePlaintext int
+
+ // SendTicketLifetime, if non-zero, is the ticket lifetime to send in
+ // NewSessionTicket messages.
+ SendTicketLifetime time.Duration
}
func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index 3cbd496..0cc0b38 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -38,6 +38,7 @@
haveVers bool // version has been negotiated
config *Config // configuration passed to constructor
handshakeComplete bool
+ skipEarlyData bool
didResume bool // whether this connection was a session resumption
extendedMasterSecret bool // whether this session used an extended master secret
cipherSuite *cipherSuite
@@ -726,6 +727,7 @@
}
func (c *Conn) doReadRecord(want recordType) (recordType, *block, error) {
+RestartReadRecord:
if c.isDTLS {
return c.dtlsDoReadRecord(want)
}
@@ -829,10 +831,24 @@
// Process message.
b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
ok, off, encTyp, alertValue := c.in.decrypt(b)
+
+ // Handle skipping over early data.
+ if !ok && c.skipEarlyData {
+ goto RestartReadRecord
+ }
+
+ // If the server is expecting a second ClientHello (in response to
+ // a HelloRetryRequest) and the client sends early data, there
+ // won't be a decryption failure but it still needs to be skipped.
+ if c.in.cipher == nil && typ == recordTypeApplicationData && c.skipEarlyData {
+ goto RestartReadRecord
+ }
+
if !ok {
return 0, nil, c.in.setErrorLocked(c.sendAlert(alertValue))
}
b.off = off
+ c.skipEarlyData = false
if c.vers >= VersionTLS13 && c.in.cipher != nil {
if typ != recordTypeApplicationData {
@@ -860,7 +876,7 @@
return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete"))
}
case recordTypeApplicationData:
- if !c.handshakeComplete && !c.config.Bugs.ExpectFalseStart {
+ if !c.handshakeComplete && !c.config.Bugs.ExpectFalseStart && len(c.config.Bugs.ExpectHalfRTTData) == 0 {
c.sendAlert(alertInternalError)
return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
}
@@ -1779,6 +1795,10 @@
ticketAgeAdd: ticketAgeAdd,
}
+ if c.config.Bugs.SendTicketLifetime != 0 {
+ m.ticketLifetime = uint32(c.config.Bugs.SendTicketLifetime / time.Second)
+ }
+
state := sessionState{
vers: c.vers,
cipherSuite: c.cipherSuite.id,
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 507ea40..02daa78 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -835,6 +835,20 @@
hs.finishedHash.addEntropy(zeroSecret)
clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel)
serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel)
+ c.in.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
+
+ // If we're expecting 0.5-RTT messages from the server, read them
+ // now.
+ for _, expectedMsg := range c.config.Bugs.ExpectHalfRTTData {
+ if err := c.readRecord(recordTypeApplicationData); err != nil {
+ return err
+ }
+ if !bytes.Equal(c.input.data[c.input.off:], expectedMsg) {
+ return errors.New("ExpectHalfRTTData: did not get expected message")
+ }
+ c.in.freeBlock(c.input)
+ c.input = nil
+ }
if certReq != nil && !c.config.Bugs.SkipClientCertificate {
certMsg := &certificateMsg{
@@ -919,7 +933,6 @@
// Switch to application data keys.
c.out.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, clientWrite)
- c.in.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel)
c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel)
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 1116d6c..38925e9 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -509,6 +509,12 @@
}
}
+ // Decide whether or not to accept early data.
+ if hs.clientHello.hasEarlyData {
+ // For now, we'll reject and skip early data.
+ c.skipEarlyData = true
+ }
+
// Resolve PSK and compute the early secret.
if hs.sessionState != nil {
hs.finishedHash.addEntropy(hs.sessionState.masterSecret)
@@ -852,6 +858,13 @@
// from the client certificate are sent over these keys.
c.out.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
+ // Send 0.5-RTT messages.
+ for _, halfRTTMsg := range config.Bugs.SendHalfRTTData {
+ if _, err := c.writeRecord(recordTypeApplicationData, halfRTTMsg); err != nil {
+ return err
+ }
+ }
+
// If we requested a client certificate, then the client must send a
// certificate message, even if it's empty.
if config.ClientAuth >= RequestClientCert {
@@ -1668,6 +1681,9 @@
}
m := new(newSessionTicketMsg)
+ if c.config.Bugs.SendTicketLifetime != 0 {
+ m.ticketLifetime = uint32(c.config.Bugs.SendTicketLifetime / time.Second)
+ }
if !c.config.Bugs.SendEmptySessionTicket {
var err error
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 54bfca5..4e08200 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -2349,7 +2349,7 @@
},
},
shouldFail: true,
- expectedError: ":NO_COMPRESSION_SPECIFIED:",
+ expectedError: ":INVALID_COMPRESSION_LIST:",
expectedLocalError: "remote error: illegal parameter",
},
{
@@ -3417,6 +3417,7 @@
},
},
resumeSession: true,
+ flags: []string{"-expect-no-session-id"},
})
tests = append(tests, testCase{
testType: serverTest,
@@ -3426,6 +3427,7 @@
SessionTicketsDisabled: true,
},
resumeSession: true,
+ flags: []string{"-expect-session-id"},
})
tests = append(tests, testCase{
testType: serverTest,
@@ -3467,6 +3469,9 @@
},
resumeSession: true,
resumeRenewedSession: true,
+ // TLS 1.3 uses tickets, so the session should not be
+ // cached statefully.
+ flags: []string{"-expect-no-session-id"},
})
tests = append(tests, testCase{
@@ -8443,10 +8448,23 @@
},
},
flags: []string{
+ "-enable-early-data",
"-expect-early-data-info",
},
})
+ // Test that 0-RTT tickets are ignored in clients unless opted in.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13-SendTicketEarlyDataInfo-Disabled",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendTicketEarlyDataInfo: 16384,
+ },
+ },
+ })
+
testCases = append(testCases, testCase{
testType: clientTest,
name: "TLS13-DuplicateTicketEarlyDataInfo",
@@ -8475,6 +8493,40 @@
"-enable-early-data",
},
})
+
+ // Test that, in TLS 1.3, the server-offered NewSessionTicket lifetime
+ // is honored.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13-HonorServerSessionTicketLifetime",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendTicketLifetime: 20 * time.Second,
+ },
+ },
+ flags: []string{
+ "-resumption-delay", "19",
+ },
+ resumeSession: true,
+ })
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13-HonorServerSessionTicketLifetime-2",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendTicketLifetime: 20 * time.Second,
+ // The client should not offer the expired session.
+ ExpectNoTLS13PSK: true,
+ },
+ },
+ flags: []string{
+ "-resumption-delay", "21",
+ },
+ resumeSession: true,
+ expectResumeRejected: true,
+ })
}
func addChangeCipherSpecTests() {
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 5bc9544..b729f69 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -123,6 +123,8 @@
&TestConfig::expect_secure_renegotiation },
{ "-expect-no-secure-renegotiation",
&TestConfig::expect_no_secure_renegotiation },
+ { "-expect-session-id", &TestConfig::expect_session_id },
+ { "-expect-no-session-id", &TestConfig::expect_no_session_id },
};
const Flag<std::string> kStringFlags[] = {
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 7cf0a6f..7122856 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -131,6 +131,8 @@
bool expect_no_secure_renegotiation = false;
int max_send_fragment = 0;
int read_size = 0;
+ bool expect_session_id = false;
+ bool expect_no_session_id = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/ssl/tls13_both.c b/src/ssl/tls13_both.c
index 1425665..a49ee14 100644
--- a/src/ssl/tls13_both.c
+++ b/src/ssl/tls13_both.c
@@ -58,15 +58,7 @@
}
case ssl_hs_read_message: {
- int ret = ssl->method->ssl_get_message(ssl, -1, ssl_dont_hash_message);
- if (ret <= 0) {
- return ret;
- }
- break;
- }
-
- case ssl_hs_write_message: {
- int ret = ssl->method->write_message(ssl);
+ int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
@@ -406,18 +398,6 @@
return ret;
}
-int tls13_check_message_type(SSL *ssl, int type) {
- if (ssl->s3->tmp.message_type != type) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- ERR_add_error_dataf("got type %d, wanted type %d",
- ssl->s3->tmp.message_type, type);
- return 0;
- }
-
- return 1;
-}
-
int tls13_process_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
uint8_t verify_data[EVP_MAX_MD_SIZE];
@@ -441,7 +421,7 @@
return 1;
}
-int tls13_prepare_certificate(SSL_HANDSHAKE *hs) {
+int tls13_add_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
CBB cbb, body, certificate_list;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) ||
@@ -453,7 +433,7 @@
}
if (!ssl_has_certificate(ssl)) {
- if (!ssl_complete_message(ssl, &cbb)) {
+ if (!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
@@ -461,9 +441,11 @@
}
CERT *cert = ssl->cert;
+ CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cert->chain, 0);
CBB leaf, extensions;
if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) ||
- !ssl_add_cert_to_cbb(&leaf, cert->x509_leaf) ||
+ !CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf),
+ CRYPTO_BUFFER_len(leaf_buf)) ||
!CBB_add_u16_length_prefixed(&certificate_list, &extensions)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
@@ -497,17 +479,19 @@
}
}
- for (size_t i = 0; i < sk_X509_num(cert->x509_chain); i++) {
+ for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) {
+ CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cert->chain, i);
CBB child;
if (!CBB_add_u24_length_prefixed(&certificate_list, &child) ||
- !ssl_add_cert_to_cbb(&child, sk_X509_value(cert->x509_chain, i)) ||
+ !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf),
+ CRYPTO_BUFFER_len(cert_buf)) ||
!CBB_add_u16(&certificate_list, 0 /* no extensions */)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
}
- if (!ssl_complete_message(ssl, &cbb)) {
+ if (!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
@@ -518,8 +502,8 @@
return 0;
}
-enum ssl_private_key_result_t tls13_prepare_certificate_verify(
- SSL_HANDSHAKE *hs, int is_first_run) {
+enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs,
+ int is_first_run) {
SSL *const ssl = hs->ssl;
enum ssl_private_key_result_t ret = ssl_private_key_failure;
uint8_t *msg = NULL;
@@ -569,7 +553,7 @@
}
if (!CBB_did_write(&child, sig_len) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
@@ -581,7 +565,7 @@
return ret;
}
-int tls13_prepare_finished(SSL_HANDSHAKE *hs) {
+int tls13_add_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
size_t verify_data_len;
uint8_t verify_data[EVP_MAX_MD_SIZE];
@@ -595,7 +579,7 @@
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_FINISHED) ||
!CBB_add_bytes(&body, verify_data, verify_data_len) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
CBB_cleanup(&cbb);
return 0;
}
diff --git a/src/ssl/tls13_client.c b/src/ssl/tls13_client.c
index 6f2bb21..74d3646 100644
--- a/src/ssl/tls13_client.c
+++ b/src/ssl/tls13_client.c
@@ -15,6 +15,7 @@
#include <openssl/ssl.h>
#include <assert.h>
+#include <limits.h>
#include <string.h>
#include <openssl/bytestring.h>
@@ -31,7 +32,6 @@
enum client_hs_state_t {
state_process_hello_retry_request = 0,
state_send_second_client_hello,
- state_flush_second_client_hello,
state_process_server_hello,
state_process_encrypted_extensions,
state_process_certificate_request,
@@ -41,9 +41,7 @@
state_send_client_certificate,
state_send_client_certificate_verify,
state_complete_client_certificate_verify,
- state_send_channel_id,
- state_send_client_finished,
- state_flush,
+ state_complete_second_flight,
state_done,
};
@@ -137,6 +135,10 @@
hs->retry_group = group_id;
}
+ if (!ssl_hash_current_message(ssl)) {
+ return ssl_hs_error;
+ }
+
hs->received_hello_retry_request = 1;
hs->tls13_state = state_send_second_client_hello;
return ssl_hs_ok;
@@ -147,18 +149,13 @@
return ssl_hs_error;
}
- hs->tls13_state = state_flush_second_client_hello;
- return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_flush_second_client_hello(SSL_HANDSHAKE *hs) {
hs->tls13_state = state_process_server_hello;
return ssl_hs_flush_and_read_message;
}
static enum ssl_hs_wait_t do_process_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_SERVER_HELLO)) {
+ if (!ssl_check_message_type(ssl, SSL3_MT_SERVER_HELLO)) {
return ssl_hs_error;
}
@@ -261,6 +258,10 @@
return ssl_hs_error;
}
ssl_set_session(ssl, NULL);
+
+ /* Resumption incorporates fresh key material, so refresh the timeout. */
+ ssl_session_renew_timeout(ssl, ssl->s3->new_session,
+ ssl->session_psk_dhe_timeout);
} else if (!ssl_get_new_session(hs, 0)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
@@ -325,14 +326,8 @@
ssl->s3->short_header = 1;
}
- /* If there was no HelloRetryRequest, the version negotiation logic has
- * already hashed the message. */
- if (hs->received_hello_retry_request &&
- !ssl_hash_current_message(ssl)) {
- return ssl_hs_error;
- }
-
- if (!tls13_derive_handshake_secrets(hs) ||
+ if (!ssl_hash_current_message(ssl) ||
+ !tls13_derive_handshake_secrets(hs) ||
!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
hs->hash_len) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
@@ -346,7 +341,7 @@
static enum ssl_hs_wait_t do_process_encrypted_extensions(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS)) {
+ if (!ssl_check_message_type(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS)) {
return ssl_hs_error;
}
@@ -428,7 +423,7 @@
static enum ssl_hs_wait_t do_process_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
!tls13_process_certificate(hs, 0 /* certificate required */) ||
!ssl_hash_current_message(ssl)) {
return ssl_hs_error;
@@ -441,7 +436,7 @@
static enum ssl_hs_wait_t do_process_server_certificate_verify(
SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
!tls13_process_certificate_verify(hs) ||
!ssl_hash_current_message(ssl)) {
return ssl_hs_error;
@@ -453,7 +448,7 @@
static enum ssl_hs_wait_t do_process_server_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) ||
!tls13_process_finished(hs) ||
!ssl_hash_current_message(ssl) ||
/* Update the secret to the master secret and derive traffic keys. */
@@ -471,7 +466,7 @@
SSL *const ssl = hs->ssl;
/* The peer didn't request a certificate. */
if (!hs->cert_request) {
- hs->tls13_state = state_send_channel_id;
+ hs->tls13_state = state_complete_second_flight;
return ssl_hs_ok;
}
@@ -490,12 +485,12 @@
}
if (!ssl_auto_chain_if_needed(ssl) ||
- !tls13_prepare_certificate(hs)) {
+ !tls13_add_certificate(hs)) {
return ssl_hs_error;
}
hs->tls13_state = state_send_client_certificate_verify;
- return ssl_hs_write_message;
+ return ssl_hs_ok;
}
static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs,
@@ -503,14 +498,14 @@
SSL *const ssl = hs->ssl;
/* Don't send CertificateVerify if there is no certificate. */
if (!ssl_has_certificate(ssl)) {
- hs->tls13_state = state_send_channel_id;
+ hs->tls13_state = state_complete_second_flight;
return ssl_hs_ok;
}
- switch (tls13_prepare_certificate_verify(hs, is_first_run)) {
+ switch (tls13_add_certificate_verify(hs, is_first_run)) {
case ssl_private_key_success:
- hs->tls13_state = state_send_channel_id;
- return ssl_hs_write_message;
+ hs->tls13_state = state_complete_second_flight;
+ return ssl_hs_ok;
case ssl_private_key_retry:
hs->tls13_state = state_complete_client_certificate_verify;
@@ -524,44 +519,35 @@
return ssl_hs_error;
}
-static enum ssl_hs_wait_t do_send_channel_id(SSL_HANDSHAKE *hs) {
+static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!ssl->s3->tlsext_channel_id_valid) {
- hs->tls13_state = state_send_client_finished;
- return ssl_hs_ok;
+
+ /* Send a Channel ID assertion if necessary. */
+ if (ssl->s3->tlsext_channel_id_valid) {
+ if (!ssl_do_channel_id_callback(ssl)) {
+ hs->tls13_state = state_complete_second_flight;
+ return ssl_hs_error;
+ }
+
+ if (ssl->tlsext_channel_id_private == NULL) {
+ return ssl_hs_channel_id_lookup;
+ }
+
+ CBB cbb, body;
+ if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CHANNEL_ID) ||
+ !tls1_write_channel_id(ssl, &body) ||
+ !ssl_add_message_cbb(ssl, &cbb)) {
+ CBB_cleanup(&cbb);
+ return ssl_hs_error;
+ }
}
- if (!ssl_do_channel_id_callback(ssl)) {
+ /* Send a Finished message. */
+ if (!tls13_add_finished(hs)) {
return ssl_hs_error;
}
- if (ssl->tlsext_channel_id_private == NULL) {
- return ssl_hs_channel_id_lookup;
- }
-
- CBB cbb, body;
- if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CHANNEL_ID) ||
- !tls1_write_channel_id(ssl, &body) ||
- !ssl_complete_message(ssl, &cbb)) {
- CBB_cleanup(&cbb);
- return ssl_hs_error;
- }
-
- hs->tls13_state = state_send_client_finished;
- return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) {
- if (!tls13_prepare_finished(hs)) {
- return ssl_hs_error;
- }
-
- hs->tls13_state = state_flush;
- return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_flush(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
+ /* Derive the final keys and enable them. */
if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_traffic_secret_0,
hs->hash_len) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_traffic_secret_0,
@@ -585,9 +571,6 @@
case state_send_second_client_hello:
ret = do_send_second_client_hello(hs);
break;
- case state_flush_second_client_hello:
- ret = do_flush_second_client_hello(hs);
- break;
case state_process_server_hello:
ret = do_process_server_hello(hs);
break;
@@ -615,14 +598,8 @@
case state_complete_client_certificate_verify:
ret = do_send_client_certificate_verify(hs, 0 /* complete */);
break;
- case state_send_channel_id:
- ret = do_send_channel_id(hs);
- break;
- case state_send_client_finished:
- ret = do_send_client_finished(hs);
- break;
- case state_flush:
- ret = do_flush(hs);
+ case state_complete_second_flight:
+ ret = do_complete_second_flight(hs);
break;
case state_done:
ret = ssl_hs_ok;
@@ -646,11 +623,12 @@
return 0;
}
- ssl_session_refresh_time(ssl, session);
+ ssl_session_rebase_time(ssl, session);
+ uint32_t server_timeout;
CBS cbs, ticket, extensions;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
- if (!CBS_get_u32(&cbs, &session->tlsext_tick_lifetime_hint) ||
+ if (!CBS_get_u32(&cbs, &server_timeout) ||
!CBS_get_u32(&cbs, &session->ticket_age_add) ||
!CBS_get_u16_length_prefixed(&cbs, &ticket) ||
!CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) ||
@@ -661,6 +639,21 @@
goto err;
}
+ /* Cap the renewable lifetime by the server advertised value. This avoids
+ * wasting bandwidth on 0-RTT when we know the server will reject it.
+ *
+ * TODO(davidben): This dance where we're not sure if long or uint32_t is
+ * bigger is silly. session->timeout should not be a long to begin with.
+ * https://crbug.com/boringssl/155. */
+#if LONG_MAX < 0xffffffff
+ if (server_timeout > LONG_MAX) {
+ server_timeout = LONG_MAX;
+ }
+#endif
+ if (session->timeout > (long)server_timeout) {
+ session->timeout = (long)server_timeout;
+ }
+
/* Parse out the extensions. */
int have_early_data_info = 0;
CBS early_data_info;
@@ -677,7 +670,7 @@
goto err;
}
- if (have_early_data_info) {
+ if (have_early_data_info && ssl->ctx->enable_early_data) {
if (!CBS_get_u32(&early_data_info, &session->ticket_max_early_data) ||
CBS_len(&early_data_info) != 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
diff --git a/src/ssl/tls13_server.c b/src/ssl/tls13_server.c
index 750e47f..db5fb24 100644
--- a/src/ssl/tls13_server.c
+++ b/src/ssl/tls13_server.c
@@ -35,25 +35,18 @@
static const size_t kMaxEarlyDataAccepted = 14336;
enum server_hs_state_t {
- state_process_client_hello = 0,
- state_select_parameters,
+ state_select_parameters = 0,
state_send_hello_retry_request,
- state_flush_hello_retry_request,
state_process_second_client_hello,
state_send_server_hello,
- state_send_encrypted_extensions,
- state_send_certificate_request,
- state_send_server_certificate,
state_send_server_certificate_verify,
state_complete_server_certificate_verify,
state_send_server_finished,
- state_flush,
state_process_client_certificate,
state_process_client_certificate_verify,
state_process_channel_id,
state_process_client_finished,
state_send_new_session_ticket,
- state_flush_new_session_tickets,
state_done,
};
@@ -94,54 +87,6 @@
return ok;
}
-static enum ssl_hs_wait_t do_process_client_hello(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
- return ssl_hs_error;
- }
-
- SSL_CLIENT_HELLO client_hello;
- if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
- ssl->init_num)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- return ssl_hs_error;
- }
-
- assert(ssl->s3->have_version);
-
- /* Load the client random. */
- if (client_hello.random_len != SSL3_RANDOM_SIZE) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return ssl_hs_error;
- }
- OPENSSL_memcpy(ssl->s3->client_random, client_hello.random,
- client_hello.random_len);
-
- /* TLS 1.3 requires the peer only advertise the null compression. */
- if (client_hello.compression_methods_len != 1 ||
- client_hello.compression_methods[0] != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
- return ssl_hs_error;
- }
-
- /* TLS extensions. */
- if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
- return ssl_hs_error;
- }
-
- /* The short record header extension is incompatible with early data. */
- if (ssl->s3->skip_early_data && ssl->s3->short_header) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- return ssl_hs_error;
- }
-
- hs->tls13_state = state_select_parameters;
- return ssl_hs_ok;
-}
-
static const SSL_CIPHER *choose_tls13_cipher(
const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
if (client_hello->cipher_suites_len % 2 != 0) {
@@ -190,21 +135,9 @@
static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- /* Call |cert_cb| to update server certificates if required. */
- if (ssl->cert->cert_cb != NULL) {
- int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
- if (rv == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return ssl_hs_error;
- }
- if (rv < 0) {
- hs->tls13_state = state_select_parameters;
- return ssl_hs_x509_lookup;
- }
- }
-
- if (!ssl_auto_chain_if_needed(ssl)) {
+ /* The short record header extension is incompatible with early data. */
+ if (ssl->s3->skip_early_data && ssl->s3->short_header) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
return ssl_hs_error;
}
@@ -287,6 +220,10 @@
}
ssl->s3->session_reused = 1;
SSL_SESSION_free(session);
+
+ /* Resumption incorporates fresh key material, so refresh the timeout. */
+ ssl_session_renew_timeout(ssl, ssl->s3->new_session,
+ ssl->session_psk_dhe_timeout);
}
if (ssl->ctx->dos_protection_cb != NULL &&
@@ -304,10 +241,12 @@
return ssl_hs_error;
}
- /* The PRF hash is now known. Set up the key schedule. */
+ /* The PRF hash is now known. Set up the key schedule and hash the
+ * ClientHello. */
size_t hash_len =
EVP_MD_size(ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl)));
- if (!tls13_init_key_schedule(hs)) {
+ if (!tls13_init_key_schedule(hs) ||
+ !ssl_hash_current_message(ssl)) {
return ssl_hs_error;
}
@@ -349,23 +288,18 @@
!CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
!CBB_add_u16(&extensions, 2 /* length */) ||
!CBB_add_u16(&extensions, group_id) ||
- !ssl_complete_message(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, &cbb)) {
CBB_cleanup(&cbb);
return ssl_hs_error;
}
- hs->tls13_state = state_flush_hello_retry_request;
- return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_flush_hello_retry_request(SSL_HANDSHAKE *hs) {
hs->tls13_state = state_process_second_client_hello;
return ssl_hs_flush_and_read_message;
}
static enum ssl_hs_wait_t do_process_second_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
+ if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_HELLO)) {
return ssl_hs_error;
}
@@ -398,6 +332,8 @@
static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
+
+ /* Send a ServerHello. */
CBB cbb, body, extensions;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
!CBB_add_u16(&body, ssl->version) ||
@@ -417,43 +353,27 @@
}
}
- if (!ssl_complete_message(ssl, &cbb)) {
+ if (!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
- hs->tls13_state = state_send_encrypted_extensions;
- return ssl_hs_write_message;
-
-err:
- CBB_cleanup(&cbb);
- return ssl_hs_error;
-}
-
-static enum ssl_hs_wait_t do_send_encrypted_extensions(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
+ /* Derive and enable the handshake traffic secrets. */
if (!tls13_derive_handshake_secrets(hs) ||
!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
hs->hash_len) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
hs->hash_len)) {
- return ssl_hs_error;
+ goto err;
}
- CBB cbb, body;
+ /* Send EncryptedExtensions. */
if (!ssl->method->init_message(ssl, &cbb, &body,
SSL3_MT_ENCRYPTED_EXTENSIONS) ||
!ssl_add_serverhello_tlsext(hs, &body) ||
- !ssl_complete_message(ssl, &cbb)) {
- CBB_cleanup(&cbb);
- return ssl_hs_error;
+ !ssl_add_message_cbb(ssl, &cbb)) {
+ goto err;
}
- hs->tls13_state = state_send_certificate_request;
- return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_send_certificate_request(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
/* Determine whether to request a client certificate. */
hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
/* CertificateRequest may only be sent in non-resumption handshakes. */
@@ -461,71 +381,63 @@
hs->cert_request = 0;
}
- if (!hs->cert_request) {
- /* Skip this state. */
- hs->tls13_state = state_send_server_certificate;
- return ssl_hs_ok;
- }
+ /* Send a CertificateRequest, if necessary. */
+ if (hs->cert_request) {
+ CBB sigalgs_cbb;
+ if (!ssl->method->init_message(ssl, &cbb, &body,
+ SSL3_MT_CERTIFICATE_REQUEST) ||
+ !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
+ goto err;
+ }
- CBB cbb, body, sigalgs_cbb;
- if (!ssl->method->init_message(ssl, &cbb, &body,
- SSL3_MT_CERTIFICATE_REQUEST) ||
- !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) {
- goto err;
- }
+ const uint16_t *sigalgs;
+ size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
+ if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
+ goto err;
+ }
- const uint16_t *sigalgs;
- size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
- if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
- goto err;
- }
+ for (size_t i = 0; i < num_sigalgs; i++) {
+ if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
+ goto err;
+ }
+ }
- for (size_t i = 0; i < num_sigalgs; i++) {
- if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
+ if (!ssl_add_client_CA_list(ssl, &body) ||
+ !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
+ !ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
}
- if (!ssl_add_client_CA_list(ssl, &body) ||
- !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
- !ssl_complete_message(ssl, &cbb)) {
- goto err;
+ /* Send the server Certificate message, if necessary. */
+ if (!ssl->s3->session_reused) {
+ if (!ssl_has_certificate(ssl)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
+ goto err;
+ }
+
+ if (!tls13_add_certificate(hs)) {
+ goto err;
+ }
+
+ hs->tls13_state = state_send_server_certificate_verify;
+ return ssl_hs_ok;
}
- hs->tls13_state = state_send_server_certificate;
- return ssl_hs_write_message;
+ hs->tls13_state = state_send_server_finished;
+ return ssl_hs_ok;
err:
CBB_cleanup(&cbb);
return ssl_hs_error;
}
-static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- if (ssl->s3->session_reused) {
- hs->tls13_state = state_send_server_finished;
- return ssl_hs_ok;
- }
-
- if (!ssl_has_certificate(ssl)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
- return ssl_hs_error;
- }
-
- if (!tls13_prepare_certificate(hs)) {
- return ssl_hs_error;
- }
-
- hs->tls13_state = state_send_server_certificate_verify;
- return ssl_hs_write_message;
-}
-
static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs,
int is_first_run) {
- switch (tls13_prepare_certificate_verify(hs, is_first_run)) {
+ switch (tls13_add_certificate_verify(hs, is_first_run)) {
case ssl_private_key_success:
hs->tls13_state = state_send_server_finished;
- return ssl_hs_write_message;
+ return ssl_hs_ok;
case ssl_private_key_retry:
hs->tls13_state = state_complete_server_certificate_verify;
@@ -540,18 +452,10 @@
}
static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
- if (!tls13_prepare_finished(hs)) {
- return ssl_hs_error;
- }
-
- hs->tls13_state = state_flush;
- return ssl_hs_write_message;
-}
-
-static enum ssl_hs_wait_t do_flush(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- /* Update the secret to the master secret and derive traffic keys. */
- if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
+ if (!tls13_add_finished(hs) ||
+ /* Update the secret to the master secret and derive traffic keys. */
+ !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
!tls13_derive_application_secrets(hs) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
hs->hash_len)) {
@@ -577,7 +481,7 @@
const int allow_anonymous =
(ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
- if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
!tls13_process_certificate(hs, allow_anonymous) ||
!ssl_hash_current_message(ssl)) {
return ssl_hs_error;
@@ -596,7 +500,7 @@
return ssl_hs_ok;
}
- if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
!tls13_process_certificate_verify(hs) ||
!ssl_hash_current_message(ssl)) {
return ssl_hs_error;
@@ -613,7 +517,7 @@
return ssl_hs_ok;
}
- if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
!tls1_verify_channel_id(ssl) ||
!ssl_hash_current_message(ssl)) {
return ssl_hs_error;
@@ -625,7 +529,7 @@
static enum ssl_hs_wait_t do_process_client_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
+ if (!ssl_check_message_type(ssl, SSL3_MT_FINISHED) ||
!tls13_process_finished(hs) ||
!ssl_hash_current_message(ssl) ||
/* evp_aead_seal keys have already been switched. */
@@ -637,18 +541,18 @@
ssl->method->received_flight(ssl);
- /* Refresh the session timestamp so that it is measured from ticket
+ /* Rebase the session timestamp so that it is measured from ticket
* issuance. */
- ssl_session_refresh_time(ssl, ssl->s3->new_session);
+ ssl_session_rebase_time(ssl, ssl->s3->new_session);
hs->tls13_state = state_send_new_session_ticket;
return ssl_hs_ok;
}
-/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
- * client makes several connections before getting a renewal. */
-static const int kNumTickets = 2;
-
static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
+ /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
+ * client makes several connections before getting a renewal. */
+ static const int kNumTickets = 2;
+
SSL *const ssl = hs->ssl;
/* If the client doesn't accept resumption with PSK_DHE_KE, don't send a
* session ticket. */
@@ -658,95 +562,75 @@
}
SSL_SESSION *session = ssl->s3->new_session;
- if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
- goto err;
- }
+ CBB cbb;
+ CBB_zero(&cbb);
- CBB cbb, body, ticket, extensions;
- if (!ssl->method->init_message(ssl, &cbb, &body,
- SSL3_MT_NEW_SESSION_TICKET) ||
- !CBB_add_u32(&body, session->timeout) ||
- !CBB_add_u32(&body, session->ticket_age_add) ||
- !CBB_add_u16_length_prefixed(&body, &ticket) ||
- !ssl_encrypt_ticket(ssl, &ticket, session) ||
- !CBB_add_u16_length_prefixed(&body, &extensions)) {
- goto err;
- }
+ for (int i = 0; i < kNumTickets; i++) {
+ if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
+ goto err;
+ }
- if (ssl->ctx->enable_early_data) {
- session->ticket_max_early_data = kMaxEarlyDataAccepted;
+ CBB body, ticket, extensions;
+ if (!ssl->method->init_message(ssl, &cbb, &body,
+ SSL3_MT_NEW_SESSION_TICKET) ||
+ !CBB_add_u32(&body, session->timeout) ||
+ !CBB_add_u32(&body, session->ticket_age_add) ||
+ !CBB_add_u16_length_prefixed(&body, &ticket) ||
+ !ssl_encrypt_ticket(ssl, &ticket, session) ||
+ !CBB_add_u16_length_prefixed(&body, &extensions)) {
+ goto err;
+ }
- CBB early_data_info;
- if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
- !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
- !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
- !CBB_flush(&extensions)) {
+ if (ssl->ctx->enable_early_data) {
+ session->ticket_max_early_data = kMaxEarlyDataAccepted;
+
+ CBB early_data_info;
+ if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
+ !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
+ !CBB_add_u32(&early_data_info, session->ticket_max_early_data) ||
+ !CBB_flush(&extensions)) {
+ goto err;
+ }
+ }
+
+ /* Add a fake extension. See draft-davidben-tls-grease-01. */
+ if (!CBB_add_u16(&extensions,
+ ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
+ !CBB_add_u16(&extensions, 0 /* empty */)) {
+ goto err;
+ }
+
+ if (!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
}
- /* Add a fake extension. See draft-davidben-tls-grease-01. */
- if (!CBB_add_u16(&extensions,
- ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
- !CBB_add_u16(&extensions, 0 /* empty */)) {
- goto err;
- }
-
- if (!ssl_complete_message(ssl, &cbb)) {
- goto err;
- }
-
hs->session_tickets_sent++;
- if (hs->session_tickets_sent >= kNumTickets) {
- hs->tls13_state = state_flush_new_session_tickets;
- } else {
- hs->tls13_state = state_send_new_session_ticket;
- }
-
- return ssl_hs_write_message;
+ hs->tls13_state = state_done;
+ return ssl_hs_flush;
err:
CBB_cleanup(&cbb);
return ssl_hs_error;
}
-static enum ssl_hs_wait_t do_flush_new_session_tickets(SSL_HANDSHAKE *hs) {
- hs->tls13_state = state_done;
- return ssl_hs_flush;
-}
-
enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
while (hs->tls13_state != state_done) {
enum ssl_hs_wait_t ret = ssl_hs_error;
enum server_hs_state_t state = hs->tls13_state;
switch (state) {
- case state_process_client_hello:
- ret = do_process_client_hello(hs);
- break;
case state_select_parameters:
ret = do_select_parameters(hs);
break;
case state_send_hello_retry_request:
ret = do_send_hello_retry_request(hs);
break;
- case state_flush_hello_retry_request:
- ret = do_flush_hello_retry_request(hs);
- break;
case state_process_second_client_hello:
ret = do_process_second_client_hello(hs);
break;
case state_send_server_hello:
ret = do_send_server_hello(hs);
break;
- case state_send_encrypted_extensions:
- ret = do_send_encrypted_extensions(hs);
- break;
- case state_send_certificate_request:
- ret = do_send_certificate_request(hs);
- break;
- case state_send_server_certificate:
- ret = do_send_server_certificate(hs);
- break;
case state_send_server_certificate_verify:
ret = do_send_server_certificate_verify(hs, 1 /* first run */);
break;
@@ -756,9 +640,6 @@
case state_send_server_finished:
ret = do_send_server_finished(hs);
break;
- case state_flush:
- ret = do_flush(hs);
- break;
case state_process_client_certificate:
ret = do_process_client_certificate(hs);
break;
@@ -774,9 +655,6 @@
case state_send_new_session_ticket:
ret = do_send_new_session_ticket(hs);
break;
- case state_flush_new_session_tickets:
- ret = do_flush_new_session_tickets(hs);
- break;
case state_done:
ret = ssl_hs_ok;
break;
diff --git a/src/ssl/tls_method.c b/src/ssl/tls_method.c
index a6584c1..70683e4 100644
--- a/src/ssl/tls_method.c
+++ b/src/ssl/tls_method.c
@@ -100,14 +100,6 @@
static int ssl3_supports_cipher(const SSL_CIPHER *cipher) { return 1; }
-static int ssl3_flush_flight(SSL *ssl) {
- int ret = BIO_flush(ssl->wbio);
- if (ret <= 0) {
- ssl->rwstate = SSL_WRITING;
- }
- return ret;
-}
-
static void ssl3_expect_flight(SSL *ssl) {}
static void ssl3_received_flight(SSL *ssl) {}
@@ -155,9 +147,9 @@
ssl3_supports_cipher,
ssl3_init_message,
ssl3_finish_message,
- ssl3_queue_message,
- ssl3_write_message,
- ssl3_send_change_cipher_spec,
+ ssl3_add_message,
+ ssl3_add_change_cipher_spec,
+ ssl3_add_alert,
ssl3_flush_flight,
ssl3_expect_flight,
ssl3_received_flight,
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c
index 362b0c2..6ff79c4 100644
--- a/src/ssl/tls_record.c
+++ b/src/ssl/tls_record.c
@@ -205,20 +205,19 @@
}
size_t SSL_max_seal_overhead(const SSL *ssl) {
- size_t ret = SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
if (SSL_is_dtls(ssl)) {
- ret += DTLS1_RT_HEADER_LENGTH;
- } else if (ssl_uses_short_header(ssl, evp_aead_seal)) {
- ret += 2;
- } else {
- ret += SSL3_RT_HEADER_LENGTH;
+ return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch);
}
+
+ size_t ret =
+ ssl_uses_short_header(ssl, evp_aead_seal) ? 2 : SSL3_RT_HEADER_LENGTH;
+ ret += SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
/* TLS 1.3 needs an extra byte for the encrypted record type. */
if (ssl->s3->have_version &&
ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
ret += 1;
}
- if (!SSL_is_dtls(ssl) && ssl_needs_record_splitting(ssl)) {
+ if (ssl_needs_record_splitting(ssl)) {
ret *= 2;
}
return ret;
diff --git a/src/tool/client.cc b/src/tool/client.cc
index c832ab5..0301a81 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -106,6 +106,11 @@
"Establish a second connection resuming the original connection.",
},
{
+ "-root-certs", kOptionalArgument,
+ "A filename containing one of more PEM root certificates. Implies that"
+ "verification is required.",
+ },
+ {
"", kOptionalArgument, "",
},
};
@@ -390,6 +395,16 @@
SSL_CTX_set_grease_enabled(ctx.get(), 1);
}
+ if (args_map.count("-root-certs") != 0) {
+ if (!SSL_CTX_load_verify_locations(
+ ctx.get(), args_map["-root-certs"].c_str(), nullptr)) {
+ fprintf(stderr, "Failed to load root certificates.\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr);
+ }
+
if (args_map.count("-resume") != 0 &&
!DoConnection(ctx.get(), args_map, &WaitForSession)) {
return false;
diff --git a/src/util/all_tests.go b/src/util/all_tests.go
index 6cf8d13..d4bb802 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -35,6 +35,7 @@
useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
useCallgrind = flag.Bool("callgrind", false, "If true, run code under valgrind to generate callgrind traces.")
useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
+ useSDE = flag.Bool("sde", false, "If true, run BoringSSL code under Intel's SDE for each supported chip")
buildDir = flag.String("build-dir", "build", "The build directory to run the tests from.")
numWorkers = flag.Int("num-workers", 1, "Runs the given number of workers when testing.")
jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
@@ -42,7 +43,12 @@
mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask each test to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
)
-type test []string
+type test struct {
+ args []string
+ // cpu, if not empty, contains an Intel CPU code to simulate. Run
+ // `sde64 -help` to get a list of these codes.
+ cpu string
+}
type result struct {
Test test
@@ -67,6 +73,27 @@
IsUnexpected bool `json:"is_unexpected"`
}
+// sdeCPUs contains a list of CPU code that we run all tests under when *useSDE
+// is true.
+var sdeCPUs = []string{
+ "p4p", // Pentium4 Prescott
+ "mrm", // Merom
+ "pnr", // Penryn
+ "nhm", // Nehalem
+ "wsm", // Westmere
+ "snb", // Sandy Bridge
+ "ivb", // Ivy Bridge
+ "hsw", // Haswell
+ "bdw", // Broadwell
+ "skx", // Skylake Server
+ "skl", // Skylake Client
+ "cnl", // Cannonlake
+ "knl", // Knights Landing
+ "slt", // Saltwell
+ "slm", // Silvermont
+ "glm", // Goldmont
+}
+
func newTestOutput() *testOutput {
return &testOutput{
Version: 3,
@@ -130,6 +157,12 @@
return exec.Command("xterm", xtermArgs...)
}
+func sdeOf(cpu, path string, args ...string) *exec.Cmd {
+ sdeArgs := []string{"-" + cpu, "--", path}
+ sdeArgs = append(sdeArgs, args...)
+ return exec.Command("sde", sdeArgs...)
+}
+
type moreMallocsError struct{}
func (moreMallocsError) Error() string {
@@ -139,8 +172,8 @@
var errMoreMallocs = moreMallocsError{}
func runTestOnce(test test, mallocNumToFail int64) (passed bool, err error) {
- prog := path.Join(*buildDir, test[0])
- args := test[1:]
+ prog := path.Join(*buildDir, test.args[0])
+ args := test.args[1:]
var cmd *exec.Cmd
if *useValgrind {
cmd = valgrindOf(false, prog, args...)
@@ -148,6 +181,8 @@
cmd = callgrindOf(prog, args...)
} else if *useGDB {
cmd = gdbOf(prog, args...)
+ } else if *useSDE {
+ cmd = sdeOf(test.cpu, prog, args...)
} else {
cmd = exec.Command(prog, args...)
}
@@ -216,12 +251,12 @@
// relevant to the test's uniqueness.
func shortTestName(test test) string {
var args []string
- for _, arg := range test {
- if test[0] == "crypto/evp/evp_test" || !strings.HasSuffix(arg, ".txt") {
+ for _, arg := range test.args {
+ if test.args[0] == "crypto/evp/evp_test" || !strings.HasSuffix(arg, ".txt") {
args = append(args, arg)
}
}
- return strings.Join(args, " ")
+ return strings.Join(args, " ") + test.cpuMsg()
}
// setWorkingDirectory walks up directories as needed until the current working
@@ -245,10 +280,15 @@
defer in.Close()
decoder := json.NewDecoder(in)
- var result []test
- if err := decoder.Decode(&result); err != nil {
+ var testArgs [][]string
+ if err := decoder.Decode(&testArgs); err != nil {
return nil, err
}
+
+ var result []test
+ for _, args := range testArgs {
+ result = append(result, test{args: args})
+ }
return result, nil
}
@@ -260,6 +300,14 @@
}
}
+func (t test) cpuMsg() string {
+ if len(t.cpu) == 0 {
+ return ""
+ }
+
+ return fmt.Sprintf(" (for CPU %q)", t.cpu)
+}
+
func main() {
flag.Parse()
setWorkingDirectory()
@@ -281,7 +329,15 @@
go func() {
for _, test := range testCases {
- tests <- test
+ if *useSDE {
+ for _, cpu := range sdeCPUs {
+ testForCPU := test
+ testForCPU.cpu = cpu
+ tests <- testForCPU
+ }
+ } else {
+ tests <- test
+ }
}
close(tests)
@@ -293,15 +349,16 @@
var failed []test
for testResult := range results {
test := testResult.Test
+ args := test.args
- fmt.Printf("%s\n", strings.Join([]string(test), " "))
+ fmt.Printf("%s%s\n", strings.Join(args, " "), test.cpuMsg())
name := shortTestName(test)
if testResult.Error != nil {
- fmt.Printf("%s failed to complete: %s\n", test[0], testResult.Error)
+ fmt.Printf("%s failed to complete: %s\n", args[0], testResult.Error)
failed = append(failed, test)
testOutput.addResult(name, "CRASHED")
} else if !testResult.Passed {
- fmt.Printf("%s failed to print PASS on the last line.\n", test[0])
+ fmt.Printf("%s failed to print PASS on the last line.\n", args[0])
failed = append(failed, test)
testOutput.addResult(name, "FAIL")
} else {
@@ -318,7 +375,7 @@
if len(failed) > 0 {
fmt.Printf("\n%d of %d tests failed:\n", len(failed), len(testCases))
for _, test := range failed {
- fmt.Printf("\t%s\n", strings.Join([]string(test), " "))
+ fmt.Printf("\t%s%s\n", strings.Join(test.args, ""), test.cpuMsg())
}
os.Exit(1)
}
diff --git a/win-x86_64/crypto/bn/x86_64-mont5.asm b/win-x86_64/crypto/bn/x86_64-mont5.asm
index cd9a6e5..58f19ac 100644
--- a/win-x86_64/crypto/bn/x86_64-mont5.asm
+++ b/win-x86_64/crypto/bn/x86_64-mont5.asm
@@ -1868,6 +1868,7 @@
ALIGN 32
$L$8x_tail_done:
+ xor rax,rax
add r8,QWORD[rdx]
adc r9,0
adc r10,0
@@ -1876,9 +1877,7 @@
adc r13,0
adc r14,0
adc r15,0
-
-
- xor rax,rax
+ adc rax,0
neg rsi
$L$8x_no_tail: