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


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36