mac80211: 802.11w - Use BIP (AES-128-CMAC)

Add mechanism for managing BIP keys (IGTK) and integrate BIP into the
TX/RX paths.

Signed-off-by: Jouni Malinen <j@w1.fi>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Jouni Malinen
2009-01-08 13:32:02 +02:00
committed by John W. Linville
parent 765cb46a3f
commit 3cfcf6ac6d
14 changed files with 317 additions and 21 deletions
+77 -2
View File
@@ -76,6 +76,9 @@ static ssize_t key_algorithm_read(struct file *file,
case ALG_CCMP:
alg = "CCMP\n";
break;
case ALG_AES_CMAC:
alg = "AES-128-CMAC\n";
break;
default:
return 0;
}
@@ -105,6 +108,12 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
break;
case ALG_AES_CMAC:
tpn = key->u.aes_cmac.tx_pn;
len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
tpn[0], tpn[1], tpn[2], tpn[3], tpn[4],
tpn[5]);
break;
default:
return 0;
}
@@ -142,6 +151,14 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
}
len = p - buf;
break;
case ALG_AES_CMAC:
rpn = key->u.aes_cmac.rx_pn;
p += scnprintf(p, sizeof(buf)+buf-p,
"%02x%02x%02x%02x%02x%02x\n",
rpn[0], rpn[1], rpn[2],
rpn[3], rpn[4], rpn[5]);
len = p - buf;
break;
default:
return 0;
}
@@ -156,13 +173,40 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf,
char buf[20];
int len;
if (key->conf.alg != ALG_CCMP)
switch (key->conf.alg) {
case ALG_CCMP:
len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
break;
case ALG_AES_CMAC:
len = scnprintf(buf, sizeof(buf), "%u\n",
key->u.aes_cmac.replays);
break;
default:
return 0;
len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
}
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
KEY_OPS(replays);
static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_key *key = file->private_data;
char buf[20];
int len;
switch (key->conf.alg) {
case ALG_AES_CMAC:
len = scnprintf(buf, sizeof(buf), "%u\n",
key->u.aes_cmac.icverrors);
break;
default:
return 0;
}
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
}
KEY_OPS(icverrors);
static ssize_t key_key_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
@@ -222,6 +266,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
DEBUGFS_ADD(tx_spec);
DEBUGFS_ADD(rx_spec);
DEBUGFS_ADD(replays);
DEBUGFS_ADD(icverrors);
DEBUGFS_ADD(key);
DEBUGFS_ADD(ifindex);
};
@@ -243,6 +288,7 @@ void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
DEBUGFS_DEL(tx_spec);
DEBUGFS_DEL(rx_spec);
DEBUGFS_DEL(replays);
DEBUGFS_DEL(icverrors);
DEBUGFS_DEL(key);
DEBUGFS_DEL(ifindex);
@@ -280,6 +326,35 @@ void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
sdata->common_debugfs.default_key = NULL;
}
void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
{
char buf[50];
struct ieee80211_key *key;
if (!sdata->debugfsdir)
return;
/* this is running under the key lock */
key = sdata->default_mgmt_key;
if (key) {
sprintf(buf, "../keys/%d", key->debugfs.cnt);
sdata->common_debugfs.default_mgmt_key =
debugfs_create_symlink("default_mgmt_key",
sdata->debugfsdir, buf);
} else
ieee80211_debugfs_key_remove_mgmt_default(sdata);
}
void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sdata)
{
if (!sdata)
return;
debugfs_remove(sdata->common_debugfs.default_mgmt_key);
sdata->common_debugfs.default_mgmt_key = NULL;
}
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
struct sta_info *sta)
{