From 7b133c71d1f99377b8bcc62ed304be9e5ed79e80 Mon Sep 17 00:00:00 2001 From: jsing Date: Sun, 16 May 2021 15:49:01 +0000 Subject: [PATCH] Absorb SSL_AEAD_CTX into struct tls12_record_protection. The information contained in SSL_AEAD_CTX really belongs in the tls12_record_protection struct. Absorb SSL_AEAD_CTX, using more appropriate types in the process. ok tb@ --- lib/libssl/ssl.h | 4 +- lib/libssl/ssl_locl.h | 24 +------ lib/libssl/tls12_record_layer.c | 108 +++++++++++++++++--------------- 3 files changed, 63 insertions(+), 73 deletions(-) diff --git a/lib/libssl/ssl.h b/lib/libssl/ssl.h index 571143040c3..f8360e5fe3f 100644 --- a/lib/libssl/ssl.h +++ b/lib/libssl/ssl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl.h,v 1.190 2021/05/10 17:10:57 tb Exp $ */ +/* $OpenBSD: ssl.h,v 1.191 2021/05/16 15:49:01 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -614,8 +614,10 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, #define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) #define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +#ifndef LIBRESSL_INTERNAL struct ssl_aead_ctx_st; typedef struct ssl_aead_ctx_st SSL_AEAD_CTX; +#endif #define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */ diff --git a/lib/libssl/ssl_locl.h b/lib/libssl/ssl_locl.h index 2e324e5d312..df115725a0c 100644 --- a/lib/libssl/ssl_locl.h +++ b/lib/libssl/ssl_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_locl.h,v 1.346 2021/05/16 13:56:31 jsing Exp $ */ +/* $OpenBSD: ssl_locl.h,v 1.347 2021/05/16 15:49:01 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1047,28 +1047,6 @@ typedef struct sess_cert_st { #define TLSV1_3_ENC_FLAGS (SSL_ENC_FLAG_SIGALGS | \ SSL_ENC_FLAG_TLS1_3_CIPHERS) -/* - * ssl_aead_ctx_st contains information about an AEAD that is being used to - * encrypt an SSL connection. - */ -struct ssl_aead_ctx_st { - EVP_AEAD_CTX ctx; - /* - * fixed_nonce contains any bytes of the nonce that are fixed for all - * records. - */ - unsigned char fixed_nonce[12]; - unsigned char fixed_nonce_len; - unsigned char variable_nonce_len; - unsigned char xor_fixed_nonce; - unsigned char tag_len; - /* - * variable_nonce_in_record is non-zero if the variable nonce - * for a record is included as a prefix before the ciphertext. - */ - char variable_nonce_in_record; -}; - extern const SSL_CIPHER ssl3_ciphers[]; const char *ssl_version_string(int ver); diff --git a/lib/libssl/tls12_record_layer.c b/lib/libssl/tls12_record_layer.c index 82a14f7147f..06d1af9def8 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.29 2021/05/16 15:21:10 jsing Exp $ */ +/* $OpenBSD: tls12_record_layer.c,v 1.30 2021/05/16 15:49:01 jsing Exp $ */ /* * Copyright (c) 2020 Joel Sing * @@ -22,13 +22,23 @@ #include "ssl_locl.h" -#define TLS12_RECORD_SEQ_NUM_LEN 8 +#define TLS12_RECORD_SEQ_NUM_LEN 8 +#define TLS12_AEAD_FIXED_NONCE_MAX_LEN 12 struct tls12_record_protection { uint16_t epoch; uint8_t seq_num[TLS12_RECORD_SEQ_NUM_LEN]; - SSL_AEAD_CTX *aead_ctx; + EVP_AEAD_CTX *aead_ctx; + + uint8_t *aead_fixed_nonce; + size_t aead_fixed_nonce_len; + + size_t aead_variable_nonce_len; + size_t aead_tag_len; + + int aead_xor_nonces; + int aead_variable_nonce_in_record; EVP_CIPHER_CTX *cipher_ctx; EVP_MD_CTX *hash_ctx; @@ -49,10 +59,12 @@ static void tls12_record_protection_clear(struct tls12_record_protection *rp) { if (rp->aead_ctx != NULL) { - EVP_AEAD_CTX_cleanup(&rp->aead_ctx->ctx); + EVP_AEAD_CTX_cleanup(rp->aead_ctx); freezero(rp->aead_ctx, sizeof(*rp->aead_ctx)); } + freezero(rp->aead_fixed_nonce, rp->aead_fixed_nonce_len); + EVP_CIPHER_CTX_free(rp->cipher_ctx); EVP_MD_CTX_free(rp->hash_ctx); @@ -218,7 +230,7 @@ tls12_record_layer_write_overhead(struct tls12_record_layer *rl, *overhead = 0; if (rl->write->aead_ctx != NULL) { - *overhead = rl->write->aead_ctx->tag_len; + *overhead = rl->write->aead_tag_len; } else if (rl->write->cipher_ctx != NULL) { eiv_len = 0; if (rl->version != TLS1_VERSION) { @@ -395,7 +407,7 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, struct tls12_record_protection *rp, int is_write, CBS *mac_key, CBS *key, CBS *iv) { - size_t aead_nonce_len, fixed_nonce_len; + size_t aead_nonce_len; if (!tls12_record_protection_unused(rp)) return 0; @@ -406,36 +418,34 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, /* AES GCM cipher suites use variable nonce in record. */ if (rl->aead == EVP_aead_aes_128_gcm() || rl->aead == EVP_aead_aes_256_gcm()) - rp->aead_ctx->variable_nonce_in_record = 1; + rp->aead_variable_nonce_in_record = 1; /* ChaCha20 Poly1305 XORs the fixed and variable nonces. */ if (rl->aead == EVP_aead_chacha20_poly1305()) - rp->aead_ctx->xor_fixed_nonce = 1; + rp->aead_xor_nonces = 1; - if (!CBS_write_bytes(iv, rp->aead_ctx->fixed_nonce, - sizeof(rp->aead_ctx->fixed_nonce), &fixed_nonce_len)) + if (!CBS_stow(iv, &rp->aead_fixed_nonce, &rp->aead_fixed_nonce_len)) return 0; - rp->aead_ctx->fixed_nonce_len = fixed_nonce_len; - rp->aead_ctx->tag_len = EVP_AEAD_max_overhead(rl->aead); - rp->aead_ctx->variable_nonce_len = 8; + rp->aead_tag_len = EVP_AEAD_max_overhead(rl->aead); + rp->aead_variable_nonce_len = 8; aead_nonce_len = EVP_AEAD_nonce_length(rl->aead); - if (rp->aead_ctx->xor_fixed_nonce) { + if (rp->aead_xor_nonces) { /* Fixed nonce length must match, variable must not exceed. */ - if (rp->aead_ctx->fixed_nonce_len != aead_nonce_len) + if (rp->aead_fixed_nonce_len != aead_nonce_len) return 0; - if (rp->aead_ctx->variable_nonce_len > aead_nonce_len) + if (rp->aead_variable_nonce_len > aead_nonce_len) return 0; } else { /* Concatenated nonce length must equal AEAD nonce length. */ - if (rp->aead_ctx->fixed_nonce_len + - rp->aead_ctx->variable_nonce_len != aead_nonce_len) + if (rp->aead_fixed_nonce_len + + rp->aead_variable_nonce_len != aead_nonce_len) return 0; } - if (!EVP_AEAD_CTX_init(&rp->aead_ctx->ctx, rl->aead, CBS_data(key), + if (!EVP_AEAD_CTX_init(rp->aead_ctx, rl->aead, CBS_data(key), CBS_len(key), EVP_AEAD_DEFAULT_TAG_LENGTH, NULL)) return 0; @@ -770,21 +780,21 @@ tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, static int tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, - const SSL_AEAD_CTX *aead, const uint8_t *seq_num, + struct tls12_record_protection *rp, const uint8_t *seq_num, uint8_t **out, size_t *out_len) { CBB cbb; - if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE) + if (rp->aead_variable_nonce_len > SSL3_SEQUENCE_SIZE) return 0; /* Fixed nonce and variable nonce (sequence number) are concatenated. */ if (!CBB_init(&cbb, 16)) goto err; - if (!CBB_add_bytes(&cbb, aead->fixed_nonce, - aead->fixed_nonce_len)) + if (!CBB_add_bytes(&cbb, rp->aead_fixed_nonce, + rp->aead_fixed_nonce_len)) goto err; - if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len)) + if (!CBB_add_bytes(&cbb, seq_num, rp->aead_variable_nonce_len)) goto err; if (!CBB_finish(&cbb, out, out_len)) goto err; @@ -799,7 +809,7 @@ tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, static int tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, - const SSL_AEAD_CTX *aead, const uint8_t *seq_num, + struct tls12_record_protection *rp, const uint8_t *seq_num, uint8_t **out, size_t *out_len) { uint8_t *nonce = NULL; @@ -808,9 +818,9 @@ tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, CBB cbb; int i; - if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE) + if (rp->aead_variable_nonce_len > SSL3_SEQUENCE_SIZE) return 0; - if (aead->fixed_nonce_len < aead->variable_nonce_len) + if (rp->aead_fixed_nonce_len < rp->aead_variable_nonce_len) return 0; /* @@ -820,15 +830,15 @@ tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, if (!CBB_init(&cbb, 16)) goto err; if (!CBB_add_space(&cbb, &pad, - aead->fixed_nonce_len - aead->variable_nonce_len)) + rp->aead_fixed_nonce_len - rp->aead_variable_nonce_len)) goto err; - if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len)) + if (!CBB_add_bytes(&cbb, seq_num, rp->aead_variable_nonce_len)) goto err; if (!CBB_finish(&cbb, &nonce, &nonce_len)) goto err; - for (i = 0; i < aead->fixed_nonce_len; i++) - nonce[i] ^= aead->fixed_nonce[i]; + for (i = 0; i < rp->aead_fixed_nonce_len; i++) + nonce[i] ^= rp->aead_fixed_nonce[i]; *out = nonce; *out_len = nonce_len; @@ -861,7 +871,7 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, 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; + struct tls12_record_protection *rp = rl->read; uint8_t *header = NULL, *nonce = NULL; size_t header_len = 0, nonce_len = 0; uint8_t *plain; @@ -870,25 +880,25 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, 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, + if (rp->aead_xor_nonces) { + if (!tls12_record_layer_aead_xored_nonce(rl, rp, CBS_data(seq_num), &nonce, &nonce_len)) goto err; - } else if (aead->variable_nonce_in_record) { + } else if (rp->aead_variable_nonce_in_record) { if (!CBS_get_bytes(fragment, &var_nonce, - aead->variable_nonce_len)) + rp->aead_variable_nonce_len)) goto err; - if (!tls12_record_layer_aead_concat_nonce(rl, aead, + if (!tls12_record_layer_aead_concat_nonce(rl, rp, CBS_data(&var_nonce), &nonce, &nonce_len)) goto err; } else { - if (!tls12_record_layer_aead_concat_nonce(rl, aead, + if (!tls12_record_layer_aead_concat_nonce(rl, rp, CBS_data(seq_num), &nonce, &nonce_len)) goto err; } /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ - if (CBS_len(fragment) < aead->tag_len) { + if (CBS_len(fragment) < rp->aead_tag_len) { rl->alert_desc = SSL_AD_BAD_RECORD_MAC; goto err; } @@ -899,13 +909,13 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, /* XXX - decrypt/process in place for now. */ plain = (uint8_t *)CBS_data(fragment); - plain_len = CBS_len(fragment) - aead->tag_len; + plain_len = CBS_len(fragment) - rp->aead_tag_len; if (!tls12_record_layer_pseudo_header(rl, content_type, plain_len, seq_num, &header, &header_len)) goto err; - if (!EVP_AEAD_CTX_open(&aead->ctx, plain, out_len, plain_len, + if (!EVP_AEAD_CTX_open(rp->aead_ctx, plain, out_len, plain_len, nonce, nonce_len, CBS_data(fragment), CBS_len(fragment), header, header_len)) { rl->alert_desc = SSL_AD_BAD_RECORD_MAC; @@ -1125,7 +1135,7 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, 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; + struct tls12_record_protection *rp = rl->write; uint8_t *header = NULL, *nonce = NULL; size_t header_len = 0, nonce_len = 0; size_t enc_record_len, out_len; @@ -1133,20 +1143,20 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, 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, + if (rp->aead_xor_nonces) { + if (!tls12_record_layer_aead_xored_nonce(rl, rp, CBS_data(seq_num), &nonce, &nonce_len)) goto err; } else { - if (!tls12_record_layer_aead_concat_nonce(rl, aead, + if (!tls12_record_layer_aead_concat_nonce(rl, rp, CBS_data(seq_num), &nonce, &nonce_len)) goto err; } - if (aead->variable_nonce_in_record) { + if (rp->aead_variable_nonce_in_record) { /* XXX - length check? */ if (!CBB_add_bytes(out, CBS_data(seq_num), - aead->variable_nonce_len)) + rp->aead_variable_nonce_len)) goto err; } @@ -1155,13 +1165,13 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, goto err; /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ - enc_record_len = content_len + aead->tag_len; + enc_record_len = content_len + rp->aead_tag_len; if (enc_record_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) goto err; if (!CBB_add_space(out, &enc_data, enc_record_len)) goto err; - if (!EVP_AEAD_CTX_seal(&aead->ctx, enc_data, &out_len, enc_record_len, + if (!EVP_AEAD_CTX_seal(rp->aead_ctx, enc_data, &out_len, enc_record_len, nonce, nonce_len, content, content_len, header, header_len)) goto err; -- 2.20.1