2 * Wi-Fi Protected Setup - attribute building
3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include "dh_groups.h"
24 int wps_build_public_key(struct wps_data
*wps
, struct wpabuf
*msg
)
26 struct wpabuf
*pubkey
;
28 wpa_printf(MSG_DEBUG
, "WPS: * Public Key");
29 pubkey
= dh_init(dh_groups_get(WPS_DH_GROUP
), &wps
->dh_privkey
);
30 pubkey
= wpabuf_zeropad(pubkey
, 192);
32 wpa_printf(MSG_DEBUG
, "WPS: Failed to initialize "
33 "Diffie-Hellman handshake");
37 wpabuf_put_be16(msg
, ATTR_PUBLIC_KEY
);
38 wpabuf_put_be16(msg
, wpabuf_len(pubkey
));
39 wpabuf_put_buf(msg
, pubkey
);
42 wpabuf_free(wps
->dh_pubkey_r
);
43 wps
->dh_pubkey_r
= pubkey
;
45 wpabuf_free(wps
->dh_pubkey_e
);
46 wps
->dh_pubkey_e
= pubkey
;
53 int wps_build_req_type(struct wpabuf
*msg
, enum wps_request_type type
)
55 wpa_printf(MSG_DEBUG
, "WPS: * Request Type");
56 wpabuf_put_be16(msg
, ATTR_REQUEST_TYPE
);
57 wpabuf_put_be16(msg
, 1);
58 wpabuf_put_u8(msg
, type
);
63 int wps_build_config_methods(struct wpabuf
*msg
, u16 methods
)
65 wpa_printf(MSG_DEBUG
, "WPS: * Config Methods (%x)", methods
);
66 wpabuf_put_be16(msg
, ATTR_CONFIG_METHODS
);
67 wpabuf_put_be16(msg
, 2);
68 wpabuf_put_be16(msg
, methods
);
73 int wps_build_uuid_e(struct wpabuf
*msg
, const u8
*uuid
)
75 wpa_printf(MSG_DEBUG
, "WPS: * UUID-E");
76 wpabuf_put_be16(msg
, ATTR_UUID_E
);
77 wpabuf_put_be16(msg
, WPS_UUID_LEN
);
78 wpabuf_put_data(msg
, uuid
, WPS_UUID_LEN
);
83 int wps_build_dev_password_id(struct wpabuf
*msg
, u16 id
)
85 wpa_printf(MSG_DEBUG
, "WPS: * Device Password ID (%d)", id
);
86 wpabuf_put_be16(msg
, ATTR_DEV_PASSWORD_ID
);
87 wpabuf_put_be16(msg
, 2);
88 wpabuf_put_be16(msg
, id
);
93 int wps_build_config_error(struct wpabuf
*msg
, u16 err
)
95 wpa_printf(MSG_DEBUG
, "WPS: * Configuration Error (%d)", err
);
96 wpabuf_put_be16(msg
, ATTR_CONFIG_ERROR
);
97 wpabuf_put_be16(msg
, 2);
98 wpabuf_put_be16(msg
, err
);
103 int wps_build_authenticator(struct wps_data
*wps
, struct wpabuf
*msg
)
105 u8 hash
[SHA256_MAC_LEN
];
109 if (wps
->last_msg
== NULL
) {
110 wpa_printf(MSG_DEBUG
, "WPS: Last message not available for "
111 "building authenticator");
115 /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
116 * (M_curr* is M_curr without the Authenticator attribute)
118 addr
[0] = wpabuf_head(wps
->last_msg
);
119 len
[0] = wpabuf_len(wps
->last_msg
);
120 addr
[1] = wpabuf_head(msg
);
121 len
[1] = wpabuf_len(msg
);
122 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 2, addr
, len
, hash
);
124 wpa_printf(MSG_DEBUG
, "WPS: * Authenticator");
125 wpabuf_put_be16(msg
, ATTR_AUTHENTICATOR
);
126 wpabuf_put_be16(msg
, WPS_AUTHENTICATOR_LEN
);
127 wpabuf_put_data(msg
, hash
, WPS_AUTHENTICATOR_LEN
);
133 int wps_build_version(struct wpabuf
*msg
)
135 wpa_printf(MSG_DEBUG
, "WPS: * Version");
136 wpabuf_put_be16(msg
, ATTR_VERSION
);
137 wpabuf_put_be16(msg
, 1);
138 wpabuf_put_u8(msg
, WPS_VERSION
);
143 int wps_build_msg_type(struct wpabuf
*msg
, enum wps_msg_type msg_type
)
145 wpa_printf(MSG_DEBUG
, "WPS: * Message Type (%d)", msg_type
);
146 wpabuf_put_be16(msg
, ATTR_MSG_TYPE
);
147 wpabuf_put_be16(msg
, 1);
148 wpabuf_put_u8(msg
, msg_type
);
153 int wps_build_enrollee_nonce(struct wps_data
*wps
, struct wpabuf
*msg
)
155 wpa_printf(MSG_DEBUG
, "WPS: * Enrollee Nonce");
156 wpabuf_put_be16(msg
, ATTR_ENROLLEE_NONCE
);
157 wpabuf_put_be16(msg
, WPS_NONCE_LEN
);
158 wpabuf_put_data(msg
, wps
->nonce_e
, WPS_NONCE_LEN
);
163 int wps_build_registrar_nonce(struct wps_data
*wps
, struct wpabuf
*msg
)
165 wpa_printf(MSG_DEBUG
, "WPS: * Registrar Nonce");
166 wpabuf_put_be16(msg
, ATTR_REGISTRAR_NONCE
);
167 wpabuf_put_be16(msg
, WPS_NONCE_LEN
);
168 wpabuf_put_data(msg
, wps
->nonce_r
, WPS_NONCE_LEN
);
173 int wps_build_auth_type_flags(struct wps_data
*wps
, struct wpabuf
*msg
)
175 wpa_printf(MSG_DEBUG
, "WPS: * Authentication Type Flags");
176 wpabuf_put_be16(msg
, ATTR_AUTH_TYPE_FLAGS
);
177 wpabuf_put_be16(msg
, 2);
178 wpabuf_put_be16(msg
, WPS_AUTH_TYPES
);
183 int wps_build_encr_type_flags(struct wps_data
*wps
, struct wpabuf
*msg
)
185 wpa_printf(MSG_DEBUG
, "WPS: * Encryption Type Flags");
186 wpabuf_put_be16(msg
, ATTR_ENCR_TYPE_FLAGS
);
187 wpabuf_put_be16(msg
, 2);
188 wpabuf_put_be16(msg
, WPS_ENCR_TYPES
);
193 int wps_build_conn_type_flags(struct wps_data
*wps
, struct wpabuf
*msg
)
195 wpa_printf(MSG_DEBUG
, "WPS: * Connection Type Flags");
196 wpabuf_put_be16(msg
, ATTR_CONN_TYPE_FLAGS
);
197 wpabuf_put_be16(msg
, 1);
198 wpabuf_put_u8(msg
, WPS_CONN_ESS
);
203 int wps_build_assoc_state(struct wps_data
*wps
, struct wpabuf
*msg
)
205 wpa_printf(MSG_DEBUG
, "WPS: * Association State");
206 wpabuf_put_be16(msg
, ATTR_ASSOC_STATE
);
207 wpabuf_put_be16(msg
, 2);
208 wpabuf_put_be16(msg
, WPS_ASSOC_NOT_ASSOC
);
213 int wps_build_key_wrap_auth(struct wps_data
*wps
, struct wpabuf
*msg
)
215 u8 hash
[SHA256_MAC_LEN
];
217 wpa_printf(MSG_DEBUG
, "WPS: * Key Wrap Authenticator");
218 hmac_sha256(wps
->authkey
, WPS_AUTHKEY_LEN
, wpabuf_head(msg
),
219 wpabuf_len(msg
), hash
);
221 wpabuf_put_be16(msg
, ATTR_KEY_WRAP_AUTH
);
222 wpabuf_put_be16(msg
, WPS_KWA_LEN
);
223 wpabuf_put_data(msg
, hash
, WPS_KWA_LEN
);
228 int wps_build_encr_settings(struct wps_data
*wps
, struct wpabuf
*msg
,
229 struct wpabuf
*plain
)
232 const size_t block_size
= 16;
235 wpa_printf(MSG_DEBUG
, "WPS: * Encrypted Settings");
237 /* PKCS#5 v2.0 pad */
238 pad_len
= block_size
- wpabuf_len(plain
) % block_size
;
239 os_memset(wpabuf_put(plain
, pad_len
), pad_len
, pad_len
);
241 wpabuf_put_be16(msg
, ATTR_ENCR_SETTINGS
);
242 wpabuf_put_be16(msg
, block_size
+ wpabuf_len(plain
));
244 iv
= wpabuf_put(msg
, block_size
);
245 if (os_get_random(iv
, block_size
) < 0)
248 data
= wpabuf_put(msg
, 0);
249 wpabuf_put_buf(msg
, plain
);
250 if (aes_128_cbc_encrypt(wps
->keywrapkey
, iv
, data
, wpabuf_len(plain
)))