summaryrefslogtreecommitdiffstats
path: root/src/crypto
diff options
context:
space:
mode:
authorAdam Langley <agl@google.com>2015-10-30 13:15:30 -0700
committerAdam Langley <agl@google.com>2015-10-30 13:39:01 -0700
commitfdeb488e6332a17729db5a04236e48a46a019272 (patch)
treeb4e43f0c1d2161af97e2b7e030644ca1d54a839c /src/crypto
parent6e19d4dc059301bed57d7dae7750c69fecb51b15 (diff)
downloadexternal_boringssl-fdeb488e6332a17729db5a04236e48a46a019272.zip
external_boringssl-fdeb488e6332a17729db5a04236e48a46a019272.tar.gz
external_boringssl-fdeb488e6332a17729db5a04236e48a46a019272.tar.bz2
external/boringssl: sync with upstream.
See the following URL for a list of the changes included in this sync: https://boringssl.googlesource.com/boringssl/+log/d98dc1311e20193ac188e359e91aeaaf5cc3a7e2..51a01a5cd44b3bdfab5220847000f13fc85f000b Change-Id: I36535827f652536dfd687c1646bbea1535fc8e44
Diffstat (limited to 'src/crypto')
-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
118 files changed, 3776 insertions, 1563 deletions
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)