Deleted Added
full compact
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 ---