external/boringssl: Sync to 9f0e7cb314ae64234b928fd379381ae9760a9a5f. am: 15c0b3594b am: 0bd8f8c09f
am: 7a510ed57f
Change-Id: I427127e3a3b422eb02add996564f346ca106667a
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index a472103..6346331 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-f11ea19043f2b3ee42e4a76d0645914347e1a36e
+9f0e7cb314ae64234b928fd379381ae9760a9a5f
diff --git a/src/crypto/asn1/a_strnid.c b/src/crypto/asn1/a_strnid.c
index 379a79f..efbf0fa 100644
--- a/src/crypto/asn1/a_strnid.c
+++ b/src/crypto/asn1/a_strnid.c
@@ -223,6 +223,7 @@
return ttmp;
if (!stable)
return NULL;
+ sk_ASN1_STRING_TABLE_sort(stable);
found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd);
if (!found)
return NULL;
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index 9f4639f..5752712 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -164,31 +164,21 @@
#endif
}
-const char *SSLeay_version(int unused) {
- return "BoringSSL";
-}
+const char *SSLeay_version(int unused) { return "BoringSSL"; }
-const char *OpenSSL_version(int unused) {
- return "BoringSSL";
-}
+const char *OpenSSL_version(int unused) { return "BoringSSL"; }
-unsigned long SSLeay(void) {
- return OPENSSL_VERSION_NUMBER;
-}
+unsigned long SSLeay(void) { return OPENSSL_VERSION_NUMBER; }
-unsigned long OpenSSL_version_num(void) {
- return OPENSSL_VERSION_NUMBER;
-}
+unsigned long OpenSSL_version_num(void) { return OPENSSL_VERSION_NUMBER; }
-int CRYPTO_malloc_init(void) {
- return 1;
-}
+int CRYPTO_malloc_init(void) { return 1; }
+
+int OPENSSL_malloc_init(void) { return 1; }
void ENGINE_load_builtin_engines(void) {}
-int ENGINE_register_all_complete(void) {
- return 1;
-}
+int ENGINE_register_all_complete(void) { return 1; }
void OPENSSL_load_builtin_modules(void) {}
diff --git a/src/crypto/stack/stack.c b/src/crypto/stack/stack.c
index f6b4412..7aa3218 100644
--- a/src/crypto/stack/stack.c
+++ b/src/crypto/stack/stack.c
@@ -223,7 +223,7 @@
return NULL;
}
-int sk_find(_STACK *sk, size_t *out_index, void *p) {
+int sk_find(const _STACK *sk, size_t *out_index, void *p) {
if (sk == NULL) {
return 0;
}
@@ -245,7 +245,17 @@
return 0;
}
- sk_sort(sk);
+ if (!sk_is_sorted(sk)) {
+ for (size_t i = 0; i < sk->num; i++) {
+ if (sk->comp((const void **)&p, (const void **)&sk->data[i]) == 0) {
+ if (out_index) {
+ *out_index = i;
+ }
+ return 1;
+ }
+ }
+ return 0;
+ }
// sk->comp is a function that takes pointers to pointers to elements, but
// qsort and bsearch take a comparison function that just takes pointers to
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index 635b851..b3bfffe 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -387,6 +387,7 @@
*/
CRYPTO_MUTEX_lock_write(&xl->store_ctx->objs_lock);
tmp = NULL;
+ sk_X509_OBJECT_sort(xl->store_ctx->objs);
if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) {
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx);
}
@@ -404,6 +405,7 @@
*/
if (!hent) {
htmp.hash = h;
+ sk_BY_DIR_HASH_sort(ent->hashes);
if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp))
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
}
@@ -422,6 +424,7 @@
ok = 0;
goto finish;
}
+ sk_BY_DIR_HASH_sort(ent->hashes);
} else if (hent->suffix < k)
hent->suffix = k;
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index 1a841db..ea01427 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -473,6 +473,7 @@
}
size_t idx;
+ sk_X509_OBJECT_sort(h);
if (!sk_X509_OBJECT_find(h, &idx, &stmp))
return -1;
@@ -604,6 +605,7 @@
size_t idx, i;
X509_OBJECT *obj;
+ sk_X509_OBJECT_sort(h);
if (!sk_X509_OBJECT_find(h, &idx, x)) {
return NULL;
}
diff --git a/src/crypto/x509/x509_trs.c b/src/crypto/x509/x509_trs.c
index c7dfcad..f899424 100644
--- a/src/crypto/x509/x509_trs.c
+++ b/src/crypto/x509/x509_trs.c
@@ -158,6 +158,7 @@
tmp.trust = id;
if (!trtable)
return -1;
+ sk_X509_TRUST_sort(trtable);
if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
return -1;
}
diff --git a/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 43353c6..84ec838 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/crypto/x509/x509_vpm.c
@@ -614,6 +614,7 @@
} else {
size_t idx;
+ sk_X509_VERIFY_PARAM_sort(param_table);
if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) {
ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
X509_VERIFY_PARAM_free(ptmp);
@@ -649,6 +650,7 @@
pm.name = (char *)name;
if (param_table) {
size_t idx;
+ sk_X509_VERIFY_PARAM_sort(param_table);
if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm))
return sk_X509_VERIFY_PARAM_value(param_table, idx);
}
diff --git a/src/crypto/x509v3/pcy_cache.c b/src/crypto/x509v3/pcy_cache.c
index b8a4be2..755c079 100644
--- a/src/crypto/x509v3/pcy_cache.c
+++ b/src/crypto/x509v3/pcy_cache.c
@@ -93,6 +93,7 @@
/*
* Duplicate policy OIDs are illegal: reject if matches found.
*/
+ sk_X509_POLICY_DATA_sort(cache->data);
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
if (cache->anyPolicy) {
ret = -1;
@@ -262,6 +263,7 @@
X509_POLICY_DATA tmp;
tmp.valid_policy = (ASN1_OBJECT *)id;
+ sk_X509_POLICY_DATA_sort(cache->data);
if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp))
return NULL;
return sk_X509_POLICY_DATA_value(cache->data, idx);
diff --git a/src/crypto/x509v3/pcy_node.c b/src/crypto/x509v3/pcy_node.c
index b3edfe4..6682282 100644
--- a/src/crypto/x509v3/pcy_node.c
+++ b/src/crypto/x509v3/pcy_node.c
@@ -83,6 +83,7 @@
n.valid_policy = (ASN1_OBJECT *)id;
l.data = &n;
+ sk_X509_POLICY_NODE_sort(nodes);
if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l))
return NULL;
diff --git a/src/crypto/x509v3/pcy_tree.c b/src/crypto/x509v3/pcy_tree.c
index 256fe88..136b45f 100644
--- a/src/crypto/x509v3/pcy_tree.c
+++ b/src/crypto/x509v3/pcy_tree.c
@@ -543,9 +543,11 @@
*pnodes = policy_node_cmp_new();
if (!*pnodes)
return 0;
- } else if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
+ } else {
+ sk_X509_POLICY_NODE_sort(*pnodes);
+ if (sk_X509_POLICY_NODE_find(*pnodes, NULL, pcy))
return 1;
-
+ }
if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
return 0;
diff --git a/src/crypto/x509v3/v3_lib.c b/src/crypto/x509v3/v3_lib.c
index 8f5435d..d5eda3d 100644
--- a/src/crypto/x509v3/v3_lib.c
+++ b/src/crypto/x509v3/v3_lib.c
@@ -116,6 +116,7 @@
if (!ext_list)
return NULL;
+ sk_X509V3_EXT_METHOD_sort(ext_list);
if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp))
return NULL;
return sk_X509V3_EXT_METHOD_value(ext_list, idx);
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 324de85..f70a804 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -205,6 +205,7 @@
if (!xptable)
return -1;
+ sk_X509_PURPOSE_sort(xptable);
if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp))
return -1;
return idx + X509_PURPOSE_COUNT;
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index 7d109ee..589e296 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -650,6 +650,7 @@
if (!*sk)
return 0;
/* Don't add duplicates */
+ sk_OPENSSL_STRING_sort(*sk);
if (sk_OPENSSL_STRING_find(*sk, NULL, (char *)email->data))
return 1;
emtmp = BUF_strdup((char *)email->data);
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index bd41d11..e2d15fa 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -155,7 +155,7 @@
// A consumer may use this symbol in the preprocessor to temporarily build
// against multiple revisions of BoringSSL at the same time. It is not
// recommended to do so for longer than is necessary.
-#define BORINGSSL_API_VERSION 7
+#define BORINGSSL_API_VERSION 8
#if defined(BORINGSSL_SHARED_LIBRARY)
diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h
index ccf5012..cc6fc3c 100644
--- a/src/include/openssl/crypto.h
+++ b/src/include/openssl/crypto.h
@@ -92,6 +92,9 @@
// CRYPTO_malloc_init returns one.
OPENSSL_EXPORT int CRYPTO_malloc_init(void);
+// OPENSSL_malloc_init returns one.
+OPENSSL_EXPORT int OPENSSL_malloc_init(void);
+
// ENGINE_load_builtin_engines does nothing.
OPENSSL_EXPORT void ENGINE_load_builtin_engines(void);
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index d22d396..2922473 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -1749,6 +1749,15 @@
OPENSSL_EXPORT uint32_t
SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session);
+// SSL_SESSION_get0_cipher returns the cipher negotiated by the connection which
+// established |session|.
+//
+// Note that, in TLS 1.3, there is no guarantee that resumptions with |session|
+// will use that cipher. Prefer calling |SSL_get_current_cipher| on the |SSL|
+// instead.
+OPENSSL_EXPORT const SSL_CIPHER *SSL_SESSION_get0_cipher(
+ const SSL_SESSION *session);
+
// Session caching.
//
diff --git a/src/include/openssl/stack.h b/src/include/openssl/stack.h
index 625f66e..6975db6 100644
--- a/src/include/openssl/stack.h
+++ b/src/include/openssl/stack.h
@@ -163,12 +163,17 @@
OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, void *p);
// sk_find returns the first value in the stack equal to |p|. If a comparison
-// function has been set on the stack, then equality is defined by it and the
-// stack will be sorted if need be so that a binary search can be used.
-// Otherwise pointer equality is used. If a matching element is found, its
-// index is written to |*out_index| (if |out_index| is not NULL) and one is
-// returned. Otherwise zero is returned.
-OPENSSL_EXPORT int sk_find(_STACK *sk, size_t *out_index, void *p);
+// function has been set on the stack, equality is defined by it, otherwise
+// pointer equality is used. If the stack is sorted, then a binary search is
+// used, otherwise a linear search is performed. If a matching element is found,
+// its index is written to
+// |*out_index| (if |out_index| is not NULL) and one is returned. Otherwise zero
+// is returned.
+//
+// Note this differs from OpenSSL. The type signature is slightly different, and
+// OpenSSL's sk_find will implicitly sort |sk| if it has a comparison function
+// defined.
+OPENSSL_EXPORT int sk_find(const _STACK *sk, size_t *out_index, void *p);
// sk_shift removes and returns the first element in the stack, or returns NULL
// if the stack is empty.
@@ -302,8 +307,8 @@
} \
\
static inline OPENSSL_UNUSED int sk_##name##_find( \
- STACK_OF(name) *sk, size_t *out_index, ptrtype p) { \
- return sk_find((_STACK *)sk, out_index, (void *)p); \
+ const STACK_OF(name) *sk, size_t *out_index, ptrtype p) { \
+ return sk_find((const _STACK *)sk, out_index, (void *)p); \
} \
\
static inline OPENSSL_UNUSED ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \
diff --git a/src/ssl/dtls_record.cc b/src/ssl/dtls_record.cc
index 5e795fa..d348601 100644
--- a/src/ssl/dtls_record.cc
+++ b/src/ssl/dtls_record.cc
@@ -219,8 +219,8 @@
return ssl_open_record_discard;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER,
- in.subspan(0, DTLS1_RT_HEADER_LENGTH));
+ Span<const uint8_t> header = in.subspan(0, DTLS1_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header);
uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1];
if (epoch != ssl->d1->r_epoch ||
@@ -235,7 +235,7 @@
// discard the body in-place.
if (!ssl->s3->aead_read_ctx->Open(
- out, type, version, sequence,
+ out, type, version, sequence, header,
MakeSpan(const_cast<uint8_t *>(CBS_data(&body)), CBS_len(&body)))) {
// Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
// Clear the error queue of any errors decryption may have added. Drop the
@@ -328,25 +328,25 @@
OPENSSL_memcpy(&out[5], &seq[2], 6);
size_t ciphertext_len;
- if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
- max_out - DTLS1_RT_HEADER_LENGTH, type, record_version,
- &out[3] /* seq */, in, in_len) ||
- !ssl_record_sequence_update(&seq[2], 6)) {
- return 0;
- }
-
- if (ciphertext_len >= 1 << 16) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ if (!aead->CiphertextLen(&ciphertext_len, in_len, 0)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return 0;
}
out[11] = ciphertext_len >> 8;
out[12] = ciphertext_len & 0xff;
+ Span<const uint8_t> header = MakeConstSpan(out, DTLS1_RT_HEADER_LENGTH);
+
+ size_t len_copy;
+ if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &len_copy,
+ max_out - DTLS1_RT_HEADER_LENGTH, type, record_version,
+ &out[3] /* seq */, header, in, in_len) ||
+ !ssl_record_sequence_update(&seq[2], 6)) {
+ return 0;
+ }
+ assert(ciphertext_len == len_copy);
*out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
-
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER,
- MakeSpan(out, DTLS1_RT_HEADER_LENGTH));
-
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header);
return 1;
}
diff --git a/src/ssl/handoff.cc b/src/ssl/handoff.cc
index dd73c83..2cbbaeb 100644
--- a/src/ssl/handoff.cc
+++ b/src/ssl/handoff.cc
@@ -133,10 +133,6 @@
s3->session_reused ? ssl->session : s3->hs->new_session.get();
if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1_uint64(&seq, kHandbackVersion) ||
- !CBB_add_asn1_uint64(&seq, ssl->version) ||
- !CBB_add_asn1_uint64(&seq, ssl->conf_max_version) ||
- !CBB_add_asn1_uint64(&seq, ssl->conf_min_version) ||
- !CBB_add_asn1_uint64(&seq, ssl->max_send_fragment) ||
!CBB_add_asn1_octet_string(&seq, s3->read_sequence,
sizeof(s3->read_sequence)) ||
!CBB_add_asn1_octet_string(&seq, s3->write_sequence,
@@ -148,7 +144,6 @@
!CBB_add_asn1_octet_string(&seq, read_iv, iv_len) ||
!CBB_add_asn1_octet_string(&seq, write_iv, iv_len) ||
!CBB_add_asn1_bool(&seq, s3->session_reused) ||
- !CBB_add_asn1_bool(&seq, s3->send_connection_binding) ||
!CBB_add_asn1_bool(&seq, s3->tlsext_channel_id_valid) ||
!ssl_session_serialize(session, &seq) ||
!CBB_add_asn1_octet_string(&seq, s3->next_proto_negotiated.data(),
@@ -160,14 +155,8 @@
hostname_len) ||
!CBB_add_asn1_octet_string(&seq, s3->tlsext_channel_id,
sizeof(s3->tlsext_channel_id)) ||
- !CBB_add_asn1_uint64(&seq, ssl->options) ||
- !CBB_add_asn1_uint64(&seq, ssl->mode) ||
- !CBB_add_asn1_uint64(&seq, ssl->max_cert_list) ||
- !CBB_add_asn1_bool(&seq, ssl->quiet_shutdown) ||
- !CBB_add_asn1_bool(&seq, ssl->tlsext_channel_id_enabled) ||
- !CBB_add_asn1_bool(&seq, ssl->retain_only_sha256_of_client_certs) ||
- !CBB_add_asn1_bool(&seq, ssl->token_binding_negotiated) ||
- !CBB_add_asn1_uint64(&seq, ssl->negotiated_token_binding_param) ||
+ !CBB_add_asn1_bool(&seq, ssl->s3->token_binding_negotiated) ||
+ !CBB_add_asn1_uint64(&seq, ssl->s3->negotiated_token_binding_param) ||
!CBB_add_asn1_bool(&seq, s3->hs->next_proto_neg_seen) ||
!CBB_add_asn1_bool(&seq, s3->hs->cert_request) ||
!CBB_add_asn1_bool(&seq, s3->hs->extended_master_secret) ||
@@ -191,16 +180,12 @@
}
SSL3_STATE *const s3 = ssl->s3;
- uint64_t handback_version, version, conf_max_version, conf_min_version,
- max_send_fragment, options, mode, max_cert_list,
- negotiated_token_binding_param, cipher;
+ uint64_t handback_version, negotiated_token_binding_param, cipher;
CBS seq, read_seq, write_seq, server_rand, client_rand, read_iv, write_iv,
next_proto, alpn, hostname, channel_id, transcript, key_share;
- int session_reused, send_connection_binding, channel_id_valid, quiet_shutdown,
- channel_id_enabled, retain_only_sha256, cert_request,
- extended_master_secret, ticket_expected, token_binding_negotiated,
- next_proto_neg_seen;
+ int session_reused, channel_id_valid, cert_request, extended_master_secret,
+ ticket_expected, token_binding_negotiated, next_proto_neg_seen;
SSL_SESSION *session = nullptr;
CBS handback_cbs(handback);
@@ -210,11 +195,7 @@
return false;
}
- if (!CBS_get_asn1_uint64(&seq, &version) ||
- !CBS_get_asn1_uint64(&seq, &conf_max_version) ||
- !CBS_get_asn1_uint64(&seq, &conf_min_version) ||
- !CBS_get_asn1_uint64(&seq, &max_send_fragment) ||
- !CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) ||
+ if (!CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) ||
CBS_len(&read_seq) != sizeof(s3->read_sequence) ||
!CBS_get_asn1(&seq, &write_seq, CBS_ASN1_OCTETSTRING) ||
CBS_len(&write_seq) != sizeof(s3->write_sequence) ||
@@ -229,7 +210,6 @@
!CBS_get_asn1(&seq, &read_iv, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&seq, &write_iv, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1_bool(&seq, &session_reused) ||
- !CBS_get_asn1_bool(&seq, &send_connection_binding) ||
!CBS_get_asn1_bool(&seq, &channel_id_valid)) {
return false;
}
@@ -253,12 +233,6 @@
CBS_len(&channel_id) != sizeof(s3->tlsext_channel_id) ||
!CBS_copy_bytes(&channel_id, s3->tlsext_channel_id,
sizeof(s3->tlsext_channel_id)) ||
- !CBS_get_asn1_uint64(&seq, &options) ||
- !CBS_get_asn1_uint64(&seq, &mode) ||
- !CBS_get_asn1_uint64(&seq, &max_cert_list) ||
- !CBS_get_asn1_bool(&seq, &quiet_shutdown) ||
- !CBS_get_asn1_bool(&seq, &channel_id_enabled) ||
- !CBS_get_asn1_bool(&seq, &retain_only_sha256) ||
!CBS_get_asn1_bool(&seq, &token_binding_negotiated) ||
!CBS_get_asn1_uint64(&seq, &negotiated_token_binding_param) ||
!CBS_get_asn1_bool(&seq, &next_proto_neg_seen) ||
@@ -277,21 +251,14 @@
return false;
}
- ssl->version = version;
- ssl->conf_max_version = conf_max_version;
- ssl->conf_min_version = conf_min_version;
- ssl->max_send_fragment = max_send_fragment;
+ ssl->version = session->ssl_version;
ssl->do_handshake = ssl_server_handshake;
ssl->server = true;
- ssl->options = options;
- ssl->mode = mode;
- ssl->max_cert_list = max_cert_list;
s3->have_version = true;
s3->hs->state = CBS_len(&transcript) == 0 ? state12_finish_server_handshake
: state12_read_client_certificate;
s3->session_reused = session_reused;
- s3->send_connection_binding = send_connection_binding;
s3->tlsext_channel_id_valid = channel_id_valid;
s3->next_proto_negotiated.CopyFrom(next_proto);
s3->alpn_selected.CopyFrom(alpn);
@@ -307,11 +274,8 @@
s3->hostname.reset(hostname_str);
}
- ssl->quiet_shutdown = quiet_shutdown;
- ssl->tlsext_channel_id_enabled = channel_id_enabled;
- ssl->retain_only_sha256_of_client_certs = retain_only_sha256;
- ssl->token_binding_negotiated = token_binding_negotiated;
- ssl->negotiated_token_binding_param =
+ s3->token_binding_negotiated = token_binding_negotiated;
+ s3->negotiated_token_binding_param =
static_cast<uint8_t>(negotiated_token_binding_param);
s3->hs->next_proto_neg_seen = next_proto_neg_seen;
s3->hs->wait = ssl_hs_flush;
diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc
index 0b352c2..087645d 100644
--- a/src/ssl/handshake_client.cc
+++ b/src/ssl/handshake_client.cc
@@ -740,7 +740,7 @@
return ssl_hs_error;
}
- if (ssl->token_binding_negotiated &&
+ if (ssl->s3->token_binding_negotiated &&
(!hs->extended_master_secret || !ssl->s3->send_connection_binding)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI);
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
diff --git a/src/ssl/handshake_server.cc b/src/ssl/handshake_server.cc
index 5f2f41f..7ade8fc 100644
--- a/src/ssl/handshake_server.cc
+++ b/src/ssl/handshake_server.cc
@@ -334,7 +334,7 @@
SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello,
const struct ssl_cipher_preference_list_st *server_pref) {
SSL *const ssl = hs->ssl;
- STACK_OF(SSL_CIPHER) *prio, *allow;
+ const STACK_OF(SSL_CIPHER) *prio, *allow;
// in_group_flags will either be NULL, or will point to an array of bytes
// which indicate equal-preference groups in the |prio| stack. See the
// comment about |in_group_flags| in the |ssl_cipher_preference_list_st|
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index e884b63..f4dc96f 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -657,19 +657,26 @@
bool SuffixLen(size_t *out_suffix_len, size_t in_len,
size_t extra_in_len) const;
+ // CiphertextLen calculates the total ciphertext length written by
+ // |SealScatter| and writes it to |*out_len|. It returns true on success and
+ // false on error. |in_len| and |extra_in_len| should equal the argument of
+ // the same names passed to |SealScatter|.
+ bool CiphertextLen(size_t *out_len, size_t in_len, size_t extra_in_len) const;
+
// Open authenticates and decrypts |in| in-place. On success, it sets |*out|
// to the plaintext in |in| and returns true. Otherwise, it returns
// false. The output will always be |ExplicitNonceLen| bytes ahead of |in|.
bool Open(Span<uint8_t> *out, uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], Span<uint8_t> in);
+ const uint8_t seqnum[8], Span<const uint8_t> header,
+ Span<uint8_t> in);
// Seal encrypts and authenticates |in_len| bytes from |in| and writes the
// result to |out|. It returns true on success and false on error.
//
// If |in| and |out| alias then |out| + |ExplicitNonceLen| must be == |in|.
bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type,
- uint16_t record_version, const uint8_t seqnum[8], const uint8_t *in,
- size_t in_len);
+ uint16_t record_version, const uint8_t seqnum[8],
+ Span<const uint8_t> header, const uint8_t *in, size_t in_len);
// SealScatter encrypts and authenticates |in_len| bytes from |in| and splits
// the result between |out_prefix|, |out| and |out_suffix|. It returns one on
@@ -688,17 +695,20 @@
// alias anything.
bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix,
uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], const uint8_t *in, size_t in_len,
- const uint8_t *extra_in, size_t extra_in_len);
+ const uint8_t seqnum[8], Span<const uint8_t> header,
+ const uint8_t *in, size_t in_len, const uint8_t *extra_in,
+ size_t extra_in_len);
bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const;
private:
- // GetAdditionalData writes the additional data into |out| and returns the
- // number of bytes written.
- size_t GetAdditionalData(uint8_t out[13], uint8_t type,
- uint16_t record_version, const uint8_t seqnum[8],
- size_t plaintext_len, size_t ciphertext_len);
+ // GetAdditionalData returns the additional data, writing into |storage| if
+ // necessary.
+ Span<const uint8_t> GetAdditionalData(uint8_t storage[13], uint8_t type,
+ uint16_t record_version,
+ const uint8_t seqnum[8],
+ size_t plaintext_len,
+ Span<const uint8_t> header);
const SSL_CIPHER *cipher_;
ScopedEVP_AEAD_CTX ctx_;
@@ -717,6 +727,9 @@
// randomly generated, rather than derived from the sequence
// number.
bool random_variable_nonce_ : 1;
+ // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the
+ // variable nonce rather than prepended.
+ bool xor_fixed_nonce_ : 1;
// omit_length_in_ad_ is true if the length should be omitted in the
// AEAD's ad parameter.
bool omit_length_in_ad_ : 1;
@@ -725,12 +738,8 @@
bool omit_version_in_ad_ : 1;
// omit_ad_ is true if the AEAD's ad parameter should be omitted.
bool omit_ad_ : 1;
- // tls13_ad_ is true if the AEAD's ad parameter should be based on the
- // TLS 1.3 format.
- bool tls13_ad_ : 1;
- // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the
- // variable nonce rather than prepended.
- bool xor_fixed_nonce_ : 1;
+ // ad_is_header_ is true if the AEAD's ad parameter is the record header.
+ bool ad_is_header_ : 1;
};
@@ -2299,6 +2308,10 @@
// key_update_count is the number of consecutive KeyUpdates received.
uint8_t key_update_count = 0;
+ // The negotiated Token Binding key parameter. Only valid if
+ // |token_binding_negotiated| is set.
+ uint8_t negotiated_token_binding_param = 0;
+
// skip_early_data instructs the record layer to skip unexpected early data
// messages when 0RTT is rejected.
bool skip_early_data:1;
@@ -2348,6 +2361,9 @@
// fired, were it not a draft.
bool draft_downgrade:1;
+ // token_binding_negotiated is set if Token Binding was negotiated.
+ bool token_binding_negotiated:1;
+
// hs_buf is the buffer of handshake data to process.
UniquePtr<BUF_MEM> hs_buf;
@@ -2671,10 +2687,6 @@
uint8_t *token_binding_params;
size_t token_binding_params_len;
- // The negotiated Token Binding key parameter. Only valid if
- // |token_binding_negotiated| is set.
- uint8_t negotiated_token_binding_param;
-
// Contains the QUIC transport params that this endpoint will send.
uint8_t *quic_transport_params;
size_t quic_transport_params_len;
@@ -2706,9 +2718,6 @@
// we'll advertise support.
bool tlsext_channel_id_enabled:1;
- // token_binding_negotiated is set if Token Binding was negotiated.
- bool token_binding_negotiated:1;
-
// retain_only_sha256_of_client_certs is true if we should compute the SHA256
// hash of the peer's certificate and then discard it to save memory and
// session space. Only effective on the server side.
diff --git a/src/ssl/s3_lib.cc b/src/ssl/s3_lib.cc
index a3fc8d7..baa5a17 100644
--- a/src/ssl/s3_lib.cc
+++ b/src/ssl/s3_lib.cc
@@ -177,7 +177,8 @@
key_update_pending(false),
wpend_pending(false),
early_data_accepted(false),
- draft_downgrade(false) {}
+ draft_downgrade(false),
+ token_binding_negotiated(false) {}
SSL3_STATE::~SSL3_STATE() {}
diff --git a/src/ssl/ssl_aead_ctx.cc b/src/ssl/ssl_aead_ctx.cc
index e6b3ee9..363c959 100644
--- a/src/ssl/ssl_aead_ctx.cc
+++ b/src/ssl/ssl_aead_ctx.cc
@@ -40,11 +40,11 @@
is_dtls_(is_dtls_arg),
variable_nonce_included_in_record_(false),
random_variable_nonce_(false),
+ xor_fixed_nonce_(false),
omit_length_in_ad_(false),
omit_version_in_ad_(false),
omit_ad_(false),
- tls13_ad_(false),
- xor_fixed_nonce_(false) {
+ ad_is_header_(false) {
OPENSSL_memset(fixed_nonce_, 0, sizeof(fixed_nonce_));
}
@@ -136,7 +136,7 @@
aead_ctx->variable_nonce_len_ = 8;
aead_ctx->variable_nonce_included_in_record_ = false;
if (ssl_is_draft28(version)) {
- aead_ctx->tls13_ad_ = true;
+ aead_ctx->ad_is_header_ = true;
} else {
aead_ctx->omit_ad_ = true;
}
@@ -198,6 +198,22 @@
extra_in_len);
}
+bool SSLAEADContext::CiphertextLen(size_t *out_len, const size_t in_len,
+ const size_t extra_in_len) const {
+ size_t len;
+ if (!SuffixLen(&len, in_len, extra_in_len)) {
+ return false;
+ }
+ len += ExplicitNonceLen();
+ len += in_len;
+ if (len < in_len || len >= 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return false;
+ }
+ *out_len = len;
+ return true;
+}
+
size_t SSLAEADContext::MaxOverhead() const {
return ExplicitNonceLen() +
(is_null_cipher() || FUZZER_MODE
@@ -205,38 +221,34 @@
: EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get())));
}
-size_t SSLAEADContext::GetAdditionalData(uint8_t out[13], uint8_t type,
- uint16_t record_version,
- const uint8_t seqnum[8],
- size_t plaintext_len,
- size_t ciphertext_len) {
- if (omit_ad_) {
- return 0;
+Span<const uint8_t> SSLAEADContext::GetAdditionalData(
+ uint8_t storage[13], uint8_t type, uint16_t record_version,
+ const uint8_t seqnum[8], size_t plaintext_len, Span<const uint8_t> header) {
+ if (ad_is_header_) {
+ return header;
}
- size_t len = 0;
- if (!tls13_ad_) {
- OPENSSL_memcpy(out, seqnum, 8);
- len += 8;
+ if (omit_ad_) {
+ return {};
}
- out[len++] = type;
+
+ OPENSSL_memcpy(storage, seqnum, 8);
+ size_t len = 8;
+ storage[len++] = type;
if (!omit_version_in_ad_) {
- out[len++] = static_cast<uint8_t>((record_version >> 8));
- out[len++] = static_cast<uint8_t>(record_version);
+ storage[len++] = static_cast<uint8_t>((record_version >> 8));
+ storage[len++] = static_cast<uint8_t>(record_version);
}
- if (tls13_ad_) {
- out[len++] = static_cast<uint8_t>((ciphertext_len >> 8));
- out[len++] = static_cast<uint8_t>(ciphertext_len);
- } else if (!omit_length_in_ad_) {
- out[len++] = static_cast<uint8_t>((plaintext_len >> 8));
- out[len++] = static_cast<uint8_t>(plaintext_len);
+ if (!omit_length_in_ad_) {
+ storage[len++] = static_cast<uint8_t>((plaintext_len >> 8));
+ storage[len++] = static_cast<uint8_t>(plaintext_len);
}
- return len;
+ return MakeConstSpan(storage, len);
}
bool SSLAEADContext::Open(Span<uint8_t> *out, uint8_t type,
uint16_t record_version, const uint8_t seqnum[8],
- Span<uint8_t> in) {
+ Span<const uint8_t> header, Span<uint8_t> in) {
if (is_null_cipher() || FUZZER_MODE) {
// Handle the initial NULL cipher.
*out = in;
@@ -255,9 +267,10 @@
}
plaintext_len = in.size() - overhead;
}
- uint8_t ad[13];
- size_t ad_len = GetAdditionalData(ad, type, record_version, seqnum,
- plaintext_len, in.size());
+
+ uint8_t ad_storage[13];
+ Span<const uint8_t> ad = GetAdditionalData(ad_storage, type, record_version,
+ seqnum, plaintext_len, header);
// Assemble the nonce.
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
@@ -298,7 +311,8 @@
// Decrypt in-place.
size_t len;
if (!EVP_AEAD_CTX_open(ctx_.get(), in.data(), &len, in.size(), nonce,
- nonce_len, in.data(), in.size(), ad, ad_len)) {
+ nonce_len, in.data(), in.size(), ad.data(),
+ ad.size())) {
return false;
}
*out = in.subspan(0, len);
@@ -308,7 +322,8 @@
bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out,
uint8_t *out_suffix, uint8_t type,
uint16_t record_version,
- const uint8_t seqnum[8], const uint8_t *in,
+ const uint8_t seqnum[8],
+ Span<const uint8_t> header, const uint8_t *in,
size_t in_len, const uint8_t *extra_in,
size_t extra_in_len) {
const size_t prefix_len = ExplicitNonceLen();
@@ -331,9 +346,9 @@
return true;
}
- uint8_t ad[13];
- size_t ad_len = GetAdditionalData(ad, type, record_version, seqnum, in_len,
- in_len + suffix_len);
+ uint8_t ad_storage[13];
+ Span<const uint8_t> ad = GetAdditionalData(ad_storage, type, record_version,
+ seqnum, in_len, header);
// Assemble the nonce.
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
@@ -384,15 +399,15 @@
size_t written_suffix_len;
bool result = !!EVP_AEAD_CTX_seal_scatter(
ctx_.get(), out, out_suffix, &written_suffix_len, suffix_len, nonce,
- nonce_len, in, in_len, extra_in, extra_in_len, ad, ad_len);
+ nonce_len, in, in_len, extra_in, extra_in_len, ad.data(), ad.size());
assert(!result || written_suffix_len == suffix_len);
return result;
}
bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len,
uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], const uint8_t *in,
- size_t in_len) {
+ const uint8_t seqnum[8], Span<const uint8_t> header,
+ const uint8_t *in, size_t in_len) {
const size_t prefix_len = ExplicitNonceLen();
size_t suffix_len;
if (!SuffixLen(&suffix_len, in_len, 0)) {
@@ -410,7 +425,7 @@
}
if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len, type,
- record_version, seqnum, in, in_len, 0, 0)) {
+ record_version, seqnum, header, in, in_len, 0, 0)) {
return false;
}
*out_len = prefix_len + in_len + suffix_len;
diff --git a/src/ssl/ssl_file.cc b/src/ssl/ssl_file.cc
index bafa64a..ca4b0be 100644
--- a/src/ssl/ssl_file.cc
+++ b/src/ssl/ssl_file.cc
@@ -165,6 +165,7 @@
}
// Check for duplicates.
+ sk_X509_NAME_sort(sk);
if (sk_X509_NAME_find(sk, NULL, xn)) {
continue;
}
@@ -223,6 +224,7 @@
}
// Check for duplicates.
+ sk_X509_NAME_sort(stack);
if (sk_X509_NAME_find(stack, NULL, xn)) {
continue;
}
diff --git a/src/ssl/ssl_key_share.cc b/src/ssl/ssl_key_share.cc
index 2a076c3..c7f6f88 100644
--- a/src/ssl/ssl_key_share.cc
+++ b/src/ssl/ssl_key_share.cc
@@ -248,11 +248,11 @@
UniquePtr<SSLKeyShare> SSLKeyShare::Create(CBS *in) {
uint64_t group;
- if (!CBS_get_asn1_uint64(in, &group)) {
+ if (!CBS_get_asn1_uint64(in, &group) || group > 0xffff) {
return nullptr;
}
- UniquePtr<SSLKeyShare> key_share = Create(static_cast<uint64_t>(group));
- if (!key_share->Deserialize(in)) {
+ UniquePtr<SSLKeyShare> key_share = Create(static_cast<uint16_t>(group));
+ if (!key_share || !key_share->Deserialize(in)) {
return nullptr;
}
return key_share;
diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc
index 6312504..14fb0ff 100644
--- a/src/ssl/ssl_lib.cc
+++ b/src/ssl/ssl_lib.cc
@@ -2164,11 +2164,11 @@
}
int SSL_is_token_binding_negotiated(const SSL *ssl) {
- return ssl->token_binding_negotiated;
+ return ssl->s3->token_binding_negotiated;
}
uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl) {
- return ssl->negotiated_token_binding_param;
+ return ssl->s3->negotiated_token_binding_param;
}
size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
diff --git a/src/ssl/ssl_session.cc b/src/ssl/ssl_session.cc
index 34e7b31..bc2c14c 100644
--- a/src/ssl/ssl_session.cc
+++ b/src/ssl/ssl_session.cc
@@ -990,6 +990,10 @@
return session->tlsext_tick_lifetime_hint;
}
+const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *session) {
+ return session->cipher;
+}
+
SSL_SESSION *SSL_magic_pending_session_ptr(void) {
return (SSL_SESSION *)&g_pending_session_magic;
}
diff --git a/src/ssl/t1_lib.cc b/src/ssl/t1_lib.cc
index 97c0c4b..2d3a664 100644
--- a/src/ssl/t1_lib.cc
+++ b/src/ssl/t1_lib.cc
@@ -2528,8 +2528,8 @@
for (size_t i = 0; i < ssl->token_binding_params_len; ++i) {
if (param == ssl->token_binding_params[i]) {
- ssl->negotiated_token_binding_param = param;
- ssl->token_binding_negotiated = true;
+ ssl->s3->negotiated_token_binding_param = param;
+ ssl->s3->token_binding_negotiated = true;
return true;
}
}
@@ -2547,7 +2547,7 @@
uint8_t tb_param = ssl->token_binding_params[i];
for (uint8_t peer_param : peer_params) {
if (tb_param == peer_param) {
- ssl->negotiated_token_binding_param = tb_param;
+ ssl->s3->negotiated_token_binding_param = tb_param;
return true;
}
}
@@ -2587,14 +2587,14 @@
return true;
}
- ssl->token_binding_negotiated = true;
+ ssl->s3->token_binding_negotiated = true;
return true;
}
static bool ext_token_binding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
- if (!ssl->token_binding_negotiated) {
+ if (!ssl->s3->token_binding_negotiated) {
return true;
}
@@ -2603,7 +2603,7 @@
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16(&contents, hs->negotiated_token_binding_version) ||
!CBB_add_u8_length_prefixed(&contents, ¶ms) ||
- !CBB_add_u8(¶ms, ssl->negotiated_token_binding_param) ||
+ !CBB_add_u8(¶ms, ssl->s3->negotiated_token_binding_param) ||
!CBB_flush(out)) {
return false;
}
@@ -3220,7 +3220,7 @@
static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (ssl->token_binding_negotiated &&
+ if (ssl->s3->token_binding_negotiated &&
!(SSL_get_secure_renegotiation_support(ssl) &&
SSL_get_extms_support(ssl))) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI);
diff --git a/src/ssl/tls13_client.cc b/src/ssl/tls13_client.cc
index aa05456..6e328b8 100644
--- a/src/ssl/tls13_client.cc
+++ b/src/ssl/tls13_client.cc
@@ -436,7 +436,7 @@
return ssl_hs_error;
}
if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension ||
- ssl->token_binding_negotiated) {
+ ssl->s3->token_binding_negotiated) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA);
return ssl_hs_error;
}
diff --git a/src/ssl/tls13_server.cc b/src/ssl/tls13_server.cc
index 3bd6786..9d7f5e0 100644
--- a/src/ssl/tls13_server.cc
+++ b/src/ssl/tls13_server.cc
@@ -391,7 +391,7 @@
// Channel ID is incompatible with 0-RTT.
!ssl->s3->tlsext_channel_id_valid &&
// If Token Binding is negotiated, reject 0-RTT.
- !ssl->token_binding_negotiated &&
+ !ssl->s3->token_binding_negotiated &&
// Custom extensions is incompatible with 0-RTT.
hs->custom_extensions.received == 0 &&
// The negotiated ALPN must match the one in the ticket.
diff --git a/src/ssl/tls_record.cc b/src/ssl/tls_record.cc
index 3152e7a..a2e4a20 100644
--- a/src/ssl/tls_record.cc
+++ b/src/ssl/tls_record.cc
@@ -258,8 +258,8 @@
return ssl_open_record_partial;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER,
- in.subspan(0, SSL3_RT_HEADER_LENGTH));
+ Span<const uint8_t> header = in.subspan(0, SSL3_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, header);
*out_consumed = in.size() - CBS_len(&cbs);
@@ -288,7 +288,7 @@
// Decrypt the body in-place.
if (!ssl->s3->aead_read_ctx->Open(
- out, type, version, ssl->s3->read_sequence,
+ out, type, version, ssl->s3->read_sequence, header,
MakeSpan(const_cast<uint8_t *>(CBS_data(&body)), CBS_len(&body)))) {
if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) {
ERR_clear_error();
@@ -376,27 +376,22 @@
static int do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
uint8_t *out_suffix, uint8_t type, const uint8_t *in,
const size_t in_len) {
+ SSLAEADContext *aead = ssl->s3->aead_write_ctx.get();
uint8_t *extra_in = NULL;
size_t extra_in_len = 0;
- if (!ssl->s3->aead_write_ctx->is_null_cipher() &&
- ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) {
+ if (!aead->is_null_cipher() &&
+ aead->ProtocolVersion() >= TLS1_3_VERSION) {
// TLS 1.3 hides the actual record type inside the encrypted data.
extra_in = &type;
extra_in_len = 1;
}
- size_t suffix_len;
- if (!ssl->s3->aead_write_ctx->SuffixLen(&suffix_len, in_len, extra_in_len)) {
+ size_t suffix_len, ciphertext_len;
+ if (!aead->SuffixLen(&suffix_len, in_len, extra_in_len) ||
+ !aead->CiphertextLen(&ciphertext_len, in_len, extra_in_len)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return 0;
}
- size_t ciphertext_len =
- ssl->s3->aead_write_ctx->ExplicitNonceLen() + suffix_len;
- if (ciphertext_len + in_len < ciphertext_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
- return 0;
- }
- ciphertext_len += in_len;
assert(in == out || !buffers_alias(in, in_len, out, in_len));
assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl)));
@@ -408,28 +403,27 @@
out_prefix[0] = type;
}
- uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion();
+ uint16_t record_version = aead->RecordVersion();
out_prefix[1] = record_version >> 8;
out_prefix[2] = record_version & 0xff;
out_prefix[3] = ciphertext_len >> 8;
out_prefix[4] = ciphertext_len & 0xff;
+ Span<const uint8_t> header = MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH);
- if (!ssl->s3->aead_write_ctx->SealScatter(
- out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, out_prefix[0],
- record_version, ssl->s3->write_sequence, in, in_len, extra_in,
- extra_in_len) ||
+ if (!aead->SealScatter(out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix,
+ out_prefix[0], record_version, ssl->s3->write_sequence,
+ header, in, in_len, extra_in, extra_in_len) ||
!ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
return 0;
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER,
- MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH));
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, header);
return 1;
}
static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
- size_t in_len) {
+ size_t in_len) {
size_t ret = SSL3_RT_HEADER_LENGTH;
if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
ssl_needs_record_splitting(ssl)) {
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index d95fa9e..ed3484a 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -142,68 +142,89 @@
return true;
}
-static bool SpeedRSA(const std::string &key_name, RSA *key,
- const std::string &selected) {
- if (!selected.empty() && key_name.find(selected) == std::string::npos) {
+static bool SpeedRSA(const std::string &selected) {
+ if (!selected.empty() && selected.find("RSA") == std::string::npos) {
return true;
}
- std::unique_ptr<uint8_t[]> sig(new uint8_t[RSA_size(key)]);
- const uint8_t fake_sha256_hash[32] = {0};
- unsigned sig_len;
+ static const struct {
+ const char *name;
+ const uint8_t *key;
+ const size_t key_len;
+ } kRSAKeys[] = {
+ {"RSA 2048", kDERRSAPrivate2048, kDERRSAPrivate2048Len},
+ {"RSA 4096", kDERRSAPrivate4096, kDERRSAPrivate4096Len},
+ };
- TimeResults results;
- if (!TimeFunction(&results,
- [key, &sig, &fake_sha256_hash, &sig_len]() -> bool {
- // Usually during RSA signing we're using a long-lived |RSA| that has
- // already had all of its |BN_MONT_CTX|s constructed, so it makes
- // sense to use |key| directly here.
- return RSA_sign(NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash),
- sig.get(), &sig_len, key);
- })) {
- fprintf(stderr, "RSA_sign failed.\n");
- ERR_print_errors_fp(stderr);
- return false;
- }
- results.Print(key_name + " signing");
+ for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kRSAKeys); i++) {
+ const std::string name = kRSAKeys[i].name;
- if (!TimeFunction(&results,
- [key, &fake_sha256_hash, &sig, sig_len]() -> bool {
- return RSA_verify(NID_sha256, fake_sha256_hash,
- sizeof(fake_sha256_hash), sig.get(), sig_len, key);
- })) {
- fprintf(stderr, "RSA_verify failed.\n");
- ERR_print_errors_fp(stderr);
- return false;
- }
- results.Print(key_name + " verify (same key)");
+ bssl::UniquePtr<RSA> key(
+ RSA_private_key_from_bytes(kRSAKeys[i].key, kRSAKeys[i].key_len));
+ if (key == nullptr) {
+ fprintf(stderr, "Failed to parse %s key.\n", name.c_str());
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
- if (!TimeFunction(&results,
- [key, &fake_sha256_hash, &sig, sig_len]() -> bool {
- // Usually during RSA verification we have to parse an RSA key from a
- // certificate or similar, in which case we'd need to construct a new
- // RSA key, with a new |BN_MONT_CTX| for the public modulus. If we were
- // to use |key| directly instead, then these costs wouldn't be
- // accounted for.
- bssl::UniquePtr<RSA> verify_key(RSA_new());
- if (!verify_key) {
- return false;
- }
- verify_key->n = BN_dup(key->n);
- verify_key->e = BN_dup(key->e);
- if (!verify_key->n ||
- !verify_key->e) {
- return false;
- }
- return RSA_verify(NID_sha256, fake_sha256_hash,
- sizeof(fake_sha256_hash), sig.get(), sig_len,
- verify_key.get());
- })) {
- fprintf(stderr, "RSA_verify failed.\n");
- ERR_print_errors_fp(stderr);
- return false;
+ std::unique_ptr<uint8_t[]> sig(new uint8_t[RSA_size(key.get())]);
+ const uint8_t fake_sha256_hash[32] = {0};
+ unsigned sig_len;
+
+ TimeResults results;
+ if (!TimeFunction(&results,
+ [&key, &sig, &fake_sha256_hash, &sig_len]() -> bool {
+ // Usually during RSA signing we're using a long-lived |RSA| that has
+ // already had all of its |BN_MONT_CTX|s constructed, so it makes
+ // sense to use |key| directly here.
+ return RSA_sign(NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash),
+ sig.get(), &sig_len, key.get());
+ })) {
+ fprintf(stderr, "RSA_sign failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ results.Print(name + " signing");
+
+ if (!TimeFunction(&results,
+ [&key, &fake_sha256_hash, &sig, sig_len]() -> bool {
+ return RSA_verify(
+ NID_sha256, fake_sha256_hash, sizeof(fake_sha256_hash),
+ sig.get(), sig_len, key.get());
+ })) {
+ fprintf(stderr, "RSA_verify failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ results.Print(name + " verify (same key)");
+
+ if (!TimeFunction(&results,
+ [&key, &fake_sha256_hash, &sig, sig_len]() -> bool {
+ // Usually during RSA verification we have to parse an RSA key from a
+ // certificate or similar, in which case we'd need to construct a new
+ // RSA key, with a new |BN_MONT_CTX| for the public modulus. If we
+ // were to use |key| directly instead, then these costs wouldn't be
+ // accounted for.
+ bssl::UniquePtr<RSA> verify_key(RSA_new());
+ if (!verify_key) {
+ return false;
+ }
+ verify_key->n = BN_dup(key->n);
+ verify_key->e = BN_dup(key->e);
+ if (!verify_key->n ||
+ !verify_key->e) {
+ return false;
+ }
+ return RSA_verify(NID_sha256, fake_sha256_hash,
+ sizeof(fake_sha256_hash), sig.get(), sig_len,
+ verify_key.get());
+ })) {
+ fprintf(stderr, "RSA_verify failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ results.Print(name + " verify (fresh key)");
}
- results.Print(key_name + " verify (fresh key)");
return true;
}
@@ -381,7 +402,7 @@
static bool SpeedHashChunk(const EVP_MD *md, const std::string &name,
size_t chunk_len) {
- EVP_MD_CTX *ctx = EVP_MD_CTX_create();
+ bssl::ScopedEVP_MD_CTX ctx;
uint8_t scratch[8192];
if (chunk_len > sizeof(scratch)) {
@@ -389,13 +410,13 @@
}
TimeResults results;
- if (!TimeFunction(&results, [ctx, md, chunk_len, &scratch]() -> bool {
+ if (!TimeFunction(&results, [&ctx, md, chunk_len, &scratch]() -> bool {
uint8_t digest[EVP_MAX_MD_SIZE];
unsigned int md_len;
- return EVP_DigestInit_ex(ctx, md, NULL /* ENGINE */) &&
- EVP_DigestUpdate(ctx, scratch, chunk_len) &&
- EVP_DigestFinal_ex(ctx, digest, &md_len);
+ return EVP_DigestInit_ex(ctx.get(), md, NULL /* ENGINE */) &&
+ EVP_DigestUpdate(ctx.get(), scratch, chunk_len) &&
+ EVP_DigestFinal_ex(ctx.get(), digest, &md_len);
})) {
fprintf(stderr, "EVP_DigestInit_ex failed.\n");
ERR_print_errors_fp(stderr);
@@ -403,9 +424,6 @@
}
results.PrintWithBytes(name, chunk_len);
-
- EVP_MD_CTX_destroy(ctx);
-
return true;
}
static bool SpeedHash(const EVP_MD *md, const std::string &name,
@@ -745,32 +763,6 @@
g_timeout_seconds = atoi(args_map["-timeout"].c_str());
}
- bssl::UniquePtr<RSA> key(
- RSA_private_key_from_bytes(kDERRSAPrivate2048, kDERRSAPrivate2048Len));
- if (key == nullptr) {
- fprintf(stderr, "Failed to parse RSA key.\n");
- ERR_print_errors_fp(stderr);
- return false;
- }
-
- if (!SpeedRSA("RSA 2048", key.get(), selected)) {
- return false;
- }
-
- key.reset(
- RSA_private_key_from_bytes(kDERRSAPrivate4096, kDERRSAPrivate4096Len));
- if (key == nullptr) {
- fprintf(stderr, "Failed to parse 4096-bit RSA key.\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!SpeedRSA("RSA 4096", key.get(), selected)) {
- return false;
- }
-
- key.reset();
-
// kTLSADLen is the number of bytes of additional data that TLS passes to
// AEADs.
static const size_t kTLSADLen = 13;
@@ -780,7 +772,8 @@
// knowledge in them and construct a couple of the AD bytes internally.
static const size_t kLegacyADLen = kTLSADLen - 2;
- if (!SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) ||
+ if (!SpeedRSA(selected) ||
+ !SpeedAEAD(EVP_aead_aes_128_gcm(), "AES-128-GCM", kTLSADLen, selected) ||
!SpeedAEAD(EVP_aead_aes_256_gcm(), "AES-256-GCM", kTLSADLen, selected) ||
!SpeedAEAD(EVP_aead_chacha20_poly1305(), "ChaCha20-Poly1305", kTLSADLen,
selected) ||
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index f2b10de..caed812 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -294,11 +294,13 @@
out.write(self.header)
self.PrintVariableSection(out, 'crypto_sources',
- files['crypto'] + files['crypto_headers'] +
+ files['crypto'] +
files['crypto_internal_headers'])
+ self.PrintVariableSection(out, 'crypto_headers',
+ files['crypto_headers'])
self.PrintVariableSection(out, 'ssl_sources',
- files['ssl'] + files['ssl_headers'] +
- files['ssl_internal_headers'])
+ files['ssl'] + files['ssl_internal_headers'])
+ self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers'])
for ((osname, arch), asm_files) in asm_outputs:
self.PrintVariableSection(