1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Wi-Fi Protected Setup - attribute building 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2008, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/dh_groups.h" 19b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/sha256.h" 20b349ef9e9f3f5399bf96b3c1c663cb9e547f50a1Dmitry Shmidt#include "crypto/aes_wrap.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wps_i.h" 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_public_key(struct wps_data *wps, struct wpabuf *msg) 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *pubkey; 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Public Key"); 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pubkey = dh_init(dh_groups_get(WPS_DH_GROUP), &wps->dh_privkey); 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pubkey = wpabuf_zeropad(pubkey, 192); 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pubkey == NULL) { 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Diffie-Hellman handshake"); 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, wpabuf_len(pubkey)); 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_buf(msg, pubkey); 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wps->registrar) { 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(wps->dh_pubkey_r); 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wps->dh_pubkey_r = pubkey; 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_free(wps->dh_pubkey_e); 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wps->dh_pubkey_e = pubkey; 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_req_type(struct wpabuf *msg, enum wps_request_type type) 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Request Type"); 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_REQUEST_TYPE); 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 1); 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_u8(msg, type); 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_config_methods(struct wpabuf *msg, u16 methods) 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods); 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_CONFIG_METHODS); 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 2); 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, methods); 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid) 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * UUID-E"); 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_UUID_E); 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_UUID_LEN); 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_data(msg, uuid, WPS_UUID_LEN); 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_dev_password_id(struct wpabuf *msg, u16 id) 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id); 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID); 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 2); 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, id); 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_config_error(struct wpabuf *msg, u16 err) 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err); 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_CONFIG_ERROR); 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 2); 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, err); 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg) 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[SHA256_MAC_LEN]; 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr[2]; 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len[2]; 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wps->last_msg == NULL) { 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Last message not available for " 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "building authenticator"); 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*) 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * (M_curr* is M_curr without the Authenticator attribute) 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[0] = wpabuf_head(wps->last_msg); 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[0] = wpabuf_len(wps->last_msg); 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt addr[1] = wpabuf_head(msg); 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len[1] = wpabuf_len(msg); 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash); 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Authenticator"); 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_AUTHENTICATOR); 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN); 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN); 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_version(struct wpabuf *msg) 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Version"); 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_VERSION); 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 1); 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_u8(msg, WPS_VERSION); 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type) 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Message Type (%d)", msg_type); 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_MSG_TYPE); 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 1); 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_u8(msg, msg_type); 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg) 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Enrollee Nonce"); 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE); 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_NONCE_LEN); 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN); 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg) 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Registrar Nonce"); 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE); 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_NONCE_LEN); 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN); 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg) 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Authentication Type Flags"); 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS); 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 2); 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_AUTH_TYPES); 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg) 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Encryption Type Flags"); 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS); 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 2); 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_ENCR_TYPES); 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg) 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Connection Type Flags"); 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS); 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 1); 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_u8(msg, WPS_CONN_ESS); 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg) 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Association State"); 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_ASSOC_STATE); 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, 2); 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg) 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 hash[SHA256_MAC_LEN]; 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator"); 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg), 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_len(msg), hash); 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH); 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, WPS_KWA_LEN); 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_data(msg, hash, WPS_KWA_LEN); 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg, 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpabuf *plain) 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t pad_len; 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const size_t block_size = 16; 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *iv, *data; 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: * Encrypted Settings"); 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* PKCS#5 v2.0 pad */ 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pad_len = block_size - wpabuf_len(plain) % block_size; 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len); 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS); 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_be16(msg, block_size + wpabuf_len(plain)); 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iv = wpabuf_put(msg, block_size); 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_get_random(iv, block_size) < 0) 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data = wpabuf_put(msg, 0); 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpabuf_put_buf(msg, plain); 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain))) 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 255