diff --git a/CHANGES.md b/CHANGES.md index 46a878a6a53e72..3c8aa2258cbf42 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,18 @@ OpenSSL Releases - [OpenSSL 1.0.0](#openssl-100) - [OpenSSL 0.9.x](#openssl-09x) +OpenSSL 3.4 +----------- + +### Changes between 3.3 and 3.4 [xx XXX xxxx] + + * Added to TLS v1.3 support for integrity-only cipher suites + TLS_SHA256_SHA256 and TLS_SHA384_SHA384, as defined in RFC 9150. + + This work was sponsored by Siemens AG. + + *Rajeev Ranjan* + OpenSSL 3.3 ----------- @@ -96,11 +108,6 @@ OpenSSL 3.3 *Richard Levitte* - * Added to TLS v1.3 support for integrity-only cipher suites - TLS_SHA256_SHA256 and TLS_SHA384_SHA384, as defined in RFC 9150. - - *Rajeev Ranjan, Siemens AG* - * The BLAKE2s hash algorithm matches BLAKE2b's support for configurable output length. diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in index a5105655c9d131..fbd198916609cf 100644 --- a/doc/man1/openssl-ciphers.pod.in +++ b/doc/man1/openssl-ciphers.pod.in @@ -743,6 +743,10 @@ Note: the CBC modes mentioned in this RFC are not supported. TLS_SHA256_SHA256 TLS_SHA256_SHA256 TLS_SHA384_SHA384 TLS_SHA384_SHA384 +Note: these ciphers are HMAC based and do not provide any confidentiality +and thus are disabled by default. +These ciphers are available at security level 0. + =head2 Older names used by OpenSSL The following names are accepted by older releases: diff --git a/doc/man3/SSL_CTX_set_cipher_list.pod b/doc/man3/SSL_CTX_set_cipher_list.pod index 71f399400c2a12..de0d639b67b486 100644 --- a/doc/man3/SSL_CTX_set_cipher_list.pod +++ b/doc/man3/SSL_CTX_set_cipher_list.pod @@ -50,6 +50,10 @@ ciphersuite names in order of preference. Valid TLSv1.3 ciphersuite names are: =item TLS_AES_128_CCM_8_SHA256 +=item TLS_SHA384_SHA384 + +=item TLS_SHA256_SHA256 + =back An empty list is permissible. The default value for the this setting is: diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index dc6cdeb3f09833..d17987b930a24a 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -295,7 +295,7 @@ struct ossl_record_layer_st /* cryptographic state */ EVP_CIPHER_CTX *enc_ctx; - /* TLSv1.3 MAC ctx, ony used with NULL cipher*/ + /* TLSv1.3 MAC ctx, only used with Integrity-Only cipher*/ EVP_MAC_CTX *mac_ctx; /* Explicit IV length */ @@ -337,7 +337,6 @@ struct ossl_record_layer_st /* TLSv1.3 fields */ /* static IV */ - unsigned char iv_intern[EVP_MAX_IV_LENGTH]; unsigned char *iv; unsigned char *nonce; int allow_plain_alerts; diff --git a/ssl/record/methods/tls13_meth.c b/ssl/record/methods/tls13_meth.c index 144847e00bdb9f..02851031deefe6 100644 --- a/ssl/record/methods/tls13_meth.c +++ b/ssl/record/methods/tls13_meth.c @@ -31,24 +31,20 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0; rl->iv = OPENSSL_zalloc(ivlen); - if (rl->iv == NULL) - { + if (rl->iv == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return OSSL_RECORD_RETURN_FATAL; } rl->nonce = OPENSSL_zalloc(ivlen); - if (rl->nonce == NULL) - { + if (rl->nonce == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return OSSL_RECORD_RETURN_FATAL; } memcpy(rl->iv, iv, ivlen); /* Integrity only */ - if (EVP_CIPHER_is_a(ciph, "NULL") - && mactype == NID_hmac - && md != NULL) { + if (EVP_CIPHER_is_a(ciph, "NULL") && mactype == NID_hmac && md != NULL) { mac = EVP_MAC_fetch(rl->libctx, "HMAC", rl->propq); if (mac == NULL || (mac_ctx = rl->mac_ctx = EVP_MAC_CTX_new(mac)) == NULL) { @@ -105,7 +101,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, WPACKET wpkt; const EVP_CIPHER *cipher; EVP_MAC_CTX *mac_ctx = NULL; - int mode, ret = 0; + int mode; if (n_recs != 1) { /* Should not happen */ @@ -134,6 +130,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, return 1; } + /* For Integrity Only, ivlen is same as MAC size */ if (rl->mac_ctx != NULL) ivlen = EVP_MAC_CTX_get_mac_size(rl->mac_ctx); else @@ -179,23 +176,28 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, } if (rl->mac_ctx != NULL) { + int ret = 0; + if ((mac_ctx = EVP_MAC_CTX_dup(rl->mac_ctx)) == NULL || !EVP_MAC_update(mac_ctx, nonce, ivlen) || !EVP_MAC_update(mac_ctx, recheader, sizeof(recheader)) || !EVP_MAC_update(mac_ctx, rec->input, rec->length) || !EVP_MAC_final(mac_ctx, tag, &taglen, rl->taglen)) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto end; + goto end_mac; } if (sending) { memcpy(rec->data + rec->length, tag, rl->taglen); rec->length += rl->taglen; - } else if (CRYPTO_memcmp(tag, rec->data + rec->length, rl->taglen) != 0) { - goto end; + } else if (CRYPTO_memcmp(tag, rec->data + rec->length, + rl->taglen) != 0) { + goto end_mac; } ret = 1; - goto end; + end_mac: + EVP_MAC_CTX_free(mac_ctx); + return ret; } cipher = EVP_CIPHER_CTX_get0_cipher(ctx); @@ -206,9 +208,9 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, mode = EVP_CIPHER_get_mode(cipher); if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, sending) <= 0 - || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, - rl->taglen, - rec->data + rec->length) <= 0)) { + || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + rl->taglen, + rec->data + rec->length) <= 0)) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -236,11 +238,9 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, return 0; } rec->length += rl->taglen; - } - ret = 1; - end: - EVP_MAC_CTX_free(mac_ctx); - return ret; + } + + return 1; } static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl, diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 41537ceefb833d..5c74f53cb44392 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -524,11 +524,10 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, } else { const EVP_MD *digest = ctx->ssl_digest_methods[i]; - if (digest == NULL - || !ssl_evp_md_up_ref(digest)) { + if (digest == NULL || !ssl_evp_md_up_ref(digest)) return 0; - } - *md = ctx->ssl_digest_methods[i]; + + *md = digest; if (mac_pkey_type != NULL) *mac_pkey_type = ctx->ssl_mac_pkey_id[i]; if (mac_secret_size != NULL) @@ -586,7 +585,7 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, && (*md != NULL || (EVP_CIPHER_get_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) && (c->algorithm_mac == SSL_AEAD - ||!mac_pkey_type || *mac_pkey_type != NID_undef)) { + || mac_pkey_type == NULL || *mac_pkey_type != NID_undef)) { const EVP_CIPHER *evp = NULL; if (use_etm diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index c242f12e531731..67e79af3db0684 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -377,7 +377,8 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - *keylen = *ivlen = *taglen = (size_t)mac_mdleni; + *ivlen = *taglen = (size_t)mac_mdleni; + *keylen = s->s3.tmp.new_mac_secret_size; } else { *keylen = EVP_CIPHER_get_key_length(ciph); @@ -473,7 +474,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) const EVP_CIPHER *cipher = NULL; int mac_pkey_type = NID_undef; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen, mac_secret_size; + size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen; + EVP_MD_CTX *mdctx = NULL; int level; int direction = (which & SSL3_CC_READ) != 0 ? OSSL_RECORD_DIRECTION_READ : OSSL_RECORD_DIRECTION_WRITE; @@ -481,7 +483,6 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if (((which & SSL3_CC_CLIENT) && (which & SSL3_CC_WRITE)) || ((which & SSL3_CC_SERVER) && (which & SSL3_CC_READ))) { if (which & SSL3_CC_EARLY) { - EVP_MD_CTX *mdctx = NULL; long handlen; void *hdata; unsigned int hashlenui; @@ -537,18 +538,14 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); - EVP_MD_CTX_free(mdctx); goto err; } - if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { - /* Cipher is not AEAD */ - if (!ssl_cipher_get_evp_md_mac(sctx, sslcipher, &mac_md, - &mac_pkey_type, - &mac_secret_size)){ - EVP_MD_CTX_free(mdctx); - goto err; - } + if (((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0) + && (!ssl_cipher_get_evp_md_mac(sctx, sslcipher, &mac_md, + &mac_pkey_type, NULL))) { + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); + goto err; } md = ssl_md(sctx, sslcipher->algorithm2); @@ -556,11 +553,9 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) || !EVP_DigestUpdate(mdctx, hdata, handlen) || !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - EVP_MD_CTX_free(mdctx); goto err; } hashlen = hashlenui; - EVP_MD_CTX_free(mdctx); if (!tls13_hkdf_expand(s, md, insecret, early_exporter_master_secret, @@ -730,10 +725,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) err: if ((which & SSL3_CC_EARLY) != 0) { /* We up-refed this so now we need to down ref */ - if (!(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) + if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0) ssl_evp_md_free(mac_md); + EVP_MD_CTX_free(mdctx); ssl_evp_cipher_free(cipher); - } OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); diff --git a/test/sslapitest.c b/test/sslapitest.c index e524810d5a5a32..2c569f8d5fd93e 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -3905,7 +3905,7 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) unsigned char buf[20]; size_t readbytes, written; - if (is_fips && (cipher == 4 || cipher == 5 || cipher == 6)) + if (is_fips && cipher >= 4 ) return 1; if (ciphersuites[cipher] == NULL)