diff options
Diffstat (limited to 'lib/libssl/tls12_record_layer.c')
-rw-r--r-- | lib/libssl/tls12_record_layer.c | 167 |
1 files changed, 110 insertions, 57 deletions
diff --git a/lib/libssl/tls12_record_layer.c b/lib/libssl/tls12_record_layer.c index f090e2d940a..b7e891d2687 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.18 2021/02/27 13:38:35 jsing Exp $ */ +/* $OpenBSD: tls12_record_layer.c,v 1.19 2021/02/27 14:20:50 jsing Exp $ */ /* * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> * @@ -33,10 +33,6 @@ struct tls12_record_protection { uint8_t *mac_key; size_t mac_key_len; - /* - * XXX - for now these are just pointers to externally managed - * structs/memory. These should eventually be owned by the record layer. - */ EVP_CIPHER_CTX *cipher_ctx; EVP_MD_CTX *hash_ctx; }; @@ -58,6 +54,12 @@ tls12_record_protection_clear(struct tls12_record_protection *rp) rp->aead_ctx = NULL; } + EVP_CIPHER_CTX_free(rp->cipher_ctx); + rp->cipher_ctx = NULL; + + EVP_MD_CTX_free(rp->hash_ctx); + rp->hash_ctx = NULL; + freezero(rp->mac_key, rp->mac_key_len); rp->mac_key = NULL; rp->mac_key_len = 0; @@ -149,6 +151,9 @@ struct tls12_record_layer { uint8_t alert_desc; const EVP_AEAD *aead; + const EVP_CIPHER *cipher; + const EVP_MD *handshake_hash; + const EVP_MD *mac_hash; /* Pointers to active record protection (memory is not owned). */ struct tls12_record_protection *read; @@ -247,6 +252,16 @@ tls12_record_layer_set_aead(struct tls12_record_layer *rl, const EVP_AEAD *aead) } void +tls12_record_layer_set_cipher_hash(struct tls12_record_layer *rl, + const EVP_CIPHER *cipher, const EVP_MD *handshake_hash, + const EVP_MD *mac_hash) +{ + rl->cipher = cipher; + rl->handshake_hash = handshake_hash; + rl->mac_hash = mac_hash; +} + +void tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) { rl->version = version; @@ -290,35 +305,15 @@ tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, uint16_t epoc rl->write_previous = NULL; } -static void -tls12_record_layer_set_read_state(struct tls12_record_layer *rl, - EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) -{ - rl->read->cipher_ctx = cipher_ctx; - rl->read->hash_ctx = hash_ctx; - rl->read->stream_mac = stream_mac; -} - -static void -tls12_record_layer_set_write_state(struct tls12_record_layer *rl, - EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) -{ - rl->write->cipher_ctx = cipher_ctx; - rl->write->hash_ctx = hash_ctx; - rl->write->stream_mac = stream_mac; -} - void tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) { - tls12_record_layer_set_read_state(rl, NULL, NULL, 0); tls12_record_protection_clear(rl->read); } void tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) { - tls12_record_layer_set_write_state(rl, NULL, NULL, 0); tls12_record_protection_clear(rl->write); tls12_record_protection_free(rl->write_previous); @@ -326,48 +321,36 @@ tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) } void -tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl) -{ - memcpy(rl->write->seq_num, rl->read->seq_num, - sizeof(rl->write->seq_num)); -} - -int -tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl, - EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) +tls12_record_layer_read_cipher_hash(struct tls12_record_layer *rl, + EVP_CIPHER_CTX **cipher, EVP_MD_CTX **hash) { - tls12_record_layer_set_read_state(rl, cipher_ctx, hash_ctx, - stream_mac); - - return 1; + *cipher = rl->read->cipher_ctx; + *hash = rl->read->hash_ctx; } -int -tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl, - EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) +void +tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl) { - tls12_record_layer_set_write_state(rl, cipher_ctx, hash_ctx, - stream_mac); - - return 1; + memcpy(rl->write->seq_num, rl->read->seq_num, + sizeof(rl->write->seq_num)); } -int -tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, +static int +tls12_record_layer_set_mac_key(struct tls12_record_protection *rp, const uint8_t *mac_key, size_t mac_key_len) { - freezero(rl->read->mac_key, rl->read->mac_key_len); - rl->read->mac_key = NULL; - rl->read->mac_key_len = 0; + freezero(rp->mac_key, rp->mac_key_len); + rp->mac_key = NULL; + rp->mac_key_len = 0; if (mac_key == NULL || mac_key_len == 0) return 1; - if ((rl->read->mac_key = calloc(1, mac_key_len)) == NULL) + if ((rp->mac_key = calloc(1, mac_key_len)) == NULL) return 0; - memcpy(rl->read->mac_key, mac_key, mac_key_len); - rl->read->mac_key_len = mac_key_len; + memcpy(rp->mac_key, mac_key, mac_key_len); + rp->mac_key_len = mac_key_len; return 1; } @@ -421,6 +404,76 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, } static int +tls12_record_layer_ccs_cipher(struct tls12_record_layer *rl, + struct tls12_record_protection *rp, int is_write, const uint8_t *mac_key, + size_t mac_key_len, const uint8_t *key, size_t key_len, const uint8_t *iv, + size_t iv_len) +{ + EVP_PKEY *mac_pkey = NULL; + int gost_param_nid; + int mac_type; + int ret = 0; + + mac_type = EVP_PKEY_HMAC; + rp->stream_mac = 0; + + /* Special handling for GOST... */ + if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) { + if (mac_key_len != 32) + goto err; + mac_type = EVP_PKEY_GOSTIMIT; + rp->stream_mac = 1; + } else { + if (EVP_MD_size(rl->mac_hash) != mac_key_len) + goto err; + } + + if ((rp->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + if ((rp->hash_ctx = EVP_MD_CTX_new()) == NULL) + goto err; + + if (!tls12_record_layer_set_mac_key(rp, mac_key, mac_key_len)) + goto err; + + if ((mac_pkey = EVP_PKEY_new_mac_key(mac_type, NULL, mac_key, + mac_key_len)) == NULL) + goto err; + + if (!EVP_CipherInit_ex(rp->cipher_ctx, rl->cipher, NULL, key, iv, + is_write)) + goto err; + + if (EVP_DigestSignInit(rp->hash_ctx, NULL, rl->mac_hash, NULL, + mac_pkey) <= 0) + goto err; + + /* More special handling for GOST... */ + if (EVP_CIPHER_type(rl->cipher) == NID_gost89_cnt) { + gost_param_nid = NID_id_tc26_gost_28147_param_Z; + if (EVP_MD_type(rl->handshake_hash) == NID_id_GostR3411_94) + gost_param_nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; + + if (EVP_CIPHER_CTX_ctrl(rp->cipher_ctx, EVP_CTRL_GOST_SET_SBOX, + gost_param_nid, 0) <= 0) + goto err; + + if (EVP_MD_type(rl->mac_hash) == NID_id_Gost28147_89_MAC) { + if (EVP_MD_CTX_ctrl(rp->hash_ctx, EVP_MD_CTRL_GOST_SET_SBOX, + gost_param_nid, 0) <= 0) + goto err; + } + } + + ret = 1; + + err: + EVP_PKEY_free(mac_pkey); + + return ret; +} + +static int tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl, struct tls12_record_protection *rp, int is_write, const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, size_t key_len, const uint8_t *iv, @@ -433,11 +486,11 @@ tls12_record_layer_change_cipher_state(struct tls12_record_layer *rl, if (mac_key_len > INT_MAX || key_len > INT_MAX || iv_len > INT_MAX) return 0; - /* XXX - only aead for now. */ - if (rl->aead == NULL) - return 1; + if (rl->aead != NULL) + return tls12_record_layer_ccs_aead(rl, rp, is_write, mac_key, + mac_key_len, key, key_len, iv, iv_len); - return tls12_record_layer_ccs_aead(rl, rp, is_write, mac_key, + return tls12_record_layer_ccs_cipher(rl, rp, is_write, mac_key, mac_key_len, key, key_len, iv, iv_len); } |