summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2015-11-06 23:39:13 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-11-06 23:39:13 +0000
commitcf79b9c51a06c935943059d7800e3f15c0e6cb10 (patch)
tree37655d933cb72bcd7553af526581d3e24e051d7d
parent47e0ae95b75c3d1c435f16ccd959638015c6d9b9 (diff)
parente99801b603dea8893dcc61c70b327ef2d00b652c (diff)
downloadexternal_boringssl-cf79b9c51a06c935943059d7800e3f15c0e6cb10.zip
external_boringssl-cf79b9c51a06c935943059d7800e3f15c0e6cb10.tar.gz
external_boringssl-cf79b9c51a06c935943059d7800e3f15c0e6cb10.tar.bz2
Revert "Revert "external/boringssl: sync with upstream.""
am: e99801b603 * commit 'e99801b603dea8893dcc61c70b327ef2d00b652c': Revert "Revert "external/boringssl: sync with upstream.""
-rw-r--r--Android.mk20
-rw-r--r--BORINGSSL_REVISION2
-rw-r--r--linux-arm/crypto/aes/bsaes-armv7.S2
-rw-r--r--linux-arm/crypto/modes/ghash-armv4.S3
-rw-r--r--linux-x86/crypto/sha/sha1-586.S189
-rw-r--r--linux-x86/crypto/sha/sha256-586.S236
-rw-r--r--mac-x86/crypto/sha/sha1-586.S185
-rw-r--r--mac-x86/crypto/sha/sha256-586.S236
-rw-r--r--sources.mk3
-rw-r--r--src/BUILDING.md77
-rw-r--r--src/CMakeLists.txt24
-rw-r--r--src/PORTING.md25
-rw-r--r--src/README.md29
-rw-r--r--src/crypto/CMakeLists.txt3
-rw-r--r--src/crypto/aes/CMakeLists.txt1
-rw-r--r--src/crypto/aes/aes.c65
-rw-r--r--src/crypto/aes/asm/aesni-x86.pl2
-rw-r--r--src/crypto/aes/asm/bsaes-armv7.pl2
-rw-r--r--src/crypto/aes/mode_wrappers.c4
-rw-r--r--src/crypto/asn1/tasn_dec.c4
-rw-r--r--src/crypto/base64/CMakeLists.txt1
-rw-r--r--src/crypto/bio/CMakeLists.txt1
-rw-r--r--src/crypto/bio/bio.c10
-rw-r--r--src/crypto/bio/bio_mem.c2
-rw-r--r--src/crypto/bio/connect.c126
-rw-r--r--src/crypto/bio/fd.c4
-rw-r--r--src/crypto/bio/printf.c6
-rw-r--r--src/crypto/bn/CMakeLists.txt1
-rw-r--r--src/crypto/bn/asm/rsaz-avx2.pl30
-rw-r--r--src/crypto/bn/asm/rsaz-x86_64.pl25
-rw-r--r--src/crypto/bn/asm/x86_64-mont.pl20
-rw-r--r--src/crypto/bn/asm/x86_64-mont5.pl20
-rw-r--r--src/crypto/bn/exponentiation.c28
-rw-r--r--src/crypto/bn/generic.c2
-rw-r--r--src/crypto/bn/montgomery.c18
-rw-r--r--src/crypto/bn/prime.c2
-rw-r--r--src/crypto/buf/buf.c2
-rw-r--r--src/crypto/bytestring/CMakeLists.txt1
-rw-r--r--src/crypto/bytestring/bytestring_test.cc50
-rw-r--r--src/crypto/bytestring/cbb.c18
-rw-r--r--src/crypto/chacha/chacha_generic.c17
-rw-r--r--src/crypto/chacha/chacha_vec.c28
-rw-r--r--src/crypto/chacha/chacha_vec_arm.S597
-rw-r--r--src/crypto/chacha/chacha_vec_arm_generate.go9
-rw-r--r--src/crypto/cipher/CMakeLists.txt1
-rw-r--r--src/crypto/cipher/aead_test.cc3
-rw-r--r--src/crypto/cipher/e_aes.c128
-rw-r--r--src/crypto/cipher/e_chacha20poly1305.c207
-rw-r--r--src/crypto/cipher/e_tls.c6
-rw-r--r--src/crypto/cipher/test/aes_128_gcm_tests.txt105
-rw-r--r--src/crypto/cipher/test/aes_256_gcm_tests.txt46
-rw-r--r--src/crypto/cipher/test/chacha20_poly1305_old_tests.txt422
-rw-r--r--src/crypto/cipher/test/chacha20_poly1305_tests.txt404
-rw-r--r--src/crypto/cmac/CMakeLists.txt1
-rw-r--r--src/crypto/cpu-arm.c22
-rw-r--r--src/crypto/crypto.c30
-rw-r--r--src/crypto/des/des.c2
-rw-r--r--src/crypto/dh/CMakeLists.txt1
-rw-r--r--src/crypto/dh/dh.c20
-rw-r--r--src/crypto/dh/params.c2
-rw-r--r--src/crypto/digest/CMakeLists.txt1
-rw-r--r--src/crypto/dsa/CMakeLists.txt1
-rw-r--r--src/crypto/dsa/dsa.c2
-rw-r--r--src/crypto/dsa/dsa_impl.c18
-rw-r--r--src/crypto/ec/CMakeLists.txt2
-rw-r--r--src/crypto/ec/ec.c159
-rw-r--r--src/crypto/ec/ec_asn1.c12
-rw-r--r--src/crypto/ec/ec_montgomery.c31
-rw-r--r--src/crypto/ec/internal.h80
-rw-r--r--src/crypto/ec/oct.c34
-rw-r--r--src/crypto/ec/p224-64.c1341
-rw-r--r--src/crypto/ec/p256-64.c18
-rw-r--r--src/crypto/ec/simple.c29
-rw-r--r--src/crypto/ec/wnaf.c5
-rw-r--r--src/crypto/ecdh/ecdh.c72
-rw-r--r--src/crypto/ecdsa/CMakeLists.txt1
-rw-r--r--src/crypto/err/CMakeLists.txt1
-rw-r--r--src/crypto/err/err_test.cc2
-rw-r--r--src/crypto/evp/CMakeLists.txt1
-rw-r--r--src/crypto/evp/digestsign.c5
-rw-r--r--src/crypto/evp/evp_asn1.c19
-rw-r--r--src/crypto/evp/evp_extra_test.cc85
-rw-r--r--src/crypto/evp/pbkdf.c16
-rw-r--r--src/crypto/evp/pbkdf_test.cc43
-rw-r--r--src/crypto/hkdf/CMakeLists.txt1
-rw-r--r--src/crypto/hmac/CMakeLists.txt1
-rw-r--r--src/crypto/lhash/CMakeLists.txt1
-rw-r--r--src/crypto/modes/CMakeLists.txt1
-rw-r--r--src/crypto/modes/asm/aesni-gcm-x86_64.pl24
-rw-r--r--src/crypto/modes/asm/ghash-armv4.pl3
-rw-r--r--src/crypto/modes/asm/ghash-x86_64.pl24
-rw-r--r--src/crypto/modes/cbc.c1
-rw-r--r--src/crypto/modes/cfb.c5
-rw-r--r--src/crypto/modes/ctr.c6
-rw-r--r--src/crypto/modes/gcm.c49
-rw-r--r--src/crypto/modes/gcm_test.c9
-rw-r--r--src/crypto/modes/internal.h175
-rw-r--r--src/crypto/modes/ofb.c5
-rw-r--r--src/crypto/pem/pem_info.c2
-rwxr-xr-xsrc/crypto/perlasm/x86_64-xlate.pl15
-rw-r--r--src/crypto/pkcs8/CMakeLists.txt1
-rw-r--r--src/crypto/pkcs8/p5_pbev2.c5
-rw-r--r--src/crypto/pkcs8/pkcs12_test.cc16
-rw-r--r--src/crypto/pkcs8/pkcs8.c25
-rw-r--r--src/crypto/poly1305/CMakeLists.txt1
-rw-r--r--src/crypto/poly1305/poly1305_test.txt2
-rw-r--r--src/crypto/rand/CMakeLists.txt1
-rw-r--r--src/crypto/rand/hwrand.c65
-rw-r--r--src/crypto/rand/internal.h5
-rw-r--r--src/crypto/rand/rand.c62
-rw-r--r--src/crypto/rc4/rc4.c17
-rw-r--r--src/crypto/rsa/CMakeLists.txt1
-rw-r--r--src/crypto/rsa/rsa.c27
-rw-r--r--src/crypto/rsa/rsa_asn1.c15
-rw-r--r--src/crypto/rsa/rsa_impl.c2
-rw-r--r--src/crypto/rsa/rsa_test.cc73
-rw-r--r--src/crypto/sha/asm/sha1-586.pl25
-rw-r--r--src/crypto/sha/asm/sha1-x86_64.pl26
-rw-r--r--src/crypto/sha/asm/sha256-586.pl28
-rw-r--r--src/crypto/sha/asm/sha512-x86_64.pl32
-rw-r--r--src/crypto/test/scoped_types.h1
-rw-r--r--src/crypto/x509/CMakeLists.txt1
-rw-r--r--src/crypto/x509/x509_lu.c30
-rw-r--r--src/crypto/x509/x509_vfy.c2
-rw-r--r--src/crypto/x509/x_x509.c15
-rw-r--r--src/crypto/x509v3/CMakeLists.txt2
-rw-r--r--src/crypto/x509v3/pcy_tree.c2
-rw-r--r--src/crypto/x509v3/tab_test.c5
-rw-r--r--src/crypto/x509v3/v3_alt.c24
-rw-r--r--src/crypto/x509v3/v3_purp.c19
-rw-r--r--src/crypto/x509v3/v3_utl.c10
-rw-r--r--src/decrepit/CMakeLists.txt2
-rw-r--r--src/decrepit/des/cfb64ede.c6
-rw-r--r--src/decrepit/xts/xts.c3
-rw-r--r--src/include/openssl/aead.h16
-rw-r--r--src/include/openssl/arm_arch.h9
-rw-r--r--src/include/openssl/asn1.h1
-rw-r--r--src/include/openssl/asn1_mac.h1
-rw-r--r--src/include/openssl/asn1t.h1
-rw-r--r--src/include/openssl/base.h2
-rw-r--r--src/include/openssl/base64.h57
-rw-r--r--src/include/openssl/bio.h6
-rw-r--r--src/include/openssl/bn.h7
-rw-r--r--src/include/openssl/bytestring.h10
-rw-r--r--src/include/openssl/chacha.h2
-rw-r--r--src/include/openssl/cmac.h2
-rw-r--r--src/include/openssl/cpu.h48
-rw-r--r--src/include/openssl/crypto.h6
-rw-r--r--src/include/openssl/des.h13
-rw-r--r--src/include/openssl/digest.h15
-rw-r--r--src/include/openssl/ec.h6
-rw-r--r--src/include/openssl/ecdh.h6
-rw-r--r--src/include/openssl/ecdsa.h2
-rw-r--r--src/include/openssl/lhash.h2
-rw-r--r--src/include/openssl/modes.h223
-rw-r--r--src/include/openssl/obj.h6
-rw-r--r--src/include/openssl/pkcs8.h31
-rw-r--r--src/include/openssl/poly1305.h11
-rw-r--r--src/include/openssl/rsa.h8
-rw-r--r--src/include/openssl/ssl.h1684
-rw-r--r--src/include/openssl/ssl3.h268
-rw-r--r--src/include/openssl/time_support.h6
-rw-r--r--src/include/openssl/tls1.h77
-rw-r--r--src/include/openssl/x509.h1
-rw-r--r--src/include/openssl/x509_vfy.h1
-rw-r--r--src/ssl/CMakeLists.txt4
-rw-r--r--src/ssl/d1_both.c4
-rw-r--r--src/ssl/d1_clnt.c2
-rw-r--r--src/ssl/d1_meth.c1
-rw-r--r--src/ssl/d1_pkt.c4
-rw-r--r--src/ssl/d1_srtp.c3
-rw-r--r--src/ssl/d1_srvr.c3
-rw-r--r--src/ssl/internal.h34
-rw-r--r--src/ssl/pqueue/CMakeLists.txt1
-rw-r--r--src/ssl/pqueue/pqueue_test.c3
-rw-r--r--src/ssl/s3_clnt.c436
-rw-r--r--src/ssl/s3_enc.c5
-rw-r--r--src/ssl/s3_lib.c7
-rw-r--r--src/ssl/s3_pkt.c21
-rw-r--r--src/ssl/s3_srvr.c302
-rw-r--r--src/ssl/ssl_asn1.c8
-rw-r--r--src/ssl/ssl_cipher.c100
-rw-r--r--src/ssl/ssl_file.c10
-rw-r--r--src/ssl/ssl_lib.c413
-rw-r--r--src/ssl/ssl_rsa.c30
-rw-r--r--src/ssl/ssl_session.c223
-rw-r--r--src/ssl/ssl_stat.c613
-rw-r--r--src/ssl/ssl_test.cc190
-rw-r--r--src/ssl/ssl_txt.c214
-rw-r--r--src/ssl/t1_lib.c109
-rw-r--r--src/ssl/test/bssl_shim.cc131
-rw-r--r--src/ssl/test/runner/alert.go2
-rw-r--r--src/ssl/test/runner/chacha20_poly1305.go2
-rw-r--r--src/ssl/test/runner/chacha20_poly1305_test.go2
-rw-r--r--src/ssl/test/runner/cipher_suites.go2
-rw-r--r--src/ssl/test/runner/common.go11
-rw-r--r--src/ssl/test/runner/conn.go2
-rw-r--r--src/ssl/test/runner/dtls.go2
-rw-r--r--src/ssl/test/runner/handshake_client.go6
-rw-r--r--src/ssl/test/runner/handshake_messages.go2
-rw-r--r--src/ssl/test/runner/handshake_server.go16
-rw-r--r--src/ssl/test/runner/key_agreement.go2
-rw-r--r--src/ssl/test/runner/packet_adapter.go2
-rw-r--r--src/ssl/test/runner/poly1305.go2
-rw-r--r--src/ssl/test/runner/prf.go2
-rw-r--r--src/ssl/test/runner/recordingconn.go2
-rw-r--r--src/ssl/test/runner/runner.go242
-rw-r--r--src/ssl/test/runner/runner_test.go7
-rw-r--r--src/ssl/test/runner/test_output.go2
-rw-r--r--src/ssl/test/runner/ticket.go2
-rw-r--r--src/ssl/test/runner/tls.go2
-rw-r--r--src/ssl/test/test_config.cc8
-rw-r--r--src/ssl/test/test_config.h6
-rw-r--r--src/ssl/tls_record.c19
-rw-r--r--src/tool/speed.cc6
-rw-r--r--src/tool/tool.cc3
-rw-r--r--src/tool/transport_common.cc10
-rw-r--r--src/util/all_tests.json1
-rwxr-xr-xsrc/util/bot/go/bootstrap.py5
-rw-r--r--src/util/doc.config2
-rw-r--r--src/util/doc.go64
-rw-r--r--src/util/generate_build_files.py50
-rw-r--r--win-x86/crypto/sha/sha1-586.asm182
-rw-r--r--win-x86/crypto/sha/sha256-586.asm236
224 files changed, 6970 insertions, 5714 deletions
diff --git a/Android.mk b/Android.mk
index 5ae544c..9cbc910 100644
--- a/Android.mk
+++ b/Android.mk
@@ -13,7 +13,7 @@ LOCAL_MODULE := libcrypto_static
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
LOCAL_SDK_VERSION := 9
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
# sha256-armv4.S does not compile with clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
LOCAL_CLANG_ASFLAGS_arm64 += -march=armv8-a+crypto
@@ -26,7 +26,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libcrypto
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SDK_VERSION := 9
# sha256-armv4.S does not compile with clang.
LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
@@ -41,7 +41,7 @@ LOCAL_CPP_EXTENSION := cc
LOCAL_MODULE := bssl
LOCAL_MODULE_TAGS := optional
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SHARED_LIBRARIES=libcrypto libssl
include $(LOCAL_PATH)/sources.mk
LOCAL_SRC_FILES = $(tool_sources)
@@ -54,7 +54,7 @@ LOCAL_MODULE := libcrypto_static
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
# Windows and Macs both have problems with assembly files
LOCAL_CFLAGS_darwin += -DOPENSSL_NO_ASM
LOCAL_CFLAGS_windows += -DOPENSSL_NO_ASM
@@ -68,7 +68,7 @@ LOCAL_MODULE := libcrypto-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_MULTILIB := both
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/crypto-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
# Windows and Macs both have problems with assembly files
LOCAL_CFLAGS_darwin += -DOPENSSL_NO_ASM
LOCAL_CFLAGS_windows += -DOPENSSL_NO_ASM
@@ -85,7 +85,7 @@ LOCAL_MODULE := libssl_static
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
LOCAL_SDK_VERSION := 9
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
include $(LOCAL_PATH)/ssl-sources.mk
include $(BUILD_STATIC_LIBRARY)
@@ -95,7 +95,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libssl
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SHARED_LIBRARIES=libcrypto
LOCAL_SDK_VERSION := 9
include $(LOCAL_PATH)/ssl-sources.mk
@@ -107,7 +107,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libssl_static-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
include $(LOCAL_PATH)/ssl-sources.mk
include $(BUILD_HOST_STATIC_LIBRARY)
@@ -119,7 +119,7 @@ LOCAL_CPP_EXTENSION := cc
LOCAL_MODULE := bssl
LOCAL_MODULE_TAGS := optional
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SHARED_LIBRARIES=libcrypto-host libssl-host
# Needed for clock_gettime.
LOCAL_LDFLAGS := -lrt
@@ -135,7 +135,7 @@ LOCAL_MODULE := libssl-host
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/src/include
LOCAL_MULTILIB := both
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/ssl-sources.mk
-LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -Wno-unused-parameter
+LOCAL_CFLAGS += -fvisibility=hidden -DBORINGSSL_SHARED_LIBRARY -DBORINGSSL_IMPLEMENTATION -DOPENSSL_SMALL -Wno-unused-parameter
LOCAL_SHARED_LIBRARIES += libcrypto-host
include $(LOCAL_PATH)/ssl-sources.mk
include $(BUILD_HOST_SHARED_LIBRARY)
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index f3dd323..ee868fd 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-d98dc1311e20193ac188e359e91aeaaf5cc3a7e2
+51a01a5cd44b3bdfab5220847000f13fc85f000b
diff --git a/linux-arm/crypto/aes/bsaes-armv7.S b/linux-arm/crypto/aes/bsaes-armv7.S
index 85262d5..a3ebec8 100644
--- a/linux-arm/crypto/aes/bsaes-armv7.S
+++ b/linux-arm/crypto/aes/bsaes-armv7.S
@@ -47,7 +47,6 @@
@
@ <ard.biesheuvel@linaro.org>
-#if defined(__arm__)
#ifndef __KERNEL__
# include <openssl/arm_arch.h>
@@ -2575,5 +2574,4 @@ bsaes_xts_decrypt:
.size bsaes_xts_decrypt,.-bsaes_xts_decrypt
#endif
-#endif
#endif \ No newline at end of file
diff --git a/linux-arm/crypto/modes/ghash-armv4.S b/linux-arm/crypto/modes/ghash-armv4.S
index f868c2d..0a43989 100644
--- a/linux-arm/crypto/modes/ghash-armv4.S
+++ b/linux-arm/crypto/modes/ghash-armv4.S
@@ -1,5 +1,4 @@
#if defined(__arm__)
-#if defined(__arm__)
#include <openssl/arm_arch.h>
.syntax unified
@@ -536,6 +535,4 @@ gcm_ghash_neon:
.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2
-
-#endif
#endif \ No newline at end of file
diff --git a/linux-x86/crypto/sha/sha1-586.S b/linux-x86/crypto/sha/sha1-586.S
index 808ccac..dd86f31 100644
--- a/linux-x86/crypto/sha/sha1-586.S
+++ b/linux-x86/crypto/sha/sha1-586.S
@@ -23,8 +23,6 @@ sha1_block_data_order:
movl 8(%esi),%ecx
testl $16777216,%eax
jz .L001x86
- testl $536870912,%ecx
- jnz .Lshaext_shortcut
jmp .Lssse3_shortcut
.align 16
.L001x86:
@@ -1393,177 +1391,6 @@ sha1_block_data_order:
popl %ebp
ret
.size sha1_block_data_order,.-.L_sha1_block_data_order_begin
-.hidden _sha1_block_data_order_shaext
-.type _sha1_block_data_order_shaext,@function
-.align 16
-_sha1_block_data_order_shaext:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- call .L003pic_point
-.L003pic_point:
- popl %ebp
- leal .LK_XX_XX-.L003pic_point(%ebp),%ebp
-.Lshaext_shortcut:
- movl 20(%esp),%edi
- movl %esp,%ebx
- movl 24(%esp),%esi
- movl 28(%esp),%ecx
- subl $32,%esp
- movdqu (%edi),%xmm0
- movd 16(%edi),%xmm1
- andl $-32,%esp
- movdqa 80(%ebp),%xmm3
- movdqu (%esi),%xmm4
- pshufd $27,%xmm0,%xmm0
- movdqu 16(%esi),%xmm5
- pshufd $27,%xmm1,%xmm1
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,227
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,235
-.byte 102,15,56,0,243
-.byte 102,15,56,0,251
- jmp .L004loop_shaext
-.align 16
-.L004loop_shaext:
- decl %ecx
- leal 64(%esi),%eax
- movdqa %xmm1,(%esp)
- paddd %xmm4,%xmm1
- cmovnel %eax,%esi
- movdqa %xmm0,16(%esp)
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
- movdqu (%esi),%xmm4
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,213
- movdqu 16(%esi),%xmm5
-.byte 102,15,56,0,227
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,206
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,235
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,215
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,243
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
- movdqa (%esp),%xmm2
-.byte 102,15,56,0,251
-.byte 15,56,200,202
- paddd 16(%esp),%xmm0
- jnz .L004loop_shaext
- pshufd $27,%xmm0,%xmm0
- pshufd $27,%xmm1,%xmm1
- movdqu %xmm0,(%edi)
- movd %xmm1,16(%edi)
- movl %ebx,%esp
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.size _sha1_block_data_order_shaext,.-_sha1_block_data_order_shaext
.hidden _sha1_block_data_order_ssse3
.type _sha1_block_data_order_ssse3,@function
.align 16
@@ -1572,10 +1399,10 @@ _sha1_block_data_order_ssse3:
pushl %ebx
pushl %esi
pushl %edi
- call .L005pic_point
-.L005pic_point:
+ call .L003pic_point
+.L003pic_point:
popl %ebp
- leal .LK_XX_XX-.L005pic_point(%ebp),%ebp
+ leal .LK_XX_XX-.L003pic_point(%ebp),%ebp
.Lssse3_shortcut:
movdqa (%ebp),%xmm7
movdqa 16(%ebp),%xmm0
@@ -1628,9 +1455,9 @@ _sha1_block_data_order_ssse3:
xorl %edx,%ebp
pshufd $238,%xmm0,%xmm4
andl %ebp,%esi
- jmp .L006loop
+ jmp .L004loop
.align 16
-.L006loop:
+.L004loop:
rorl $2,%ebx
xorl %edx,%esi
movl %eax,%ebp
@@ -2533,7 +2360,7 @@ _sha1_block_data_order_ssse3:
addl %edx,%ecx
movl 196(%esp),%ebp
cmpl 200(%esp),%ebp
- je .L007done
+ je .L005done
movdqa 160(%esp),%xmm7
movdqa 176(%esp),%xmm6
movdqu (%ebp),%xmm0
@@ -2668,9 +2495,9 @@ _sha1_block_data_order_ssse3:
pshufd $238,%xmm0,%xmm4
andl %ebx,%esi
movl %ebp,%ebx
- jmp .L006loop
+ jmp .L004loop
.align 16
-.L007done:
+.L005done:
addl 16(%esp),%ebx
xorl %edi,%esi
movl %ecx,%ebp
diff --git a/linux-x86/crypto/sha/sha256-586.S b/linux-x86/crypto/sha/sha256-586.S
index 08d9484..196f7f9 100644
--- a/linux-x86/crypto/sha/sha256-586.S
+++ b/linux-x86/crypto/sha/sha256-586.S
@@ -37,17 +37,15 @@ sha256_block_data_order:
jz .L003no_xmm
andl $1073741824,%ecx
andl $268435968,%ebx
- testl $536870912,%edx
- jnz .L004shaext
orl %ebx,%ecx
andl $1342177280,%ecx
cmpl $1342177280,%ecx
testl $512,%ebx
- jnz .L005SSSE3
+ jnz .L004SSSE3
.L003no_xmm:
subl %edi,%eax
cmpl $256,%eax
- jae .L006unrolled
+ jae .L005unrolled
jmp .L002loop
.align 16
.L002loop:
@@ -119,7 +117,7 @@ sha256_block_data_order:
movl %ecx,28(%esp)
movl %edi,32(%esp)
.align 16
-.L00700_15:
+.L00600_15:
movl %edx,%ecx
movl 24(%esp),%esi
rorl $14,%ecx
@@ -157,11 +155,11 @@ sha256_block_data_order:
addl $4,%ebp
addl %ebx,%eax
cmpl $3248222580,%esi
- jne .L00700_15
+ jne .L00600_15
movl 156(%esp),%ecx
- jmp .L00816_63
+ jmp .L00716_63
.align 16
-.L00816_63:
+.L00716_63:
movl %ecx,%ebx
movl 104(%esp),%esi
rorl $11,%ecx
@@ -216,7 +214,7 @@ sha256_block_data_order:
addl $4,%ebp
addl %ebx,%eax
cmpl $3329325298,%esi
- jne .L00816_63
+ jne .L00716_63
movl 356(%esp),%esi
movl 8(%esp),%ebx
movl 16(%esp),%ecx
@@ -260,7 +258,7 @@ sha256_block_data_order:
.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
.byte 62,0
.align 16
-.L006unrolled:
+.L005unrolled:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebp
@@ -277,9 +275,9 @@ sha256_block_data_order:
movl %ebx,20(%esp)
movl %ecx,24(%esp)
movl %esi,28(%esp)
- jmp .L009grand_loop
+ jmp .L008grand_loop
.align 16
-.L009grand_loop:
+.L008grand_loop:
movl (%edi),%ebx
movl 4(%edi),%ecx
bswap %ebx
@@ -3159,7 +3157,7 @@ sha256_block_data_order:
movl %ebx,24(%esp)
movl %ecx,28(%esp)
cmpl 104(%esp),%edi
- jb .L009grand_loop
+ jb .L008grand_loop
movl 108(%esp),%esp
popl %edi
popl %esi
@@ -3167,205 +3165,7 @@ sha256_block_data_order:
popl %ebp
ret
.align 32
-.L004shaext:
- subl $32,%esp
- movdqu (%esi),%xmm1
- leal 128(%ebp),%ebp
- movdqu 16(%esi),%xmm2
- movdqa 128(%ebp),%xmm7
- pshufd $27,%xmm1,%xmm0
- pshufd $177,%xmm1,%xmm1
- pshufd $27,%xmm2,%xmm2
-.byte 102,15,58,15,202,8
- punpcklqdq %xmm0,%xmm2
- jmp .L010loop_shaext
-.align 16
-.L010loop_shaext:
- movdqu (%edi),%xmm3
- movdqu 16(%edi),%xmm4
- movdqu 32(%edi),%xmm5
-.byte 102,15,56,0,223
- movdqu 48(%edi),%xmm6
- movdqa %xmm2,16(%esp)
- movdqa -128(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 102,15,56,0,231
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- nop
- movdqa %xmm1,(%esp)
-.byte 15,56,203,202
- movdqa -112(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 102,15,56,0,239
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- leal 64(%edi),%edi
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 102,15,56,0,247
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -80(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa -64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa -48(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -16(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa (%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 16(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa 32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa 48(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa 64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 80(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
-.byte 15,56,203,202
- paddd %xmm7,%xmm6
- movdqa 96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
-.byte 15,56,205,245
- movdqa 128(%ebp),%xmm7
-.byte 15,56,203,202
- movdqa 112(%ebp),%xmm0
- paddd %xmm6,%xmm0
- nop
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- cmpl %edi,%eax
- nop
-.byte 15,56,203,202
- paddd 16(%esp),%xmm2
- paddd (%esp),%xmm1
- jnz .L010loop_shaext
- pshufd $177,%xmm2,%xmm2
- pshufd $27,%xmm1,%xmm7
- pshufd $177,%xmm1,%xmm1
- punpckhqdq %xmm2,%xmm1
-.byte 102,15,58,15,215,8
- movl 44(%esp),%esp
- movdqu %xmm1,(%esi)
- movdqu %xmm2,16(%esi)
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.align 32
-.L005SSSE3:
+.L004SSSE3:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebx
@@ -3384,9 +3184,9 @@ sha256_block_data_order:
movl %ecx,24(%esp)
movl %esi,28(%esp)
movdqa 256(%ebp),%xmm7
- jmp .L011grand_ssse3
+ jmp .L009grand_ssse3
.align 16
-.L011grand_ssse3:
+.L009grand_ssse3:
movdqu (%edi),%xmm0
movdqu 16(%edi),%xmm1
movdqu 32(%edi),%xmm2
@@ -3409,9 +3209,9 @@ sha256_block_data_order:
paddd %xmm3,%xmm7
movdqa %xmm6,64(%esp)
movdqa %xmm7,80(%esp)
- jmp .L012ssse3_00_47
+ jmp .L010ssse3_00_47
.align 16
-.L012ssse3_00_47:
+.L010ssse3_00_47:
addl $64,%ebp
movl %edx,%ecx
movdqa %xmm1,%xmm4
@@ -4054,7 +3854,7 @@ sha256_block_data_order:
addl %ecx,%eax
movdqa %xmm6,80(%esp)
cmpl $66051,64(%ebp)
- jne .L012ssse3_00_47
+ jne .L010ssse3_00_47
movl %edx,%ecx
rorl $14,%edx
movl 20(%esp),%esi
@@ -4568,7 +4368,7 @@ sha256_block_data_order:
movdqa 64(%ebp),%xmm7
subl $192,%ebp
cmpl 104(%esp),%edi
- jb .L011grand_ssse3
+ jb .L009grand_ssse3
movl 108(%esp),%esp
popl %edi
popl %esi
diff --git a/mac-x86/crypto/sha/sha1-586.S b/mac-x86/crypto/sha/sha1-586.S
index 97aafbf..f880e7e 100644
--- a/mac-x86/crypto/sha/sha1-586.S
+++ b/mac-x86/crypto/sha/sha1-586.S
@@ -22,8 +22,6 @@ L000pic_point:
movl 8(%esi),%ecx
testl $16777216,%eax
jz L001x86
- testl $536870912,%ecx
- jnz Lshaext_shortcut
jmp Lssse3_shortcut
.align 4,0x90
L001x86:
@@ -1391,9 +1389,9 @@ L002loop:
popl %ebx
popl %ebp
ret
-.private_extern __sha1_block_data_order_shaext
+.private_extern __sha1_block_data_order_ssse3
.align 4
-__sha1_block_data_order_shaext:
+__sha1_block_data_order_ssse3:
pushl %ebp
pushl %ebx
pushl %esi
@@ -1402,175 +1400,6 @@ __sha1_block_data_order_shaext:
L003pic_point:
popl %ebp
leal LK_XX_XX-L003pic_point(%ebp),%ebp
-Lshaext_shortcut:
- movl 20(%esp),%edi
- movl %esp,%ebx
- movl 24(%esp),%esi
- movl 28(%esp),%ecx
- subl $32,%esp
- movdqu (%edi),%xmm0
- movd 16(%edi),%xmm1
- andl $-32,%esp
- movdqa 80(%ebp),%xmm3
- movdqu (%esi),%xmm4
- pshufd $27,%xmm0,%xmm0
- movdqu 16(%esi),%xmm5
- pshufd $27,%xmm1,%xmm1
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,227
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,235
-.byte 102,15,56,0,243
-.byte 102,15,56,0,251
- jmp L004loop_shaext
-.align 4,0x90
-L004loop_shaext:
- decl %ecx
- leal 64(%esi),%eax
- movdqa %xmm1,(%esp)
- paddd %xmm4,%xmm1
- cmovnel %eax,%esi
- movdqa %xmm0,16(%esp)
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,0
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,0
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,1
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,1
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
-.byte 15,56,201,229
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,213
- pxor %xmm6,%xmm4
-.byte 15,56,201,238
-.byte 15,56,202,231
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,2
-.byte 15,56,200,206
- pxor %xmm7,%xmm5
-.byte 15,56,202,236
-.byte 15,56,201,247
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,2
-.byte 15,56,200,215
- pxor %xmm4,%xmm6
-.byte 15,56,201,252
-.byte 15,56,202,245
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,204
- pxor %xmm5,%xmm7
-.byte 15,56,202,254
- movdqu (%esi),%xmm4
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,213
- movdqu 16(%esi),%xmm5
-.byte 102,15,56,0,227
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
-.byte 15,56,200,206
- movdqu 32(%esi),%xmm6
-.byte 102,15,56,0,235
- movdqa %xmm0,%xmm2
-.byte 15,58,204,193,3
-.byte 15,56,200,215
- movdqu 48(%esi),%xmm7
-.byte 102,15,56,0,243
- movdqa %xmm0,%xmm1
-.byte 15,58,204,194,3
- movdqa (%esp),%xmm2
-.byte 102,15,56,0,251
-.byte 15,56,200,202
- paddd 16(%esp),%xmm0
- jnz L004loop_shaext
- pshufd $27,%xmm0,%xmm0
- pshufd $27,%xmm1,%xmm1
- movdqu %xmm0,(%edi)
- movd %xmm1,16(%edi)
- movl %ebx,%esp
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.private_extern __sha1_block_data_order_ssse3
-.align 4
-__sha1_block_data_order_ssse3:
- pushl %ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- call L005pic_point
-L005pic_point:
- popl %ebp
- leal LK_XX_XX-L005pic_point(%ebp),%ebp
Lssse3_shortcut:
movdqa (%ebp),%xmm7
movdqa 16(%ebp),%xmm0
@@ -1623,9 +1452,9 @@ Lssse3_shortcut:
xorl %edx,%ebp
pshufd $238,%xmm0,%xmm4
andl %ebp,%esi
- jmp L006loop
+ jmp L004loop
.align 4,0x90
-L006loop:
+L004loop:
rorl $2,%ebx
xorl %edx,%esi
movl %eax,%ebp
@@ -2528,7 +2357,7 @@ L006loop:
addl %edx,%ecx
movl 196(%esp),%ebp
cmpl 200(%esp),%ebp
- je L007done
+ je L005done
movdqa 160(%esp),%xmm7
movdqa 176(%esp),%xmm6
movdqu (%ebp),%xmm0
@@ -2663,9 +2492,9 @@ L006loop:
pshufd $238,%xmm0,%xmm4
andl %ebx,%esi
movl %ebp,%ebx
- jmp L006loop
+ jmp L004loop
.align 4,0x90
-L007done:
+L005done:
addl 16(%esp),%ebx
xorl %edi,%esi
movl %ecx,%ebp
diff --git a/mac-x86/crypto/sha/sha256-586.S b/mac-x86/crypto/sha/sha256-586.S
index f0ba612..4615588 100644
--- a/mac-x86/crypto/sha/sha256-586.S
+++ b/mac-x86/crypto/sha/sha256-586.S
@@ -36,17 +36,15 @@ L000pic_point:
jz L003no_xmm
andl $1073741824,%ecx
andl $268435968,%ebx
- testl $536870912,%edx
- jnz L004shaext
orl %ebx,%ecx
andl $1342177280,%ecx
cmpl $1342177280,%ecx
testl $512,%ebx
- jnz L005SSSE3
+ jnz L004SSSE3
L003no_xmm:
subl %edi,%eax
cmpl $256,%eax
- jae L006unrolled
+ jae L005unrolled
jmp L002loop
.align 4,0x90
L002loop:
@@ -118,7 +116,7 @@ L002loop:
movl %ecx,28(%esp)
movl %edi,32(%esp)
.align 4,0x90
-L00700_15:
+L00600_15:
movl %edx,%ecx
movl 24(%esp),%esi
rorl $14,%ecx
@@ -156,11 +154,11 @@ L00700_15:
addl $4,%ebp
addl %ebx,%eax
cmpl $3248222580,%esi
- jne L00700_15
+ jne L00600_15
movl 156(%esp),%ecx
- jmp L00816_63
+ jmp L00716_63
.align 4,0x90
-L00816_63:
+L00716_63:
movl %ecx,%ebx
movl 104(%esp),%esi
rorl $11,%ecx
@@ -215,7 +213,7 @@ L00816_63:
addl $4,%ebp
addl %ebx,%eax
cmpl $3329325298,%esi
- jne L00816_63
+ jne L00716_63
movl 356(%esp),%esi
movl 8(%esp),%ebx
movl 16(%esp),%ecx
@@ -259,7 +257,7 @@ L001K256:
.byte 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
.byte 62,0
.align 4,0x90
-L006unrolled:
+L005unrolled:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebp
@@ -276,9 +274,9 @@ L006unrolled:
movl %ebx,20(%esp)
movl %ecx,24(%esp)
movl %esi,28(%esp)
- jmp L009grand_loop
+ jmp L008grand_loop
.align 4,0x90
-L009grand_loop:
+L008grand_loop:
movl (%edi),%ebx
movl 4(%edi),%ecx
bswap %ebx
@@ -3158,7 +3156,7 @@ L009grand_loop:
movl %ebx,24(%esp)
movl %ecx,28(%esp)
cmpl 104(%esp),%edi
- jb L009grand_loop
+ jb L008grand_loop
movl 108(%esp),%esp
popl %edi
popl %esi
@@ -3166,205 +3164,7 @@ L009grand_loop:
popl %ebp
ret
.align 5,0x90
-L004shaext:
- subl $32,%esp
- movdqu (%esi),%xmm1
- leal 128(%ebp),%ebp
- movdqu 16(%esi),%xmm2
- movdqa 128(%ebp),%xmm7
- pshufd $27,%xmm1,%xmm0
- pshufd $177,%xmm1,%xmm1
- pshufd $27,%xmm2,%xmm2
-.byte 102,15,58,15,202,8
- punpcklqdq %xmm0,%xmm2
- jmp L010loop_shaext
-.align 4,0x90
-L010loop_shaext:
- movdqu (%edi),%xmm3
- movdqu 16(%edi),%xmm4
- movdqu 32(%edi),%xmm5
-.byte 102,15,56,0,223
- movdqu 48(%edi),%xmm6
- movdqa %xmm2,16(%esp)
- movdqa -128(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 102,15,56,0,231
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- nop
- movdqa %xmm1,(%esp)
-.byte 15,56,203,202
- movdqa -112(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 102,15,56,0,239
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- leal 64(%edi),%edi
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 102,15,56,0,247
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -80(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa -64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa -48(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa -32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa -16(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa (%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 16(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
- nop
- paddd %xmm7,%xmm6
-.byte 15,56,204,220
-.byte 15,56,203,202
- movdqa 32(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,205,245
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm6,%xmm7
-.byte 102,15,58,15,253,4
- nop
- paddd %xmm7,%xmm3
-.byte 15,56,204,229
-.byte 15,56,203,202
- movdqa 48(%ebp),%xmm0
- paddd %xmm6,%xmm0
-.byte 15,56,205,222
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm3,%xmm7
-.byte 102,15,58,15,254,4
- nop
- paddd %xmm7,%xmm4
-.byte 15,56,204,238
-.byte 15,56,203,202
- movdqa 64(%ebp),%xmm0
- paddd %xmm3,%xmm0
-.byte 15,56,205,227
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm4,%xmm7
-.byte 102,15,58,15,251,4
- nop
- paddd %xmm7,%xmm5
-.byte 15,56,204,243
-.byte 15,56,203,202
- movdqa 80(%ebp),%xmm0
- paddd %xmm4,%xmm0
-.byte 15,56,205,236
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- movdqa %xmm5,%xmm7
-.byte 102,15,58,15,252,4
-.byte 15,56,203,202
- paddd %xmm7,%xmm6
- movdqa 96(%ebp),%xmm0
- paddd %xmm5,%xmm0
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
-.byte 15,56,205,245
- movdqa 128(%ebp),%xmm7
-.byte 15,56,203,202
- movdqa 112(%ebp),%xmm0
- paddd %xmm6,%xmm0
- nop
-.byte 15,56,203,209
- pshufd $14,%xmm0,%xmm0
- cmpl %edi,%eax
- nop
-.byte 15,56,203,202
- paddd 16(%esp),%xmm2
- paddd (%esp),%xmm1
- jnz L010loop_shaext
- pshufd $177,%xmm2,%xmm2
- pshufd $27,%xmm1,%xmm7
- pshufd $177,%xmm1,%xmm1
- punpckhqdq %xmm2,%xmm1
-.byte 102,15,58,15,215,8
- movl 44(%esp),%esp
- movdqu %xmm1,(%esi)
- movdqu %xmm2,16(%esi)
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-.align 5,0x90
-L005SSSE3:
+L004SSSE3:
leal -96(%esp),%esp
movl (%esi),%eax
movl 4(%esi),%ebx
@@ -3383,9 +3183,9 @@ L005SSSE3:
movl %ecx,24(%esp)
movl %esi,28(%esp)
movdqa 256(%ebp),%xmm7
- jmp L011grand_ssse3
+ jmp L009grand_ssse3
.align 4,0x90
-L011grand_ssse3:
+L009grand_ssse3:
movdqu (%edi),%xmm0
movdqu 16(%edi),%xmm1
movdqu 32(%edi),%xmm2
@@ -3408,9 +3208,9 @@ L011grand_ssse3:
paddd %xmm3,%xmm7
movdqa %xmm6,64(%esp)
movdqa %xmm7,80(%esp)
- jmp L012ssse3_00_47
+ jmp L010ssse3_00_47
.align 4,0x90
-L012ssse3_00_47:
+L010ssse3_00_47:
addl $64,%ebp
movl %edx,%ecx
movdqa %xmm1,%xmm4
@@ -4053,7 +3853,7 @@ L012ssse3_00_47:
addl %ecx,%eax
movdqa %xmm6,80(%esp)
cmpl $66051,64(%ebp)
- jne L012ssse3_00_47
+ jne L010ssse3_00_47
movl %edx,%ecx
rorl $14,%edx
movl 20(%esp),%esi
@@ -4567,7 +4367,7 @@ L012ssse3_00_47:
movdqa 64(%ebp),%xmm7
subl $192,%ebp
cmpl 104(%esp),%edi
- jb L011grand_ssse3
+ jb L009grand_ssse3
movl 108(%esp),%esp
popl %edi
popl %esi
diff --git a/sources.mk b/sources.mk
index 42d9fa6..386a21b 100644
--- a/sources.mk
+++ b/sources.mk
@@ -127,6 +127,7 @@ crypto_sources := \
src/crypto/ec/ec_key.c\
src/crypto/ec/ec_montgomery.c\
src/crypto/ec/oct.c\
+ src/crypto/ec/p224-64.c\
src/crypto/ec/p256-64.c\
src/crypto/ec/simple.c\
src/crypto/ec/util-64.c\
@@ -177,7 +178,6 @@ crypto_sources := \
src/crypto/poly1305/poly1305.c\
src/crypto/poly1305/poly1305_arm.c\
src/crypto/poly1305/poly1305_vec.c\
- src/crypto/rand/hwrand.c\
src/crypto/rand/rand.c\
src/crypto/rand/urandom.c\
src/crypto/rand/windows.c\
@@ -308,7 +308,6 @@ ssl_sources := \
src/ssl/ssl_rsa.c\
src/ssl/ssl_session.c\
src/ssl/ssl_stat.c\
- src/ssl/ssl_txt.c\
src/ssl/t1_enc.c\
src/ssl/t1_lib.c\
src/ssl/tls_record.c\
diff --git a/src/BUILDING.md b/src/BUILDING.md
index c75851f..7d4eac4 100644
--- a/src/BUILDING.md
+++ b/src/BUILDING.md
@@ -2,27 +2,40 @@
## Build Prerequisites
- * [CMake] [1] 2.8.8 or later is required.
+ * [CMake](http://www.cmake.org/download/) 2.8.8 or later is required.
- * Perl 5.6.1 or later is required. On Windows, [Strawberry Perl] [2] and MSYS
- Perl have both been reported to work. If not found by CMake, it may be
- configured explicitly by setting `PERL_EXECUTABLE`.
+ * Perl 5.6.1 or later is required. On Windows,
+ [Strawberry Perl](http://strawberryperl.com/) and MSYS Perl have both been
+ reported to work. If not found by CMake, it may be configured explicitly by
+ setting `PERL_EXECUTABLE`.
- * On Windows you currently must use [Ninja] [3] to build; on other platforms,
- it is not required, but recommended, because it makes builds faster.
+ * On Windows you currently must use [Ninja](https://martine.github.io/ninja/)
+ to build; on other platforms, it is not required, but recommended, because
+ it makes builds faster.
* If you need to build Ninja from source, then a recent version of
- [Python] [4] is required (Python 2.7.5 works).
+ [Python](https://www.python.org/downloads/) is required (Python 2.7.5 works).
- * On Windows only, [Yasm] [5] is required. If not found by CMake, it may be
- configured explicitly by setting `CMAKE_ASM_NASM_COMPILER`.
+ * On Windows only, [Yasm](http://yasm.tortall.net/) is required. If not found
+ by CMake, it may be configured explicitly by setting
+ `CMAKE_ASM_NASM_COMPILER`.
* A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
with Platform SDK 8.1 or later are supported. Recent versions of GCC and
Clang should work on non-Windows platforms, and maybe on Windows too.
- * [Go] [6] is required. If not found by CMake, the go executable may be
- configured explicitly by setting `GO_EXECUTABLE`.
+ * [Go](https://golang.org/dl/) is required. If not found by CMake, the go
+ executable may be configured explicitly by setting `GO_EXECUTABLE`.
+
+ * If you change crypto/chacha/chacha_vec.c, you will need the
+ arm-linux-gnueabihf-gcc compiler:
+
+ ```
+ $ wget https://releases.linaro.org/14.11/components/toolchain/binaries/arm-linux-gnueabihf/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz
+ $ echo bc4ca2ced084d2dc12424815a4442e19cb1422db87068830305d90075feb1a3b gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz | sha256sum -c
+ $ tar xf gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf.tar.xz
+ $ sudo mv gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf /opt/
+ ```
## Building
@@ -58,6 +71,10 @@ Windows, where functions need to be tagged with `dllimport` when coming from a
shared library, define `BORINGSSL_SHARED_LIBRARY` in any code which `#include`s
the BoringSSL headers.
+In order to serve environments where code-size is important as well as those
+where performance is the overriding concern, `OPENSSL_SMALL` can be defined to
+remove some code that is especially large.
+
### Building for Android
It's possible to build BoringSSL with the Android NDK using CMake. This has
@@ -91,10 +108,36 @@ binaries.
don't have steps for assembling the assembly language source files, so they
currently cannot be used to build BoringSSL.
+## Embedded ARM
+
+ARM, unlike Intel, does not have an instruction that allows applications to
+discover the capabilities of the processor. Instead, the capability information
+has to be provided by the operating system somehow.
+
+BoringSSL will try to use `getauxval` to discover the capabilities and, failing
+that, will probe for NEON support by executing a NEON instruction and handling
+any illegal-instruction signal. But some environments don't support that sort
+of thing and, for them, it's possible to configure the CPU capabilities
+at compile time.
+
+If you define `OPENSSL_STATIC_ARMCAP` then you can define any of the following
+to enabling the corresponding ARM feature.
+
+ * `OPENSSL_STATIC_ARMCAP_NEON` or `__ARM_NEON__` (note that the latter is set by compilers when NEON support is enabled).
+ * `OPENSSL_STATIC_ARMCAP_AES`
+ * `OPENSSL_STATIC_ARMCAP_SHA1`
+ * `OPENSSL_STATIC_ARMCAP_SHA256`
+ * `OPENSSL_STATIC_ARMCAP_PMULL`
+
+Note that if a feature is enabled in this way, but not actually supported at
+run-time, BoringSSL will likely crash.
+
+# Running tests
+
+There are two sets of tests: the C/C++ tests and the blackbox tests. For former
+are built by Ninja and can be run from the top-level directory with `go run
+util/all_tests.go`. The latter have to be run separately by running `go test`
+from within `ssl/test/runner`.
- [1]: http://www.cmake.org/download/
- [2]: http://strawberryperl.com/
- [3]: https://martine.github.io/ninja/
- [4]: https://www.python.org/downloads/
- [5]: http://yasm.tortall.net/
- [6]: https://golang.org/dl/
+Both sets of tests may also be run with `ninja -C build run_tests`, but CMake
+3.2 or later is required to avoid Ninja's output buffering.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c1a6a37..5b5c088 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,15 +17,14 @@ if (NOT GO_EXECUTABLE)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -ggdb -fvisibility=hidden")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -ggdb -std=c++0x -fvisibility=hidden")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wsign-compare -ggdb -fvisibility=hidden")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wsign-compare -ggdb -std=c++0x -fvisibility=hidden")
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4100" # 'exarg' : unreferenced formal parameter
"C4127" # conditional expression is constant
"C4200" # nonstandard extension used : zero-sized array in
# struct/union.
- "C4210" # nonstandard extension used : function given file scope
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
# possible loss of data
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
@@ -138,8 +137,27 @@ if (OPENSSL_NO_ASM)
set(ARCH "generic")
endif()
+# Declare a dummy target to build all unit tests. Test targets should inject
+# themselves as dependencies next to the target definition.
+add_custom_target(all_tests)
+
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(ssl/test)
add_subdirectory(tool)
add_subdirectory(decrepit)
+
+if (NOT ${CMAKE_VERSION} VERSION_LESS "3.2")
+ # USES_TERMINAL is only available in CMake 3.2 or later.
+ set(MAYBE_USES_TERMINAL USES_TERMINAL)
+endif()
+
+add_custom_target(
+ run_tests
+ COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir
+ ${CMAKE_BINARY_DIR}
+ COMMAND cd ssl/test/runner
+ COMMAND ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim>
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ DEPENDS all_tests bssl_shim
+ ${MAYBE_USES_TERMINAL})
diff --git a/src/PORTING.md b/src/PORTING.md
index 70b67cc..b3e50d7 100644
--- a/src/PORTING.md
+++ b/src/PORTING.md
@@ -103,11 +103,12 @@ OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
from the peer transparently. Renegotiation is an extremely problematic protocol
feature, so BoringSSL rejects peer renegotiations by default.
-To enable renegotiation, call `SSL_set_reject_peer_renegotiations` and set it to
-off. Renegotiation is only supported as a client in SSL3/TLS and the
-HelloRequest must be received at a quiet point in the application protocol. This
-is sufficient to support the common use of requesting a new client certificate
-between an HTTP request and response in (unpipelined) HTTP/1.1.
+To enable renegotiation, call `SSL_set_renegotiate_mode` and set it to
+`ssl_renegotiate_once` or `ssl_renegotiate_freely`. Renegotiation is only
+supported as a client in SSL3/TLS and the HelloRequest must be received at a
+quiet point in the application protocol. This is sufficient to support the
+common use of requesting a new client certificate between an HTTP request and
+response in (unpipelined) HTTP/1.1.
Things which do not work:
@@ -123,6 +124,12 @@ Things which do not work:
* If a HelloRequest is received while `SSL_write` has unsent application data,
the renegotiation is rejected.
+### Lowercase hexadecimal
+
+BoringSSL's `BN_bn2hex` function uses lowercase hexadecimal digits instead of
+uppercase. Some code may require changes to avoid being sensitive to this
+difference.
+
## Optional BoringSSL-specific simplifications
@@ -143,10 +150,10 @@ OpenSSL has a number of different initialization functions for setting up error
strings and loading algorithms, etc. All of these functions still exist in
BoringSSL for convenience, but they do nothing and are not necessary.
-The one exception is `CRYPTO_library_init` (and `SSL_library_init` which merely
-calls it). In `BORINGSSL_NO_STATIC_INITIALIZER` builds, it must be called to
-query CPU capabitilies before the rest of the library. In the default
-configuration, this is done with a static initializer and is also unnecessary.
+The one exception is `CRYPTO_library_init`. In `BORINGSSL_NO_STATIC_INITIALIZER`
+builds, it must be called to query CPU capabitilies before the rest of the
+library. In the default configuration, this is done with a static initializer
+and is also unnecessary.
### Threading
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 0000000..142fc0a
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,29 @@
+# BoringSSL
+
+BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.
+
+Although BoringSSL is an open source project, it is not intended for general
+use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing
+so is likely to be frustrating because there are no guarantees of API or ABI
+stability.
+
+Programs ship their own copies of BoringSSL when they use it and we update
+everything as needed when deciding to make API changes. This allows us to
+mostly avoid compromises in the name of compatibility. It works for us, but it
+may not work for you.
+
+BoringSSL arose because Google used OpenSSL for many years in various ways and,
+over time, built up a large number of patches that were maintained while
+tracking upstream OpenSSL. As Google's product portfolio became more complex,
+more copies of OpenSSL sprung up and the effort involved in maintaining all
+these patches in multiple places was growing steadily.
+
+Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's
+not part of the NDK) and a number of other apps/programs.
+
+There are other files in this directory which might be helpful:
+
+ * [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
+ * [BUILDING.md](/BUILDING.md): how to build BoringSSL
+ * [STYLE.md](/STYLE.md): rules and guidelines for coding style.
+ * include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 3115279..89f4ce5 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -210,6 +210,7 @@ add_executable(
)
target_link_libraries(constant_time_test crypto)
+add_dependencies(all_tests constant_time_test)
add_executable(
thread_test
@@ -220,6 +221,7 @@ add_executable(
)
target_link_libraries(thread_test crypto)
+add_dependencies(all_tests thread_test)
add_executable(
refcount_test
@@ -228,3 +230,4 @@ add_executable(
)
target_link_libraries(refcount_test crypto)
+add_dependencies(all_tests refcount_test)
diff --git a/src/crypto/aes/CMakeLists.txt b/src/crypto/aes/CMakeLists.txt
index c82d99a..0566e39 100644
--- a/src/crypto/aes/CMakeLists.txt
+++ b/src/crypto/aes/CMakeLists.txt
@@ -69,3 +69,4 @@ add_executable(
)
target_link_libraries(aes_test crypto)
+add_dependencies(all_tests aes_test)
diff --git a/src/crypto/aes/aes.c b/src/crypto/aes/aes.c
index 933aa07..8823919 100644
--- a/src/crypto/aes/aes.c
+++ b/src/crypto/aes/aes.c
@@ -49,6 +49,9 @@
#include <openssl/aes.h>
#include <assert.h>
+#include <stdlib.h>
+
+#include <openssl/cpu.h>
#include "internal.h"
@@ -1057,6 +1060,44 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
#else
+#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+
+static int hwaes_capable(void) {
+ return CRYPTO_is_ARMv8_AES_capable();
+}
+
+int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
+ AES_KEY *key);
+int aes_v8_set_decrypt_key(const uint8_t *user_key, const int bits,
+ AES_KEY *key);
+void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
+
+#else
+
+static int hwaes_capable(void) {
+ return 0;
+}
+
+static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
+ abort();
+}
+
+static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
+ abort();
+}
+
+static void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+ abort();
+}
+
+static void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+ abort();
+}
+
+#endif
+
+
/* In this case several functions are provided by asm code. However, one cannot
* control asm symbol visibility with command line flags and such so they are
* always hidden and wrapped by these C functions, which can be so
@@ -1064,22 +1105,38 @@ void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
- asm_AES_encrypt(in, out, key);
+ if (hwaes_capable()) {
+ aes_v8_encrypt(in, out, key);
+ } else {
+ asm_AES_encrypt(in, out, key);
+ }
}
void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
- asm_AES_decrypt(in, out, key);
+ if (hwaes_capable()) {
+ aes_v8_decrypt(in, out, key);
+ } else {
+ asm_AES_decrypt(in, out, key);
+ }
}
int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
- return asm_AES_set_encrypt_key(key, bits, aeskey);
+ if (hwaes_capable()) {
+ return aes_v8_set_encrypt_key(key, bits, aeskey);
+ } else {
+ return asm_AES_set_encrypt_key(key, bits, aeskey);
+ }
}
int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey);
int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) {
- return asm_AES_set_decrypt_key(key, bits, aeskey);
+ if (hwaes_capable()) {
+ return aes_v8_set_decrypt_key(key, bits, aeskey);
+ } else {
+ return asm_AES_set_decrypt_key(key, bits, aeskey);
+ }
}
#endif /* OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) */
diff --git a/src/crypto/aes/asm/aesni-x86.pl b/src/crypto/aes/asm/aesni-x86.pl
index f67df8c..9b2e37a 100644
--- a/src/crypto/aes/asm/aesni-x86.pl
+++ b/src/crypto/aes/asm/aesni-x86.pl
@@ -88,7 +88,7 @@ $inout3="xmm5"; $in1="xmm5";
$inout4="xmm6"; $in0="xmm6";
$inout5="xmm7"; $ivec="xmm7";
-# AESNI extenstion
+# AESNI extension
sub aeskeygenassist
{ my($dst,$src,$imm)=@_;
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index 7fe349a..2617fef 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -701,7 +701,6 @@ ___
}
$code.=<<___;
-#if defined(__arm__)
#ifndef __KERNEL__
# include <openssl/arm_arch.h>
@@ -2497,7 +2496,6 @@ ___
}
$code.=<<___;
#endif
-#endif
___
$code =~ s/\`([^\`]*)\`/eval($1)/gem;
diff --git a/src/crypto/aes/mode_wrappers.c b/src/crypto/aes/mode_wrappers.c
index c706896..dc657dc 100644
--- a/src/crypto/aes/mode_wrappers.c
+++ b/src/crypto/aes/mode_wrappers.c
@@ -48,9 +48,9 @@
#include <openssl/aes.h>
-#include "assert.h"
+#include <assert.h>
-#include <openssl/modes.h>
+#include "../modes/internal.h"
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index 507a842..d852ad7 100644
--- a/src/crypto/asn1/tasn_dec.c
+++ b/src/crypto/asn1/tasn_dec.c
@@ -359,9 +359,9 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
}
asn1_set_choice_selector(pval, i, it);
- *in = p;
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
+ *in = p;
return 1;
case ASN1_ITYPE_NDEF_SEQUENCE:
@@ -515,9 +515,9 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* Save encoding */
if (!asn1_enc_save(pval, *in, p - *in, it))
goto auxerr;
- *in = p;
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
goto auxerr;
+ *in = p;
return 1;
default:
diff --git a/src/crypto/base64/CMakeLists.txt b/src/crypto/base64/CMakeLists.txt
index f1dba6c..15ee691 100644
--- a/src/crypto/base64/CMakeLists.txt
+++ b/src/crypto/base64/CMakeLists.txt
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(base64_test crypto)
+add_dependencies(all_tests base64_test)
diff --git a/src/crypto/bio/CMakeLists.txt b/src/crypto/bio/CMakeLists.txt
index 8de090a..7859b58 100644
--- a/src/crypto/bio/CMakeLists.txt
+++ b/src/crypto/bio/CMakeLists.txt
@@ -30,3 +30,4 @@ target_link_libraries(bio_test crypto)
if (WIN32)
target_link_libraries(bio_test ws2_32)
endif()
+add_dependencies(all_tests bio_test)
diff --git a/src/crypto/bio/bio.c b/src/crypto/bio/bio.c
index 4bc98ba..7a1a9e3 100644
--- a/src/crypto/bio/bio.c
+++ b/src/crypto/bio/bio.c
@@ -529,7 +529,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
uint8_t header[6];
static const size_t kInitialHeaderLen = 2;
- if (BIO_read(bio, header, kInitialHeaderLen) != kInitialHeaderLen) {
+ if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) {
return 0;
}
@@ -559,7 +559,8 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
return 0;
}
- if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) != num_bytes) {
+ if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) !=
+ (int)num_bytes) {
return 0;
}
header_len = kInitialHeaderLen + num_bytes;
@@ -585,7 +586,8 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
}
if (len + header_len < len ||
- len + header_len > max_len) {
+ len + header_len > max_len ||
+ len > INT_MAX) {
return 0;
}
len += header_len;
@@ -597,7 +599,7 @@ int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
}
memcpy(*out, header, header_len);
if (BIO_read(bio, (*out) + header_len, len - header_len) !=
- len - header_len) {
+ (int) (len - header_len)) {
OPENSSL_free(*out);
return 0;
}
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index ef56111..6864f6f 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -176,7 +176,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
if (INT_MAX - blen < inl) {
goto err;
}
- if (BUF_MEM_grow_clean(b, blen + inl) != (blen + inl)) {
+ if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) {
goto err;
}
memcpy(&b->data[blen], in, inl);
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index 2ed2def..0b34d7f 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -93,7 +93,6 @@ typedef struct bio_connect_st {
char *param_port;
int nbio;
- uint8_t ip[4];
unsigned short port;
struct sockaddr_storage them;
@@ -114,23 +113,59 @@ static int closesocket(int sock) {
}
#endif
-/* maybe_copy_ipv4_address sets |*ipv4| to the IPv4 address from |ss| (in
- * big-endian order), if |ss| contains an IPv4 socket address. */
-static void maybe_copy_ipv4_address(uint8_t *ipv4,
- const struct sockaddr_storage *ss) {
- const struct sockaddr_in *sin;
+/* split_host_and_port sets |*out_host| and |*out_port| to the host and port
+ * parsed from |name|. It returns one on success or zero on error. Even when
+ * successful, |*out_port| may be NULL on return if no port was specified. */
+static int split_host_and_port(char **out_host, char **out_port, const char *name) {
+ const char *host, *port = NULL;
+ size_t host_len = 0;
- if (ss->ss_family != AF_INET) {
- return;
+ *out_host = NULL;
+ *out_port = NULL;
+
+ if (name[0] == '[') { /* bracketed IPv6 address */
+ const char *close = strchr(name, ']');
+ if (close == NULL) {
+ return 0;
+ }
+ host = name + 1;
+ host_len = close - host;
+ if (close[1] == ':') { /* [IP]:port */
+ port = close + 2;
+ } else if (close[1] != 0) {
+ return 0;
+ }
+ } else {
+ const char *colon = strchr(name, ':');
+ if (colon == NULL || strchr(colon + 1, ':') != NULL) { /* IPv6 address */
+ host = name;
+ host_len = strlen(name);
+ } else { /* host:port */
+ host = name;
+ host_len = colon - name;
+ port = colon + 1;
+ }
}
- sin = (const struct sockaddr_in*) ss;
- memcpy(ipv4, &sin->sin_addr, 4);
+ *out_host = BUF_strndup(host, host_len);
+ if (*out_host == NULL) {
+ return 0;
+ }
+ if (port == NULL) {
+ *out_port = NULL;
+ return 1;
+ }
+ *out_port = OPENSSL_strdup(port);
+ if (*out_port == NULL) {
+ OPENSSL_free(*out_host);
+ *out_host = NULL;
+ return 0;
+ }
+ return 1;
}
static int conn_state(BIO *bio, BIO_CONNECT *c) {
int ret = -1, i;
- char *p, *q;
int (*cb)(const BIO *, int, int) = NULL;
if (c->info_callback != NULL) {
@@ -140,36 +175,30 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
for (;;) {
switch (c->state) {
case BIO_CONN_S_BEFORE:
- p = c->param_hostname;
- if (p == NULL) {
+ /* If there's a hostname and a port, assume that both are
+ * exactly what they say. If there is only a hostname, try
+ * (just once) to split it into a hostname and port. */
+
+ if (c->param_hostname == NULL) {
OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
- for (; *p != 0; p++) {
- if (*p == ':' || *p == '/') {
- break;
- }
- }
- i = *p;
- if (i == ':' || i == '/') {
- *(p++) = 0;
- if (i == ':') {
- for (q = p; *q; q++) {
- if (*q == '/') {
- *q = 0;
- break;
- }
- }
- OPENSSL_free(c->param_port);
- c->param_port = BUF_strdup(p);
+ if (c->param_port == NULL) {
+ char *host, *port;
+ if (!split_host_and_port(&host, &port, c->param_hostname) ||
+ port == NULL) {
+ OPENSSL_free(host);
+ OPENSSL_free(port);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
+ ERR_add_error_data(2, "host=", c->param_hostname);
+ goto exit_loop;
}
- }
- if (c->param_port == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
- ERR_add_error_data(2, "host=", c->param_hostname);
- goto exit_loop;
+ OPENSSL_free(c->param_port);
+ c->param_port = port;
+ OPENSSL_free(c->param_hostname);
+ c->param_hostname = host;
}
if (!bio_ip_and_port_to_socket_and_addr(
@@ -180,9 +209,6 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
goto exit_loop;
}
- memset(c->ip, 0, 4);
- maybe_copy_ipv4_address(c->ip, &c->them);
-
if (c->nbio) {
if (!bio_socket_nbio(bio->num, 1)) {
OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
@@ -376,7 +402,6 @@ static int conn_write(BIO *bio, const char *in, int in_len) {
static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
int *ip;
- const char **pptr;
long ret = 1;
BIO_CONNECT *data;
@@ -397,25 +422,6 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
ret = 1;
}
break;
- case BIO_C_GET_CONNECT:
- /* TODO(fork): can this be removed? (Or maybe this whole file). */
- if (ptr != NULL) {
- pptr = (const char **)ptr;
- if (num == 0) {
- *pptr = data->param_hostname;
- } else if (num == 1) {
- *pptr = data->param_port;
- } else if (num == 2) {
- *pptr = (char *) &data->ip[0];
- } else if (num == 3) {
- *((int *)ptr) = data->port;
- }
- if (!bio->init) {
- *pptr = "not initialized";
- }
- ret = 1;
- }
- break;
case BIO_C_SET_CONNECT:
if (ptr != NULL) {
bio->init = 1;
@@ -445,9 +451,9 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = bio->num;
}
- ret = 1;
+ ret = bio->num;
} else {
- ret = 0;
+ ret = -1;
}
break;
case BIO_CTRL_GET_CLOSE:
diff --git a/src/crypto/bio/fd.c b/src/crypto/bio/fd.c
index 0b5baca..0b3484c 100644
--- a/src/crypto/bio/fd.c
+++ b/src/crypto/bio/fd.c
@@ -208,9 +208,9 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
if (ip != NULL) {
*ip = b->num;
}
- return 1;
+ return b->num;
} else {
- ret = 0;
+ ret = -1;
}
break;
case BIO_CTRL_GET_CLOSE:
diff --git a/src/crypto/bio/printf.c b/src/crypto/bio/printf.c
index 2f5ae4a..3709fcb 100644
--- a/src/crypto/bio/printf.c
+++ b/src/crypto/bio/printf.c
@@ -87,7 +87,11 @@ int BIO_printf(BIO *bio, const char *format, ...) {
}
#endif
- if (out_len >= sizeof(buf)) {
+ if (out_len < 0) {
+ return -1;
+ }
+
+ if ((size_t) out_len >= sizeof(buf)) {
const int requested_len = out_len;
/* The output was truncated. Note that vsnprintf's return value
* does not include a trailing NUL, but the buffer must be sized
diff --git a/src/crypto/bn/CMakeLists.txt b/src/crypto/bn/CMakeLists.txt
index 232e40a..b7130d7 100644
--- a/src/crypto/bn/CMakeLists.txt
+++ b/src/crypto/bn/CMakeLists.txt
@@ -76,3 +76,4 @@ add_executable(
)
target_link_libraries(bn_test crypto)
+add_dependencies(all_tests bn_test)
diff --git a/src/crypto/bn/asm/rsaz-avx2.pl b/src/crypto/bn/asm/rsaz-avx2.pl
index 3b6ccf8..bbceccb 100644
--- a/src/crypto/bn/asm/rsaz-avx2.pl
+++ b/src/crypto/bn/asm/rsaz-avx2.pl
@@ -79,29 +79,13 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
- $addx = ($1>=2.23);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
- $addx = ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
- $addx = ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
- my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
- $avx = ($ver>=3.0) + ($ver>=3.01);
- $addx = ($ver>=3.03);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable these after testing. $avx goes up to 2 and $addx to 1.
+$avx = 0;
+$addx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT = *OUT;
diff --git a/src/crypto/bn/asm/rsaz-x86_64.pl b/src/crypto/bn/asm/rsaz-x86_64.pl
index 3bd45db..4113d53 100644
--- a/src/crypto/bn/asm/rsaz-x86_64.pl
+++ b/src/crypto/bn/asm/rsaz-x86_64.pl
@@ -98,25 +98,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.23);
-}
-
-if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.10);
-}
-
-if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=12);
-}
-
-if (!$addx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
- my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
- $addx = ($ver>=3.03);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $addx goes up to 1.
+$addx = 0;
($out, $inp, $mod) = ("%rdi", "%rsi", "%rbp"); # common internal API
{
diff --git a/src/crypto/bn/asm/x86_64-mont.pl b/src/crypto/bn/asm/x86_64-mont.pl
index 39476ab..04c4bea 100644
--- a/src/crypto/bn/asm/x86_64-mont.pl
+++ b/src/crypto/bn/asm/x86_64-mont.pl
@@ -53,20 +53,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.23);
-}
-
-if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.10);
-}
-
-if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=12);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this option after testing. $addx goes up to 1.
+$addx = 0;
# int bn_mul_mont(
$rp="%rdi"; # BN_ULONG *rp,
diff --git a/src/crypto/bn/asm/x86_64-mont5.pl b/src/crypto/bn/asm/x86_64-mont5.pl
index 80e9126..38def07 100644
--- a/src/crypto/bn/asm/x86_64-mont5.pl
+++ b/src/crypto/bn/asm/x86_64-mont5.pl
@@ -38,20 +38,12 @@ die "can't locate x86_64-xlate.pl";
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.23);
-}
-
-if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $addx = ($1>=2.10);
-}
-
-if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=12);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $addx goes up to 1.
+$addx = 0;
# int bn_mul_mont_gather5(
$rp="%rdi"; # BN_ULONG *rp,
diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c
index 6c5e11b..9cefa62 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -123,6 +123,17 @@
#define RSAZ_ENABLED
#include "rsaz_exp.h"
+
+void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
+ const BN_ULONG *np, const BN_ULONG *n0, int num,
+ int power);
+void bn_scatter5(const BN_ULONG *inp, size_t num, void *table, size_t power);
+void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
+void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
+ const BN_ULONG *np, const BN_ULONG *n0, int num, int power);
+int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
+ const BN_ULONG *not_used, const BN_ULONG *np,
+ const BN_ULONG *n0, int num);
#endif
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
@@ -274,10 +285,10 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
goto err;
}
- if (BN_ucmp(m, &(recp->N)) < 0) {
+ if (BN_ucmp(m, &recp->N) < 0) {
BN_zero(d);
if (!BN_copy(r, m)) {
- return 0;
+ goto err;
}
BN_CTX_end(ctx);
return 1;
@@ -994,19 +1005,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
* 512-bit RSA is hardly relevant, we omit it to spare size... */
if (window == 5 && top > 1) {
- void bn_mul_mont_gather5(BN_ULONG * rp, const BN_ULONG * ap,
- const void * table, const BN_ULONG * np,
- const BN_ULONG * n0, int num, int power);
- void bn_scatter5(const BN_ULONG * inp, size_t num, void * table,
- size_t power);
- void bn_gather5(BN_ULONG * out, size_t num, void * table, size_t power);
- void bn_power5(BN_ULONG * rp, const BN_ULONG * ap, const void * table,
- const BN_ULONG * np, const BN_ULONG * n0, int num,
- int power);
- int bn_from_montgomery(BN_ULONG * rp, const BN_ULONG * ap,
- const BN_ULONG * not_used, const BN_ULONG * np,
- const BN_ULONG * n0, int num);
-
BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
/* BN_to_montgomery can contaminate words above .top
diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c
index 0e7d867..c240a54 100644
--- a/src/crypto/bn/generic.c
+++ b/src/crypto/bn/generic.c
@@ -1068,7 +1068,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
tp[num + 1] = 0;
goto enter;
- for (i = 0; i < num; i++) {
+ for (; i < num; i++) {
c0 = 0;
ml = bp[i];
#ifdef mul64
diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c
index c6c9c88..3fec7e3 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -130,16 +130,12 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
return NULL;
}
- BN_MONT_CTX_init(ret);
- ret->flags = BN_FLG_MALLOCED;
- return ret;
-}
+ memset(ret, 0, sizeof(BN_MONT_CTX));
+ BN_init(&ret->RR);
+ BN_init(&ret->N);
+ BN_init(&ret->Ni);
-void BN_MONT_CTX_init(BN_MONT_CTX *mont) {
- memset(mont, 0, sizeof(BN_MONT_CTX));
- BN_init(&mont->RR);
- BN_init(&mont->N);
- BN_init(&mont->Ni);
+ return ret;
}
void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
@@ -150,9 +146,7 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
BN_free(&mont->RR);
BN_free(&mont->N);
BN_free(&mont->Ni);
- if (mont->flags & BN_FLG_MALLOCED) {
- OPENSSL_free(mont);
- }
+ OPENSSL_free(mont);
}
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) {
diff --git a/src/crypto/bn/prime.c b/src/crypto/bn/prime.c
index bbb8fe0..d07e609 100644
--- a/src/crypto/bn/prime.c
+++ b/src/crypto/bn/prime.c
@@ -710,7 +710,7 @@ loop:
if (!BN_add_word(rnd, delta)) {
return 0;
}
- if (BN_num_bits(rnd) != bits) {
+ if (BN_num_bits(rnd) != (unsigned)bits) {
goto again;
}
diff --git a/src/crypto/buf/buf.c b/src/crypto/buf/buf.c
index 13b5ceb..b918f01 100644
--- a/src/crypto/buf/buf.c
+++ b/src/crypto/buf/buf.c
@@ -220,7 +220,7 @@ size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) {
void *BUF_memdup(const void *data, size_t dst_size) {
void *ret;
- if (data == NULL) {
+ if (dst_size == 0) {
return NULL;
}
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index 3462aee..33d3c21 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -19,3 +19,4 @@ add_executable(
)
target_link_libraries(bytestring_test crypto)
+add_dependencies(all_tests bytestring_test)
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index e987e1b..eae88d9 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -365,6 +365,55 @@ static bool TestCBBPrefixed() {
return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
}
+static bool TestCBBDiscardChild() {
+ ScopedCBB cbb;
+ CBB contents, inner_contents, inner_inner_contents;
+
+ if (!CBB_init(cbb.get(), 0) ||
+ !CBB_add_u8(cbb.get(), 0xaa)) {
+ return false;
+ }
+
+ // Discarding |cbb|'s children preserves the byte written.
+ CBB_discard_child(cbb.get());
+
+ if (!CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u8(&contents, 0xbb) ||
+ !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u16(&contents, 0xcccc) ||
+ !CBB_add_u24_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u24(&contents, 0xdddddd) ||
+ !CBB_add_u8_length_prefixed(cbb.get(), &contents) ||
+ !CBB_add_u8(&contents, 0xff) ||
+ !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
+ !CBB_add_u8(&inner_contents, 0x42) ||
+ !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) ||
+ !CBB_add_u8(&inner_inner_contents, 0x99)) {
+ return false;
+ }
+
+ // Discard everything from |inner_contents| down.
+ CBB_discard_child(&contents);
+
+ uint8_t *buf;
+ size_t buf_len;
+ if (!CBB_finish(cbb.get(), &buf, &buf_len)) {
+ return false;
+ }
+ ScopedOpenSSLBytes scoper(buf);
+
+ static const uint8_t kExpected[] = {
+ 0xaa,
+ 0,
+ 1, 0xbb,
+ 0, 2, 0xcc, 0xcc,
+ 0, 0, 3, 0xdd, 0xdd, 0xdd,
+ 1, 0xff,
+ };
+ return buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0;
+}
+
static bool TestCBBMisuse() {
CBB cbb, child, contents;
uint8_t *buf;
@@ -670,6 +719,7 @@ int main(void) {
!TestCBBFinishChild() ||
!TestCBBMisuse() ||
!TestCBBPrefixed() ||
+ !TestCBBDiscardChild() ||
!TestCBBASN1() ||
!TestBerConvert() ||
!TestASN1Uint64() ||
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index 1da6a21..434ec13 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -70,6 +70,10 @@ int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
void CBB_cleanup(CBB *cbb) {
if (cbb->base) {
+ /* Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They
+ * are implicitly discarded when the parent is flushed or cleaned up. */
+ assert(cbb->is_top_level);
+
if (cbb->base->can_resize) {
OPENSSL_free(cbb->base->buf);
}
@@ -356,6 +360,20 @@ int CBB_add_u24(CBB *cbb, uint32_t value) {
return cbb_buffer_add_u(cbb->base, value, 3);
}
+void CBB_discard_child(CBB *cbb) {
+ if (cbb->child == NULL) {
+ return;
+ }
+
+ cbb->base->len = cbb->offset;
+
+ cbb->child->base = NULL;
+ cbb->child = NULL;
+ cbb->pending_len_len = 0;
+ cbb->pending_is_asn1 = 0;
+ cbb->offset = 0;
+}
+
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
CBB child;
size_t i;
diff --git a/src/crypto/chacha/chacha_generic.c b/src/crypto/chacha/chacha_generic.c
index 31cf4f0..f262033 100644
--- a/src/crypto/chacha/chacha_generic.c
+++ b/src/crypto/chacha/chacha_generic.c
@@ -54,8 +54,8 @@ static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
/* Defined in chacha_vec.c */
void CRYPTO_chacha_20_neon(uint8_t *out, const uint8_t *in, size_t in_len,
- const uint8_t key[32], const uint8_t nonce[8],
- size_t counter);
+ const uint8_t key[32], const uint8_t nonce[12],
+ uint32_t counter);
#endif
/* chacha_core performs 20 rounds of ChaCha on the input words in
@@ -85,8 +85,8 @@ static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
}
void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
- const uint8_t key[32], const uint8_t nonce[8],
- size_t counter) {
+ const uint8_t key[32], const uint8_t nonce[12],
+ uint32_t counter) {
uint32_t input[16];
uint8_t buf[64];
size_t todo, i;
@@ -114,9 +114,9 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
input[11] = U8TO32_LITTLE(key + 28);
input[12] = counter;
- input[13] = ((uint64_t)counter) >> 32;
- input[14] = U8TO32_LITTLE(nonce + 0);
- input[15] = U8TO32_LITTLE(nonce + 4);
+ input[13] = U8TO32_LITTLE(nonce + 0);
+ input[14] = U8TO32_LITTLE(nonce + 4);
+ input[15] = U8TO32_LITTLE(nonce + 8);
while (in_len > 0) {
todo = sizeof(buf);
@@ -134,9 +134,6 @@ void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
in_len -= todo;
input[12]++;
- if (input[12] == 0) {
- input[13]++;
- }
}
}
diff --git a/src/crypto/chacha/chacha_vec.c b/src/crypto/chacha/chacha_vec.c
index 14b54a7..addbaa3 100644
--- a/src/crypto/chacha/chacha_vec.c
+++ b/src/crypto/chacha/chacha_vec.c
@@ -154,12 +154,12 @@ void CRYPTO_chacha_20(
const uint8_t *in,
size_t inlen,
const uint8_t key[32],
- const uint8_t nonce[8],
- size_t counter)
+ const uint8_t nonce[12],
+ uint32_t counter)
{
unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
#if defined(__ARM_NEON__)
- uint32_t np[2];
+ uint32_t np[3];
uint8_t alignment_buffer[16] __attribute__((aligned(16)));
#endif
vec s0, s1, s2, s3;
@@ -167,20 +167,16 @@ void CRYPTO_chacha_20(
{0x61707865,0x3320646E,0x79622D32,0x6B206574};
kp = (unsigned *)key;
#if defined(__ARM_NEON__)
- memcpy(np, nonce, 8);
+ memcpy(np, nonce, 12);
#endif
s0 = LOAD_ALIGNED(chacha_const);
s1 = LOAD(&((vec*)kp)[0]);
s2 = LOAD(&((vec*)kp)[1]);
s3 = (vec){
- counter & 0xffffffff,
-#if __ARM_NEON__ || defined(OPENSSL_X86)
- 0, /* can't right-shift 32 bits on a 32-bit system. */
-#else
- counter >> 32,
-#endif
+ counter,
((uint32_t*)nonce)[0],
- ((uint32_t*)nonce)[1]
+ ((uint32_t*)nonce)[1],
+ ((uint32_t*)nonce)[2]
};
for (iters = 0; iters < inlen/(BPI*64); iters++)
@@ -212,8 +208,8 @@ void CRYPTO_chacha_20(
x2 = chacha_const[2]; x3 = chacha_const[3];
x4 = kp[0]; x5 = kp[1]; x6 = kp[2]; x7 = kp[3];
x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
- x12 = counter+BPI*iters+(BPI-1); x13 = 0;
- x14 = np[0]; x15 = np[1];
+ x12 = counter+BPI*iters+(BPI-1); x13 = np[0];
+ x14 = np[1]; x15 = np[2];
#endif
for (i = CHACHA_RNDS/2; i; i--)
{
@@ -265,9 +261,9 @@ void CRYPTO_chacha_20(
op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter+BPI*iters+(BPI-1)));
- op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13));
- op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[0]));
- op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[1]));
+ op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0]));
+ op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1]));
+ op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2]));
s3 += ONE;
ip += 16;
op += 16;
diff --git a/src/crypto/chacha/chacha_vec_arm.S b/src/crypto/chacha/chacha_vec_arm.S
index 0f82627..f18c867 100644
--- a/src/crypto/chacha/chacha_vec_arm.S
+++ b/src/crypto/chacha/chacha_vec_arm.S
@@ -23,7 +23,7 @@
# /opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -O3 -mcpu=cortex-a8 -mfpu=neon -fpic -DASM_GEN -I ../../include -S chacha_vec.c -o -
#if !defined(OPENSSL_NO_ASM)
-#if defined(__arm__) || defined(__aarch64__)
+#if defined(__arm__)
.syntax unified
.cpu cortex-a8
@@ -60,137 +60,138 @@
.thumb_func
.type CRYPTO_chacha_20_neon, %function
CRYPTO_chacha_20_neon:
- @ args = 8, pretend = 0, frame = 152
+ @ args = 8, pretend = 0, frame = 160
@ frame_needed = 1, uses_anonymous_args = 0
push {r4, r5, r6, r7, r8, r9, r10, fp, lr}
- mov r8, r3
+ mov r9, r3
vpush.64 {d8, d9, d10, d11, d12, d13, d14, d15}
- mov r9, r2
+ mov r10, r2
ldr r4, .L91+16
- mov fp, r0
- mov r10, r1
- mov lr, r8
+ mov fp, r1
+ mov r8, r9
.LPIC16:
add r4, pc
- sub sp, sp, #156
+ sub sp, sp, #164
add r7, sp, #0
sub sp, sp, #112
- add r6, r7, #144
- str r0, [r7, #88]
+ add lr, r7, #148
+ str r0, [r7, #80]
str r1, [r7, #12]
str r2, [r7, #8]
ldmia r4, {r0, r1, r2, r3}
add r4, sp, #15
bic r4, r4, #15
- ldr ip, [r7, #256]
- str r4, [r7, #84]
+ ldr r6, [r7, #264]
+ str r4, [r7, #88]
mov r5, r4
adds r4, r4, #64
- adds r5, r5, #80
- str r8, [r7, #68]
+ add ip, r5, #80
+ str r9, [r7, #56]
stmia r4, {r0, r1, r2, r3}
movw r4, #43691
- ldr r0, [ip] @ unaligned
+ ldr r0, [r6] @ unaligned
movt r4, 43690
- ldr r1, [ip, #4] @ unaligned
- ldr r3, [r7, #84]
- ldr r2, [r8, #8] @ unaligned
- mov r8, #0
- stmia r6!, {r0, r1}
- mov r6, r5
- ldr r1, [lr, #4] @ unaligned
- ldr r0, [lr] @ unaligned
- vldr d24, [r3, #64]
- vldr d25, [r3, #72]
- ldr r3, [lr, #12] @ unaligned
- str r5, [r7, #80]
- stmia r5!, {r0, r1, r2, r3}
- ldr r0, [lr, #16]! @ unaligned
- ldr r2, [r7, #84]
- umull r4, r5, r9, r4
+ ldr r1, [r6, #4] @ unaligned
+ ldr r2, [r6, #8] @ unaligned
+ ldr r3, [r9, #12] @ unaligned
+ str ip, [r7, #84]
+ stmia lr!, {r0, r1, r2}
+ mov lr, ip
+ ldr r1, [r9, #4] @ unaligned
+ ldr r2, [r9, #8] @ unaligned
+ ldr r0, [r9] @ unaligned
+ vldr d24, [r5, #64]
+ vldr d25, [r5, #72]
+ umull r4, r5, r10, r4
+ stmia ip!, {r0, r1, r2, r3}
+ ldr r0, [r8, #16]! @ unaligned
+ ldr r2, [r7, #88]
+ ldr r4, [r7, #268]
+ ldr r1, [r8, #4] @ unaligned
vldr d26, [r2, #80]
vldr d27, [r2, #88]
- ldr r1, [lr, #4] @ unaligned
- ldr r2, [lr, #8] @ unaligned
- ldr r3, [lr, #12] @ unaligned
- ldr r4, [r7, #260]
- stmia r6!, {r0, r1, r2, r3}
- ldr r3, [ip]
- ldr r1, [r7, #84]
- ldr r2, [ip, #4]
- str r3, [r7, #64]
- vldr d28, [r1, #80]
- vldr d29, [r1, #88]
- str r3, [r7, #136]
+ ldr r3, [r8, #12] @ unaligned
+ ldr r2, [r8, #8] @ unaligned
+ stmia lr!, {r0, r1, r2, r3}
+ ldr r3, [r6]
+ ldr r1, [r6, #4]
+ ldr r6, [r6, #8]
+ str r3, [r7, #68]
+ str r3, [r7, #132]
lsrs r3, r5, #7
+ str r6, [r7, #140]
+ str r6, [r7, #60]
+ ldr r6, [r7, #88]
str r4, [r7, #128]
- str r2, [r7, #140]
- str r8, [r7, #132]
- str r2, [r7, #60]
+ str r1, [r7, #136]
+ str r1, [r7, #64]
+ vldr d28, [r6, #80]
+ vldr d29, [r6, #88]
vldr d22, [r7, #128]
vldr d23, [r7, #136]
beq .L26
+ mov r5, r6
lsls r2, r3, #8
- ldr r5, [r1, #64]
sub r3, r2, r3, lsl #6
- ldr r2, [r1, #68]
+ ldr r2, [r5, #68]
+ ldr r6, [r6, #64]
vldr d0, .L91
vldr d1, .L91+8
- adds r4, r4, #2
- str r5, [r7, #56]
- str r2, [r7, #52]
- ldr r5, [r1, #72]
- ldr r2, [r1, #76]
+ str r2, [r7, #48]
+ ldr r2, [r5, #72]
str r3, [r7, #4]
- str r5, [r7, #48]
+ str r6, [r7, #52]
str r2, [r7, #44]
- mov r2, fp
- str r4, [r7, #72]
+ adds r2, r4, #2
+ str r2, [r7, #72]
+ ldr r2, [r5, #76]
+ str fp, [r7, #76]
+ str r2, [r7, #40]
+ ldr r2, [r7, #80]
adds r3, r2, r3
- str r10, [r7, #76]
str r3, [r7, #16]
.L4:
- ldr r5, [r7, #68]
- add r8, r7, #44
- ldr r4, [r7, #72]
+ ldr r5, [r7, #56]
+ add r8, r7, #40
+ ldr r4, [r7, #68]
vadd.i32 q3, q11, q0
ldmia r8, {r8, r9, r10, fp}
- vmov q8, q14 @ v4si
+ mov r1, r5
ldr r2, [r5, #4]
- vmov q1, q13 @ v4si
+ vmov q8, q14 @ v4si
ldr r3, [r5]
+ vmov q1, q13 @ v4si
+ ldr r6, [r1, #28]
vmov q9, q12 @ v4si
- ldr lr, [r5, #20]
- vmov q2, q11 @ v4si
mov r0, r2
ldr r2, [r5, #8]
- str r3, [r7, #108]
- mov r3, r5
- ldr ip, [r5, #16]
+ str r4, [r7, #112]
+ movs r1, #10
+ ldr r4, [r7, #72]
+ vmov q2, q11 @ v4si
+ ldr lr, [r5, #20]
vmov q15, q14 @ v4si
- mov r1, r2
- ldr r2, [r5, #12]
- ldr r5, [r5, #24]
+ str r3, [r7, #108]
vmov q5, q13 @ v4si
- ldr r6, [r3, #28]
+ str r2, [r7, #116]
vmov q10, q12 @ v4si
+ ldr r2, [r5, #12]
+ ldr ip, [r5, #16]
ldr r3, [r7, #64]
- str r5, [r7, #116]
- movs r5, #10
+ ldr r5, [r5, #24]
str r6, [r7, #120]
- str r4, [r7, #112]
+ str r1, [r7, #92]
ldr r6, [r7, #60]
+ str r4, [r7, #100]
+ ldr r1, [r7, #116]
+ ldr r4, [r7, #108]
str r8, [r7, #96]
mov r8, r10
- ldr r4, [r7, #108]
- mov r10, r9
- ldr r9, [r7, #116]
str lr, [r7, #104]
+ mov r10, r9
mov lr, r3
- str r5, [r7, #92]
- movs r5, #0
+ mov r9, r5
str r6, [r7, #124]
- str r5, [r7, #100]
b .L92
.L93:
.align 3
@@ -213,25 +214,24 @@ CRYPTO_chacha_20_neon:
str r5, [r7, #116]
add r10, r10, r1
vrev32.16 q3, q3
- eor lr, lr, r10
+ str r6, [r7, #108]
vadd.i32 q8, q8, q3
vrev32.16 q2, q2
vadd.i32 q15, q15, q2
mov fp, r3
- ldr r3, [r7, #112]
+ ldr r3, [r7, #100]
veor q4, q8, q1
- str r6, [r7, #112]
veor q6, q15, q5
+ add fp, fp, r2
eors r3, r3, r5
mov r5, r6
- ldr r6, [r7, #100]
+ ldr r6, [r7, #112]
vshl.i32 q1, q4, #12
vshl.i32 q5, q6, #12
- add fp, fp, r2
- eors r6, r6, r5
ror r3, r3, #16
+ eors r6, r6, r5
+ eor lr, lr, r10
vsri.32 q1, q4, #20
- ror lr, lr, #16
mov r5, r6
ldr r6, [r7, #124]
vsri.32 q5, q6, #20
@@ -239,25 +239,26 @@ CRYPTO_chacha_20_neon:
eor r6, r6, fp
ror r5, r5, #16
vadd.i32 q9, q9, q1
- add r9, r9, lr
+ ror lr, lr, #16
ror r3, r6, #16
ldr r6, [r7, #124]
vadd.i32 q10, q10, q5
- str r3, [r7, #108]
+ add r9, r9, lr
veor q4, q9, q3
add ip, ip, r6
ldr r6, [r7, #104]
veor q6, q10, q2
eor r4, ip, r4
- eor r1, r9, r1
+ str r3, [r7, #104]
vshl.i32 q3, q4, #8
+ eor r1, r9, r1
mov r8, r6
ldr r6, [r7, #120]
vshl.i32 q2, q6, #8
ror r4, r4, #20
add r6, r6, r3
vsri.32 q3, q4, #24
- str r6, [r7, #104]
+ str r6, [r7, #100]
eors r2, r2, r6
ldr r6, [r7, #116]
vsri.32 q2, q6, #24
@@ -268,7 +269,7 @@ CRYPTO_chacha_20_neon:
eor r0, r8, r0
vadd.i32 q15, q15, q2
mov r3, r6
- ldr r6, [r7, #112]
+ ldr r6, [r7, #108]
veor q6, q4, q1
ror r0, r0, #20
str r3, [r7, #112]
@@ -285,7 +286,7 @@ CRYPTO_chacha_20_neon:
ror r1, r1, #20
eors r5, r5, r6
vsri.32 q8, q6, #25
- ldr r6, [r7, #108]
+ ldr r6, [r7, #104]
ror r3, r3, #24
ror r5, r5, #24
vsri.32 q1, q5, #25
@@ -297,7 +298,7 @@ CRYPTO_chacha_20_neon:
vext.32 q8, q8, q8, #1
str ip, [r7, #124]
add ip, r5, r8
- ldr r5, [r7, #104]
+ ldr r5, [r7, #100]
eor lr, r10, lr
ror r6, r6, #24
vext.32 q1, q1, q1, #1
@@ -410,7 +411,7 @@ CRYPTO_chacha_20_neon:
veor q6, q15, q1
ldr r3, [r7, #116]
vshl.i32 q1, q4, #7
- str r2, [r7, #112]
+ str r2, [r7, #100]
add r3, r3, r2
str r3, [r7, #120]
vshl.i32 q5, q6, #7
@@ -423,7 +424,7 @@ CRYPTO_chacha_20_neon:
vsri.32 q5, q6, #25
ldr r3, [r7, #92]
ror r4, r4, #25
- str r6, [r7, #100]
+ str r6, [r7, #112]
ror r0, r0, #25
subs r3, r3, #1
str r5, [r7, #104]
@@ -437,308 +438,325 @@ CRYPTO_chacha_20_neon:
vext.32 q5, q5, q5, #3
vext.32 q1, q1, q1, #3
bne .L3
- ldr r3, [r7, #80]
+ ldr r3, [r7, #84]
vadd.i32 q4, q12, q10
- str r9, [r7, #116]
+ str r9, [r7, #92]
mov r9, r10
mov r10, r8
ldr r8, [r7, #96]
str lr, [r7, #96]
mov lr, r5
- ldr r5, [r7, #56]
+ ldr r5, [r7, #52]
vadd.i32 q5, q13, q5
ldr r6, [r7, #76]
vadd.i32 q15, q14, q15
add fp, fp, r5
- ldr r5, [r7, #52]
- str r4, [r7, #108]
+ ldr r5, [r7, #48]
+ str r3, [r7, #104]
vadd.i32 q7, q14, q8
- ldr r4, [r7, #112]
- add r5, r10, r5
- str r3, [r7, #112]
- vadd.i32 q2, q11, q2
ldr r3, [r6, #12] @ unaligned
+ add r10, r10, r5
+ str r0, [r7, #36]
+ vadd.i32 q2, q11, q2
+ ldr r0, [r6] @ unaligned
vadd.i32 q6, q12, q9
- str r0, [r7, #92]
+ ldr r5, [r7, #104]
vadd.i32 q1, q13, q1
- ldr r0, [r6] @ unaligned
+ str r1, [r7, #116]
vadd.i32 q11, q11, q0
- str r1, [r7, #40]
- str r2, [r7, #36]
- vadd.i32 q3, q11, q3
ldr r1, [r6, #4] @ unaligned
- vadd.i32 q11, q11, q0
+ str r2, [r7, #32]
+ vadd.i32 q3, q11, q3
ldr r2, [r6, #8] @ unaligned
- str r5, [r7, #104]
vadd.i32 q11, q11, q0
- ldr r5, [r7, #112]
- ldr r10, [r7, #80]
+ str r4, [r7, #108]
+ ldr r4, [r7, #100]
+ vadd.i32 q11, q11, q0
stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r0, [r7, #84]
- ldr r2, [r7, #48]
- ldr r3, [r7, #72]
- vldr d20, [r0, #80]
- vldr d21, [r0, #88]
- add r9, r9, r2
+ ldr r2, [r7, #88]
+ ldr r3, [r7, #44]
+ ldr r5, [r7, #84]
+ vldr d20, [r2, #80]
+ vldr d21, [r2, #88]
+ add r3, r9, r3
+ str r3, [r7, #104]
veor q10, q10, q4
- ldr r2, [r7, #44]
+ ldr r3, [r7, #40]
+ add r3, r8, r3
+ str r3, [r7, #100]
+ ldr r3, [r7, #72]
+ vstr d20, [r2, #80]
+ vstr d21, [r2, #88]
adds r1, r4, r3
str r1, [r7, #28]
- add r2, r8, r2
- str r2, [r7, #32]
- vstr d20, [r0, #80]
- vstr d21, [r0, #88]
ldmia r5!, {r0, r1, r2, r3}
+ ldr r4, [r7, #68]
+ ldr r5, [r7, #112]
+ ldr r8, [r7, #84]
+ add r5, r5, r4
ldr r4, [r7, #96]
+ str r5, [r7, #24]
ldr r5, [r7, #64]
add r4, r4, r5
- ldr r5, [r7, #124]
+ ldr r5, [r7, #60]
str r4, [r7, #96]
- ldr r4, [r7, #60]
- add r5, r5, r4
- ldr r4, [r7, #88]
- str r5, [r7, #24]
- mov r5, r10
+ ldr r4, [r7, #124]
+ add r4, r4, r5
+ str r4, [r7, #20]
+ ldr r4, [r7, #80]
+ mov r5, r8
str r0, [r4] @ unaligned
mov r0, r4
str r1, [r4, #4] @ unaligned
- mov r8, r0
+ mov r4, r8
str r2, [r0, #8] @ unaligned
- mov r4, r10
+ mov r8, r0
str r3, [r0, #12] @ unaligned
+ mov r9, r4
ldr r0, [r6, #16]! @ unaligned
+ ldr r3, [r6, #12] @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
- ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r3, [r7, #84]
+ mov r5, r8
+ ldr r3, [r7, #88]
vldr d20, [r3, #80]
vldr d21, [r3, #88]
veor q10, q10, q5
vstr d20, [r3, #80]
vstr d21, [r3, #88]
ldmia r4!, {r0, r1, r2, r3}
- mov r4, r8
+ mov r4, r9
str r0, [r8, #16] @ unaligned
str r1, [r8, #20] @ unaligned
str r2, [r8, #24] @ unaligned
str r3, [r8, #28] @ unaligned
- mov r8, r4
+ mov r8, r5
ldr r0, [r6, #32]! @ unaligned
- str r10, [r7, #124]
+ mov r5, r9
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r2, [r7, #84]
- vldr d16, [r2, #80]
- vldr d17, [r2, #88]
+ mov r5, r8
+ ldr r1, [r7, #88]
+ vldr d16, [r1, #80]
+ vldr d17, [r1, #88]
veor q15, q8, q15
- vstr d30, [r2, #80]
- vstr d31, [r2, #88]
- ldmia r10!, {r0, r1, r2, r3}
- str r0, [r4, #32] @ unaligned
- str r1, [r4, #36] @ unaligned
- str r2, [r4, #40] @ unaligned
- str r3, [r4, #44] @ unaligned
+ vstr d30, [r1, #80]
+ vstr d31, [r1, #88]
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ str r0, [r8, #32] @ unaligned
+ str r1, [r8, #36] @ unaligned
+ str r2, [r8, #40] @ unaligned
+ str r3, [r8, #44] @ unaligned
+ mov r8, r5
ldr r0, [r6, #48]! @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- ldr r1, [r7, #84]
+ stmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ ldr r1, [r7, #88]
+ str r9, [r7, #112]
vldr d18, [r1, #80]
vldr d19, [r1, #88]
veor q9, q9, q2
vstr d18, [r1, #80]
vstr d19, [r1, #88]
- ldr r3, [r7, #112]
- ldr r5, [r7, #80]
- mov r10, r3
- ldmia r10!, {r0, r1, r2, r3}
- str r0, [r4, #48] @ unaligned
- str r1, [r4, #52] @ unaligned
- str r2, [r4, #56] @ unaligned
- str r3, [r4, #60] @ unaligned
+ ldmia r9!, {r0, r1, r2, r3}
+ str r0, [r5, #48] @ unaligned
+ str r1, [r5, #52] @ unaligned
+ str r2, [r5, #56] @ unaligned
+ str r3, [r5, #60] @ unaligned
ldr r0, [r6, #64]! @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- ldr r1, [r7, #84]
- ldr r3, [r7, #112]
- ldr r5, [r7, #80]
+ mov r9, r6
+ mov r6, r4
+ stmia r6!, {r0, r1, r2, r3}
+ mov r6, r4
+ ldr r1, [r7, #88]
vldr d18, [r1, #80]
vldr d19, [r1, #88]
veor q9, q9, q6
- mov r10, r3
- str r5, [r7, #20]
vstr d18, [r1, #80]
vstr d19, [r1, #88]
- ldmia r10!, {r0, r1, r2, r3}
- str r1, [r4, #68] @ unaligned
- str r2, [r4, #72] @ unaligned
- str r3, [r4, #76] @ unaligned
- str r0, [r4, #64] @ unaligned
- ldr r0, [r6, #80]! @ unaligned
- ldr r1, [r6, #4] @ unaligned
- ldr r2, [r6, #8] @ unaligned
- ldr r3, [r6, #12] @ unaligned
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r6
+ str r3, [r5, #76] @ unaligned
+ mov r3, r9
+ str r2, [r5, #72] @ unaligned
+ str r0, [r5, #64] @ unaligned
+ str r1, [r5, #68] @ unaligned
+ mov r5, r4
+ ldr r0, [r3, #80]! @ unaligned
+ mov r9, r3
+ ldr r1, [r9, #4] @ unaligned
+ ldr r2, [r9, #8] @ unaligned
+ ldr r3, [r9, #12] @ unaligned
+ mov r9, r4
ldr r6, [r7, #76]
+ str r9, [r7, #124]
stmia r5!, {r0, r1, r2, r3}
- ldr r1, [r7, #84]
- ldr r3, [r7, #20]
- ldr r5, [r7, #80]
+ mov r5, r8
+ ldr r1, [r7, #88]
vldr d18, [r1, #80]
vldr d19, [r1, #88]
veor q1, q9, q1
- mov r10, r3
vstr d2, [r1, #80]
vstr d3, [r1, #88]
- ldmia r10!, {r0, r1, r2, r3}
- mov r10, r5
- str r0, [r4, #80] @ unaligned
- str r1, [r4, #84] @ unaligned
- str r2, [r4, #88] @ unaligned
- str r3, [r4, #92] @ unaligned
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ str r0, [r8, #80] @ unaligned
+ str r1, [r8, #84] @ unaligned
+ str r2, [r8, #88] @ unaligned
+ str r3, [r8, #92] @ unaligned
ldr r0, [r6, #96]! @ unaligned
+ ldr r3, [r6, #12] @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
- ldr r3, [r6, #12] @ unaligned
ldr r6, [r7, #76]
- stmia r5!, {r0, r1, r2, r3}
- mov r5, r10
- ldr r3, [r7, #84]
+ stmia r4!, {r0, r1, r2, r3}
+ mov r4, r9
+ ldr r3, [r7, #88]
vldr d16, [r3, #80]
vldr d17, [r3, #88]
veor q8, q8, q7
vstr d16, [r3, #80]
vstr d17, [r3, #88]
- ldmia r10!, {r0, r1, r2, r3}
- str r0, [r4, #96] @ unaligned
- str r1, [r4, #100] @ unaligned
- str r2, [r4, #104] @ unaligned
- str r3, [r4, #108] @ unaligned
+ ldmia r9!, {r0, r1, r2, r3}
+ str r0, [r5, #96] @ unaligned
+ str r1, [r5, #100] @ unaligned
+ str r2, [r5, #104] @ unaligned
+ str r3, [r5, #108] @ unaligned
ldr r0, [r6, #112]! @ unaligned
ldr r1, [r6, #4] @ unaligned
ldr r2, [r6, #8] @ unaligned
ldr r3, [r6, #12] @ unaligned
- mov r6, r5
+ mov r6, r4
stmia r6!, {r0, r1, r2, r3}
- ldr r3, [r7, #84]
+ mov r6, r5
+ ldr r3, [r7, #88]
vldr d16, [r3, #80]
vldr d17, [r3, #88]
veor q8, q8, q3
vstr d16, [r3, #80]
vstr d17, [r3, #88]
- ldmia r5!, {r0, r1, r2, r3}
- str r1, [r4, #116] @ unaligned
- ldr r1, [r7, #76]
- str r0, [r4, #112] @ unaligned
- str r2, [r4, #120] @ unaligned
- str r3, [r4, #124] @ unaligned
- ldr r3, [r1, #128]
- ldr r2, [r7, #104]
+ ldmia r4!, {r0, r1, r2, r3}
+ mov r4, r5
+ mov r8, r4
+ str r2, [r5, #120] @ unaligned
+ ldr r2, [r7, #76]
+ str r0, [r5, #112] @ unaligned
+ str r1, [r5, #116] @ unaligned
+ str r3, [r5, #124] @ unaligned
+ ldr r3, [r2, #128]
+ ldr r1, [r7, #104]
eor r3, fp, r3
- str r3, [r4, #128]
- ldr r3, [r1, #132]
- eors r2, r2, r3
- str r2, [r8, #132]
- ldr r3, [r1, #136]
- ldr r5, [r7, #68]
- ldr r6, [r7, #32]
- eor r3, r9, r3
- str r3, [r4, #136]
- ldr r3, [r1, #140]
- ldr r0, [r7, #92]
- eors r3, r3, r6
- ldr r6, [r7, #108]
+ str r3, [r5, #128]
+ ldr r3, [r2, #132]
+ mov r5, r2
+ eor r3, r10, r3
+ str r3, [r6, #132]
+ ldr r3, [r2, #136]
+ mov r6, r5
+ eors r1, r1, r3
+ str r1, [r8, #136]
+ ldr r1, [r7, #56]
+ ldr r3, [r2, #140]
+ ldr r2, [r7, #100]
+ ldr r0, [r7, #108]
+ eors r3, r3, r2
str r3, [r4, #140]
- ldr r3, [r5]
- ldr r2, [r1, #144]
- add r6, r6, r3
- eors r2, r2, r6
+ ldr r3, [r1]
+ ldr r2, [r5, #144]
+ mov r8, r0
+ add r8, r8, r3
+ mov r5, r6
+ mov r3, r8
+ eors r2, r2, r3
str r2, [r4, #144]
- ldr r2, [r5, #4]
- ldr r3, [r1, #148]
- add r0, r0, r2
+ ldr r3, [r6, #148]
+ ldr r2, [r1, #4]
ldr r6, [r7, #36]
- eors r3, r3, r0
- ldr r0, [r7, #40]
- str r3, [r4, #148]
- ldr r2, [r5, #8]
- ldr r3, [r1, #152]
- add r0, r0, r2
- eors r3, r3, r0
- str r3, [r4, #152]
- ldr r2, [r5, #12]
- mov r0, r4
- ldr r3, [r1, #156]
- mov r4, r1
add r6, r6, r2
- mov r1, r0
eors r3, r3, r6
- str r3, [r0, #156]
- ldr r2, [r5, #16]
- ldr r3, [r4, #160]
+ mov r6, r1
+ str r3, [r4, #148]
+ ldr r2, [r1, #8]
+ ldr r1, [r7, #116]
+ ldr r3, [r5, #152]
+ mov r8, r1
+ add r8, r8, r2
+ ldr r1, [r7, #32]
+ mov r2, r8
+ eors r3, r3, r2
+ str r3, [r4, #152]
+ mov r8, r4
+ ldr r2, [r6, #12]
+ ldr r3, [r5, #156]
+ add r1, r1, r2
+ eors r3, r3, r1
+ str r3, [r4, #156]
+ ldr r2, [r6, #16]
+ mov r1, r4
+ ldr r3, [r5, #160]
+ mov r4, r5
add ip, ip, r2
+ mov r5, r6
eor r3, ip, r3
str r3, [r1, #160]
- ldr r2, [r5, #20]
+ ldr r2, [r6, #20]
ldr r3, [r4, #164]
add lr, lr, r2
- ldr r2, [r7, #116]
+ ldr r2, [r7, #92]
eor r3, lr, r3
str r3, [r1, #164]
ldr r6, [r5, #24]
mov lr, r4
ldr r3, [r4, #168]
add r2, r2, r6
- mov r6, r4
+ ldr r6, [r7, #120]
eors r3, r3, r2
str r3, [r1, #168]
ldr r5, [r5, #28]
- mov r2, r1
ldr r3, [r4, #172]
- ldr r0, [r7, #120]
- add r0, r0, r5
- ldr r5, [r7, #24]
- eors r3, r3, r0
+ add r6, r6, r5
+ eors r3, r3, r6
str r3, [r1, #172]
- ldr r3, [r7, #72]
ldr r4, [r4, #176]
- ldr r1, [r7, #28]
- eors r4, r4, r1
- adds r1, r3, #3
- str r4, [r2, #176]
- ldr r3, [r7, #100]
+ ldr r0, [r7, #28]
+ ldr r5, [r7, #24]
+ eors r4, r4, r0
+ str r4, [r8, #176]
ldr r0, [lr, #180]
- str r1, [r7, #72]
- eors r3, r3, r0
- mov r0, r3
- mov r3, r2
- str r0, [r2, #180]
- adds r3, r3, #192
- ldr r1, [lr, #184]
ldr r2, [r7, #96]
+ eors r0, r0, r5
+ str r0, [r8, #180]
+ ldr r1, [lr, #184]
+ ldr r4, [r7, #20]
eors r1, r1, r2
- str r1, [r3, #-8]
+ str r1, [r8, #184]
ldr r2, [lr, #188]
- mov r1, r6
- adds r1, r1, #192
- str r1, [r7, #76]
- eors r2, r2, r5
- str r2, [r3, #-4]
+ add r1, lr, #192
+ ldr r3, [r7, #72]
+ eors r2, r2, r4
+ str r2, [r8, #188]
ldr r2, [r7, #16]
- str r3, [r7, #88]
+ adds r3, r3, #3
+ str r3, [r7, #72]
+ mov r3, r8
+ adds r3, r3, #192
+ str r1, [r7, #76]
cmp r2, r3
+ str r3, [r7, #80]
bne .L4
ldr r3, [r7, #12]
ldr r2, [r7, #4]
@@ -757,8 +775,8 @@ CRYPTO_chacha_20_neon:
beq .L6
ldr r5, [r7, #12]
ldr r4, [r7, #16]
- ldr r6, [r7, #84]
- ldr lr, [r7, #80]
+ ldr r6, [r7, #88]
+ ldr lr, [r7, #84]
vldr d30, .L94
vldr d31, .L94+8
str fp, [r7, #120]
@@ -964,7 +982,7 @@ CRYPTO_chacha_20_neon:
mov r9, r5
bhi .L88
vadd.i32 q12, q12, q10
- ldr r3, [r7, #84]
+ ldr r3, [r7, #88]
vst1.64 {d24-d25}, [r3:128]
.L14:
ldr r3, [r7, #8]
@@ -1001,7 +1019,7 @@ CRYPTO_chacha_20_neon:
movcs r1, ip
cmp r1, #0
beq .L17
- ldr r5, [r7, #84]
+ ldr r5, [r7, #88]
cmp r1, #1
ldrb r0, [r0] @ zero_extendqisi2
add r3, r2, #1
@@ -1136,7 +1154,7 @@ CRYPTO_chacha_20_neon:
ldr r5, [r7, #16]
cmp r6, #1
add r0, r1, r2
- ldr r1, [r7, #84]
+ ldr r1, [r7, #88]
add r1, r1, r2
vld1.64 {d18-d19}, [r0:64]
add r2, r2, r5
@@ -1174,7 +1192,7 @@ CRYPTO_chacha_20_neon:
add r3, r3, lr
beq .L1
.L19:
- ldr r4, [r7, #84]
+ ldr r4, [r7, #88]
adds r2, r3, #1
ldr r1, [r7, #12]
cmp r2, r9
@@ -1289,7 +1307,7 @@ CRYPTO_chacha_20_neon:
eor r1, r1, r0
strb r1, [r5, r2]
bls .L1
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
ldrb r1, [r2, r3] @ zero_extendqisi2
ldr r2, [r7, #12]
ldrb r2, [r2, r3] @ zero_extendqisi2
@@ -1297,7 +1315,7 @@ CRYPTO_chacha_20_neon:
ldr r1, [r7, #16]
strb r2, [r1, r3]
.L1:
- adds r7, r7, #156
+ adds r7, r7, #164
mov sp, r7
@ sp needed
vldm sp!, {d8-d15}
@@ -1305,7 +1323,7 @@ CRYPTO_chacha_20_neon:
.L88:
ldr r5, [r7, #12]
vadd.i32 q12, q12, q10
- ldr r4, [r7, #80]
+ ldr r4, [r7, #84]
cmp r9, #31
ldr r0, [r5] @ unaligned
ldr r1, [r5, #4] @ unaligned
@@ -1313,7 +1331,7 @@ CRYPTO_chacha_20_neon:
ldr r2, [r5, #8] @ unaligned
ldr r3, [r5, #12] @ unaligned
stmia r6!, {r0, r1, r2, r3}
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
ldr r6, [r7, #16]
vldr d18, [r2, #80]
vldr d19, [r2, #88]
@@ -1328,7 +1346,7 @@ CRYPTO_chacha_20_neon:
str r3, [r6, #12] @ unaligned
bhi .L89
vadd.i32 q13, q13, q15
- ldr r3, [r7, #84]
+ ldr r3, [r7, #88]
vstr d26, [r3, #16]
vstr d27, [r3, #24]
b .L14
@@ -1337,7 +1355,7 @@ CRYPTO_chacha_20_neon:
ldr r2, [r7, #12]
add r2, r2, r9
mov r5, r2
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
add r2, r2, r3
mov r3, r2
.L24:
@@ -1347,17 +1365,18 @@ CRYPTO_chacha_20_neon:
eor r2, r2, r1
strb r2, [r4], #1
bne .L24
- adds r7, r7, #156
+ adds r7, r7, #164
mov sp, r7
@ sp needed
vldm sp!, {d8-d15}
pop {r4, r5, r6, r7, r8, r9, r10, fp, pc}
.L26:
- str fp, [r7, #16]
+ ldr r3, [r7, #80]
+ str r3, [r7, #16]
b .L2
.L89:
mov r3, r5
- ldr r4, [r7, #80]
+ ldr r4, [r7, #84]
ldr r0, [r3, #16]! @ unaligned
add lr, r1, #16
mov r5, r1
@@ -1368,7 +1387,7 @@ CRYPTO_chacha_20_neon:
ldr r2, [r3, #8] @ unaligned
ldr r3, [r3, #12] @ unaligned
stmia r6!, {r0, r1, r2, r3}
- ldr r2, [r7, #84]
+ ldr r2, [r7, #88]
vldr d18, [r2, #80]
vldr d19, [r2, #88]
veor q13, q9, q13
@@ -1381,16 +1400,16 @@ CRYPTO_chacha_20_neon:
str r3, [lr, #12] @ unaligned
bhi .L90
vadd.i32 q8, q14, q8
- ldr r3, [r7, #84]
+ ldr r3, [r7, #88]
vstr d16, [r3, #32]
vstr d17, [r3, #40]
b .L14
.L90:
ldr r3, [r7, #12]
add lr, r5, #32
- ldr r4, [r7, #80]
+ ldr r4, [r7, #84]
vadd.i32 q8, q14, q8
- ldr r5, [r7, #84]
+ ldr r5, [r7, #88]
vadd.i32 q11, q11, q3
ldr r0, [r3, #32]! @ unaligned
mov r6, r4
@@ -1424,5 +1443,5 @@ CRYPTO_chacha_20_neon:
.ident "GCC: (Linaro GCC 2014.11) 4.9.3 20141031 (prerelease)"
.section .note.GNU-stack,"",%progbits
-#endif /* __arm__ || __aarch64__ */
+#endif /* __arm__ */
#endif /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/chacha/chacha_vec_arm_generate.go b/src/crypto/chacha/chacha_vec_arm_generate.go
index 6d167b9..82aa847 100644
--- a/src/crypto/chacha/chacha_vec_arm_generate.go
+++ b/src/crypto/chacha/chacha_vec_arm_generate.go
@@ -12,7 +12,10 @@
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-// This package generates chacha_vec_arm.S from chacha_vec.c.
+// This package generates chacha_vec_arm.S from chacha_vec.c. Install the
+// arm-linux-gnueabihf-gcc compiler as described in BUILDING.md. Then:
+// `(cd crypto/chacha && go run chacha_vec_arm_generate.go)`.
+
package main
import (
@@ -53,7 +56,7 @@ func main() {
output.WriteString(" ")
output.WriteString(strings.Join(args, " "))
output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n")
- output.WriteString("#if defined(__arm__) || defined(__aarch64__)\n\n")
+ output.WriteString("#if defined(__arm__)\n\n")
cmd := exec.Command(compiler, args...)
cmd.Stderr = os.Stderr
@@ -145,6 +148,6 @@ const attr28Block = `
`
const trailer = `
-#endif /* __arm__ || __aarch64__ */
+#endif /* __arm__ */
#endif /* !OPENSSL_NO_ASM */
`
diff --git a/src/crypto/cipher/CMakeLists.txt b/src/crypto/cipher/CMakeLists.txt
index 6b4c729..52b87b6 100644
--- a/src/crypto/cipher/CMakeLists.txt
+++ b/src/crypto/cipher/CMakeLists.txt
@@ -37,3 +37,4 @@ add_executable(
target_link_libraries(cipher_test crypto)
target_link_libraries(aead_test crypto)
+add_dependencies(all_tests cipher_test aead_test)
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index baaee9e..a4ddd3b 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -213,7 +213,8 @@ struct AEADName {
static const struct AEADName kAEADs[] = {
{ "aes-128-gcm", EVP_aead_aes_128_gcm },
{ "aes-256-gcm", EVP_aead_aes_256_gcm },
- { "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
+ { "chacha20-poly1305", EVP_aead_chacha20_poly1305_rfc7539 },
+ { "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old },
{ "rc4-md5-tls", EVP_aead_rc4_md5_tls },
{ "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
{ "aes-128-cbc-sha1-tls", EVP_aead_aes_128_cbc_sha1_tls },
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index e8905f6..442d1ed 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -54,7 +54,6 @@
#include <openssl/cpu.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/modes.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
@@ -120,8 +119,8 @@ static char bsaes_capable(void) {
#endif
#define HWAES
-static char hwaes_capable(void) {
- return (OPENSSL_armcap_P & ARMV8_AES) != 0;
+static int hwaes_capable(void) {
+ return CRYPTO_is_ARMv8_AES_capable();
}
int aes_v8_set_encrypt_key(const uint8_t *user_key, const int bits,
@@ -151,13 +150,14 @@ static char bsaes_capable(void) {
/* On other platforms, bsaes_capable() will always return false and so the
* following will never be called. */
-void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
- const AES_KEY *key, uint8_t ivec[16], int enc) {
+static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+ const AES_KEY *key, uint8_t ivec[16], int enc) {
abort();
}
-void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
- const AES_KEY *key, const uint8_t ivec[16]) {
+static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+ size_t len, const AES_KEY *key,
+ const uint8_t ivec[16]) {
abort();
}
#endif
@@ -180,20 +180,22 @@ static char vpaes_capable(void) {
/* On other platforms, vpaes_capable() will always return false and so the
* following will never be called. */
-int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key) {
+static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
+ AES_KEY *key) {
abort();
}
-int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key) {
+static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
+ AES_KEY *key) {
abort();
}
-void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
-void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
-void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
- const AES_KEY *key, uint8_t *ivec, int enc) {
+static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+ const AES_KEY *key, uint8_t *ivec, int enc) {
abort();
}
#endif
@@ -201,34 +203,38 @@ void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
#if !defined(HWAES)
/* If HWAES isn't defined then we provide dummy functions for each of the hwaes
* functions. */
-int hwaes_capable(void) {
+static int hwaes_capable(void) {
return 0;
}
-int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits,
- AES_KEY *key) {
+static int aes_v8_set_encrypt_key(const uint8_t *user_key, int bits,
+ AES_KEY *key) {
abort();
}
-int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key) {
+static int aes_v8_set_decrypt_key(const uint8_t *user_key, int bits,
+ AES_KEY *key) {
abort();
}
-void aes_v8_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void aes_v8_encrypt(const uint8_t *in, uint8_t *out,
+ const AES_KEY *key) {
abort();
}
-void aes_v8_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void aes_v8_decrypt(const uint8_t *in, uint8_t *out,
+ const AES_KEY *key) {
abort();
}
-void aes_v8_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
- const AES_KEY *key, uint8_t *ivec, int enc) {
+static void aes_v8_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
+ const AES_KEY *key, uint8_t *ivec, int enc) {
abort();
}
-void aes_v8_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
- const AES_KEY *key, const uint8_t ivec[16]) {
+static void aes_v8_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+ size_t len, const AES_KEY *key,
+ const uint8_t ivec[16]) {
abort();
}
#endif
@@ -266,14 +272,16 @@ void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in,
/* On other platforms, aesni_capable() will always return false and so the
* following will never be called. */
-void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
+static void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
abort();
}
-int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key) {
+static int aesni_set_encrypt_key(const uint8_t *userKey, int bits,
+ AES_KEY *key) {
abort();
}
-void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks,
- const void *key, const uint8_t *ivec) {
+static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
+ size_t blocks, const void *key,
+ const uint8_t *ivec) {
abort();
}
@@ -472,14 +480,14 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
iv = gctx->iv;
}
if (iv) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
gctx->iv_set = 1;
}
gctx->key_set = 1;
} else {
/* If key set use IV, otherwise copy */
if (gctx->key_set) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
} else {
memcpy(gctx->iv, iv, gctx->ivlen);
}
@@ -583,7 +591,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
if (gctx->iv_gen == 0 || gctx->key_set == 0) {
return 0;
}
- CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
if (arg <= 0 || arg > gctx->ivlen) {
arg = gctx->ivlen;
}
@@ -600,19 +608,13 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
return 0;
}
memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
- CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
gctx->iv_set = 1;
return 1;
case EVP_CTRL_COPY: {
EVP_CIPHER_CTX *out = ptr;
EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
- if (gctx->gcm.key) {
- if (gctx->gcm.key != &gctx->ks) {
- return 0;
- }
- gctx_out->gcm.key = &gctx_out->ks;
- }
if (gctx->iv == c->iv) {
gctx_out->iv = out->iv;
} else {
@@ -654,24 +656,24 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
if (len >= 32 && AES_GCM_ASM(gctx)) {
size_t res = (16 - gctx->gcm.mres) % 16;
- if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) {
+ if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, res)) {
return -1;
}
- bulk = AES_gcm_encrypt(in + res, out + res, len - res, gctx->gcm.key,
+ bulk = AES_gcm_encrypt(in + res, out + res, len - res, &gctx->ks.ks,
gctx->gcm.Yi.c, gctx->gcm.Xi.u);
gctx->gcm.len.u[1] += bulk;
bulk += res;
}
#endif
- if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in + bulk, out + bulk,
- len - bulk, gctx->ctr)) {
+ if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk, gctx->ctr)) {
return -1;
}
} else {
size_t bulk = 0;
- if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in + bulk, out + bulk,
- len - bulk)) {
+ if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk)) {
return -1;
}
}
@@ -682,24 +684,24 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
if (len >= 16 && AES_GCM_ASM(gctx)) {
size_t res = (16 - gctx->gcm.mres) % 16;
- if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) {
+ if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, res)) {
return -1;
}
- bulk = AES_gcm_decrypt(in + res, out + res, len - res, gctx->gcm.key,
+ bulk = AES_gcm_decrypt(in + res, out + res, len - res, &gctx->ks.ks,
gctx->gcm.Yi.c, gctx->gcm.Xi.u);
gctx->gcm.len.u[1] += bulk;
bulk += res;
}
#endif
- if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in + bulk, out + bulk,
- len - bulk, gctx->ctr)) {
+ if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk, gctx->ctr)) {
return -1;
}
} else {
size_t bulk = 0;
- if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in + bulk, out + bulk,
- len - bulk)) {
+ if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in + bulk,
+ out + bulk, len - bulk)) {
return -1;
}
}
@@ -893,14 +895,14 @@ static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
iv = gctx->iv;
}
if (iv) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
gctx->iv_set = 1;
}
gctx->key_set = 1;
} else {
/* If key set use IV, otherwise copy */
if (gctx->key_set) {
- CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+ CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
} else {
memcpy(gctx->iv, iv, gctx->ivlen);
}
@@ -1100,7 +1102,6 @@ static int aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
- size_t bulk = 0;
const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
GCM128_CONTEXT gcm;
@@ -1114,20 +1115,22 @@ static int aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
+ const AES_KEY *key = &gcm_ctx->ks.ks;
+
memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
- CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
return 0;
}
if (gcm_ctx->ctr) {
- if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, in_len - bulk,
+ if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len,
gcm_ctx->ctr)) {
return 0;
}
} else {
- if (!CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk, in_len - bulk)) {
+ if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) {
return 0;
}
}
@@ -1142,7 +1145,6 @@ static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
- size_t bulk = 0;
const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN];
size_t plaintext_len;
@@ -1160,22 +1162,22 @@ static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
+ const AES_KEY *key = &gcm_ctx->ks.ks;
+
memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
- CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
return 0;
}
if (gcm_ctx->ctr) {
- if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
- in_len - bulk - gcm_ctx->tag_len,
- gcm_ctx->ctr)) {
+ if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out,
+ in_len - gcm_ctx->tag_len, gcm_ctx->ctr)) {
return 0;
}
} else {
- if (!CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
- in_len - bulk - gcm_ctx->tag_len)) {
+ if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len - gcm_ctx->tag_len)) {
return 0;
}
}
@@ -1752,7 +1754,7 @@ int EVP_has_aes_hardware(void) {
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
return aesni_capable() && crypto_gcm_clmul_enabled();
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
- return hwaes_capable() && (OPENSSL_armcap_P & ARMV8_PMULL);
+ return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable();
#else
return 0;
#endif
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index 9dda1b0..3bf7834 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -26,7 +26,6 @@
#define POLY1305_TAG_LEN 16
-#define CHACHA20_NONCE_LEN 8
struct aead_chacha20_poly1305_ctx {
unsigned char key[32];
@@ -68,18 +67,15 @@ static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) {
OPENSSL_free(c20_ctx);
}
-static void poly1305_update_with_length(poly1305_state *poly1305,
- const uint8_t *data, size_t data_len) {
- size_t j = data_len;
+static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
uint8_t length_bytes[8];
unsigned i;
for (i = 0; i < sizeof(length_bytes); i++) {
- length_bytes[i] = j;
- j >>= 8;
+ length_bytes[i] = data_len;
+ data_len >>= 8;
}
- CRYPTO_poly1305_update(poly1305, data, data_len);
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
@@ -89,18 +85,37 @@ static void poly1305_update_with_length(poly1305_state *poly1305,
#define ALIGNED
#endif
-static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
- size_t *out_len, size_t max_out_len,
- const uint8_t *nonce, size_t nonce_len,
- const uint8_t *in, size_t in_len,
- const uint8_t *ad, size_t ad_len) {
- const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+typedef void (*aead_poly1305_update)(poly1305_state *ctx, const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len);
+
+/* aead_poly1305 fills |tag| with the authentication tag for the given
+ * inputs, using |update| to control the order and format that the inputs are
+ * signed/authenticated. */
+static void aead_poly1305(aead_poly1305_update update,
+ uint8_t tag[POLY1305_TAG_LEN],
+ const struct aead_chacha20_poly1305_ctx *c20_ctx,
+ const uint8_t nonce[12], const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len) {
uint8_t poly1305_key[32] ALIGNED;
- poly1305_state poly1305;
+ memset(poly1305_key, 0, sizeof(poly1305_key));
+ CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
+ c20_ctx->key, nonce, 0);
+ poly1305_state ctx;
+ CRYPTO_poly1305_init(&ctx, poly1305_key);
+ update(&ctx, ad, ad_len, ciphertext, ciphertext_len);
+ CRYPTO_poly1305_finish(&ctx, tag);
+}
+
+static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
+ uint8_t *out, size_t *out_len, size_t max_out_len,
+ const uint8_t nonce[12], const uint8_t *in, size_t in_len,
+ const uint8_t *ad, size_t ad_len) {
+ const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
const uint64_t in_len_64 = in_len;
- /* The underlying ChaCha implementation may not overflow the block
- * counter into the second counter word. Therefore we disallow
+ /* |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow
* individual operations that work on more than 256GB at a time.
* |in_len_64| is needed because, on 32-bit platforms, size_t is only
* 32-bits and this produces a warning because it's always false.
@@ -121,37 +136,22 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
- if (nonce_len != CHACHA20_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
- return 0;
- }
-
- memset(poly1305_key, 0, sizeof(poly1305_key));
- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
- c20_ctx->key, nonce, 0);
-
- CRYPTO_poly1305_init(&poly1305, poly1305_key);
- poly1305_update_with_length(&poly1305, ad, ad_len);
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
- poly1305_update_with_length(&poly1305, out, in_len);
uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
- CRYPTO_poly1305_finish(&poly1305, tag);
+ aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, out, in_len);
+
memcpy(out + in_len, tag, c20_ctx->tag_len);
*out_len = in_len + c20_ctx->tag_len;
return 1;
}
-static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
- size_t *out_len, size_t max_out_len,
- const uint8_t *nonce, size_t nonce_len,
- const uint8_t *in, size_t in_len,
- const uint8_t *ad, size_t ad_len) {
+static int open(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
+ uint8_t *out, size_t *out_len, size_t max_out_len,
+ const uint8_t nonce[12], const uint8_t *in, size_t in_len,
+ const uint8_t *ad, size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
- uint8_t mac[POLY1305_TAG_LEN];
- uint8_t poly1305_key[32] ALIGNED;
size_t plaintext_len;
- poly1305_state poly1305;
const uint64_t in_len_64 = in_len;
if (in_len < c20_ctx->tag_len) {
@@ -159,8 +159,7 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
- /* The underlying ChaCha implementation may not overflow the block
- * counter into the second counter word. Therefore we disallow
+ /* |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow
* individual operations that work on more than 256GB at a time.
* |in_len_64| is needed because, on 32-bit platforms, size_t is only
* 32-bits and this produces a warning because it's always false.
@@ -171,40 +170,68 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
- if (nonce_len != CHACHA20_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
+ plaintext_len = in_len - c20_ctx->tag_len;
+ uint8_t tag[POLY1305_TAG_LEN] ALIGNED;
+ aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, in,
+ plaintext_len);
+ if (CRYPTO_memcmp(tag, in + plaintext_len, c20_ctx->tag_len) != 0) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
- plaintext_len = in_len - c20_ctx->tag_len;
+ CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
+ *out_len = plaintext_len;
+ return 1;
+}
- if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
- return 0;
- }
+static void poly1305_update_padded_16(poly1305_state *poly1305,
+ const uint8_t *data, size_t data_len) {
+ static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
- memset(poly1305_key, 0, sizeof(poly1305_key));
- CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
- c20_ctx->key, nonce, 0);
+ CRYPTO_poly1305_update(poly1305, data, data_len);
+ if (data_len % 16 != 0) {
+ CRYPTO_poly1305_update(poly1305, padding, sizeof(padding) - (data_len % 16));
+ }
+}
- CRYPTO_poly1305_init(&poly1305, poly1305_key);
- poly1305_update_with_length(&poly1305, ad, ad_len);
- poly1305_update_with_length(&poly1305, in, plaintext_len);
- CRYPTO_poly1305_finish(&poly1305, mac);
+static void poly1305_update(poly1305_state *ctx, const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len) {
+ poly1305_update_padded_16(ctx, ad, ad_len);
+ poly1305_update_padded_16(ctx, ciphertext, ciphertext_len);
+ poly1305_update_length(ctx, ad_len);
+ poly1305_update_length(ctx, ciphertext_len);
+}
- if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
+static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
+ size_t *out_len, size_t max_out_len,
+ const uint8_t *nonce, size_t nonce_len,
+ const uint8_t *in, size_t in_len,
+ const uint8_t *ad, size_t ad_len) {
+ if (nonce_len != 12) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
+ return seal(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
+ in_len, ad, ad_len);
+}
- CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
- *out_len = plaintext_len;
- return 1;
+static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
+ size_t *out_len, size_t max_out_len,
+ const uint8_t *nonce, size_t nonce_len,
+ const uint8_t *in, size_t in_len,
+ const uint8_t *ad, size_t ad_len) {
+ if (nonce_len != 12) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ return 0;
+ }
+ return open(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
+ in_len, ad, ad_len);
}
static const EVP_AEAD aead_chacha20_poly1305 = {
32, /* key len */
- CHACHA20_NONCE_LEN, /* nonce len */
+ 12, /* nonce len */
POLY1305_TAG_LEN, /* overhead */
POLY1305_TAG_LEN, /* max tag length */
aead_chacha20_poly1305_init,
@@ -215,6 +242,66 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
NULL, /* get_rc4_state */
};
-const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
+const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
return &aead_chacha20_poly1305;
}
+
+static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
+ size_t ad_len, const uint8_t *ciphertext,
+ size_t ciphertext_len) {
+ CRYPTO_poly1305_update(ctx, ad, ad_len);
+ poly1305_update_length(ctx, ad_len);
+ CRYPTO_poly1305_update(ctx, ciphertext, ciphertext_len);
+ poly1305_update_length(ctx, ciphertext_len);
+}
+
+static int aead_chacha20_poly1305_old_seal(
+ const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len,
+ const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len,
+ const uint8_t *ad, size_t ad_len) {
+ if (nonce_len != 8) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ return 0;
+ }
+ uint8_t nonce_96[12];
+ memset(nonce_96, 0, 4);
+ memcpy(nonce_96 + 4, nonce, 8);
+ return seal(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
+ in_len, ad, ad_len);
+}
+
+static int aead_chacha20_poly1305_old_open(
+ const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len,
+ const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len,
+ const uint8_t *ad, size_t ad_len) {
+ if (nonce_len != 8) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ return 0;
+ }
+ uint8_t nonce_96[12];
+ memset(nonce_96, 0, 4);
+ memcpy(nonce_96 + 4, nonce, 8);
+ return open(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
+ in_len, ad, ad_len);
+}
+
+static const EVP_AEAD aead_chacha20_poly1305_old = {
+ 32, /* key len */
+ 8, /* nonce len */
+ POLY1305_TAG_LEN, /* overhead */
+ POLY1305_TAG_LEN, /* max tag length */
+ aead_chacha20_poly1305_init,
+ NULL, /* init_with_direction */
+ aead_chacha20_poly1305_cleanup,
+ aead_chacha20_poly1305_old_seal,
+ aead_chacha20_poly1305_old_open,
+ NULL, /* get_rc4_state */
+};
+
+const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
+ return &aead_chacha20_poly1305_old;
+}
+
+const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
+ return &aead_chacha20_poly1305_old;
+}
diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c
index 2778881..c3ddbde 100644
--- a/src/crypto/cipher/e_tls.c
+++ b/src/crypto/cipher/e_tls.c
@@ -494,7 +494,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
SHA256_DIGEST_LENGTH + 16, /* key len (SHA256 + AES128) */
16, /* nonce len (IV) */
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
- SHA_DIGEST_LENGTH, /* max tag length */
+ SHA256_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_aes_128_cbc_sha256_tls_init,
aead_tls_cleanup,
@@ -533,7 +533,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
SHA256_DIGEST_LENGTH + 32, /* key len (SHA256 + AES256) */
16, /* nonce len (IV) */
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
- SHA_DIGEST_LENGTH, /* max tag length */
+ SHA256_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_aes_256_cbc_sha256_tls_init,
aead_tls_cleanup,
@@ -546,7 +546,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
SHA384_DIGEST_LENGTH + 32, /* key len (SHA384 + AES256) */
16, /* nonce len (IV) */
16 + SHA384_DIGEST_LENGTH, /* overhead (padding + SHA384) */
- SHA_DIGEST_LENGTH, /* max tag length */
+ SHA384_DIGEST_LENGTH, /* max tag length */
NULL, /* init */
aead_aes_256_cbc_sha384_tls_init,
aead_tls_cleanup,
diff --git a/src/crypto/cipher/test/aes_128_gcm_tests.txt b/src/crypto/cipher/test/aes_128_gcm_tests.txt
index 75466fe..0e33c91 100644
--- a/src/crypto/cipher/test/aes_128_gcm_tests.txt
+++ b/src/crypto/cipher/test/aes_128_gcm_tests.txt
@@ -1,3 +1,6 @@
+# The AES-128-GCM test cases from cipher_test.txt have been merged into this
+# file.
+
KEY: d480429666d48b400633921c5407d1d1
NONCE: 3388c676dc754acfa66e172a
IN:
@@ -424,3 +427,105 @@ IN: 48656c6c6f2c20576f726c64
AD:
CT: cec189d0e8419b90fb16d555
TAG: 32893832a8d609224d77c2e56a922282
+
+# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
+
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: ""
+CT: ""
+AD: ""
+TAG: 58e2fccefa7e3061367f1d57a4e7455a
+
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 00000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78
+AD: ""
+TAG: ab6e47d42cec13bdf53a67b21257bddf
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+CT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985
+AD: ""
+TAG: 4d5c2af327cd64a62cf35abd2ba6fab4
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 5bc94fbc3221a5db94fae95ae7121a47
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbad
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 3612d2e79e3b0785561be14aaca2fccb
+
+KEY: feffe9928665731c6d6a8f9467308308
+NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 619cc5aefffe0bfa462af43c1699d050
+
+# local add-ons, primarily streaming ghash tests
+
+# 128 bytes AD
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: ""
+CT: ""
+AD: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+TAG: 5fea793a2d6f974d37e68e0cb8ff9492
+
+# 48 bytes plaintext
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0
+AD: ""
+TAG: 9dd0a376b08e40eb00c35f29f9ea61a4
+
+# 80 bytes plaintext
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291
+AD: ""
+TAG: 98885a3a22bd4742fe7b72172193b163
+
+# 128 bytes plaintext
+KEY: 00000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40
+AD: ""
+TAG: cac45f60e31efd3b5a43b98a22ce1aa1
+
+# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
+KEY: 00000000000000000000000000000000
+NONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606
+AD: ""
+TAG: 566f8ef683078bfdeeffa869d751a017
+
+# 288 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
+KEY: 00000000000000000000000000000000
+NONCE: ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+IN: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+CT: 56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606872ca10dee15b3249b1a1b958f23134c4bccb7d03200bce420a2f8eb66dcf3644d1423c1b5699003c13ecef4bf38a3b60eedc34033bac1902783dc6d89e2e774188a439c7ebcc0672dbda4ddcfb2794613b0be41315ef778708a70ee7d75165c
+AD: ""
+TAG: 8b307f6b33286d0ab026a9ed3fe1e85f
+
+# 80 bytes plaintext, submitted by Intel
+KEY: 843ffcf5d2b72694d19ed01d01249412
+NONCE: dbcca32ebf9b804617c3aa9e
+IN: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f
+AD: 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f
+CT: 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5
+TAG: 3b629ccfbc1119b7319e1dce2cd6fd6d
diff --git a/src/crypto/cipher/test/aes_256_gcm_tests.txt b/src/crypto/cipher/test/aes_256_gcm_tests.txt
index 021c275..dbcee81 100644
--- a/src/crypto/cipher/test/aes_256_gcm_tests.txt
+++ b/src/crypto/cipher/test/aes_256_gcm_tests.txt
@@ -1,3 +1,6 @@
+# The AES-256-GCM test cases from cipher_test.txt have been merged into this
+# file.
+
KEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01
NONCE: 5bf11a0951f0bfc7ea5c9e58
IN:
@@ -418,3 +421,46 @@ AD: 2134f74e882a44e457c38b6580cd58ce20e81267baeb4a9d50c41ababc2a91ddf300c3996364
CT: 0fe35823610ea698aeb5b571f3ebbaf0ac3586ecb3b24fcc7c56943d4426f7fdf4e4a53fb430751456d41551f8e5502faa0e1ac5f452b27b13c1dc63e9231c6b192f8dd2978300293298acb6293459d3204429e374881085d49ed6ad76f1d85e3f6dd5455a7a5a9d7127386a30f80658395dc8eb158e5ca052a7137feef28aa247e176cceb9c031f73fb8d48139e3bdb30e2e19627f7fc3501a6d6287e2fb89ad184cefa1774585aa663586f289c778462eee3cd88071140274770e4ed98b9b83cd4fa659fcdd2d1fde7e58333c6cf7f83fe285b97ad8f276a375fafa15f88e6167f5f2bfb95af1aefee80b0620a9bc09402ab79036e716f0c8d518ae2fa15094f6ea4c5e8b283f97cc27f2f1d0b6367b4b508c7bad16f1539325751bd785e9e08cd508bdb3b84
TAG: 1976d7e121704ce463a8d4fe1b93d90f
+# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
+
+KEY: 0000000000000000000000000000000000000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: ""
+CT: ""
+AD: ""
+TAG: 530f8afbc74536b9a963b4f1c4cb738b
+
+KEY: 0000000000000000000000000000000000000000000000000000000000000000
+NONCE: 000000000000000000000000
+IN: 00000000000000000000000000000000
+CT: cea7403d4d606b6e074ec5d3baf39d18
+AD: ""
+TAG: d0d1c8a799996bf0265b98b5d48ab919
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255
+CT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad
+AD: ""
+TAG: b094dac5d93471bdec1a502270e3cc6c
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbaddecaf888
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 76fc6ece0f4e1768cddf8853bb2d551b
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: cafebabefacedbad
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: 3a337dbf46a792c45e454913fe2ea8f2
+
+KEY: feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308
+NONCE: 9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b
+IN: d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39
+CT: 5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f
+AD: feedfacedeadbeeffeedfacedeadbeefabaddad2
+TAG: a44a8266ee1c8eb0c8b5d4cf5ae9f19a
diff --git a/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
new file mode 100644
index 0000000..55c506d
--- /dev/null
+++ b/src/crypto/cipher/test/chacha20_poly1305_old_tests.txt
@@ -0,0 +1,422 @@
+KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
+NONCE: 3de9c0da2bd7f91e
+IN: ""
+AD: ""
+CT: ""
+TAG: 5a6e21f4ba6dbee57380e79e79c30def
+
+KEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5
+NONCE: 1e8b4c510f5ca083
+IN: 8c8419bc27
+AD: 34ab88c265
+CT: 1a7c2f33f5
+TAG: 2875c659d0f2808de3a40027feff91a4
+
+KEY: 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007
+NONCE: cd7cf67be39c794a
+IN: 86d09974840bded2a5ca
+AD: 87e229d4500845a079c0
+CT: e3e446f7ede9a19b62a4
+TAG: 677dabf4e3d24b876bb284753896e1d6
+
+KEY: 422a5355b56dcf2b436aa8152858106a88d9ba23cdfe087b5e74e817a52388b3
+NONCE: 1d12d6d91848f2ea
+IN: 537a645387f22d6f6dbbea568d3feb
+AD: bef267c99aec8af56bc238612bfea6
+CT: 281a366705c5a24b94e56146681e44
+TAG: 38f2b8ee3be44abba3c010d9cab6e042
+
+KEY: ec7b864a078c3d05d970b6ea3ba6d33d6bb73dfa64c622a4727a96ede876f685
+NONCE: 2bca0e59e39508d3
+IN: b76733895c871edd728a45ed1a21f15a9597d49d
+AD: cc1243ea54272db602fb0853c8e7027c56338b6c
+CT: 1fb9b2958fce47a5cada9d895fbb0c00d3569858
+TAG: 042ad5042c89ebc1aad57d3fb703d314
+
+KEY: 2c4c0fdb611df2d4d5e7898c6af0022795364adb8749155e2c68776a090e7d5c
+NONCE: 13ce7382734c4a71
+IN: 0dc6ff21a346e1337dd0db81d8f7d9f6fd1864418b98aadcdb
+AD: 0115edcb176ab8bfa947d1f7c3a86a845d310bf6706c59a8f9
+CT: dad65e4244a1a17ce59d88b00af4f7434bd7830ffdd4c5558f
+TAG: ac1437b45d8eacf9c0fe547c84fb82a2
+
+KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
+NONCE: 5d9856060c54ab06
+IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
+AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
+CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
+TAG: 6dd98710d8a889dceea0d0a936f98617
+
+KEY: a8b9766f404dea8cf7d7dfaf5822f53df9ccd092e332a57f007b301b507d5e14
+NONCE: c7f2f7a233104a2d
+IN: 4d6faeaee39179a7c892faae3719656cc614c7e6ecd8fcb570a3b82c4dace969090338
+AD: c6d83b6a56408a356e68d0494d4eff150530b09551d008373d6dee2b8d6b5619d67fdb
+CT: a15443f083316eef627a371f4c9ac654d0dd75255d8a303125e9f51af4233ff4ceb7fe
+TAG: 52504e880f6792a60708cc6db72eae42
+
+KEY: 5e8d0e5f1467f7a750c55144d0c670f7d91075f386795b230c9bf1c04ba250bc
+NONCE: 88049f44ba61b88f
+IN: 51a1eebcc348e0582196a0bce16ed1f8ac2e91c3e8a690e04a9f4b5cf63313d7ad08d1efbff85c89
+AD: 5d09bf0be90026f9fc51f73418d6d864b6d197ea030b3de072bd2c2f5cab5860a342abbd29dba9dc
+CT: 35aa4bd4537aa611fd7578fc227df50ebcb00c692a1cf6f02e50ed9270bd93af3bc68f4c75b96638
+TAG: ccea1cbbc83944cc66df4dbf6fb7fc46
+
+KEY: 21a9f07ec891d488805e9b92bb1b2286f3f0410c323b07fee1dc6f7379e22e48
+NONCE: 066215be6567377a
+IN: c1b0affaf2b8d7ef51cca9aacf7969f92f928c2e3cc7db2e15f47ee1f65023910d09f209d007b7436ee898133d
+AD: dfdfdf4d3a68b47ad0d48828dc17b2585da9c81c3a8d71d826b5fa8020fee002397e91fc9658e9d61d728b93eb
+CT: 8ff4ceb600e7d45696d02467f8e30df0d33864a040a41ffb9e4c2da09b92e88b6f6b850e9f7258d827b9aaf346
+TAG: 4eeddc99784011f0758ba5ebfba61827
+
+KEY: 54c93db9aa0e00d10b45041c7a7e41ee9f90ab78ae4c1bba18d673c3b370abde
+NONCE: 3f2d44e7b352360f
+IN: 1241e7d6fbe5eef5d8af9c2fb8b516e0f1dd49aa4ebe5491205194fe5aea3704efaf30d392f44cc99e0925b84460d4873344
+AD: f1d1b08dd6fe96c46578c1d1ad38881840b10cb5eae41e5f05fe5287223fa72242aea48cb374a80be937b541f9381efa66bb
+CT: 027b86865b80b4c4da823a7d3dbcf5845bf57d58ee334eb357e82369cc628979e2947830d9d4817efd3d0bc4779f0b388943
+TAG: 4303fa0174ac2b9916bf89c593baee37
+
+KEY: 808e0e73e9bcd274d4c6f65df2fe957822a602f039d4752616ba29a28926ef4a
+NONCE: 1b9cd73d2fc3cb8e
+IN: 3436c7b5be2394af7e88320c82326a6db37887ff9de41961c7d654dd22dd1f7d40444d48f5c663b86ff41f3e15b5c8ca1337f97635858f
+AD: d57cfbe5f2538044282e53b2f0bb4e86ea2233041fb36adb8338ded092148f8c2e894ef8766a7ec2dd02c6ac5dbab0c3703c5e9119e37c
+CT: 9b950b3caf7d25eaf5fca6fa3fe12ed077d80dcd5579851233c766bb8bb613ec91d925a939bb52fb88d5eda803cfe2a8cda2e055b962fd
+TAG: 6bf5b718f5bbe1395a5fdfcbbef752f5
+
+KEY: 4adfe1a26c5636536cd7cb72aa5bded0b1aa64487ad0e4078f311e8782768e97
+NONCE: d69e54badec11560
+IN: 19b3f9411ce875fcb684cbdc07938c4c1347e164f9640d37b22f975b4b9a373c4302ae0e7dfdeba1e0d00ced446e338f4c5bc01b4becef5115825276
+AD: bda1b0f6c2f4eb8121dcbd2eebd91a03ae1d6e0523b9b6f34b6f16ceca0d086654fb0552bfd5c8e1887730e1449ea02d7f647ae835bc2dab4bbc65b9
+CT: ea765a829d961e08bacaed801237ef4067df38ad3737b7c6de4db587a102a86fc4abbaabea0ee97c95ca7f571c7bab6f38cbae60cd6e6a4ce3c7a320
+TAG: b425cdf10cd0123a7e64b347c6b4b1f0
+
+KEY: eb3db86c14b7cc2e494345d0dfb4841bbd3aa1e2bc640cca0c6c405520685639
+NONCE: 88b54b28d6da8c81
+IN: f75c0a357271430b1ecff07a307b6c29325c6e66935046704a19845e629f87a9e3b8aa6c1df55dd426a487d533bb333e46f0d3418464ac1bef059231f8e87e6284
+AD: 34b08bb0df821c573dcb56f5b8b4a9920465067f3b5bf3e3254ea1da1a7fc9847fd38bdfe6b30927945263a91fa288c7cf1bee0fddb0fadf5948c5d83eb4623575
+CT: 146ec84f5dc1c9fe9de3307a9182dbaa75965bf85f5e64563e68d039a5b659aa8863b89228edb93ff3d8c3323ab0d03300476aa4aca206d4626a6b269b2078912d
+TAG: 0058a8dff32c29935c62210c359bd281
+
+KEY: dd5b49b5953e04d926d664da3b65ebcffbbf06abbe93a3819dfc1abbecbaab13
+NONCE: c5c8009459b9e31a
+IN: f21f6706a4dc33a361362c214defd56d353bcb29811e5819ab3c5c2c13950c7aa0000b9d1fe69bb46454514dcce88a4a5eda097c281b81e51d6a4dba47c80326ba6cea8e2bab
+AD: fe6f4cbb00794adea59e9de8b03c7fdf482e46f6c47a35f96997669c735ed5e729a49416b42468777e6a8d7aa173c18b8177418ded600124a98cbb65489f9c24a04f1e7127ce
+CT: 911ead61b2aa81d00c5eff53aeea3ab713709ed571765890d558fb59d3993b45f598a39e5eff4be844c4d4bd1ef9622e60412b21140007d54dcf31b2c0e3e98cf33a00fd27f0
+TAG: d38d672665e2c8c4a07954b10ecff7d9
+
+KEY: 3b319e40148a67dc0bb19271d9272b327bc5eee087173d3d134ad56c8c7dc020
+NONCE: ce5cf6fef84d0010
+IN: 27b5627b17a2de31ad00fc2ecb347da0a399bb75cc6eadd4d6ee02de8fbd6a2168d4763ba9368ba982e97a2db8126df0343cdad06d2bc7d7e12eec731d130f8b8745c1954bfd1d717b4ea2
+AD: a026b6638f2939ec9cc28d935fb7113157f3b5b7e26c12f8f25b36412b0cd560b7f11b62788a76bd171342e2ae858bcecb8266ff8482bbaed593afe818b9829e05e8e2b281ae7799580142
+CT: 368fb69892447b75778f1c5236e1e9d5d89255c3d68d565a5bba4f524d6ad27de13087f301e2ef4c08f5e2c6128b1d3e26de845c4ac4869e4c8bd8858ad0d26dec3b5d61a9e3666a3911ba
+TAG: 2e70564c3999c448d92cc6df29d095c4
+
+KEY: 43bf97407a82d0f684bb85342380d66b85fcc81c3e22f1c0d972cd5bfdf407f4
+NONCE: 8b6ba494c540fba4
+IN: 4b4c7e292a357f56fdf567c32fc0f33608110d7ce5c69112987d7b5a0bd46d8627a721b0aed070b54ea9726084188c518cba829f3920365afc9382c6a5eb0dd332b84612366735be2479b63c9efc7ff5
+AD: 1e0acf4070e8d6758b60d81b6d289a4ecdc30e3de4f9090c13691d5b93d5bbcef984f90956de53c5cf44be6c70440661fa58e65dec2734ff51d6d03f57bddda1f47807247e3194e2f7ddd5f3cafd250f
+CT: d0076c88ad4bc12d77eb8ae8d9b5bf3a2c5888a8d4c15297b38ece5d64f673191dc81547240a0cbe066c9c563f5c3424809971b5a07dcc70b107305561ce85aecb0b0ea0e8b4ff4d1e4f84836955a945
+TAG: 75c9347425b459af6d99b17345c61ff7
+
+KEY: 12fc0bc94104ed8150bde1e56856ce3c57cd1cf633954d22552140e1f4e7c65d
+NONCE: d3875d1b6c808353
+IN: 24592082d6e73eb65c409b26ceae032e57f6877514947fc45eb007b8a6034494dde5563ac586ea081dc12fa6cda32266be858e4748be40bb20f71320711bf84c3f0e2783a63ad6e25a63b44c373a99af845cdf452c
+AD: b8be08463e84a909d071f5ff87213391b7da889dc56fd2f1e3cf86a0a03e2c8eaa2f539bf73f90f5298c26f27ef4a673a12784833acb4d0861562142c974ee37b09ae7708a19f14d1ad8c402bd1ecf5ea280fab280
+CT: 9d9ae6328711fb897a88462d20b8aa1b278134cdf7b23e1f1c809fa408b68a7bfc2be61a790008edaa98823381f45ae65f71042689d88acfa5f63332f0fba737c4772c972eba266640056452903d6522cefd3f264e
+TAG: e9c982d4ade7397bcfaa1e4c5a6cd578
+
+KEY: 7b6300f7dc21c9fddeaa71f439d53b553a7bf3e69ff515b5cb6495d652a0f99c
+NONCE: 40b32e3fdc646453
+IN: 572f60d98c8becc8ba80dd6b8d2d0f7b7bbfd7e4abc235f374abd44d9035c7650a79d1dd545fa2f6fb0b5eba271779913e5c5eb450528e4128909a96d11a652bf3f7ae9d0d17adbf612ec9ca32e73ef6e87d7f4e21fe3412ce14
+AD: 9ff377545a35cf1bfb77c734ad900c703aee6c3174fdb3736664863036a3a9d09163c2992f093e2408911b8751f001e493decc41e4eeeed04f698b6daed48452a7e1a74ec3b4f3dcf2151ca249fa568aa084c8428a41f20be5fd
+CT: 229da76844426639e2fd3ef253a195e0a93f08452ba37219b6773f103134f3f87b1345f9b4bf8cfc11277c311780a2b6e19a363b6ac2efe6c4cc54a39b144e29c94b9ebbde6fd094c30f59d1b770ebf9fcad2a5c695dc003bf51
+TAG: b72acab50131a29558d56ae7b9d48e4e
+
+KEY: 4aeb62f024e187606ee7cc9f5865c391c43df1963f459c87ba00e44bb163a866
+NONCE: 9559bd08718b75af
+IN: c5d586ceece6f41812c969bcf1e727fe6ff8d1ae8c8c52367c612caa7cdf50e0662f5dffc5ea7d3cc39400dfe3dc1897905f6490fd7747b5f5f9842739c67d07ce7c339a5b3997a7fb4cd0d8e4817ff8916b251c11ef919167f858e41504b9
+AD: 51f5b503b73a5de8b96534c2a3f2d859ece0bd063ea6dfa486a7eec99f6c020983f7148cccb86202cf9685cc1cc266930f04e536ad8bc26094252baa4606d883bd2aeed6b430152202e9b6cc797ff24fc365315ed67391374c1357c9a845f2
+CT: 252ea42b6e5740306816974a4fe67b66e793ebe0914778ef485d55288eb6c9c45fa34ac853dc7a39252520514c3cb34c72b973b14b32bc257687d398f36f64cc2a668faffa7305ab240171343b5f9f49b6c2197e4fbe187b10540d7cdcfa37
+TAG: 711ff33ef8d2b067a1b85c64f32f1814
+
+KEY: 9a19e72f005cae1ae78b8e350d7aabe59fc8845999e8c52fad545b942c225eaf
+NONCE: d9dae2ea8d2ffc31
+IN: 2110378d856ded07eb2be8e8f43308e0c75bc8a3fcc7b1773b0725b7de49f6a166c4528e64120bdf7c9776615d3ce6feeb03de964a7b919206a77392f80437faceb6745845cafc166e1c13b68e70ca2a1d00c71737b8fcbbbd50902565c32159e05fcd23
+AD: 1cd73b72c4e103afbefd7c777e0480f3f5e68c60b85bd2e71ef5caebb175d7fc6535d39f38f92c24f2eb0fe97d878ed3d5967c0bb4394a5d41f7d34cda6e1523d3848f049cde554a7d31e1afeab5d3e6150f85858335cbd28c8a7f87d528058df50eea06
+CT: 5f009fbce4ec8e4ca9d8d42258b1a3e4e920b2fbad33d5e9f07557d9595e841025193b521ba440110dd83958e8ee30219d952b418e98a6c624894aa248aedc0678f2d263e7bfaf54ca379fef6c5d2f7ac422ea4b4369408b82d6225a7a2cf9a9f46fd4ef
+TAG: aa0a5fa7d3cf717a4704a59973b1cd15
+
+KEY: ba1d0b3329ecc009f1da0fab4c854b00ad944870fdca561838e38bad364da507
+NONCE: 8a81c92b37221f2f
+IN: 6289944ffa3ccea4bf25cd601b271f64e6deb0eba77d65efb4d69ca93e01996e4727168b6f74f3ccf17bd44715f23ceb8fc030c0e035e77f53263db025021fd2d04b87a1b54b12229c5e860481452a80a125cb0693a2ba1b47e28ee7cbaf9e683c178232c7f6d34f97
+AD: e57883961b8d041d9b9eeaddcfd61fa9f59213f66571fadffffdd1498b9b014f1ef2e7e56c3044d7f9fa7a1403a1169e86430a2a782137093f5456e142aad03a5f7a66d38009dd01b7fc02c9cf61642dedaf7cc8d46066c281ee17780674c3a36eae66c58d2d765075
+CT: 9c44d9135db0dbf81c862c1f69bec55a279794cdd29a58e61909aa29ec4c120c9c5a508d856b9e56138095714a4bb58402a1ad06774cf4ecdf2273839c0007cb88b5444b25c76f6d2424281101d043fc6369ebb3b2ff63cdb0f11a6ea1b8a7dafc80cdaef2813fa661
+TAG: 65c746f659bcbdcd054e768c57c848c9
+
+KEY: 0cf8c73a6cffc1b8b2f5d320da1d859d314374e4a9468db7fd42c8d270b7613a
+NONCE: 3c4c6f0281841aff
+IN: 4434728d234603c916e2faa06b25d83bad3348990ecde2344368d1a7af1309bd04251bb2e0b72044948f8dea33cce2618283b6af742073a9586b26c1089335fe735141e099785a1235810a3a67ff309e2f0ce68220ba0077ad1a5dc1a4aef898a3b9ff8f5ad7fe60149bd0bd6d83
+AD: a38d09a4f1c9241623c639b7688d8d35345ea5824080c9d74e4352919db63c74d318f19e1cbb9b14eebd7c74b0ad0119247651911f3551583e749ea50ff648858dcaaa789b7419d9e93a5bf6c8167188dbac2f36804380db325201982b8b06597efeb7684546b272642941591e92
+CT: bdfbfea261b1f4c134445321db9e6e40476e2dd2f4e4dbe86e31d6a116d25830762e065b07b11a3799aab93a94b4f98c31c0faeb77ec52c02048e9579257e67f5a6bae9bc65210c25b37fc16ee93bda88fd5f30a533e470b6188c6ce5739fa3e90f77120b490fc1027964f277f40
+TAG: 4993ee9582f58eabdb26b98c4d56a244
+
+KEY: 69f4e5788d486a75adf9207df1bd262dd2fe3dd3a0236420390d16e2a3040466
+NONCE: 6255bf5c71bb27d1
+IN: c15048ca2941ef9600e767a5045aa98ac615225b805a9fbda3ac6301cd5a66aef611400fa3bc04838ead9924d382bef8251a47f1e487d2f3ca4bccd3476a6ca7f13e94fd639a259ef23cc2f8b8d248a471d30ac9219631c3e6985100dc45e0b59b8fc62046309165ddb6f092da3a4f067c8a44
+AD: 0c83039504c8464b49d63b7f944802f0d39c85e9f3745e250f10119fa2c960490f75ae4dced8503b156d072a69f20400e9494ab2fa58446c255d82ff0be4b7e43046580bc1cf34060c6f076c72ea455c3687381a3b908e152b10c95c7b94155b0b4b303b7764a8a27d1db0a885f1040d5dbcc3
+CT: f0bb2b73d94f2a7cef70fe77e054f206998eacf2b86c05c4fa3f40f2b8cebf034fe17bcbee4dea821f51c18c0aa85b160f8508bd1dc455cc7f49668b1fb25557cdae147bf2399e07fcacaca18eccded741e026ef25365a6b0f44a6b3dd975ee6bb580f5fccd040b73c18b0fbf8f63199ba10fe
+TAG: 4236a8750f0cafee3c4a06a577a85cb3
+
+KEY: ad7b9409147a896648a2a2fe2128f79022a70d96dc482730cd85c70db492b638
+NONCE: a28a6dedf3f2b01a
+IN: 791d293ff0a3b8510b4d494b30f50b38a01638bf130e58c7601904f12cb8900871e8cf3d50abd4d34fda122c76dfee5b7f82cd6e8590647535c915ae08714e427da52f80aef09f40040036034ca52718ea68313c534e7a045cd51745ec52f2e1b59463db07de7ca401c6f6453841d247f370341b2dbc1212
+AD: 9a6defddb9b8d5c24a26dd8096f5b8c3af7a89e1f7d886f560fabbe64f14db838d6eb9d6879f4f0b769fe1f9eebf67fcd47b6f9ceb4840b2dba7587e98dc5cae186ef2a0f8601060e8058d9dda812d91387c583da701d2ba3347f285c5d44385a2b0bf07150cbc95e7fcfa8ae07132849a023c98817c03d2
+CT: c2f109d6d94f77a7289c8a2ab33bc6a98d976554721b0c726cbf4121069473e62ba36e7090e02414f3edc25c5d83ac80b49ad528cda1e3ad815b5a8c8ae9ad0753de725319df236983abd3f69ab4465d9b806c075b1896d40bdba72d73ba84c4a530896eb94ffccf5fb67eb59119e66a1861872218f928cf
+TAG: e48dc0153d5b0f7edb76fc97a0224987
+
+KEY: 48470da98228c9b53f58747673504f74ca1737d7d4bb6dbf7c0cba6ca42f80b9
+NONCE: 56fb4923a97e9320
+IN: bc6626d651e2b237f22ee51608ddcffeba5f31c26df72f443f701f2b085d6f34f806e29673584cb21522179edb62a82427d946acabce065b88b2878e9eb87ed1004e55ef58f51ec46375ac542c5782725ff013136cb506fcf99496e13fcd224b8a74a971cc8ddb8b393ccc6ac910bd1906ea9f2ed8a5d066dc639c20cd
+AD: df8ab634d3dca14e2e091b15ecc78f91e229a1a13cba5edd6526d182525ec575aa45bc70fb6193ffcd59bad3c347159099c4f139c323c30a230753d070018786b2e59b758dd4a97d1a88e8f672092bef780b451fd66ba7431cbb5660ea7816cdf26e19a6ebb9aadc3088e6923f29f53f877a6758068f79a6f2a182b4bf
+CT: a62e313ecf258cc9087cbb94fcc12643eb722d255c3f98c39f130e10058a375f0809662442c7b18044feb1602d89be40facae8e89ca967015f0b7f8c2e4e4a3855dbb46a066e49abf9cef67e6036400c8ff46b241fc99ba1974ba3ba6ea20dc52ec6753f6fc7697adbccd02b0bbea1df8352629b03b43cc3d632576787
+TAG: 675287f8143b9b976e50a80f8531bd39
+
+KEY: b62fb85c1decd0faf242ce662140ad1b82975e99a3fa01666cac2385ab91da54
+NONCE: 2f4a5ca096a4faf8
+IN: 03b14f13c0065e4a4421de62ab1d842bffb80f3da30bf47d115c09857f5bdd5756fd7c9ac3d9af1c9fb94f2640f7f4386cfba74db468e5288dbe4dd78bfe4f69e41480ca6138e8beacc6eaa3374157c713cfa900c07dd836eaecc8827fa3e70e052ae09e8473e2ae1a10b1bb669ef60a8dd957f6553daa8114918e17371f2ac327bd
+AD: cfe3b7ab7550b0e8e2e8235fa0dcef95647ce6814abd3dc3f5a3bd7d6d282504660c34ad8341e4d11402c7d46c83a494d7ddb105e1002979023e0e3dc2978c9ae53e10eb8567e7a02b60e51e945c7040d832ca900d132b4205a35034fed939a1b7965183c25654931a9b744401c4649c945710b0d9733b87451348b32ba81de30ea7
+CT: 8965db3d3ae4fb483208f147276e7d81b71a86e7202ffc9b1eaade009bc016838dc09ca4bcf30887b2f4243fbd652cd90ebed1ceef8151ff17ea70518d03b0f2a24960aa7de9b30fa65c2e2d57360061aae6d9376e984e9fcd5e5dd0911a4bc8deca832ffb76f252bd7da523076593ba6b174f7d9fb0377e066ecbb6638036241e86
+TAG: 3d0fc53e9058c2be32aa0850e0fab5a6
+
+KEY: de9c657258774d4ebc09d109a0fc79d66493ae578797cac4eb8830a6a4b547e0
+NONCE: b5e35fe3398efa34
+IN: 4d68fb683aa4f4c7a16ba1114fc0b1b8d8898610fa2763e435ded8771b3651078bef73d4dfd14e76a34cd5eb9ef4db4ead4da9e83f4ce50fe059977b2d17d687c29335a04d87389d211f8215449749969f7652dc1935a0f9a94538dc81dc9a39af63446a6517609076987920547d0098a9c6766cf5e704883ea32feaea1889b1554b5eb0ce5ecc
+AD: 436ea5a5fee8293b93e4e8488116c94d3269c19f1d5050def23d280515457b931bbed64a542b317cc5023d648330a4b7adca14dd6f3783207b94f86ccaa0a0ac39b7db00ac87a99e3cd8a764ed9c75da8454479636ab2b29e770b166a5b75cacc425c919bf1ce9ac34afe6b4425c3d9fd2e48bc81e7d15516d60e592bfcc2ebefb660f0995f2b5
+CT: 97a97b8f0f5420845ae8d57567f9bba693d30e6db916fad0b971f553ad7d993f806f27ab8b458d8046062ced4778c004b4f958a4436141637c6039963308dea2f54008b7feab79650295ed41bf9e65e1a2d75ab1c7b2a70ebb9e9f38d07a9a672d3e95ea78afe9ac02f2566b48b0251aef6eeeca8bd15bd8d43b559426aa9d15d960ee35cb3edf
+TAG: e55dbb21851e8a5b365f86d02518331c
+
+KEY: 6885bd333c336c7672db8ebdf24c1a1b605c5a4ae279f0f698162f47e6c73401
+NONCE: f0c4a213a6168aab
+IN: fa905a2bfa5b5bad767239fb070a7bc0b303d1503ecd2b429418cc8feba843e5444ed89022fdb379c3b155a0f9ceab2979000a0f60292a631771f2fde4ef065aa746426609082969530a9c70ad145308c30ba389ea122fd766081511a031ce3a0bd9f9f583c7000b333b79ac004fbde6ec3eb2d905977ff95dcff77858e3c424fe8932a6a12139e6ec8d5e98
+AD: 8ded368f919efb522bb6a9ad009e02ffbc6a16536e34d95cdb34f1153d7cb7b0f3c2b13dd05cedae27cfe68ec3aca8047e0930a29c9d0770c1b83c234dcb0385deae7ae85da73a5f8de3dfb28612a001f4e552c4f67ae0e2ec53853289b7017a58591fd6f70b0e954876bb2f7ec33001e298856a64bb16181017ba924648c09fc63c62eff262c80d614679bd
+CT: 0cb3d6c31e0f4029eca5524f951244df042fc637c4162511fea512a52d3f7581af097eb642e79e48666cb1086edbd38c4777c535a20945fabc23e7c9277e2b960aac46865f1026eb6da82759108b9baece5da930ccfc1052b1656b0eadaa120ed0c45ad04b24ae8cdb22ceab76c5f180b46a392ab45b1b99c612546e6b947f4d5c06ad5abee92ff96345ad43
+TAG: d3b541ac446c84626daf800c0172eec6
+
+KEY: fbc978abb1240a6937ccc16735b8d6ed5411cdbc1897214165a174e16f4e699b
+NONCE: 7968379a8ce88117
+IN: 1a8196cd4a1389ec916ef8b7da5078a2afa8e9f1081223fa72f6524ac0a1a8019e44a09563a953615587429295052cc904b89f778ef446ed341430d7d8f747cf2db4308478524639f44457253ae5a4451c7efca8ae0b6c5c051aaa781e9c505489b381a6dcba87b157edc7f820a8fbaf2a52e484dc121f33d9d8b9ac59d4901d6ed8996ed4f62d9d4d82274c449cd74efa
+AD: 3913cd01299b8a4e507f067d887d7e9a6ded16dd9f9bb3115c5779aa14239fd33ee9f25756d45262dc3011069356425b5c81a4729594e17c9747119f81463e85625d5603d05e00f568b0c800bb181eb717be8d7a93166a504ce1bc817e15530c5bd2b3df1d4222245ea78a38bc10f66c5cf68d661503131f11af885c8a910b6dce70bc3a7448dfae00595beb707fe054d3
+CT: d152bcb4c24c3711b0fad28548dc4db605bbc89237cdbea7dbf956b8855d1161a0781f27bd56d798141e2ace339955efb98fe05d9b44cd011e645106bf47726183958cb6df34ce5766695f60bc70b6fe0fabb9afa009a8ef043dbf75f861881368fa07726625448fe608d578cdc48277f2dc53eaaf1bdc075269a42f9302a57cad387a82c6969608acacda20e1cac4596c
+TAG: 945dca73cf2f007ae243991c4fbe0479
+
+KEY: 77d1a857fbadfe01aba7974eea2dfb3dc7bf41de73686aece403993e5016c714
+NONCE: fdd913a321c40eb0
+IN: db8915bfe651e2ecb3ce0b27d99a6bfa7a7c507cfcb2987293018636c365a459c6a138b4428be538413db15bda69e697cbb92b154b7f4d2cbb07965225aa6865d7dcd1ba2c17c484b00b1986fed63e889f25a4966dc3ed4273f1577768f665362d7d3e824484f0dded7f82b8be8797ad951719719365e45abbf76324bc7d657799d4d4f4bb1dba67d96ab1c88519a5bee704f7214814
+AD: 3cb2c06c20cb0832bbacebfc205d77393ca1816346ea2681de4d3ab1fadb774ad273e4713290454496f5281ebc65e04cfe84ed37cd0aedc4bbe3decbd8d79d04a4e434876650e0d64309e336bfb10e924066a64acb92260b2dbd96735d03af03909aa6a80a6e89fda81037257aec21fe9be7e91a64e88e0a58fa38ecba4c4c4cffb61958f3c486cbb0b1d0b0014a2d1d3df248eec1ca
+CT: acb825e6023b44b03b2efc265603e887954e8612b2ee134bdcb61501cfb9492952bf67be597c3a005b09af74d9e421a576d2c65e98104780feab838d8cb1bd135452ea39dc8907a4c1a6a9161805e4fa3e16989e6a418a7eea2582bf895da967028eab7c95d846a6de4b9980785814cf00484baa2f6de609912fff689bce6e854261ffe866bd8e63274605c7c5ad677bd7897ade543e
+TAG: 938478a41a3223a2199f9276d116210f
+
+KEY: b7e9b90dc02b5cd6df5df7283ef293ed4dc07513d9e67331b606f4d42dec7d29
+NONCE: a6c191f6d1818f8e
+IN: 2ada0e3c7ca6db1f780ce8c79472af4e8e951ddc828e0d6e8a67df520638ff5f14a2f95a5e5931749ae2c4e9946ae4d5eb5de42fb5b77d2236e2e2bd817df51be40b1b8a6c21015a7c79fe06dba4a08b34013dfa02747b5f03930268404c455dc54a74d9c6e35485e10026da573cb41cd50b64cfafe4cfcdf3c9684ef877e45d84e22bd5e15fa6c8fd5be921366ff0dc6fe2df45f7252972c9b303
+AD: 0f4269ed5ef0bfff7be39946a4e86e8bf79f84b70cd0b14fecb7be3c071316ce86de3d99d6871e0ba5667d9d7bba7dcaba10cb2a36668b6c3e2fb6c102938b75008bb9c213ebf9b85b5e91a802df0d31d7f11d764b2289f6225212694ab6b7c0e3ff36e84245d9f4f43fc5f98e654dea7ba9bd918658879c5bb4a1642af0d83113e3cf935d3c0d5208318f66f654eb17d8c28a602543e77ad3e815
+CT: 22586fe7338e99cdaad9f85bd724ba4cfe6249b8a71399f9a3707b5c4323b8d96679568dfc8d230aefb453df596e13eb3e8a439249bd64bc93a58f95089a62b94f6562b821c83d91f56c55147381e9de4beb4ae81bd6fe7caef7e7e9a2078f2fba8f3e70d4910da9accc92b8e81a61b0fefbece4bd89443e66e8ddda8e47a66a62f17fd0e7d0a4852ce1a4d43d72a0b5e8914bbec698f060f2b092
+TAG: c082470297da8c5f682a169d28bc0239
+
+KEY: 6b2cb2678d1102f2fbbd028794a79f14585c223d405e1ae904c0361e9b241e99
+NONCE: 7b3ae31f8f938251
+IN: b3cb745930e05f3ab8c926c0a343a6eb14809fd21b8390a6fcc58adb5579e5432021765b2d249a0ecf6ba678634c4f53f71495865f031ee97aa159f9ead3a3fcb823ee5238bdf12706a9c6137d236e2e7110ce650c321e41daf0afd62bab2a8fe55d7018de49a14efe6d83a15b2f256d595e998d25309f23633360f5745c50c4e5af8ccc9a8a2cb47064105a023e919c7795d2dc331d3f2afb8c42e5c0bcc26d
+AD: 1c32fd3df22b3e440e2a3c7a7624990194cb16a5f74af36f87fd6ca7d410ce9064316a2d091945deef7d9b35ceec8396069307caced2b80afd7d53ec479c35cedf2dfd4c95c3dd8400f71ad34028c6e4f8681d93d0774064ba38f3fb9b0c1dfa1f5f0c7d20676a5911d999fb6a1d41367a8e99d852bf3d3b7b3f4c233249ed1ca135389a674ff48232ded3f6800a97b6d409c40e6cd70d09bf9d2ad25d9b9485
+CT: ef70c7de98ab1d4ad817024a970be463443640eb0cd7ff234bdd00e653074a77a1d5749e698bd526dc709f82df06f4c0e64046b3dc5f3c7044aef53aebb807d32239d0652dd990362c44ec25bf5aeae641e27bf716e0c4a1c9fbd37bbf602bb0d0c35b0638be20dd5d5891d446137e842f92c0ee075c68225e4dbacb63cc6fb32442b4bcda5e62cb500a4df2741a4059034d2ccb71b0b8b0112bf1c4ca6eec74
+TAG: 393ae233848034248c191ac0e36b6123
+
+KEY: 4dbc80a402c9fceaa755e1105dc49ef6489016776883e06fcf3aed93bf7f6af7
+NONCE: 2358ae0ce3fb8e9f
+IN: 197c06403eb896d2fa6465e4d64426d24cc7476aa1ae4127cd2bd8a48ce2c99c16b1cbf3064856e84073b6cf12e7406698ef3dd1240c026cbd1ab04ee603e1e6e735c9b7551fd0d355202b4f64b482dd4a7c7d82c4fe2eb494d0d5e17788982d704c1356c41a94655530deda23118cba281d0f717e149fbeb2c59b22d0c0574c1a2e640afad1a6ceb92e1bf1dde71752a1c991e9a5517fe98688a16b073dbf6884cfde61ac
+AD: cf6ce7b899fb700a90d2a5466d54d31358ecf0562e02b330a27ba0138006b342b7ed6349d73c4c5c6d29bde75a25089b11dac5b27adea7e7640ca1a7ceb050e3aae84a47e11640a6e485bd54ae9fdb547edc7313d24a0328429fcffd8b18f39880edd616447344ebeec9eadb2dcb1fa7e67179e7f913c194ebd8f5a58aea73b0c5d1133561245b6d9c5cfd8bb0c25b38ffb37db5e2de5cdded6b57355e9d215cb095b8731f
+CT: aa87f9a83048b6919c8f2b050315db4e2adae4a9c2ca0109b81961b520e63299dcb028cec0b9d3249a945ee67dd029b40f361245c740f004f8cf0d2214fcfa65e6124a3e74b78aa94345c46fdc158d34823ed249ee550431eaae9218367321cdd6e6a477650469bb3cc137a8f48d9cf27934b16703608b383d2145659922fb83bb2e7ee2ef938a90f2ff846a4a949129b1fb74dde55c5ae013c2f285de84f7dac7d1662f23
+TAG: 06b4318ac7f65d556f781428a0514ffe
+
+KEY: 9e4a62016dae4b3223fed1d01d0787e31d30694f79e8142224fe4c4735248a83
+NONCE: 263a2fc06a2872e7
+IN: 5a46946601f93a0cee5993c69575e599cc24f51aafa2d7c28d816a5b9b4decda2e59c111075fb60a903d701ad2680bb14aeda14af2ae9c07a759d8388b30446f28b85f0a05cd150050bd2e715ff550ebbd24da3ebb1eac15aba23d448659de34be962ab3ab31cb1758db76c468b5bb8ce44b06c4e4db9bd2f0615b1e727f053f6b4ffb6358d248f022bcad6ca973044bed23d3920906a89a9a9c5d8024ec67d7f061f64529a955ce16b3
+AD: 4cd65f68f9f88c0516231f2a425c8f8a287de47d409d5ecde3ad151e906b3839fb01bb91a456f20ea9d394d4b06604ab1f9009ef29019af7968d965d1643161ab33a5354cda2fdc9f1d21ec9cb71c325c65964a14f9b26eb16560beb9792075a1597394000fd5f331bd8b7d20d88e5f89cf8d0b33e4e78e4904bb59c9c8d5d31ac86b893e4a0667af1be85fdb77f7ec3e2594a68048d20c2fb9422f5879078772ee26a1c560cbcbb2113
+CT: e944bb2ab06d138ad633c16ce82706ecf0ef5d119be1f3460c9ce101d9c4e04ef1677707fca40d1f8ca181e07273707b06624d6d7063c3b7b0bb0151b757b3e5237fb8004c161233d8bc7e5f28ea1c18da1874b3d54c5ad6ff0835eed35c8853704585cf83996e5e7cec68180af414e04f08134d3b0384ebdf0393c9310b55d8698fe10cb362defc0995e9a13b48b42cff61ffd9fe4c3c8c6dab355713b88f6e98a02e7231a0c6644ec4
+TAG: 27de0d4ca7648f6396d5419a7b1243b7
+
+KEY: 18ca3ea3e8baeed1b341189297d33cef7f4e0a2fab40ec3b6bb67385d0969cfe
+NONCE: b6aef34c75818e7c
+IN: ef6d1bb4094782f602fcf41561cba4970679661c63befe35ff2ca7ad1a280bf6b1e7f153fa848edfeffe25153f540b71253e8baba9aeb719a02752cda60ea5938aab339eead5aabf81b19b0fc5c1ed556be6ad8970ea43c303d3046205b12c419dea71c4245cfedd0a31b0f4150b5a9fe80052790188529ab32f5e61d8ccde5973ed30bdf290cbfbd5f073c0c6a020eac0332fced17a9a08cef6f9217bd6bef68c1505d6eed40953e15508d87f08fc
+AD: f40f03beaa023db6311bad9b4d5d0d66a58d978e0bcbbf78acebde1f4eb9a284095628955a0b15afc454152f962ec3ea2b9a3b089b99658e68ede4dee5acd56672025eb7323bcbc6ba5d91c94310f18c918e3914bbbf869e1b8721476f9def31b9d32c471a54132481aa89f6c735ab193369496d8dbeb49b130d85fbff3f9cb7dccea4c1da7a2846eef5e6929d9009a9149e39c6c8ec150c9ab49a09c18c4749a0a9fcba77057cdea6efd4d142256c
+CT: c531633c0c98230dcf059c1081d1d69c96bab71c3143ae60f9fc2b9cd18762314496ab6e90bf6796252cb9f667a1f08da47fc2b0eecda813228cae00d4c0d71f5e01b6ce762fa636efffe55d0e89fdc89ba42521cc019ab9d408fcd79c14914e8bbf0ea44d8a1d35743ad628327e432fdcfeb0b6679ddca8c92b998473732abd55dba54eefff83c78488eee5f92b145a74b6866531476fc46279d4fde24d049c1ce2b42358ff3ab2ba3a8866e547af
+TAG: a0a5242759a6d9b1aa5baf9a4ef895a2
+
+KEY: 95fdd2d3d4296069055b6b79e5d1387628254a7be647baafdf99dd8af354d817
+NONCE: cd7ed9e70f608613
+IN: 0248284acffa4b2c46636bdf8cc70028dd151a6d8e7a5a5bc2d39acc1020e736885031b252bfe9f96490921f41d1e174bf1ac03707bc2ae5088a1208a7c664583835e8bb93c787b96dea9fc4b884930c57799e7b7a6649c61340376d042b9f5faee8956c70a63cf1cff4fc2c7cb8535c10214e73cec6b79669d824f23ff8c8a2ca1c05974dd6189cfee484d0906df487b6bd85671ce2b23825052e44b84803e2839a96391abc25945cb867b527cdd9b373fbfb83
+AD: 24a45a3a0076a5bcfd5afe1c54f7b77496117d29f4c0909f1e6940b81dde3abacb71ec71f0f4db8a7e540bd4c2c60faee21dd3ce72963855be1b0ce54fb20ad82dbc45be20cd6c171e2bebb79e65e7d01567ad0eeb869883e4e814c93688607a12b3b732c1703b09566c308d29ce676a5c762a85700639b70d82aaef408cf98821a372c6a0614a73ba9918a7951ea8b2bb77cd9896d26988086d8586d72edc92af2042ff5e5f1429a22f61065e03cfcd7edc2a93
+CT: 40c6318d9e383e107cdd3e1c8951562193c3ef64ee442432a63e2edefc78f32ab07772aeac172cb67ecf4d21f8b448423527bbeb9d8ddd0b46bdb27f74096ceb24e41963b4cdca176676a75bdbe3abc270b349ac0c6cbd9c3a5cd5bce20202fc5cc0c1bdd4fd25e121e0a24bd7bbeb9b19b1912467bf5338ee2ce88aa383c082b42cc399c9654ca325f35523e81438beb3f8926be79c378822d7c8f785614408a5f7cac49e4543188725643e6c1a70b46d0ec400
+TAG: 5801e84192c7267f66b0e04607a39a3e
+
+KEY: 6ae1102f84ed4dc114bb9d63f4dc78d7dbb1ab63f1659dd95f47940a7b7a811f
+NONCE: c965d578ba91d227
+IN: b82a8a9209618f1f5be9c2c32aba3dc45b4947007b14c851cd694456b303ad59a465662803006705673d6c3e29f1d3510dfc0405463c03414e0e07e359f1f1816c68b2434a19d3eee0464873e23c43f3ab60a3f606a0e5be81e3ab4aa27fb7707a57b949f00d6cd3a11ae4827d4889dd455a0b6d39e99012fd40db23fb50e79e11f8a6451669beb2fbd913effd49ad1b43926311f6e13a6e7a09cf4bebb1c0bf63ce59cd5a08e4b8d8dbf9d002e8a3d9e80c7995bb0b485280
+AD: dfd4ac3e80b2904623ff79ea8ee87862268939decf5306c07a175b6b9da0eb13ac209b4d164755929e03240a0fe26599f136fb2afdffd12bb20354aa1d20e5799839abb68ae46d50c8974e13e361d87ef550fe6d82e8b5b172cf5cd08482efdef793ede3530d24667faf3a1e96348867c2942641f4c036981b83f50236b8e8a10b83ebf6909aad0076302f1083f72de4cf4a1a3183fe6ec6bfe2e73e2af8e1e8c9d85079083fd179ccc2ee9ff002f213dbd7333053a46c5e43
+CT: a9aeb8f0a2b3ca141ac71a808dcc0c9798ac117c5d2bd09b3cfe622693a9f8ca62e841b58bddb2042f888e3099b53638b88dfc930b7a6ee4272d77e4b1d7e442bab6afbde96ab0b432f0092d9ca50eef42f63c60c09e7b8de019b32ebe4030c37b8183cc1e3b913b0ce4ee4d744398fa03f9af1c070bed8cdafd65b3a84140cb4deadc70184de757332ce3780af84353f540755227e886a8d7ad980f3dd6fd68263d82e93f883381dec888bc9f4f48349aa2b4c342cb9f48c6
+TAG: f26b3af8a45c416291ce66330733b2f8
+
+KEY: 405bb7b94715b875df068655f00513cb1ae23ffaac977ce273e57d3f83b43663
+NONCE: 5c6da1259451119a
+IN: f9f143c0c52c94b4ba7b0608b144156a49e7b5d27c97315743d171911e3645ab7957c80924e3c6b9c22ab7a1cac4b7e9c0de84e49fd5e4a2d1ab51d764fc5670318688ec942f7ab34c331dce8f90fea6972e07f0dadec29d8eb3b7b6521ddd678a6527a962f4d8af78c077e27f7a0b2ef7eabd19e92b7f8c1e8fb166d4763ce9c40c888cf49aa9cdfc3e997c8fe1cce3fe802441bbd698de269ff316f31c196e62d12c6bb5cd93fb3c79ca6369f8c1ac9102daf818975ea7f513bb38576a
+AD: 6fe6446505677bf08b385e2f6d83ef70e1547712208d9cebc010cba8c16ea4ece058d73c72273eed650afdc9f954f35aa1bdf90f1118b1173368acbc8d38d93ebf85bd30d6dc6d1b90913790c3efa55f34d31531f70c958759b2ba6f956c6fcdd289b58cb4c26e9515bf550f0fd71ab8527f062c9505cbb16e8e037d34de1756bef02a133dbf4a9c00ac03befc3fb7f137af04e12595ce9560f98b612480fcdba3b8be01db56ebec40f9deae532c3b0370b5c23a2a6b02a4de69efa8900c
+CT: 1a4b073881922c6366680cc9c2a127b26f264148651b29abb0c388cf6c9b1865dba5a991e1f8309efbdb91bce44b278772c58fd41273526c33fec84beb53d1689b9da8483f71be6db73a73417069bb4cd3f195236e8d0a00d124eed3a6b6f89415b19a27fbe35774f6a1a6ee4bd4350b252b975f0db2d2eea82f4836350850d6290901e726e8af13644e2d98bc1d569c20800521e6affe976bd407049a2e6d9dd23f88d52e651391ecd2fc45b864310824aaadfa203762a77c1d64562dae
+TAG: 0060026d3efc120f11c0739959ae0066
+
+KEY: 8c602bd94c630cd00c7a9c508067a5a9f133d12f06d9f6fe2a7b68dce4786d8a
+NONCE: 760de0f7b7cb67e2
+IN: c3ff559cf1d6ba6c0cc793ca09a0ba573a28359386a6ec93e1bacd8e630209e0b477a20aedec3c9cbf513ee6a1e3887112218d6155b9875f7e6c4bbba2c31972e905d19f529f4f0f9502996199f94f8728ba8d6424bb15f87fcacd88bb42c63fcc513759712bd0172b1e87c9da122f1993ffb7efd3a5c34b240dd3db89dddea36dbeb2836d9f8648f8e7cd428c0f948097af753b35f9876059e7702027bb00dc69071206e785f48fcbf81b39cc0343974ac70784a2e60c0df93b40379bea4ad8cac625
+AD: 9e14907c3a8e96c2636db1f3d78eb1f673d6ef043cbbb349467f1fe29bf60f23d5d5d1c3b133a8ad72065d822347541c13d1574baf737eb3cc3382fb479e6d5193b9c8e7d2444c66971ef099dc7f37f6cd97b9f7959d46e2cf25e8a5b3111b4d9e2ef906d905f0ee2d17587f7082d7c8e9a51509bde03d3d64338e1838d71700f1b4fcb100b5e0402969da462f26f974b4f9e766121f8fd54be99fc10beb9a606e13fbb1f960062815d19e67f80093360324013095719273c65542b0e31b1a2a3d928f
+CT: 2794e6e133f6892f23837fff60cf7c28ee9942f8982ef8089db117903d0143293fdf12ea1cc014bcd8806fb83c19570eed7af522db0de489bbc87133a13434518bcfb9cda4d9f6d832a69209657a447abf8afd816ae15f313c7ea95ec4bc694efc2386cdd8d915dc475e8fadf3421fbb0319a3c0b3b6dfa80ca3bb22c7aab07fe14a3fea5f0aee17ab1302338eeac010a04e505e20096a95f3347dc2b4510f62d6a4c1fae6b36939503a6ac22780a62d72f2fc3849d4ef21267fffdef23196d88fbb9b
+TAG: 457cce6e075ffdb180765ab2e105c707
+
+KEY: bd68ff5eb296c71cfe6bc903c14907f7726bcb1331f0c75f7801cd1b7948f3a1
+NONCE: 65a748004b352ba6
+IN: 52bf78c00f6e5dca2fc60e2e9a52e827df97808e9cf727773860cafc89f4b64178a19b30b46ed813fe00c8f09b25a6a1b6e350d5b005122934a59bfbd5e6e0c635c84a5226c3f2f7dcf951560f18ac220453d583015fdb2e446c69c6e6fdecf2e595e04fab1b0c506e3c6bd5e4414a35f15021e97f447aa334f54a8f1ef942dec6273511b5668b696fca97188ff15ed84b2f46145cce031c1a7f00bd88bb83d90797edc46161b3fda7a2299173496d73b812139556e8b4eb318078b9eb2ae5046e83b79dd3d45950
+AD: 5557b08a5010cbc9f46bb140c2505f68684eb24889324bff44b27234fd7a95a99cfb4ff90a8f9982085b725f78ac42eca6ce7f3314e457dc41f404008681a9d29ba765660de2e05bb679d65b81f5e797d8417b94eb9aabbd0576b5c57f86eae25f6050a7918e4c8021a85b47f7a83b4c8446898441c5cc4e0229776ef3e809cb085d71f3c75ec03378730cb066150f07e60f96aec983c0e7e72bf6bf87ae42228dfda195f97855fcdf4e6d1c4479d978abcfa276d16ed60ecbfbfc664041335ce65a40a2ca3424df
+CT: a5c8cf42287d4760fca755e2111817b981c47e85b0047de270ec301ca5f7b3679f4749210892b6ea6568f3a6a4344734a0efc0120ffedecf212d55cbcbb67815ac964875af45f735b70092a8f8435f52fc01b981ae971d486026fb69a9c3927acfe1f2eab0340ae95f8dbee41b2548e400805ece191db5fd1f0804053f1dbfaf7f8d6fded3874cb92d99a2729d3faaa60522060cf0b8101b463b3eb35b380fcddb6406c027d73fe701a5090c8dd531c203ce979e26b9ced3431e2b726a7244a20d9377bd62951bf5
+TAG: 4579fa1fdb4c674cc3cd232b8da52a97
+
+KEY: 934fd043c32d16a88fad01c3506469b077cb79d258b5664fa55ad8521afdcaa2
+NONCE: c7091f6afbbeb360
+IN: 2bdd1fc4f011ef97ea52ec643819941c7e0fb39023c2f3c7683804a0ddee14a5d1784a5246966d533b3538edc7d8742d27061c3cab88df0318ab242102de3a54d03632eeb871b72c7e8f8065b49f4a91e95e15f3f46b29fd76b8fcea0d23570c5530e3bbb8a6aafa9ae32c1b3eac653c5ed5fdb2da5a986075808f6385870c85b1913e26042a9d8e78f5bc2ea6de5a64f8aeafa22adcffc7f6932d543c29bb3a04614783f948680e433a71573568d2ce984d249fb4fc06a9f358c76aa3e64a357f4eae924c1356bd5baccf7e0f
+AD: f737dd85638eb324dd3891219c5eef7c2dd053cfd055d447a411eba304a4b27dce981d112c4540590933c153d603022c91ebd2b4a58069d27e6ca17a462ef822ca41bffa80b43a68b1b564644cb3c5a7f0fddf7a13a30ff24437fddd8ef93c6f6f205d054f81890d982bd4d4ece0b1563677e843fe48c1f54e9a57ed4da66061482712e710a401073be5080d5b8b96525bffa67de5af31d50385fbbf1a87c21bf0e0a1fdff69ec32c7b7103e0b8ee6c844245e0fc84b9f89fcce62966cea68e2871d3b82e8df424c76309fc88d
+CT: dd13fbf22c8d18354d774bcd18f7eb814e9b528e9e424abc4e3f2463195e8018576565d16ab48845d11c9277f2865ebb4dc412fd5b27078f8325eadf971e6944c66542e34d9dda971e2aba70dbd3e94a1e638d521477a027776b52acf90520ca229ebc760b73128879475d1cbe1f70fc598b549cd92d8a9ac6833e500c138c56474db84cb3d70b7aa4f293a4c2b4d818b0ff9fd85918dc590a12a8c0e375c4d98b7fc87596547eb960676aad5559834588f00f251a9d53f95c47af4df3c4299175d5211779c148cfc988a5e9d9
+TAG: 476616ea15190c1093fdc4a087643cae
+
+KEY: f9f6eb9ad736a8f66e7459fef5ec2890188dc26baf34a95f6f0384e79f5c6559
+NONCE: 7858dfc084fe4b0f
+IN: a644ca6e7cc076e87eb2929fd257693fce0f6fb64fd632f7f07c648ebd03696c8e262e6a810d7b7c4e5eef8c65b5323c99dbba50a70b4a9e5c2a9e7315973cd67f35d8052ce9a85a206416dd3031929f4f929b13d0a5fb10cb73c65f6c0ace019da146b51c5274a099f44e3669d26add6f2ff081e886f3cf952fe0dbbe6b0534c23e307574bd35fbd657f5fcbd5dc19fb382a1dc0a2dc8285a0350f71554e4c601497749e35567dd4a273cddc9a48ce53a5f1d297fd8baf8d1b9feb35d9151114345abada4d90db947bb9a743c175f5653d1
+AD: 2048d1c2ddfb5ec385b201832c7a993f229ba72ec16d6ebf723ef0c5032b9966209a9e8a63151b40412e96b82f86728ea6588c7e8e11ac71cc8eabab8c4b54de866658d9c5011def61fb3dbe4e630158a45ea41a2ed55ebd1efb1abeda7637de6fa5fd2f151c6d2f385bf6cd002ca8b4a2896e0d65944ee913e3c784669dd201b1985ef3577f7f123a5f9bcffa176c8f557c4f729133cac518642f27d9b22ca9b97faaafe5b669a10b79ace4a7d5727df146c77ce681357d69f9c2d65b4401bd73cd113387e3b3a05d897adad7a24c485e7b
+CT: 4146faffd7313f5d9f625370d20413cc62ab65f4acfa3c7ee1125b937dd7a39f638fc46c8ed004fb525698de5d8620ec153435571817c3de257b0d0e648ebb92940c86a98262d54e764f28cbdd4f7d9bea970291f2110414f62064d7229c6332236c507b3dac742e651d85a2a22fb243c0cc7cc2d016e5bea38f33f9a9ce048944a5fe8b078d71d23168e12dfe5a0f0b829771edc7073fb96032b7be471337a37aca0cf7c0cdd543eed686cd34934717fd79a3f18492eef72f9f450b880aa7e2e1b65e3b04c22e72301338b43aa32ceec2e6
+TAG: 10ffaf2be316676da02d7473a9df87b9
+
+KEY: 29b19636cdd32507fd98ec4ee26caab1a917646fb8f05b0dc01728a9f4a127f0
+NONCE: 06699d245916686d
+IN: 5fdf913aceab1d6dbaf7d9a29352fa8a3eb22718043a79cffa2fe8c35c820aec7c07644b8785dcf7a433b4189abb257fb12b06fae0662641011a069873c3e3c5ccc78e7358184a62c2005c44b8a92254958eb5ff460d73cd80284d6daba22c3faba046c5426fe8b7cacec64b235a8f8d3e2641e5bc378830594bcfb27c177aea745951ee5780a63705727ef42c4ad3abf556d88e3830f3db6b09e93edd09485cbf907f79de61f8dc5cb5fb7665ffa0ef53cb48702f6a81d8ad421cef20c1dbdf402b8fafed56a5361b2f93f914a2380fdd0557faf1f4de
+AD: 39116c49cc13adb065b92cb7635f73d5f6bf6b5ccbf72a3f65a5df6bd4a661105015358d9e69f42e98aed795e8161282bc113058b7ef3b9e23fcd8eeab34a392e03f4d6329c112cb968385ec52a7afc98bb8695785af6b27b700973cc952630b7247ce226b4fbb99b8a486370bf6345d4516c52c64e33f407c4f2d1ba90545c88732d98bbd97972ac5e94c694624a9b3782b0099824651cb7567914d25b3e13181a791dbcd40e76e836b3350d310a52151bf835d3c357c9871482c2928e8404c6e533406d4d6fa8f63366f2c4ed828141f1ff00f01a536
+CT: 01e237220b619054a1f3670928fe67d40484b5af40fbd04d032500aac5acaa3b4584dd99a58c390627636a50de5d744f76a56a33205f9e3b00e16162eb47ff3333e1e208ca200f1a5338a86e17bd92dd2d16af8bb022a7dc05b923d019e05247f1a0d0b4bfcfce58dd6d83830705707676d55739abee89fcd5cb94b8fde006a5da02df64b00a467f45970b5ca440f22319b9735a55d454b9fba0588fef0c59d3d83823eba6e0601a96e10233826c5adeea6b2a51d386a07a9e047ad405b23d4c3d89f30c31e3199f0c8f927bfac43ceea1f969de0a8c0f
+TAG: 092f9f3c5d4f2570c9946c87967f4579
+
+KEY: bae06b9b5456707551c7b0e207aae02a19b4848ad8ca4ce40705bf8c856a6e52
+NONCE: 9c27065c3ef2d522
+IN: 50cdd88137ff428a88e87b5845be4924f6387537bb5c0b654c80107ab5698db75b2e131848e7aec156d31aed0766d31c379fece4095d38264c6d5945974d25f729c3b0ba11ea853e9cebdb6f03bb670fce08adff74d0a8f02d633fb34e0fb7337a8e66e1c12084d914fb6173b8105684db822752c6751a372bb16690284d661b8b8bc6a6dfbddf45ebc2219596f9f2f878c118df69030de38b4d99dde43b9b9e20a3dab691645dd518342f49b06a0fe0a397adf261e99f07af5b0b3798b1022ba0939c42a54d3b93641cffa3c2e174bce9ab7ad7e7c7924308d1a77a
+AD: 5d5590db1bd316eb7a0e30e4c7a6dfdbef9d3287fdb8d824389599c3c2ee262b2192eb5b9708e66e22dbc7eca83fa1a995da3ce64c86fe5aa08b826d476dc439497e2d12e2702c63c8d27aa7f09fedee816dc8bffe1351d53271a34d4292b613b7efcedb7e3cf3e6ad389eef12471e9e20e38e7ae22a323abbadfe8f2e84271bffb1819feb4f77b82843cb8757cfae293631bc6d39669107e7015c85d7343ffa6fc1bbe6f5ab4de30cd752a281e03061ea89de2a3f5e90e20da22fd6e8525c100738667f42212b2cf45fcb23bbb54b21c117484b22c6e514685314df
+CT: 66b7f69ac49fab4e5975aeb6fa9287d8eac02ac312c4de78f77f59da16cbcf87274e66801c4b862c33ea79cdc76528862bb2956c06db8b8acfac4794ebf39e35ac03cc73a4351a4ff762f681a48d6f25cad36e2814c9b5c40b9ae92509e58429106847789454d376836936bebc7a80e6c66e7aa52936d6b361378a41f849ad4e48f9ee2d3e92217a908fa8eb35736ac8ada7d32ae05391f2d807be3512543c36138a5fe660dd4cd4cd184bb43b6ba6bc0bae634e2fa9669304cd510ed5103f630068ff76d3375738de60a381842b421477e25a490cdd6894b2704125
+TAG: c9998a677dfb0e91924aec9de0afd585
+
+KEY: 2cb374cb048c168f2e43597f028d9e73cade1b458284ffc260d4fc6b9011c414
+NONCE: 9fb909169bc9f4e9
+IN: 39eb929482784b463546f5d84f80510f2019923d465b99d194246d68c7ae343f91971d8f7059cebb86aa5dd099289aa648248b8c5ca04e66ac5e9bf06776e3883495397618a0227f035666806e636836b47d3d2d255a49db79866cf00d9ddabda259c4f968a1e01e651c7811cebbee2ee71803ea1d9d23487eb221f2d9555756800aba5e6abbefd6fb72b3151cc99ced599cd86df2a9b1ce94f89f347eeb124d9e7f0d9cc48d3dedd819e6d3dbac57ecee199547b266116a2035c9acc4c8ca3271ac74952372897c4a5f2cb84e2d81817fec9d6774f6d8a5b2021684132db4fca3
+AD: 0c7bd4f3a30ee944ccf9489181e6911684dcffad4593a9b65a67dfc80718c69b35897d01281016b7731e12c15cad8482e79458e08a755622e3f3f22a23ef6c8487a36ad1771ba06c641f06f85de0db3776cc6df06ad8fe3b4d60d58508de943083f17cbb9dc0d390ac94d8429e8c6fcfe063f424fbde0f62f6a7f91a626d195dc498a6e69bd93109c4e9ba13e7330aba456d710a4b0cc279d4045660406e26d61dff70d4a33c4f1052869f9248024e7a0f85f1effb32f6f7ccb1f860f3ef04e8f7b29096e6bcf9d4b3e0ce703e9bf228fdf515c2ff9cbabd16987be0f9babd3d8a
+CT: 91ddadb86b7ebef798ddaa59da51d71316fcf6c9678143178227d778750dc9827fc6cc21e605c505023e6db25849df7fb6fc1ca4d223aa215f8c85b724643c83bf8218815a9f9e2952384e0ca6a80a3760b39daf91a3c6154c4728c2371fd181fa3764753d0b0c23808a82cd8f0497246e3a0f17f8906a07c725d2891ce968a9d432c2b102d85c05510b28e715bb60d0403a77490e7f18be81218bc4f39287b9bb09f50227dd2f55e4fb70c4438da8ba3c8ffbced87d90155913faa9979fc57e6cbeddfaba3d3ab4163c0eebc7d94279c27d3ed56338893dba542eaefba30f8c3b
+TAG: 728e60f8124effbac234f70da925881c
+
+KEY: f0f16b6f12b3840bbd1c4a6a0811eef237f1521b45de9986daec9f28fca6485c
+NONCE: 7ac93e754e290323
+IN: 0530556424d823f90a7f1c524c4baa706aad2807e289e9479301e3e7a71f2a5e14e6232ea785f339c669af2e6d25f1d5a261096a548d23864945c3a589b67b09b0304a784d61b42b2419139485242e0d51fcbe9e8fed996d214de8717e6a71f8987ccad65eb92e66707034a5ae38e6486e26eb4374c565aad5df949dab209f7f7bcd8eb6fc52761a26cfe5d01fd349e59f4042e6dbe6b232f9301b971dee121d8aa1e62d40f043a42f3aa859d867eb809b1ced5ae1ec62cacf94a69fafd0631a8b5dfd66d855900fb295eec90ae5fcbf77beae267a79d24081bb322d8c4e0630fed252541b36
+AD: 13bfcc17b810099cda31ca53a1323db9b07633ceb2088a42263a4cbd6a4d47978776005c9a20203319c3a3ae434e9a26fb541047dc9df38dc36c095267272e203d0b24d119a70a7e96041b6d82b7c4d5570e1e4a1cf2f6e44ae63fe005a1f5b900778c482f7bd89e2e02305e35b8f61b7bb2c78a13aebfce0145d1c5aa0bf1d10d23616d5a3a446de550302f56f81dc56fe4f3700f14242688d9b92d8a427979b403c8de8c493a2cde510eaf6b285e6675b173aa0314a386b635c7577d5aff0d868a0cb3f73c8d2005f8c7c9dab5a060ef80102c9d4a4af988838afe87aff04c0689e8c3c7f9
+CT: 2c14c3931e98e84507c4c165c2ed47ad4a178f0e216cd7ac2453bbbf9f85dd06bd8ef54a9ff1fd3dd8e0cafb635d8f2de861a0db5b14d03f17aaea8c89b3010797c71c13a0e666899d7ff6e53c4f08be8ddb3e37688b5afa088079b6c7519b833e16560073e699530302028a3496e05edddec01a23a4c7983956250e8d9e616f7b940856955cde81c1efabf6b7b92f153d03f4cd17e7f7d2907670cfc84d45c1d7936775a3fce47968504278ffaecacea0871b227f250e2979516f6fa310fec0d8df1af7872e5a534e82870aa05f43ef0a455846b93ce938064fa33e92de262e4156dae56775
+TAG: d95d73bf9aeb71eba9042396f3725424
+
+KEY: 3792943c0396f1840496917ce8ad89608385007e796febeea3805f3f4cbeccf7
+NONCE: 23b2f9068b2c4c85
+IN: be6b67eb943ee7b5c785cd882f653e73a8f75b4a41a2a7c56ae5a10f729caf39948fe48ad0e51240e2e7aa43193c7ec6ce7f4909fc94c9f99e38e6a0ad7e98eb29c5c2e61c99e9cbe890f154185cec213a74725d23c1a4e4d0cb9b1a36b78c87e5eee20d2aa29aae80d4759eb0c51c5dc3a95bdbbf7e14eb434419a6c88a954ac03d0c98739f4211b8732acd71c297f578b8cb64ccac45f7235ddc7f2a3f5f997525c1ed39dc550126cdf9cedaf55425489085e91b170be6205a5a395f2dd4084a3e8dbc4fd8b13252f7effae067b571cb94a1e54aba45b1b9841308db0cc75b03cfce4ddafe89ce20f2d1
+AD: 7eb6d7b7bbaaa3c202a4f0f1de2263767169eb4a64853240d48c0f8d5d31b08d5baf42977614a57aad99426cde76d242cb37d2956d8c77dc4fd62a3abf30e8ac6cd58c8ef35e67497022960138c57787818892460f3bfc16e37ff388b1edc6ce2bc53c22717edc7a03d4c78b0dbbe9121c7fd8a3e3993b87a4fe389bff13bdae3b349de0b6db561602c53f746022aeb4483c723b67825042f4af20b7dd1e6031cf54215266295c524ac8e1370424c5c5e607fb3e23e97c8eebe64656775edf616422a8b974e1acf13ab45c9a367a7dd9b2d62f48bbc05819b65eccb813ca813f57b22ee4c280dbb5a9d8d5
+CT: 0b316ab2bcf5359900fa4082d5d253b49ad94b70e3fab544f98bd111cbcef6766cf953deec08cae1f489fe12f7acc0032db8a6b0c0eee0c206ea5fb973feaebf90f690e840094db5e13fdd7157ba127368c995b426529435a1bcdd1f14ce9125b8a0e4c96b6ec09e3c36a180adf81941c002d19c19d53c2009be803b987504606b7d43bdee5e0b32ff23c466b6cccfcd0d4e88fd1332e73712b5ab725c1a383e584f34f80daff29d285ae5e43cf1d0cc7a828e75c25daced3a581a93d7a50f313b33f38dddfaa23cd5b9914797db820ee2400d52bf5fa982277fe9b5881ac42981633b3957b0e935051828
+TAG: 01973ee2e81cef22751a6a8831d752ef
+
+KEY: fe4be6054773f634356ac328591fbc6f833b0d1beeb38dd5b6feb7481b4489d4
+NONCE: 0b3f16f898a5a7d5
+IN: 76ced1ade6d1ef4069afddb32e7432d4ff2fd06685121f7b16464e7a72d365744f547d2ccf53486310e38b42d8bacaf711e54c5458d2d68c4dbcc8de31ab6732f4430e88a64565f5b287640775aaa2af1cc461d3e415bb275c6246b1b58517aa72667eae291a2982eda175d1b22c5a58e6fec2b3743d55712f201ca24ba5c0ae8c25724871b2ec2fb914a8da5a52670ab9b43a83b8568ce74db5c634061cb80530c8070c38b8f48c33ba136cb9f2158ee7eda8b65f2192fc94d1291f182f101795b7190c74b319d2d3e02a97c824d9c9471a83797e4936310b207e3a1e0bcf75f7c3e3ee48a747641cdc4377f2d55082
+AD: 834cd775cbefe4b33a3ca53a00c06a3c4a666983e4115a029f15729460daa45d1505e95172d3695625a186b28b8be173a925af04665f209267b3c5123e8be13da447ee1ae856bb0925f35aaa76e04a7bca8460f76c2024de2149f38a8cfba81694b854885d72568105571b6b213a0bc188a44cc7fe13153cbf261401b238cf12a95e23cb56f240114f16e2f1e3a514615aab4449c0c49e4d900b0e17d1a8dabb53d43dca32fa052d576b73dd9b40856b515d6d7efc2a5c17e0ebcb17bd59dc86f22ce909301a2652f134e82ef0e4519487ed12d51536024f2ae8f75d937c42d003076e5dea8de0c684cda1f34253d8fc
+CT: f8defb6fe95dfec499b909996a1f75a198a90e4d6c6464d00a357a555311c42fe92dbbc4b79c935e4f0b1a95e44fdbc1380bebabca28db4dd0d2870daaafc38ef27908c3509e945714801cc51f1a07b2430c74fa64f2a7c2f7fd1551d258c9c3be020873fc1bf19f33ab6c660911dcf2317195d0efee82d20ec26d22611f9cf86c51a64e28b3a1f344500018e0855c88dae3c07acaeaa10b60388484dce93e16e6e1a6e69e899806648a92568c8780e9f4baacd98cbb353ac2f908e775d92303cfab843f15be0e0c322a958802fb1a60fcc7631f151f4c2b8cb965d2d296acef250275a2fecc0cea803ce7c058b12dd2
+TAG: ade515091930dd7861b27f78a87ef60c
+
+KEY: a288b11ce5382ec724ce4ab2d7efa8e777e91ebd04367935e15f9dac483e9596
+NONCE: 874144dbf648b325
+IN: 4c9195280a79a509919af4947e9e07231695fd7c5088539f23936ce88770ce07d9ad3ae4a463b3a57d0634d3a77ceaadf347a334682b04be8e58b8e86fb94a1f93255132b8cdb0df86f5bea354eea4e8315fea83e3fdf6e58aa9f26e93caa08e5e2551a94bd916a51fed29ec16f66800cda6a0aa24ec308bf5fb885afba272685de27c1edcdd3668048ef07b06e90d464a8aa28664903cac45e154e8e1e39c257e1ff506b9d95cef4f300bb73b899e7828602c3c1d290b8cf55ee5fd72ecce9e6efc9293aebf674a70e2a7673e75629c12950622dff71d3ec0992e57776c788c6927d30b4e24b749191c3ce8017f0ada6276e43720
+AD: 04abe8588c8c8c39a182092e5e7840442bd1c1149da102c4ee412bd8b82baa5087ef7291b5cd077c177c42770b0023e0e462b06e7553f191bcb0315a34918dcdbffe2b99c3e011b4220cc1775debcc0db55fa60df9b52234f3d3fa9606508badc26f30b47cdb4f1c0f4708d417b6853e66c2f1f67f6200daf760ceb64ffc43db27f057ad3ee973e31d7e5d5deb050315c1c687980c0c148ee1a492d47acfcd6132334176c11258c89b19ba02e6acc55d852f87b6a2169ed34a6147caa60906ac8c0813c0f05522af7b7f0faddb4bc297405e28ecf5a0f6aac6258422d29cfe250d61402840f3c27d0ce39b3e2d5f1e520541d2965e
+CT: 0afce770a12f15d67ac104ba0640aab95922390607473cbda71321156a5559906be933fb0980da56f27e89796eaa1054f5aacf1668d9f273cc69071b9e8e22af6a205a6a88f7ad918e22f616bddbb07c78913c7e056e769e6fcf91c7600c2740212e3a176e4110cac9e361a59a773457064d2dc652dd115d04f1c3756c0e1d39f6737a16b4508663e310934c49c58058b3c7b9af7bb2334c8a163608c42499658986927cda365e2aead3ac29de16e47e954383ea566f8fb245a4e5a934c767bb3bf7e0eb8a477fd0e1f61bcb238462a0d19c5cea9293ca58ade76829413216a7882cd2846323046694f78cd8b0347792ebb75abdc1
+TAG: 973e58b1b8adb176a6f1e5c963bfdc5c
+
+KEY: 65b63ed53750c88c508c44881ae59e6fff69c66288f3c14cfec503391262cafc
+NONCE: 7f5e560a1de434ba
+IN: 845ef27b6615fb699d37971db6b597930a7ef1e6f90054791eb04ddfe7252b5f88fd60eba5af469bc09661c0987a496fa540621afeec51bebda786826800943d977039dee76235248112ff8b743f25ed5f3cb0d3307f5e118d84fdbb9c3f5531bc177fb84549c994ea4496c65e5249da987dd755d46dc1788f582410266a10f291c1474f732183a2a39afe603771bb9c423fe3e8906f2be44a0c9a7c3f0ceb09d1d0f92d942383a875c0567c7869f045e56dd1a4d6e90c58d44fe0c5760bb4fd01de55439db52b56831e5a26a47de14249453a4f8e7da3cb3282c6622916197ebfaad85dd65c61e7d2d3ba626276366746f396394c1bf75f51ce
+AD: 51a3588398808e1d6a98505c6e5601ae2a2766f1f28f8f69d1ccbcad18038c157b41525be58ae4527a073748b7a04809e52a5df0c7988417607738e63d7ead47db795a346b04e740186e73ccad79f725b58ee22dc6e30d1f0a218eda1791e2229b253d4ab2b963a43e12318c8b0785c20fca3abcf220c08745d9f9602f0ece544a05736d76b12d249699c9e3e99f3f13cf4e5dc13a04125c949a5b30d034b23cb364c8781964bc6c30e5e5ca9673d517ef5f35965d8a8cf1be017e343df97b6bee37b30638b154286d1f36d2f9a0eaa23cc484eac5a05b15d9efc537d989dbc8b3106c0dc1a56e97e6aec2eff54a82cf7ae9df2af46b4c860f83
+CT: 027b14197b4012256b133b78ddc94e72fb4d724fefa4ae329f5a5fa3fa784fe6d7e1e805e3f7a75557de64de506d38237b467fa577efb59e7cfe2356bed6655c5aa4e238dcfeb75c16549a0917268768a96acb5e20546a1fb7e3a7cff887f49f2cd7a135f72a98a779150f3207bf733e88861fd79eadbf77fa3bfe97bfe8b6a991cb3bcc2cde8287f7e89384846561934b0f3e05e0646e0e1907770df67a7594161a4d0763faa6fa844080932159999d528ee0558710058ce16f97d13ac9fd9bf5044191188bbfb598d0fafbdf790b61ce0781ecc04218a30ded45efd498cc9ba03562ed2b4a993ee98876b3ab7a9bc07829f1c4ca6ead98c06b
+TAG: e4d18a701b8308697b5e79141ed783c1
+
+KEY: 4986fd62d6cb86b2eaf219174bec681bebcdef86c8be291f27d3e5dc69e2feba
+NONCE: d08d486620ed2e84
+IN: 3a22ad5de387db4fdd5d62a1b728c23a8dddc50b1e89f54f6198b90499f9da3122ebeb38ebf5fdfe30309734f79aff01e3de1e196b35bffa33bae451f31f74b8aec03763f9e0861a34fe5db0b40c76e57c7fc582bfa19c94ee25b5e168270f379bf9f8a0a18bed05de256f8f0dd7c23ba2ff1c7f721409462f04cc611ad9bd4c3c9acf30742acfb9518a6375cbb15d65a1bc6993ea434894f93d4f6e05996ebc1bd56579296309a2c6b8fde95072168b5fd31927c4c0abaa056bcd16221d5f220be47591f43255013a262dce439817f534830ba82155347e5fe3101f8011b89365a6568214ed0661914e8cb3431d6c8f2347dfc1209a3eca4aaf0a111f47fe
+AD: 7dd3f656a03c001b45ca0680bc3ac9d68c6e96b591d3c69eb8c65e489009d845cb331c98b82e627e06d5bf01e74c573df268c2386f12628c019951d42f55991ff20d72a7b2c45f41d0be7af428c92f324aaab8df70d900301cdf09a3d93eb711c919d34a86fff9cb078322ee2e0ad48dbdf3b7884f0f2dc5c36262c59bcfd75ac6200f59c6fcd0ce10ff5005fef5df8f0432377dfbfc1db8f559e27e1aeef3380ea3864867d36a25a18654779a751586cad3b8a46b90864ee697b08605673b8d2123433c020a21c4db243dde2420c12fd4d54a2704a0c8c376454a1b5e80fd6db89aabd56d9b421f29649e474824dfa56cb5c673c504d10be52b53751709fe
+CT: c40180afd53001663ff4834110f56e6b0f178cd3c0e7f7de5d0089ee41d8403ffb98e84922706544a344d7e2625b12cf66b9c966f9f57d7b94e3e4b34e6f0aaed1763ce012782e2f5e1682e6c343fc7961fedddd0919d0b910e9923c17e36406979b256b85aec24ee352f03b48c1302eab419c83dccc5372cc059e9de596224fa70098eb32fc9579e97917b923914fa2efc30ab29b457bf14e45583b3771486bdc0876f3ea6e1a646746c4f8c5cb2641a1557c8473e6ea67d4811a67485ae9a678ff3a2408ca845c3b51957e189eef47dfc1d46bde4b9d754d7df13f828ddadb06e4ebddb5f0dafbdb28de4c5e6078926f20cdf9e97ecd58e309e640f74f06
+TAG: fd5e29332832a14a31a9ce2ca8568498
+
+KEY: 7d28a60810e43d3dfa32e97c07957ec069fc80cc6a50061830aa29b3aa777dfc
+NONCE: 47738ac8f10f2c3a
+IN: b50278ae0f0fa2f918bb9a5ed3a0797c328e452974d33cbf26a1e213aa20c03d0d89490869754abf84dbbe231d7bccdced77d53fd4527356d8e02b681fc89a535ae87308bf7fbc26197a5ea85bdb3aa033b8da5cd197ea6d72f96f63b03f4ecc7adedf399a5043776cdb32c08f30b77f34df85f8adb8e02649a04b020b03e17d445ca63e4ed73ae432c481392e031eba2f9d2f7f981d1e50917822bd6ff71c239d33444ada3523a59dfbce5457eadec1ab926c9e6c5299c7521e3f204b96901a712504fcc782e8cea80ba12a7f7e71cec3d0871899b6ca059061da037715f7d13fed01c9cade1e687b4fbb1f4ac4b040db3b43800f112fb900e4f772d61b921cbce4da6f
+AD: 324292813b7df15bc070cc5d8a4bf74ead036430be63abc43304cf653959a24a91c7de5a671c50fa8a87e21bb82b069999aadfb6895d8bda4c3083d17b8ca55b9ab1511ed8c4b39d8c28c11a22ef90c08a983e3fe2d988df9e02b16a20b24f39ddb28429625f511db08298c4dc321f6c268fc836a6191df6232f51c463a397a8d8b33374abe94e62c0f5c322387e1fc4a1c1980a04a1a3c2c31b32f183a11c3268c6dca521149dc16af120a78be6627210e8ddbc44472bc24d66ce3681c7579b3d9a425212a704a4f5105cb80f0d18ee860953d10b59c114826779bbc368d7a0eece9f223e47cd8e5fd453607d101d9d9c2bd9a658d6520b87d7b4263f6d845a524a36e4
+CT: 2c217e969c04740a1acfa30117eb5b32dc573df3354f4cc3bf8f696ff905f1e640f3b2c250473b376622e0c9bda13b94640521be1ef0fc660b4c10dbe2bfc093030753e04f6aaecf813b43b61f960455974b8bb8a9b461d1e8fd3802315e863c00448f24dd38deb90e135493274eb14ccbde15c50dcad734ed815a806be6622492a84cd062e3ba567b909a205a1d0d2bedd40169697d261c7b6c2e0b1f069853fd470e8f364a142c386c439a6dbe192ded5a3d0fbf73799f588c59e58c60249d980ddcf0d9693631cd9b3f972509c3a77123d38d9e267ecad06e1208e3f1c0a69fbca7c3bb1a48fda19493d0f8f48398820057b94120f3ef97d87e9e8a1b301a2534c68f
+TAG: 1fdd2dcd935f55822bf7231a516ca841
+
+KEY: a76e9b916f5a67b78a5949651c8c3a9741a1bc3c41cdf85fd2c8f3e9a0616098
+NONCE: 0808da8292dc14e0
+IN: 9c149eeb09345c3c22462b03e49eb4dba6bc98b269b1086d752bcd8eea53b8977b238a04a994baf915591686baab90b79a3bf7d9adb2c6c2e31acd3e72f0813fb745aa5fb2e3da408f78001c9c09bd26a1a2646011b6120aaa2bbacc4a16c39fb5257b9b2ea2ad8bf70bcc9855cf11841116c2767310cf3cd49d1aa44cd505f079761e064d5bc7cea4a7173b086882a77d3fc179efc86fc4db8a373491d2ed81eabc63c950e832db17d09f474d4ec46bde47830caf26fabaa0372b81fccc449c0e19ccd630caf693a7b43bb1c408a54e03f50c44280a05ad89fb6e8f01d8ac278edf556e5d86ceb4b614fb2ef133819c6e1ff6abb86c54a135256204b5cd400b93624d3932e7c2b046
+AD: 6aeb7031e4a2e23eea93f05fdc562aa2bf43b8998bea7344377aaddc60fbdb7bcb1491d379ed0cb613ee757cfb66490db61bb431d2fad34b38ddd55bc5b22aa6c4773b9992f34b878c5663f6e8cdb5f80a17f4d312bf342492e48d1ce4c6d754076a634fece61500acf8168d47381af4faf980c6cac2bfd5da8c09b6edb0f543bf0fe02643e38d73fa37d8ae87fb66193f22e57faf4393c007d48c8631a685d520578f8f89db684fb371ea02f3a58b1e2168f0216321139472e0d03b6d90ba8aab65402e1c1ac4f9172a60e27e3d997b9b05e2f672120d6c87bcafa6d4c9b4cf8ba8a82932d92840368fc53dc5b48526103dcab5f1531038aabe89171327ac559b98a3cf4ea70bf051
+CT: 9c3faab9261a63cea9477b3269007283995b06ba77ef83d9e693f7e4ee9855550eef94855be39a7a435b6a3584b202973777c7b2482376ba47b49311947a64983b60236756ee4455d4cfada8c36af8eb06b06ba2f6b79ffb1185c89f2b2a831cfaa3855fc1841d8910908be5078352011168a67d36372d851a3217cabf593ea462dcd325cf9a4f67e85418fd5c924e9b92ab026cbee4e7ab1067066cb5949dfc699a68fe539e1abb13cec33904e5207e6963d24f5a0b770613b8b00014e791bfff88f9c25ca126127a2f8d1d1e9794efd28dce98b53e228073faae8d5047530d502184fc341321c3f55fcbf41187fc31262c325b97f519959b6a29b36c71f76f60196bb1457b77c8bb
+TAG: b45df119043d29008fcef36a169ef886
+
+KEY: 98cd2477a7a072c69f375b88d09ed9d7b9c3df3f87e36ce621726f76e3b41a1d
+NONCE: 77d185aaf715aa48
+IN: 42b31eefdacab0f03ef6060156000c8195adb0976cabbe1a42bfcc09f85659c60b98638401f2d2e2facfb9a97a62926bb0cecaf3af0180a01bfb6e576babf7fc43331937a92abd30cddfa3e450f895e9dd914dea3fafd759c136d685310ebce28ac0613ccdbf30115946c9634b67510b77d0e37f07714b2ddac9d7095b8d4bd887c132c4a9127eb01c8dedb4c39c87b98a741316656f9a8d5a5b0c0ac84789aa2347a5f99ca5ad55cd1bcf98f703eb4b00badb8a8555f38b3b368db8ba7ceea94e8b219f51edce75d84166b5602156ed5962a93a51db73c59d87e906179d7a74a2a2a69d8ad99f323225c87e475d3f771b4a203a2e2b03b458401044649fa6536dfab24d7037807dcbf6518e6578
+AD: f5bb1496052a4361dddf72a288e36953a3d815d6876c013f1d6ba839e127f721b052b1f7d8ca20c7dc0386a7d459ebd7eb9fc8cb08941e6ca9ddb980f3115f65bc1928a414d441ae71dcb879d5bfe0cde0562bc37f8fde0d5291ad405c92fcbb860c43b55ac0fe663b54b3d0616aca13a5c82b7b5d34125a05c2acb5530141030e6f2aa0c8322b2c8fa307e7518918e550e9f48921c6168f094d8758e16b9f815fd0458095c4143f0922adb1840d0e685636825a9c90ee90ee537f4b8dceecbc4287c82dc9a00d7e51671e37ea284ee3ca501b1b2596459d3f592f70186f41125739e342c9f6be9241973b1414dfe5fb8cba1af82e679278cfcf95420df0c5364af4d7e72ad57d5c871fcbc35462
+CT: 7a3bf3e3ad5ae3ab71fb1f7121c3d8fb511099484b50af7ca128ee0337ed4b828dc4cde0b88dc1e8089101fa82c9beb3eb48fdcf0f5b16da441f5a3fce9a590022af95a94aed6a3e71e505f60f303c78c356f274ea85a55354078530664ecda32c80e77dc20974b3b38f4825b8fbee8c3970769a2f42c5181608a8d7d76ef4d093961b665ee42b9708fcafe2c82d3a307173e2a25ad2528c3bf83352b9265e45b70722d7cf8c9b80826d21335234ee3db69d0d37871c83222365900c96c17a7e9f5742d0bfe383be24d0d44590d4b0f29f7abe0c65daaffb968b3f2657b1eb300534eacb52ec7a6b6f9f57a50a91b1799f491361cf613c934b7f520dc4eeeb40ffc45e10be0a95e76f366d4eac14
+TAG: f613b65226afb64c614fe60d9c71ed74
+
+KEY: 2f0f4631ab1c1bcf8f3ad0559c818d50e0af7d8cd63faa357f2069f30881d9cb
+NONCE: 7d0ced2fdb1c9173
+IN: 6516ba1d29357144eebfa486d21decf223da3aa76ec29bbfcbe7f1eeaf4a847710e5080177f7e5a7c8b4752c219b1cc70aef4db861ba67d0fa6222d9f4a1dc756a0ba44e62906f9374a960c16198866d867854d88f528a60e212eb91645787e75685b2e215c0a41990abc344a77236ec0186ba63a664592938cc5a8ac1d3eb99c95ce00e19fbe249263083d85b052d48bfdffc01585dc57bb2a2c6c4a819604c1ec0548c6f0f78dc05e4418b36277dc07233c7532f9c289d6aed0cc6bc7df4fd0a536c497b982e2dad2c30d2db1c6545a845c5dfa83a4ac49ef06fc9c919079d3e299e31b5c3be370814ae5022ae469d3ee55246a41bd0dc4e64351cc38c3c09af0a1aee3b388a6892deff0df3f93cd92d722b
+AD: 1ccfa1ececc8de1e200d0ecc19dcf67b7c96bea3a282c2bccba61035db5c14776387b8b8f58e5757deb0129d4e5e315f64df354a5985d2e47ebbbeafe0c914f7cf1d63dd0311ace19e69a8b6ff0ab25cc8df0408d22132205e89e5eb679268d82b2913e64e3f885bbf4a6d379b760b94590e3140dd7275ab4713cb56d0b716e2718f11316640cb394802862d39e77a46d0c065af3caf7dec14e887039d8aa8c3d3a8ac1ee06026f49d00b2f59d971b54735e95a51f199389a93a4fc24ebaba1f7a2eef7412f61febf79084fbf481afc6fb6b204084e5ef5df71f30506459dea074f11fc055cd2a8c0fc922c4811a849984352a56a15659b7d07a4cc90b88623638ea00c4c8bc13884df2237b359f2877aa41d6
+CT: e580093789ba17ffb46672dc326f09278aca08598d3e5458eaa53e6ed45d5c71a396e35b5ea3fe7b7c0496a734d24f1c75420694be2ff095d5172fd3407794e4b99fd7c374fbe8d1564a048614d3f355bfb5866de1a53e1a51f9f5e8312253cfd82f36efaa1898c850ca0d975ad1e8b0d9597a5a9e6516fe2a3c92efb7495557a8afc3da15b0d3e2ba58f612519836946cf2d15b898320d16a026c8c00a1be2e35f0ebe68f28d91c6c45d24c3f3c157cb132fa659b7794df883d90741fa2d2afcc4f27858e13ecd41b154a35d24947ae7361170060c107d8ecacb393ea67104b60457278a392fdf1794bab97d3b02b71a4eb015eaa38a4b4c944c2bc7cd5e329da4a1ab2937a6af81a6caa5fce752331fdefd4
+TAG: 0fd7419c54bc84265ed310a3411a3f2e
+
+KEY: a48b9b6df475e566aba7671fbd76772cb0eff0b12499967978ce3e25fac92feb
+NONCE: 2ccbf0d6c40cb302
+IN: 09da1cacd001dce4f7573a065a4406fe0da04ab367a2d87780a2762e168957a88d3fa78f0a4b6978d449026e5a801d32884b6e14fdaaaf864214f928ebc03dead081fee96683ebb032362d5088c4c2a3b1e242f055f2604919f4dd551db777a258cf9da6d95a2bde249247812b9efc7985cf08707620808524d6dd3079b0b63bf0f71ea5de834ccb8b7c6a97125fd6ca49148e866d3134bbf1d8a6b714e9a80fe549c8bfefe342f41be2ba2300e0028f78cefab65274632dfdbe70bf7d655ec4036df561f2d4fc4d56a482bbe2f9f2ae279b3aa216b39afee75e53602de319484db89a51e844f38c361634e474f8f1f01c340f3f3594860d671346449c6d08ee38de22d246309bc7e4a252a29c86aa6d94b5b4fa58904c70
+AD: 1c2503d5aa1aad193f0da12874074ea0432bb76a61cd43a3017061514da0759846a0f3ae3a49fdb0b6d29f713de665beacb6568f2694112ca380d13f3c1698316866a7a7f87f1d7503a92176ab84fc08977b46ba664508a858e7525753c45511b3d2f407d5e993c6ede77f13d12975707e5195704970a89f71fc30828049f92f944f3aa93d6a5297e678e08952919beb7eac5919df1919cab3c3da6aa696a1eeab6371f310f7e81143e7d240b0213ae554524b52000306160dd4877bf13ba0f13bbe867da7c7d707f31335eef4cd942938ac890a0829ec66bd30ae01a2188a6e5ea0f17cd7dc875e17f03c0ab5dd18e36db8a1fc1f72859ee046b62368f168b3bea2234e0432c07b7d8e1b9277f21e692c513b9e816e6860
+CT: 7d35cfe4be56bd6e0e09dedcd01735b915bc1891a4d1f6a541abc4bcd0ebe89dcb8e365e5813742e8ec65777b6159422fada747da99394252baf8a046fc1b60ad79755f545f4448627b7acaf403000894f5641e78d3f946dfca29ec617f0660dcd6e8d8827e67e1022a245c595d86e60fbd176bf721b171bbe5ecaf4ae671b9f3dd3920146e6ad431bd8fc431820e19454b6ca209723d80fdbee187fca9c937c979206ae97be55f6ba7366a5608770a11d537396485eb0a66586385f4d4cf3905d1fc90831c3e136d5d513fa22be285193142994a3ed477145bacdcbdd791e8b3b88b0d4f1d18b27382550a818c4fd8884bf36f677c6c3ff5677406e510911e696af75e5b3f859bef699bdd16e6215fdb98d874025eada50
+TAG: 2aabff35611b3e0013f6ae0df130799b
+
+KEY: 923d4b086b9e43b986f7b65e4cea6113a3d8aabefa89323c5e4d5b6f158bb7e0
+NONCE: a0f73297b87f5deb
+IN: 21435e8d5c8edf0684f58c2cba4070c10b4801adf46b6c4d322eb3990a38a9ad338ad704b9df6597f3e68d66cd5b56290c8466db2231e56d6bcb9c44e1bd081f42ca2a894dad369df2bd0d2c63d6c881732d6ea22bb22b5bc9a62eaffa1b094d0845f6b966d2cb095e7b3b8bcbc15e707449d35c8df4aea30c3b7243e977fffd59c80f1c5c9af4bb5a54b9c786fbbe8d21b2b906a87a786caed841a34a3e0cc0ac3209d83c58afba19edd63622dd261532d2cfb0b49d527d8eaa0887a087f5129d897f665264b229f860363d71a88b7d49c8dc6360182b357b0662391bb41337f46010ac32b9fada2d60a2efcb99365d3b27b7ac396900d1c821d0df8b86cc9cc1f2673259a33efea610bf8e1d00d7e9db2afea21da8f58c55f799999d
+AD: c853a8b39c0dc597d562f123cd221e4104b65423a062a4f4ba890ba344feb84290f61817e23330c365f58c3583ce08360d3c1171982ead5496d525ac878f23a57480a6ee39d4e65afd6268245bb982a2545fa1195427cdbbcd404cdad5198f55cce2a5a028fae435f71b15921d066e8d43766c32b2f2c3f57c0674e129607dcd3703eca529414adaee79d81fed432153cceb6f3fc53404810d8ec878f7d94be5d379d0e0e1aa9bc404b4b5d396038a9d76a5ce53c9f3759b8e50fb331858ca58cee81bfc3ee58baef5d19c402a3dc8b36370ec1ace5a4aa2527fb94b4f933a4ab8ccaaf6a5af5a779eae5667c2a24ab027e781c8d4f30c377aa5885a2fdaf6507d18cd824a847c35368b4ea984d2c3c3824a5b8ba3042e1852504a21a3
+CT: f2e21052eebbb86a4f5e803360855d8632aa727dca6f5e79dd74d7aff106e442001928d113005b030f8446f8eff2ee951db663978abe43090dd5ad2c51ba97a0ecf988c607d95e486d02524f690fa3c28d5c48c1f75c1f555e7b43fe7e46f2ca2b9fdb408ec4ba18b6cdde2af673183cb7b1a3c23ae77eddd4cac75e1ea14743fc571f8d31ce2e96787524cd48aadaa474181c096a032184574ddc25a6e0ac8441c212bc36298708e33c963ae931e6c6241d1affeef7b6ef759495df44b6ab647447693cf703569e69aa72f1def9a342b8978c1edea9703a421ca75b92cac4de14b88c693200022b8a2ed22b1c4678b99f4d695e080dd1196d7168e14f0d0f8ff880d742e97b9f6d00af1f7118e10b77c5ef3ea6c52f84a20fd6ea46dc
+TAG: fa8ee13400fb3f63b899df582f2fec45
+
+KEY: df73adab2768559ea983cce85453fe81d79be3b3c57f202b31b94d6635cf2e4b
+NONCE: e7a87e6bf6b5a354
+IN: 0032a37abf661faa18c587fd2aa88885c061deeba81105dd221969bed5d59c7204b09b1a8c4c8de3b9f748c7fc70626ebeaca060233a57b102221b1bf0f3d9fdaaad3d2b1439c24d08f9c67f49f3c47128f92ee530abf4c4f4573bc60ae4b38109f55bca3ca9e1ba9f9fd6e34ba0d174892977a53356e1f5c88c614fe3ff3b3dd0818e7a2285412e3b37444bbe8a80942efcfd03958809a6966cda9430b2f0c9e552f4bced6e19eb3e85fc5758bd7b588297ccbed37ed94c3adc8c08ea8b058462aac9d57a939ec711bc4ecfec944d2b653b7cfc7b02a65d7057c9fdadd51b9da8cc4a3c68dae9da8b9c5319c1a2baa3d6c891c5ac4a39461484b5a01abc64df447ada24c04a4363e605eaccf339a9aa515e724206206da6d22bbd2f52e64cd7c895
+AD: f833e5ab4f8bc89167f80f576b1d6b22cdd0e30721f5f735799746cf645b6eff531d4c7b03584f3dfcb73cbd35ac42736216dc7f0de098a4f42c61ceb4b227ee288e47d697a0a76afc762f084e8fdbf9351c28340c324771c109a469341ab10ca10483ed2af5e878d7d3dc2bced2f72da3d1a25852b103ee9878e8158eb4309c1ce528f3a178ace153b6d3ae0af0d577cb3cb1540489e80427f792217ad8a09b84f027fca7ceb651b4264e98e94b4cb8a37b133390897233e8ba9103628d05b9609e8552c4a4b11e3f2fa8d56af36957390e88cba44656be3edace798cf8cdf7771bac338a256bc3cba6df97728f222f423ca7c6d149c9372d66163a98f79a234b00d4b75fb2ec860dcc2d1998105e4b9c01d68f079f3e0aa21cc534047fc7b858f8
+CT: b842eadfdf431c135bd6581d3eccae54e2267d8890036aa33dfe2d2d9715c44625441210a3a0d666d708d30588fe851ec36e10d8fa3584ed77b095149494b7c54379d62c8935e1d2b9a8f47e4759ad0b3437fdf2cc2fb6c5ea25ad10e0bdc9dc5b0517fc237eb783cc461c46665e2b1d1a5b8008dbf409ea2a63fea0276de23a32c99d92a498807a0f95e208fc6262321a78aafaf0cc3f833fff37bd4efa66f6023a25cdc6702cee3912799563d908a5183c9956a06aa71085d855dc7c809ed6e2889592b361ab3ab39060f8e419152187a794a19c2a1128882201900ea2cd597860674bf78d9720643df8701676718fd201baed4935a88e50558daf86edd08a9ab227ac7afae55c974b68de8dacad4a4d79b13ed6dfe74017a4cb9148e033436fb6
+TAG: 184095b7a8190abec08bb72d19eeb103
+
+KEY: 55a4be2448b464c2ea52a2f2664ed6aba865c14ea1fea77f4689331fd105c8d4
+NONCE: db37c0a405b4626d
+IN: d266e66272e5d3462081b004cb42429c8b9741e9f678153754d726f6f9aa513464763c5e793b482fe512fece97585f1426120d4cefb3d0a8cc0a8db4bde93fc72c78f44d4fecca14650c660d3e285b327e7cdd813063e7e867b8a2d059a41bab70432b7f857199894da90dca3fe5272bae1ec694a1a07b60b05df275784d4975637e4673109f3ba846dfd1a048b202ed8e89973be608b91ee4743b1e759900f1443038951fe6189e806638985f3c16338c3c60695df58e621154d79bb973859c4558e9dca90470f77c73f004443ad5db0717abbe43266f90e57397b83ac34d1fef2e897e2483d5bcdcb627abd64b0d1aef525835f25e76d6e9158232cdde6dce970b59f58de8a98e653be32fb58edabbcefa5065d73afdf1c9c4fbf50c1022bd22bfcb98e4b422
+AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813bf5c501ad31e5d791c4b5b3a0a71b63fdddcc8de4b056064ef467989ecccc5d0160d403bf3a025d4892b3b1de3e062bc3581d4410f273338311eb4637529e4a680a6e4a5e26e308630a5b6d49ead6d543f8f2bf9050aa94ce091318721e1d8b96e279f34b9759b65037bec4bf6ccda6929705aeeeebe49e327e4d7a916620c9faf3765120658af34c53fbb97ec07657b3f088fcbdc401aa7949ddeda34d885018c2c23f4f0bb8218bf0d4fc90643658b4d8834f4a8c08e590c2a790995baa9e77627c342d283e454f84fcc05be15e9627a2d9be340c9d72f222bbdfc47905f56616cd9f936d49e4732f319f020513340fb8b22828db251b102b6b137c9533936d6
+CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
+TAG: f7d3b58a34a86e99267e5db206f17bbe
+
+# BoringSSL has additional tests here for truncated tags. *ring* doesn't
+# support tag truncation, so those tests were removed.
diff --git a/src/crypto/cipher/test/chacha20_poly1305_tests.txt b/src/crypto/cipher/test/chacha20_poly1305_tests.txt
index b7f1cc6..a71ac14 100644
--- a/src/crypto/cipher/test/chacha20_poly1305_tests.txt
+++ b/src/crypto/cipher/test/chacha20_poly1305_tests.txt
@@ -1,524 +1,474 @@
+# Test vector from RFC 7539 Section 2.8.1.
+
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
+AD: 50515253c0c1c2c3c4c5c6c7
+CT: d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116
+TAG: 1ae10b594f09e26a7e902ecbd0600691
+
+# Test padding AD with 15 zeros in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "123456789abcdef0"
+AD: "1"
+CT: ae49da6934cb77822c83ed9852e46c9e
+TAG: dac9c841c168379dcf8f2bb8e22d6da2
+
+# Test padding IN with 15 zeros in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "1"
+AD: "123456789abcdef0"
+CT: ae
+TAG: 3ed2f824f901a8994052f852127c196a
+
+# Test padding AD with 1 zero in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "123456789abcdef0"
+AD: "123456789abcdef"
+CT: ae49da6934cb77822c83ed9852e46c9e
+TAG: 2e9c9b1689adb5ec444002eb920efb66
+
+# Test padding IN with 1 zero in the tag calculation.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: 070000004041424344454647
+IN: "123456789abcdef"
+AD: "123456789abcdef0"
+CT: ae49da6934cb77822c83ed9852e46c
+TAG: 05b2937f8bbc64fed21f0fb74cd7147c
+
+# Test maximal nonce value.
+KEY: 808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f
+NONCE: ffffffffffffffffffffffff
+IN: "123456789abcdef0"
+AD: "123456789abcdef0"
+CT: e275aeb341e1fc9a70c4fd4496fc7cdb
+TAG: 41acd0560ea6843d3e5d4e5babf6e946
+
+# Test vectors from chacha20_poly1305_deprecated_tests.txt, modified for the
+# RFC 7539 AEAD construction.
+
KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
-NONCE: 3de9c0da2bd7f91e
-IN:
-AD:
-CT:
+NONCE: 000000003de9c0da2bd7f91e
+IN: ""
+AD: ""
+CT: ""
TAG: 5a6e21f4ba6dbee57380e79e79c30def
KEY: bcb2639bf989c6251b29bf38d39a9bdce7c55f4b2ac12a39c8a37b5d0a5cc2b5
-NONCE: 1e8b4c510f5ca083
+NONCE: 000000001e8b4c510f5ca083
IN: 8c8419bc27
AD: 34ab88c265
CT: 1a7c2f33f5
-TAG: 2875c659d0f2808de3a40027feff91a4
+TAG: 2a63876a887f4f080c9df418813fc1fd
KEY: 4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007
-NONCE: cd7cf67be39c794a
+NONCE: 00000000cd7cf67be39c794a
IN: 86d09974840bded2a5ca
AD: 87e229d4500845a079c0
CT: e3e446f7ede9a19b62a4
-TAG: 677dabf4e3d24b876bb284753896e1d6
+TAG: 356d9eda66d08016b853d87c08b5c1b3
KEY: 422a5355b56dcf2b436aa8152858106a88d9ba23cdfe087b5e74e817a52388b3
-NONCE: 1d12d6d91848f2ea
+NONCE: 000000001d12d6d91848f2ea
IN: 537a645387f22d6f6dbbea568d3feb
AD: bef267c99aec8af56bc238612bfea6
CT: 281a366705c5a24b94e56146681e44
-TAG: 38f2b8ee3be44abba3c010d9cab6e042
+TAG: 59143dab187449060a3ec2a1681613cc
KEY: ec7b864a078c3d05d970b6ea3ba6d33d6bb73dfa64c622a4727a96ede876f685
-NONCE: 2bca0e59e39508d3
+NONCE: 000000002bca0e59e39508d3
IN: b76733895c871edd728a45ed1a21f15a9597d49d
AD: cc1243ea54272db602fb0853c8e7027c56338b6c
CT: 1fb9b2958fce47a5cada9d895fbb0c00d3569858
-TAG: 042ad5042c89ebc1aad57d3fb703d314
+TAG: 219b4252deb16a43b292165aabc5d5ce
KEY: 2c4c0fdb611df2d4d5e7898c6af0022795364adb8749155e2c68776a090e7d5c
-NONCE: 13ce7382734c4a71
+NONCE: 0000000013ce7382734c4a71
IN: 0dc6ff21a346e1337dd0db81d8f7d9f6fd1864418b98aadcdb
AD: 0115edcb176ab8bfa947d1f7c3a86a845d310bf6706c59a8f9
CT: dad65e4244a1a17ce59d88b00af4f7434bd7830ffdd4c5558f
-TAG: ac1437b45d8eacf9c0fe547c84fb82a2
+TAG: 7ae32f186cf9ec59b41b764b34307d4f
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
-NONCE: 5d9856060c54ab06
+NONCE: 000000005d9856060c54ab06
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
-TAG: 6dd98710d8a889dceea0d0a936f98617
+TAG: d3f7b9c295f374651a84138648a5919a
KEY: a8b9766f404dea8cf7d7dfaf5822f53df9ccd092e332a57f007b301b507d5e14
-NONCE: c7f2f7a233104a2d
+NONCE: 00000000c7f2f7a233104a2d
IN: 4d6faeaee39179a7c892faae3719656cc614c7e6ecd8fcb570a3b82c4dace969090338
AD: c6d83b6a56408a356e68d0494d4eff150530b09551d008373d6dee2b8d6b5619d67fdb
CT: a15443f083316eef627a371f4c9ac654d0dd75255d8a303125e9f51af4233ff4ceb7fe
-TAG: 52504e880f6792a60708cc6db72eae42
+TAG: 63c2b4e0973096299488b0a66ffa54c1
KEY: 5e8d0e5f1467f7a750c55144d0c670f7d91075f386795b230c9bf1c04ba250bc
-NONCE: 88049f44ba61b88f
+NONCE: 0000000088049f44ba61b88f
IN: 51a1eebcc348e0582196a0bce16ed1f8ac2e91c3e8a690e04a9f4b5cf63313d7ad08d1efbff85c89
AD: 5d09bf0be90026f9fc51f73418d6d864b6d197ea030b3de072bd2c2f5cab5860a342abbd29dba9dc
CT: 35aa4bd4537aa611fd7578fc227df50ebcb00c692a1cf6f02e50ed9270bd93af3bc68f4c75b96638
-TAG: ccea1cbbc83944cc66df4dbf6fb7fc46
+TAG: 4461139c4055333106cf7f7556fd4171
KEY: 21a9f07ec891d488805e9b92bb1b2286f3f0410c323b07fee1dc6f7379e22e48
-NONCE: 066215be6567377a
+NONCE: 00000000066215be6567377a
IN: c1b0affaf2b8d7ef51cca9aacf7969f92f928c2e3cc7db2e15f47ee1f65023910d09f209d007b7436ee898133d
AD: dfdfdf4d3a68b47ad0d48828dc17b2585da9c81c3a8d71d826b5fa8020fee002397e91fc9658e9d61d728b93eb
CT: 8ff4ceb600e7d45696d02467f8e30df0d33864a040a41ffb9e4c2da09b92e88b6f6b850e9f7258d827b9aaf346
-TAG: 4eeddc99784011f0758ba5ebfba61827
+TAG: b2ad07b86aca1b3ab34033c12d6a08cc
KEY: 54c93db9aa0e00d10b45041c7a7e41ee9f90ab78ae4c1bba18d673c3b370abde
-NONCE: 3f2d44e7b352360f
+NONCE: 000000003f2d44e7b352360f
IN: 1241e7d6fbe5eef5d8af9c2fb8b516e0f1dd49aa4ebe5491205194fe5aea3704efaf30d392f44cc99e0925b84460d4873344
AD: f1d1b08dd6fe96c46578c1d1ad38881840b10cb5eae41e5f05fe5287223fa72242aea48cb374a80be937b541f9381efa66bb
CT: 027b86865b80b4c4da823a7d3dbcf5845bf57d58ee334eb357e82369cc628979e2947830d9d4817efd3d0bc4779f0b388943
-TAG: 4303fa0174ac2b9916bf89c593baee37
+TAG: 6de01091d749f189c4e25aa315b31495
KEY: 808e0e73e9bcd274d4c6f65df2fe957822a602f039d4752616ba29a28926ef4a
-NONCE: 1b9cd73d2fc3cb8e
+NONCE: 000000001b9cd73d2fc3cb8e
IN: 3436c7b5be2394af7e88320c82326a6db37887ff9de41961c7d654dd22dd1f7d40444d48f5c663b86ff41f3e15b5c8ca1337f97635858f
AD: d57cfbe5f2538044282e53b2f0bb4e86ea2233041fb36adb8338ded092148f8c2e894ef8766a7ec2dd02c6ac5dbab0c3703c5e9119e37c
CT: 9b950b3caf7d25eaf5fca6fa3fe12ed077d80dcd5579851233c766bb8bb613ec91d925a939bb52fb88d5eda803cfe2a8cda2e055b962fd
-TAG: 6bf5b718f5bbe1395a5fdfcbbef752f5
+TAG: 0887ec7d5e1a4e532746ec247a30825a
KEY: 4adfe1a26c5636536cd7cb72aa5bded0b1aa64487ad0e4078f311e8782768e97
-NONCE: d69e54badec11560
+NONCE: 00000000d69e54badec11560
IN: 19b3f9411ce875fcb684cbdc07938c4c1347e164f9640d37b22f975b4b9a373c4302ae0e7dfdeba1e0d00ced446e338f4c5bc01b4becef5115825276
AD: bda1b0f6c2f4eb8121dcbd2eebd91a03ae1d6e0523b9b6f34b6f16ceca0d086654fb0552bfd5c8e1887730e1449ea02d7f647ae835bc2dab4bbc65b9
CT: ea765a829d961e08bacaed801237ef4067df38ad3737b7c6de4db587a102a86fc4abbaabea0ee97c95ca7f571c7bab6f38cbae60cd6e6a4ce3c7a320
-TAG: b425cdf10cd0123a7e64b347c6b4b1f0
+TAG: a27f18846f5a4f7fcc724656c91cf4f3
KEY: eb3db86c14b7cc2e494345d0dfb4841bbd3aa1e2bc640cca0c6c405520685639
-NONCE: 88b54b28d6da8c81
+NONCE: 0000000088b54b28d6da8c81
IN: f75c0a357271430b1ecff07a307b6c29325c6e66935046704a19845e629f87a9e3b8aa6c1df55dd426a487d533bb333e46f0d3418464ac1bef059231f8e87e6284
AD: 34b08bb0df821c573dcb56f5b8b4a9920465067f3b5bf3e3254ea1da1a7fc9847fd38bdfe6b30927945263a91fa288c7cf1bee0fddb0fadf5948c5d83eb4623575
CT: 146ec84f5dc1c9fe9de3307a9182dbaa75965bf85f5e64563e68d039a5b659aa8863b89228edb93ff3d8c3323ab0d03300476aa4aca206d4626a6b269b2078912d
-TAG: 0058a8dff32c29935c62210c359bd281
+TAG: 854cbb42bade86a09597482c8604681a
KEY: dd5b49b5953e04d926d664da3b65ebcffbbf06abbe93a3819dfc1abbecbaab13
-NONCE: c5c8009459b9e31a
+NONCE: 00000000c5c8009459b9e31a
IN: f21f6706a4dc33a361362c214defd56d353bcb29811e5819ab3c5c2c13950c7aa0000b9d1fe69bb46454514dcce88a4a5eda097c281b81e51d6a4dba47c80326ba6cea8e2bab
AD: fe6f4cbb00794adea59e9de8b03c7fdf482e46f6c47a35f96997669c735ed5e729a49416b42468777e6a8d7aa173c18b8177418ded600124a98cbb65489f9c24a04f1e7127ce
CT: 911ead61b2aa81d00c5eff53aeea3ab713709ed571765890d558fb59d3993b45f598a39e5eff4be844c4d4bd1ef9622e60412b21140007d54dcf31b2c0e3e98cf33a00fd27f0
-TAG: d38d672665e2c8c4a07954b10ecff7d9
+TAG: 2865d2a26f413cc92416340f9491e1be
KEY: 3b319e40148a67dc0bb19271d9272b327bc5eee087173d3d134ad56c8c7dc020
-NONCE: ce5cf6fef84d0010
+NONCE: 00000000ce5cf6fef84d0010
IN: 27b5627b17a2de31ad00fc2ecb347da0a399bb75cc6eadd4d6ee02de8fbd6a2168d4763ba9368ba982e97a2db8126df0343cdad06d2bc7d7e12eec731d130f8b8745c1954bfd1d717b4ea2
AD: a026b6638f2939ec9cc28d935fb7113157f3b5b7e26c12f8f25b36412b0cd560b7f11b62788a76bd171342e2ae858bcecb8266ff8482bbaed593afe818b9829e05e8e2b281ae7799580142
CT: 368fb69892447b75778f1c5236e1e9d5d89255c3d68d565a5bba4f524d6ad27de13087f301e2ef4c08f5e2c6128b1d3e26de845c4ac4869e4c8bd8858ad0d26dec3b5d61a9e3666a3911ba
-TAG: 2e70564c3999c448d92cc6df29d095c4
+TAG: 1414f1b91966340417c38226ccca9d3d
KEY: 43bf97407a82d0f684bb85342380d66b85fcc81c3e22f1c0d972cd5bfdf407f4
-NONCE: 8b6ba494c540fba4
+NONCE: 000000008b6ba494c540fba4
IN: 4b4c7e292a357f56fdf567c32fc0f33608110d7ce5c69112987d7b5a0bd46d8627a721b0aed070b54ea9726084188c518cba829f3920365afc9382c6a5eb0dd332b84612366735be2479b63c9efc7ff5
AD: 1e0acf4070e8d6758b60d81b6d289a4ecdc30e3de4f9090c13691d5b93d5bbcef984f90956de53c5cf44be6c70440661fa58e65dec2734ff51d6d03f57bddda1f47807247e3194e2f7ddd5f3cafd250f
CT: d0076c88ad4bc12d77eb8ae8d9b5bf3a2c5888a8d4c15297b38ece5d64f673191dc81547240a0cbe066c9c563f5c3424809971b5a07dcc70b107305561ce85aecb0b0ea0e8b4ff4d1e4f84836955a945
-TAG: 75c9347425b459af6d99b17345c61ff7
+TAG: c5ca34599c6a8b357c6723ee12b24da8
KEY: 12fc0bc94104ed8150bde1e56856ce3c57cd1cf633954d22552140e1f4e7c65d
-NONCE: d3875d1b6c808353
+NONCE: 00000000d3875d1b6c808353
IN: 24592082d6e73eb65c409b26ceae032e57f6877514947fc45eb007b8a6034494dde5563ac586ea081dc12fa6cda32266be858e4748be40bb20f71320711bf84c3f0e2783a63ad6e25a63b44c373a99af845cdf452c
AD: b8be08463e84a909d071f5ff87213391b7da889dc56fd2f1e3cf86a0a03e2c8eaa2f539bf73f90f5298c26f27ef4a673a12784833acb4d0861562142c974ee37b09ae7708a19f14d1ad8c402bd1ecf5ea280fab280
CT: 9d9ae6328711fb897a88462d20b8aa1b278134cdf7b23e1f1c809fa408b68a7bfc2be61a790008edaa98823381f45ae65f71042689d88acfa5f63332f0fba737c4772c972eba266640056452903d6522cefd3f264e
-TAG: e9c982d4ade7397bcfaa1e4c5a6cd578
+TAG: e84211b6cfd43543f8b1b4db07a494d1
KEY: 7b6300f7dc21c9fddeaa71f439d53b553a7bf3e69ff515b5cb6495d652a0f99c
-NONCE: 40b32e3fdc646453
+NONCE: 0000000040b32e3fdc646453
IN: 572f60d98c8becc8ba80dd6b8d2d0f7b7bbfd7e4abc235f374abd44d9035c7650a79d1dd545fa2f6fb0b5eba271779913e5c5eb450528e4128909a96d11a652bf3f7ae9d0d17adbf612ec9ca32e73ef6e87d7f4e21fe3412ce14
AD: 9ff377545a35cf1bfb77c734ad900c703aee6c3174fdb3736664863036a3a9d09163c2992f093e2408911b8751f001e493decc41e4eeeed04f698b6daed48452a7e1a74ec3b4f3dcf2151ca249fa568aa084c8428a41f20be5fd
CT: 229da76844426639e2fd3ef253a195e0a93f08452ba37219b6773f103134f3f87b1345f9b4bf8cfc11277c311780a2b6e19a363b6ac2efe6c4cc54a39b144e29c94b9ebbde6fd094c30f59d1b770ebf9fcad2a5c695dc003bf51
-TAG: b72acab50131a29558d56ae7b9d48e4e
+TAG: 55e025a1eb87bc84d4be00c775c92ad2
KEY: 4aeb62f024e187606ee7cc9f5865c391c43df1963f459c87ba00e44bb163a866
-NONCE: 9559bd08718b75af
+NONCE: 000000009559bd08718b75af
IN: c5d586ceece6f41812c969bcf1e727fe6ff8d1ae8c8c52367c612caa7cdf50e0662f5dffc5ea7d3cc39400dfe3dc1897905f6490fd7747b5f5f9842739c67d07ce7c339a5b3997a7fb4cd0d8e4817ff8916b251c11ef919167f858e41504b9
AD: 51f5b503b73a5de8b96534c2a3f2d859ece0bd063ea6dfa486a7eec99f6c020983f7148cccb86202cf9685cc1cc266930f04e536ad8bc26094252baa4606d883bd2aeed6b430152202e9b6cc797ff24fc365315ed67391374c1357c9a845f2
CT: 252ea42b6e5740306816974a4fe67b66e793ebe0914778ef485d55288eb6c9c45fa34ac853dc7a39252520514c3cb34c72b973b14b32bc257687d398f36f64cc2a668faffa7305ab240171343b5f9f49b6c2197e4fbe187b10540d7cdcfa37
-TAG: 711ff33ef8d2b067a1b85c64f32f1814
+TAG: ab1d8a5a1f3eda9b5609c0028737477f
KEY: 9a19e72f005cae1ae78b8e350d7aabe59fc8845999e8c52fad545b942c225eaf
-NONCE: d9dae2ea8d2ffc31
+NONCE: 00000000d9dae2ea8d2ffc31
IN: 2110378d856ded07eb2be8e8f43308e0c75bc8a3fcc7b1773b0725b7de49f6a166c4528e64120bdf7c9776615d3ce6feeb03de964a7b919206a77392f80437faceb6745845cafc166e1c13b68e70ca2a1d00c71737b8fcbbbd50902565c32159e05fcd23
AD: 1cd73b72c4e103afbefd7c777e0480f3f5e68c60b85bd2e71ef5caebb175d7fc6535d39f38f92c24f2eb0fe97d878ed3d5967c0bb4394a5d41f7d34cda6e1523d3848f049cde554a7d31e1afeab5d3e6150f85858335cbd28c8a7f87d528058df50eea06
CT: 5f009fbce4ec8e4ca9d8d42258b1a3e4e920b2fbad33d5e9f07557d9595e841025193b521ba440110dd83958e8ee30219d952b418e98a6c624894aa248aedc0678f2d263e7bfaf54ca379fef6c5d2f7ac422ea4b4369408b82d6225a7a2cf9a9f46fd4ef
-TAG: aa0a5fa7d3cf717a4704a59973b1cd15
+TAG: 1c6bdff7d8b9554dc7bf40e50b37d352
KEY: ba1d0b3329ecc009f1da0fab4c854b00ad944870fdca561838e38bad364da507
-NONCE: 8a81c92b37221f2f
+NONCE: 000000008a81c92b37221f2f
IN: 6289944ffa3ccea4bf25cd601b271f64e6deb0eba77d65efb4d69ca93e01996e4727168b6f74f3ccf17bd44715f23ceb8fc030c0e035e77f53263db025021fd2d04b87a1b54b12229c5e860481452a80a125cb0693a2ba1b47e28ee7cbaf9e683c178232c7f6d34f97
AD: e57883961b8d041d9b9eeaddcfd61fa9f59213f66571fadffffdd1498b9b014f1ef2e7e56c3044d7f9fa7a1403a1169e86430a2a782137093f5456e142aad03a5f7a66d38009dd01b7fc02c9cf61642dedaf7cc8d46066c281ee17780674c3a36eae66c58d2d765075
CT: 9c44d9135db0dbf81c862c1f69bec55a279794cdd29a58e61909aa29ec4c120c9c5a508d856b9e56138095714a4bb58402a1ad06774cf4ecdf2273839c0007cb88b5444b25c76f6d2424281101d043fc6369ebb3b2ff63cdb0f11a6ea1b8a7dafc80cdaef2813fa661
-TAG: 65c746f659bcbdcd054e768c57c848c9
+TAG: 689a141bc11159d306dad7a4ecf6ad9d
KEY: 0cf8c73a6cffc1b8b2f5d320da1d859d314374e4a9468db7fd42c8d270b7613a
-NONCE: 3c4c6f0281841aff
+NONCE: 000000003c4c6f0281841aff
IN: 4434728d234603c916e2faa06b25d83bad3348990ecde2344368d1a7af1309bd04251bb2e0b72044948f8dea33cce2618283b6af742073a9586b26c1089335fe735141e099785a1235810a3a67ff309e2f0ce68220ba0077ad1a5dc1a4aef898a3b9ff8f5ad7fe60149bd0bd6d83
AD: a38d09a4f1c9241623c639b7688d8d35345ea5824080c9d74e4352919db63c74d318f19e1cbb9b14eebd7c74b0ad0119247651911f3551583e749ea50ff648858dcaaa789b7419d9e93a5bf6c8167188dbac2f36804380db325201982b8b06597efeb7684546b272642941591e92
CT: bdfbfea261b1f4c134445321db9e6e40476e2dd2f4e4dbe86e31d6a116d25830762e065b07b11a3799aab93a94b4f98c31c0faeb77ec52c02048e9579257e67f5a6bae9bc65210c25b37fc16ee93bda88fd5f30a533e470b6188c6ce5739fa3e90f77120b490fc1027964f277f40
-TAG: 4993ee9582f58eabdb26b98c4d56a244
+TAG: 780cc54bb6f1c9b78545c1562cd9d550
KEY: 69f4e5788d486a75adf9207df1bd262dd2fe3dd3a0236420390d16e2a3040466
-NONCE: 6255bf5c71bb27d1
+NONCE: 000000006255bf5c71bb27d1
IN: c15048ca2941ef9600e767a5045aa98ac615225b805a9fbda3ac6301cd5a66aef611400fa3bc04838ead9924d382bef8251a47f1e487d2f3ca4bccd3476a6ca7f13e94fd639a259ef23cc2f8b8d248a471d30ac9219631c3e6985100dc45e0b59b8fc62046309165ddb6f092da3a4f067c8a44
AD: 0c83039504c8464b49d63b7f944802f0d39c85e9f3745e250f10119fa2c960490f75ae4dced8503b156d072a69f20400e9494ab2fa58446c255d82ff0be4b7e43046580bc1cf34060c6f076c72ea455c3687381a3b908e152b10c95c7b94155b0b4b303b7764a8a27d1db0a885f1040d5dbcc3
CT: f0bb2b73d94f2a7cef70fe77e054f206998eacf2b86c05c4fa3f40f2b8cebf034fe17bcbee4dea821f51c18c0aa85b160f8508bd1dc455cc7f49668b1fb25557cdae147bf2399e07fcacaca18eccded741e026ef25365a6b0f44a6b3dd975ee6bb580f5fccd040b73c18b0fbf8f63199ba10fe
-TAG: 4236a8750f0cafee3c4a06a577a85cb3
+TAG: 2ecccea4607d14dbb2d2475792aeb468
KEY: ad7b9409147a896648a2a2fe2128f79022a70d96dc482730cd85c70db492b638
-NONCE: a28a6dedf3f2b01a
+NONCE: 00000000a28a6dedf3f2b01a
IN: 791d293ff0a3b8510b4d494b30f50b38a01638bf130e58c7601904f12cb8900871e8cf3d50abd4d34fda122c76dfee5b7f82cd6e8590647535c915ae08714e427da52f80aef09f40040036034ca52718ea68313c534e7a045cd51745ec52f2e1b59463db07de7ca401c6f6453841d247f370341b2dbc1212
AD: 9a6defddb9b8d5c24a26dd8096f5b8c3af7a89e1f7d886f560fabbe64f14db838d6eb9d6879f4f0b769fe1f9eebf67fcd47b6f9ceb4840b2dba7587e98dc5cae186ef2a0f8601060e8058d9dda812d91387c583da701d2ba3347f285c5d44385a2b0bf07150cbc95e7fcfa8ae07132849a023c98817c03d2
CT: c2f109d6d94f77a7289c8a2ab33bc6a98d976554721b0c726cbf4121069473e62ba36e7090e02414f3edc25c5d83ac80b49ad528cda1e3ad815b5a8c8ae9ad0753de725319df236983abd3f69ab4465d9b806c075b1896d40bdba72d73ba84c4a530896eb94ffccf5fb67eb59119e66a1861872218f928cf
-TAG: e48dc0153d5b0f7edb76fc97a0224987
+TAG: 17ec6cf2b172f01e3c456ad047196805
KEY: 48470da98228c9b53f58747673504f74ca1737d7d4bb6dbf7c0cba6ca42f80b9
-NONCE: 56fb4923a97e9320
+NONCE: 0000000056fb4923a97e9320
IN: bc6626d651e2b237f22ee51608ddcffeba5f31c26df72f443f701f2b085d6f34f806e29673584cb21522179edb62a82427d946acabce065b88b2878e9eb87ed1004e55ef58f51ec46375ac542c5782725ff013136cb506fcf99496e13fcd224b8a74a971cc8ddb8b393ccc6ac910bd1906ea9f2ed8a5d066dc639c20cd
AD: df8ab634d3dca14e2e091b15ecc78f91e229a1a13cba5edd6526d182525ec575aa45bc70fb6193ffcd59bad3c347159099c4f139c323c30a230753d070018786b2e59b758dd4a97d1a88e8f672092bef780b451fd66ba7431cbb5660ea7816cdf26e19a6ebb9aadc3088e6923f29f53f877a6758068f79a6f2a182b4bf
CT: a62e313ecf258cc9087cbb94fcc12643eb722d255c3f98c39f130e10058a375f0809662442c7b18044feb1602d89be40facae8e89ca967015f0b7f8c2e4e4a3855dbb46a066e49abf9cef67e6036400c8ff46b241fc99ba1974ba3ba6ea20dc52ec6753f6fc7697adbccd02b0bbea1df8352629b03b43cc3d632576787
-TAG: 675287f8143b9b976e50a80f8531bd39
+TAG: d29a8968067aeb457ffc114c3a9efb95
KEY: b62fb85c1decd0faf242ce662140ad1b82975e99a3fa01666cac2385ab91da54
-NONCE: 2f4a5ca096a4faf8
+NONCE: 000000002f4a5ca096a4faf8
IN: 03b14f13c0065e4a4421de62ab1d842bffb80f3da30bf47d115c09857f5bdd5756fd7c9ac3d9af1c9fb94f2640f7f4386cfba74db468e5288dbe4dd78bfe4f69e41480ca6138e8beacc6eaa3374157c713cfa900c07dd836eaecc8827fa3e70e052ae09e8473e2ae1a10b1bb669ef60a8dd957f6553daa8114918e17371f2ac327bd
AD: cfe3b7ab7550b0e8e2e8235fa0dcef95647ce6814abd3dc3f5a3bd7d6d282504660c34ad8341e4d11402c7d46c83a494d7ddb105e1002979023e0e3dc2978c9ae53e10eb8567e7a02b60e51e945c7040d832ca900d132b4205a35034fed939a1b7965183c25654931a9b744401c4649c945710b0d9733b87451348b32ba81de30ea7
CT: 8965db3d3ae4fb483208f147276e7d81b71a86e7202ffc9b1eaade009bc016838dc09ca4bcf30887b2f4243fbd652cd90ebed1ceef8151ff17ea70518d03b0f2a24960aa7de9b30fa65c2e2d57360061aae6d9376e984e9fcd5e5dd0911a4bc8deca832ffb76f252bd7da523076593ba6b174f7d9fb0377e066ecbb6638036241e86
-TAG: 3d0fc53e9058c2be32aa0850e0fab5a6
+TAG: 28a5284696ed82714eaa94c9ebe6e815
KEY: de9c657258774d4ebc09d109a0fc79d66493ae578797cac4eb8830a6a4b547e0
-NONCE: b5e35fe3398efa34
+NONCE: 00000000b5e35fe3398efa34
IN: 4d68fb683aa4f4c7a16ba1114fc0b1b8d8898610fa2763e435ded8771b3651078bef73d4dfd14e76a34cd5eb9ef4db4ead4da9e83f4ce50fe059977b2d17d687c29335a04d87389d211f8215449749969f7652dc1935a0f9a94538dc81dc9a39af63446a6517609076987920547d0098a9c6766cf5e704883ea32feaea1889b1554b5eb0ce5ecc
AD: 436ea5a5fee8293b93e4e8488116c94d3269c19f1d5050def23d280515457b931bbed64a542b317cc5023d648330a4b7adca14dd6f3783207b94f86ccaa0a0ac39b7db00ac87a99e3cd8a764ed9c75da8454479636ab2b29e770b166a5b75cacc425c919bf1ce9ac34afe6b4425c3d9fd2e48bc81e7d15516d60e592bfcc2ebefb660f0995f2b5
CT: 97a97b8f0f5420845ae8d57567f9bba693d30e6db916fad0b971f553ad7d993f806f27ab8b458d8046062ced4778c004b4f958a4436141637c6039963308dea2f54008b7feab79650295ed41bf9e65e1a2d75ab1c7b2a70ebb9e9f38d07a9a672d3e95ea78afe9ac02f2566b48b0251aef6eeeca8bd15bd8d43b559426aa9d15d960ee35cb3edf
-TAG: e55dbb21851e8a5b365f86d02518331c
+TAG: 4ef49e8a0c2ef85826d7f03e81c577f2
KEY: 6885bd333c336c7672db8ebdf24c1a1b605c5a4ae279f0f698162f47e6c73401
-NONCE: f0c4a213a6168aab
+NONCE: 00000000f0c4a213a6168aab
IN: fa905a2bfa5b5bad767239fb070a7bc0b303d1503ecd2b429418cc8feba843e5444ed89022fdb379c3b155a0f9ceab2979000a0f60292a631771f2fde4ef065aa746426609082969530a9c70ad145308c30ba389ea122fd766081511a031ce3a0bd9f9f583c7000b333b79ac004fbde6ec3eb2d905977ff95dcff77858e3c424fe8932a6a12139e6ec8d5e98
AD: 8ded368f919efb522bb6a9ad009e02ffbc6a16536e34d95cdb34f1153d7cb7b0f3c2b13dd05cedae27cfe68ec3aca8047e0930a29c9d0770c1b83c234dcb0385deae7ae85da73a5f8de3dfb28612a001f4e552c4f67ae0e2ec53853289b7017a58591fd6f70b0e954876bb2f7ec33001e298856a64bb16181017ba924648c09fc63c62eff262c80d614679bd
CT: 0cb3d6c31e0f4029eca5524f951244df042fc637c4162511fea512a52d3f7581af097eb642e79e48666cb1086edbd38c4777c535a20945fabc23e7c9277e2b960aac46865f1026eb6da82759108b9baece5da930ccfc1052b1656b0eadaa120ed0c45ad04b24ae8cdb22ceab76c5f180b46a392ab45b1b99c612546e6b947f4d5c06ad5abee92ff96345ad43
-TAG: d3b541ac446c84626daf800c0172eec6
+TAG: fad7d5a5193dfb121c68529ba8c0c35d
KEY: fbc978abb1240a6937ccc16735b8d6ed5411cdbc1897214165a174e16f4e699b
-NONCE: 7968379a8ce88117
+NONCE: 000000007968379a8ce88117
IN: 1a8196cd4a1389ec916ef8b7da5078a2afa8e9f1081223fa72f6524ac0a1a8019e44a09563a953615587429295052cc904b89f778ef446ed341430d7d8f747cf2db4308478524639f44457253ae5a4451c7efca8ae0b6c5c051aaa781e9c505489b381a6dcba87b157edc7f820a8fbaf2a52e484dc121f33d9d8b9ac59d4901d6ed8996ed4f62d9d4d82274c449cd74efa
AD: 3913cd01299b8a4e507f067d887d7e9a6ded16dd9f9bb3115c5779aa14239fd33ee9f25756d45262dc3011069356425b5c81a4729594e17c9747119f81463e85625d5603d05e00f568b0c800bb181eb717be8d7a93166a504ce1bc817e15530c5bd2b3df1d4222245ea78a38bc10f66c5cf68d661503131f11af885c8a910b6dce70bc3a7448dfae00595beb707fe054d3
CT: d152bcb4c24c3711b0fad28548dc4db605bbc89237cdbea7dbf956b8855d1161a0781f27bd56d798141e2ace339955efb98fe05d9b44cd011e645106bf47726183958cb6df34ce5766695f60bc70b6fe0fabb9afa009a8ef043dbf75f861881368fa07726625448fe608d578cdc48277f2dc53eaaf1bdc075269a42f9302a57cad387a82c6969608acacda20e1cac4596c
-TAG: 945dca73cf2f007ae243991c4fbe0479
+TAG: 96ae06cd7c72456e5568a42317046158
KEY: 77d1a857fbadfe01aba7974eea2dfb3dc7bf41de73686aece403993e5016c714
-NONCE: fdd913a321c40eb0
+NONCE: 00000000fdd913a321c40eb0
IN: db8915bfe651e2ecb3ce0b27d99a6bfa7a7c507cfcb2987293018636c365a459c6a138b4428be538413db15bda69e697cbb92b154b7f4d2cbb07965225aa6865d7dcd1ba2c17c484b00b1986fed63e889f25a4966dc3ed4273f1577768f665362d7d3e824484f0dded7f82b8be8797ad951719719365e45abbf76324bc7d657799d4d4f4bb1dba67d96ab1c88519a5bee704f7214814
AD: 3cb2c06c20cb0832bbacebfc205d77393ca1816346ea2681de4d3ab1fadb774ad273e4713290454496f5281ebc65e04cfe84ed37cd0aedc4bbe3decbd8d79d04a4e434876650e0d64309e336bfb10e924066a64acb92260b2dbd96735d03af03909aa6a80a6e89fda81037257aec21fe9be7e91a64e88e0a58fa38ecba4c4c4cffb61958f3c486cbb0b1d0b0014a2d1d3df248eec1ca
CT: acb825e6023b44b03b2efc265603e887954e8612b2ee134bdcb61501cfb9492952bf67be597c3a005b09af74d9e421a576d2c65e98104780feab838d8cb1bd135452ea39dc8907a4c1a6a9161805e4fa3e16989e6a418a7eea2582bf895da967028eab7c95d846a6de4b9980785814cf00484baa2f6de609912fff689bce6e854261ffe866bd8e63274605c7c5ad677bd7897ade543e
-TAG: 938478a41a3223a2199f9276d116210f
+TAG: bcf523a9bcf772e157941753c6d7401e
KEY: b7e9b90dc02b5cd6df5df7283ef293ed4dc07513d9e67331b606f4d42dec7d29
-NONCE: a6c191f6d1818f8e
+NONCE: 00000000a6c191f6d1818f8e
IN: 2ada0e3c7ca6db1f780ce8c79472af4e8e951ddc828e0d6e8a67df520638ff5f14a2f95a5e5931749ae2c4e9946ae4d5eb5de42fb5b77d2236e2e2bd817df51be40b1b8a6c21015a7c79fe06dba4a08b34013dfa02747b5f03930268404c455dc54a74d9c6e35485e10026da573cb41cd50b64cfafe4cfcdf3c9684ef877e45d84e22bd5e15fa6c8fd5be921366ff0dc6fe2df45f7252972c9b303
AD: 0f4269ed5ef0bfff7be39946a4e86e8bf79f84b70cd0b14fecb7be3c071316ce86de3d99d6871e0ba5667d9d7bba7dcaba10cb2a36668b6c3e2fb6c102938b75008bb9c213ebf9b85b5e91a802df0d31d7f11d764b2289f6225212694ab6b7c0e3ff36e84245d9f4f43fc5f98e654dea7ba9bd918658879c5bb4a1642af0d83113e3cf935d3c0d5208318f66f654eb17d8c28a602543e77ad3e815
CT: 22586fe7338e99cdaad9f85bd724ba4cfe6249b8a71399f9a3707b5c4323b8d96679568dfc8d230aefb453df596e13eb3e8a439249bd64bc93a58f95089a62b94f6562b821c83d91f56c55147381e9de4beb4ae81bd6fe7caef7e7e9a2078f2fba8f3e70d4910da9accc92b8e81a61b0fefbece4bd89443e66e8ddda8e47a66a62f17fd0e7d0a4852ce1a4d43d72a0b5e8914bbec698f060f2b092
-TAG: c082470297da8c5f682a169d28bc0239
+TAG: bd05336ed6426de412aac37661953052
KEY: 6b2cb2678d1102f2fbbd028794a79f14585c223d405e1ae904c0361e9b241e99
-NONCE: 7b3ae31f8f938251
+NONCE: 000000007b3ae31f8f938251
IN: b3cb745930e05f3ab8c926c0a343a6eb14809fd21b8390a6fcc58adb5579e5432021765b2d249a0ecf6ba678634c4f53f71495865f031ee97aa159f9ead3a3fcb823ee5238bdf12706a9c6137d236e2e7110ce650c321e41daf0afd62bab2a8fe55d7018de49a14efe6d83a15b2f256d595e998d25309f23633360f5745c50c4e5af8ccc9a8a2cb47064105a023e919c7795d2dc331d3f2afb8c42e5c0bcc26d
AD: 1c32fd3df22b3e440e2a3c7a7624990194cb16a5f74af36f87fd6ca7d410ce9064316a2d091945deef7d9b35ceec8396069307caced2b80afd7d53ec479c35cedf2dfd4c95c3dd8400f71ad34028c6e4f8681d93d0774064ba38f3fb9b0c1dfa1f5f0c7d20676a5911d999fb6a1d41367a8e99d852bf3d3b7b3f4c233249ed1ca135389a674ff48232ded3f6800a97b6d409c40e6cd70d09bf9d2ad25d9b9485
CT: ef70c7de98ab1d4ad817024a970be463443640eb0cd7ff234bdd00e653074a77a1d5749e698bd526dc709f82df06f4c0e64046b3dc5f3c7044aef53aebb807d32239d0652dd990362c44ec25bf5aeae641e27bf716e0c4a1c9fbd37bbf602bb0d0c35b0638be20dd5d5891d446137e842f92c0ee075c68225e4dbacb63cc6fb32442b4bcda5e62cb500a4df2741a4059034d2ccb71b0b8b0112bf1c4ca6eec74
-TAG: 393ae233848034248c191ac0e36b6123
+TAG: d48657033095db3f873c33445fec8d35
KEY: 4dbc80a402c9fceaa755e1105dc49ef6489016776883e06fcf3aed93bf7f6af7
-NONCE: 2358ae0ce3fb8e9f
+NONCE: 000000002358ae0ce3fb8e9f
IN: 197c06403eb896d2fa6465e4d64426d24cc7476aa1ae4127cd2bd8a48ce2c99c16b1cbf3064856e84073b6cf12e7406698ef3dd1240c026cbd1ab04ee603e1e6e735c9b7551fd0d355202b4f64b482dd4a7c7d82c4fe2eb494d0d5e17788982d704c1356c41a94655530deda23118cba281d0f717e149fbeb2c59b22d0c0574c1a2e640afad1a6ceb92e1bf1dde71752a1c991e9a5517fe98688a16b073dbf6884cfde61ac
AD: cf6ce7b899fb700a90d2a5466d54d31358ecf0562e02b330a27ba0138006b342b7ed6349d73c4c5c6d29bde75a25089b11dac5b27adea7e7640ca1a7ceb050e3aae84a47e11640a6e485bd54ae9fdb547edc7313d24a0328429fcffd8b18f39880edd616447344ebeec9eadb2dcb1fa7e67179e7f913c194ebd8f5a58aea73b0c5d1133561245b6d9c5cfd8bb0c25b38ffb37db5e2de5cdded6b57355e9d215cb095b8731f
CT: aa87f9a83048b6919c8f2b050315db4e2adae4a9c2ca0109b81961b520e63299dcb028cec0b9d3249a945ee67dd029b40f361245c740f004f8cf0d2214fcfa65e6124a3e74b78aa94345c46fdc158d34823ed249ee550431eaae9218367321cdd6e6a477650469bb3cc137a8f48d9cf27934b16703608b383d2145659922fb83bb2e7ee2ef938a90f2ff846a4a949129b1fb74dde55c5ae013c2f285de84f7dac7d1662f23
-TAG: 06b4318ac7f65d556f781428a0514ffe
+TAG: 298f84c8312029a7b1f38c5ea6021f57
KEY: 9e4a62016dae4b3223fed1d01d0787e31d30694f79e8142224fe4c4735248a83
-NONCE: 263a2fc06a2872e7
+NONCE: 00000000263a2fc06a2872e7
IN: 5a46946601f93a0cee5993c69575e599cc24f51aafa2d7c28d816a5b9b4decda2e59c111075fb60a903d701ad2680bb14aeda14af2ae9c07a759d8388b30446f28b85f0a05cd150050bd2e715ff550ebbd24da3ebb1eac15aba23d448659de34be962ab3ab31cb1758db76c468b5bb8ce44b06c4e4db9bd2f0615b1e727f053f6b4ffb6358d248f022bcad6ca973044bed23d3920906a89a9a9c5d8024ec67d7f061f64529a955ce16b3
AD: 4cd65f68f9f88c0516231f2a425c8f8a287de47d409d5ecde3ad151e906b3839fb01bb91a456f20ea9d394d4b06604ab1f9009ef29019af7968d965d1643161ab33a5354cda2fdc9f1d21ec9cb71c325c65964a14f9b26eb16560beb9792075a1597394000fd5f331bd8b7d20d88e5f89cf8d0b33e4e78e4904bb59c9c8d5d31ac86b893e4a0667af1be85fdb77f7ec3e2594a68048d20c2fb9422f5879078772ee26a1c560cbcbb2113
CT: e944bb2ab06d138ad633c16ce82706ecf0ef5d119be1f3460c9ce101d9c4e04ef1677707fca40d1f8ca181e07273707b06624d6d7063c3b7b0bb0151b757b3e5237fb8004c161233d8bc7e5f28ea1c18da1874b3d54c5ad6ff0835eed35c8853704585cf83996e5e7cec68180af414e04f08134d3b0384ebdf0393c9310b55d8698fe10cb362defc0995e9a13b48b42cff61ffd9fe4c3c8c6dab355713b88f6e98a02e7231a0c6644ec4
-TAG: 27de0d4ca7648f6396d5419a7b1243b7
+TAG: 6234e81e089b779d0d509d14e566b5d7
KEY: 18ca3ea3e8baeed1b341189297d33cef7f4e0a2fab40ec3b6bb67385d0969cfe
-NONCE: b6aef34c75818e7c
+NONCE: 00000000b6aef34c75818e7c
IN: ef6d1bb4094782f602fcf41561cba4970679661c63befe35ff2ca7ad1a280bf6b1e7f153fa848edfeffe25153f540b71253e8baba9aeb719a02752cda60ea5938aab339eead5aabf81b19b0fc5c1ed556be6ad8970ea43c303d3046205b12c419dea71c4245cfedd0a31b0f4150b5a9fe80052790188529ab32f5e61d8ccde5973ed30bdf290cbfbd5f073c0c6a020eac0332fced17a9a08cef6f9217bd6bef68c1505d6eed40953e15508d87f08fc
AD: f40f03beaa023db6311bad9b4d5d0d66a58d978e0bcbbf78acebde1f4eb9a284095628955a0b15afc454152f962ec3ea2b9a3b089b99658e68ede4dee5acd56672025eb7323bcbc6ba5d91c94310f18c918e3914bbbf869e1b8721476f9def31b9d32c471a54132481aa89f6c735ab193369496d8dbeb49b130d85fbff3f9cb7dccea4c1da7a2846eef5e6929d9009a9149e39c6c8ec150c9ab49a09c18c4749a0a9fcba77057cdea6efd4d142256c
CT: c531633c0c98230dcf059c1081d1d69c96bab71c3143ae60f9fc2b9cd18762314496ab6e90bf6796252cb9f667a1f08da47fc2b0eecda813228cae00d4c0d71f5e01b6ce762fa636efffe55d0e89fdc89ba42521cc019ab9d408fcd79c14914e8bbf0ea44d8a1d35743ad628327e432fdcfeb0b6679ddca8c92b998473732abd55dba54eefff83c78488eee5f92b145a74b6866531476fc46279d4fde24d049c1ce2b42358ff3ab2ba3a8866e547af
-TAG: a0a5242759a6d9b1aa5baf9a4ef895a2
+TAG: e3b4192f6e50528c4f4f70267f094c56
KEY: 95fdd2d3d4296069055b6b79e5d1387628254a7be647baafdf99dd8af354d817
-NONCE: cd7ed9e70f608613
+NONCE: 00000000cd7ed9e70f608613
IN: 0248284acffa4b2c46636bdf8cc70028dd151a6d8e7a5a5bc2d39acc1020e736885031b252bfe9f96490921f41d1e174bf1ac03707bc2ae5088a1208a7c664583835e8bb93c787b96dea9fc4b884930c57799e7b7a6649c61340376d042b9f5faee8956c70a63cf1cff4fc2c7cb8535c10214e73cec6b79669d824f23ff8c8a2ca1c05974dd6189cfee484d0906df487b6bd85671ce2b23825052e44b84803e2839a96391abc25945cb867b527cdd9b373fbfb83
AD: 24a45a3a0076a5bcfd5afe1c54f7b77496117d29f4c0909f1e6940b81dde3abacb71ec71f0f4db8a7e540bd4c2c60faee21dd3ce72963855be1b0ce54fb20ad82dbc45be20cd6c171e2bebb79e65e7d01567ad0eeb869883e4e814c93688607a12b3b732c1703b09566c308d29ce676a5c762a85700639b70d82aaef408cf98821a372c6a0614a73ba9918a7951ea8b2bb77cd9896d26988086d8586d72edc92af2042ff5e5f1429a22f61065e03cfcd7edc2a93
CT: 40c6318d9e383e107cdd3e1c8951562193c3ef64ee442432a63e2edefc78f32ab07772aeac172cb67ecf4d21f8b448423527bbeb9d8ddd0b46bdb27f74096ceb24e41963b4cdca176676a75bdbe3abc270b349ac0c6cbd9c3a5cd5bce20202fc5cc0c1bdd4fd25e121e0a24bd7bbeb9b19b1912467bf5338ee2ce88aa383c082b42cc399c9654ca325f35523e81438beb3f8926be79c378822d7c8f785614408a5f7cac49e4543188725643e6c1a70b46d0ec400
-TAG: 5801e84192c7267f66b0e04607a39a3e
+TAG: 874875c9a0ba3060a0680291c3dc85a2
KEY: 6ae1102f84ed4dc114bb9d63f4dc78d7dbb1ab63f1659dd95f47940a7b7a811f
-NONCE: c965d578ba91d227
+NONCE: 00000000c965d578ba91d227
IN: b82a8a9209618f1f5be9c2c32aba3dc45b4947007b14c851cd694456b303ad59a465662803006705673d6c3e29f1d3510dfc0405463c03414e0e07e359f1f1816c68b2434a19d3eee0464873e23c43f3ab60a3f606a0e5be81e3ab4aa27fb7707a57b949f00d6cd3a11ae4827d4889dd455a0b6d39e99012fd40db23fb50e79e11f8a6451669beb2fbd913effd49ad1b43926311f6e13a6e7a09cf4bebb1c0bf63ce59cd5a08e4b8d8dbf9d002e8a3d9e80c7995bb0b485280
AD: dfd4ac3e80b2904623ff79ea8ee87862268939decf5306c07a175b6b9da0eb13ac209b4d164755929e03240a0fe26599f136fb2afdffd12bb20354aa1d20e5799839abb68ae46d50c8974e13e361d87ef550fe6d82e8b5b172cf5cd08482efdef793ede3530d24667faf3a1e96348867c2942641f4c036981b83f50236b8e8a10b83ebf6909aad0076302f1083f72de4cf4a1a3183fe6ec6bfe2e73e2af8e1e8c9d85079083fd179ccc2ee9ff002f213dbd7333053a46c5e43
CT: a9aeb8f0a2b3ca141ac71a808dcc0c9798ac117c5d2bd09b3cfe622693a9f8ca62e841b58bddb2042f888e3099b53638b88dfc930b7a6ee4272d77e4b1d7e442bab6afbde96ab0b432f0092d9ca50eef42f63c60c09e7b8de019b32ebe4030c37b8183cc1e3b913b0ce4ee4d744398fa03f9af1c070bed8cdafd65b3a84140cb4deadc70184de757332ce3780af84353f540755227e886a8d7ad980f3dd6fd68263d82e93f883381dec888bc9f4f48349aa2b4c342cb9f48c6
-TAG: f26b3af8a45c416291ce66330733b2f8
+TAG: f6dcad5412b95994f5e4d6829c2eba98
KEY: 405bb7b94715b875df068655f00513cb1ae23ffaac977ce273e57d3f83b43663
-NONCE: 5c6da1259451119a
+NONCE: 000000005c6da1259451119a
IN: f9f143c0c52c94b4ba7b0608b144156a49e7b5d27c97315743d171911e3645ab7957c80924e3c6b9c22ab7a1cac4b7e9c0de84e49fd5e4a2d1ab51d764fc5670318688ec942f7ab34c331dce8f90fea6972e07f0dadec29d8eb3b7b6521ddd678a6527a962f4d8af78c077e27f7a0b2ef7eabd19e92b7f8c1e8fb166d4763ce9c40c888cf49aa9cdfc3e997c8fe1cce3fe802441bbd698de269ff316f31c196e62d12c6bb5cd93fb3c79ca6369f8c1ac9102daf818975ea7f513bb38576a
AD: 6fe6446505677bf08b385e2f6d83ef70e1547712208d9cebc010cba8c16ea4ece058d73c72273eed650afdc9f954f35aa1bdf90f1118b1173368acbc8d38d93ebf85bd30d6dc6d1b90913790c3efa55f34d31531f70c958759b2ba6f956c6fcdd289b58cb4c26e9515bf550f0fd71ab8527f062c9505cbb16e8e037d34de1756bef02a133dbf4a9c00ac03befc3fb7f137af04e12595ce9560f98b612480fcdba3b8be01db56ebec40f9deae532c3b0370b5c23a2a6b02a4de69efa8900c
CT: 1a4b073881922c6366680cc9c2a127b26f264148651b29abb0c388cf6c9b1865dba5a991e1f8309efbdb91bce44b278772c58fd41273526c33fec84beb53d1689b9da8483f71be6db73a73417069bb4cd3f195236e8d0a00d124eed3a6b6f89415b19a27fbe35774f6a1a6ee4bd4350b252b975f0db2d2eea82f4836350850d6290901e726e8af13644e2d98bc1d569c20800521e6affe976bd407049a2e6d9dd23f88d52e651391ecd2fc45b864310824aaadfa203762a77c1d64562dae
-TAG: 0060026d3efc120f11c0739959ae0066
+TAG: 90fcc2544880250f1c3abe8a3761ba08
KEY: 8c602bd94c630cd00c7a9c508067a5a9f133d12f06d9f6fe2a7b68dce4786d8a
-NONCE: 760de0f7b7cb67e2
+NONCE: 00000000760de0f7b7cb67e2
IN: c3ff559cf1d6ba6c0cc793ca09a0ba573a28359386a6ec93e1bacd8e630209e0b477a20aedec3c9cbf513ee6a1e3887112218d6155b9875f7e6c4bbba2c31972e905d19f529f4f0f9502996199f94f8728ba8d6424bb15f87fcacd88bb42c63fcc513759712bd0172b1e87c9da122f1993ffb7efd3a5c34b240dd3db89dddea36dbeb2836d9f8648f8e7cd428c0f948097af753b35f9876059e7702027bb00dc69071206e785f48fcbf81b39cc0343974ac70784a2e60c0df93b40379bea4ad8cac625
AD: 9e14907c3a8e96c2636db1f3d78eb1f673d6ef043cbbb349467f1fe29bf60f23d5d5d1c3b133a8ad72065d822347541c13d1574baf737eb3cc3382fb479e6d5193b9c8e7d2444c66971ef099dc7f37f6cd97b9f7959d46e2cf25e8a5b3111b4d9e2ef906d905f0ee2d17587f7082d7c8e9a51509bde03d3d64338e1838d71700f1b4fcb100b5e0402969da462f26f974b4f9e766121f8fd54be99fc10beb9a606e13fbb1f960062815d19e67f80093360324013095719273c65542b0e31b1a2a3d928f
CT: 2794e6e133f6892f23837fff60cf7c28ee9942f8982ef8089db117903d0143293fdf12ea1cc014bcd8806fb83c19570eed7af522db0de489bbc87133a13434518bcfb9cda4d9f6d832a69209657a447abf8afd816ae15f313c7ea95ec4bc694efc2386cdd8d915dc475e8fadf3421fbb0319a3c0b3b6dfa80ca3bb22c7aab07fe14a3fea5f0aee17ab1302338eeac010a04e505e20096a95f3347dc2b4510f62d6a4c1fae6b36939503a6ac22780a62d72f2fc3849d4ef21267fffdef23196d88fbb9b
-TAG: 457cce6e075ffdb180765ab2e105c707
+TAG: 7fa630c9bcb455e89f13d7a99d5e8dbe
KEY: bd68ff5eb296c71cfe6bc903c14907f7726bcb1331f0c75f7801cd1b7948f3a1
-NONCE: 65a748004b352ba6
+NONCE: 0000000065a748004b352ba6
IN: 52bf78c00f6e5dca2fc60e2e9a52e827df97808e9cf727773860cafc89f4b64178a19b30b46ed813fe00c8f09b25a6a1b6e350d5b005122934a59bfbd5e6e0c635c84a5226c3f2f7dcf951560f18ac220453d583015fdb2e446c69c6e6fdecf2e595e04fab1b0c506e3c6bd5e4414a35f15021e97f447aa334f54a8f1ef942dec6273511b5668b696fca97188ff15ed84b2f46145cce031c1a7f00bd88bb83d90797edc46161b3fda7a2299173496d73b812139556e8b4eb318078b9eb2ae5046e83b79dd3d45950
AD: 5557b08a5010cbc9f46bb140c2505f68684eb24889324bff44b27234fd7a95a99cfb4ff90a8f9982085b725f78ac42eca6ce7f3314e457dc41f404008681a9d29ba765660de2e05bb679d65b81f5e797d8417b94eb9aabbd0576b5c57f86eae25f6050a7918e4c8021a85b47f7a83b4c8446898441c5cc4e0229776ef3e809cb085d71f3c75ec03378730cb066150f07e60f96aec983c0e7e72bf6bf87ae42228dfda195f97855fcdf4e6d1c4479d978abcfa276d16ed60ecbfbfc664041335ce65a40a2ca3424df
CT: a5c8cf42287d4760fca755e2111817b981c47e85b0047de270ec301ca5f7b3679f4749210892b6ea6568f3a6a4344734a0efc0120ffedecf212d55cbcbb67815ac964875af45f735b70092a8f8435f52fc01b981ae971d486026fb69a9c3927acfe1f2eab0340ae95f8dbee41b2548e400805ece191db5fd1f0804053f1dbfaf7f8d6fded3874cb92d99a2729d3faaa60522060cf0b8101b463b3eb35b380fcddb6406c027d73fe701a5090c8dd531c203ce979e26b9ced3431e2b726a7244a20d9377bd62951bf5
-TAG: 4579fa1fdb4c674cc3cd232b8da52a97
+TAG: 82c6194de4d27aac4c54b023b9831634
KEY: 934fd043c32d16a88fad01c3506469b077cb79d258b5664fa55ad8521afdcaa2
-NONCE: c7091f6afbbeb360
+NONCE: 00000000c7091f6afbbeb360
IN: 2bdd1fc4f011ef97ea52ec643819941c7e0fb39023c2f3c7683804a0ddee14a5d1784a5246966d533b3538edc7d8742d27061c3cab88df0318ab242102de3a54d03632eeb871b72c7e8f8065b49f4a91e95e15f3f46b29fd76b8fcea0d23570c5530e3bbb8a6aafa9ae32c1b3eac653c5ed5fdb2da5a986075808f6385870c85b1913e26042a9d8e78f5bc2ea6de5a64f8aeafa22adcffc7f6932d543c29bb3a04614783f948680e433a71573568d2ce984d249fb4fc06a9f358c76aa3e64a357f4eae924c1356bd5baccf7e0f
AD: f737dd85638eb324dd3891219c5eef7c2dd053cfd055d447a411eba304a4b27dce981d112c4540590933c153d603022c91ebd2b4a58069d27e6ca17a462ef822ca41bffa80b43a68b1b564644cb3c5a7f0fddf7a13a30ff24437fddd8ef93c6f6f205d054f81890d982bd4d4ece0b1563677e843fe48c1f54e9a57ed4da66061482712e710a401073be5080d5b8b96525bffa67de5af31d50385fbbf1a87c21bf0e0a1fdff69ec32c7b7103e0b8ee6c844245e0fc84b9f89fcce62966cea68e2871d3b82e8df424c76309fc88d
CT: dd13fbf22c8d18354d774bcd18f7eb814e9b528e9e424abc4e3f2463195e8018576565d16ab48845d11c9277f2865ebb4dc412fd5b27078f8325eadf971e6944c66542e34d9dda971e2aba70dbd3e94a1e638d521477a027776b52acf90520ca229ebc760b73128879475d1cbe1f70fc598b549cd92d8a9ac6833e500c138c56474db84cb3d70b7aa4f293a4c2b4d818b0ff9fd85918dc590a12a8c0e375c4d98b7fc87596547eb960676aad5559834588f00f251a9d53f95c47af4df3c4299175d5211779c148cfc988a5e9d9
-TAG: 476616ea15190c1093fdc4a087643cae
+TAG: aeb0a4eb29886f0a7a12ec0516bd4af5
KEY: f9f6eb9ad736a8f66e7459fef5ec2890188dc26baf34a95f6f0384e79f5c6559
-NONCE: 7858dfc084fe4b0f
+NONCE: 000000007858dfc084fe4b0f
IN: a644ca6e7cc076e87eb2929fd257693fce0f6fb64fd632f7f07c648ebd03696c8e262e6a810d7b7c4e5eef8c65b5323c99dbba50a70b4a9e5c2a9e7315973cd67f35d8052ce9a85a206416dd3031929f4f929b13d0a5fb10cb73c65f6c0ace019da146b51c5274a099f44e3669d26add6f2ff081e886f3cf952fe0dbbe6b0534c23e307574bd35fbd657f5fcbd5dc19fb382a1dc0a2dc8285a0350f71554e4c601497749e35567dd4a273cddc9a48ce53a5f1d297fd8baf8d1b9feb35d9151114345abada4d90db947bb9a743c175f5653d1
AD: 2048d1c2ddfb5ec385b201832c7a993f229ba72ec16d6ebf723ef0c5032b9966209a9e8a63151b40412e96b82f86728ea6588c7e8e11ac71cc8eabab8c4b54de866658d9c5011def61fb3dbe4e630158a45ea41a2ed55ebd1efb1abeda7637de6fa5fd2f151c6d2f385bf6cd002ca8b4a2896e0d65944ee913e3c784669dd201b1985ef3577f7f123a5f9bcffa176c8f557c4f729133cac518642f27d9b22ca9b97faaafe5b669a10b79ace4a7d5727df146c77ce681357d69f9c2d65b4401bd73cd113387e3b3a05d897adad7a24c485e7b
CT: 4146faffd7313f5d9f625370d20413cc62ab65f4acfa3c7ee1125b937dd7a39f638fc46c8ed004fb525698de5d8620ec153435571817c3de257b0d0e648ebb92940c86a98262d54e764f28cbdd4f7d9bea970291f2110414f62064d7229c6332236c507b3dac742e651d85a2a22fb243c0cc7cc2d016e5bea38f33f9a9ce048944a5fe8b078d71d23168e12dfe5a0f0b829771edc7073fb96032b7be471337a37aca0cf7c0cdd543eed686cd34934717fd79a3f18492eef72f9f450b880aa7e2e1b65e3b04c22e72301338b43aa32ceec2e6
-TAG: 10ffaf2be316676da02d7473a9df87b9
+TAG: 61c6d4d6918b04fc1b72a7a0e9a3b799
KEY: 29b19636cdd32507fd98ec4ee26caab1a917646fb8f05b0dc01728a9f4a127f0
-NONCE: 06699d245916686d
+NONCE: 0000000006699d245916686d
IN: 5fdf913aceab1d6dbaf7d9a29352fa8a3eb22718043a79cffa2fe8c35c820aec7c07644b8785dcf7a433b4189abb257fb12b06fae0662641011a069873c3e3c5ccc78e7358184a62c2005c44b8a92254958eb5ff460d73cd80284d6daba22c3faba046c5426fe8b7cacec64b235a8f8d3e2641e5bc378830594bcfb27c177aea745951ee5780a63705727ef42c4ad3abf556d88e3830f3db6b09e93edd09485cbf907f79de61f8dc5cb5fb7665ffa0ef53cb48702f6a81d8ad421cef20c1dbdf402b8fafed56a5361b2f93f914a2380fdd0557faf1f4de
AD: 39116c49cc13adb065b92cb7635f73d5f6bf6b5ccbf72a3f65a5df6bd4a661105015358d9e69f42e98aed795e8161282bc113058b7ef3b9e23fcd8eeab34a392e03f4d6329c112cb968385ec52a7afc98bb8695785af6b27b700973cc952630b7247ce226b4fbb99b8a486370bf6345d4516c52c64e33f407c4f2d1ba90545c88732d98bbd97972ac5e94c694624a9b3782b0099824651cb7567914d25b3e13181a791dbcd40e76e836b3350d310a52151bf835d3c357c9871482c2928e8404c6e533406d4d6fa8f63366f2c4ed828141f1ff00f01a536
CT: 01e237220b619054a1f3670928fe67d40484b5af40fbd04d032500aac5acaa3b4584dd99a58c390627636a50de5d744f76a56a33205f9e3b00e16162eb47ff3333e1e208ca200f1a5338a86e17bd92dd2d16af8bb022a7dc05b923d019e05247f1a0d0b4bfcfce58dd6d83830705707676d55739abee89fcd5cb94b8fde006a5da02df64b00a467f45970b5ca440f22319b9735a55d454b9fba0588fef0c59d3d83823eba6e0601a96e10233826c5adeea6b2a51d386a07a9e047ad405b23d4c3d89f30c31e3199f0c8f927bfac43ceea1f969de0a8c0f
-TAG: 092f9f3c5d4f2570c9946c87967f4579
+TAG: b9fec6da464c7b85b2a4726694562fe9
KEY: bae06b9b5456707551c7b0e207aae02a19b4848ad8ca4ce40705bf8c856a6e52
-NONCE: 9c27065c3ef2d522
+NONCE: 000000009c27065c3ef2d522
IN: 50cdd88137ff428a88e87b5845be4924f6387537bb5c0b654c80107ab5698db75b2e131848e7aec156d31aed0766d31c379fece4095d38264c6d5945974d25f729c3b0ba11ea853e9cebdb6f03bb670fce08adff74d0a8f02d633fb34e0fb7337a8e66e1c12084d914fb6173b8105684db822752c6751a372bb16690284d661b8b8bc6a6dfbddf45ebc2219596f9f2f878c118df69030de38b4d99dde43b9b9e20a3dab691645dd518342f49b06a0fe0a397adf261e99f07af5b0b3798b1022ba0939c42a54d3b93641cffa3c2e174bce9ab7ad7e7c7924308d1a77a
AD: 5d5590db1bd316eb7a0e30e4c7a6dfdbef9d3287fdb8d824389599c3c2ee262b2192eb5b9708e66e22dbc7eca83fa1a995da3ce64c86fe5aa08b826d476dc439497e2d12e2702c63c8d27aa7f09fedee816dc8bffe1351d53271a34d4292b613b7efcedb7e3cf3e6ad389eef12471e9e20e38e7ae22a323abbadfe8f2e84271bffb1819feb4f77b82843cb8757cfae293631bc6d39669107e7015c85d7343ffa6fc1bbe6f5ab4de30cd752a281e03061ea89de2a3f5e90e20da22fd6e8525c100738667f42212b2cf45fcb23bbb54b21c117484b22c6e514685314df
CT: 66b7f69ac49fab4e5975aeb6fa9287d8eac02ac312c4de78f77f59da16cbcf87274e66801c4b862c33ea79cdc76528862bb2956c06db8b8acfac4794ebf39e35ac03cc73a4351a4ff762f681a48d6f25cad36e2814c9b5c40b9ae92509e58429106847789454d376836936bebc7a80e6c66e7aa52936d6b361378a41f849ad4e48f9ee2d3e92217a908fa8eb35736ac8ada7d32ae05391f2d807be3512543c36138a5fe660dd4cd4cd184bb43b6ba6bc0bae634e2fa9669304cd510ed5103f630068ff76d3375738de60a381842b421477e25a490cdd6894b2704125
-TAG: c9998a677dfb0e91924aec9de0afd585
+TAG: 94118ccc68de1921d480aab43d1ef0d1
KEY: 2cb374cb048c168f2e43597f028d9e73cade1b458284ffc260d4fc6b9011c414
-NONCE: 9fb909169bc9f4e9
+NONCE: 000000009fb909169bc9f4e9
IN: 39eb929482784b463546f5d84f80510f2019923d465b99d194246d68c7ae343f91971d8f7059cebb86aa5dd099289aa648248b8c5ca04e66ac5e9bf06776e3883495397618a0227f035666806e636836b47d3d2d255a49db79866cf00d9ddabda259c4f968a1e01e651c7811cebbee2ee71803ea1d9d23487eb221f2d9555756800aba5e6abbefd6fb72b3151cc99ced599cd86df2a9b1ce94f89f347eeb124d9e7f0d9cc48d3dedd819e6d3dbac57ecee199547b266116a2035c9acc4c8ca3271ac74952372897c4a5f2cb84e2d81817fec9d6774f6d8a5b2021684132db4fca3
AD: 0c7bd4f3a30ee944ccf9489181e6911684dcffad4593a9b65a67dfc80718c69b35897d01281016b7731e12c15cad8482e79458e08a755622e3f3f22a23ef6c8487a36ad1771ba06c641f06f85de0db3776cc6df06ad8fe3b4d60d58508de943083f17cbb9dc0d390ac94d8429e8c6fcfe063f424fbde0f62f6a7f91a626d195dc498a6e69bd93109c4e9ba13e7330aba456d710a4b0cc279d4045660406e26d61dff70d4a33c4f1052869f9248024e7a0f85f1effb32f6f7ccb1f860f3ef04e8f7b29096e6bcf9d4b3e0ce703e9bf228fdf515c2ff9cbabd16987be0f9babd3d8a
CT: 91ddadb86b7ebef798ddaa59da51d71316fcf6c9678143178227d778750dc9827fc6cc21e605c505023e6db25849df7fb6fc1ca4d223aa215f8c85b724643c83bf8218815a9f9e2952384e0ca6a80a3760b39daf91a3c6154c4728c2371fd181fa3764753d0b0c23808a82cd8f0497246e3a0f17f8906a07c725d2891ce968a9d432c2b102d85c05510b28e715bb60d0403a77490e7f18be81218bc4f39287b9bb09f50227dd2f55e4fb70c4438da8ba3c8ffbced87d90155913faa9979fc57e6cbeddfaba3d3ab4163c0eebc7d94279c27d3ed56338893dba542eaefba30f8c3b
-TAG: 728e60f8124effbac234f70da925881c
+TAG: 8980e8e4fe796428b733f4f8e1954a45
KEY: f0f16b6f12b3840bbd1c4a6a0811eef237f1521b45de9986daec9f28fca6485c
-NONCE: 7ac93e754e290323
+NONCE: 000000007ac93e754e290323
IN: 0530556424d823f90a7f1c524c4baa706aad2807e289e9479301e3e7a71f2a5e14e6232ea785f339c669af2e6d25f1d5a261096a548d23864945c3a589b67b09b0304a784d61b42b2419139485242e0d51fcbe9e8fed996d214de8717e6a71f8987ccad65eb92e66707034a5ae38e6486e26eb4374c565aad5df949dab209f7f7bcd8eb6fc52761a26cfe5d01fd349e59f4042e6dbe6b232f9301b971dee121d8aa1e62d40f043a42f3aa859d867eb809b1ced5ae1ec62cacf94a69fafd0631a8b5dfd66d855900fb295eec90ae5fcbf77beae267a79d24081bb322d8c4e0630fed252541b36
AD: 13bfcc17b810099cda31ca53a1323db9b07633ceb2088a42263a4cbd6a4d47978776005c9a20203319c3a3ae434e9a26fb541047dc9df38dc36c095267272e203d0b24d119a70a7e96041b6d82b7c4d5570e1e4a1cf2f6e44ae63fe005a1f5b900778c482f7bd89e2e02305e35b8f61b7bb2c78a13aebfce0145d1c5aa0bf1d10d23616d5a3a446de550302f56f81dc56fe4f3700f14242688d9b92d8a427979b403c8de8c493a2cde510eaf6b285e6675b173aa0314a386b635c7577d5aff0d868a0cb3f73c8d2005f8c7c9dab5a060ef80102c9d4a4af988838afe87aff04c0689e8c3c7f9
CT: 2c14c3931e98e84507c4c165c2ed47ad4a178f0e216cd7ac2453bbbf9f85dd06bd8ef54a9ff1fd3dd8e0cafb635d8f2de861a0db5b14d03f17aaea8c89b3010797c71c13a0e666899d7ff6e53c4f08be8ddb3e37688b5afa088079b6c7519b833e16560073e699530302028a3496e05edddec01a23a4c7983956250e8d9e616f7b940856955cde81c1efabf6b7b92f153d03f4cd17e7f7d2907670cfc84d45c1d7936775a3fce47968504278ffaecacea0871b227f250e2979516f6fa310fec0d8df1af7872e5a534e82870aa05f43ef0a455846b93ce938064fa33e92de262e4156dae56775
-TAG: d95d73bf9aeb71eba9042396f3725424
+TAG: 16c972829819b8fb030b2c5f40dab717
KEY: 3792943c0396f1840496917ce8ad89608385007e796febeea3805f3f4cbeccf7
-NONCE: 23b2f9068b2c4c85
+NONCE: 0000000023b2f9068b2c4c85
IN: be6b67eb943ee7b5c785cd882f653e73a8f75b4a41a2a7c56ae5a10f729caf39948fe48ad0e51240e2e7aa43193c7ec6ce7f4909fc94c9f99e38e6a0ad7e98eb29c5c2e61c99e9cbe890f154185cec213a74725d23c1a4e4d0cb9b1a36b78c87e5eee20d2aa29aae80d4759eb0c51c5dc3a95bdbbf7e14eb434419a6c88a954ac03d0c98739f4211b8732acd71c297f578b8cb64ccac45f7235ddc7f2a3f5f997525c1ed39dc550126cdf9cedaf55425489085e91b170be6205a5a395f2dd4084a3e8dbc4fd8b13252f7effae067b571cb94a1e54aba45b1b9841308db0cc75b03cfce4ddafe89ce20f2d1
AD: 7eb6d7b7bbaaa3c202a4f0f1de2263767169eb4a64853240d48c0f8d5d31b08d5baf42977614a57aad99426cde76d242cb37d2956d8c77dc4fd62a3abf30e8ac6cd58c8ef35e67497022960138c57787818892460f3bfc16e37ff388b1edc6ce2bc53c22717edc7a03d4c78b0dbbe9121c7fd8a3e3993b87a4fe389bff13bdae3b349de0b6db561602c53f746022aeb4483c723b67825042f4af20b7dd1e6031cf54215266295c524ac8e1370424c5c5e607fb3e23e97c8eebe64656775edf616422a8b974e1acf13ab45c9a367a7dd9b2d62f48bbc05819b65eccb813ca813f57b22ee4c280dbb5a9d8d5
CT: 0b316ab2bcf5359900fa4082d5d253b49ad94b70e3fab544f98bd111cbcef6766cf953deec08cae1f489fe12f7acc0032db8a6b0c0eee0c206ea5fb973feaebf90f690e840094db5e13fdd7157ba127368c995b426529435a1bcdd1f14ce9125b8a0e4c96b6ec09e3c36a180adf81941c002d19c19d53c2009be803b987504606b7d43bdee5e0b32ff23c466b6cccfcd0d4e88fd1332e73712b5ab725c1a383e584f34f80daff29d285ae5e43cf1d0cc7a828e75c25daced3a581a93d7a50f313b33f38dddfaa23cd5b9914797db820ee2400d52bf5fa982277fe9b5881ac42981633b3957b0e935051828
-TAG: 01973ee2e81cef22751a6a8831d752ef
+TAG: c549aa944d6d97e52e0793ed572682c0
KEY: fe4be6054773f634356ac328591fbc6f833b0d1beeb38dd5b6feb7481b4489d4
-NONCE: 0b3f16f898a5a7d5
+NONCE: 000000000b3f16f898a5a7d5
IN: 76ced1ade6d1ef4069afddb32e7432d4ff2fd06685121f7b16464e7a72d365744f547d2ccf53486310e38b42d8bacaf711e54c5458d2d68c4dbcc8de31ab6732f4430e88a64565f5b287640775aaa2af1cc461d3e415bb275c6246b1b58517aa72667eae291a2982eda175d1b22c5a58e6fec2b3743d55712f201ca24ba5c0ae8c25724871b2ec2fb914a8da5a52670ab9b43a83b8568ce74db5c634061cb80530c8070c38b8f48c33ba136cb9f2158ee7eda8b65f2192fc94d1291f182f101795b7190c74b319d2d3e02a97c824d9c9471a83797e4936310b207e3a1e0bcf75f7c3e3ee48a747641cdc4377f2d55082
AD: 834cd775cbefe4b33a3ca53a00c06a3c4a666983e4115a029f15729460daa45d1505e95172d3695625a186b28b8be173a925af04665f209267b3c5123e8be13da447ee1ae856bb0925f35aaa76e04a7bca8460f76c2024de2149f38a8cfba81694b854885d72568105571b6b213a0bc188a44cc7fe13153cbf261401b238cf12a95e23cb56f240114f16e2f1e3a514615aab4449c0c49e4d900b0e17d1a8dabb53d43dca32fa052d576b73dd9b40856b515d6d7efc2a5c17e0ebcb17bd59dc86f22ce909301a2652f134e82ef0e4519487ed12d51536024f2ae8f75d937c42d003076e5dea8de0c684cda1f34253d8fc
CT: f8defb6fe95dfec499b909996a1f75a198a90e4d6c6464d00a357a555311c42fe92dbbc4b79c935e4f0b1a95e44fdbc1380bebabca28db4dd0d2870daaafc38ef27908c3509e945714801cc51f1a07b2430c74fa64f2a7c2f7fd1551d258c9c3be020873fc1bf19f33ab6c660911dcf2317195d0efee82d20ec26d22611f9cf86c51a64e28b3a1f344500018e0855c88dae3c07acaeaa10b60388484dce93e16e6e1a6e69e899806648a92568c8780e9f4baacd98cbb353ac2f908e775d92303cfab843f15be0e0c322a958802fb1a60fcc7631f151f4c2b8cb965d2d296acef250275a2fecc0cea803ce7c058b12dd2
-TAG: ade515091930dd7861b27f78a87ef60c
+TAG: baf9a51180f172e5c0cc2c946ce55055
KEY: a288b11ce5382ec724ce4ab2d7efa8e777e91ebd04367935e15f9dac483e9596
-NONCE: 874144dbf648b325
+NONCE: 00000000874144dbf648b325
IN: 4c9195280a79a509919af4947e9e07231695fd7c5088539f23936ce88770ce07d9ad3ae4a463b3a57d0634d3a77ceaadf347a334682b04be8e58b8e86fb94a1f93255132b8cdb0df86f5bea354eea4e8315fea83e3fdf6e58aa9f26e93caa08e5e2551a94bd916a51fed29ec16f66800cda6a0aa24ec308bf5fb885afba272685de27c1edcdd3668048ef07b06e90d464a8aa28664903cac45e154e8e1e39c257e1ff506b9d95cef4f300bb73b899e7828602c3c1d290b8cf55ee5fd72ecce9e6efc9293aebf674a70e2a7673e75629c12950622dff71d3ec0992e57776c788c6927d30b4e24b749191c3ce8017f0ada6276e43720
AD: 04abe8588c8c8c39a182092e5e7840442bd1c1149da102c4ee412bd8b82baa5087ef7291b5cd077c177c42770b0023e0e462b06e7553f191bcb0315a34918dcdbffe2b99c3e011b4220cc1775debcc0db55fa60df9b52234f3d3fa9606508badc26f30b47cdb4f1c0f4708d417b6853e66c2f1f67f6200daf760ceb64ffc43db27f057ad3ee973e31d7e5d5deb050315c1c687980c0c148ee1a492d47acfcd6132334176c11258c89b19ba02e6acc55d852f87b6a2169ed34a6147caa60906ac8c0813c0f05522af7b7f0faddb4bc297405e28ecf5a0f6aac6258422d29cfe250d61402840f3c27d0ce39b3e2d5f1e520541d2965e
CT: 0afce770a12f15d67ac104ba0640aab95922390607473cbda71321156a5559906be933fb0980da56f27e89796eaa1054f5aacf1668d9f273cc69071b9e8e22af6a205a6a88f7ad918e22f616bddbb07c78913c7e056e769e6fcf91c7600c2740212e3a176e4110cac9e361a59a773457064d2dc652dd115d04f1c3756c0e1d39f6737a16b4508663e310934c49c58058b3c7b9af7bb2334c8a163608c42499658986927cda365e2aead3ac29de16e47e954383ea566f8fb245a4e5a934c767bb3bf7e0eb8a477fd0e1f61bcb238462a0d19c5cea9293ca58ade76829413216a7882cd2846323046694f78cd8b0347792ebb75abdc1
-TAG: 973e58b1b8adb176a6f1e5c963bfdc5c
+TAG: eb9b2ee43e9a3ae1e33561800169d868
KEY: 65b63ed53750c88c508c44881ae59e6fff69c66288f3c14cfec503391262cafc
-NONCE: 7f5e560a1de434ba
+NONCE: 000000007f5e560a1de434ba
IN: 845ef27b6615fb699d37971db6b597930a7ef1e6f90054791eb04ddfe7252b5f88fd60eba5af469bc09661c0987a496fa540621afeec51bebda786826800943d977039dee76235248112ff8b743f25ed5f3cb0d3307f5e118d84fdbb9c3f5531bc177fb84549c994ea4496c65e5249da987dd755d46dc1788f582410266a10f291c1474f732183a2a39afe603771bb9c423fe3e8906f2be44a0c9a7c3f0ceb09d1d0f92d942383a875c0567c7869f045e56dd1a4d6e90c58d44fe0c5760bb4fd01de55439db52b56831e5a26a47de14249453a4f8e7da3cb3282c6622916197ebfaad85dd65c61e7d2d3ba626276366746f396394c1bf75f51ce
AD: 51a3588398808e1d6a98505c6e5601ae2a2766f1f28f8f69d1ccbcad18038c157b41525be58ae4527a073748b7a04809e52a5df0c7988417607738e63d7ead47db795a346b04e740186e73ccad79f725b58ee22dc6e30d1f0a218eda1791e2229b253d4ab2b963a43e12318c8b0785c20fca3abcf220c08745d9f9602f0ece544a05736d76b12d249699c9e3e99f3f13cf4e5dc13a04125c949a5b30d034b23cb364c8781964bc6c30e5e5ca9673d517ef5f35965d8a8cf1be017e343df97b6bee37b30638b154286d1f36d2f9a0eaa23cc484eac5a05b15d9efc537d989dbc8b3106c0dc1a56e97e6aec2eff54a82cf7ae9df2af46b4c860f83
CT: 027b14197b4012256b133b78ddc94e72fb4d724fefa4ae329f5a5fa3fa784fe6d7e1e805e3f7a75557de64de506d38237b467fa577efb59e7cfe2356bed6655c5aa4e238dcfeb75c16549a0917268768a96acb5e20546a1fb7e3a7cff887f49f2cd7a135f72a98a779150f3207bf733e88861fd79eadbf77fa3bfe97bfe8b6a991cb3bcc2cde8287f7e89384846561934b0f3e05e0646e0e1907770df67a7594161a4d0763faa6fa844080932159999d528ee0558710058ce16f97d13ac9fd9bf5044191188bbfb598d0fafbdf790b61ce0781ecc04218a30ded45efd498cc9ba03562ed2b4a993ee98876b3ab7a9bc07829f1c4ca6ead98c06b
-TAG: e4d18a701b8308697b5e79141ed783c1
+TAG: e0bf9b6837428843f5a233ee5ddb8a1e
KEY: 4986fd62d6cb86b2eaf219174bec681bebcdef86c8be291f27d3e5dc69e2feba
-NONCE: d08d486620ed2e84
+NONCE: 00000000d08d486620ed2e84
IN: 3a22ad5de387db4fdd5d62a1b728c23a8dddc50b1e89f54f6198b90499f9da3122ebeb38ebf5fdfe30309734f79aff01e3de1e196b35bffa33bae451f31f74b8aec03763f9e0861a34fe5db0b40c76e57c7fc582bfa19c94ee25b5e168270f379bf9f8a0a18bed05de256f8f0dd7c23ba2ff1c7f721409462f04cc611ad9bd4c3c9acf30742acfb9518a6375cbb15d65a1bc6993ea434894f93d4f6e05996ebc1bd56579296309a2c6b8fde95072168b5fd31927c4c0abaa056bcd16221d5f220be47591f43255013a262dce439817f534830ba82155347e5fe3101f8011b89365a6568214ed0661914e8cb3431d6c8f2347dfc1209a3eca4aaf0a111f47fe
AD: 7dd3f656a03c001b45ca0680bc3ac9d68c6e96b591d3c69eb8c65e489009d845cb331c98b82e627e06d5bf01e74c573df268c2386f12628c019951d42f55991ff20d72a7b2c45f41d0be7af428c92f324aaab8df70d900301cdf09a3d93eb711c919d34a86fff9cb078322ee2e0ad48dbdf3b7884f0f2dc5c36262c59bcfd75ac6200f59c6fcd0ce10ff5005fef5df8f0432377dfbfc1db8f559e27e1aeef3380ea3864867d36a25a18654779a751586cad3b8a46b90864ee697b08605673b8d2123433c020a21c4db243dde2420c12fd4d54a2704a0c8c376454a1b5e80fd6db89aabd56d9b421f29649e474824dfa56cb5c673c504d10be52b53751709fe
CT: c40180afd53001663ff4834110f56e6b0f178cd3c0e7f7de5d0089ee41d8403ffb98e84922706544a344d7e2625b12cf66b9c966f9f57d7b94e3e4b34e6f0aaed1763ce012782e2f5e1682e6c343fc7961fedddd0919d0b910e9923c17e36406979b256b85aec24ee352f03b48c1302eab419c83dccc5372cc059e9de596224fa70098eb32fc9579e97917b923914fa2efc30ab29b457bf14e45583b3771486bdc0876f3ea6e1a646746c4f8c5cb2641a1557c8473e6ea67d4811a67485ae9a678ff3a2408ca845c3b51957e189eef47dfc1d46bde4b9d754d7df13f828ddadb06e4ebddb5f0dafbdb28de4c5e6078926f20cdf9e97ecd58e309e640f74f06
-TAG: fd5e29332832a14a31a9ce2ca8568498
+TAG: 2e8eb9ff4467c0f61c2abf6ca10893ef
KEY: 7d28a60810e43d3dfa32e97c07957ec069fc80cc6a50061830aa29b3aa777dfc
-NONCE: 47738ac8f10f2c3a
+NONCE: 0000000047738ac8f10f2c3a
IN: b50278ae0f0fa2f918bb9a5ed3a0797c328e452974d33cbf26a1e213aa20c03d0d89490869754abf84dbbe231d7bccdced77d53fd4527356d8e02b681fc89a535ae87308bf7fbc26197a5ea85bdb3aa033b8da5cd197ea6d72f96f63b03f4ecc7adedf399a5043776cdb32c08f30b77f34df85f8adb8e02649a04b020b03e17d445ca63e4ed73ae432c481392e031eba2f9d2f7f981d1e50917822bd6ff71c239d33444ada3523a59dfbce5457eadec1ab926c9e6c5299c7521e3f204b96901a712504fcc782e8cea80ba12a7f7e71cec3d0871899b6ca059061da037715f7d13fed01c9cade1e687b4fbb1f4ac4b040db3b43800f112fb900e4f772d61b921cbce4da6f
AD: 324292813b7df15bc070cc5d8a4bf74ead036430be63abc43304cf653959a24a91c7de5a671c50fa8a87e21bb82b069999aadfb6895d8bda4c3083d17b8ca55b9ab1511ed8c4b39d8c28c11a22ef90c08a983e3fe2d988df9e02b16a20b24f39ddb28429625f511db08298c4dc321f6c268fc836a6191df6232f51c463a397a8d8b33374abe94e62c0f5c322387e1fc4a1c1980a04a1a3c2c31b32f183a11c3268c6dca521149dc16af120a78be6627210e8ddbc44472bc24d66ce3681c7579b3d9a425212a704a4f5105cb80f0d18ee860953d10b59c114826779bbc368d7a0eece9f223e47cd8e5fd453607d101d9d9c2bd9a658d6520b87d7b4263f6d845a524a36e4
CT: 2c217e969c04740a1acfa30117eb5b32dc573df3354f4cc3bf8f696ff905f1e640f3b2c250473b376622e0c9bda13b94640521be1ef0fc660b4c10dbe2bfc093030753e04f6aaecf813b43b61f960455974b8bb8a9b461d1e8fd3802315e863c00448f24dd38deb90e135493274eb14ccbde15c50dcad734ed815a806be6622492a84cd062e3ba567b909a205a1d0d2bedd40169697d261c7b6c2e0b1f069853fd470e8f364a142c386c439a6dbe192ded5a3d0fbf73799f588c59e58c60249d980ddcf0d9693631cd9b3f972509c3a77123d38d9e267ecad06e1208e3f1c0a69fbca7c3bb1a48fda19493d0f8f48398820057b94120f3ef97d87e9e8a1b301a2534c68f
-TAG: 1fdd2dcd935f55822bf7231a516ca841
+TAG: ce507bdb0c71f8e89f5078495f7995b8
KEY: a76e9b916f5a67b78a5949651c8c3a9741a1bc3c41cdf85fd2c8f3e9a0616098
-NONCE: 0808da8292dc14e0
+NONCE: 000000000808da8292dc14e0
IN: 9c149eeb09345c3c22462b03e49eb4dba6bc98b269b1086d752bcd8eea53b8977b238a04a994baf915591686baab90b79a3bf7d9adb2c6c2e31acd3e72f0813fb745aa5fb2e3da408f78001c9c09bd26a1a2646011b6120aaa2bbacc4a16c39fb5257b9b2ea2ad8bf70bcc9855cf11841116c2767310cf3cd49d1aa44cd505f079761e064d5bc7cea4a7173b086882a77d3fc179efc86fc4db8a373491d2ed81eabc63c950e832db17d09f474d4ec46bde47830caf26fabaa0372b81fccc449c0e19ccd630caf693a7b43bb1c408a54e03f50c44280a05ad89fb6e8f01d8ac278edf556e5d86ceb4b614fb2ef133819c6e1ff6abb86c54a135256204b5cd400b93624d3932e7c2b046
AD: 6aeb7031e4a2e23eea93f05fdc562aa2bf43b8998bea7344377aaddc60fbdb7bcb1491d379ed0cb613ee757cfb66490db61bb431d2fad34b38ddd55bc5b22aa6c4773b9992f34b878c5663f6e8cdb5f80a17f4d312bf342492e48d1ce4c6d754076a634fece61500acf8168d47381af4faf980c6cac2bfd5da8c09b6edb0f543bf0fe02643e38d73fa37d8ae87fb66193f22e57faf4393c007d48c8631a685d520578f8f89db684fb371ea02f3a58b1e2168f0216321139472e0d03b6d90ba8aab65402e1c1ac4f9172a60e27e3d997b9b05e2f672120d6c87bcafa6d4c9b4cf8ba8a82932d92840368fc53dc5b48526103dcab5f1531038aabe89171327ac559b98a3cf4ea70bf051
CT: 9c3faab9261a63cea9477b3269007283995b06ba77ef83d9e693f7e4ee9855550eef94855be39a7a435b6a3584b202973777c7b2482376ba47b49311947a64983b60236756ee4455d4cfada8c36af8eb06b06ba2f6b79ffb1185c89f2b2a831cfaa3855fc1841d8910908be5078352011168a67d36372d851a3217cabf593ea462dcd325cf9a4f67e85418fd5c924e9b92ab026cbee4e7ab1067066cb5949dfc699a68fe539e1abb13cec33904e5207e6963d24f5a0b770613b8b00014e791bfff88f9c25ca126127a2f8d1d1e9794efd28dce98b53e228073faae8d5047530d502184fc341321c3f55fcbf41187fc31262c325b97f519959b6a29b36c71f76f60196bb1457b77c8bb
-TAG: b45df119043d29008fcef36a169ef886
+TAG: 73b00b1705602479aab944dcc1b282a2
KEY: 98cd2477a7a072c69f375b88d09ed9d7b9c3df3f87e36ce621726f76e3b41a1d
-NONCE: 77d185aaf715aa48
+NONCE: 0000000077d185aaf715aa48
IN: 42b31eefdacab0f03ef6060156000c8195adb0976cabbe1a42bfcc09f85659c60b98638401f2d2e2facfb9a97a62926bb0cecaf3af0180a01bfb6e576babf7fc43331937a92abd30cddfa3e450f895e9dd914dea3fafd759c136d685310ebce28ac0613ccdbf30115946c9634b67510b77d0e37f07714b2ddac9d7095b8d4bd887c132c4a9127eb01c8dedb4c39c87b98a741316656f9a8d5a5b0c0ac84789aa2347a5f99ca5ad55cd1bcf98f703eb4b00badb8a8555f38b3b368db8ba7ceea94e8b219f51edce75d84166b5602156ed5962a93a51db73c59d87e906179d7a74a2a2a69d8ad99f323225c87e475d3f771b4a203a2e2b03b458401044649fa6536dfab24d7037807dcbf6518e6578
AD: f5bb1496052a4361dddf72a288e36953a3d815d6876c013f1d6ba839e127f721b052b1f7d8ca20c7dc0386a7d459ebd7eb9fc8cb08941e6ca9ddb980f3115f65bc1928a414d441ae71dcb879d5bfe0cde0562bc37f8fde0d5291ad405c92fcbb860c43b55ac0fe663b54b3d0616aca13a5c82b7b5d34125a05c2acb5530141030e6f2aa0c8322b2c8fa307e7518918e550e9f48921c6168f094d8758e16b9f815fd0458095c4143f0922adb1840d0e685636825a9c90ee90ee537f4b8dceecbc4287c82dc9a00d7e51671e37ea284ee3ca501b1b2596459d3f592f70186f41125739e342c9f6be9241973b1414dfe5fb8cba1af82e679278cfcf95420df0c5364af4d7e72ad57d5c871fcbc35462
CT: 7a3bf3e3ad5ae3ab71fb1f7121c3d8fb511099484b50af7ca128ee0337ed4b828dc4cde0b88dc1e8089101fa82c9beb3eb48fdcf0f5b16da441f5a3fce9a590022af95a94aed6a3e71e505f60f303c78c356f274ea85a55354078530664ecda32c80e77dc20974b3b38f4825b8fbee8c3970769a2f42c5181608a8d7d76ef4d093961b665ee42b9708fcafe2c82d3a307173e2a25ad2528c3bf83352b9265e45b70722d7cf8c9b80826d21335234ee3db69d0d37871c83222365900c96c17a7e9f5742d0bfe383be24d0d44590d4b0f29f7abe0c65daaffb968b3f2657b1eb300534eacb52ec7a6b6f9f57a50a91b1799f491361cf613c934b7f520dc4eeeb40ffc45e10be0a95e76f366d4eac14
-TAG: f613b65226afb64c614fe60d9c71ed74
+TAG: 69302888812eea030d621b640e7bcf7c
KEY: 2f0f4631ab1c1bcf8f3ad0559c818d50e0af7d8cd63faa357f2069f30881d9cb
-NONCE: 7d0ced2fdb1c9173
+NONCE: 000000007d0ced2fdb1c9173
IN: 6516ba1d29357144eebfa486d21decf223da3aa76ec29bbfcbe7f1eeaf4a847710e5080177f7e5a7c8b4752c219b1cc70aef4db861ba67d0fa6222d9f4a1dc756a0ba44e62906f9374a960c16198866d867854d88f528a60e212eb91645787e75685b2e215c0a41990abc344a77236ec0186ba63a664592938cc5a8ac1d3eb99c95ce00e19fbe249263083d85b052d48bfdffc01585dc57bb2a2c6c4a819604c1ec0548c6f0f78dc05e4418b36277dc07233c7532f9c289d6aed0cc6bc7df4fd0a536c497b982e2dad2c30d2db1c6545a845c5dfa83a4ac49ef06fc9c919079d3e299e31b5c3be370814ae5022ae469d3ee55246a41bd0dc4e64351cc38c3c09af0a1aee3b388a6892deff0df3f93cd92d722b
AD: 1ccfa1ececc8de1e200d0ecc19dcf67b7c96bea3a282c2bccba61035db5c14776387b8b8f58e5757deb0129d4e5e315f64df354a5985d2e47ebbbeafe0c914f7cf1d63dd0311ace19e69a8b6ff0ab25cc8df0408d22132205e89e5eb679268d82b2913e64e3f885bbf4a6d379b760b94590e3140dd7275ab4713cb56d0b716e2718f11316640cb394802862d39e77a46d0c065af3caf7dec14e887039d8aa8c3d3a8ac1ee06026f49d00b2f59d971b54735e95a51f199389a93a4fc24ebaba1f7a2eef7412f61febf79084fbf481afc6fb6b204084e5ef5df71f30506459dea074f11fc055cd2a8c0fc922c4811a849984352a56a15659b7d07a4cc90b88623638ea00c4c8bc13884df2237b359f2877aa41d6
CT: e580093789ba17ffb46672dc326f09278aca08598d3e5458eaa53e6ed45d5c71a396e35b5ea3fe7b7c0496a734d24f1c75420694be2ff095d5172fd3407794e4b99fd7c374fbe8d1564a048614d3f355bfb5866de1a53e1a51f9f5e8312253cfd82f36efaa1898c850ca0d975ad1e8b0d9597a5a9e6516fe2a3c92efb7495557a8afc3da15b0d3e2ba58f612519836946cf2d15b898320d16a026c8c00a1be2e35f0ebe68f28d91c6c45d24c3f3c157cb132fa659b7794df883d90741fa2d2afcc4f27858e13ecd41b154a35d24947ae7361170060c107d8ecacb393ea67104b60457278a392fdf1794bab97d3b02b71a4eb015eaa38a4b4c944c2bc7cd5e329da4a1ab2937a6af81a6caa5fce752331fdefd4
-TAG: 0fd7419c54bc84265ed310a3411a3f2e
+TAG: 19bbacfac768bb0ce71e39c5d4d3e9a0
KEY: a48b9b6df475e566aba7671fbd76772cb0eff0b12499967978ce3e25fac92feb
-NONCE: 2ccbf0d6c40cb302
+NONCE: 000000002ccbf0d6c40cb302
IN: 09da1cacd001dce4f7573a065a4406fe0da04ab367a2d87780a2762e168957a88d3fa78f0a4b6978d449026e5a801d32884b6e14fdaaaf864214f928ebc03dead081fee96683ebb032362d5088c4c2a3b1e242f055f2604919f4dd551db777a258cf9da6d95a2bde249247812b9efc7985cf08707620808524d6dd3079b0b63bf0f71ea5de834ccb8b7c6a97125fd6ca49148e866d3134bbf1d8a6b714e9a80fe549c8bfefe342f41be2ba2300e0028f78cefab65274632dfdbe70bf7d655ec4036df561f2d4fc4d56a482bbe2f9f2ae279b3aa216b39afee75e53602de319484db89a51e844f38c361634e474f8f1f01c340f3f3594860d671346449c6d08ee38de22d246309bc7e4a252a29c86aa6d94b5b4fa58904c70
AD: 1c2503d5aa1aad193f0da12874074ea0432bb76a61cd43a3017061514da0759846a0f3ae3a49fdb0b6d29f713de665beacb6568f2694112ca380d13f3c1698316866a7a7f87f1d7503a92176ab84fc08977b46ba664508a858e7525753c45511b3d2f407d5e993c6ede77f13d12975707e5195704970a89f71fc30828049f92f944f3aa93d6a5297e678e08952919beb7eac5919df1919cab3c3da6aa696a1eeab6371f310f7e81143e7d240b0213ae554524b52000306160dd4877bf13ba0f13bbe867da7c7d707f31335eef4cd942938ac890a0829ec66bd30ae01a2188a6e5ea0f17cd7dc875e17f03c0ab5dd18e36db8a1fc1f72859ee046b62368f168b3bea2234e0432c07b7d8e1b9277f21e692c513b9e816e6860
CT: 7d35cfe4be56bd6e0e09dedcd01735b915bc1891a4d1f6a541abc4bcd0ebe89dcb8e365e5813742e8ec65777b6159422fada747da99394252baf8a046fc1b60ad79755f545f4448627b7acaf403000894f5641e78d3f946dfca29ec617f0660dcd6e8d8827e67e1022a245c595d86e60fbd176bf721b171bbe5ecaf4ae671b9f3dd3920146e6ad431bd8fc431820e19454b6ca209723d80fdbee187fca9c937c979206ae97be55f6ba7366a5608770a11d537396485eb0a66586385f4d4cf3905d1fc90831c3e136d5d513fa22be285193142994a3ed477145bacdcbdd791e8b3b88b0d4f1d18b27382550a818c4fd8884bf36f677c6c3ff5677406e510911e696af75e5b3f859bef699bdd16e6215fdb98d874025eada50
-TAG: 2aabff35611b3e0013f6ae0df130799b
+TAG: 0fa4cb2bab84336409aa4349ab99a8bd
KEY: 923d4b086b9e43b986f7b65e4cea6113a3d8aabefa89323c5e4d5b6f158bb7e0
-NONCE: a0f73297b87f5deb
+NONCE: 00000000a0f73297b87f5deb
IN: 21435e8d5c8edf0684f58c2cba4070c10b4801adf46b6c4d322eb3990a38a9ad338ad704b9df6597f3e68d66cd5b56290c8466db2231e56d6bcb9c44e1bd081f42ca2a894dad369df2bd0d2c63d6c881732d6ea22bb22b5bc9a62eaffa1b094d0845f6b966d2cb095e7b3b8bcbc15e707449d35c8df4aea30c3b7243e977fffd59c80f1c5c9af4bb5a54b9c786fbbe8d21b2b906a87a786caed841a34a3e0cc0ac3209d83c58afba19edd63622dd261532d2cfb0b49d527d8eaa0887a087f5129d897f665264b229f860363d71a88b7d49c8dc6360182b357b0662391bb41337f46010ac32b9fada2d60a2efcb99365d3b27b7ac396900d1c821d0df8b86cc9cc1f2673259a33efea610bf8e1d00d7e9db2afea21da8f58c55f799999d
AD: c853a8b39c0dc597d562f123cd221e4104b65423a062a4f4ba890ba344feb84290f61817e23330c365f58c3583ce08360d3c1171982ead5496d525ac878f23a57480a6ee39d4e65afd6268245bb982a2545fa1195427cdbbcd404cdad5198f55cce2a5a028fae435f71b15921d066e8d43766c32b2f2c3f57c0674e129607dcd3703eca529414adaee79d81fed432153cceb6f3fc53404810d8ec878f7d94be5d379d0e0e1aa9bc404b4b5d396038a9d76a5ce53c9f3759b8e50fb331858ca58cee81bfc3ee58baef5d19c402a3dc8b36370ec1ace5a4aa2527fb94b4f933a4ab8ccaaf6a5af5a779eae5667c2a24ab027e781c8d4f30c377aa5885a2fdaf6507d18cd824a847c35368b4ea984d2c3c3824a5b8ba3042e1852504a21a3
CT: f2e21052eebbb86a4f5e803360855d8632aa727dca6f5e79dd74d7aff106e442001928d113005b030f8446f8eff2ee951db663978abe43090dd5ad2c51ba97a0ecf988c607d95e486d02524f690fa3c28d5c48c1f75c1f555e7b43fe7e46f2ca2b9fdb408ec4ba18b6cdde2af673183cb7b1a3c23ae77eddd4cac75e1ea14743fc571f8d31ce2e96787524cd48aadaa474181c096a032184574ddc25a6e0ac8441c212bc36298708e33c963ae931e6c6241d1affeef7b6ef759495df44b6ab647447693cf703569e69aa72f1def9a342b8978c1edea9703a421ca75b92cac4de14b88c693200022b8a2ed22b1c4678b99f4d695e080dd1196d7168e14f0d0f8ff880d742e97b9f6d00af1f7118e10b77c5ef3ea6c52f84a20fd6ea46dc
-TAG: fa8ee13400fb3f63b899df582f2fec45
+TAG: 9bd8b7743c056bb2334833afd6143e18
KEY: df73adab2768559ea983cce85453fe81d79be3b3c57f202b31b94d6635cf2e4b
-NONCE: e7a87e6bf6b5a354
+NONCE: 00000000e7a87e6bf6b5a354
IN: 0032a37abf661faa18c587fd2aa88885c061deeba81105dd221969bed5d59c7204b09b1a8c4c8de3b9f748c7fc70626ebeaca060233a57b102221b1bf0f3d9fdaaad3d2b1439c24d08f9c67f49f3c47128f92ee530abf4c4f4573bc60ae4b38109f55bca3ca9e1ba9f9fd6e34ba0d174892977a53356e1f5c88c614fe3ff3b3dd0818e7a2285412e3b37444bbe8a80942efcfd03958809a6966cda9430b2f0c9e552f4bced6e19eb3e85fc5758bd7b588297ccbed37ed94c3adc8c08ea8b058462aac9d57a939ec711bc4ecfec944d2b653b7cfc7b02a65d7057c9fdadd51b9da8cc4a3c68dae9da8b9c5319c1a2baa3d6c891c5ac4a39461484b5a01abc64df447ada24c04a4363e605eaccf339a9aa515e724206206da6d22bbd2f52e64cd7c895
AD: f833e5ab4f8bc89167f80f576b1d6b22cdd0e30721f5f735799746cf645b6eff531d4c7b03584f3dfcb73cbd35ac42736216dc7f0de098a4f42c61ceb4b227ee288e47d697a0a76afc762f084e8fdbf9351c28340c324771c109a469341ab10ca10483ed2af5e878d7d3dc2bced2f72da3d1a25852b103ee9878e8158eb4309c1ce528f3a178ace153b6d3ae0af0d577cb3cb1540489e80427f792217ad8a09b84f027fca7ceb651b4264e98e94b4cb8a37b133390897233e8ba9103628d05b9609e8552c4a4b11e3f2fa8d56af36957390e88cba44656be3edace798cf8cdf7771bac338a256bc3cba6df97728f222f423ca7c6d149c9372d66163a98f79a234b00d4b75fb2ec860dcc2d1998105e4b9c01d68f079f3e0aa21cc534047fc7b858f8
CT: b842eadfdf431c135bd6581d3eccae54e2267d8890036aa33dfe2d2d9715c44625441210a3a0d666d708d30588fe851ec36e10d8fa3584ed77b095149494b7c54379d62c8935e1d2b9a8f47e4759ad0b3437fdf2cc2fb6c5ea25ad10e0bdc9dc5b0517fc237eb783cc461c46665e2b1d1a5b8008dbf409ea2a63fea0276de23a32c99d92a498807a0f95e208fc6262321a78aafaf0cc3f833fff37bd4efa66f6023a25cdc6702cee3912799563d908a5183c9956a06aa71085d855dc7c809ed6e2889592b361ab3ab39060f8e419152187a794a19c2a1128882201900ea2cd597860674bf78d9720643df8701676718fd201baed4935a88e50558daf86edd08a9ab227ac7afae55c974b68de8dacad4a4d79b13ed6dfe74017a4cb9148e033436fb6
-TAG: 184095b7a8190abec08bb72d19eeb103
+TAG: ee1ec36804e1d5cdbddb52608c711fd8
KEY: 55a4be2448b464c2ea52a2f2664ed6aba865c14ea1fea77f4689331fd105c8d4
-NONCE: db37c0a405b4626d
+NONCE: 00000000db37c0a405b4626d
IN: d266e66272e5d3462081b004cb42429c8b9741e9f678153754d726f6f9aa513464763c5e793b482fe512fece97585f1426120d4cefb3d0a8cc0a8db4bde93fc72c78f44d4fecca14650c660d3e285b327e7cdd813063e7e867b8a2d059a41bab70432b7f857199894da90dca3fe5272bae1ec694a1a07b60b05df275784d4975637e4673109f3ba846dfd1a048b202ed8e89973be608b91ee4743b1e759900f1443038951fe6189e806638985f3c16338c3c60695df58e621154d79bb973859c4558e9dca90470f77c73f004443ad5db0717abbe43266f90e57397b83ac34d1fef2e897e2483d5bcdcb627abd64b0d1aef525835f25e76d6e9158232cdde6dce970b59f58de8a98e653be32fb58edabbcefa5065d73afdf1c9c4fbf50c1022bd22bfcb98e4b422
AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813bf5c501ad31e5d791c4b5b3a0a71b63fdddcc8de4b056064ef467989ecccc5d0160d403bf3a025d4892b3b1de3e062bc3581d4410f273338311eb4637529e4a680a6e4a5e26e308630a5b6d49ead6d543f8f2bf9050aa94ce091318721e1d8b96e279f34b9759b65037bec4bf6ccda6929705aeeeebe49e327e4d7a916620c9faf3765120658af34c53fbb97ec07657b3f088fcbdc401aa7949ddeda34d885018c2c23f4f0bb8218bf0d4fc90643658b4d8834f4a8c08e590c2a790995baa9e77627c342d283e454f84fcc05be15e9627a2d9be340c9d72f222bbdfc47905f56616cd9f936d49e4732f319f020513340fb8b22828db251b102b6b137c9533936d6
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
-TAG: f7d3b58a34a86e99267e5db206f17bbe
-
-KEY: 3304e4917ad7777b86c26a636292c9cc4c10d32003c49e07209eb0ef8505031a
-NONCE: 4d572d116fbd8c4d
-IN: 2f242c2ba33790ecef862b0e077ff8b15eb9d10cf2ff621ed65902494431dcbd
-AD: e699bbf250cdd93d229d0740e433897e2d19132e2b722df8b69bb6a7c2cf3b93
-CT: fb81e30436e437c7f686f86b1b65c73549a9d09db810d320785c3634934150b3
-TAG: 8b
-
-KEY: ed6057bb163f1609ff28b938122f495e3d5ae4ec3dbd7456c9b5c82e28e952dc
-NONCE: e6ff6852f3a3afde
-IN: 3c50edc967eb0b3b2355f6400e0a036e796c8b7d72c5e583a86e820d53e76c43
-AD: 2441db55148e14e9e241d68296eb60d529408f0534143089671bce546db96d88
-CT: 6ecabccee31519374d4bed11296e7483d1cb759bea3f4446a96bda8b4ca6d7ac
-TAG: 355f
-
-KEY: 73568183c1f9725af30e0f2067606ce802c3fe3ab5cff8d02b3db8c35176ee0d
-NONCE: 0bc9e19321b3d00a
-IN: ec2590af5ccd226a32ff750c1b029c11e3dd76c469a5579da9418e4c3fdc0d41
-AD: df30160ae0cbf2cf8992221bd62dffe691dd602afa784ca691479e957af3acf1
-CT: 9e8d8ac30626f8b831448d6976933aa5bb8c6dbc794e1f4b7eeb0e4a59342c07
-TAG: 9fd36a
-
-KEY: 273bcb3f8c067da4ec3418799ad40e7e4aee74ad7e629499d646df4a7e585025
-NONCE: f60be3eb894b4030
-IN: 697498ba964d5ef401da4d94844fab1efc635e7157d0831a325bb5a4cf1fbd34
-AD: 9129715deab14f02c76ba8172571b1fa9d50365cd795bfccdfc28e7e7b4f66fc
-CT: bd4cd5af83be1c13933302675d9fcaf1c4cacdf269f6ff441d1ea2211c54e7ed
-TAG: 7ab12a37
-
-KEY: ad39610c2e6a6d0961207390e076e972c2edadca885c92965fa648b2ce34fdbf
-NONCE: a90db690bba83b78
-IN: 31c49e3cd3d80a82e6b90316dfb94b38b8a23042519bf40c8181fec873c99002
-AD: ddbd7d821d18d44c66295abf245b227b5cf4366811b7b34c07679600abdbfc29
-CT: 94628fc303a0546edd51e966f2bd87968f37800c607d5e5a91f727fc1fec406f
-TAG: c22ec4e4c8
-
-KEY: 29984954060ba06ece1bcfc0e50195f4632c6df48da1e02ae6c14f7065668971
-NONCE: cce53a25aeeaf747
-IN: b9b87433a9894f3c9ca8212623d62369a565a2edcddd276e07d611eda3597426
-AD: 19fa9aa59697559d8b46d9cd49c3b763c0b73b26b9e334a3eeac2c86fdbaca8d
-CT: b68c83397770c36f073710882fa86d43b0e54e8efef0ff75075604d0d7ec4e1b
-TAG: 40d4ab752f3d
-
-KEY: 5c3b838b84100b2a818c0842e9fe19a7c50cf5f3ea73364c816ef588e500ff3f
-NONCE: fdf6b0229e4bcc2a
-IN: 2ba91904c143be99297b39f52856904af41705c176c8c6554b6bc89bddffbcc1
-AD: 3539d9dd821f004f4ced1637071f4be6abd7fe98f017f0a8ce3f49dc8d496f46
-CT: ff9d6d924e737a1df8c2bd3047e40ab401f903aa0e5b51acb991bac38ac2cc4d
-TAG: 1bcaa415a6a3c7
-
-KEY: 6d65e627cab6d5eb1a088b25bd6c3a8a004a7a19cccae909d62fed3559c812f7
-NONCE: 7ff00a8798b792de
-IN: 6848ee4ac820291a2e1dc3baad97f1ad8b7160dfeaa1bc83b2700ae42b5a366b
-AD: d2437b1306bf0ea211449fac863ca0d1074d84caee9009c5d54b9e9bdc8de6b1
-CT: 2da0abe2a71e1c0b1ab309c160a8cebe45c6e16170aa5561806484ba2b5b9a9a
-TAG: 566003e1f78d2a90
-
-KEY: 63401046a96efbc8c6483a2c396b2a593d3fae0db565525b85999fae13a46b6a
-NONCE: 051393d775e635ee
-IN: 2b4b6477580382aae782f8b5772c0948a444d8d95caacd85c0856c7e4393fe09
-AD: 3d84d2e70e9c062d1f511eb685a9a90c8d5fa50eadf8455c7148666b3e7155e0
-CT: 880c1123e54fd8ffb3c293720dd174913572e619ef46504cdaa64fc451b0ec1c
-TAG: 339274339c88d50ac0
-
-KEY: 291fccfce0782f1787d62d4b9293d2ada4c04d37a8288ba9ba9aae0d31aad204
-NONCE: 7450bbd62e4aba7b
-IN: adc251e793181e5d4c4bd983b853eb13f2096ccb340996b6eca4cd2157efcec7
-AD: 4c598f6deedc8c1d97da33654763495cca3517430eec4edb006b10c95e031ae6
-CT: 28bda22e4922cd8ff6739cd8a6bdafce036d9c61a145a65ca1b86f6d4d3206a1
-TAG: d98fd43fe7ac74d4b016
-
-KEY: fa3a9674d4a0eb36b2f7547c956443d09e6b4e4acfc9deda838eb7ebdb999a8d
-NONCE: 0a2572592c3bbbf6
-IN: ae27f70fda9f5a5be0f704a27f0b8a9c04ce83d3c2e0d7ec152da25f473b0c8a
-AD: 6ee8705a9a3655d198497ad410da02005872ecbe397824851b80f4050bfdd311
-CT: f356cbd88e4e2aff62d91e3f914032085388955bbba995fde013758b8702e38f
-TAG: 00324c76fecd3f50e1e3b8
-
-KEY: 471ec87b992b104d369748d96856b5f66149cb45ca05c17f29d24eb9526fe6db
-NONCE: 23a2df9ed0b47439
-IN: 2b9452bca0f48e5519ec3d0736597608df6ad9ce799eba913cff71573d79c092
-AD: a56722ddfaee5f1b64398c225ee8bcdcfde5c2127101c363bfac52bc409c1082
-CT: 7bbc464aac5dd29c25262fe0b116c176d827c2cc8dd63428393b0a9110f3c194
-TAG: 2e87f4a6663a62e47c7e197f
-
-KEY: a29d1cfd4ccdc18803fbca9500f4bb29ce99cfcbf8acc41b8208dae4b7ee5d64
-NONCE: 634f99e88e237ef0
-IN: 09ee5982c5743f396d0c29c13e3fbb8fb89f61705da05466291e010effd51a5c
-AD: 564dddfcc3227b413244f1105b610f192decf15c4cfa067f4d7fcd6bd7af11b8
-CT: 32916b67a6f32733623344c98c49773f3e721dc2ded105fb245799525bc9c84c
-TAG: ff463c07e7ef831321d3fd775f
-
-KEY: 08ba23616d911188f91da063278bef1237dcbf17f52585e53c2c4b6cf3ac9f0d
-NONCE: 989ae593eddd3874
-IN: 749152c9478944c8271c0c11e07bc1c569eec01493e65b3b94842a1bf5d721f8
-AD: a12d1a45b7c9b91ab08751a70b753714052ad24e0b2619fe8c3be303c65f2dbc
-CT: 34c40538ee1d22ddf8ac290dd7d423dfc622b5cf8f3412a5343e277822aea713
-TAG: 014c7c678e0949e88071d1fe3531
-
-KEY: c2ba8bed8634156afc6bfe3754c91744d4131de39d059f3a866399f916553b5c
-NONCE: 80fbf7b433a4cd9c
-IN: 419be6623e7964f9f26068dd969e4a139617e67c5ffb269b3013c433fe771c77
-AD: 3937592db78a61ff469691b6800792019bc2b3d42512f23c1b1a66a8274495cb
-CT: 9d5bd1c7e766763eb00684c038043111d8c6390a8d6e17a15ef97c02ab16f09c
-TAG: a64d0eeb4a01481ec0cee8c1c357e3
+TAG: 296a397d280d026fc3627f4718971be9
+
+# BoringSSL has additional tests here for truncated tags. *ring* doesn't
+# support tag truncation, so those tests were removed.
diff --git a/src/crypto/cmac/CMakeLists.txt b/src/crypto/cmac/CMakeLists.txt
index bb3abc3..a346b24 100644
--- a/src/crypto/cmac/CMakeLists.txt
+++ b/src/crypto/cmac/CMakeLists.txt
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(cmac_test crypto)
+add_dependencies(all_tests cmac_test)
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 6e037ab..14ad2ee 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -14,15 +14,14 @@
#include <openssl/cpu.h>
-#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_STATIC_ARMCAP)
#include <inttypes.h>
#include <string.h>
-#if !defined(OPENSSL_TRUSTY)
#include <setjmp.h>
#include <signal.h>
-#endif
#include <openssl/arm_arch.h>
@@ -33,6 +32,8 @@
unsigned long getauxval(unsigned long type) __attribute__((weak));
+extern uint32_t OPENSSL_armcap_P;
+
char CRYPTO_is_NEON_capable(void) {
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
}
@@ -62,7 +63,15 @@ void CRYPTO_set_NEON_functional(char neon_functional) {
}
}
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM) && !defined(OPENSSL_TRUSTY)
+int CRYPTO_is_ARMv8_AES_capable(void) {
+ return (OPENSSL_armcap_P & ARMV8_AES) != 0;
+}
+
+int CRYPTO_is_ARMv8_PMULL_capable(void) {
+ return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
+}
+
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM)
static sigjmp_buf sigill_jmp;
@@ -120,7 +129,7 @@ static int probe_for_NEON(void) {
return 0;
}
-#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM && !OPENSSL_TRUSTY */
+#endif /* !OPENSSL_NO_ASM && OPENSSL_ARM */
void OPENSSL_cpuid_setup(void) {
if (getauxval == NULL) {
@@ -186,4 +195,5 @@ void OPENSSL_cpuid_setup(void) {
}
}
-#endif /* defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) */
+#endif /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) &&
+ !defined(OPENSSL_STATIC_ARMCAP) */
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index 34d04b4..d70c8c7 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -17,7 +17,7 @@
#include "internal.h"
-#if !defined(OPENSSL_NO_ASM) && \
+#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
/* x86, x86_64 and the ARMs need to record the result of a cpuid call for the
@@ -57,7 +57,27 @@ uint32_t OPENSSL_ia32cap_P[4] = {0};
#include <openssl/arm_arch.h>
-#if defined(__ARM_NEON__)
+#if defined(OPENSSL_STATIC_ARMCAP)
+
+uint32_t OPENSSL_armcap_P =
+#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
+ ARMV7_NEON | ARMV7_NEON_FUNCTIONAL |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_AES)
+ ARMV8_AES |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_SHA1)
+ ARMV8_SHA1 |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_SHA256)
+ ARMV8_SHA256 |
+#endif
+#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
+ ARMV8_PMULL |
+#endif
+ 0;
+
+#elif defined(__ARM_NEON__)
uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
#else
uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
@@ -110,3 +130,9 @@ const char *SSLeay_version(int unused) {
unsigned long SSLeay(void) {
return OPENSSL_VERSION_NUMBER;
}
+
+int CRYPTO_malloc_init(void) {
+ return 1;
+}
+
+void ENGINE_load_builtin_engines(void) {}
diff --git a/src/crypto/des/des.c b/src/crypto/des/des.c
index a5669a6..1d27ebe 100644
--- a/src/crypto/des/des.c
+++ b/src/crypto/des/des.c
@@ -499,7 +499,6 @@ static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
data[1] = ROTATE(r, 3) & 0xffffffffL;
}
-/* DES_encrypt3 is not static because it's used in decrepit. */
void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
uint32_t l, r;
@@ -519,7 +518,6 @@ void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
data[1] = r;
}
-/* DES_decrypt3 is not static because it's used in decrepit. */
void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
uint32_t l, r;
diff --git a/src/crypto/dh/CMakeLists.txt b/src/crypto/dh/CMakeLists.txt
index 1a46512..8ddf03d 100644
--- a/src/crypto/dh/CMakeLists.txt
+++ b/src/crypto/dh/CMakeLists.txt
@@ -21,3 +21,4 @@ add_executable(
)
target_link_libraries(dh_test crypto)
+add_dependencies(all_tests dh_test)
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index d25f358..ee6c9a0 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -97,12 +97,14 @@ DH *DH_new_method(const ENGINE *engine) {
dh->references = 1;
if (!CRYPTO_new_ex_data(&g_ex_data_class, dh, &dh->ex_data)) {
+ CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
OPENSSL_free(dh);
return NULL;
}
if (dh->meth->init && !dh->meth->init(dh)) {
CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data);
+ CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
METHOD_unref(dh->meth);
OPENSSL_free(dh);
return NULL;
@@ -127,15 +129,15 @@ void DH_free(DH *dh) {
CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data);
- if (dh->method_mont_p) BN_MONT_CTX_free(dh->method_mont_p);
- if (dh->p != NULL) BN_clear_free(dh->p);
- if (dh->g != NULL) BN_clear_free(dh->g);
- if (dh->q != NULL) BN_clear_free(dh->q);
- if (dh->j != NULL) BN_clear_free(dh->j);
- if (dh->seed) OPENSSL_free(dh->seed);
- if (dh->counter != NULL) BN_clear_free(dh->counter);
- if (dh->pub_key != NULL) BN_clear_free(dh->pub_key);
- if (dh->priv_key != NULL) BN_clear_free(dh->priv_key);
+ BN_MONT_CTX_free(dh->method_mont_p);
+ BN_clear_free(dh->p);
+ BN_clear_free(dh->g);
+ BN_clear_free(dh->q);
+ BN_clear_free(dh->j);
+ OPENSSL_free(dh->seed);
+ BN_clear_free(dh->counter);
+ BN_clear_free(dh->pub_key);
+ BN_clear_free(dh->priv_key);
CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
OPENSSL_free(dh);
diff --git a/src/crypto/dh/params.c b/src/crypto/dh/params.c
index 82d1d92..2bfccb8 100644
--- a/src/crypto/dh/params.c
+++ b/src/crypto/dh/params.c
@@ -295,7 +295,7 @@ DH *DH_get_2048_256(const ENGINE *engine) {
}
void DH_check_standard_parameters(DH *dh) {
- int i;
+ unsigned i;
if (dh->p == NULL ||
dh->g == NULL ||
diff --git a/src/crypto/digest/CMakeLists.txt b/src/crypto/digest/CMakeLists.txt
index 856e45a..7a68f6f 100644
--- a/src/crypto/digest/CMakeLists.txt
+++ b/src/crypto/digest/CMakeLists.txt
@@ -18,3 +18,4 @@ add_executable(
)
target_link_libraries(digest_test crypto)
+add_dependencies(all_tests digest_test)
diff --git a/src/crypto/dsa/CMakeLists.txt b/src/crypto/dsa/CMakeLists.txt
index e8b7793..654f18c 100644
--- a/src/crypto/dsa/CMakeLists.txt
+++ b/src/crypto/dsa/CMakeLists.txt
@@ -19,3 +19,4 @@ add_executable(
)
target_link_libraries(dsa_test crypto)
+add_dependencies(all_tests dsa_test)
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index 3ff29c4..eb8e61f 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -103,6 +103,7 @@ DSA *DSA_new_method(const ENGINE *engine) {
CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
if (!CRYPTO_new_ex_data(&g_ex_data_class, dsa, &dsa->ex_data)) {
+ CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
METHOD_unref(dsa->meth);
OPENSSL_free(dsa);
return NULL;
@@ -110,6 +111,7 @@ DSA *DSA_new_method(const ENGINE *engine) {
if (dsa->meth->init && !dsa->meth->init(dsa)) {
CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data);
+ CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
METHOD_unref(dsa->meth);
OPENSSL_free(dsa);
return NULL;
diff --git a/src/crypto/dsa/dsa_impl.c b/src/crypto/dsa/dsa_impl.c
index b10610d..e046f9c 100644
--- a/src/crypto/dsa/dsa_impl.c
+++ b/src/crypto/dsa/dsa_impl.c
@@ -463,23 +463,11 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
int r = 0;
BN_CTX *ctx = NULL;
unsigned int h = 2;
- unsigned qbits, qsize;
+ unsigned qsize;
const EVP_MD *evpmd;
- if (bits >= 2048) {
- qbits = 256;
- evpmd = EVP_sha256();
- } else {
- qbits = 160;
- evpmd = EVP_sha1();
- }
- qsize = qbits / 8;
-
- if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
- qsize != SHA256_DIGEST_LENGTH) {
- /* invalid q size */
- return 0;
- }
+ evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1();
+ qsize = EVP_MD_size(evpmd);
if (bits < 512) {
bits = 512;
diff --git a/src/crypto/ec/CMakeLists.txt b/src/crypto/ec/CMakeLists.txt
index 38a91f8..9808cd5 100644
--- a/src/crypto/ec/CMakeLists.txt
+++ b/src/crypto/ec/CMakeLists.txt
@@ -10,6 +10,7 @@ add_library(
ec_key.c
ec_montgomery.c
oct.c
+ p224-64.c
p256-64.c
util-64.c
simple.c
@@ -34,3 +35,4 @@ add_executable(
target_link_libraries(example_mul crypto)
target_link_libraries(ec_test crypto)
+add_dependencies(all_tests example_mul ec_test)
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index 3117f16..ec01766 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -218,15 +218,25 @@ static const struct curve_data P521 = {
0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
+/* MSan appears to have a bug that causes code to be miscompiled in opt mode.
+ * While that is being looked at, don't run the uint128_t code under MSan. */
+#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
+ !defined(MEMORY_SANITIZER)
+#define BORINGSSL_USE_INT128_CODE
+#endif
+
const struct built_in_curve OPENSSL_built_in_curves[] = {
- {NID_secp224r1, &P224, 0},
+ {
+ NID_secp224r1, &P224,
+#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
+ EC_GFp_nistp224_method,
+#else
+ 0,
+#endif
+ },
{
NID_X9_62_prime256v1, &P256,
- /* MSAN appears to have a bug that causes this P-256 code to be miscompiled
- * in opt mode. While that is being looked at, don't run the uint128_t
- * P-256 code under MSAN for now. */
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
- !defined(MEMORY_SANITIZER)
+#if defined(BORINGSSL_USE_INT128_CODE)
EC_GFp_nistp256_method,
#else
0,
@@ -549,30 +559,17 @@ int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
BIGNUM *out_b, BN_CTX *ctx) {
- if (group->meth->group_get_curve == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
+ return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
}
int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
-int EC_GROUP_get_degree(const EC_GROUP *group) {
- if (group->meth->group_get_degree == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
- return group->meth->group_get_degree(group);
+unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
+ return ec_GFp_simple_group_get_degree(group);
}
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
- if (group->meth->mul == 0) {
- /* use default */
- return ec_wNAF_precompute_mult(group, ctx);
- }
-
- if (group->meth->precompute_mult != 0) {
+ if (group->meth->precompute_mult != NULL) {
return group->meth->precompute_mult(group, ctx);
}
@@ -580,16 +577,10 @@ int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
}
int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
- if (group->meth->mul == 0) {
- /* use default */
- return ec_wNAF_have_precompute_mult(group);
- }
-
- if (group->meth->have_precompute_mult != 0) {
- return group->meth->have_precompute_mult(group);
+ if (group->pre_comp != NULL) {
+ return 1;
}
-
- return 0; /* cannot tell whether precomputation has been performed */
+ return 0;
}
EC_POINT *EC_POINT_new(const EC_GROUP *group) {
@@ -599,10 +590,6 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
- if (group->meth->point_init == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return NULL;
- }
ret = OPENSSL_malloc(sizeof *ret);
if (ret == NULL) {
@@ -612,7 +599,7 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
ret->meth = group->meth;
- if (!ret->meth->point_init(ret)) {
+ if (!ec_GFp_simple_point_init(ret)) {
OPENSSL_free(ret);
return NULL;
}
@@ -625,9 +612,8 @@ void EC_POINT_free(EC_POINT *point) {
return;
}
- if (point->meth->point_finish != 0) {
- point->meth->point_finish(point);
- }
+ ec_GFp_simple_point_finish(point);
+
OPENSSL_free(point);
}
@@ -636,20 +622,13 @@ void EC_POINT_clear_free(EC_POINT *point) {
return;
}
- if (point->meth->point_clear_finish != 0) {
- point->meth->point_clear_finish(point);
- } else if (point->meth->point_finish != 0) {
- point->meth->point_finish(point);
- }
+ ec_GFp_simple_point_clear_finish(point);
+
OPENSSL_cleanse(point, sizeof *point);
OPENSSL_free(point);
}
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
- if (dest->meth->point_copy == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (dest->meth != src->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
@@ -657,7 +636,7 @@ int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
if (dest == src) {
return 1;
}
- return dest->meth->point_copy(dest, src);
+ return ec_GFp_simple_point_copy(dest, src);
}
EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
@@ -683,82 +662,58 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
}
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
- if (group->meth->point_set_to_infinity == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_to_infinity(group, point);
+ return ec_GFp_simple_point_set_to_infinity(group, point);
}
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
- if (group->meth->is_at_infinity == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->is_at_infinity(group, point);
+ return ec_GFp_simple_is_at_infinity(group, point);
}
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx) {
- if (group->meth->is_on_curve == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->is_on_curve(group, point, ctx);
+ return ec_GFp_simple_is_on_curve(group, point, ctx);
}
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
BN_CTX *ctx) {
- if (group->meth->point_cmp == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return -1;
- }
if ((group->meth != a->meth) || (a->meth != b->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return -1;
}
- return group->meth->point_cmp(group, a, b, ctx);
+ return ec_GFp_simple_cmp(group, a, b, ctx);
}
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
- if (group->meth->make_affine == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->make_affine(group, point, ctx);
+ return ec_GFp_simple_make_affine(group, point, ctx);
}
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
BN_CTX *ctx) {
size_t i;
- if (group->meth->points_make_affine == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
- return group->meth->points_make_affine(group, num, points, ctx);
+ return ec_GFp_simple_points_make_affine(group, num, points, ctx);
}
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
@@ -778,56 +733,40 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx) {
- if (group->meth->point_set_affine_coordinates == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+ return ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx);
}
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx) {
- if (group->meth->add == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if ((group->meth != r->meth) || (r->meth != a->meth) ||
(a->meth != b->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->add(group, r, a, b, ctx);
+ return ec_GFp_simple_add(group, r, a, b, ctx);
}
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
BN_CTX *ctx) {
- if (group->meth->dbl == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if ((group->meth != r->meth) || (r->meth != a->meth)) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->dbl(group, r, a, ctx);
+ return ec_GFp_simple_dbl(group, r, a, ctx);
}
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
- if (group->meth->invert == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != a->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->invert(group, a, ctx);
+ return ec_GFp_simple_invert(group, a, ctx);
}
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
@@ -847,9 +786,15 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *ctx) {
- if (group->meth->mul == 0) {
- /* use default. Warning, not constant-time. */
- return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ size_t i;
+ for (i = 0; i < num; i++) {
+ if (points[i]->meth != r->meth) {
+ break;
+ }
+ }
+ if (i != num) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
}
return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
@@ -858,16 +803,12 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
const BIGNUM *z, BN_CTX *ctx) {
- if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
- z, ctx);
+ return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
+ ctx);
}
void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index 31d8944..7c4be07 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -212,7 +212,7 @@ EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
curve = &OPENSSL_built_in_curves[i];
const unsigned param_len = curve->data->param_len;
- if (ecparams->order->length == param_len &&
+ if ((unsigned) ecparams->order->length == param_len &&
memcmp(ecparams->order->data, &curve->data->data[param_len * 5],
param_len) == 0) {
nid = curve->nid;
@@ -239,8 +239,9 @@ static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
long len) {
EC_GROUP *group = NULL;
ECPKPARAMETERS *params = NULL;
+ const uint8_t *in = *inp;
- params = d2i_ECPKPARAMETERS(NULL, inp, len);
+ params = d2i_ECPKPARAMETERS(NULL, &in, len);
if (params == NULL) {
OPENSSL_PUT_ERROR(EC, EC_R_D2I_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(params);
@@ -260,6 +261,7 @@ static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
}
ECPKPARAMETERS_free(params);
+ *inp = in;
return group;
}
@@ -280,12 +282,13 @@ static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
return ret;
}
-EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) {
int ok = 0;
EC_KEY *ret = NULL;
EC_PRIVATEKEY *priv_key = NULL;
- priv_key = d2i_EC_PRIVATEKEY(NULL, in, len);
+ const uint8_t *in = *inp;
+ priv_key = d2i_EC_PRIVATEKEY(NULL, &in, len);
if (priv_key == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
return NULL;
@@ -364,6 +367,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
if (a) {
*a = ret;
}
+ *inp = in;
ok = 1;
err:
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index b897000..3715e0c 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -75,41 +75,16 @@
const EC_METHOD *EC_GFp_mont_method(void) {
- static const EC_METHOD ret = {EC_FLAGS_DEFAULT_OCT,
- ec_GFp_mont_group_init,
+ static const EC_METHOD ret = {ec_GFp_mont_group_init,
ec_GFp_mont_group_finish,
ec_GFp_mont_group_clear_finish,
ec_GFp_mont_group_copy,
ec_GFp_mont_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
- 0,
- 0,
- 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
- 0 /* mul */,
- 0 /* precompute_mult */,
- 0 /* have_precompute_mult */,
+ ec_wNAF_mul /* XXX: Not constant time. */,
+ ec_wNAF_precompute_mult,
ec_GFp_mont_field_mul,
ec_GFp_mont_field_sqr,
- 0 /* field_div */,
ec_GFp_mont_field_encode,
ec_GFp_mont_field_decode,
ec_GFp_mont_field_set_to_one};
diff --git a/src/crypto/ec/internal.h b/src/crypto/ec/internal.h
index 71062c1..459bab5 100644
--- a/src/crypto/ec/internal.h
+++ b/src/crypto/ec/internal.h
@@ -79,13 +79,7 @@ extern "C" {
#endif
-/* Use default functions for poin2oct, oct2point and compressed coordinates */
-#define EC_FLAGS_DEFAULT_OCT 0x1
-
struct ec_method_st {
- /* Various method flags */
- int flags;
-
/* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
int (*group_init)(EC_GROUP *);
void (*group_finish)(EC_GROUP *);
@@ -96,66 +90,10 @@ struct ec_method_st {
/* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
- int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
- BN_CTX *);
-
- /* used by EC_GROUP_get_degree: */
- int (*group_get_degree)(const EC_GROUP *);
-
- /* used by EC_GROUP_check: */
- int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *);
-
- /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
- int (*point_init)(EC_POINT *);
- void (*point_finish)(EC_POINT *);
- void (*point_clear_finish)(EC_POINT *);
- int (*point_copy)(EC_POINT *, const EC_POINT *);
-
- /* used by EC_POINT_set_to_infinity,
- * EC_POINT_set_Jprojective_coordinates_GFp,
- * EC_POINT_get_Jprojective_coordinates_GFp,
- * EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
- * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
- * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
- */
- int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
- int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, const BIGNUM *y,
- const BIGNUM *z, BN_CTX *);
- int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *,
- const EC_POINT *, BIGNUM *x,
- BIGNUM *y, BIGNUM *z, BN_CTX *);
- int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, const BIGNUM *y,
- BN_CTX *);
+
+ /* used by EC_POINT_get_affine_coordinates_GFp: */
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
- int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *,
- const BIGNUM *x, int y_bit, BN_CTX *);
-
- /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
- size_t (*point2oct)(const EC_GROUP *, const EC_POINT *,
- point_conversion_form_t form, unsigned char *buf,
- size_t len, BN_CTX *);
- int (*oct2point)(const EC_GROUP *, EC_POINT *, const unsigned char *buf,
- size_t len, BN_CTX *);
-
- /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
- int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
- const EC_POINT *b, BN_CTX *);
- int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
- int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *);
-
- /* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */
- int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *);
- int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *);
- int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
- BN_CTX *);
-
- /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
- int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
- int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT * [],
- BN_CTX *);
/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
* EC_POINT_have_precompute_mult
@@ -164,19 +102,15 @@ struct ec_method_st {
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
- int (*have_precompute_mult)(const EC_GROUP *group);
-
/* internal functions */
- /* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl'
- * so that the same implementations of point operations can be used with
- * different optimized implementations of expensive field operations: */
+ /* 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that the
+ * same implementations of point operations can be used with different
+ * optimized implementations of expensive field operations: */
int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
- int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
- const BIGNUM *b, BN_CTX *);
int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
BN_CTX *); /* e.g. to Montgomery */
@@ -234,7 +168,6 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
BN_CTX *);
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
-int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
/* method functions in simple.c */
int ec_GFp_simple_group_init(EC_GROUP *);
@@ -245,7 +178,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
const BIGNUM *b, BN_CTX *);
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
BIGNUM *b, BN_CTX *);
-int ec_GFp_simple_group_get_degree(const EC_GROUP *);
+unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *);
int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
int ec_GFp_simple_point_init(EC_POINT *);
void ec_GFp_simple_point_finish(EC_POINT *);
@@ -319,6 +252,7 @@ void ec_GFp_nistp_points_make_affine_internal(
void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
+const EC_METHOD *EC_GFp_nistp224_method(void);
const EC_METHOD *EC_GFp_nistp256_method(void);
struct ec_key_st {
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index cb50e17..365dc3d 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -277,39 +277,21 @@ err:
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
const uint8_t *buf, size_t len, BN_CTX *ctx) {
- if (group->meth->oct2point == 0 &&
- !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
- return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
- }
-
- return group->meth->oct2point(group, point, buf, len, ctx);
+ return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
}
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
point_conversion_form_t form, uint8_t *buf,
size_t len, BN_CTX *ctx) {
- if (group->meth->point2oct == 0 &&
- !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
- return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
- }
-
- return group->meth->point2oct(group, point, form, buf, len, ctx);
+ return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
}
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
@@ -452,19 +434,9 @@ err:
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point, const BIGNUM *x,
int y_bit, BN_CTX *ctx) {
- if (group->meth->point_set_compressed_coordinates == 0 &&
- !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
if (group->meth != point->meth) {
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
- if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
- return ec_GFp_simple_set_compressed_coordinates(group, point, x, y_bit,
- ctx);
- }
- return group->meth->point_set_compressed_coordinates(group, point, x, y_bit,
- ctx);
+ return ec_GFp_simple_set_compressed_coordinates(group, point, x, y_bit, ctx);
}
diff --git a/src/crypto/ec/p224-64.c b/src/crypto/ec/p224-64.c
new file mode 100644
index 0000000..bcc4158
--- /dev/null
+++ b/src/crypto/ec/p224-64.c
@@ -0,0 +1,1341 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+/* A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
+ *
+ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
+ * and Adam Langley's public domain 64-bit C implementation of curve25519. */
+
+#include <openssl/base.h>
+
+#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
+ !defined(OPENSSL_SMALL)
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+
+#include <string.h>
+
+#include "internal.h"
+
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/* Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
+ * using 64-bit coefficients called 'limbs', and sometimes (for multiplication
+ * results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 +
+ * 2^336*b_6 using 128-bit coefficients called 'widelimbs'. A 4-limb
+ * representation is an 'felem'; a 7-widelimb representation is a 'widefelem'.
+ * Even within felems, bits of adjacent limbs overlap, and we don't always
+ * reduce the representations: we ensure that inputs to each felem
+ * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60, and
+ * fit into a 128-bit word without overflow. The coefficients are then again
+ * partially reduced to obtain an felem satisfying a_i < 2^57. We only reduce
+ * to the unique minimal representation at the end of the computation. */
+
+typedef uint64_t limb;
+typedef __uint128_t widelimb;
+
+typedef limb felem[4];
+typedef widelimb widefelem[7];
+
+/* Field element represented as a byte arrary. 28*8 = 224 bits is also the
+ * group order size for the elliptic curve, and we also use this type for
+ * scalars for point multiplication. */
+typedef u8 felem_bytearray[28];
+
+static const felem_bytearray nistp224_curve_params[5] = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
+ {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
+ 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B,
+ 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
+ {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
+ 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32,
+ 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
+ {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
+ 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5,
+ 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34}};
+
+/* Precomputed multiples of the standard generator
+ * Points are given in coordinates (X, Y, Z) where Z normally is 1
+ * (0 for the point at infinity).
+ * For each field element, slice a_0 is word 0, etc.
+ *
+ * The table has 2 * 16 elements, starting with the following:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^56G
+ * 3 | 0 0 1 1 | (2^56 + 1)G
+ * 4 | 0 1 0 0 | 2^112G
+ * 5 | 0 1 0 1 | (2^112 + 1)G
+ * 6 | 0 1 1 0 | (2^112 + 2^56)G
+ * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
+ * 8 | 1 0 0 0 | 2^168G
+ * 9 | 1 0 0 1 | (2^168 + 1)G
+ * 10 | 1 0 1 0 | (2^168 + 2^56)G
+ * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
+ * 12 | 1 1 0 0 | (2^168 + 2^112)G
+ * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
+ * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
+ * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
+ * followed by a copy of this with each element multiplied by 2^28.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements. */
+static const felem gmul[2][16][3] = {
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
+ {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
+ {1, 0, 0, 0}},
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
+ {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
+ {1, 0, 0, 0}},
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
+ {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
+ {1, 0, 0, 0}},
+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
+ {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
+ {1, 0, 0, 0}},
+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
+ {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
+ {1, 0, 0, 0}},
+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
+ {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
+ {1, 0, 0, 0}},
+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
+ {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
+ {1, 0, 0, 0}},
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
+ {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
+ {1, 0, 0, 0}},
+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
+ {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
+ {1, 0, 0, 0}},
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
+ {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
+ {1, 0, 0, 0}},
+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
+ {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
+ {1, 0, 0, 0}},
+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
+ {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
+ {1, 0, 0, 0}},
+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
+ {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
+ {1, 0, 0, 0}},
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
+ {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
+ {1, 0, 0, 0}},
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
+ {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
+ {1, 0, 0, 0}}},
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
+ {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
+ {1, 0, 0, 0}},
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
+ {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
+ {1, 0, 0, 0}},
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
+ {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
+ {1, 0, 0, 0}},
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
+ {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
+ {1, 0, 0, 0}},
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
+ {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
+ {1, 0, 0, 0}},
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
+ {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
+ {1, 0, 0, 0}},
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
+ {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
+ {1, 0, 0, 0}},
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
+ {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
+ {1, 0, 0, 0}},
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
+ {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
+ {1, 0, 0, 0}},
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
+ {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
+ {1, 0, 0, 0}},
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
+ {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
+ {1, 0, 0, 0}},
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
+ {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
+ {1, 0, 0, 0}},
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
+ {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
+ {1, 0, 0, 0}},
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
+ {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
+ {1, 0, 0, 0}},
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
+ {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
+ {1, 0, 0, 0}}}};
+
+/* Helper functions to convert field elements to/from internal representation */
+static void bin28_to_felem(felem out, const u8 in[28]) {
+ out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
+ out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
+ out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
+ out[3] = (*((const uint64_t *)(in + 20))) >> 8;
+}
+
+static void felem_to_bin28(u8 out[28], const felem in) {
+ unsigned i;
+ for (i = 0; i < 7; ++i) {
+ out[i] = in[0] >> (8 * i);
+ out[i + 7] = in[1] >> (8 * i);
+ out[i + 14] = in[2] >> (8 * i);
+ out[i + 21] = in[3] >> (8 * i);
+ }
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len) {
+ unsigned i;
+ for (i = 0; i < len; ++i) {
+ out[i] = in[len - 1 - i];
+ }
+}
+
+/* From OpenSSL BIGNUM to internal representation */
+static int BN_to_felem(felem out, const BIGNUM *bn) {
+ /* BN_bn2bin eats leading zeroes */
+ felem_bytearray b_out;
+ memset(b_out, 0, sizeof(b_out));
+ unsigned num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof(b_out) ||
+ BN_is_negative(bn)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+
+ felem_bytearray b_in;
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin28_to_felem(out, b_out);
+ return 1;
+}
+
+/* From internal representation to OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) {
+ felem_bytearray b_in, b_out;
+ felem_to_bin28(b_in, in);
+ flip_endian(b_out, b_in, sizeof(b_out));
+ return BN_bin2bn(b_out, sizeof(b_out), out);
+}
+
+/* Field operations, using the internal representation of field elements.
+ * NB! These operations are specific to our point multiplication and cannot be
+ * expected to be correct in general - e.g., multiplication with a large scalar
+ * will cause an overflow. */
+
+static void felem_one(felem out) {
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+}
+
+static void felem_assign(felem out, const felem in) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+/* Sum two field elements: out += in */
+static void felem_sum(felem out, const felem in) {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+}
+
+/* Get negative value: out = -in */
+/* Assumes in[i] < 2^57 */
+static void felem_neg(felem out, const felem in) {
+ static const limb two58p2 = (((limb)1) << 58) + (((limb)1) << 2);
+ static const limb two58m2 = (((limb)1) << 58) - (((limb)1) << 2);
+ static const limb two58m42m2 =
+ (((limb)1) << 58) - (((limb)1) << 42) - (((limb)1) << 2);
+
+ /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] = two58p2 - in[0];
+ out[1] = two58m42m2 - in[1];
+ out[2] = two58m2 - in[2];
+ out[3] = two58m2 - in[3];
+}
+
+/* Subtract field elements: out -= in */
+/* Assumes in[i] < 2^57 */
+static void felem_diff(felem out, const felem in) {
+ static const limb two58p2 = (((limb)1) << 58) + (((limb)1) << 2);
+ static const limb two58m2 = (((limb)1) << 58) - (((limb)1) << 2);
+ static const limb two58m42m2 =
+ (((limb)1) << 58) - (((limb)1) << 42) - (((limb)1) << 2);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two58p2;
+ out[1] += two58m42m2;
+ out[2] += two58m2;
+ out[3] += two58m2;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/* Subtract in unreduced 128-bit mode: out -= in */
+/* Assumes in[i] < 2^119 */
+static void widefelem_diff(widefelem out, const widefelem in) {
+ static const widelimb two120 = ((widelimb)1) << 120;
+ static const widelimb two120m64 =
+ (((widelimb)1) << 120) - (((widelimb)1) << 64);
+ static const widelimb two120m104m64 =
+ (((widelimb)1) << 120) - (((widelimb)1) << 104) - (((widelimb)1) << 64);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two120;
+ out[1] += two120m64;
+ out[2] += two120m64;
+ out[3] += two120;
+ out[4] += two120m104m64;
+ out[5] += two120m64;
+ out[6] += two120m64;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+}
+
+/* Subtract in mixed mode: out128 -= in64 */
+/* in[i] < 2^63 */
+static void felem_diff_128_64(widefelem out, const felem in) {
+ static const widelimb two64p8 = (((widelimb)1) << 64) + (((widelimb)1) << 8);
+ static const widelimb two64m8 = (((widelimb)1) << 64) - (((widelimb)1) << 8);
+ static const widelimb two64m48m8 =
+ (((widelimb)1) << 64) - (((widelimb)1) << 48) - (((widelimb)1) << 8);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two64p8;
+ out[1] += two64m48m8;
+ out[2] += two64m8;
+ out[3] += two64m8;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/* Multiply a field element by a scalar: out = out * scalar
+ * The scalars we actually use are small, so results fit without overflow */
+static void felem_scalar(felem out, const limb scalar) {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+}
+
+/* Multiply an unreduced field element by a scalar: out = out * scalar
+ * The scalars we actually use are small, so results fit without overflow */
+static void widefelem_scalar(widefelem out, const widelimb scalar) {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+}
+
+/* Square a field element: out = in^2 */
+static void felem_square(widefelem out, const felem in) {
+ limb tmp0, tmp1, tmp2;
+ tmp0 = 2 * in[0];
+ tmp1 = 2 * in[1];
+ tmp2 = 2 * in[2];
+ out[0] = ((widelimb)in[0]) * in[0];
+ out[1] = ((widelimb)in[0]) * tmp1;
+ out[2] = ((widelimb)in[0]) * tmp2 + ((widelimb)in[1]) * in[1];
+ out[3] = ((widelimb)in[3]) * tmp0 + ((widelimb)in[1]) * tmp2;
+ out[4] = ((widelimb)in[3]) * tmp1 + ((widelimb)in[2]) * in[2];
+ out[5] = ((widelimb)in[3]) * tmp2;
+ out[6] = ((widelimb)in[3]) * in[3];
+}
+
+/* Multiply two field elements: out = in1 * in2 */
+static void felem_mul(widefelem out, const felem in1, const felem in2) {
+ out[0] = ((widelimb)in1[0]) * in2[0];
+ out[1] = ((widelimb)in1[0]) * in2[1] + ((widelimb)in1[1]) * in2[0];
+ out[2] = ((widelimb)in1[0]) * in2[2] + ((widelimb)in1[1]) * in2[1] +
+ ((widelimb)in1[2]) * in2[0];
+ out[3] = ((widelimb)in1[0]) * in2[3] + ((widelimb)in1[1]) * in2[2] +
+ ((widelimb)in1[2]) * in2[1] + ((widelimb)in1[3]) * in2[0];
+ out[4] = ((widelimb)in1[1]) * in2[3] + ((widelimb)in1[2]) * in2[2] +
+ ((widelimb)in1[3]) * in2[1];
+ out[5] = ((widelimb)in1[2]) * in2[3] + ((widelimb)in1[3]) * in2[2];
+ out[6] = ((widelimb)in1[3]) * in2[3];
+}
+
+/* Reduce seven 128-bit coefficients to four 64-bit coefficients.
+ * Requires in[i] < 2^126,
+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
+static void felem_reduce(felem out, const widefelem in) {
+ static const widelimb two127p15 =
+ (((widelimb)1) << 127) + (((widelimb)1) << 15);
+ static const widelimb two127m71 =
+ (((widelimb)1) << 127) - (((widelimb)1) << 71);
+ static const widelimb two127m71m55 =
+ (((widelimb)1) << 127) - (((widelimb)1) << 71) - (((widelimb)1) << 55);
+ widelimb output[5];
+
+ /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
+ output[0] = in[0] + two127p15;
+ output[1] = in[1] + two127m71m55;
+ output[2] = in[2] + two127m71;
+ output[3] = in[3];
+ output[4] = in[4];
+
+ /* Eliminate in[4], in[5], in[6] */
+ output[4] += in[6] >> 16;
+ output[3] += (in[6] & 0xffff) << 40;
+ output[2] -= in[6];
+
+ output[3] += in[5] >> 16;
+ output[2] += (in[5] & 0xffff) << 40;
+ output[1] -= in[5];
+
+ output[2] += output[4] >> 16;
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 2 -> 3 -> 4 */
+ output[3] += output[2] >> 56;
+ output[2] &= 0x00ffffffffffffff;
+
+ output[4] = output[3] >> 56;
+ output[3] &= 0x00ffffffffffffff;
+
+ /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
+
+ /* Eliminate output[4] */
+ output[2] += output[4] >> 16;
+ /* output[2] < 2^56 + 2^56 = 2^57 */
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 0 -> 1 -> 2 -> 3 */
+ output[1] += output[0] >> 56;
+ out[0] = output[0] & 0x00ffffffffffffff;
+
+ output[2] += output[1] >> 56;
+ /* output[2] < 2^57 + 2^72 */
+ out[1] = output[1] & 0x00ffffffffffffff;
+ output[3] += output[2] >> 56;
+ /* output[3] <= 2^56 + 2^16 */
+ out[2] = output[2] & 0x00ffffffffffffff;
+
+ /* out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
+ * out[3] <= 2^56 + 2^16 (due to final carry),
+ * so out < 2*p */
+ out[3] = output[3];
+}
+
+static void felem_square_reduce(felem out, const felem in) {
+ widefelem tmp;
+ felem_square(tmp, in);
+ felem_reduce(out, tmp);
+}
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2) {
+ widefelem tmp;
+ felem_mul(tmp, in1, in2);
+ felem_reduce(out, tmp);
+}
+
+/* Reduce to unique minimal representation.
+ * Requires 0 <= in < 2*p (always call felem_reduce first) */
+static void felem_contract(felem out, const felem in) {
+ static const int64_t two56 = ((limb)1) << 56;
+ /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
+ /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
+ int64_t tmp[4], a;
+ tmp[0] = in[0];
+ tmp[1] = in[1];
+ tmp[2] = in[2];
+ tmp[3] = in[3];
+ /* Case 1: a = 1 iff in >= 2^224 */
+ a = (in[3] >> 56);
+ tmp[0] -= a;
+ tmp[1] += a << 40;
+ tmp[3] &= 0x00ffffffffffffff;
+ /* Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 and
+ * the lower part is non-zero */
+ a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
+ (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
+ a &= 0x00ffffffffffffff;
+ /* turn a into an all-one mask (if a = 0) or an all-zero mask */
+ a = (a - 1) >> 63;
+ /* subtract 2^224 - 2^96 + 1 if a is all-one */
+ tmp[3] &= a ^ 0xffffffffffffffff;
+ tmp[2] &= a ^ 0xffffffffffffffff;
+ tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
+ tmp[0] -= 1 & a;
+
+ /* eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
+ * be non-zero, so we only need one step */
+ a = tmp[0] >> 63;
+ tmp[0] += two56 & a;
+ tmp[1] -= 1 & a;
+
+ /* carry 1 -> 2 -> 3 */
+ tmp[2] += tmp[1] >> 56;
+ tmp[1] &= 0x00ffffffffffffff;
+
+ tmp[3] += tmp[2] >> 56;
+ tmp[2] &= 0x00ffffffffffffff;
+
+ /* Now 0 <= out < p */
+ out[0] = tmp[0];
+ out[1] = tmp[1];
+ out[2] = tmp[2];
+ out[3] = tmp[3];
+}
+
+/* Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
+ * elements are reduced to in < 2^225, so we only need to check three cases: 0,
+ * 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 */
+static limb felem_is_zero(const felem in) {
+ limb zero = in[0] | in[1] | in[2] | in[3];
+ zero = (((int64_t)(zero)-1) >> 63) & 1;
+
+ limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) |
+ (in[2] ^ 0x00ffffffffffffff) |
+ (in[3] ^ 0x00ffffffffffffff);
+ two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1;
+ limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) |
+ (in[2] ^ 0x00ffffffffffffff) |
+ (in[3] ^ 0x01ffffffffffffff);
+ two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1;
+ return (zero | two224m96p1 | two225m97p2);
+}
+
+static limb felem_is_zero_int(const felem in) {
+ return (int)(felem_is_zero(in) & ((limb)1));
+}
+
+/* Invert a field element */
+/* Computation chain copied from djb's code */
+static void felem_inv(felem out, const felem in) {
+ felem ftmp, ftmp2, ftmp3, ftmp4;
+ widefelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in);
+ felem_reduce(ftmp, tmp); /* 2 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^2 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 2 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^4 - 2 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^5 - 4 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^6 - 8 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^6 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^7 - 2 */
+ for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^12 - 1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^13 - 2 */
+ for (i = 0; i < 11; ++i) {/* 2^24 - 2^12 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^25 - 2 */
+ for (i = 0; i < 23; ++i) {/* 2^48 - 2^24 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp4, tmp); /* 2^49 - 2 */
+ for (i = 0; i < 47; ++i) {/* 2^96 - 2^48 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp4);
+ felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp4, tmp); /* 2^97 - 2 */
+ for (i = 0; i < 23; ++i) {/* 2^120 - 2^24 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp4);
+ felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
+ for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^126 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^127 - 2 */
+ felem_mul(tmp, ftmp, in);
+ felem_reduce(ftmp, tmp); /* 2^127 - 1 */
+ for (i = 0; i < 97; ++i) {/* 2^224 - 2^97 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ }
+ felem_mul(tmp, ftmp, ftmp3);
+ felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */
+}
+
+/* Copy in constant time:
+ * if icopy == 1, copy in to out,
+ * if icopy == 0, copy out to itself. */
+static void copy_conditional(felem out, const felem in, limb icopy) {
+ unsigned i;
+ /* icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one */
+ const limb copy = -icopy;
+ for (i = 0; i < 4; ++i) {
+ const limb tmp = copy & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+}
+
+/* ELLIPTIC CURVE POINT OPERATIONS
+ *
+ * Points are represented in Jacobian projective coordinates:
+ * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
+ * or to the point at infinity if Z == 0. */
+
+/* Double an elliptic curve point:
+ * (X', Y', Z') = 2 * (X, Y, Z), where
+ * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+ * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in) {
+ widefelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ felem_assign(ftmp, x_in);
+ felem_assign(ftmp2, x_in);
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp);
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp);
+
+ /* beta = x*gamma */
+ felem_mul(tmp, x_in, gamma);
+ felem_reduce(beta, tmp);
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff(ftmp, delta);
+ /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
+ felem_sum(ftmp2, delta);
+ /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
+ felem_scalar(ftmp2, 3);
+ /* ftmp2[i] < 3 * 2^58 < 2^60 */
+ felem_mul(tmp, ftmp, ftmp2);
+ /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
+ felem_reduce(alpha, tmp);
+
+ /* x' = alpha^2 - 8*beta */
+ felem_square(tmp, alpha);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+ felem_assign(ftmp, beta);
+ felem_scalar(ftmp, 8);
+ /* ftmp[i] < 8 * 2^57 = 2^60 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(x_out, tmp);
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum(delta, gamma);
+ /* delta[i] < 2^57 + 2^57 = 2^58 */
+ felem_assign(ftmp, y_in);
+ felem_sum(ftmp, z_in);
+ /* ftmp[i] < 2^57 + 2^57 = 2^58 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
+ felem_diff_128_64(tmp, delta);
+ /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
+ felem_reduce(z_out, tmp);
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar(beta, 4);
+ /* beta[i] < 4 * 2^57 = 2^59 */
+ felem_diff(beta, x_out);
+ /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
+ felem_mul(tmp, alpha, beta);
+ /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
+ felem_square(tmp2, gamma);
+ /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
+ widefelem_scalar(tmp2, 8);
+ /* tmp2[i] < 8 * 2^116 = 2^119 */
+ widefelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^119 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp);
+}
+
+/* Add two elliptic curve points:
+ * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
+ * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
+ * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
+ * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 *
+ * X_1)^2 - X_3) -
+ * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
+ * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
+ *
+ * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0. */
+
+/* This function is not entirely constant-time: it includes a branch for
+ * checking whether the two input points are equal, (while not equal to the
+ * point at infinity). This case never happens during single point
+ * multiplication, so there is no timing leak for ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3, const felem x1,
+ const felem y1, const felem z1, const int mixed,
+ const felem x2, const felem y2, const felem z2) {
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
+ widefelem tmp, tmp2;
+ limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+
+ if (!mixed) {
+ /* ftmp2 = z2^2 */
+ felem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* ftmp4 = z2^3 */
+ felem_mul(tmp, ftmp2, z2);
+ felem_reduce(ftmp4, tmp);
+
+ /* ftmp4 = z2^3*y1 */
+ felem_mul(tmp2, ftmp4, y1);
+ felem_reduce(ftmp4, tmp2);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_mul(tmp2, ftmp2, x1);
+ felem_reduce(ftmp2, tmp2);
+ } else {
+ /* We'll assume z2 = 1 (special case z2 = 0 is handled later) */
+
+ /* ftmp4 = z2^3*y1 */
+ felem_assign(ftmp4, y1);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_assign(ftmp2, x1);
+ }
+
+ /* ftmp = z1^2 */
+ felem_square(tmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp3 = z1^3 */
+ felem_mul(tmp, ftmp, z1);
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^3*y2 */
+ felem_mul(tmp, ftmp3, y2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp3 = z1^3*y2 - z2^3*y1 */
+ felem_diff_128_64(tmp, ftmp4);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^2*x2 */
+ felem_mul(tmp, ftmp, x2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp = z1^2*x2 - z2^2*x1 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp, tmp);
+
+ /* the formulae are incorrect if the points are equal
+ * so we check for this and do doubling if this happens */
+ x_equal = felem_is_zero(ftmp);
+ y_equal = felem_is_zero(ftmp3);
+ z1_is_zero = felem_is_zero(z1);
+ z2_is_zero = felem_is_zero(z2);
+ /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* ftmp5 = z1*z2 */
+ if (!mixed) {
+ felem_mul(tmp, z1, z2);
+ felem_reduce(ftmp5, tmp);
+ } else {
+ /* special case z2 = 0 is handled later */
+ felem_assign(ftmp5, z1);
+ }
+
+ /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(z_out, tmp);
+
+ /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(ftmp5, tmp);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp4, ftmp5);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
+ felem_square(tmp2, ftmp3);
+ /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
+
+ /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp2);
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2 * 2^57 = 2^58 */
+
+ /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
+ 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
+ felem_reduce(x_out, tmp2);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
+ felem_diff(ftmp2, x_out);
+ /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) */
+ felem_mul(tmp2, ftmp3, ftmp2);
+ /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
+
+ /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
+ z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ widefelem_diff(tmp2, tmp);
+ /* tmp2[i] < 2^118 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp2);
+
+ /* the result (x_out, y_out, z_out) is incorrect if one of the inputs is
+ * the point at infinity, so we need to check for this separately */
+
+ /* if point 1 is at infinity, copy point 2 to output, and vice versa */
+ copy_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+}
+
+/* select_point selects the |idx|th point from a precomputation table and
+ * copies it to out. */
+static void select_point(const u64 idx, unsigned int size,
+ const felem pre_comp[/*size*/][3], felem out[3]) {
+ unsigned i, j;
+ limb *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(felem));
+
+ for (i = 0; i < size; i++) {
+ const limb *inlimbs = &pre_comp[i][0][0];
+ u64 mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < 4 * 3; j++) {
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+ }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, unsigned i) {
+ if (i >= 224) {
+ return 0;
+ }
+ return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/* Interleaved point multiplication using precomputed point multiples:
+ * The small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[],
+ * the scalars in scalars[]. If g_scalar is non-NULL, we also add this multiple
+ * of the generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[],
+ const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const felem pre_comp[][17][3],
+ const felem g_pre_comp[2][16][3]) {
+ int i, skip;
+ unsigned num;
+ unsigned gen_mul = (g_scalar != NULL);
+ felem nq[3], tmp[4];
+ u64 bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /* Loop over all scalars msb-to-lsb, interleaving additions
+ * of multiples of the generator (two in each of the last 28 rounds)
+ * and additions of other points multiples (every 5th round). */
+ skip = 1; /* save two point operations in the first round */
+ for (i = (num_points ? 220 : 27); i >= 0; --i) {
+ /* double */
+ if (!skip) {
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 27)) {
+ /* first, look 28 bits upwards */
+ bits = get_bit(g_scalar, i + 196) << 3;
+ bits |= get_bit(g_scalar, i + 140) << 2;
+ bits |= get_bit(g_scalar, i + 84) << 1;
+ bits |= get_bit(g_scalar, i + 28);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[1], tmp);
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+
+ /* second, look at the current position */
+ bits = get_bit(g_scalar, i + 168) << 3;
+ bits |= get_bit(g_scalar, i + 112) << 2;
+ bits |= get_bit(g_scalar, i + 56) << 1;
+ bits |= get_bit(g_scalar, i);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[0], tmp);
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0],
+ tmp[1], tmp[2]);
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0)) {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num) {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /* select the point to add or subtract */
+ select_point(digit, 17, pre_comp[num], tmp);
+ felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative point */
+ copy_conditional(tmp[1], tmp[3], sign);
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], mixed, tmp[0],
+ tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+}
+
+int ec_GFp_nistp224_group_init(EC_GROUP *group) {
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+}
+
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx) {
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL) {
+ ctx = BN_CTX_new();
+ new_ctx = ctx;
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL)) {
+ goto err;
+ }
+ BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if (BN_cmp(curve_p, p) ||
+ BN_cmp(curve_a, a) ||
+ BN_cmp(curve_b, b)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+/* Takes the Jacobian coordinates (X, Y, Z) of a point and returns
+ * (X', Y') = (X/Z^2, Y/Z^3) */
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx) {
+ felem z1, z2, x_in, y_in, x_out, y_out;
+ widefelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ if (!BN_to_felem(x_in, &point->X) ||
+ !BN_to_felem(y_in, &point->Y) ||
+ !BN_to_felem(z1, &point->Z)) {
+ return 0;
+ }
+
+ felem_inv(z2, z1);
+ felem_square(tmp, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1);
+ felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL && !felem_to_BN(x, x_out)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ return 0;
+ }
+
+ felem_mul(tmp, z1, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1);
+ felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL && !felem_to_BN(y, y_out)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void make_points_affine(size_t num, felem points[/*num*/][3],
+ felem tmp_felems[/*num+1*/]) {
+ /* Runs in constant time, unless an input is the point at infinity
+ * (which normally shouldn't happen). */
+ ec_GFp_nistp_points_make_affine_internal(
+ num, points, sizeof(felem), tmp_felems, (void (*)(void *))felem_one,
+ (int (*)(const void *))felem_is_zero_int,
+ (void (*)(void *, const void *))felem_assign,
+ (void (*)(void *, const void *))felem_square_reduce,
+ (void (*)(void *, const void *, const void *))felem_mul_reduce,
+ (void (*)(void *, const void *))felem_inv,
+ (void (*)(void *, const void *))felem_contract);
+}
+
+/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
+ * Result is stored in r (r can equal one of the inputs). */
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx) {
+ int ret = 0;
+ int j;
+ unsigned i;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ felem(*pre_comp)[17][3] = NULL;
+ felem *tmp_felems = NULL;
+ felem_bytearray tmp;
+ unsigned num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ felem x_in, y_in, z_in, x_out, y_out, z_out;
+ const felem(*g_pre_comp)[16][3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL) {
+ ctx = BN_CTX_new();
+ new_ctx = ctx;
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+
+ BN_CTX_start(ctx);
+ if ((x = BN_CTX_get(ctx)) == NULL ||
+ (y = BN_CTX_get(ctx)) == NULL ||
+ (z = BN_CTX_get(ctx)) == NULL ||
+ (tmp_scalar = BN_CTX_get(ctx)) == NULL) {
+ goto err;
+ }
+
+ if (scalar != NULL) {
+ /* try to use the standard precomputation */
+ g_pre_comp = &gmul[0];
+ generator = EC_POINT_new(group);
+ if (generator == NULL) {
+ goto err;
+ }
+ /* get the generator from precomputation */
+ if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
+ !felem_to_BN(y, g_pre_comp[0][1][1]) ||
+ !felem_to_BN(z, g_pre_comp[0][1][2])) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z,
+ ctx)) {
+ goto err;
+ }
+
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ } else {
+ /* we don't have valid precomputation:
+ * treat the generator as a random point */
+ num_points = num_points + 1;
+ }
+ }
+
+ if (num_points > 0) {
+ if (num_points >= 3) {
+ /* unless we precompute multiples for just one or two points,
+ * converting those into affine form is time well spent */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
+ if (mixed) {
+ tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
+ }
+ if (secrets == NULL ||
+ pre_comp == NULL ||
+ (mixed && tmp_felems == NULL)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+ for (i = 0; i < num_points; ++i) {
+ if (i == num) {
+ /* the generator */
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ } else {
+ /* the i^th point */
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+
+ if (p_scalar != NULL && p != NULL) {
+ /* reduce scalar to 0 <= scalar < 2^224 */
+ if (BN_num_bits(p_scalar) > 224 || BN_is_negative(p_scalar)) {
+ /* this is an unusual input, and we don't guarantee
+ * constant-timeness */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else {
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ }
+
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if (!BN_to_felem(x_out, &p->X) ||
+ !BN_to_felem(y_out, &p->Y) ||
+ !BN_to_felem(z_out, &p->Z)) {
+ goto err;
+ }
+
+ felem_assign(pre_comp[i][1][0], x_out);
+ felem_assign(pre_comp[i][1][1], y_out);
+ felem_assign(pre_comp[i][1][2], z_out);
+
+ for (j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ point_add(pre_comp[i][j][0], pre_comp[i][j][1], pre_comp[i][j][2],
+ pre_comp[i][1][0], pre_comp[i][1][1], pre_comp[i][1][2],
+ 0, pre_comp[i][j - 1][0], pre_comp[i][j - 1][1],
+ pre_comp[i][j - 1][2]);
+ } else {
+ point_double(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][j / 2][0],
+ pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]);
+ }
+ }
+ }
+ }
+
+ if (mixed) {
+ make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+ }
+ }
+
+ /* the scalar for the generator */
+ if (scalar != NULL && have_pre_comp) {
+ memset(g_secret, 0, sizeof(g_secret));
+ /* reduce scalar to 0 <= scalar < 2^224 */
+ if (BN_num_bits(scalar) > 224 || BN_is_negative(scalar)) {
+ /* this is an unusual input, and we don't guarantee constant-timeness */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else {
+ num_bytes = BN_bn2bin(scalar, tmp);
+ }
+
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation */
+ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
+ num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp,
+ g_pre_comp);
+ } else {
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
+ num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+ }
+
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if (!felem_to_BN(x, x_in) ||
+ !felem_to_BN(y, y_in) ||
+ !felem_to_BN(z, z_in)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = ec_point_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+err:
+ BN_CTX_end(ctx);
+ EC_POINT_free(generator);
+ BN_CTX_free(new_ctx);
+ OPENSSL_free(secrets);
+ OPENSSL_free(pre_comp);
+ OPENSSL_free(tmp_felems);
+ return ret;
+}
+
+const EC_METHOD *EC_GFp_nistp224_method(void) {
+ static const EC_METHOD ret = {ec_GFp_nistp224_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_nistp224_group_set_curve,
+ ec_GFp_nistp224_point_get_affine_coordinates,
+ ec_GFp_nistp224_points_mul,
+ 0 /* precompute_mult */,
+ ec_GFp_simple_field_mul,
+ ec_GFp_simple_field_sqr,
+ 0 /* field_encode */,
+ 0 /* field_decode */,
+ 0 /* field_set_to_one */};
+
+ return &ret;
+}
+
+#endif /* 64_BIT && !WINDOWS && !SMALL */
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index 3946b29..2adcd6b 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -1902,26 +1902,14 @@ err:
const EC_METHOD *EC_GFp_nistp256_method(void) {
static const EC_METHOD ret = {
- EC_FLAGS_DEFAULT_OCT,
ec_GFp_nistp256_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve,
- ec_GFp_simple_group_get_curve, ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant, ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish, ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy, ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_nistp256_point_get_affine_coordinates,
- 0 /* point_set_compressed_coordinates */, 0 /* point2oct */,
- 0 /* oct2point */, ec_GFp_simple_add, ec_GFp_simple_dbl,
- ec_GFp_simple_invert, ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve, ec_GFp_simple_cmp, ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine, ec_GFp_nistp256_points_mul,
- 0 /* precompute_mult */, 0 /* have_precompute_mult */,
- ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr, 0 /* field_div */,
+ ec_GFp_nistp256_points_mul,
+ 0 /* precompute_mult */,
+ ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */
};
diff --git a/src/crypto/ec/simple.c b/src/crypto/ec/simple.c
index c62199c..7e611eb 100644
--- a/src/crypto/ec/simple.c
+++ b/src/crypto/ec/simple.c
@@ -77,41 +77,16 @@
const EC_METHOD *EC_GFp_simple_method(void) {
- static const EC_METHOD ret = {EC_FLAGS_DEFAULT_OCT,
- ec_GFp_simple_group_init,
+ static const EC_METHOD ret = {ec_GFp_simple_group_init,
ec_GFp_simple_group_finish,
ec_GFp_simple_group_clear_finish,
ec_GFp_simple_group_copy,
ec_GFp_simple_group_set_curve,
- ec_GFp_simple_group_get_curve,
- ec_GFp_simple_group_get_degree,
- ec_GFp_simple_group_check_discriminant,
- ec_GFp_simple_point_init,
- ec_GFp_simple_point_finish,
- ec_GFp_simple_point_clear_finish,
- ec_GFp_simple_point_copy,
- ec_GFp_simple_point_set_to_infinity,
- ec_GFp_simple_set_Jprojective_coordinates_GFp,
- ec_GFp_simple_get_Jprojective_coordinates_GFp,
- ec_GFp_simple_point_set_affine_coordinates,
ec_GFp_simple_point_get_affine_coordinates,
- 0,
- 0,
- 0,
- ec_GFp_simple_add,
- ec_GFp_simple_dbl,
- ec_GFp_simple_invert,
- ec_GFp_simple_is_at_infinity,
- ec_GFp_simple_is_on_curve,
- ec_GFp_simple_cmp,
- ec_GFp_simple_make_affine,
- ec_GFp_simple_points_make_affine,
0 /* mul */,
0 /* precompute_mult */,
- 0 /* have_precompute_mult */,
ec_GFp_simple_field_mul,
ec_GFp_simple_field_sqr,
- 0 /* field_div */,
0 /* field_encode */,
0 /* field_decode */,
0 /* field_set_to_one */};
@@ -270,7 +245,7 @@ err:
return ret;
}
-int ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
+unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
return BN_num_bits(&group->field);
}
diff --git a/src/crypto/ec/wnaf.c b/src/crypto/ec/wnaf.c
index 7fa0e1b..4aaffd9 100644
--- a/src/crypto/ec/wnaf.c
+++ b/src/crypto/ec/wnaf.c
@@ -846,8 +846,3 @@ err:
EC_POINT_free(base);
return ret;
}
-
-
-int ec_wNAF_have_precompute_mult(const EC_GROUP *group) {
- return group->pre_comp != NULL;
-}
diff --git a/src/crypto/ecdh/ecdh.c b/src/crypto/ecdh/ecdh.c
index 14856db..4a1964a 100644
--- a/src/crypto/ecdh/ecdh.c
+++ b/src/crypto/ecdh/ecdh.c
@@ -75,33 +75,27 @@
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
- EC_KEY *priv_key, void *(*KDF)(const void *in, size_t inlen,
- void *out, size_t *outlen)) {
- BN_CTX *ctx;
- EC_POINT *tmp = NULL;
- BIGNUM *x = NULL, *y = NULL;
- const BIGNUM *priv;
- const EC_GROUP *group;
- int ret = -1;
- size_t buflen;
- uint8_t *buf = NULL;
-
- if ((ctx = BN_CTX_new()) == NULL) {
- goto err;
- }
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
-
- priv = EC_KEY_get0_private_key(priv_key);
+ EC_KEY *priv_key,
+ void *(*kdf)(const void *in, size_t inlen, void *out,
+ size_t *outlen)) {
+ const BIGNUM *const priv = EC_KEY_get0_private_key(priv_key);
if (priv == NULL) {
OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE);
- goto err;
+ return -1;
}
- group = EC_KEY_get0_group(priv_key);
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return -1;
+ }
+ BN_CTX_start(ctx);
+
+ int ret = -1;
+ size_t buflen = 0;
+ uint8_t *buf = NULL;
- tmp = EC_POINT_new(group);
+ const EC_GROUP *const group = EC_KEY_get0_group(priv_key);
+ EC_POINT *tmp = EC_POINT_new(group);
if (tmp == NULL) {
OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
goto err;
@@ -112,7 +106,13 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
goto err;
}
- if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
+ BIGNUM *x = BN_CTX_get(ctx);
+ if (!x) {
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx)) {
OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
@@ -129,33 +129,25 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
goto err;
}
- if (KDF != 0) {
- if (KDF(buf, buflen, out, &outlen) == NULL) {
+ if (kdf != NULL) {
+ if (kdf(buf, buflen, out, &outlen) == NULL) {
OPENSSL_PUT_ERROR(ECDH, ECDH_R_KDF_FAILED);
goto err;
}
- ret = outlen;
} else {
/* no KDF, just copy as much as we can */
- if (outlen > buflen) {
+ if (buflen < outlen) {
outlen = buflen;
}
memcpy(out, buf, outlen);
- ret = outlen;
}
+ ret = outlen;
+
err:
- if (tmp) {
- EC_POINT_free(tmp);
- }
- if (ctx) {
- BN_CTX_end(ctx);
- }
- if (ctx) {
- BN_CTX_free(ctx);
- }
- if (buf) {
- OPENSSL_free(buf);
- }
+ OPENSSL_free(buf);
+ EC_POINT_free(tmp);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
return ret;
}
diff --git a/src/crypto/ecdsa/CMakeLists.txt b/src/crypto/ecdsa/CMakeLists.txt
index e7581be..0cc672e 100644
--- a/src/crypto/ecdsa/CMakeLists.txt
+++ b/src/crypto/ecdsa/CMakeLists.txt
@@ -19,3 +19,4 @@ add_executable(
)
target_link_libraries(ecdsa_test crypto)
+add_dependencies(all_tests ecdsa_test)
diff --git a/src/crypto/err/CMakeLists.txt b/src/crypto/err/CMakeLists.txt
index 8519e51..a095b54 100644
--- a/src/crypto/err/CMakeLists.txt
+++ b/src/crypto/err/CMakeLists.txt
@@ -47,3 +47,4 @@ add_executable(
)
target_link_libraries(err_test crypto)
+add_dependencies(all_tests err_test)
diff --git a/src/crypto/err/err_test.cc b/src/crypto/err/err_test.cc
index 6643c68..bdf3486 100644
--- a/src/crypto/err/err_test.cc
+++ b/src/crypto/err/err_test.cc
@@ -30,7 +30,7 @@ static bool TestOverflow() {
/* Errors are returned in order they were pushed, with the least recent ones
* removed, up to |ERR_NUM_ERRORS - 1| errors. So the errors returned are
* |ERR_NUM_ERRORS + 2| through |ERR_NUM_ERRORS * 2|, inclusive. */
- if (err == 0 || ERR_GET_REASON(err) != i + ERR_NUM_ERRORS + 2) {
+ if (err == 0 || ((unsigned)ERR_GET_REASON(err)) != i + ERR_NUM_ERRORS + 2) {
fprintf(stderr, "ERR_get_error failed at %u\n", i);
return false;
}
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 5d2e918..000f076 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -47,3 +47,4 @@ add_executable(
target_link_libraries(evp_extra_test crypto)
target_link_libraries(evp_test crypto)
target_link_libraries(pbkdf_test crypto)
+add_dependencies(all_tests evp_extra_test evp_test pbkdf_test)
diff --git a/src/crypto/evp/digestsign.c b/src/crypto/evp/digestsign.c
index ccb4de4..69c483a 100644
--- a/src/crypto/evp/digestsign.c
+++ b/src/crypto/evp/digestsign.c
@@ -55,7 +55,6 @@
#include <openssl/evp.h>
-#include <openssl/digest.h>
#include <openssl/err.h>
#include "internal.h"
@@ -79,10 +78,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ctx->pctx_ops = &md_pctx_ops;
if (type == NULL) {
- type = EVP_sha1();
- }
-
- if (type == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST);
return 0;
}
diff --git a/src/crypto/evp/evp_asn1.c b/src/crypto/evp/evp_asn1.c
index 356c62b..c57f411 100644
--- a/src/crypto/evp/evp_asn1.c
+++ b/src/crypto/evp/evp_asn1.c
@@ -83,16 +83,22 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
goto err;
}
+ const uint8_t *in = *inp;
if (!ret->ameth->old_priv_decode ||
- !ret->ameth->old_priv_decode(ret, inp, len)) {
+ !ret->ameth->old_priv_decode(ret, &in, len)) {
if (ret->ameth->priv_decode) {
- PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, inp, len);
+ /* Reset |in| in case |old_priv_decode| advanced it on error. */
+ in = *inp;
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &in, len);
if (!p8) {
goto err;
}
EVP_PKEY_free(ret);
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
+ if (ret == NULL) {
+ goto err;
+ }
} else {
OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
goto err;
@@ -102,6 +108,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
if (out != NULL) {
*out = ret;
}
+ *inp = in;
return ret;
err:
@@ -129,7 +136,8 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
keytype = EVP_PKEY_EC;
} else if (sk_ASN1_TYPE_num(inkey) == 3) {
/* This seems to be PKCS8, not traditional format */
- PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, inp, len);
+ p = *inp;
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
EVP_PKEY *ret;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
@@ -139,6 +147,11 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
}
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ *inp = p;
if (out) {
*out = ret;
}
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index 9c955fa..bd70040 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -321,6 +321,27 @@ static const uint8_t kExampleBadECKeyDER[] = {
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
+// kExampleBadECKeyDER2 is a sample EC private key encoded as an ECPrivateKey
+// structure, but with the curve OID swapped out for 1.1.1.1.1.1.1.1.1. It is
+// then concatenated with an ECPrivateKey wrapped in a PrivateKeyInfo,
+// optional public key omitted, and with the private key chopped off.
+static const uint8_t kExampleBadECKeyDER2[] = {
+ 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x07, 0x0f, 0x08, 0x72, 0x7a,
+ 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08,
+ 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e, 0xe8, 0xd1, 0xc9, 0xce, 0x0a,
+ 0x8b, 0xb4, 0x6a, 0xa0, 0x0a, 0x06, 0x08, 0x29, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69,
+ 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c,
+ 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9,
+ 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18,
+ 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16,
+ 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22,
+ 0xc1, 0x30, 0x41, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
+ 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+ 0x03, 0x01, 0x07, 0x04, 0x27, 0x30, 0x25, 0x02, 0x01, 0x01, 0x04, 0x20,
+ 0x07,
+};
+
static ScopedEVP_PKEY LoadExampleRSAKey() {
ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
sizeof(kExampleRSAKeyDER)));
@@ -530,6 +551,64 @@ static bool TestEVP_PKCS82PKEY(void) {
fprintf(stderr, "Imported invalid EC key\n");
return false;
}
+ ERR_clear_error();
+
+ return true;
+}
+
+// Testd2i_PrivateKey tests |d2i_PrivateKey|.
+static bool Testd2i_PrivateKey(void) {
+ const uint8_t *derp = kExampleRSAKeyDER;
+ ScopedEVP_PKEY pkey(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
+ sizeof(kExampleRSAKeyDER)));
+ if (!pkey || derp != kExampleRSAKeyDER + sizeof(kExampleRSAKeyDER)) {
+ fprintf(stderr, "Failed to import raw RSA key.\n");
+ return false;
+ }
+
+ derp = kExampleDSAKeyDER;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_DSA, nullptr, &derp,
+ sizeof(kExampleDSAKeyDER)));
+ if (!pkey || derp != kExampleDSAKeyDER + sizeof(kExampleDSAKeyDER)) {
+ fprintf(stderr, "Failed to import raw DSA key.\n");
+ return false;
+ }
+
+ derp = kExampleRSAKeyPKCS8;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &derp,
+ sizeof(kExampleRSAKeyPKCS8)));
+ if (!pkey || derp != kExampleRSAKeyPKCS8 + sizeof(kExampleRSAKeyPKCS8)) {
+ fprintf(stderr, "Failed to import PKCS#8 RSA key.\n");
+ return false;
+ }
+
+ derp = kExampleECKeyDER;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
+ sizeof(kExampleECKeyDER)));
+ if (!pkey || derp != kExampleECKeyDER + sizeof(kExampleECKeyDER)) {
+ fprintf(stderr, "Failed to import raw EC key.\n");
+ return false;
+ }
+
+ derp = kExampleBadECKeyDER;
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
+ sizeof(kExampleBadECKeyDER)));
+ if (pkey) {
+ fprintf(stderr, "Imported invalid EC key.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ // Copy the input into a |malloc|'d vector to flag memory errors.
+ std::vector<uint8_t> copy(kExampleBadECKeyDER2, kExampleBadECKeyDER2 +
+ sizeof(kExampleBadECKeyDER2));
+ derp = bssl::vector_data(&copy);
+ pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp, copy.size()));
+ if (pkey) {
+ fprintf(stderr, "Imported invalid EC key #2.\n");
+ return false;
+ }
+ ERR_clear_error();
return true;
}
@@ -596,6 +675,12 @@ int main(void) {
return 1;
}
+ if (!Testd2i_PrivateKey()) {
+ fprintf(stderr, "Testd2i_PrivateKey failed\n");
+ ERR_print_errors_fp(stderr);
+ return 1;
+ }
+
printf("PASS\n");
return 0;
}
diff --git a/src/crypto/evp/pbkdf.c b/src/crypto/evp/pbkdf.c
index be6ed86..b06b922 100644
--- a/src/crypto/evp/pbkdf.c
+++ b/src/crypto/evp/pbkdf.c
@@ -123,6 +123,22 @@ int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len,
p += cplen;
}
HMAC_CTX_cleanup(&hctx_tpl);
+
+ // RFC 2898 describes iterations (c) as being a "positive integer", so a
+ // value of 0 is an error.
+ //
+ // Unfortunatley not all consumers of PKCS5_PBKDF2_HMAC() check their return
+ // value, expecting it to succeed and unconditonally using |out_key|.
+ // As a precaution for such callsites in external code, the old behavior
+ // of iterations < 1 being treated as iterations == 1 is preserved, but
+ // additionally an error result is returned.
+ //
+ // TODO(eroman): Figure out how to remove this compatibility hack, or change
+ // the default to something more sensible like 2048.
+ if (iterations == 0) {
+ return 0;
+ }
+
return 1;
}
diff --git a/src/crypto/evp/pbkdf_test.cc b/src/crypto/evp/pbkdf_test.cc
index ae2f405..a39189f 100644
--- a/src/crypto/evp/pbkdf_test.cc
+++ b/src/crypto/evp/pbkdf_test.cc
@@ -149,6 +149,44 @@ static bool TestSHA2() {
return true;
}
+// Tests key derivation using iterations=0.
+//
+// RFC 2898 defines the iteration count (c) as a "positive integer". So doing a
+// key derivation with iterations=0 is ill-defined and should result in a
+// failure.
+static bool TestZeroIterations() {
+ static const char kPassword[] = "password";
+ const size_t password_len = strlen(kPassword);
+ static const uint8_t kSalt[] = {1, 2, 3, 4};
+ const size_t salt_len = sizeof(kSalt);
+ const EVP_MD *digest = EVP_sha1();
+
+ uint8_t key[10] = {0};
+ const size_t key_len = sizeof(key);
+
+ // Verify that calling with iterations=1 works.
+ if (!PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
+ 1 /* iterations */, digest, key_len, key)) {
+ fprintf(stderr, "PBKDF2 failed with iterations=1\n");
+ return false;
+ }
+
+ // Flip the first key byte (so can later test if it got set).
+ const uint8_t expected_first_byte = key[0];
+ key[0] = ~key[0];
+
+ // However calling it with iterations=0 fails.
+ if (PKCS5_PBKDF2_HMAC(kPassword, password_len, kSalt, salt_len,
+ 0 /* iterations */, digest, key_len, key)) {
+ fprintf(stderr, "PBKDF2 returned zero with iterations=0\n");
+ return false;
+ }
+
+ // For backwards compatibility, the iterations == 0 case still fills in
+ // the out key.
+ return key[0] == expected_first_byte;
+}
+
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
@@ -173,6 +211,11 @@ int main(void) {
return 1;
}
+ if (!TestZeroIterations()) {
+ fprintf(stderr, "TestZeroIterations failed\n");
+ return 1;
+ }
+
printf("PASS\n");
ERR_free_strings();
return 0;
diff --git a/src/crypto/hkdf/CMakeLists.txt b/src/crypto/hkdf/CMakeLists.txt
index 53bf558..d9db933 100644
--- a/src/crypto/hkdf/CMakeLists.txt
+++ b/src/crypto/hkdf/CMakeLists.txt
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(hkdf_test crypto)
+add_dependencies(all_tests hkdf_test)
diff --git a/src/crypto/hmac/CMakeLists.txt b/src/crypto/hmac/CMakeLists.txt
index 392ce01..179a53b 100644
--- a/src/crypto/hmac/CMakeLists.txt
+++ b/src/crypto/hmac/CMakeLists.txt
@@ -18,3 +18,4 @@ add_executable(
)
target_link_libraries(hmac_test crypto)
+add_dependencies(all_tests hmac_test)
diff --git a/src/crypto/lhash/CMakeLists.txt b/src/crypto/lhash/CMakeLists.txt
index ce785eb..4f4dea7 100644
--- a/src/crypto/lhash/CMakeLists.txt
+++ b/src/crypto/lhash/CMakeLists.txt
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(lhash_test crypto)
+add_dependencies(all_tests lhash_test)
diff --git a/src/crypto/modes/CMakeLists.txt b/src/crypto/modes/CMakeLists.txt
index 6da5207..41f71d7 100644
--- a/src/crypto/modes/CMakeLists.txt
+++ b/src/crypto/modes/CMakeLists.txt
@@ -63,3 +63,4 @@ add_executable(
)
target_link_libraries(gcm_test crypto)
+add_dependencies(all_tests gcm_test)
diff --git a/src/crypto/modes/asm/aesni-gcm-x86_64.pl b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
index 7e4e04e..0ca89c7 100644
--- a/src/crypto/modes/asm/aesni-gcm-x86_64.pl
+++ b/src/crypto/modes/asm/aesni-gcm-x86_64.pl
@@ -41,24 +41,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $avx goes up to 2.
+$avx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl
index dc5b99e..df33be5 100644
--- a/src/crypto/modes/asm/ghash-armv4.pl
+++ b/src/crypto/modes/asm/ghash-armv4.pl
@@ -133,7 +133,6 @@ ___
}
$code=<<___;
-#if defined(__arm__)
#include <openssl/arm_arch.h>
.syntax unified
@@ -504,8 +503,6 @@ ___
$code.=<<___;
.asciz "GHASH for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
-
-#endif
___
foreach (split("\n",$code)) {
diff --git a/src/crypto/modes/asm/ghash-x86_64.pl b/src/crypto/modes/asm/ghash-x86_64.pl
index 5a7ce39..e42ca32 100644
--- a/src/crypto/modes/asm/ghash-x86_64.pl
+++ b/src/crypto/modes/asm/ghash-x86_64.pl
@@ -90,24 +90,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $avx goes up to 2.
+$avx = 0;
open OUT,"| \"$^X\" $xlate $flavour $output";
*STDOUT=*OUT;
diff --git a/src/crypto/modes/cbc.c b/src/crypto/modes/cbc.c
index 931b718..e41f2b4 100644
--- a/src/crypto/modes/cbc.c
+++ b/src/crypto/modes/cbc.c
@@ -45,7 +45,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
#include <assert.h>
#include <string.h>
diff --git a/src/crypto/modes/cfb.c b/src/crypto/modes/cfb.c
index 738a438..c58614b 100644
--- a/src/crypto/modes/cfb.c
+++ b/src/crypto/modes/cfb.c
@@ -46,7 +46,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+#include <openssl/type_check.h>
#include <assert.h>
#include <string.h>
@@ -54,6 +54,8 @@
#include "internal.h"
+OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
+
void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num, int enc,
block128_f block) {
@@ -61,7 +63,6 @@ void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
size_t l = 0;
assert(in && out && key && ivec && num);
- assert((16 % sizeof(size_t)) == 0);
n = *num;
diff --git a/src/crypto/modes/ctr.c b/src/crypto/modes/ctr.c
index 64062b2..52ff048 100644
--- a/src/crypto/modes/ctr.c
+++ b/src/crypto/modes/ctr.c
@@ -45,7 +45,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+
+#include <openssl/type_check.h>
#include <assert.h>
#include <string.h>
@@ -72,6 +73,8 @@ static void ctr128_inc(uint8_t *counter) {
} while (n);
}
+OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
+
/* The input encrypted as though 128bit counter mode is being used. The extra
* state information to record how much of the 128bit block we have used is
* contained in *num, and the encrypted counter is kept in ecount_buf. Both
@@ -91,7 +94,6 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
assert(key && ecount_buf && num);
assert(len == 0 || (in && out));
assert(*num < 16);
- assert((16 % sizeof(size_t)) == 0);
n = *num;
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index 593dce8..8aac741 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -46,7 +46,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+#include <openssl/base.h>
#include <assert.h>
#include <string.h>
@@ -86,6 +86,9 @@
} \
} while (0)
+// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four
+// bits of a |size_t|.
+static const size_t kSizeTWithoutLower4Bits = (size_t) -16;
static void gcm_init_4bit(u128 Htable[16], uint64_t H[2]) {
u128 V;
@@ -355,7 +358,7 @@ void gcm_ghash_4bit_x86(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in
#define GCM_FUNCREF_4BIT
static int pmull_capable(void) {
- return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
+ return CRYPTO_is_ARMv8_PMULL_capable();
}
void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]);
@@ -403,7 +406,7 @@ void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
#endif
#endif
-GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) {
+GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key, block128_f block) {
GCM128_CONTEXT *ret;
ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT));
@@ -414,7 +417,8 @@ GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) {
return ret;
}
-void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) {
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
+ block128_f block) {
const union {
long one;
char little;
@@ -422,7 +426,6 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) {
memset(ctx, 0, sizeof(*ctx));
ctx->block = block;
- ctx->key = key;
(*block)(ctx->H.c, ctx->H.c, key);
@@ -488,7 +491,8 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) {
#endif
}
-void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv, size_t len) {
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *iv, size_t len) {
const union {
long one;
char little;
@@ -556,7 +560,7 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv, size_t len) {
}
}
- (*ctx->block)(ctx->Yi.c, ctx->EK0.c, ctx->key);
+ (*ctx->block)(ctx->Yi.c, ctx->EK0.c, key);
++ctr;
if (is_endian.little) {
PUTU32(ctx->Yi.c + 12, ctr);
@@ -629,8 +633,9 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) {
return 1;
}
-int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
- unsigned char *out, size_t len) {
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
+ const unsigned char *in, unsigned char *out,
+ size_t len) {
const union {
long one;
char little;
@@ -639,7 +644,6 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
size_t i;
uint64_t mlen = ctx->len.u[1];
block128_f block = ctx->block;
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -789,8 +793,9 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
return 1;
}
-int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
- unsigned char *out, size_t len) {
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
+ const unsigned char *in, unsigned char *out,
+ size_t len) {
const union {
long one;
char little;
@@ -799,7 +804,6 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
size_t i;
uint64_t mlen = ctx->len.u[1];
block128_f block = ctx->block;
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -956,16 +960,15 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const unsigned char *in,
return 1;
}
-int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len, ctr128_f stream) {
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out, size_t len,
+ ctr128_f stream) {
const union {
long one;
char little;
} is_endian = {1};
unsigned int n, ctr;
- size_t i;
uint64_t mlen = ctx->len.u[1];
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -1022,7 +1025,8 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
len -= GHASH_CHUNK;
}
#endif
- if ((i = (len & (size_t) - 16))) {
+ size_t i = len & kSizeTWithoutLower4Bits;
+ if (i != 0) {
size_t j = i / 16;
(*stream)(in, out, j, key, ctx->Yi.c);
@@ -1065,17 +1069,15 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
return 1;
}
-int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len,
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out, size_t len,
ctr128_f stream) {
const union {
long one;
char little;
} is_endian = {1};
unsigned int n, ctr;
- size_t i;
uint64_t mlen = ctx->len.u[1];
- void *key = ctx->key;
#ifdef GCM_FUNCREF_4BIT
void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult;
#ifdef GHASH
@@ -1134,7 +1136,8 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const uint8_t *in,
len -= GHASH_CHUNK;
}
#endif
- if ((i = (len & (size_t) - 16))) {
+ size_t i = len & kSizeTWithoutLower4Bits;
+ if (i != 0) {
size_t j = i / 16;
#if defined(GHASH)
diff --git a/src/crypto/modes/gcm_test.c b/src/crypto/modes/gcm_test.c
index 89ed792..9414ac6 100644
--- a/src/crypto/modes/gcm_test.c
+++ b/src/crypto/modes/gcm_test.c
@@ -52,7 +52,6 @@
#include <openssl/aes.h>
#include <openssl/crypto.h>
#include <openssl/mem.h>
-#include <openssl/modes.h>
#include "internal.h"
#include "../test/test_util.h"
@@ -346,13 +345,13 @@ static int run_test_case(unsigned test_num, const struct test_case *test) {
}
CRYPTO_gcm128_init(&ctx, &aes_key, (block128_f) AES_encrypt);
- CRYPTO_gcm128_setiv(&ctx, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_len);
memset(out, 0, plaintext_len);
if (additional_data) {
CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len);
}
if (plaintext) {
- CRYPTO_gcm128_encrypt(&ctx, plaintext, out, plaintext_len);
+ CRYPTO_gcm128_encrypt(&ctx, &aes_key, plaintext, out, plaintext_len);
}
if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len) ||
(ciphertext && memcmp(out, ciphertext, plaintext_len) != 0)) {
@@ -362,13 +361,13 @@ static int run_test_case(unsigned test_num, const struct test_case *test) {
goto out;
}
- CRYPTO_gcm128_setiv(&ctx, nonce, nonce_len);
+ CRYPTO_gcm128_setiv(&ctx, &aes_key, nonce, nonce_len);
memset(out, 0, plaintext_len);
if (additional_data) {
CRYPTO_gcm128_aad(&ctx, additional_data, additional_data_len);
}
if (ciphertext) {
- CRYPTO_gcm128_decrypt(&ctx, ciphertext, out, plaintext_len);
+ CRYPTO_gcm128_decrypt(&ctx, &aes_key, ciphertext, out, plaintext_len);
}
if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len)) {
fprintf(stderr, "%u: decrypt failed.\n", test_num);
diff --git a/src/crypto/modes/internal.h b/src/crypto/modes/internal.h
index caeac40..7255a7c 100644
--- a/src/crypto/modes/internal.h
+++ b/src/crypto/modes/internal.h
@@ -149,9 +149,16 @@ __inline uint32_t _bswap4(uint32_t val) {
#endif
+/* block128_f is the type of a 128-bit, block cipher. */
+typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16],
+ const void *key);
+
/* GCM definitions */
typedef struct { uint64_t hi,lo; } u128;
+/* This differs from upstream's |gcm128_context| in that it does not have the
+ * |key| pointer, in order to make it |memcpy|-friendly. Rather the key is
+ * passed into each call that needs it. */
struct gcm128_context {
/* Following 6 names follow names in GCM specification */
union {
@@ -170,7 +177,6 @@ struct gcm128_context {
unsigned int mres, ares;
block128_f block;
- void *key;
};
struct ccm128_context {
@@ -190,6 +196,173 @@ int crypto_gcm_clmul_enabled(void);
#endif
+/* CTR. */
+
+/* ctr128_f is the type of a function that performs CTR-mode encryption. */
+typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks,
+ const void *key, const uint8_t ivec[16]);
+
+/* CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode)
+ * |len| bytes from |in| to |out| using |block| in counter mode. There's no
+ * requirement that |len| be a multiple of any value and any partial blocks are
+ * stored in |ecount_buf| and |*num|, which must be zeroed before the initial
+ * call. The counter is a 128-bit, big-endian value in |ivec| and is
+ * incremented by this function. */
+void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16],
+ uint8_t ecount_buf[16], unsigned int *num,
+ block128_f block);
+
+/* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
+ * |ctr|, a function that performs CTR mode but only deals with the lower 32
+ * bits of the counter. This is useful when |ctr| can be an optimised
+ * function. */
+void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16],
+ uint8_t ecount_buf[16], unsigned int *num,
+ ctr128_f ctr);
+
+
+/* GCM.
+ *
+ * This API differs from the upstream API slightly. The |GCM128_CONTEXT| does
+ * not have a |key| pointer that points to the key as upstream's version does.
+ * Instead, every function takes a |key| parameter. This way |GCM128_CONTEXT|
+ * can be safely copied. */
+
+typedef struct gcm128_context GCM128_CONTEXT;
+
+/* CRYPTO_gcm128_new allocates a fresh |GCM128_CONTEXT| and calls
+ * |CRYPTO_gcm128_init|. It returns the new context, or NULL on error. */
+OPENSSL_EXPORT GCM128_CONTEXT *CRYPTO_gcm128_new(const void *key,
+ block128_f block);
+
+/* CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with
+ * the given key. */
+OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key,
+ block128_f block);
+
+/* CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. The |key| must be the
+ * same key that was passed to |CRYPTO_gcm128_init|. */
+OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *iv, size_t iv_len);
+
+/* CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM.
+ * This must be called before and data is encrypted. It returns one on success
+ * and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad,
+ size_t len);
+
+/* CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. The |key|
+ * must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one
+ * on success and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len);
+
+/* CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. The |key|
+ * must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one
+ * on success and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len);
+
+/* CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using
+ * a CTR function that only handles the bottom 32 bits of the nonce, like
+ * |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was
+ * passed to |CRYPTO_gcm128_init|. It returns one on success and zero
+ * otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+ const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len, ctr128_f stream);
+
+/* CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using
+ * a CTR function that only handles the bottom 32 bits of the nonce, like
+ * |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was
+ * passed to |CRYPTO_gcm128_init|. It returns one on success and zero
+ * otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+ const void *key,
+ const uint8_t *in, uint8_t *out,
+ size_t len, ctr128_f stream);
+
+/* CRYPTO_gcm128_finish calculates the authenticator and compares it against
+ * |len| bytes of |tag|. It returns one on success and zero otherwise. */
+OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag,
+ size_t len);
+
+/* CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|.
+ * The minimum of |len| and 16 bytes are copied into |tag|. */
+OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag,
+ size_t len);
+
+/* CRYPTO_gcm128_release clears and frees |ctx|. */
+OPENSSL_EXPORT void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+
+/* CBC. */
+
+/* cbc128_f is the type of a function that performs CBC-mode encryption. */
+typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], int enc);
+
+/* CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the
+ * given IV and block cipher in CBC mode. The input need not be a multiple of
+ * 128 bits long, but the output will round up to the nearest 128 bit multiple,
+ * zero padding the input if needed. The IV will be updated on return. */
+void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], block128_f block);
+
+/* CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the
+ * given IV and block cipher in CBC mode. If |len| is not a multiple of 128
+ * bits then only that many bytes will be written, but a multiple of 128 bits
+ * is always read from |in|. The IV will be updated on return. */
+void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], block128_f block);
+
+
+/* OFB. */
+
+/* CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode)
+ * |len| bytes from |in| to |out| using |block| in OFB mode. There's no
+ * requirement that |len| be a multiple of any value and any partial blocks are
+ * stored in |ivec| and |*num|, the latter must be zero before the initial
+ * call. */
+void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
+ size_t len, const void *key, uint8_t ivec[16],
+ int *num, block128_f block);
+
+
+/* CFB. */
+
+/* CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
+ * from |in| to |out| using |block| in CFB mode. There's no requirement that
+ * |len| be a multiple of any value and any partial blocks are stored in |ivec|
+ * and |*num|, the latter must be zero before the initial call. */
+void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], int *num, int enc,
+ block128_f block);
+
+/* CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
+ * from |in| to |out| using |block| in CFB-8 mode. Prior to the first call
+ * |num| should be set to zero. */
+void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16], int *num,
+ int enc, block128_f block);
+
+/* CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
+ * from |in| to |out| using |block| in CFB-1 mode. Prior to the first call
+ * |num| should be set to zero. */
+void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
+ const void *key, uint8_t ivec[16], int *num,
+ int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
+ const void *key, uint8_t ivec[16],
+ block128_f block);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/crypto/modes/ofb.c b/src/crypto/modes/ofb.c
index 5836a9f..63c3165 100644
--- a/src/crypto/modes/ofb.c
+++ b/src/crypto/modes/ofb.c
@@ -46,20 +46,21 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
-#include <openssl/modes.h>
+#include <openssl/type_check.h>
#include <assert.h>
#include "internal.h"
+OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
+
void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num,
block128_f block) {
unsigned int n;
assert(in && out && key && ivec && num);
- assert((16 % sizeof(size_t)) == 0);
n = *num;
diff --git a/src/crypto/pem/pem_info.c b/src/crypto/pem/pem_info.c
index b4ae805..2a39a5b 100644
--- a/src/crypto/pem/pem_info.c
+++ b/src/crypto/pem/pem_info.c
@@ -292,7 +292,7 @@ err:
if (xi != NULL) X509_INFO_free(xi);
if (!ok)
{
- for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++)
+ for (i=0; i<sk_X509_INFO_num(ret); i++)
{
xi=sk_X509_INFO_value(ret,i);
X509_INFO_free(xi);
diff --git a/src/crypto/perlasm/x86_64-xlate.pl b/src/crypto/perlasm/x86_64-xlate.pl
index 8b46329..3ebb018 100755
--- a/src/crypto/perlasm/x86_64-xlate.pl
+++ b/src/crypto/perlasm/x86_64-xlate.pl
@@ -79,22 +79,17 @@ my $nasmref=2.03;
my $nasm=0;
if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1;
+ # TODO(davidben): Before supporting the
+ # mingw64 perlasm flavour, do away with this
+ # environment variable check.
+ die "mingw64 not supported";
$prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`;
chomp($prefix);
}
elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; }
elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; }
elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; }
-elsif (!$gas)
-{ if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i)
- { $nasm = $1 + $2*0.01; $PTR=""; }
- elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
- { $masm = $1 + $2*2**-16 + $4*2**-32; }
- die "no assembler found on %PATH" if (!($nasm || $masm));
- $win64=1;
- $elf=0;
- $decor="\$L\$";
-}
+elsif (!$gas) { die "unknown flavour $flavour"; }
my $current_segment;
my $current_function;
diff --git a/src/crypto/pkcs8/CMakeLists.txt b/src/crypto/pkcs8/CMakeLists.txt
index ce5bce1..9550109 100644
--- a/src/crypto/pkcs8/CMakeLists.txt
+++ b/src/crypto/pkcs8/CMakeLists.txt
@@ -27,3 +27,4 @@ add_executable(
target_link_libraries(pkcs8_test crypto)
target_link_libraries(pkcs12_test crypto)
+add_dependencies(all_tests pkcs8_test pkcs12_test)
diff --git a/src/crypto/pkcs8/p5_pbev2.c b/src/crypto/pkcs8/p5_pbev2.c
index f58aae7..fec0d86 100644
--- a/src/crypto/pkcs8/p5_pbev2.c
+++ b/src/crypto/pkcs8/p5_pbev2.c
@@ -356,7 +356,8 @@ static int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx,
goto err;
}
long iterations = ASN1_INTEGER_get(pbkdf2param->iter);
- if (iterations < 0 || iterations > UINT_MAX) {
+ if (iterations <= 0 ||
+ (sizeof(long) > sizeof(unsigned) && iterations > (long)UINT_MAX)) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
goto err;
}
@@ -367,7 +368,7 @@ static int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx,
}
const size_t iv_len = EVP_CIPHER_CTX_iv_length(ctx);
- if (iv->value.octet_string->length != iv_len) {
+ if ((size_t) iv->value.octet_string->length != iv_len) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
goto err;
}
diff --git a/src/crypto/pkcs8/pkcs12_test.cc b/src/crypto/pkcs8/pkcs12_test.cc
index 8b265cd..55006b4 100644
--- a/src/crypto/pkcs8/pkcs12_test.cc
+++ b/src/crypto/pkcs8/pkcs12_test.cc
@@ -681,6 +681,8 @@ static const uint8_t kWindows[] = {
0xfe, 0x3a, 0x66, 0x47, 0x40, 0x49, 0x02, 0x02, 0x07, 0xd0,
};
+static const char kPassword[] = "foo";
+
static bool Test(const char *name, const uint8_t *der, size_t der_len) {
ScopedX509Stack certs(sk_X509_new_null());
if (!certs) {
@@ -690,7 +692,7 @@ static bool Test(const char *name, const uint8_t *der, size_t der_len) {
CBS pkcs12;
EVP_PKEY *key = nullptr;
CBS_init(&pkcs12, der, der_len);
- if (!PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, "foo")) {
+ if (!PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, kPassword)) {
fprintf(stderr, "PKCS12 failed on %s data.\n", name);
ERR_print_errors_fp(stderr);
return false;
@@ -718,10 +720,20 @@ static bool TestCompat(const uint8_t *der, size_t der_len) {
return false;
}
+ if (PKCS12_verify_mac(p12.get(), "badpass", 7)) {
+ fprintf(stderr, "PKCS12_verify_mac accepted bad password.\n");
+ return false;
+ }
+
+ if (!PKCS12_verify_mac(p12.get(), kPassword, sizeof(kPassword) - 1)) {
+ fprintf(stderr, "PKCS12_verify_mac rejected good password.\n");
+ return false;
+ }
+
EVP_PKEY *key = nullptr;
X509 *cert = nullptr;
STACK_OF(X509) *ca_certs = nullptr;
- if (!PKCS12_parse(p12.get(), "foo", &key, &cert, &ca_certs)) {
+ if (!PKCS12_parse(p12.get(), kPassword, &key, &cert, &ca_certs)) {
fprintf(stderr, "PKCS12_parse failed.\n");
ERR_print_errors_fp(stderr);
return false;
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index 8067c91..c097881 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -1176,6 +1176,31 @@ int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey,
return 1;
}
+int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
+ int password_len) {
+ if (password == NULL) {
+ if (password_len != 0) {
+ return 0;
+ }
+ } else if (password_len != -1 &&
+ (password[password_len] != 0 ||
+ memchr(password, 0, password_len) != NULL)) {
+ return 0;
+ }
+
+ EVP_PKEY *pkey = NULL;
+ X509 *cert = NULL;
+ if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) {
+ ERR_clear_error();
+ return 0;
+ }
+
+ EVP_PKEY_free(pkey);
+ X509_free(cert);
+
+ return 1;
+}
+
void PKCS12_free(PKCS12 *p12) {
OPENSSL_free(p12->ber_bytes);
OPENSSL_free(p12);
diff --git a/src/crypto/poly1305/CMakeLists.txt b/src/crypto/poly1305/CMakeLists.txt
index 674d9f6..1b6a804 100644
--- a/src/crypto/poly1305/CMakeLists.txt
+++ b/src/crypto/poly1305/CMakeLists.txt
@@ -28,3 +28,4 @@ add_executable(
)
target_link_libraries(poly1305_test crypto)
+add_dependencies(all_tests poly1305_test)
diff --git a/src/crypto/poly1305/poly1305_test.txt b/src/crypto/poly1305/poly1305_test.txt
index 6c5d403..2a92c12 100644
--- a/src/crypto/poly1305/poly1305_test.txt
+++ b/src/crypto/poly1305/poly1305_test.txt
@@ -5,7 +5,7 @@ Input = "Cryptographic Forum Research Group"
MAC = a8061dc1305136c6c22b8baf0c0127a9
-# RFC 7359, section A.3.
+# RFC 7539, section A.3.
Key = 0000000000000000000000000000000000000000000000000000000000000000
Input = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/src/crypto/rand/CMakeLists.txt b/src/crypto/rand/CMakeLists.txt
index 35d5290..eedf81b 100644
--- a/src/crypto/rand/CMakeLists.txt
+++ b/src/crypto/rand/CMakeLists.txt
@@ -16,7 +16,6 @@ add_library(
rand.c
urandom.c
windows.c
- hwrand.c
${RAND_ARCH_SOURCES}
)
diff --git a/src/crypto/rand/hwrand.c b/src/crypto/rand/hwrand.c
deleted file mode 100644
index f0bbccd..0000000
--- a/src/crypto/rand/hwrand.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-#include <openssl/rand.h>
-
-#include <assert.h>
-#include <string.h>
-
-#include <openssl/cpu.h>
-
-#include "internal.h"
-
-
-#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
-
-/* These functions are defined in asm/rdrand-x86_64.pl */
-extern int CRYPTO_rdrand(uint8_t out[8]);
-extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len);
-
-static int have_rdrand(void) {
- return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
-}
-
-int CRYPTO_hwrand(uint8_t *buf, size_t len) {
- if (!have_rdrand()) {
- return 0;
- }
-
- const size_t len_multiple8 = len & ~7;
- if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) {
- return 0;
- }
- len -= len_multiple8;
-
- if (len != 0) {
- assert(len < 8);
-
- uint8_t rand_buf[8];
- if (!CRYPTO_rdrand(rand_buf)) {
- return 0;
- }
- memcpy(buf + len_multiple8, rand_buf, len);
- }
-
- return 1;
-}
-
-#else
-
-int CRYPTO_hwrand(uint8_t *buf, size_t len) {
- return 0;
-}
-
-#endif
diff --git a/src/crypto/rand/internal.h b/src/crypto/rand/internal.h
index f35abbb..dcff3aa 100644
--- a/src/crypto/rand/internal.h
+++ b/src/crypto/rand/internal.h
@@ -24,11 +24,6 @@ extern "C" {
* system. */
void CRYPTO_sysrand(uint8_t *buf, size_t len);
-/* CRYPTO_hwrand fills |len| bytes at |buf| with entropy from the hardware. It
- * returns one on success or zero on hardware failure or if hardware support is
- * unavailable. */
-int CRYPTO_hwrand(uint8_t *buf, size_t len);
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index e76a120..8b11728 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -14,10 +14,12 @@
#include <openssl/rand.h>
+#include <assert.h>
#include <limits.h>
#include <string.h>
#include <openssl/chacha.h>
+#include <openssl/cpu.h>
#include <openssl/mem.h>
#include "internal.h"
@@ -70,12 +72,54 @@ static void rand_thread_state_free(void *state) {
OPENSSL_free(state);
}
+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
+
+/* These functions are defined in asm/rdrand-x86_64.pl */
+extern int CRYPTO_rdrand(uint8_t out[8]);
+extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len);
+
+static int have_rdrand(void) {
+ return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
+}
+
+static int hwrand(uint8_t *buf, size_t len) {
+ if (!have_rdrand()) {
+ return 0;
+ }
+
+ const size_t len_multiple8 = len & ~7;
+ if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) {
+ return 0;
+ }
+ len -= len_multiple8;
+
+ if (len != 0) {
+ assert(len < 8);
+
+ uint8_t rand_buf[8];
+ if (!CRYPTO_rdrand(rand_buf)) {
+ return 0;
+ }
+ memcpy(buf + len_multiple8, rand_buf, len);
+ }
+
+ return 1;
+}
+
+#else
+
+static int hwrand(uint8_t *buf, size_t len) {
+ return 0;
+}
+
+#endif
+
int RAND_bytes(uint8_t *buf, size_t len) {
if (len == 0) {
return 1;
}
- if (!CRYPTO_hwrand(buf, len)) {
+ if (!hwrand(buf, len)) {
/* Without a hardware RNG to save us from address-space duplication, the OS
* entropy is used directly. */
CRYPTO_sysrand(buf, len);
@@ -108,24 +152,28 @@ int RAND_bytes(uint8_t *buf, size_t len) {
if (len >= sizeof(state->partial_block)) {
size_t remaining = len;
while (remaining > 0) {
- // kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this
- // is sufficient and easier on 32-bit.
+ /* kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this
+ * is sufficient and easier on 32-bit. */
static const size_t kMaxBytesPerCall = 0x80000000;
size_t todo = remaining;
if (todo > kMaxBytesPerCall) {
todo = kMaxBytesPerCall;
}
- CRYPTO_chacha_20(buf, buf, todo, state->key,
- (uint8_t *)&state->calls_used, 0);
+ uint8_t nonce[12];
+ memset(nonce, 0, 4);
+ memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used));
+ CRYPTO_chacha_20(buf, buf, todo, state->key, nonce, 0);
buf += todo;
remaining -= todo;
state->calls_used++;
}
} else {
if (sizeof(state->partial_block) - state->partial_block_used < len) {
+ uint8_t nonce[12];
+ memset(nonce, 0, 4);
+ memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used));
CRYPTO_chacha_20(state->partial_block, state->partial_block,
- sizeof(state->partial_block), state->key,
- (uint8_t *)&state->calls_used, 0);
+ sizeof(state->partial_block), state->key, nonce, 0);
state->partial_block_used = 0;
}
diff --git a/src/crypto/rc4/rc4.c b/src/crypto/rc4/rc4.c
index aa19dc2..b8e1d9f 100644
--- a/src/crypto/rc4/rc4.c
+++ b/src/crypto/rc4/rc4.c
@@ -234,23 +234,22 @@ void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) {
void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) {
uint32_t tmp;
- int id1, id2;
+ unsigned i, id1, id2;
uint32_t *d;
- unsigned int i;
d = &rc4key->data[0];
rc4key->x = 0;
rc4key->y = 0;
id1 = id2 = 0;
-#define SK_LOOP(d, n) \
- { \
- tmp = d[(n)]; \
+#define SK_LOOP(d, n) \
+ { \
+ tmp = d[(n)]; \
id2 = (key[id1] + tmp + id2) & 0xff; \
- if (++id1 == len) \
- id1 = 0; \
- d[(n)] = d[id2]; \
- d[id2] = tmp; \
+ if (++id1 == len) \
+ id1 = 0; \
+ d[(n)] = d[id2]; \
+ d[id2] = tmp; \
}
for (i = 0; i < 256; i++) {
diff --git a/src/crypto/rsa/CMakeLists.txt b/src/crypto/rsa/CMakeLists.txt
index bd8ad3b..969b753 100644
--- a/src/crypto/rsa/CMakeLists.txt
+++ b/src/crypto/rsa/CMakeLists.txt
@@ -21,3 +21,4 @@ add_executable(
)
target_link_libraries(rsa_test crypto)
+add_dependencies(all_tests rsa_test) \ No newline at end of file
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 2f23165..3ea4bff 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -56,6 +56,7 @@
#include <openssl/rsa.h>
+#include <limits.h>
#include <string.h>
#include <openssl/bn.h>
@@ -99,6 +100,7 @@ RSA *RSA_new_method(const ENGINE *engine) {
CRYPTO_MUTEX_init(&rsa->lock);
if (!CRYPTO_new_ex_data(&g_ex_data_class, rsa, &rsa->ex_data)) {
+ CRYPTO_MUTEX_cleanup(&rsa->lock);
METHOD_unref(rsa->meth);
OPENSSL_free(rsa);
return NULL;
@@ -106,6 +108,7 @@ RSA *RSA_new_method(const ENGINE *engine) {
if (rsa->meth->init && !rsa->meth->init(rsa)) {
CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
+ CRYPTO_MUTEX_cleanup(&rsa->lock);
METHOD_unref(rsa->meth);
OPENSSL_free(rsa);
return NULL;
@@ -198,7 +201,7 @@ int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
padding);
}
-int RSA_public_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -206,6 +209,10 @@ int RSA_public_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -219,7 +226,7 @@ int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
padding);
}
-int RSA_private_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -227,6 +234,10 @@ int RSA_private_encrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -240,7 +251,7 @@ int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
padding);
}
-int RSA_private_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -248,6 +259,10 @@ int RSA_private_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
@@ -261,7 +276,7 @@ int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
padding);
}
-int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
+int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
int padding) {
size_t out_len;
@@ -269,6 +284,10 @@ int RSA_public_decrypt(int flen, const uint8_t *from, uint8_t *to, RSA *rsa,
return -1;
}
+ if (out_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ return -1;
+ }
return out_len;
}
diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c
index e3756ba..5d2a2b7 100644
--- a/src/crypto/rsa/rsa_asn1.c
+++ b/src/crypto/rsa/rsa_asn1.c
@@ -203,9 +203,17 @@ RSA *RSA_parse_private_key(CBS *cbs) {
CBS child;
uint64_t version;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1_uint64(&child, &version) ||
- (version != kVersionTwoPrime && version != kVersionMulti) ||
- !parse_integer(&child, &ret->n) ||
+ !CBS_get_asn1_uint64(&child, &version)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ goto err;
+ }
+
+ if (version != kVersionTwoPrime && version != kVersionMulti) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION);
+ goto err;
+ }
+
+ if (!parse_integer(&child, &ret->n) ||
!parse_integer(&child, &ret->e) ||
!parse_integer(&child, &ret->d) ||
!parse_integer(&child, &ret->p) ||
@@ -213,7 +221,6 @@ RSA *RSA_parse_private_key(CBS *cbs) {
!parse_integer(&child, &ret->dmp1) ||
!parse_integer(&child, &ret->dmq1) ||
!parse_integer(&child, &ret->iqmp)) {
- OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION);
goto err;
}
diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c
index eb4a36f..b14f7a0 100644
--- a/src/crypto/rsa/rsa_impl.c
+++ b/src/crypto/rsa/rsa_impl.c
@@ -1010,7 +1010,7 @@ static int keygen_multiprime(RSA *rsa, int bits, int num_primes,
if (!BN_mul(r1, rsa->n, ap->prime, ctx)) {
goto err;
}
- if (BN_num_bits(r1) == bits) {
+ if (BN_num_bits(r1) == (unsigned) bits) {
break;
}
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
index d52b78b..57b360c 100644
--- a/src/crypto/rsa/rsa_test.cc
+++ b/src/crypto/rsa/rsa_test.cc
@@ -498,7 +498,7 @@ static const uint8_t kEstonianRSAKey[] = {
static bool TestRSA(const uint8_t *der, size_t der_len,
const uint8_t *oaep_ciphertext,
size_t oaep_ciphertext_len) {
- ScopedRSA key(d2i_RSAPrivateKey(nullptr, &der, der_len));
+ ScopedRSA key(RSA_private_key_from_bytes(der, der_len));
if (!key) {
return false;
}
@@ -510,43 +510,48 @@ static bool TestRSA(const uint8_t *der, size_t der_len,
uint8_t ciphertext[256];
- int num = RSA_public_encrypt(kPlaintextLen, kPlaintext, ciphertext, key.get(),
- RSA_PKCS1_PADDING);
- if (num < 0 || (size_t)num != RSA_size(key.get())) {
+ size_t ciphertext_len = 0;
+ if (!RSA_encrypt(key.get(), &ciphertext_len, ciphertext, sizeof(ciphertext),
+ kPlaintext, kPlaintextLen, RSA_PKCS1_PADDING) ||
+ ciphertext_len != RSA_size(key.get())) {
fprintf(stderr, "PKCS#1 v1.5 encryption failed!\n");
return false;
}
uint8_t plaintext[256];
- num = RSA_private_decrypt(num, ciphertext, plaintext, key.get(),
- RSA_PKCS1_PADDING);
- if (num < 0 ||
- (size_t)num != kPlaintextLen || memcmp(plaintext, kPlaintext, num) != 0) {
+ size_t plaintext_len = 0;
+ if (!RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, ciphertext_len, RSA_PKCS1_PADDING) ||
+ plaintext_len != kPlaintextLen ||
+ memcmp(plaintext, kPlaintext, plaintext_len) != 0) {
fprintf(stderr, "PKCS#1 v1.5 decryption failed!\n");
return false;
}
- num = RSA_public_encrypt(kPlaintextLen, kPlaintext, ciphertext, key.get(),
- RSA_PKCS1_OAEP_PADDING);
- if (num < 0 || (size_t)num != RSA_size(key.get())) {
+ ciphertext_len = 0;
+ if (!RSA_encrypt(key.get(), &ciphertext_len, ciphertext, sizeof(ciphertext),
+ kPlaintext, kPlaintextLen, RSA_PKCS1_OAEP_PADDING) ||
+ ciphertext_len != RSA_size(key.get())) {
fprintf(stderr, "OAEP encryption failed!\n");
return false;
}
- num = RSA_private_decrypt(num, ciphertext, plaintext, key.get(),
- RSA_PKCS1_OAEP_PADDING);
- if (num < 0 ||
- (size_t)num != kPlaintextLen || memcmp(plaintext, kPlaintext, num) != 0) {
+ plaintext_len = 0;
+ if (!RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, ciphertext_len, RSA_PKCS1_OAEP_PADDING) ||
+ plaintext_len != kPlaintextLen ||
+ memcmp(plaintext, kPlaintext, plaintext_len) != 0) {
fprintf(stderr, "OAEP decryption (encrypted data) failed!\n");
return false;
}
// |oaep_ciphertext| should decrypt to |kPlaintext|.
- num = RSA_private_decrypt(oaep_ciphertext_len, oaep_ciphertext, plaintext,
- key.get(), RSA_PKCS1_OAEP_PADDING);
-
- if (num < 0 ||
- (size_t)num != kPlaintextLen || memcmp(plaintext, kPlaintext, num) != 0) {
+ plaintext_len = 0;
+ if (!RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ oaep_ciphertext, oaep_ciphertext_len,
+ RSA_PKCS1_OAEP_PADDING) ||
+ plaintext_len != kPlaintextLen ||
+ memcmp(plaintext, kPlaintext, plaintext_len) != 0) {
fprintf(stderr, "OAEP decryption (test vector data) failed!\n");
return false;
}
@@ -554,20 +559,22 @@ static bool TestRSA(const uint8_t *der, size_t der_len,
// Try decrypting corrupted ciphertexts.
memcpy(ciphertext, oaep_ciphertext, oaep_ciphertext_len);
for (size_t i = 0; i < oaep_ciphertext_len; i++) {
- uint8_t saved = ciphertext[i];
- for (unsigned b = 0; b < 256; b++) {
- if (b == saved) {
- continue;
- }
- ciphertext[i] = b;
- num = RSA_private_decrypt(num, ciphertext, plaintext, key.get(),
- RSA_PKCS1_OAEP_PADDING);
- if (num > 0) {
- fprintf(stderr, "Corrupt data decrypted!\n");
- return false;
- }
+ ciphertext[i] ^= 1;
+ if (RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, oaep_ciphertext_len, RSA_PKCS1_OAEP_PADDING)) {
+ fprintf(stderr, "Corrupt data decrypted!\n");
+ return false;
+ }
+ ciphertext[i] ^= 1;
+ }
+
+ // Test truncated ciphertexts.
+ for (size_t len = 0; len < oaep_ciphertext_len; len++) {
+ if (RSA_decrypt(key.get(), &plaintext_len, plaintext, sizeof(plaintext),
+ ciphertext, len, RSA_PKCS1_OAEP_PADDING)) {
+ fprintf(stderr, "Corrupt data decrypted!\n");
+ return false;
}
- ciphertext[i] = saved;
}
return true;
diff --git a/src/crypto/sha/asm/sha1-586.pl b/src/crypto/sha/asm/sha1-586.pl
index e0b5d83..09fd3fc 100644
--- a/src/crypto/sha/asm/sha1-586.pl
+++ b/src/crypto/sha/asm/sha1-586.pl
@@ -118,24 +118,21 @@ require "x86asm.pl";
$xmm=$ymm=0;
for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-$ymm=1 if ($xmm &&
- `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/ &&
- $1>=2.19); # first version supporting AVX
-
-$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
- $1>=2.03); # first version supporting AVX
-
-$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" &&
- `ml 2>&1` =~ /Version ([0-9]+)\./ &&
- $1>=10); # first version supporting AVX
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $ymm goes up to 1.
+$ymm = 0;
-$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/ &&
- $2>=3.0); # first version supporting AVX
+$ymm = 0 unless ($xmm);
$shaext=$xmm; ### set to zero if compiling for 1.0.1
+# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
+# been tested.
+$shaext = 0;
+
&external_label("OPENSSL_ia32cap_P") if ($xmm);
diff --git a/src/crypto/sha/asm/sha1-x86_64.pl b/src/crypto/sha/asm/sha1-x86_64.pl
index 124034d..59b1607 100644
--- a/src/crypto/sha/asm/sha1-x86_64.pl
+++ b/src/crypto/sha/asm/sha1-x86_64.pl
@@ -92,25 +92,15 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([2-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $avx goes up to 2.
+$avx = 0;
+# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
+# been tested.
$shaext=0; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
diff --git a/src/crypto/sha/asm/sha256-586.pl b/src/crypto/sha/asm/sha256-586.pl
index e907714..1866d5a 100644
--- a/src/crypto/sha/asm/sha256-586.pl
+++ b/src/crypto/sha/asm/sha256-586.pl
@@ -68,27 +68,21 @@ require "x86asm.pl";
$xmm=$avx=0;
for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
-if ($xmm && `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if ($xmm && !$avx && $ARGV[0] eq "win32n" &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.03) + ($1>=2.10);
-}
-
-if ($xmm && !$avx && $ARGV[0] eq "win32" &&
- `ml 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $avx goes up to 2.
+$avx = 0;
-if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+$avx = 0 unless ($xmm);
$shaext=$xmm; ### set to zero if compiling for 1.0.1
+# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
+# been tested.
+$shaext = 0;
+
$unroll_after = 64*4; # If pre-evicted from L1P cache first spin of
# fully unrolled loop was measured to run about
# 3-4x slower. If slowdown coefficient is N and
diff --git a/src/crypto/sha/asm/sha512-x86_64.pl b/src/crypto/sha/asm/sha512-x86_64.pl
index 6660a88..9a0d0c4 100644
--- a/src/crypto/sha/asm/sha512-x86_64.pl
+++ b/src/crypto/sha/asm/sha512-x86_64.pl
@@ -109,25 +109,15 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
die "can't locate x86_64-xlate.pl";
-if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
- =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.19) + ($1>=2.22);
-}
-
-if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
- `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
- $avx = ($1>=2.09) + ($1>=2.10);
-}
-
-if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
- `ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $avx = ($1>=10) + ($1>=11);
-}
-
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9]\.[0-9]+)/) {
- $avx = ($2>=3.0) + ($2>3.0);
-}
+# In upstream, this is controlled by shelling out to the compiler to check
+# versions, but BoringSSL is intended to be used with pre-generated perlasm
+# output, so this isn't useful anyway.
+#
+# TODO(davidben): Enable this after testing. $avx goes up to 2.
+$avx = 0;
+# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
+# been tested.
$shaext=0; ### set to zero if compiling for 1.0.1
$avx=1 if (!$shaext && $avx);
@@ -2264,7 +2254,8 @@ $code.=<<___;
ret
.size se_handler,.-se_handler
___
-$code.=<<___ if ($SZ == 4 && $shaext);
+
+$code.=<<___ if ($SZ==4 && $shaext);
.type shaext_handler,\@abi-omnipotent
.align 16
shaext_handler:
@@ -2298,6 +2289,7 @@ shaext_handler:
jmp .Lin_prologue
.size shaext_handler,.-shaext_handler
___
+
$code.=<<___;
.section .pdata
.align 4
@@ -2305,7 +2297,7 @@ $code.=<<___;
.rva .LSEH_end_$func
.rva .LSEH_info_$func
___
-$code.=<<___ if ($SZ==4 && $shext);
+$code.=<<___ if ($SZ==4 && $shaext);
.rva .LSEH_begin_${func}_shaext
.rva .LSEH_end_${func}_shaext
.rva .LSEH_info_${func}_shaext
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index e44c6ed..2ce4526 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -117,6 +117,7 @@ using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
+using ScopedCBB = ScopedOpenSSLContext<CBB, void, CBB_zero, CBB_cleanup>;
using ScopedEVP_AEAD_CTX = ScopedOpenSSLContext<EVP_AEAD_CTX, void,
EVP_AEAD_CTX_zero,
EVP_AEAD_CTX_cleanup>;
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 258c263..8ffeaa0 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -65,3 +65,4 @@ add_executable(
)
target_link_libraries(pkcs7_test crypto)
+add_dependencies(all_tests pkcs7_test)
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 6d7bc26..5751f75 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -187,12 +187,16 @@ X509_STORE *X509_STORE_new(void)
if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
return NULL;
memset(ret, 0, sizeof(*ret));
- ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
CRYPTO_MUTEX_init(&ret->objs_lock);
+ ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+ if (ret->objs == NULL)
+ goto err;
ret->cache = 1;
ret->get_cert_methods = sk_X509_LOOKUP_new_null();
-
- if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
+ if (ret->get_cert_methods == NULL)
+ goto err;
+ ret->param = X509_VERIFY_PARAM_new();
+ if (ret->param == NULL)
goto err;
ret->references = 1;
@@ -200,6 +204,7 @@ X509_STORE *X509_STORE_new(void)
err:
if (ret)
{
+ CRYPTO_MUTEX_cleanup(&ret->objs_lock);
if (ret->param)
X509_VERIFY_PARAM_free(ret->param);
if (ret->get_cert_methods)
@@ -436,7 +441,6 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
X509_CINF cinf_s;
X509_CRL crl_s;
X509_CRL_INFO crl_info_s;
- size_t idx;
stmp.type=type;
switch (type)
@@ -456,8 +460,11 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
return -1;
}
- idx = -1;
- if (sk_X509_OBJECT_find(h, &idx, &stmp) && pnmatch)
+ size_t idx;
+ if (!sk_X509_OBJECT_find(h, &idx, &stmp))
+ return -1;
+
+ if (pnmatch != NULL)
{
int tidx;
const X509_OBJECT *tobj, *pstmp;
@@ -498,6 +505,8 @@ STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
X509 *x;
X509_OBJECT *obj;
sk = sk_X509_new_null();
+ if (sk == NULL)
+ return NULL;
CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
if (idx < 0)
@@ -546,13 +555,10 @@ STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
X509_CRL *x;
X509_OBJECT *obj, xobj;
sk = sk_X509_CRL_new_null();
- CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock);
- /* Check cache first */
- idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+ if (sk == NULL)
+ return NULL;
- /* Always do lookup to possibly add new CRLs to cache
- */
- CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
+ /* Always do lookup to possibly add new CRLs to cache. */
if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
{
sk_X509_CRL_free(sk);
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index 5d856f0..695793e 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -1191,7 +1191,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
int cidx = ctx->error_depth;
size_t i;
- if (cidx != sk_X509_num(ctx->chain) - 1)
+ if ((size_t) cidx != sk_X509_num(ctx->chain) - 1)
cidx++;
crl_issuer = sk_X509_value(ctx->chain, cidx);
diff --git a/src/crypto/x509/x_x509.c b/src/crypto/x509/x_x509.c
index c975dd3..b8f318a 100644
--- a/src/crypto/x509/x_x509.c
+++ b/src/crypto/x509/x_x509.c
@@ -178,22 +178,21 @@ void *X509_get_ex_data(X509 *r, int idx)
X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
{
- const unsigned char *q;
+ const unsigned char *q = *pp;
X509 *ret;
int freeret = 0;
- /* Save start position */
- q = *pp;
-
if (!a || *a == NULL)
freeret = 1;
- ret = d2i_X509(a, pp, length);
+ ret = d2i_X509(a, &q, length);
/* If certificate unreadable then forget it */
if(!ret) return NULL;
/* update length */
- length -= *pp - q;
- if(!length) return ret;
- if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
+ length -= q - *pp;
+ /* Parse auxiliary information if there is any. */
+ if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
+ goto err;
+ *pp = q;
return ret;
err:
if (freeret)
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index 5cc1b49..cf2474a 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -52,6 +52,7 @@ add_executable(
)
target_link_libraries(v3name_test crypto)
+add_dependencies(all_tests v3name_test)
add_executable(
tab_test
@@ -62,3 +63,4 @@ add_executable(
)
target_link_libraries(tab_test crypto)
+add_dependencies(all_tests tab_test)
diff --git a/src/crypto/x509v3/pcy_tree.c b/src/crypto/x509v3/pcy_tree.c
index 682474d..8e9ef25 100644
--- a/src/crypto/x509v3/pcy_tree.c
+++ b/src/crypto/x509v3/pcy_tree.c
@@ -426,7 +426,7 @@ static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
{
/* If mapping: matched if one child per expected policy set */
STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
- if (node->nchild == sk_ASN1_OBJECT_num(expset))
+ if ((size_t) node->nchild == sk_ASN1_OBJECT_num(expset))
return 1;
/* Locate unmatched nodes */
for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
diff --git a/src/crypto/x509v3/tab_test.c b/src/crypto/x509v3/tab_test.c
index 6b97e91..c0e0cb6 100644
--- a/src/crypto/x509v3/tab_test.c
+++ b/src/crypto/x509v3/tab_test.c
@@ -73,7 +73,8 @@
int main(void)
{
#if !defined(BORINGSSL_SHARED_LIBRARY)
- int i, prev = -1, bad = 0;
+ unsigned i;
+ int prev = -1, bad = 0;
const X509V3_EXT_METHOD *const *tmp;
CRYPTO_library_init();
i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
@@ -89,7 +90,7 @@ int main(void)
tmp = standard_exts;
fprintf(stderr, "Extensions out of order!\n");
for(i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
- printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
+ printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
return 1;
} else {
printf("PASS\n");
diff --git a/src/crypto/x509v3/v3_alt.c b/src/crypto/x509v3/v3_alt.c
index e639f45..cfc1348 100644
--- a/src/crypto/x509v3/v3_alt.c
+++ b/src/crypto/x509v3/v3_alt.c
@@ -596,25 +596,27 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
{
- int ret;
- STACK_OF(CONF_VALUE) *sk;
- X509_NAME *nm;
- if (!(nm = X509_NAME_new()))
- return 0;
+ int ret = 0;
+ STACK_OF(CONF_VALUE) *sk = NULL;
+ X509_NAME *nm = X509_NAME_new();
+ if (nm == NULL)
+ goto err;
sk = X509V3_get_section(ctx, value);
- if (!sk)
+ if (sk == NULL)
{
OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
ERR_add_error_data(2, "section=", value);
- X509_NAME_free(nm);
- return 0;
+ goto err;
}
/* FIXME: should allow other character types... */
- ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
+ if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC))
+ goto err;
+ gen->d.dirn = nm;
+ ret = 1;
+
+err:
if (!ret)
X509_NAME_free(nm);
- gen->d.dirn = nm;
X509V3_section_free(ctx, sk);
-
return ret;
}
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index f53c0f1..9a0a7bc 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -70,6 +70,14 @@
#include "../internal.h"
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+ (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
static void x509v3_cache_extensions(X509 *x);
static int check_ssl_ca(const X509 *x);
@@ -494,7 +502,8 @@ static void x509v3_cache_extensions(X509 *x)
{
x->ex_flags |= EXFLAG_SI;
/* If SKID matches AKID also indicate self signed */
- if (X509_check_akid(x, x->akid) == X509_V_OK)
+ if (X509_check_akid(x, x->akid) == X509_V_OK &&
+ !ku_reject(x, KU_KEY_CERT_SIGN))
x->ex_flags |= EXFLAG_SS;
}
x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
@@ -531,14 +540,6 @@ static void x509v3_cache_extensions(X509 *x)
* 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
*/
-#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
-#define ku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
-#define xku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
-#define ns_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
-
static int check_ca(const X509 *x)
{
/* keyUsage if present should allow cert signing */
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index aa65c79..6bcb6da 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -899,7 +899,7 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
X509_NAME *name = NULL;
size_t i;
int j;
- int cnid;
+ int cnid = NID_undef;
int alt_type;
int san_present = 0;
int rv = 0;
@@ -927,7 +927,6 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
}
else
{
- cnid = 0;
alt_type = V_ASN1_OCTET_STRING;
equal = equal_case;
}
@@ -957,11 +956,16 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
GENERAL_NAMES_free(gens);
if (rv != 0)
return rv;
- if (!cnid
+ if (cnid == NID_undef
|| (san_present
&& !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
return 0;
}
+
+ /* We're done if CN-ID is not pertinent */
+ if (cnid == NID_undef)
+ return 0;
+
j = -1;
name = X509_get_subject_name(x);
while((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0)
diff --git a/src/decrepit/CMakeLists.txt b/src/decrepit/CMakeLists.txt
index 84e5252..0773f9a 100644
--- a/src/decrepit/CMakeLists.txt
+++ b/src/decrepit/CMakeLists.txt
@@ -15,3 +15,5 @@ add_library(
$<TARGET_OBJECTS:rsa_decrepit>
$<TARGET_OBJECTS:xts>
)
+
+target_link_libraries(decrepit crypto)
diff --git a/src/decrepit/des/cfb64ede.c b/src/decrepit/des/cfb64ede.c
index 680a75a..f7e81d4 100644
--- a/src/decrepit/des/cfb64ede.c
+++ b/src/decrepit/des/cfb64ede.c
@@ -61,12 +61,6 @@
#include "../crypto/des/internal.h"
-/* defined in des.c */
-void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
- const DES_key_schedule *ks2, const DES_key_schedule *ks3);
-void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
- const DES_key_schedule *ks2, const DES_key_schedule *ks3);
-
/* The input and output encrypted as though 64bit cfb mode is being used. The
* extra state information to record how much of the 64bit block we have used
* is contained in *num; */
diff --git a/src/decrepit/xts/xts.c b/src/decrepit/xts/xts.c
index cf8ad39..632e0f8 100644
--- a/src/decrepit/xts/xts.c
+++ b/src/decrepit/xts/xts.c
@@ -52,7 +52,8 @@
#include <openssl/aes.h>
#include <openssl/cipher.h>
-#include <openssl/modes.h>
+
+#include "../crypto/modes/internal.h"
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64)
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index 659f05f..f719f02 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -98,9 +98,23 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
/* EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
-/* EVP_aead_chacha20_poly1305 is an AEAD built from ChaCha20 and Poly1305. */
+/* EVP_aead_chacha20_poly1305_old is an AEAD built from ChaCha20 and
+ * Poly1305 that is used in the experimental ChaCha20-Poly1305 TLS cipher
+ * suites. */
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void);
+
+/* EVP_aead_chacha20_poly1305 is currently an alias for
+ * |EVP_aead_chacha20_poly1305_old|. In the future, the RFC 7539 version will
+ * take this name. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
+/* EVP_aead_chacha20_poly1305_rfc7539 is the AEAD built from ChaCha20 and
+ * Poly1305 as described in RFC 7539.
+ *
+ * WARNING: this function is not ready yet. It will be renamed in the future to
+ * drop the “_rfc7539” suffix. */
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
+
/* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be
* used except to interoperate with existing systems that use this mode.
*
diff --git a/src/include/openssl/arm_arch.h b/src/include/openssl/arm_arch.h
index 123a890..1471db9 100644
--- a/src/include/openssl/arm_arch.h
+++ b/src/include/openssl/arm_arch.h
@@ -102,15 +102,6 @@
* will be included. */
#define __ARM_MAX_ARCH__ 8
-#if !__ASSEMBLER__
-
-/* OPENSSL_armcap_P contains flags describing the capabilities of the CPU and
- * is easy for assembly code to acesss. For C code, see the functions in
- * |cpu.h|. */
-extern uint32_t OPENSSL_armcap_P;
-
-#endif /* !__ASSEMBLER__ */
-
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
#define ARMV7_NEON (1 << 0)
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 043524d..08886d1 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -1,4 +1,3 @@
-/* crypto/asn1/asn1.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
diff --git a/src/include/openssl/asn1_mac.h b/src/include/openssl/asn1_mac.h
index 49b2a28..f319bee 100644
--- a/src/include/openssl/asn1_mac.h
+++ b/src/include/openssl/asn1_mac.h
@@ -1,4 +1,3 @@
-/* crypto/asn1/asn1_mac.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
diff --git a/src/include/openssl/asn1t.h b/src/include/openssl/asn1t.h
index 0f2560b..b43c332 100644
--- a/src/include/openssl/asn1t.h
+++ b/src/include/openssl/asn1t.h
@@ -1,4 +1,3 @@
-/* asn1t.h */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index 41e4b60..ea7185f 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -109,6 +109,7 @@ extern "C" {
#define OPENSSL_IS_BORINGSSL
#define OPENSSL_VERSION_NUMBER 0x10002000
+#define BORINGSSL_201510
#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
#if defined(BORINGSSL_SHARED_LIBRARY)
@@ -214,6 +215,7 @@ typedef struct env_md_st EVP_MD;
typedef struct evp_aead_st EVP_AEAD;
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_encode_ctx_st EVP_ENCODE_CTX;
typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
diff --git a/src/include/openssl/base64.h b/src/include/openssl/base64.h
index 2d27c89..f28e7dd 100644
--- a/src/include/openssl/base64.h
+++ b/src/include/openssl/base64.h
@@ -70,32 +70,8 @@ extern "C" {
* base64 encoding and decoding. */
-typedef struct evp_encode_ctx_st EVP_ENCODE_CTX;
-
-
/* Encoding */
-/* EVP_EncodeInit initialises |*ctx|, which is typically stack
- * allocated, for an encoding operation.
- *
- * NOTE: The encoding operation breaks its output with newlines every
- * 64 characters of output (48 characters of input). Use
- * EVP_EncodeBlock to encode raw base64. */
-OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
-
-/* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
- * version of them to |out| and sets |*out_len| to the number of bytes written.
- * Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
- * flush it before using the encoded data. */
-OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
- int *out_len, const uint8_t *in,
- size_t in_len);
-
-/* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
- * sets |*out_len| to the number of bytes written. */
-OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
- int *out_len);
-
/* EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the
* result to |dst| with a trailing NUL. It returns the number of bytes
* written, not including this trailing NUL. */
@@ -124,6 +100,36 @@ OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *in,
size_t in_len);
+
+/* Deprecated functions.
+ *
+ * OpenSSL provides a streaming base64 implementation, however its behavior is
+ * very specific to PEM. It is also very lenient of invalid input. Use of any of
+ * these functions is thus deprecated.
+ *
+ * TODO(davidben): Import upstream's rewrite that rejects the invalid input. */
+
+/* EVP_EncodeInit initialises |*ctx|, which is typically stack
+ * allocated, for an encoding operation.
+ *
+ * NOTE: The encoding operation breaks its output with newlines every
+ * 64 characters of output (48 characters of input). Use
+ * EVP_EncodeBlock to encode raw base64. */
+OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+
+/* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
+ * version of them to |out| and sets |*out_len| to the number of bytes written.
+ * Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
+ * flush it before using the encoded data. */
+OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
+ int *out_len, const uint8_t *in,
+ size_t in_len);
+
+/* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
+ * sets |*out_len| to the number of bytes written. */
+OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
+ int *out_len);
+
/* EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for
* a decoding operation.
*
@@ -148,9 +154,6 @@ OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len);
-
-/* Deprecated functions. */
-
/* EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to
* |dst|. It returns the number of bytes written or -1 on error.
*
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index 04e3790..44de50f 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -444,8 +444,9 @@ OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag);
* or zero on error. */
OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag);
-/* BIO_get_fd sets |*out_fd| to the file descriptor currently in use by |bio|.
- * It returns one on success and zero on error. */
+/* BIO_get_fd returns the file descriptor currently in use by |bio| or -1 if
+ * |bio| does not wrap a file descriptor. If there is a file descriptor and
+ * |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor. */
OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd);
@@ -841,7 +842,6 @@ struct bio_st {
#define BIO_C_GET_MD_CTX 120
#define BIO_C_GET_PROXY_PARAM 121
#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */
-#define BIO_C_GET_CONNECT 123
#define BIO_C_GET_ACCEPT 124
#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125
#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index 8de8cc4..46673dc 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -731,11 +731,7 @@ OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
/* BN_MONT_CTX_new returns a fresh BN_MONT_CTX or NULL on allocation failure. */
OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void);
-/* BN_MONT_CTX_init initialises a stack allocated |BN_MONT_CTX|. */
-OPENSSL_EXPORT void BN_MONT_CTX_init(BN_MONT_CTX *mont);
-
-/* BN_MONT_CTX_free frees the contexts of |mont| and, if it was originally
- * allocated with |BN_MONT_CTX_new|, |mont| itself. */
+/* BN_MONT_CTX_free frees memory associated with |mont|. */
OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont);
/* BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or
@@ -843,7 +839,6 @@ struct bn_mont_ctx_st {
* (Ni is only stored for bignum algorithm) */
BN_ULONG n0[2]; /* least significant word(s) of Ni;
(type changed with 0.9.9, was "BN_ULONG n0;" before) */
- int flags;
int ri; /* number of bits in R */
};
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 1b1a0a9..2fa065e 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -270,7 +270,11 @@ OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
/* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
* writing to the same buffer. This should be used in an error case where a
- * serialisation is abandoned. */
+ * serialisation is abandoned.
+ *
+ * This function can only be called on a "top level" |CBB|, i.e. one initialised
+ * with |CBB_init| or |CBB_init_fixed|, or a |CBB| set to the zero state with
+ * |CBB_zero|. */
OPENSSL_EXPORT void CBB_cleanup(CBB *cbb);
/* CBB_finish completes any pending length prefix and sets |*out_data| to a
@@ -340,6 +344,10 @@ OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value);
* returns one on success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value);
+/* CBB_discard_child discards the current unflushed child of |cbb|. Neither the
+ * child's contents nor the length prefix will be included in the output. */
+OPENSSL_EXPORT void CBB_discard_child(CBB *cbb);
+
/* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
* and writes |value| in its contents. It returns one on success and zero on
* error. */
diff --git a/src/include/openssl/chacha.h b/src/include/openssl/chacha.h
index b7f5882..64713c2 100644
--- a/src/include/openssl/chacha.h
+++ b/src/include/openssl/chacha.h
@@ -27,7 +27,7 @@ extern "C" {
* initial block counter is specified by |counter|. */
OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
size_t in_len, const uint8_t key[32],
- const uint8_t nonce[8], size_t counter);
+ const uint8_t nonce[12], uint32_t counter);
#if defined(__cplusplus)
diff --git a/src/include/openssl/cmac.h b/src/include/openssl/cmac.h
index 183f41b..0bb44b9 100644
--- a/src/include/openssl/cmac.h
+++ b/src/include/openssl/cmac.h
@@ -73,4 +73,4 @@ OPENSSL_EXPORT int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len);
} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_CBC_H */
+#endif /* OPENSSL_HEADER_CMAC_H */
diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h
index 981d246..19e11d0 100644
--- a/src/include/openssl/cpu.h
+++ b/src/include/openssl/cpu.h
@@ -94,6 +94,14 @@ extern uint32_t OPENSSL_ia32cap_P[4];
#endif
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+
+#if defined(OPENSSL_APPLE)
+/* iOS builds use the static ARM configuration. */
+#define OPENSSL_STATIC_ARMCAP
+#endif
+
+#if !defined(OPENSSL_STATIC_ARMCAP)
+
/* CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. Note
* that |OPENSSL_armcap_P| also exists and contains the same information in a
* form that's easier for assembly to use. */
@@ -116,6 +124,46 @@ OPENSSL_EXPORT char CRYPTO_is_NEON_functional(void);
* compiled with |-mfpu=neon| or if |CRYPTO_set_NEON_capable| has been called
* with a non-zero argument. */
OPENSSL_EXPORT void CRYPTO_set_NEON_functional(char neon_functional);
+
+/* CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the
+ * ARMv8 AES instruction. */
+int CRYPTO_is_ARMv8_AES_capable(void);
+
+/* CRYPTO_is_ARMv8_PMULL_capable returns true if the current CPU supports the
+ * ARMv8 PMULL instruction. */
+int CRYPTO_is_ARMv8_PMULL_capable(void);
+
+#else
+
+static inline int CRYPTO_is_NEON_capable(void) {
+#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static inline int CRYPTO_is_NEON_functional(void) {
+ return CRYPTO_is_NEON_capable();
+}
+
+static inline int CRYPTO_is_ARMv8_AES_capable(void) {
+#if defined(OPENSSL_STATIC_ARMCAP_AES)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static inline int CRYPTO_is_ARMv8_PMULL_capable(void) {
+#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#endif /* OPENSSL_STATIC_ARMCAP */
#endif /* OPENSSL_ARM */
diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h
index 5207a12..b421884 100644
--- a/src/include/openssl/crypto.h
+++ b/src/include/openssl/crypto.h
@@ -54,6 +54,12 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
* base.h. */
OPENSSL_EXPORT unsigned long SSLeay(void);
+/* CRYPTO_malloc_init returns one. */
+OPENSSL_EXPORT int CRYPTO_malloc_init(void);
+
+/* ENGINE_load_builtin_engines does nothing. */
+OPENSSL_EXPORT void ENGINE_load_builtin_engines(void);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/des.h b/src/include/openssl/des.h
index f9db62d..2b8dd0f 100644
--- a/src/include/openssl/des.h
+++ b/src/include/openssl/des.h
@@ -157,6 +157,19 @@ OPENSSL_EXPORT void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out,
DES_cblock *ivec, int enc);
+/* Private functions.
+ *
+ * These functions are only exported for use in |decrepit|. */
+
+OPENSSL_EXPORT void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2,
+ const DES_key_schedule *ks3);
+
+OPENSSL_EXPORT void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2,
+ const DES_key_schedule *ks3);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 66be4d0..80028ef 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -138,8 +138,9 @@ OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
size_t len);
-/* EVP_MAX_MD_SIZE is the largest digest size supported. Functions that output
- * a digest generally require the buffer have at least this much space. */
+/* EVP_MAX_MD_SIZE is the largest digest size supported, in bytes.
+ * Functions that output a digest generally require the buffer have
+ * at least this much space. */
#define EVP_MAX_MD_SIZE 64 /* SHA-512 is the longest so far. */
/* EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to
@@ -180,7 +181,7 @@ OPENSSL_EXPORT uint32_t EVP_MD_flags(const EVP_MD *md);
/* EVP_MD_size returns the digest size of |md|, in bytes. */
OPENSSL_EXPORT size_t EVP_MD_size(const EVP_MD *md);
-/* EVP_MD_block_size returns the native block-size of |md|. */
+/* EVP_MD_block_size returns the native block-size of |md|, in bytes. */
OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md);
/* EVP_MD_FLAG_PKEY_DIGEST indicates the the digest function is used with a
@@ -204,7 +205,7 @@ OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
* compatibility with OpenSSL. */
OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest);
-/* EVP_get_cipherbyname returns an |EVP_MD| given a human readable name in
+/* EVP_get_digestbyname returns an |EVP_MD| given a human readable name in
* |name|, or NULL if the name is unknown. */
OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *);
@@ -215,12 +216,12 @@ OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *);
* been set. */
OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
-/* EVP_MD_CTX_size returns the digest size of |ctx|. It will crash if a digest
- * hasn't been set on |ctx|. */
+/* EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It
+ * will crash if a digest hasn't been set on |ctx|. */
OPENSSL_EXPORT unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx);
/* EVP_MD_CTX_block_size returns the block size of the digest function used by
- * |ctx|. It will crash if a digest hasn't been set on |ctx|. */
+ * |ctx|, in bytes. It will crash if a digest hasn't been set on |ctx|. */
OPENSSL_EXPORT unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx);
/* EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|.
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index f664211..fe1c89e 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -87,7 +87,7 @@ typedef enum {
/** the point is encoded as z||x, where the octet z specifies
* which solution of the quadratic equation y is */
POINT_CONVERSION_COMPRESSED = 2,
- /** the point is encoded as z||x||y, where z is the octet 0x02 */
+ /** the point is encoded as z||x||y, where z is the octet 0x04 */
POINT_CONVERSION_UNCOMPRESSED = 4
} point_conversion_form_t;
@@ -144,7 +144,7 @@ OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group);
/* EC_GROUP_get_degree returns the number of bits needed to represent an
* element of the field underlying |group|. */
-OPENSSL_EXPORT int EC_GROUP_get_degree(const EC_GROUP *group);
+OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group);
/* EC_GROUP_precompute_mult precomputes multiplies of the generator in order to
* speed up operations that involve calculating generator multiples. It returns
@@ -325,9 +325,7 @@ OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
/* Old code expects to get EC_KEY from ec.h. */
-#if !defined(OPENSSL_HEADER_EC_KEY_H)
#include <openssl/ec_key.h>
-#endif
#if defined(__cplusplus)
diff --git a/src/include/openssl/ecdh.h b/src/include/openssl/ecdh.h
index 878cbeb..5fe3ae9 100644
--- a/src/include/openssl/ecdh.h
+++ b/src/include/openssl/ecdh.h
@@ -80,14 +80,14 @@ extern "C" {
/* ECDH_compute_key calculates the shared key between |pub_key| and |priv_key|.
- * If |KDF| is not NULL, then it is called with the bytes of the shared key and
- * the parameter |out|. When |KDF| returns, the value of |*outlen| becomes the
+ * If |kdf| is not NULL, then it is called with the bytes of the shared key and
+ * the parameter |out|. When |kdf| returns, the value of |*outlen| becomes the
* return value. Otherwise, as many bytes of the shared key as will fit are
* copied directly to, at most, |outlen| bytes at |out|. It returns the number
* of bytes written to |out|, or -1 on error. */
OPENSSL_EXPORT int ECDH_compute_key(void *out, size_t outlen,
const EC_POINT *pub_key, EC_KEY *priv_key,
- void *(*KDF)(const void *in, size_t inlen,
+ void *(*kdf)(const void *in, size_t inlen,
void *out, size_t *outlen));
diff --git a/src/include/openssl/ecdsa.h b/src/include/openssl/ecdsa.h
index 84702c3..b7f15c4 100644
--- a/src/include/openssl/ecdsa.h
+++ b/src/include/openssl/ecdsa.h
@@ -161,7 +161,7 @@ OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in,
* the result to |cbb|. It returns one on success and zero on error. */
OPENSSL_EXPORT int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig);
-/* ECDSA_SIG_to_asn1 marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on
+/* ECDSA_SIG_to_bytes marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on
* success, sets |*out_bytes| to a newly allocated buffer containing the result
* and returns one. Otherwise, it returns zero. The result should be freed with
* |OPENSSL_free|. */
diff --git a/src/include/openssl/lhash.h b/src/include/openssl/lhash.h
index 691b247..0d6d3ae 100644
--- a/src/include/openssl/lhash.h
+++ b/src/include/openssl/lhash.h
@@ -189,4 +189,4 @@ OPENSSL_EXPORT uint32_t lh_strhash(const char *c);
} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_STACK_H */
+#endif /* OPENSSL_HEADER_LHASH_H */
diff --git a/src/include/openssl/modes.h b/src/include/openssl/modes.h
deleted file mode 100644
index 220adec..0000000
--- a/src/include/openssl/modes.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ==================================================================== */
-
-#ifndef OPENSSL_HEADER_MODES_H
-#define OPENSSL_HEADER_MODES_H
-
-#include <openssl/base.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-
-/* modes.h contains functions that implement various block-cipher modes. */
-
-
-/* block128_f is the type of a 128-bit, block cipher. */
-typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16],
- const void *key);
-
-
-/* CTR. */
-
-/* ctr128_f is the type of a function that performs CTR-mode encryption. */
-typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks,
- const void *key, const uint8_t ivec[16]);
-
-/* CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode)
- * |len| bytes from |in| to |out| using |block| in counter mode. There's no
- * requirement that |len| be a multiple of any value and any partial blocks are
- * stored in |ecount_buf| and |*num|, which must be zeroed before the initial
- * call. The counter is a 128-bit, big-endian value in |ivec| and is
- * incremented by this function. */
-OPENSSL_EXPORT void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out,
- size_t len, const void *key,
- uint8_t ivec[16],
- uint8_t ecount_buf[16],
- unsigned int *num, block128_f block);
-
-/* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
- * |ctr|, a function that performs CTR mode but only deals with the lower 32
- * bits of the counter. This is useful when |ctr| can be an optimised
- * function. */
-OPENSSL_EXPORT void CRYPTO_ctr128_encrypt_ctr32(
- const uint8_t *in, uint8_t *out, size_t len, const void *key,
- uint8_t ivec[16], uint8_t ecount_buf[16], unsigned int *num, ctr128_f ctr);
-
-
-/* GCM. */
-
-typedef struct gcm128_context GCM128_CONTEXT;
-
-/* CRYPTO_gcm128_new allocates a fresh |GCM128_CONTEXT| and calls
- * |CRYPTO_gcm128_init|. It returns the new context, or NULL on error. */
-OPENSSL_EXPORT GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
-
-/* CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with the
- * given key. */
-OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key,
- block128_f block);
-
-/* CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const uint8_t *iv,
- size_t len);
-
-/* CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. This
- * must be called before and data is encrypted. It returns one on success and
- * zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad,
- size_t len);
-
-/* CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. It returns
- * one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len);
-
-/* CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. It returns
- * one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const uint8_t *in,
- uint8_t *out, size_t len);
-
-/* CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using a
- * CTR function that only handles the bottom 32 bits of the nonce, like
- * |CRYPTO_ctr128_encrypt_ctr32|. It returns one on success and zero
- * otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
- const uint8_t *in, uint8_t *out,
- size_t len, ctr128_f stream);
-
-/* CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using a
- * CTR function that only handles the bottom 32 bits of the nonce, like
- * |CRYPTO_ctr128_encrypt_ctr32|. It returns one on success and zero
- * otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
- const uint8_t *in, uint8_t *out,
- size_t len, ctr128_f stream);
-
-/* CRYPTO_gcm128_finish calculates the authenticator and compares it against
- * |len| bytes of |tag|. It returns one on success and zero otherwise. */
-OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag,
- size_t len);
-
-/* CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. The
- * minimum of |len| and 16 bytes are copied into |tag|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag,
- size_t len);
-
-/* CRYPTO_gcm128_release clears and frees |ctx|. */
-OPENSSL_EXPORT void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
-
-
-/* CBC. */
-
-/* cbc128_f is the type of a function that performs CBC-mode encryption. */
-typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], int enc);
-
-/* CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the
- * given IV and block cipher in CBC mode. The input need not be a multiple of
- * 128 bits long, but the output will round up to the nearest 128 bit multiple,
- * zero padding the input if needed. The IV will be updated on return. */
-void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], block128_f block);
-
-/* CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the
- * given IV and block cipher in CBC mode. If |len| is not a multiple of 128
- * bits then only that many bytes will be written, but a multiple of 128 bits
- * is always read from |in|. The IV will be updated on return. */
-void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], block128_f block);
-
-
-/* OFB. */
-
-/* CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode)
- * |len| bytes from |in| to |out| using |block| in OFB mode. There's no
- * requirement that |len| be a multiple of any value and any partial blocks are
- * stored in |ivec| and |*num|, the latter must be zero before the initial
- * call. */
-void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
- size_t len, const void *key, uint8_t ivec[16],
- int *num, block128_f block);
-
-
-/* CFB. */
-
-/* CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
- * from |in| to |out| using |block| in CFB mode. There's no requirement that
- * |len| be a multiple of any value and any partial blocks are stored in |ivec|
- * and |*num|, the latter must be zero before the initial call. */
-void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], int *num, int enc,
- block128_f block);
-
-/* CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
- * from |in| to |out| using |block| in CFB-8 mode. Prior to the first call
- * |num| should be set to zero. */
-void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16], int *num,
- int enc, block128_f block);
-
-/* CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
- * from |in| to |out| using |block| in CFB-1 mode. Prior to the first call
- * |num| should be set to zero. */
-void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
- const void *key, uint8_t ivec[16], int *num,
- int enc, block128_f block);
-
-size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
- const void *key, uint8_t ivec[16],
- block128_f block);
-
-
-#if defined(__cplusplus)
-} /* extern C */
-#endif
-
-#endif /* OPENSSL_HEADER_MODES_H */
diff --git a/src/include/openssl/obj.h b/src/include/openssl/obj.h
index 0c7ae60..956bbe9 100644
--- a/src/include/openssl/obj.h
+++ b/src/include/openssl/obj.h
@@ -54,8 +54,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#ifndef OPENSSL_HEADER_OBJECTS_H
-#define OPENSSL_HEADER_OBJECTS_H
+#ifndef OPENSSL_HEADER_OBJ_H
+#define OPENSSL_HEADER_OBJ_H
#include <openssl/base.h>
@@ -195,4 +195,4 @@ OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid,
#define OBJ_R_UNKNOWN_NID 100
-#endif /* OPENSSL_HEADER_OBJECTS_H */
+#endif /* OPENSSL_HEADER_OBJ_H */
diff --git a/src/include/openssl/pkcs8.h b/src/include/openssl/pkcs8.h
index bb6b03c..6b51f85 100644
--- a/src/include/openssl/pkcs8.h
+++ b/src/include/openssl/pkcs8.h
@@ -106,6 +106,14 @@ OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_pbe(X509_SIG *pkcs8,
const uint8_t *pass_raw,
size_t pass_raw_len);
+/* PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates
+ * and decrypts it using |password|, sets |*out_key| to the included private
+ * key and appends the included certificates to |out_certs|. It returns one on
+ * success and zero on error. The caller takes ownership of the outputs. */
+OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key,
+ STACK_OF(X509) *out_certs,
+ CBS *in, const char *password);
+
/* Deprecated functions. */
@@ -127,17 +135,6 @@ OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8,
const char *pass,
int pass_len);
-/* PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates
- * and decrypts it using |password|, sets |*out_key| to the included private
- * key and appends the included certificates to |out_certs|. It returns one on
- * success and zero on error. The caller takes ownership of the outputs. */
-OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key,
- STACK_OF(X509) *out_certs,
- CBS *in, const char *password);
-
-
-/* Deprecated functions. */
-
/* PKCS12_PBE_add does nothing. It exists for compatibility with OpenSSL. */
OPENSSL_EXPORT void PKCS12_PBE_add(void);
@@ -169,9 +166,21 @@ OPENSSL_EXPORT int PKCS12_parse(const PKCS12 *p12, const char *password,
EVP_PKEY **out_pkey, X509 **out_cert,
STACK_OF(X509) **out_ca_certs);
+/* PKCS12_verify_mac returns one if |password| is a valid password for |p12|
+ * and zero otherwise. Since |PKCS12_parse| doesn't take a length parameter,
+ * it's not actually possible to use a non-NUL-terminated password to actually
+ * get anything from a |PKCS12|. Thus |password| and |password_len| may be
+ * |NULL| and zero, respectively, or else |password_len| may be -1, or else
+ * |password[password_len]| must be zero and no other NUL bytes may appear in
+ * |password|. If the |password_len| checks fail, zero is returned
+ * immediately. */
+OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
+ int password_len);
+
/* PKCS12_free frees |p12| and its contents. */
OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12);
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/poly1305.h b/src/include/openssl/poly1305.h
index 0da9f6e..b4e23e2 100644
--- a/src/include/openssl/poly1305.h
+++ b/src/include/openssl/poly1305.h
@@ -24,21 +24,22 @@ extern "C" {
typedef uint8_t poly1305_state[512];
-/* poly1305_init sets up |state| so that it can be used to calculate an
+/* CRYPTO_poly1305_init sets up |state| so that it can be used to calculate an
* authentication tag with the one-time key |key|. Note that |key| is a
* one-time key and therefore there is no `reset' method because that would
* enable several messages to be authenticated with the same key. */
OPENSSL_EXPORT void CRYPTO_poly1305_init(poly1305_state* state,
const uint8_t key[32]);
-/* poly1305_update processes |in_len| bytes from |in|. It can be called zero or
- * more times after poly1305_init. */
+/* CRYPTO_poly1305_update processes |in_len| bytes from |in|. It can be called
+ * zero or more times after poly1305_init. */
OPENSSL_EXPORT void CRYPTO_poly1305_update(poly1305_state* state,
const uint8_t* in,
size_t in_len);
-/* poly1305_finish completes the poly1305 calculation and writes a 16 byte
- * authentication tag to |mac|. The |mac| address must be 16-byte aligned. */
+/* CRYPTO_poly1305_finish completes the poly1305 calculation and writes a 16
+ * byte authentication tag to |mac|. The |mac| address must be 16-byte
+ * aligned. */
OPENSSL_EXPORT void CRYPTO_poly1305_finish(poly1305_state* state,
uint8_t mac[16]);
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index 2be50dc..e0c4368 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -152,7 +152,7 @@ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out,
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_encrypt| instead. */
-OPENSSL_EXPORT int RSA_public_encrypt(int flen, const uint8_t *from,
+OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
/* RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in
@@ -164,7 +164,7 @@ OPENSSL_EXPORT int RSA_public_encrypt(int flen, const uint8_t *from,
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_decrypt| instead. */
-OPENSSL_EXPORT int RSA_private_decrypt(int flen, const uint8_t *from,
+OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
/* RSA_message_index_PKCS1_type_2 performs the first step of a PKCS #1 padding
@@ -244,7 +244,7 @@ OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_sign_raw| instead. */
-OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
+OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
/* RSA_public_decrypt verifies |flen| bytes of signature from |from| using the
@@ -255,7 +255,7 @@ OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
*
* WARNING: this function is dangerous because it breaks the usual return value
* convention. Use |RSA_verify_raw| instead. */
-OPENSSL_EXPORT int RSA_public_decrypt(int flen, const uint8_t *from,
+OPENSSL_EXPORT int RSA_public_decrypt(size_t flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 24bdf8e..dbf8705 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -1,4 +1,3 @@
-/* ssl/ssl.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -150,7 +149,9 @@
#include <openssl/hmac.h>
#include <openssl/lhash.h>
#include <openssl/pem.h>
+#include <openssl/ssl3.h>
#include <openssl/thread.h>
+#include <openssl/tls1.h>
#include <openssl/x509.h>
#if !defined(OPENSSL_WINDOWS)
@@ -173,70 +174,6 @@ extern "C" {
/* SSL implementation. */
-/* Initialization. */
-
-/* SSL_library_init initializes the crypto and SSL libraries and returns one. */
-OPENSSL_EXPORT int SSL_library_init(void);
-
-
-/* Cipher suites.
- *
- * |SSL_CIPHER| objects represent cipher suites. */
-
-DECLARE_STACK_OF(SSL_CIPHER)
-
-/* SSL_get_cipher_by_value returns the structure representing a TLS cipher
- * suite based on its assigned number, or NULL if unknown. See
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. */
-OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
-
-/* SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to
- * get the cipher suite value. */
-OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_is_AES returns one if |cipher| uses AES (either GCM or CBC
- * mode). */
-OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_has_MD5_HMAC returns one if |cipher| uses HMAC-MD5. */
-OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_is_AESGCM returns one if |cipher| uses AES-GCM. */
-OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_is_CHACHA20POLY1305 returns one if |cipher| uses
- * CHACHA20_POLY1305. */
-OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_is_NULL returns one if |cipher| does not encrypt. */
-OPENSSL_EXPORT int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_is_RC4 returns one if |cipher| uses RC4. */
-OPENSSL_EXPORT int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. */
-OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
- * method used by |cipher|. For example, "ECDHE_ECDSA". */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
- * name for |cipher| or NULL on error. For example,
- * "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The caller is responsible for
- * calling |OPENSSL_free| on the result. */
-OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
-
-/* SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If
- * |out_alg_bits| is not NULL, it writes the number of bits consumed by the
- * symmetric algorithm to |*out_alg_bits|. */
-OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
- int *out_alg_bits);
-
-
/* SSL contexts.
*
* |SSL_CTX| objects manage shared state and configuration between multiple TLS
@@ -278,6 +215,11 @@ OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx);
/* SSL_free releases memory associated with |ssl|. */
OPENSSL_EXPORT void SSL_free(SSL *ssl);
+/* SSL_get_SSL_CTX returns the |SSL_CTX| associated with |ssl|. If
+ * |SSL_set_SSL_CTX| is called, it returns the new |SSL_CTX|, not the initial
+ * one. */
+OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+
/* SSL_set_connect_state configures |ssl| to be a client. */
OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl);
@@ -292,6 +234,9 @@ OPENSSL_EXPORT int SSL_is_server(SSL *ssl);
* takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl|
* only takes ownership of one reference.
*
+ * In DTLS, if |rbio| is blocking, it must handle
+ * |BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT| control requests to set read timeouts.
+ *
* Calling this function on an already-configured |ssl| is deprecated. */
OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
@@ -301,11 +246,44 @@ OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl);
/* SSL_get_wbio returns the |BIO| that |ssl| writes to. */
OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl);
+/* SSL_get_fd calls |SSL_get_rfd|. */
+OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl);
+
+/* SSL_get_rfd returns the file descriptor that |ssl| is configured to read
+ * from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file
+ * descriptor then it returns -1. */
+OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl);
+
+/* SSL_get_wfd returns the file descriptor that |ssl| is configured to write
+ * to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file
+ * descriptor then it returns -1. */
+OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl);
+
+/* SSL_set_wfd configures |ssl| to read from and write to |fd|. It returns one
+ * on success and zero on allocation error. The caller retains ownership of
+ * |fd|. */
+OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd);
+
+/* SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and
+ * zero on allocation error. The caller retains ownership of |fd|. */
+OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd);
+
+/* SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and
+ * zero on allocation error. The caller retains ownership of |fd|. */
+OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd);
+
/* SSL_do_handshake continues the current handshake. If there is none or the
* handshake has completed or False Started, it returns one. Otherwise, it
* returns <= 0. The caller should pass the value into |SSL_get_error| to
* determine how to proceed.
*
+ * In DTLS, if the read |BIO| is non-blocking, the caller must drive
+ * retransmissions. Whenever |SSL_get_error| signals |SSL_ERROR_WANT_READ|, use
+ * |DTLSv1_get_timeout| to determine the current timeout. If it expires before
+ * the next retry, call |DTLSv1_handle_timeout|. Note that DTLS handshake
+ * retransmissions use fresh sequence numbers, so it is not sufficient to replay
+ * packets at the transport.
+ *
* TODO(davidben): Ensure 0 is only returned on transport EOF.
* https://crbug.com/466303. */
OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl);
@@ -330,6 +308,10 @@ OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
/* SSL_peek behaves like |SSL_read| but does not consume any bytes returned. */
OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num);
+/* SSL_pending returns the number of bytes available in |ssl|. It does not read
+ * from the transport. */
+OPENSSL_EXPORT int SSL_pending(const SSL *ssl);
+
/* SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs
* any pending handshakes, including renegotiations when enabled. On success, it
* returns the number of bytes read. Otherwise, it returns <= 0. The caller
@@ -375,8 +357,27 @@ OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num);
* it? */
OPENSSL_EXPORT int SSL_shutdown(SSL *ssl);
+/* SSL_CTX_set_quiet_shutdown sets quiet shutdown on |ctx| to |mode|. If
+ * enabled, |SSL_shutdown| will not send a close_notify alert or wait for one
+ * from the peer. It will instead synchronously return one. */
+OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
+
+/* SSL_CTX_get_quiet_shutdown returns whether quiet shutdown is enabled for
+ * |ctx|. */
+OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+
+/* SSL_set_quiet_shutdown sets quiet shutdown on |ssl| to |mode|. If enabled,
+ * |SSL_shutdown| will not send a close_notify alert or wait for one from the
+ * peer. It will instead synchronously return one. */
+OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+
+/* SSL_get_quiet_shutdown returns whether quiet shutdown is enabled for
+ * |ssl|. */
+OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
+
/* SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on
- * |ssl|. It should be called after an operation failed to determine. */
+ * |ssl|. It should be called after an operation failed to determine whether the
+ * error was fatal and, if not, when to retry. */
OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
/* SSL_ERROR_NONE indicates the operation succeeded. */
@@ -388,7 +389,11 @@ OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
/* SSL_ERROR_WANT_READ indicates the operation failed attempting to read from
* the transport. The caller may retry the operation when the transport is ready
- * for reading. */
+ * for reading.
+ *
+ * If signaled by a DTLS handshake, the caller must also call
+ * |DTLSv1_get_timeout| and |DTLSv1_handle_timeout| as appropriate. See
+ * |SSL_do_handshake|. */
#define SSL_ERROR_WANT_READ 2
/* SSL_ERROR_WANT_READ indicates the operation failed attempting to write to
@@ -447,7 +452,7 @@ OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
* retry the operation when lookup has completed. Note: when the operation is
* retried, the early callback will not be called a second time.
*
- * See also |select_certificate_cb| on |SSL_CTX|. */
+ * See also |SSL_CTX_set_select_certificate_cb|. */
#define SSL_ERROR_PENDING_CERTIFICATE 12
/* SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because
@@ -457,6 +462,33 @@ OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
* See also |SSL_set_private_key_method|. */
#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13
+/* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
+ * and zero on failure. */
+OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
+
+/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a
+ * timeout in progress, it sets |*out| to the time remaining and returns one.
+ * Otherwise, it returns zero.
+ *
+ * When the timeout expires, call |DTLSv1_handle_timeout| to handle the
+ * retransmit behavior.
+ *
+ * NOTE: This function must be queried again whenever the handshake state
+ * machine changes, including when |DTLSv1_handle_timeout| is called. */
+OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out);
+
+/* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no
+ * timeout had expired, it returns 0. Otherwise, it retransmits the previous
+ * flight of handshake messages and returns 1. If too many timeouts had expired
+ * without progress or an error occurs, it returns -1.
+ *
+ * NOTE: The caller's external timer should be compatible with the one |ssl|
+ * queries within some fudge factor. Otherwise, the call will be a no-op, but
+ * |DTLSv1_get_timeout| will return an updated timeout.
+ *
+ * WARNING: This function breaks the usual return value convention. */
+OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
+
/* Protocol versions. */
@@ -526,6 +558,11 @@ OPENSSL_EXPORT int SSL_version(const SSL *ssl);
* client's. */
#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
+/* SSL_OP_DISABLE_NPN configures an individual |SSL| to not advertise NPN,
+ * despite |SSL_CTX_set_next_proto_select_cb| being configured on the
+ * |SSL_CTX|. */
+#define SSL_OP_DISABLE_NPN 0x00800000L
+
/* SSL_CTX_set_options enables all options set in |options| (which should be one
* or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
* bitmask representing the resulting enabled options. */
@@ -575,8 +612,15 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
/* SSL_MODE_ENABLE_FALSE_START allows clients to send application data before
- * receipt of CCS and Finished. This mode enables full-handshakes to 'complete'
- * in one RTT. See draft-bmoeller-tls-falsestart-01. */
+ * receipt of ChangeCipherSpec and Finished. This mode enables full-handshakes
+ * to 'complete' in one RTT. See draft-bmoeller-tls-falsestart-01.
+ *
+ * When False Start is enabled, |SSL_do_handshake| may succeed before the
+ * handshake has completely finished. |SSL_write| will function at this point,
+ * and |SSL_read| will transparently wait for the final handshake leg before
+ * returning application data. To determine if False Start occurred or when the
+ * handshake is completely finished, see |SSL_in_false_start|, |SSL_in_init|,
+ * and |SSL_CB_HANDSHAKE_DONE| from |SSL_CTX_set_info_callback|. */
#define SSL_MODE_ENABLE_FALSE_START 0x00000080L
/* SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and
@@ -708,7 +752,11 @@ OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl);
/* SSL_CTX_set_cert_cb sets a callback that is called to select a certificate.
* The callback returns one on success, zero on internal error, and a negative
* number on failure or to pause the handshake. If the handshake is paused,
- * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. */
+ * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|.
+ *
+ * On the client, the callback may call |SSL_get0_certificate_types| and
+ * |SSL_get_client_CA_list| for information on the server's certificate
+ * request. */
OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx,
int (*cb)(SSL *ssl, void *arg),
void *arg);
@@ -716,10 +764,24 @@ OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx,
/* SSL_set_cert_cb sets a callback that is called to select a certificate. The
* callback returns one on success, zero on internal error, and a negative
* number on failure or to pause the handshake. If the handshake is paused,
- * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. */
+ * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|.
+ *
+ * On the client, the callback may call |SSL_get0_certificate_types| and
+ * |SSL_get_client_CA_list| for information on the server's certificate
+ * request. */
OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg),
void *arg);
+/* SSL_get0_certificate_types, for a client, sets |*out_types| to an array
+ * containing the client certificate types requested by a server. It returns the
+ * length of the array.
+ *
+ * The behavior of this function is undefined except during the callbacks set by
+ * by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the
+ * handshake is paused because of them. */
+OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl,
+ const uint8_t **out_types);
+
/* SSL_certs_clear resets the private key, leaf certificate, and certificate
* chain of |ssl|. */
OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl);
@@ -840,10 +902,10 @@ OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file,
OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file,
int type);
-/* SSL_CTX_use_certificate_file configures certificates for |ctx|. It reads the
- * contents of |file| as a PEM-encoded leaf certificate followed optionally by
- * the certificate chain to send to the peer. It returns one on success and zero
- * on failure. */
+/* SSL_CTX_use_certificate_chain_file configures certificates for |ctx|. It
+ * reads the contents of |file| as a PEM-encoded leaf certificate followed
+ * optionally by the certificate chain to send to the peer. It returns one on
+ * success and zero on failure. */
OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx,
const char *file);
@@ -904,7 +966,37 @@ typedef struct ssl_private_key_method_st {
* it is an error to call |sign_complete| if there is no pending |sign|
* operation in progress on |ssl|. */
enum ssl_private_key_result_t (*sign_complete)(SSL *ssl, uint8_t *out,
- size_t *out_len, size_t max_out);
+ size_t *out_len,
+ size_t max_out);
+
+ /* decrypt decrypts |in_len| bytes of encrypted data from |in|. On success it
+ * returns |ssl_private_key_success|, writes at most |max_out| bytes of
+ * decrypted data to |out| and sets |*out_len| to the actual number of bytes
+ * written. On failure it returns |ssl_private_key_failure|. If the operation
+ * has not completed, it returns |ssl_private_key_retry|. The caller should
+ * arrange for the high-level operation on |ssl| to be retried when the
+ * operation is completed, which will result in a call to |decrypt_complete|.
+ * This function only works with RSA keys and should perform a raw RSA
+ * decryption operation with no padding.
+ *
+ * It is an error to call |decrypt| while another private key operation is in
+ * progress on |ssl|. */
+ enum ssl_private_key_result_t (*decrypt)(SSL *ssl, uint8_t *out,
+ size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len);
+
+ /* decrypt_complete completes a pending |decrypt| operation. If the operation
+ * has completed, it returns |ssl_private_key_success| and writes the result
+ * to |out| as in |decrypt|. Otherwise, it returns |ssl_private_key_failure|
+ * on failure and |ssl_private_key_retry| if the operation is still in
+ * progress.
+ *
+ * |decrypt_complete| may be called arbitrarily many times before completion,
+ * but it is an error to call |decrypt_complete| if there is no pending
+ * |decrypt| operation in progress on |ssl|. */
+ enum ssl_private_key_result_t (*decrypt_complete)(SSL *ssl, uint8_t *out,
+ size_t *out_len,
+ size_t max_out);
} SSL_PRIVATE_KEY_METHOD;
/* SSL_set_private_key_method configures a custom private key on |ssl|.
@@ -913,23 +1005,244 @@ OPENSSL_EXPORT void SSL_set_private_key_method(
SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method);
+/* Cipher suites.
+ *
+ * |SSL_CIPHER| objects represent cipher suites. */
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+/* SSL_get_cipher_by_value returns the structure representing a TLS cipher
+ * suite based on its assigned number, or NULL if unknown. See
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value);
+
+/* SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to
+ * get the cipher suite value. */
+OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AES returns one if |cipher| uses AES (either GCM or CBC
+ * mode). */
+OPENSSL_EXPORT int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_has_MD5_HMAC returns one if |cipher| uses HMAC-MD5. */
+OPENSSL_EXPORT int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_AESGCM returns one if |cipher| uses AES-GCM. */
+OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_CHACHA20POLY1305 returns one if |cipher| uses
+ * CHACHA20_POLY1305. */
+OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_NULL returns one if |cipher| does not encrypt. */
+OPENSSL_EXPORT int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_RC4 returns one if |cipher| uses RC4. */
+OPENSSL_EXPORT int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. */
+OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_kx_name returns a string that describes the key-exchange
+ * method used by |cipher|. For example, "ECDHE_ECDSA". */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_rfc_name returns a newly-allocated string with the standard
+ * name for |cipher| or NULL on error. For example,
+ * "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". The caller is responsible for
+ * calling |OPENSSL_free| on the result. */
+OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If
+ * |out_alg_bits| is not NULL, it writes the number of bits consumed by the
+ * symmetric algorithm to |*out_alg_bits|. */
+OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
+ int *out_alg_bits);
+
+
+/* Cipher suite configuration.
+ *
+ * OpenSSL uses a mini-language to configure cipher suites. The language
+ * maintains an ordered list of enabled ciphers, along with an ordered list of
+ * disabled but available ciphers. Initially, all ciphers are disabled with a
+ * default ordering. The cipher string is then interpreted as a sequence of
+ * directives, separated by colons, each of which modifies this state.
+ *
+ * Most directives consist of a one character or empty opcode followed by a
+ * selector which matches a subset of available ciphers.
+ *
+ * Available opcodes are:
+ *
+ * The empty opcode enables and appends all matching disabled ciphers to the
+ * end of the enabled list. The newly appended ciphers are ordered relative to
+ * each other matching their order in the disabled list.
+ *
+ * |-| disables all matching enabled ciphers and prepends them to the disabled
+ * list, with relative order from the enabled list preserved. This means the
+ * most recently disabled ciphers get highest preference relative to other
+ * disabled ciphers if re-enabled.
+ *
+ * |+| moves all matching enabled ciphers to the end of the enabled list, with
+ * relative order preserved.
+ *
+ * |!| deletes all matching ciphers, enabled or not, from either list. Deleted
+ * ciphers will not matched by future operations.
+ *
+ * A selector may be a specific cipher (using the OpenSSL name for the cipher)
+ * or one or more rules separated by |+|. The final selector matches the
+ * intersection of each rule. For instance, |AESGCM+aECDSA| matches
+ * ECDSA-authenticated AES-GCM ciphers.
+ *
+ * Available cipher rules are:
+ *
+ * |ALL| matches all ciphers.
+ *
+ * |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE,
+ * ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is
+ * matched by |kECDHE| and not |kPSK|.
+ *
+ * |aRSA|, |aECDSA|, and |aPSK| match ciphers authenticated by RSA, ECDSA, and
+ * a pre-shared key, respectively.
+ *
+ * |RSA|, |DHE|, |ECDHE|, |PSK|, |ECDSA|, and |PSK| are aliases for the
+ * corresponding |k*| or |a*| cipher rule. |RSA| is an alias for |kRSA|, not
+ * |aRSA|.
+ *
+ * |3DES|, |RC4|, |AES128|, |AES256|, |AES|, |AESGCM|, |CHACHA20| match
+ * ciphers whose bulk cipher use the corresponding encryption scheme. Note
+ * that |AES|, |AES128|, and |AES256| match both CBC and GCM ciphers.
+ *
+ * |MD5|, |SHA1|, |SHA256|, and |SHA384| match legacy cipher suites using the
+ * corresponding hash function in their MAC. AEADs are matched by none of
+ * these.
+ *
+ * |SHA| is an alias for |SHA1|.
+ *
+ * Although implemented, authentication-only ciphers match no rules and must be
+ * explicitly selected by name.
+ *
+ * Deprecated cipher rules:
+ *
+ * |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|,
+ * |kECDHE|, and |ECDHE|, respectively.
+ *
+ * |MEDIUM| and |HIGH| match ciphers historically labeled by OpenSSL as
+ * 'medium' and 'high', respectively.
+ *
+ * |FIPS| matches ciphers historically FIPS-approved in OpenSSL.
+ *
+ * |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier.
+ * |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not
+ * be used.
+ *
+ * Unknown rules silently match nothing.
+ *
+ * The special |@STRENGTH| directive will sort all enabled ciphers by strength.
+ *
+ * The |DEFAULT| directive, when appearing at the front of the string, expands
+ * to the default ordering of available ciphers.
+ *
+ * If configuring a server, one may also configure equal-preference groups to
+ * partially respect the client's preferences when
+ * |SSL_OP_CIPHER_SERVER_PREFERENCE| is enabled. Ciphers in an equal-preference
+ * group have equal priority and use the client order. This may be used to
+ * enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305
+ * based on client preferences. An equal-preference is specified with square
+ * brackets, combining multiple selectors separated by |. For example:
+ *
+ * [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]
+ *
+ * Once an equal-preference group is used, future directives must be
+ * opcode-less. */
+
+/* SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is
+ * substituted when a cipher string starts with 'DEFAULT'. */
+#define SSL_DEFAULT_CIPHER_LIST "ALL"
+
+/* SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating
+ * |str| as a cipher string. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str);
+
+/* SSL_CTX_set_cipher_list configures the TLS 1.0+ cipher list for |ctx|,
+ * evaluating |str| as a cipher string. It returns one on success and zero on
+ * failure. If set, servers will use this cipher suite list for TLS 1.0 or
+ * higher. */
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str);
+
+/* SSL_CTX_set_cipher_list configures the TLS 1.1+ cipher list for |ctx|,
+ * evaluating |str| as a cipher string. It returns one on success and zero on
+ * failure. If set, servers will use this cipher suite list for TLS 1.1 or
+ * higher. */
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str);
+
+/* SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as
+ * a cipher string. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str);
+
+/* SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. If
+ * |SSL_CTX_set_cipher_list_tls10| or |SSL_CTX_set_cipher_list_tls11| has been
+ * used, the corresponding list for the current version is returned. */
+OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl);
+
+
/* Connection information. */
+/* SSL_is_init_finished returns one if |ssl| has completed its initial handshake
+ * and has no pending handshake. It returns zero otherwise. */
+OPENSSL_EXPORT int SSL_is_init_finished(const SSL *ssl);
+
+/* SSL_in_init returns one if |ssl| has a pending handshake and zero
+ * otherwise. */
+OPENSSL_EXPORT int SSL_in_init(const SSL *ssl);
+
+/* SSL_in_false_start returns one if |ssl| has a pending handshake that is in
+ * False Start. |SSL_write| may be called at this point without waiting for the
+ * peer, but |SSL_read| will complete the handshake before accepting application
+ * data.
+ *
+ * See also |SSL_MODE_ENABLE_FALSE_START|. */
+OPENSSL_EXPORT int SSL_in_false_start(const SSL *ssl);
+
/* SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the
* peer did not use certificates. The caller must call |X509_free| on the
* result to release it. */
OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl);
/* SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if
- * unavailable or the peer did not use certificates. For historical reasons,
- * this may not be available if resuming a serialized |SSL_SESSION|. The caller
- * does not take ownership of the result.
+ * unavailable or the peer did not use certificates. This is the unverified
+ * list of certificates as sent by the peer, not the final chain built during
+ * verification. For historical reasons, this value may not be available if
+ * resuming a serialized |SSL_SESSION|. The caller does not take ownership of
+ * the result.
*
* WARNING: This function behaves differently between client and server. If
* |ssl| is a server, the returned chain does not include the leaf certificate.
* If a client, it does. */
OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl);
+/* SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to
+ * |*out_len| bytes of SCT information from the server. This is only valid if
+ * |ssl| is a client. The SCT information is a SignedCertificateTimestampList
+ * (including the two leading length bytes).
+ * See https://tools.ietf.org/html/rfc6962#section-3.3
+ * If no SCT was received then |*out_len| will be zero on return.
+ *
+ * WARNING: the returned data is not guaranteed to be well formed. */
+OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl,
+ const uint8_t **out,
+ size_t *out_len);
+
+/* SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len|
+ * bytes of an OCSP response from the server. This is the DER encoding of an
+ * OCSPResponse type as defined in RFC 2560.
+ *
+ * WARNING: the returned data is not guaranteed to be well formed. */
+OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
+ size_t *out_len);
+
/* SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value
* for |ssl| to |out| and sets |*out_len| to the number of bytes written. It
* returns one on success or zero on error. In general |max_out| should be at
@@ -969,6 +1282,16 @@ OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl);
* renegotiation (RFC 5746) and zero otherwise. */
OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl);
+/* SSL_export_keying_material exports a value derived from the master secret, as
+ * specified in RFC 5705. It writes |out_len| bytes to |out| given a label and
+ * optional context. (Since a zero length context is allowed, the |use_context|
+ * flag controls whether a context is included.)
+ *
+ * It returns one on success and zero otherwise. */
+OPENSSL_EXPORT int SSL_export_keying_material(
+ SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len,
+ const uint8_t *context, size_t context_len, int use_context);
+
/* Custom extensions.
*
@@ -1064,6 +1387,7 @@ OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext(
* different threads and must not be modified. */
DECLARE_LHASH_OF(SSL_SESSION)
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
/* SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on
* error. This may be useful in writing tests but otherwise should not be
@@ -1130,9 +1454,9 @@ OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session);
* be used. */
OPENSSL_EXPORT long SSL_SESSION_set_time(SSL_SESSION *session, long time);
-/* SSL_SESSION_set_time sets |session|'s timeout to |timeout| and returns one.
- * This function may be useful in writing tests but otherwise should not be
- * used. */
+/* SSL_SESSION_set_timeout sets |session|'s timeout to |timeout| and returns
+ * one. This function may be useful in writing tests but otherwise should not
+ * be used. */
OPENSSL_EXPORT long SSL_SESSION_set_timeout(SSL_SESSION *session, long timeout);
/* SSL_SESSION_set1_id_context sets |session|'s session ID context (see
@@ -1169,11 +1493,8 @@ OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session,
/* SSL_SESS_CACHE_OFF disables all session caching. */
#define SSL_SESS_CACHE_OFF 0x0000
-/* SSL_SESS_CACHE_CLIENT enables session caching for a client.
- *
- * TODO(davidben): The internal cache is useless on the client. Always act as if
- * SSL_SESS_CACHE_NO_INTERNAL is set. https://crbug.com/531194. Also see TODO
- * attached to |SSL_CTX_sess_set_new_cb|. */
+/* SSL_SESS_CACHE_CLIENT enables session caching for a client. The internal
+ * cache is never used on a client, so this only enables the callbacks. */
#define SSL_SESS_CACHE_CLIENT 0x0001
/* SSL_SESS_CACHE_SERVER enables session caching for a server. */
@@ -1186,15 +1507,16 @@ OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session,
* |SSL_CTX_flush_sessions| every 255 connections. */
#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
-/* SSL_SESS_CACHE_NO_INTERNAL_LOOKUP disables looking up a session from the
- * internal session cache. */
+/* SSL_SESS_CACHE_NO_INTERNAL_LOOKUP, on a server, disables looking up a session
+ * from the internal session cache. */
#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
-/* SSL_SESS_CACHE_NO_INTERNAL_STORE disables storing sessions in the internal
- * session cache. */
+/* SSL_SESS_CACHE_NO_INTERNAL_STORE, on a server, disables storing sessions in
+ * the internal session cache. */
#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
-/* SSL_SESS_CACHE_NO_INTERNAL disables the internal session cache. */
+/* SSL_SESS_CACHE_NO_INTERNAL, on a server, disables the internal session
+ * cache. */
#define SSL_SESS_CACHE_NO_INTERNAL \
(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
@@ -1206,8 +1528,9 @@ OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
* |ctx| */
OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
- /* SSL_set_session, for a client, configures |ssl| to offer to resume |session|
- * in the initial handshake. */
+/* SSL_set_session, for a client, configures |ssl| to offer to resume |session|
+ * in the initial handshake and returns one. The caller retains ownership of
+ * |session|. */
OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session);
/* SSL_get_session returns a non-owning pointer to |ssl|'s session. Prior to the
@@ -1277,14 +1600,12 @@ OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
/* SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It
- * returns one on success and zero on error or if |ctx| already included a
- * session with that session ID. The caller retains its reference to
- * |session|. */
+ * returns one on success and zero on error or if |session| is already in the
+ * cache. The caller retains its reference to |session|. */
OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session);
/* SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache.
- * It returns one on success and zero on error or if no session with a matching
- * ID was found. */
+ * It returns one on success and zero if |session| was not in the cache. */
OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session);
/* SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as
@@ -1349,7 +1670,10 @@ OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
* |SSL_ERROR_PENDING_SESSION|.
*
* If the internal session cache is enabled, the callback is only consulted if
- * the internal cache does not return a match. */
+ * the internal cache does not return a match.
+ *
+ * The callback's |id| parameter is not const for historical reasons, but the
+ * contents may not be modified. */
OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
SSL_CTX *ctx,
SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, int id_len,
@@ -1366,33 +1690,6 @@ OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
* when the lookup has completed. */
OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
-/* GEN_SESSION_CB is a callback to generate session IDs for |ssl|. It returns
- * one on success and zero on error. On success, the generated ID is written to
- * |id| and |*id_len| set to the length. On entry, |*id_len| is the maximum
- * length of the ID, but the callback may shorten it if desired. It is an error
- * for the callback to set the size to zero.
- *
- * Callbacks may use |SSL_has_matching_session_id| to check that the generated
- * ID is unique. */
-typedef int (*GEN_SESSION_CB)(const SSL *ssl, uint8_t *id, unsigned *id_len);
-
-/* SSL_CTX_set_generate_session_id sets the session ID callback of |ctx| to
- * |cb| and returns one. It will be called on the server when establishing a new
- * session. */
-OPENSSL_EXPORT int SSL_CTX_set_generate_session_id(SSL_CTX *ctx,
- GEN_SESSION_CB cb);
-
-/* SSL_set_generate_session_id sets the session ID callback of |ssl| to |cb| and
- * returns one. It will be called on the server when establishing a new
- * session. */
-OPENSSL_EXPORT int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb);
-
-/* SSL_has_matching_session_id returns one if |ssl|'s session cache has a
- * session of value |id| and zero otherwise. */
-OPENSSL_EXPORT int SSL_has_matching_session_id(const SSL *ssl,
- const uint8_t *id,
- unsigned id_len);
-
/* Session tickets.
*
@@ -1583,8 +1880,11 @@ OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
* certificate verification externally. This may be done with
* |SSL_CTX_set_cert_verify_callback| or by extracting the chain with
* |SSL_get_peer_cert_chain| after the handshake. In the future, functions will
- * be added to use the SSL stack without depending on any part of the legacy
- * X.509 and ASN.1 stack. */
+ * be added to use the SSL stack without dependency on any part of the legacy
+ * X.509 and ASN.1 stack.
+ *
+ * To augment certificate verification, a client may also enable OCSP stapling
+ * (RFC 6066) and Certificate Transparency (RFC 6962) extensions. */
/* SSL_VERIFY_NONE, on a client, verifies the server certificate but does not
* make errors fatal. The result may be checked with |SSL_get_verify_result|. On
@@ -1750,6 +2050,36 @@ OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(
SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg),
void *arg);
+/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
+ * of a connection) to request SCTs from the server. See
+ * https://tools.ietf.org/html/rfc6962. It returns one.
+ *
+ * Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the
+ * handshake. */
+OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
+
+/* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
+ * objects created from |ctx|.
+ *
+ * Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the
+ * handshake. */
+OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
+
+/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
+ * connection) to request a stapled OCSP response from the server. It returns
+ * one.
+ *
+ * Call |SSL_get0_ocsp_response| to recover the OCSP response after the
+ * handshake. */
+OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
+
+/* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
+ * created from |ctx|.
+ *
+ * Call |SSL_get0_ocsp_response| to recover the OCSP response after the
+ * handshake. */
+OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
+
/* Client certificate CA list.
*
@@ -1767,7 +2097,14 @@ OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl,
OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,
STACK_OF(X509_NAME) *name_list);
-/* SSL_get_client_CA_list returns |ssl|'s client certificate CA list. */
+/* SSL_get_client_CA_list returns |ssl|'s client certificate CA list. If |ssl|
+ * has not been configured as a client, this is the list configured by
+ * |SSL_CTX_set_client_CA_list|.
+ *
+ * If configured as a client, it returns the client certificate CA list sent by
+ * the server. In this mode, the behavior is undefined except during the
+ * callbacks set by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or
+ * when the handshake is paused because of them. */
OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl);
/* SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. */
@@ -1806,6 +2143,52 @@ OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
const char *dir);
+/* Server name indication.
+ *
+ * The server_name extension (RFC 3546) allows the client to advertise the name
+ * of the server it is connecting to. This is used in virtual hosting
+ * deployments to select one of a several certificates on a single IP. Only the
+ * host_name name type is supported. */
+
+#define TLSEXT_NAMETYPE_host_name 0
+
+/* SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name|
+ * in the server_name extension. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name);
+
+/* SSL_get_servername, for a server, returns the hostname supplied by the
+ * client or NULL if there was none. The |type| argument must be
+ * |TLSEXT_NAMETYPE_host_name|. */
+OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type);
+
+/* SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name|
+ * if the client sent a hostname and -1 otherwise. */
+OPENSSL_EXPORT int SSL_get_servername_type(const SSL *ssl);
+
+/* SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on
+ * the server after ClientHello extensions have been parsed and returns one.
+ * The callback may use |SSL_get_servername| to examine the server_name extension
+ * and returns a |SSL_TLSEXT_ERR_*| value. The value of |arg| may be set by
+ * calling |SSL_CTX_set_tlsext_servername_arg|.
+ *
+ * If the callback returns |SSL_TLSEXT_ERR_NOACK|, the server_name extension is
+ * not acknowledged in the ServerHello. If the return value is
+ * |SSL_TLSEXT_ERR_ALERT_FATAL| or |SSL_TLSEXT_ERR_ALERT_WARNING| then
+ * |*out_alert| must be set to the alert value to send. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback(
+ SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg));
+
+/* SSL_CTX_set_tlsext_servername_arg sets the argument to the servername
+ * callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
+
+/* SSL_TLSEXT_ERR_* are values returned by some extension-related callbacks. */
+#define SSL_TLSEXT_ERR_OK 0
+#define SSL_TLSEXT_ERR_ALERT_WARNING 1
+#define SSL_TLSEXT_ERR_ALERT_FATAL 2
+#define SSL_TLSEXT_ERR_NOACK 3
+
+
/* Application-layer protocol negotation.
*
* The ALPN extension (RFC 7301) allows negotiating different application-layer
@@ -2119,6 +2502,66 @@ OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl);
OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl);
+/* Alerts.
+ *
+ * TLS and SSL 3.0 use alerts to signal error conditions. Alerts have a type
+ * (warning or fatal) and description. OpenSSL internally handles fatal alerts
+ * with dedicated error codes (see |SSL_AD_REASON_OFFSET|). Except for
+ * close_notify, warning alerts are silently ignored and may only be surfaced
+ * with |SSL_CTX_set_info_callback|. */
+
+/* SSL_AD_REASON_OFFSET is the offset between error reasons and |SSL_AD_*|
+ * values. Any error code under |ERR_LIB_SSL| with an error reason above this
+ * value corresponds to an alert description. Consumers may add or subtract
+ * |SSL_AD_REASON_OFFSET| to convert between them.
+ *
+ * make_errors.go reserves error codes above 1000 for manually-assigned errors.
+ * This value must be kept in sync with reservedReasonCode in make_errors.h */
+#define SSL_AD_REASON_OFFSET 1000
+
+/* SSL_AD_* are alert descriptions for SSL 3.0 and TLS. */
+#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
+#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE
+#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC
+#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED
+#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW
+#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE
+#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE
+#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not used in TLS */
+#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE
+#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE
+#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED
+#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED
+#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN
+#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER
+#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA
+#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED
+#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR
+#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR
+#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION
+#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION
+#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY
+#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR
+#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
+#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
+#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
+#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
+#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
+#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \
+ TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY
+#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK
+
+/* SSL_alert_type_string_long returns a string description of |value| as an
+ * alert type (warning or fatal). */
+OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
+
+/* SSL_alert_desc_string_long returns a string description of |value| as an
+ * alert description or "unknown" if unknown. */
+OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
+
+
/* ex_data functions.
*
* See |ex_data.h| for details. */
@@ -2162,104 +2605,6 @@ OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size,
size_t *ssl_ctx_size,
size_t *ssl_session_size);
-
-/* Underdocumented functions.
- *
- * Functions below here haven't been touched up and may be underdocumented. */
-
-/* SSLeay version number for ASN.1 encoding of the session information */
-/* Version 0 - initial version
- * Version 1 - added the optional peer certificate. */
-#define SSL_SESSION_ASN1_VERSION 0x0001
-
-#define SSL_MAX_SSL_SESSION_ID_LENGTH 32
-#define SSL_MAX_SID_CTX_LENGTH 32
-#define SSL_MAX_MASTER_KEY_LENGTH 48
-
-/* These are used to specify which ciphers to use and not to use */
-
-#define SSL_TXT_MEDIUM "MEDIUM"
-#define SSL_TXT_HIGH "HIGH"
-#define SSL_TXT_FIPS "FIPS"
-
-#define SSL_TXT_kRSA "kRSA"
-#define SSL_TXT_kDHE "kDHE"
-#define SSL_TXT_kEDH "kEDH" /* same as "kDHE" */
-#define SSL_TXT_kECDHE "kECDHE"
-#define SSL_TXT_kEECDH "kEECDH" /* same as "kECDHE" */
-#define SSL_TXT_kPSK "kPSK"
-
-#define SSL_TXT_aRSA "aRSA"
-#define SSL_TXT_aECDSA "aECDSA"
-#define SSL_TXT_aPSK "aPSK"
-
-#define SSL_TXT_DH "DH"
-#define SSL_TXT_DHE "DHE" /* same as "kDHE" */
-#define SSL_TXT_EDH "EDH" /* same as "DHE" */
-#define SSL_TXT_RSA "RSA"
-#define SSL_TXT_ECDH "ECDH"
-#define SSL_TXT_ECDHE "ECDHE" /* same as "kECDHE" */
-#define SSL_TXT_EECDH "EECDH" /* same as "ECDHE" */
-#define SSL_TXT_ECDSA "ECDSA"
-#define SSL_TXT_PSK "PSK"
-
-#define SSL_TXT_3DES "3DES"
-#define SSL_TXT_RC4 "RC4"
-#define SSL_TXT_AES128 "AES128"
-#define SSL_TXT_AES256 "AES256"
-#define SSL_TXT_AES "AES"
-#define SSL_TXT_AES_GCM "AESGCM"
-#define SSL_TXT_CHACHA20 "CHACHA20"
-
-#define SSL_TXT_MD5 "MD5"
-#define SSL_TXT_SHA1 "SHA1"
-#define SSL_TXT_SHA "SHA" /* same as "SHA1" */
-#define SSL_TXT_SHA256 "SHA256"
-#define SSL_TXT_SHA384 "SHA384"
-
-#define SSL_TXT_SSLV3 "SSLv3"
-#define SSL_TXT_TLSV1 "TLSv1"
-#define SSL_TXT_TLSV1_1 "TLSv1.1"
-#define SSL_TXT_TLSV1_2 "TLSv1.2"
-
-#define SSL_TXT_ALL "ALL"
-
-/* COMPLEMENTOF* definitions. These identifiers are used to (de-select) ciphers
- * normally not being used.
- *
- * Example: "RC4" will activate all ciphers using RC4 including ciphers without
- * authentication, which would normally disabled by DEFAULT (due the "!ADH"
- * being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" will make sure
- * that it is also disabled in the specific selection. COMPLEMENTOF*
- * identifiers are portable between version, as adjustments to the default
- * cipher setup will also be included here.
- *
- * COMPLEMENTOFDEFAULT does not experience the same special treatment that
- * DEFAULT gets, as only selection is being done and no sorting as needed for
- * DEFAULT. */
-#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT"
-
-/* The following cipher list is used by default. It also is substituted when an
- * application-defined cipher list string starts with 'DEFAULT'. */
-#define SSL_DEFAULT_CIPHER_LIST "ALL"
-
-/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
- * starts with a reasonable order, and all we have to do for DEFAULT is
- * throwing out anonymous and unencrypted ciphersuites! (The latter are not
- * actually enabled by ALL, but "ALL:RSA" would enable some of them.) */
-
-/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
-#define SSL_SENT_SHUTDOWN 1
-#define SSL_RECEIVED_SHUTDOWN 2
-
-typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
-typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
-typedef struct ssl3_enc_method SSL3_ENC_METHOD;
-
-/* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
- * and zero on failure. */
-OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
-
/* SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|.
* This callback will be called when sending or receiving low-level record
* headers, complete handshake messages, ChangeCipherSpec, and alerts.
@@ -2299,11 +2644,82 @@ OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg);
* https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. */
OPENSSL_EXPORT void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio);
+enum ssl_renegotiate_mode_t {
+ ssl_renegotiate_never = 0,
+ ssl_renegotiate_once,
+ ssl_renegotiate_freely,
+};
-struct ssl_aead_ctx_st;
-typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
+/* SSL_set_renegotiate_mode configures how |ssl|, a client, reacts to
+ * renegotiation attempts by a server. If |ssl| is a server, peer-initiated
+ * renegotiations are *always* rejected and this function does nothing.
+ *
+ * The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set
+ * at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to
+ * allow one renegotiation and |ssl_renegotiate_freely| to allow all
+ * renegotiations.
+ *
+ * There is no support in BoringSSL for initiating renegotiations as a client
+ * or server. */
+OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl,
+ enum ssl_renegotiate_mode_t mode);
+
+/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
+ * renegotiation. */
+OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
+
+/* SSL_total_renegotiations returns the total number of renegotiation handshakes
+ * peformed by |ssl|. This includes the pending renegotiation, if any. */
+OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
+
+/* SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer
+ * certificate chain. */
+#define SSL_MAX_CERT_LIST_DEFAULT 1024 * 100
+
+/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
+ * certificate chain accepted by |ctx|. */
+OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
+ * certificate chain to |max_cert_list|. This affects how much memory may be
+ * consumed during the handshake. */
+OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
+ size_t max_cert_list);
+
+/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
+ * certificate chain accepted by |ssl|. */
+OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);
-#define SSL_MAX_CERT_LIST_DEFAULT 1024 * 100 /* 100k max cert list */
+/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
+ * certificate chain to |max_cert_list|. This affects how much memory may be
+ * consumed during the handshake. */
+OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);
+
+/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
+ * sent by |ctx|. Beyond this length, handshake messages and application data
+ * will be split into multiple records. */
+OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
+ size_t max_send_fragment);
+
+/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
+ * sent by |ssl|. Beyond this length, handshake messages and application data
+ * will be split into multiple records. */
+OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
+ size_t max_send_fragment);
+
+/* OPENSSL_get_big_buffer_use_count returns the total number of invalid TLS
+ * records that were accepted because of |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER|.
+ *
+ * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be
+ * unnecessary. */
+OPENSSL_EXPORT uint64_t OPENSSL_get_big_buffer_use_count(void);
+
+/* OPENSSL_get_d5_bug_use_count returns the total number of invalid RSA
+ * ClientKeyExchanges that were accepted because of |SSL_OP_TLS_D5_BUG|.
+ *
+ * TODO(davidben): Remove this when (hopefully!) the quirk is demonstrated to be
+ * unnecessary. */
+OPENSSL_EXPORT uint64_t OPENSSL_get_d5_bug_use_count(void);
/* ssl_early_callback_ctx is passed to certain callbacks that are called very
* early on during the server handshake. At this point, much of the SSL* hasn't
@@ -2327,93 +2743,33 @@ struct ssl_early_callback_ctx {
* sets |out_data| to point to the extension contents (not including the type
* and length bytes), sets |out_len| to the length of the extension contents
* and returns one. */
-OPENSSL_EXPORT char SSL_early_callback_ctx_extension_get(
+OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get(
const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
const uint8_t **out_data, size_t *out_len);
-OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx,
- void (*cb)(const SSL *ssl,
- int type, int val));
-OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,
- int type,
- int val);
-OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
- SSL_CTX *ctx,
- int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
-OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl,
- X509 **x509,
- EVP_PKEY **pkey);
-/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
- * of a connection) to request SCTs from the server. See
- * https://tools.ietf.org/html/rfc6962. It returns one. */
-OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
-
-/* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
- * objects created from |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
-
-/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
- * connection) to request a stapled OCSP response from the server. It returns
- * one. */
-OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
-
-/* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
- * created from |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
-
-/* SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to
- * |*out_len| bytes of SCT information from the server. This is only valid if
- * |ssl| is a client. The SCT information is a SignedCertificateTimestampList
- * (including the two leading length bytes).
- * See https://tools.ietf.org/html/rfc6962#section-3.3
- * If no SCT was received then |*out_len| will be zero on return.
- *
- * WARNING: the returned data is not guaranteed to be well formed. */
-OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl,
- const uint8_t **out,
- size_t *out_len);
-
-/* SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len|
- * bytes of an OCSP response from the server. This is the DER encoding of an
- * OCSPResponse type as defined in RFC 2560.
- *
- * WARNING: the returned data is not guaranteed to be well formed. */
-OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
- size_t *out_len);
-
-/* SSL_set_reject_peer_renegotiations controls whether renegotiation attempts by
- * the peer are rejected. It may be set at any point in a connection's lifetime
- * to control future renegotiations programmatically. By default, renegotiations
- * are rejected. (Renegotiations requested by a client are always rejected.) */
-OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
-
-#define SSL_NOTHING 1
-#define SSL_WRITING 2
-#define SSL_READING 3
-#define SSL_X509_LOOKUP 4
-#define SSL_CHANNEL_ID_LOOKUP 5
-#define SSL_PENDING_SESSION 7
-#define SSL_CERTIFICATE_SELECTION_PENDING 8
-#define SSL_PRIVATE_KEY_OPERATION 9
+/* SSL_CTX_set_select_certificate_cb sets a callback that is called before most
+ * ClientHello processing and before the decision whether to resume a session
+ * is made. The callback may inspect the ClientHello and configure the
+ * connection. It may then return one to continue the handshake or zero to
+ * pause the handshake to perform an asynchronous operation. If paused,
+ * |SSL_get_error| will return |SSL_ERROR_PENDING_CERTIFICATE|.
+ *
+ * Note: The |ssl_early_callback_ctx| is only valid for the duration of the
+ * callback and is not valid while the handshake is paused. Further, unlike with
+ * most callbacks, when the handshake loop is resumed, it will not call the
+ * callback a second time. The caller must finish reconfiguring the connection
+ * before resuming the handshake. */
+OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
-/* These will only be used when doing non-blocking IO */
-#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
-#define SSL_want_read(s) (SSL_want(s) == SSL_READING)
-#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
-#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
-#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
-#define SSL_want_session(s) (SSL_want(s) == SSL_PENDING_SESSION)
-#define SSL_want_certificate(s) \
- (SSL_want(s) == SSL_CERTIFICATE_SELECTION_PENDING)
-#define SSL_want_private_key_operation(s) \
- (SSL_want(s) == SSL_PRIVATE_KEY_OPERATION)
-
-/* The following are the possible values for ssl->state are are used to
- * indicate where we are up to in the SSL connection establishment. The macros
- * that follow are about the only things you should need to use and even then,
- * only when using non-blocking IO. It can also be useful to work out where you
- * were when the connection failed */
+/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
+ * resumption decision for a ClientHello has been made. It can return one to
+ * allow the handshake to continue or zero to cause the handshake to abort. */
+OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+/* SSL_ST_* are possible values for |SSL_state| and the bitmasks that make them
+ * up. */
#define SSL_ST_CONNECT 0x1000
#define SSL_ST_ACCEPT 0x2000
#define SSL_ST_MASK 0x0FFF
@@ -2421,11 +2777,13 @@ OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
#define SSL_ST_OK 0x03
#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT)
+/* SSL_CB_* are possible values for the |type| parameter in the info
+ * callback and the bitmasks that make them up. */
#define SSL_CB_LOOP 0x01
#define SSL_CB_EXIT 0x02
#define SSL_CB_READ 0x04
#define SSL_CB_WRITE 0x08
-#define SSL_CB_ALERT 0x4000 /* used in callback */
+#define SSL_CB_ALERT 0x4000
#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ)
#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE)
#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP)
@@ -2435,190 +2793,93 @@ OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
#define SSL_CB_HANDSHAKE_START 0x10
#define SSL_CB_HANDSHAKE_DONE 0x20
-/* Is the SSL_connection established? */
-#define SSL_get_state(a) SSL_state(a)
-#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
-#define SSL_in_init(a) (SSL_state(a) & SSL_ST_INIT)
-#define SSL_in_connect_init(a) (SSL_state(a) & SSL_ST_CONNECT)
-#define SSL_in_accept_init(a) (SSL_state(a) & SSL_ST_ACCEPT)
-
-/* SSL_in_false_start returns one if |s| has a pending unfinished handshake that
- * is in False Start. |SSL_write| may be called at this point without waiting
- * for the peer, but |SSL_read| will require the handshake to be completed. */
-OPENSSL_EXPORT int SSL_in_false_start(const SSL *s);
-
-/* Obtain latest Finished message
- * -- that we sent (SSL_get_finished)
- * -- that we expected from peer (SSL_get_peer_finished).
- * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
-OPENSSL_EXPORT size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
-OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
-
-#define d2i_SSL_SESSION_bio(bp, s_id) \
- ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bp, s_id)
-#define i2d_SSL_SESSION_bio(bp, s_id) \
- ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bp, s_id)
-
-DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
-
-/* make_errors.go reserves error codes above 1000 for manually-assigned errors.
- * This value must be kept in sync with reservedReasonCode in make_errors.h */
-#define SSL_AD_REASON_OFFSET \
- 1000 /* offset to get SSL_R_... value from SSL_AD_... */
-
-/* These alert types are for SSLv3 and TLSv1 */
-#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
-#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
-#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */
-#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED
-#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW
-#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE /* fatal */
-#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE /* fatal */
-#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */
-#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE
-#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE
-#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED
-#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED
-#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN
-#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */
-#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */
-#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */
-#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */
-#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR
-#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION /* fatal */
-#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */
-#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY /* fatal */
-#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */
-#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
-#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
-#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
-#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
-#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
-#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \
- TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
-#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
-#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
-#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK /* fatal */
-
-/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a
- * timeout in progress, it sets |*out| to the time remaining and returns one.
- * Otherwise, it returns zero.
+/* SSL_set_info_callback configures a callback to be run when various events
+ * occur during a connection's lifetime. The |type| argumentj determines the
+ * type of event and the meaning of the |value| argument. Callbacks must ignore
+ * unexpected |type| values.
*
- * When the timeout expires, call |DTLSv1_handle_timeout| to handle the
- * retransmit behavior.
+ * |SSL_CB_READ_ALERT| is signaled for each alert received, warning or fatal.
+ * The |value| argument is a 16-bit value where the alert level (either
+ * |SSL3_AL_WARNING| or |SSL3_AL_FATAL|) is in the most-significant eight bits and
+ * the alert type (one of |SSL_AD_*|) is in the least-significant eight.
*
- * NOTE: This function must be queried again whenever the handshake state
- * machine changes, including when |DTLSv1_handle_timeout| is called. */
-OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out);
-
-/* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no
- * timeout had expired, it returns 0. Otherwise, it retransmits the previous
- * flight of handshake messages and returns 1. If too many timeouts had expired
- * without progress or an error occurs, it returns -1.
+ * |SSL_CB_WRITE_ALERT| is signaled for each alert sent. The |value| argument
+ * is constructed as with |SSL_CB_READ_ALERT|.
*
- * NOTE: The caller's external timer should be compatible with the one |ssl|
- * queries within some fudge factor. Otherwise, the call will be a no-op, but
- * |DTLSv1_get_timeout| will return an updated timeout.
+ * |SSL_CB_HANDSHAKE_START| is signaled when a handshake begins. The |value|
+ * argument is always one.
*
- * WARNING: This function breaks the usual return value convention. */
-OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
-
-/* SSL_total_renegotiations returns the total number of renegotiation handshakes
- * peformed by |ssl|. This includes the pending renegotiation, if any. */
-OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
-
-/* SSL_get0_certificate_types, for a client, sets |*out_types| to an array
- * containing the client certificate types requested by a server. It returns the
- * length of the array. */
-OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl,
- const uint8_t **out_types);
-
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls10(SSL_CTX *, const char *str);
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
-OPENSSL_EXPORT int SSL_want(const SSL *s);
-
-OPENSSL_EXPORT int SSL_get_fd(const SSL *s);
-OPENSSL_EXPORT int SSL_get_rfd(const SSL *s);
-OPENSSL_EXPORT int SSL_get_wfd(const SSL *s);
-OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *s, int n);
-OPENSSL_EXPORT int SSL_pending(const SSL *s);
-OPENSSL_EXPORT int SSL_set_fd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_rfd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_wfd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_cipher_list(SSL *s, const char *str);
-
-OPENSSL_EXPORT const char *SSL_state_string(const SSL *s);
-OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *s);
-
-OPENSSL_EXPORT int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
-OPENSSL_EXPORT int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
-
-OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+ * |SSL_CB_HANDSHAKE_DONE| is signaled when a handshake completes successfully.
+ * The |value| argument is always one. If a handshake False Starts, this event
+ * may be used to determine when the Finished message is received.
+ *
+ * The following event types expose implementation details of the handshake
+ * state machine. Consuming them is deprecated.
+ *
+ * |SSL_CB_ACCEPT_LOOP| (respectively, |SSL_CB_CONNECT_LOOP|) is signaled when
+ * a server (respectively, client) handshake progresses. The |value| argument
+ * is always one. For the duration of the callback, |SSL_state| will return the
+ * previous state.
+ *
+ * |SSL_CB_ACCEPT_EXIT| (respectively, |SSL_CB_CONNECT_EXIT|) is signaled when
+ * a server (respectively, client) handshake completes, fails, or is paused.
+ * The |value| argument is one if the handshake succeeded and <= 0
+ * otherwise. */
+OPENSSL_EXPORT void SSL_CTX_set_info_callback(
+ SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value));
-/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
- * renegotiation. */
-OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
+/* SSL_CTX_get_info_callback returns the callback set by
+ * |SSL_CTX_set_info_callback|. */
+OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,
+ int type,
+ int value);
-OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
-OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
-OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
-OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
+/* SSL_set_info_callback configures a callback to be run at various events
+ * during a connection's lifetime. See |SSL_CTX_set_info_callback|. */
+OPENSSL_EXPORT void SSL_set_info_callback(
+ SSL *ssl, void (*cb)(const SSL *ssl, int type, int value));
-OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
-OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode);
-OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
-OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode);
-OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
-OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
-OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_set_info_callback(SSL *ssl,
- void (*cb)(const SSL *ssl, int type,
- int val));
+/* SSL_get_info_callback returns the callback set by |SSL_set_info_callback|. */
OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,
- int type, int val);
-OPENSSL_EXPORT int SSL_state(const SSL *ssl);
-
-/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
- * certificate chain accepted by |ctx|. */
-OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
-
-/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
- * certificate chain to |max_cert_list|. This affects how much memory may be
- * consumed during the handshake. */
-OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
- size_t max_cert_list);
-
-/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
- * certificate chain accepted by |ssl|. */
-OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);
+ int type,
+ int value);
+
+/* SSL_state_string_long returns the current state of the handshake state
+ * machine as a string. This may be useful for debugging and logging. */
+OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *ssl);
+
+/* SSL_set_SSL_CTX partially changes |ssl|'s |SSL_CTX|. |ssl| will use the
+ * certificate and session_id_context from |ctx|, and |SSL_get_SSL_CTX| will
+ * report |ctx|. However most settings and the session cache itself will
+ * continue to use the initial |SSL_CTX|. It is often used as part of SNI.
+ *
+ * TODO(davidben): Make a better story here and get rid of this API. Also
+ * determine if there's anything else affected by |SSL_set_SSL_CTX| that
+ * matters. Not as many values are affected as one might initially think. The
+ * session cache explicitly selects the initial |SSL_CTX|. Most settings are
+ * copied at |SSL_new| so |ctx|'s versions don't apply. This, notably, has some
+ * consequences for any plans to make |SSL| copy-on-write most of its
+ * configuration. */
+OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
-/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
- * certificate chain to |max_cert_list|. This affects how much memory may be
- * consumed during the handshake. */
-OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);
+#define SSL_SENT_SHUTDOWN 1
+#define SSL_RECEIVED_SHUTDOWN 2
-/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ctx|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
- size_t max_send_fragment);
+/* SSL_get_shutdown returns a bitmask with a subset of |SSL_SENT_SHUTDOWN| and
+ * |SSL_RECEIVED_SHUTDOWN| to query whether close_notify was sent or received,
+ * respectively. */
+OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
-/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ssl|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
- size_t max_send_fragment);
-/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
- * resumption decision for a ClientHello has been made. It can return 1 to
- * allow the handshake to continue or zero to cause the handshake to abort. */
-OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
- SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+/* Deprecated functions. */
+/* SSL_library_init calls |CRYPTO_library_init| and returns one. */
+OPENSSL_EXPORT int SSL_library_init(void);
-/* Deprecated functions. */
+/* SSL_set_reject_peer_renegotiations calls |SSL_set_renegotiate_mode| with
+ * |ssl_never_renegotiate| if |reject| is one and |ssl_renegotiate_freely| if
+ * zero. */
+OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
/* SSL_CIPHER_description writes a description of |cipher| into |buf| and
* returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be
@@ -2784,6 +3045,15 @@ OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp);
OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp,
long length);
+/* i2d_SSL_SESSION_bio serializes |session| and writes the result to |bio|. It
+ * returns the number of bytes written on success and <= 0 on error. */
+OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session);
+
+/* d2i_SSL_SESSION_bio reads a serialized |SSL_SESSION| from |bio| and returns a
+ * newly-allocated |SSL_SESSION| or NULL on error. If |out| is not NULL, it also
+ * frees |*out| and sets |*out| to the new |SSL_SESSION|. */
+OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out);
+
/* ERR_load_SSL_strings does nothing. */
OPENSSL_EXPORT void ERR_load_SSL_strings(void);
@@ -2893,12 +3163,153 @@ OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl);
* For example, "TLSv1.2" or "SSLv3". */
OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl);
+/* SSL_get_cipher_list returns the name of the |n|th cipher in the output of
+ * |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| insteads. */
+OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n);
+
+/* SSL_CTX_set_client_cert_cb sets a callback which is called on the client if
+ * the server requests a client certificate and none is configured. On success,
+ * the callback should return one and set |*out_x509| to |*out_pkey| to a leaf
+ * certificate and private key, respectively, passing ownership. It should
+ * return zero to send no certificate and -1 to fail or pause the handshake. If
+ * the handshake is paused, |SSL_get_error| will return
+ * |SSL_ERROR_WANT_X509_LOOKUP|.
+ *
+ * The callback may call |SSL_get0_certificate_types| and
+ * |SSL_get_client_CA_list| for information on the server's certificate request.
+ *
+ * Use |SSL_CTX_set_cert_cb| instead. Configuring intermediate certificates with
+ * this function is confusing. */
+OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
+ SSL_CTX *ctx,
+ int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey));
+
+/* SSL_CTX_get_client_cert_cb returns the callback set by
+ * |SSL_CTX_set_client_cert_cb|. */
+OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(
+ SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
+
+#define SSL_NOTHING 1
+#define SSL_WRITING 2
+#define SSL_READING 3
+#define SSL_X509_LOOKUP 4
+#define SSL_CHANNEL_ID_LOOKUP 5
+#define SSL_PENDING_SESSION 7
+#define SSL_CERTIFICATE_SELECTION_PENDING 8
+#define SSL_PRIVATE_KEY_OPERATION 9
+
+/* SSL_want returns one of the above values to determine what the most recent
+ * operation on |ssl| was blocked on. Use |SSL_get_error| instead. */
+OPENSSL_EXPORT int SSL_want(const SSL *ssl);
+
+#define SSL_want_nothing(ssl) (SSL_want(ssl) == SSL_NOTHING)
+#define SSL_want_read(ssl) (SSL_want(ssl) == SSL_READING)
+#define SSL_want_write(ssl) (SSL_want(ssl) == SSL_WRITING)
+#define SSL_want_x509_lookup(ssl) (SSL_want(ssl) == SSL_X509_LOOKUP)
+#define SSL_want_channel_id_lookup(ssl) (SSL_want(ssl) == SSL_CHANNEL_ID_LOOKUP)
+#define SSL_want_session(ssl) (SSL_want(ssl) == SSL_PENDING_SESSION)
+#define SSL_want_certificate(ssl) \
+ (SSL_want(ssl) == SSL_CERTIFICATE_SELECTION_PENDING)
+#define SSL_want_private_key_operation(ssl) \
+ (SSL_want(ssl) == SSL_PRIVATE_KEY_OPERATION)
+
+ /* SSL_get_finished writes up to |count| bytes of the Finished message sent by
+ * |ssl| to |buf|. It returns the total untruncated length or zero if none has
+ * been sent yet.
+ *
+ * Use |SSL_get_tls_unique| instead. */
+OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count);
+
+ /* SSL_get_peer_finished writes up to |count| bytes of the Finished message
+ * received from |ssl|'s peer to |buf|. It returns the total untruncated length
+ * or zero if none has been received yet.
+ *
+ * Use |SSL_get_tls_unique| instead. */
+OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf,
+ size_t count);
+
+/* SSL_alert_type_string returns "!". Use |SSL_alert_type_string_long|
+ * instead. */
+OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
+
+/* SSL_alert_desc_string returns "!!". Use |SSL_alert_desc_string_long|
+ * instead. */
+OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
+
+/* SSL_TXT_* expand to strings. */
+#define SSL_TXT_MEDIUM "MEDIUM"
+#define SSL_TXT_HIGH "HIGH"
+#define SSL_TXT_FIPS "FIPS"
+#define SSL_TXT_kRSA "kRSA"
+#define SSL_TXT_kDHE "kDHE"
+#define SSL_TXT_kEDH "kEDH"
+#define SSL_TXT_kECDHE "kECDHE"
+#define SSL_TXT_kEECDH "kEECDH"
+#define SSL_TXT_kPSK "kPSK"
+#define SSL_TXT_aRSA "aRSA"
+#define SSL_TXT_aECDSA "aECDSA"
+#define SSL_TXT_aPSK "aPSK"
+#define SSL_TXT_DH "DH"
+#define SSL_TXT_DHE "DHE"
+#define SSL_TXT_EDH "EDH"
+#define SSL_TXT_RSA "RSA"
+#define SSL_TXT_ECDH "ECDH"
+#define SSL_TXT_ECDHE "ECDHE"
+#define SSL_TXT_EECDH "EECDH"
+#define SSL_TXT_ECDSA "ECDSA"
+#define SSL_TXT_PSK "PSK"
+#define SSL_TXT_3DES "3DES"
+#define SSL_TXT_RC4 "RC4"
+#define SSL_TXT_AES128 "AES128"
+#define SSL_TXT_AES256 "AES256"
+#define SSL_TXT_AES "AES"
+#define SSL_TXT_AES_GCM "AESGCM"
+#define SSL_TXT_CHACHA20 "CHACHA20"
+#define SSL_TXT_MD5 "MD5"
+#define SSL_TXT_SHA1 "SHA1"
+#define SSL_TXT_SHA "SHA"
+#define SSL_TXT_SHA256 "SHA256"
+#define SSL_TXT_SHA384 "SHA384"
+#define SSL_TXT_SSLV3 "SSLv3"
+#define SSL_TXT_TLSV1 "TLSv1"
+#define SSL_TXT_TLSV1_1 "TLSv1.1"
+#define SSL_TXT_TLSV1_2 "TLSv1.2"
+#define SSL_TXT_ALL "ALL"
+#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT"
+
+typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
+
+/* SSL_state returns the current state of the handshake state machine. */
+OPENSSL_EXPORT int SSL_state(const SSL *ssl);
+
+#define SSL_get_state(ssl) SSL_state(ssl)
+
+/* SSL_state_string returns the current state of the handshake state machine as
+ * a six-letter string. Use |SSL_state_string */
+OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl);
+
+/* SSL_set_shutdown causes |ssl| to behave as if the shutdown bitmask (see
+ * |SSL_get_shutdown|) were |mode|. This may be used to skip sending or
+ * receiving close_notify in |SSL_shutdown| by causing the implementation to
+ * believe the events already happened.
+ *
+ * It is an error to use |SSL_set_shutdown| to unset a bit that has already been
+ * set. Doing so will trigger an |assert| in debug builds and otherwise be
+ * ignored.
+ *
+ * Use |SSL_CTX_set_quiet_shutdown| instead. */
+OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode);
+
/* Private structures.
*
* This structures are exposed for historical reasons, but access to them is
* deprecated. */
+typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
+typedef struct ssl3_enc_method SSL3_ENC_METHOD;
+typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
+
struct ssl_cipher_st {
/* name is the OpenSSL name for the cipher. */
const char *name;
@@ -2921,6 +3332,10 @@ struct ssl_cipher_st {
int alg_bits;
};
+#define SSL_MAX_SSL_SESSION_ID_LENGTH 32
+#define SSL_MAX_SID_CTX_LENGTH 32
+#define SSL_MAX_MASTER_KEY_LENGTH 48
+
struct ssl_session_st {
int ssl_version; /* what ssl version session info is being kept in here? */
@@ -3122,7 +3537,7 @@ struct ssl_ctx_st {
void *default_passwd_callback_userdata;
/* get client cert callback */
- int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
/* get channel id callback */
void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey);
@@ -3136,8 +3551,7 @@ struct ssl_ctx_st {
/* Default values used when no per-SSL value is defined follow */
- void (*info_callback)(const SSL *ssl, int type,
- int val); /* used if SSL's info_callback is NULL */
+ void (*info_callback)(const SSL *ssl, int type, int value);
/* what we put in client cert requests */
STACK_OF(X509_NAME) *client_CA;
@@ -3163,9 +3577,6 @@ struct ssl_ctx_st {
int (*default_verify_callback)(
int ok, X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
- /* Default generate session ID callback. */
- GEN_SESSION_CB generate_session_id;
-
X509_VERIFY_PARAM *param;
/* select_certificate_cb is called before most ClientHello processing and
@@ -3382,17 +3793,13 @@ struct ssl_st {
/* This can also be in the session once a session is established */
SSL_SESSION *session;
- /* Default generate session ID callback. */
- GEN_SESSION_CB generate_session_id;
-
/* Used in SSL2 and SSL3 */
int verify_mode; /* 0 don't care about verify failure.
* 1 fail if verify fails */
int (*verify_callback)(int ok,
X509_STORE_CTX *ctx); /* fail if callback returns 0 */
- void (*info_callback)(const SSL *ssl, int type,
- int val); /* optional informational callback */
+ void (*info_callback)(const SSL *ssl, int type, int value);
/* Server-only: psk_identity_hint is the identity hint to send in
* PSK-based key exchanges. */
@@ -3463,9 +3870,8 @@ struct ssl_st {
uint8_t *alpn_client_proto_list;
unsigned alpn_client_proto_list_len;
- /* accept_peer_renegotiations, if one, accepts renegotiation attempts from the
- * peer. Otherwise, they will be rejected with a fatal error. */
- char accept_peer_renegotiations;
+ /* renegotiate_mode controls how peer renegotiation attempts are handled. */
+ enum ssl_renegotiate_mode_t renegotiate_mode;
/* These fields are always NULL and exist only to keep wpa_supplicant happy
* about the change to EVP_AEAD. They are only needed for EAP-FAST, which we
@@ -3474,8 +3880,260 @@ struct ssl_st {
EVP_MD_CTX *read_hash;
};
+typedef struct ssl3_record_st {
+ /* type is the record type. */
+ uint8_t type;
+ /* length is the number of unconsumed bytes of |data|. */
+ uint16_t length;
+ /* off is the number of consumed bytes of |data|. */
+ uint16_t off;
+ /* data is a non-owning pointer to the record contents. The total length of
+ * the buffer is |off| + |length|. */
+ uint8_t *data;
+} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st {
+ /* buf is the memory allocated for this buffer. */
+ uint8_t *buf;
+ /* offset is the offset into |buf| which the buffer contents start at. */
+ uint16_t offset;
+ /* len is the length of the buffer contents from |buf| + |offset|. */
+ uint16_t len;
+ /* cap is how much memory beyond |buf| + |offset| is available. */
+ uint16_t cap;
+} SSL3_BUFFER;
+
+/* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec
+ * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */
+#define SSL3_FLAGS_EXPECT_CCS 0x0080
+
+typedef struct ssl3_state_st {
+ long flags;
+
+ uint8_t read_sequence[8];
+ int read_mac_secret_size;
+ uint8_t read_mac_secret[EVP_MAX_MD_SIZE];
+ uint8_t write_sequence[8];
+ int write_mac_secret_size;
+ uint8_t write_mac_secret[EVP_MAX_MD_SIZE];
+
+ uint8_t server_random[SSL3_RANDOM_SIZE];
+ uint8_t client_random[SSL3_RANDOM_SIZE];
+
+ /* flags for countermeasure against known-IV weakness */
+ int need_record_splitting;
+
+ /* have_version is true if the connection's final version is known. Otherwise
+ * the version has not been negotiated yet. */
+ char have_version;
+
+ /* initial_handshake_complete is true if the initial handshake has
+ * completed. */
+ char initial_handshake_complete;
+
+ /* read_buffer holds data from the transport to be processed. */
+ SSL3_BUFFER read_buffer;
+ /* write_buffer holds data to be written to the transport. */
+ SSL3_BUFFER write_buffer;
+
+ SSL3_RECORD rrec; /* each decoded record goes in here */
+
+ /* storage for Handshake protocol data received but not yet processed by
+ * ssl3_read_bytes: */
+ uint8_t handshake_fragment[4];
+ unsigned int handshake_fragment_len;
+
+ /* partial write - check the numbers match */
+ unsigned int wnum; /* number of bytes sent so far */
+ int wpend_tot; /* number bytes written */
+ int wpend_type;
+ int wpend_ret; /* number of bytes submitted */
+ const uint8_t *wpend_buf;
+
+ /* handshake_buffer, if non-NULL, contains the handshake transcript. */
+ BUF_MEM *handshake_buffer;
+ /* handshake_hash, if initialized with an |EVP_MD|, maintains the handshake
+ * hash. For TLS 1.1 and below, it is the SHA-1 half. */
+ EVP_MD_CTX handshake_hash;
+ /* handshake_md5, if initialized with an |EVP_MD|, maintains the MD5 half of
+ * the handshake hash for TLS 1.1 and below. */
+ EVP_MD_CTX handshake_md5;
+
+ /* this is set whenerver we see a change_cipher_spec message come in when we
+ * are not looking for one */
+ int change_cipher_spec;
+
+ int warn_alert;
+ int fatal_alert;
+ /* we allow one fatal and one warning alert to be outstanding, send close
+ * alert via the warning alert */
+ int alert_dispatch;
+ uint8_t send_alert[2];
+
+ int total_renegotiations;
+
+ /* empty_record_count is the number of consecutive empty records received. */
+ uint8_t empty_record_count;
+
+ /* warning_alert_count is the number of consecutive warning alerts
+ * received. */
+ uint8_t warning_alert_count;
+
+ /* State pertaining to the pending handshake.
+ *
+ * TODO(davidben): State is current spread all over the place. Move
+ * pending handshake state here so it can be managed separately from
+ * established connection state in case of renegotiations. */
+ struct {
+ /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+ uint8_t finish_md[EVP_MAX_MD_SIZE * 2];
+ int finish_md_len;
+ uint8_t peer_finish_md[EVP_MAX_MD_SIZE * 2];
+ int peer_finish_md_len;
+
+ unsigned long message_size;
+ int message_type;
+
+ /* used to hold the new cipher we are going to use */
+ const SSL_CIPHER *new_cipher;
+ DH *dh;
+
+ EC_KEY *ecdh; /* holds short lived ECDH key */
+
+ /* used when SSL_ST_FLUSH_DATA is entered */
+ int next_state;
+
+ int reuse_message;
+
+ union {
+ /* sent is a bitset where the bits correspond to elements of kExtensions
+ * in t1_lib.c. Each bit is set if that extension was sent in a
+ * ClientHello. It's not used by servers. */
+ uint32_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which extensions were received from a client. */
+ uint32_t received;
+ } extensions;
+
+ union {
+ /* sent is a bitset where the bits correspond to elements of
+ * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
+ * extension was sent in a ClientHello. It's not used by servers. */
+ uint16_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which custom extensions were received from a client. The bits here
+ * correspond to |server_custom_extensions|. */
+ uint16_t received;
+ } custom_extensions;
+
+ /* SNI extension */
+
+ /* should_ack_sni is used by a server and indicates that the SNI extension
+ * should be echoed in the ServerHello. */
+ unsigned should_ack_sni:1;
+
+
+ /* Client-only: cert_req determines if a client certificate is to be sent.
+ * This is 0 if no client Certificate message is to be sent, 1 if there is
+ * a client certificate, and 2 to send an empty client Certificate
+ * message. */
+ int cert_req;
+
+ /* Client-only: ca_names contains the list of CAs received in a
+ * CertificateRequest message. */
+ STACK_OF(X509_NAME) *ca_names;
+
+ /* Client-only: certificate_types contains the set of certificate types
+ * received in a CertificateRequest message. */
+ uint8_t *certificate_types;
+ size_t num_certificate_types;
+
+ int key_block_length;
+ uint8_t *key_block;
+
+ const EVP_AEAD *new_aead;
+ uint8_t new_mac_secret_len;
+ uint8_t new_fixed_iv_len;
+ uint8_t new_variable_iv_len;
+
+ /* Server-only: cert_request is true if a client certificate was
+ * requested. */
+ int cert_request;
+
+ /* certificate_status_expected is true if OCSP stapling was negotiated and
+ * the server is expected to send a CertificateStatus message. (This is
+ * used on both the client and server sides.) */
+ unsigned certificate_status_expected:1;
+
+ /* ocsp_stapling_requested is true if a client requested OCSP stapling. */
+ unsigned ocsp_stapling_requested:1;
+
+ /* Server-only: peer_ellipticcurvelist contains the EC curve IDs advertised
+ * by the peer. This is only set on the server's end. The server does not
+ * advertise this extension to the client. */
+ uint16_t *peer_ellipticcurvelist;
+ size_t peer_ellipticcurvelist_length;
+
+ /* extended_master_secret indicates whether the extended master secret
+ * computation is used in this handshake. Note that this is different from
+ * whether it was used for the current session. If this is a resumption
+ * handshake then EMS might be negotiated in the client and server hello
+ * messages, but it doesn't matter if the session that's being resumed
+ * didn't use it to create the master secret initially. */
+ char extended_master_secret;
+
+ /* Client-only: peer_psk_identity_hint is the psk_identity_hint sent by the
+ * server when using a PSK key exchange. */
+ char *peer_psk_identity_hint;
+
+ /* new_mac_secret_size is unused and exists only until wpa_supplicant can
+ * be updated. It is only needed for EAP-FAST, which we don't support. */
+ uint8_t new_mac_secret_size;
+
+ /* Client-only: in_false_start is one if there is a pending handshake in
+ * False Start. The client may write data at this point. */
+ char in_false_start;
+
+ /* peer_dh_tmp, on a client, is the server's DHE public key. */
+ DH *peer_dh_tmp;
+
+ /* peer_ecdh_tmp, on a client, is the server's ECDHE public key. */
+ EC_KEY *peer_ecdh_tmp;
+ } tmp;
+
+ /* Connection binding to prevent renegotiation attacks */
+ uint8_t previous_client_finished[EVP_MAX_MD_SIZE];
+ uint8_t previous_client_finished_len;
+ uint8_t previous_server_finished[EVP_MAX_MD_SIZE];
+ uint8_t previous_server_finished_len;
+ int send_connection_binding; /* TODOEKR */
+
+ /* Set if we saw the Next Protocol Negotiation extension from our peer. */
+ int next_proto_neg_seen;
+
+ /* ALPN information
+ * (we are in the process of transitioning from NPN to ALPN.) */
+
+ /* In a server these point to the selected ALPN protocol after the
+ * ClientHello has been processed. In a client these contain the protocol
+ * that the server selected once the ServerHello has been processed. */
+ uint8_t *alpn_selected;
+ size_t alpn_selected_len;
+
+ /* In a client, this means that the server supported Channel ID and that a
+ * Channel ID was sent. In a server it means that we echoed support for
+ * Channel IDs and that tlsext_channel_id will be valid after the
+ * handshake. */
+ char tlsext_channel_id_valid;
+ /* For a server:
+ * If |tlsext_channel_id_valid| is true, then this contains the
+ * verified Channel ID from the client: a P256 point, (x,y), where
+ * each are big-endian values. */
+ uint8_t tlsext_channel_id[64];
+} SSL3_STATE;
-/* Android compatibility section.
+
+/* Android compatibility section (hidden).
*
* These functions are declared, temporarily, for Android because
* wpa_supplicant will take a little time to sync with upstream. Outside of
@@ -3489,16 +4147,8 @@ OPENSSL_EXPORT int SSL_set_session_secret_cb(SSL *s, void *cb, void *arg);
OPENSSL_EXPORT int SSL_set_session_ticket_ext_cb(SSL *s, void *cb, void *arg);
OPENSSL_EXPORT int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
-#define OPENSSL_VERSION_TEXT "BoringSSL"
-
-#define SSLEAY_VERSION 0
-
-/* SSLeay_version is a compatibility function that returns the string
- * "BoringSSL". */
-OPENSSL_EXPORT const char *SSLeay_version(int unused);
-
-/* Preprocessor compatibility section.
+/* Preprocessor compatibility section (hidden).
*
* Historically, a number of APIs were implemented in OpenSSL as macros and
* constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this
@@ -3635,22 +4285,6 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
} /* extern C */
#endif
-
-/* Library consumers assume these headers are included by ssl.h, but they depend
- * on ssl.h, so include them after all declarations.
- *
- * TODO(davidben): The separation between ssl.h and these version-specific
- * headers introduces circular dependencies and is inconsistent. The function
- * declarations should move to ssl.h. Many of the constants can probably be
- * pruned or unexported. */
-#include <openssl/ssl3.h>
-#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
-
-
-/* BEGIN ERROR CODES */
-/* The following lines are auto generated by the script make_errors.go. Any
- * changes made after this point may be overwritten when the script is next run.
- */
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101
#define SSL_R_BAD_ALERT 102
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 1f6ca31..0d013d5 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -114,19 +114,17 @@
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
-#ifndef HEADER_SSL3_H
-#define HEADER_SSL3_H
+#ifndef OPENSSL_HEADER_SSL3_H
+#define OPENSSL_HEADER_SSL3_H
#include <openssl/aead.h>
-#include <openssl/buf.h>
-#include <openssl/evp.h>
-#include <openssl/ssl.h>
#include <openssl/type_check.h>
#ifdef __cplusplus
extern "C" {
#endif
+
/* These are kept to support clients that negotiates higher protocol versions
* using SSLv2 client hello records. */
#define SSL2_MT_CLIENT_HELLO 1
@@ -297,29 +295,6 @@ OPENSSL_COMPILE_ASSERT(
#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */
#define SSL3_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
-typedef struct ssl3_record_st {
- /* type is the record type. */
- uint8_t type;
- /* length is the number of unconsumed bytes of |data|. */
- uint16_t length;
- /* off is the number of consumed bytes of |data|. */
- uint16_t off;
- /* data is a non-owning pointer to the record contents. The total length of
- * the buffer is |off| + |length|. */
- uint8_t *data;
-} SSL3_RECORD;
-
-typedef struct ssl3_buffer_st {
- /* buf is the memory allocated for this buffer. */
- uint8_t *buf;
- /* offset is the offset into |buf| which the buffer contents start at. */
- uint16_t offset;
- /* len is the length of the buffer contents from |buf| + |offset|. */
- uint16_t len;
- /* cap is how much memory beyond |buf| + |offset| is available. */
- uint16_t cap;
-} SSL3_BUFFER;
-
#define SSL3_CT_RSA_SIGN 1
#define SSL3_CT_DSS_SIGN 2
#define SSL3_CT_RSA_FIXED_DH 3
@@ -328,236 +303,6 @@ typedef struct ssl3_buffer_st {
#define SSL3_CT_DSS_EPHEMERAL_DH 6
#define SSL3_CT_FORTEZZA_DMS 20
-
-/* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec
- * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */
-#define SSL3_FLAGS_EXPECT_CCS 0x0080
-
-typedef struct ssl3_state_st {
- long flags;
-
- uint8_t read_sequence[8];
- int read_mac_secret_size;
- uint8_t read_mac_secret[EVP_MAX_MD_SIZE];
- uint8_t write_sequence[8];
- int write_mac_secret_size;
- uint8_t write_mac_secret[EVP_MAX_MD_SIZE];
-
- uint8_t server_random[SSL3_RANDOM_SIZE];
- uint8_t client_random[SSL3_RANDOM_SIZE];
-
- /* flags for countermeasure against known-IV weakness */
- int need_record_splitting;
-
- /* have_version is true if the connection's final version is known. Otherwise
- * the version has not been negotiated yet. */
- char have_version;
-
- /* initial_handshake_complete is true if the initial handshake has
- * completed. */
- char initial_handshake_complete;
-
- /* read_buffer holds data from the transport to be processed. */
- SSL3_BUFFER read_buffer;
- /* write_buffer holds data to be written to the transport. */
- SSL3_BUFFER write_buffer;
-
- SSL3_RECORD rrec; /* each decoded record goes in here */
-
- /* storage for Handshake protocol data received but not yet processed by
- * ssl3_read_bytes: */
- uint8_t handshake_fragment[4];
- unsigned int handshake_fragment_len;
-
- /* partial write - check the numbers match */
- unsigned int wnum; /* number of bytes sent so far */
- int wpend_tot; /* number bytes written */
- int wpend_type;
- int wpend_ret; /* number of bytes submitted */
- const uint8_t *wpend_buf;
-
- /* handshake_buffer, if non-NULL, contains the handshake transcript. */
- BUF_MEM *handshake_buffer;
- /* handshake_hash, if initialized with an |EVP_MD|, maintains the handshake
- * hash. For TLS 1.1 and below, it is the SHA-1 half. */
- EVP_MD_CTX handshake_hash;
- /* handshake_md5, if initialized with an |EVP_MD|, maintains the MD5 half of
- * the handshake hash for TLS 1.1 and below. */
- EVP_MD_CTX handshake_md5;
-
- /* this is set whenerver we see a change_cipher_spec message come in when we
- * are not looking for one */
- int change_cipher_spec;
-
- int warn_alert;
- int fatal_alert;
- /* we allow one fatal and one warning alert to be outstanding, send close
- * alert via the warning alert */
- int alert_dispatch;
- uint8_t send_alert[2];
-
- int total_renegotiations;
-
- /* empty_record_count is the number of consecutive empty records received. */
- uint8_t empty_record_count;
-
- /* warning_alert_count is the number of consecutive warning alerts
- * received. */
- uint8_t warning_alert_count;
-
- /* State pertaining to the pending handshake.
- *
- * TODO(davidben): State is current spread all over the place. Move
- * pending handshake state here so it can be managed separately from
- * established connection state in case of renegotiations. */
- struct {
- /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
- uint8_t finish_md[EVP_MAX_MD_SIZE * 2];
- int finish_md_len;
- uint8_t peer_finish_md[EVP_MAX_MD_SIZE * 2];
- int peer_finish_md_len;
-
- unsigned long message_size;
- int message_type;
-
- /* used to hold the new cipher we are going to use */
- const SSL_CIPHER *new_cipher;
- DH *dh;
-
- EC_KEY *ecdh; /* holds short lived ECDH key */
-
- /* used when SSL_ST_FLUSH_DATA is entered */
- int next_state;
-
- int reuse_message;
-
- union {
- /* sent is a bitset where the bits correspond to elements of kExtensions
- * in t1_lib.c. Each bit is set if that extension was sent in a
- * ClientHello. It's not used by servers. */
- uint32_t sent;
- /* received is a bitset, like |sent|, but is used by servers to record
- * which extensions were received from a client. */
- uint32_t received;
- } extensions;
-
- union {
- /* sent is a bitset where the bits correspond to elements of
- * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
- * extension was sent in a ClientHello. It's not used by servers. */
- uint16_t sent;
- /* received is a bitset, like |sent|, but is used by servers to record
- * which custom extensions were received from a client. The bits here
- * correspond to |server_custom_extensions|. */
- uint16_t received;
- } custom_extensions;
-
- /* SNI extension */
-
- /* should_ack_sni is used by a server and indicates that the SNI extension
- * should be echoed in the ServerHello. */
- unsigned should_ack_sni:1;
-
-
- /* Client-only: cert_req determines if a client certificate is to be sent.
- * This is 0 if no client Certificate message is to be sent, 1 if there is
- * a client certificate, and 2 to send an empty client Certificate
- * message. */
- int cert_req;
-
- /* Client-only: ca_names contains the list of CAs received in a
- * CertificateRequest message. */
- STACK_OF(X509_NAME) *ca_names;
-
- /* Client-only: certificate_types contains the set of certificate types
- * received in a CertificateRequest message. */
- uint8_t *certificate_types;
- size_t num_certificate_types;
-
- int key_block_length;
- uint8_t *key_block;
-
- const EVP_AEAD *new_aead;
- uint8_t new_mac_secret_len;
- uint8_t new_fixed_iv_len;
- uint8_t new_variable_iv_len;
-
- /* Server-only: cert_request is true if a client certificate was
- * requested. */
- int cert_request;
-
- /* certificate_status_expected is true if OCSP stapling was negotiated and
- * the server is expected to send a CertificateStatus message. (This is
- * used on both the client and server sides.) */
- unsigned certificate_status_expected:1;
-
- /* ocsp_stapling_requested is true if a client requested OCSP stapling. */
- unsigned ocsp_stapling_requested:1;
-
- /* Server-only: peer_ellipticcurvelist contains the EC curve IDs advertised
- * by the peer. This is only set on the server's end. The server does not
- * advertise this extension to the client. */
- uint16_t *peer_ellipticcurvelist;
- size_t peer_ellipticcurvelist_length;
-
- /* extended_master_secret indicates whether the extended master secret
- * computation is used in this handshake. Note that this is different from
- * whether it was used for the current session. If this is a resumption
- * handshake then EMS might be negotiated in the client and server hello
- * messages, but it doesn't matter if the session that's being resumed
- * didn't use it to create the master secret initially. */
- char extended_master_secret;
-
- /* Client-only: peer_psk_identity_hint is the psk_identity_hint sent by the
- * server when using a PSK key exchange. */
- char *peer_psk_identity_hint;
-
- /* new_mac_secret_size is unused and exists only until wpa_supplicant can
- * be updated. It is only needed for EAP-FAST, which we don't support. */
- uint8_t new_mac_secret_size;
-
- /* Client-only: in_false_start is one if there is a pending handshake in
- * False Start. The client may write data at this point. */
- char in_false_start;
-
- /* peer_dh_tmp, on a client, is the server's DHE public key. */
- DH *peer_dh_tmp;
-
- /* peer_ecdh_tmp, on a client, is the server's ECDHE public key. */
- EC_KEY *peer_ecdh_tmp;
- } tmp;
-
- /* Connection binding to prevent renegotiation attacks */
- uint8_t previous_client_finished[EVP_MAX_MD_SIZE];
- uint8_t previous_client_finished_len;
- uint8_t previous_server_finished[EVP_MAX_MD_SIZE];
- uint8_t previous_server_finished_len;
- int send_connection_binding; /* TODOEKR */
-
- /* Set if we saw the Next Protocol Negotiation extension from our peer. */
- int next_proto_neg_seen;
-
- /* ALPN information
- * (we are in the process of transitioning from NPN to ALPN.) */
-
- /* In a server these point to the selected ALPN protocol after the
- * ClientHello has been processed. In a client these contain the protocol
- * that the server selected once the ServerHello has been processed. */
- uint8_t *alpn_selected;
- size_t alpn_selected_len;
-
- /* In a client, this means that the server supported Channel ID and that a
- * Channel ID was sent. In a server it means that we echoed support for
- * Channel IDs and that tlsext_channel_id will be valid after the
- * handshake. */
- char tlsext_channel_id_valid;
- /* For a server:
- * If |tlsext_channel_id_valid| is true, then this contains the
- * verified Channel ID from the client: a P256 point, (x,y), where
- * each are big-endian values. */
- uint8_t tlsext_channel_id[64];
-} SSL3_STATE;
-
/* SSLv3 */
/* client */
/* extra state */
@@ -613,7 +358,6 @@ typedef struct ssl3_state_st {
/* read from client */
#define SSL3_ST_SR_INITIAL_BYTES (0x240 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_V2_CLIENT_HELLO (0x241 | SSL_ST_ACCEPT)
-/* Do not change the number values, they do matter */
#define SSL3_ST_SR_CLNT_HELLO_A (0x110 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_B (0x111 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CLNT_HELLO_C (0x112 | SSL_ST_ACCEPT)
@@ -638,6 +382,7 @@ typedef struct ssl3_state_st {
#define SSL3_ST_SR_CERT_B (0x181 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_KEY_EXCH_A (0x190 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_KEY_EXCH_B (0x191 | SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_C (0x192 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CERT_VRFY_A (0x1A0 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CERT_VRFY_B (0x1A1 | SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE (0x1B0 | SSL_ST_ACCEPT)
@@ -692,6 +437,7 @@ typedef struct ssl3_state_st {
#ifdef __cplusplus
-}
-#endif
+} /* extern C */
#endif
+
+#endif /* OPENSSL_HEADER_SSL3_H */
diff --git a/src/include/openssl/time_support.h b/src/include/openssl/time_support.h
index 912e672..cec430d 100644
--- a/src/include/openssl/time_support.h
+++ b/src/include/openssl/time_support.h
@@ -55,8 +55,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-#ifndef OPENSSL_HEADER_TIME_H
-#define OPENSSL_HEADER_TIME_H
+#ifndef OPENSSL_HEADER_TIME_SUPPORT_H
+#define OPENSSL_HEADER_TIME_SUPPORT_H
#include <openssl/base.h>
@@ -87,4 +87,4 @@ int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
} /* extern C */
#endif
-#endif /* OPENSSL_HEADER_TIME_H */
+#endif /* OPENSSL_HEADER_TIME_SUPPORT_H */
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index 7d16b55..92210f6 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -1,4 +1,3 @@
-/* ssl/tls1.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -148,11 +147,10 @@
* OTHERWISE.
*/
-#ifndef HEADER_TLS1_H
-#define HEADER_TLS1_H
+#ifndef OPENSSL_HEADER_TLS1_H
+#define OPENSSL_HEADER_TLS1_H
-#include <openssl/buf.h>
-#include <openssl/stack.h>
+#include <openssl/base.h>
#ifdef __cplusplus
extern "C" {
@@ -217,10 +215,7 @@ extern "C" {
/* ExtensionType value from RFC7301 */
#define TLSEXT_TYPE_application_layer_protocol_negotiation 16
-/* ExtensionType value for TLS padding extension.
- * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
- * http://tools.ietf.org/html/draft-agl-tls-padding-03
- */
+/* ExtensionType value from RFC7685 */
#define TLSEXT_TYPE_padding 21
/* https://tools.ietf.org/html/draft-ietf-tls-session-hash-01 */
@@ -241,8 +236,6 @@ extern "C" {
/* This is not an IANA defined extension number */
#define TLSEXT_TYPE_channel_id 30032
-/* NameType value from RFC 3546 */
-#define TLSEXT_NAMETYPE_host_name 0
/* status request value from RFC 3546 */
#define TLSEXT_STATUSTYPE_ocsp 1
@@ -277,42 +270,6 @@ extern "C" {
#define TLSEXT_MAXLEN_host_name 255
-OPENSSL_EXPORT const char *SSL_get_servername(const SSL *s, const int type);
-OPENSSL_EXPORT int SSL_get_servername_type(const SSL *s);
-
-/* SSL_export_keying_material exports a value derived from the master secret, as
- * specified in RFC 5705. It writes |out_len| bytes to |out| given a label and
- * optional context. (Since a zero length context is allowed, the |use_context|
- * flag controls whether a context is included.)
- *
- * It returns one on success and zero otherwise. */
-OPENSSL_EXPORT int SSL_export_keying_material(
- SSL *s, uint8_t *out, size_t out_len, const char *label, size_t label_len,
- const uint8_t *context, size_t context_len, int use_context);
-
-/* SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name|
- * in the server_name extension. It returns one on success and zero on error. */
-OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name);
-
-/* SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on
- * the server after ClientHello extensions have been parsed and returns one.
- * |callback| may use |SSL_get_servername| to examine the server_name extension
- * and return a |SSL_TLSEXT_ERR_*| value. If it returns |SSL_TLSEXT_ERR_NOACK|,
- * the server_name extension is not acknowledged in the ServerHello. If the
- * return value signals an alert, |callback| should set |*out_alert| to the
- * alert to send. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback(
- SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg));
-
-#define SSL_TLSEXT_ERR_OK 0
-#define SSL_TLSEXT_ERR_ALERT_WARNING 1
-#define SSL_TLSEXT_ERR_ALERT_FATAL 2
-#define SSL_TLSEXT_ERR_NOACK 3
-
-/* SSL_CTX_set_tlsext_servername_arg sets the argument to the servername
- * callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
-
/* PSK ciphersuites from 4279 */
#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A
#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B
@@ -470,8 +427,15 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
#define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031
#define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032
-#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CC13
-#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CC14
+#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD 0x0300CC13
+#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD 0x0300CC14
+
+/* TODO(davidben): Remove these once WebRTC is no longer using them, so they
+ * may point to the future RFC 7539 variant. */
+#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 \
+ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD
+#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 \
+ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD
/* XXX
* Inconsistency alert:
@@ -633,10 +597,14 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
#define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256"
#define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384"
-#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305"
-#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 \
+#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD \
+ "ECDHE-RSA-CHACHA20-POLY1305"
+#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD \
"ECDHE-ECDSA-CHACHA20-POLY1305"
-#define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305"
+
+/* TODO(davidben): Remove this once QUIC has switched to the '_OLD' name. */
+#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 \
+ TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
@@ -666,6 +634,7 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
#ifdef __cplusplus
-}
-#endif
+} /* extern C */
#endif
+
+#endif /* OPENSSL_HEADER_TLS1_H */
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index f6b3af0..da569e8 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -1,4 +1,3 @@
-/* crypto/x509/x509.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index 146e047..c11820b 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -1,4 +1,3 @@
-/* crypto/x509/x509_vfy.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index 2785dcf..a5ad126 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -31,7 +31,6 @@ add_library(
ssl_rsa.c
ssl_session.c
ssl_stat.c
- ssl_txt.c
t1_enc.c
t1_lib.c
tls_record.c
@@ -39,6 +38,8 @@ add_library(
$<TARGET_OBJECTS:pqueue>
)
+target_link_libraries(ssl crypto)
+
add_executable(
ssl_test
@@ -48,3 +49,4 @@ add_executable(
)
target_link_libraries(ssl_test ssl crypto)
+add_dependencies(all_tests ssl_test)
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index 1acb3ce..4d550e9 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -399,7 +399,7 @@ static int dtls1_discard_fragment_body(SSL *s, size_t frag_len) {
while (frag_len > 0) {
size_t chunk = frag_len < sizeof(discard) ? frag_len : sizeof(discard);
int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, discard, chunk, 0);
- if (ret != chunk) {
+ if (ret != (int) chunk) {
return 0;
}
frag_len -= chunk;
@@ -525,7 +525,7 @@ static int dtls1_process_fragment(SSL *s) {
/* Read the body of the fragment. */
ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment + frag_off,
frag_len, 0);
- if (ret != frag_len) {
+ if (ret != (int) frag_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return -1;
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index 73a3f8a..3dd5f8c 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -135,7 +135,7 @@ static int dtls1_get_hello_verify(SSL *s);
int dtls1_connect(SSL *s) {
BUF_MEM *buf = NULL;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
int ret = -1;
int new_state, state, skip = 0;
diff --git a/src/ssl/d1_meth.c b/src/ssl/d1_meth.c
index d54a037..4dc3404 100644
--- a/src/ssl/d1_meth.c
+++ b/src/ssl/d1_meth.c
@@ -1,4 +1,3 @@
-/* ssl/d1_meth.h */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index e2d505c..a31dcc3 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -228,7 +228,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) {
int al, i, ret;
unsigned int n;
SSL3_RECORD *rr;
- void (*cb)(const SSL *ssl, int type2, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) ||
(peek && type != SSL3_RT_APPLICATION_DATA)) {
@@ -557,7 +557,7 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
int dtls1_dispatch_alert(SSL *s) {
int i, j;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
uint8_t buf[DTLS1_AL_HEADER_LENGTH];
uint8_t *ptr = &buf[0];
diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.c
index 2fcc1ea..628bb29 100644
--- a/src/ssl/d1_srtp.c
+++ b/src/ssl/d1_srtp.c
@@ -171,7 +171,8 @@ static int ssl_ctx_make_profiles(const char *profiles_string,
const SRTP_PROTECTION_PROFILE *p;
col = strchr(ptr, ':');
- if (find_profile_by_name(ptr, &p, col ? col - ptr : strlen(ptr))) {
+ if (find_profile_by_name(ptr, &p,
+ col ? (size_t)(col - ptr) : strlen(ptr))) {
sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index 89c26aa..f1e8826 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -132,7 +132,7 @@
int dtls1_accept(SSL *s) {
BUF_MEM *buf = NULL;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
uint32_t alg_a;
int ret = -1;
int new_state, state, skip = 0;
@@ -330,6 +330,7 @@ int dtls1_accept(SSL *s) {
case SSL3_ST_SR_KEY_EXCH_A:
case SSL3_ST_SR_KEY_EXCH_B:
+ case SSL3_ST_SR_KEY_EXCH_C:
ret = ssl3_get_client_key_exchange(s);
if (ret <= 0) {
goto end;
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 6fb8dbe..76a31bf 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -181,7 +181,7 @@
#define SSL_AES256 0x00000008L
#define SSL_AES128GCM 0x00000010L
#define SSL_AES256GCM 0x00000020L
-#define SSL_CHACHA20POLY1305 0x00000040L
+#define SSL_CHACHA20POLY1305_OLD 0x00000040L
#define SSL_eNULL 0x00000080L
#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
@@ -464,6 +464,13 @@ enum ssl_private_key_result_t ssl_private_key_sign(
enum ssl_private_key_result_t ssl_private_key_sign_complete(
SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out);
+enum ssl_private_key_result_t ssl_private_key_decrypt(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len);
+
+enum ssl_private_key_result_t ssl_private_key_decrypt_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out);
+
/* Custom extensions */
@@ -957,7 +964,7 @@ CERT *ssl_cert_new(void);
CERT *ssl_cert_dup(CERT *cert);
void ssl_cert_clear_certs(CERT *c);
void ssl_cert_free(CERT *c);
-int ssl_get_new_session(SSL *s, int session);
+int ssl_get_new_session(SSL *ssl, int is_server);
enum ssl_session_result_t {
ssl_session_success,
@@ -976,7 +983,6 @@ enum ssl_session_result_t ssl_get_prev_session(
const struct ssl_early_callback_ctx *ctx);
STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
-int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p);
struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
struct ssl_cipher_preference_list_st *cipher_list);
void ssl_cipher_preference_list_free(
@@ -994,7 +1000,7 @@ void ssl_cert_set_cert_cb(CERT *cert,
int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
int ssl_add_cert_chain(SSL *s, unsigned long *l);
-void ssl_update_cache(SSL *s, int mode);
+void ssl_update_cache(SSL *ssl, int mode);
/* ssl_get_compatible_server_ciphers determines the key exchange and
* authentication cipher suite masks compatible with the server configuration
@@ -1104,7 +1110,7 @@ unsigned int dtls1_min_mtu(void);
void dtls1_hm_fragment_free(hm_fragment *frag);
/* some client-only functions */
-int ssl3_send_client_hello(SSL *s);
+int ssl3_send_client_hello(SSL *ssl);
int ssl3_get_server_hello(SSL *s);
int ssl3_get_certificate_request(SSL *s);
int ssl3_get_new_session_ticket(SSL *s);
@@ -1116,15 +1122,15 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
int ssl3_send_client_key_exchange(SSL *s);
int ssl3_get_server_key_exchange(SSL *s);
int ssl3_get_server_certificate(SSL *s);
-int ssl3_send_next_proto(SSL *s);
-int ssl3_send_channel_id(SSL *s);
+int ssl3_send_next_proto(SSL *ssl);
+int ssl3_send_channel_id(SSL *ssl);
int ssl3_verify_server_cert(SSL *s);
/* some server-only functions */
int ssl3_get_initial_bytes(SSL *s);
int ssl3_get_v2_client_hello(SSL *s);
int ssl3_get_client_hello(SSL *s);
-int ssl3_send_server_hello(SSL *s);
+int ssl3_send_server_hello(SSL *ssl);
int ssl3_send_server_key_exchange(SSL *s);
int ssl3_send_certificate_request(SSL *s);
int ssl3_send_server_done(SSL *s);
@@ -1208,10 +1214,14 @@ int tls1_check_ec_tmp_key(SSL *s);
int tls1_shared_list(SSL *s, const uint8_t *l1, size_t l1len, const uint8_t *l2,
size_t l2len, int nmatch);
-uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *const buf,
- uint8_t *const limit, size_t header_len);
-uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *const buf,
- uint8_t *const limit);
+
+/* ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It
+ * returns one on success and zero on failure. The |header_len| argument is the
+ * length of the ClientHello written so far and is used to compute the padding
+ * length. (It does not include the record header.) */
+int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len);
+
+int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out);
int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs);
int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs);
diff --git a/src/ssl/pqueue/CMakeLists.txt b/src/ssl/pqueue/CMakeLists.txt
index 53d2a8b..3a8b82b 100644
--- a/src/ssl/pqueue/CMakeLists.txt
+++ b/src/ssl/pqueue/CMakeLists.txt
@@ -17,3 +17,4 @@ add_executable(
)
target_link_libraries(pqueue_test ssl crypto)
+add_dependencies(all_tests pqueue_test)
diff --git a/src/ssl/pqueue/pqueue_test.c b/src/ssl/pqueue/pqueue_test.c
index 5a68fc4..f76e4a3 100644
--- a/src/ssl/pqueue/pqueue_test.c
+++ b/src/ssl/pqueue/pqueue_test.c
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
+#include <openssl/crypto.h>
#include <openssl/pqueue.h>
#include <openssl/ssl.h>
@@ -117,7 +118,7 @@ static int fixed_random(void) {
}
int main(void) {
- SSL_library_init();
+ CRYPTO_library_init();
if (!trivial() || !fixed_random()) {
return 1;
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index 559db72..13bc0e8 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -1,4 +1,3 @@
-/* ssl/s3_clnt.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -175,7 +174,7 @@
int ssl3_connect(SSL *s) {
BUF_MEM *buf = NULL;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
int ret = -1;
int new_state, state, skip = 0;
@@ -589,140 +588,140 @@ end:
return ret;
}
-int ssl3_send_client_hello(SSL *s) {
- uint8_t *buf, *p, *d;
- int i;
- unsigned long l;
-
- buf = (uint8_t *)s->init_buf->data;
- if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
- if (!s->s3->have_version) {
- uint16_t max_version = ssl3_get_max_client_version(s);
- /* Disabling all versions is silly: return an error. */
- if (max_version == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
- goto err;
- }
- s->version = max_version;
- s->client_version = max_version;
- }
+static int ssl3_write_client_cipher_list(SSL *ssl, CBB *out) {
+ /* Prepare disabled cipher masks. */
+ ssl_set_client_disabled(ssl);
- /* If the configured session was created at a version higher than our
- * maximum version, drop it. */
- if (s->session &&
- (s->session->session_id_length == 0 || s->session->not_resumable ||
- (!SSL_IS_DTLS(s) && s->session->ssl_version > s->version) ||
- (SSL_IS_DTLS(s) && s->session->ssl_version < s->version))) {
- SSL_set_session(s, NULL);
- }
+ CBB child;
+ if (!CBB_add_u16_length_prefixed(out, &child)) {
+ return 0;
+ }
- /* else use the pre-loaded session */
- p = s->s3->client_random;
+ STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl);
- /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
- * renegerate the client_random. The random must be reused. */
- if ((!SSL_IS_DTLS(s) || !s->d1->send_cookie) &&
- !ssl_fill_hello_random(p, sizeof(s->s3->client_random),
- 0 /* client */)) {
- goto err;
+ int any_enabled = 0;
+ size_t i;
+ for (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_ssl & ssl->cert->mask_ssl ||
+ cipher->algorithm_mkey & ssl->cert->mask_k ||
+ cipher->algorithm_auth & ssl->cert->mask_a) {
+ continue;
}
+ any_enabled = 1;
+ if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) {
+ return 0;
+ }
+ }
- /* Do the message type and length last. Note: the final argument to
- * ssl_add_clienthello_tlsext below depends on the size of this prefix. */
- d = p = ssl_handshake_start(s);
+ /* If all ciphers were disabled, return the error to the caller. */
+ if (!any_enabled) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE);
+ return 0;
+ }
- /* version indicates the negotiated version: for example from an SSLv2/v3
- * compatible client hello). The client_version field is the maximum
- * version we permit and it is also used in RSA encrypted premaster
- * secrets. Some servers can choke if we initially report a higher version
- * then renegotiate to a lower one in the premaster secret. This didn't
- * happen with TLS 1.0 as most servers supported it but it can with TLS 1.1
- * or later if the server only supports 1.0.
- *
- * Possible scenario with previous logic:
- * 1. Client hello indicates TLS 1.2
- * 2. Server hello says TLS 1.0
- * 3. RSA encrypted premaster secret uses 1.2.
- * 4. Handhaked proceeds using TLS 1.0.
- * 5. Server sends hello request to renegotiate.
- * 6. Client hello indicates TLS v1.0 as we now
- * know that is maximum server supports.
- * 7. Server chokes on RSA encrypted premaster secret
- * containing version 1.0.
- *
- * For interoperability it should be OK to always use the maximum version
- * we support in client hello and then rely on the checking of version to
- * ensure the servers isn't being inconsistent: for example initially
- * negotiating with TLS 1.0 and renegotiating with TLS 1.2. We do this by
- * using client_version in client hello and not resetting it to the
- * negotiated version. */
- *(p++) = s->client_version >> 8;
- *(p++) = s->client_version & 0xff;
-
- /* Random stuff */
- memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
- p += SSL3_RANDOM_SIZE;
-
- /* Session ID */
- if (s->s3->initial_handshake_complete || s->session == NULL) {
- /* Renegotiations do not participate in session resumption. */
- i = 0;
- } else {
- i = s->session->session_id_length;
- }
- *(p++) = i;
- if (i != 0) {
- if (i > (int)sizeof(s->session->session_id)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- memcpy(p, s->session->session_id, i);
- p += i;
+ /* For SSLv3, the SCSV is added. Otherwise the renegotiation extension is
+ * added. */
+ if (ssl->client_version == SSL3_VERSION &&
+ !ssl->s3->initial_handshake_complete) {
+ if (!CBB_add_u16(&child, SSL3_CK_SCSV & 0xffff)) {
+ return 0;
}
+ /* The renegotiation extension is required to be at index zero. */
+ ssl->s3->tmp.extensions.sent |= (1u << 0);
+ }
- /* cookie stuff for DTLS */
- if (SSL_IS_DTLS(s)) {
- if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- *(p++) = s->d1->cookie_len;
- memcpy(p, s->d1->cookie, s->d1->cookie_len);
- p += s->d1->cookie_len;
- }
+ if ((ssl->mode & SSL_MODE_SEND_FALLBACK_SCSV) &&
+ !CBB_add_u16(&child, SSL3_CK_FALLBACK_SCSV & 0xffff)) {
+ return 0;
+ }
- /* Ciphers supported */
- i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
- if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE);
- goto err;
- }
- s2n(i, p);
- p += i;
+ return CBB_flush(out);
+}
- /* COMPRESSION */
- *(p++) = 1;
- *(p++) = 0; /* Add the NULL method */
+int ssl3_send_client_hello(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_CLNT_HELLO_B) {
+ return ssl_do_write(ssl);
+ }
- /* TLS extensions*/
- p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH,
- p - buf);
- if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB cbb;
+ CBB_zero(&cbb);
+
+ assert(ssl->state == SSL3_ST_CW_CLNT_HELLO_A);
+ if (!ssl->s3->have_version) {
+ uint16_t max_version = ssl3_get_max_client_version(ssl);
+ /* Disabling all versions is silly: return an error. */
+ if (max_version == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
goto err;
}
- l = p - d;
- if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l)) {
+ ssl->version = max_version;
+ /* Only set |ssl->client_version| on the initial handshake. Renegotiations,
+ * although locked to a version, reuse the value. When using the plain RSA
+ * key exchange, the ClientHello version is checked in the premaster secret.
+ * Some servers fail when this value changes. */
+ ssl->client_version = max_version;
+ }
+
+ /* If the configured session has expired or was created at a version higher
+ * than our maximum version, drop it. */
+ if (ssl->session != NULL &&
+ (ssl->session->session_id_length == 0 || ssl->session->not_resumable ||
+ ssl->session->timeout < (long)(time(NULL) - ssl->session->time) ||
+ (!SSL_IS_DTLS(ssl) && ssl->session->ssl_version > ssl->version) ||
+ (SSL_IS_DTLS(ssl) && ssl->session->ssl_version < ssl->version))) {
+ SSL_set_session(ssl, NULL);
+ }
+
+ /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't
+ * renegerate the client_random. The random must be reused. */
+ if ((!SSL_IS_DTLS(ssl) || !ssl->d1->send_cookie) &&
+ !ssl_fill_hello_random(ssl->s3->client_random,
+ sizeof(ssl->s3->client_random), 0 /* client */)) {
+ goto err;
+ }
+
+ /* Renegotiations do not participate in session resumption. */
+ int has_session = ssl->session != NULL &&
+ !ssl->s3->initial_handshake_complete;
+
+ CBB child;
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u16(&cbb, ssl->client_version) ||
+ !CBB_add_bytes(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ (has_session &&
+ !CBB_add_bytes(&child, ssl->session->session_id,
+ ssl->session->session_id_length))) {
+ goto err;
+ }
+
+ if (SSL_IS_DTLS(ssl)) {
+ if (!CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) {
goto err;
}
- s->state = SSL3_ST_CW_CLNT_HELLO_B;
}
- /* SSL3_ST_CW_CLNT_HELLO_B */
- return ssl_do_write(s);
+ size_t length;
+ if (!ssl3_write_client_cipher_list(ssl, &cbb) ||
+ !CBB_add_u8(&cbb, 1 /* one compression method */) ||
+ !CBB_add_u8(&cbb, 0 /* null compression */) ||
+ !ssl_add_clienthello_tlsext(ssl, &cbb,
+ CBB_len(&cbb) + SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_CLIENT_HELLO, length)) {
+ goto err;
+ }
+
+ ssl->state = SSL3_ST_CW_CLNT_HELLO_B;
+ return ssl_do_write(ssl);
err:
+ CBB_cleanup(&cbb);
return -1;
}
@@ -813,7 +812,7 @@ int ssl3_get_server_hello(SSL *s) {
/* The session wasn't resumed. Create a fresh SSL_SESSION to
* fill out. */
s->hit = 0;
- if (!ssl_get_new_session(s, 0)) {
+ if (!ssl_get_new_session(s, 0 /* client */)) {
goto f_err;
}
/* Note: session_id could be empty. */
@@ -1429,10 +1428,7 @@ err:
int ssl3_get_new_session_ticket(SSL *s) {
int ok, al;
- long n;
- CBS new_session_ticket, ticket;
-
- n = s->method->ssl_get_message(
+ long n = s->method->ssl_get_message(
s, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B,
SSL3_MT_NEWSESSION_TICKET, 16384, ssl_hash_message, &ok);
@@ -1440,6 +1436,24 @@ int ssl3_get_new_session_ticket(SSL *s) {
return n;
}
+ CBS new_session_ticket, ticket;
+ uint32_t ticket_lifetime_hint;
+ CBS_init(&new_session_ticket, s->init_msg, n);
+ if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) ||
+ !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
+ CBS_len(&new_session_ticket) != 0) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ goto f_err;
+ }
+
+ if (CBS_len(&ticket) == 0) {
+ /* RFC 5077 allows a server to change its mind and send no ticket after
+ * negotiating the extension. Behave as if no ticket was sent. */
+ s->tlsext_ticket_expected = 0;
+ return 1;
+ }
+
if (s->hit) {
/* The server is sending a new ticket for an existing session. Sessions are
* immutable once established, so duplicate all but the ticket of the
@@ -1461,22 +1475,12 @@ int ssl3_get_new_session_ticket(SSL *s) {
s->session = new_session;
}
- CBS_init(&new_session_ticket, s->init_msg, n);
-
- if (!CBS_get_u32(&new_session_ticket,
- &s->session->tlsext_tick_lifetime_hint) ||
- !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
- CBS_len(&new_session_ticket) != 0) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto f_err;
- }
-
if (!CBS_stow(&ticket, &s->session->tlsext_tick,
&s->session->tlsext_ticklen)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
+ s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
/* Generate a session ID for this session based on the session ticket. We use
* the session ID mechanism for detecting ticket resumption. This also fits in
@@ -1562,6 +1566,8 @@ int ssl3_get_server_done(SSL *s) {
return 1;
}
+OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),
+ SIZE_T_IS_SMALLER_THAN_UNSIGNED);
int ssl3_send_client_key_exchange(SSL *s) {
uint8_t *p;
@@ -1735,7 +1741,7 @@ int ssl3_send_client_key_exchange(SSL *s) {
} else if (alg_k & SSL_kECDHE) {
const EC_GROUP *srvr_group = NULL;
EC_KEY *tkey;
- int field_size = 0, ecdh_len;
+ int ecdh_len;
if (s->s3->tmp.peer_ecdh_tmp == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1768,8 +1774,8 @@ int ssl3_send_client_key_exchange(SSL *s) {
goto err;
}
- field_size = EC_GROUP_get_degree(srvr_group);
- if (field_size <= 0) {
+ unsigned field_size = EC_GROUP_get_degree(srvr_group);
+ if (field_size == 0) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
@@ -2068,93 +2074,88 @@ int ssl3_send_client_certificate(SSL *s) {
return ssl_do_write(s);
}
-int ssl3_send_next_proto(SSL *s) {
- unsigned int len, padding_len;
- uint8_t *d, *p;
+int ssl3_send_next_proto(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_NEXT_PROTO_B) {
+ return ssl_do_write(ssl);
+ }
- if (s->state == SSL3_ST_CW_NEXT_PROTO_A) {
- len = s->next_proto_negotiated_len;
- padding_len = 32 - ((len + 2) % 32);
+ assert(ssl->state == SSL3_ST_CW_NEXT_PROTO_A);
- d = p = ssl_handshake_start(s);
- *(p++) = len;
- memcpy(p, s->next_proto_negotiated, len);
- p += len;
- *(p++) = padding_len;
- memset(p, 0, padding_len);
- p += padding_len;
+ static const uint8_t kZero[32] = {0};
+ size_t padding_len = 32 - ((ssl->next_proto_negotiated_len + 2) % 32);
- if (!ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d)) {
- return -1;
- }
- s->state = SSL3_ST_CW_NEXT_PROTO_B;
+ CBB cbb, child;
+ size_t length;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, ssl->next_proto_negotiated,
+ ssl->next_proto_negotiated_len) ||
+ !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_bytes(&child, kZero, padding_len) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_NEXT_PROTO, length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&cbb);
+ return -1;
}
- return ssl_do_write(s);
+ ssl->state = SSL3_ST_CW_NEXT_PROTO_B;
+ return ssl_do_write(ssl);
}
-int ssl3_send_channel_id(SSL *s) {
- uint8_t *d;
- int ret = -1, public_key_len;
- EVP_MD_CTX md_ctx;
- ECDSA_SIG *sig = NULL;
- uint8_t *public_key = NULL, *derp, *der_sig = NULL;
+static int write_32_byte_big_endian(CBB *out, const BIGNUM *in) {
+ uint8_t *ptr;
+ return CBB_add_space(out, &ptr, 32) &&
+ BN_bn2bin_padded(ptr, 32, in);
+}
- if (s->state != SSL3_ST_CW_CHANNEL_ID_A) {
- return ssl_do_write(s);
+int ssl3_send_channel_id(SSL *ssl) {
+ if (ssl->state == SSL3_ST_CW_CHANNEL_ID_B) {
+ return ssl_do_write(ssl);
}
- if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb) {
+ assert(ssl->state == SSL3_ST_CW_CHANNEL_ID_A);
+
+ if (ssl->tlsext_channel_id_private == NULL &&
+ ssl->ctx->channel_id_cb != NULL) {
EVP_PKEY *key = NULL;
- s->ctx->channel_id_cb(s, &key);
- if (key != NULL) {
- s->tlsext_channel_id_private = key;
+ ssl->ctx->channel_id_cb(ssl, &key);
+ if (key != NULL &&
+ !SSL_set1_tls_channel_id(ssl, key)) {
+ EVP_PKEY_free(key);
+ return -1;
}
+ EVP_PKEY_free(key);
}
- if (!s->tlsext_channel_id_private) {
- s->rwstate = SSL_CHANNEL_ID_LOOKUP;
+ if (ssl->tlsext_channel_id_private == NULL) {
+ ssl->rwstate = SSL_CHANNEL_ID_LOOKUP;
return -1;
}
- s->rwstate = SSL_NOTHING;
+ ssl->rwstate = SSL_NOTHING;
- if (EVP_PKEY_id(s->tlsext_channel_id_private) != EVP_PKEY_EC) {
+ if (EVP_PKEY_id(ssl->tlsext_channel_id_private) != EVP_PKEY_EC) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
- EC_KEY *ec_key = s->tlsext_channel_id_private->pkey.ec;
-
- d = ssl_handshake_start(s);
- s2n(TLSEXT_TYPE_channel_id, d);
- s2n(TLSEXT_CHANNEL_ID_SIZE, d);
-
- EVP_MD_CTX_init(&md_ctx);
-
- public_key_len = i2o_ECPublicKey(ec_key, NULL);
- if (public_key_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
- goto err;
- }
- /* i2o_ECPublicKey will produce an ANSI X9.62 public key which, for a
- * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
- * field elements as 32-byte, big-endian numbers. */
- if (public_key_len != 65) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
- goto err;
- }
- public_key = OPENSSL_malloc(public_key_len);
- if (!public_key) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ int ret = -1;
+ EC_KEY *ec_key = ssl->tlsext_channel_id_private->pkey.ec;
+ BIGNUM *x = BN_new();
+ BIGNUM *y = BN_new();
+ ECDSA_SIG *sig = NULL;
+ if (x == NULL || y == NULL ||
+ !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key),
+ EC_KEY_get0_public_key(ec_key),
+ x, y, NULL)) {
goto err;
}
- derp = public_key;
- i2o_ECPublicKey(ec_key, &derp);
-
uint8_t digest[EVP_MAX_MD_SIZE];
size_t digest_len;
- if (!tls1_channel_id_hash(s, digest, &digest_len)) {
+ if (!tls1_channel_id_hash(ssl, digest, &digest_len)) {
goto err;
}
@@ -2163,38 +2164,39 @@ int ssl3_send_channel_id(SSL *s) {
goto err;
}
- /* The first byte of public_key will be 0x4, denoting an uncompressed key. */
- memcpy(d, public_key + 1, 64);
- d += 64;
- if (!BN_bn2bin_padded(d, 32, sig->r) ||
- !BN_bn2bin_padded(d + 32, 32, sig->s)) {
+ CBB cbb, child;
+ size_t length;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u16(&cbb, TLSEXT_TYPE_channel_id) ||
+ !CBB_add_u16_length_prefixed(&cbb, &child) ||
+ !write_32_byte_big_endian(&child, x) ||
+ !write_32_byte_big_endian(&child, y) ||
+ !write_32_byte_big_endian(&child, sig->r) ||
+ !write_32_byte_big_endian(&child, sig->s) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS, length)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&cbb);
goto err;
}
- if (!ssl_set_handshake_header(s, SSL3_MT_ENCRYPTED_EXTENSIONS,
- 2 + 2 + TLSEXT_CHANNEL_ID_SIZE)) {
- goto err;
- }
- s->state = SSL3_ST_CW_CHANNEL_ID_B;
-
- ret = ssl_do_write(s);
+ ssl->state = SSL3_ST_CW_CHANNEL_ID_B;
+ ret = ssl_do_write(ssl);
err:
- EVP_MD_CTX_cleanup(&md_ctx);
- OPENSSL_free(public_key);
- OPENSSL_free(der_sig);
+ BN_free(x);
+ BN_free(y);
ECDSA_SIG_free(sig);
-
return ret;
}
-int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) {
- int i = 0;
- if (s->ctx->client_cert_cb) {
- i = s->ctx->client_cert_cb(s, px509, ppkey);
+int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) {
+ if (ssl->ctx->client_cert_cb == NULL) {
+ return 0;
}
- return i;
+ return ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey);
}
int ssl3_verify_server_cert(SSL *s) {
diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c
index f1924c0..aa0d717 100644
--- a/src/ssl/s3_enc.c
+++ b/src/ssl/s3_enc.c
@@ -334,7 +334,7 @@ int ssl3_final_finish_mac(SSL *s, const char *sender, int len, uint8_t *p) {
static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
uint8_t *p) {
unsigned int ret;
- int npad, n;
+ size_t npad, n;
unsigned int i;
uint8_t md_buf[EVP_MAX_MD_SIZE];
EVP_MD_CTX ctx;
@@ -357,9 +357,6 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
}
n = EVP_MD_CTX_size(&ctx);
- if (n < 0) {
- return 0;
- }
npad = (48 / n) * n;
if (sender != NULL) {
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 617ea6e..5209802 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -335,14 +335,17 @@ int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) {
}
int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) {
- ssl->tlsext_channel_id_enabled = 1;
if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
- EVP_PKEY_bits(private_key) != 256) {
+ EC_GROUP_get_curve_name(EC_KEY_get0_group(private_key->pkey.ec)) !=
+ NID_X9_62_prime256v1) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
}
+
EVP_PKEY_free(ssl->tlsext_channel_id_private);
ssl->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key);
+ ssl->tlsext_channel_id_enabled = 1;
+
return 1;
}
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 3c2435d..1cb2ac6 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -337,6 +337,20 @@ void ssl3_read_close_notify(SSL *ssl) {
ssl3_read_bytes(ssl, 0, NULL, 0, 0);
}
+static int ssl3_can_renegotiate(SSL *ssl) {
+ switch (ssl->renegotiate_mode) {
+ case ssl_renegotiate_never:
+ return 0;
+ case ssl_renegotiate_once:
+ return ssl->s3->total_renegotiations == 0;
+ case ssl_renegotiate_freely:
+ return 1;
+ }
+
+ assert(0);
+ return 0;
+}
+
/* Return up to 'len' payload bytes received in 'type' records.
* 'type' is one of the following:
*
@@ -368,7 +382,7 @@ int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) {
int al, i, ret;
unsigned int n;
SSL3_RECORD *rr;
- void (*cb)(const SSL *ssl, int type2, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
if ((type && type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) ||
(peek && type != SSL3_RT_APPLICATION_DATA)) {
@@ -509,7 +523,7 @@ start:
if (rr->type == SSL3_RT_HANDSHAKE) {
/* If peer renegotiations are disabled, all out-of-order handshake records
* are fatal. Renegotiations as a server are never supported. */
- if (!s->accept_peer_renegotiations || s->server) {
+ if (s->server || !ssl3_can_renegotiate(s)) {
al = SSL_AD_NO_RENEGOTIATION;
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
goto f_err;
@@ -563,6 +577,7 @@ start:
}
/* Begin a new handshake. */
+ s->s3->total_renegotiations++;
s->state = SSL_ST_CONNECT;
i = s->handshake_func(s);
if (i < 0) {
@@ -771,7 +786,7 @@ int ssl3_send_alert(SSL *s, int level, int desc) {
int ssl3_dispatch_alert(SSL *s) {
int i, j;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
s->s3->alert_dispatch = 0;
i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2);
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c
index b428043..fad2d0a 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -177,7 +177,7 @@
int ssl3_accept(SSL *s) {
BUF_MEM *buf = NULL;
uint32_t alg_a;
- void (*cb)(const SSL *ssl, int type, int val) = NULL;
+ void (*cb)(const SSL *ssl, int type, int value) = NULL;
int ret = -1;
int new_state, state, skip = 0;
@@ -399,6 +399,7 @@ int ssl3_accept(SSL *s) {
case SSL3_ST_SR_KEY_EXCH_A:
case SSL3_ST_SR_KEY_EXCH_B:
+ case SSL3_ST_SR_KEY_EXCH_C:
ret = ssl3_get_client_key_exchange(s);
if (ret <= 0) {
goto end;
@@ -482,7 +483,7 @@ int ssl3_accept(SSL *s) {
/* If this is a full handshake with ChannelID then record the hashshake
* hashes in |s->session| in case we need them to verify a ChannelID
* signature on a resumption of this session in the future. */
- if (!s->hit) {
+ if (!s->hit && s->s3->tlsext_channel_id_valid) {
ret = tls1_record_handshake_hashes_for_channel_id(s);
if (ret <= 0) {
goto end;
@@ -944,8 +945,15 @@ int ssl3_get_client_hello(SSL *s) {
session = NULL;
s->verify_result = s->session->verify_result;
- } else if (!ssl_get_new_session(s, 1)) {
- goto err;
+ } else {
+ if (!ssl_get_new_session(s, 1 /* server */)) {
+ goto err;
+ }
+
+ /* Clear the session ID if we want the session to be single-use. */
+ if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) {
+ s->session->session_id_length = 0;
+ }
}
if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) {
@@ -1106,90 +1114,55 @@ err:
return ret;
}
-int ssl3_send_server_hello(SSL *s) {
- uint8_t *buf;
- uint8_t *p, *d;
- int sl;
- unsigned long l;
-
- if (s->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. */
- if (s->s3->tlsext_channel_id_valid &&
- (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kECDHE) == 0) {
- s->s3->tlsext_channel_id_valid = 0;
- }
-
- /* If this is a resumption and the original handshake didn't support
- * ChannelID then we didn't record the original handshake hashes in the
- * session and so cannot resume with ChannelIDs. */
- if (s->hit && s->session->original_handshake_hash_len == 0) {
- s->s3->tlsext_channel_id_valid = 0;
- }
-
- buf = (uint8_t *)s->init_buf->data;
- /* Do the message type and length last */
- d = p = ssl_handshake_start(s);
-
- *(p++) = s->version >> 8;
- *(p++) = s->version & 0xff;
-
- /* Random stuff */
- if (!ssl_fill_hello_random(s->s3->server_random, SSL3_RANDOM_SIZE,
- 1 /* server */)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
- p += SSL3_RANDOM_SIZE;
-
- /* There are several cases for the session ID to send
- * back in the server hello:
- * - For session reuse from the session cache, we send back the old session
- * ID.
- * - If stateless session reuse (using a session ticket) is successful, we
- * send back the client's "session ID" (which doesn't actually identify
- * the session).
- * - If it is a new session, we send back the new session ID.
- * - However, if we want the new session to be single-use, we send back a
- * 0-length session ID.
- * s->hit is non-zero in either case of session reuse, so the following
- * won't overwrite an ID that we're supposed to send back. */
- if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) && !s->hit) {
- s->session->session_id_length = 0;
- }
+int ssl3_send_server_hello(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_SRVR_HELLO_B) {
+ return ssl_do_write(ssl);
+ }
- sl = s->session->session_id_length;
- if (sl > (int)sizeof(s->session->session_id)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
- }
- *(p++) = sl;
- memcpy(p, s->session->session_id, sl);
- p += sl;
+ assert(ssl->state == SSL3_ST_SW_SRVR_HELLO_A);
- /* put the cipher */
- s2n(ssl_cipher_get_value(s->s3->tmp.new_cipher), p);
+ /* We only accept ChannelIDs on connections with ECDHE in order to avoid a
+ * known attack while we fix ChannelID itself. */
+ if (ssl->s3->tlsext_channel_id_valid &&
+ (ssl->s3->tmp.new_cipher->algorithm_mkey & SSL_kECDHE) == 0) {
+ ssl->s3->tlsext_channel_id_valid = 0;
+ }
- /* put the compression method */
- *(p++) = 0;
+ /* If this is a resumption and the original handshake didn't support
+ * ChannelID then we didn't record the original handshake hashes in the
+ * session and so cannot resume with ChannelIDs. */
+ if (ssl->hit && ssl->session->original_handshake_hash_len == 0) {
+ ssl->s3->tlsext_channel_id_valid = 0;
+ }
- p = ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH);
- if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
- }
+ if (!ssl_fill_hello_random(ssl->s3->server_random, SSL3_RANDOM_SIZE,
+ 1 /* server */)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
- /* do the header */
- l = (p - d);
- if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) {
- return -1;
- }
- s->state = SSL3_ST_SW_SRVR_HELLO_B;
+ CBB cbb, session_id;
+ size_t length;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u16(&cbb, ssl->version) ||
+ !CBB_add_bytes(&cbb, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
+ !CBB_add_u8_length_prefixed(&cbb, &session_id) ||
+ !CBB_add_bytes(&session_id, ssl->session->session_id,
+ ssl->session->session_id_length) ||
+ !CBB_add_u16(&cbb, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
+ !CBB_add_u8(&cbb, 0 /* no compression */) ||
+ !ssl_add_serverhello_tlsext(ssl, &cbb) ||
+ !CBB_finish(&cbb, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_SERVER_HELLO, length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&cbb);
+ return -1;
}
- /* SSL3_ST_SW_SRVR_HELLO_B */
- return ssl_do_write(s);
+ ssl->state = SSL3_ST_SW_SRVR_HELLO_B;
+ return ssl_do_write(ssl);
}
int ssl3_send_certificate_status(SSL *ssl) {
@@ -1603,17 +1576,24 @@ err:
return -1;
}
+static struct CRYPTO_STATIC_MUTEX g_d5_bug_lock = CRYPTO_STATIC_MUTEX_INIT;
+static uint64_t g_d5_bug_use_count = 0;
+
+uint64_t OPENSSL_get_d5_bug_use_count(void) {
+ CRYPTO_STATIC_MUTEX_lock_read(&g_d5_bug_lock);
+ uint64_t ret = g_d5_bug_use_count;
+ CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock);
+ return ret;
+}
+
int ssl3_get_client_key_exchange(SSL *s) {
- int al, ok;
- long n;
+ int al;
CBS client_key_exchange;
uint32_t alg_k;
uint32_t alg_a;
uint8_t *premaster_secret = NULL;
size_t premaster_secret_len = 0;
- RSA *rsa = NULL;
uint8_t *decrypt_buf = NULL;
- EVP_PKEY *pkey = NULL;
BIGNUM *pub = NULL;
DH *dh_srvr;
@@ -1624,17 +1604,18 @@ int ssl3_get_client_key_exchange(SSL *s) {
unsigned int psk_len = 0;
uint8_t psk[PSK_MAX_PSK_LEN];
- n = s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A,
- SSL3_ST_SR_KEY_EXCH_B,
- SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, /* ??? */
- ssl_hash_message, &ok);
-
- if (!ok) {
- return n;
+ if (s->state == SSL3_ST_SR_KEY_EXCH_A ||
+ s->state == SSL3_ST_SR_KEY_EXCH_B) {
+ int ok;
+ const long n = s->method->ssl_get_message(
+ s, SSL3_ST_SR_KEY_EXCH_A, SSL3_ST_SR_KEY_EXCH_B,
+ SSL3_MT_CLIENT_KEY_EXCHANGE, 2048 /* ??? */, ssl_hash_message, &ok);
+ if (!ok) {
+ return n;
+ }
}
- CBS_init(&client_key_exchange, s->init_msg, n);
-
+ CBS_init(&client_key_exchange, s->init_msg, s->init_num);
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -1691,68 +1672,82 @@ int ssl3_get_client_key_exchange(SSL *s) {
CBS encrypted_premaster_secret;
uint8_t rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
uint8_t good;
- size_t rsa_size, decrypt_len, premaster_index, j;
+ size_t decrypt_len, premaster_index, j;
+ const size_t rsa_size = ssl_private_key_max_signature_len(s);
- pkey = s->cert->privatekey;
- if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
- goto f_err;
+ /* Allocate a buffer large enough for an RSA decryption. */
+ decrypt_buf = OPENSSL_malloc(rsa_size);
+ if (decrypt_buf == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
}
- rsa = pkey->pkey.rsa;
-
- /* TLS and [incidentally] DTLS{0xFEFF} */
- if (s->version > SSL3_VERSION) {
- CBS copy = client_key_exchange;
- if (!CBS_get_u16_length_prefixed(&client_key_exchange,
- &encrypted_premaster_secret) ||
- CBS_len(&client_key_exchange) != 0) {
- if (!(s->options & SSL_OP_TLS_D5_BUG)) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
- goto f_err;
- } else {
- encrypted_premaster_secret = copy;
+
+ enum ssl_private_key_result_t decrypt_result;
+ if (s->state == SSL3_ST_SR_KEY_EXCH_B) {
+ if (!ssl_has_private_key(s) || ssl_private_key_type(s) != EVP_PKEY_RSA) {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
+ goto f_err;
+ }
+ /* TLS and [incidentally] DTLS{0xFEFF} */
+ if (s->version > SSL3_VERSION) {
+ CBS copy = client_key_exchange;
+ if (!CBS_get_u16_length_prefixed(&client_key_exchange,
+ &encrypted_premaster_secret) ||
+ CBS_len(&client_key_exchange) != 0) {
+ if (!(s->options & SSL_OP_TLS_D5_BUG)) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL,
+ SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+ goto f_err;
+ } else {
+ CRYPTO_STATIC_MUTEX_lock_write(&g_d5_bug_lock);
+ g_d5_bug_use_count++;
+ CRYPTO_STATIC_MUTEX_unlock(&g_d5_bug_lock);
+
+ encrypted_premaster_secret = copy;
+ }
}
+ } else {
+ encrypted_premaster_secret = client_key_exchange;
}
- } else {
- encrypted_premaster_secret = client_key_exchange;
- }
- /* Reject overly short RSA keys because we want to be sure that the buffer
- * size makes it safe to iterate over the entire size of a premaster secret
- * (SSL_MAX_MASTER_KEY_LENGTH). The actual expected size is larger due to
- * RSA padding, but the bound is sufficient to be safe. */
- rsa_size = RSA_size(rsa);
- if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) {
- al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
- goto f_err;
- }
+ /* Reject overly short RSA keys because we want to be sure that the buffer
+ * size makes it safe to iterate over the entire size of a premaster
+ * secret (SSL_MAX_MASTER_KEY_LENGTH). The actual expected size is larger
+ * due to RSA padding, but the bound is sufficient to be safe. */
+ if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) {
+ al = SSL_AD_DECRYPT_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
+ goto f_err;
+ }
- /* We must not leak whether a decryption failure occurs because of
- * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
- * section 7.4.7.1). The code follows that advice of the TLS RFC and
- * generates a random premaster secret for the case that the decrypt fails.
- * See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
- if (!RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret))) {
- goto err;
+ /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
+ * timing-sensitive code below. */
+ decrypt_result = ssl_private_key_decrypt(
+ s, decrypt_buf, &decrypt_len, rsa_size,
+ CBS_data(&encrypted_premaster_secret),
+ CBS_len(&encrypted_premaster_secret));
+ } else {
+ assert(s->state == SSL3_ST_SR_KEY_EXCH_C);
+ /* Complete async decrypt. */
+ decrypt_result = ssl_private_key_decrypt_complete(
+ s, decrypt_buf, &decrypt_len, rsa_size);
}
- /* Allocate a buffer large enough for an RSA decryption. */
- decrypt_buf = OPENSSL_malloc(rsa_size);
- if (decrypt_buf == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ switch (decrypt_result) {
+ case ssl_private_key_success:
+ s->rwstate = SSL_NOTHING;
+ break;
+ case ssl_private_key_failure:
+ s->rwstate = SSL_NOTHING;
+ goto err;
+ case ssl_private_key_retry:
+ s->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ s->state = SSL3_ST_SR_KEY_EXCH_C;
+ goto err;
}
- /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
- * timing-sensitive code below. */
- if (!RSA_decrypt(rsa, &decrypt_len, decrypt_buf, rsa_size,
- CBS_data(&encrypted_premaster_secret),
- CBS_len(&encrypted_premaster_secret), RSA_NO_PADDING)) {
- goto err;
- }
if (decrypt_len != rsa_size) {
/* This should never happen, but do a check so we do not read
* uninitialized memory. */
@@ -1796,6 +1791,15 @@ int ssl3_get_client_key_exchange(SSL *s) {
good &= constant_time_eq_8(premaster_secret[1],
(unsigned)(s->client_version & 0xff));
+ /* We must not leak whether a decryption failure occurs because of
+ * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
+ * section 7.4.7.1). The code follows that advice of the TLS RFC and
+ * generates a random premaster secret for the case that the decrypt
+ * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
+ if (!RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret))) {
+ goto err;
+ }
+
/* Now copy rand_premaster_secret over premaster_secret using
* decrypt_good_mask. */
for (j = 0; j < sizeof(rand_premaster_secret); j++) {
@@ -1850,7 +1854,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
premaster_secret_len = dh_len;
} else if (alg_k & SSL_kECDHE) {
- int field_size = 0, ecdh_len;
+ int ecdh_len;
const EC_KEY *tkey;
const EC_GROUP *group;
const BIGNUM *priv_key;
@@ -1905,8 +1909,8 @@ int ssl3_get_client_key_exchange(SSL *s) {
}
/* Allocate a buffer for both the secret and the PSK. */
- field_size = EC_GROUP_get_degree(group);
- if (field_size <= 0) {
+ unsigned field_size = EC_GROUP_get_degree(group);
+ if (field_size == 0) {
OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.c
index 0d4760d..0ad4a11 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.c
@@ -130,13 +130,15 @@
* compressionMethod [11] OCTET STRING OPTIONAL,
* srpUsername [12] OCTET STRING OPTIONAL, */
+static const unsigned kVersion = 1;
+
static const int kTimeTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
static const int kTimeoutTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
static const int kPeerTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
- static const int kSessionIDContextTag =
+static const int kSessionIDContextTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4;
static const int kVerifyResultTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5;
@@ -190,7 +192,7 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
CBB_zero(&cbb);
if (!CBB_init(&cbb, 0) ||
!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION) ||
+ !CBB_add_asn1_uint64(&session, kVersion) ||
!CBB_add_asn1_uint64(&session, in->ssl_version) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
!CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) ||
@@ -509,7 +511,7 @@ static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
uint64_t version, ssl_version;
if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1_uint64(&session, &version) ||
- version != SSL_SESSION_ASN1_VERSION ||
+ version != kVersion ||
!CBS_get_asn1_uint64(&session, &ssl_version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index b23d775..0ffeb5b 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -452,17 +452,17 @@ const SSL_CIPHER kCiphers[] = {
/* ChaCha20-Poly1305 cipher suites. */
{
- TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
- TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aRSA,
- SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD,
+ TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aRSA,
+ SSL_CHACHA20POLY1305_OLD, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256,
256, 256,
},
{
- TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
- TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aECDSA,
- SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
+ TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD,
+ TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aECDSA,
+ SSL_CHACHA20POLY1305_OLD, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256,
256, 256,
},
@@ -502,7 +502,7 @@ typedef struct cipher_alias_st {
static const CIPHER_ALIAS kCipherAliases[] = {
/* "ALL" doesn't include eNULL (must be specifically enabled) */
- {SSL_TXT_ALL, ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, ~0u},
+ {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, ~0u},
/* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
@@ -510,58 +510,58 @@ static const CIPHER_ALIAS kCipherAliases[] = {
* (some of those using only a single bit here combine
* multiple key exchange algs according to the RFCs,
* e.g. kEDH combines DHE_DSS and DHE_RSA) */
- {SSL_TXT_kRSA, SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kDHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kEDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_DH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"DH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kEECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_ECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_kPSK, SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
/* server authentication aliases */
- {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
- {SSL_TXT_aECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_ECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_aPSK, ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
+ {"aRSA", ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
+ {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
+ {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
+ {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
/* aliases combining key exchange and server authentication */
- {SSL_TXT_DHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_EDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_ECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_EECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
- {SSL_TXT_PSK, SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
+ {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
+ {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
+ {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
/* symmetric encryption aliases */
- {SSL_TXT_3DES, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
- {SSL_TXT_RC4, ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
- {SSL_TXT_AES128, ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
- {SSL_TXT_AES256, ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
- {SSL_TXT_AES, ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
- {SSL_TXT_AES_GCM, ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
- {SSL_TXT_CHACHA20, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u},
+ {"3DES", ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
+ {"RC4", ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
+ {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
+ {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
+ {"AES", ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
+ {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
+ {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u},
/* MAC aliases */
- {SSL_TXT_MD5, ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
- {SSL_TXT_SHA1, ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
- {SSL_TXT_SHA, ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
- {SSL_TXT_SHA256, ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
- {SSL_TXT_SHA384, ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
+ {"MD5", ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
+ {"SHA1", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
+ {"SHA", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
+ {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
+ {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
/* protocol version aliases */
- {SSL_TXT_SSLV3, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_SSLV3, ~0u},
- {SSL_TXT_TLSV1, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1, ~0u},
- {SSL_TXT_TLSV1_2, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1_2, ~0u},
+ {"SSLv3", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_SSLV3, ~0u},
+ {"TLSv1", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1, ~0u},
+ {"TLSv1.2", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1_2, ~0u},
/* strength classes */
- {SSL_TXT_MEDIUM, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
- {SSL_TXT_HIGH, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
+ {"MEDIUM", ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
+ {"HIGH", ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
/* FIPS 140-2 approved ciphersuite */
- {SSL_TXT_FIPS, ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, SSL_FIPS},
+ {"FIPS", ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, SSL_FIPS},
};
static const size_t kCipherAliasesLen =
@@ -612,8 +612,8 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
return 1;
#if !defined(BORINGSSL_ANDROID_SYSTEM)
- case SSL_CHACHA20POLY1305:
- *out_aead = EVP_aead_chacha20_poly1305();
+ case SSL_CHACHA20POLY1305_OLD:
+ *out_aead = EVP_aead_chacha20_poly1305_old();
*out_fixed_iv_len = 0;
return 1;
#endif
@@ -1236,10 +1236,10 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
-1, 0, &head, &tail);
ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
-1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u,
CIPHER_ADD, -1, 0, &head, &tail);
} else {
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, ~0u, ~0u,
CIPHER_ADD, -1, 0, &head, &tail);
ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
-1, 0, &head, &tail);
@@ -1389,7 +1389,7 @@ int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
}
int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) {
- return (cipher->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
+ return (cipher->algorithm_enc & SSL_CHACHA20POLY1305_OLD) != 0;
}
int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) {
@@ -1470,7 +1470,7 @@ static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
return "AES_128_GCM";
case SSL_AES256GCM:
return "AES_256_GCM";
- case SSL_CHACHA20POLY1305:
+ case SSL_CHACHA20POLY1305_OLD:
return "CHACHA20_POLY1305";
break;
default:
@@ -1626,7 +1626,7 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
enc = "AESGCM(256)";
break;
- case SSL_CHACHA20POLY1305:
+ case SSL_CHACHA20POLY1305_OLD:
enc = "ChaCha20-Poly1305";
break;
diff --git a/src/ssl/ssl_file.c b/src/ssl/ssl_file.c
index 88ad5b7..42cf800 100644
--- a/src/ssl/ssl_file.c
+++ b/src/ssl/ssl_file.c
@@ -113,6 +113,7 @@
#include <errno.h>
#include <string.h>
+#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -620,4 +621,13 @@ void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) {
ctx->default_passwd_callback_userdata = data;
}
+SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
+ return ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bio,
+ out);
+}
+
+int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
+ return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session);
+}
+
IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 74bd633..5fc2f66 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -183,9 +183,9 @@ int SSL_library_init(void) {
static uint32_t ssl_session_hash(const SSL_SESSION *a) {
uint32_t hash =
- ((uint32_t)a->session_id[0]) ||
- ((uint32_t)a->session_id[1] << 8) ||
- ((uint32_t)a->session_id[2] << 16) ||
+ ((uint32_t)a->session_id[0]) |
+ ((uint32_t)a->session_id[1] << 8) |
+ ((uint32_t)a->session_id[2] << 16) |
((uint32_t)a->session_id[3] << 24);
return hash;
@@ -385,7 +385,6 @@ SSL *SSL_new(SSL_CTX *ctx) {
assert(s->sid_ctx_length <= sizeof s->sid_ctx);
memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
s->verify_callback = ctx->default_verify_callback;
- s->generate_session_id = ctx->generate_session_id;
s->param = X509_VERIFY_PARAM_new();
if (!s->param) {
@@ -943,39 +942,6 @@ int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
return 1;
}
-int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
- ctx->generate_session_id = cb;
- return 1;
-}
-
-int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
- ssl->generate_session_id = cb;
- return 1;
-}
-
-int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
- unsigned id_len) {
- /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
- * can "construct" a session to give us the desired check - ie. to find if
- * there's a session in the hash table that would conflict with any new
- * session built out of this id/id_len and the ssl_version in use by this
- * SSL. */
- SSL_SESSION r, *p;
-
- if (id_len > sizeof r.session_id) {
- return 0;
- }
-
- r.ssl_version = ssl->version;
- r.session_id_length = id_len;
- memcpy(r.session_id, id, id_len);
-
- CRYPTO_MUTEX_lock_read(&ssl->ctx->lock);
- p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
- CRYPTO_MUTEX_unlock(&ssl->ctx->lock);
- return p != NULL;
-}
-
int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
}
@@ -1071,123 +1037,94 @@ X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); }
-int SSL_get_fd(const SSL *s) { return SSL_get_rfd(s); }
+int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); }
-int SSL_get_rfd(const SSL *s) {
+int SSL_get_rfd(const SSL *ssl) {
int ret = -1;
- BIO *b, *r;
-
- b = SSL_get_rbio(s);
- r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
- if (r != NULL) {
- BIO_get_fd(r, &ret);
+ BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR);
+ if (b != NULL) {
+ BIO_get_fd(b, &ret);
}
return ret;
}
-int SSL_get_wfd(const SSL *s) {
+int SSL_get_wfd(const SSL *ssl) {
int ret = -1;
- BIO *b, *r;
-
- b = SSL_get_wbio(s);
- r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
- if (r != NULL) {
- BIO_get_fd(r, &ret);
+ BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR);
+ if (b != NULL) {
+ BIO_get_fd(b, &ret);
}
-
return ret;
}
-int SSL_set_fd(SSL *s, int fd) {
- int ret = 0;
- BIO *bio = NULL;
-
- bio = BIO_new(BIO_s_fd());
-
+int SSL_set_fd(SSL *ssl, int fd) {
+ BIO *bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
- goto err;
+ return 0;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, bio, bio);
- ret = 1;
-
-err:
- return ret;
+ SSL_set_bio(ssl, bio, bio);
+ return 1;
}
-int SSL_set_wfd(SSL *s, int fd) {
- int ret = 0;
- BIO *bio = NULL;
-
- if (s->rbio == NULL || BIO_method_type(s->rbio) != BIO_TYPE_FD ||
- (int)BIO_get_fd(s->rbio, NULL) != fd) {
- bio = BIO_new(BIO_s_fd());
-
+int SSL_set_wfd(SSL *ssl, int fd) {
+ if (ssl->rbio == NULL ||
+ BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
+ BIO_get_fd(ssl->rbio, NULL) != fd) {
+ BIO *bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
- goto err;
+ return 0;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, SSL_get_rbio(s), bio);
+ SSL_set_bio(ssl, SSL_get_rbio(ssl), bio);
} else {
- SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
+ SSL_set_bio(ssl, SSL_get_rbio(ssl), SSL_get_rbio(ssl));
}
- ret = 1;
-
-err:
- return ret;
+ return 1;
}
-int SSL_set_rfd(SSL *s, int fd) {
- int ret = 0;
- BIO *bio = NULL;
-
- if (s->wbio == NULL || BIO_method_type(s->wbio) != BIO_TYPE_FD ||
- (int)BIO_get_fd(s->wbio, NULL) != fd) {
- bio = BIO_new(BIO_s_fd());
-
+int SSL_set_rfd(SSL *ssl, int fd) {
+ if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
+ BIO_get_fd(ssl->wbio, NULL) != fd) {
+ BIO *bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
- goto err;
+ return 0;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
- SSL_set_bio(s, bio, SSL_get_wbio(s));
+ SSL_set_bio(ssl, bio, SSL_get_wbio(ssl));
} else {
- SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
+ SSL_set_bio(ssl, SSL_get_wbio(ssl), SSL_get_wbio(ssl));
}
- ret = 1;
-
-err:
- return ret;
+ return 1;
}
-/* return length of latest Finished message we sent, copy to 'buf' */
-size_t SSL_get_finished(const SSL *s, void *buf, size_t count) {
+size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
size_t ret = 0;
- if (s->s3 != NULL) {
- ret = s->s3->tmp.finish_md_len;
+ if (ssl->s3 != NULL) {
+ ret = ssl->s3->tmp.finish_md_len;
if (count > ret) {
count = ret;
}
- memcpy(buf, s->s3->tmp.finish_md, count);
+ memcpy(buf, ssl->s3->tmp.finish_md, count);
}
return ret;
}
-/* return length of latest Finished message we expected, copy to 'buf' */
-size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) {
+size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
size_t ret = 0;
- if (s->s3 != NULL) {
- ret = s->s3->tmp.peer_finish_md_len;
+ if (ssl->s3 != NULL) {
+ ret = ssl->s3->tmp.peer_finish_md_len;
if (count > ret) {
count = ret;
}
- memcpy(buf, s->s3->tmp.peer_finish_md, count);
+ memcpy(buf, ssl->s3->tmp.peer_finish_md, count);
}
return ret;
@@ -1238,9 +1175,11 @@ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
void SSL_set_read_ahead(SSL *s, int yes) { }
-int SSL_pending(const SSL *s) {
- return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length
- : 0;
+int SSL_pending(const SSL *ssl) {
+ if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) {
+ return 0;
+ }
+ return ssl->s3->rrec.length;
}
/* Fix this so it checks all the valid key/cert options */
@@ -1367,29 +1306,27 @@ int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) {
return ctx->session_cache_mode;
}
-/* return a STACK of the ciphers available for the SSL and in order of
- * preference */
-STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
- if (s == NULL) {
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- if (s->cipher_list != NULL) {
- return s->cipher_list->ciphers;
+ if (ssl->cipher_list != NULL) {
+ return ssl->cipher_list->ciphers;
}
- if (s->version >= TLS1_1_VERSION && s->ctx != NULL &&
- s->ctx->cipher_list_tls11 != NULL) {
- return s->ctx->cipher_list_tls11->ciphers;
+ if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls11 != NULL) {
+ return ssl->ctx->cipher_list_tls11->ciphers;
}
- if (s->version >= TLS1_VERSION && s->ctx != NULL &&
- s->ctx->cipher_list_tls10 != NULL) {
- return s->ctx->cipher_list_tls10->ciphers;
+ if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
+ ssl->ctx->cipher_list_tls10 != NULL) {
+ return ssl->ctx->cipher_list_tls10->ciphers;
}
- if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
- return s->ctx->cipher_list->ciphers;
+ if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
+ return ssl->ctx->cipher_list->ciphers;
}
return NULL;
@@ -1413,16 +1350,15 @@ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) {
return NULL;
}
-/* The old interface to get the same thing as SSL_get_ciphers() */
-const char *SSL_get_cipher_list(const SSL *s, int n) {
+const char *SSL_get_cipher_list(const SSL *ssl, int n) {
const SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *sk;
- if (s == NULL) {
+ if (ssl == NULL) {
return NULL;
}
- sk = SSL_get_ciphers(s);
+ sk = SSL_get_ciphers(ssl);
if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
return NULL;
}
@@ -1435,20 +1371,15 @@ const char *SSL_get_cipher_list(const SSL *s, int n) {
return c->name;
}
-/* specify the ciphers to be used by default by the SSL_CTX */
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
- &ctx->cipher_list_by_id, str);
- /* ssl_create_cipher_list may return an empty stack if it was unable to find
- * a cipher matching the given rule string (for example if the rule string
- * specifies a cipher which has been disabled). This is not an error as far
- * as ssl_create_cipher_list is concerned, and hence ctx->cipher_list and
- * ctx->cipher_list_by_id has been updated. */
- if (sk == NULL) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ctx->method, &ctx->cipher_list, &ctx->cipher_list_by_id, str);
+ if (cipher_list == NULL) {
return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
+ }
+
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@@ -1457,12 +1388,14 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
}
int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls10, NULL, str);
- if (sk == NULL) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ctx->method, &ctx->cipher_list_tls10, NULL, str);
+ if (cipher_list == NULL) {
return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
+ }
+
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@@ -1471,30 +1404,14 @@ int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
}
int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str);
- if (sk == NULL) {
- return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ctx->method, &ctx->cipher_list_tls11, NULL, str);
+ if (cipher_list == NULL) {
return 0;
}
- return 1;
-}
-
-/* specify the ciphers to be used by the SSL */
-int SSL_set_cipher_list(SSL *s, const char *str) {
- STACK_OF(SSL_CIPHER) *sk;
-
- sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
- &s->cipher_list_by_id, str);
-
- /* see comment in SSL_CTX_set_cipher_list */
- if (sk == NULL) {
- return 0;
- } else if (sk_SSL_CIPHER_num(sk) == 0) {
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@@ -1502,49 +1419,20 @@ int SSL_set_cipher_list(SSL *s, const char *str) {
return 1;
}
-int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
- size_t i;
- const SSL_CIPHER *c;
- CERT *ct = s->cert;
- uint8_t *q;
- /* Set disabled masks for this session */
- ssl_set_client_disabled(s);
-
- if (sk == NULL) {
+int SSL_set_cipher_list(SSL *ssl, const char *str) {
+ STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
+ ssl->ctx->method, &ssl->cipher_list, &ssl->cipher_list_by_id, str);
+ if (cipher_list == NULL) {
return 0;
}
- q = p;
- for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
- c = sk_SSL_CIPHER_value(sk, i);
- /* Skip disabled ciphers */
- if (c->algorithm_ssl & ct->mask_ssl ||
- c->algorithm_mkey & ct->mask_k ||
- c->algorithm_auth & ct->mask_a) {
- continue;
- }
- s2n(ssl_cipher_get_value(c), p);
- }
-
- /* If all ciphers were disabled, return the error to the caller. */
- if (p == q) {
+ /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
+ if (sk_SSL_CIPHER_num(cipher_list) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
- /* For SSLv3, the SCSV is added. Otherwise the renegotiation extension is
- * added. */
- if (s->client_version == SSL3_VERSION &&
- !s->s3->initial_handshake_complete) {
- s2n(SSL3_CK_SCSV & 0xffff, p);
- /* The renegotiation extension is required to be at index zero. */
- s->s3->tmp.extensions.sent |= (1u << 0);
- }
-
- if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
- s2n(SSL3_CK_FALLBACK_SCSV & 0xffff, p);
- }
-
- return p - q;
+ return 1;
}
STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
@@ -1613,21 +1501,25 @@ err:
return NULL;
}
-
-/* return a servername extension value if provided in Client Hello, or NULL. So
- * far, only host_name types are defined (RFC 3546). */
-const char *SSL_get_servername(const SSL *s, const int type) {
+const char *SSL_get_servername(const SSL *ssl, const int type) {
if (type != TLSEXT_NAMETYPE_host_name) {
return NULL;
}
- return s->session && !s->tlsext_hostname ? s->session->tlsext_hostname
- : s->tlsext_hostname;
+ /* Historically, |SSL_get_servername| was also the configuration getter
+ * corresponding to |SSL_set_tlsext_host_name|. */
+ if (ssl->tlsext_hostname != NULL) {
+ return ssl->tlsext_hostname;
+ }
+
+ if (ssl->session == NULL) {
+ return NULL;
+ }
+ return ssl->session->tlsext_hostname;
}
-int SSL_get_servername_type(const SSL *s) {
- if (s->session &&
- (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) {
+int SSL_get_servername_type(const SSL *ssl) {
+ if (ssl->session != NULL && ssl->session->tlsext_hostname != NULL) {
return TLSEXT_NAMETYPE_host_name;
}
@@ -1812,16 +1704,16 @@ void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
}
}
-int SSL_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
+int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
const char *label, size_t label_len,
const uint8_t *context, size_t context_len,
int use_context) {
- if (s->version < TLS1_VERSION) {
+ if (ssl->version < TLS1_VERSION) {
return 0;
}
- return s->enc_method->export_keying_material(
- s, out, out_len, label, label_len, context, context_len, use_context);
+ return ssl->enc_method->export_keying_material(
+ ssl, out, out_len, label, label_len, context, context_len, use_context);
}
void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
@@ -1913,35 +1805,34 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
*out_mask_a = mask_a;
}
-void ssl_update_cache(SSL *s, int mode) {
+void ssl_update_cache(SSL *ssl, int mode) {
+ SSL_CTX *ctx = ssl->initial_ctx;
/* Never cache sessions with empty session IDs. */
- if (s->session->session_id_length == 0) {
+ if (ssl->session->session_id_length == 0 ||
+ (ctx->session_cache_mode & mode) != mode) {
return;
}
- int has_new_session = !s->hit;
- if (!s->server && s->tlsext_ticket_expected) {
- /* A client may see new sessions on abbreviated handshakes if the server
- * decides to renew the ticket. Once the handshake is completed, it should
- * be inserted into the cache. */
- has_new_session = 1;
- }
+ /* Clients never use the internal session cache. */
+ int use_internal_cache = ssl->server && !(ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_STORE);
- SSL_CTX *ctx = s->initial_ctx;
- if ((ctx->session_cache_mode & mode) == mode && has_new_session &&
- ((ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) ||
- SSL_CTX_add_session(ctx, s->session)) &&
- ctx->new_session_cb != NULL) {
- /* Note: |new_session_cb| is called whether the internal session cache is
- * used or not. */
- if (!ctx->new_session_cb(s, SSL_SESSION_up_ref(s->session))) {
- SSL_SESSION_free(s->session);
+ /* A client may see new sessions on abbreviated handshakes if the server
+ * decides to renew the ticket. Once the handshake is completed, it should be
+ * inserted into the cache. */
+ if (!ssl->hit || (!ssl->server && ssl->tlsext_ticket_expected)) {
+ if (use_internal_cache) {
+ SSL_CTX_add_session(ctx, ssl->session);
+ }
+ if (ctx->new_session_cb != NULL &&
+ !ctx->new_session_cb(ssl, SSL_SESSION_up_ref(ssl->session))) {
+ /* |new_session_cb|'s return value signals whether it took ownership. */
+ SSL_SESSION_free(ssl->session);
}
}
- if (!(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) &&
- !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE) &&
- (ctx->session_cache_mode & mode) == mode) {
+ if (use_internal_cache &&
+ !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) {
/* Automatically flush the internal session cache every 255 connections. */
int flush_cache = 0;
CRYPTO_MUTEX_lock_write(&ctx->lock);
@@ -2102,15 +1993,21 @@ int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
return ctx->quiet_shutdown;
}
-void SSL_set_quiet_shutdown(SSL *s, int mode) { s->quiet_shutdown = mode; }
+void SSL_set_quiet_shutdown(SSL *ssl, int mode) { ssl->quiet_shutdown = mode; }
-int SSL_get_quiet_shutdown(const SSL *s) { return s->quiet_shutdown; }
+int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; }
-void SSL_set_shutdown(SSL *s, int mode) { s->shutdown = mode; }
+void SSL_set_shutdown(SSL *ssl, int mode) {
+ /* It is an error to clear any bits that have already been set. (We can't try
+ * to get a second close_notify or send two.) */
+ assert((ssl->shutdown & mode) == ssl->shutdown);
+
+ ssl->shutdown |= mode;
+}
-int SSL_get_shutdown(const SSL *s) { return s->shutdown; }
+int SSL_get_shutdown(const SSL *ssl) { return ssl->shutdown; }
-int SSL_version(const SSL *s) { return s->version; }
+int SSL_version(const SSL *ssl) { return ssl->version; }
SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
@@ -2147,12 +2044,12 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
}
void SSL_set_info_callback(SSL *ssl,
- void (*cb)(const SSL *ssl, int type, int val)) {
+ void (*cb)(const SSL *ssl, int type, int value)) {
ssl->info_callback = cb;
}
-void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/, int /*type*/,
- int /*val*/) {
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type,
+ int value) {
return ssl->info_callback;
}
@@ -2212,7 +2109,7 @@ void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
ctx->cert_store = store;
}
-int SSL_want(const SSL *s) { return s->rwstate; }
+int SSL_want(const SSL *ssl) { return ssl->rwstate; }
void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
RSA *(*cb)(SSL *ssl, int is_export,
@@ -2455,8 +2352,16 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
return ret;
}
-int SSL_in_false_start(const SSL *s) {
- return s->s3->tmp.in_false_start;
+int SSL_is_init_finished(const SSL *ssl) {
+ return ssl->state == SSL_ST_OK;
+}
+
+int SSL_in_init(const SSL *ssl) {
+ return (ssl->state & SSL_ST_INIT) != 0;
+}
+
+int SSL_in_false_start(const SSL *ssl) {
+ return ssl->s3->tmp.in_false_start;
}
int SSL_cutthrough_complete(const SSL *s) {
@@ -2481,7 +2386,7 @@ int ssl3_can_false_start(const SSL *s) {
cipher->algorithm_mkey == SSL_kECDHE &&
(cipher->algorithm_enc == SSL_AES128GCM ||
cipher->algorithm_enc == SSL_AES256GCM ||
- cipher->algorithm_enc == SSL_CHACHA20POLY1305);
+ cipher->algorithm_enc == SSL_CHACHA20POLY1305_OLD);
}
const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
@@ -2700,13 +2605,23 @@ int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
int SSL_is_server(SSL *ssl) { return ssl->server; }
+void SSL_CTX_set_select_certificate_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
+ ctx->select_certificate_cb = cb;
+}
+
void SSL_CTX_set_dos_protection_cb(
SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
ctx->dos_protection_cb = cb;
}
-void SSL_set_reject_peer_renegotiations(SSL *s, int reject) {
- s->accept_peer_renegotiations = !reject;
+void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) {
+ ssl->renegotiate_mode = mode;
+}
+
+void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject) {
+ SSL_set_renegotiate_mode(
+ ssl, reject ? ssl_renegotiate_never : ssl_renegotiate_freely);
}
int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index ccd3858..512a41f 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -376,3 +376,33 @@ enum ssl_private_key_result_t ssl_private_key_sign_complete(
/* Only custom keys may be asynchronous. */
return ssl->cert->key_method->sign_complete(ssl, out, out_len, max_out);
}
+
+enum ssl_private_key_result_t ssl_private_key_decrypt(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
+ in_len);
+ }
+
+ if (ssl_private_key_type(ssl) != EVP_PKEY_RSA) {
+ /* Decrypt operations are only supported for RSA keys. */
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return ssl_private_key_failure;
+ }
+
+ enum ssl_private_key_result_t ret = ssl_private_key_failure;
+ RSA *rsa = ssl->cert->privatekey->pkey.rsa;
+ /* Decrypt with no padding. PKCS#1 padding will be removed as part
+ * of the timing-sensitive code by the caller. */
+ if (RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
+ ret = ssl_private_key_success;
+ }
+ return ret;
+}
+
+enum ssl_private_key_result_t ssl_private_key_decrypt_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ /* Only custom keys may be asynchronous. */
+ return ssl->cert->key_method->decrypt_complete(ssl, out, out_len, max_out);
+}
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.c
index 345aca2..ead0b75 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.c
@@ -217,6 +217,10 @@ long SSL_SESSION_get_timeout(const SSL_SESSION *session) {
}
long SSL_SESSION_get_time(const SSL_SESSION *session) {
+ if (session == NULL) {
+ /* NULL should crash, but silently accept it here for compatibility. */
+ return 0;
+ }
return session->time;
}
@@ -293,142 +297,63 @@ void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) {
return CRYPTO_get_ex_data(&session->ex_data, idx);
}
-/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space.
- * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random
- * gunk repeatedly until we have no conflict is going to complete in one
- * iteration pretty much "most" of the time (btw: understatement). So, if it
- * takes us 10 iterations and we still can't avoid a conflict - well that's a
- * reasonable point to call it quits. Either the RAND code is broken or someone
- * is trying to open roughly very close to 2^128 (or 2^256) SSL sessions to our
- * server. How you might store that many sessions is perhaps a more interesting
- * question ... */
-static int def_generate_session_id(const SSL *ssl, uint8_t *id,
- unsigned *id_len) {
- static const unsigned kMaxAttempts = 10;
- unsigned retry = 0;
- do {
- if (!RAND_bytes(id, *id_len)) {
- return 0;
- }
- } while (SSL_has_matching_session_id(ssl, id, *id_len) &&
- (++retry < kMaxAttempts));
-
- if (retry < kMaxAttempts) {
- return 1;
- }
-
- /* else - woops a session_id match */
- /* XXX We should also check the external cache -- but the probability of a
- * collision is negligible, and we could not prevent the concurrent creation
- * of sessions with identical IDs since we currently don't have means to
- * atomically check whether a session ID already exists and make a
- * reservation for it if it does not (this problem applies to the internal
- * cache as well). */
- return 0;
-}
-
-int ssl_get_new_session(SSL *s, int session) {
- /* This gets used by clients and servers. */
-
- unsigned int tmp;
- SSL_SESSION *ss = NULL;
- GEN_SESSION_CB cb = def_generate_session_id;
-
- if (s->mode & SSL_MODE_NO_SESSION_CREATION) {
+int ssl_get_new_session(SSL *ssl, int is_server) {
+ if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED);
return 0;
}
- ss = SSL_SESSION_new();
- if (ss == NULL) {
+ SSL_SESSION *session = SSL_SESSION_new();
+ if (session == NULL) {
return 0;
}
/* If the context has a default timeout, use it over the default. */
- if (s->initial_ctx->session_timeout != 0) {
- ss->timeout = s->initial_ctx->session_timeout;
+ if (ssl->initial_ctx->session_timeout != 0) {
+ session->timeout = ssl->initial_ctx->session_timeout;
}
- SSL_SESSION_free(s->session);
- s->session = NULL;
+ session->ssl_version = ssl->version;
- if (session) {
- if (s->version == SSL3_VERSION || s->version == TLS1_VERSION ||
- s->version == TLS1_1_VERSION || s->version == TLS1_2_VERSION ||
- s->version == DTLS1_VERSION || s->version == DTLS1_2_VERSION) {
- ss->ssl_version = s->version;
- ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+ if (is_server) {
+ if (ssl->tlsext_ticket_expected) {
+ /* Don't set session IDs for sessions resumed with tickets. This will keep
+ * them out of the session cache. */
+ session->session_id_length = 0;
} else {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_SSL_VERSION);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- /* If RFC4507 ticket use empty session ID */
- if (s->tlsext_ticket_expected) {
- ss->session_id_length = 0;
- goto sess_id_done;
- }
-
- /* Choose which callback will set the session ID */
- if (s->generate_session_id) {
- cb = s->generate_session_id;
- } else if (s->initial_ctx->generate_session_id) {
- cb = s->initial_ctx->generate_session_id;
- }
-
- /* Choose a session ID */
- tmp = ss->session_id_length;
- if (!cb(s, ss->session_id, &tmp)) {
- /* The callback failed */
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- /* Don't allow the callback to set the session length to zero. nor set it
- * higher than it was. */
- if (!tmp || tmp > ss->session_id_length) {
- /* The callback set an illegal length */
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
- SSL_SESSION_free(ss);
- return 0;
- }
-
- ss->session_id_length = tmp;
- /* Finally, check for a conflict */
- if (SSL_has_matching_session_id(s, ss->session_id, ss->session_id_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONFLICT);
- SSL_SESSION_free(ss);
- return 0;
+ session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+ if (!RAND_bytes(session->session_id, session->session_id_length)) {
+ goto err;
+ }
}
- sess_id_done:
- if (s->tlsext_hostname) {
- ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
- if (ss->tlsext_hostname == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- SSL_SESSION_free(ss);
- return 0;
+ if (ssl->tlsext_hostname != NULL) {
+ session->tlsext_hostname = BUF_strdup(ssl->tlsext_hostname);
+ if (session->tlsext_hostname == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
}
}
} else {
- ss->session_id_length = 0;
+ session->session_id_length = 0;
}
- if (s->sid_ctx_length > sizeof(ss->sid_ctx)) {
+ if (ssl->sid_ctx_length > sizeof(session->sid_ctx)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- SSL_SESSION_free(ss);
- return 0;
+ goto err;
}
+ memcpy(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length);
+ session->sid_ctx_length = ssl->sid_ctx_length;
- memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
- ss->sid_ctx_length = s->sid_ctx_length;
- s->session = ss;
- ss->ssl_version = s->version;
- ss->verify_result = X509_V_OK;
+ session->verify_result = X509_V_OK;
+ SSL_SESSION_free(ssl->session);
+ ssl->session = session;
return 1;
+
+err:
+ SSL_SESSION_free(session);
+ return 0;
}
/* ssl_lookup_session looks up |session_id| in the session cache and sets
@@ -457,6 +382,7 @@ static enum ssl_session_result_t ssl_lookup_session(
if (session != NULL) {
SSL_SESSION_up_ref(session);
}
+ /* TODO(davidben): This should probably move it to the front of the list. */
CRYPTO_MUTEX_unlock(&ssl->initial_ctx->lock);
if (session != NULL) {
@@ -510,7 +436,7 @@ enum ssl_session_result_t ssl_get_prev_session(
size_t ticket_len = 0;
const int tickets_supported =
!(SSL_get_options(ssl) & SSL_OP_NO_TICKET) &&
- (ssl->version > SSL3_VERSION || ctx->extensions != NULL) &&
+ ssl->version > SSL3_VERSION &&
SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
&ticket, &ticket_len);
if (tickets_supported) {
@@ -571,15 +497,11 @@ no_session:
}
int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
- int ret = 0;
- SSL_SESSION *old_session;
-
- /* Add just 1 reference count for the |SSL_CTX|'s session cache even though it
- * has two ways of access: each session is in a doubly linked list and an
- * lhash. */
+ /* Although |session| is inserted into two structures (a doubly-linked list
+ * and the hash table), |ctx| only takes one reference. */
SSL_SESSION_up_ref(session);
- /* If |session| is in already in cache, we take back the increment later. */
+ SSL_SESSION *old_session;
CRYPTO_MUTEX_lock_write(&ctx->lock);
if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) {
CRYPTO_MUTEX_unlock(&ctx->lock);
@@ -587,45 +509,33 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
return 0;
}
- /* |old_session| != NULL iff we already had a session with the given session
- * ID. In this case, |old_session| == |session| should hold (then we did not
- * really modify |ctx->sessions|), or we're in trouble. */
- if (old_session != NULL && old_session != session) {
- /* We *are* in trouble ... */
+ if (old_session != NULL) {
+ if (old_session == session) {
+ /* |session| was already in the cache. */
+ CRYPTO_MUTEX_unlock(&ctx->lock);
+ SSL_SESSION_free(old_session);
+ return 0;
+ }
+
+ /* There was a session ID collision. |old_session| must be removed from
+ * the linked list and released. */
SSL_SESSION_list_remove(ctx, old_session);
SSL_SESSION_free(old_session);
- /* ... so pretend the other session did not exist in cache (we cannot
- * handle two |SSL_SESSION| structures with identical session ID in the same
- * cache, which could happen e.g. when two threads concurrently obtain the
- * same session from an external cache). */
- old_session = NULL;
}
- /* Put at the head of the queue unless it is already in the cache. */
- if (old_session == NULL) {
- SSL_SESSION_list_add(ctx, session);
- }
+ SSL_SESSION_list_add(ctx, session);
- if (old_session != NULL) {
- /* Existing cache entry -- decrement previously incremented reference count
- * because it already takes into account the cache. */
- SSL_SESSION_free(old_session); /* |old_session| == |session| */
- ret = 0;
- } else {
- /* New cache entry -- remove old ones if cache has become too large. */
- ret = 1;
-
- if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
- while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
- if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
- break;
- }
+ /* Enforce any cache size limits. */
+ if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
+ while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
+ if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) {
+ break;
}
}
}
CRYPTO_MUTEX_unlock(&ctx->lock);
- return ret;
+ return 1;
}
int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
@@ -822,23 +732,24 @@ SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
return ctx->get_session_cb;
}
-void SSL_CTX_set_info_callback(SSL_CTX *ctx,
- void (*cb)(const SSL *ssl, int type, int val)) {
+void SSL_CTX_set_info_callback(
+ SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)) {
ctx->info_callback = cb;
}
void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type,
- int val) {
+ int value) {
return ctx->info_callback;
}
-void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509,
- EVP_PKEY **pkey)) {
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl,
+ X509 **out_x509,
+ EVP_PKEY **out_pkey)) {
ctx->client_cert_cb = cb;
}
-int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509,
- EVP_PKEY **pkey) {
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **out_x509,
+ EVP_PKEY **out_pkey) {
return ctx->client_cert_cb;
}
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.c
index 5ad1e47..8fa197d 100644
--- a/src/ssl/ssl_stat.c
+++ b/src/ssl/ssl_stat.c
@@ -1,4 +1,3 @@
-/* ssl/ssl_stat.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -87,516 +86,389 @@
#include "internal.h"
-const char *SSL_state_string_long(const SSL *s) {
- const char *str;
-
- switch (s->state) {
+const char *SSL_state_string_long(const SSL *ssl) {
+ switch (ssl->state) {
case SSL_ST_ACCEPT:
- str = "before accept initialization";
- break;
+ return "before accept initialization";
case SSL_ST_CONNECT:
- str = "before connect initialization";
- break;
+ return "before connect initialization";
case SSL_ST_OK:
- str = "SSL negotiation finished successfully";
- break;
+ return "SSL negotiation finished successfully";
case SSL_ST_RENEGOTIATE:
- str = "SSL renegotiate ciphers";
- break;
+ return "SSL renegotiate ciphers";
/* SSLv3 additions */
case SSL3_ST_CW_CLNT_HELLO_A:
- str = "SSLv3 write client hello A";
- break;
+ return "SSLv3 write client hello A";
case SSL3_ST_CW_CLNT_HELLO_B:
- str = "SSLv3 write client hello B";
- break;
+ return "SSLv3 write client hello B";
case SSL3_ST_CR_SRVR_HELLO_A:
- str = "SSLv3 read server hello A";
- break;
+ return "SSLv3 read server hello A";
case SSL3_ST_CR_SRVR_HELLO_B:
- str = "SSLv3 read server hello B";
- break;
+ return "SSLv3 read server hello B";
case SSL3_ST_CR_CERT_A:
- str = "SSLv3 read server certificate A";
- break;
+ return "SSLv3 read server certificate A";
case SSL3_ST_CR_CERT_B:
- str = "SSLv3 read server certificate B";
- break;
+ return "SSLv3 read server certificate B";
case SSL3_ST_CR_KEY_EXCH_A:
- str = "SSLv3 read server key exchange A";
- break;
+ return "SSLv3 read server key exchange A";
case SSL3_ST_CR_KEY_EXCH_B:
- str = "SSLv3 read server key exchange B";
- break;
+ return "SSLv3 read server key exchange B";
case SSL3_ST_CR_CERT_REQ_A:
- str = "SSLv3 read server certificate request A";
- break;
+ return "SSLv3 read server certificate request A";
case SSL3_ST_CR_CERT_REQ_B:
- str = "SSLv3 read server certificate request B";
- break;
+ return "SSLv3 read server certificate request B";
case SSL3_ST_CR_SESSION_TICKET_A:
- str = "SSLv3 read server session ticket A";
- break;
+ return "SSLv3 read server session ticket A";
case SSL3_ST_CR_SESSION_TICKET_B:
- str = "SSLv3 read server session ticket B";
- break;
+ return "SSLv3 read server session ticket B";
case SSL3_ST_CR_SRVR_DONE_A:
- str = "SSLv3 read server done A";
- break;
+ return "SSLv3 read server done A";
case SSL3_ST_CR_SRVR_DONE_B:
- str = "SSLv3 read server done B";
- break;
+ return "SSLv3 read server done B";
case SSL3_ST_CW_CERT_A:
- str = "SSLv3 write client certificate A";
- break;
+ return "SSLv3 write client certificate A";
case SSL3_ST_CW_CERT_B:
- str = "SSLv3 write client certificate B";
- break;
+ return "SSLv3 write client certificate B";
case SSL3_ST_CW_CERT_C:
- str = "SSLv3 write client certificate C";
- break;
+ return "SSLv3 write client certificate C";
case SSL3_ST_CW_CERT_D:
- str = "SSLv3 write client certificate D";
- break;
+ return "SSLv3 write client certificate D";
case SSL3_ST_CW_KEY_EXCH_A:
- str = "SSLv3 write client key exchange A";
- break;
+ return "SSLv3 write client key exchange A";
case SSL3_ST_CW_KEY_EXCH_B:
- str = "SSLv3 write client key exchange B";
- break;
+ return "SSLv3 write client key exchange B";
case SSL3_ST_CW_CERT_VRFY_A:
- str = "SSLv3 write certificate verify A";
- break;
+ return "SSLv3 write certificate verify A";
case SSL3_ST_CW_CERT_VRFY_B:
- str = "SSLv3 write certificate verify B";
- break;
+ return "SSLv3 write certificate verify B";
case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_SW_CHANGE_A:
- str = "SSLv3 write change cipher spec A";
- break;
+ return "SSLv3 write change cipher spec A";
case SSL3_ST_CW_CHANGE_B:
case SSL3_ST_SW_CHANGE_B:
- str = "SSLv3 write change cipher spec B";
- break;
+ return "SSLv3 write change cipher spec B";
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_SW_FINISHED_A:
- str = "SSLv3 write finished A";
- break;
+ return "SSLv3 write finished A";
case SSL3_ST_CW_FINISHED_B:
case SSL3_ST_SW_FINISHED_B:
- str = "SSLv3 write finished B";
- break;
+ return "SSLv3 write finished B";
case SSL3_ST_CR_CHANGE:
case SSL3_ST_SR_CHANGE:
- str = "SSLv3 read change cipher spec";
- break;
+ return "SSLv3 read change cipher spec";
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_SR_FINISHED_A:
- str = "SSLv3 read finished A";
- break;
+ return "SSLv3 read finished A";
case SSL3_ST_CR_FINISHED_B:
case SSL3_ST_SR_FINISHED_B:
- str = "SSLv3 read finished B";
- break;
+ return "SSLv3 read finished B";
case SSL3_ST_CW_FLUSH:
case SSL3_ST_SW_FLUSH:
- str = "SSLv3 flush data";
- break;
+ return "SSLv3 flush data";
case SSL3_ST_SR_CLNT_HELLO_A:
- str = "SSLv3 read client hello A";
- break;
+ return "SSLv3 read client hello A";
case SSL3_ST_SR_CLNT_HELLO_B:
- str = "SSLv3 read client hello B";
- break;
+ return "SSLv3 read client hello B";
case SSL3_ST_SR_CLNT_HELLO_C:
- str = "SSLv3 read client hello C";
- break;
+ return "SSLv3 read client hello C";
case SSL3_ST_SR_CLNT_HELLO_D:
- str = "SSLv3 read client hello D";
- break;
+ return "SSLv3 read client hello D";
case SSL3_ST_SW_HELLO_REQ_A:
- str = "SSLv3 write hello request A";
- break;
+ return "SSLv3 write hello request A";
case SSL3_ST_SW_HELLO_REQ_B:
- str = "SSLv3 write hello request B";
- break;
+ return "SSLv3 write hello request B";
case SSL3_ST_SW_HELLO_REQ_C:
- str = "SSLv3 write hello request C";
- break;
+ return "SSLv3 write hello request C";
case SSL3_ST_SW_SRVR_HELLO_A:
- str = "SSLv3 write server hello A";
- break;
+ return "SSLv3 write server hello A";
case SSL3_ST_SW_SRVR_HELLO_B:
- str = "SSLv3 write server hello B";
- break;
+ return "SSLv3 write server hello B";
case SSL3_ST_SW_CERT_A:
- str = "SSLv3 write certificate A";
- break;
+ return "SSLv3 write certificate A";
case SSL3_ST_SW_CERT_B:
- str = "SSLv3 write certificate B";
- break;
+ return "SSLv3 write certificate B";
case SSL3_ST_SW_KEY_EXCH_A:
- str = "SSLv3 write key exchange A";
- break;
+ return "SSLv3 write key exchange A";
case SSL3_ST_SW_KEY_EXCH_B:
- str = "SSLv3 write key exchange B";
- break;
+ return "SSLv3 write key exchange B";
case SSL3_ST_SW_CERT_REQ_A:
- str = "SSLv3 write certificate request A";
- break;
+ return "SSLv3 write certificate request A";
case SSL3_ST_SW_CERT_REQ_B:
- str = "SSLv3 write certificate request B";
- break;
+ return "SSLv3 write certificate request B";
case SSL3_ST_SW_SESSION_TICKET_A:
- str = "SSLv3 write session ticket A";
- break;
+ return "SSLv3 write session ticket A";
case SSL3_ST_SW_SESSION_TICKET_B:
- str = "SSLv3 write session ticket B";
- break;
+ return "SSLv3 write session ticket B";
case SSL3_ST_SW_SRVR_DONE_A:
- str = "SSLv3 write server done A";
- break;
+ return "SSLv3 write server done A";
case SSL3_ST_SW_SRVR_DONE_B:
- str = "SSLv3 write server done B";
- break;
+ return "SSLv3 write server done B";
case SSL3_ST_SR_CERT_A:
- str = "SSLv3 read client certificate A";
- break;
+ return "SSLv3 read client certificate A";
case SSL3_ST_SR_CERT_B:
- str = "SSLv3 read client certificate B";
- break;
+ return "SSLv3 read client certificate B";
case SSL3_ST_SR_KEY_EXCH_A:
- str = "SSLv3 read client key exchange A";
- break;
+ return "SSLv3 read client key exchange A";
case SSL3_ST_SR_KEY_EXCH_B:
- str = "SSLv3 read client key exchange B";
- break;
+ return "SSLv3 read client key exchange B";
case SSL3_ST_SR_CERT_VRFY_A:
- str = "SSLv3 read certificate verify A";
- break;
+ return "SSLv3 read certificate verify A";
case SSL3_ST_SR_CERT_VRFY_B:
- str = "SSLv3 read certificate verify B";
- break;
+ return "SSLv3 read certificate verify B";
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
- str = "DTLS1 read hello verify request A";
- break;
+ return "DTLS1 read hello verify request A";
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
- str = "DTLS1 read hello verify request B";
- break;
+ return "DTLS1 read hello verify request B";
default:
- str = "unknown state";
- break;
+ return "unknown state";
}
-
- return str;
}
-const char *SSL_state_string(const SSL *s) {
- const char *str;
-
- switch (s->state) {
+const char *SSL_state_string(const SSL *ssl) {
+ switch (ssl->state) {
case SSL_ST_ACCEPT:
- str = "AINIT ";
- break;
+ return "AINIT ";
case SSL_ST_CONNECT:
- str = "CINIT ";
- break;
+ return "CINIT ";
case SSL_ST_OK:
- str = "SSLOK ";
- break;
+ return "SSLOK ";
/* SSLv3 additions */
case SSL3_ST_SW_FLUSH:
case SSL3_ST_CW_FLUSH:
- str = "3FLUSH";
- break;
+ return "3FLUSH";
case SSL3_ST_CW_CLNT_HELLO_A:
- str = "3WCH_A";
- break;
+ return "3WCH_A";
case SSL3_ST_CW_CLNT_HELLO_B:
- str = "3WCH_B";
- break;
+ return "3WCH_B";
case SSL3_ST_CR_SRVR_HELLO_A:
- str = "3RSH_A";
- break;
+ return "3RSH_A";
case SSL3_ST_CR_SRVR_HELLO_B:
- str = "3RSH_B";
- break;
+ return "3RSH_B";
case SSL3_ST_CR_CERT_A:
- str = "3RSC_A";
- break;
+ return "3RSC_A";
case SSL3_ST_CR_CERT_B:
- str = "3RSC_B";
- break;
+ return "3RSC_B";
case SSL3_ST_CR_KEY_EXCH_A:
- str = "3RSKEA";
- break;
+ return "3RSKEA";
case SSL3_ST_CR_KEY_EXCH_B:
- str = "3RSKEB";
- break;
+ return "3RSKEB";
case SSL3_ST_CR_CERT_REQ_A:
- str = "3RCR_A";
- break;
+ return "3RCR_A";
case SSL3_ST_CR_CERT_REQ_B:
- str = "3RCR_B";
- break;
+ return "3RCR_B";
case SSL3_ST_CR_SRVR_DONE_A:
- str = "3RSD_A";
- break;
+ return "3RSD_A";
case SSL3_ST_CR_SRVR_DONE_B:
- str = "3RSD_B";
- break;
+ return "3RSD_B";
case SSL3_ST_CW_CERT_A:
- str = "3WCC_A";
- break;
+ return "3WCC_A";
case SSL3_ST_CW_CERT_B:
- str = "3WCC_B";
- break;
+ return "3WCC_B";
case SSL3_ST_CW_CERT_C:
- str = "3WCC_C";
- break;
+ return "3WCC_C";
case SSL3_ST_CW_CERT_D:
- str = "3WCC_D";
- break;
+ return "3WCC_D";
case SSL3_ST_CW_KEY_EXCH_A:
- str = "3WCKEA";
- break;
+ return "3WCKEA";
case SSL3_ST_CW_KEY_EXCH_B:
- str = "3WCKEB";
- break;
+ return "3WCKEB";
case SSL3_ST_CW_CERT_VRFY_A:
- str = "3WCV_A";
- break;
+ return "3WCV_A";
case SSL3_ST_CW_CERT_VRFY_B:
- str = "3WCV_B";
- break;
+ return "3WCV_B";
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_CW_CHANGE_A:
- str = "3WCCSA";
- break;
+ return "3WCCSA";
case SSL3_ST_SW_CHANGE_B:
case SSL3_ST_CW_CHANGE_B:
- str = "3WCCSB";
- break;
+ return "3WCCSB";
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_CW_FINISHED_A:
- str = "3WFINA";
- break;
+ return "3WFINA";
case SSL3_ST_SW_FINISHED_B:
case SSL3_ST_CW_FINISHED_B:
- str = "3WFINB";
- break;
+ return "3WFINB";
case SSL3_ST_CR_CHANGE:
case SSL3_ST_SR_CHANGE:
- str = "3RCCS_";
- break;
+ return "3RCCS_";
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_CR_FINISHED_A:
- str = "3RFINA";
- break;
+ return "3RFINA";
case SSL3_ST_SR_FINISHED_B:
case SSL3_ST_CR_FINISHED_B:
- str = "3RFINB";
- break;
+ return "3RFINB";
case SSL3_ST_SW_HELLO_REQ_A:
- str = "3WHR_A";
- break;
+ return "3WHR_A";
case SSL3_ST_SW_HELLO_REQ_B:
- str = "3WHR_B";
- break;
+ return "3WHR_B";
case SSL3_ST_SW_HELLO_REQ_C:
- str = "3WHR_C";
- break;
+ return "3WHR_C";
case SSL3_ST_SR_CLNT_HELLO_A:
- str = "3RCH_A";
- break;
+ return "3RCH_A";
case SSL3_ST_SR_CLNT_HELLO_B:
- str = "3RCH_B";
- break;
+ return "3RCH_B";
case SSL3_ST_SR_CLNT_HELLO_C:
- str = "3RCH_C";
- break;
+ return "3RCH_C";
case SSL3_ST_SR_CLNT_HELLO_D:
- str = "3RCH_D";
- break;
+ return "3RCH_D";
case SSL3_ST_SW_SRVR_HELLO_A:
- str = "3WSH_A";
- break;
+ return "3WSH_A";
case SSL3_ST_SW_SRVR_HELLO_B:
- str = "3WSH_B";
- break;
+ return "3WSH_B";
case SSL3_ST_SW_CERT_A:
- str = "3WSC_A";
- break;
+ return "3WSC_A";
case SSL3_ST_SW_CERT_B:
- str = "3WSC_B";
- break;
+ return "3WSC_B";
case SSL3_ST_SW_KEY_EXCH_A:
- str = "3WSKEA";
- break;
+ return "3WSKEA";
case SSL3_ST_SW_KEY_EXCH_B:
- str = "3WSKEB";
- break;
+ return "3WSKEB";
case SSL3_ST_SW_CERT_REQ_A:
- str = "3WCR_A";
- break;
+ return "3WCR_A";
case SSL3_ST_SW_CERT_REQ_B:
- str = "3WCR_B";
- break;
+ return "3WCR_B";
case SSL3_ST_SW_SRVR_DONE_A:
- str = "3WSD_A";
- break;
+ return "3WSD_A";
case SSL3_ST_SW_SRVR_DONE_B:
- str = "3WSD_B";
- break;
+ return "3WSD_B";
case SSL3_ST_SR_CERT_A:
- str = "3RCC_A";
- break;
+ return "3RCC_A";
case SSL3_ST_SR_CERT_B:
- str = "3RCC_B";
- break;
+ return "3RCC_B";
case SSL3_ST_SR_KEY_EXCH_A:
- str = "3RCKEA";
- break;
+ return "3RCKEA";
case SSL3_ST_SR_KEY_EXCH_B:
- str = "3RCKEB";
- break;
+ return "3RCKEB";
case SSL3_ST_SR_CERT_VRFY_A:
- str = "3RCV_A";
- break;
+ return "3RCV_A";
case SSL3_ST_SR_CERT_VRFY_B:
- str = "3RCV_B";
- break;
+ return "3RCV_B";
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
- str = "DRCHVA";
- break;
+ return "DRCHVA";
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
- str = "DRCHVB";
- break;
+ return "DRCHVB";
default:
- str = "UNKWN ";
- break;
+ return "UNKWN ";
}
-
- return str;
}
const char *SSL_alert_type_string_long(int value) {
@@ -611,276 +483,109 @@ const char *SSL_alert_type_string_long(int value) {
}
const char *SSL_alert_type_string(int value) {
- value >>= 8;
- if (value == SSL3_AL_WARNING) {
- return "W";
- } else if (value == SSL3_AL_FATAL) {
- return "F";
- }
-
- return "U";
+ return "!";
}
const char *SSL_alert_desc_string(int value) {
- const char *str;
-
- switch (value & 0xff) {
- case SSL3_AD_CLOSE_NOTIFY:
- str = "CN";
- break;
-
- case SSL3_AD_UNEXPECTED_MESSAGE:
- str = "UM";
- break;
-
- case SSL3_AD_BAD_RECORD_MAC:
- str = "BM";
- break;
-
- case SSL3_AD_DECOMPRESSION_FAILURE:
- str = "DF";
- break;
-
- case SSL3_AD_HANDSHAKE_FAILURE:
- str = "HF";
- break;
-
- case SSL3_AD_NO_CERTIFICATE:
- str = "NC";
- break;
-
- case SSL3_AD_BAD_CERTIFICATE:
- str = "BC";
- break;
-
- case SSL3_AD_UNSUPPORTED_CERTIFICATE:
- str = "UC";
- break;
-
- case SSL3_AD_CERTIFICATE_REVOKED:
- str = "CR";
- break;
-
- case SSL3_AD_CERTIFICATE_EXPIRED:
- str = "CE";
- break;
-
- case SSL3_AD_CERTIFICATE_UNKNOWN:
- str = "CU";
- break;
-
- case SSL3_AD_ILLEGAL_PARAMETER:
- str = "IP";
- break;
-
- case TLS1_AD_DECRYPTION_FAILED:
- str = "DC";
- break;
-
- case TLS1_AD_RECORD_OVERFLOW:
- str = "RO";
- break;
-
- case TLS1_AD_UNKNOWN_CA:
- str = "CA";
- break;
-
- case TLS1_AD_ACCESS_DENIED:
- str = "AD";
- break;
-
- case TLS1_AD_DECODE_ERROR:
- str = "DE";
- break;
-
- case TLS1_AD_DECRYPT_ERROR:
- str = "CY";
- break;
-
- case TLS1_AD_EXPORT_RESTRICTION:
- str = "ER";
- break;
-
- case TLS1_AD_PROTOCOL_VERSION:
- str = "PV";
- break;
-
- case TLS1_AD_INSUFFICIENT_SECURITY:
- str = "IS";
- break;
-
- case TLS1_AD_INTERNAL_ERROR:
- str = "IE";
- break;
-
- case TLS1_AD_USER_CANCELLED:
- str = "US";
- break;
-
- case TLS1_AD_NO_RENEGOTIATION:
- str = "NR";
- break;
-
- case TLS1_AD_UNSUPPORTED_EXTENSION:
- str = "UE";
- break;
-
- case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
- str = "CO";
- break;
-
- case TLS1_AD_UNRECOGNIZED_NAME:
- str = "UN";
- break;
-
- case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
- str = "BR";
- break;
-
- case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
- str = "BH";
- break;
-
- case TLS1_AD_UNKNOWN_PSK_IDENTITY:
- str = "UP";
- break;
-
- default:
- str = "UK";
- break;
- }
-
- return str;
+ return "!!";
}
const char *SSL_alert_desc_string_long(int value) {
- const char *str;
-
switch (value & 0xff) {
case SSL3_AD_CLOSE_NOTIFY:
- str = "close notify";
- break;
+ return "close notify";
case SSL3_AD_UNEXPECTED_MESSAGE:
- str = "unexpected_message";
- break;
+ return "unexpected_message";
case SSL3_AD_BAD_RECORD_MAC:
- str = "bad record mac";
- break;
+ return "bad record mac";
case SSL3_AD_DECOMPRESSION_FAILURE:
- str = "decompression failure";
- break;
+ return "decompression failure";
case SSL3_AD_HANDSHAKE_FAILURE:
- str = "handshake failure";
- break;
+ return "handshake failure";
case SSL3_AD_NO_CERTIFICATE:
- str = "no certificate";
- break;
+ return "no certificate";
case SSL3_AD_BAD_CERTIFICATE:
- str = "bad certificate";
- break;
+ return "bad certificate";
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
- str = "unsupported certificate";
- break;
+ return "unsupported certificate";
case SSL3_AD_CERTIFICATE_REVOKED:
- str = "certificate revoked";
- break;
+ return "certificate revoked";
case SSL3_AD_CERTIFICATE_EXPIRED:
- str = "certificate expired";
- break;
+ return "certificate expired";
case SSL3_AD_CERTIFICATE_UNKNOWN:
- str = "certificate unknown";
- break;
+ return "certificate unknown";
case SSL3_AD_ILLEGAL_PARAMETER:
- str = "illegal parameter";
- break;
+ return "illegal parameter";
case TLS1_AD_DECRYPTION_FAILED:
- str = "decryption failed";
- break;
+ return "decryption failed";
case TLS1_AD_RECORD_OVERFLOW:
- str = "record overflow";
- break;
+ return "record overflow";
case TLS1_AD_UNKNOWN_CA:
- str = "unknown CA";
- break;
+ return "unknown CA";
case TLS1_AD_ACCESS_DENIED:
- str = "access denied";
- break;
+ return "access denied";
case TLS1_AD_DECODE_ERROR:
- str = "decode error";
- break;
+ return "decode error";
case TLS1_AD_DECRYPT_ERROR:
- str = "decrypt error";
- break;
+ return "decrypt error";
case TLS1_AD_EXPORT_RESTRICTION:
- str = "export restriction";
- break;
+ return "export restriction";
case TLS1_AD_PROTOCOL_VERSION:
- str = "protocol version";
- break;
+ return "protocol version";
case TLS1_AD_INSUFFICIENT_SECURITY:
- str = "insufficient security";
- break;
+ return "insufficient security";
case TLS1_AD_INTERNAL_ERROR:
- str = "internal error";
- break;
+ return "internal error";
case TLS1_AD_USER_CANCELLED:
- str = "user canceled";
- break;
+ return "user canceled";
case TLS1_AD_NO_RENEGOTIATION:
- str = "no renegotiation";
- break;
+ return "no renegotiation";
case TLS1_AD_UNSUPPORTED_EXTENSION:
- str = "unsupported extension";
- break;
+ return "unsupported extension";
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
- str = "certificate unobtainable";
- break;
+ return "certificate unobtainable";
case TLS1_AD_UNRECOGNIZED_NAME:
- str = "unrecognized name";
- break;
+ return "unrecognized name";
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
- str = "bad certificate status response";
- break;
+ return "bad certificate status response";
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
- str = "bad certificate hash value";
- break;
+ return "bad certificate hash value";
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
- str = "unknown PSK identity";
- break;
+ return "unknown PSK identity";
+
+ case SSL3_AD_INAPPROPRIATE_FALLBACK:
+ return "inappropriate fallback";
default:
- str = "unknown";
- break;
+ return "unknown";
}
-
- return str;
}
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 810d3fa..0cd42a2 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -14,12 +14,15 @@
#include <stdio.h>
#include <string.h>
+#include <time.h>
+#include <algorithm>
#include <string>
#include <vector>
#include <openssl/base64.h>
#include <openssl/bio.h>
+#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
@@ -47,8 +50,8 @@ static const char kRule1[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected1[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
@@ -64,9 +67,9 @@ static const char kRule2[] =
"+aRSA";
static const ExpectedCipher kExpected2[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
};
@@ -80,7 +83,7 @@ static const char kRule3[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected3[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
};
@@ -116,8 +119,8 @@ static const char kRule6[] =
"BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
static const ExpectedCipher kExpected6[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
@@ -130,9 +133,9 @@ static const char kRule7[] =
"ECDHE-RSA-AES128-GCM-SHA256";
static const ExpectedCipher kExpected7[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 1 },
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1 },
{ TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
{ 0, 0 },
};
@@ -154,7 +157,7 @@ static const char kRule8[] =
static const ExpectedCipher kExpected8[] = {
{ TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 },
{ TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 },
{ SSL3_CK_RSA_RC4_128_SHA, 0 },
@@ -172,8 +175,8 @@ static const char kRule9[] =
"!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305";
static const ExpectedCipher kExpected9[] = {
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 },
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 },
{ 0, 0 },
};
@@ -666,9 +669,9 @@ static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
{ TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
// These names are non-standard:
- { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
+ { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
- { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
+ { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
};
@@ -711,6 +714,9 @@ static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
}
memset(session->tlsext_tick, 'a', ticket_len);
session->tlsext_ticklen = ticket_len;
+
+ // Fix up the timeout.
+ session->time = time(NULL);
return session;
}
@@ -818,8 +824,159 @@ static bool TestClientCAList() {
return SSL_get_client_CA_list(ssl.get()) == stack;
}
+static void AppendSession(SSL_SESSION *session, void *arg) {
+ std::vector<SSL_SESSION*> *out =
+ reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
+ out->push_back(session);
+}
+
+// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
+// order.
+static bool ExpectCache(SSL_CTX *ctx,
+ const std::vector<SSL_SESSION*> &expected) {
+ // Check the linked list.
+ SSL_SESSION *ptr = ctx->session_cache_head;
+ for (SSL_SESSION *session : expected) {
+ if (ptr != session) {
+ return false;
+ }
+ // TODO(davidben): This is an absurd way to denote the end of the list.
+ if (ptr->next ==
+ reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
+ ptr = nullptr;
+ } else {
+ ptr = ptr->next;
+ }
+ }
+ if (ptr != nullptr) {
+ return false;
+ }
+
+ // Check the hash table.
+ std::vector<SSL_SESSION*> actual, expected_copy;
+ lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
+ expected_copy = expected;
+
+ std::sort(actual.begin(), actual.end());
+ std::sort(expected_copy.begin(), expected_copy.end());
+
+ return actual == expected_copy;
+}
+
+static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
+ ScopedSSL_SESSION ret(SSL_SESSION_new());
+ if (!ret) {
+ return nullptr;
+ }
+
+ ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+ memset(ret->session_id, 0, ret->session_id_length);
+ memcpy(ret->session_id, &number, sizeof(number));
+ return ret;
+}
+
+// TODO(davidben): Switch this to a |std::vector<ScopedSSL_SESSION>| once we can
+// rely on a move-aware |std::vector|.
+class ScopedSessionVector {
+ public:
+ explicit ScopedSessionVector(std::vector<SSL_SESSION*> *sessions)
+ : sessions_(sessions) {}
+
+ ~ScopedSessionVector() {
+ for (SSL_SESSION *session : *sessions_) {
+ SSL_SESSION_free(session);
+ }
+ }
+
+ private:
+ std::vector<SSL_SESSION*> *const sessions_;
+};
+
+// Test that the internal session cache behaves as expected.
+static bool TestInternalSessionCache() {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+
+ // Prepare 10 test sessions.
+ std::vector<SSL_SESSION*> sessions;
+ ScopedSessionVector cleanup(&sessions);
+ for (int i = 0; i < 10; i++) {
+ ScopedSSL_SESSION session = CreateTestSession(i);
+ if (!session) {
+ return false;
+ }
+ sessions.push_back(session.release());
+ }
+
+ SSL_CTX_sess_set_cache_size(ctx.get(), 5);
+
+ // Insert all the test sessions.
+ for (SSL_SESSION *session : sessions) {
+ if (!SSL_CTX_add_session(ctx.get(), session)) {
+ return false;
+ }
+ }
+
+ // Only the last five should be in the list.
+ std::vector<SSL_SESSION*> expected;
+ expected.push_back(sessions[9]);
+ expected.push_back(sessions[8]);
+ expected.push_back(sessions[7]);
+ expected.push_back(sessions[6]);
+ expected.push_back(sessions[5]);
+ if (!ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Inserting an element already in the cache should fail.
+ if (SSL_CTX_add_session(ctx.get(), sessions[7]) ||
+ !ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Although collisions should be impossible (256-bit session IDs), the cache
+ // must handle them gracefully.
+ ScopedSSL_SESSION collision(CreateTestSession(7));
+ if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
+ return false;
+ }
+ expected.clear();
+ expected.push_back(collision.get());
+ expected.push_back(sessions[9]);
+ expected.push_back(sessions[8]);
+ expected.push_back(sessions[6]);
+ expected.push_back(sessions[5]);
+ if (!ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Removing sessions behaves correctly.
+ if (!SSL_CTX_remove_session(ctx.get(), sessions[6])) {
+ return false;
+ }
+ expected.clear();
+ expected.push_back(collision.get());
+ expected.push_back(sessions[9]);
+ expected.push_back(sessions[8]);
+ expected.push_back(sessions[5]);
+ if (!ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ // Removing sessions requires an exact match.
+ if (SSL_CTX_remove_session(ctx.get(), sessions[0]) ||
+ SSL_CTX_remove_session(ctx.get(), sessions[7]) ||
+ !ExpectCache(ctx.get(), expected)) {
+ return false;
+ }
+
+ return true;
+}
+
int main() {
- SSL_library_init();
+ CRYPTO_library_init();
if (!TestCipherRules() ||
!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
@@ -838,7 +995,8 @@ int main() {
!TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
!TestCipherGetRFCName() ||
!TestPaddingExtension() ||
- !TestClientCAList()) {
+ !TestClientCAList() ||
+ !TestInternalSessionCache()) {
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/ssl/ssl_txt.c b/src/ssl/ssl_txt.c
deleted file mode 100644
index 3ba0887..0000000
--- a/src/ssl/ssl_txt.c
+++ /dev/null
@@ -1,214 +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.]
- */
-/* ====================================================================
- * Copyright 2005 Nokia. All rights reserved.
- *
- * The portions of the attached software ("Contribution") is developed by
- * Nokia Corporation and is licensed pursuant to the OpenSSL open source
- * license.
- *
- * The Contribution, originally written by Mika Kousa and Pasi Eronen of
- * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
- * support (see RFC 4279) to OpenSSL.
- *
- * No patent licenses or other rights except those expressly stated in
- * the OpenSSL open source license shall be deemed granted or received
- * expressly, by implication, estoppel, or otherwise.
- *
- * No assurances are provided by Nokia that the Contribution does not
- * infringe the patent or other intellectual property rights of any third
- * party or that the license provides you with all the necessary rights
- * to make use of the Contribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
- * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
- * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
- * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
- * OTHERWISE. */
-
-#include <openssl/ssl.h>
-
-#include <inttypes.h>
-#include <stdio.h>
-
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/x509.h>
-
-#include "internal.h"
-
-
-int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) {
- BIO *b;
- int ret;
-
- b = BIO_new(BIO_s_file());
- if (b == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
- return 0;
- }
-
- BIO_set_fp(b, fp, BIO_NOCLOSE);
- ret = SSL_SESSION_print(b, x);
- BIO_free(b);
- return ret;
-}
-
-int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) {
- unsigned int i;
- const char *s;
-
- if (x == NULL ||
- BIO_puts(bp, "SSL-Session:\n") <= 0) {
- goto err;
- }
-
- if (x->ssl_version == SSL3_VERSION) {
- s = "SSLv3";
- } else if (x->ssl_version == TLS1_2_VERSION) {
- s = "TLSv1.2";
- } else if (x->ssl_version == TLS1_1_VERSION) {
- s = "TLSv1.1";
- } else if (x->ssl_version == TLS1_VERSION) {
- s = "TLSv1";
- } else if (x->ssl_version == DTLS1_VERSION) {
- s = "DTLSv1";
- } else if (x->ssl_version == DTLS1_2_VERSION) {
- s = "DTLSv1.2";
- } else {
- s = "unknown";
- }
-
- if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) {
- goto err;
- }
-
- if (BIO_printf(bp, " Cipher : %s\n",
- ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0) {
- goto err;
- }
-
- if (BIO_puts(bp, " Session-ID: ") <= 0) {
- goto err;
- }
-
- for (i = 0; i < x->session_id_length; i++) {
- if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) {
- goto err;
- }
- }
-
- if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) {
- goto err;
- }
-
- for (i = 0; i < x->sid_ctx_length; i++) {
- if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) {
- goto err;
- }
- }
-
- if (BIO_puts(bp, "\n Master-Key: ") <= 0) {
- goto err;
- }
-
- for (i = 0; i < (unsigned int)x->master_key_length; i++) {
- if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) {
- goto err;
- }
- }
-
- if (BIO_puts(bp, "\n PSK identity: ") <= 0 ||
- BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) {
- goto err;
- }
-
- if (x->tlsext_tick_lifetime_hint &&
- BIO_printf(bp, "\n TLS session ticket lifetime hint: %" PRIu32
- " (seconds)",
- x->tlsext_tick_lifetime_hint) <= 0) {
- goto err;
- }
-
- if (x->tlsext_tick) {
- if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0 ||
- BIO_hexdump(bp, x->tlsext_tick, x->tlsext_ticklen, 4) <= 0) {
- goto err;
- }
- }
-
- if (x->time != 0L && BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0) {
- goto err;
- }
-
- if (x->timeout != 0L &&
- BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) {
- goto err;
- }
-
- if (BIO_puts(bp, "\n") <= 0 ||
- BIO_puts(bp, " Verify return code: ") <= 0 ||
- BIO_printf(bp, "%ld (%s)\n", x->verify_result,
- X509_verify_cert_error_string(x->verify_result)) <= 0) {
- goto err;
- }
-
- return 1;
-
-err:
- return 0;
-}
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index f30e8eb..a6c48f1 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -122,6 +122,7 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
+#include <openssl/type_check.h>
#include "internal.h"
@@ -308,7 +309,7 @@ char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx) {
return 1;
}
-char SSL_early_callback_ctx_extension_get(
+int SSL_early_callback_ctx_extension_get(
const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
const uint8_t **out_data, size_t *out_len) {
CBS extensions;
@@ -1205,7 +1206,7 @@ static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert,
static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
/* This function isn't used because the ticket extension from the client is
- * handled in ssl_sess.c. */
+ * handled in ssl_session.c. */
return 1;
}
@@ -1374,6 +1375,7 @@ static void ext_npn_init(SSL *ssl) {
static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
if (ssl->s3->initial_handshake_complete ||
ssl->ctx->next_proto_select_cb == NULL ||
+ (ssl->options & SSL_OP_DISABLE_NPN) ||
SSL_IS_DTLS(ssl)) {
return 1;
}
@@ -1398,6 +1400,7 @@ static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
assert(!ssl->s3->initial_handshake_complete);
assert(!SSL_IS_DTLS(ssl));
assert(ssl->ctx->next_proto_select_cb != NULL);
+ assert(!(ssl->options & SSL_OP_DISABLE_NPN));
if (ssl->s3->alpn_selected != NULL) {
/* NPN and ALPN may not be negotiated in the same connection. */
@@ -2228,55 +2231,50 @@ int SSL_extension_supported(unsigned extension_value) {
tls_extension_find(&index, extension_value) != NULL;
}
-/* header_len is the length of the ClientHello header written so far, used to
- * compute padding. It does not include the record header. Pass 0 if no padding
- * is to be done. */
-uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *const buf,
- uint8_t *const limit, size_t header_len) {
+int ssl_add_clienthello_tlsext(SSL *ssl, CBB *out, size_t header_len) {
/* don't add extensions for SSLv3 unless doing secure renegotiation */
- if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) {
- return buf;
+ if (ssl->client_version == SSL3_VERSION &&
+ !ssl->s3->send_connection_binding) {
+ return 1;
}
- CBB cbb, extensions;
- CBB_zero(&cbb);
- if (!CBB_init_fixed(&cbb, buf, limit - buf) ||
- !CBB_add_u16_length_prefixed(&cbb, &extensions)) {
+ size_t orig_len = CBB_len(out);
+ CBB extensions;
+ if (!CBB_add_u16_length_prefixed(out, &extensions)) {
goto err;
}
- s->s3->tmp.extensions.sent = 0;
- s->s3->tmp.custom_extensions.sent = 0;
+ ssl->s3->tmp.extensions.sent = 0;
+ ssl->s3->tmp.custom_extensions.sent = 0;
size_t i;
for (i = 0; i < kNumExtensions; i++) {
if (kExtensions[i].init != NULL) {
- kExtensions[i].init(s);
+ kExtensions[i].init(ssl);
}
}
for (i = 0; i < kNumExtensions; i++) {
const size_t len_before = CBB_len(&extensions);
- if (!kExtensions[i].add_clienthello(s, &extensions)) {
+ if (!kExtensions[i].add_clienthello(ssl, &extensions)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
goto err;
}
if (CBB_len(&extensions) != len_before) {
- s->s3->tmp.extensions.sent |= (1u << i);
+ ssl->s3->tmp.extensions.sent |= (1u << i);
}
}
- if (!custom_ext_add_clienthello(s, &extensions)) {
+ if (!custom_ext_add_clienthello(ssl, &extensions)) {
goto err;
}
- if (header_len > 0) {
- header_len += CBB_len(&extensions);
+ if (!SSL_IS_DTLS(ssl)) {
+ header_len += CBB_len(&extensions) - orig_len;
if (header_len > 0xff && header_len < 0x200) {
- /* Add padding to workaround bugs in F5 terminators. See
- * https://tools.ietf.org/html/draft-agl-tls-padding-03
+ /* Add padding to workaround bugs in F5 terminators. See RFC 7685.
*
* NB: because this code works out the length of all existing extensions
* it MUST always appear last. */
@@ -2301,80 +2299,58 @@ uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *const buf,
}
}
- if (!CBB_flush(&cbb)) {
- goto err;
- }
-
- uint8_t *ret = buf;
- const size_t cbb_len = CBB_len(&cbb);
/* If only two bytes have been written then the extensions are actually empty
* and those two bytes are the zero length. In that case, we don't bother
* sending the extensions length. */
- if (cbb_len > 2) {
- ret += cbb_len;
+ if (CBB_len(&extensions) - orig_len == 2) {
+ CBB_discard_child(out);
}
- CBB_cleanup(&cbb);
- return ret;
+ return CBB_flush(out);
err:
- CBB_cleanup(&cbb);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return NULL;
+ return 0;
}
-uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *const buf,
- uint8_t *const limit) {
- /* don't add extensions for SSLv3, unless doing secure renegotiation */
- if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) {
- return buf;
- }
+int ssl_add_serverhello_tlsext(SSL *ssl, CBB *out) {
+ const size_t orig_len = CBB_len(out);
- CBB cbb, extensions;
- CBB_zero(&cbb);
- if (!CBB_init_fixed(&cbb, buf, limit - buf) ||
- !CBB_add_u16_length_prefixed(&cbb, &extensions)) {
+ CBB extensions;
+ if (!CBB_add_u16_length_prefixed(out, &extensions)) {
goto err;
}
unsigned i;
for (i = 0; i < kNumExtensions; i++) {
- if (!(s->s3->tmp.extensions.received & (1u << i))) {
+ if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
/* Don't send extensions that were not received. */
continue;
}
- if (!kExtensions[i].add_serverhello(s, &extensions)) {
+ if (!kExtensions[i].add_serverhello(ssl, &extensions)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
goto err;
}
}
- if (!custom_ext_add_serverhello(s, &extensions)) {
+ if (!custom_ext_add_serverhello(ssl, &extensions)) {
goto err;
}
- if (!CBB_flush(&cbb)) {
- goto err;
- }
-
- uint8_t *ret = buf;
- const size_t cbb_len = CBB_len(&cbb);
/* If only two bytes have been written then the extensions are actually empty
* and those two bytes are the zero length. In that case, we don't bother
* sending the extensions length. */
- if (cbb_len > 2) {
- ret += cbb_len;
+ if (CBB_len(&extensions) - orig_len == 2) {
+ CBB_discard_child(out);
}
- CBB_cleanup(&cbb);
- return ret;
+ return CBB_flush(out);
err:
- CBB_cleanup(&cbb);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return NULL;
+ return 0;
}
static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
@@ -2413,6 +2389,12 @@ static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
return 0;
}
+ /* RFC 5746 made the existence of extensions in SSL 3.0 somewhat
+ * ambiguous. Ignore all but the renegotiation_info extension. */
+ if (s->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) {
+ continue;
+ }
+
unsigned ext_index;
const struct tls_extension *const ext =
tls_extension_find(&ext_index, type);
@@ -2468,9 +2450,10 @@ int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
return 1;
}
+OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(uint32_t) * 8, too_many_bits);
+
static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
uint32_t received = 0;
- assert(kNumExtensions <= sizeof(received) * 8);
if (CBS_len(cbs) != 0) {
/* Decode the extensions block and check it is valid. */
@@ -2605,10 +2588,6 @@ static int ssl_check_serverhello_tlsext(SSL *s) {
int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs) {
int alert = -1;
- if (s->version < SSL3_VERSION) {
- return 1;
- }
-
if (ssl_scan_serverhello_tlsext(s, cbs, &alert) <= 0) {
ssl3_send_alert(s, SSL3_AL_FATAL, alert);
return 0;
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index edae67b..3f4e9cf 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -39,6 +39,7 @@
#include <openssl/buf.h>
#include <openssl/bytestring.h>
#include <openssl/cipher.h>
+#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
@@ -96,10 +97,10 @@ struct TestState {
bool handshake_done = false;
// private_key is the underlying private key used when testing custom keys.
ScopedEVP_PKEY private_key;
- std::vector<uint8_t> signature;
- // signature_retries is the number of times an asynchronous sign operation has
- // been retried.
- unsigned signature_retries = 0;
+ std::vector<uint8_t> private_key_result;
+ // private_key_retries is the number of times an asynchronous private key
+ // operation has been retried.
+ unsigned private_key_retries = 0;
bool got_new_session = false;
};
@@ -152,7 +153,7 @@ static ssl_private_key_result_t AsyncPrivateKeySign(
SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
const EVP_MD *md, const uint8_t *in, size_t in_len) {
TestState *test_state = GetTestState(ssl);
- if (!test_state->signature.empty()) {
+ if (!test_state->private_key_result.empty()) {
fprintf(stderr, "AsyncPrivateKeySign called with operation pending.\n");
abort();
}
@@ -170,42 +171,103 @@ static ssl_private_key_result_t AsyncPrivateKeySign(
!EVP_PKEY_sign(ctx.get(), nullptr, &len, in, in_len)) {
return ssl_private_key_failure;
}
- test_state->signature.resize(len);
- if (!EVP_PKEY_sign(ctx.get(), bssl::vector_data(&test_state->signature), &len,
- in, in_len)) {
+ test_state->private_key_result.resize(len);
+ if (!EVP_PKEY_sign(ctx.get(), bssl::vector_data(
+ &test_state->private_key_result), &len, in, in_len)) {
return ssl_private_key_failure;
}
- test_state->signature.resize(len);
+ test_state->private_key_result.resize(len);
- // The signature will be released asynchronously in |AsyncPrivateKeySignComplete|.
+ // The signature will be released asynchronously in
+ // |AsyncPrivateKeySignComplete|.
return ssl_private_key_retry;
}
static ssl_private_key_result_t AsyncPrivateKeySignComplete(
SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
TestState *test_state = GetTestState(ssl);
- if (test_state->signature.empty()) {
+ if (test_state->private_key_result.empty()) {
fprintf(stderr,
"AsyncPrivateKeySignComplete called without operation pending.\n");
abort();
}
- if (test_state->signature_retries < 2) {
+ if (test_state->private_key_retries < 2) {
// Only return the signature on the second attempt, to test both incomplete
// |sign| and |sign_complete|.
return ssl_private_key_retry;
}
- if (max_out < test_state->signature.size()) {
+ if (max_out < test_state->private_key_result.size()) {
fprintf(stderr, "Output buffer too small.\n");
return ssl_private_key_failure;
}
- memcpy(out, bssl::vector_data(&test_state->signature),
- test_state->signature.size());
- *out_len = test_state->signature.size();
+ memcpy(out, bssl::vector_data(&test_state->private_key_result),
+ test_state->private_key_result.size());
+ *out_len = test_state->private_key_result.size();
- test_state->signature.clear();
- test_state->signature_retries = 0;
+ test_state->private_key_result.clear();
+ test_state->private_key_retries = 0;
+ return ssl_private_key_success;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeyDecrypt(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const uint8_t *in, size_t in_len) {
+ TestState *test_state = GetTestState(ssl);
+ if (!test_state->private_key_result.empty()) {
+ fprintf(stderr,
+ "AsyncPrivateKeyDecrypt called with operation pending.\n");
+ abort();
+ }
+
+ EVP_PKEY *pkey = test_state->private_key.get();
+ if (pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
+ fprintf(stderr,
+ "AsyncPrivateKeyDecrypt called with incorrect key type.\n");
+ abort();
+ }
+ RSA *rsa = pkey->pkey.rsa;
+ test_state->private_key_result.resize(RSA_size(rsa));
+ if (!RSA_decrypt(rsa, out_len,
+ bssl::vector_data(&test_state->private_key_result),
+ RSA_size(rsa), in, in_len, RSA_NO_PADDING)) {
+ return ssl_private_key_failure;
+ }
+
+ test_state->private_key_result.resize(*out_len);
+
+ // The decryption will be released asynchronously in
+ // |AsyncPrivateKeyDecryptComplete|.
+ return ssl_private_key_retry;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeyDecryptComplete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ TestState *test_state = GetTestState(ssl);
+ if (test_state->private_key_result.empty()) {
+ fprintf(stderr,
+ "AsyncPrivateKeyDecryptComplete called without operation "
+ "pending.\n");
+ abort();
+ }
+
+ if (test_state->private_key_retries < 2) {
+ // Only return the decryption on the second attempt, to test both incomplete
+ // |decrypt| and |decrypt_complete|.
+ return ssl_private_key_retry;
+ }
+
+ if (max_out < test_state->private_key_result.size()) {
+ fprintf(stderr, "Output buffer too small.\n");
+ return ssl_private_key_failure;
+ }
+ memcpy(out, bssl::vector_data(&test_state->private_key_result),
+ test_state->private_key_result.size());
+ *out_len = test_state->private_key_result.size();
+
+ test_state->private_key_result.clear();
+ test_state->private_key_retries = 0;
return ssl_private_key_success;
}
@@ -214,6 +276,8 @@ static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
AsyncPrivateKeyMaxSignatureLen,
AsyncPrivateKeySign,
AsyncPrivateKeySignComplete,
+ AsyncPrivateKeyDecrypt,
+ AsyncPrivateKeyDecryptComplete
};
template<typename T>
@@ -249,7 +313,7 @@ static bool InstallCertificate(SSL *ssl) {
}
if (!config->key_file.empty()) {
- if (config->use_async_private_key) {
+ if (config->async) {
test_state->private_key = LoadPrivateKey(config->key_file.c_str());
if (!test_state->private_key) {
return false;
@@ -678,7 +742,7 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
SSL_CTX_set_session_cache_mode(ssl_ctx.get(), SSL_SESS_CACHE_BOTH);
}
- ssl_ctx->select_certificate_cb = SelectCertificateCallback;
+ SSL_CTX_set_select_certificate_cb(ssl_ctx.get(), SelectCertificateCallback);
SSL_CTX_set_next_protos_advertised_cb(
ssl_ctx.get(), NextProtosAdvertisedCallback, NULL);
@@ -788,7 +852,7 @@ static bool RetryAsync(SSL *ssl, int ret) {
// The handshake will resume without a second call to the early callback.
return InstallCertificate(ssl);
case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
- test_state->signature_retries++;
+ test_state->private_key_retries++;
return true;
default:
return false;
@@ -863,7 +927,7 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
(!SSL_session_reused(ssl) || config->expect_ticket_renewal);
if (expect_new_session != GetTestState(ssl)->got_new_session) {
fprintf(stderr,
- "new session was%s established, but we expected the opposite\n",
+ "new session was%s cached, but we expected the opposite\n",
GetTestState(ssl)->got_new_session ? "" : " not");
return false;
}
@@ -1114,13 +1178,18 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->install_ddos_callback) {
SSL_CTX_set_dos_protection_cb(ssl_ctx, DDoSCallback);
}
- if (!config->reject_peer_renegotiations) {
- /* Renegotiations are disabled by default. */
- SSL_set_reject_peer_renegotiations(ssl.get(), 0);
+ if (config->renegotiate_once) {
+ SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_once);
+ }
+ if (config->renegotiate_freely) {
+ SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
}
if (!config->check_close_notify) {
SSL_set_quiet_shutdown(ssl.get(), 1);
}
+ if (config->disable_npn) {
+ SSL_set_options(ssl.get(), SSL_OP_DISABLE_NPN);
+ }
int sock = Connect(config->port);
if (sock == -1) {
@@ -1333,6 +1402,14 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
return false;
}
+ if (SSL_total_renegotiations(ssl.get()) !=
+ config->expect_total_renegotiations) {
+ fprintf(stderr, "Expected %d renegotiations, got %d\n",
+ config->expect_total_renegotiations,
+ SSL_total_renegotiations(ssl.get()));
+ return false;
+ }
+
return true;
}
@@ -1354,9 +1431,7 @@ int main(int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
#endif
- if (!SSL_library_init()) {
- return 1;
- }
+ CRYPTO_library_init();
g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
g_state_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, TestStateExFree);
if (g_config_index < 0 || g_state_index < 0) {
diff --git a/src/ssl/test/runner/alert.go b/src/ssl/test/runner/alert.go
index b48ab2a..541216e 100644
--- a/src/ssl/test/runner/alert.go
+++ b/src/ssl/test/runner/alert.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import "strconv"
diff --git a/src/ssl/test/runner/chacha20_poly1305.go b/src/ssl/test/runner/chacha20_poly1305.go
index 42911d4..f2a1bbf 100644
--- a/src/ssl/test/runner/chacha20_poly1305.go
+++ b/src/ssl/test/runner/chacha20_poly1305.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"crypto/cipher"
diff --git a/src/ssl/test/runner/chacha20_poly1305_test.go b/src/ssl/test/runner/chacha20_poly1305_test.go
index 726f482..be49b11 100644
--- a/src/ssl/test/runner/chacha20_poly1305_test.go
+++ b/src/ssl/test/runner/chacha20_poly1305_test.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"bytes"
diff --git a/src/ssl/test/runner/cipher_suites.go b/src/ssl/test/runner/cipher_suites.go
index ffc056d..c406000 100644
--- a/src/ssl/test/runner/cipher_suites.go
+++ b/src/ssl/test/runner/cipher_suites.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"crypto/aes"
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 77be9f6..7defec1 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"container/list"
@@ -773,6 +773,15 @@ type ProtocolBugs struct {
// NegotiateALPNAndNPN, if true, causes the server to negotiate both
// ALPN and NPN in the same connetion.
NegotiateALPNAndNPN bool
+
+ // SendEmptySessionTicket, if true, causes the server to send an empty
+ // session ticket.
+ SendEmptySessionTicket bool
+
+ // FailIfSessionOffered, if true, causes the server to fail any
+ // connections where the client offers a non-empty session ID or session
+ // ticket.
+ FailIfSessionOffered bool
}
func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index 39bdfda..986e2b5 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -4,7 +4,7 @@
// TLS low level connection and record layer
-package main
+package runner
import (
"bytes"
diff --git a/src/ssl/test/runner/dtls.go b/src/ssl/test/runner/dtls.go
index 5c59dea..fac035e 100644
--- a/src/ssl/test/runner/dtls.go
+++ b/src/ssl/test/runner/dtls.go
@@ -12,7 +12,7 @@
// with simulated loss, but there is no point in forcing the test
// driver to.
-package main
+package runner
import (
"bytes"
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index a3ce686..9d8ffee 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"bytes"
@@ -833,6 +833,10 @@ func (hs *clientHandshakeState) readSessionTicket() error {
return nil
}
+ if c.vers == VersionSSL30 {
+ return errors.New("tls: negotiated session tickets in SSL 3.0")
+ }
+
msg, err := c.readHandshake()
if err != nil {
return err
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index da85e7a..530ddbc 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import "bytes"
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 068dff9..9647715 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"bytes"
@@ -358,6 +358,10 @@ Curves:
return false, errors.New("tls: offered resumption on renegotiation")
}
+ if c.config.Bugs.FailIfSessionOffered && (len(hs.clientHello.sessionTicket) > 0 || len(hs.clientHello.sessionId) > 0) {
+ return false, errors.New("tls: client offered a session ticket or ID")
+ }
+
if hs.checkForResumption() {
return true, nil
}
@@ -866,10 +870,12 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
m := new(newSessionTicketMsg)
- var err error
- m.ticket, err = c.encryptTicket(&state)
- if err != nil {
- return err
+ if !c.config.Bugs.SendEmptySessionTicket {
+ var err error
+ m.ticket, err = c.encryptTicket(&state)
+ if err != nil {
+ return err
+ }
}
hs.writeServerHash(m.marshal())
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index 2ee0087..3a9b899 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"crypto"
diff --git a/src/ssl/test/runner/packet_adapter.go b/src/ssl/test/runner/packet_adapter.go
index bbcd388..b432659 100644
--- a/src/ssl/test/runner/packet_adapter.go
+++ b/src/ssl/test/runner/packet_adapter.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"encoding/binary"
diff --git a/src/ssl/test/runner/poly1305.go b/src/ssl/test/runner/poly1305.go
index 51a1009..edef338 100644
--- a/src/ssl/test/runner/poly1305.go
+++ b/src/ssl/test/runner/poly1305.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
// Based on original, public domain implementation from NaCl by D. J.
// Bernstein.
diff --git a/src/ssl/test/runner/prf.go b/src/ssl/test/runner/prf.go
index d445e76..8521aba 100644
--- a/src/ssl/test/runner/prf.go
+++ b/src/ssl/test/runner/prf.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"crypto"
diff --git a/src/ssl/test/runner/recordingconn.go b/src/ssl/test/runner/recordingconn.go
index a67fa48..6537714 100644
--- a/src/ssl/test/runner/recordingconn.go
+++ b/src/ssl/test/runner/recordingconn.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"bufio"
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 269a955..17fdff9 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -1,4 +1,4 @@
-package main
+package runner
import (
"bytes"
@@ -149,6 +149,9 @@ type testCase struct {
// expectedNextProto controls whether the connection should
// negotiate a next protocol via NPN or ALPN.
expectedNextProto string
+ // expectNoNextProto, if true, means that no next protocol should be
+ // negotiated.
+ expectNoNextProto bool
// expectedNextProtoType, if non-zero, is the expected next
// protocol negotiation mechanism.
expectedNextProtoType int
@@ -203,9 +206,9 @@ type testCase struct {
// connection immediately after the handshake rather than echoing
// messages from the runner.
shimShutsDown bool
- // renegotiate indicates the the connection should be renegotiated
- // during the exchange.
- renegotiate bool
+ // renegotiate indicates the number of times the connection should be
+ // renegotiated during the exchange.
+ renegotiate int
// renegotiateCiphers is a list of ciphersuite ids that will be
// switched in just before renegotiation.
renegotiateCiphers []uint16
@@ -328,6 +331,12 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) er
}
}
+ if test.expectNoNextProto {
+ if actual := connState.NegotiatedProtocol; actual != "" {
+ return fmt.Errorf("got unexpected next proto %s", actual)
+ }
+ }
+
if test.expectedNextProtoType != 0 {
if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
return fmt.Errorf("next proto type mismatch")
@@ -394,12 +403,14 @@ func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) er
tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
}
- if test.renegotiate {
+ if test.renegotiate > 0 {
if test.renegotiateCiphers != nil {
config.CipherSuites = test.renegotiateCiphers
}
- if err := tlsConn.Renegotiate(); err != nil {
- return err
+ for i := 0; i < test.renegotiate; i++ {
+ if err := tlsConn.Renegotiate(); err != nil {
+ return err
+ }
}
} else if test.renegotiateCiphers != nil {
panic("renegotiateCiphers without renegotiate")
@@ -1960,6 +1971,18 @@ func addBasicTests() {
// does not fail.
expectMessageDropped: true,
},
+ {
+ name: "SendEmptySessionTicket",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendEmptySessionTicket: true,
+ FailIfSessionOffered: true,
+ },
+ },
+ flags: []string{"-expect-no-session"},
+ resumeSession: true,
+ expectResumeRejected: true,
+ },
}
testCases = append(testCases, basicTests...)
}
@@ -2562,7 +2585,7 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
// TLS client auth.
tests = append(tests, testCase{
testType: clientTest,
- name: "ClientAuth-Client",
+ name: "ClientAuth-RSA-Client",
config: Config{
ClientAuth: RequireAnyClientCert,
},
@@ -2571,35 +2594,50 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
"-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-ECDSA-Client",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
+ },
+ })
if async {
+ // Test async keys against each key exchange.
tests = append(tests, testCase{
- testType: clientTest,
- name: "ClientAuth-Client-AsyncKey",
+ testType: serverTest,
+ name: "Basic-Server-RSA",
config: Config{
- ClientAuth: RequireAnyClientCert,
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
},
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
- "-use-async-private-key",
},
})
tests = append(tests, testCase{
testType: serverTest,
- name: "Basic-Server-RSAAsyncKey",
+ name: "Basic-Server-ECDHE-RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ },
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
- "-use-async-private-key",
},
})
tests = append(tests, testCase{
testType: serverTest,
- name: "Basic-Server-ECDSAAsyncKey",
+ name: "Basic-Server-ECDHE-ECDSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ },
flags: []string{
"-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
"-key-file", path.Join(*resourceDir, ecdsaKeyFile),
- "-use-async-private-key",
},
})
}
@@ -2701,7 +2739,11 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
if protocol == tls {
tests = append(tests, testCase{
name: "Renegotiate-Client",
- renegotiate: true,
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
// NPN on client and server; results in post-handshake message.
tests = append(tests, testCase{
@@ -3339,6 +3381,18 @@ func addExtensionTests() {
shouldFail: true,
expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
})
+ // Test that NPN can be disabled with SSL_OP_DISABLE_NPN.
+ testCases = append(testCases, testCase{
+ name: "DisableNPN",
+ config: Config{
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-select-next-proto", "foo",
+ "-disable-npn",
+ },
+ expectNoNextProto: true,
+ })
// Resume with a corrupt ticket.
testCases = append(testCases, testCase{
testType: serverTest,
@@ -3492,6 +3546,68 @@ func addExtensionTests() {
// long.
flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
})
+
+ // Extensions should not function in SSL 3.0.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-NoALPN",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ NextProtos: []string{"foo", "bar", "baz"},
+ },
+ flags: []string{
+ "-select-alpn", "foo",
+ },
+ expectNoNextProto: true,
+ })
+
+ // Test session tickets separately as they follow a different codepath.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-NoTickets",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ Bugs: ProtocolBugs{
+ // Historically, session tickets in SSL 3.0
+ // failed in different ways depending on whether
+ // the client supported renegotiation_info.
+ NoRenegotiationInfo: true,
+ },
+ },
+ resumeSession: true,
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-NoTickets2",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ },
+ resumeSession: true,
+ })
+
+ // But SSL 3.0 does send and process renegotiation_info.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-RenegotiationInfo",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ Bugs: ProtocolBugs{
+ RequireRenegotiationInfo: true,
+ },
+ },
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SSLv3Extensions-RenegotiationInfo-SCSV",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfo: true,
+ SendRenegotiationSCSV: true,
+ RequireRenegotiationInfo: true,
+ },
+ },
+ })
}
func addResumptionVersionTests() {
@@ -3603,8 +3719,7 @@ func addRenegotiationTests() {
testCases = append(testCases, testCase{
testType: serverTest,
name: "Renegotiate-Server-Forbidden",
- renegotiate: true,
- flags: []string{"-reject-peer-renegotiations"},
+ renegotiate: 1,
shouldFail: true,
expectedError: ":NO_RENEGOTIATION:",
expectedLocalError: "remote error: no renegotiation",
@@ -3643,27 +3758,33 @@ func addRenegotiationTests() {
FailIfResumeOnRenego: true,
},
},
- renegotiate: true,
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-EmptyExt",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
EmptyRenegotiationInfo: true,
},
},
+ flags: []string{"-renegotiate-freely"},
shouldFail: true,
expectedError: ":RENEGOTIATION_MISMATCH:",
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-BadExt",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
BadRenegotiationInfo: true,
},
},
+ flags: []string{"-renegotiate-freely"},
shouldFail: true,
expectedError: ":RENEGOTIATION_MISMATCH:",
})
@@ -3680,50 +3801,58 @@ func addRenegotiationTests() {
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-NoExt-Allowed",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
Bugs: ProtocolBugs{
NoRenegotiationInfo: true,
},
},
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-SwitchCiphers",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
},
renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-Client-SwitchCiphers2",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
},
renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- })
- testCases = append(testCases, testCase{
- name: "Renegotiate-Client-Forbidden",
- renegotiate: true,
- flags: []string{"-reject-peer-renegotiations"},
- shouldFail: true,
- expectedError: ":NO_RENEGOTIATION:",
- expectedLocalError: "remote error: no renegotiation",
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-SameClientVersion",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
MaxVersion: VersionTLS10,
Bugs: ProtocolBugs{
RequireSameRenegoClientVersion: true,
},
},
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
})
testCases = append(testCases, testCase{
name: "Renegotiate-FalseStart",
- renegotiate: true,
+ renegotiate: 1,
config: Config{
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"foo"},
@@ -3731,9 +3860,52 @@ func addRenegotiationTests() {
flags: []string{
"-false-start",
"-select-next-proto", "foo",
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
},
shimWritesFirst: true,
})
+
+ // Client-side renegotiation controls.
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Forbidden-1",
+ renegotiate: 1,
+ shouldFail: true,
+ expectedError: ":NO_RENEGOTIATION:",
+ expectedLocalError: "remote error: no renegotiation",
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Once-1",
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-once",
+ "-expect-total-renegotiations", "1",
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Freely-1",
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Once-2",
+ renegotiate: 2,
+ flags: []string{"-renegotiate-once"},
+ shouldFail: true,
+ expectedError: ":NO_RENEGOTIATION:",
+ expectedLocalError: "remote error: no renegotiation",
+ })
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-Freely-2",
+ renegotiate: 2,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "2",
+ },
+ })
}
func addDTLSReplayTests() {
diff --git a/src/ssl/test/runner/runner_test.go b/src/ssl/test/runner/runner_test.go
new file mode 100644
index 0000000..320ff52
--- /dev/null
+++ b/src/ssl/test/runner/runner_test.go
@@ -0,0 +1,7 @@
+package runner
+
+import "testing"
+
+func TestAll(t *testing.T) {
+ main()
+}
diff --git a/src/ssl/test/runner/test_output.go b/src/ssl/test/runner/test_output.go
index bcb7a93..2112092 100644
--- a/src/ssl/test/runner/test_output.go
+++ b/src/ssl/test/runner/test_output.go
@@ -12,7 +12,7 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-package main
+package runner
import (
"encoding/json"
diff --git a/src/ssl/test/runner/ticket.go b/src/ssl/test/runner/ticket.go
index 8355822..e121c05 100644
--- a/src/ssl/test/runner/ticket.go
+++ b/src/ssl/test/runner/ticket.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package main
+package runner
import (
"bytes"
diff --git a/src/ssl/test/runner/tls.go b/src/ssl/test/runner/tls.go
index 6b637c8..24f9b1e 100644
--- a/src/ssl/test/runner/tls.go
+++ b/src/ssl/test/runner/tls.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package tls partially implements TLS 1.2, as specified in RFC 5246.
-package main
+package runner
import (
"crypto"
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 1c42b2e..abec0e1 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -76,10 +76,8 @@ const Flag<bool> kBoolFlags[] = {
{ "-fail-second-ddos-callback", &TestConfig::fail_second_ddos_callback },
{ "-handshake-never-done", &TestConfig::handshake_never_done },
{ "-use-export-context", &TestConfig::use_export_context },
- { "-reject-peer-renegotiations", &TestConfig::reject_peer_renegotiations },
{ "-no-legacy-server-connect", &TestConfig::no_legacy_server_connect },
{ "-tls-unique", &TestConfig::tls_unique },
- { "-use-async-private-key", &TestConfig::use_async_private_key },
{ "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
{ "-expect-no-session", &TestConfig::expect_no_session },
{ "-use-ticket-callback", &TestConfig::use_ticket_callback },
@@ -95,7 +93,10 @@ const Flag<bool> kBoolFlags[] = {
{ "-microsoft-big-sslv3-buffer", &TestConfig::microsoft_big_sslv3_buffer },
{ "-verify-fail", &TestConfig::verify_fail },
{ "-verify-peer", &TestConfig::verify_peer },
- { "-expect-verify-result", &TestConfig::expect_verify_result }
+ { "-expect-verify-result", &TestConfig::expect_verify_result },
+ { "-renegotiate-once", &TestConfig::renegotiate_once },
+ { "-renegotiate-freely", &TestConfig::renegotiate_freely },
+ { "-disable-npn", &TestConfig::disable_npn },
};
const Flag<std::string> kStringFlags[] = {
@@ -138,6 +139,7 @@ const Flag<int> kIntFlags[] = {
{ "-max-version", &TestConfig::max_version },
{ "-mtu", &TestConfig::mtu },
{ "-export-keying-material", &TestConfig::export_keying_material },
+ { "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations },
};
} // namespace
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 9dea8e9..23fa1f1 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -77,10 +77,8 @@ struct TestConfig {
std::string export_label;
std::string export_context;
bool use_export_context = false;
- bool reject_peer_renegotiations = false;
bool no_legacy_server_connect = false;
bool tls_unique = false;
- bool use_async_private_key = false;
bool expect_ticket_renewal = false;
bool expect_no_session = false;
bool use_ticket_callback = false;
@@ -97,6 +95,10 @@ struct TestConfig {
bool verify_peer = false;
bool expect_verify_result = false;
std::string signed_cert_timestamps;
+ int expect_total_renegotiations = 0;
+ bool renegotiate_once = false;
+ bool renegotiate_freely = false;
+ bool disable_npn = false;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c
index 36e31b4..bdc5c01 100644
--- a/src/ssl/tls_record.c
+++ b/src/ssl/tls_record.c
@@ -114,6 +114,7 @@
#include <openssl/err.h>
#include "internal.h"
+#include "../crypto/internal.h"
/* kMaxEmptyRecords is the number of consecutive, empty records that will be
@@ -122,6 +123,16 @@
* forever. */
static const uint8_t kMaxEmptyRecords = 32;
+static struct CRYPTO_STATIC_MUTEX g_big_buffer_lock = CRYPTO_STATIC_MUTEX_INIT;
+static uint64_t g_big_buffer_use_count = 0;
+
+uint64_t OPENSSL_get_big_buffer_use_count(void) {
+ CRYPTO_STATIC_MUTEX_lock_read(&g_big_buffer_lock);
+ uint64_t ret = g_big_buffer_use_count;
+ CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock);
+ return ret;
+}
+
size_t ssl_record_prefix_len(const SSL *ssl) {
if (SSL_IS_DTLS(ssl)) {
return DTLS1_RT_HEADER_LENGTH +
@@ -230,6 +241,14 @@ enum ssl_open_record_t tls_open_record(
return ssl_open_record_error;
}
+ if (extra > 0 &&
+ (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH ||
+ plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH)) {
+ CRYPTO_STATIC_MUTEX_lock_write(&g_big_buffer_lock);
+ g_big_buffer_use_count++;
+ CRYPTO_STATIC_MUTEX_unlock(&g_big_buffer_lock);
+ }
+
/* Limit the number of consecutive empty records. */
if (plaintext_len == 0) {
ssl->s3->empty_record_count++;
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index 307b0b9..39bbadb 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -458,8 +458,10 @@ bool Speed(const std::vector<std::string> &args) {
if (!SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) ||
!SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", kTLSADLen, selected) ||
- !SpeedAEAD(EVP_aead_chacha20_poly1305(), "ChaCha20-Poly1305", kTLSADLen,
- selected) ||
+ !SpeedAEAD(EVP_aead_chacha20_poly1305_rfc7539(), "ChaCha20-Poly1305",
+ kTLSADLen, selected) ||
+ !SpeedAEAD(EVP_aead_chacha20_poly1305_old(), "ChaCha20-Poly1305-Old",
+ kTLSADLen, selected) ||
!SpeedAEAD(EVP_aead_rc4_md5_tls(), "RC4-MD5", kLegacyADLen, selected) ||
!SpeedAEAD(EVP_aead_aes_128_cbc_sha1_tls(), "AES-128-CBC-SHA1",
kLegacyADLen, selected) ||
diff --git a/src/tool/tool.cc b/src/tool/tool.cc
index e4d5201..f67f0c7 100644
--- a/src/tool/tool.cc
+++ b/src/tool/tool.cc
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
+#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
@@ -109,7 +110,7 @@ int main(int argc, char **argv) {
}
#endif
- SSL_library_init();
+ CRYPTO_library_init();
int starting_arg = 1;
tool_func_t tool = nullptr;
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 98f0f95..cfda6c3 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -133,19 +133,19 @@ out:
}
bool Accept(int *out_sock, const std::string &port) {
- struct sockaddr_in addr, cli_addr;
+ struct sockaddr_in6 addr, cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons(atoi(port.c_str()));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_addr = in6addr_any;
+ addr.sin6_port = htons(atoi(port.c_str()));
bool ok = false;
int server_sock = -1;
server_sock =
- socket(addr.sin_family, SOCK_STREAM, 0);
+ socket(addr.sin6_family, SOCK_STREAM, 0);
if (server_sock < 0) {
perror("socket");
goto out;
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
index a6daa2f..ba57cc7 100644
--- a/src/util/all_tests.json
+++ b/src/util/all_tests.json
@@ -9,6 +9,7 @@
["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"],
["crypto/cipher/aead_test", "aes-256-key-wrap", "crypto/cipher/test/aes_256_key_wrap_tests.txt"],
["crypto/cipher/aead_test", "chacha20-poly1305", "crypto/cipher/test/chacha20_poly1305_tests.txt"],
+ ["crypto/cipher/aead_test", "chacha20-poly1305-old", "crypto/cipher/test/chacha20_poly1305_old_tests.txt"],
["crypto/cipher/aead_test", "rc4-md5-tls", "crypto/cipher/test/rc4_md5_tls_tests.txt"],
["crypto/cipher/aead_test", "rc4-sha1-tls", "crypto/cipher/test/rc4_sha1_tls_tests.txt"],
["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt"],
diff --git a/src/util/bot/go/bootstrap.py b/src/util/bot/go/bootstrap.py
index 166ef3b..4a52d9e 100755
--- a/src/util/bot/go/bootstrap.py
+++ b/src/util/bot/go/bootstrap.py
@@ -45,12 +45,11 @@ WORKSPACE = os.path.join(ROOT, 'go')
EXE_SFX = '.exe' if sys.platform == 'win32' else ''
# Pinned version of Go toolset to download.
-TOOLSET_VERSION = 'go1.4'
+TOOLSET_VERSION = 'go1.5.1'
# Platform dependent portion of a download URL. See http://golang.org/dl/.
TOOLSET_VARIANTS = {
- ('darwin', 'x86-32'): 'darwin-386-osx10.8.tar.gz',
- ('darwin', 'x86-64'): 'darwin-amd64-osx10.8.tar.gz',
+ ('darwin', 'x86-64'): 'darwin-amd64.tar.gz',
('linux2', 'x86-32'): 'linux-386.tar.gz',
('linux2', 'x86-64'): 'linux-amd64.tar.gz',
('win32', 'x86-32'): 'windows-386.zip',
diff --git a/src/util/doc.config b/src/util/doc.config
index a427e04..77498ee 100644
--- a/src/util/doc.config
+++ b/src/util/doc.config
@@ -16,7 +16,6 @@
"include/openssl/obj.h",
"include/openssl/rand.h",
"include/openssl/stack.h",
- "include/openssl/thread.h",
"include/openssl/time_support.h"
]
},{
@@ -35,7 +34,6 @@
"include/openssl/engine.h",
"include/openssl/hmac.h",
"include/openssl/md5.h",
- "include/openssl/modes.h",
"include/openssl/rc4.h",
"include/openssl/rsa.h",
"include/openssl/sha.h"
diff --git a/src/util/doc.go b/src/util/doc.go
index 23cd5f4..ce7a3e8 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -42,6 +42,8 @@ type HeaderFile struct {
// is a separate paragraph.
Preamble []string
Sections []HeaderSection
+ // AllDecls maps all decls to their URL fragments.
+ AllDecls map[string]string
}
type HeaderSection struct {
@@ -237,6 +239,10 @@ func sanitizeAnchor(name string) string {
return strings.Replace(name, " ", "-", -1)
}
+func isPrivateSection(name string) bool {
+ return strings.HasPrefix(name, "Private functions") || strings.HasPrefix(name, "Private structures") || strings.Contains(name, "(hidden)")
+}
+
func (config *Config) parseHeader(path string) (*HeaderFile, error) {
headerPath := filepath.Join(config.BaseDirectory, path)
@@ -278,7 +284,8 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
lines = lines[2:]
header := &HeaderFile{
- Name: filepath.Base(path),
+ Name: filepath.Base(path),
+ AllDecls: make(map[string]string),
}
for i, line := range lines {
@@ -341,7 +348,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
}
section.Preamble = comment
- section.IsPrivate = len(comment) > 0 && strings.HasPrefix(comment[0], "Private functions")
+ section.IsPrivate = len(comment) > 0 && isPrivateSection(comment[0])
section.Anchor = anchor
lines = rest[1:]
lineNo = restLineNo + 1
@@ -387,6 +394,8 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
// duplicate table-of-contents entries.
allAnchors[anchor] = struct{}{}
+ header.AllDecls[name] = anchor
+
section.Decls = append(section.Decls, HeaderDecl{
Comment: comment,
Name: name,
@@ -422,7 +431,7 @@ func firstSentence(paragraphs []string) string {
return s
}
-func markupPipeWords(s string) template.HTML {
+func markupPipeWords(allDecls map[string]string, s string) template.HTML {
ret := ""
for {
@@ -438,7 +447,14 @@ func markupPipeWords(s string) template.HTML {
j := strings.Index(s, " ")
if i > 0 && (j == -1 || j > i) {
ret += "<tt>"
+ anchor, isLink := allDecls[s[:i]]
+ if isLink {
+ ret += fmt.Sprintf("<a href=\"%s\">", template.HTMLEscapeString(anchor))
+ }
ret += s[:i]
+ if isLink {
+ ret += "</a>"
+ }
ret += "</tt>"
s = s[i+1:]
} else {
@@ -456,6 +472,11 @@ again:
if end > 0 {
end += start
w := strings.ToLower(string(s[start:end]))
+ // The first word was already marked up as an HTML tag. Don't
+ // mark it up further.
+ if strings.ContainsRune(w, '<') {
+ return s
+ }
if w == "a" || w == "an" {
start = end + 1
goto again
@@ -476,10 +497,12 @@ func newlinesToBR(html template.HTML) template.HTML {
}
func generate(outPath string, config *Config) (map[string]string, error) {
+ allDecls := make(map[string]string)
+
headerTmpl := template.New("headerTmpl")
headerTmpl.Funcs(template.FuncMap{
"firstSentence": firstSentence,
- "markupPipeWords": markupPipeWords,
+ "markupPipeWords": func(s string) template.HTML { return markupPipeWords(allDecls, s) },
"markupFirstWord": markupFirstWord,
"newlinesToBR": newlinesToBR,
})
@@ -510,23 +533,19 @@ func generate(outPath string, config *Config) (map[string]string, error) {
{{range .Sections}}
{{if not .IsPrivate}}
- <div class="section">
+ <div class="section" {{if .Anchor}}id="{{.Anchor}}"{{end}}>
{{if .Preamble}}
<div class="sectionpreamble">
- <a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
{{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}}
- </a>
</div>
{{end}}
{{range .Decls}}
- <div class="decl">
- <a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
+ <div class="decl" {{if .Anchor}}id="{{.Anchor}}"{{end}}>
{{range .Comment}}
<p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p>
{{end}}
<pre>{{.Decl}}</pre>
- </a>
</div>
{{end}}
</div>
@@ -540,6 +559,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
}
headerDescriptions := make(map[string]string)
+ var headers []*HeaderFile
for _, section := range config.Sections {
for _, headerPath := range section.Headers {
@@ -548,18 +568,26 @@ func generate(outPath string, config *Config) (map[string]string, error) {
return nil, errors.New("while parsing " + headerPath + ": " + err.Error())
}
headerDescriptions[header.Name] = firstSentence(header.Preamble)
- filename := filepath.Join(outPath, header.Name+".html")
- file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
- if err != nil {
- panic(err)
- }
- defer file.Close()
- if err := headerTmpl.Execute(file, header); err != nil {
- return nil, err
+ headers = append(headers, header)
+
+ for name, anchor := range header.AllDecls {
+ allDecls[name] = fmt.Sprintf("%s#%s", header.Name+".html", anchor)
}
}
}
+ for _, header := range headers {
+ filename := filepath.Join(outPath, header.Name+".html")
+ file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
+ if err != nil {
+ panic(err)
+ }
+ defer file.Close()
+ if err := headerTmpl.Execute(file, header); err != nil {
+ return nil, err
+ }
+ }
+
return headerDescriptions, nil
}
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 2eae98a..856960e 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -190,7 +190,7 @@ class Bazel(object):
out.write(']\n')
def WriteFiles(self, files, asm_outputs):
- with open('BUILD.generated', 'w+') as out:
+ with open('BUILD.generated.bzl', 'w+') as out:
out.write(self.header)
self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers'])
@@ -204,12 +204,10 @@ class Bazel(object):
self.PrintVariableSection(out, 'tool_sources', files['tool'])
for ((osname, arch), asm_files) in asm_outputs:
- if osname is not 'linux':
- continue
self.PrintVariableSection(
- out, 'crypto_sources_%s' % arch, asm_files)
+ out, 'crypto_sources_%s_%s' % (osname, arch), asm_files)
- with open('BUILD.generated_tests', 'w+') as out:
+ with open('BUILD.generated_tests.bzl', 'w+') as out:
out.write(self.header)
out.write('test_support_sources = [\n')
@@ -217,8 +215,12 @@ class Bazel(object):
if os.path.basename(filename) == 'malloc.cc':
continue
out.write(' "%s",\n' % filename)
- out.write('] + glob(["src/crypto/test/*.h"])\n\n')
+ out.write(']\n\n')
+
+ out.write('def create_tests(copts):\n')
+ out.write(' test_support_sources_complete = test_support_sources + \\\n')
+ out.write(' native.glob(["src/crypto/test/*.h"])\n')
name_counts = {}
for test in files['tests']:
name = os.path.basename(test[0])
@@ -245,39 +247,39 @@ class Bazel(object):
else:
raise ValueError("Can't find source for %s" % test[0])
- out.write('cc_test(\n')
- out.write(' name = "%s",\n' % name)
- out.write(' size = "small",\n')
- out.write(' srcs = ["%s"] + test_support_sources,\n' % src)
+ out.write(' native.cc_test(\n')
+ out.write(' name = "%s",\n' % name)
+ out.write(' size = "small",\n')
+ out.write(' srcs = ["%s"] + test_support_sources_complete,\n' % src)
data_files = []
if len(test) > 1:
- out.write(' args = [\n')
+ out.write(' args = [\n')
for arg in test[1:]:
if '/' in arg:
- out.write(' "$(location src/%s)",\n' % arg)
+ out.write(' "$(location src/%s)",\n' % arg)
data_files.append('src/%s' % arg)
else:
- out.write(' "%s",\n' % arg)
- out.write(' ],\n')
+ out.write(' "%s",\n' % arg)
+ out.write(' ],\n')
- out.write(' copts = boringssl_copts,\n')
+ out.write(' copts = copts,\n')
if len(data_files) > 0:
- out.write(' data = [\n')
+ out.write(' data = [\n')
for filename in data_files:
- out.write(' "%s",\n' % filename)
- out.write(' ],\n')
+ out.write(' "%s",\n' % filename)
+ out.write(' ],\n')
if 'ssl/' in test[0]:
- out.write(' deps = [\n')
- out.write(' ":crypto",\n')
- out.write(' ":ssl",\n')
- out.write(' ],\n')
+ out.write(' deps = [\n')
+ out.write(' ":crypto",\n')
+ out.write(' ":ssl",\n')
+ out.write(' ],\n')
else:
- out.write(' deps = [":crypto"],\n')
- out.write(')\n')
+ out.write(' deps = [":crypto"],\n')
+ out.write(' )\n')
def FindCMakeFiles(directory):
diff --git a/win-x86/crypto/sha/sha1-586.asm b/win-x86/crypto/sha/sha1-586.asm
index e24449d..43bf964 100644
--- a/win-x86/crypto/sha/sha1-586.asm
+++ b/win-x86/crypto/sha/sha1-586.asm
@@ -35,8 +35,6 @@ L$000pic_point:
mov ecx,DWORD [8+esi]
test eax,16777216
jz NEAR L$001x86
- test ecx,536870912
- jnz NEAR L$shaext_shortcut
jmp NEAR L$ssse3_shortcut
align 16
L$001x86:
@@ -1405,7 +1403,7 @@ L$002loop:
pop ebp
ret
align 16
-__sha1_block_data_order_shaext:
+__sha1_block_data_order_ssse3:
push ebp
push ebx
push esi
@@ -1414,174 +1412,6 @@ __sha1_block_data_order_shaext:
L$003pic_point:
pop ebp
lea ebp,[(L$K_XX_XX-L$003pic_point)+ebp]
-L$shaext_shortcut:
- mov edi,DWORD [20+esp]
- mov ebx,esp
- mov esi,DWORD [24+esp]
- mov ecx,DWORD [28+esp]
- sub esp,32
- movdqu xmm0,[edi]
- movd xmm1,DWORD [16+edi]
- and esp,-32
- movdqa xmm3,[80+ebp]
- movdqu xmm4,[esi]
- pshufd xmm0,xmm0,27
- movdqu xmm5,[16+esi]
- pshufd xmm1,xmm1,27
- movdqu xmm6,[32+esi]
-db 102,15,56,0,227
- movdqu xmm7,[48+esi]
-db 102,15,56,0,235
-db 102,15,56,0,243
-db 102,15,56,0,251
- jmp NEAR L$004loop_shaext
-align 16
-L$004loop_shaext:
- dec ecx
- lea eax,[64+esi]
- movdqa [esp],xmm1
- paddd xmm1,xmm4
- cmovne esi,eax
- movdqa [16+esp],xmm0
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,0
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,0
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,0
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,0
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,0
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,1
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,1
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,1
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,1
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,1
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,2
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,2
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
-db 15,56,201,229
- movdqa xmm2,xmm0
-db 15,58,204,193,2
-db 15,56,200,213
- pxor xmm4,xmm6
-db 15,56,201,238
-db 15,56,202,231
- movdqa xmm1,xmm0
-db 15,58,204,194,2
-db 15,56,200,206
- pxor xmm5,xmm7
-db 15,56,202,236
-db 15,56,201,247
- movdqa xmm2,xmm0
-db 15,58,204,193,2
-db 15,56,200,215
- pxor xmm6,xmm4
-db 15,56,201,252
-db 15,56,202,245
- movdqa xmm1,xmm0
-db 15,58,204,194,3
-db 15,56,200,204
- pxor xmm7,xmm5
-db 15,56,202,254
- movdqu xmm4,[esi]
- movdqa xmm2,xmm0
-db 15,58,204,193,3
-db 15,56,200,213
- movdqu xmm5,[16+esi]
-db 102,15,56,0,227
- movdqa xmm1,xmm0
-db 15,58,204,194,3
-db 15,56,200,206
- movdqu xmm6,[32+esi]
-db 102,15,56,0,235
- movdqa xmm2,xmm0
-db 15,58,204,193,3
-db 15,56,200,215
- movdqu xmm7,[48+esi]
-db 102,15,56,0,243
- movdqa xmm1,xmm0
-db 15,58,204,194,3
- movdqa xmm2,[esp]
-db 102,15,56,0,251
-db 15,56,200,202
- paddd xmm0,[16+esp]
- jnz NEAR L$004loop_shaext
- pshufd xmm0,xmm0,27
- pshufd xmm1,xmm1,27
- movdqu [edi],xmm0
- movd DWORD [16+edi],xmm1
- mov esp,ebx
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-align 16
-__sha1_block_data_order_ssse3:
- push ebp
- push ebx
- push esi
- push edi
- call L$005pic_point
-L$005pic_point:
- pop ebp
- lea ebp,[(L$K_XX_XX-L$005pic_point)+ebp]
L$ssse3_shortcut:
movdqa xmm7,[ebp]
movdqa xmm0,[16+ebp]
@@ -1634,9 +1464,9 @@ db 102,15,56,0,222
xor ebp,edx
pshufd xmm4,xmm0,238
and esi,ebp
- jmp NEAR L$006loop
+ jmp NEAR L$004loop
align 16
-L$006loop:
+L$004loop:
ror ebx,2
xor esi,edx
mov ebp,eax
@@ -2539,7 +2369,7 @@ L$006loop:
add ecx,edx
mov ebp,DWORD [196+esp]
cmp ebp,DWORD [200+esp]
- je NEAR L$007done
+ je NEAR L$005done
movdqa xmm7,[160+esp]
movdqa xmm6,[176+esp]
movdqu xmm0,[ebp]
@@ -2674,9 +2504,9 @@ db 102,15,56,0,222
pshufd xmm4,xmm0,238
and esi,ebx
mov ebx,ebp
- jmp NEAR L$006loop
+ jmp NEAR L$004loop
align 16
-L$007done:
+L$005done:
add ebx,DWORD [16+esp]
xor esi,edi
mov ebp,ecx
diff --git a/win-x86/crypto/sha/sha256-586.asm b/win-x86/crypto/sha/sha256-586.asm
index fe36bc5..d03558c 100644
--- a/win-x86/crypto/sha/sha256-586.asm
+++ b/win-x86/crypto/sha/sha256-586.asm
@@ -49,17 +49,15 @@ L$000pic_point:
jz NEAR L$003no_xmm
and ecx,1073741824
and ebx,268435968
- test edx,536870912
- jnz NEAR L$004shaext
or ecx,ebx
and ecx,1342177280
cmp ecx,1342177280
test ebx,512
- jnz NEAR L$005SSSE3
+ jnz NEAR L$004SSSE3
L$003no_xmm:
sub eax,edi
cmp eax,256
- jae NEAR L$006unrolled
+ jae NEAR L$005unrolled
jmp NEAR L$002loop
align 16
L$002loop:
@@ -131,7 +129,7 @@ L$002loop:
mov DWORD [28+esp],ecx
mov DWORD [32+esp],edi
align 16
-L$00700_15:
+L$00600_15:
mov ecx,edx
mov esi,DWORD [24+esp]
ror ecx,14
@@ -169,11 +167,11 @@ L$00700_15:
add ebp,4
add eax,ebx
cmp esi,3248222580
- jne NEAR L$00700_15
+ jne NEAR L$00600_15
mov ecx,DWORD [156+esp]
- jmp NEAR L$00816_63
+ jmp NEAR L$00716_63
align 16
-L$00816_63:
+L$00716_63:
mov ebx,ecx
mov esi,DWORD [104+esp]
ror ecx,11
@@ -228,7 +226,7 @@ L$00816_63:
add ebp,4
add eax,ebx
cmp esi,3329325298
- jne NEAR L$00816_63
+ jne NEAR L$00716_63
mov esi,DWORD [356+esp]
mov ebx,DWORD [8+esp]
mov ecx,DWORD [16+esp]
@@ -272,7 +270,7 @@ db 67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97
db 112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103
db 62,0
align 16
-L$006unrolled:
+L$005unrolled:
lea esp,[esp-96]
mov eax,DWORD [esi]
mov ebp,DWORD [4+esi]
@@ -289,9 +287,9 @@ L$006unrolled:
mov DWORD [20+esp],ebx
mov DWORD [24+esp],ecx
mov DWORD [28+esp],esi
- jmp NEAR L$009grand_loop
+ jmp NEAR L$008grand_loop
align 16
-L$009grand_loop:
+L$008grand_loop:
mov ebx,DWORD [edi]
mov ecx,DWORD [4+edi]
bswap ebx
@@ -3171,7 +3169,7 @@ L$009grand_loop:
mov DWORD [24+esp],ebx
mov DWORD [28+esp],ecx
cmp edi,DWORD [104+esp]
- jb NEAR L$009grand_loop
+ jb NEAR L$008grand_loop
mov esp,DWORD [108+esp]
pop edi
pop esi
@@ -3179,205 +3177,7 @@ L$009grand_loop:
pop ebp
ret
align 32
-L$004shaext:
- sub esp,32
- movdqu xmm1,[esi]
- lea ebp,[128+ebp]
- movdqu xmm2,[16+esi]
- movdqa xmm7,[128+ebp]
- pshufd xmm0,xmm1,27
- pshufd xmm1,xmm1,177
- pshufd xmm2,xmm2,27
-db 102,15,58,15,202,8
- punpcklqdq xmm2,xmm0
- jmp NEAR L$010loop_shaext
-align 16
-L$010loop_shaext:
- movdqu xmm3,[edi]
- movdqu xmm4,[16+edi]
- movdqu xmm5,[32+edi]
-db 102,15,56,0,223
- movdqu xmm6,[48+edi]
- movdqa [16+esp],xmm2
- movdqa xmm0,[ebp-128]
- paddd xmm0,xmm3
-db 102,15,56,0,231
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- nop
- movdqa [esp],xmm1
-db 15,56,203,202
- movdqa xmm0,[ebp-112]
- paddd xmm0,xmm4
-db 102,15,56,0,239
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- lea edi,[64+edi]
-db 15,56,204,220
-db 15,56,203,202
- movdqa xmm0,[ebp-96]
- paddd xmm0,xmm5
-db 102,15,56,0,247
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm6
-db 102,15,58,15,253,4
- nop
- paddd xmm3,xmm7
-db 15,56,204,229
-db 15,56,203,202
- movdqa xmm0,[ebp-80]
- paddd xmm0,xmm6
-db 15,56,205,222
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm3
-db 102,15,58,15,254,4
- nop
- paddd xmm4,xmm7
-db 15,56,204,238
-db 15,56,203,202
- movdqa xmm0,[ebp-64]
- paddd xmm0,xmm3
-db 15,56,205,227
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm4
-db 102,15,58,15,251,4
- nop
- paddd xmm5,xmm7
-db 15,56,204,243
-db 15,56,203,202
- movdqa xmm0,[ebp-48]
- paddd xmm0,xmm4
-db 15,56,205,236
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm5
-db 102,15,58,15,252,4
- nop
- paddd xmm6,xmm7
-db 15,56,204,220
-db 15,56,203,202
- movdqa xmm0,[ebp-32]
- paddd xmm0,xmm5
-db 15,56,205,245
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm6
-db 102,15,58,15,253,4
- nop
- paddd xmm3,xmm7
-db 15,56,204,229
-db 15,56,203,202
- movdqa xmm0,[ebp-16]
- paddd xmm0,xmm6
-db 15,56,205,222
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm3
-db 102,15,58,15,254,4
- nop
- paddd xmm4,xmm7
-db 15,56,204,238
-db 15,56,203,202
- movdqa xmm0,[ebp]
- paddd xmm0,xmm3
-db 15,56,205,227
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm4
-db 102,15,58,15,251,4
- nop
- paddd xmm5,xmm7
-db 15,56,204,243
-db 15,56,203,202
- movdqa xmm0,[16+ebp]
- paddd xmm0,xmm4
-db 15,56,205,236
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm5
-db 102,15,58,15,252,4
- nop
- paddd xmm6,xmm7
-db 15,56,204,220
-db 15,56,203,202
- movdqa xmm0,[32+ebp]
- paddd xmm0,xmm5
-db 15,56,205,245
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm6
-db 102,15,58,15,253,4
- nop
- paddd xmm3,xmm7
-db 15,56,204,229
-db 15,56,203,202
- movdqa xmm0,[48+ebp]
- paddd xmm0,xmm6
-db 15,56,205,222
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm3
-db 102,15,58,15,254,4
- nop
- paddd xmm4,xmm7
-db 15,56,204,238
-db 15,56,203,202
- movdqa xmm0,[64+ebp]
- paddd xmm0,xmm3
-db 15,56,205,227
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm4
-db 102,15,58,15,251,4
- nop
- paddd xmm5,xmm7
-db 15,56,204,243
-db 15,56,203,202
- movdqa xmm0,[80+ebp]
- paddd xmm0,xmm4
-db 15,56,205,236
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- movdqa xmm7,xmm5
-db 102,15,58,15,252,4
-db 15,56,203,202
- paddd xmm6,xmm7
- movdqa xmm0,[96+ebp]
- paddd xmm0,xmm5
-db 15,56,203,209
- pshufd xmm0,xmm0,14
-db 15,56,205,245
- movdqa xmm7,[128+ebp]
-db 15,56,203,202
- movdqa xmm0,[112+ebp]
- paddd xmm0,xmm6
- nop
-db 15,56,203,209
- pshufd xmm0,xmm0,14
- cmp eax,edi
- nop
-db 15,56,203,202
- paddd xmm2,[16+esp]
- paddd xmm1,[esp]
- jnz NEAR L$010loop_shaext
- pshufd xmm2,xmm2,177
- pshufd xmm7,xmm1,27
- pshufd xmm1,xmm1,177
- punpckhqdq xmm1,xmm2
-db 102,15,58,15,215,8
- mov esp,DWORD [44+esp]
- movdqu [esi],xmm1
- movdqu [16+esi],xmm2
- pop edi
- pop esi
- pop ebx
- pop ebp
- ret
-align 32
-L$005SSSE3:
+L$004SSSE3:
lea esp,[esp-96]
mov eax,DWORD [esi]
mov ebx,DWORD [4+esi]
@@ -3396,9 +3196,9 @@ L$005SSSE3:
mov DWORD [24+esp],ecx
mov DWORD [28+esp],esi
movdqa xmm7,[256+ebp]
- jmp NEAR L$011grand_ssse3
+ jmp NEAR L$009grand_ssse3
align 16
-L$011grand_ssse3:
+L$009grand_ssse3:
movdqu xmm0,[edi]
movdqu xmm1,[16+edi]
movdqu xmm2,[32+edi]
@@ -3421,9 +3221,9 @@ db 102,15,56,0,223
paddd xmm7,xmm3
movdqa [64+esp],xmm6
movdqa [80+esp],xmm7
- jmp NEAR L$012ssse3_00_47
+ jmp NEAR L$010ssse3_00_47
align 16
-L$012ssse3_00_47:
+L$010ssse3_00_47:
add ebp,64
mov ecx,edx
movdqa xmm4,xmm1
@@ -4066,7 +3866,7 @@ db 102,15,58,15,249,4
add eax,ecx
movdqa [80+esp],xmm6
cmp DWORD [64+ebp],66051
- jne NEAR L$012ssse3_00_47
+ jne NEAR L$010ssse3_00_47
mov ecx,edx
ror edx,14
mov esi,DWORD [20+esp]
@@ -4580,7 +4380,7 @@ db 102,15,58,15,249,4
movdqa xmm7,[64+ebp]
sub ebp,192
cmp edi,DWORD [104+esp]
- jb NEAR L$011grand_ssse3
+ jb NEAR L$009grand_ssse3
mov esp,DWORD [108+esp]
pop edi
pop esi