1 /* 2 * Copyright 2003-2005 Devicescape Software, Inc. 3 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/kobject.h> 12 #include <linux/slab.h> 13 #include "ieee80211_i.h" 14 #include "key.h" 15 #include "debugfs.h" 16 #include "debugfs_key.h" 17 18 #define KEY_READ(name, prop, format_string) \ 19 static ssize_t key_##name##_read(struct file *file, \ 20 char __user *userbuf, \ 21 size_t count, loff_t *ppos) \ 22 { \ 23 struct ieee80211_key *key = file->private_data; \ 24 return mac80211_format_buffer(userbuf, count, ppos, \ 25 format_string, key->prop); \ 26 } 27 #define KEY_READ_D(name) KEY_READ(name, name, "%d\n") 28 #define KEY_READ_X(name) KEY_READ(name, name, "0x%x\n") 29 30 #define KEY_OPS(name) \ 31 static const struct file_operations key_ ##name## _ops = { \ 32 .read = key_##name##_read, \ 33 .open = simple_open, \ 34 .llseek = generic_file_llseek, \ 35 } 36 37 #define KEY_FILE(name, format) \ 38 KEY_READ_##format(name) \ 39 KEY_OPS(name) 40 41 #define KEY_CONF_READ(name, format_string) \ 42 KEY_READ(conf_##name, conf.name, format_string) 43 #define KEY_CONF_READ_D(name) KEY_CONF_READ(name, "%d\n") 44 45 #define KEY_CONF_OPS(name) \ 46 static const struct file_operations key_ ##name## _ops = { \ 47 .read = key_conf_##name##_read, \ 48 .open = simple_open, \ 49 .llseek = generic_file_llseek, \ 50 } 51 52 #define KEY_CONF_FILE(name, format) \ 53 KEY_CONF_READ_##format(name) \ 54 KEY_CONF_OPS(name) 55 56 KEY_CONF_FILE(keylen, D); 57 KEY_CONF_FILE(keyidx, D); 58 KEY_CONF_FILE(hw_key_idx, D); 59 KEY_FILE(flags, X); 60 KEY_READ(ifindex, sdata->name, "%s\n"); 61 KEY_OPS(ifindex); 62 63 static ssize_t key_algorithm_read(struct file *file, 64 char __user *userbuf, 65 size_t count, loff_t *ppos) 66 { 67 char buf[15]; 68 struct ieee80211_key *key = file->private_data; 69 u32 c = key->conf.cipher; 70 71 sprintf(buf, "%.2x-%.2x-%.2x:%d\n", 72 c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff); 73 return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); 74 } 75 KEY_OPS(algorithm); 76 77 static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, 78 size_t count, loff_t *ppos) 79 { 80 u64 pn; 81 char buf[20]; 82 int len; 83 struct ieee80211_key *key = file->private_data; 84 85 switch (key->conf.cipher) { 86 case WLAN_CIPHER_SUITE_WEP40: 87 case WLAN_CIPHER_SUITE_WEP104: 88 len = scnprintf(buf, sizeof(buf), "\n"); 89 break; 90 case WLAN_CIPHER_SUITE_TKIP: 91 len = scnprintf(buf, sizeof(buf), "%08x %04x\n", 92 key->u.tkip.tx.iv32, 93 key->u.tkip.tx.iv16); 94 break; 95 case WLAN_CIPHER_SUITE_CCMP: 96 case WLAN_CIPHER_SUITE_CCMP_256: 97 case WLAN_CIPHER_SUITE_AES_CMAC: 98 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 99 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 100 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 101 case WLAN_CIPHER_SUITE_GCMP: 102 case WLAN_CIPHER_SUITE_GCMP_256: 103 pn = atomic64_read(&key->conf.tx_pn); 104 len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", 105 (u8)(pn >> 40), (u8)(pn >> 32), (u8)(pn >> 24), 106 (u8)(pn >> 16), (u8)(pn >> 8), (u8)pn); 107 break; 108 default: 109 return 0; 110 } 111 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 112 } 113 KEY_OPS(tx_spec); 114 115 static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, 116 size_t count, loff_t *ppos) 117 { 118 struct ieee80211_key *key = file->private_data; 119 char buf[14*IEEE80211_NUM_TIDS+1], *p = buf; 120 int i, len; 121 const u8 *rpn; 122 123 switch (key->conf.cipher) { 124 case WLAN_CIPHER_SUITE_WEP40: 125 case WLAN_CIPHER_SUITE_WEP104: 126 len = scnprintf(buf, sizeof(buf), "\n"); 127 break; 128 case WLAN_CIPHER_SUITE_TKIP: 129 for (i = 0; i < IEEE80211_NUM_TIDS; i++) 130 p += scnprintf(p, sizeof(buf)+buf-p, 131 "%08x %04x\n", 132 key->u.tkip.rx[i].iv32, 133 key->u.tkip.rx[i].iv16); 134 len = p - buf; 135 break; 136 case WLAN_CIPHER_SUITE_CCMP: 137 case WLAN_CIPHER_SUITE_CCMP_256: 138 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) { 139 rpn = key->u.ccmp.rx_pn[i]; 140 p += scnprintf(p, sizeof(buf)+buf-p, 141 "%02x%02x%02x%02x%02x%02x\n", 142 rpn[0], rpn[1], rpn[2], 143 rpn[3], rpn[4], rpn[5]); 144 } 145 len = p - buf; 146 break; 147 case WLAN_CIPHER_SUITE_AES_CMAC: 148 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 149 rpn = key->u.aes_cmac.rx_pn; 150 p += scnprintf(p, sizeof(buf)+buf-p, 151 "%02x%02x%02x%02x%02x%02x\n", 152 rpn[0], rpn[1], rpn[2], 153 rpn[3], rpn[4], rpn[5]); 154 len = p - buf; 155 break; 156 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 157 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 158 rpn = key->u.aes_gmac.rx_pn; 159 p += scnprintf(p, sizeof(buf)+buf-p, 160 "%02x%02x%02x%02x%02x%02x\n", 161 rpn[0], rpn[1], rpn[2], 162 rpn[3], rpn[4], rpn[5]); 163 len = p - buf; 164 break; 165 case WLAN_CIPHER_SUITE_GCMP: 166 case WLAN_CIPHER_SUITE_GCMP_256: 167 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) { 168 rpn = key->u.gcmp.rx_pn[i]; 169 p += scnprintf(p, sizeof(buf)+buf-p, 170 "%02x%02x%02x%02x%02x%02x\n", 171 rpn[0], rpn[1], rpn[2], 172 rpn[3], rpn[4], rpn[5]); 173 } 174 len = p - buf; 175 break; 176 default: 177 return 0; 178 } 179 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 180 } 181 KEY_OPS(rx_spec); 182 183 static ssize_t key_replays_read(struct file *file, char __user *userbuf, 184 size_t count, loff_t *ppos) 185 { 186 struct ieee80211_key *key = file->private_data; 187 char buf[20]; 188 int len; 189 190 switch (key->conf.cipher) { 191 case WLAN_CIPHER_SUITE_CCMP: 192 case WLAN_CIPHER_SUITE_CCMP_256: 193 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); 194 break; 195 case WLAN_CIPHER_SUITE_AES_CMAC: 196 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 197 len = scnprintf(buf, sizeof(buf), "%u\n", 198 key->u.aes_cmac.replays); 199 break; 200 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 201 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 202 len = scnprintf(buf, sizeof(buf), "%u\n", 203 key->u.aes_gmac.replays); 204 break; 205 case WLAN_CIPHER_SUITE_GCMP: 206 case WLAN_CIPHER_SUITE_GCMP_256: 207 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.gcmp.replays); 208 break; 209 default: 210 return 0; 211 } 212 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 213 } 214 KEY_OPS(replays); 215 216 static ssize_t key_icverrors_read(struct file *file, char __user *userbuf, 217 size_t count, loff_t *ppos) 218 { 219 struct ieee80211_key *key = file->private_data; 220 char buf[20]; 221 int len; 222 223 switch (key->conf.cipher) { 224 case WLAN_CIPHER_SUITE_AES_CMAC: 225 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 226 len = scnprintf(buf, sizeof(buf), "%u\n", 227 key->u.aes_cmac.icverrors); 228 break; 229 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 230 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 231 len = scnprintf(buf, sizeof(buf), "%u\n", 232 key->u.aes_gmac.icverrors); 233 break; 234 default: 235 return 0; 236 } 237 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 238 } 239 KEY_OPS(icverrors); 240 241 static ssize_t key_mic_failures_read(struct file *file, char __user *userbuf, 242 size_t count, loff_t *ppos) 243 { 244 struct ieee80211_key *key = file->private_data; 245 char buf[20]; 246 int len; 247 248 if (key->conf.cipher != WLAN_CIPHER_SUITE_TKIP) 249 return -EINVAL; 250 251 len = scnprintf(buf, sizeof(buf), "%u\n", key->u.tkip.mic_failures); 252 253 return simple_read_from_buffer(userbuf, count, ppos, buf, len); 254 } 255 KEY_OPS(mic_failures); 256 257 static ssize_t key_key_read(struct file *file, char __user *userbuf, 258 size_t count, loff_t *ppos) 259 { 260 struct ieee80211_key *key = file->private_data; 261 int i, bufsize = 2 * key->conf.keylen + 2; 262 char *buf = kmalloc(bufsize, GFP_KERNEL); 263 char *p = buf; 264 ssize_t res; 265 266 if (!buf) 267 return -ENOMEM; 268 269 for (i = 0; i < key->conf.keylen; i++) 270 p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]); 271 p += scnprintf(p, bufsize+buf-p, "\n"); 272 res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); 273 kfree(buf); 274 return res; 275 } 276 KEY_OPS(key); 277 278 #define DEBUGFS_ADD(name) \ 279 debugfs_create_file(#name, 0400, key->debugfs.dir, \ 280 key, &key_##name##_ops); 281 282 void ieee80211_debugfs_key_add(struct ieee80211_key *key) 283 { 284 static int keycount; 285 char buf[100]; 286 struct sta_info *sta; 287 288 if (!key->local->debugfs.keys) 289 return; 290 291 sprintf(buf, "%d", keycount); 292 key->debugfs.cnt = keycount; 293 keycount++; 294 key->debugfs.dir = debugfs_create_dir(buf, 295 key->local->debugfs.keys); 296 297 if (!key->debugfs.dir) 298 return; 299 300 sta = key->sta; 301 if (sta) { 302 sprintf(buf, "../../netdev:%s/stations/%pM", 303 sta->sdata->name, sta->sta.addr); 304 key->debugfs.stalink = 305 debugfs_create_symlink("station", key->debugfs.dir, buf); 306 } 307 308 DEBUGFS_ADD(keylen); 309 DEBUGFS_ADD(flags); 310 DEBUGFS_ADD(keyidx); 311 DEBUGFS_ADD(hw_key_idx); 312 DEBUGFS_ADD(algorithm); 313 DEBUGFS_ADD(tx_spec); 314 DEBUGFS_ADD(rx_spec); 315 DEBUGFS_ADD(replays); 316 DEBUGFS_ADD(icverrors); 317 DEBUGFS_ADD(mic_failures); 318 DEBUGFS_ADD(key); 319 DEBUGFS_ADD(ifindex); 320 }; 321 322 void ieee80211_debugfs_key_remove(struct ieee80211_key *key) 323 { 324 if (!key) 325 return; 326 327 debugfs_remove_recursive(key->debugfs.dir); 328 key->debugfs.dir = NULL; 329 } 330 331 void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) 332 { 333 char buf[50]; 334 struct ieee80211_key *key; 335 336 if (!sdata->vif.debugfs_dir) 337 return; 338 339 lockdep_assert_held(&sdata->local->key_mtx); 340 341 debugfs_remove(sdata->debugfs.default_unicast_key); 342 sdata->debugfs.default_unicast_key = NULL; 343 344 if (sdata->default_unicast_key) { 345 key = key_mtx_dereference(sdata->local, 346 sdata->default_unicast_key); 347 sprintf(buf, "../keys/%d", key->debugfs.cnt); 348 sdata->debugfs.default_unicast_key = 349 debugfs_create_symlink("default_unicast_key", 350 sdata->vif.debugfs_dir, buf); 351 } 352 353 debugfs_remove(sdata->debugfs.default_multicast_key); 354 sdata->debugfs.default_multicast_key = NULL; 355 356 if (sdata->default_multicast_key) { 357 key = key_mtx_dereference(sdata->local, 358 sdata->default_multicast_key); 359 sprintf(buf, "../keys/%d", key->debugfs.cnt); 360 sdata->debugfs.default_multicast_key = 361 debugfs_create_symlink("default_multicast_key", 362 sdata->vif.debugfs_dir, buf); 363 } 364 } 365 366 void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) 367 { 368 char buf[50]; 369 struct ieee80211_key *key; 370 371 if (!sdata->vif.debugfs_dir) 372 return; 373 374 key = key_mtx_dereference(sdata->local, 375 sdata->default_mgmt_key); 376 if (key) { 377 sprintf(buf, "../keys/%d", key->debugfs.cnt); 378 sdata->debugfs.default_mgmt_key = 379 debugfs_create_symlink("default_mgmt_key", 380 sdata->vif.debugfs_dir, buf); 381 } else 382 ieee80211_debugfs_key_remove_mgmt_default(sdata); 383 } 384 385 void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sdata) 386 { 387 if (!sdata) 388 return; 389 390 debugfs_remove(sdata->debugfs.default_mgmt_key); 391 sdata->debugfs.default_mgmt_key = NULL; 392 } 393 394 void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, 395 struct sta_info *sta) 396 { 397 debugfs_remove(key->debugfs.stalink); 398 key->debugfs.stalink = NULL; 399 } 400