Cleanse buffers
[openssl.git] / ssl / t1_enc.c
index 666864e85c72c3c8049e6b140cb70b10174b3b8b..1833eb7646128a1ea0269b2a6aa0de923cdf1c60 100644 (file)
@@ -548,16 +548,24 @@ int tls1_change_cipher_state(SSL *s, int which)
 #endif                          /* KSSL_DEBUG */
 
     if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
-        EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE));
-        EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
-    } else
-        EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
-
+        if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE))
+            || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    } else {
+        if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    }
     /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
-    if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
-        EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY,
-                            *mac_secret_size, mac_secret);
-
+    if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size
+        && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY,
+                                *mac_secret_size, mac_secret)) {
+        SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+        goto err2;
+    }
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
     if (s->msg_callback) {
         int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0;
@@ -649,6 +657,7 @@ int tls1_setup_key_block(SSL *s)
 
     if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) {
         SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(p1);
         goto err;
     }
 #ifdef TLS_DEBUG
@@ -940,6 +949,8 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen,
                   s->session->master_key, s->session->master_key_length,
                   out, buf2, sizeof buf2))
         return 0;
+    OPENSSL_cleanse(hash, hashlen);
+    OPENSSL_cleanse(buf2, sizeof(buf2));
     return sizeof buf2;
 }
 
@@ -1062,21 +1073,48 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
                                 int len)
 {
     unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
-    const void *co = NULL, *so = NULL;
-    int col = 0, sol = 0;
 
 #ifdef KSSL_DEBUG
     fprintf(stderr, "tls1_generate_master_secret(%p,%p, %p, %d)\n", s, out, p,
             len);
 #endif                          /* KSSL_DEBUG */
 
-
-    tls1_PRF(ssl_get_algorithm2(s),
-             TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
-             s->s3->client_random, SSL3_RANDOM_SIZE,
-             co, col,
-             s->s3->server_random, SSL3_RANDOM_SIZE,
-             so, sol, p, len, s->session->master_key, buff, sizeof buff);
+    if (s->session->flags & SSL_SESS_FLAG_EXTMS) {
+        unsigned char hash[EVP_MAX_MD_SIZE * 2];
+        int hashlen;
+        /* If we don't have any digests cache records */
+        if (s->s3->handshake_buffer) {
+            /*
+             * keep record buffer: this wont affect client auth because we're
+             * freezing the buffer at the same point (after client key
+             * exchange and before certificate verify)
+             */
+            s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
+            ssl3_digest_cached_records(s);
+        }
+        hashlen = ssl_handshake_hash(s, hash, sizeof(hash));
+#ifdef SSL_DEBUG
+        fprintf(stderr, "Handshake hashes:\n");
+        BIO_dump_fp(stderr, (char *)hash, hashlen);
+#endif
+        tls1_PRF(ssl_get_algorithm2(s),
+                 TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+                 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE,
+                 hash, hashlen,
+                 NULL, 0,
+                 NULL, 0,
+                 NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
+        OPENSSL_cleanse(hash, hashlen);
+    } else {
+        tls1_PRF(ssl_get_algorithm2(s),
+                 TLS_MD_MASTER_SECRET_CONST,
+                 TLS_MD_MASTER_SECRET_CONST_SIZE,
+                 s->s3->client_random, SSL3_RANDOM_SIZE,
+                 NULL, 0,
+                 s->s3->server_random, SSL3_RANDOM_SIZE,
+                 NULL, 0, p, len, s->session->master_key, buff, sizeof buff);
+    }
+    OPENSSL_cleanse(buff, sizeof buff);
 #ifdef SSL_DEBUG
     fprintf(stderr, "Premaster Secret:\n");
     BIO_dump_fp(stderr, (char *)p, len);
@@ -1175,6 +1213,9 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
     if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
                TLS_MD_MASTER_SECRET_CONST_SIZE) == 0)
         goto err1;
+    if (memcmp(val, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+               TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE) == 0)
+        goto err1;
     if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
                TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0)
         goto err1;
@@ -1187,6 +1228,8 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                   NULL, 0,
                   s->session->master_key, s->session->master_key_length,
                   out, buff, olen);
+    OPENSSL_cleanse(val, vallen);
+    OPENSSL_cleanse(buff, olen);
 
 #ifdef KSSL_DEBUG
     fprintf(stderr, "tls1_export_keying_material() complete\n");
@@ -1273,11 +1316,6 @@ int tls1_alert_code(int code)
         return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
     case SSL_AD_INAPPROPRIATE_FALLBACK:
         return (TLS1_AD_INAPPROPRIATE_FALLBACK);
-#if 0
-        /* not appropriate for TLS, not used for DTLS */
-    case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE:
-        return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
-#endif
     default:
         return (-1);
     }