0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kobject.h>
0011 #include <linux/slab.h>
0012 #include "ieee80211_i.h"
0013 #include "key.h"
0014 #include "debugfs.h"
0015 #include "debugfs_key.h"
0016
0017 #define KEY_READ(name, prop, format_string) \
0018 static ssize_t key_##name##_read(struct file *file, \
0019 char __user *userbuf, \
0020 size_t count, loff_t *ppos) \
0021 { \
0022 struct ieee80211_key *key = file->private_data; \
0023 return mac80211_format_buffer(userbuf, count, ppos, \
0024 format_string, key->prop); \
0025 }
0026 #define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n")
0027
0028 #define KEY_OPS(name) \
0029 static const struct file_operations key_ ##name## _ops = { \
0030 .read = key_##name##_read, \
0031 .open = simple_open, \
0032 .llseek = generic_file_llseek, \
0033 }
0034
0035 #define KEY_OPS_W(name) \
0036 static const struct file_operations key_ ##name## _ops = { \
0037 .read = key_##name##_read, \
0038 .write = key_##name##_write, \
0039 .open = simple_open, \
0040 .llseek = generic_file_llseek, \
0041 }
0042
0043 #define KEY_FILE(name, format) \
0044 KEY_READ_##format(name) \
0045 KEY_OPS(name)
0046
0047 #define KEY_CONF_READ(name, format_string) \
0048 KEY_READ(conf_##name, conf.name, format_string)
0049 #define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n")
0050
0051 #define KEY_CONF_OPS(name) \
0052 static const struct file_operations key_ ##name## _ops = { \
0053 .read = key_conf_##name##_read, \
0054 .open = simple_open, \
0055 .llseek = generic_file_llseek, \
0056 }
0057
0058 #define KEY_CONF_FILE(name, format) \
0059 KEY_CONF_READ_##format(name) \
0060 KEY_CONF_OPS(name)
0061
0062 KEY_CONF_FILE(keylen, D);
0063 KEY_CONF_FILE(keyidx, D);
0064 KEY_CONF_FILE(hw_key_idx, D);
0065 KEY_FILE(flags, X);
0066 KEY_READ(ifindex, sdata->name, "%s\n");
0067 KEY_OPS(ifindex);
0068
0069 static ssize_t key_algorithm_read(struct file *file,
0070 char __user *userbuf,
0071 size_t count, loff_t *ppos)
0072 {
0073 char buf[15];
0074 struct ieee80211_key *key = file->private_data;
0075 u32 c = key->conf.cipher;
0076
0077 sprintf(buf, "%.2x-%.2x-%.2x:%d\n",
0078 c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
0079 return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
0080 }
0081 KEY_OPS(algorithm);
0082
0083 static ssize_t key_tx_spec_write(struct file *file, const char __user *userbuf,
0084 size_t count, loff_t *ppos)
0085 {
0086 struct ieee80211_key *key = file->private_data;
0087 u64 pn;
0088 int ret;
0089
0090 switch (key->conf.cipher) {
0091 case WLAN_CIPHER_SUITE_WEP40:
0092 case WLAN_CIPHER_SUITE_WEP104:
0093 return -EINVAL;
0094 case WLAN_CIPHER_SUITE_TKIP:
0095
0096 return -EOPNOTSUPP;
0097 case WLAN_CIPHER_SUITE_CCMP:
0098 case WLAN_CIPHER_SUITE_CCMP_256:
0099 case WLAN_CIPHER_SUITE_AES_CMAC:
0100 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
0101 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
0102 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
0103 case WLAN_CIPHER_SUITE_GCMP:
0104 case WLAN_CIPHER_SUITE_GCMP_256:
0105 ret = kstrtou64_from_user(userbuf, count, 16, &pn);
0106 if (ret)
0107 return ret;
0108
0109 if (pn >= (1ULL << 48))
0110 return -ERANGE;
0111 atomic64_set(&key->conf.tx_pn, pn);
0112 return count;
0113 default:
0114 return 0;
0115 }
0116 }
0117
0118 static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
0119 size_t count, loff_t *ppos)
0120 {
0121 u64 pn;
0122 char buf[20];
0123 int len;
0124 struct ieee80211_key *key = file->private_data;
0125
0126 switch (key->conf.cipher) {
0127 case WLAN_CIPHER_SUITE_WEP40:
0128 case WLAN_CIPHER_SUITE_WEP104:
0129 len = scnprintf(buf, sizeof(buf), "\n");
0130 break;
0131 case WLAN_CIPHER_SUITE_TKIP:
0132 pn = atomic64_read(&key->conf.tx_pn);
0133 len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
0134 TKIP_PN_TO_IV32(pn),
0135 TKIP_PN_TO_IV16(pn));
0136 break;
0137 case WLAN_CIPHER_SUITE_CCMP:
0138 case WLAN_CIPHER_SUITE_CCMP_256:
0139 case WLAN_CIPHER_SUITE_AES_CMAC:
0140 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
0141 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
0142 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
0143 case WLAN_CIPHER_SUITE_GCMP:
0144 case WLAN_CIPHER_SUITE_GCMP_256:
0145 pn = atomic64_read(&key->conf.tx_pn);
0146 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
0147 (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24),
0148 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn);
0149 break;
0150 default:
0151 return 0;
0152 }
0153 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
0154 }
0155 KEY_OPS_W(tx_spec);
0156
0157 static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
0158 size_t count, loff_t *ppos)
0159 {
0160 struct ieee80211_key *key = file->private_data;
0161 char buf[14*IEEE80211_NUM_TIDS+1], *p = buf;
0162 int i, len;
0163 const u8 *rpn;
0164
0165 switch (key->conf.cipher) {
0166 case WLAN_CIPHER_SUITE_WEP40:
0167 case WLAN_CIPHER_SUITE_WEP104:
0168 len = scnprintf(buf, sizeof(buf), "\n");
0169 break;
0170 case WLAN_CIPHER_SUITE_TKIP:
0171 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
0172 p += scnprintf(p, sizeof(buf)+buf-p,
0173 "%08x %04x\n",
0174 key->u.tkip.rx[i].iv32,
0175 key->u.tkip.rx[i].iv16);
0176 len = p - buf;
0177 break;
0178 case WLAN_CIPHER_SUITE_CCMP:
0179 case WLAN_CIPHER_SUITE_CCMP_256:
0180 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
0181 rpn = key->u.ccmp.rx_pn[i];
0182 p += scnprintf(p, sizeof(buf)+buf-p,
0183 "%02x%02x%02x%02x%02x%02x\n",
0184 rpn[0], rpn[1], rpn[2],
0185 rpn[3], rpn[4], rpn[5]);
0186 }
0187 len = p - buf;
0188 break;
0189 case WLAN_CIPHER_SUITE_AES_CMAC:
0190 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
0191 rpn = key->u.aes_cmac.rx_pn;
0192 p += scnprintf(p, sizeof(buf)+buf-p,
0193 "%02x%02x%02x%02x%02x%02x\n",
0194 rpn[0], rpn[1], rpn[2],
0195 rpn[3], rpn[4], rpn[5]);
0196 len = p - buf;
0197 break;
0198 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
0199 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
0200 rpn = key->u.aes_gmac.rx_pn;
0201 p += scnprintf(p, sizeof(buf)+buf-p,
0202 "%02x%02x%02x%02x%02x%02x\n",
0203 rpn[0], rpn[1], rpn[2],
0204 rpn[3], rpn[4], rpn[5]);
0205 len = p - buf;
0206 break;
0207 case WLAN_CIPHER_SUITE_GCMP:
0208 case WLAN_CIPHER_SUITE_GCMP_256:
0209 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
0210 rpn = key->u.gcmp.rx_pn[i];
0211 p += scnprintf(p, sizeof(buf)+buf-p,
0212 "%02x%02x%02x%02x%02x%02x\n",
0213 rpn[0], rpn[1], rpn[2],
0214 rpn[3], rpn[4], rpn[5]);
0215 }
0216 len = p - buf;
0217 break;
0218 default:
0219 return 0;
0220 }
0221 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
0222 }
0223 KEY_OPS(rx_spec);
0224
0225 static ssize_t key_replays_read(struct file *file, char __user *userbuf,
0226 size_t count, loff_t *ppos)
0227 {
0228 struct ieee80211_key *key = file->private_data;
0229 char buf[20];
0230 int len;
0231
0232 switch (key->conf.cipher) {
0233 case WLAN_CIPHER_SUITE_CCMP:
0234 case WLAN_CIPHER_SUITE_CCMP_256:
0235 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
0236 break;
0237 case WLAN_CIPHER_SUITE_AES_CMAC:
0238 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
0239 len = scnprintf(buf, sizeof(buf), "%u\n",
0240 key->u.aes_cmac.replays);
0241 break;
0242 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
0243 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
0244 len = scnprintf(buf, sizeof(buf), "%u\n",
0245 key->u.aes_gmac.replays);
0246 break;
0247 case WLAN_CIPHER_SUITE_GCMP:
0248 case WLAN_CIPHER_SUITE_GCMP_256:
0249 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.gcmp.replays);
0250 break;
0251 default:
0252 return 0;
0253 }
0254 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
0255 }
0256 KEY_OPS(replays);
0257
0258 static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
0259 size_t count, loff_t *ppos)
0260 {
0261 struct ieee80211_key *key = file->private_data;
0262 char buf[20];
0263 int len;
0264
0265 switch (key->conf.cipher) {
0266 case WLAN_CIPHER_SUITE_AES_CMAC:
0267 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
0268 len = scnprintf(buf, sizeof(buf), "%u\n",
0269 key->u.aes_cmac.icverrors);
0270 break;
0271 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
0272 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
0273 len = scnprintf(buf, sizeof(buf), "%u\n",
0274 key->u.aes_gmac.icverrors);
0275 break;
0276 default:
0277 return 0;
0278 }
0279 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
0280 }
0281 KEY_OPS(icverrors);
0282
0283 static ssize_t key_mic_failures_read(struct file *file, char __user *userbuf,
0284 size_t count, loff_t *ppos)
0285 {
0286 struct ieee80211_key *key = file->private_data;
0287 char buf[20];
0288 int len;
0289
0290 if (key->conf.cipher != WLAN_CIPHER_SUITE_TKIP)
0291 return -EINVAL;
0292
0293 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.tkip.mic_failures);
0294
0295 return simple_read_from_buffer(userbuf, count, ppos, buf, len);
0296 }
0297 KEY_OPS(mic_failures);
0298
0299 static ssize_t key_key_read(struct file *file, char __user *userbuf,
0300 size_t count, loff_t *ppos)
0301 {
0302 struct ieee80211_key *key = file->private_data;
0303 int i, bufsize = 2 * key->conf.keylen + 2;
0304 char *buf = kmalloc(bufsize, GFP_KERNEL);
0305 char *p = buf;
0306 ssize_t res;
0307
0308 if (!buf)
0309 return -ENOMEM;
0310
0311 for (i = 0; i < key->conf.keylen; i++)
0312 p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
0313 p += scnprintf(p, bufsize+buf-p, "\n");
0314 res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
0315 kfree(buf);
0316 return res;
0317 }
0318 KEY_OPS(key);
0319
0320 #define DEBUGFS_ADD(name) \
0321 debugfs_create_file(#name, 0400, key->debugfs.dir, \
0322 key, &key_##name##_ops)
0323 #define DEBUGFS_ADD_W(name) \
0324 debugfs_create_file(#name, 0600, key->debugfs.dir, \
0325 key, &key_##name##_ops);
0326
0327 void ieee80211_debugfs_key_add(struct ieee80211_key *key)
0328 {
0329 static int keycount;
0330 char buf[100];
0331 struct sta_info *sta;
0332
0333 if (!key->local->debugfs.keys)
0334 return;
0335
0336 sprintf(buf, "%d", keycount);
0337 key->debugfs.cnt = keycount;
0338 keycount++;
0339 key->debugfs.dir = debugfs_create_dir(buf,
0340 key->local->debugfs.keys);
0341
0342 sta = key->sta;
0343 if (sta) {
0344 sprintf(buf, "../../netdev:%s/stations/%pM",
0345 sta->sdata->name, sta->sta.addr);
0346 key->debugfs.stalink =
0347 debugfs_create_symlink("station", key->debugfs.dir, buf);
0348 }
0349
0350 DEBUGFS_ADD(keylen);
0351 DEBUGFS_ADD(flags);
0352 DEBUGFS_ADD(keyidx);
0353 DEBUGFS_ADD(hw_key_idx);
0354 DEBUGFS_ADD(algorithm);
0355 DEBUGFS_ADD_W(tx_spec);
0356 DEBUGFS_ADD(rx_spec);
0357 DEBUGFS_ADD(replays);
0358 DEBUGFS_ADD(icverrors);
0359 DEBUGFS_ADD(mic_failures);
0360 DEBUGFS_ADD(key);
0361 DEBUGFS_ADD(ifindex);
0362 };
0363
0364 void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
0365 {
0366 if (!key)
0367 return;
0368
0369 debugfs_remove_recursive(key->debugfs.dir);
0370 key->debugfs.dir = NULL;
0371 }
0372
0373 void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
0374 {
0375 char buf[50];
0376 struct ieee80211_key *key;
0377
0378 if (!sdata->vif.debugfs_dir)
0379 return;
0380
0381 lockdep_assert_held(&sdata->local->key_mtx);
0382
0383 debugfs_remove(sdata->debugfs.default_unicast_key);
0384 sdata->debugfs.default_unicast_key = NULL;
0385
0386 if (sdata->default_unicast_key) {
0387 key = key_mtx_dereference(sdata->local,
0388 sdata->default_unicast_key);
0389 sprintf(buf, "../keys/%d", key->debugfs.cnt);
0390 sdata->debugfs.default_unicast_key =
0391 debugfs_create_symlink("default_unicast_key",
0392 sdata->vif.debugfs_dir, buf);
0393 }
0394
0395 debugfs_remove(sdata->debugfs.default_multicast_key);
0396 sdata->debugfs.default_multicast_key = NULL;
0397
0398 if (sdata->deflink.default_multicast_key) {
0399 key = key_mtx_dereference(sdata->local,
0400 sdata->deflink.default_multicast_key);
0401 sprintf(buf, "../keys/%d", key->debugfs.cnt);
0402 sdata->debugfs.default_multicast_key =
0403 debugfs_create_symlink("default_multicast_key",
0404 sdata->vif.debugfs_dir, buf);
0405 }
0406 }
0407
0408 void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
0409 {
0410 char buf[50];
0411 struct ieee80211_key *key;
0412
0413 if (!sdata->vif.debugfs_dir)
0414 return;
0415
0416 key = key_mtx_dereference(sdata->local,
0417 sdata->deflink.default_mgmt_key);
0418 if (key) {
0419 sprintf(buf, "../keys/%d", key->debugfs.cnt);
0420 sdata->debugfs.default_mgmt_key =
0421 debugfs_create_symlink("default_mgmt_key",
0422 sdata->vif.debugfs_dir, buf);
0423 } else
0424 ieee80211_debugfs_key_remove_mgmt_default(sdata);
0425 }
0426
0427 void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sdata)
0428 {
0429 if (!sdata)
0430 return;
0431
0432 debugfs_remove(sdata->debugfs.default_mgmt_key);
0433 sdata->debugfs.default_mgmt_key = NULL;
0434 }
0435
0436 void
0437 ieee80211_debugfs_key_add_beacon_default(struct ieee80211_sub_if_data *sdata)
0438 {
0439 char buf[50];
0440 struct ieee80211_key *key;
0441
0442 if (!sdata->vif.debugfs_dir)
0443 return;
0444
0445 key = key_mtx_dereference(sdata->local,
0446 sdata->deflink.default_beacon_key);
0447 if (key) {
0448 sprintf(buf, "../keys/%d", key->debugfs.cnt);
0449 sdata->debugfs.default_beacon_key =
0450 debugfs_create_symlink("default_beacon_key",
0451 sdata->vif.debugfs_dir, buf);
0452 } else {
0453 ieee80211_debugfs_key_remove_beacon_default(sdata);
0454 }
0455 }
0456
0457 void
0458 ieee80211_debugfs_key_remove_beacon_default(struct ieee80211_sub_if_data *sdata)
0459 {
0460 if (!sdata)
0461 return;
0462
0463 debugfs_remove(sdata->debugfs.default_beacon_key);
0464 sdata->debugfs.default_beacon_key = NULL;
0465 }
0466
0467 void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
0468 struct sta_info *sta)
0469 {
0470 debugfs_remove(key->debugfs.stalink);
0471 key->debugfs.stalink = NULL;
0472 }