Patch containing TLS implementation for GOST 2012
[openssl.git] / ssl / s3_enc.c
index bde19e1fb8ad3bc6a9bf0a502d46d230620f8f32..1a5aaeceaa8ef4236e8214f2b388ce505eb2fbaf 100644 (file)
@@ -253,7 +253,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
             EVP_CIPHER_CTX_init(s->enc_read_ctx);
         dd = s->enc_read_ctx;
 
-        if (!ssl_replace_hash(&s->read_hash, m)) {
+        if (ssl_replace_hash(&s->read_hash, m) == NULL) {
                 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
                 goto err2;
         }
@@ -286,7 +286,7 @@ int ssl3_change_cipher_state(SSL *s, int which)
              */
             EVP_CIPHER_CTX_init(s->enc_write_ctx);
         dd = s->enc_write_ctx;
-        if (!ssl_replace_hash(&s->write_hash, m)) {
+        if (ssl_replace_hash(&s->write_hash, m) == NULL) {
                 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
                 goto err2;
         }
@@ -476,15 +476,21 @@ void ssl3_cleanup_key_block(SSL *s)
 
 void ssl3_init_finished_mac(SSL *s)
 {
-    BIO_free(s->s3->handshake_buffer);
     ssl3_free_digest_list(s);
     s->s3->handshake_buffer = BIO_new(BIO_s_mem());
     (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
 }
 
+/*
+ * Free digest list. Also frees handshake buffer since they are always freed
+ * together.
+ */
+
 void ssl3_free_digest_list(SSL *s)
 {
     int i;
+    BIO_free(s->s3->handshake_buffer);
+    s->s3->handshake_buffer = NULL;
     if (!s->s3->handshake_dgst)
         return;
     for (i = 0; i < SSL_MAX_DIGEST; i++) {
@@ -497,8 +503,7 @@ void ssl3_free_digest_list(SSL *s)
 
 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
 {
-    if (s->s3->handshake_buffer
-        && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
+    if (s->s3->handshake_dgst == NULL) {
         BIO_write(s->s3->handshake_buffer, (void *)buf, len);
     } else {
         int i;
@@ -509,7 +514,7 @@ void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
     }
 }
 
-int ssl3_digest_cached_records(SSL *s)
+int ssl3_digest_cached_records(SSL *s, int keep)
 {
     int i;
     long mask;
@@ -517,38 +522,37 @@ int ssl3_digest_cached_records(SSL *s)
     long hdatalen;
     void *hdata;
 
-    /* Allocate handshake_dgst array */
-    ssl3_free_digest_list(s);
-    s->s3->handshake_dgst =
-        OPENSSL_malloc(sizeof(*s->s3->handshake_dgst) * SSL_MAX_DIGEST);
     if (s->s3->handshake_dgst == NULL) {
-        SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-    memset(s->s3->handshake_dgst, 0,
-           sizeof(*s->s3->handshake_dgst) * SSL_MAX_DIGEST);
-    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
-    if (hdatalen <= 0) {
-        SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
-        return 0;
-    }
+        /* Allocate handshake_dgst array */
+        s->s3->handshake_dgst =
+            OPENSSL_malloc(sizeof(*s->s3->handshake_dgst) * SSL_MAX_DIGEST);
+        if (s->s3->handshake_dgst == NULL) {
+            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+        if (hdatalen <= 0) {
+            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
+            return 0;
+        }
 
-    /* Loop through bitso of algorithm2 field and create MD_CTX-es */
-    for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
-        if ((mask & ssl_get_algorithm2(s)) && md) {
-            s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
-            if (EVP_MD_nid(md) == NID_md5) {
-                EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
-                                     EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+        /* Loop through bits of algorithm2 field and create MD_CTX-es */
+        for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
+            if ((mask & ssl_get_algorithm2(s)) && md) {
+                s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
+                if (EVP_MD_nid(md) == NID_md5) {
+                    EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
+                                         EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+                }
+                EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
+                EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
+            } else {
+                s->s3->handshake_dgst[i] = NULL;
             }
-            EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
-            EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
-        } else {
-            s->s3->handshake_dgst[i] = NULL;
         }
+
     }
-    if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
-        /* Free handshake_buffer BIO */
+    if (keep == 0) {
         BIO_free(s->s3->handshake_buffer);
         s->s3->handshake_buffer = NULL;
     }
@@ -588,9 +592,8 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
     unsigned char md_buf[EVP_MAX_MD_SIZE];
     EVP_MD_CTX ctx, *d = NULL;
 
-    if (s->s3->handshake_buffer)
-        if (!ssl3_digest_cached_records(s))
-            return 0;
+    if (!ssl3_digest_cached_records(s, 0))
+        return 0;
 
     /*
      * Search for digest of specified type in the handshake_dgst array
@@ -614,19 +617,21 @@ static int ssl3_handshake_mac(SSL *s, int md_nid,
         return 0;
 
     npad = (48 / n) * n;
-    if (sender != NULL)
-        EVP_DigestUpdate(&ctx, sender, len);
-    EVP_DigestUpdate(&ctx, s->session->master_key,
-                     s->session->master_key_length);
-    EVP_DigestUpdate(&ctx, ssl3_pad_1, npad);
-    EVP_DigestFinal_ex(&ctx, md_buf, &i);
-
-    EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL);
-    EVP_DigestUpdate(&ctx, s->session->master_key,
-                     s->session->master_key_length);
-    EVP_DigestUpdate(&ctx, ssl3_pad_2, npad);
-    EVP_DigestUpdate(&ctx, md_buf, i);
-    EVP_DigestFinal_ex(&ctx, p, &ret);
+    if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0)
+            || EVP_DigestUpdate(&ctx, s->session->master_key,
+                                s->session->master_key_length) <= 0
+            || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0
+            || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0
+
+            || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0
+            || EVP_DigestUpdate(&ctx, s->session->master_key,
+                                s->session->master_key_length) <= 0
+            || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0
+            || EVP_DigestUpdate(&ctx, md_buf, i) <= 0
+            || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) {
+        SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR);
+        ret = 0;
+    }
 
     EVP_MD_CTX_cleanup(&ctx);
 
@@ -657,24 +662,31 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 
     EVP_MD_CTX_init(&ctx);
     for (i = 0; i < 3; i++) {
-        EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL);
-        EVP_DigestUpdate(&ctx, salt[i], strlen((const char *)salt[i]));
-        EVP_DigestUpdate(&ctx, p, len);
-        EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), SSL3_RANDOM_SIZE);
-        EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), SSL3_RANDOM_SIZE);
-        EVP_DigestFinal_ex(&ctx, buf, &n);
-
-        EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL);
-        EVP_DigestUpdate(&ctx, p, len);
-        EVP_DigestUpdate(&ctx, buf, n);
-        EVP_DigestFinal_ex(&ctx, out, &n);
+        if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0
+                || EVP_DigestUpdate(&ctx, salt[i],
+                                    strlen((const char *)salt[i])) <= 0
+                || EVP_DigestUpdate(&ctx, p, len) <= 0
+                || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]),
+                                    SSL3_RANDOM_SIZE) <= 0
+                || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]),
+                                    SSL3_RANDOM_SIZE) <= 0
+                || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0
+
+                || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0
+                || EVP_DigestUpdate(&ctx, p, len) <= 0
+                || EVP_DigestUpdate(&ctx, buf, n) <= 0
+                || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) {
+            SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+            ret = 0;
+            break;
+        }
         out += n;
         ret += n;
     }
     EVP_MD_CTX_cleanup(&ctx);
 
 #ifdef OPENSSL_SSL_TRACE_CRYPTO
-    if (s->msg_callback) {
+    if (ret > 0 && s->msg_callback) {
         s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
                         p, len, s, s->msg_callback_arg);
         s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,