netdev: refactored code to prep for AP code

Added several helpers for code that will be reused by AP
This commit is contained in:
James Prestwood 2018-06-20 11:05:13 -07:00 committed by Denis Kenzior
parent d76cf840ed
commit b059a699ab
1 changed files with 68 additions and 81 deletions

View File

@ -954,7 +954,8 @@ done:
netdev_connect_ok(netdev); netdev_connect_ok(netdev);
} }
static struct l_genl_msg *netdev_build_cmd_set_station(struct netdev *netdev) static struct l_genl_msg *netdev_build_cmd_set_station(struct netdev *netdev,
const uint8_t *sta)
{ {
struct l_genl_msg *msg; struct l_genl_msg *msg;
struct nl80211_sta_flag_update flags; struct nl80211_sta_flag_update flags;
@ -965,8 +966,7 @@ static struct l_genl_msg *netdev_build_cmd_set_station(struct netdev *netdev)
msg = l_genl_msg_new_sized(NL80211_CMD_SET_STATION, 512); msg = l_genl_msg_new_sized(NL80211_CMD_SET_STATION, 512);
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index); l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, sta);
netdev->handshake->aa);
l_genl_msg_append_attr(msg, NL80211_ATTR_STA_FLAGS2, l_genl_msg_append_attr(msg, NL80211_ATTR_STA_FLAGS2,
sizeof(struct nl80211_sta_flag_update), &flags); sizeof(struct nl80211_sta_flag_update), &flags);
@ -1025,6 +1025,56 @@ static struct l_genl_msg *netdev_build_cmd_new_key_group(struct netdev *netdev,
return msg; return msg;
} }
static bool netdev_copy_tk(uint8_t *tk_buf, const uint8_t *tk,
uint32_t cipher, bool authenticator)
{
switch (cipher) {
case CRYPTO_CIPHER_CCMP:
/*
* 802.11-2016 12.8.3 Mapping PTK to CCMP keys:
* "A STA shall use the temporal key as the CCMP key
* for MPDUs between the two communicating STAs."
*/
memcpy(tk_buf, tk, 16);
break;
case CRYPTO_CIPHER_TKIP:
/*
* 802.11-2016 12.8.1 Mapping PTK to TKIP keys:
* "A STA shall use bits 0-127 of the temporal key as its
* input to the TKIP Phase 1 and Phase 2 mixing functions.
*
* A STA shall use bits 128-191 of the temporal key as
* the michael key for MSDUs from the Authenticator's STA
* to the Supplicant's STA.
*
* A STA shall use bits 192-255 of the temporal key as
* the michael key for MSDUs from the Supplicant's STA
* to the Authenticator's STA."
*/
if (authenticator) {
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_ENCR_KEY,
tk, 16);
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY,
tk + 16, 8);
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
tk + 24, 8);
} else {
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_ENCR_KEY,
tk, 16);
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
tk + 16, 8);
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY,
tk + 24, 8);
}
break;
default:
l_error("Unexpected cipher: %x", cipher);
return false;
}
return true;
}
static void netdev_set_gtk(uint32_t ifindex, uint8_t key_index, static void netdev_set_gtk(uint32_t ifindex, uint8_t key_index,
const uint8_t *gtk, uint8_t gtk_len, const uint8_t *gtk, uint8_t gtk_len,
const uint8_t *rsc, uint8_t rsc_len, const uint8_t *rsc, uint8_t rsc_len,
@ -1045,36 +1095,7 @@ static void netdev_set_gtk(uint32_t ifindex, uint8_t key_index,
return; return;
} }
switch (cipher) { if (!netdev_copy_tk(gtk_buf, gtk, cipher, false)) {
case CRYPTO_CIPHER_CCMP:
/*
* 802.11-2012 11.7.4 Mapping GTK to CCMP keys:
* "A STA shall use the temporal key as the CCMP key."
*/
memcpy(gtk_buf, gtk, 16);
break;
case CRYPTO_CIPHER_TKIP:
/*
* 802.11-2012 11.7.2 Mapping GTK to TKIP keys:
* "A STA shall use bits 0-127 of the temporal key as the
* input to the TKIP Phase 1 and Phase 2 mixing functions.
*
* A STA shall use bits 128-191 of the temporal key as
* the Michael key for MSDUs from the Authenticator's STA
* to the Supplicant's STA.
*
* A STA shall use bits 192-255 of the temporal key as
* the Michael key for MSDUs from the Supplicant's STA
* to the Authenticator's STA."
*/
memcpy(gtk_buf + NL80211_TKIP_DATA_OFFSET_ENCR_KEY, gtk, 16);
memcpy(gtk_buf + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
gtk + 16, 8);
memcpy(gtk_buf + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY,
gtk + 24, 8);
break;
default:
l_error("Unexpected cipher: %x", cipher);
netdev_setting_keys_failed(netdev, netdev_setting_keys_failed(netdev,
MMPDU_REASON_CODE_INVALID_GROUP_CIPHER); MMPDU_REASON_CODE_INVALID_GROUP_CIPHER);
return; return;
@ -1157,7 +1178,7 @@ static void netdev_set_pairwise_key_cb(struct l_genl_msg *msg, void *data)
* we're already operational, it will not hurt during re-keying * we're already operational, it will not hurt during re-keying
* and is necessary after an FT. * and is necessary after an FT.
*/ */
msg = netdev_build_cmd_set_station(netdev); msg = netdev_build_cmd_set_station(netdev, netdev->handshake->aa);
netdev->set_station_cmd_id = netdev->set_station_cmd_id =
l_genl_family_send(nl80211, msg, netdev_set_station_cb, l_genl_family_send(nl80211, msg, netdev_set_station_cb,
@ -1232,6 +1253,7 @@ static void netdev_set_tk(uint32_t ifindex, const uint8_t *aa,
uint8_t tk_buf[32]; uint8_t tk_buf[32];
struct netdev *netdev; struct netdev *netdev;
struct l_genl_msg *msg; struct l_genl_msg *msg;
enum mmpdu_reason_code rc;
netdev = netdev_find(ifindex); netdev = netdev_find(ifindex);
if (!netdev) if (!netdev)
@ -1243,64 +1265,29 @@ static void netdev_set_tk(uint32_t ifindex, const uint8_t *aa,
netdev->event_filter(netdev, NETDEV_EVENT_SETTING_KEYS, netdev->event_filter(netdev, NETDEV_EVENT_SETTING_KEYS,
netdev->user_data); netdev->user_data);
switch (cipher) { rc = MMPDU_REASON_CODE_INVALID_PAIRWISE_CIPHER;
case CRYPTO_CIPHER_CCMP: if (!netdev_copy_tk(tk_buf, tk, cipher, false))
/* goto invalid_key;
* 802.11-2012 11.7.3 Mapping PTK to CCMP keys:
* "A STA shall use the temporal key as the CCMP key
* for MPDUs between the two communicating STAs."
*/
memcpy(tk_buf, tk, 16);
break;
case CRYPTO_CIPHER_TKIP:
/*
* 802.11-2012 11.7.1 Mapping PTK to TKIP keys:
* "A STA shall use bits 0-127 of the temporal key as its
* input to the TKIP Phase 1 and Phase 2 mixing functions.
*
* A STA shall use bits 128-191 of the temporal key as
* the Michael key for MSDUs from the Authenticator's STA
* to the Supplicant's STA.
*
* A STA shall use bits 192-255 of the temporal key as
* the Michael key for MSDUs from the Supplicant's STA
* to the Authenticator's STA."
*/
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_ENCR_KEY, tk, 16);
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
tk + 16, 8);
memcpy(tk_buf + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY,
tk + 24, 8);
break;
default:
l_error("Unexpected cipher: %x", cipher);
netdev_setting_keys_failed(netdev,
MMPDU_REASON_CODE_INVALID_PAIRWISE_CIPHER);
return;
}
msg = netdev_build_cmd_new_key_pairwise(netdev, cipher, aa, rc = MMPDU_REASON_CODE_UNSPECIFIED;
tk_buf, msg = netdev_build_cmd_new_key_pairwise(netdev, cipher, aa, tk_buf,
crypto_cipher_key_len(cipher)); crypto_cipher_key_len(cipher));
netdev->pairwise_new_key_cmd_id = netdev->pairwise_new_key_cmd_id = l_genl_family_send(nl80211, msg,
l_genl_family_send(nl80211, msg, netdev_new_pairwise_key_cb, netdev_new_pairwise_key_cb, netdev, NULL);
netdev, NULL); if (!netdev->pairwise_new_key_cmd_id)
if (!netdev->pairwise_new_key_cmd_id) { goto send_failed;
l_genl_msg_unref(msg);
goto error;
}
msg = netdev_build_cmd_set_key_pairwise(netdev); msg = netdev_build_cmd_set_key_pairwise(netdev);
netdev->pairwise_set_key_cmd_id = netdev->pairwise_set_key_cmd_id =
l_genl_family_send(nl80211, msg, netdev_set_pairwise_key_cb, l_genl_family_send(nl80211, msg, netdev_set_pairwise_key_cb,
netdev, NULL); netdev, NULL);
if (netdev->pairwise_set_key_cmd_id > 0) if (netdev->pairwise_set_key_cmd_id > 0)
return; return;
send_failed:
l_genl_msg_unref(msg); l_genl_msg_unref(msg);
error: invalid_key:
netdev_setting_keys_failed(netdev, MMPDU_REASON_CODE_UNSPECIFIED); netdev_setting_keys_failed(netdev, rc);
} }
static void netdev_handshake_failed(uint32_t ifindex, static void netdev_handshake_failed(uint32_t ifindex,