diff options
author | Nick Harper <nharper@chromium.org> | 2024-06-20 22:10:42 +0000 |
---|---|---|
committer | Boringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2024-06-24 23:02:22 +0000 |
commit | ca2eba6a5e6a1db7fc970b38c2975fb7bb7153fa (patch) | |
tree | b93b1d99e72a4c6a710258a643934373e5c8d9db | |
parent | f01108e4761e1d4189cb134322c3cb01dc71ef87 (diff) | |
download | boringssl-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.cc | 14 | ||||
-rw-r--r-- | ssl/d1_pkt.cc | 8 | ||||
-rw-r--r-- | ssl/dtls_record.cc | 27 | ||||
-rw-r--r-- | ssl/internal.h | 19 | ||||
-rw-r--r-- | ssl/tls_record.cc | 2 |
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; |