Make the bssl::SealRecord out_suffix arg fixed length.
Similarly, add EVP_AEAD_CTX_tag_len which computes the exact tag length
for required by EVP_AEAD_CTX_seal_scatter.
Change-Id: I069b0ad16fab314fd42f6048a3c1dc45e8376f7f
Reviewed-on: https://boringssl-review.googlesource.com/18324
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_aead_ctx.cc b/ssl/ssl_aead_ctx.cc
index 3b8d1b2..53dff78 100644
--- a/ssl/ssl_aead_ctx.cc
+++ b/ssl/ssl_aead_ctx.cc
@@ -150,15 +150,21 @@
return 0;
}
-size_t SSLAEADContext::MaxSuffixLen(size_t extra_in_len) const {
- return extra_in_len +
- (is_null_cipher() || FUZZER_MODE
- ? 0
- : EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get())));
+bool SSLAEADContext::SuffixLen(size_t *out_suffix_len, const size_t in_len,
+ const size_t extra_in_len) const {
+ if (is_null_cipher() || FUZZER_MODE) {
+ *out_suffix_len = extra_in_len;
+ return true;
+ }
+ return !!EVP_AEAD_CTX_tag_len(ctx_.get(), out_suffix_len, in_len,
+ extra_in_len);
}
size_t SSLAEADContext::MaxOverhead() const {
- return ExplicitNonceLen() + MaxSuffixLen(0);
+ return ExplicitNonceLen() +
+ (is_null_cipher() || FUZZER_MODE
+ ? 0
+ : EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get())));
}
size_t SSLAEADContext::GetAdditionalData(uint8_t out[13], uint8_t type,
@@ -255,18 +261,20 @@
}
bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out,
- uint8_t *out_suffix, size_t *out_suffix_len,
- size_t max_out_suffix_len, uint8_t type,
+ uint8_t *out_suffix, uint8_t type,
uint16_t wire_version, const uint8_t seqnum[8],
const uint8_t *in, size_t in_len,
const uint8_t *extra_in, size_t extra_in_len) {
- if ((in != out && buffers_alias(in, in_len, out, in_len)) ||
- buffers_alias(in, in_len, out_suffix, max_out_suffix_len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ const size_t prefix_len = ExplicitNonceLen();
+ size_t suffix_len;
+ if (!SuffixLen(&suffix_len, in_len, extra_in_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return false;
}
- if (extra_in_len > max_out_suffix_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ if ((in != out && buffers_alias(in, in_len, out, in_len)) ||
+ buffers_alias(in, in_len, out_prefix, prefix_len) ||
+ buffers_alias(in, in_len, out_suffix, suffix_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
return false;
}
@@ -274,7 +282,6 @@
/* Handle the initial NULL cipher. */
OPENSSL_memmove(out, in, in_len);
OPENSSL_memmove(out_suffix, extra_in, extra_in_len);
- *out_suffix_len = extra_in_len;
return true;
}
@@ -327,32 +334,38 @@
}
}
- return !!EVP_AEAD_CTX_seal_scatter(
- ctx_.get(), out, out_suffix, out_suffix_len, max_out_suffix_len, nonce,
+ 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);
+ 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 wire_version,
const uint8_t seqnum[8], const uint8_t *in,
size_t in_len) {
- size_t prefix_len = ExplicitNonceLen();
- if (in_len + prefix_len < in_len) {
+ const size_t prefix_len = ExplicitNonceLen();
+ size_t suffix_len;
+ if (!SuffixLen(&suffix_len, in_len, 0)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
+ return false;
+ }
+ if (in_len + prefix_len < in_len ||
+ in_len + prefix_len + suffix_len < in_len + prefix_len) {
OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE);
return false;
}
- if (in_len + prefix_len > max_out_len) {
+ if (in_len + prefix_len + suffix_len > max_out_len) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return false;
}
- size_t suffix_len;
- if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len,
- &suffix_len, max_out_len - prefix_len - in_len, type,
+ if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len, type,
wire_version, seqnum, in, in_len, 0, 0)) {
return false;
}
- assert(suffix_len <= MaxSuffixLen(0));
*out_len = prefix_len + in_len + suffix_len;
return true;
}