summaryrefslogtreecommitdiff
path: root/src/lib/libssl/t1_enc.c
diff options
context:
space:
mode:
authorjsing <>2018-09-05 16:48:11 +0000
committerjsing <>2018-09-05 16:48:11 +0000
commit3dd336e6ff4073ca34d5f248d90afd65c6e3f27f (patch)
tree7285548c994d450785c9af93c1936fef8e5ee489 /src/lib/libssl/t1_enc.c
parent500c35c4f020d87efbd1b5f638d51d78cce1b5ea (diff)
downloadopenbsd-3dd336e6ff4073ca34d5f248d90afd65c6e3f27f.tar.gz
openbsd-3dd336e6ff4073ca34d5f248d90afd65c6e3f27f.tar.bz2
openbsd-3dd336e6ff4073ca34d5f248d90afd65c6e3f27f.zip
Correctly clear the current cipher state, when changing cipher state.
When a renegotiation results in a change of cipher suite, the renegotation would fail if it switched from AEAD to non-AEAD or vice versa. This is due to the fact that the previous EVP_AEAD or EVP_CIPHER state remained, resulting in incorrect logic that caused MAC failures. Rename ssl_clear_cipher_ctx() to ssl_clear_cipher_state() and split it into separate read/write components, then call these functions from the appropriate places when a ChangeCipherSpec message is being processed. Also, remove the separate ssl_clear_hash_ctx() calls and fold these into the ssl_clear_cipher_{read,write}_state() functions. Issue reported by Bernard Spil, who also tested this diff. ok tb@
Diffstat (limited to 'src/lib/libssl/t1_enc.c')
-rw-r--r--src/lib/libssl/t1_enc.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 24fc8ede68..39f542215b 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_enc.c,v 1.110 2018/08/31 18:31:34 jsing Exp $ */ 1/* $OpenBSD: t1_enc.c,v 1.111 2018/09/05 16:48:11 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -397,10 +397,13 @@ tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key,
397 SSL_AEAD_CTX *aead_ctx; 397 SSL_AEAD_CTX *aead_ctx;
398 398
399 if (is_read) { 399 if (is_read) {
400 ssl_clear_cipher_read_state(s);
400 if (!tls1_aead_ctx_init(&s->internal->aead_read_ctx)) 401 if (!tls1_aead_ctx_init(&s->internal->aead_read_ctx))
401 return 0; 402 return 0;
402 aead_ctx = s->internal->aead_read_ctx; 403 aead_ctx = s->internal->aead_read_ctx;
403 } else { 404 } else {
405 /* XXX - Need to correctly handle DTLS. */
406 ssl_clear_cipher_write_state(s);
404 if (!tls1_aead_ctx_init(&s->internal->aead_write_ctx)) 407 if (!tls1_aead_ctx_init(&s->internal->aead_write_ctx))
405 return 0; 408 return 0;
406 aead_ctx = s->internal->aead_write_ctx; 409 aead_ctx = s->internal->aead_write_ctx;
@@ -468,10 +471,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
468 else 471 else
469 s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; 472 s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
470 473
471 EVP_CIPHER_CTX_free(s->enc_read_ctx); 474 ssl_clear_cipher_read_state(s);
472 s->enc_read_ctx = NULL;
473 EVP_MD_CTX_destroy(s->read_hash);
474 s->read_hash = NULL;
475 475
476 if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) 476 if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL)
477 goto err; 477 goto err;
@@ -492,12 +492,9 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
492 * contexts that are used for DTLS - these are instead freed 492 * contexts that are used for DTLS - these are instead freed
493 * by DTLS when its frees a ChangeCipherSpec fragment. 493 * by DTLS when its frees a ChangeCipherSpec fragment.
494 */ 494 */
495 if (!SSL_IS_DTLS(s)) { 495 if (!SSL_IS_DTLS(s))
496 EVP_CIPHER_CTX_free(s->internal->enc_write_ctx); 496 ssl_clear_cipher_write_state(s);
497 s->internal->enc_write_ctx = NULL; 497
498 EVP_MD_CTX_destroy(s->internal->write_hash);
499 s->internal->write_hash = NULL;
500 }
501 if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL) 498 if ((cipher_ctx = EVP_CIPHER_CTX_new()) == NULL)
502 goto err; 499 goto err;
503 s->internal->enc_write_ctx = cipher_ctx; 500 s->internal->enc_write_ctx = cipher_ctx;