xref: /aosp_15_r20/external/wpa_supplicant_8/src/common/sae.h (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker  * Simultaneous authentication of equals
3*03f9172cSAndroid Build Coastguard Worker  * Copyright (c) 2012-2013, Jouni Malinen <[email protected]>
4*03f9172cSAndroid Build Coastguard Worker  *
5*03f9172cSAndroid Build Coastguard Worker  * This software may be distributed under the terms of the BSD license.
6*03f9172cSAndroid Build Coastguard Worker  * See README for more details.
7*03f9172cSAndroid Build Coastguard Worker  */
8*03f9172cSAndroid Build Coastguard Worker 
9*03f9172cSAndroid Build Coastguard Worker #ifndef SAE_H
10*03f9172cSAndroid Build Coastguard Worker #define SAE_H
11*03f9172cSAndroid Build Coastguard Worker 
12*03f9172cSAndroid Build Coastguard Worker #define SAE_KCK_LEN 32
13*03f9172cSAndroid Build Coastguard Worker #define SAE_PMK_LEN 32
14*03f9172cSAndroid Build Coastguard Worker #define SAE_PMK_LEN_MAX 64
15*03f9172cSAndroid Build Coastguard Worker #define SAE_PMKID_LEN 16
16*03f9172cSAndroid Build Coastguard Worker #define SAE_MAX_PRIME_LEN 512
17*03f9172cSAndroid Build Coastguard Worker #define SAE_MAX_ECC_PRIME_LEN 66
18*03f9172cSAndroid Build Coastguard Worker #define SAE_MAX_HASH_LEN 64
19*03f9172cSAndroid Build Coastguard Worker #define SAE_COMMIT_MAX_LEN (2 + 3 * SAE_MAX_PRIME_LEN + 255)
20*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE_PK
21*03f9172cSAndroid Build Coastguard Worker #define SAE_CONFIRM_MAX_LEN ((2 + SAE_MAX_HASH_LEN) + 1500)
22*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_SAE_PK */
23*03f9172cSAndroid Build Coastguard Worker #define SAE_CONFIRM_MAX_LEN (2 + SAE_MAX_HASH_LEN)
24*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE_PK */
25*03f9172cSAndroid Build Coastguard Worker #define SAE_PK_M_LEN 16
26*03f9172cSAndroid Build Coastguard Worker 
27*03f9172cSAndroid Build Coastguard Worker /* Special value returned by sae_parse_commit() */
28*03f9172cSAndroid Build Coastguard Worker #define SAE_SILENTLY_DISCARD 65535
29*03f9172cSAndroid Build Coastguard Worker 
30*03f9172cSAndroid Build Coastguard Worker struct sae_pk {
31*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *m;
32*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec_key *key;
33*03f9172cSAndroid Build Coastguard Worker 	int group;
34*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *pubkey; /* DER encoded subjectPublicKey */
35*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_TESTING_OPTIONS
36*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec_key *sign_key_override;
37*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_TESTING_OPTIONS */
38*03f9172cSAndroid Build Coastguard Worker };
39*03f9172cSAndroid Build Coastguard Worker 
40*03f9172cSAndroid Build Coastguard Worker 
41*03f9172cSAndroid Build Coastguard Worker struct sae_temporary_data {
42*03f9172cSAndroid Build Coastguard Worker 	u8 kck[SAE_MAX_HASH_LEN];
43*03f9172cSAndroid Build Coastguard Worker 	size_t kck_len;
44*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *own_commit_scalar;
45*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *own_commit_element_ffc;
46*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec_point *own_commit_element_ecc;
47*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *peer_commit_element_ffc;
48*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec_point *peer_commit_element_ecc;
49*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec_point *pwe_ecc;
50*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *pwe_ffc;
51*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *sae_rand;
52*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec *ec;
53*03f9172cSAndroid Build Coastguard Worker 	int prime_len;
54*03f9172cSAndroid Build Coastguard Worker 	int order_len;
55*03f9172cSAndroid Build Coastguard Worker 	const struct dh_group *dh;
56*03f9172cSAndroid Build Coastguard Worker 	const struct crypto_bignum *prime;
57*03f9172cSAndroid Build Coastguard Worker 	const struct crypto_bignum *order;
58*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *prime_buf;
59*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *order_buf;
60*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *anti_clogging_token;
61*03f9172cSAndroid Build Coastguard Worker 	char *pw_id;
62*03f9172cSAndroid Build Coastguard Worker 	int vlan_id;
63*03f9172cSAndroid Build Coastguard Worker 	u8 bssid[ETH_ALEN];
64*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *own_rejected_groups;
65*03f9172cSAndroid Build Coastguard Worker 	struct wpabuf *peer_rejected_groups;
66*03f9172cSAndroid Build Coastguard Worker 	unsigned int own_addr_higher:1;
67*03f9172cSAndroid Build Coastguard Worker 
68*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE_PK
69*03f9172cSAndroid Build Coastguard Worker 	u8 kek[SAE_MAX_HASH_LEN];
70*03f9172cSAndroid Build Coastguard Worker 	size_t kek_len;
71*03f9172cSAndroid Build Coastguard Worker 	const struct sae_pk *ap_pk;
72*03f9172cSAndroid Build Coastguard Worker 	u8 own_addr[ETH_ALEN];
73*03f9172cSAndroid Build Coastguard Worker 	u8 peer_addr[ETH_ALEN];
74*03f9172cSAndroid Build Coastguard Worker 	u8 fingerprint[SAE_MAX_HASH_LEN];
75*03f9172cSAndroid Build Coastguard Worker 	size_t fingerprint_bytes;
76*03f9172cSAndroid Build Coastguard Worker 	size_t fingerprint_bits;
77*03f9172cSAndroid Build Coastguard Worker 	size_t lambda;
78*03f9172cSAndroid Build Coastguard Worker 	unsigned int sec;
79*03f9172cSAndroid Build Coastguard Worker 	u8 ssid[32];
80*03f9172cSAndroid Build Coastguard Worker 	size_t ssid_len;
81*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_TESTING_OPTIONS
82*03f9172cSAndroid Build Coastguard Worker 	bool omit_pk_elem;
83*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_TESTING_OPTIONS */
84*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE_PK */
85*03f9172cSAndroid Build Coastguard Worker 
86*03f9172cSAndroid Build Coastguard Worker 	struct os_reltime disabled_until;
87*03f9172cSAndroid Build Coastguard Worker };
88*03f9172cSAndroid Build Coastguard Worker 
89*03f9172cSAndroid Build Coastguard Worker struct sae_pt {
90*03f9172cSAndroid Build Coastguard Worker 	struct sae_pt *next;
91*03f9172cSAndroid Build Coastguard Worker 	int group;
92*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec *ec;
93*03f9172cSAndroid Build Coastguard Worker 	struct crypto_ec_point *ecc_pt;
94*03f9172cSAndroid Build Coastguard Worker 
95*03f9172cSAndroid Build Coastguard Worker 	const struct dh_group *dh;
96*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *ffc_pt;
97*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE_PK
98*03f9172cSAndroid Build Coastguard Worker 	u8 ssid[32];
99*03f9172cSAndroid Build Coastguard Worker 	size_t ssid_len;
100*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE_PK */
101*03f9172cSAndroid Build Coastguard Worker };
102*03f9172cSAndroid Build Coastguard Worker 
103*03f9172cSAndroid Build Coastguard Worker enum sae_state {
104*03f9172cSAndroid Build Coastguard Worker 	SAE_NOTHING, SAE_COMMITTED, SAE_CONFIRMED, SAE_ACCEPTED
105*03f9172cSAndroid Build Coastguard Worker };
106*03f9172cSAndroid Build Coastguard Worker 
107*03f9172cSAndroid Build Coastguard Worker struct sae_data {
108*03f9172cSAndroid Build Coastguard Worker 	enum sae_state state;
109*03f9172cSAndroid Build Coastguard Worker 	u16 send_confirm;
110*03f9172cSAndroid Build Coastguard Worker 	u8 pmk[SAE_PMK_LEN_MAX];
111*03f9172cSAndroid Build Coastguard Worker 	size_t pmk_len;
112*03f9172cSAndroid Build Coastguard Worker 	int akmp; /* WPA_KEY_MGMT_* used in key derivation */
113*03f9172cSAndroid Build Coastguard Worker 	u32 own_akm_suite_selector;
114*03f9172cSAndroid Build Coastguard Worker 	u32 peer_akm_suite_selector;
115*03f9172cSAndroid Build Coastguard Worker 	u8 pmkid[SAE_PMKID_LEN];
116*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *peer_commit_scalar;
117*03f9172cSAndroid Build Coastguard Worker 	struct crypto_bignum *peer_commit_scalar_accepted;
118*03f9172cSAndroid Build Coastguard Worker 	int group;
119*03f9172cSAndroid Build Coastguard Worker 	unsigned int sync; /* protocol instance variable: Sync */
120*03f9172cSAndroid Build Coastguard Worker 	u16 rc; /* protocol instance variable: Rc (received send-confirm) */
121*03f9172cSAndroid Build Coastguard Worker 	unsigned int h2e:1;
122*03f9172cSAndroid Build Coastguard Worker 	unsigned int pk:1;
123*03f9172cSAndroid Build Coastguard Worker 	struct sae_temporary_data *tmp;
124*03f9172cSAndroid Build Coastguard Worker };
125*03f9172cSAndroid Build Coastguard Worker 
126*03f9172cSAndroid Build Coastguard Worker int sae_set_group(struct sae_data *sae, int group);
127*03f9172cSAndroid Build Coastguard Worker void sae_clear_temp_data(struct sae_data *sae);
128*03f9172cSAndroid Build Coastguard Worker void sae_clear_data(struct sae_data *sae);
129*03f9172cSAndroid Build Coastguard Worker 
130*03f9172cSAndroid Build Coastguard Worker int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
131*03f9172cSAndroid Build Coastguard Worker 		       const u8 *password, size_t password_len,
132*03f9172cSAndroid Build Coastguard Worker 		       struct sae_data *sae);
133*03f9172cSAndroid Build Coastguard Worker int sae_prepare_commit_pt(struct sae_data *sae, const struct sae_pt *pt,
134*03f9172cSAndroid Build Coastguard Worker 			  const u8 *addr1, const u8 *addr2,
135*03f9172cSAndroid Build Coastguard Worker 			  int *rejected_groups, const struct sae_pk *pk);
136*03f9172cSAndroid Build Coastguard Worker int sae_process_commit(struct sae_data *sae);
137*03f9172cSAndroid Build Coastguard Worker int sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
138*03f9172cSAndroid Build Coastguard Worker 		     const struct wpabuf *token, const char *identifier);
139*03f9172cSAndroid Build Coastguard Worker u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
140*03f9172cSAndroid Build Coastguard Worker 		     const u8 **token, size_t *token_len, int *allowed_groups,
141*03f9172cSAndroid Build Coastguard Worker 		     int h2e, int *ie_offset);
142*03f9172cSAndroid Build Coastguard Worker int sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
143*03f9172cSAndroid Build Coastguard Worker int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len,
144*03f9172cSAndroid Build Coastguard Worker 		      int *ie_offset);
145*03f9172cSAndroid Build Coastguard Worker u16 sae_group_allowed(struct sae_data *sae, int *allowed_groups, u16 group);
146*03f9172cSAndroid Build Coastguard Worker const char * sae_state_txt(enum sae_state state);
147*03f9172cSAndroid Build Coastguard Worker size_t sae_ecc_prime_len_2_hash_len(size_t prime_len);
148*03f9172cSAndroid Build Coastguard Worker size_t sae_ffc_prime_len_2_hash_len(size_t prime_len);
149*03f9172cSAndroid Build Coastguard Worker struct sae_pt * sae_derive_pt(int *groups, const u8 *ssid, size_t ssid_len,
150*03f9172cSAndroid Build Coastguard Worker 			      const u8 *password, size_t password_len,
151*03f9172cSAndroid Build Coastguard Worker 			      const char *identifier);
152*03f9172cSAndroid Build Coastguard Worker struct crypto_ec_point *
153*03f9172cSAndroid Build Coastguard Worker sae_derive_pwe_from_pt_ecc(const struct sae_pt *pt,
154*03f9172cSAndroid Build Coastguard Worker 			   const u8 *addr1, const u8 *addr2);
155*03f9172cSAndroid Build Coastguard Worker struct crypto_bignum *
156*03f9172cSAndroid Build Coastguard Worker sae_derive_pwe_from_pt_ffc(const struct sae_pt *pt,
157*03f9172cSAndroid Build Coastguard Worker 			   const u8 *addr1, const u8 *addr2);
158*03f9172cSAndroid Build Coastguard Worker void sae_deinit_pt(struct sae_pt *pt);
159*03f9172cSAndroid Build Coastguard Worker 
160*03f9172cSAndroid Build Coastguard Worker /* sae_pk.c */
161*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_SAE_PK
162*03f9172cSAndroid Build Coastguard Worker bool sae_pk_valid_password(const char *pw);
163*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_SAE_PK */
sae_pk_valid_password(const char * pw)164*03f9172cSAndroid Build Coastguard Worker static inline bool sae_pk_valid_password(const char *pw)
165*03f9172cSAndroid Build Coastguard Worker {
166*03f9172cSAndroid Build Coastguard Worker 	return false;
167*03f9172cSAndroid Build Coastguard Worker }
168*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_SAE_PK */
169*03f9172cSAndroid Build Coastguard Worker char * sae_pk_base32_encode(const u8 *src, size_t len_bits);
170*03f9172cSAndroid Build Coastguard Worker u8 * sae_pk_base32_decode(const char *src, size_t len, size_t *out_len);
171*03f9172cSAndroid Build Coastguard Worker int sae_pk_set_password(struct sae_data *sae, const char *password);
172*03f9172cSAndroid Build Coastguard Worker void sae_deinit_pk(struct sae_pk *pk);
173*03f9172cSAndroid Build Coastguard Worker struct sae_pk * sae_parse_pk(const char *val);
174*03f9172cSAndroid Build Coastguard Worker int sae_write_confirm_pk(struct sae_data *sae, struct wpabuf *buf);
175*03f9172cSAndroid Build Coastguard Worker int sae_check_confirm_pk(struct sae_data *sae, const u8 *ies, size_t ies_len);
176*03f9172cSAndroid Build Coastguard Worker int sae_hash(size_t hash_len, const u8 *data, size_t len, u8 *hash);
177*03f9172cSAndroid Build Coastguard Worker u32 sae_pk_get_be19(const u8 *buf);
178*03f9172cSAndroid Build Coastguard Worker void sae_pk_buf_shift_left_19(u8 *buf, size_t len);
179*03f9172cSAndroid Build Coastguard Worker 
180*03f9172cSAndroid Build Coastguard Worker #endif /* SAE_H */
181