Skip to content

Commit

Permalink
fixup! Adds DTLS unified header support
Browse files Browse the repository at this point in the history
  • Loading branch information
fwh-dc committed Oct 8, 2024
1 parent ebc2f6c commit 3d7454d
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 25 deletions.
84 changes: 70 additions & 14 deletions ssl/record/methods/dtls_meth.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,47 @@ static void dtls_set_in_init(OSSL_RECORD_LAYER *rl, int in_init)
rl->in_init = in_init;
}

#define DTLS13_UNI_HDR_FIX_BITS 0x20
#define DTLS13_UNI_HDR_CID_BIT 0x10
#define DTLS13_UNI_HDR_SEQ_BIT 0x08
#define DTLS13_UNI_HDR_LEN_BIT 0x04
#define DTLS13_UNI_HDR_FIX_BITS_MASK 0xe0
#define DTLS13_UNI_HDR_EPOCH_BITS_MASK 0x03

#define DTLS13_UNI_HDR_FIX_BITS_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_FIX_BITS_MASK) == DTLS13_UNI_HDR_FIX_BITS)
#define DTLS13_UNI_HDR_CID_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_CID_BIT) == DTLS13_UNI_HDR_CID_BIT)
#define DTLS13_UNI_HDR_SEQ_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_SEQ_BIT) == DTLS13_UNI_HDR_SEQ_BIT)
#define DTLS13_UNI_HDR_LEN_BIT_IS_SET(byte) \
(((byte) & DTLS13_UNI_HDR_LEN_BIT) == DTLS13_UNI_HDR_LEN_BIT)

static size_t dtls_get_rec_header_size(uint8_t hdr_first_byte) {
size_t size = 0;

if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(hdr_first_byte)
&& ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(hdr_first_byte))) {
/* DTLSv1.3 unified record header */
size = 1;
size += DTLS13_UNI_HDR_SEQ_BIT_IS_SET(hdr_first_byte) ? 2 : 1;
size += DTLS13_UNI_HDR_LEN_BIT_IS_SET(hdr_first_byte) ? 2 : 0;
} else {
/* DTLSv1.0, DTLSv1.2 or unencrypted DTLSv1.3 record header */
size = DTLS1_RT_HEADER_LENGTH;
}

return size;
}

static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap)
{
int i;
int enc_err;
TLS_RL_RECORD *rr;
int imac_size;
size_t mac_size = 0;
size_t rechdrsize = dtls_get_rec_header_size(rl->packet[0]);
unsigned char md[EVP_MAX_MD_SIZE];
SSL_MAC_BUF macbuf = { NULL, 0 };
int ret = 0;
Expand All @@ -122,7 +156,7 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap)
* At this point, rl->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length,
* and we have that many bytes in rl->packet
*/
rr->input = &(rl->packet[DTLS1_RT_HEADER_LENGTH]);
rr->input = rl->packet + rechdrsize;

/*
* ok, we can now read from 'rl->packet' data into 'rr'. rr->input
Expand Down Expand Up @@ -382,7 +416,6 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
int rret;
size_t more, n;
TLS_RL_RECORD *rr;
unsigned char *p = NULL;
DTLS_BITMAP *bitmap;
unsigned int is_next_epoch;

Expand Down Expand Up @@ -476,26 +509,28 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
* If so, the implementation MUST process the record as DTLSCiphertext;
*/
unsigned int length;
unsigned int record_version = DTLS1_3_VERSION, epoch = rl->epoch;
unsigned int record_version = DTLS1_2_VERSION, epoch = rl->epoch;
int cbitisset = (rr->type & 0x10) == 0x10;
int sbitisset = (rr->type & 0x08) == 0x08;
int lbitisset = (rr->type & 0x04) == 0x04;

if (/* OpenSSL does not support connection ID's and a connection ID
* is only set if one has been negotiated: silently discard */
rr->type & 0x10
|| !PACKET_get_net_2(&dtlsrecord, &epoch)
cbitisset
/*
* Naive approach? We expect sequence number to be filled already
* and then override the last bytes of the sequence number.
*/
|| rr->type & 0x8 ? !PACKET_copy_bytes(&dtlsrecord, rl->sequence + 6, 2)
: !PACKET_copy_bytes(&dtlsrecord, rl->sequence + 7, 1)
|| (sbitisset ? !PACKET_copy_bytes(&dtlsrecord, rl->sequence + 6, 2)
: !PACKET_copy_bytes(&dtlsrecord, rl->sequence + 7, 1))
/*
* rfc9147:
* The length field MAY be omitted by clearing the L bit, which means
* that the record consumes the entire rest of the datagram in the
* lower level transport
*/
|| rr->type & 0x4 ? !PACKET_get_net_2(&dtlsrecord, &length)
: (length = PACKET_remaining(&dtlsrecord)) > 0) {
|| (lbitisset ? !PACKET_get_net_2(&dtlsrecord, &length)
: (length = PACKET_remaining(&dtlsrecord)) > 0)) {
rr->length = 0;
rl->packet_length = 0;
goto again;
Expand All @@ -512,6 +547,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl)
rr->rec_version = (int)record_version;
rr->epoch = epoch;
rr->length = length;
//rr->type = SSL3_RT_APPLICATION_DATA;
} else {
unsigned int record_version, epoch, length;

Expand Down Expand Up @@ -790,25 +826,45 @@ int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl,
unsigned char **recdata)
{
size_t maxcomplen;
int unifiedheader = rl->version == DTLS1_3_VERSION && rl->epoch > 0;

*recdata = NULL;

maxcomplen = templ->buflen;
if (rl->compctx != NULL)
maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;

if (!WPACKET_put_bytes_u8(thispkt, rectype)
if (unifiedheader) {
uint8_t fixedbits = 0x20;
uint8_t cbit = 0;
uint8_t sbit = 0x08;
uint8_t lbit = 0x04;
uint8_t ebits = rl->epoch & 0x3;
uint8_t unifiedhdrbits = fixedbits | cbit | sbit | lbit | ebits;

if (!WPACKET_put_bytes_u8(thispkt, unifiedhdrbits)
|| !WPACKET_memcpy(thispkt, &(rl->sequence[6]), 2)
|| !WPACKET_start_sub_packet_u16(thispkt)
|| (rl->eivlen > 0
&& !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL))
|| (maxcomplen > 0
&& !WPACKET_reserve_bytes(thispkt, maxcomplen, recdata))) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
} else {
if (!WPACKET_put_bytes_u8(thispkt, rectype)
|| !WPACKET_put_bytes_u16(thispkt, templ->version)
|| !WPACKET_put_bytes_u16(thispkt, rl->epoch)
|| !WPACKET_memcpy(thispkt, &(rl->sequence[2]), 6)
|| !WPACKET_start_sub_packet_u16(thispkt)
|| (rl->eivlen > 0
&& !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL))
|| (maxcomplen > 0
&& !WPACKET_reserve_bytes(thispkt, maxcomplen,
recdata))) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
&& !WPACKET_reserve_bytes(thispkt, maxcomplen, recdata))) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
}

return 1;
Expand Down
58 changes: 47 additions & 11 deletions ssl/record/methods/tls13_meth.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,

if ((mac_ctx = EVP_MAC_CTX_dup(rl->mac_ctx)) == NULL
|| !EVP_MAC_update(mac_ctx, nonce, nonce_len)
|| !EVP_MAC_update(mac_ctx, recheader, sizeof(recheader))
|| !EVP_MAC_update(mac_ctx, recheader, hdrlen)
|| !EVP_MAC_update(mac_ctx, rec->input, rec->length)
|| !EVP_MAC_final(mac_ctx, tag, &taglen, rl->taglen)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
Expand Down Expand Up @@ -212,19 +212,37 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
return 0;
}

//if (!sending) {
// printf("receiver: tag(%zu):", rl->taglen);
// for (size_t i = 0; i < rl->taglen; i++) {
// printf("0x%2x, ", *(rec->data + rec->length + i));
// }
// printf("\n");
// printf("receiver: hdr(%zu):", hdrlen);
// for (size_t i = 0; i < hdrlen; i++)
// printf("0x%2x, ", *(recheader + i));
// printf("\n");
// printf("receiver: data(%zu):", rec->length);
// for (size_t i = 0; i < rec->length; i++)
// printf("0x%2x, ", *(rec->data + i));
// printf("\n");
// printf("receiver: nonce(%zu):", nonce_len);
// for (size_t i = 0; i < nonce_len; i++) {
// printf("0x%2x, ", *(nonce + i));
// }
// printf("\n");
//}

/*
* For CCM we must explicitly set the total plaintext length before we add
* any AAD.
*/
if ((mode == EVP_CIPH_CCM_MODE
&& EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL,
(unsigned int)rec->length) <= 0)
|| EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader,
sizeof(recheader)) <= 0
|| EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input,
(unsigned int)rec->length) <= 0
|| EVP_CipherFinal_ex(enc_ctx, rec->data + lenu, &lenf) <= 0
|| (size_t)(lenu + lenf) != rec->length) {
&& EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL, (int)rec->length) <= 0)
|| EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader, (int)hdrlen) <= 0
|| EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input, (int)rec->length) <= 0
|| EVP_CipherFinal_ex(enc_ctx, rec->data + lenu, &lenf) <= 0
|| (size_t)(lenu + lenf) != rec->length) {
return 0;
}
if (sending) {
Expand All @@ -234,6 +252,23 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs,
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
//printf("sender: tag(%zu):", rl->taglen);
//for (size_t i = 0; i < rl->taglen; i++)
// printf("0x%2x, ", *(rec->data + rec->length + i));
//printf("\n");
//printf("sender: hdr(%zu):", hdrlen);
//for (size_t i = 0; i < hdrlen; i++)
// printf("0x%2x, ", *(recheader + i));
//printf("\n");
//printf("sender: data(%zu):", rec->length);
//for (size_t i = 0; i < rec->length; i++)
// printf("0x%2x, ", *(rec->data + i));
//printf("\n");
//printf("sender: nonce(%zu):", nonce_len);
//for (size_t i = 0; i < nonce_len; i++) {
// printf("0x%2x, ", *(nonce + i));
//}
//printf("\n");
rec->length += rl->taglen;
}

Expand Down Expand Up @@ -271,7 +306,8 @@ static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec)
size_t end;

if (rec->length == 0
|| rec->type != SSL3_RT_APPLICATION_DATA) {
|| rl->isdtls ? (rec->type & 0xe0) != 0x20
: rec->type != SSL3_RT_APPLICATION_DATA) {
RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE,
SSL_R_BAD_RECORD_TYPE);
return 0;
Expand Down Expand Up @@ -309,7 +345,7 @@ static uint8_t tls13_get_record_type(OSSL_RECORD_LAYER *rl,
* when encrypting in TLSv1.3. The "inner" record type encodes the "real"
* record type from the template.
*/
return SSL3_RT_APPLICATION_DATA;
return rl->isdtls ? 0x2c | (0x3 & rl->epoch) : SSL3_RT_APPLICATION_DATA;
}

static int tls13_add_record_padding(OSSL_RECORD_LAYER *rl,
Expand Down
1 change: 1 addition & 0 deletions ssl/record/methods/tls_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,7 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl,
TLS_RL_RECORD *thiswr)
{
size_t origlen, len;
/*TODO unified header support*/
size_t headerlen = rl->isdtls ? DTLS1_RT_HEADER_LENGTH
: SSL3_RT_HEADER_LENGTH;

Expand Down
1 change: 1 addition & 0 deletions ssl/record/record.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*****************************************************************************/

#define SEQ_NUM_SIZE 8
#define REC_NUM_SIZE 16

typedef struct tls_record_st {
void *rechandle;
Expand Down

0 comments on commit 3d7454d

Please sign in to comment.