aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Harper <nharper@chromium.org>2024-06-20 22:10:42 +0000
committerBoringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-06-24 23:02:22 +0000
commitca2eba6a5e6a1db7fc970b38c2975fb7bb7153fa (patch)
treeb93b1d99e72a4c6a710258a643934373e5c8d9db
parentf01108e4761e1d4189cb134322c3cb01dc71ef87 (diff)
downloadboringssl-ca2eba6a5e6a1db7fc970b38c2975fb7bb7153fa.zip
boringssl-ca2eba6a5e6a1db7fc970b38c2975fb7bb7153fa.tar.gz
boringssl-ca2eba6a5e6a1db7fc970b38c2975fb7bb7153fa.tar.bz2
[DTLS] Use absolute instead of relative epoch numbers.
DTLS 1.3 needs to be able to handle absolute epoch numbers (e.g. "write data at the handshake epoch" instead of "write data at the current epoch"). Bug: 715 Change-Id: I2aed5346afdb9a247977564105009a726f3b8c12 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/69527 Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: Bob Beck <bbe@google.com> Auto-Submit: Nick Harper <nharper@chromium.org>
-rw-r--r--ssl/d1_both.cc14
-rw-r--r--ssl/d1_pkt.cc8
-rw-r--r--ssl/dtls_record.cc27
-rw-r--r--ssl/internal.h19
-rw-r--r--ssl/tls_record.cc2
5 files changed, 32 insertions, 38 deletions
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc
index b910b96..1a68d93 100644
--- a/ssl/d1_both.cc
+++ b/ssl/d1_both.cc
@@ -624,16 +624,14 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out,
assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len);
assert(msg == &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]);
- enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch;
- if (ssl->d1->w_epoch >= 1 && msg->epoch == ssl->d1->w_epoch - 1) {
- use_epoch = dtls1_use_previous_epoch;
- } else if (msg->epoch != ssl->d1->w_epoch) {
+ if (msg->epoch != ssl->d1->w_epoch &&
+ (ssl->d1->w_epoch == 0 || msg->epoch != ssl->d1->w_epoch - 1)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return seal_error;
}
- size_t overhead = dtls_max_seal_overhead(ssl, use_epoch);
- size_t prefix = dtls_seal_prefix_len(ssl, use_epoch);
+ size_t overhead = dtls_max_seal_overhead(ssl, msg->epoch);
+ size_t prefix = dtls_seal_prefix_len(ssl, msg->epoch);
if (msg->is_ccs) {
// Check there is room for the ChangeCipherSpec.
@@ -644,7 +642,7 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out,
if (!dtls_seal_record(ssl, out, out_len, max_out,
SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
- sizeof(kChangeCipherSpec), use_epoch)) {
+ sizeof(kChangeCipherSpec), msg->epoch)) {
return seal_error;
}
@@ -697,7 +695,7 @@ static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out,
MakeSpan(frag, frag_len));
if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE,
- out + prefix, frag_len, use_epoch)) {
+ out + prefix, frag_len, msg->epoch)) {
return seal_error;
}
diff --git a/ssl/d1_pkt.cc b/ssl/d1_pkt.cc
index b866156..da898b4 100644
--- a/ssl/d1_pkt.cc
+++ b/ssl/d1_pkt.cc
@@ -208,7 +208,7 @@ int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake,
}
int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in,
- dtls1_use_current_epoch);
+ ssl->d1->w_epoch);
if (ret <= 0) {
return ret;
}
@@ -217,7 +217,7 @@ int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake,
}
int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
- enum dtls1_use_epoch_t use_epoch) {
+ uint16_t epoch) {
SSLBuffer *buf = &ssl->s3->write_buffer;
assert(in.size() <= SSL3_RT_MAX_PLAIN_LENGTH);
// There should never be a pending write buffer in DTLS. One can't write half
@@ -235,7 +235,7 @@ int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
in.size() + SSL_max_seal_overhead(ssl)) ||
!dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len,
buf->remaining().size(), type, in.data(), in.size(),
- use_epoch)) {
+ epoch)) {
buf->Clear();
return -1;
}
@@ -250,7 +250,7 @@ int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
int dtls1_dispatch_alert(SSL *ssl) {
int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, ssl->s3->send_alert,
- dtls1_use_current_epoch);
+ ssl->d1->w_epoch);
if (ret <= 0) {
return ret;
}
diff --git a/ssl/dtls_record.cc b/ssl/dtls_record.cc
index 068864f..6551aa4 100644
--- a/ssl/dtls_record.cc
+++ b/ssl/dtls_record.cc
@@ -258,29 +258,30 @@ enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
}
static const SSLAEADContext *get_write_aead(const SSL *ssl,
- enum dtls1_use_epoch_t use_epoch) {
- if (use_epoch == dtls1_use_previous_epoch) {
- assert(ssl->d1->w_epoch >= 1);
+ uint16_t epoch) {
+ if (epoch < ssl->d1->w_epoch) {
+ assert(epoch + 1 == ssl->d1->w_epoch);
return ssl->d1->last_aead_write_ctx.get();
}
+ assert(epoch == ssl->d1->w_epoch);
return ssl->s3->aead_write_ctx.get();
}
size_t dtls_max_seal_overhead(const SSL *ssl,
- enum dtls1_use_epoch_t use_epoch) {
- return DTLS1_RT_HEADER_LENGTH + get_write_aead(ssl, use_epoch)->MaxOverhead();
+ uint16_t epoch) {
+ return DTLS1_RT_HEADER_LENGTH + get_write_aead(ssl, epoch)->MaxOverhead();
}
-size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) {
+size_t dtls_seal_prefix_len(const SSL *ssl, uint16_t epoch) {
return DTLS1_RT_HEADER_LENGTH +
- get_write_aead(ssl, use_epoch)->ExplicitNonceLen();
+ get_write_aead(ssl, epoch)->ExplicitNonceLen();
}
bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
uint8_t type, const uint8_t *in, size_t in_len,
- enum dtls1_use_epoch_t use_epoch) {
- const size_t prefix = dtls_seal_prefix_len(ssl, use_epoch);
+ uint16_t epoch) {
+ const size_t prefix = dtls_seal_prefix_len(ssl, epoch);
if (buffers_alias(in, in_len, out, max_out) &&
(max_out < prefix || out + prefix != in)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
@@ -288,14 +289,14 @@ bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
}
// Determine the parameters for the current epoch.
- uint16_t epoch = ssl->d1->w_epoch;
SSLAEADContext *aead = ssl->s3->aead_write_ctx.get();
uint64_t *seq = &ssl->s3->write_sequence;
- if (use_epoch == dtls1_use_previous_epoch) {
- assert(ssl->d1->w_epoch >= 1);
- epoch = ssl->d1->w_epoch - 1;
+ if (epoch < ssl->d1->w_epoch) {
+ assert(epoch + 1 == ssl->d1->w_epoch);
aead = ssl->d1->last_aead_write_ctx.get();
seq = &ssl->d1->last_write_sequence;
+ } else {
+ assert(epoch == ssl->d1->w_epoch);
}
if (max_out < DTLS1_RT_HEADER_LENGTH) {
diff --git a/ssl/internal.h b/ssl/internal.h
index 2e44641..4db9f17 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1044,26 +1044,21 @@ size_t ssl_seal_align_prefix_len(const SSL *ssl);
bool tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
uint8_t type, const uint8_t *in, size_t in_len);
-enum dtls1_use_epoch_t {
- dtls1_use_previous_epoch,
- dtls1_use_current_epoch,
-};
-
// dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a
// record.
-size_t dtls_max_seal_overhead(const SSL *ssl, enum dtls1_use_epoch_t use_epoch);
+size_t dtls_max_seal_overhead(const SSL *ssl, uint16_t epoch);
// dtls_seal_prefix_len returns the number of bytes of prefix to reserve in
// front of the plaintext when sealing a record in-place.
-size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch);
+size_t dtls_seal_prefix_len(const SSL *ssl, uint16_t epoch);
-// dtls_seal_record implements |tls_seal_record| for DTLS. |use_epoch| selects
-// which epoch's cipher state to use. Unlike |tls_seal_record|, |in| and |out|
-// may alias but, if they do, |in| must be exactly |dtls_seal_prefix_len| bytes
+// dtls_seal_record implements |tls_seal_record| for DTLS. |epoch| selects which
+// epoch's cipher state to use. Unlike |tls_seal_record|, |in| and |out| may
+// alias but, if they do, |in| must be exactly |dtls_seal_prefix_len| bytes
// ahead of |out|.
bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
uint8_t type, const uint8_t *in, size_t in_len,
- enum dtls1_use_epoch_t use_epoch);
+ uint16_t epoch);
// ssl_process_alert processes |in| as an alert and updates |ssl|'s shutdown
// state. It returns one of |ssl_open_record_discard|, |ssl_open_record_error|,
@@ -3379,7 +3374,7 @@ int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake,
// dtls1_write_record sends a record. It returns one on success and <= 0 on
// error.
int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in,
- enum dtls1_use_epoch_t use_epoch);
+ uint16_t epoch);
int dtls1_retransmit_outgoing_messages(SSL *ssl);
bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc
index 395b9a4..5a820f6 100644
--- a/ssl/tls_record.cc
+++ b/ssl/tls_record.cc
@@ -606,7 +606,7 @@ using namespace bssl;
size_t SSL_max_seal_overhead(const SSL *ssl) {
if (SSL_is_dtls(ssl)) {
- return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch);
+ return dtls_max_seal_overhead(ssl, ssl->d1->w_epoch);
}
size_t ret = SSL3_RT_HEADER_LENGTH;