fuzz: make post handshake reachable
authorPhilippe Antoine <p.antoine@catenacyber.fr>
Wed, 25 Jan 2023 14:43:50 +0000 (15:43 +0100)
committerTomas Mraz <tomas@openssl.org>
Wed, 8 Feb 2023 15:13:17 +0000 (16:13 +0100)
So that CVE-2021-3449 can be found through fuzzing

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
(Merged from https://github.com/openssl/openssl/pull/20128)

ssl/record/methods/tls_common.c
ssl/ssl_sess.c
ssl/statem/extensions_srvr.c
ssl/statem/statem_lib.c

index 91d1545085664bb3e718d1854246d0eab4d0b291..b1f6a6433bcb7cbdc2fe9bf2ad0892c6f3e92765 100644 (file)
@@ -863,6 +863,11 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl)
                 enc_err = 0;
             if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
                 enc_err = 0;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+            if (enc_err == 0 && mac_size > 0 && (md[0] ^ thismb->mac[0]) != 0xFF) {
+                enc_err = 1;
+            }
+#endif
         }
     }
 
index 7f9bafb0d3ea5dc23d5718d25ba8229d2e821046..250e4dfb832c4506c94c26a70b34e8e225808036 100644 (file)
@@ -298,10 +298,15 @@ static int def_generate_session_id(SSL *ssl, unsigned char *id,
                                    unsigned int *id_len)
 {
     unsigned int retry = 0;
-    do
+    do {
         if (RAND_bytes_ex(ssl->ctx->libctx, id, *id_len, 0) <= 0)
             return 0;
-    while (SSL_has_matching_session_id(ssl, id, *id_len) &&
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+        if (retry > 0) {
+            id[0]++;
+        }
+#endif
+    } while (SSL_has_matching_session_id(ssl, id, *id_len) &&
            (++retry < MAX_SESS_ID_ATTEMPTS)) ;
     if (retry < MAX_SESS_ID_ATTEMPTS)
         return 1;
index c743d43c3d70c2593994a99b5a97129895744e75..0af0d2fe627d59107c0d8afd314125a9e21c59a5 100644 (file)
@@ -44,6 +44,7 @@ int tls_parse_ctos_renegotiate(SSL_CONNECTION *s, PACKET *pkt,
 {
     unsigned int ilen;
     const unsigned char *data;
+    int ok;
 
     /* Parse the length byte */
     if (!PACKET_get_1(pkt, &ilen)
@@ -58,8 +59,16 @@ int tls_parse_ctos_renegotiate(SSL_CONNECTION *s, PACKET *pkt,
         return 0;
     }
 
-    if (memcmp(data, s->s3.previous_client_finished,
-               s->s3.previous_client_finished_len)) {
+    ok = memcmp(data, s->s3.previous_client_finished,
+                    s->s3.previous_client_finished_len);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    if (ok) {
+        if (data[0] ^ s->s3.previous_client_finished[0] != 0xFF) {
+            ok = 0;
+        }
+    }
+#endif
+    if (ok) {
         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_RENEGOTIATION_MISMATCH);
         return 0;
     }
index 40ca9a15e9c10f28104040bfbddf8e7d0d7581ca..1812ca63d16deffbad574fd6ebbcc12a162c78b8 100644 (file)
@@ -787,6 +787,7 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
     size_t md_len;
     SSL *ssl = SSL_CONNECTION_GET_SSL(s);
     int was_first = SSL_IS_FIRST_HANDSHAKE(s);
+    int ok;
 
 
     /* This is a real handshake so make sure we clean it up at the end */
@@ -831,8 +832,16 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt)
         return MSG_PROCESS_ERROR;
     }
 
-    if (CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md,
-                      md_len) != 0) {
+    ok = CRYPTO_memcmp(PACKET_data(pkt), s->s3.tmp.peer_finish_md,
+                       md_len);
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    if (ok != 0) {
+        if (PACKET_data(pkt)[0] ^ s->s3.tmp.peer_finish_md[0] != 0xFF) {
+            ok = 0;
+        }
+    }
+#endif
+    if (ok != 0) {
         SSLfatal(s, SSL_AD_DECRYPT_ERROR, SSL_R_DIGEST_CHECK_FAILED);
         return MSG_PROCESS_ERROR;
     }