2012-12-30 20:48:19 +01:00
|
|
|
/*
|
|
|
|
* Simultaneous authentication of equals
|
2013-01-01 13:00:40 +01:00
|
|
|
* Copyright (c) 2012-2013, Jouni Malinen <j@w1.fi>
|
2012-12-30 20:48:19 +01:00
|
|
|
*
|
|
|
|
* This software may be distributed under the terms of the BSD license.
|
|
|
|
* See README for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SAE_H
|
|
|
|
#define SAE_H
|
|
|
|
|
2013-01-01 10:52:49 +01:00
|
|
|
#define SAE_KCK_LEN 32
|
|
|
|
#define SAE_PMK_LEN 32
|
|
|
|
#define SAE_PMKID_LEN 16
|
2013-01-05 20:22:00 +01:00
|
|
|
#define SAE_MAX_PRIME_LEN 512
|
2013-01-06 17:12:58 +01:00
|
|
|
#define SAE_MAX_ECC_PRIME_LEN 66
|
2019-08-27 15:33:15 +02:00
|
|
|
#define SAE_MAX_HASH_LEN 64
|
2019-08-27 15:33:15 +02:00
|
|
|
#define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN + 255)
|
2019-08-27 15:33:15 +02:00
|
|
|
#define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_HASH_LEN)
|
2012-12-30 21:06:11 +01:00
|
|
|
|
2015-06-23 21:30:15 +02:00
|
|
|
/* Special value returned by sae_parse_commit() */
|
|
|
|
#define SAE_SILENTLY_DISCARD 65535
|
|
|
|
|
2013-01-06 18:26:27 +01:00
|
|
|
struct sae_temporary_data {
|
2019-08-27 15:33:15 +02:00
|
|
|
u8 kck[SAE_MAX_HASH_LEN];
|
|
|
|
size_t kck_len;
|
2013-01-06 15:57:53 +01:00
|
|
|
struct crypto_bignum *own_commit_scalar;
|
2013-01-06 17:12:58 +01:00
|
|
|
struct crypto_bignum *own_commit_element_ffc;
|
|
|
|
struct crypto_ec_point *own_commit_element_ecc;
|
|
|
|
struct crypto_bignum *peer_commit_element_ffc;
|
|
|
|
struct crypto_ec_point *peer_commit_element_ecc;
|
2013-01-06 15:10:48 +01:00
|
|
|
struct crypto_ec_point *pwe_ecc;
|
|
|
|
struct crypto_bignum *pwe_ffc;
|
2013-01-06 14:32:38 +01:00
|
|
|
struct crypto_bignum *sae_rand;
|
2013-01-01 10:29:53 +01:00
|
|
|
struct crypto_ec *ec;
|
|
|
|
int prime_len;
|
SAE: Fix KCK, PMK, and PMKID derivation for groups 22, 23, 24
IEEE Std 802.11-2016 is not exactly clear on the encoding of the bit
string that is needed for KCK, PMK, and PMKID derivation, but it seems
to make most sense to encode the (commit-scalar + peer-commit-scalar)
mod r part as a bit string by zero padding it from left to the length of
the order (in full octets).
The previous implementation used the length of the prime (in full
octets). This would work for KCK/PMK, but this results in deriving all
zero PMKIDs for the groups where the size of the order is smaller than
the size of the prime. This is the case for groups 22, 23, and 24.
However, those groups have been marked as being unsuitable for use with
SAE, so this fix should not really have a practical impact anymore.
Anyway, better fix it and document this clearly in the implementation
taken into account the unclarity of the standard in this area.
Signed-off-by: Jouni Malinen <j@w1.fi>
2019-08-03 16:00:39 +02:00
|
|
|
int order_len;
|
2013-01-05 20:22:00 +01:00
|
|
|
const struct dh_group *dh;
|
2013-01-05 20:12:29 +01:00
|
|
|
const struct crypto_bignum *prime;
|
|
|
|
const struct crypto_bignum *order;
|
2013-01-05 20:22:00 +01:00
|
|
|
struct crypto_bignum *prime_buf;
|
|
|
|
struct crypto_bignum *order_buf;
|
2014-11-25 03:04:40 +01:00
|
|
|
struct wpabuf *anti_clogging_token;
|
2018-05-19 16:28:01 +02:00
|
|
|
char *pw_id;
|
2019-02-17 16:22:37 +01:00
|
|
|
int vlan_id;
|
2019-03-03 15:23:19 +01:00
|
|
|
u8 bssid[ETH_ALEN];
|
2019-08-27 15:33:15 +02:00
|
|
|
struct wpabuf *own_rejected_groups;
|
2019-09-07 17:38:29 +02:00
|
|
|
struct wpabuf *peer_rejected_groups;
|
2019-08-27 15:33:15 +02:00
|
|
|
unsigned int h2e:1;
|
|
|
|
unsigned int own_addr_higher:1;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct sae_pt {
|
|
|
|
struct sae_pt *next;
|
|
|
|
int group;
|
|
|
|
struct crypto_ec *ec;
|
|
|
|
struct crypto_ec_point *ecc_pt;
|
|
|
|
|
|
|
|
const struct dh_group *dh;
|
|
|
|
struct crypto_bignum *ffc_pt;
|
2012-12-30 20:48:19 +01:00
|
|
|
};
|
|
|
|
|
2017-12-26 23:07:42 +01:00
|
|
|
enum sae_state {
|
|
|
|
SAE_NOTHING, SAE_COMMITTED, SAE_CONFIRMED, SAE_ACCEPTED
|
|
|
|
};
|
|
|
|
|
2013-01-06 18:26:27 +01:00
|
|
|
struct sae_data {
|
2017-12-26 23:07:42 +01:00
|
|
|
enum sae_state state;
|
2013-01-06 18:26:27 +01:00
|
|
|
u16 send_confirm;
|
|
|
|
u8 pmk[SAE_PMK_LEN];
|
2015-12-27 03:20:51 +01:00
|
|
|
u8 pmkid[SAE_PMKID_LEN];
|
2013-01-06 18:26:27 +01:00
|
|
|
struct crypto_bignum *peer_commit_scalar;
|
|
|
|
int group;
|
2017-12-26 11:46:22 +01:00
|
|
|
unsigned int sync; /* protocol instance variable: Sync */
|
2017-12-27 11:14:41 +01:00
|
|
|
u16 rc; /* protocol instance variable: Rc (received send-confirm) */
|
2013-01-06 18:26:27 +01:00
|
|
|
struct sae_temporary_data *tmp;
|
|
|
|
};
|
|
|
|
|
2013-01-01 10:29:53 +01:00
|
|
|
int sae_set_group(struct sae_data *sae, int group);
|
2013-01-06 18:06:59 +01:00
|
|
|
void sae_clear_temp_data(struct sae_data *sae);
|
2013-01-01 10:29:53 +01:00
|
|
|
void sae_clear_data(struct sae_data *sae);
|
|
|
|
|
2012-12-30 21:06:11 +01:00
|
|
|
int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
|
|
|
const u8 *password, size_t password_len,
|
2018-05-19 16:28:01 +02:00
|
|
|
const char *identifier, struct sae_data *sae);
|
2019-08-27 15:33:15 +02:00
|
|
|
int sae_prepare_commit_pt(struct sae_data *sae, const struct sae_pt *pt,
|
|
|
|
const u8 *addr1, const u8 *addr2,
|
|
|
|
int *rejected_groups);
|
2012-12-30 21:16:18 +01:00
|
|
|
int sae_process_commit(struct sae_data *sae);
|
2012-12-31 15:58:36 +01:00
|
|
|
void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
2018-05-19 16:28:01 +02:00
|
|
|
const struct wpabuf *token, const char *identifier);
|
2012-12-31 15:58:36 +01:00
|
|
|
u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
|
2019-09-07 17:33:02 +02:00
|
|
|
const u8 **token, size_t *token_len, int *allowed_groups,
|
|
|
|
int h2e);
|
2012-12-30 21:28:57 +01:00
|
|
|
void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
|
2012-12-30 21:31:19 +01:00
|
|
|
int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len);
|
2014-11-25 03:04:41 +01:00
|
|
|
u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group);
|
2017-12-26 23:07:42 +01:00
|
|
|
const char * sae_state_txt(enum sae_state state);
|
2019-08-27 15:33:15 +02:00
|
|
|
struct sae_pt * sae_derive_pt(int *groups, const u8 *ssid, size_t ssid_len,
|
|
|
|
const u8 *password, size_t password_len,
|
|
|
|
const char *identifier);
|
|
|
|
struct crypto_ec_point *
|
|
|
|
sae_derive_pwe_from_pt_ecc(const struct sae_pt *pt,
|
|
|
|
const u8 *addr1, const u8 *addr2);
|
|
|
|
struct crypto_bignum *
|
|
|
|
sae_derive_pwe_from_pt_ffc(const struct sae_pt *pt,
|
|
|
|
const u8 *addr1, const u8 *addr2);
|
|
|
|
void sae_deinit_pt(struct sae_pt *pt);
|
2012-12-30 21:06:11 +01:00
|
|
|
|
2012-12-30 20:48:19 +01:00
|
|
|
#endif /* SAE_H */
|