Add a CBB_add_zeros helper.
We fill in placeholder values of all zeros fairly often in TLS now,
as workarounds for messages being constructed in the wrong order.
draft-12 of ECH adds even more of these. Add a helper so we don't need
to interrupt an || chain with a memset.
Change-Id: Id4f9d988ee67598645a01637cc9515b475c1aec2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48909
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/bytestring/bytestring_test.cc b/crypto/bytestring/bytestring_test.cc
index eafb0de..484cd34 100644
--- a/crypto/bytestring/bytestring_test.cc
+++ b/crypto/bytestring/bytestring_test.cc
@@ -322,11 +322,11 @@
}
TEST(CBBTest, Basic) {
- static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7,
- 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe,
- 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 3, 2,
- 10, 9, 8, 7, 0x12, 0x11, 0x10,
- 0xf, 0xe, 0xd, 0xc, 0xb};
+ static const uint8_t kExpected[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
+ 0x03, 0x02, 0x0a, 0x09, 0x08, 0x07, 0x12, 0x11, 0x10, 0x0f,
+ 0x0e, 0x0d, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x00};
uint8_t *buf;
size_t buf_len;
@@ -335,6 +335,7 @@
cbb.Reset();
ASSERT_TRUE(CBB_init(cbb.get(), 0));
+ ASSERT_TRUE(CBB_add_zeros(cbb.get(), 0));
ASSERT_TRUE(CBB_add_u8(cbb.get(), 1));
ASSERT_TRUE(CBB_add_u16(cbb.get(), 0x203));
ASSERT_TRUE(CBB_add_u24(cbb.get(), 0x40506));
@@ -344,6 +345,7 @@
ASSERT_TRUE(CBB_add_u16le(cbb.get(), 0x203));
ASSERT_TRUE(CBB_add_u32le(cbb.get(), 0x708090a));
ASSERT_TRUE(CBB_add_u64le(cbb.get(), 0xb0c0d0e0f101112));
+ ASSERT_TRUE(CBB_add_zeros(cbb.get(), 4));
ASSERT_TRUE(CBB_finish(cbb.get(), &buf, &buf_len));
bssl::UniquePtr<uint8_t> scoper(buf);
diff --git a/crypto/bytestring/cbb.c b/crypto/bytestring/cbb.c
index efb89c7..12587cd 100644
--- a/crypto/bytestring/cbb.c
+++ b/crypto/bytestring/cbb.c
@@ -404,6 +404,15 @@
return 1;
}
+int CBB_add_zeros(CBB *cbb, size_t len) {
+ uint8_t *out;
+ if (!CBB_add_space(cbb, &out, len)) {
+ return 0;
+ }
+ OPENSSL_memset(out, 0, len);
+ return 1;
+}
+
int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) {
if (!CBB_flush(cbb) ||
!cbb_buffer_add(cbb->base, out_data, len)) {
diff --git a/include/openssl/bytestring.h b/include/openssl/bytestring.h
index 39b7fb2..180326d 100644
--- a/include/openssl/bytestring.h
+++ b/include/openssl/bytestring.h
@@ -463,6 +463,10 @@
// success and zero otherwise.
OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
+// CBB_add_zeros append |len| bytes with value zero to |cbb|. It returns one on
+// success and zero otherwise.
+OPENSSL_EXPORT int CBB_add_zeros(CBB *cbb, size_t len);
+
// CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
// the beginning of that space. The caller must then write |len| bytes of
// actual contents to |*out_data|. It returns one on success and zero
diff --git a/ssl/extensions.cc b/ssl/extensions.cc
index 48fc5c5..9af928c 100644
--- a/ssl/extensions.cc
+++ b/ssl/extensions.cc
@@ -1991,7 +1991,6 @@
// Fill in a placeholder zero binder of the appropriate length. It will be
// computed and filled in later after length prefixes are computed.
- uint8_t zero_binder[EVP_MAX_MD_SIZE] = {0};
size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session.get()));
CBB contents, identity, ticket, binders, binder;
@@ -2004,7 +2003,7 @@
!CBB_add_u32(&identity, obfuscated_ticket_age) ||
!CBB_add_u16_length_prefixed(&contents, &binders) ||
!CBB_add_u8_length_prefixed(&binders, &binder) ||
- !CBB_add_bytes(&binder, zero_binder, binder_len)) {
+ !CBB_add_zeros(&binder, binder_len)) {
return false;
}
@@ -3324,14 +3323,12 @@
static bool add_padding_extension(CBB *cbb, uint16_t ext, size_t len) {
CBB child;
- uint8_t *ptr;
if (!CBB_add_u16(cbb, ext) || //
!CBB_add_u16_length_prefixed(cbb, &child) ||
- !CBB_add_space(&child, &ptr, len)) {
+ !CBB_add_zeros(&child, len)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return false;
}
- OPENSSL_memset(ptr, 0, len);
return CBB_flush(cbb);
}