00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019 #include "dh_group5.h"
00020 #include "crypto.h"
00021 #include "sha256.h"
00022 #include "aes_wrap.h"
00023 #include "wps_i.h"
00024
00025
00026 int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg)
00027 {
00028 struct wpabuf *pubkey;
00029
00030 wpa_printf(MSG_DEBUG, "WPS: * Public Key");
00031 wpabuf_free(wps->dh_privkey);
00032 if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey) {
00033 wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys");
00034 wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey);
00035 wps->dh_ctx = wps->wps->dh_ctx;
00036 wps->wps->dh_ctx = NULL;
00037 pubkey = wpabuf_dup(wps->wps->dh_pubkey);
00038 } else {
00039 wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys");
00040 wps->dh_privkey = NULL;
00041 dh5_free(wps->dh_ctx);
00042 wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey);
00043 pubkey = wpabuf_zeropad(pubkey, 192);
00044 }
00045 if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) {
00046 wpa_printf(MSG_DEBUG, "WPS: Failed to initialize "
00047 "Diffie-Hellman handshake");
00048 wpabuf_free(pubkey);
00049 return -1;
00050 }
00051
00052 wpabuf_put_be16(msg, ATTR_PUBLIC_KEY);
00053 wpabuf_put_be16(msg, wpabuf_len(pubkey));
00054 wpabuf_put_buf(msg, pubkey);
00055
00056 if (wps->registrar) {
00057 wpabuf_free(wps->dh_pubkey_r);
00058 wps->dh_pubkey_r = pubkey;
00059 } else {
00060 wpabuf_free(wps->dh_pubkey_e);
00061 wps->dh_pubkey_e = pubkey;
00062 }
00063
00064 return 0;
00065 }
00066
00067
00068 int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type)
00069 {
00070 wpa_printf(MSG_DEBUG, "WPS: * Request Type");
00071 wpabuf_put_be16(msg, ATTR_REQUEST_TYPE);
00072 wpabuf_put_be16(msg, 1);
00073 wpabuf_put_u8(msg, type);
00074 return 0;
00075 }
00076
00077
00078 int wps_build_config_methods(struct wpabuf *msg, u16 methods)
00079 {
00080 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
00081 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
00082 wpabuf_put_be16(msg, 2);
00083 wpabuf_put_be16(msg, methods);
00084 return 0;
00085 }
00086
00087
00088 int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid)
00089 {
00090 wpa_printf(MSG_DEBUG, "WPS: * UUID-E");
00091 wpabuf_put_be16(msg, ATTR_UUID_E);
00092 wpabuf_put_be16(msg, WPS_UUID_LEN);
00093 wpabuf_put_data(msg, uuid, WPS_UUID_LEN);
00094 return 0;
00095 }
00096
00097
00098 int wps_build_dev_password_id(struct wpabuf *msg, u16 id)
00099 {
00100 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id);
00101 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
00102 wpabuf_put_be16(msg, 2);
00103 wpabuf_put_be16(msg, id);
00104 return 0;
00105 }
00106
00107
00108 int wps_build_config_error(struct wpabuf *msg, u16 err)
00109 {
00110 wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err);
00111 wpabuf_put_be16(msg, ATTR_CONFIG_ERROR);
00112 wpabuf_put_be16(msg, 2);
00113 wpabuf_put_be16(msg, err);
00114 return 0;
00115 }
00116
00117
00118 int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg)
00119 {
00120 u8 hash[SHA256_MAC_LEN];
00121 const u8 *addr[2];
00122 size_t len[2];
00123
00124 if (wps->last_msg == NULL) {
00125 wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
00126 "building authenticator");
00127 return -1;
00128 }
00129
00130
00131
00132
00133 addr[0] = wpabuf_head(wps->last_msg);
00134 len[0] = wpabuf_len(wps->last_msg);
00135 addr[1] = wpabuf_head(msg);
00136 len[1] = wpabuf_len(msg);
00137 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
00138
00139 wpa_printf(MSG_DEBUG, "WPS: * Authenticator");
00140 wpabuf_put_be16(msg, ATTR_AUTHENTICATOR);
00141 wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN);
00142 wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN);
00143
00144 return 0;
00145 }
00146
00147
00148 int wps_build_version(struct wpabuf *msg)
00149 {
00150 wpa_printf(MSG_DEBUG, "WPS: * Version");
00151 wpabuf_put_be16(msg, ATTR_VERSION);
00152 wpabuf_put_be16(msg, 1);
00153 wpabuf_put_u8(msg, WPS_VERSION);
00154 return 0;
00155 }
00156
00157
00158 int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type)
00159 {
00160 wpa_printf(MSG_DEBUG, "WPS: * Message Type (%d)", msg_type);
00161 wpabuf_put_be16(msg, ATTR_MSG_TYPE);
00162 wpabuf_put_be16(msg, 1);
00163 wpabuf_put_u8(msg, msg_type);
00164 return 0;
00165 }
00166
00167
00168 int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg)
00169 {
00170 wpa_printf(MSG_DEBUG, "WPS: * Enrollee Nonce");
00171 wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
00172 wpabuf_put_be16(msg, WPS_NONCE_LEN);
00173 wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN);
00174 return 0;
00175 }
00176
00177
00178 int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg)
00179 {
00180 wpa_printf(MSG_DEBUG, "WPS: * Registrar Nonce");
00181 wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
00182 wpabuf_put_be16(msg, WPS_NONCE_LEN);
00183 wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN);
00184 return 0;
00185 }
00186
00187
00188 int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
00189 {
00190 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type Flags");
00191 wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS);
00192 wpabuf_put_be16(msg, 2);
00193 wpabuf_put_be16(msg, WPS_AUTH_TYPES);
00194 return 0;
00195 }
00196
00197
00198 int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg)
00199 {
00200 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type Flags");
00201 wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS);
00202 wpabuf_put_be16(msg, 2);
00203 wpabuf_put_be16(msg, WPS_ENCR_TYPES);
00204 return 0;
00205 }
00206
00207
00208 int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg)
00209 {
00210 wpa_printf(MSG_DEBUG, "WPS: * Connection Type Flags");
00211 wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS);
00212 wpabuf_put_be16(msg, 1);
00213 wpabuf_put_u8(msg, WPS_CONN_ESS);
00214 return 0;
00215 }
00216
00217
00218 int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg)
00219 {
00220 wpa_printf(MSG_DEBUG, "WPS: * Association State");
00221 wpabuf_put_be16(msg, ATTR_ASSOC_STATE);
00222 wpabuf_put_be16(msg, 2);
00223 wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC);
00224 return 0;
00225 }
00226
00227
00228 int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg)
00229 {
00230 u8 hash[SHA256_MAC_LEN];
00231
00232 wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator");
00233 hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg),
00234 wpabuf_len(msg), hash);
00235
00236 wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH);
00237 wpabuf_put_be16(msg, WPS_KWA_LEN);
00238 wpabuf_put_data(msg, hash, WPS_KWA_LEN);
00239 return 0;
00240 }
00241
00242
00243 int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
00244 struct wpabuf *plain)
00245 {
00246 size_t pad_len;
00247 const size_t block_size = 16;
00248 u8 *iv, *data;
00249
00250 wpa_printf(MSG_DEBUG, "WPS: * Encrypted Settings");
00251
00252
00253 pad_len = block_size - wpabuf_len(plain) % block_size;
00254 os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len);
00255
00256 wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS);
00257 wpabuf_put_be16(msg, block_size + wpabuf_len(plain));
00258
00259 iv = wpabuf_put(msg, block_size);
00260 if (os_get_random(iv, block_size) < 0)
00261 return -1;
00262
00263 data = wpabuf_put(msg, 0);
00264 wpabuf_put_buf(msg, plain);
00265 if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain)))
00266 return -1;
00267
00268 return 0;
00269 }
00270
00271
00272 #ifdef CONFIG_WPS_OOB
00273 int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps)
00274 {
00275 size_t hash_len;
00276 const u8 *addr[1];
00277 u8 pubkey_hash[WPS_HASH_LEN];
00278 u8 dev_password_bin[WPS_OOB_DEVICE_PASSWORD_LEN];
00279
00280 wpa_printf(MSG_DEBUG, "WPS: * OOB Device Password");
00281
00282 addr[0] = wpabuf_head(wps->dh_pubkey);
00283 hash_len = wpabuf_len(wps->dh_pubkey);
00284 sha256_vector(1, addr, &hash_len, pubkey_hash);
00285
00286 if (os_get_random((u8 *) &wps->oob_dev_pw_id, sizeof(u16)) < 0) {
00287 wpa_printf(MSG_ERROR, "WPS: device password id "
00288 "generation error");
00289 return -1;
00290 }
00291 wps->oob_dev_pw_id |= 0x0010;
00292
00293 if (os_get_random(dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN) < 0) {
00294 wpa_printf(MSG_ERROR, "WPS: OOB device password "
00295 "generation error");
00296 return -1;
00297 }
00298
00299 wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD);
00300 wpabuf_put_be16(msg, WPS_OOB_DEVICE_PASSWORD_ATTR_LEN);
00301 wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN);
00302 wpabuf_put_be16(msg, wps->oob_dev_pw_id);
00303 wpabuf_put_data(msg, dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN);
00304
00305 wpa_snprintf_hex_uppercase(
00306 wpabuf_put(wps->oob_conf.dev_password,
00307 wpabuf_size(wps->oob_conf.dev_password)),
00308 wpabuf_size(wps->oob_conf.dev_password),
00309 dev_password_bin, WPS_OOB_DEVICE_PASSWORD_LEN);
00310
00311 return 0;
00312 }
00313 #endif
00314