summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/run-checker-merge.yml1
-rw-r--r--CHANGES.md7
-rwxr-xr-xConfigure1
-rw-r--r--INSTALL.md4
-rw-r--r--doc/man1/openssl-ciphers.pod.in11
-rw-r--r--doc/man3/SSL_CTX_set_cipher_list.pod4
-rw-r--r--include/openssl/tls1.h6
-rw-r--r--ssl/record/methods/recmethod_local.h7
-rw-r--r--ssl/record/methods/tls13_meth.c127
-rw-r--r--ssl/record/methods/tls_common.c4
-rw-r--r--ssl/s3_lib.c60
-rw-r--r--ssl/ssl_ciph.c61
-rw-r--r--ssl/ssl_local.h3
-rw-r--r--ssl/t1_trce.c2
-rw-r--r--ssl/tls13_enc.c162
-rw-r--r--test/ciphername_test.c2
-rw-r--r--test/evp_libctx_test.c12
-rw-r--r--test/evp_test.c2
-rw-r--r--test/helpers/ssltestlib.h2
-rw-r--r--test/quicapitest.c10
-rw-r--r--test/sslapitest.c65
-rw-r--r--test/tls13secretstest.c7
22 files changed, 423 insertions, 137 deletions
diff --git a/.github/workflows/run-checker-merge.yml b/.github/workflows/run-checker-merge.yml
index 8a1da0c2f2..98dcde18b9 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,
enable-pie,
diff --git a/CHANGES.md b/CHANGES.md
index 9211c30be3..cf0efe31ba 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -53,6 +53,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 f7fc016c8c..75f3f720f9 100755
--- a/Configure
+++ b/Configure
@@ -529,6 +529,7 @@ my @disablables = (
"thread-pool",
"threads",
"tls",
+ "integrity-only-ciphers",
"trace",
"ts",
"ubsan",
diff --git a/INSTALL.md b/INSTALL.md
index a34de9bbf8..6073979bc0 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1117,6 +1117,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 a84d2daff5..5239beca1d 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 71f399400c..0fe8be8094 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 7e3d1a725b..8ff39e3956 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/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h
index fe9dce1535..5a3d010503 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 d782c327ec..afae14ad22 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 d9e017d254..bf6dc0d1f5 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 2bc5e79fd1..5c7f338c65 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 a9cf6416b1..e70b800a5c 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 49a514fee4..2d827d8bb9 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -2495,6 +2495,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 29dce65e4f..9c811c5ee6 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 56f100371d..f6b4b9f4c2 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;
@@ -496,6 +527,23 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which)
}
/*
+ * 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
* use ssl_handshake_md().
@@ -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 c4ec6cadd7..8f10f26ba1 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 30fc85e8d3..3ca25d12f7 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 21106dd633..71fea6f47f 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -1195,7 +1195,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 871f9bd52e..468662ed0b 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 227f6de8c8..d8e65dc4e5 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 e948ae01a2..21027a9db4 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;
@@ -12152,7 +12189,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 352c1898ad..71123b947f 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,