Browse Source

EAP-AKA': Use SHA256 for AT_CHECKCODE

Jouni Malinen 16 years ago
parent
commit
f54e2c34bf

+ 3 - 2
src/eap_common/eap_sim_common.c

@@ -1,5 +1,5 @@
 /*
- * EAP peer/server: EAP-SIM/AKA shared routines
+ * EAP peer/server: EAP-SIM/AKA/AKA' shared routines
  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -554,7 +554,8 @@ int eap_sim_parse_attr(const u8 *start, const u8 *end,
 			}
 			apos += 2;
 			alen -= 2;
-			if (alen != 0 && alen != EAP_AKA_CHECKCODE_LEN) {
+			if (alen != 0 && alen != EAP_AKA_CHECKCODE_LEN &&
+			    alen != EAP_AKA_PRIME_CHECKCODE_LEN) {
 				wpa_printf(MSG_INFO, "EAP-AKA: Invalid "
 					   "AT_CHECKCODE (len %lu)",
 					   (unsigned long) alen);

+ 3 - 2
src/eap_common/eap_sim_common.h

@@ -1,6 +1,6 @@
 /*
- * EAP peer/server: EAP-SIM/AKA shared routines
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * EAP peer/server: EAP-SIM/AKA/AKA' shared routines
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -70,6 +70,7 @@
 #define EAP_AKA_MIN_RES_LEN 4
 #define EAP_AKA_MAX_RES_LEN 16
 #define EAP_AKA_CHECKCODE_LEN 20
+#define EAP_AKA_PRIME_CHECKCODE_LEN 32
 
 struct wpabuf;
 

+ 21 - 9
src/eap_peer/eap_aka_prime.c

@@ -19,6 +19,7 @@
 #include "pcsc_funcs.h"
 #include "eap_common/eap_sim_common.h"
 #include "sha1.h"
+#include "sha256.h"
 #include "crypto.h"
 #include "eap_peer/eap_config.h"
 #ifdef CONFIG_USIM_SIMULATOR
@@ -309,7 +310,7 @@ static void eap_aka_add_checkcode(struct eap_aka_data *data,
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
 
 	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
 
@@ -322,14 +323,18 @@ static void eap_aka_add_checkcode(struct eap_aka_data *data,
 		return;
 	}
 
-	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	/* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
-	sha1_vector(1, &addr, &len, hash);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+		sha1_vector(1, &addr, &len, hash);
 
 	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
-			EAP_AKA_CHECKCODE_LEN);
+			data->eap_method == EAP_TYPE_AKA_PRIME ?
+			EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
 }
 
 
@@ -338,7 +343,8 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data,
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
+	size_t hash_len;
 
 	if (checkcode == NULL)
 		return -1;
@@ -353,19 +359,25 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data,
 		return 0;
 	}
 
-	if (checkcode_len != EAP_AKA_CHECKCODE_LEN) {
+	hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
+		EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
+
+	if (checkcode_len != hash_len) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
 			   "indicates that AKA/Identity message were not "
 			   "used, but they were");
 		return -1;
 	}
 
-	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	/* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
-	sha1_vector(1, &addr, &len, hash);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+		sha1_vector(1, &addr, &len, hash);
 
-	if (os_memcmp(hash, checkcode, EAP_AKA_CHECKCODE_LEN) != 0) {
+	if (os_memcmp(hash, checkcode, hash_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
 		return -1;
 	}

+ 19 - 7
src/eap_server/eap_aka_prime.c

@@ -19,6 +19,7 @@
 #include "eap_common/eap_sim_common.h"
 #include "eap_server/eap_sim_db.h"
 #include "sha1.h"
+#include "sha256.h"
 #include "crypto.h"
 
 
@@ -149,7 +150,7 @@ static void eap_aka_add_checkcode(struct eap_aka_data *data,
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
 
 	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
 
@@ -166,10 +167,14 @@ static void eap_aka_add_checkcode(struct eap_aka_data *data,
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
-	sha1_vector(1, &addr, &len, hash);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+		sha1_vector(1, &addr, &len, hash);
 
 	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
-			EAP_AKA_CHECKCODE_LEN);
+			data->eap_method == EAP_TYPE_AKA_PRIME ?
+			EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
 }
 
 
@@ -178,7 +183,8 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data,
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
+	size_t hash_len;
 
 	if (checkcode == NULL)
 		return -1;
@@ -193,7 +199,10 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data,
 		return 0;
 	}
 
-	if (checkcode_len != EAP_AKA_CHECKCODE_LEN) {
+	hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
+		EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
+
+	if (checkcode_len != hash_len) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from peer indicates "
 			   "that AKA/Identity message were not used, but they "
 			   "were");
@@ -203,9 +212,12 @@ static int eap_aka_verify_checkcode(struct eap_aka_data *data,
 	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
-	sha1_vector(1, &addr, &len, hash);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+		sha1_vector(1, &addr, &len, hash);
 
-	if (os_memcmp(hash, checkcode, EAP_AKA_CHECKCODE_LEN) != 0) {
+	if (os_memcmp(hash, checkcode, hash_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
 		return -1;
 	}