ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
(const u8 *) ssid->wpa_passphrase,
os_strlen(ssid->wpa_passphrase),
- NULL);
+ NULL, 0);
if (!ssid->pt)
return -1;
}
pw->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
(const u8 *) pw->password,
os_strlen(pw->password),
- pw->identifier);
+ (const u8 *) pw->identifier,
+ pw->identifier ?
+ os_strlen(pw->identifier) : 0);
if (!pw->pt)
return -1;
}
return -1;
}
- params->sae_password = sae_get_password(hapd, NULL, NULL, NULL,
- NULL, NULL);
+ params->sae_password = sae_get_password(hapd, NULL, NULL, 0,
+ NULL, NULL, NULL);
if (!params->sae_password) {
wpa_printf(MSG_ERROR, "SAE password not configured for offload");
return -1;
const char * sae_get_password(struct hostapd_data *hapd,
struct sta_info *sta,
- const char *rx_id,
+ const u8 *rx_id, size_t rx_id_len,
struct sae_password_entry **pw_entry,
struct sae_pt **s_pt,
const struct sae_pk **s_pk)
if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier))
continue;
if (rx_id && pw->identifier &&
- os_strcmp(rx_id, pw->identifier) != 0)
+ (rx_id_len != os_strlen(pw->identifier) ||
+ os_memcmp(rx_id, pw->identifier, rx_id_len) != 0))
continue;
password = pw->password;
pt = pw->pt;
struct wpabuf *buf;
const char *password = NULL;
struct sae_password_entry *pw;
- const char *rx_id = NULL;
+ const u8 *rx_id = NULL;
+ size_t rx_id_len = 0;
int use_pt = 0;
struct sae_pt *pt = NULL;
const struct sae_pk *pk = NULL;
if (sta->sae->tmp) {
rx_id = sta->sae->tmp->parsed_pw_id ?
sta->sae->tmp->parsed_pw_id : sta->sae->tmp->pw_id;
+ rx_id_len = sta->sae->tmp->parsed_pw_id ?
+ sta->sae->tmp->parsed_pw_id_len :
+ sta->sae->tmp->pw_id_len;
use_pt = sta->sae->h2e;
#ifdef CONFIG_SAE_PK
os_memcpy(sta->sae->tmp->own_addr, own_addr, ETH_ALEN);
status_code == WLAN_STATUS_SAE_PK)
use_pt = 1;
- password = sae_get_password(hapd, sta, rx_id, &pw, &pt, &pk);
+ password = sae_get_password(hapd, sta, rx_id, rx_id_len, &pw, &pt, &pk);
if (!password || (use_pt && !pt)) {
wpa_printf(MSG_DEBUG, "SAE: No password available");
return NULL;
}
buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN +
- (rx_id ? 3 + os_strlen(rx_id) : 0));
+ (rx_id ? 3 + rx_id_len : 0));
if (buf &&
sae_write_commit(sta->sae, buf, sta->sae->tmp ?
sta->sae->tmp->anti_clogging_token : NULL,
- rx_id) < 0) {
+ rx_id, rx_id_len) < 0) {
wpabuf_free(buf);
buf = NULL;
}
if (tmp && tmp->parsed_pw_id && !tmp->pw_id) {
tmp->pw_id = tmp->parsed_pw_id;
+ tmp->pw_id_len = tmp->parsed_pw_id_len;
tmp->parsed_pw_id = NULL;
- wpa_printf(MSG_DEBUG,
- "SAE: Known Password Identifier bound to this STA: '%s'",
- tmp->pw_id);
+ tmp->parsed_pw_id_len = 0;
+ wpa_hexdump_ascii(MSG_DEBUG,
+ "SAE: Known Password Identifier bound to this STA",
+ tmp->pw_id, tmp->pw_id_len);
}
sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
pasn_enable_kdk_derivation(pasn);
#endif /* CONFIG_TESTING_OPTIONS */
pasn->use_anti_clogging = use_anti_clogging(hapd);
- pasn_set_password(pasn, sae_get_password(hapd, sta, NULL, NULL,
+ pasn_set_password(pasn, sae_get_password(hapd, sta, NULL, 0, NULL,
&pasn->pt, NULL));
pasn->rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &pasn->rsn_ie_len);
pasn_set_rsnxe_ie(pasn, hostapd_wpa_ie(hapd, WLAN_EID_RSNX));
int sae_password_bind(struct hostapd_data *hapd, const u8 *addr,
const char *password);
const char * sae_get_password(struct hostapd_data *hapd,
- struct sta_info *sta, const char *rx_id,
+ struct sta_info *sta, const u8 *rx_id,
+ size_t rx_id_len,
struct sae_password_entry **pw_entry,
struct sae_pt **s_pt, const struct sae_pk **s_pk);
struct sta_info * hostapd_ml_get_assoc_sta(struct hostapd_data *hapd,
goto fail;
/* Check that output matches the test vector */
- if (sae_write_commit(&sae, buf, NULL, NULL) < 0)
+ if (sae_write_commit(&sae, buf, NULL, NULL, 0) < 0)
goto fail;
wpa_hexdump_buf(MSG_DEBUG, "SAE: Commit message", buf);
pt_info = sae_derive_pt(pt_groups,
(const u8 *) ssid, os_strlen(ssid),
- (const u8 *) pw, os_strlen(pw), pwid);
+ (const u8 *) pw, os_strlen(pw),
+ (const u8 *) pwid,
+ os_strlen(pwid));
if (!pt_info)
goto fail;
}
pasn->pt = sae_derive_pt(pasn_groups, (const u8 *) PR_PASN_SSID,
os_strlen(PR_PASN_SSID),
- (const u8 *) passphrase, len, NULL);
+ (const u8 *) passphrase, len, NULL, 0);
/* Set passphrase for PASN responder to validate Auth 1 frame */
pasn->password = passphrase;
}
static int sae_pwd_seed(size_t hash_len, const u8 *ssid, size_t ssid_len,
const u8 *password, size_t password_len,
- const char *identifier, u8 *pwd_seed)
+ const u8 *identifier, size_t identifier_len,
+ u8 *pwd_seed)
{
const u8 *addr[2];
size_t len[2];
wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
password, password_len);
if (identifier) {
- wpa_printf(MSG_DEBUG, "SAE: password identifier: %s",
- identifier);
+ wpa_hexdump_ascii(MSG_DEBUG, "SAE: password identifier",
+ identifier, identifier_len);
addr[num_elem] = (const u8 *) identifier;
- len[num_elem] = os_strlen(identifier);
+ len[num_elem] = identifier_len;
num_elem++;
}
if (hkdf_extract(hash_len, ssid, ssid_len, num_elem, addr, len,
sae_derive_pt_ecc(struct crypto_ec *ec, int group,
const u8 *ssid, size_t ssid_len,
const u8 *password, size_t password_len,
- const char *identifier)
+ const u8 *identifier, size_t identifier_len)
{
u8 pwd_seed[64];
u8 pwd_value[SAE_MAX_ECC_PRIME_LEN * 2];
pwd_value_len = prime_len + (prime_len + 1) / 2;
if (sae_pwd_seed(hash_len, ssid, ssid_len, password, password_len,
- identifier, pwd_seed) < 0)
+ identifier, identifier_len, pwd_seed) < 0)
goto fail;
/* pwd-value = HKDF-Expand(pwd-seed, "SAE Hash to Element u1 P1", len)
sae_derive_pt_ffc(const struct dh_group *dh, int group,
const u8 *ssid, size_t ssid_len,
const u8 *password, size_t password_len,
- const char *identifier)
+ const u8 *identifier, size_t identifier_len)
{
size_t hash_len, prime_len, pwd_value_len;
struct crypto_bignum *prime, *order;
goto fail;
if (sae_pwd_seed(hash_len, ssid, ssid_len, password, password_len,
- identifier, pwd_seed) < 0)
+ identifier, identifier_len, pwd_seed) < 0)
goto fail;
/* pwd-value = HKDF-Expand(pwd-seed, "SAE Hash to Element", len) */
static struct sae_pt *
sae_derive_pt_group(int group, const u8 *ssid, size_t ssid_len,
const u8 *password, size_t password_len,
- const char *identifier)
+ const u8 *identifier, size_t identifier_len)
{
struct sae_pt *pt;
if (pt->ec) {
pt->ecc_pt = sae_derive_pt_ecc(pt->ec, group, ssid, ssid_len,
password, password_len,
- identifier);
+ identifier, identifier_len);
if (!pt->ecc_pt) {
wpa_printf(MSG_DEBUG, "SAE: Failed to derive PT");
goto fail;
}
pt->ffc_pt = sae_derive_pt_ffc(pt->dh, group, ssid, ssid_len,
- password, password_len, identifier);
+ password, password_len, identifier,
+ identifier_len);
if (!pt->ffc_pt) {
wpa_printf(MSG_DEBUG, "SAE: Failed to derive PT");
goto fail;
struct sae_pt * sae_derive_pt(const int *groups,
const u8 *ssid, size_t ssid_len,
const u8 *password, size_t password_len,
- const char *identifier)
+ const u8 *identifier, size_t identifier_len)
{
struct sae_pt *pt = NULL, *last = NULL, *tmp;
const int default_groups[] = { 19, 0 };
groups = default_groups;
for (i = 0; groups[i] > 0; i++) {
tmp = sae_derive_pt_group(groups[i], ssid, ssid_len, password,
- password_len, identifier);
+ password_len, identifier,
+ identifier_len);
if (!tmp)
continue;
int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
- const struct wpabuf *token, const char *identifier)
+ const struct wpabuf *token, const u8 *identifier,
+ size_t identifier_len)
{
u8 *pos;
if (identifier) {
/* Password Identifier element */
wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
- wpabuf_put_u8(buf, 1 + os_strlen(identifier));
+ wpabuf_put_u8(buf, 1 + identifier_len);
wpabuf_put_u8(buf, WLAN_EID_EXT_PASSWORD_IDENTIFIER);
- wpabuf_put_str(buf, identifier);
- wpa_printf(MSG_DEBUG, "SAE: own Password Identifier: %s",
- identifier);
+ wpabuf_put_data(buf, identifier, identifier_len);
+ wpa_hexdump_ascii(MSG_DEBUG, "SAE: own Password Identifier",
+ identifier, identifier_len);
}
if (sae->h2e && sae->tmp->own_rejected_groups) {
}
os_free(sae->tmp->parsed_pw_id);
sae->tmp->parsed_pw_id = NULL;
+ sae->tmp->parsed_pw_id_len = 0;
return WLAN_STATUS_SUCCESS; /* No Password Identifier */
}
}
if (sae->tmp->pw_id &&
- (len != os_strlen(sae->tmp->pw_id) ||
+ (len != sae->tmp->pw_id_len ||
os_memcmp(sae->tmp->pw_id, epos, len) != 0)) {
wpa_printf(MSG_DEBUG,
"SAE: The included Password Identifier does not match the expected one (%s)",
os_free(sae->tmp->parsed_pw_id);
sae->tmp->parsed_pw_id = os_malloc(len + 1);
- if (!sae->tmp->parsed_pw_id)
+ if (!sae->tmp->parsed_pw_id) {
+ sae->tmp->parsed_pw_id_len = 0;
return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
os_memcpy(sae->tmp->parsed_pw_id, epos, len);
+ sae->tmp->parsed_pw_id_len = len;
sae->tmp->parsed_pw_id[len] = '\0';
wpa_hexdump_ascii(MSG_DEBUG, "SAE: Received Password Identifier",
sae->tmp->parsed_pw_id, len);
struct crypto_bignum *prime_buf;
struct crypto_bignum *order_buf;
struct wpabuf *anti_clogging_token;
- char *pw_id;
- char *parsed_pw_id;
+ u8 *pw_id;
+ size_t pw_id_len;
+ u8 *parsed_pw_id;
+ size_t parsed_pw_id_len;
int vlan_id;
u8 bssid[ETH_ALEN];
struct wpabuf *own_rejected_groups;
int *rejected_groups, const struct sae_pk *pk);
int sae_process_commit(struct sae_data *sae);
int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
- const struct wpabuf *token, const char *identifier);
+ const struct wpabuf *token, const u8 *identifier,
+ size_t identifier_len);
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
const u8 **token, size_t *token_len, int *allowed_groups,
int h2e, int *ie_offset);
struct sae_pt * sae_derive_pt(const int *groups,
const u8 *ssid, size_t ssid_len,
const u8 *password, size_t password_len,
- const char *identifier);
+ const u8 *identifier, size_t identifier_len);
struct crypto_ec_point *
sae_derive_pwe_from_pt_ecc(const struct sae_pt *pt,
const u8 *addr1, const u8 *addr2);
}
pasn->pt = sae_derive_pt(pasn_groups, (const u8 *) P2P_PAIRING_SSID,
os_strlen(P2P_PAIRING_SSID),
- (const u8 *) passphrase, len, NULL);
+ (const u8 *) passphrase, len, NULL, 0);
/* Set passphrase for pairing responder to validate PASN auth 1 frame */
pasn->password = passphrase;
}
wpabuf_put_le16(buf, 1);
wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
- sae_write_commit(&pasn->sae, buf, NULL, NULL);
+ sae_write_commit(&pasn->sae, buf, NULL, NULL, 0);
pasn->sae.state = SAE_COMMITTED;
return buf;
wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
/* Write the actual commit and update the length accordingly */
- sae_write_commit(&pasn->sae, buf, NULL, NULL);
+ sae_write_commit(&pasn->sae, buf, NULL, NULL, 0);
len = wpabuf_len(buf);
WPA_PUT_LE16(len_ptr, len - 2);
}
if (sta->sae->tmp && !sta->sae->tmp->pw_id && ssid->sae_password_id) {
- sta->sae->tmp->pw_id = os_strdup(ssid->sae_password_id);
+ sta->sae->tmp->pw_id = (u8 *) os_strdup(ssid->sae_password_id);
if (!sta->sae->tmp->pw_id)
return -1;
+ sta->sae->tmp->pw_id_len = os_strlen(ssid->sae_password_id);
}
return sae_prepare_commit(wpa_s->own_addr, sta->addr,
(u8 *) password, os_strlen(password),
}
return sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
- (const u8 *) password, os_strlen(password),
- ssid->sae_password_id);
+ (const u8 *) password, os_strlen(password),
+ (const u8 *) ssid->sae_password_id,
+ ssid->sae_password_id ?
+ os_strlen(ssid->sae_password_id) : 0);
}
wpa_s->key_mgmt;
const u8 *addr = mld_addr ? mld_addr : bssid;
enum sae_pwe sae_pwe;
+ const u8 *password_id = (const u8 *) ssid->sae_password_id;
+ size_t password_id_len = ssid->sae_password_id ?
+ os_strlen(ssid->sae_password_id) : 0;
if (ret_use_pt)
*ret_use_pt = 0;
wpabuf_put_le16(buf,WLAN_STATUS_SUCCESS);
}
if (sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
- ssid->sae_password_id) < 0) {
+ password_id, password_id_len) < 0) {
wpabuf_free(buf);
goto fail;
}
int default_groups[] = { 19, 20, 21, 0 };
const char *password;
enum sae_pwe sae_pwe;
+ const u8 *password_id = (const u8 *) ssid->sae_password_id;
+ size_t password_id_len = ssid->sae_password_id ?
+ os_strlen(ssid->sae_password_id) : 0;
if (!groups || groups[0] <= 0)
groups = default_groups;
return; /* PT already derived */
ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
(const u8 *) password, os_strlen(password),
- ssid->sae_password_id);
+ password_id, password_id_len);
#endif /* CONFIG_SAE */
}