Don't attempt to send fragments > max_send_fragment in DTLS
[oweals/openssl.git] / ssl / tls13_enc.c
index d42be60c6710213d1571d0febe941171226b4187..9030d1a2924d321f5b766266d6ccc2302316f75d 100644 (file)
@@ -124,6 +124,8 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
     size_t mdlen, prevsecretlen;
     int ret;
     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
+    static const char derived_secret_label[] = "derived secret";
+    unsigned char preextractsec[EVP_MAX_MD_SIZE];
 
     if (pctx == NULL)
         return 0;
@@ -138,6 +140,26 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
         prevsecret = default_zeros;
         prevsecretlen = 0;
     } else {
+        EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+        unsigned char hash[EVP_MAX_MD_SIZE];
+
+        /* The pre-extract derive step uses a hash of no messages */
+        if (mctx == NULL
+                || EVP_DigestInit_ex(mctx, md, NULL) <= 0
+                || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) {
+            EVP_MD_CTX_free(mctx);
+            return 0;
+        }
+        EVP_MD_CTX_free(mctx);
+
+        /* Generate the pre-extract secret */
+        if (!tls13_hkdf_expand(s, md, prevsecret,
+                               (unsigned char *)derived_secret_label,
+                               sizeof(derived_secret_label) - 1, hash,
+                               preextractsec, mdlen))
+            return 0;
+
+        prevsecret = preextractsec;
         prevsecretlen = mdlen;
     }
 
@@ -152,6 +174,8 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
                <= 0;
 
     EVP_PKEY_CTX_free(pctx);
+    if (prevsecret == preextractsec)
+        OPENSSL_cleanse(preextractsec, mdlen);
     return ret == 0;
 }
 
@@ -243,7 +267,7 @@ int tls13_setup_key_block(SSL *s)
     return 1;
 }
 
-static int derive_secret_key_and_iv(SSL *s, int send, const EVP_MD *md,
+static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
                                     const EVP_CIPHER *ciph,
                                     const unsigned char *insecret,
                                     const unsigned char *hash,
@@ -264,9 +288,16 @@ static int derive_secret_key_and_iv(SSL *s, int send, const EVP_MD *md,
     /* TODO(size_t): convert me */
     keylen = EVP_CIPHER_key_length(ciph);
     if (EVP_CIPHER_mode(ciph) == EVP_CIPH_CCM_MODE) {
+        uint32_t algenc;
+
         ivlen = EVP_CCM_TLS_IV_LEN;
-        if (s->s3->tmp.new_cipher->algorithm_enc
-                & (SSL_AES128CCM8 | SSL_AES256CCM8))
+        if (s->s3->tmp.new_cipher == NULL) {
+            /* We've not selected a cipher yet - we must be doing early data */
+            algenc = s->session->cipher->algorithm_enc;
+        } else {
+            algenc = s->s3->tmp.new_cipher->algorithm_enc;
+        }
+        if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
             taglen = EVP_CCM8_TLS_TAG_LEN;
          else
             taglen = EVP_CCM_TLS_TAG_LEN;
@@ -281,7 +312,7 @@ static int derive_secret_key_and_iv(SSL *s, int send, const EVP_MD *md,
         goto err;
     }
 
-    if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, send) <= 0
+    if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
         || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL)
         || (taglen != 0 && !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
                                                 taglen, NULL))
@@ -292,7 +323,7 @@ static int derive_secret_key_and_iv(SSL *s, int send, const EVP_MD *md,
 
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
     if (s->msg_callback) {
-        int wh = send ? TLS1_RT_CRYPTO_WRITE : 0;
+        int wh = sending ? TLS1_RT_CRYPTO_WRITE : 0;
 
         if (ciph->key_len)
             s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
@@ -336,8 +367,8 @@ int tls13_change_cipher_state(SSL *s, int which)
     const unsigned char *label;
     size_t labellen, hashlen = 0;
     int ret = 0;
-    const EVP_MD *md;
-    const EVP_CIPHER *cipher;
+    const EVP_MD *md = NULL;
+    const EVP_CIPHER *cipher = NULL;
 
     if (which & SSL3_CC_READ) {
         if (s->enc_read_ctx != NULL) {
@@ -423,15 +454,15 @@ int tls13_change_cipher_state(SSL *s, int which)
             labellen = sizeof(client_handshake_traffic) - 1;
             log_label = CLIENT_HANDSHAKE_LABEL;
             /*
-             * The hanshake hash used for the server read handshake traffic
-             * secret is the same as the hash for the server write handshake
-             * traffic secret. However, if we processed early data then we delay
-             * changing the server read cipher state until later, and the
-             * handshake hashes have moved on. Therefore we use the value saved
-             * earlier when we did the server write change cipher state.
+             * The handshake hash used for the server read/client write handshake
+             * traffic secret is the same as the hash for the server
+             * write/client read handshake traffic secret. However, if we
+             * processed early data then we delay changing the server
+             * read/client write cipher state until later, and the handshake
+             * hashes have moved on. Therefore we use the value saved earlier
+             * when we did the server write/client read change cipher state.
              */
-            if (s->server)
-                hash = s->handshake_traffic_hash;
+            hash = s->handshake_traffic_hash;
         } else {
             insecret = s->master_secret;
             label = client_application_traffic;
@@ -479,7 +510,7 @@ int tls13_change_cipher_state(SSL *s, int which)
     if (label == server_application_traffic)
         memcpy(s->server_finished_hash, hashval, hashlen);
 
-    if (s->server && label == server_handshake_traffic)
+    if (label == server_handshake_traffic)
         memcpy(s->handshake_traffic_hash, hashval, hashlen);
 
     if (label == client_application_traffic) {
@@ -526,7 +557,7 @@ int tls13_change_cipher_state(SSL *s, int which)
     return ret;
 }
 
-int tls13_update_key(SSL *s, int send)
+int tls13_update_key(SSL *s, int sending)
 {
     static const unsigned char application_traffic[] =
         "application traffic secret";
@@ -537,12 +568,12 @@ int tls13_update_key(SSL *s, int send)
     EVP_CIPHER_CTX *ciph_ctx;
     int ret = 0;
 
-    if (s->server == send)
+    if (s->server == sending)
         insecret = s->server_app_traffic_secret;
     else
         insecret = s->client_app_traffic_secret;
 
-    if (send) {
+    if (sending) {
         iv = s->write_iv;
         ciph_ctx = s->enc_write_ctx;
         RECORD_LAYER_reset_write_sequence(&s->rlayer);
@@ -552,7 +583,7 @@ int tls13_update_key(SSL *s, int send)
         RECORD_LAYER_reset_read_sequence(&s->rlayer);
     }
 
-    if (!derive_secret_key_and_iv(s, send, ssl_handshake_md(s),
+    if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s),
                                   s->s3->tmp.new_sym_enc, insecret, NULL,
                                   application_traffic,
                                   sizeof(application_traffic) - 1, secret, iv,
@@ -569,7 +600,7 @@ int tls13_update_key(SSL *s, int send)
 
 int tls13_alert_code(int code)
 {
-    if (code == SSL_AD_MISSING_EXTENSION || code == SSL_AD_END_OF_EARLY_DATA)
+    if (code == SSL_AD_MISSING_EXTENSION)
         return code;
 
     return tls1_alert_code(code);