diff mbox

[1/6] mka: some cleanups

Message ID 05d47fdaedfcceab692c4326a287b53197b1a5b1.1470913867.git.sd@queasysnail.net
State Accepted
Headers show

Commit Message

Sabrina Dubroca Aug. 15, 2016, 9:43 a.m. UTC
This patch contains a number of cleanups for the KaY code:
 - use less bitfields in the 802.1X-2010 structs
 - fix a few typos
 - refactor the get_*_peer functions
 - add some helper functions (sci comparison, peer dumping and creation)
 - clean up cipher_suite lookup function
 - move kay_ops struct out of ieee802_1x_alloc_kay_sm

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
---
 src/pae/ieee802_1x_kay.c   | 174 +++++++++++++++++++++++----------------------
 src/pae/ieee802_1x_kay_i.h | 138 +++++++++++++++++------------------
 wpa_supplicant/wpas_kay.c  |  49 +++++++------
 3 files changed, 185 insertions(+), 176 deletions(-)
diff mbox

Patch

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index dfc58707eae7..65c3eff9a009 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -122,7 +122,7 @@  ieee802_1x_mka_dump_basic_body(struct ieee802_1x_mka_basic_body *body)
 	wpa_printf(MSG_DEBUG, "\tPriority......: %d", body->priority);
 	wpa_printf(MSG_DEBUG, "\tKeySvr........: %d", body->key_server);
 	wpa_printf(MSG_DEBUG, "\tMACSecDesired.: %d", body->macsec_desired);
-	wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capbility);
+	wpa_printf(MSG_DEBUG, "\tMACSecCapable.: %d", body->macsec_capability);
 	wpa_printf(MSG_DEBUG, "\tBody Length...: %d", (int) body_len);
 	wpa_printf(MSG_DEBUG, "\tSCI MAC.......: " MACSTR,
 		   MAC2STR(body->actor_sci.addr));
@@ -300,13 +300,35 @@  static struct ieee802_1x_kay_peer * get_peer_mi(struct dl_list *peers,
 
 
 /**
+ * ieee802_1x_kay_get_potential_peer
+ */
+static struct ieee802_1x_kay_peer *
+ieee802_1x_kay_get_potential_peer(struct ieee802_1x_mka_participant *participant,
+			     const u8 *mi)
+{
+	return get_peer_mi(&participant->potential_peers, mi);
+}
+
+
+/**
+ * ieee802_1x_kay_get_live_peer
+ */
+static struct ieee802_1x_kay_peer *
+ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant,
+			     const u8 *mi)
+{
+	return get_peer_mi(&participant->live_peers, mi);
+}
+
+
+/**
  * ieee802_1x_kay_is_in_potential_peer
  */
 static Boolean
 ieee802_1x_kay_is_in_potential_peer(
 	struct ieee802_1x_mka_participant *participant, const u8 *mi)
 {
-	return get_peer_mi(&participant->potential_peers, mi) != NULL;
+	return ieee802_1x_kay_get_potential_peer(participant, mi) != NULL;
 }
 
 
@@ -317,7 +339,7 @@  static Boolean
 ieee802_1x_kay_is_in_live_peer(
 	struct ieee802_1x_mka_participant *participant, const u8 *mi)
 {
-	return get_peer_mi(&participant->live_peers, mi) != NULL;
+	return ieee802_1x_kay_get_live_peer(participant, mi) != NULL;
 }
 
 
@@ -342,22 +364,11 @@  ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant,
 {
 	struct ieee802_1x_kay_peer *peer;
 
-	peer = get_peer_mi(&participant->live_peers, mi);
+	peer = ieee802_1x_kay_get_live_peer(participant, mi);
 	if (peer)
 		return peer;
 
-	return get_peer_mi(&participant->potential_peers, mi);
-}
-
-
-/**
- * ieee802_1x_kay_get_live_peer
- */
-static struct ieee802_1x_kay_peer *
-ieee802_1x_kay_get_live_peer(struct ieee802_1x_mka_participant *participant,
-			     const u8 *mi)
-{
-	return get_peer_mi(&participant->live_peers, mi);
+	return ieee802_1x_kay_get_potential_peer(participant, mi);
 }
 
 
@@ -372,15 +383,18 @@  ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant,
 
 	for (i = 0; i < CS_TABLE_SIZE; i++) {
 		if (os_memcmp(cipher_suite_tbl[i].id, cs_id, CS_ID_LEN) == 0)
-			break;
+			return &cipher_suite_tbl[i];
 	}
-	if (i >= CS_TABLE_SIZE)
-		return NULL;
 
-	return &cipher_suite_tbl[i];
+	return NULL;
 }
 
 
+static Boolean sci_equal(const struct ieee802_1x_mka_sci *a, const struct ieee802_1x_mka_sci *b)
+{
+	return !os_memcmp(a, b, sizeof(a));
+}
+
 /**
  * ieee802_1x_kay_get_peer_sci
  */
@@ -392,13 +406,13 @@  ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant,
 
 	dl_list_for_each(peer, &participant->live_peers,
 			 struct ieee802_1x_kay_peer, list) {
-		if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0)
+		if (sci_equal(&peer->sci, sci))
 			return peer;
 	}
 
 	dl_list_for_each(peer, &participant->potential_peers,
 			 struct ieee802_1x_kay_peer, list) {
-		if (os_memcmp(&peer->sci, sci, sizeof(peer->sci)) == 0)
+		if (sci_equal(&peer->sci, sci))
 			return peer;
 	}
 
@@ -509,6 +523,30 @@  ieee802_1x_kay_deinit_receive_sc(
 }
 
 
+static void ieee802_1x_kay_dump_peer(struct ieee802_1x_kay_peer *peer)
+{
+	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
+	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
+	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
+	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+}
+
+static struct ieee802_1x_kay_peer *ieee802_1x_kay_create_peer(const u8 *mi, u32 mn)
+{
+	struct ieee802_1x_kay_peer *peer = os_zalloc(sizeof(*peer));
+	if (peer == NULL) {
+		wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
+		return NULL;
+	}
+
+	os_memcpy(peer->mi, mi, MI_LEN);
+	peer->mn = mn;
+	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
+	peer->sak_used = FALSE;
+
+	return peer;
+}
+
 /**
  * ieee802_1x_kay_create_live_peer
  */
@@ -520,21 +558,14 @@  ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant,
 	struct receive_sc *rxsc;
 	u32 sc_ch = 0;
 
-	peer = os_zalloc(sizeof(*peer));
-	if (peer == NULL) {
-		wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
-		return NULL;
-	}
+	peer = ieee802_1x_kay_create_peer(mi, mn);
 
-	os_memcpy(peer->mi, mi, MI_LEN);
-	peer->mn = mn;
-	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
-	peer->sak_used = FALSE;
 	os_memcpy(&peer->sci, &participant->current_peer_sci,
 		  sizeof(peer->sci));
 
 	secy_get_available_receive_sc(participant->kay, &sc_ch);
 
+
 	rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch);
 	if (!rxsc) {
 		os_free(peer);
@@ -546,10 +577,7 @@  ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant,
 	secy_create_receive_sc(participant->kay, rxsc);
 
 	wpa_printf(MSG_DEBUG, "KaY: Live peer created");
-	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
-	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
-	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
-	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+	ieee802_1x_kay_dump_peer(peer);
 
 	return peer;
 }
@@ -562,26 +590,15 @@  static struct ieee802_1x_kay_peer *
 ieee802_1x_kay_create_potential_peer(
 	struct ieee802_1x_mka_participant *participant, const u8 *mi, u32 mn)
 {
-	struct ieee802_1x_kay_peer *peer;
+	struct ieee802_1x_kay_peer *peer = ieee802_1x_kay_create_peer(mi, mn);
 
-	peer = os_zalloc(sizeof(*peer));
-	if (peer == NULL) {
-		wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__);
+	if (!peer)
 		return NULL;
-	}
-
-	os_memcpy(peer->mi, mi, MI_LEN);
-	peer->mn = mn;
-	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
-	peer->sak_used = FALSE;
 
 	dl_list_add(&participant->potential_peers, &peer->list);
 
 	wpa_printf(MSG_DEBUG, "KaY: potential peer created");
-	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
-	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
-	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
-	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+	ieee802_1x_kay_dump_peer(peer);
 
 	return peer;
 }
@@ -598,11 +615,7 @@  ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant,
 	struct receive_sc *rxsc;
 	u32 sc_ch = 0;
 
-	dl_list_for_each(peer, &participant->potential_peers,
-			 struct ieee802_1x_kay_peer, list) {
-		if (os_memcmp(peer->mi, mi, MI_LEN) == 0)
-			break;
-	}
+	peer = ieee802_1x_kay_get_potential_peer(participant, mi);
 
 	rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci,
 					      sc_ch);
@@ -615,10 +628,7 @@  ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant,
 	peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
 
 	wpa_printf(MSG_DEBUG, "KaY: move potential peer to live peer");
-	wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi, sizeof(peer->mi));
-	wpa_printf(MSG_DEBUG, "\tMN: %d", peer->mn);
-	wpa_hexdump(MSG_DEBUG, "\tSCI Addr: ", peer->sci.addr, ETH_ALEN);
-	wpa_printf(MSG_DEBUG, "\tPort: %d", peer->sci.port);
+	ieee802_1x_kay_dump_peer(peer);
 
 	dl_list_del(&peer->list);
 	dl_list_add_tail(&participant->live_peers, &peer->list);
@@ -680,7 +690,7 @@  ieee802_1x_mka_encode_basic_body(
 		body->key_server = participant->can_be_key_server;
 
 	body->macsec_desired = kay->macsec_desired;
-	body->macsec_capbility = kay->macsec_capable;
+	body->macsec_capability = kay->macsec_capable;
 	set_mka_param_body_len(body, length - MKA_HDR_LEN);
 
 	os_memcpy(body->actor_sci.addr, kay->actor_sci.addr,
@@ -766,14 +776,14 @@  ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
 			return NULL;
 
 		peer->macsec_desired = body->macsec_desired;
-		peer->macsec_capbility = body->macsec_capbility;
+		peer->macsec_capability = body->macsec_capability;
 		peer->is_key_server = (Boolean) body->key_server;
 		peer->key_server_priority = body->priority;
 	} else if (peer->mn < be_to_host32(body->actor_mn)) {
 		peer->mn = be_to_host32(body->actor_mn);
 		peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
 		peer->macsec_desired = body->macsec_desired;
-		peer->macsec_capbility = body->macsec_capbility;
+		peer->macsec_capability = body->macsec_capability;
 		peer->is_key_server = (Boolean) body->key_server;
 		peer->key_server_priority = body->priority;
 	} else {
@@ -1581,8 +1591,7 @@  ieee802_1x_mka_decode_dist_sak_body(
 			   "KaY: The key server is not in my live peers list");
 		return -1;
 	}
-	if (os_memcmp(&participant->kay->key_server_sci,
-		      &peer->sci, sizeof(struct ieee802_1x_mka_sci)) != 0) {
+	if (!sci_equal(&participant->kay->key_server_sci, &peer->sci)) {
 		wpa_printf(MSG_ERROR, "KaY: The key server is not elected");
 		return -1;
 	}
@@ -1865,7 +1874,7 @@  static int ieee802_1x_mka_decode_announce_body(
 }
 
 
-static struct mka_param_body_handler mak_body_handler[] = {
+static struct mka_param_body_handler mka_body_handler[] = {
 	/* basic parameter set */
 	{
 		ieee802_1x_mka_encode_basic_body,
@@ -2160,8 +2169,7 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 
 	if (i_is_key_server) {
 		ieee802_1x_cp_set_electedself(kay->cp, TRUE);
-		if (os_memcmp(&kay->key_server_sci, &kay->actor_sci,
-			      sizeof(kay->key_server_sci))) {
+		if (!sci_equal(&kay->key_server_sci, &kay->actor_sci)) {
 			ieee802_1x_cp_signal_chgdserver(kay->cp);
 			ieee802_1x_cp_sm_step(kay->cp);
 		}
@@ -2178,8 +2186,7 @@  ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
 		kay->key_server_priority = kay->actor_priority;
 	} else if (key_server) {
 		ieee802_1x_cp_set_electedself(kay->cp, FALSE);
-		if (os_memcmp(&kay->key_server_sci, &key_server->sci,
-			      sizeof(kay->key_server_sci))) {
+		if (!sci_equal(&kay->key_server_sci, &key_server->sci)) {
 			ieee802_1x_cp_signal_chgdserver(kay->cp);
 			ieee802_1x_cp_sm_step(kay->cp);
 		}
@@ -2237,11 +2244,11 @@  ieee802_1x_kay_decide_macsec_use(
 		if (!peer->macsec_desired)
 			continue;
 
-		if (peer->macsec_capbility == MACSEC_CAP_NOT_IMPLEMENTED)
+		if (peer->macsec_capability == MACSEC_CAP_NOT_IMPLEMENTED)
 			continue;
 
-		less_capability = (less_capability < peer->macsec_capbility) ?
-			less_capability : peer->macsec_capbility;
+		less_capability = (less_capability < peer->macsec_capability) ?
+			less_capability : peer->macsec_capability;
 		has_peer = TRUE;
 	}
 
@@ -2302,10 +2309,10 @@  ieee802_1x_kay_encode_mkpdu(struct ieee802_1x_mka_participant *participant,
 	eapol_hdr->type = IEEE802_1X_TYPE_EAPOL_MKA;
 	eapol_hdr->length = host_to_be16(pbuf->size - pbuf->used);
 
-	for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) {
-		if (mak_body_handler[i].body_present &&
-		    mak_body_handler[i].body_present(participant)) {
-			if (mak_body_handler[i].body_tx(participant, pbuf))
+	for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
+		if (mka_body_handler[i].body_present &&
+		    mka_body_handler[i].body_present(participant)) {
+			if (mka_body_handler[i].body_tx(participant, pbuf))
 				return -1;
 		}
 	}
@@ -2327,10 +2334,10 @@  ieee802_1x_participant_send_mkpdu(
 
 	wpa_printf(MSG_DEBUG, "KaY: to enpacket and send the MKPDU");
 	length += sizeof(struct ieee802_1x_hdr) + sizeof(struct ieee8023_hdr);
-	for (i = 0; i < ARRAY_SIZE(mak_body_handler); i++) {
-		if (mak_body_handler[i].body_present &&
-		    mak_body_handler[i].body_present(participant))
-			length += mak_body_handler[i].body_length(participant);
+	for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
+		if (mka_body_handler[i].body_present &&
+		    mka_body_handler[i].body_present(participant))
+			length += mka_body_handler[i].body_length(participant);
 	}
 
 	buf = wpabuf_alloc(length);
@@ -2408,8 +2415,7 @@  static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
 			dl_list_for_each_safe(rxsc, pre_rxsc,
 					      &participant->rxsc_list,
 					      struct receive_sc, list) {
-				if (os_memcmp(&rxsc->sci, &peer->sci,
-					      sizeof(rxsc->sci)) == 0) {
+				if (sci_equal(&rxsc->sci, &peer->sci)) {
 					secy_delete_receive_sc(kay, rxsc);
 					ieee802_1x_kay_deinit_receive_sc(
 						participant, rxsc);
@@ -3069,9 +3075,9 @@  static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
 			goto next_para_set;
 
 		handled[body_type] = TRUE;
-		if (body_type < ARRAY_SIZE(mak_body_handler) &&
-		    mak_body_handler[body_type].body_rx) {
-			mak_body_handler[body_type].body_rx
+		if (body_type < ARRAY_SIZE(mka_body_handler) &&
+		    mka_body_handler[body_type].body_rx) {
+			mka_body_handler[body_type].body_rx
 				(participant, pos, left_len);
 		} else {
 			wpa_printf(MSG_ERROR,
diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
index 72c7d0bb8590..558bad9f4795 100644
--- a/src/pae/ieee802_1x_kay_i.h
+++ b/src/pae/ieee802_1x_kay_i.h
@@ -49,7 +49,7 @@  struct ieee802_1x_kay_peer {
 	Boolean is_key_server;
 	u8 key_server_priority;
 	Boolean macsec_desired;
-	enum macsec_cap macsec_capbility;
+	enum macsec_cap macsec_capability;
 	Boolean sak_used;
 	struct dl_list list;
 };
@@ -241,44 +241,44 @@  struct ieee802_1x_mka_participant {
 
 struct ieee802_1x_mka_hdr {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
-	u32 reserve:8;
+	u8 reserve;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #else
 #error "Please fix <bits/endian.h>"
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 };
 
 #define MKA_HDR_LEN sizeof(struct ieee802_1x_mka_hdr)
 
 struct ieee802_1x_mka_basic_body {
 	/* octet 1 */
-	u32 version:8;
+	u8 version;
 	/* octet 2 */
-	u32 priority:8;
+	u8 priority;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 macsec_capbility:2;
-	u32 macsec_desired:1;
-	u32 key_server:1;
+	u8 length:4;
+	u8 macsec_capability:2;
+	u8 macsec_desired:1;
+	u8 key_server:1;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 key_server:1;
-	u32 macsec_desired:1;
-	u32 macsec_capbility:2;
-	u32 length:4;
+	u8 key_server:1;
+	u8 macsec_desired:1;
+	u8 macsec_capability:2;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	struct ieee802_1x_mka_sci actor_sci;
 	u8 actor_mi[MI_LEN];
@@ -291,19 +291,19 @@  struct ieee802_1x_mka_basic_body {
 
 struct ieee802_1x_mka_peer_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
-	u32 reserve:8;
+	u8 reserve;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	u8 peer[0];
 	/* followed by Peers */
@@ -311,41 +311,41 @@  struct ieee802_1x_mka_peer_body {
 
 struct ieee802_1x_mka_sak_use_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 orx:1;
-	u32 otx:1;
-	u32 oan:2;
-	u32 lrx:1;
-	u32 ltx:1;
-	u32 lan:2;
+	u8 orx:1;
+	u8 otx:1;
+	u8 oan:2;
+	u8 lrx:1;
+	u8 ltx:1;
+	u8 lan:2;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 lan:2;
-	u32 ltx:1;
-	u32 lrx:1;
-	u32 oan:2;
-	u32 otx:1;
-	u32 orx:1;
+	u8 lan:2;
+	u8 ltx:1;
+	u8 lrx:1;
+	u8 oan:2;
+	u8 otx:1;
+	u8 orx:1;
 #endif
 
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 delay_protect:1;
-	u32 reserve:1;
-	u32 prx:1;
-	u32 ptx:1;
+	u8 length:4;
+	u8 delay_protect:1;
+	u8 reserve:1;
+	u8 prx:1;
+	u8 ptx:1;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 ptx:1;
-	u32 prx:1;
-	u32 reserve:1;
-	u32 delay_protect:1;
-	u32 length:4;
+	u8 ptx:1;
+	u8 prx:1;
+	u8 reserve:1;
+	u8 delay_protect:1;
+	u8 length:4;
 #endif
 
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	/* octet 5 - 16 */
 	u8 lsrv_mi[MI_LEN];
@@ -365,27 +365,27 @@  struct ieee802_1x_mka_sak_use_body {
 
 struct ieee802_1x_mka_dist_sak_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 reserve:4;
-	u32 confid_offset:2;
-	u32 dan:2;
+	u8 reserve:4;
+	u8 confid_offset:2;
+	u8 dan:2;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 dan:2;
-	u32 confid_offset:2;
-	u32 reserve:4;
+	u8 dan:2;
+	u8 confid_offset:2;
+	u8 reserve:4;
 #endif
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 	/* octet 5 - 8 */
 	be32 kn;
 
@@ -398,19 +398,19 @@  struct ieee802_1x_mka_dist_sak_body {
 
 struct ieee802_1x_mka_icv_body {
 	/* octet 1 */
-	u32 type:8;
+	u8 type;
 	/* octet 2 */
-	u32 reserve:8;
+	u8 reserve;
 	/* octet 3 */
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-	u32 length:4;
-	u32 reserve1:4;
+	u8 length:4;
+	u8 reserve1:4;
 #elif __BYTE_ORDER == __BIG_ENDIAN
-	u32 reserve1:4;
-	u32 length:4;
+	u8 reserve1:4;
+	u8 length:4;
 #endif
 	/* octet 4 */
-	u32 length1:8;
+	u8 length1;
 
 	/* octet 5 - */
 	u8 icv[0];
diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c
index 0b876008d582..788710a94da2 100644
--- a/wpa_supplicant/wpas_kay.c
+++ b/wpa_supplicant/wpas_kay.c
@@ -184,6 +184,30 @@  static int wpas_disable_transmit_sa(void *wpa_s, u32 channel, u8 an)
 }
 
 
+static const struct ieee802_1x_kay_ctx kay_ops = {
+	.macsec_init			= wpas_macsec_init,
+	.macsec_deinit			= wpas_macsec_deinit,
+	.enable_protect_frames		= wpas_enable_protect_frames,
+	.set_replay_protect		= wpas_set_replay_protect,
+	.set_current_cipher_suite	= wpas_set_current_cipher_suite,
+	.enable_controlled_port		= wpas_enable_controlled_port,
+	.get_receive_lowest_pn		= wpas_get_receive_lowest_pn,
+	.get_transmit_next_pn		= wpas_get_transmit_next_pn,
+	.set_transmit_next_pn		= wpas_set_transmit_next_pn,
+	.get_available_receive_sc	= wpas_get_available_receive_sc,
+	.create_receive_sc		= wpas_create_receive_sc,
+	.delete_receive_sc		= wpas_delete_receive_sc,
+	.create_receive_sa		= wpas_create_receive_sa,
+	.enable_receive_sa		= wpas_enable_receive_sa,
+	.disable_receive_sa		= wpas_disable_receive_sa,
+	.get_available_transmit_sc	= wpas_get_available_transmit_sc,
+	.create_transmit_sc		= wpas_create_transmit_sc,
+	.delete_transmit_sc		= wpas_delete_transmit_sc,
+	.create_transmit_sa		= wpas_create_transmit_sa,
+	.enable_transmit_sa		= wpas_enable_transmit_sa,
+	.disable_transmit_sa		= wpas_disable_transmit_sa,
+};
+
 int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
 {
 	struct ieee802_1x_kay_ctx *kay_ctx;
@@ -197,34 +221,13 @@  int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
 
 	policy = ssid->macsec_policy == 1 ? SHOULD_SECURE : DO_NOT_SECURE;
 
-	kay_ctx = os_zalloc(sizeof(*kay_ctx));
+	kay_ctx = os_malloc(sizeof(*kay_ctx));
 	if (!kay_ctx)
 		return -1;
 
+	os_memcpy(kay_ctx, &kay_ops, sizeof(*kay_ctx));
 	kay_ctx->ctx = wpa_s;
 
-	kay_ctx->macsec_init = wpas_macsec_init;
-	kay_ctx->macsec_deinit = wpas_macsec_deinit;
-	kay_ctx->enable_protect_frames = wpas_enable_protect_frames;
-	kay_ctx->set_replay_protect = wpas_set_replay_protect;
-	kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite;
-	kay_ctx->enable_controlled_port = wpas_enable_controlled_port;
-	kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn;
-	kay_ctx->get_transmit_next_pn = wpas_get_transmit_next_pn;
-	kay_ctx->set_transmit_next_pn = wpas_set_transmit_next_pn;
-	kay_ctx->get_available_receive_sc = wpas_get_available_receive_sc;
-	kay_ctx->create_receive_sc = wpas_create_receive_sc;
-	kay_ctx->delete_receive_sc = wpas_delete_receive_sc;
-	kay_ctx->create_receive_sa = wpas_create_receive_sa;
-	kay_ctx->enable_receive_sa = wpas_enable_receive_sa;
-	kay_ctx->disable_receive_sa = wpas_disable_receive_sa;
-	kay_ctx->get_available_transmit_sc = wpas_get_available_transmit_sc;
-	kay_ctx->create_transmit_sc = wpas_create_transmit_sc;
-	kay_ctx->delete_transmit_sc = wpas_delete_transmit_sc;
-	kay_ctx->create_transmit_sa = wpas_create_transmit_sa;
-	kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa;
-	kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa;
-
 	res = ieee802_1x_kay_init(kay_ctx, policy, wpa_s->ifname,
 				  wpa_s->own_addr);
 	if (res == NULL) {