Changeset a931b7b in mainline


Ignore:
Timestamp:
2015-04-13T20:48:33Z (9 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc575ef9
Parents:
053fc2b
Message:

Added TKIP support, handling old WPA in 4way handshake, some fixes in wifi_supplicant app

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/wifi_supplicant/wifi_supplicant.c

    r053fc2b ra931b7b  
    187187        }
    188188       
    189         ieee80211_connect(sess, ssid_start, password);
     189        rc = ieee80211_connect(sess, ssid_start, password);
    190190        if(rc != EOK) {
    191191                if(rc == EREFUSED) {
  • uspace/drv/nic/ar9271/ar9271.c

    r053fc2b ra931b7b  
    440440                uint32_t key[5];
    441441                uint32_t key_type;
    442                 uint32_t reg_ptr;
     442                uint32_t reg_ptr, mic_reg_ptr;
    443443                void *data_start;
    444444               
     
    465465                if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) {
    466466                        reg_ptr = AR9271_KEY_TABLE_STA;
     467                        mic_reg_ptr = AR9271_KEY_TABLE_MIC_STA;
    467468                } else {
    468469                        reg_ptr = AR9271_KEY_TABLE_GRP;
     470                        mic_reg_ptr = AR9271_KEY_TABLE_MIC_GRP;
    469471                }
    470472               
    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;
    499489                }
     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);
    500497               
    501498                uint32_t macL, macH;
     
    516513                wmi_reg_write(ar9271->htc_device, reg_ptr + 24, macL);
    517514                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                }
    518556               
    519557                if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP)
  • uspace/drv/nic/ar9271/ar9271.h

    r053fc2b ra931b7b  
    138138        AR9271_KEY_TABLE_GRP = 0x8820,
    139139        AR9271_KEY_TABLE_STA = 0x8880,
     140        AR9271_KEY_TABLE_MIC_GRP = 0x9020,
     141        AR9271_KEY_TABLE_MIC_STA = 0x9080,
    140142        AR9271_KEY_TABLE_TYPE_WEP40 = 0x0,
    141143        AR9271_KEY_TABLE_TYPE_WEP104 = 0x1,
    142144        AR9271_KEY_TABLE_TYPE_TKIP = 0x4,
    143145        AR9271_KEY_TABLE_TYPE_CCMP = 0x6,
     146        AR9271_KEY_TABLE_TYPE_CLR = 0x7,
    144147               
    145148        /* Physical layer registers */
  • uspace/lib/crypto/crypto.c

    r053fc2b ra931b7b  
    252252
    253253/**
    254  * Hash-based message authentication code using SHA-1 algorithm.
     254 * Hash-based message authentication code.
    255255 *
    256256 * @param key Cryptographic key sequence.
     
    308308 * Password-Based Key Derivation Function 2 as defined in RFC 2898,
    309309 * using HMAC-SHA1 with 4096 iterations and 32 bytes key result used
    310  * for WPA2.
     310 * for WPA/WPA2.
    311311 *
    312312 * @param pass Password sequence.
     
    315315 * @param salt_size Salt sequence length.
    316316 * @param hash Output parameter for result hash (32 byte value).
    317  * @param hash_sel Hash function selector.
    318317 *
    319318 * @return EINVAL when pass or salt not specified, ENOMEM when pointer for
     
    321320 */
    322321int 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)
    324323{
    325324        if(!pass || !salt)
     
    331330        uint8_t work_salt[salt_size + sizeof(uint32_t)];
    332331        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];
    337336       
    338337        for(size_t i = 0; i < 2; i++) {
     
    340339                memcpy(work_salt + salt_size, &big_i, sizeof(uint32_t));
    341340                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);
    344343                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++) {
    349348                                xor_hmac[t] ^= work_hmac[t];
    350349                        }
    351350                }
    352                 memcpy(temp_hash + i*hash_sel, xor_hmac, hash_sel);
     351                memcpy(temp_hash + i*HASH_SHA1, xor_hmac, HASH_SHA1);
    353352        }
    354353       
  • uspace/lib/crypto/crypto.h

    r053fc2b ra931b7b  
    4141} hash_func_t;
    4242
    43 extern int rc4(uint8_t *key, size_t key_size, uint8_t *input,
    44         size_t input_size, uint8_t *output);
     43extern int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size,
     44        size_t skip, uint8_t *output);
    4545extern int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output);
    4646extern int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output);
     
    5050        uint8_t *hash, hash_func_t hash_sel);
    5151extern 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);
    5353
    5454#endif
  • uspace/lib/crypto/rc4.c

    r053fc2b ra931b7b  
    8282 * @param input Input data sequence to be processed.
    8383 * @param input_size Size of input data sequence.
     84 * @param skip Number of bytes to be skipped from the beginning of key stream.
    8485 * @param output Result data sequence.
    8586 *
     
    8889 */
    8990int 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)
    9192{
    9293        if(!key || !input)
     
    100101        create_sbox(key, key_size, sbox);
    101102       
     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       
    102111        /* Processing loop. */
    103         uint8_t i = 0, j = 0, val;
     112        uint8_t val;
    104113        for(size_t k = 0; k < input_size; k++) {
    105114                i = i+1;
  • uspace/lib/ieee80211/include/ieee80211.h

    r053fc2b ra931b7b  
    8282} ieee80211_key_flags_t;
    8383
     84typedef enum {
     85        IEEE80211_TKIP_TX_MIC_OFFSET = 16,
     86        IEEE80211_TKIP_RX_MIC_OFFSET = 24
     87} ieee80211_tkip_mic_offset_t;
     88
    8489/** Key config structure. */
    8590typedef struct {
  • uspace/lib/ieee80211/include/ieee80211_impl.h

    r053fc2b ra931b7b  
    5353extern int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev);
    5454extern int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash,
    55         hash_func_t hash_sel);
     55        size_t output_size);
     56extern int ieee80211_rc4_key_unwrap(uint8_t *key, uint8_t *data,
     57        size_t data_size, uint8_t *output);
    5658extern int ieee80211_aes_key_unwrap(uint8_t *kek, uint8_t *data,
    5759        size_t data_size, uint8_t *output);
  • uspace/lib/ieee80211/include/ieee80211_private.h

    r053fc2b ra931b7b  
    5252
    5353/* Timeout in us for waiting to finish 4-way handshake process. */
    54 #define HANDSHAKE_TIMEOUT 3000000
     54#define HANDSHAKE_TIMEOUT 5000000
    5555
    5656/* Scanning period. */
     
    8686/* TK offset inside PTK. */
    8787#define TK_OFFSET 32
    88 
    89 /* Length of CCMP header we need to reserve. */
    90 #define IEEE80211_CCMP_HEADER_LENGTH 8
    9188
    9289/*
     
    9592 */
    9693#define PRF_CRYPT_DATA_LENGTH 2*32 + 2*ETH_ADDR
     94
     95/* Special room in header reserved for encryption. */
     96typedef 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. */
     102typedef enum {
     103        IEEE80211_TKIP_FOOTER_LENGTH = 4,
     104        IEEE80211_CCMP_FOOTER_LENGTH = 8
     105} ieee80211_encrypt_footer_reserve_length_t;
    97106
    98107/** IEEE 802.11 PTK key length. */
     
    199208        time_t last_beacon;
    200209        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;
    203212} ieee80211_scan_result_link_t;
    204213
  • uspace/lib/ieee80211/src/ieee80211.c

    r053fc2b ra931b7b  
    504504        while(true) {
    505505                ieee80211_dev->ops->scan(ieee80211_dev);
    506                 async_usleep(35000000);
     506                async_usleep(SCAN_PERIOD_USEC);
    507507        }
    508508       
     
    577577        memset(add_data, 0, 8);
    578578       
     579        // TODO: Distinguish used key (pair/group) by dest address ?
    579580        if(ieee80211_query_using_key(ieee80211_dev)) {
    580581                int sec_suite = auth_data->security.pair_alg;
    581582                switch(sec_suite) {
     583                        case IEEE80211_SECURITY_SUITE_TKIP:
     584                                add_size = IEEE80211_TKIP_HEADER_LENGTH;
     585                                // TODO: Add data?
     586                                break;
    582587                        case IEEE80211_SECURITY_SUITE_CCMP:
    583588                                add_size = IEEE80211_CCMP_HEADER_LENGTH;
     
    978983                payload_size;
    979984       
    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;
    982988        }
    983989       
     
    10171023        }
    10181024       
    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);
    10211028        }
    10221029       
     
    10371044/**
    10381045 * IEEE 802.11 deauthentication implementation.
     1046 *
     1047 * Note: Expecting locked results_mutex or scan_mutex.
    10391048 *
    10401049 * @param ieee80211_dev Pointer to IEEE 802.11 device structure.
     
    11471156{
    11481157        return (*seq << 24) + (*(seq+1) << 16) + (*(seq+2) << 8) + *(seq+3);
     1158}
     1159
     1160static 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);
    11491167}
    11501168
     
    11701188                                ieee80211_process_auth_info(ap_data,
    11711189                                        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);
    11771191                                break;
    11781192                        case IEEE80211_VENDOR_IE:
     
    11801194                                        sizeof(ieee80211_ie_header_t)) ==
    11811195                                        WPA_OUI) {
     1196                                        /* Prefering WPA2. */
    11821197                                        if(ap_data->scan_result.security.type ==
    11831198                                                IEEE80211_SECURITY_WPA2) {
     
    11901205                                                sizeof(ieee80211_ie_header_t) +
    11911206                                                sizeof(uint32_t));
     1207                                        copy_auth_ie(ie_header, ap_data, it);
    11921208                                } else if(uint32_from_uint8_seq(it +
    11931209                                        sizeof(ieee80211_ie_header_t)) ==
     
    13561372                (ieee80211_eapol_key_frame_t *) buffer;
    13571373       
    1358         bool handshake_done = false;
    1359                
    1360         ieee80211_scan_result_link_t *auth_link =
     1374        ieee80211_scan_result_link_t *auth_link =
    13611375                ieee80211_dev->bssid_info.res_link;
    13621376
    13631377        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       
    13641384        uint8_t *ptk = ieee80211_dev->bssid_info.ptk;
    13651385        uint8_t *gtk = ieee80211_dev->bssid_info.gtk;
    13661386
     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       
    13671404        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       
    13861424        size_t output_size =
    13871425                sizeof(eth_header_t) +
     
    13891427
    13901428        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;
    13931431        }
    13941432
     
    14151453
    14161454        output_key_frame->proto_version = 0x1;
    1417         output_key_frame->key_length = 0;
    14181455        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);
    14201457        output_key_frame->key_info &=
    14211458                ~host2uint16_t_be(
     
    14231460                );
    14241461
    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) {
    14311463                output_key_frame->key_info &=
    14321464                        ~host2uint16_t_be(
     
    14381470                        );
    14391471                output_key_frame->key_data_length = 0;
    1440                 output_key_frame->key_length = 0;
    14411472                memset(output_key_frame->key_nonce, 0, 32);
    14421473                memset(output_key_frame->key_mic, 0, 16);
     
    14451476
    14461477                /* 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                        }
    14551497                       
    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                                }
    14621507                        }
    14631508                }
     
    14681513                        );
    14691514                output_key_frame->key_data_length =
    1470                         host2uint16_t_be(auth_link->rsn_copy_len);
     1515                        host2uint16_t_be(auth_link->auth_ie_len);
    14711516                memcpy((void *)output_key_frame +
    14721517                        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);
    14751520
    14761521                /* Compute PMK. */
     
    14791524                        str_size(ieee80211_dev->bssid_info.password),
    14801525                        (uint8_t *) auth_data->ssid,
    1481                         str_size(auth_data->ssid), pmk, hash_sel);
     1526                        str_size(auth_data->ssid), pmk);
    14821527
    14831528                uint8_t *anonce = key_frame->key_nonce;
     
    14931538
    14941539                /* Derive PTK and save it. */
    1495                 uint8_t prf_result[ptk_key_length];
    14961540                uint8_t crypt_data[PRF_CRYPT_DATA_LENGTH];
    14971541                memcpy(crypt_data,
     
    15071551                        max_sequence(anonce, snonce, 32),
    15081552                        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);
    15111554        }
    15121555
    15131556        /* Compute MIC of key frame data from KCK part of PTK. */
    1514         uint8_t mic[hash_sel];
     1557        uint8_t mic[mic_hash];
    15151558        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);
    15171560
    15181561        memcpy(output_key_frame->key_mic, mic, 16);
     
    15221565        free(output_buffer);
    15231566
    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)) {
    15271571                key_config.suite = auth_data->security.pair_alg;
    15281572                key_config.flags =
     
    15341578                ieee80211_dev->ops->key_config(ieee80211_dev,
    15351579                        &key_config, true);
    1536                
    1537                 /* Insert Group key. */
     1580        }
     1581       
     1582        /* Insert Group key. */
     1583        if(final_phase) {
    15381584                key_config.suite = auth_data->security.group_alg;
    15391585                key_config.flags =
     
    15431589                ieee80211_dev->ops->key_config(ieee80211_dev,
    15441590                        &key_config, true);
    1545 
    1546                 /* Signal successful handshake completion. */
     1591        }
     1592
     1593        /* Signal successful handshake completion. */
     1594        if(handshake_done) {
    15471595                fibril_mutex_lock(&ieee80211_dev->gen_mutex);
    15481596                fibril_condvar_signal(&ieee80211_dev->gen_cond);
     
    15861634                        ARRAY_SIZE(rfc1042_header);
    15871635               
    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 ?
    15891639                if(ieee80211_is_encrypted_frame(data_header->frame_ctrl)) {
    15901640                        strip_length += 8;
  • uspace/lib/ieee80211/src/ieee80211_impl.c

    r053fc2b ra931b7b  
    165165
    166166/**
    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.
    168169 *
    169170 * @param key Key with PBKDF2 encrypted passphrase.
    170171 * @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.
    173174 *
    174175 * @return EINVAL when key or data not specified, ENOMEM when pointer for
     
    176177 */
    177178int ieee80211_prf(uint8_t *key, uint8_t *data, uint8_t *hash,
    178         hash_func_t hash_sel)
     179        size_t output_size)
    179180{
    180181        if(!key || !data)
     
    184185                return ENOMEM;
    185186       
    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;
    189188       
    190189        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];
    193192        size_t data_size = PRF_CRYPT_DATA_LENGTH + str_size(a) + 2;
    194193        uint8_t work_arr[data_size];
     
    201200                memcpy(work_arr + data_size - 1, &i, 1);
    202201                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
     211int 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);
    210215}
    211216
     
    230235       
    231236        memcpy(work_data, data + 8, n*8);
    232         for(int j = 5; j >=0; j--) {
     237        for(int j = 5; j >= 0; j--) {
    233238                for(int i = n; i > 0; i--) {
    234239                        for(size_t k = 0; k < 8; k++) {
Note: See TracChangeset for help on using the changeset viewer.