15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* 25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * IEEE 802.1X-2010 Key Agree Protocol of PAE state machine 35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Copyright (c) 2013, Qualcomm Atheros, Inc. 45a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * 55a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * This software may be distributed under the terms of the BSD license. 65a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * See README for more details. 75a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 85a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 95a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include <time.h> 105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "includes.h" 115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common.h" 125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "list.h" 135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "eloop.h" 145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "wpabuf.h" 155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "state_machine.h" 165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "l2_packet/l2_packet.h" 175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/eapol_common.h" 185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "crypto/aes_wrap.h" 195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_cp.h" 205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_key.h" 215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_kay.h" 225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_kay_i.h" 235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_secy_ops.h" 245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define DEFAULT_SA_KEY_LEN 16 275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define DEFAULT_ICV_LEN 16 285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MAX_ICV_LEN 32 /* 32 bytes, 256 bits */ 295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define PENDING_PN_EXHAUSTION 0xC0000000 315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* IEEE Std 802.1X-2010, Table 9-1 - MKA Algorithm Agility */ 335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MKA_ALGO_AGILITY_2009 { 0x00, 0x80, 0xC2, 0x01 } 345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic u8 mka_algo_agility[4] = MKA_ALGO_AGILITY_2009; 355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* IEEE802.1AE-2006 Table 14-1 MACsec Cipher Suites */ 375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct macsec_ciphersuite cipher_suite_tbl[] = { 385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* GCM-AES-128 */ 395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt CS_ID_GCM_AES_128, 415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt CS_NAME_GCM_AES_128, 425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt MACSEC_CAP_INTEG_AND_CONF_0_30_50, 435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16, 445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 0 /* index */ 465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}; 485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define CS_TABLE_SIZE (ARRAY_SIZE(cipher_suite_tbl)) 495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define DEFAULT_CS_INDEX 0 505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct mka_alg mka_alg_tbl[] = { 525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt MKA_ALGO_AGILITY_2009, 545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* 128-bit CAK, KEK, ICK, ICV */ 555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16, 16, 16, 16, 565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cak_128bits_aes_cmac, 575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_ckn_128bits_aes_cmac, 585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kek_128bits_aes_cmac, 595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_ick_128bits_aes_cmac, 605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_icv_128bits_aes_cmac, 615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1, /* index */ 635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}; 655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MKA_ALG_TABLE_SIZE (ARRAY_SIZE(mka_alg_tbl)) 665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int is_ki_equal(struct ieee802_1x_mka_ki *ki1, 695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *ki2) 705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return os_memcmp(ki1->mi, ki2->mi, MI_LEN) == 0 && 725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ki1->kn == ki2->kn; 735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct mka_param_body_handler { 775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int (*body_tx)(struct ieee802_1x_mka_participant *participant, 785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf); 795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int (*body_rx)(struct ieee802_1x_mka_participant *participant, 805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len); 815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int (*body_length)(struct ieee802_1x_mka_participant *participant); 825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean (*body_present)(struct ieee802_1x_mka_participant *participant); 835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}; 845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void set_mka_param_body_len(void *body, unsigned int len) 875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr = body; 895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr->length = (len >> 8) & 0x0f; 905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr->length1 = len & 0xff; 915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic unsigned int get_mka_param_body_len(const void *body) 955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const struct ieee802_1x_mka_hdr *hdr = body; 975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return (hdr->length << 8) | hdr->length1; 985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int get_mka_param_body_type(const void *body) 1025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 1035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const struct ieee802_1x_mka_hdr *hdr = body; 1045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return hdr->type; 1055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 1065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 1095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_dump_basic_body - 1105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 1115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void 1125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body *body) 1135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 1145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 1155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!body) 1175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 1185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(body); 1205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "*** MKA Basic Parameter set ***"); 1215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tVersion.......: %d", body->version); 1225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tPriority......: %d", body->priority); 1235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tKeySvr........: %d", body->key_server); 1245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMACSecDesired.: %d", body->macsec_desired); 1255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capbility); 1265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len); 1275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tSCI MAC.......: " MACSTR, 1285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt MAC2STR(body->actor_sci.addr)); 1295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tSCI Port .....: %d", 1305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host16(body->actor_sci.port)); 1315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tMember Id.....:", 1325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->actor_mi, sizeof(body->actor_mi)); 1335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMessage Number: %d", 1345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->actor_mn)); 1355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tAlgo Agility..:", 1365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->algo_agility, sizeof(body->algo_agility)); 1375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "\tCAK Name......:", body->ckn, 1385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len + MKA_HDR_LEN - sizeof(*body)); 1395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 1405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 1435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_dump_peer_body - 1445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 1455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void 1465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_dump_peer_body(struct ieee802_1x_mka_peer_body *body) 1475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 1485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 1495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t i; 1505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *mi; 1515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 mn; 1525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body == NULL) 1545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 1555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(body); 1575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->type == MKA_LIVE_PEER_LIST) { 1585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "*** Live Peer List ***"); 1595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len); 1605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else if (body->type == MKA_POTENTIAL_PEER_LIST) { 1615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "*** Potential Live Peer List ***"); 1625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len); 1635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 1645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < body_len; i += MI_LEN + sizeof(mn)) { 1665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mi = body->peer + i; 1675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&mn, mi + MI_LEN, sizeof(mn)); 1685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "\tMember Id.....:", mi, MI_LEN); 1695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMessage Number: %d", be_to_host32(mn)); 1705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 1715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 1725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 1755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_dump_dist_sak_body - 1765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 1775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void 1785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_dump_dist_sak_body(struct ieee802_1x_mka_dist_sak_body *body) 1795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 1805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 1815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body == NULL) 1835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 1845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(body); 1865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "*** Distributed SAK ***"); 1875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "\tDistributed AN........: %d", body->dan); 1885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "\tConfidentiality Offset: %d", 1895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->confid_offset); 1905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "\tBody Length...........: %d", (int) body_len); 1915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!body_len) 1925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 1935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "\tKey Number............: %d", 1955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->kn)); 1965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_INFO, "\tAES Key Wrap of SAK...:", body->sak, 24); 1975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 1985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic const char * yes_no(int val) 2015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 2025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return val ? "Yes" : "No"; 2035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 2045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 2075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_dump_sak_use_body - 2085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 2095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void 2105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body *body) 2115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 2125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int body_len; 2135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body == NULL) 2155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 2165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(body); 2185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "*** MACsec SAK Use ***"); 2195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tLatest Key AN....: %d", body->lan); 2205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tLatest Key Tx....: %s", yes_no(body->ltx)); 2215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tLatest Key Rx....: %s", yes_no(body->lrx)); 2225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tOld Key AN....: %d", body->oan); 2235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tOld Key Tx....: %s", yes_no(body->otx)); 2245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tOld Key Rx....: %s", yes_no(body->orx)); 2255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tPlain Key Tx....: %s", yes_no(body->ptx)); 2265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tPlain Key Rx....: %s", yes_no(body->prx)); 2275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tDelay Protect....: %s", 2285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt yes_no(body->delay_protect)); 2295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tBody Length......: %d", body_len); 2305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!body_len) 2315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 2325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tKey Server MI....:", 2345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lsrv_mi, sizeof(body->lsrv_mi)); 2355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tKey Number.......: %u", 2365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->lkn)); 2375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tLowest PN........: %u", 2385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->llpn)); 2395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "\tOld Key Server MI....:", 2405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->osrv_mi, sizeof(body->osrv_mi)); 2415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tOld Key Number.......: %u", 2425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->okn)); 2435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tOld Lowest PN........: %u", 2445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->olpn)); 2455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 2465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 2495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_participant - 2505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 2515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_mka_participant * 2525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn) 2535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 2545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 2555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(participant, &kay->participant_list, 2575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant, list) { 2585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(participant->ckn.name, ckn, 2595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ckn.len) == 0) 2605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return participant; 2615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 2625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: participant is not found"); 2645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 2665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 2675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 2705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_principal_participant - 2715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 2725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_mka_participant * 2735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay *kay) 2745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 2755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 2765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(participant, &kay->participant_list, 2785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant, list) { 2795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->principal) 2805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return participant; 2815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 2825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: principal participant is not founded"); 2845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 2855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 2865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * get_peer_mi(struct dl_list *peers, 2895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mi) 2905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 2915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 2925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, peers, struct ieee802_1x_kay_peer, list) { 2945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(peer->mi, mi, MI_LEN) == 0) 2955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 2965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 2975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 2995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_is_in_potential_peer 3045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 3065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_is_in_potential_peer( 3075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, const u8 *mi) 3085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return get_peer_mi(&participant->potential_peers, mi) != NULL; 3105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_is_in_live_peer 3155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 3175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_is_in_live_peer( 3185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, const u8 *mi) 3195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return get_peer_mi(&participant->live_peers, mi) != NULL; 3215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_is_in_peer 3265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 3285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_is_in_peer(struct ieee802_1x_mka_participant *participant, 3295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mi) 3305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return ieee802_1x_kay_is_in_live_peer(participant, mi) || 3325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_is_in_potential_peer(participant, mi); 3335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_peer 3385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * 3405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant, 3415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mi) 3425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 3445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = get_peer_mi(&participant->live_peers, mi); 3465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer) 3475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 3485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return get_peer_mi(&participant->potential_peers, mi); 3505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_live_peer 3555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * 3575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant, 3585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mi) 3595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return get_peer_mi(&participant->live_peers, mi); 3615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_cipher_suite 3665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct macsec_ciphersuite * 3685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant, 3695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *cs_id) 3705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int i; 3725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < CS_TABLE_SIZE; i++) { 3745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(cipher_suite_tbl[i].id, cs_id, CS_ID_LEN) == 0) 3755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 3765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 3775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (i >= CS_TABLE_SIZE) 3785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 3795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return &cipher_suite_tbl[i]; 3815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 3855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_peer_sci 3865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 3875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * 3885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant, 3895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const struct ieee802_1x_mka_sci *sci) 3905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 3915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 3925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 3945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 3955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0) 3965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 3975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 3985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->potential_peers, 4005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 4015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0) 4025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 4035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 4045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 4065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 4075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 4105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_init_receive_sa - 4115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 4125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct receive_sa * 4135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn, 4145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *key) 4155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 4165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa *psa; 4175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!psc || !key) 4195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 4205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa = os_zalloc(sizeof(*psa)); 4225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!psa) { 4235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 4245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 4255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 4265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->pkey = key; 4285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->lowest_pn = lowest_pn; 4295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->next_pn = lowest_pn; 4305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->an = an; 4315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->sc = psc; 4325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_time(&psa->created_time); 4345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->in_use = FALSE; 4355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&psc->sa_list, &psa->list); 4375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, 4385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Create receive SA(AN: %d lowest_pn: %u of SC(channel: %d)", 4395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) an, lowest_pn, psc->channel); 4405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return psa; 4425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 4435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 4465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_deinit_receive_sa - 4475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 4485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa) 4495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 4505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->pkey = NULL; 4515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, 4525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Delete receive SA(an: %d) of SC(channel: %d)", 4535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->an, psa->sc->channel); 4545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&psa->list); 4555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(psa); 4565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 4575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 4605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_init_receive_sc - 4615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 4625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct receive_sc * 4635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci, 4645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int channel) 4655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 4665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *psc; 4675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!psci) 4695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 4705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc = os_zalloc(sizeof(*psc)); 4725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!psc) { 4735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 4745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 4755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 4765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&psc->sci, psci, sizeof(psc->sci)); 4785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->channel = channel; 4795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_time(&psc->created_time); 4815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->receiving = FALSE; 4825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&psc->sa_list); 4845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Create receive SC(channel: %d)", channel); 4855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)psci, sizeof(*psci)); 4865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return psc; 4885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 4895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 4925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_deinit_receive_sc - 4935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt **/ 4945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void 4955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_deinit_receive_sc( 4965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, struct receive_sc *psc) 4975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 4985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa *psa, *pre_sa; 4995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Delete receive SC(channel: %d)", 5015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->channel); 5025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, 5035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt list) { 5045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_disable_receive_sa(participant->kay, psa); 5055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_receive_sa(psa); 5065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 5075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&psc->list); 5085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(psc); 5095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 5105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 5135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_create_live_peer 5145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 5155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * 5165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant, 5175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *mi, u32 mn) 5185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 5195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 5205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 5215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 sc_ch = 0; 5225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = os_zalloc(sizeof(*peer)); 5245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer == NULL) { 5255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 5265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 5275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 5285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(peer->mi, mi, MI_LEN); 5305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->mn = mn; 5315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 5325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->sak_used = FALSE; 5335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&peer->sci, &participant->current_peer_sci, 5345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(peer->sci)); 5355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&participant->live_peers, &peer->list); 5365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_get_available_receive_sc(participant->kay, &sc_ch); 5385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch); 5405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!rxsc) 5415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 5425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&participant->rxsc_list, &rxsc->list); 5445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_create_receive_sc(participant->kay, rxsc); 5455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Live peer created"); 5475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi)); 5485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 5495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN); 5505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port); 5515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 5535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 5545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 5575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_create_potential_peer 5585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 5595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * 5605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_create_potential_peer( 5615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, const u8 *mi, u32 mn) 5625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 5635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 5645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = os_zalloc(sizeof(*peer)); 5665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer == NULL) { 5675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 5685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 5695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 5705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(peer->mi, mi, MI_LEN); 5725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->mn = mn; 5735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 5745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->sak_used = FALSE; 5755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&participant->potential_peers, &peer->list); 5775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: potential peer created"); 5795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi)); 5805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 5815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN); 5825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port); 5835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 5855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 5865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 5895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_move_live_peer 5905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 5915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_kay_peer * 5925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant, 5935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *mi, u32 mn) 5945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 5955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 5965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 5975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 sc_ch = 0; 5985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 5995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->potential_peers, 6005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 6015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(peer->mi, mi, MI_LEN) == 0) 6025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 6035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 6045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&peer->sci, &participant->current_peer_sci, 6065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(peer->sci)); 6075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->mn = mn; 6085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 6095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: move potential peer to live peer"); 6115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi)); 6125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 6135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN); 6145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port); 6155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&peer->list); 6175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add_tail(&participant->live_peers, &peer->list); 6185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_get_available_receive_sc(participant->kay, &sc_ch); 6205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch); 6225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!rxsc) 6235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 6245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&participant->rxsc_list, &rxsc->list); 6265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_create_receive_sc(participant->kay, rxsc); 6275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return peer; 6295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 6305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 6345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_basic_body_present - 6355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 6365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 6375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_basic_body_present( 6385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 6395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 6405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return TRUE; 6415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 6425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 6455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_basic_body_length - 6465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 6475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 6485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant *participant) 6495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 6505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int length; 6515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = sizeof(struct ieee802_1x_mka_basic_body); 6535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length += participant->ckn.len; 6545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return (length + 0x3) & ~0x3; 6555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 6565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 6595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_encode_basic_body 6605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 6615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 6625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_encode_basic_body( 6635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 6645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf) 6655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 6665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_basic_body *body; 6675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay = participant->kay; 6685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int length = ieee802_1x_mka_basic_body_length(participant); 6695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = wpabuf_put(buf, length); 6715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->version = kay->mka_version; 6735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->priority = kay->actor_priority; 6745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->is_elected) 6755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->key_server = participant->is_key_server; 6765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 6775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->key_server = participant->can_be_key_server; 6785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->macsec_desired = kay->macsec_desired; 6805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->macsec_capbility = kay->macsec_capable; 6815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt set_mka_param_body_len(body, length - MKA_HDR_LEN); 6825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->actor_sci.addr, kay->actor_sci.addr, 6845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->actor_sci.addr)); 6855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->actor_sci.port = host_to_be16(kay->actor_sci.port); 6865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi)); 6885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mn = participant->mn + 1; 6895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->actor_mn = host_to_be32(participant->mn); 6905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->algo_agility, participant->kay->algo_agility, 6915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(body->algo_agility)); 6925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len); 6945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_basic_body(body); 6965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 6975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 6985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 6995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 7025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_basic_body - 7035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 7045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_mka_participant * 7055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg, 7065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t msg_len) 7075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 7085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 7095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const struct ieee802_1x_mka_basic_body *body; 7105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 7115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = (const struct ieee802_1x_mka_basic_body *) mka_msg; 7135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->version > MKA_VERSION_ID) { 7155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, 7165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: peer's version(%d) greater than mka current version(%d)", 7175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->version, MKA_VERSION_ID); 7185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 7195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->is_obliged_key_server && body->key_server) { 7205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "I must be as key server"); 7215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 7225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 7235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_kay_get_participant(kay, body->ckn); 7255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) { 7265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "Peer is not included in my CA"); 7275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 7285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 7295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* If the peer's MI is my MI, I will choose new MI */ 7315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) { 7325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_random(participant->mi, sizeof(participant->mi)); 7335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mn = 0; 7345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 7355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(participant->current_peer_id.mi, body->actor_mi, MI_LEN); 7375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mn = be_to_host32(body->actor_mn); 7385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(participant->current_peer_sci.addr, body->actor_sci.addr, 7395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(participant->current_peer_sci.addr)); 7405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_sci.port = be_to_host16(body->actor_sci.port); 7415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* handler peer */ 7435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = ieee802_1x_kay_get_peer(participant, body->actor_mi); 7445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer) { 7455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* Check duplicated SCI */ 7465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* TODO: What policy should be applied to detect duplicated SCI 7475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * is active attacker or a valid peer whose MI is be changed? 7485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 7495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = ieee802_1x_kay_get_peer_sci(participant, 7505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt &body->actor_sci); 7515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer) { 7525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, 7535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: duplicated SCI detected, Maybe active attacker"); 7545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&peer->list); 7555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(peer); 7565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 7575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = ieee802_1x_kay_create_potential_peer( 7595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, body->actor_mi, 7605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt be_to_host32(body->actor_mn)); 7615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer) 7625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 7635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->macsec_desired = body->macsec_desired; 7655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->macsec_capbility = body->macsec_capbility; 7665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->is_key_server = (Boolean) body->key_server; 7675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->key_server_priority = body->priority; 7685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else if (peer->mn < be_to_host32(body->actor_mn)) { 7695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->mn = be_to_host32(body->actor_mn); 7705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 7715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->macsec_desired = body->macsec_desired; 7725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->macsec_capbility = body->macsec_capbility; 7735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->is_key_server = (Boolean) body->key_server; 7745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->key_server_priority = body->priority; 7755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 7765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: The peer MN have received"); 7775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 7785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 7795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return participant; 7815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 7825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 7855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_live_peer_body_present 7865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 7875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 7885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_live_peer_body_present( 7895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 7905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 7915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return !dl_list_empty(&participant->live_peers); 7925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 7935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 7955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 7965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_live_peer_length 7975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 7985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 7995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_get_live_peer_length( 8005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 8015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 8025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int len = MKA_HDR_LEN; 8035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 8045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 8065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) 8075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt len += sizeof(struct ieee802_1x_mka_peer_id); 8085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return (len + 0x3) & ~0x3; 8105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 8115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 8145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_encode_live_peer_body - 8155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 8165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 8175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_encode_live_peer_body( 8185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 8195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf) 8205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 8215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_peer_body *body; 8225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 8235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int length; 8245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_peer_id *body_peer; 8255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = ieee802_1x_mka_get_live_peer_length(participant); 8275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body)); 8285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->type = MKA_LIVE_PEER_LIST; 8305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt set_mka_param_body_len(body, length - MKA_HDR_LEN); 8315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 8335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 8345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_peer = wpabuf_put(buf, 8355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(struct ieee802_1x_mka_peer_id)); 8365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body_peer->mi, peer->mi, MI_LEN); 8375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_peer->mn = host_to_be32(peer->mn); 8385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_peer++; 8395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 8405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_peer_body(body); 8425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 8435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 8445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 8465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_potential_peer_body_present 8475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 8485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 8495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_potential_peer_body_present( 8505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 8515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 8525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return !dl_list_empty(&participant->potential_peers); 8535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 8545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 8575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_potential_peer_length 8585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 8595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 8605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_get_potential_peer_length( 8615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 8625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 8635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int len = MKA_HDR_LEN; 8645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 8655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->potential_peers, 8675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) 8685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt len += sizeof(struct ieee802_1x_mka_peer_id); 8695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return (len + 0x3) & ~0x3; 8715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 8725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 8755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_encode_potential_peer_body - 8765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 8775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 8785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_encode_potential_peer_body( 8795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 8805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf) 8815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 8825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_peer_body *body; 8835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 8845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int length; 8855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_peer_id *body_peer; 8865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = ieee802_1x_mka_get_potential_peer_length(participant); 8885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_peer_body)); 8895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->type = MKA_POTENTIAL_PEER_LIST; 8915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt set_mka_param_body_len(body, length - MKA_HDR_LEN); 8925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->potential_peers, 8945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 8955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_peer = wpabuf_put(buf, 8965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(struct ieee802_1x_mka_peer_id)); 8975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body_peer->mi, peer->mi, MI_LEN); 8985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_peer->mn = host_to_be32(peer->mn); 8995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_peer++; 9005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 9015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_peer_body(body); 9035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 9045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 9055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 9085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_i_in_peerlist - 9095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 9105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 9115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant, 9125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 9135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 9145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean included = FALSE; 9155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 9165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 9175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t left_len; 9185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int body_type; 9195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 peer_mn; 9205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *peer_mi; 9215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *pos; 9225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t i; 9235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos = mka_msg; 9255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len = msg_len; 9265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) { 9275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) pos; 9285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 9295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_type = get_mka_param_body_type(hdr); 9305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_type != MKA_LIVE_PEER_LIST && 9325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_type != MKA_POTENTIAL_PEER_LIST) 9335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto SKIP_PEER; 9345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_peer_body( 9365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (struct ieee802_1x_mka_peer_body *)pos); 9375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) { 9395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 9405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV", 9415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) left_len, (int) MKA_HDR_LEN, 9425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len, DEFAULT_ICV_LEN); 9435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto SKIP_PEER; 9445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 9455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if ((body_len % 16) != 0) { 9475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 9485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Peer Packet Body Length (%d bytes) should multiple of 16 octets", 9495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len); 9505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto SKIP_PEER; 9515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 9525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) { 9545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mi = MKA_HDR_LEN + pos + i; 9555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&peer_mn, peer_mi + MI_LEN, sizeof(peer_mn)); 9565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mn = be_to_host32(peer_mn); 9575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0 && 9585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mn == participant->mn) { 9595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt included = TRUE; 9605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 9615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 9625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 9635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (included) 9655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return TRUE; 9665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9675a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSKIP_PEER: 9685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len -= body_len + MKA_HDR_LEN; 9695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos += body_len + MKA_HDR_LEN; 9705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 9715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return FALSE; 9735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 9745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 9775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_live_peer_body - 9785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 9795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int ieee802_1x_mka_decode_live_peer_body( 9805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 9815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *peer_msg, size_t msg_len) 9825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 9835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const struct ieee802_1x_mka_hdr *hdr; 9845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 9855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 9865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 peer_mn; 9875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *peer_mi; 9885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t i; 9895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean is_included; 9905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt is_included = ieee802_1x_kay_is_in_live_peer( 9925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, participant->current_peer_id.mi); 9935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (const struct ieee802_1x_mka_hdr *) peer_msg; 9955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 9965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 9975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) { 9985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mi = MKA_HDR_LEN + peer_msg + i; 9995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&peer_mn, peer_mi + MI_LEN, sizeof(peer_mn)); 10005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mn = be_to_host32(peer_mn); 10015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* it is myself */ 10035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) { 10045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* My message id is used by other participant */ 10055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer_mn > participant->mn) { 10065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_random(participant->mi, 10075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(participant->mi)); 10085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mn = 0; 10095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 10115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!is_included) 10135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 10145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = ieee802_1x_kay_get_peer(participant, peer_mi); 10165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (NULL != peer) { 10175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->mn = peer_mn; 10185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->expire = time(NULL) + MKA_LIFE_TIME / 1000; 10195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 10205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!ieee802_1x_kay_create_potential_peer( 10215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, peer_mi, peer_mn)) { 10225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 10235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 10285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 10295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 10325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_potential_peer_body - 10335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 10345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 10355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_potential_peer_body( 10365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 10375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *peer_msg, size_t msg_len) 10385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 10395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 10405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 10415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 peer_mn; 10425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *peer_mi; 10435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t i; 10445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) peer_msg; 10465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 10475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) { 10495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mi = MKA_HDR_LEN + peer_msg + i; 10505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&peer_mn, peer_mi + MI_LEN, sizeof(peer_mn)); 10515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer_mn = be_to_host32(peer_mn); 10525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* it is myself */ 10545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) { 10555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* My message id is used by other participant */ 10565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer_mn > participant->mn) { 10575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_random(participant->mi, 10585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(participant->mi)); 10595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mn = 0; 10605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 10625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 10645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 10665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 10675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 10705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_sak_use_body_present 10715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 10725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 10735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_sak_use_body_present( 10745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 10755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 10765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->to_use_sak) 10775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return TRUE; 10785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 10795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return FALSE; 10805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 10815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 10845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_get_sak_use_length 10855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 10865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 10875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_get_sak_use_length( 10885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 10895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 10905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int length = MKA_HDR_LEN; 10915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->kay->macsec_desired && participant->advised_desired) 10935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = sizeof(struct ieee802_1x_mka_sak_use_body); 10945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 10955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = MKA_HDR_LEN; 10965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = (length + 0x3) & ~0x3; 10985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 10995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return length; 11005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 11015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 11045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * 11055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 11065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic u32 11075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant *principal, 11085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *ki) 11095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 11105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa *rxsa; 11115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 11125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 lpn = 0; 11135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 11155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) 11165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 11175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { 11185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_get_receive_lowest_pn(principal->kay, 11195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt rxsa); 11205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt lpn = lpn > rxsa->lowest_pn ? 11225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt lpn : rxsa->lowest_pn; 11235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 11245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 11255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 11265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 11275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (lpn == 0) 11295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt lpn = 1; 11305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return lpn; 11325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 11335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 11365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_encode_sak_use_body - 11375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 11385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 11395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_encode_sak_use_body( 11405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 11415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf) 11425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 11435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_sak_use_body *body; 11445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int length; 11455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 pn = 1; 11465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = ieee802_1x_mka_get_sak_use_length(participant); 11485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = wpabuf_put(buf, sizeof(struct ieee802_1x_mka_sak_use_body)); 11495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->type = MKA_SAK_USE; 11515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt set_mka_param_body_len(body, length - MKA_HDR_LEN); 11525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (length == MKA_HDR_LEN) { 11545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->ptx = TRUE; 11555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->prx = TRUE; 11565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lan = 0; 11575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lrx = FALSE; 11585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->ltx = FALSE; 11595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->delay_protect = FALSE; 11605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 11615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 11625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* data protect, lowest accept packet number */ 11645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->delay_protect = participant->kay->macsec_replay_protect; 11655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pn = ieee802_1x_mka_get_lpn(participant, &participant->lki); 11665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (pn > participant->kay->pn_exhaustion) { 11675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion"); 11685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->is_key_server) 11695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = TRUE; 11705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 11715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->llpn = host_to_be32(pn); 11735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pn = ieee802_1x_mka_get_lpn(participant, &participant->oki); 11745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->olpn = host_to_be32(pn); 11755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* plain tx, plain rx */ 11775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->kay->macsec_protect) 11785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->ptx = FALSE; 11795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 11805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->ptx = TRUE; 11815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->kay->macsec_validate == Strict) 11835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->prx = FALSE; 11845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 11855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->prx = TRUE; 11865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* latest key: rx, tx, key server member identifier key number */ 11885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lan = participant->lan; 11895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->lsrv_mi, participant->lki.mi, 11905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(body->lsrv_mi)); 11915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lkn = host_to_be32(participant->lki.kn); 11925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lrx = participant->lrx; 11935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->ltx = participant->ltx; 11945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 11955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* old key: rx, tx, key server member identifier key number */ 11965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->oan = participant->oan; 11975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->oki.kn != participant->lki.kn && 11985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->oki.kn != 0) { 11995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->otx = TRUE; 12005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->orx = TRUE; 12015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->osrv_mi, participant->oki.mi, 12025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(body->osrv_mi)); 12035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->okn = host_to_be32(participant->oki.kn); 12045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 12055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->otx = FALSE; 12065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->orx = FALSE; 12075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* set CP's variable */ 12105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->ltx) { 12115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->kay->tx_enable) 12125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->tx_enable = TRUE; 12135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->kay->port_enable) 12155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->port_enable = TRUE; 12165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->lrx) { 12185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->kay->rx_enable) 12195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->rx_enable = TRUE; 12205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_sak_use_body(body); 12235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 12245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 12255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 12285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_sak_use_body - 12295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 12305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 12315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_sak_use_body( 12325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 12335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 12345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 12355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 12365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_sak_use_body *body; 12375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 12385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *txsa; 12395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sa_key = NULL; 12405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 12415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki ki; 12425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u32 lpn; 12435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean all_receiving; 12445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean founded; 12455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->principal) { 12475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: Participant is not principal"); 12485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 12495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = ieee802_1x_kay_get_live_peer(participant, 12515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mi); 12525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer) { 12535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: the peer is not my live peer"); 12545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 12555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 12585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 12595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = (struct ieee802_1x_mka_sak_use_body *) mka_msg; 12605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_sak_use_body(body); 12615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if ((body_len != 0) && (body_len < 40)) { 12635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 12645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 40, or more octets", 12655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len); 12665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 12675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* TODO: what action should I take when peer does not support MACsec */ 12705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_len == 0) { 12715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: Peer does not support MACsec"); 12725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 12735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* TODO: when the plain tx or rx of peer is true, should I change 12765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * the attribute of controlled port 12775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 12785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->prx) 12795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: peer's plain rx are TRUE"); 12805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->ptx) 12825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: peer's plain tx are TRUE"); 12835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 12845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* check latest key is valid */ 12855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->ltx || body->lrx) { 12865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt founded = FALSE; 12875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi)); 12885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ki.kn = ntohl(body->lkn); 12895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(sa_key, &participant->sak_list, 12905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key, list) { 12915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&sa_key->key_identifier, &ki)) { 12925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt founded = TRUE; 12935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 12945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 12965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!founded) { 12975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: Latest key is invalid"); 12985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 12995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(participant->lki.mi, body->lsrv_mi, 13015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(participant->lki.mi)) == 0 && 13025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ntohl(body->lkn) == participant->lki.kn && 13035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->lan == participant->lan) { 13045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->sak_used = TRUE; 13055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->ltx && peer->is_key_server) { 13075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_servertransmitting( 13085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->cp, TRUE); 13095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 13105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* check old key is valid */ 13145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->otx || body->orx) { 13155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(participant->oki.mi, body->osrv_mi, 13165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(participant->oki.mi)) != 0 || 13175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ntohl(body->okn) != participant->oki.kn || 13185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->oan != participant->oan) { 13195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: Old key is invalid"); 13205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 13215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* TODO: how to set the MACsec hardware when delay_protect is true */ 13255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body->delay_protect && (!ntohl(body->llpn) || !ntohl(body->olpn))) { 13265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, 13275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Lowest packet number should greater than 0 when delay_protect is TRUE"); 13285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 13295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* check all live peer have used the sak for receiving sa */ 13325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt all_receiving = TRUE; 13335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 13345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 13355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer->sak_used) { 13365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt all_receiving = FALSE; 13375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 13385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (all_receiving) { 13415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_dist_sak = FALSE; 13425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_allreceiving(participant->kay->cp, TRUE); 13435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 13445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* if i'm key server, and detects peer member pn exhaustion, rekey.*/ 13475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt lpn = ntohl(body->llpn); 13485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (lpn > participant->kay->pn_exhaustion) { 13495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->is_key_server) { 13505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = TRUE; 13515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion"); 13525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt founded = FALSE; 13565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(txsa, &participant->txsc->sa_list, 13575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa, list) { 13585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (sa_key != NULL && txsa->pkey == sa_key) { 13595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt founded = TRUE; 13605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 13615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!founded) { 13645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY: Can't find txsa"); 13655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 13665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* FIXME: Secy creates txsa with default npn. If MKA detected Latest Key 13695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * npn is larger than txsa's npn, set it to txsa. 13705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 13715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_get_transmit_next_pn(participant->kay, txsa); 13725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (lpn > txsa->next_pn) { 13735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_set_transmit_next_pn(participant->kay, txsa); 13745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "KaY: update lpn =0x%x", lpn); 13755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 13765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 13785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 13795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 13825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_dist_sak_body_present 13835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 13845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 13855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_dist_sak_body_present( 13865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 13875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 13885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->to_dist_sak || !participant->new_key) 13895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return FALSE; 13905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return TRUE; 13925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 13935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 13955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 13965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_dist_sak_length 13975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 13985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 13995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_get_dist_sak_length( 14005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 14015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 14025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int length; 14035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int cs_index = participant->kay->macsec_csindex; 14045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->advised_desired) { 14065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = sizeof(struct ieee802_1x_mka_dist_sak_body); 14075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (cs_index != DEFAULT_CS_INDEX) 14085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length += CS_ID_LEN; 14095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length += cipher_suite_tbl[cs_index].sak_len + 8; 14115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 14125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = MKA_HDR_LEN; 14135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 14145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = (length + 0x3) & ~0x3; 14155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return length; 14175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 14185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 14215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_encode_dist_sak_body - 14225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 14235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 14245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_encode_dist_sak_body( 14255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 14265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf) 14275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 14285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_dist_sak_body *body; 14295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sak; 14305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int length; 14315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int cs_index; 14325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int sak_pos; 14335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = ieee802_1x_mka_get_dist_sak_length(participant); 14355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = wpabuf_put(buf, length); 14365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->type = MKA_DISTRIBUTED_SAK; 14375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt set_mka_param_body_len(body, length - MKA_HDR_LEN); 14385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (length == MKA_HDR_LEN) { 14395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->confid_offset = 0; 14405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->dan = 0; 14415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 14425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 14435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak = participant->new_key; 14455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->confid_offset = sak->confidentiality_offset; 14465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->dan = sak->an; 14475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->kn = host_to_be32(sak->key_identifier.kn); 14485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt cs_index = participant->kay->macsec_csindex; 14495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak_pos = 0; 14505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (cs_index != DEFAULT_CS_INDEX) { 14515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN); 14525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak_pos = CS_ID_LEN; 14535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 14549ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (aes_wrap(participant->kek.key, 16, 14555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt cipher_suite_tbl[cs_index].sak_len / 8, 14565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak->key, body->sak + sak_pos)) { 14575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: AES wrap failed"); 14585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 14595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 14605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_dist_sak_body(body); 14625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 14645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 14655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 14685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_init_data_key - 14695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 14705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct data_key * 14715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init_data_key(const struct key_conf *conf) 14725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 14735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *pkey; 14745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!conf) 14765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 14775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey = os_zalloc(sizeof(*pkey)); 14795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (pkey == NULL) { 14805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 14815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 14825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 14835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->key = os_zalloc(conf->key_len); 14855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (pkey->key == NULL) { 14865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 14875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(pkey); 14885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 14895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 14905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 14915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(pkey->key, conf->key, conf->key_len); 14925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&pkey->key_identifier, &conf->ki, 14935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(pkey->key_identifier)); 14945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->confidentiality_offset = conf->offset; 14955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->an = conf->an; 14965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->transmits = conf->tx; 14975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->receives = conf->rx; 14985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_time(&pkey->created_time); 14995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->user = 1; 15015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return pkey; 15035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 15045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 15075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_decode_dist_sak_body - 15085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 15095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 15105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_dist_sak_body( 15115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 15125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 15135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 15145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 15155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_dist_sak_body *body; 15165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 15175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct macsec_ciphersuite *cs; 15185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 15195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct key_conf *conf; 15205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sa_key = NULL; 15215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki sak_ki; 15225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int sak_len; 15235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *wrap_sak; 15245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *unwrap_sak; 15255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 15275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 15285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if ((body_len != 0) && (body_len != 28) && (body_len < 36)) { 15295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 15305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 0, 28, 36, or more octets", 15315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len); 15325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 15335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->principal) { 15365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 15375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: I can't accept the distributed SAK as I am not principal"); 15385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 15395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->is_key_server) { 15415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 15425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: I can't accept the distributed SAK as myself is key server "); 15435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 15445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->kay->macsec_desired || 15465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 15475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 15485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: I am not MACsec-desired or without MACsec capable"); 15495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 15505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = ieee802_1x_kay_get_live_peer(participant, 15535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mi); 15545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer) { 15555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 15565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: The key server is not in my live peers list"); 15575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 15585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(&participant->kay->key_server_sci, 15605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt &peer->sci, sizeof(struct ieee802_1x_mka_sci)) != 0) { 15615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: The key server is not elected"); 15625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 15635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_len == 0) { 15655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->authenticated = TRUE; 15665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->secured = FALSE; 15675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->failed = FALSE; 15685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = FALSE; 15695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_connect_authenticated(participant->kay->cp); 15705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 15715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY:The Key server advise no MACsec"); 15725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_use_sak = TRUE; 15735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 15745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = TRUE; 15765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->authenticated = FALSE; 15775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->secured = TRUE; 15785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->failed = FALSE; 15795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_connect_secure(participant->kay->cp); 15805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 15815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 15825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg; 15835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_dist_sak_body(body); 15845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(sa_key, &participant->sak_list, struct data_key, list) 15855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 15865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(sa_key->key_identifier.mi, 15875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mi, MI_LEN) == 0 && 15885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key->key_identifier.kn == be_to_host32(body->kn)) { 15895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, "KaY:The Key has installed"); 15905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 15915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 15935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_len == 28) { 15945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak_len = DEFAULT_SA_KEY_LEN; 15955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wrap_sak = body->sak; 15965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->macsec_csindex = DEFAULT_CS_INDEX; 15975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 15985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak); 15995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!cs) { 16005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 16015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: I can't support the Cipher Suite advised by key server"); 16025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 16035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak_len = cs->sak_len; 16055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wrap_sak = body->sak + CS_ID_LEN; 16065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->macsec_csindex = cs->index; 16075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unwrap_sak = os_zalloc(sak_len); 16105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!unwrap_sak) { 16115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 16125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 16135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16149ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (aes_unwrap(participant->kek.key, 16, sak_len >> 3, wrap_sak, 16155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unwrap_sak)) { 16165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: AES unwrap failed"); 16175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(unwrap_sak); 16185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 16195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len); 16215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf = os_zalloc(sizeof(*conf)); 16235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!conf) { 16245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 16255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(unwrap_sak); 16265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 16275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->key_len = sak_len; 16295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->key = os_zalloc(conf->key_len); 16315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!conf->key) { 16325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 16335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(unwrap_sak); 16345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 16355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 16365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(conf->key, unwrap_sak, conf->key_len); 16395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&sak_ki.mi, &participant->current_peer_id.mi, 16415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(sak_ki.mi)); 16425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak_ki.kn = be_to_host32(body->kn); 16435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(conf->ki.mi, sak_ki.mi, MI_LEN); 16455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->ki.kn = sak_ki.kn; 16465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->an = body->dan; 16475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->offset = body->confid_offset; 16485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->rx = TRUE; 16495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->tx = TRUE; 16505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key = ieee802_1x_kay_init_data_key(conf); 16525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!sa_key) { 16535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(unwrap_sak); 16545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf->key); 16555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 16565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 16575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 16585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&participant->sak_list, &sa_key->list); 16605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_ciphersuite( 16625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->cp, 16635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt cipher_suite_tbl[participant->kay->macsec_csindex].id); 16645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 16655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_offset(participant->kay->cp, body->confid_offset); 16665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 16675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_distributedki(participant->kay->cp, &sak_ki); 16685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_distributedan(participant->kay->cp, body->dan); 16695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_signal_newsak(participant->kay->cp); 16705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(participant->kay->cp); 16715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_use_sak = TRUE; 16735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(unwrap_sak); 16755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf->key); 16765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 16775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 16795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 16805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 16835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_icv_body_present 16845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 16855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic Boolean 16865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_icv_body_present(struct ieee802_1x_mka_participant *participant) 16875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 16885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return TRUE; 16895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 16905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 16925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 16935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_get_icv_length 16945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 16955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 16965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant) 16975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 16985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int length; 16995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = sizeof(struct ieee802_1x_mka_icv_body); 17015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length += mka_alg_tbl[participant->kay->mka_algindex].icv_len; 17025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return (length + 0x3) & ~0x3; 17045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 17055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 17085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_encode_icv_body - 17095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 17105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 17115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant, 17125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf) 17135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 17145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_icv_body *body; 17155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int length; 17165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 cmac[MAX_ICV_LEN]; 17175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length = ieee802_1x_mka_get_icv_length(participant); 17195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (length != DEFAULT_ICV_LEN) { 17205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = wpabuf_put(buf, MKA_HDR_LEN); 17215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body->type = MKA_ICV_INDICATOR; 17225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt set_mka_param_body_len(body, length - MKA_HDR_LEN); 17235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 17245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mka_alg_tbl[participant->kay->mka_algindex].icv_hash( 17265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ick.key, wpabuf_head(buf), buf->used, cmac)) { 17275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY, omac1_aes_128 failed"); 17285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 17295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 17305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (length != DEFAULT_ICV_LEN) { 17325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(wpabuf_put(buf, length - MKA_HDR_LEN), cmac, 17335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length - MKA_HDR_LEN); 17345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 17355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(wpabuf_put(buf, length), cmac, length); 17365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 17375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 17395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 17405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 17425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_icv_body - 17435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 17445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic u8 * 17455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_icv_body(struct ieee802_1x_mka_participant *participant, 17465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 17475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 17485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 17495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_icv_body *body; 17505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 17515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t left_len; 17525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int body_type; 17535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *pos; 17545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos = mka_msg; 17565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len = msg_len; 17575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (left_len > (MKA_HDR_LEN + DEFAULT_ICV_LEN)) { 17585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) pos; 17595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 17605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_type = get_mka_param_body_type(hdr); 17615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (left_len < (body_len + MKA_HDR_LEN)) 17635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 17645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_type != MKA_ICV_INDICATOR) { 17665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len -= MKA_HDR_LEN + body_len; 17675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos += MKA_HDR_LEN + body_len; 17685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 17695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 17705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = (struct ieee802_1x_mka_icv_body *)pos; 17725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_len 17735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt < mka_alg_tbl[participant->kay->mka_algindex].icv_len) { 17745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 17755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 17765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return body->icv; 17785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 17795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return (u8 *) (mka_msg + msg_len - DEFAULT_ICV_LEN); 17815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 17825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 17855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_dist_cak_body- 17865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 17875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 17885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_dist_cak_body( 17895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 17905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 17915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 17925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 17935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 17945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 17955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 17965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 17975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_len < 28) { 17985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 17995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 28 or more octets", 18005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len); 18015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 18025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 18035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 18055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 18065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 18095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_kmd_body - 18105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 18115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 18125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_mka_decode_kmd_body( 18135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 18145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 18155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 18165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 18175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 18185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) mka_msg; 18205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 18215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_len < 5) { 18225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 18235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Use SAK Packet Body Length (%d bytes) should be 5 or more octets", 18245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len); 18255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 18265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 18275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 18295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 18305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 18335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_mka_decode_announce_body - 18345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 18355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int ieee802_1x_mka_decode_announce_body( 18365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, 18375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *mka_msg, size_t msg_len) 18385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 18395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 18405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 18415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct mka_param_body_handler mak_body_handler[] = { 18445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* basic parameter set */ 18455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_encode_basic_body, 18475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 18485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_basic_body_length, 18495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_basic_body_present 18505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* live peer list parameter set */ 18535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_encode_live_peer_body, 18555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_live_peer_body, 18565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_get_live_peer_length, 18575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_live_peer_body_present 18585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* potential peer list parameter set */ 18615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_encode_potential_peer_body, 18635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_potential_peer_body, 18645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_get_potential_peer_length, 18655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_potential_peer_body_present 18665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* sak use parameter set */ 18695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_encode_sak_use_body, 18715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_sak_use_body, 18725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_get_sak_use_length, 18735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_sak_use_body_present 18745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* distribute sak parameter set */ 18775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_encode_dist_sak_body, 18795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_dist_sak_body, 18805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_get_dist_sak_length, 18815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dist_sak_body_present 18825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* distribute cak parameter set */ 18855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 18875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_dist_cak_body, 18885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 18895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL 18905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 18925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* kmd parameter set */ 18935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 18945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 18955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_kmd_body, 18965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 18975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL 18985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 18995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* announce parameter set */ 19015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 19025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 19035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_decode_announce_body, 19045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 19055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL 19065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 19075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* icv parameter set */ 19095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 19105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_encode_icv_body, 19115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL, 19125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_get_icv_length, 19135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_icv_body_present 19145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt }, 19155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}; 19165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 19195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_deinit_data_key - 19205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 19215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_kay_deinit_data_key(struct data_key *pkey) 19225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 19235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!pkey) 19245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 19255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pkey->user--; 19275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (pkey->user > 1) 19285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 19295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&pkey->list); 19315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(pkey->key); 19325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(pkey); 19335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 19345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 19375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_generate_new_sak - 19385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 19395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 19405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant) 19415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 19425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sa_key = NULL; 19435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct key_conf *conf; 19445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 19455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay = participant->kay; 19465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int ctx_len, ctx_offset; 19475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *context; 19485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* check condition for generating a fresh SAK: 19505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * must have one live peer 19515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * and MKA life time elapse since last distribution 19525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * or potential peer is empty 19535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 19545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (dl_list_empty(&participant->live_peers)) { 19555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 19565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Live peers list must not empty when generating fresh SAK"); 19575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 19585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 19595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* FIXME: A fresh SAK not generated until 19615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * the live peer list contains at least one peer and 19625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * MKA life time has elapsed since the prior SAK was first distributed, 19635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * or the Key server's potential peer is empty 19645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * but I can't understand the second item, so 19655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * here only check first item and ingore 19665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * && (!dl_list_empty(&participant->potential_peers))) { 19675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 19685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if ((time(NULL) - kay->dist_time) < MKA_LIFE_TIME / 1000) { 19695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 19705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Life time have not elapsed since prior SAK distributed"); 19715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 19725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 19735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf = os_zalloc(sizeof(*conf)); 19755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!conf) { 19765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 19775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 19785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 19795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->key_len = cipher_suite_tbl[kay->macsec_csindex].sak_len; 19805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->key = os_zalloc(conf->key_len); 19825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!conf->key) { 19835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 19845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: Out of memory", __func__); 19855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 19865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 19875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_len = conf->key_len + sizeof(kay->dist_kn); 19895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 19905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) 19915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_len += sizeof(peer->mi); 19925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_len += sizeof(participant->mi); 19935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 19945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt context = os_zalloc(ctx_len); 19955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!context) { 19965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf->key); 19975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 19985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 19995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 20005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_offset = 0; 20015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_random(context + ctx_offset, conf->key_len); 20025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_offset += conf->key_len; 20035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 20045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 20055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(context + ctx_offset, peer->mi, sizeof(peer->mi)); 20065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_offset += sizeof(peer->mi); 20075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 20085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(context + ctx_offset, participant->mi, 20095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(participant->mi)); 20105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ctx_offset += sizeof(participant->mi); 20115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(context + ctx_offset, &kay->dist_kn, sizeof(kay->dist_kn)); 20125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (conf->key_len == 16) { 20145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_sak_128bits_aes_cmac(participant->cak.key, 20155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt context, ctx_len, conf->key); 20165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else if (conf->key_len == 32) { 20175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_sak_128bits_aes_cmac(participant->cak.key, 20185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt context, ctx_len, conf->key); 20195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 20205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: SAK Length not support"); 20215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf->key); 20225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 20235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(context); 20245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 20255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 20265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK", 20275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->key, conf->key_len); 20285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(conf->ki.mi, participant->mi, MI_LEN); 20305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->ki.kn = participant->kay->dist_kn; 20315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->an = participant->kay->dist_an; 20325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->offset = kay->macsec_confidentiality; 20335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->rx = TRUE; 20345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf->tx = TRUE; 20355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key = ieee802_1x_kay_init_data_key(conf); 20375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!sa_key) { 20385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf->key); 20395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 20405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(context); 20415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 20425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 20435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_key = sa_key; 20445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&participant->sak_list, &sa_key->list); 20465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_ciphersuite(participant->kay->cp, 20475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt cipher_suite_tbl[kay->macsec_csindex].id); 20485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 20495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_offset(kay->cp, conf->offset); 20505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 20515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_distributedki(kay->cp, &conf->ki); 20525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_distributedan(kay->cp, conf->an); 20535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_signal_newsak(kay->cp); 20545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 20555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 20575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) 20585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer->sak_used = FALSE; 20595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->dist_kn++; 20615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->dist_an++; 20625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->kay->dist_an > 3) 20635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->dist_an = 0; 20645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay->dist_time = time(NULL); 20665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf->key); 20685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(conf); 20695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(context); 20705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 20715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 20725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 20755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_elect_key_server - elect the key server 20765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * when to elect: whenever the live peers list changes 20775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 20785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 20795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant) 20805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 20815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 20825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *key_server = NULL; 20835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay = participant->kay; 20845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean i_is_key_server; 20855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int i; 20865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->is_obliged_key_server) { 20885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = TRUE; 20895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_dist_sak = FALSE; 20905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_electedself(kay->cp, TRUE); 20915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 20925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 20935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 20945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* elect the key server among the peers */ 20955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 20965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 20975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer->is_key_server) 20985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 20995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!key_server) { 21015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key_server = peer; 21025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 21035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer->key_server_priority < 21065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key_server->key_server_priority) { 21075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key_server = peer; 21085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else if (peer->key_server_priority == 21095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key_server->key_server_priority) { 21105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < 6; i++) { 21115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer->sci.addr[i] < 21125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key_server->sci.addr[i]) 21135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key_server = peer; 21145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* elect the key server between me and the above elected peer */ 21195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt i_is_key_server = FALSE; 21205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (key_server && participant->can_be_key_server) { 21215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->actor_priority 21225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt < key_server->key_server_priority) { 21235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt i_is_key_server = TRUE; 21245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else if (kay->actor_priority 21255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt == key_server->key_server_priority) { 21265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < 6; i++) { 21275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->actor_sci.addr[i] 21285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt < key_server->sci.addr[i]) { 21295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt i_is_key_server = TRUE; 21305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!key_server && !i_is_key_server) { 21365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->principal = FALSE; 21375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_key_server = FALSE; 21385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_elected = FALSE; 21395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 21405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (i_is_key_server) { 21435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_electedself(kay->cp, TRUE); 21445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(&kay->key_server_sci, &kay->actor_sci, 21455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->key_server_sci))) { 21465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_signal_chgdserver(kay->cp); 21475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 21485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_key_server = TRUE; 21515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->principal = TRUE; 21525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = TRUE; 21535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: I is elected as key server"); 21545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_dist_sak = FALSE; 21555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_elected = TRUE; 21565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&kay->key_server_sci, &kay->actor_sci, 21585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->key_server_sci)); 21595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->key_server_priority = kay->actor_priority; 21605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (key_server) { 21635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_electedself(kay->cp, FALSE); 21645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(&kay->key_server_sci, &key_server->sci, 21655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->key_server_sci))) { 21665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_signal_chgdserver(kay->cp); 21675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 21685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_key_server = FALSE; 21715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->principal = TRUE; 21725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_elected = TRUE; 21735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&kay->key_server_sci, &key_server->sci, 21755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->key_server_sci)); 21765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->key_server_priority = key_server->key_server_priority; 21775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 21785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 21805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 21815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 21845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_decide_macsec_use - the key server determinate 21855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * how to use MACsec: whether use MACsec and its capability 21865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * protectFrames will be advised if the key server and one of its live peers are 21875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * MACsec capable and one of those request MACsec protection 21885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 21895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 21905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_decide_macsec_use( 21915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 21925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 21935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay = participant->kay; 21945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 21955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt enum macsec_cap less_capability; 21965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean has_peer; 21975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 21985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant->is_key_server) 21995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 22005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* key server self is MACsec-desired and requesting MACsec */ 22025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay->macsec_desired) { 22035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = FALSE; 22045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 22055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 22065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { 22075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = FALSE; 22085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 22095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 22105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt less_capability = kay->macsec_capable; 22115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* at least one of peers is MACsec-desired and requesting MACsec */ 22135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt has_peer = FALSE; 22145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(peer, &participant->live_peers, 22155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 22165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!peer->macsec_desired) 22175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 22185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (peer->macsec_capbility == MACSEC_CAP_NOT_IMPLEMENTED) 22205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt continue; 22215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt less_capability = (less_capability < peer->macsec_capbility) ? 22235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt less_capability : peer->macsec_capbility; 22245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt has_peer = TRUE; 22255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 22265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (has_peer) { 22285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = TRUE; 22295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_capability = less_capability; 22305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->authenticated = FALSE; 22315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->secured = TRUE; 22325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->failed = FALSE; 22335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_connect_secure(kay->cp); 22345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 22355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 22365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = FALSE; 22375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_capability = MACSEC_CAP_NOT_IMPLEMENTED; 22385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_use_sak = FALSE; 22395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->authenticated = TRUE; 22405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->secured = FALSE; 22415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->failed = FALSE; 22425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_kn = 0; 22435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_an = 0; 22445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_kn = 0; 22455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_an = 0; 22465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_kn = 0; 22475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_an = 0; 22485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_kn = 0; 22495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_an = 0; 22505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_connect_authenticated(kay->cp); 22515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 22525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 22535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 22555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 22565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic const u8 pae_group_addr[ETH_ALEN] = { 22585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 22595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}; 22605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 22635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_encode_mkpdu - 22645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 22655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 22665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_encode_mkpdu(struct ieee802_1x_mka_participant *participant, 22675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *pbuf) 22685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 22695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int i; 22705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee8023_hdr *ether_hdr; 22715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_hdr *eapol_hdr; 22725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ether_hdr = wpabuf_put(pbuf, sizeof(*ether_hdr)); 22745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(ether_hdr->dest, pae_group_addr, sizeof(ether_hdr->dest)); 22755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(ether_hdr->src, participant->kay->actor_sci.addr, 22765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(ether_hdr->dest)); 22775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ether_hdr->ethertype = host_to_be16(ETH_P_EAPOL); 22785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr = wpabuf_put(pbuf, sizeof(*eapol_hdr)); 22805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr->version = EAPOL_VERSION; 22815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA; 22825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr->length = host_to_be16(pbuf->size - pbuf->used); 22835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) { 22855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mak_body_handler[i].body_present && 22865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mak_body_handler[i].body_present(participant)) { 22875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mak_body_handler[i].body_tx(participant, pbuf)) 22885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 22895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 22905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 22915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 22935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 22945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 22955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 22965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_participant_send_mkpdu - 22975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 22985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int 22995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_participant_send_mkpdu( 23005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant) 23015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 23025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct wpabuf *buf; 23035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay = participant->kay; 23045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t length = 0; 23055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int i; 23065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: to enpacket and send the MKPDU"); 23085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr); 23095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) { 23105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mak_body_handler[i].body_present && 23115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mak_body_handler[i].body_present(participant)) 23125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt length += mak_body_handler[i].body_length(participant); 23135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt buf = wpabuf_alloc(length); 23165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!buf) { 23175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: out of memory"); 23185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 23195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (ieee802_1x_kay_encode_mkpdu(participant, buf)) { 23225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: encode mkpdu fail!"); 23235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 23245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt l2_packet_send(kay->l2_mka, NULL, 0, wpabuf_head(buf), wpabuf_len(buf)); 23275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpabuf_free(buf); 23285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->active = TRUE; 23305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->active = TRUE; 23315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 23335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 23345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa); 23375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 23385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_participant_timer - 23395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 23405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) 23415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 23425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 23435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay; 23445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer, *pre_peer; 23455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt time_t now = time(NULL); 23465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean lp_changed; 23475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc, *pre_rxsc; 23485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *txsa, *pre_txsa; 23495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = (struct ieee802_1x_mka_participant *)eloop_ctx; 23515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay = participant->kay; 23525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->cak_life) { 23535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (now > participant->cak_life) { 23545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->authenticated = FALSE; 23555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->secured = FALSE; 23565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->failed = TRUE; 23575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_delete_mka(kay, &participant->ckn); 23585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 23595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* should delete MKA instance if there are not live peers 23635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * when the MKA life elapsed since its creating */ 23645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->mka_life) { 23655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (dl_list_empty(&participant->live_peers)) { 23665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (now > participant->mka_life) { 23675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->authenticated = FALSE; 23685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->secured = FALSE; 23695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->failed = TRUE; 23705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_delete_mka(kay, 23715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt &participant->ckn); 23725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 23735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 23755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mka_life = 0; 23765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 23795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt lp_changed = FALSE; 23805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(peer, pre_peer, &participant->live_peers, 23815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 23825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (now > peer->expire) { 23835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Live peer removed"); 23845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, 23855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(peer->mi)); 23865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 23875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(rxsc, pre_rxsc, 23885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt &participant->rxsc_list, 23895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc, list) { 23905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(&rxsc->sci, &peer->sci, 23915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(rxsc->sci)) == 0) { 23925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_delete_receive_sc(kay, rxsc); 23935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_receive_sc( 23945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, rxsc); 23955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 23975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&peer->list); 23985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(peer); 23995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt lp_changed = TRUE; 24005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (lp_changed) { 24045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (dl_list_empty(&participant->live_peers)) { 24055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_desired = FALSE; 24065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->advised_capability = 24075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt MACSEC_CAP_NOT_IMPLEMENTED; 24085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_use_sak = FALSE; 24095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->authenticated = TRUE; 24105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->secured = FALSE; 24115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->failed = FALSE; 24125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_kn = 0; 24135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_an = 0; 24145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_kn = 0; 24155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_an = 0; 24165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_kn = 0; 24175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_an = 0; 24185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_kn = 0; 24195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_an = 0; 24205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(txsa, pre_txsa, 24215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt &participant->txsc->sa_list, 24225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa, list) { 24235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_disable_transmit_sa(kay, txsa); 24245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_transmit_sa(txsa); 24255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_connect_authenticated(kay->cp); 24285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 24295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 24305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_elect_key_server(participant); 24315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_decide_macsec_use(participant); 24325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers, 24365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list) { 24375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (now > peer->expire) { 24385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Potential peer removed"); 24395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, 24405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(peer->mi)); 24415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn); 24425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&peer->list); 24435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(peer); 24445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->new_sak) { 24485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!ieee802_1x_kay_generate_new_sak(participant)) 24495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_dist_sak = TRUE; 24505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = FALSE; 24525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->retry_count < MAX_RETRY_CNT) { 24555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_participant_send_mkpdu(participant); 24565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->retry_count++; 24575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eloop_register_timeout(MKA_HELLO_TIME / 1000, 0, 24605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_participant_timer, 24615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, NULL); 24625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 24635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 24665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_init_transmit_sa - 24675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 24685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct transmit_sa * 24695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN, 24705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *key) 24715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 24725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *psa; 24735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key->tx_latest = TRUE; 24755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key->rx_latest = TRUE; 24765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa = os_zalloc(sizeof(*psa)); 24785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!psa) { 24795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 24805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 24815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 24825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (key->confidentiality_offset >= CONFIDENTIALITY_OFFSET_0 && 24845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt key->confidentiality_offset <= CONFIDENTIALITY_OFFSET_50) 24855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->confidentiality = TRUE; 24865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 24875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->confidentiality = FALSE; 24885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->an = an; 24905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->pkey = key; 24915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->next_pn = next_PN; 24925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->sc = psc; 24935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_time(&psa->created_time); 24955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->in_use = FALSE; 24965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 24975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&psc->sa_list, &psa->list); 24985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, 24995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Create transmit SA(an: %d, next_PN: %u) of SC(channel: %d)", 25005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) an, next_PN, psc->channel); 25015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return psa; 25035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 25045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 25075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_deinit_transmit_sa - 25085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 25095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa) 25105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 25115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->pkey = NULL; 25125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, 25135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Delete transmit SA(an: %d) of SC(channel: %d)", 25145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psa->an, psa->sc->channel); 25155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&psa->list); 25165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(psa); 25175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 25185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 25215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * init_transmit_sc - 25225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 25235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct transmit_sc * 25245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci, 25255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int channel) 25265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 25275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sc *psc; 25285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc = os_zalloc(sizeof(*psc)); 25305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!psc) { 25315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "%s: out of memory", __func__); 25325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 25335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 25345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&psc->sci, sci, sizeof(psc->sci)); 25355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->channel = channel; 25365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_time(&psc->created_time); 25385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->transmitting = FALSE; 25395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->encoding_sa = FALSE; 25405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->enciphering_sa = FALSE; 25415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&psc->sa_list); 25435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Create transmit SC(channel: %d)", channel); 25445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)sci , sizeof(*sci)); 25455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return psc; 25475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 25485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 25515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_deinit_transmit_sc - 25525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 25535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void 25545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_deinit_transmit_sc( 25555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant, struct transmit_sc *psc) 25565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 25575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *psa, *tmp; 25585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC(channel: %d)", 25605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt psc->channel); 25615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, 25625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt list) { 25635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_disable_transmit_sa(participant->kay, psa); 25645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_transmit_sa(psa); 25655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 25665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(psc); 25685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 25695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/****************** Interface between CP and KAY *********************/ 25725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 25735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_set_latest_sa_attr - 25745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 25755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay, 25765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *lki, u8 lan, 25775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean ltx, Boolean lrx) 25785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 25795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 25805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 25825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 25835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 25845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!lki) 25865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memset(&principal->lki, 0, sizeof(principal->lki)); 25875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 25885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&principal->lki, lki, sizeof(principal->lki)); 25895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 25905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->lan = lan; 25915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->ltx = ltx; 25925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->lrx = lrx; 25935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!lki) { 25945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_kn = 0; 25955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_kn = 0; 25965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 25975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_kn = lki->kn; 25985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_kn = lki->kn; 25995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 26005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ltx_an = lan; 26015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->lrx_an = lan; 26025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 26045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 26055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 26085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_set_old_sa_attr - 26095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 26105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay, 26115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *oki, 26125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 oan, Boolean otx, Boolean orx) 26135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 26145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 26155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 26175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 26185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 26195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!oki) 26215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memset(&principal->oki, 0, sizeof(principal->oki)); 26225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt else 26235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&principal->oki, oki, sizeof(principal->oki)); 26245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->oan = oan; 26265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->otx = otx; 26275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->orx = orx; 26285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!oki) { 26305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_kn = 0; 26315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_kn = 0; 26325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 26335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_kn = oki->kn; 26345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_kn = oki->kn; 26355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 26365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->otx_an = oan; 26375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->orx_an = oan; 26385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 26405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 26415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 26445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_create_sas - 26455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 26465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, 26475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *lki) 26485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 26495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sa_key, *latest_sak; 26505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 26515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 26525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa *rxsa; 26535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *txsa; 26545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 26565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 26575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 26585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt latest_sak = NULL; 26605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(sa_key, &principal->sak_list, struct data_key, list) { 26615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&sa_key->key_identifier, lki)) { 26625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key->rx_latest = TRUE; 26635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key->tx_latest = TRUE; 26645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt latest_sak = sa_key; 26655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->to_use_sak = TRUE; 26665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 26675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key->rx_latest = FALSE; 26685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sa_key->tx_latest = FALSE; 26695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 26705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 26715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!latest_sak) { 26725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "lki related sak not found"); 26735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 26745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 26755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 26775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1, 26785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt latest_sak); 26795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!rxsa) 26805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 26815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_create_receive_sa(kay, rxsa); 26835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 26845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an, 26865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1, latest_sak); 26875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!txsa) 26885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 26895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_create_transmit_sa(kay, txsa); 26915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 26955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 26965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 26985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 26995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_delete_sas - 27005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 27015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, 27025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *ki) 27035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 27045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sa_key, *pre_key; 27055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *txsa, *pre_txsa; 27065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa *rxsa, *pre_rxsa; 27075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 27085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 27095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: Entry into %s", __func__); 27115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 27125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 27135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 27145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* remove the transmit sa */ 27165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list, 27175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa, list) { 27185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&txsa->pkey->key_identifier, ki)) { 27195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_disable_transmit_sa(kay, txsa); 27205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_transmit_sa(txsa); 27215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* remove the receive sa */ 27255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 27265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list, 27275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa, list) { 27285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { 27295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_disable_receive_sa(kay, rxsa); 27305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_receive_sa(rxsa); 27315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* remove the sak */ 27365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each_safe(sa_key, pre_key, &principal->sak_list, 27375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key, list) { 27385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&sa_key->key_identifier, ki)) { 27395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_data_key(sa_key); 27405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 27415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (principal->new_key == sa_key) 27435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->new_key = NULL; 27445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 27475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 27485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 27515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_enable_tx_sas - 27525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 27535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay, 27545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *lki) 27555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 27565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 27575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct transmit_sa *txsa; 27585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 27605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 27615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 27625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(txsa, &principal->txsc->sa_list, struct transmit_sa, 27645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt list) { 27655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&txsa->pkey->key_identifier, lki)) { 27665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt txsa->in_use = TRUE; 27675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_enable_transmit_sa(kay, txsa); 27685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_usingtransmitas( 27695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->kay->cp, TRUE); 27705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(principal->kay->cp); 27715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 27735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 27755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 27765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 27795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_enable_rx_sas - 27805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 27815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay, 27825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_ki *lki) 27835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 27845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 27855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sa *rxsa; 27865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 27875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 27895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 27905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 27915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 27925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { 27935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) 27945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 27955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_ki_equal(&rxsa->pkey->key_identifier, lki)) { 27965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt rxsa->in_use = TRUE; 27975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_enable_receive_sa(kay, rxsa); 27985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_set_usingreceivesas( 27995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->kay->cp, TRUE); 28005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(principal->kay->cp); 28015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 28025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 28035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 28045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 28065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 28075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 28105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_enable_new_info - 28115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 28125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay) 28135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 28145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *principal; 28155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal = ieee802_1x_kay_get_principal_participant(kay); 28175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!principal) 28185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 28195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (principal->retry_count < MAX_RETRY_CNT) { 28215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_participant_send_mkpdu(principal); 28225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt principal->retry_count++; 28235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 28245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 28265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 28275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 28305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_cp_conf - 28315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 28325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_cp_conf(struct ieee802_1x_kay *kay, 28335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_cp_conf *pconf) 28345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 28355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pconf->protect = kay->macsec_protect; 28365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pconf->replay_protect = kay->macsec_replay_protect; 28375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pconf->validate = kay->macsec_validate; 28385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 28405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 28415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 28445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_alloc_cp_sm - 28455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 28465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic struct ieee802_1x_cp_sm * 28475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_alloc_cp_sm(struct ieee802_1x_kay *kay) 28485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 28495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_cp_conf conf; 28505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memset(&conf, 0, sizeof(conf)); 28525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf.protect = kay->macsec_protect; 28535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf.replay_protect = kay->macsec_replay_protect; 28545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf.validate = kay->macsec_validate; 28555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt conf.replay_window = kay->macsec_replay_window; 28565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return ieee802_1x_cp_sm_init(kay, &conf); 28585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 28595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 28625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_mkpdu_sanity_check - 28635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * sanity check specified in clause 11.11.2 of IEEE802.1X-2010 28645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 28655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay, 28665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *buf, size_t len) 28675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 28685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee8023_hdr *eth_hdr; 28695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_hdr *eapol_hdr; 28705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *mka_hdr; 28715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_basic_body *body; 28725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t mka_msg_len; 28735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 28745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 28755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 icv[MAX_ICV_LEN]; 28765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *msg_icv; 28775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eth_hdr = (struct ieee8023_hdr *) buf; 28795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1); 28805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mka_hdr = (struct ieee802_1x_mka_hdr *) (eapol_hdr + 1); 28815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* destination address should be not individual address */ 28835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(eth_hdr->dest, pae_group_addr, ETH_ALEN) != 0) { 28845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_MSGDUMP, 28855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: ethernet destination address is not PAE group address"); 28865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 28875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 28885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 28895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* MKPDU should not less than 32 octets */ 28905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mka_msg_len = be_to_host16(eapol_hdr->length); 28915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mka_msg_len < 32) { 28925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_MSGDUMP, "KaY: MKPDU is less than 32 octets"); 28935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 28945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 28955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* MKPDU should multiple 4 octets */ 28965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if ((mka_msg_len % 4) != 0) { 28975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_MSGDUMP, 28985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKPDU is not multiple of 4 octets"); 28995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body = (struct ieee802_1x_mka_basic_body *) mka_hdr; 29035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_mka_dump_basic_body(body); 29045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(body); 29055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* EAPOL-MKA body should comprise basic parameter set and ICV */ 29065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) { 29075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 29085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Received EAPOL-MKA Packet Body Length (%d bytes) is less than the Basic Parameter Set Header Length (%d bytes) + the Basic Parameter Set Body Length (%d bytes) + %d bytes of ICV", 29095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) mka_msg_len, (int) MKA_HDR_LEN, 29105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len, DEFAULT_ICV_LEN); 29115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* CKN should be owned by I */ 29155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_kay_get_participant(kay, body->ckn); 29165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) { 29175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "CKN is not included in my CA"); 29185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* algorithm agility check */ 29225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (os_memcmp(body->algo_agility, mka_algo_agility, 29235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(body->algo_agility)) != 0) { 29245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 29255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: peer's algorithm agility not supported for me"); 29265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* ICV check */ 29305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* 29315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * The ICV will comprise the final octets of the packet body, whatever 29325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * its size, not the fixed length 16 octets, indicated by the EAPOL 29335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * packet body length. 29345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 29355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mka_alg_tbl[kay->mka_algindex].icv_hash( 29365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ick.key, 29375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt buf, len - mka_alg_tbl[kay->mka_algindex].icv_len, icv)) { 29385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: omac1_aes_128 failed"); 29395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt msg_icv = ieee802_1x_mka_decode_icv_body(participant, (u8 *) mka_hdr, 29425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mka_msg_len); 29435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (msg_icv) { 2945c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (os_memcmp_const(msg_icv, icv, 2946c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt mka_alg_tbl[kay->mka_algindex].icv_len) != 2947c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 0) { 29485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 29495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Computed ICV is not equal to Received ICV"); 29505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 29535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: No ICV"); 29545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 29565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 29585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 29595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 29625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_decode_mkpdu - 29635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 29645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay, 29655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *buf, size_t len) 29665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 29675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 29685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_hdr *hdr; 29695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t body_len; 29705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t left_len; 29715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int body_type; 29725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int i; 29735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *pos; 29745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean my_included; 29755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean handled[256]; 29765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len)) 29785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* handle basic parameter set */ 29815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos = buf + sizeof(struct ieee8023_hdr) + sizeof(struct ieee802_1x_hdr); 29825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len = len - sizeof(struct ieee8023_hdr) - 29835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(struct ieee802_1x_hdr); 29845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_mka_decode_basic_body(kay, pos, left_len); 29855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) 29865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 29875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* to skip basic parameter set */ 29895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) pos; 29905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 29915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos += body_len + MKA_HDR_LEN; 29925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len -= body_len + MKA_HDR_LEN; 29935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 29945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* check i am in the peer's peer list */ 29955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt my_included = ieee802_1x_mka_i_in_peerlist(participant, pos, left_len); 29965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (my_included) { 29975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* accept the peer as live peer */ 29985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!ieee802_1x_kay_is_in_peer( 29995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, 30005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mi)) { 30015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!ieee802_1x_kay_create_live_peer( 30025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, 30035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mi, 30045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mn)) 30055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 30065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_elect_key_server(participant); 30075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_decide_macsec_use(participant); 30085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (ieee802_1x_kay_is_in_potential_peer( 30105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, participant->current_peer_id.mi)) { 30115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_move_live_peer( 30125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, participant->current_peer_id.mi, 30135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->current_peer_id.mn); 30145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_elect_key_server(participant); 30155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_decide_macsec_use(participant); 30165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* 30205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Handle other parameter set than basic parameter set. 30215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Each parameter set should be present only once. 30225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 30235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt for (i = 0; i < 256; i++) 30245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt handled[i] = FALSE; 30255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt handled[0] = TRUE; 30275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (left_len > MKA_HDR_LEN + DEFAULT_ICV_LEN) { 30285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt hdr = (struct ieee802_1x_mka_hdr *) pos; 30295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_len = get_mka_param_body_len(hdr); 30305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_type = get_mka_param_body_type(hdr); 30315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (body_type == MKA_ICV_INDICATOR) 30335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 30345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) { 30365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 30375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: MKA Peer Packet Body Length (%d bytes) is less than the Parameter Set Header Length (%d bytes) + the Parameter Set Body Length (%d bytes) + %d bytes of ICV", 30385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) left_len, (int) MKA_HDR_LEN, 30395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (int) body_len, DEFAULT_ICV_LEN); 30405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto next_para_set; 30415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (handled[body_type]) 30445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto next_para_set; 30455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt handled[body_type] = TRUE; 30475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mak_body_handler[body_type].body_rx) { 30485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt mak_body_handler[body_type].body_rx 30495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (participant, pos, left_len); 30505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 30515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 30525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "The type %d not supported in this MKA version %d", 30535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt body_type, MKA_VERSION_ID); 30545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtnext_para_set: 30575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt pos += body_len + MKA_HDR_LEN; 30585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt left_len -= body_len + MKA_HDR_LEN; 30595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->active = TRUE; 30625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->retry_count = 0; 30635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->active = TRUE; 30645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 30665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 30675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, 30715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t len) 30725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 30735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay = ctx; 30745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee8023_hdr *eth_hdr; 30755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_hdr *eapol_hdr; 30765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* must contain at least ieee8023_hdr + ieee802_1x_hdr */ 30785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (len < sizeof(*eth_hdr) + sizeof(*eapol_hdr)) { 30795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_MSGDUMP, "KaY: EAPOL frame too short (%lu)", 30805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (unsigned long) len); 30815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 30825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eth_hdr = (struct ieee8023_hdr *) buf; 30855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr = (struct ieee802_1x_hdr *) (eth_hdr + 1); 30865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (len != sizeof(*eth_hdr) + sizeof(*eapol_hdr) + 30875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ntohs(eapol_hdr->length)) { 30885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_MSGDUMP, "KAY: EAPOL MPDU is invalid: (%lu-%lu)", 30895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (unsigned long) len, 30905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt (unsigned long) ntohs(eapol_hdr->length)); 30915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 30925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 30945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (eapol_hdr->version < EAPOL_VERSION) { 30955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_MSGDUMP, "KaY: version %d does not support MKA", 30965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr->version); 30975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 30985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 30995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (ntohs(eth_hdr->ethertype) != ETH_P_PAE || 31005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_hdr->type != IEEE802_1X_TYPE_EAPOL_MKA) 31015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 31025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "RX EAPOL-MKA: ", buf, len); 31045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (dl_list_empty(&kay->participant_list)) { 31055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: no MKA participant instance"); 31065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 31075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 31085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_decode_mkpdu(kay, buf, len); 31105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 31115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 31145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_init - 31155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 31165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_kay * 31175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, 31185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const char *ifname, const u8 *addr) 31195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 31205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay *kay; 31215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay = os_zalloc(sizeof(*kay)); 31235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay) { 31245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 31255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 31265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 31275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->ctx = ctx; 31295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->enable = TRUE; 31315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->active = FALSE; 31325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->authenticated = FALSE; 31345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->secured = FALSE; 31355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->failed = FALSE; 31365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->policy = policy; 31375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_strlcpy(kay->if_name, ifname, IFNAMSIZ); 31395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN); 31405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->actor_sci.port = 0x0001; 31415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->actor_priority = DEFAULT_PRIO_NOT_KEY_SERVER; 31425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* While actor acts as a key server, shall distribute sakey */ 31445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->dist_kn = 1; 31455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->dist_an = 0; 31465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->dist_time = 0; 31475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->pn_exhaustion = PENDING_PN_EXHAUSTION; 31495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_csindex = DEFAULT_CS_INDEX; 31505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->mka_algindex = DEFAULT_MKA_ALG_INDEX; 31515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->mka_version = MKA_VERSION_ID; 31525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(kay->algo_agility, mka_algo_agility, 31545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->algo_agility)); 31555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&kay->participant_list); 31575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (policy == DO_NOT_SECURE) { 31595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED; 31605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_desired = FALSE; 31615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_protect = FALSE; 31625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_validate = FALSE; 31635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_replay_protect = FALSE; 31645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_replay_window = 0; 31655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_confidentiality = CONFIDENTIALITY_NONE; 31665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 31675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50; 31685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_desired = TRUE; 31695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_protect = TRUE; 31705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_validate = TRUE; 31715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_replay_protect = FALSE; 31725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_replay_window = 0; 31735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0; 31745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 31755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: state machine created"); 31775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* Initialize the SecY must be prio to CP, as CP will control SecY */ 31795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_init_macsec(kay); 31805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_get_available_transmit_sc(kay, &kay->sc_ch); 31815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: secy init macsec done"); 31835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* init CP */ 31855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->cp = ieee802_1x_kay_alloc_cp_sm(kay); 31865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->cp == NULL) { 31875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit(kay); 31885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 31895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 31905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 31915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (policy == DO_NOT_SECURE) { 31925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_connect_authenticated(kay->cp); 31935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_step(kay->cp); 31945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 31955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->l2_mka = l2_packet_init(kay->if_name, NULL, ETH_P_PAE, 31965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay_l2_receive, kay, 1); 31975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->l2_mka == NULL) { 31985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_WARNING, 31995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Failed to initialize L2 packet processing for MKA packet"); 32005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit(kay); 32015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 32025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return kay; 32065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 32075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 32105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_deinit - 32115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 32125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid 32135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_deinit(struct ieee802_1x_kay *kay) 32145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 32155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 32165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay) 32185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 32195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: state machine removed"); 32215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (!dl_list_empty(&kay->participant_list)) { 32235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = dl_list_entry(kay->participant_list.next, 32245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant, 32255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt list); 32265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_delete_mka(kay, &participant->ckn); 32275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_cp_sm_deinit(kay->cp); 32305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_deinit_macsec(kay); 32315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->l2_mka) { 32335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt l2_packet_deinit(kay->l2_mka); 32345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->l2_mka = NULL; 32355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(kay->ctx); 32385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(kay); 32395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 32405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 32435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_create_mka - 32445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 32455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_mka_participant * 32465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn, 32475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct mka_key *cak, u32 life, 32485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt enum mka_created_mode mode, Boolean is_authenticator) 32495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 32505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 32515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt unsigned int usecs; 32525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay || !ckn || !cak) { 32545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: ckn or cak is null"); 32555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 32565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (cak->len != mka_alg_tbl[kay->mka_algindex].cak_len) { 32595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: CAK length not follow key schema"); 32605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 32615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (ckn->len > MAX_CKN_LEN) { 32635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: CKN is out of range(<=32 bytes)"); 32645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 32655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay->enable) { 32675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: Now is at disable state"); 32685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 32695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = os_zalloc(sizeof(*participant)); 32725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) { 32735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); 32745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 32755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 32765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ckn.len = ckn->len; 32785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(participant->ckn.name, ckn->name, ckn->len); 32795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->cak.len = cak->len; 32805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(participant->cak.key, cak->key, cak->len); 32815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (life) 32825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->cak_life = life + time(NULL); 32835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt switch (mode) { 32855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt case EAP_EXCHANGE: 32865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (is_authenticator) { 32875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_obliged_key_server = TRUE; 32885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->can_be_key_server = TRUE; 32895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_key_server = TRUE; 32905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->principal = TRUE; 32915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 32925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(&kay->key_server_sci, &kay->actor_sci, 32935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sizeof(kay->key_server_sci)); 32945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->key_server_priority = kay->actor_priority; 32955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_elected = TRUE; 32965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 32975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_obliged_key_server = FALSE; 32985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->can_be_key_server = FALSE; 32995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_key_server = FALSE; 33005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_elected = TRUE; 33015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 33025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 33035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt default: 33055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_obliged_key_server = FALSE; 33065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->can_be_key_server = TRUE; 33075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_key_server = FALSE; 33085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->is_elected = FALSE; 33095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 33105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 33115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->cached = FALSE; 33135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->active = FALSE; 33155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->participant = FALSE; 33165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->retain = FALSE; 33175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->activate = DEFAULT; 33185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant->is_key_server) 33205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->principal = TRUE; 33215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&participant->live_peers); 33235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&participant->potential_peers); 33245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->retry_count = 0; 33265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kay = kay; 33275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_get_random(participant->mi, sizeof(participant->mi)); 33295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mn = 0; 33305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->lrx = FALSE; 33325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ltx = FALSE; 33335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->orx = FALSE; 33345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->otx = FALSE; 33355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_dist_sak = FALSE; 33365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->to_use_sak = FALSE; 33375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = FALSE; 33385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&participant->sak_list); 33395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_key = NULL; 33405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_init(&participant->rxsc_list); 33415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci, 33425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->sc_ch); 33435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_create_transmit_sc(kay, participant->txsc); 33445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* to derive KEK from CAK and CKN */ 33465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kek.len = mka_alg_tbl[kay->mka_algindex].kek_len; 33475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mka_alg_tbl[kay->mka_algindex].kek_trfm(participant->cak.key, 33485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ckn.name, 33495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ckn.len, 33505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kek.key)) { 33515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: Derived KEK failed"); 33525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto fail; 33535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 33545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "KaY: Derived KEK", 33555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->kek.key, participant->kek.len); 33565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* to derive ICK from CAK and CKN */ 33585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ick.len = mka_alg_tbl[kay->mka_algindex].ick_len; 33595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (mka_alg_tbl[kay->mka_algindex].ick_trfm(participant->cak.key, 33605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ckn.name, 33615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ckn.len, 33625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ick.key)) { 33635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, "KaY: Derived ICK failed"); 33645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto fail; 33655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 33665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "KaY: Derived ICK", 33675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->ick.key, participant->ick.len); 33685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_add(&kay->participant_list, &participant->list); 33705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "KaY: Participant created:", 33715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ckn->name, ckn->len); 33725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt usecs = os_random() % (MKA_HELLO_TIME * 1000); 33745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eloop_register_timeout(0, usecs, ieee802_1x_participant_timer, 33755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant, NULL); 33765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) + 33775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt usecs / 1000000; 33785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return participant; 33805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtfail: 33825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(participant); 33835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return NULL; 33845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 33855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 33885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_delete_mka - 33895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 33905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid 33915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn) 33925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 33935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 33945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer *peer; 33955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key *sak; 33965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc *rxsc; 33975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 33985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay || !ckn) 33995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 34005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: participant removed"); 34025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* get the participant */ 34045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_kay_get_participant(kay, ckn->name); 34055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) { 34065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "KaY: participant is not found", 34075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ckn->name, ckn->len); 34085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 34095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 34105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&participant->list); 34125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* remove live peer */ 34145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (!dl_list_empty(&participant->live_peers)) { 34155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = dl_list_entry(participant->live_peers.next, 34165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list); 34175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&peer->list); 34185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(peer); 34195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 34205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* remove potential peer */ 34225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (!dl_list_empty(&participant->potential_peers)) { 34235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt peer = dl_list_entry(participant->potential_peers.next, 34245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_kay_peer, list); 34255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&peer->list); 34265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(peer); 34275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 34285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt /* remove sak */ 34305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (!dl_list_empty(&participant->sak_list)) { 34315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sak = dl_list_entry(participant->sak_list.next, 34325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct data_key, list); 34335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt dl_list_del(&sak->list); 34345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(sak->key); 34355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(sak); 34365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 34375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt while (!dl_list_empty(&participant->rxsc_list)) { 34385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt rxsc = dl_list_entry(participant->rxsc_list.next, 34395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct receive_sc, list); 34405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_delete_receive_sc(kay, rxsc); 34415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_receive_sc(participant, rxsc); 34425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 34435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt secy_delete_transmit_sc(kay, participant->txsc); 34445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt ieee802_1x_kay_deinit_transmit_sc(participant, participant->txsc); 34455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memset(&participant->cak, 0, sizeof(participant->cak)); 34475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memset(&participant->kek, 0, sizeof(participant->kek)); 34485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memset(&participant->ick, 0, sizeof(participant->ick)); 34495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_free(participant); 34505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 34515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 34545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_mka_participate - 34555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 34565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay, 34575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct mka_key_name *ckn, 34585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Boolean status) 34595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 34605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 34615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay || !ckn) 34635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 34645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_kay_get_participant(kay, ckn->name); 34665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) 34675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return; 34685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->active = status; 34705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 34715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 34745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_new_sak - 34755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 34765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint 34775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay) 34785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 34795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 34805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay) 34825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 34835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_kay_get_principal_participant(kay); 34855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!participant) 34865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 34875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = TRUE; 34895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_DEBUG, "KaY: new SAK signal"); 34905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 34925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 34935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 34955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/** 34965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_kay_change_cipher_suite - 34975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */ 34985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint 34995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, int cs_index) 35005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{ 35015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt struct ieee802_1x_mka_participant *participant; 35025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 35035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!kay) 35045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 35055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 35065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if ((unsigned int) cs_index >= CS_TABLE_SIZE) { 35075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_ERROR, 35085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "KaY: Configured cipher suite index is out of range"); 35095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -1; 35105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 35115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (kay->macsec_csindex == cs_index) 35125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return -2; 35135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 35145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (cs_index == 0) 35155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_desired = FALSE; 35165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 35175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_csindex = cs_index; 35185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable; 35195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 35205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant = ieee802_1x_kay_get_principal_participant(kay); 35215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (participant) { 35225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "KaY: Cipher Suite changed"); 35235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt participant->new_sak = TRUE; 35245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 35255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 35265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return 0; 35275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt} 3528