-/* $OpenBSD: d1_both.c,v 1.67 2021/02/20 14:14:16 tb Exp $ */
+/* $OpenBSD: d1_both.c,v 1.68 2021/02/27 14:20:50 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
if (frag == NULL)
return;
- if (frag->msg_header.is_ccs) {
- EVP_CIPHER_CTX_free(
- frag->msg_header.saved_retransmit_state.enc_write_ctx);
- EVP_MD_CTX_free(
- frag->msg_header.saved_retransmit_state.write_hash);
- }
free(frag->fragment);
free(frag->reassembly);
free(frag);
frag->msg_header.is_ccs = is_ccs;
/* save current state*/
- frag->msg_header.saved_retransmit_state.enc_write_ctx = s->internal->enc_write_ctx;
- frag->msg_header.saved_retransmit_state.write_hash = s->internal->write_hash;
frag->msg_header.saved_retransmit_state.session = s->session;
frag->msg_header.saved_retransmit_state.epoch = D1I(s)->w_epoch;
void
dtls1_clear_record_buffer(SSL *s)
{
+ hm_fragment *frag;
pitem *item;
for(item = pqueue_pop(s->d1->sent_messages); item != NULL;
item = pqueue_pop(s->d1->sent_messages)) {
- dtls1_hm_fragment_free((hm_fragment *)item->data);
+ frag = item->data;
+ if (frag->msg_header.is_ccs)
+ tls12_record_layer_write_epoch_done(s->internal->rl,
+ frag->msg_header.saved_retransmit_state.epoch);
+ dtls1_hm_fragment_free(frag);
pitem_free(item);
}
}
-/* $OpenBSD: ssl_lib.c,v 1.249 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.250 2021/02/27 14:20:50 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
void
ssl_clear_cipher_read_state(SSL *s)
{
- EVP_CIPHER_CTX_free(s->enc_read_ctx);
- s->enc_read_ctx = NULL;
- EVP_MD_CTX_free(s->read_hash);
- s->read_hash = NULL;
-
tls12_record_layer_clear_read_state(s->internal->rl);
+ tls12_record_layer_read_cipher_hash(s->internal->rl,
+ &s->enc_read_ctx, &s->read_hash);
}
void
ssl_clear_cipher_write_state(SSL *s)
{
- EVP_CIPHER_CTX_free(s->internal->enc_write_ctx);
- s->internal->enc_write_ctx = NULL;
- EVP_MD_CTX_free(s->internal->write_hash);
- s->internal->write_hash = NULL;
-
tls12_record_layer_clear_write_state(s->internal->rl);
}
-/* $OpenBSD: ssl_locl.h,v 1.323 2021/02/25 17:06:05 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.324 2021/02/27 14:20:50 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
int tls12_record_layer_write_protected(struct tls12_record_layer *rl);
void 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);
void tls12_record_layer_set_version(struct tls12_record_layer *rl,
uint16_t version);
void tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl,
void tls12_record_layer_clear_read_state(struct tls12_record_layer *rl);
void tls12_record_layer_clear_write_state(struct tls12_record_layer *rl);
void tls12_record_layer_reflect_seq_num(struct tls12_record_layer *rl);
-int tls12_record_layer_set_read_aead(struct tls12_record_layer *rl,
- SSL_AEAD_CTX *aead_ctx);
-int tls12_record_layer_set_write_aead(struct tls12_record_layer *rl,
- SSL_AEAD_CTX *aead_ctx);
-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);
-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);
-int tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl,
- const uint8_t *mac_key, size_t mac_key_len);
+void tls12_record_layer_read_cipher_hash(struct tls12_record_layer *rl,
+ EVP_CIPHER_CTX **cipher, EVP_MD_CTX **hash);
int tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl,
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);
STACK_OF(SSL_CIPHER) *cipher_list_tls13;
- EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
- EVP_MD_CTX *write_hash; /* used for mac generation */
-
struct tls12_record_layer *rl;
/* session info */
SSL_HANDSHAKE_TLS13 hs_tls13;
struct {
- int new_mac_secret_size;
-
unsigned char cert_verify_md[EVP_MAX_MD_SIZE];
unsigned char finish_md[EVP_MAX_MD_SIZE];
const EVP_CIPHER *new_sym_enc;
const EVP_AEAD *new_aead;
- const EVP_MD *new_hash;
- int new_mac_pkey_type;
+ int new_mac_secret_size;
+
int cert_request;
} tmp;
-/* $OpenBSD: t1_enc.c,v 1.132 2021/02/03 15:14:44 tb Exp $ */
+/* $OpenBSD: t1_enc.c,v 1.133 2021/02/27 14:20:50 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
NULL, 0, NULL, 0, key_block, key_block_len);
}
-/*
- * tls1_change_cipher_state_cipher performs the work needed to switch cipher
- * states when using EVP_CIPHER. The argument is_read is true iff this function
- * is being called due to reading, as opposed to writing, a ChangeCipherSpec
- * message.
- */
-static int
-tls1_change_cipher_state_cipher(SSL *s, char is_read,
- const unsigned char *mac_secret, unsigned int mac_secret_size,
- const unsigned char *key, unsigned int key_len, const unsigned char *iv,
- unsigned int iv_len)
-{
- EVP_CIPHER_CTX *cipher_ctx;
- const EVP_CIPHER *cipher;
- EVP_MD_CTX *mac_ctx;
- EVP_PKEY *mac_key;
- const EVP_MD *mac;
- int stream_mac;
- int mac_type;
-
- cipher = S3I(s)->tmp.new_sym_enc;
- mac = S3I(s)->tmp.new_hash;
- mac_type = S3I(s)->tmp.new_mac_pkey_type;
- stream_mac = S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC;
-
- if (is_read) {
- ssl_clear_cipher_read_state(s);
-
- if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL)
- goto err;
- s->enc_read_ctx = cipher_ctx;
- if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
- goto err;
- s->read_hash = mac_ctx;
-
- if (!tls12_record_layer_set_read_cipher_hash(s->internal->rl,
- cipher_ctx, mac_ctx, stream_mac))
- goto err;
-
- if (!tls12_record_layer_set_read_mac_key(s->internal->rl,
- mac_secret, mac_secret_size))
- goto err;
- } else {
- /*
- * DTLS fragments retain a pointer to the compression, cipher
- * and hash contexts, so that it can restore state in order
- * to perform retransmissions. As such, we cannot free write
- * contexts that are used for DTLS - these are instead freed
- * by DTLS when its frees a ChangeCipherSpec fragment.
- */
- if (!SSL_is_dtls(s))
- ssl_clear_cipher_write_state(s);
-
- if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL)
- goto err;
- s->internal->enc_write_ctx = cipher_ctx;
- if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
- goto err;
- s->internal->write_hash = mac_ctx;
-
- if (!tls12_record_layer_set_write_cipher_hash(s->internal->rl,
- cipher_ctx, mac_ctx, stream_mac))
- goto err;
- }
-
- EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read);
-
- if ((mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,
- mac_secret_size)) == NULL)
- goto err;
- EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key);
- EVP_PKEY_free(mac_key);
-
- if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) {
- int nid;
- if (S3I(s)->hs.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94)
- nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
- else
- nid = NID_id_tc26_gost_28147_param_Z;
-
- EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_SBOX, nid, 0);
- if (S3I(s)->hs.new_cipher->algorithm_mac == SSL_GOST89MAC)
- EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_GOST_SET_SBOX, nid, 0);
- }
-
- return (1);
-
-err:
- SSLerrorx(ERR_R_MALLOC_FAILURE);
- return (0);
-}
-
int
tls1_change_cipher_state(SSL *s, int which)
{
if (!tls12_record_layer_change_read_cipher_state(s->internal->rl,
mac_secret, mac_secret_size, key, key_len, iv, iv_len))
goto err;
+ tls12_record_layer_read_cipher_hash(s->internal->rl,
+ &s->enc_read_ctx, &s->read_hash);
} else {
if (!tls12_record_layer_change_write_cipher_state(s->internal->rl,
mac_secret, mac_secret_size, key, key_len, iv, iv_len))
goto err;
}
-
- if (aead != NULL)
- return 1;
-
- return tls1_change_cipher_state_cipher(s, is_read,
- mac_secret, mac_secret_size, key, key_len, iv, iv_len);
+ return (1);
err:
return (0);
int key_len, iv_len;
const EVP_CIPHER *cipher = NULL;
const EVP_AEAD *aead = NULL;
- const EVP_MD *mac = NULL;
+ const EVP_MD *handshake_hash = NULL;
+ const EVP_MD *mac_hash = NULL;
int ret = 0;
if (S3I(s)->hs.key_block_len != 0)
key_len = EVP_AEAD_key_length(aead);
iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher);
} else {
- if (!ssl_cipher_get_evp(s->session, &cipher, &mac, &mac_type,
- &mac_secret_size)) {
+ if (!ssl_cipher_get_evp(s->session, &cipher, &mac_hash,
+ &mac_type, &mac_secret_size)) {
SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return (0);
}
iv_len = EVP_CIPHER_iv_length(cipher);
}
+ if (!ssl_get_handshake_evp_md(s, &handshake_hash))
+ return (0);
+
S3I(s)->tmp.new_aead = aead;
S3I(s)->tmp.new_sym_enc = cipher;
- S3I(s)->tmp.new_hash = mac;
- S3I(s)->tmp.new_mac_pkey_type = mac_type;
S3I(s)->tmp.new_mac_secret_size = mac_secret_size;
tls12_record_layer_set_aead(s->internal->rl, aead);
+ tls12_record_layer_set_cipher_hash(s->internal->rl, cipher,
+ handshake_hash, mac_hash);
tls1_cleanup_key_block(s);
-/* $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>
*
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;
};
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;
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;
rl->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->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);
}
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;
}
return 1;
}
+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,
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);
}