From 949b2e1f618fe0e7080e40084166077084300937 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 27 Nov 2011 21:54:15 +0200 Subject: [PATCH] TLS: Add SHA256-based verify_data derivation for TLS v1.2 Signed-hostap: Jouni Malinen --- src/tls/tlsv1_client_read.c | 23 ++++++++++++++++++++++- src/tls/tlsv1_client_write.c | 23 ++++++++++++++++++++++- src/tls/tlsv1_server_read.c | 23 ++++++++++++++++++++++- src/tls/tlsv1_server_write.c | 23 ++++++++++++++++++++++- 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/src/tls/tlsv1_client_read.c b/src/tls/tlsv1_client_read.c index 999f76f98..8f6b049c0 100644 --- a/src/tls/tlsv1_client_read.c +++ b/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, diff --git a/src/tls/tlsv1_client_write.c b/src/tls/tlsv1_client_write.c index 48484c116..86b5f2d97 100644 --- a/src/tls/tlsv1_client_write.c +++ b/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, diff --git a/src/tls/tlsv1_server_read.c b/src/tls/tlsv1_server_read.c index 19daa516c..e727806e4 100644 --- a/src/tls/tlsv1_server_read.c +++ b/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, diff --git a/src/tls/tlsv1_server_write.c b/src/tls/tlsv1_server_write.c index 1a603fd12..b57c16dfc 100644 --- a/src/tls/tlsv1_server_write.c +++ b/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,