Clear the last of ssl->s3->tmp.

new_*_len can just be computed rather than maintained as state.

Change-Id: If097ee9e68d8791fcfeb69052151faf0134c7c52
Reviewed-on: https://boringssl-review.googlesource.com/21948
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2017-10-15 22:08:47 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent 32ce0ac0d8
commit 71ea6b127d
2 changed files with 41 additions and 49 deletions

View File

@ -2299,16 +2299,6 @@ struct SSL3_STATE {
uint8_t previous_server_finished_len = 0; uint8_t previous_server_finished_len = 0;
uint8_t previous_server_finished[12] = {0}; uint8_t previous_server_finished[12] = {0};
// State pertaining to the pending handshake.
//
// TODO(davidben): Move everything not needed after the handshake completes to
// |hs| and remove this.
struct {
uint8_t new_mac_secret_len;
uint8_t new_key_len;
uint8_t new_fixed_iv_len;
} tmp = {0, 0, 0};
// established_session is the session established by the connection. This // established_session is the session established by the connection. This
// session is only filled upon the completion of the handshake and is // session is only filled upon the completion of the handshake and is
// immutable. // immutable.

View File

@ -316,68 +316,65 @@ static int ssl3_prf(uint8_t *out, size_t out_len, const uint8_t *secret,
return 1; return 1;
} }
static int tls1_setup_key_block(SSL_HANDSHAKE *hs) { static bool get_key_block_lengths(const SSL *ssl, size_t *out_mac_secret_len,
SSL *const ssl = hs->ssl; size_t *out_key_len, size_t *out_iv_len,
if (!hs->key_block.empty()) { const SSL_CIPHER *cipher) {
return 1;
}
SSL_SESSION *session = ssl->session;
if (hs->new_session) {
session = hs->new_session.get();
}
const EVP_AEAD *aead = NULL; const EVP_AEAD *aead = NULL;
size_t mac_secret_len, fixed_iv_len; if (!ssl_cipher_get_evp_aead(&aead, out_mac_secret_len, out_iv_len, cipher,
if (session->cipher == NULL || ssl_protocol_version(ssl), SSL_is_dtls(ssl))) {
!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
session->cipher, ssl_protocol_version(ssl),
SSL_is_dtls(ssl))) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return 0; return false;
} }
size_t key_len = EVP_AEAD_key_length(aead);
if (mac_secret_len > 0) { *out_key_len = EVP_AEAD_key_length(aead);
if (*out_mac_secret_len > 0) {
// For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the // For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the
// key length reported by |EVP_AEAD_key_length| will include the MAC key // key length reported by |EVP_AEAD_key_length| will include the MAC key
// bytes and initial implicit IV. // bytes and initial implicit IV.
if (key_len < mac_secret_len + fixed_iv_len) { if (*out_key_len < *out_mac_secret_len + *out_iv_len) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0; return false;
} }
key_len -= mac_secret_len + fixed_iv_len; *out_key_len -= *out_mac_secret_len + *out_iv_len;
} }
assert(mac_secret_len < 256); return true;
assert(key_len < 256); }
assert(fixed_iv_len < 256);
ssl->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; static bool setup_key_block(SSL_HANDSHAKE *hs) {
ssl->s3->tmp.new_key_len = (uint8_t)key_len; SSL *const ssl = hs->ssl;
ssl->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; if (!hs->key_block.empty()) {
return true;
}
size_t mac_secret_len, key_len, fixed_iv_len;
Array<uint8_t> key_block; Array<uint8_t> key_block;
if (!key_block.Init(SSL_get_key_block_len(ssl)) || 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())) { !SSL_generate_key_block(ssl, key_block.data(), key_block.size())) {
return 0; return false;
} }
hs->key_block = std::move(key_block); hs->key_block = std::move(key_block);
return 1; return true;
} }
int tls1_change_cipher_state(SSL_HANDSHAKE *hs, int tls1_change_cipher_state(SSL_HANDSHAKE *hs,
evp_aead_direction_t direction) { evp_aead_direction_t direction) {
SSL *const ssl = hs->ssl; SSL *const ssl = hs->ssl;
// Ensure the key block is set up. // Ensure the key block is set up.
if (!tls1_setup_key_block(hs)) { 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)) {
return 0; return 0;
} }
size_t mac_secret_len = ssl->s3->tmp.new_mac_secret_len; if ((mac_secret_len + key_len + iv_len) * 2 != hs->key_block.size()) {
size_t key_len = ssl->s3->tmp.new_key_len; OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
size_t iv_len = ssl->s3->tmp.new_fixed_iv_len; return 0;
assert((mac_secret_len + key_len + iv_len) * 2 == hs->key_block.size()); }
Span<const uint8_t> key_block = hs->key_block; Span<const uint8_t> key_block = hs->key_block;
Span<const uint8_t> mac_secret, key, iv; Span<const uint8_t> mac_secret, key, iv;
@ -448,9 +445,14 @@ int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out,
using namespace bssl; using namespace bssl;
size_t SSL_get_key_block_len(const SSL *ssl) { size_t SSL_get_key_block_len(const SSL *ssl) {
return 2 * ((size_t)ssl->s3->tmp.new_mac_secret_len + size_t mac_secret_len, key_len, fixed_iv_len;
(size_t)ssl->s3->tmp.new_key_len + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &fixed_iv_len,
(size_t)ssl->s3->tmp.new_fixed_iv_len); SSL_get_current_cipher(ssl))) {
ERR_clear_error();
return 0;
}
return 2 * (mac_secret_len + key_len + fixed_iv_len);
} }
int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) {