From 30c277f8d63d2419b3ce33fa3c9b0208c7453c87 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Wed, 6 May 2015 01:48:39 +0200 Subject: [PATCH] unit: GTK Handshake tests. --- unit/test-eapol.c | 547 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 542 insertions(+), 5 deletions(-) diff --git a/unit/test-eapol.c b/unit/test-eapol.c index 2b2125a5..bd66abc0 100644 --- a/unit/test-eapol.c +++ b/unit/test-eapol.c @@ -41,6 +41,7 @@ struct eapol_key_data { enum eapol_descriptor_type descriptor_type; enum eapol_key_descriptor_version key_descriptor_version; bool key_type:1; + uint8_t wpa_key_id:2; bool install:1; bool key_ack:1; bool key_mic:1; @@ -324,6 +325,277 @@ static struct eapol_key_data eapol_key_test_6 = { .key_data_len = 0, }; +/* WPA2 frame, 1 of 4. For parameters see eapol_wpa2_handshake_test */ +static const unsigned char eapol_key_data_7[] = { + 0x02, 0x03, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x2b, 0x58, 0x52, 0xb8, 0x8e, 0x4c, 0xa3, + 0x4d, 0xc5, 0x99, 0xed, 0x20, 0x2c, 0x63, 0x95, 0x7c, 0x53, 0x5e, 0x3e, + 0xfa, 0x92, 0x89, 0x87, 0x34, 0x11, 0x12, 0x7c, 0xba, 0xf3, 0x58, 0x84, + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +static struct eapol_key_data eapol_key_test_7 = { + .frame = eapol_key_data_7, + .frame_len = sizeof(eapol_key_data_7), + .protocol_version = EAPOL_PROTOCOL_VERSION_2004, + .packet_len = 95, + .descriptor_type = EAPOL_DESCRIPTOR_TYPE_80211, + .key_descriptor_version = EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + .key_type = true, + .wpa_key_id = 0, + .install = false, + .key_ack = true, + .key_mic = false, + .secure = false, + .error = false, + .request = false, + .encrypted_key_data = false, + .smk_message = false, + .key_length = 16, + .key_replay_counter = 1, + .key_nonce = { 0x2b, 0x58, 0x52, 0xb8, 0x8e, 0x4c, 0xa3, 0x4d, 0xc5, + 0x99, 0xed, 0x20, 0x2c, 0x63, 0x95, 0x7c, 0x53, 0x5e, + 0x3e, 0xfa, 0x92, 0x89, 0x87, 0x34, 0x11, 0x12, 0x7c, + 0xba, 0xf3, 0x58, 0x84, 0x25 }, + .eapol_key_iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_rsc = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_mic_data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_data_len = 0, +}; + +/* WPA2 frame, 2 of 4. For parameters see eapol_wpa2_handshake_test */ +static const unsigned char eapol_key_data_8[] = { + 0x02, 0x03, 0x00, 0x73, 0x02, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x72, 0x7c, 0x65, 0x6c, 0x5e, 0xd6, 0x42, + 0xd7, 0xf4, 0x7f, 0x48, 0x43, 0x51, 0xd8, 0x08, 0x94, 0x51, 0x18, 0xda, + 0x6a, 0x49, 0x33, 0xac, 0x7e, 0x29, 0x3f, 0x2f, 0x2a, 0xc0, 0x88, 0x34, + 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x7c, 0x45, + 0x98, 0x9f, 0x49, 0x2b, 0x4a, 0x36, 0x58, 0x35, 0x29, 0x28, 0x2d, 0x8f, + 0xed, 0x00, 0x14, 0x30, 0x12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, + 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02 +}; + +static struct eapol_key_data eapol_key_test_8 = { + .frame = eapol_key_data_8, + .frame_len = sizeof(eapol_key_data_8), + .protocol_version = EAPOL_PROTOCOL_VERSION_2004, + .packet_len = 115, + .descriptor_type = EAPOL_DESCRIPTOR_TYPE_80211, + .key_descriptor_version = EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + .key_type = true, + .wpa_key_id = 0, + .install = false, + .key_ack = false, + .key_mic = true, + .secure = false, + .error = false, + .request = false, + .encrypted_key_data = false, + .smk_message = false, + .key_length = 0, + .key_replay_counter = 1, + .key_nonce = { 0x72, 0x7c, 0x65, 0x6c, 0x5e, 0xd6, 0x42, 0xd7, 0xf4, + 0x7f, 0x48, 0x43, 0x51, 0xd8, 0x08, 0x94, 0x51, 0x18, + 0xda, 0x6a, 0x49, 0x33, 0xac, 0x7e, 0x29, 0x3f, 0x2f, + 0x2a, 0xc0, 0x88, 0x34, 0x8c }, + .eapol_key_iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_rsc = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_mic_data = { 0x7d, 0x7c, 0x45, 0x98, 0x9f, 0x49, 0x2b, 0x4a, + 0x36, 0x58, 0x35, 0x29, 0x28, 0x2d, 0x8f, 0xed }, + .key_data_len = 20, +}; + +/* WPA2 frame, 3 of 4. For parameters see eapol_wpa2_handshake_test */ +static const unsigned char eapol_key_data_9[] = { + 0x02, 0x03, 0x00, 0x97, 0x02, 0x13, 0xca, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x2b, 0x58, 0x52, 0xb8, 0x8e, 0x4c, 0xa3, + 0x4d, 0xc5, 0x99, 0xed, 0x20, 0x2c, 0x63, 0x95, 0x7c, 0x53, 0x5e, 0x3e, + 0xfa, 0x92, 0x89, 0x87, 0x34, 0x11, 0x12, 0x7c, 0xba, 0xf3, 0x58, 0x84, + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x6a, + 0x57, 0x76, 0xc7, 0x33, 0xbf, 0xc0, 0x71, 0xde, 0x62, 0xeb, 0xf7, 0xa7, + 0xc5, 0x00, 0x38, 0x14, 0xdd, 0x52, 0x80, 0x3d, 0xc8, 0x3d, 0xf7, 0xba, + 0x7e, 0xb6, 0x48, 0x29, 0x6d, 0x65, 0x0e, 0x88, 0xcc, 0xc8, 0xdd, 0x67, + 0x62, 0x04, 0xa2, 0xc7, 0xc1, 0xf2, 0x65, 0x0b, 0xca, 0xf9, 0x6b, 0x66, + 0xf5, 0xb4, 0x3d, 0x99, 0x26, 0xad, 0xc5, 0xce, 0x18, 0xc0, 0xa9, 0x9b, + 0xe5, 0x0e, 0x50, 0x85, 0x84, 0xb1, 0x57, 0xe3, 0x7a, 0x5e, 0x0f +}; + +static struct eapol_key_data eapol_key_test_9 = { + .frame = eapol_key_data_9, + .frame_len = sizeof(eapol_key_data_9), + .protocol_version = EAPOL_PROTOCOL_VERSION_2004, + .packet_len = 151, + .descriptor_type = EAPOL_DESCRIPTOR_TYPE_80211, + .key_descriptor_version = EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + .key_type = true, + .wpa_key_id = 0, + .install = true, + .key_ack = true, + .key_mic = true, + .secure = true, + .error = false, + .request = false, + .encrypted_key_data = true, + .smk_message = false, + .key_length = 16, + .key_replay_counter = 2, + .key_nonce = { 0x2b, 0x58, 0x52, 0xb8, 0x8e, 0x4c, 0xa3, 0x4d, 0xc5, + 0x99, 0xed, 0x20, 0x2c, 0x63, 0x95, 0x7c, 0x53, 0x5e, + 0x3e, 0xfa, 0x92, 0x89, 0x87, 0x34, 0x11, 0x12, 0x7c, + 0xba, 0xf3, 0x58, 0x84, 0x25 }, + .eapol_key_iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_rsc = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_mic_data = { 0xf8, 0x62, 0x6a, 0x57, 0x76, 0xc7, 0x33, 0xbf, + 0xc0, 0x71, 0xde, 0x62, 0xeb, 0xf7, 0xa7, 0xc5 }, + .key_data_len = 56, +}; + +/* WPA2 frame, 4 of 4. For parameters see eapol_wpa2_handshake_test */ +static const unsigned char eapol_key_data_10[] = { + 0x02, 0x03, 0x00, 0x5f, 0x02, 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x0f, 0x34, + 0x23, 0x49, 0xf0, 0x85, 0x03, 0xe5, 0xfc, 0x54, 0xb7, 0x2c, 0xb5, 0x32, + 0x66, 0x00, 0x00 +}; + +static struct eapol_key_data eapol_key_test_10 = { + .frame = eapol_key_data_10, + .frame_len = sizeof(eapol_key_data_10), + .protocol_version = EAPOL_PROTOCOL_VERSION_2004, + .packet_len = 95, + .descriptor_type = EAPOL_DESCRIPTOR_TYPE_80211, + .key_descriptor_version = EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + .key_type = true, + .wpa_key_id = 0, + .install = false, + .key_ack = false, + .key_mic = true, + .secure = true, + .error = false, + .request = false, + .encrypted_key_data = false, + .smk_message = false, + .key_length = 0, + .key_replay_counter = 2, + .key_nonce = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .eapol_key_iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_rsc = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_mic_data = { 0x8b, 0x0f, 0x34, 0x23, 0x49, 0xf0, 0x85, 0x03, + 0xe5, 0xfc, 0x54, 0xb7, 0x2c, 0xb5, 0x32, 0x66 }, + .key_data_len = 0, +}; + +/* WPA2 frame, 1 of 2. For parameters see eapol_wpa2_handshake_test */ +static const unsigned char eapol_key_data_11[] = { + 0x02, 0x03, 0x00, 0x7f, 0x02, 0x13, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xef, 0x6d, 0xc2, 0x0c, 0x57, 0x27, 0xe8, + 0x25, 0x07, 0x75, 0x1e, 0x67, 0x36, 0x9d, 0xc9, 0x1e, 0xf1, 0x71, 0x8e, + 0xb1, 0x35, 0xb2, 0x12, 0xdf, 0x9f, 0xcb, 0x0a, 0x65, 0xa2, 0xd5, 0x67, + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x6a, 0xb0, + 0x75, 0xbc, 0x8e, 0xd1, 0x92, 0x11, 0xcd, 0xc3, 0xb0, 0xe2, 0xd6, 0x7e, + 0xcf, 0x00, 0x20, 0xe9, 0x96, 0x5b, 0x46, 0x85, 0xd5, 0x8b, 0x88, 0xbd, + 0x57, 0x48, 0x57, 0xe4, 0xf0, 0xdf, 0xdd, 0xf7, 0x2a, 0x7a, 0xa8, 0xeb, + 0x68, 0xa9, 0xef, 0x44, 0x04, 0xa6, 0x6f, 0xaa, 0x48, 0x51, 0x1b +}; + +static struct eapol_key_data eapol_key_test_11 = { + .frame = eapol_key_data_11, + .frame_len = sizeof(eapol_key_data_11), + .protocol_version = EAPOL_PROTOCOL_VERSION_2004, + .packet_len = 127, + .descriptor_type = EAPOL_DESCRIPTOR_TYPE_80211, + .key_descriptor_version = EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + .key_type = false, + .wpa_key_id = 0, + .install = false, + .key_ack = true, + .key_mic = true, + .secure = true, + .error = false, + .request = false, + .encrypted_key_data = true, + .smk_message = false, + .key_length = 16, + .key_replay_counter = 3, + .key_nonce = { 0xef, 0x6d, 0xc2, 0x0c, 0x57, 0x27, 0xe8, 0x25, + 0x07, 0x75, 0x1e, 0x67, 0x36, 0x9d, 0xc9, 0x1e, + 0xf1, 0x71, 0x8e, 0xb1, 0x35, 0xb2, 0x12, 0xdf, + 0x9f, 0xcb, 0x0a, 0x65, 0xa2, 0xd5, 0x67, 0x1d }, + .eapol_key_iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_rsc = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_mic_data = { 0x0f, 0x6a, 0xb0, 0x75, 0xbc, 0x8e, 0xd1, 0x92, + 0x11, 0xcd, 0xc3, 0xb0, 0xe2, 0xd6, 0x7e, 0xcf }, + .key_data_len = 32, +}; + +/* WPA2 frame, 2 of 2. For parameters see eapol_wpa2_handshake_test */ +static const unsigned char eapol_key_data_12[] = { + 0x02, 0x03, 0x00, 0x5f, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xbd, 0x17, + 0xf1, 0x54, 0xb7, 0x32, 0xcf, 0xbc, 0x01, 0xdb, 0x0c, 0x37, 0xe6, 0x33, + 0x9f, 0x00, 0x00 +}; + +static struct eapol_key_data eapol_key_test_12 = { + .frame = eapol_key_data_12, + .frame_len = sizeof(eapol_key_data_12), + .protocol_version = EAPOL_PROTOCOL_VERSION_2004, + .packet_len = 95, + .descriptor_type = EAPOL_DESCRIPTOR_TYPE_80211, + .key_descriptor_version = EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + .key_type = false, + .wpa_key_id = 0, + .install = false, + .key_ack = false, + .key_mic = true, + .secure = true, + .error = false, + .request = false, + .encrypted_key_data = false, + .smk_message = false, + .key_length = 0, + .key_replay_counter = 3, + .key_nonce = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .eapol_key_iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_rsc = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .key_mic_data = { 0xc9, 0xbd, 0x17, 0xf1, 0x54, 0xb7, 0x32, 0xcf, + 0xbc, 0x01, 0xdb, 0x0c, 0x37, 0xe6, 0x33, 0x9f }, + .key_data_len = 0, +}; + static void eapol_key_test(const void *data) { const struct eapol_key_data *test = data; @@ -338,6 +610,7 @@ static void eapol_key_test(const void *data) assert(packet->descriptor_type == test->descriptor_type); assert(packet->key_descriptor_version == test->key_descriptor_version); assert(packet->key_type == test->key_type); + assert(packet->wpa_key_id == test->wpa_key_id); assert(packet->install == test->install); assert(packet->key_ack == test->key_ack); assert(packet->key_mic == test->key_mic); @@ -552,8 +825,130 @@ static void eapol_4way_test(const void *data) l_free(ptk); } -static bool verify_step2_called = false; -static bool verify_step4_called = false; +static void eapol_wpa2_handshake_test(const void *data) +{ + uint8_t anonce[32]; + uint8_t snonce[32]; + uint8_t mic[16]; + struct eapol_key *frame; + uint8_t aa[] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t spa[] = { 0x02, 0x00, 0x00, 0x00, 0x01, 0x00 }; + const char *passphrase = "EasilyGuessedPassword"; + const char *ssid = "TestWPA"; + const unsigned char expected_psk[] = { + 0xbf, 0x9a, 0xa3, 0x15, 0x53, 0x00, 0x12, 0x5e, + 0x7a, 0x5e, 0xbb, 0x2a, 0x54, 0x9f, 0x8c, 0xd4, + 0xed, 0xab, 0x8e, 0xe1, 0x2e, 0x94, 0xbf, 0xc2, + 0x4b, 0x33, 0x57, 0xad, 0x04, 0x96, 0x65, 0xd9 }; + unsigned char psk[32]; + struct crypto_ptk *ptk; + size_t ptk_len; + bool ret; + const struct eapol_key *ptk_step1; + const struct eapol_key *ptk_step2; + const struct eapol_key *ptk_step3; + const struct eapol_key *ptk_step4; + const struct eapol_key *gtk_step1; + const struct eapol_key *gtk_step2; + uint8_t *decrypted_key_data; + size_t decrypted_key_data_len; + + ptk_step1 = eapol_key_validate(eapol_key_data_7, + sizeof(eapol_key_data_7)); + assert(ptk_step1); + assert(eapol_verify_ptk_1_of_4(ptk_step1)); + memcpy(anonce, ptk_step1->key_nonce, sizeof(ptk_step1->key_nonce)); + + ptk_step2 = eapol_key_validate(eapol_key_data_8, + sizeof(eapol_key_data_8)); + assert(ptk_step2); + assert(eapol_verify_ptk_2_of_4(ptk_step2)); + memcpy(snonce, ptk_step2->key_nonce, sizeof(ptk_step2->key_nonce)); + + assert(!crypto_psk_from_passphrase(passphrase, (uint8_t *) ssid, + strlen(ssid), psk)); + assert(!memcmp(expected_psk, psk, sizeof(psk))); + + ptk_len = sizeof(struct crypto_ptk) + + crypto_cipher_key_len(CRYPTO_CIPHER_CCMP); + ptk = l_malloc(ptk_len); + ret = crypto_derive_pairwise_ptk(psk, aa, spa, anonce, snonce, + ptk, ptk_len); + assert(ret); + + frame = eapol_create_ptk_2_of_4(EAPOL_PROTOCOL_VERSION_2004, + EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + eapol_key_test_8.key_replay_counter, + snonce, eapol_key_test_8.key_data_len, + eapol_key_data_8 + sizeof(struct eapol_key), + false); + assert(frame); + assert(eapol_calculate_mic(ptk->kck, frame, mic)); + memcpy(frame->key_mic_data, mic, sizeof(mic)); + assert(!memcmp(frame, eapol_key_data_8, sizeof(eapol_key_data_8))); + l_free(frame); + + ptk_step3 = eapol_key_validate(eapol_key_data_9, + sizeof(eapol_key_data_9)); + assert(ptk_step3); + assert(eapol_verify_ptk_3_of_4(ptk_step3, false)); + assert(!memcmp(anonce, ptk_step3->key_nonce, + sizeof(ptk_step3->key_nonce))); + + assert(eapol_verify_mic(ptk->kck, ptk_step3)); + + decrypted_key_data = eapol_decrypt_key_data(ptk->kek, ptk_step3, + &decrypted_key_data_len); + assert(decrypted_key_data[0] == 48); // RSNE + l_free(decrypted_key_data); + + ptk_step4 = eapol_key_validate(eapol_key_data_10, + sizeof(eapol_key_data_10)); + assert(ptk_step4); + assert(eapol_verify_ptk_4_of_4(ptk_step4, false)); + + frame = eapol_create_ptk_4_of_4(EAPOL_PROTOCOL_VERSION_2004, + EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + eapol_key_test_10.key_replay_counter, false); + assert(frame); + assert(eapol_calculate_mic(ptk->kck, frame, mic)); + memcpy(frame->key_mic_data, mic, sizeof(mic)); + assert(!memcmp(frame, eapol_key_data_10, sizeof(eapol_key_data_10))); + l_free(frame); + + gtk_step1 = eapol_key_validate(eapol_key_data_11, + sizeof(eapol_key_data_11)); + assert(gtk_step1); + assert(eapol_verify_gtk_1_of_2(gtk_step1, false)); + + decrypted_key_data = eapol_decrypt_key_data(ptk->kek, gtk_step1, + &decrypted_key_data_len); + assert(decrypted_key_data[0] == 221); /* GTK KDE */ + assert(decrypted_key_data[2] == 0x00); + assert(decrypted_key_data[3] == 0x0f); + assert(decrypted_key_data[4] == 0xac); + assert(decrypted_key_data[5] == 0x01); + l_free(decrypted_key_data); + + gtk_step2 = eapol_key_validate(eapol_key_data_12, + sizeof(eapol_key_data_12)); + assert(gtk_step2); + + frame = eapol_create_gtk_2_of_2(EAPOL_PROTOCOL_VERSION_2004, + EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES, + eapol_key_test_12.key_replay_counter, false); + assert(frame); + assert(eapol_calculate_mic(ptk->kck, frame, mic)); + memcpy(frame->key_mic_data, mic, sizeof(mic)); + assert(!memcmp(frame, eapol_key_data_12, sizeof(eapol_key_data_12))); + l_free(frame); + + l_free(ptk); +} + +static bool verify_step2_called; +static bool verify_step4_called; +static bool verify_gtk_step2_called; static uint8_t aa[] = { 0x24, 0xa2, 0xe1, 0xec, 0x17, 0x04 }; static uint8_t spa[] = { 0xa0, 0xa8, 0xcd, 0x1c, 0x7e, 0xc9 }; @@ -609,7 +1004,7 @@ static bool test_nonce(uint8_t nonce[]) return true; } -static void eapol_sm_test(const void *data) +static void eapol_sm_test_ptk(const void *data) { const unsigned char psk[] = { 0xbf, 0x9a, 0xa3, 0x15, 0x53, 0x00, 0x12, 0x5e, @@ -627,6 +1022,8 @@ static void eapol_sm_test(const void *data) /* Our test data expects 2001 protocol */ __eapol_set_protocol_version(EAPOL_PROTOCOL_VERSION_2001); __eapol_set_get_nonce_func(test_nonce); + verify_step2_called = false; + verify_step4_called = false; sm = eapol_sm_new(); eapol_sm_set_pmk(sm, psk); @@ -650,6 +1047,128 @@ static void eapol_sm_test(const void *data) eapol_exit(); } +static uint8_t aa_ptk_gtk[] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t spa_ptk_gtk[] = { 0x02, 0x00, 0x00, 0x00, 0x01, 0x00 }; + +static int verify_step2_ptk(uint32_t ifindex, const uint8_t *aa_addr, + const uint8_t *sta_addr, + const struct eapol_key *ek, + void *user_data) +{ + size_t ek_len = sizeof(struct eapol_key) + + L_BE16_TO_CPU(ek->key_data_len); + + assert(ifindex == 1); + assert(!memcmp(sta_addr, spa_ptk_gtk, sizeof(spa_ptk_gtk))); + assert(!memcmp(aa_addr, aa_ptk_gtk, sizeof(aa_ptk_gtk))); + assert(ek_len == sizeof(eapol_key_data_8)); + assert(!memcmp(ek, eapol_key_data_8, sizeof(eapol_key_data_8))); + + verify_step2_called = true; + + return 0; +} + +static int verify_step4_ptk(uint32_t ifindex, const uint8_t *aa_addr, + const uint8_t *sta_addr, + const struct eapol_key *ek, + void *user_data) +{ + size_t ek_len = sizeof(struct eapol_key) + + L_BE16_TO_CPU(ek->key_data_len); + + assert(ifindex == 1); + assert(!memcmp(sta_addr, spa_ptk_gtk, sizeof(spa_ptk_gtk))); + assert(!memcmp(aa_addr, aa_ptk_gtk, sizeof(aa_ptk_gtk))); + assert(ek_len == sizeof(eapol_key_data_10)); + assert(!memcmp(ek, eapol_key_data_10, sizeof(eapol_key_data_10))); + + verify_step4_called = true; + + return 0; +} + +static int verify_step2_gtk(uint32_t ifindex, const uint8_t *aa_addr, + const uint8_t *sta_addr, + const struct eapol_key *ek, + void *user_data) +{ + size_t ek_len = sizeof(struct eapol_key) + + L_BE16_TO_CPU(ek->key_data_len); + + assert(ifindex == 1); + assert(!memcmp(sta_addr, spa_ptk_gtk, sizeof(spa_ptk_gtk))); + assert(!memcmp(aa_addr, aa_ptk_gtk, sizeof(aa_ptk_gtk))); + assert(ek_len == sizeof(eapol_key_data_12)); + assert(!memcmp(ek, eapol_key_data_12, sizeof(eapol_key_data_12))); + + verify_gtk_step2_called = true; + + return 0; +} + +static bool test_nonce_ptk(uint8_t nonce[]) +{ + static const uint8_t snonce[] = { + 0x72, 0x7c, 0x65, 0x6c, 0x5e, 0xd6, 0x42, 0xd7, 0xf4, + 0x7f, 0x48, 0x43, 0x51, 0xd8, 0x08, 0x94, 0x51, 0x18, + 0xda, 0x6a, 0x49, 0x33, 0xac, 0x7e, 0x29, 0x3f, 0x2f, + 0x2a, 0xc0, 0x88, 0x34, 0x8c + }; + + memcpy(nonce, snonce, sizeof(snonce)); + + return true; +} + +static void eapol_sm_test_wpa2_ptk_gtk(const void *data) +{ + const unsigned char psk[] = { + 0xbf, 0x9a, 0xa3, 0x15, 0x53, 0x00, 0x12, 0x5e, + 0x7a, 0x5e, 0xbb, 0x2a, 0x54, 0x9f, 0x8c, 0xd4, + 0xed, 0xab, 0x8e, 0xe1, 0x2e, 0x94, 0xbf, 0xc2, + 0x4b, 0x33, 0x57, 0xad, 0x04, 0x96, 0x65, 0xd9 }; + const unsigned char ap_rsne[] = { + 0x30, 0x12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, + 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x02 }; + + struct eapol_sm *sm; + + eapol_init(); + __eapol_set_protocol_version(EAPOL_PROTOCOL_VERSION_2004); + __eapol_set_get_nonce_func(test_nonce_ptk); + verify_step2_called = false; + verify_step4_called = false; + verify_gtk_step2_called = false; + + sm = eapol_sm_new(); + eapol_sm_set_pmk(sm, psk); + eapol_sm_set_authenticator_address(sm, aa_ptk_gtk); + eapol_sm_set_supplicant_address(sm, spa_ptk_gtk); + eapol_sm_set_own_rsn(sm, eapol_key_data_8 + sizeof(struct eapol_key), + eapol_key_test_8.key_data_len); + eapol_sm_set_ap_rsn(sm, ap_rsne, sizeof(ap_rsne)); + eapol_start(1, sm); + + __eapol_set_tx_packet_func(verify_step2_ptk); + __eapol_rx_packet(1, spa_ptk_gtk, aa_ptk_gtk, eapol_key_data_7, + sizeof(eapol_key_data_7), NULL); + assert(verify_step2_called); + + __eapol_set_tx_packet_func(verify_step4_ptk); + __eapol_rx_packet(1, spa_ptk_gtk, aa_ptk_gtk, eapol_key_data_9, + sizeof(eapol_key_data_9), NULL); + assert(verify_step4_called); + + __eapol_set_tx_packet_func(verify_step2_gtk); + __eapol_rx_packet(1, spa_ptk_gtk, aa_ptk_gtk, eapol_key_data_11, + sizeof(eapol_key_data_11), NULL); + assert(verify_gtk_step2_called); + + eapol_exit(); +} + int main(int argc, char *argv[]) { l_test_init(&argc, &argv); @@ -666,6 +1185,18 @@ int main(int argc, char *argv[]) eapol_key_test, &eapol_key_test_5); l_test_add("/EAPoL Key/Key Frame 6", eapol_key_test, &eapol_key_test_6); + l_test_add("/EAPoL Key/Key Frame 7", + eapol_key_test, &eapol_key_test_7); + l_test_add("/EAPoL Key/Key Frame 8", + eapol_key_test, &eapol_key_test_8); + l_test_add("/EAPoL Key/Key Frame 9", + eapol_key_test, &eapol_key_test_9); + l_test_add("/EAPoL Key/Key Frame 10", + eapol_key_test, &eapol_key_test_10); + l_test_add("/EAPoL Key/Key Frame 11", + eapol_key_test, &eapol_key_test_11); + l_test_add("/EAPoL Key/Key Frame 12", + eapol_key_test, &eapol_key_test_12); l_test_add("/EAPoL Key/MIC Test 1", eapol_key_mic_test, &eapol_key_mic_test_1); @@ -675,10 +1206,16 @@ int main(int argc, char *argv[]) l_test_add("/EAPoL Key/Calculate MIC Test 1", eapol_calculate_mic_test, &eapol_calculate_mic_test_1); - l_test_add("EAPoL/4-Way Handshake", + l_test_add("EAPoL/WPA2 4-Way Handshake", &eapol_4way_test, NULL); - l_test_add("EAPoL/State Machine", &eapol_sm_test, NULL); + l_test_add("EAPoL/WPA2 4-Way & GTK Handshake", + &eapol_wpa2_handshake_test, NULL); + + l_test_add("EAPoL/WPA2 PTK State Machine", &eapol_sm_test_ptk, NULL); + + l_test_add("EAPoL/WPA2 PTK & GTK State Machine", + &eapol_sm_test_wpa2_ptk_gtk, NULL); return l_test_run(); }