Parcourir la source

SAE: Add generation of the confirm message fields

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen il y a 12 ans
Parent
commit
fb8fcc2950
4 fichiers modifiés avec 38 ajouts et 8 suppressions
  1. 2 4
      src/ap/ieee802_11.c
  2. 32 0
      src/common/sae.c
  3. 2 0
      src/common/sae.h
  4. 2 4
      wpa_supplicant/sme.c

+ 2 - 4
src/ap/ieee802_11.c

@@ -355,13 +355,11 @@ static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
 {
 	struct wpabuf *buf;
 
-	buf = wpabuf_alloc(2);
+	buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
 	if (buf == NULL)
 		return NULL;
 
-	wpabuf_put_le16(buf, sta->sae->send_confirm);
-	sta->sae->send_confirm++;
-	/* TODO: Confirm */
+	sae_write_confirm(sta->sae, buf);
 
 	return buf;
 }

+ 32 - 0
src/common/sae.c

@@ -542,3 +542,35 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len)
 
 	return WLAN_STATUS_SUCCESS;
 }
+
+
+void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf)
+{
+	const u8 *sc;
+	const u8 *addr[5];
+	size_t len[5];
+
+	/* Send-Confirm */
+	sc = wpabuf_put(buf, 0);
+	wpabuf_put_le16(buf, sae->send_confirm);
+	sae->send_confirm++;
+
+	/* Confirm
+	 * CN(key, X, Y, Z, ...) =
+	 *    HMAC-SHA256(key, D2OS(X) || D2OS(Y) || D2OS(Z) | ...)
+	 * confirm = CN(KCK, send-confirm, commit-scalar, COMMIT-ELEMENT,
+	 *              peer-commit-scalar, PEER-COMMIT-ELEMENT)
+	 */
+	addr[0] = sc;
+	len[0] = 2;
+	addr[1] = sae->own_commit_scalar;
+	len[1] = 32;
+	addr[2] = sae->own_commit_element;
+	len[2] = 2 * 32;
+	addr[3] = sae->peer_commit_scalar;
+	len[3] = 32;
+	addr[4] = sae->peer_commit_element;
+	len[4] = 2 * 32;
+	hmac_sha256_vector(sae->kck, sizeof(sae->kck), 5, addr, len,
+			   wpabuf_put(buf, SHA256_MAC_LEN));
+}

+ 2 - 0
src/common/sae.h

@@ -10,6 +10,7 @@
 #define SAE_H
 
 #define SAE_COMMIT_MAX_LEN (2 + 3 * 32)
+#define SAE_CONFIRM_MAX_LEN (2 + 32)
 
 struct sae_data {
 	enum { SAE_INIT, SAE_COMMIT, SAE_CONFIRM } state;
@@ -30,5 +31,6 @@ int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
 int sae_process_commit(struct sae_data *sae);
 void sae_write_commit(struct sae_data *sae, struct wpabuf *buf);
 u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len);
+void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf);
 
 #endif /* SAE_H */

+ 2 - 4
wpa_supplicant/sme.c

@@ -77,15 +77,13 @@ static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s)
 {
 	struct wpabuf *buf;
 
-	buf = wpabuf_alloc(4 + 2);
+	buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN);
 	if (buf == NULL)
 		return NULL;
 
 	wpabuf_put_le16(buf, 2); /* Transaction seq# */
 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
-	wpabuf_put_le16(buf, wpa_s->sme.sae.send_confirm);
-	wpa_s->sme.sae.send_confirm++;
-	/* TODO: Confirm */
+	sae_write_confirm(&wpa_s->sme.sae, buf);
 
 	return buf;
 }