Absorb SSL_AEAD_CTX into struct tls12_record_protection.
authorjsing <jsing@openbsd.org>
Sun, 16 May 2021 15:49:01 +0000 (15:49 +0000)
committerjsing <jsing@openbsd.org>
Sun, 16 May 2021 15:49:01 +0000 (15:49 +0000)
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
lib/libssl/ssl_locl.h
lib/libssl/tls12_record_layer.c

index 5711430..f8360e5 100644 (file)
@@ -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 :-) */
 
index 2e324e5..df11572 100644 (file)
@@ -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);
index 82a14f7..06d1af9 100644 (file)
@@ -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 <jsing@openbsd.org>
  *
 
 #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;