From c3b0a1c8ad694af367026d5236b725e9594677b8 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 23 Jun 2011 15:47:21 +0300 Subject: [PATCH] bsd: Fix set_key() sequence number endian issue In set_key handler, the seq[8] is in little endian order defined by WPA. BSD kernel uses a u_int64_t value ik_keyrsc to represent it internally. The kernel expects the native endian order for the value. Thus, we need to detect the endian order and swap bytes when necessary. --- src/drivers/driver_bsd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index 1b52865ea..4596a5184 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -345,8 +345,20 @@ bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) wk.ik_flags |= IEEE80211_KEY_DEFAULT; wk.ik_keylen = key_len; - if (seq) + if (seq) { +#ifdef WORDS_BIGENDIAN + /* + * wk.ik_keyrsc is in host byte order (big endian), need to + * swap it to match with the byte order used in WPA. + */ + int i; + u8 *keyrsc = (u8 *) &wk.ik_keyrsc; + for (i = 0; i < seq_len; i++) + keyrsc[WPA_KEY_RSC_LEN - i - 1] = seq[i]; +#else /* WORDS_BIGENDIAN */ os_memcpy(&wk.ik_keyrsc, seq, seq_len); +#endif /* WORDS_BIGENDIAN */ + } os_memcpy(wk.ik_keydata, key, key_len); return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));