[v6,05/17] hostapd: Set the correct key_type for key installs
diff mbox series

Message ID 20190915200837.196283-6-alexander@wetzel-home.de
State Under Review
Headers show
Series
  • Support seamless PTK rekeys with Extended Key ID
Related show

Commit Message

Alexander Wetzel Sept. 15, 2019, 8:08 p.m. UTC
In addition to the set_key boolean this also sets the corresponding
new variable key_type for all key installs.

Till set_tx is dropped drivers can use either set_tx or key_flag,
allowing to seamless migrate to key_flag.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---
 hostapd/ctrl_iface.c           | 24 ++++++++++++++----------
 src/ap/hostapd.c               | 15 +++++++++------
 src/ap/ieee802_11.c            |  3 ++-
 src/ap/ieee802_1x.c            |  7 ++++---
 src/ap/wpa_auth.c              | 11 ++++++-----
 src/ap/wpa_auth_ft.c           |  2 +-
 tests/hwsim/test_ap_ciphers.py |  2 +-
 7 files changed, 37 insertions(+), 27 deletions(-)

Comments

Jouni Malinen Sept. 20, 2019, 12:54 p.m. UTC | #1
On Sun, Sep 15, 2019 at 10:08:25PM +0200, Alexander Wetzel wrote:
> In addition to the set_key boolean this also sets the corresponding
> new variable key_type for all key installs.
> 
> Till set_tx is dropped drivers can use either set_tx or key_flag,
> allowing to seamless migrate to key_flag.

I'd assume this is talking about set_tx and key_type, not about
set_key or key_flag.

> diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
> @@ -286,7 +286,7 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
>  		if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
>  					sta->addr, 0, 1, NULL, 0, ikey,
>  					hapd->conf->individual_wep_key_len,
> -					0)) {
> +					KEY_TYPE_DEFAULT)) {

Why would this use KEY_TYPE_DEFAULT instead of KEY_TYPE_PAIRWISE? This
operation is configuring a unicast WEP key for the specific station.
Sure, it was not called pairwise before RSN was added to the standard,
but this is a WEP key that is used for unicast frames only and there is
a separate WEP key from group-addressed frames.

> diff --git a/tests/hwsim/test_ap_ciphers.py b/tests/hwsim/test_ap_ciphers.py
> @@ -862,7 +862,7 @@ def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev):

> -    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s 0" % (addr, 0, 1, 6*"00", 16*"00")):
> +    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s %d" % (addr, 0, 1, 6*"00", 16*"00", 2)):

I'm moving this and the other related changes in 4/17 into a separate
patch (i.e., 4/17 uses 0 for everything as the key_type and does not
have the exception for hostapd_ctrl_set_key()).
Alexander Wetzel Sept. 20, 2019, 2:18 p.m. UTC | #2
Am 20.09.19 um 14:54 schrieb Jouni Malinen:
> On Sun, Sep 15, 2019 at 10:08:25PM +0200, Alexander Wetzel wrote:
>> In addition to the set_key boolean this also sets the corresponding
>> new variable key_type for all key installs.
>>
>> Till set_tx is dropped drivers can use either set_tx or key_flag,
>> allowing to seamless migrate to key_flag.
> 
> I'd assume this is talking about set_tx and key_type, not about
> set_key or key_flag.
> 

Yes. Here what I should have written:
In addition to the set_tx boolean this also sets the corresponding
new variable key_type for all key installs,
Till set_tx is dropped drivers can use either set_tx or key_type,
allowing to seamless migrate to key_flag.

To many variables and renames I guess...

>> diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
>> @@ -286,7 +286,7 @@ static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
>>   		if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
>>   					sta->addr, 0, 1, NULL, 0, ikey,
>>   					hapd->conf->individual_wep_key_len,
>> -					0)) {
>> +					KEY_TYPE_DEFAULT)) {
> 
> Why would this use KEY_TYPE_DEFAULT instead of KEY_TYPE_PAIRWISE? This
> operation is configuring a unicast WEP key for the specific station.
> Sure, it was not called pairwise before RSN was added to the standard,
> but this is a WEP key that is used for unicast frames only and there is
> a separate WEP key from group-addressed frames.

I'm on really thin ice with WEP. But since set_tx is set to one here the 
intend seems to be to install the WEP key also as a default WEP key for 
the STA. So I mapped it to the equivalent, making sure there is a 
default key with WEP. Using KEY_TYPE_PAIRWISE will skip the 
NL80211_KEY_DEFAULT call for the key. Now the original code was doing 
that... If that's not required we can change it.

> 
>> diff --git a/tests/hwsim/test_ap_ciphers.py b/tests/hwsim/test_ap_ciphers.py
>> @@ -862,7 +862,7 @@ def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev):
> 
>> -    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s 0" % (addr, 0, 1, 6*"00", 16*"00")):
>> +    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s %d" % (addr, 0, 1, 6*"00", 16*"00", 2)):
> 
> I'm moving this and the other related changes in 4/17 into a separate
> patch (i.e., 4/17 uses 0 for everything as the key_type and does not
> have the exception for hostapd_ctrl_set_key()).
> 

Don't understand the reasoning for that, so just a quick explanation 
what I do here:
4/17 just added the variable key_type and added the "0" prior to the 
"%", so so tests can still be executed. Here I replace the "0" with "2" 
- which is KEY_TYPE_PAIRWISE for tests. (And start setting the value 
like the other variables.)
Alexander Wetzel Sept. 28, 2019, 4:24 p.m. UTC | #3
>>> diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
>>> @@ -286,7 +286,7 @@ static void ieee802_1x_tx_key(struct hostapd_data 
>>> *hapd, struct sta_info *sta)
>>>           if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
>>>                       sta->addr, 0, 1, NULL, 0, ikey,
>>>                       hapd->conf->individual_wep_key_len,
>>> -                    0)) {
>>> +                    KEY_TYPE_DEFAULT)) {
>>
>> Why would this use KEY_TYPE_DEFAULT instead of KEY_TYPE_PAIRWISE? This
>> operation is configuring a unicast WEP key for the specific station.
>> Sure, it was not called pairwise before RSN was added to the standard,
>> but this is a WEP key that is used for unicast frames only and there is
>> a separate WEP key from group-addressed frames.
> 
> I'm on really thin ice with WEP. But since set_tx is set to one here the 
> intend seems to be to install the WEP key also as a default WEP key for 
> the STA. So I mapped it to the equivalent, making sure there is a 
> default key with WEP. Using KEY_TYPE_PAIRWISE will skip the 
> NL80211_KEY_DEFAULT call for the key. Now the original code was doing 
> that... If that's not required we can change it.

I noticed that setting KEY_TYPE_DEFAULT and an sta addr seems to be an 
invalid combination. At least the nl80211 driver is not handling this 
combination and executes the same code as for KEY_TYPE_PAIRWISE.

So we really should use KEY_TYPE_PAIRWISE here. And maybe add a sanity 
check for set_key blocking the not implemented combination.

I've included that in the patch set I was working on and finally will 
send out in a few minutes.

>>
>>> diff --git a/tests/hwsim/test_ap_ciphers.py 
>>> b/tests/hwsim/test_ap_ciphers.py
>>> @@ -862,7 +862,7 @@ def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev):
>>
>>> -    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s 0" % 
>>> (addr, 0, 1, 6*"00", 16*"00")):
>>> +    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s %d" % 
>>> (addr, 0, 1, 6*"00", 16*"00", 2)):
>>
>> I'm moving this and the other related changes in 4/17 into a separate
>> patch (i.e., 4/17 uses 0 for everything as the key_type and does not
>> have the exception for hostapd_ctrl_set_key()).
>>
> 
> Don't understand the reasoning for that, so just a quick explanation 
> what I do here:
> 4/17 just added the variable key_type and added the "0" prior to the 
> "%", so so tests can still be executed. Here I replace the "0" with "2" 
> - which is KEY_TYPE_PAIRWISE for tests. (And start setting the value 
> like the other variables.)

Maybe one additional comment here:
It's irrelevant which patch sets the key_type to 2, it just must be done 
after 4/17 and prior to 7/17 when we don't want to break the tests 
between the patches.

Alexander

Patch
diff mbox series

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 7255f6ed6..dd1fd42f7 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -2117,7 +2117,8 @@  static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
 					hapd->last_igtk_alg,
 					broadcast_ether_addr,
 					hapd->last_igtk_key_idx, 1, NULL, 0,
-					zero, hapd->last_igtk_len, 0) < 0)
+					zero, hapd->last_igtk_len,
+					KEY_TYPE_BROADCAST) < 0)
 			return -1;
 
 		/* Set the previously configured key to reset its TSC */
@@ -2126,7 +2127,8 @@  static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
 					   broadcast_ether_addr,
 					   hapd->last_igtk_key_idx, 1, NULL, 0,
 					   hapd->last_igtk,
-					   hapd->last_igtk_len, 0);
+					   hapd->last_igtk_len,
+					   KEY_TYPE_BROADCAST);
 	}
 
 	if (is_broadcast_ether_addr(addr)) {
@@ -2141,7 +2143,8 @@  static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
 					hapd->last_gtk_alg,
 					broadcast_ether_addr,
 					hapd->last_gtk_key_idx, 1, NULL, 0,
-					zero, hapd->last_gtk_len, 0) < 0)
+					zero, hapd->last_gtk_len,
+					KEY_TYPE_BROADCAST) < 0)
 			return -1;
 
 		/* Set the previously configured key to reset its TSC */
@@ -2150,7 +2153,7 @@  static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
 					   broadcast_ether_addr,
 					   hapd->last_gtk_key_idx, 1, NULL, 0,
 					   hapd->last_gtk, hapd->last_gtk_len,
-					   0);
+					   KEY_TYPE_BROADCAST);
 	}
 
 	sta = ap_get_sta(hapd, addr);
@@ -2167,13 +2170,14 @@  static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
 	 * in the driver. */
 	if (hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
 				sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
-				zero, sta->last_tk_len, 0) < 0)
+				zero, sta->last_tk_len, KEY_TYPE_PAIRWISE) < 0)
 		return -1;
 
 	/* Set the previously configured key to reset its TSC/RSC */
 	return hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
 				   sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
-				   sta->last_tk, sta->last_tk_len, 0);
+				   sta->last_tk, sta->last_tk_len,
+				   KEY_TYPE_PAIRWISE);
 }
 
 
@@ -2247,7 +2251,7 @@  static void restore_tk(void *ctx1, void *ctx2)
 	 * preventing encryption of a single EAPOL frame. */
 	hostapd_drv_set_key(hapd->conf->iface, hapd, sta->last_tk_alg,
 			    sta->addr, sta->last_tk_key_idx, 1, NULL, 0,
-			    sta->last_tk, sta->last_tk_len, 0);
+			    sta->last_tk, sta->last_tk_len, KEY_TYPE_PAIRWISE);
 }
 
 
@@ -2271,7 +2275,7 @@  static int hostapd_ctrl_resend_m1(struct hostapd_data *hapd, const char *cmd)
 			   MAC2STR(sta->addr));
 		hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
 				    sta->addr, sta->last_tk_key_idx, 0, NULL, 0,
-				    NULL, 0, 0);
+				    NULL, 0, KEY_TYPE_PAIRWISE);
 	}
 
 	wpa_printf(MSG_INFO, "TESTING: Send M1 to " MACSTR, MAC2STR(sta->addr));
@@ -2301,7 +2305,7 @@  static int hostapd_ctrl_resend_m3(struct hostapd_data *hapd, const char *cmd)
 			   MAC2STR(sta->addr));
 		hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
 				    sta->addr, sta->last_tk_key_idx, 0, NULL, 0,
-				    NULL, 0, 0);
+				    NULL, 0, KEY_TYPE_PAIRWISE);
 	}
 
 	wpa_printf(MSG_INFO, "TESTING: Send M3 to " MACSTR, MAC2STR(sta->addr));
@@ -2331,7 +2335,7 @@  static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd,
 			   MAC2STR(sta->addr));
 		hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_NONE,
 				    sta->addr, sta->last_tk_key_idx, 0, NULL, 0,
-				    NULL, 0, 0);
+				    NULL, 0, KEY_TYPE_PAIRWISE);
 	}
 
 	wpa_printf(MSG_INFO,
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 53a2bec8f..480fc706e 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -291,8 +291,8 @@  static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
 	if (!ifname || !hapd->drv_priv)
 		return;
 	for (i = 0; i < NUM_WEP_KEYS; i++) {
-		if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
-					0, NULL, 0, NULL, 0, 0)) {
+		if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 0,
+					NULL, 0, NULL, 0, KEY_TYPE_BROADCAST)) {
 			wpa_printf(MSG_DEBUG, "Failed to clear default "
 				   "encryption keys (ifname=%s keyidx=%d)",
 				   ifname, i);
@@ -301,8 +301,8 @@  static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
 	if (hapd->conf->ieee80211w) {
 		for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
 			if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
-						NULL, i, 0, NULL,
-						0, NULL, 0, 0)) {
+						NULL, i, 0, NULL, 0,
+						NULL, 0, KEY_TYPE_BROADCAST)) {
 				wpa_printf(MSG_DEBUG, "Failed to clear "
 					   "default mgmt encryption keys "
 					   "(ifname=%s keyidx=%d)", ifname, i);
@@ -329,7 +329,7 @@  static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
 	    hostapd_drv_set_key(hapd->conf->iface,
 				hapd, WPA_ALG_WEP, broadcast_ether_addr, idx,
 				1, NULL, 0, ssid->wep.key[idx],
-				ssid->wep.len[idx], 0)) {
+				ssid->wep.len[idx], KEY_TYPE_DEFAULT)) {
 		wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
 		errors++;
 	}
@@ -555,7 +555,10 @@  static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
 		    hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
 					i == hapd->conf->ssid.wep.idx, NULL, 0,
 					hapd->conf->ssid.wep.key[i],
-					hapd->conf->ssid.wep.len[i], 0)) {
+					hapd->conf->ssid.wep.len[i],
+					i == hapd->conf->ssid.wep.idx ?
+					KEY_TYPE_DEFAULT :
+					KEY_TYPE_BROADCAST)) {
 			wpa_printf(MSG_WARNING, "Could not set WEP "
 				   "encryption.");
 			return -1;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index b60a61ff3..aa6931fd8 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -4771,7 +4771,8 @@  static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
 		    hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
 					i == ssid->wep.idx, NULL, 0,
 					ssid->wep.key[i], ssid->wep.len[i],
-					0)) {
+					i == ssid->wep.idx ? KEY_TYPE_DEFAULT :
+					KEY_TYPE_BROADCAST)) {
 			wpa_printf(MSG_WARNING,
 				   "Could not set WEP keys for WDS interface; %s",
 				   ifname_wds);
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 1a94b0c44..8174ca8d0 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -286,7 +286,7 @@  static void ieee802_1x_tx_key(struct hostapd_data *hapd, struct sta_info *sta)
 		if (hostapd_drv_set_key(hapd->conf->iface, hapd, WPA_ALG_WEP,
 					sta->addr, 0, 1, NULL, 0, ikey,
 					hapd->conf->individual_wep_key_len,
-					0)) {
+					KEY_TYPE_DEFAULT)) {
 			wpa_printf(MSG_ERROR,
 				   "Could not set individual WEP encryption");
 		}
@@ -2180,7 +2180,8 @@  static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx)
 				broadcast_ether_addr,
 				eapol->default_wep_key_idx, 1, NULL, 0,
 				eapol->default_wep_key,
-				hapd->conf->default_wep_key_len, 0)) {
+				hapd->conf->default_wep_key_len,
+				KEY_TYPE_DEFAULT)) {
 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,
 			       HOSTAPD_LEVEL_WARNING,
 			       "failed to configure a new broadcast key");
@@ -2472,7 +2473,7 @@  int ieee802_1x_init(struct hostapd_data *hapd)
 		for (i = 0; i < 4; i++)
 			hostapd_drv_set_key(hapd->conf->iface, hapd,
 					    WPA_ALG_NONE, NULL, i, 0, NULL, 0,
-					    NULL, 0, 0);
+					    NULL, 0, KEY_TYPE_BROADCAST);
 
 		ieee802_1x_rekey(hapd, NULL);
 
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index f64658264..521d18030 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -1714,7 +1714,7 @@  void wpa_remove_ptk(struct wpa_state_machine *sm)
 	sm->PTK_valid = FALSE;
 	os_memset(&sm->PTK, 0, sizeof(sm->PTK));
 	if (wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL,
-			     0, 0))
+			     0, KEY_TYPE_PAIRWISE))
 		wpa_printf(MSG_DEBUG,
 			   "RSN: PTK removal from the driver failed");
 	sm->pairwise_set = FALSE;
@@ -2746,7 +2746,7 @@  int fils_set_tk(struct wpa_state_machine *sm)
 
 	wpa_printf(MSG_DEBUG, "FILS: Configure TK to the driver");
 	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-			     sm->PTK.tk, klen, 0)) {
+			     sm->PTK.tk, klen, KEY_TYPE_PAIRWISE)) {
 		wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
 		return -1;
 	}
@@ -3327,7 +3327,7 @@  SM_STATE(WPA_PTK, PTKINITDONE)
 		enum wpa_alg alg = wpa_cipher_to_alg(sm->pairwise);
 		int klen = wpa_cipher_key_len(sm->pairwise);
 		if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-				     sm->PTK.tk, klen, 0)) {
+				     sm->PTK.tk, klen, KEY_TYPE_PAIRWISE)) {
 			wpa_sta_disconnect(sm->wpa_auth, sm->addr,
 					   WLAN_REASON_PREV_AUTH_NOT_VALID);
 			return;
@@ -3919,7 +3919,8 @@  static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
 	if (wpa_auth_set_key(wpa_auth, group->vlan_id,
 			     wpa_cipher_to_alg(wpa_auth->conf.wpa_group),
 			     broadcast_ether_addr, group->GN,
-			     group->GTK[group->GN - 1], group->GTK_len, 0) < 0)
+			     group->GTK[group->GN - 1], group->GTK_len,
+			     KEY_TYPE_BROADCAST) < 0)
 		ret = -1;
 
 	if (wpa_auth->conf.ieee80211w != NO_MGMT_FRAME_PROTECTION) {
@@ -3933,7 +3934,7 @@  static int wpa_group_config_group_keys(struct wpa_authenticator *wpa_auth,
 		    wpa_auth_set_key(wpa_auth, group->vlan_id, alg,
 				     broadcast_ether_addr, group->GN_igtk,
 				     group->IGTK[group->GN_igtk - 4],
-				     len, 0) < 0)
+				     len, KEY_TYPE_BROADCAST) < 0)
 			ret = -1;
 	}
 
diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c
index 77ddc024c..eb61b97f0 100644
--- a/src/ap/wpa_auth_ft.c
+++ b/src/ap/wpa_auth_ft.c
@@ -2649,7 +2649,7 @@  void wpa_ft_install_ptk(struct wpa_state_machine *sm)
 	 * optimized by adding the STA entry earlier.
 	 */
 	if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
-			     sm->PTK.tk, klen, 0))
+			     sm->PTK.tk, klen, KEY_TYPE_PAIRWISE))
 		return;
 
 	/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
diff --git a/tests/hwsim/test_ap_ciphers.py b/tests/hwsim/test_ap_ciphers.py
index cd45c6fd9..a6ba27d99 100644
--- a/tests/hwsim/test_ap_ciphers.py
+++ b/tests/hwsim/test_ap_ciphers.py
@@ -862,7 +862,7 @@  def test_ap_wpa2_delayed_m1_m3_zero_tk(dev, apdev):
     if "OK" not in hapd.request("RESEND_M3 " + addr):
         raise Exception("RESEND_M3 failed")
 
-    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s 0" % (addr, 0, 1, 6*"00", 16*"00")):
+    if "OK" not in hapd.request("SET_KEY 3 %s %d %d %s %s %d" % (addr, 0, 1, 6*"00", 16*"00", 2)):
         raise Exception("SET_KEY failed")
     time.sleep(0.1)
     hwsim_utils.test_connectivity(dev[0], hapd, timeout=1, broadcast=False,