Changeset a931b7b in mainline
- Timestamp:
- 2015-04-13T20:48:33Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cc575ef9
- Parents:
- 053fc2b
- Location:
- uspace
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/wifi_supplicant/wifi_supplicant.c
r053fc2b ra931b7b 187 187 } 188 188 189 ieee80211_connect(sess, ssid_start, password);189 rc = ieee80211_connect(sess, ssid_start, password); 190 190 if(rc != EOK) { 191 191 if(rc == EREFUSED) { -
uspace/drv/nic/ar9271/ar9271.c
r053fc2b ra931b7b 440 440 uint32_t key[5]; 441 441 uint32_t key_type; 442 uint32_t reg_ptr ;442 uint32_t reg_ptr, mic_reg_ptr; 443 443 void *data_start; 444 444 … … 465 465 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) { 466 466 reg_ptr = AR9271_KEY_TABLE_STA; 467 mic_reg_ptr = AR9271_KEY_TABLE_MIC_STA; 467 468 } else { 468 469 reg_ptr = AR9271_KEY_TABLE_GRP; 470 mic_reg_ptr = AR9271_KEY_TABLE_MIC_GRP; 469 471 } 470 472 471 if(key_conf->suite == IEEE80211_SECURITY_SUITE_TKIP) { 472 // TODO 473 } else { 474 data_start = (void *) key_conf->data; 475 476 key[0] = uint32_t_le2host( 477 *((uint32_t *) data_start)); 478 key[1] = uint16_t_le2host( 479 *((uint16_t *) (data_start + 4))); 480 key[2] = uint32_t_le2host( 481 *((uint32_t *) (data_start + 6))); 482 key[3] = uint16_t_le2host( 483 *((uint16_t *) (data_start + 10))); 484 key[4] = uint32_t_le2host( 485 *((uint32_t *) (data_start + 12))); 486 487 if(key_conf->suite == IEEE80211_SECURITY_SUITE_WEP40 || 488 key_conf->suite == IEEE80211_SECURITY_SUITE_WEP104) { 489 key[4] &= 0xFF; 490 } 491 492 wmi_reg_write(ar9271->htc_device, reg_ptr + 0, key[0]); 493 wmi_reg_write(ar9271->htc_device, reg_ptr + 4, key[1]); 494 wmi_reg_write(ar9271->htc_device, reg_ptr + 8, key[2]); 495 wmi_reg_write(ar9271->htc_device, reg_ptr + 12, key[3]); 496 wmi_reg_write(ar9271->htc_device, reg_ptr + 16, key[4]); 497 wmi_reg_write(ar9271->htc_device, reg_ptr + 20, 498 key_type); 473 data_start = (void *) key_conf->data; 474 475 key[0] = uint32_t_le2host( 476 *((uint32_t *) data_start)); 477 key[1] = uint16_t_le2host( 478 *((uint16_t *) (data_start + 4))); 479 key[2] = uint32_t_le2host( 480 *((uint32_t *) (data_start + 6))); 481 key[3] = uint16_t_le2host( 482 *((uint16_t *) (data_start + 10))); 483 key[4] = uint32_t_le2host( 484 *((uint32_t *) (data_start + 12))); 485 486 if(key_conf->suite == IEEE80211_SECURITY_SUITE_WEP40 || 487 key_conf->suite == IEEE80211_SECURITY_SUITE_WEP104) { 488 key[4] &= 0xFF; 499 489 } 490 491 wmi_reg_write(ar9271->htc_device, reg_ptr + 0, key[0]); 492 wmi_reg_write(ar9271->htc_device, reg_ptr + 4, key[1]); 493 wmi_reg_write(ar9271->htc_device, reg_ptr + 8, key[2]); 494 wmi_reg_write(ar9271->htc_device, reg_ptr + 12, key[3]); 495 wmi_reg_write(ar9271->htc_device, reg_ptr + 16, key[4]); 496 wmi_reg_write(ar9271->htc_device, reg_ptr + 20, key_type); 500 497 501 498 uint32_t macL, macH; … … 516 513 wmi_reg_write(ar9271->htc_device, reg_ptr + 24, macL); 517 514 wmi_reg_write(ar9271->htc_device, reg_ptr + 28, macH); 515 516 /* Setup MIC keys for TKIP. */ 517 if(key_conf->suite == IEEE80211_SECURITY_SUITE_TKIP) { 518 uint32_t mic[5]; 519 uint8_t *gen_mic = 520 data_start + IEEE80211_TKIP_RX_MIC_OFFSET; 521 uint8_t *tx_mic; 522 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP) { 523 tx_mic = gen_mic; 524 } else { 525 tx_mic = data_start + 526 IEEE80211_TKIP_TX_MIC_OFFSET; 527 } 528 529 mic[0] = uint32_t_le2host( 530 *((uint32_t *) gen_mic)); 531 mic[1] = uint16_t_le2host( 532 *((uint16_t *) (tx_mic + 2))) & 0xFFFF; 533 mic[2] = uint32_t_le2host( 534 *((uint32_t *) (gen_mic + 4))); 535 mic[3] = uint16_t_le2host( 536 *((uint16_t *) tx_mic)) & 0xFFFF; 537 mic[4] = uint32_t_le2host( 538 *((uint32_t *) (tx_mic + 4))); 539 540 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 0, 541 mic[0]); 542 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 4, 543 mic[1]); 544 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 8, 545 mic[2]); 546 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 12, 547 mic[3]); 548 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 16, 549 mic[4]); 550 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 20, 551 AR9271_KEY_TABLE_TYPE_CLR); 552 553 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 24, 0); 554 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 28, 0); 555 } 518 556 519 557 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP) -
uspace/drv/nic/ar9271/ar9271.h
r053fc2b ra931b7b 138 138 AR9271_KEY_TABLE_GRP = 0x8820, 139 139 AR9271_KEY_TABLE_STA = 0x8880, 140 AR9271_KEY_TABLE_MIC_GRP = 0x9020, 141 AR9271_KEY_TABLE_MIC_STA = 0x9080, 140 142 AR9271_KEY_TABLE_TYPE_WEP40 = 0x0, 141 143 AR9271_KEY_TABLE_TYPE_WEP104 = 0x1, 142 144 AR9271_KEY_TABLE_TYPE_TKIP = 0x4, 143 145 AR9271_KEY_TABLE_TYPE_CCMP = 0x6, 146 AR9271_KEY_TABLE_TYPE_CLR = 0x7, 144 147 145 148 /* Physical layer registers */ -
uspace/lib/crypto/crypto.c
r053fc2b ra931b7b 252 252 253 253 /** 254 * Hash-based message authentication code using SHA-1 algorithm.254 * Hash-based message authentication code. 255 255 * 256 256 * @param key Cryptographic key sequence. … … 308 308 * Password-Based Key Derivation Function 2 as defined in RFC 2898, 309 309 * using HMAC-SHA1 with 4096 iterations and 32 bytes key result used 310 * for WPA 2.310 * for WPA/WPA2. 311 311 * 312 312 * @param pass Password sequence. … … 315 315 * @param salt_size Salt sequence length. 316 316 * @param hash Output parameter for result hash (32 byte value). 317 * @param hash_sel Hash function selector.318 317 * 319 318 * @return EINVAL when pass or salt not specified, ENOMEM when pointer for … … 321 320 */ 322 321 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 323 uint8_t *hash , hash_func_t hash_sel)322 uint8_t *hash) 324 323 { 325 324 if(!pass || !salt) … … 331 330 uint8_t work_salt[salt_size + sizeof(uint32_t)]; 332 331 memcpy(work_salt, salt, salt_size); 333 uint8_t work_hmac[ hash_sel];334 uint8_t temp_hmac[ hash_sel];335 uint8_t xor_hmac[ hash_sel];336 uint8_t temp_hash[ hash_sel*2];332 uint8_t work_hmac[HASH_SHA1]; 333 uint8_t temp_hmac[HASH_SHA1]; 334 uint8_t xor_hmac[HASH_SHA1]; 335 uint8_t temp_hash[HASH_SHA1*2]; 337 336 338 337 for(size_t i = 0; i < 2; i++) { … … 340 339 memcpy(work_salt + salt_size, &big_i, sizeof(uint32_t)); 341 340 hmac(pass, pass_size, work_salt, salt_size + sizeof(uint32_t), 342 work_hmac, hash_sel);343 memcpy(xor_hmac, work_hmac, hash_sel);341 work_hmac, HASH_SHA1); 342 memcpy(xor_hmac, work_hmac, HASH_SHA1); 344 343 for(size_t k = 1; k < 4096; k++) { 345 memcpy(temp_hmac, work_hmac, hash_sel);346 hmac(pass, pass_size, temp_hmac, hash_sel,347 work_hmac, hash_sel);348 for(size_t t = 0; t < hash_sel; t++) {344 memcpy(temp_hmac, work_hmac, HASH_SHA1); 345 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 346 work_hmac, HASH_SHA1); 347 for(size_t t = 0; t < HASH_SHA1; t++) { 349 348 xor_hmac[t] ^= work_hmac[t]; 350 349 } 351 350 } 352 memcpy(temp_hash + i* hash_sel, xor_hmac, hash_sel);351 memcpy(temp_hash + i*HASH_SHA1, xor_hmac, HASH_SHA1); 353 352 } 354 353 -
uspace/lib/crypto/crypto.h
r053fc2b ra931b7b 41 41 } hash_func_t; 42 42 43 extern int rc4(uint8_t *key, size_t key_size, uint8_t *input, 44 size_t input_size, uint8_t *output);43 extern int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 44 size_t skip, uint8_t *output); 45 45 extern int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output); 46 46 extern int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output); … … 50 50 uint8_t *hash, hash_func_t hash_sel); 51 51 extern int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, 52 size_t salt_size, uint8_t *hash , hash_func_t hash_sel);52 size_t salt_size, uint8_t *hash); 53 53 54 54 #endif -
uspace/lib/crypto/rc4.c
r053fc2b ra931b7b 82 82 * @param input Input data sequence to be processed. 83 83 * @param input_size Size of input data sequence. 84 * @param skip Number of bytes to be skipped from the beginning of key stream. 84 85 * @param output Result data sequence. 85 86 * … … 88 89 */ 89 90 int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 90 uint8_t *output)91 size_t skip, uint8_t *output) 91 92 { 92 93 if(!key || !input) … … 100 101 create_sbox(key, key_size, sbox); 101 102 103 /* Skip first x bytes. */ 104 uint8_t i = 0, j = 0; 105 for(size_t k = 0; k < skip; k++) { 106 i = i+1; 107 j = j + sbox[i]; 108 swap(i, j, sbox); 109 } 110 102 111 /* Processing loop. */ 103 uint8_t i = 0, j = 0,val;112 uint8_t val; 104 113 for(size_t k = 0; k < input_size; k++) { 105 114 i = i+1; -
uspace/lib/ieee80211/include/ieee80211.h
r053fc2b ra931b7b 82 82 } ieee80211_key_flags_t; 83 83 84 typedef enum { 85 IEEE80211_TKIP_TX_MIC_OFFSET = 16, 86 IEEE80211_TKIP_RX_MIC_OFFSET = 24 87 } ieee80211_tkip_mic_offset_t; 88 84 89 /** Key config structure. */ 85 90 typedef struct { -
uspace/lib/ieee80211/include/ieee80211_impl.h
r053fc2b ra931b7b 53 53 extern int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev); 54 54 extern int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash, 55 hash_func_t hash_sel); 55 size_t output_size); 56 extern int ieee80211_rc4_key_unwrap(uint8_t *key, uint8_t *data, 57 size_t data_size, uint8_t *output); 56 58 extern int ieee80211_aes_key_unwrap(uint8_t *kek, uint8_t *data, 57 59 size_t data_size, uint8_t *output); -
uspace/lib/ieee80211/include/ieee80211_private.h
r053fc2b ra931b7b 52 52 53 53 /* Timeout in us for waiting to finish 4-way handshake process. */ 54 #define HANDSHAKE_TIMEOUT 300000054 #define HANDSHAKE_TIMEOUT 5000000 55 55 56 56 /* Scanning period. */ … … 86 86 /* TK offset inside PTK. */ 87 87 #define TK_OFFSET 32 88 89 /* Length of CCMP header we need to reserve. */90 #define IEEE80211_CCMP_HEADER_LENGTH 891 88 92 89 /* … … 95 92 */ 96 93 #define PRF_CRYPT_DATA_LENGTH 2*32 + 2*ETH_ADDR 94 95 /* Special room in header reserved for encryption. */ 96 typedef enum { 97 IEEE80211_TKIP_HEADER_LENGTH = 8, 98 IEEE80211_CCMP_HEADER_LENGTH = 8 99 } ieee80211_encrypt_header_reserve_length_t; 100 101 /* Special room in footer reserved for encryption. */ 102 typedef enum { 103 IEEE80211_TKIP_FOOTER_LENGTH = 4, 104 IEEE80211_CCMP_FOOTER_LENGTH = 8 105 } ieee80211_encrypt_footer_reserve_length_t; 97 106 98 107 /** IEEE 802.11 PTK key length. */ … … 199 208 time_t last_beacon; 200 209 ieee80211_scan_result_t scan_result; 201 uint8_t rsn_copy[256];202 size_t rsn_copy_len;210 uint8_t auth_ie[256]; 211 size_t auth_ie_len; 203 212 } ieee80211_scan_result_link_t; 204 213 -
uspace/lib/ieee80211/src/ieee80211.c
r053fc2b ra931b7b 504 504 while(true) { 505 505 ieee80211_dev->ops->scan(ieee80211_dev); 506 async_usleep( 35000000);506 async_usleep(SCAN_PERIOD_USEC); 507 507 } 508 508 … … 577 577 memset(add_data, 0, 8); 578 578 579 // TODO: Distinguish used key (pair/group) by dest address ? 579 580 if(ieee80211_query_using_key(ieee80211_dev)) { 580 581 int sec_suite = auth_data->security.pair_alg; 581 582 switch(sec_suite) { 583 case IEEE80211_SECURITY_SUITE_TKIP: 584 add_size = IEEE80211_TKIP_HEADER_LENGTH; 585 // TODO: Add data? 586 break; 582 587 case IEEE80211_SECURITY_SUITE_CCMP: 583 588 add_size = IEEE80211_CCMP_HEADER_LENGTH; … … 978 983 payload_size; 979 984 980 if(auth_data->security.type == IEEE80211_SECURITY_WPA2) { 981 buffer_size += auth_link->rsn_copy_len; 985 if(auth_data->security.type == IEEE80211_SECURITY_WPA || 986 auth_data->security.type == IEEE80211_SECURITY_WPA2) { 987 buffer_size += auth_link->auth_ie_len; 982 988 } 983 989 … … 1017 1023 } 1018 1024 1019 if(auth_data->security.type == IEEE80211_SECURITY_WPA2) { 1020 memcpy(it, auth_link->rsn_copy, auth_link->rsn_copy_len); 1025 if(auth_data->security.type == IEEE80211_SECURITY_WPA || 1026 auth_data->security.type == IEEE80211_SECURITY_WPA2) { 1027 memcpy(it, auth_link->auth_ie, auth_link->auth_ie_len); 1021 1028 } 1022 1029 … … 1037 1044 /** 1038 1045 * IEEE 802.11 deauthentication implementation. 1046 * 1047 * Note: Expecting locked results_mutex or scan_mutex. 1039 1048 * 1040 1049 * @param ieee80211_dev Pointer to IEEE 802.11 device structure. … … 1147 1156 { 1148 1157 return (*seq << 24) + (*(seq+1) << 16) + (*(seq+2) << 8) + *(seq+3); 1158 } 1159 1160 static void copy_auth_ie(ieee80211_ie_header_t *ie_header, 1161 ieee80211_scan_result_link_t *ap_data, void *it) 1162 { 1163 ap_data->auth_ie_len = ie_header->length + 1164 sizeof(ieee80211_ie_header_t); 1165 1166 memcpy(ap_data->auth_ie, it, ap_data->auth_ie_len); 1149 1167 } 1150 1168 … … 1170 1188 ieee80211_process_auth_info(ap_data, 1171 1189 it + sizeof(ieee80211_ie_header_t)); 1172 ap_data->rsn_copy_len = ie_header->length + 1173 sizeof(ieee80211_ie_header_t); 1174 memcpy(ap_data->rsn_copy, 1175 it, 1176 ap_data->rsn_copy_len); 1190 copy_auth_ie(ie_header, ap_data, it); 1177 1191 break; 1178 1192 case IEEE80211_VENDOR_IE: … … 1180 1194 sizeof(ieee80211_ie_header_t)) == 1181 1195 WPA_OUI) { 1196 /* Prefering WPA2. */ 1182 1197 if(ap_data->scan_result.security.type == 1183 1198 IEEE80211_SECURITY_WPA2) { … … 1190 1205 sizeof(ieee80211_ie_header_t) + 1191 1206 sizeof(uint32_t)); 1207 copy_auth_ie(ie_header, ap_data, it); 1192 1208 } else if(uint32_from_uint8_seq(it + 1193 1209 sizeof(ieee80211_ie_header_t)) == … … 1356 1372 (ieee80211_eapol_key_frame_t *) buffer; 1357 1373 1358 bool handshake_done = false; 1359 1360 ieee80211_scan_result_link_t *auth_link = 1374 ieee80211_scan_result_link_t *auth_link = 1361 1375 ieee80211_dev->bssid_info.res_link; 1362 1376 1363 1377 ieee80211_scan_result_t *auth_data = &auth_link->scan_result; 1378 1379 /* We don't support 802.1X authentication yet. */ 1380 if(auth_data->security.auth == IEEE80211_AUTH_AKM_8021X) { 1381 return ENOTSUP; 1382 } 1383 1364 1384 uint8_t *ptk = ieee80211_dev->bssid_info.ptk; 1365 1385 uint8_t *gtk = ieee80211_dev->bssid_info.gtk; 1366 1386 1387 bool handshake_done = false; 1388 1389 bool old_wpa = 1390 auth_data->security.type == IEEE80211_SECURITY_WPA; 1391 1392 bool key_phase = 1393 uint16_t_be2host(key_frame->key_info) & 1394 IEEE80211_EAPOL_KEY_KEYINFO_MIC; 1395 1396 bool final_phase = 1397 uint16_t_be2host(key_frame->key_info) & 1398 IEEE80211_EAPOL_KEY_KEYINFO_SECURE; 1399 1400 bool ccmp_used = 1401 auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP || 1402 auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP; 1403 1367 1404 size_t ptk_key_length, gtk_key_length; 1368 hash_func_t hash_sel; 1369 switch(auth_data->security.pair_alg) { 1370 case IEEE80211_SECURITY_SUITE_CCMP: 1371 ptk_key_length = IEEE80211_PTK_CCMP_LENGTH; 1372 hash_sel = HASH_SHA1; 1373 break; 1374 default: 1375 return ENOTSUP; 1376 } 1377 1378 switch(auth_data->security.group_alg) { 1379 case IEEE80211_SECURITY_SUITE_CCMP: 1380 gtk_key_length = IEEE80211_GTK_CCMP_LENGTH; 1381 break; 1382 default: 1383 return ENOTSUP; 1384 } 1385 1405 hash_func_t mic_hash; 1406 if(ccmp_used) { 1407 mic_hash = HASH_SHA1; 1408 } else { 1409 mic_hash = HASH_MD5; 1410 } 1411 1412 if(auth_data->security.pair_alg == IEEE80211_SECURITY_SUITE_CCMP) { 1413 ptk_key_length = IEEE80211_PTK_CCMP_LENGTH; 1414 } else { 1415 ptk_key_length = IEEE80211_PTK_TKIP_LENGTH; 1416 } 1417 1418 if(auth_data->security.group_alg == IEEE80211_SECURITY_SUITE_CCMP) { 1419 gtk_key_length = IEEE80211_GTK_CCMP_LENGTH; 1420 } else { 1421 gtk_key_length = IEEE80211_GTK_TKIP_LENGTH; 1422 } 1423 1386 1424 size_t output_size = 1387 1425 sizeof(eth_header_t) + … … 1389 1427 1390 1428 if(!(uint16_t_be2host(key_frame->key_info) & 1391 IEEE80211_EAPOL_KEY_KEYINFO_ SECURE)) {1392 output_size += auth_link-> rsn_copy_len;1429 IEEE80211_EAPOL_KEY_KEYINFO_MIC)) { 1430 output_size += auth_link->auth_ie_len; 1393 1431 } 1394 1432 … … 1415 1453 1416 1454 output_key_frame->proto_version = 0x1; 1417 output_key_frame->key_length = 0;1418 1455 output_key_frame->body_length = 1419 host2uint16_t_be(output_size - sizeof(eth_header_t) -4);1456 host2uint16_t_be(output_size - sizeof(eth_header_t) - 4); 1420 1457 output_key_frame->key_info &= 1421 1458 ~host2uint16_t_be( … … 1423 1460 ); 1424 1461 1425 /* 1426 * Check if it is last or first incoming message in 4-way 1427 * handshake. 1428 */ 1429 if(uint16_t_be2host(key_frame->key_info) & 1430 IEEE80211_EAPOL_KEY_KEYINFO_SECURE) { 1462 if(key_phase) { 1431 1463 output_key_frame->key_info &= 1432 1464 ~host2uint16_t_be( … … 1438 1470 ); 1439 1471 output_key_frame->key_data_length = 0; 1440 output_key_frame->key_length = 0;1441 1472 memset(output_key_frame->key_nonce, 0, 32); 1442 1473 memset(output_key_frame->key_mic, 0, 16); … … 1445 1476 1446 1477 /* Derive GTK and save it. */ 1447 uint16_t key_data_length = 1448 uint16_t_be2host(key_frame->key_data_length); 1449 uint16_t decrypt_len = key_data_length - 8; 1450 uint8_t key_data[decrypt_len]; 1451 uint8_t *data_ptr = (uint8_t *) (buffer + 1452 sizeof(ieee80211_eapol_key_frame_t)); 1453 if(ieee80211_aes_key_unwrap(ptk + KEK_OFFSET, data_ptr, 1454 key_data_length, key_data) == EOK) { 1478 if(final_phase) { 1479 uint16_t key_data_length = 1480 uint16_t_be2host(key_frame->key_data_length); 1481 uint8_t key_data[key_data_length]; 1482 uint8_t *data_ptr = (uint8_t *) (buffer + 1483 sizeof(ieee80211_eapol_key_frame_t)); 1484 1485 int rc; 1486 uint8_t work_key[32]; 1487 1488 if(ccmp_used) { 1489 rc = ieee80211_aes_key_unwrap(ptk + KEK_OFFSET, 1490 data_ptr, key_data_length, key_data); 1491 } else { 1492 memcpy(work_key, key_frame->eapol_key_iv, 16); 1493 memcpy(work_key + 16, ptk + KEK_OFFSET, 16); 1494 rc = ieee80211_rc4_key_unwrap(work_key, 1495 data_ptr, key_data_length, key_data); 1496 } 1455 1497 1456 uint8_t *key_ptr = ieee80211_process_ies(ieee80211_dev, 1457 NULL, key_data, decrypt_len); 1458 1459 if(key_ptr) { 1460 memcpy(gtk, key_ptr, gtk_key_length); 1461 handshake_done = true; 1498 if(rc == EOK) { 1499 uint8_t *key_ptr = old_wpa ? key_data : 1500 ieee80211_process_ies(ieee80211_dev, 1501 NULL, key_data, key_data_length); 1502 1503 if(key_ptr) { 1504 memcpy(gtk, key_ptr, gtk_key_length); 1505 handshake_done = true; 1506 } 1462 1507 } 1463 1508 } … … 1468 1513 ); 1469 1514 output_key_frame->key_data_length = 1470 host2uint16_t_be(auth_link-> rsn_copy_len);1515 host2uint16_t_be(auth_link->auth_ie_len); 1471 1516 memcpy((void *)output_key_frame + 1472 1517 sizeof(ieee80211_eapol_key_frame_t), 1473 auth_link-> rsn_copy,1474 auth_link-> rsn_copy_len);1518 auth_link->auth_ie, 1519 auth_link->auth_ie_len); 1475 1520 1476 1521 /* Compute PMK. */ … … 1479 1524 str_size(ieee80211_dev->bssid_info.password), 1480 1525 (uint8_t *) auth_data->ssid, 1481 str_size(auth_data->ssid), pmk , hash_sel);1526 str_size(auth_data->ssid), pmk); 1482 1527 1483 1528 uint8_t *anonce = key_frame->key_nonce; … … 1493 1538 1494 1539 /* Derive PTK and save it. */ 1495 uint8_t prf_result[ptk_key_length];1496 1540 uint8_t crypt_data[PRF_CRYPT_DATA_LENGTH]; 1497 1541 memcpy(crypt_data, … … 1507 1551 max_sequence(anonce, snonce, 32), 1508 1552 32); 1509 ieee80211_prf(pmk, crypt_data, prf_result, hash_sel); 1510 memcpy(ptk, prf_result, ptk_key_length); 1553 ieee80211_prf(pmk, crypt_data, ptk, ptk_key_length); 1511 1554 } 1512 1555 1513 1556 /* Compute MIC of key frame data from KCK part of PTK. */ 1514 uint8_t mic[ hash_sel];1557 uint8_t mic[mic_hash]; 1515 1558 hmac(ptk, 16, (uint8_t *) output_key_frame, 1516 output_size - sizeof(eth_header_t), mic, hash_sel);1559 output_size - sizeof(eth_header_t), mic, mic_hash); 1517 1560 1518 1561 memcpy(output_key_frame->key_mic, mic, 16); … … 1522 1565 free(output_buffer); 1523 1566 1524 if(handshake_done) { 1525 /* Insert Pairwise key. */ 1526 ieee80211_key_config_t key_config; 1567 ieee80211_key_config_t key_config; 1568 1569 /* Insert Pairwise key. */ 1570 if((key_phase && old_wpa) || (final_phase && !old_wpa)) { 1527 1571 key_config.suite = auth_data->security.pair_alg; 1528 1572 key_config.flags = … … 1534 1578 ieee80211_dev->ops->key_config(ieee80211_dev, 1535 1579 &key_config, true); 1536 1537 /* Insert Group key. */ 1580 } 1581 1582 /* Insert Group key. */ 1583 if(final_phase) { 1538 1584 key_config.suite = auth_data->security.group_alg; 1539 1585 key_config.flags = … … 1543 1589 ieee80211_dev->ops->key_config(ieee80211_dev, 1544 1590 &key_config, true); 1545 1546 /* Signal successful handshake completion. */ 1591 } 1592 1593 /* Signal successful handshake completion. */ 1594 if(handshake_done) { 1547 1595 fibril_mutex_lock(&ieee80211_dev->gen_mutex); 1548 1596 fibril_condvar_signal(&ieee80211_dev->gen_cond); … … 1586 1634 ARRAY_SIZE(rfc1042_header); 1587 1635 1588 /* TODO: Probably different by used security alg. */ 1636 /* TODO: Different by used security alg. */ 1637 /* TODO: Trim frame by used security alg. */ 1638 // TODO: Distinguish used key (pair/group) by dest address ? 1589 1639 if(ieee80211_is_encrypted_frame(data_header->frame_ctrl)) { 1590 1640 strip_length += 8; -
uspace/lib/ieee80211/src/ieee80211_impl.c
r053fc2b ra931b7b 165 165 166 166 /** 167 * Pseudorandom function used for IEEE 802.11 pairwise key computation. 167 * Pseudorandom function used for IEEE 802.11 pairwise key computation 168 * using SHA1 hash algorithm. 168 169 * 169 170 * @param key Key with PBKDF2 encrypted passphrase. 170 171 * @param data Concatenated sequence of both mac addresses and nonces. 171 * @param hash Output parameter for result hash (48 byte value).172 * @param hash_sel Hash function selector.172 * @param hash Output parameter for result hash. 173 * @param output_size Length of output sequence to be generated. 173 174 * 174 175 * @return EINVAL when key or data not specified, ENOMEM when pointer for … … 176 177 */ 177 178 int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash, 178 hash_func_t hash_sel)179 size_t output_size) 179 180 { 180 181 if(!key || !data) … … 184 185 return ENOMEM; 185 186 186 size_t result_length = (hash_sel == HASH_MD5) ? 187 IEEE80211_PTK_TKIP_LENGTH : IEEE80211_PTK_CCMP_LENGTH; 188 size_t iters = ((result_length * 8) + 159) / 160; 187 size_t iters = ((output_size * 8) + 159) / 160; 189 188 190 189 const char *a = "Pairwise key expansion"; 191 uint8_t result[ hash_sel*iters];192 uint8_t temp[ hash_sel];190 uint8_t result[HASH_SHA1*iters]; 191 uint8_t temp[HASH_SHA1]; 193 192 size_t data_size = PRF_CRYPT_DATA_LENGTH + str_size(a) + 2; 194 193 uint8_t work_arr[data_size]; … … 201 200 memcpy(work_arr + data_size - 1, &i, 1); 202 201 hmac(key, PBKDF2_KEY_LENGTH, work_arr, data_size, temp, 203 hash_sel); 204 memcpy(result + i*hash_sel, temp, hash_sel); 205 } 206 207 memcpy(hash, result, result_length); 208 209 return EOK; 202 HASH_SHA1); 203 memcpy(result + i*HASH_SHA1, temp, HASH_SHA1); 204 } 205 206 memcpy(hash, result, output_size); 207 208 return EOK; 209 } 210 211 int ieee80211_rc4_key_unwrap(uint8_t *key, uint8_t *data, size_t data_size, 212 uint8_t *output) 213 { 214 return rc4(key, 32, data, data_size, 256, output); 210 215 } 211 216 … … 230 235 231 236 memcpy(work_data, data + 8, n*8); 232 for(int j = 5; j >= 0; j--) {237 for(int j = 5; j >= 0; j--) { 233 238 for(int i = n; i > 0; i--) { 234 239 for(size_t k = 0; k < 8; k++) {
Note:
See TracChangeset
for help on using the changeset viewer.