ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
}
-static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
+ u8 *aeskey, int keylen, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
int i;
if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
return -1;
+ if (aeskey != NULL && keylen >= CCMP_TK_LEN)
+ memcpy(aeskey, key->key, CCMP_TK_LEN);
+
pos = skb_push(skb, CCMP_HDR_LEN);
memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
pos += hdr_len;
return -1;
data_len = skb->len - hdr_len;
- len = ieee80211_ccmp_hdr(skb, hdr_len, priv);
+ len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
if (len < 0)
return -1;
#endif
}
-static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
+ u8 * rc4key, int keylen, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
int len;
- u8 *rc4key, *pos, *icv;
+ u8 *pos;
struct ieee80211_hdr_4addr *hdr;
- u32 crc;
hdr = (struct ieee80211_hdr_4addr *)skb->data;
if (skb_headroom(skb) < 8 || skb->len < hdr_len)
- return NULL;
+ return -1;
+
+ if (rc4key == NULL || keylen < 16)
+ return -1;
if (!tkey->tx_phase1_done) {
tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
tkey->tx_iv32);
tkey->tx_phase1_done = 1;
}
- rc4key = kmalloc(16, GFP_ATOMIC);
- if (!rc4key)
- return NULL;
tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
len = skb->len - hdr_len;
pos = skb_push(skb, 8);
memmove(pos, pos + 8, hdr_len);
pos += hdr_len;
- icv = skb_put(skb, 4);
*pos++ = *rc4key;
*pos++ = *(rc4key + 1);
*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
- crc = ~crc32_le(~0, pos, len);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
+ tkey->tx_iv16++;
+ if (tkey->tx_iv16 == 0) {
+ tkey->tx_phase1_done = 0;
+ tkey->tx_iv32++;
+ }
- return rc4key;
+ return 8;
}
static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
int len;
- const u8 *rc4key;
- u8 *pos;
+ u8 rc4key[16], *pos, *icv;
+ u32 crc;
struct scatterlist sg;
if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
if (net_ratelimit()) {
struct ieee80211_hdr_4addr *hdr =
(struct ieee80211_hdr_4addr *)skb->data;
- printk(KERN_DEBUG "TKIP countermeasures: dropped "
+ printk(KERN_DEBUG ": TKIP countermeasures: dropped "
"TX packet to " MAC_FMT "\n",
MAC_ARG(hdr->addr1));
}
len = skb->len - hdr_len;
pos = skb->data + hdr_len;
- rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
- if (!rc4key)
+ if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
return -1;
+ icv = skb_put(skb, 4);
+
+ crc = ~crc32_le(~0, pos, len);
+ icv[0] = crc;
+ icv[1] = crc >> 8;
+ icv[2] = crc >> 16;
+ icv[3] = crc >> 24;
+
crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
sg.page = virt_to_page(pos);
sg.offset = offset_in_page(pos);
sg.length = len + 4;
crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
- tkey->tx_iv16++;
- if (tkey->tx_iv16 == 0) {
- tkey->tx_phase1_done = 0;
- tkey->tx_iv32++;
- }
-
return 0;
}
if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP countermeasures: dropped "
+ printk(KERN_DEBUG ": TKIP countermeasures: dropped "
"received packet from " MAC_FMT "\n",
MAC_ARG(hdr->addr2));
}
.name = "TKIP",
.init = ieee80211_tkip_init,
.deinit = ieee80211_tkip_deinit,
+ .build_iv = ieee80211_tkip_hdr,
.encrypt_mpdu = ieee80211_tkip_encrypt,
.decrypt_mpdu = ieee80211_tkip_decrypt,
.encrypt_msdu = ieee80211_michael_mic_add,
}
/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
-static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, void *priv)
+static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len,
+ u8 *key, int keylen, void *priv)
{
struct prism2_wep_data *wep = priv;
u32 klen, len;
return -1;
/* add the IV to the frame */
- if (prism2_wep_build_iv(skb, hdr_len, priv))
+ if (prism2_wep_build_iv(skb, hdr_len, NULL, 0, priv))
return -1;
/* Copy the IV into the first 3 bytes of the key */