Add support for integrity-only cipher suites for TLS v1.3
authorRajeev Ranjan <ranjan.rajeev@siemens.com>
Fri, 1 Dec 2023 11:47:07 +0000 (12:47 +0100)
committerTomas Mraz <tomas@openssl.org>
Tue, 14 May 2024 13:39:15 +0000 (15:39 +0200)
- add test vectors for tls1_3 integrity-only ciphers
- recmethod_local.h: add new member for MAC
- tls13_meth.c: add MAC only to tls 1.3
- tls13_enc.c: extend function to add MAC only
- ssl_local.h: add ssl_cipher_get_evp_md_mac()
- s3_lib.c: add the new ciphers and add #ifndef OPENSSL_NO_INTEGRITY_ONLY_CIPHERS
- ssl_ciph.c : add ssl_cipher_get_evp_md_mac() and use it
- tls13secretstest.c: add dummy test function
- Configure: add integrity-only-ciphers option
- document the new ciphers

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22903)

22 files changed:
.github/workflows/run-checker-merge.yml
CHANGES.md
Configure
INSTALL.md
doc/man1/openssl-ciphers.pod.in
doc/man3/SSL_CTX_set_cipher_list.pod
include/openssl/tls1.h
ssl/record/methods/recmethod_local.h
ssl/record/methods/tls13_meth.c
ssl/record/methods/tls_common.c
ssl/s3_lib.c
ssl/ssl_ciph.c
ssl/ssl_local.h
ssl/t1_trce.c
ssl/tls13_enc.c
test/ciphername_test.c
test/evp_libctx_test.c
test/evp_test.c
test/helpers/ssltestlib.h
test/quicapitest.c
test/sslapitest.c
test/tls13secretstest.c

index 8a1da0c2f2a5bcfb63381d1acb35497ef45e9007..98dcde18b97b92871a45781d0e1135c47f646435 100644 (file)
@@ -33,6 +33,7 @@ jobs:
           no-srp,
           no-srtp,
           no-ts,
+          no-integrity-only-ciphers,
           enable-weak-ssl-ciphers,
           enable-zlib,
           enable-pie,
index 9211c30be3ff869e630349dcbe8051c3b858c299..cf0efe31ba54630b3aae41c64295f95d455196be 100644 (file)
@@ -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.
index f7fc016c8cab2030dd95a6e043ed7477d56eddab..75f3f720f9fcf8e55978d6516ad731062c767ebd 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -529,6 +529,7 @@ my @disablables = (
     "thread-pool",
     "threads",
     "tls",
+    "integrity-only-ciphers",
     "trace",
     "ts",
     "ubsan",
index a34de9bbf8c9e522327da85862c8bdb9d262c0db..6073979bc0dc8869874e39745c5e17729c1106ba 100644 (file)
@@ -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
index a84d2daff5a7030f0911e04a83d934d18905adb7..5239beca1d6925fb0520fd7b90564a85f6edc9e8 100644 (file)
@@ -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.
index 71f399400c2a1276879a6a1958db037c3aacbbcd..0fe8be8094c8f55162125692fcdeb943f2175b8f 100644 (file)
@@ -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:
index 7e3d1a725b82e020dcd4dc20a3872fd203b600d6..8ff39e3956bb9513c1818405805039c89080a3d3 100644 (file)
@@ -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"
index fe9dce15358edf9877e7032ad9e2a4ffcaa51ddd..5a3d010503a869f15e1632ec40a44e7669a1a37a 100644 (file)
@@ -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 */
index d782c327ec071308b52995de4b411c1e37d3eb65..afae14ad22b20158cc4ff889ad58549b41abf003 100644 (file)
@@ -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;
index d9e017d254afdf7d86a3a1dd52987e03f03a36dd..bf6dc0d1f55c63f133b9ce079258f45d9bd0d4a9 100644 (file)
@@ -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));
 
index 2bc5e79fd12960875a4aa3c927fae64ed48f7a6e..5c7f338c65283bb9ca5914d9e6121a986f572111 100644 (file)
@@ -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",
index a9cf6416b105b2f408f8414ffc2fc6900ecf49d4..e70b800a5c673477f756e6ffbc997e6e0880285b 100644 (file)
@@ -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
index 49a514fee4eff411d7b80c46b3c0f95c38e6efbd..2d827d8bb9b28ef71294f2d0df3f2c12f8780b1e 100644 (file)
@@ -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,
index 29dce65e4f62fe56d66a1c6d2fa910469bd9d24d..9c811c5ee6afe08e69ccebcd89b5ae55b2a02f18 100644 (file)
@@ -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"},
index 56f100371d47e89a8265c5161207d2b0de55220b..f6b4b9f4c21af9bf4ae576035be7a56f1d2af0d7 100644 (file)
@@ -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;
 }
 
index c4ec6cadd740bb4b8739526f775f45e8c274b753..8f10f26ba1687ac0ec3740e5aff9f98612d2edac 100644 (file)
@@ -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"},
 };
index 30fc85e8d3a351556837be8cab4bf4695bc15718..3ca25d12f720bced680eb48b38611a74c56cf560 100644 (file)
@@ -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
     };
index 21106dd63343d770d232a62ef4ea2be6ac458c28..71fea6f47ffa8ce92c1f8eb2fba9ea1f82db4efb 100644 (file)
@@ -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";
index 871f9bd52e09dbbf01053401318e3728e79fd313..468662ed0bfd7a201a53e126b5893504140fb9bd 100644 (file)
@@ -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,
index 227f6de8c8a8b4d92c7739b18b75be7a683a6aae..d8e65dc4e5b0ccd9ee6540e637960e5b181f92be 100644 (file)
@@ -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,
index e948ae01a2a9cbb65cea566bbfa560511eb7b704..21027a9db4d8dfac41f728034c1409e465fc6929 100644 (file)
@@ -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);
index 352c1898adfb1765d54bcea117aa67391cbd3ccc..71123b947f6ac6356dcad53d9cf5e93f0187aec7 100644 (file)
@@ -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,