diff --git a/.github/workflows/run-checker-merge.yml b/.github/workflows/run-checker-merge.yml index e5746d75bdf8c..c278617a66ce8 100644 --- a/.github/workflows/run-checker-merge.yml +++ b/.github/workflows/run-checker-merge.yml @@ -33,6 +33,7 @@ jobs: no-srp, no-srtp, no-ts, + no-integrity-only-ciphers, enable-weak-ssl-ciphers, enable-zlib, ] diff --git a/CHANGES.md b/CHANGES.md index 21fd185444d77..1733dd220b53b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -47,6 +47,13 @@ OpenSSL 3.4 *Tim Perry* + * Added support for integrity-only cipher suites TLS_SHA256_SHA256 and + TLS_SHA384_SHA384 in TLS 1.3, as defined in RFC 9150. + + This work was sponsored by Siemens AG. + + *Rajeev Ranjan* + * Added support for requesting CRL in CMP. This work was sponsored by Siemens AG. diff --git a/Configure b/Configure index cef9e8c3e6662..7d45e92e4022f 100755 --- a/Configure +++ b/Configure @@ -528,6 +528,7 @@ my @disablables = ( "thread-pool", "threads", "tls", + "integrity-only-ciphers", "trace", "ts", "ubsan", diff --git a/INSTALL.md b/INSTALL.md index b486ee1556a25..b70211cfe7be6 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1113,6 +1113,10 @@ synonymous with `no-ssl3`. Note this only affects version negotiation. OpenSSL will still provide the methods for applications to explicitly select the individual protocol versions. +### no-integrity-only-ciphers + +Don't build support for integrity only ciphers in tls. + ### no-{protocol}-method no-{ssl3|tls1|tls1_1|tls1_2|dtls1|dtls1_2}-method diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in index a84d2daff5a70..5239beca1d692 100644 --- a/doc/man1/openssl-ciphers.pod.in +++ b/doc/man1/openssl-ciphers.pod.in @@ -738,6 +738,15 @@ Note: the CBC modes mentioned in this RFC are not supported. TLS_AES_128_CCM_SHA256 TLS_AES_128_CCM_SHA256 TLS_AES_128_CCM_8_SHA256 TLS_AES_128_CCM_8_SHA256 +=head2 TLS v1.3 integrity-only cipher suites according to RFC 9150 + + TLS_SHA256_SHA256 TLS_SHA256_SHA256 + TLS_SHA384_SHA384 TLS_SHA384_SHA384 + +Note: these ciphers are purely HMAC based and do not provide any confidentiality +and thus are disabled by default. +These ciphers are only available at security level 0. + =head2 Older names used by OpenSSL The following names are accepted by older releases: @@ -802,6 +811,8 @@ The B<-convert> option was added in OpenSSL 1.1.1. Support for standard IANA names in cipher lists was added in OpenSSL 3.2.0. +The support for TLS v1.3 integrity-only cipher suites was added in OpenSSL 3.4. + =head1 COPYRIGHT Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/SSL_CTX_set_cipher_list.pod b/doc/man3/SSL_CTX_set_cipher_list.pod index 71f399400c2a1..0fe8be8094c8f 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 - integrity-only + +=item TLS_SHA256_SHA256 - integrity-only + =back An empty list is permissible. The default value for the this setting is: diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 7e3d1a725b82e..8ff39e3956bb9 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -622,6 +622,10 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb # define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 # define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 +/* Integrity-only ciphersuites from RFC 9150 */ +# define TLS1_3_CK_SHA256_SHA256 0x0300C0B4 +# define TLS1_3_CK_SHA384_SHA384 0x0300C0B5 + /* Aria ciphersuites from RFC6209 */ # define TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C050 # define TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C051 @@ -699,6 +703,8 @@ int SSL_CTX_set_tlsext_ticket_key_evp_cb # define TLS1_3_RFC_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" # define TLS1_3_RFC_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" # define TLS1_3_RFC_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +# define TLS1_3_RFC_SHA256_SHA256 "TLS_SHA256_SHA256" +# define TLS1_3_RFC_SHA384_SHA384 "TLS_SHA384_SHA384" # define TLS1_3_RFC_AES_128_CCM_SHA256 "TLS_AES_128_CCM_SHA256" # define TLS1_3_RFC_AES_128_CCM_8_SHA256 "TLS_AES_128_CCM_8_SHA256" # define TLS1_RFC_ECDHE_ECDSA_WITH_NULL_SHA "TLS_ECDHE_ECDSA_WITH_NULL_SHA" diff --git a/providers/implementations/ciphers/cipher_null.c b/providers/implementations/ciphers/cipher_null.c index c911049e2d0b7..81f9fa10be473 100644 --- a/providers/implementations/ciphers/cipher_null.c +++ b/providers/implementations/ciphers/cipher_null.c @@ -82,7 +82,7 @@ static int null_cipher(void *vctx, unsigned char *out, size_t *outl, } if (outsize < inl) return 0; - if (in != out) + if (out != NULL && in != out) memcpy(out, in, inl); *outl = inl; return 1; diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index fe9dce15358ed..5a3d010503a86 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -295,6 +295,9 @@ struct ossl_record_layer_st /* cryptographic state */ EVP_CIPHER_CTX *enc_ctx; + /* TLSv1.3 MAC ctx, only used with integrity-only cipher */ + EVP_MAC_CTX *mac_ctx; + /* Explicit IV length */ size_t eivlen; @@ -333,8 +336,8 @@ struct ossl_record_layer_st int tlstree; /* TLSv1.3 fields */ - /* static IV */ - unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char *iv; /* static IV */ + unsigned char *nonce; /* part of static IV followed by sequence number */ int allow_plain_alerts; /* TLS "any" fields */ diff --git a/ssl/record/methods/tls13_meth.c b/ssl/record/methods/tls13_meth.c index d782c327ec071..afae14ad22b20 100644 --- a/ssl/record/methods/tls13_meth.c +++ b/ssl/record/methods/tls13_meth.c @@ -24,15 +24,42 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, COMP_METHOD *comp) { EVP_CIPHER_CTX *ciph_ctx; + EVP_MAC_CTX *mac_ctx; + EVP_MAC *mac; + OSSL_PARAM params[2], *p = params; int mode; int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0; - if (ivlen > sizeof(rl->iv)) { - ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + rl->iv = OPENSSL_malloc(ivlen); + if (rl->iv == NULL) return OSSL_RECORD_RETURN_FATAL; - } + + rl->nonce = OPENSSL_malloc(ivlen); + if (rl->nonce == NULL) + return OSSL_RECORD_RETURN_FATAL; + memcpy(rl->iv, iv, ivlen); + /* Integrity only */ + 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) { + EVP_MAC_free(mac); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + EVP_MAC_free(mac); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + (char *)EVP_MD_name(md), 0); + *p = OSSL_PARAM_construct_end(); + if (!EVP_MAC_init(mac_ctx, key, keylen, params)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + goto end; + } + ciph_ctx = rl->enc_ctx = EVP_CIPHER_CTX_new(); if (ciph_ctx == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); @@ -51,7 +78,7 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return OSSL_RECORD_RETURN_FATAL; } - + end: return OSSL_RECORD_RETURN_SUCCESS; } @@ -59,15 +86,18 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, size_t n_recs, int sending, SSL_MAC_BUF *mac, size_t macsize) { - EVP_CIPHER_CTX *ctx; - unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH]; - size_t ivlen, offset, loop, hdrlen; + EVP_CIPHER_CTX *enc_ctx; + unsigned char recheader[SSL3_RT_HEADER_LENGTH]; + unsigned char tag[EVP_MAX_MD_SIZE]; + size_t nonce_len, offset, loop, hdrlen, taglen; unsigned char *staticiv; + unsigned char *nonce; unsigned char *seq = rl->sequence; int lenu, lenf; TLS_RL_RECORD *rec = &recs[0]; WPACKET wpkt; const EVP_CIPHER *cipher; + EVP_MAC_CTX *mac_ctx = NULL; int mode; if (n_recs != 1) { @@ -76,15 +106,14 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, return 0; } - ctx = rl->enc_ctx; + enc_ctx = rl->enc_ctx; /* enc_ctx is ignored when rl->mac_ctx != NULL */ staticiv = rl->iv; + nonce = rl->nonce; - cipher = EVP_CIPHER_CTX_get0_cipher(ctx); - if (cipher == NULL) { + if (enc_ctx == NULL && rl->mac_ctx == NULL) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - mode = EVP_CIPHER_get_mode(cipher); /* * If we're sending an alert and ctx != NULL then we must be forcing @@ -92,13 +121,17 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, * plaintext alerts at certain points in the handshake. If we've got this * far then we have already validated that a plaintext alert is ok here. */ - if (ctx == NULL || rec->type == SSL3_RT_ALERT) { + if (rec->type == SSL3_RT_ALERT) { memmove(rec->data, rec->input, rec->length); rec->input = rec->data; return 1; } - ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + /* For integrity-only ciphers, nonce_len is same as MAC size */ + if (rl->mac_ctx != NULL) + nonce_len = EVP_MAC_CTX_get_mac_size(rl->mac_ctx); + else + nonce_len = EVP_CIPHER_CTX_get_iv_length(enc_ctx); if (!sending) { /* @@ -110,30 +143,22 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, rec->length -= rl->taglen; } - /* Set up IV */ - if (ivlen < SEQ_NUM_SIZE) { + /* Set up nonce: part of static IV followed by sequence number */ + if (nonce_len < SEQ_NUM_SIZE) { /* Should not happen */ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - offset = ivlen - SEQ_NUM_SIZE; - memcpy(iv, staticiv, offset); + offset = nonce_len - SEQ_NUM_SIZE; + memcpy(nonce, staticiv, offset); for (loop = 0; loop < SEQ_NUM_SIZE; loop++) - iv[offset + loop] = staticiv[offset + loop] ^ seq[loop]; + nonce[offset + loop] = staticiv[offset + loop] ^ seq[loop]; if (!tls_increment_sequence_ctr(rl)) { /* RLAYERfatal already called */ return 0; } - if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 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; - } - /* Set up the AAD */ if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0) || !WPACKET_put_bytes_u8(&wpkt, rec->type) @@ -147,24 +172,64 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, return 0; } + 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, nonce_len) + || !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_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_mac; + } + ret = 1; + end_mac: + EVP_MAC_CTX_free(mac_ctx); + return ret; + } + + cipher = EVP_CIPHER_CTX_get0_cipher(enc_ctx); + if (cipher == NULL) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + mode = EVP_CIPHER_get_mode(cipher); + + if (EVP_CipherInit_ex(enc_ctx, NULL, NULL, NULL, nonce, sending) <= 0 + || (!sending && EVP_CIPHER_CTX_ctrl(enc_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; + } + /* * For CCM we must explicitly set the total plaintext length before we add * any AAD. */ if ((mode == EVP_CIPH_CCM_MODE - && EVP_CipherUpdate(ctx, NULL, &lenu, NULL, + && EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL, (unsigned int)rec->length) <= 0) - || EVP_CipherUpdate(ctx, NULL, &lenu, recheader, + || EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader, sizeof(recheader)) <= 0 - || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input, + || EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input, (unsigned int)rec->length) <= 0 - || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 + || EVP_CipherFinal_ex(enc_ctx, rec->data + lenu, &lenf) <= 0 || (size_t)(lenu + lenf) != rec->length) { return 0; } if (sending) { /* Add the tag */ - if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen, + if (EVP_CIPHER_CTX_ctrl(enc_ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen, rec->data + rec->length) <= 0) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index d9e017d254afd..bf6dc0d1f55c6 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -1434,11 +1434,13 @@ static void tls_int_free(OSSL_RECORD_LAYER *rl) tls_release_write_buffer(rl); EVP_CIPHER_CTX_free(rl->enc_ctx); + EVP_MAC_CTX_free(rl->mac_ctx); EVP_MD_CTX_free(rl->md_ctx); #ifndef OPENSSL_NO_COMP COMP_CTX_free(rl->compctx); #endif - + OPENSSL_free(rl->iv); + OPENSSL_free(rl->nonce); if (rl->version == SSL3_VERSION) OPENSSL_cleanse(rl->mac_secret, sizeof(rl->mac_secret)); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 2bc5e79fd1296..5c7f338c65283 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -112,7 +112,40 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_HANDSHAKE_MAC_SHA256, 64, /* CCM8 uses a short tag, so we have a low security strength */ 128, - } + }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS + { + 1, + TLS1_3_RFC_SHA256_SHA256, + TLS1_3_RFC_SHA256_SHA256, + TLS1_3_CK_SHA256_SHA256, + SSL_kANY, + SSL_aANY, + SSL_eNULL, + SSL_SHA256, + TLS1_3_VERSION, TLS1_3_VERSION, + 0, 0, + SSL_NOT_DEFAULT | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_SHA256, + 0, + 256, + }, { + 1, + TLS1_3_RFC_SHA384_SHA384, + TLS1_3_RFC_SHA384_SHA384, + TLS1_3_CK_SHA384_SHA384, + SSL_kANY, + SSL_aANY, + SSL_eNULL, + SSL_SHA384, + TLS1_3_VERSION, TLS1_3_VERSION, + 0, 0, + SSL_NOT_DEFAULT | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_SHA384, + 0, + 384, + }, +#endif }; /* @@ -126,6 +159,7 @@ static SSL_CIPHER tls13_ciphers[] = { * Weak ciphers */ static SSL_CIPHER ssl3_ciphers[] = { +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, SSL3_TXT_RSA_NULL_MD5, @@ -158,6 +192,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -352,6 +387,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_RSA_WITH_NULL_SHA256, @@ -368,6 +404,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif { 1, TLS1_TXT_RSA_WITH_AES_128_SHA256, @@ -944,6 +981,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 64, /* CCM8 uses a short tag, so we have a low security strength */ 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, @@ -960,6 +998,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -1010,6 +1049,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, @@ -1026,6 +1066,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -1076,6 +1117,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_ECDH_anon_WITH_NULL_SHA, @@ -1092,6 +1134,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -1270,6 +1313,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_PSK_WITH_NULL_SHA, @@ -1318,6 +1362,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -1596,6 +1641,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_PSK_WITH_NULL_SHA256, @@ -1628,6 +1674,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif { 1, TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256, @@ -1660,6 +1707,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_DHE_PSK_WITH_NULL_SHA256, @@ -1692,6 +1740,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif { 1, TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256, @@ -1724,6 +1773,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_RSA_PSK_WITH_NULL_SHA256, @@ -1756,6 +1806,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +#endif # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -1838,6 +1889,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +#ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA, @@ -1886,7 +1938,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, - +#endif # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS { 1, @@ -2613,6 +2665,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +# ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, "GOST2001-NULL-GOST94", @@ -2629,6 +2682,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +# endif { 1, "IANA-GOST2012-GOST8912-GOST8912", @@ -2661,6 +2715,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 256, 256, }, +# ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS { 1, "GOST2012-NULL-GOST12", @@ -2677,6 +2732,7 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, +# endif { 1, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC", diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index ddde21b968c7c..5a48be01713a5 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -482,7 +482,8 @@ static int load_builtin_compressions(void) int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, const EVP_CIPHER **enc) { - int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, sslc->algorithm_enc); + int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, + sslc->algorithm_enc); if (i == -1) { *enc = NULL; @@ -508,6 +509,33 @@ int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, return 1; } +int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_MD **md, + int *mac_pkey_type, size_t *mac_secret_size) +{ + int i = ssl_cipher_info_lookup(ssl_cipher_table_mac, sslc->algorithm_mac); + + if (i == -1) { + *md = NULL; + if (mac_pkey_type != NULL) + *mac_pkey_type = NID_undef; + if (mac_secret_size != NULL) + *mac_secret_size = 0; + } else { + const EVP_MD *digest = ctx->ssl_digest_methods[i]; + + if (digest == NULL || !ssl_evp_md_up_ref(digest)) + return 0; + + *md = digest; + if (mac_pkey_type != NULL) + *mac_pkey_type = ctx->ssl_mac_pkey_id[i]; + if (mac_secret_size != NULL) + *mac_secret_size = ctx->ssl_mac_secret_size[i]; + } + return 1; +} + int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, const EVP_CIPHER **enc, const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size, @@ -547,34 +575,17 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, if (!ssl_cipher_get_evp_cipher(ctx, c, enc)) return 0; - i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac); - if (i == -1) { - *md = NULL; - if (mac_pkey_type != NULL) - *mac_pkey_type = NID_undef; - if (mac_secret_size != NULL) - *mac_secret_size = 0; - if (c->algorithm_mac == SSL_AEAD) - mac_pkey_type = NULL; - } else { - const EVP_MD *digest = ctx->ssl_digest_methods[i]; - - if (digest == NULL - || !ssl_evp_md_up_ref(digest)) { - ssl_evp_cipher_free(*enc); - return 0; - } - *md = digest; - if (mac_pkey_type != NULL) - *mac_pkey_type = ctx->ssl_mac_pkey_id[i]; - if (mac_secret_size != NULL) - *mac_secret_size = ctx->ssl_mac_secret_size[i]; + if (!ssl_cipher_get_evp_md_mac(ctx, c, md, mac_pkey_type, + mac_secret_size)) { + ssl_evp_cipher_free(*enc); + return 0; } if ((*enc != NULL) - && (*md != NULL + && (*md != NULL || (EVP_CIPHER_get_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) - && (!mac_pkey_type || *mac_pkey_type != NID_undef)) { + && (c->algorithm_mac == SSL_AEAD + || mac_pkey_type == NULL || *mac_pkey_type != NID_undef)) { const EVP_CIPHER *evp = NULL; if (use_etm diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index f448cfdbc94a1..9940438adfa29 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -2500,6 +2500,9 @@ __owur int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, void ssl_update_cache(SSL_CONNECTION *s, int mode); __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, const EVP_CIPHER **enc); +__owur int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_MD **md, + int *mac_pkey_type, size_t *mac_secret_size); __owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s, const EVP_CIPHER **enc, const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size, diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index 29dce65e4f62f..9c811c5ee6afe 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -446,6 +446,8 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = { {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, {0xFF85, "LEGACY-GOST2012-GOST8912-GOST8912"}, {0xFF87, "GOST2012-NULL-GOST12"}, + {0xC0B4, "TLS_SHA256_SHA256"}, + {0xC0B5, "TLS_SHA384_SHA384"}, {0xC100, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC"}, {0xC101, "GOST2012-MAGMA-MAGMAOMAC"}, {0xC102, "GOST2012-GOST8912-IANA"}, diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 56f100371d47e..f6b4b9f4c21af 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -323,10 +323,12 @@ int tls13_setup_key_block(SSL_CONNECTION *s) { const EVP_CIPHER *c; const EVP_MD *hash; + int mac_type = NID_undef; + size_t mac_secret_size = 0; s->session->cipher = s->s3.tmp.new_cipher; if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, - NULL, NULL, NULL, 0)) { + &mac_type, &mac_secret_size, NULL, 0)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; @@ -336,23 +338,27 @@ int tls13_setup_key_block(SSL_CONNECTION *s) s->s3.tmp.new_sym_enc = c; ssl_evp_md_free(s->s3.tmp.new_hash); s->s3.tmp.new_hash = hash; + s->s3.tmp.new_mac_pkey_type = mac_type; + s->s3.tmp.new_mac_secret_size = mac_secret_size; return 1; } static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, const EVP_CIPHER *ciph, + int mac_type, + const EVP_MD *mac_md, const unsigned char *insecret, const unsigned char *hash, const unsigned char *label, size_t labellen, unsigned char *secret, unsigned char *key, size_t *keylen, - unsigned char *iv, size_t *ivlen, + unsigned char **iv, size_t *ivlen, size_t *taglen) { int hashleni = EVP_MD_get_size(md); size_t hashlen; - int mode; + int mode, mac_mdleni; /* Ensure cast to size_t is safe */ if (!ossl_assert(hashleni >= 0)) { @@ -367,48 +373,71 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, return 0; } - *keylen = EVP_CIPHER_get_key_length(ciph); - - mode = EVP_CIPHER_get_mode(ciph); - if (mode == EVP_CIPH_CCM_MODE) { - uint32_t algenc; - - *ivlen = EVP_CCM_TLS_IV_LEN; - if (s->s3.tmp.new_cipher != NULL) { - algenc = s->s3.tmp.new_cipher->algorithm_enc; - } else if (s->session->cipher != NULL) { - /* We've not selected a cipher yet - we must be doing early data */ - algenc = s->session->cipher->algorithm_enc; - } else if (s->psksession != NULL && s->psksession->cipher != NULL) { - /* We must be doing early data with out-of-band PSK */ - algenc = s->psksession->cipher->algorithm_enc; - } else { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + /* if ciph is NULL cipher, then use new_hash to calculate keylen */ + if (EVP_CIPHER_is_a(ciph, "NULL") + && mac_md != NULL + && mac_type == NID_hmac) { + mac_mdleni = EVP_MD_get_size(mac_md); + + if (mac_mdleni < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) - *taglen = EVP_CCM8_TLS_TAG_LEN; - else - *taglen = EVP_CCM_TLS_TAG_LEN; + *ivlen = *taglen = (size_t)mac_mdleni; + *keylen = s->s3.tmp.new_mac_secret_size; } else { - int iivlen; - if (mode == EVP_CIPH_GCM_MODE) { - *taglen = EVP_GCM_TLS_TAG_LEN; + *keylen = EVP_CIPHER_get_key_length(ciph); + + mode = EVP_CIPHER_get_mode(ciph); + if (mode == EVP_CIPH_CCM_MODE) { + uint32_t algenc; + + *ivlen = EVP_CCM_TLS_IV_LEN; + if (s->s3.tmp.new_cipher != NULL) { + algenc = s->s3.tmp.new_cipher->algorithm_enc; + } else if (s->session->cipher != NULL) { + /* We've not selected a cipher yet - we must be doing early data */ + algenc = s->session->cipher->algorithm_enc; + } else if (s->psksession != NULL && s->psksession->cipher != NULL) { + /* We must be doing early data with out-of-band PSK */ + algenc = s->psksession->cipher->algorithm_enc; + } else { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; + } + if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) + *taglen = EVP_CCM8_TLS_TAG_LEN; + else + *taglen = EVP_CCM_TLS_TAG_LEN; } else { - /* CHACHA20P-POLY1305 */ - *taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; + int iivlen; + + if (mode == EVP_CIPH_GCM_MODE) { + *taglen = EVP_GCM_TLS_TAG_LEN; + } else { + /* CHACHA20P-POLY1305 */ + *taglen = EVP_CHACHAPOLY_TLS_TAG_LEN; + } + iivlen = EVP_CIPHER_get_iv_length(ciph); + if (iivlen < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + return 0; + } + *ivlen = iivlen; } - iivlen = EVP_CIPHER_get_iv_length(ciph); - if (iivlen < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); + } + + if (*ivlen > EVP_MAX_IV_LENGTH) { + *iv = OPENSSL_malloc(*ivlen); + if (*iv == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } - *ivlen = iivlen; } if (!tls13_derive_key(s, md, secret, key, *keylen) - || !tls13_derive_iv(s, md, secret, iv, *ivlen)) { + || !tls13_derive_iv(s, md, secret, *iv, *ivlen)) { /* SSLfatal() already called */ return 0; } @@ -434,7 +463,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) static const unsigned char resumption_master_secret[] = "\x72\x65\x73\x20\x6D\x61\x73\x74\x65\x72"; /* ASCII: "e exp master", in hex for EBCDIC compatibility */ static const unsigned char early_exporter_master_secret[] = "\x65\x20\x65\x78\x70\x20\x6D\x61\x73\x74\x65\x72"; - unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char iv_intern[EVP_MAX_IV_LENGTH]; + unsigned char *iv = iv_intern; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; @@ -446,17 +476,18 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) const unsigned char *label; size_t labellen, hashlen = 0; int ret = 0; - const EVP_MD *md = NULL; + const EVP_MD *md = NULL, *mac_md = NULL; const EVP_CIPHER *cipher = NULL; + int mac_pkey_type = NID_undef; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - size_t keylen, ivlen, taglen; + size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen; int level; int direction = (which & SSL3_CC_READ) != 0 ? OSSL_RECORD_DIRECTION_READ : OSSL_RECORD_DIRECTION_WRITE; if (((which & SSL3_CC_CLIENT) && (which & SSL3_CC_WRITE)) || ((which & SSL3_CC_SERVER) && (which & SSL3_CC_READ))) { - if (which & SSL3_CC_EARLY) { + if ((which & SSL3_CC_EARLY) != 0) { EVP_MD_CTX *mdctx = NULL; long handlen; void *hdata; @@ -495,6 +526,23 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) goto err; } + /* + * This ups the ref count on cipher so we better make sure we free + * it again + */ + if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) { + /* Error is already recorded */ + SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); + 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; + } + /* * We need to calculate the handshake digest using the digest from * the session. We haven't yet selected our ciphersuite so we can't @@ -506,17 +554,6 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) goto err; } - /* - * This ups the ref count on cipher so we better make sure we free - * it again - */ - 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; - } - md = ssl_md(sctx, sslcipher->algorithm2); if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL) || !EVP_DigestUpdate(mdctx, hdata, handlen) @@ -598,9 +635,11 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) } } - if (!(which & SSL3_CC_EARLY)) { + if ((which & SSL3_CC_EARLY) == 0) { md = ssl_handshake_md(s); cipher = s->s3.tmp.new_sym_enc; + mac_md = s->s3.tmp.new_hash; + mac_pkey_type = s->s3.tmp.new_mac_pkey_type; if (!ssl3_digest_cached_records(s, 1) || !ssl_handshake_hash(s, hashval, sizeof(hashval), &hashlen)) { /* SSLfatal() already called */; @@ -637,9 +676,9 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if (!ossl_assert(cipher != NULL)) goto err; - if (!derive_secret_key_and_iv(s, md, cipher, + if (!derive_secret_key_and_iv(s, md, cipher, mac_pkey_type, mac_md, insecret, hash, label, labellen, secret, key, - &keylen, iv, &ivlen, &taglen)) { + &keylen, &iv, &ivlen, &taglen)) { /* SSLfatal() already called */ goto err; } @@ -692,8 +731,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if (!ssl_set_new_record_layer(s, s->version, direction, level, secret, hashlen, key, keylen, iv, - ivlen, NULL, 0, cipher, taglen, NID_undef, - NULL, NULL, md)) { + ivlen, NULL, 0, cipher, taglen, + mac_pkey_type, mac_md, NULL, md)) { /* SSLfatal already called */ goto err; } @@ -702,10 +741,14 @@ 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) == 0) + ssl_evp_md_free(mac_md); ssl_evp_cipher_free(cipher); } OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); + if (iv != iv_intern) + OPENSSL_free(iv); return ret; } @@ -723,7 +766,8 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) int ret = 0, l; int direction = sending ? OSSL_RECORD_DIRECTION_WRITE : OSSL_RECORD_DIRECTION_READ; - unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char iv_intern[EVP_MAX_IV_LENGTH]; + unsigned char *iv = iv_intern; if ((l = EVP_MD_get_size(md)) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -737,10 +781,12 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) insecret = s->client_app_traffic_secret; if (!derive_secret_key_and_iv(s, md, - s->s3.tmp.new_sym_enc, insecret, NULL, + s->s3.tmp.new_sym_enc, + s->s3.tmp.new_mac_pkey_type, s->s3.tmp.new_hash, + insecret, NULL, application_traffic, sizeof(application_traffic) - 1, secret, key, - &keylen, iv, &ivlen, &taglen)) { + &keylen, &iv, &ivlen, &taglen)) { /* SSLfatal() already called */ goto err; } @@ -767,6 +813,8 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) err: OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); + if (iv != iv_intern) + OPENSSL_free(iv); return ret; } diff --git a/test/ciphername_test.c b/test/ciphername_test.c index c4ec6cadd740b..8f10f26ba1687 100644 --- a/test/ciphername_test.c +++ b/test/ciphername_test.c @@ -361,6 +361,8 @@ static CIPHER_ID_NAME cipher_names[] = { {0x1303, "TLS_CHACHA20_POLY1305_SHA256"}, {0x1304, "TLS_AES_128_CCM_SHA256"}, {0x1305, "TLS_AES_128_CCM_8_SHA256"}, + {0xC0B4, "TLS_SHA256_SHA256"}, + {0xC0B5, "TLS_SHA384_SHA384"}, {0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, }; diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c index 30fc85e8d3a35..3ca25d12f720b 100644 --- a/test/evp_libctx_test.c +++ b/test/evp_libctx_test.c @@ -365,7 +365,11 @@ static int test_cipher_reinit(int test_id) 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; - unsigned char iv[16] = { + unsigned char iv[48] = { + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; @@ -456,7 +460,11 @@ static int test_cipher_reinit_partialupdate(int test_id) 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, }; - static const unsigned char iv[16] = { + static const unsigned char iv[48] = { + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; diff --git a/test/evp_test.c b/test/evp_test.c index 5634631703240..e0edd36b9a97c 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1064,7 +1064,7 @@ static int cipher_test_enc(EVP_TEST *t, int enc, size_t out_misalign, tmp + out_misalign, tmplen + tmpflen)) goto err; if (enc && expected->aead && !expected->tls_aad) { - unsigned char rtag[16]; + unsigned char rtag[48]; /* longest known for TLS_SHA384_SHA384 */ if (!TEST_size_t_le(expected->tag_len, sizeof(rtag))) { t->err = "TAG_LENGTH_INTERNAL_ERROR"; diff --git a/test/helpers/ssltestlib.h b/test/helpers/ssltestlib.h index 871f9bd52e09d..468662ed0bfd7 100644 --- a/test/helpers/ssltestlib.h +++ b/test/helpers/ssltestlib.h @@ -17,6 +17,8 @@ #define TLS13_CHACHA20_POLY1305_SHA256_BYTES ((const unsigned char *)"\x13\x03") #define TLS13_AES_128_CCM_SHA256_BYTES ((const unsigned char *)"\x13\x04") #define TLS13_AES_128_CCM_8_SHA256_BYTES ((const unsigned char *)"\x13\05") +#define TLS13_SHA256_SHA256_BYTES ((const unsigned char *)"\xC0\xB4") +#define TLS13_SHA384_SHA384_BYTES ((const unsigned char *)"\xC0\xB5") int create_ssl_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, diff --git a/test/quicapitest.c b/test/quicapitest.c index 227f6de8c8a8b..d8e65dc4e5b0c 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -342,7 +342,11 @@ static int test_cipher_find(void) { TLS13_AES_256_GCM_SHA384_BYTES, 1 }, { TLS13_CHACHA20_POLY1305_SHA256_BYTES, 1 }, { TLS13_AES_128_CCM_SHA256_BYTES, 0 }, - { TLS13_AES_128_CCM_8_SHA256_BYTES, 0 } + { TLS13_AES_128_CCM_8_SHA256_BYTES, 0 }, +#if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) + { TLS13_SHA256_SHA256_BYTES, 0 }, + { TLS13_SHA384_SHA384_BYTES, 0 } +#endif }; size_t i; int testresult = 0; @@ -588,7 +592,9 @@ static int test_quic_forbidden_apis_ctx(void) #define NON_QUIC_CIPHERSUITES \ "TLS_AES_128_CCM_SHA256:" \ "TLS_AES_256_CCM_SHA384:" \ - "TLS_AES_128_CCM_8_SHA256" + "TLS_AES_128_CCM_8_SHA256:" \ + "TLS_SHA256_SHA256:" \ + "TLS_SHA384_SHA384" /* Set TLSv1.3 ciphersuite list for the SSL_CTX. */ if (!TEST_true(SSL_CTX_set_ciphersuites(ctx, diff --git a/test/sslapitest.c b/test/sslapitest.c index b57ca8b113333..8601b79299f5e 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -3915,7 +3915,13 @@ static const char *ciphersuites[] = { "TLS_AES_256_GCM_SHA384", "TLS_AES_128_CCM_SHA256", #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) - "TLS_CHACHA20_POLY1305_SHA256" + "TLS_CHACHA20_POLY1305_SHA256", +#else + NULL, +#endif +#if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) + "TLS_SHA256_SHA256", + "TLS_SHA384_SHA384" #endif }; @@ -3936,16 +3942,19 @@ 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) + if (is_fips && cipher >= 4) return 1; + if (ciphersuites[cipher] == NULL) + return TEST_skip("Cipher not supported"); + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), TLS1_VERSION, 0, &sctx, &cctx, cert, privkey))) goto end; - if (cipher == 0) { + if (cipher == 0 || cipher == 5 || cipher == 6) { SSL_CTX_set_security_level(sctx, 0); SSL_CTX_set_security_level(cctx, 0); } @@ -3956,8 +3965,9 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, idx, - cipher == 2 ? SHA384_DIGEST_LENGTH - : SHA256_DIGEST_LENGTH))) + (cipher == 2 || cipher == 6) + ? SHA384_DIGEST_LENGTH + : SHA256_DIGEST_LENGTH))) goto end; if (testtype == 1 || testtype == 2) { @@ -4414,12 +4424,14 @@ static int test_early_data_psk(int idx) } /* - * Test TLSv1.3 PSK can be used to send early_data with all 5 ciphersuites + * Test TLSv1.3 PSK can be used to send early_data with all 7 ciphersuites * idx == 0: Test with TLS1_3_RFC_AES_128_GCM_SHA256 * idx == 1: Test with TLS1_3_RFC_AES_256_GCM_SHA384 * idx == 2: Test with TLS1_3_RFC_CHACHA20_POLY1305_SHA256, * idx == 3: Test with TLS1_3_RFC_AES_128_CCM_SHA256 * idx == 4: Test with TLS1_3_RFC_AES_128_CCM_8_SHA256 + * idx == 5: Test with TLS1_3_RFC_SHA256_SHA256 + * idx == 6: Test with TLS1_3_RFC_SHA384_SHA384 */ static int test_early_data_psk_with_all_ciphers(int idx) { @@ -4440,7 +4452,14 @@ static int test_early_data_psk_with_all_ciphers(int idx) NULL, # endif TLS1_3_RFC_AES_128_CCM_SHA256, - TLS1_3_RFC_AES_128_CCM_8_SHA256 + TLS1_3_RFC_AES_128_CCM_8_SHA256, +# if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) + TLS1_3_RFC_SHA256_SHA256, + TLS1_3_RFC_SHA384_SHA384 +#else + NULL, + NULL +#endif }; const unsigned char *cipher_bytes[] = { TLS13_AES_128_GCM_SHA256_BYTES, @@ -4451,13 +4470,23 @@ static int test_early_data_psk_with_all_ciphers(int idx) NULL, # endif TLS13_AES_128_CCM_SHA256_BYTES, - TLS13_AES_128_CCM_8_SHA256_BYTES + TLS13_AES_128_CCM_8_SHA256_BYTES, +# if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) + TLS13_SHA256_SHA256_BYTES, + TLS13_SHA384_SHA384_BYTES +#else + NULL, + NULL +#endif }; if (cipher_str[idx] == NULL) return 1; - /* Skip ChaCha20Poly1305 as currently FIPS module does not support it */ - if (idx == 2 && is_fips == 1) + /* + * Skip ChaCha20Poly1305 and TLS_SHA{256,384}_SHA{256,384} ciphers + * as currently FIPS module does not support them. + */ + if ((idx == 2 || idx == 5 || idx == 6) && is_fips == 1) return 1; /* We always set this up with a final parameter of "2" for PSK */ @@ -4466,8 +4495,11 @@ static int test_early_data_psk_with_all_ciphers(int idx) SHA384_DIGEST_LENGTH))) goto end; - if (idx == 4) { - /* CCM8 ciphers are considered low security due to their short tag */ + if (idx == 4 || idx == 5 || idx == 6) { + /* + * CCM8 ciphers are considered low security due to their short tag. + * Integrity-only cipher do not provide any confidentiality. + */ SSL_set_security_level(clientssl, 0); SSL_set_security_level(serverssl, 0); } @@ -5318,7 +5350,12 @@ static int test_tls13_ciphersuite(int idx) # endif /* CCM8 ciphers are considered low security due to their short tag */ { TLS1_3_RFC_AES_128_CCM_8_SHA256 - ":" TLS1_3_RFC_AES_128_CCM_SHA256, 1, 1 } + ":" TLS1_3_RFC_AES_128_CCM_SHA256, 1, 1 }, +# if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) + /* Integrity-only cipher do not provide any confidentiality */ + { TLS1_3_RFC_SHA256_SHA256, 0, 1 }, + { TLS1_3_RFC_SHA384_SHA384, 0, 1 } +# endif }; const char *t13_cipher = NULL; const char *t12_cipher = NULL; @@ -12064,7 +12101,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_early_data_skip_abort, OSSL_NELEM(ciphersuites) * 3); ADD_ALL_TESTS(test_early_data_not_sent, 3); ADD_ALL_TESTS(test_early_data_psk, 8); - ADD_ALL_TESTS(test_early_data_psk_with_all_ciphers, 5); + ADD_ALL_TESTS(test_early_data_psk_with_all_ciphers, 7); ADD_ALL_TESTS(test_early_data_not_expected, 3); # ifndef OPENSSL_NO_TLS1_2 ADD_ALL_TESTS(test_early_data_tls1_2, 3); diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c index 352c1898adfb1..71123b947f6ac 100644 --- a/test/tls13secretstest.c +++ b/test/tls13secretstest.c @@ -163,6 +163,13 @@ int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, return 0; } +int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_MD **md, + int *mac_pkey_type, size_t *mac_secret_size) +{ + return 0; +} + int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, const EVP_CIPHER **enc, const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size,