Avoid re-hashing the transcript multiple times.

tls13_init_key_schedule calls InitHash internally, but we also call
InitHash earlier at various times. On the client, we do it early to
handle HelloRetryRequest and 0-RTT. ECH draft-12 will also need to do it
early. Apparently we do it early on the server too.

Probably tls13_init_key_schedule doesn't need to call InitHash, but for
now, it is an easy check in SSLTranscript.

Change-Id: I5473047c1f29bdeb60901e4e6e80979e592bd6e9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48911
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
grpc-202302
David Benjamin 3 years ago committed by Boringssl LUCI CQ
parent a75027b040
commit d55f450c4f
  1. 3
      ssl/internal.h
  2. 18
      ssl/ssl_transcript.cc
  3. 3
      ssl/tls13_server.cc

@ -694,7 +694,8 @@ class SSLTranscript {
// InitHash initializes the handshake hash based on the PRF and contents of
// the handshake transcript. Subsequent calls to |Update| will update the
// rolling hash. It returns one on success and zero on failure. It is an error
// to call this function after the handshake buffer is released.
// to call this function after the handshake buffer is released. This may be
// called multiple times to change the hash function.
bool InitHash(uint16_t version, const SSL_CIPHER *cipher);
// UpdateForHelloRetryRequest resets the rolling hash with the

@ -158,20 +158,14 @@ bool SSLTranscript::Init() {
return true;
}
// InitDigestWithData calls |EVP_DigestInit_ex| on |ctx| with |md| and then
// writes the data in |buf| to it.
static bool InitDigestWithData(EVP_MD_CTX *ctx, const EVP_MD *md,
const BUF_MEM *buf) {
if (!EVP_DigestInit_ex(ctx, md, NULL)) {
return false;
}
EVP_DigestUpdate(ctx, buf->data, buf->length);
return true;
}
bool SSLTranscript::InitHash(uint16_t version, const SSL_CIPHER *cipher) {
const EVP_MD *md = ssl_get_handshake_digest(version, cipher);
return InitDigestWithData(hash_.get(), md, buffer_.get());
if (Digest() == md) {
// No need to re-hash the buffer.
return true;
}
return EVP_DigestInit_ex(hash_.get(), md, nullptr) &&
EVP_DigestUpdate(hash_.get(), buffer_->data, buffer_->length);
}
void SSLTranscript::FreeBuffer() {

@ -246,8 +246,7 @@ static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
return ssl_hs_error;
}
// The PRF hash is now known. Set up the key schedule and hash the
// ClientHello.
// The PRF hash is now known.
if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) {
return ssl_hs_error;
}

Loading…
Cancel
Save