wpa_pasn_add_parameter_ie(buf, sta->pasn->group,
sta->pasn->wrapped_data_format,
- pubkey, NULL, 0);
+ pubkey, true, NULL, 0);
if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
goto fail;
const int *groups = hapd->conf->pasn_groups;
static const int default_groups[] = { 19, 0 };
u16 status = WLAN_STATUS_SUCCESS;
- int ret;
+ int ret, inc_y;
bool derive_keys;
u32 i;
sta->pasn->group = pasn_params.group;
- secret = crypto_ecdh_set_peerkey(sta->pasn->ecdh, 0,
- pasn_params.pubkey,
- pasn_params.pubkey_len);
+ if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
+ inc_y = 1;
+ } else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
+ pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
+ inc_y = 0;
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid first octet in pubkey=0x%x",
+ pasn_params.pubkey[0]);
+ status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto send_resp;
+ }
+
+ secret = crypto_ecdh_set_peerkey(sta->pasn->ecdh, inc_y,
+ pasn_params.pubkey + 1,
+ pasn_params.pubkey_len - 1);
if (!secret) {
wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
* @pasn_group: Finite Cyclic Group ID for PASN authentication
* @wrapped_data_format: Format of the data in the Wrapped Data IE
* @pubkey: A buffer holding the local public key. Can be NULL
+ * @compressed: In case pubkey is included, indicates if the public key is
+ * compressed (only x coordinate is included) or not (both x and y
+ * coordinates are included)
* @comeback: A buffer holding the comeback token. Can be NULL
* @after: If comeback is set, defined the comeback time in seconds. -1 to not
* include the Comeback After field (frames from non-AP STA).
*/
void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
u8 wrapped_data_format,
- struct wpabuf *pubkey,
+ struct wpabuf *pubkey, bool compressed,
struct wpabuf *comeback, int after)
{
struct pasn_parameter_ie *params;
/*
* 2 octets for the finite cyclic group + 2 octets public key
- * length + the actual key
+ * length + 1 octet for the compressed/uncompressed indication +
+ * the actual key.
*/
- params->len += 2 + 1 + wpabuf_len(pubkey);
+ params->len += 2 + 1 + 1 + wpabuf_len(pubkey);
params->control |= WPA_PASN_CTRL_GROUP_AND_KEY_PRESENT;
wpabuf_put_le16(buf, pasn_group);
- wpabuf_put_u8(buf, wpabuf_len(pubkey));
+
+ /*
+ * The first octet indicates whether the public key is
+ * compressed, as defined in RFC 5480 section 2.2.
+ */
+ wpabuf_put_u8(buf, wpabuf_len(pubkey) + 1);
+ wpabuf_put_u8(buf, compressed ? WPA_PASN_PUBKEY_COMPRESSED_0 :
+ WPA_PASN_PUBKEY_UNCOMPRESSED);
+
wpabuf_put_buf(buf, pubkey);
}
}
const u8 *pubkey;
};
+/* See RFC 5480 section 2.2 */
+#define WPA_PASN_PUBKEY_COMPRESSED_0 0x02
+#define WPA_PASN_PUBKEY_COMPRESSED_1 0x03
+#define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04
+
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
int use_sha384);
void wpa_pasn_add_parameter_ie(struct wpabuf *buf, u16 pasn_group,
u8 wrapped_data_format,
- struct wpabuf *pubkey,
+ struct wpabuf *pubkey, bool compressed,
struct wpabuf *comeback, int after);
int wpa_pasn_add_wrapped_data(struct wpabuf *buf,
wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
- pubkey, NULL, -1);
+ pubkey, true, NULL, -1);
if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
goto fail;
wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
- NULL, NULL, -1);
+ NULL, false, NULL, -1);
if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
goto fail;
u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
u8 mic_len;
u16 status;
- int ret;
+ int ret, inc_y;
u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
(WLAN_FC_STYPE_AUTH << 4));
goto fail;
}
- secret = crypto_ecdh_set_peerkey(pasn->ecdh, 0,
- pasn_params.pubkey,
- pasn_params.pubkey_len);
+ if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
+ inc_y = 1;
+ } else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
+ pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
+ inc_y = 0;
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Invalid first octet in pubkey=0x%x",
+ pasn_params.pubkey[0]);
+ goto fail;
+ }
+
+ secret = crypto_ecdh_set_peerkey(pasn->ecdh, inc_y,
+ pasn_params.pubkey + 1,
+ pasn_params.pubkey_len - 1);
if (!secret) {
wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");