wps_common.c (302408) | wps_common.c (337817) |
---|---|
1/* 2 * Wi-Fi Protected Setup - common functionality 3 * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 --- 76 unchanged lines hidden (view full) --- 85 wps->dh_ctx = NULL; 86 dh_shared = wpabuf_zeropad(dh_shared, 192); 87 if (dh_shared == NULL) { 88 wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key"); 89 return -1; 90 } 91 92 /* Own DH private key is not needed anymore */ | 1/* 2 * Wi-Fi Protected Setup - common functionality 3 * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 --- 76 unchanged lines hidden (view full) --- 85 wps->dh_ctx = NULL; 86 dh_shared = wpabuf_zeropad(dh_shared, 192); 87 if (dh_shared == NULL) { 88 wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key"); 89 return -1; 90 } 91 92 /* Own DH private key is not needed anymore */ |
93 wpabuf_free(wps->dh_privkey); | 93 wpabuf_clear_free(wps->dh_privkey); |
94 wps->dh_privkey = NULL; 95 96 wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared); 97 98 /* DHKey = SHA-256(g^AB mod p) */ 99 addr[0] = wpabuf_head(dh_shared); 100 len[0] = wpabuf_len(dh_shared); 101 sha256_vector(1, addr, len, dhkey); 102 wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey)); | 94 wps->dh_privkey = NULL; 95 96 wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared); 97 98 /* DHKey = SHA-256(g^AB mod p) */ 99 addr[0] = wpabuf_head(dh_shared); 100 len[0] = wpabuf_len(dh_shared); 101 sha256_vector(1, addr, len, dhkey); 102 wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey)); |
103 wpabuf_free(dh_shared); | 103 wpabuf_clear_free(dh_shared); |
104 105 /* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */ 106 addr[0] = wps->nonce_e; 107 len[0] = WPS_NONCE_LEN; 108 addr[1] = wps->mac_addr_e; 109 len[1] = ETH_ALEN; 110 addr[2] = wps->nonce_r; 111 len[2] = WPS_NONCE_LEN; --- 12 unchanged lines hidden (view full) --- 124 wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey", 125 wps->keywrapkey, WPS_KEYWRAPKEY_LEN); 126 wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN); 127 128 return 0; 129} 130 131 | 104 105 /* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */ 106 addr[0] = wps->nonce_e; 107 len[0] = WPS_NONCE_LEN; 108 addr[1] = wps->mac_addr_e; 109 len[1] = ETH_ALEN; 110 addr[2] = wps->nonce_r; 111 len[2] = WPS_NONCE_LEN; --- 12 unchanged lines hidden (view full) --- 124 wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey", 125 wps->keywrapkey, WPS_KEYWRAPKEY_LEN); 126 wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN); 127 128 return 0; 129} 130 131 |
132void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd, 133 size_t dev_passwd_len) | 132int wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd, 133 size_t dev_passwd_len) |
134{ 135 u8 hash[SHA256_MAC_LEN]; 136 | 134{ 135 u8 hash[SHA256_MAC_LEN]; 136 |
137 hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd, 138 (dev_passwd_len + 1) / 2, hash); | 137 if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd, 138 (dev_passwd_len + 1) / 2, hash) < 0) 139 return -1; |
139 os_memcpy(wps->psk1, hash, WPS_PSK_LEN); | 140 os_memcpy(wps->psk1, hash, WPS_PSK_LEN); |
140 hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, 141 dev_passwd + (dev_passwd_len + 1) / 2, 142 dev_passwd_len / 2, hash); | 141 if (hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, 142 dev_passwd + (dev_passwd_len + 1) / 2, 143 dev_passwd_len / 2, hash) < 0) 144 return -1; |
143 os_memcpy(wps->psk2, hash, WPS_PSK_LEN); 144 145 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password", 146 dev_passwd, dev_passwd_len); 147 wpa_hexdump_key(MSG_DEBUG, "WPS: PSK1", wps->psk1, WPS_PSK_LEN); 148 wpa_hexdump_key(MSG_DEBUG, "WPS: PSK2", wps->psk2, WPS_PSK_LEN); | 145 os_memcpy(wps->psk2, hash, WPS_PSK_LEN); 146 147 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password", 148 dev_passwd, dev_passwd_len); 149 wpa_hexdump_key(MSG_DEBUG, "WPS: PSK1", wps->psk1, WPS_PSK_LEN); 150 wpa_hexdump_key(MSG_DEBUG, "WPS: PSK2", wps->psk2, WPS_PSK_LEN); |
151 return 0; |
|
149} 150 151 152struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr, 153 size_t encr_len) 154{ 155 struct wpabuf *decrypted; 156 const size_t block_size = 16; --- 11 unchanged lines hidden (view full) --- 168 decrypted = wpabuf_alloc(encr_len - block_size); 169 if (decrypted == NULL) 170 return NULL; 171 172 wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len); 173 wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size); 174 if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted), 175 wpabuf_len(decrypted))) { | 152} 153 154 155struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr, 156 size_t encr_len) 157{ 158 struct wpabuf *decrypted; 159 const size_t block_size = 16; --- 11 unchanged lines hidden (view full) --- 171 decrypted = wpabuf_alloc(encr_len - block_size); 172 if (decrypted == NULL) 173 return NULL; 174 175 wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len); 176 wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size); 177 if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted), 178 wpabuf_len(decrypted))) { |
176 wpabuf_free(decrypted); | 179 wpabuf_clear_free(decrypted); |
177 return NULL; 178 } 179 180 wpa_hexdump_buf_key(MSG_MSGDUMP, "WPS: Decrypted Encrypted Settings", 181 decrypted); 182 183 pos = wpabuf_head_u8(decrypted) + wpabuf_len(decrypted) - 1; 184 pad = *pos; 185 if (pad > wpabuf_len(decrypted)) { 186 wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value"); | 180 return NULL; 181 } 182 183 wpa_hexdump_buf_key(MSG_MSGDUMP, "WPS: Decrypted Encrypted Settings", 184 decrypted); 185 186 pos = wpabuf_head_u8(decrypted) + wpabuf_len(decrypted) - 1; 187 pad = *pos; 188 if (pad > wpabuf_len(decrypted)) { 189 wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value"); |
187 wpabuf_free(decrypted); | 190 wpabuf_clear_free(decrypted); |
188 return NULL; 189 } 190 for (i = 0; i < pad; i++) { 191 if (*pos-- != pad) { 192 wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad " 193 "string"); | 191 return NULL; 192 } 193 for (i = 0; i < pad; i++) { 194 if (*pos-- != pad) { 195 wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad " 196 "string"); |
194 wpabuf_free(decrypted); | 197 wpabuf_clear_free(decrypted); |
195 return NULL; 196 } 197 } 198 decrypted->used -= pad; 199 200 return decrypted; 201} 202 --- 27 unchanged lines hidden (view full) --- 230 return wps_pin_checksum(pin / 10) == (pin % 10); 231} 232 233 234/** 235 * wps_generate_pin - Generate a random PIN 236 * Returns: Eight digit PIN (i.e., including the checksum digit) 237 */ | 198 return NULL; 199 } 200 } 201 decrypted->used -= pad; 202 203 return decrypted; 204} 205 --- 27 unchanged lines hidden (view full) --- 233 return wps_pin_checksum(pin / 10) == (pin % 10); 234} 235 236 237/** 238 * wps_generate_pin - Generate a random PIN 239 * Returns: Eight digit PIN (i.e., including the checksum digit) 240 */ |
238unsigned int wps_generate_pin(void) | 241int wps_generate_pin(unsigned int *pin) |
239{ 240 unsigned int val; 241 242 /* Generate seven random digits for the PIN */ | 242{ 243 unsigned int val; 244 245 /* Generate seven random digits for the PIN */ |
243 if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) { 244 struct os_time now; 245 os_get_time(&now); 246 val = os_random() ^ now.sec ^ now.usec; 247 } | 246 if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) 247 return -1; |
248 val %= 10000000; 249 250 /* Append checksum digit */ | 248 val %= 10000000; 249 250 /* Append checksum digit */ |
251 return val * 10 + wps_pin_checksum(val); | 251 *pin = val * 10 + wps_pin_checksum(val); 252 return 0; |
252} 253 254 255int wps_pin_str_valid(const char *pin) 256{ 257 const char *p; 258 size_t len; 259 --- 110 unchanged lines hidden (view full) --- 370 data.auth_type = wps->auth_types; 371 data.encr_type = wps->encr_types; 372 if (wps_build_cred(&data, plain) || 373 (rf_band && wps_build_rf_bands_attr(plain, rf_band)) || 374 (channel && wps_build_ap_channel(plain, channel)) || 375 wps_build_mac_addr(plain, wps->dev.mac_addr) || 376 wps_build_wfa_ext(plain, 0, NULL, 0)) { 377 os_free(data.new_psk); | 253} 254 255 256int wps_pin_str_valid(const char *pin) 257{ 258 const char *p; 259 size_t len; 260 --- 110 unchanged lines hidden (view full) --- 371 data.auth_type = wps->auth_types; 372 data.encr_type = wps->encr_types; 373 if (wps_build_cred(&data, plain) || 374 (rf_band && wps_build_rf_bands_attr(plain, rf_band)) || 375 (channel && wps_build_ap_channel(plain, channel)) || 376 wps_build_mac_addr(plain, wps->dev.mac_addr) || 377 wps_build_wfa_ext(plain, 0, NULL, 0)) { 378 os_free(data.new_psk); |
378 wpabuf_free(plain); | 379 wpabuf_clear_free(plain); |
379 return NULL; 380 } 381 382 if (wps->wps_state == WPS_STATE_NOT_CONFIGURED && data.new_psk && 383 wps->ap) { 384 struct wps_credential cred; 385 386 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based " --- 31 unchanged lines hidden (view full) --- 418 if (data == NULL) 419 return NULL; 420 421 if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey, 422 wpabuf_head(dev_pw), wpabuf_len(dev_pw)) || 423 wps_build_wfa_ext(data, 0, NULL, 0)) { 424 wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password " 425 "token"); | 380 return NULL; 381 } 382 383 if (wps->wps_state == WPS_STATE_NOT_CONFIGURED && data.new_psk && 384 wps->ap) { 385 struct wps_credential cred; 386 387 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based " --- 31 unchanged lines hidden (view full) --- 419 if (data == NULL) 420 return NULL; 421 422 if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey, 423 wpabuf_head(dev_pw), wpabuf_len(dev_pw)) || 424 wps_build_wfa_ext(data, 0, NULL, 0)) { 425 wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password " 426 "token"); |
426 wpabuf_free(data); | 427 wpabuf_clear_free(data); |
427 return NULL; 428 } 429 430 return data; 431} 432 433 434int wps_oob_use_cred(struct wps_context *wps, struct wps_parse_attr *attr) --- 220 unchanged lines hidden (view full) --- 655 wpabuf_free(priv); 656 return -1; 657 } 658 wpa_hexdump_buf(MSG_DEBUG, "WPS: Generated new DH pubkey", pub); 659 dh5_free(dh_ctx); 660 661 wpabuf_free(*pubkey); 662 *pubkey = pub; | 428 return NULL; 429 } 430 431 return data; 432} 433 434 435int wps_oob_use_cred(struct wps_context *wps, struct wps_parse_attr *attr) --- 220 unchanged lines hidden (view full) --- 656 wpabuf_free(priv); 657 return -1; 658 } 659 wpa_hexdump_buf(MSG_DEBUG, "WPS: Generated new DH pubkey", pub); 660 dh5_free(dh_ctx); 661 662 wpabuf_free(*pubkey); 663 *pubkey = pub; |
663 wpabuf_free(*privkey); | 664 wpabuf_clear_free(*privkey); |
664 *privkey = priv; 665 666 return 0; 667} 668 669 670struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, 671 struct wpabuf **privkey, --- 14 unchanged lines hidden (view full) --- 686 } 687 688 if (wps_nfc_gen_dh(pubkey, privkey) < 0) { 689 wpabuf_free(pw); 690 return NULL; 691 } 692 693 *id = 0x10 + val % 0xfff0; | 665 *privkey = priv; 666 667 return 0; 668} 669 670 671struct wpabuf * wps_nfc_token_gen(int ndef, int *id, struct wpabuf **pubkey, 672 struct wpabuf **privkey, --- 14 unchanged lines hidden (view full) --- 687 } 688 689 if (wps_nfc_gen_dh(pubkey, privkey) < 0) { 690 wpabuf_free(pw); 691 return NULL; 692 } 693 694 *id = 0x10 + val % 0xfff0; |
694 wpabuf_free(*dev_pw); | 695 wpabuf_clear_free(*dev_pw); |
695 *dev_pw = pw; 696 697 return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw); 698} 699 700 701struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx, 702 struct wpabuf *nfc_dh_pubkey) --- 207 unchanged lines hidden --- | 696 *dev_pw = pw; 697 698 return wps_nfc_token_build(ndef, *id, *pubkey, *dev_pw); 699} 700 701 702struct wpabuf * wps_build_nfc_handover_req(struct wps_context *ctx, 703 struct wpabuf *nfc_dh_pubkey) --- 207 unchanged lines hidden --- |