Deleted Added
full compact
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));
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
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
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;
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;
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;
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);
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);
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);
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)
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 */
251 return val * 10 + wps_pin_checksum(val);
251 *pin = val * 10 + wps_pin_checksum(val);
252 return 0;
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);
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);
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);
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);
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 ---