Reslice TLS AEAD setup.
This change reslices how the functions that generate the key block and
initialise the TLS AEADs are cut. This makes future changes easier.
Change-Id: I7e0f7327375301bed96f33c195b80156db83ce6d
Reviewed-on: https://boringssl-review.googlesource.com/24845
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/t1_enc.cc b/ssl/t1_enc.cc
index 7f4f10b..d1fb710 100644
--- a/ssl/t1_enc.cc
+++ b/ssl/t1_enc.cc
@@ -239,42 +239,26 @@
return true;
}
-static bool setup_key_block(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- if (!hs->key_block.empty()) {
- return true;
- }
-
- size_t mac_secret_len, key_len, fixed_iv_len;
- Array<uint8_t> key_block;
- if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &fixed_iv_len,
- hs->new_cipher) ||
- !key_block.Init(2 * (mac_secret_len + key_len + fixed_iv_len)) ||
- !SSL_generate_key_block(ssl, key_block.data(), key_block.size())) {
- return false;
- }
-
- hs->key_block = std::move(key_block);
- return true;
-}
-
-int tls1_change_cipher_state(SSL_HANDSHAKE *hs,
- evp_aead_direction_t direction) {
- SSL *const ssl = hs->ssl;
- // Ensure the key block is set up.
+static int tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction,
+ Array<uint8_t> *key_block_cache,
+ const SSL_CIPHER *cipher,
+ Span<const uint8_t> iv_override) {
size_t mac_secret_len, key_len, iv_len;
- if (!setup_key_block(hs) ||
- !get_key_block_lengths(ssl, &mac_secret_len, &key_len, &iv_len,
- hs->new_cipher)) {
+ if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &iv_len, cipher)) {
return 0;
}
- if ((mac_secret_len + key_len + iv_len) * 2 != hs->key_block.size()) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
+ // Ensure that |key_block_cache| is set up.
+ const size_t key_block_size = 2 * (mac_secret_len + key_len + iv_len);
+ if (key_block_cache->empty()) {
+ if (!key_block_cache->Init(key_block_size) ||
+ !SSL_generate_key_block(ssl, key_block_cache->data(), key_block_size)) {
+ return 0;
+ }
}
+ assert(key_block_cache->size() == key_block_size);
- Span<const uint8_t> key_block = hs->key_block;
+ Span<const uint8_t> key_block = *key_block_cache;
Span<const uint8_t> mac_secret, key, iv;
if (direction == (ssl->server ? evp_aead_open : evp_aead_seal)) {
// Use the client write (server read) keys.
@@ -288,9 +272,15 @@
iv = key_block.subspan(2 * mac_secret_len + 2 * key_len + iv_len, iv_len);
}
- UniquePtr<SSLAEADContext> aead_ctx =
- SSLAEADContext::Create(direction, ssl->version, SSL_is_dtls(ssl),
- hs->new_cipher, key, mac_secret, iv);
+ if (!iv_override.empty()) {
+ if (iv_override.size() != iv_len) {
+ return 0;
+ }
+ iv = iv_override;
+ }
+
+ UniquePtr<SSLAEADContext> aead_ctx = SSLAEADContext::Create(
+ direction, ssl->version, SSL_is_dtls(ssl), cipher, key, mac_secret, iv);
if (!aead_ctx) {
return 0;
}
@@ -302,6 +292,12 @@
return ssl->method->set_write_state(ssl, std::move(aead_ctx));
}
+int tls1_change_cipher_state(SSL_HANDSHAKE *hs,
+ evp_aead_direction_t direction) {
+ return tls1_configure_aead(hs->ssl, direction, &hs->key_block,
+ hs->new_cipher, {});
+}
+
int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out,
Span<const uint8_t> premaster) {
static const char kMasterSecretLabel[] = "master secret";