summaryrefslogtreecommitdiffstats
path: root/lib/libssl/tls12_record_layer.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libssl/tls12_record_layer.c')
-rw-r--r--lib/libssl/tls12_record_layer.c151
1 files changed, 87 insertions, 64 deletions
diff --git a/lib/libssl/tls12_record_layer.c b/lib/libssl/tls12_record_layer.c
index 2b331355be3..50311a3d846 100644
--- a/lib/libssl/tls12_record_layer.c
+++ b/lib/libssl/tls12_record_layer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls12_record_layer.c,v 1.8 2021/01/12 17:47:20 jsing Exp $ */
+/* $OpenBSD: tls12_record_layer.c,v 1.9 2021/01/13 18:20:54 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
@@ -114,12 +114,6 @@ tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version)
}
void
-tls12_record_layer_set_read_epoch(struct tls12_record_layer *rl, uint16_t epoch)
-{
- rl->read->epoch = epoch;
-}
-
-void
tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch)
{
rl->write->epoch = epoch;
@@ -256,8 +250,8 @@ tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb,
static int
tls12_record_layer_pseudo_header(struct tls12_record_layer *rl,
- uint8_t content_type, uint16_t record_len, uint16_t epoch, uint8_t *seq_num,
- size_t seq_num_len, uint8_t **out, size_t *out_len)
+ uint8_t content_type, uint16_t record_len, CBS *seq_num, uint8_t **out,
+ size_t *out_len)
{
CBB cbb;
@@ -268,8 +262,7 @@ tls12_record_layer_pseudo_header(struct tls12_record_layer *rl,
if (!CBB_init(&cbb, 13))
goto err;
- if (!tls12_record_layer_build_seq_num(rl, &cbb, epoch,
- seq_num, seq_num_len))
+ if (!CBB_add_bytes(&cbb, CBS_data(seq_num), CBS_len(seq_num)))
goto err;
if (!CBB_add_u8(&cbb, content_type))
goto err;
@@ -291,9 +284,8 @@ tls12_record_layer_pseudo_header(struct tls12_record_layer *rl,
static int
tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb,
- EVP_MD_CTX *hash_ctx, int stream_mac, uint16_t epoch, uint8_t *seq_num,
- size_t seq_num_len, uint8_t content_type, const uint8_t *content,
- size_t content_len, size_t *out_len)
+ EVP_MD_CTX *hash_ctx, int stream_mac, CBS *seq_num, uint8_t content_type,
+ const uint8_t *content, size_t content_len, size_t *out_len)
{
EVP_MD_CTX *mac_ctx = NULL;
uint8_t *header = NULL;
@@ -308,7 +300,7 @@ tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb,
goto err;
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
- epoch, seq_num, seq_num_len, &header, &header_len))
+ seq_num, &header, &header_len))
goto err;
if (EVP_DigestSignUpdate(mac_ctx, header, header_len) <= 0)
@@ -341,8 +333,8 @@ tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb,
static int
tls12_record_layer_read_mac_cbc(struct tls12_record_layer *rl, CBB *cbb,
- uint8_t content_type, const uint8_t *content, size_t content_len,
- size_t mac_len, size_t padding_len)
+ uint8_t content_type, CBS *seq_num, const uint8_t *content,
+ size_t content_len, size_t mac_len, size_t padding_len)
{
uint8_t *header = NULL;
size_t header_len = 0;
@@ -358,8 +350,7 @@ tls12_record_layer_read_mac_cbc(struct tls12_record_layer *rl, CBB *cbb,
goto err;
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
- rl->read->epoch, rl->read->seq_num, SSL3_SEQUENCE_SIZE,
- &header, &header_len))
+ seq_num, &header, &header_len))
goto err;
if (!CBB_add_space(cbb, &mac, mac_len))
@@ -381,7 +372,8 @@ tls12_record_layer_read_mac_cbc(struct tls12_record_layer *rl, CBB *cbb,
static int
tls12_record_layer_read_mac(struct tls12_record_layer *rl, CBB *cbb,
- uint8_t content_type, const uint8_t *content, size_t content_len)
+ uint8_t content_type, CBS *seq_num, const uint8_t *content,
+ size_t content_len)
{
EVP_CIPHER_CTX *enc = rl->read->cipher_ctx;
size_t out_len;
@@ -390,18 +382,18 @@ tls12_record_layer_read_mac(struct tls12_record_layer *rl, CBB *cbb,
return 0;
return tls12_record_layer_mac(rl, cbb, rl->read->hash_ctx,
- rl->read->stream_mac, rl->read->epoch, rl->read->seq_num,
- SSL3_SEQUENCE_SIZE, content_type, content, content_len, &out_len);
+ rl->read->stream_mac, seq_num, content_type, content, content_len,
+ &out_len);
}
static int
tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb,
- uint8_t content_type, const uint8_t *content, size_t content_len,
- size_t *out_len)
+ uint8_t content_type, CBS *seq_num, const uint8_t *content,
+ size_t content_len, size_t *out_len)
{
return tls12_record_layer_mac(rl, cbb, rl->write->hash_ctx,
- rl->write->stream_mac, rl->write->epoch, rl->write->seq_num,
- SSL3_SEQUENCE_SIZE, content_type, content, content_len, out_len);
+ rl->write->stream_mac, seq_num, content_type, content, content_len,
+ out_len);
}
static int
@@ -494,21 +486,21 @@ tls12_record_layer_open_record_plaintext(struct tls12_record_layer *rl,
static int
tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl,
- uint8_t content_type, CBS *fragment, uint8_t **out, size_t *out_len)
+ uint8_t content_type, CBS *seq_num, CBS *fragment, uint8_t **out,
+ size_t *out_len)
{
const SSL_AEAD_CTX *aead = rl->read->aead_ctx;
uint8_t *header = NULL, *nonce = NULL;
size_t header_len = 0, nonce_len = 0;
uint8_t *plain;
size_t plain_len;
- uint16_t epoch = 0;
CBS var_nonce;
int ret = 0;
/* XXX - move to nonce allocated in record layer, matching TLSv1.3 */
if (aead->xor_fixed_nonce) {
if (!tls12_record_layer_aead_xored_nonce(rl, aead,
- rl->read->seq_num, &nonce, &nonce_len))
+ CBS_data(seq_num), &nonce, &nonce_len))
goto err;
} else if (aead->variable_nonce_in_record) {
if (!CBS_get_bytes(fragment, &var_nonce,
@@ -519,7 +511,7 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl,
goto err;
} else {
if (!tls12_record_layer_aead_concat_nonce(rl, aead,
- rl->read->seq_num, &nonce, &nonce_len))
+ CBS_data(seq_num), &nonce, &nonce_len))
goto err;
}
@@ -538,7 +530,7 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl,
plain_len = CBS_len(fragment) - aead->tag_len;
if (!tls12_record_layer_pseudo_header(rl, content_type, plain_len,
- epoch, rl->read->seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len))
+ seq_num, &header, &header_len))
goto err;
if (!EVP_AEAD_CTX_open(&aead->ctx, plain, out_len, plain_len,
@@ -569,7 +561,8 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl,
static int
tls12_record_layer_open_record_protected_cipher(struct tls12_record_layer *rl,
- uint8_t content_type, CBS *fragment, uint8_t **out, size_t *out_len)
+ uint8_t content_type, CBS *seq_num, CBS *fragment, uint8_t **out,
+ size_t *out_len)
{
EVP_CIPHER_CTX *enc = rl->read->cipher_ctx;
SSL3_RECORD_INTERNAL rrec;
@@ -651,13 +644,14 @@ tls12_record_layer_open_record_protected_cipher(struct tls12_record_layer *rl,
rrec.padding_length);
rrec.length -= mac_len;
if (!tls12_record_layer_read_mac_cbc(rl, &cbb_mac, content_type,
- rrec.input, rrec.length, mac_len, rrec.padding_length))
+ seq_num, rrec.input, rrec.length, mac_len,
+ rrec.padding_length))
goto err;
} else {
rrec.length -= mac_len;
memcpy(mac, rrec.data + rrec.length, mac_len);
if (!tls12_record_layer_read_mac(rl, &cbb_mac, content_type,
- rrec.input, rrec.length))
+ seq_num, rrec.input, rrec.length))
goto err;
}
if (!CBB_finish(&cbb_mac, &out_mac, &out_mac_len))
@@ -696,20 +690,26 @@ int
tls12_record_layer_open_record(struct tls12_record_layer *rl, uint8_t *buf,
size_t buf_len, uint8_t **out, size_t *out_len)
{
- CBS cbs, fragment, seq_no;
- uint16_t epoch, version;
+ CBS cbs, fragment, seq_num;
+ uint16_t version;
uint8_t content_type;
CBS_init(&cbs, buf, buf_len);
+ CBS_init(&seq_num, rl->read->seq_num, SSL3_SEQUENCE_SIZE);
if (!CBS_get_u8(&cbs, &content_type))
return 0;
if (!CBS_get_u16(&cbs, &version))
return 0;
if (rl->dtls) {
- if (!CBS_get_u16(&cbs, &epoch))
- return 0;
- if (!CBS_get_bytes(&cbs, &seq_no, 6))
+ /*
+ * The DTLS sequence number is split into a 16 bit epoch and
+ * 48 bit sequence number, however for the purposes of record
+ * processing it is treated the same as a TLS 64 bit sequence
+ * number. DTLS also uses explicit read sequence numbers, which
+ * we need to extract from the DTLS record header.
+ */
+ if (!CBS_get_bytes(&cbs, &seq_num, SSL3_SEQUENCE_SIZE))
return 0;
}
if (!CBS_get_u16_length_prefixed(&cbs, &fragment))
@@ -717,11 +717,11 @@ tls12_record_layer_open_record(struct tls12_record_layer *rl, uint8_t *buf,
if (rl->read->aead_ctx != NULL) {
if (!tls12_record_layer_open_record_protected_aead(rl,
- content_type, &fragment, out, out_len))
+ content_type, &seq_num, &fragment, out, out_len))
return 0;
} else if (rl->read->cipher_ctx != NULL) {
if (!tls12_record_layer_open_record_protected_cipher(rl,
- content_type, &fragment, out, out_len))
+ content_type, &seq_num, &fragment, out, out_len))
return 0;
} else {
if (!tls12_record_layer_open_record_plaintext(rl,
@@ -747,35 +747,36 @@ tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl,
static int
tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl,
- uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
+ uint8_t content_type, CBS *seq_num, const uint8_t *content,
+ size_t content_len, CBB *out)
{
const SSL_AEAD_CTX *aead = rl->write->aead_ctx;
uint8_t *header = NULL, *nonce = NULL;
size_t header_len = 0, nonce_len = 0;
size_t enc_record_len, out_len;
- uint16_t epoch = 0;
uint8_t *enc_data;
int ret = 0;
/* XXX - move to nonce allocated in record layer, matching TLSv1.3 */
if (aead->xor_fixed_nonce) {
if (!tls12_record_layer_aead_xored_nonce(rl, aead,
- rl->write->seq_num, &nonce, &nonce_len))
+ CBS_data(seq_num), &nonce, &nonce_len))
goto err;
} else {
if (!tls12_record_layer_aead_concat_nonce(rl, aead,
- rl->write->seq_num, &nonce, &nonce_len))
+ CBS_data(seq_num), &nonce, &nonce_len))
goto err;
}
if (aead->variable_nonce_in_record) {
/* XXX - length check? */
- if (!CBB_add_bytes(out, rl->write->seq_num, aead->variable_nonce_len))
+ if (!CBB_add_bytes(out, CBS_data(seq_num),
+ aead->variable_nonce_len))
goto err;
}
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
- epoch, rl->write->seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len))
+ seq_num, &header, &header_len))
goto err;
/* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */
@@ -803,7 +804,8 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl,
static int
tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl,
- uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
+ uint8_t content_type, CBS *seq_num, const uint8_t *content,
+ size_t content_len, CBB *out)
{
EVP_CIPHER_CTX *enc = rl->write->cipher_ctx;
size_t mac_len, pad_len;
@@ -836,7 +838,7 @@ tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl,
mac_len = 0;
if (rl->write->hash_ctx != NULL) {
if (!tls12_record_layer_write_mac(rl, &cbb, content_type,
- content, content_len, &mac_len))
+ seq_num, content, content_len, &mac_len))
goto err;
}
@@ -883,39 +885,60 @@ int
tls12_record_layer_seal_record(struct tls12_record_layer *rl,
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *cbb)
{
- CBB fragment;
+ uint8_t *seq_num_data = NULL;
+ size_t seq_num_len = 0;
+ CBB fragment, seq_num_cbb;
+ CBS seq_num;
+ int ret = 0;
+
+ /*
+ * Construct the effective sequence number - this is used in both
+ * the DTLS header and for MAC calculations.
+ */
+ if (!CBB_init(&seq_num_cbb, SSL3_SEQUENCE_SIZE))
+ goto err;
+ if (!tls12_record_layer_build_seq_num(rl, &seq_num_cbb, rl->write->epoch,
+ rl->write->seq_num, SSL3_SEQUENCE_SIZE))
+ goto err;
+ if (!CBB_finish(&seq_num_cbb, &seq_num_data, &seq_num_len))
+ goto err;
+ CBS_init(&seq_num, seq_num_data, seq_num_len);
if (!CBB_add_u8(cbb, content_type))
- return 0;
+ goto err;
if (!CBB_add_u16(cbb, rl->version))
- return 0;
+ goto err;
if (rl->dtls) {
- if (!tls12_record_layer_build_seq_num(rl, cbb,
- rl->write->epoch, rl->write->seq_num,
- SSL3_SEQUENCE_SIZE))
- return 0;
+ if (!CBB_add_bytes(cbb, CBS_data(&seq_num), CBS_len(&seq_num)))
+ goto err;
}
if (!CBB_add_u16_length_prefixed(cbb, &fragment))
- return 0;
+ goto err;
if (rl->write->aead_ctx != NULL) {
if (!tls12_record_layer_seal_record_protected_aead(rl,
- content_type, content, content_len, &fragment))
- return 0;
+ content_type, &seq_num, content, content_len, &fragment))
+ goto err;
} else if (rl->write->cipher_ctx != NULL) {
if (!tls12_record_layer_seal_record_protected_cipher(rl,
- content_type, content, content_len, &fragment))
- return 0;
+ content_type, &seq_num, content, content_len, &fragment))
+ goto err;
} else {
if (!tls12_record_layer_seal_record_plaintext(rl,
content_type, content, content_len, &fragment))
- return 0;
+ goto err;
}
if (!CBB_flush(cbb))
- return 0;
+ goto err;
tls1_record_sequence_increment(rl->write->seq_num);
- return 1;
+ ret = 1;
+
+ err:
+ CBB_cleanup(&seq_num_cbb);
+ free(seq_num_data);
+
+ return ret;
}