Parcourir la source

TLS: Add SHA256-based verify_data derivation for TLS v1.2

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen il y a 13 ans
Parent
commit
949b2e1f61

+ 22 - 1
src/tls/tlsv1_client_read.c

@@ -17,6 +17,7 @@
 #include "common.h"
 #include "crypto/md5.h"
 #include "crypto/sha1.h"
+#include "crypto/sha256.h"
 #include "crypto/tls.h"
 #include "x509v3.h"
 #include "tlsv1_common.h"
@@ -822,6 +823,21 @@ static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
 		    pos, TLS_VERIFY_DATA_LEN);
 
+#ifdef CONFIG_TLSV12
+	if (conn->rl.tls_version >= TLS_VERSION_1_2) {
+		hlen = SHA256_MAC_LEN;
+		if (conn->verify.sha256_server == NULL ||
+		    crypto_hash_finish(conn->verify.sha256_server, hash, &hlen)
+		    < 0) {
+			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
+				  TLS_ALERT_INTERNAL_ERROR);
+			conn->verify.sha256_server = NULL;
+			return -1;
+		}
+		conn->verify.sha256_server = NULL;
+	} else {
+#endif /* CONFIG_TLSV12 */
+
 	hlen = MD5_MAC_LEN;
 	if (conn->verify.md5_server == NULL ||
 	    crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
@@ -843,10 +859,15 @@ static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
 		return -1;
 	}
 	conn->verify.sha1_server = NULL;
+	hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
+
+#ifdef CONFIG_TLSV12
+	}
+#endif /* CONFIG_TLSV12 */
 
 	if (tls_prf(conn->rl.tls_version,
 		    conn->master_secret, TLS_MASTER_SECRET_LEN,
-		    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
+		    "server finished", hash, hlen,
 		    verify_data, TLS_VERIFY_DATA_LEN)) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,

+ 22 - 1
src/tls/tlsv1_client_write.c

@@ -17,6 +17,7 @@
 #include "common.h"
 #include "crypto/md5.h"
 #include "crypto/sha1.h"
+#include "crypto/sha256.h"
 #include "crypto/tls.h"
 #include "crypto/random.h"
 #include "x509v3.h"
@@ -599,6 +600,21 @@ static int tls_write_client_finished(struct tlsv1_client *conn,
 
 	/* Encrypted Handshake Message: Finished */
 
+#ifdef CONFIG_TLSV12
+	if (conn->rl.tls_version >= TLS_VERSION_1_2) {
+		hlen = SHA256_MAC_LEN;
+		if (conn->verify.sha256_client == NULL ||
+		    crypto_hash_finish(conn->verify.sha256_client, hash, &hlen)
+		    < 0) {
+			tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
+				  TLS_ALERT_INTERNAL_ERROR);
+			conn->verify.sha256_client = NULL;
+			return -1;
+		}
+		conn->verify.sha256_client = NULL;
+	} else {
+#endif /* CONFIG_TLSV12 */
+
 	hlen = MD5_MAC_LEN;
 	if (conn->verify.md5_client == NULL ||
 	    crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {
@@ -620,10 +636,15 @@ static int tls_write_client_finished(struct tlsv1_client *conn,
 		return -1;
 	}
 	conn->verify.sha1_client = NULL;
+	hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
+
+#ifdef CONFIG_TLSV12
+	}
+#endif /* CONFIG_TLSV12 */
 
 	if (tls_prf(conn->rl.tls_version,
 		    conn->master_secret, TLS_MASTER_SECRET_LEN,
-		    "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
+		    "client finished", hash, hlen,
 		    verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
 		tls_alert(conn, TLS_ALERT_LEVEL_FATAL,

+ 22 - 1
src/tls/tlsv1_server_read.c

@@ -17,6 +17,7 @@
 #include "common.h"
 #include "crypto/md5.h"
 #include "crypto/sha1.h"
+#include "crypto/sha256.h"
 #include "crypto/tls.h"
 #include "x509v3.h"
 #include "tlsv1_common.h"
@@ -1041,6 +1042,21 @@ static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct,
 	wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
 		    pos, TLS_VERIFY_DATA_LEN);
 
+#ifdef CONFIG_TLSV12
+	if (conn->rl.tls_version >= TLS_VERSION_1_2) {
+		hlen = SHA256_MAC_LEN;
+		if (conn->verify.sha256_client == NULL ||
+		    crypto_hash_finish(conn->verify.sha256_client, hash, &hlen)
+		    < 0) {
+			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
+					   TLS_ALERT_INTERNAL_ERROR);
+			conn->verify.sha256_client = NULL;
+			return -1;
+		}
+		conn->verify.sha256_client = NULL;
+	} else {
+#endif /* CONFIG_TLSV12 */
+
 	hlen = MD5_MAC_LEN;
 	if (conn->verify.md5_client == NULL ||
 	    crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {
@@ -1062,10 +1078,15 @@ static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct,
 		return -1;
 	}
 	conn->verify.sha1_client = NULL;
+	hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
+
+#ifdef CONFIG_TLSV12
+	}
+#endif /* CONFIG_TLSV12 */
 
 	if (tls_prf(conn->rl.tls_version,
 		    conn->master_secret, TLS_MASTER_SECRET_LEN,
-		    "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
+		    "client finished", hash, hlen,
 		    verify_data, TLS_VERIFY_DATA_LEN)) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,

+ 22 - 1
src/tls/tlsv1_server_write.c

@@ -17,6 +17,7 @@
 #include "common.h"
 #include "crypto/md5.h"
 #include "crypto/sha1.h"
+#include "crypto/sha256.h"
 #include "crypto/tls.h"
 #include "crypto/random.h"
 #include "x509v3.h"
@@ -587,6 +588,21 @@ static int tls_write_server_finished(struct tlsv1_server *conn,
 
 	/* Encrypted Handshake Message: Finished */
 
+#ifdef CONFIG_TLSV12
+	if (conn->rl.tls_version >= TLS_VERSION_1_2) {
+		hlen = SHA256_MAC_LEN;
+		if (conn->verify.sha256_server == NULL ||
+		    crypto_hash_finish(conn->verify.sha256_server, hash, &hlen)
+		    < 0) {
+			conn->verify.sha256_server = NULL;
+			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
+					   TLS_ALERT_INTERNAL_ERROR);
+			return -1;
+		}
+		conn->verify.sha256_server = NULL;
+	} else {
+#endif /* CONFIG_TLSV12 */
+
 	hlen = MD5_MAC_LEN;
 	if (conn->verify.md5_server == NULL ||
 	    crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
@@ -608,10 +624,15 @@ static int tls_write_server_finished(struct tlsv1_server *conn,
 		return -1;
 	}
 	conn->verify.sha1_server = NULL;
+	hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
+
+#ifdef CONFIG_TLSV12
+	}
+#endif /* CONFIG_TLSV12 */
 
 	if (tls_prf(conn->rl.tls_version,
 		    conn->master_secret, TLS_MASTER_SECRET_LEN,
-		    "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
+		    "server finished", hash, hlen,
 		    verify_data + 1 + 3, TLS_VERIFY_DATA_LEN)) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
 		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,