]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Move Authentication Request building into a separate function
authorJouni Malinen <jouni@qca.qualcomm.com>
Sun, 22 Oct 2017 14:08:25 +0000 (17:08 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 22 Oct 2017 15:25:30 +0000 (18:25 +0300)
This cleans up dpp_auth_init() a bit by separating initialization steps
for a DPP authentication session from the code needed to build the
frame. In addition, this makes it easier to remove some of the
attributes for protocol testing purposes.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/common/dpp.c

index b15b172ed8b3ee4b42a7d4a4131ea02c6c83e035..0d5c561ed45abf1286674a189081f852c702dd50 100644 (file)
@@ -1339,16 +1339,13 @@ static int dpp_derive_ke(struct dpp_authentication *auth, u8 *ke,
 }
 
 
-struct dpp_authentication * dpp_auth_init(void *msg_ctx,
-                                         struct dpp_bootstrap_info *peer_bi,
-                                         struct dpp_bootstrap_info *own_bi,
-                                         int configurator)
+static struct wpabuf * dpp_auth_build_req(struct dpp_authentication *auth,
+                                         const struct wpabuf *pi,
+                                         size_t nonce_len,
+                                         const u8 *r_pubkey_hash,
+                                         const u8 *i_pubkey_hash)
 {
-       struct dpp_authentication *auth;
-       size_t nonce_len;
-       EVP_PKEY_CTX *ctx = NULL;
-       size_t secret_len;
-       struct wpabuf *msg, *pi = NULL;
+       struct wpabuf *msg;
        u8 clear[4 + DPP_MAX_NONCE_LEN + 4 + 1];
        u8 wrapped_data[4 + DPP_MAX_NONCE_LEN + 4 + 1 + AES_BLOCK_SIZE];
        u8 *pos;
@@ -1356,57 +1353,8 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        size_t len[2], siv_len, attr_len;
        u8 *attr_start, *attr_end;
 
-       auth = os_zalloc(sizeof(*auth));
-       if (!auth)
-               return NULL;
-       auth->msg_ctx = msg_ctx;
-       auth->initiator = 1;
-       auth->configurator = configurator;
-       auth->peer_bi = peer_bi;
-       auth->own_bi = own_bi;
-       auth->curve = peer_bi->curve;
-
-       nonce_len = auth->curve->nonce_len;
-       if (random_get_bytes(auth->i_nonce, nonce_len)) {
-               wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
-               goto fail;
-       }
-       wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len);
-
-       auth->own_protocol_key = dpp_gen_keypair(auth->curve);
-       if (!auth->own_protocol_key)
-               goto fail;
-
-       pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
-       if (!pi)
-               goto fail;
-
-       /* ECDH: M = pI * BR */
-       ctx = EVP_PKEY_CTX_new(auth->own_protocol_key, NULL);
-       if (!ctx ||
-           EVP_PKEY_derive_init(ctx) != 1 ||
-           EVP_PKEY_derive_set_peer(ctx, auth->peer_bi->pubkey) != 1 ||
-           EVP_PKEY_derive(ctx, NULL, &secret_len) != 1 ||
-           secret_len > DPP_MAX_SHARED_SECRET_LEN ||
-           EVP_PKEY_derive(ctx, auth->Mx, &secret_len) != 1) {
-               wpa_printf(MSG_ERROR,
-                          "DPP: Failed to derive ECDH shared secret: %s",
-                          ERR_error_string(ERR_get_error(), NULL));
-               goto fail;
-       }
-       auth->secret_len = secret_len;
-       EVP_PKEY_CTX_free(ctx);
-       ctx = NULL;
-
-       wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
-                       auth->Mx, auth->secret_len);
-
-       if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
-                         auth->curve->hash_len) < 0)
-               goto fail;
-
        /* Build DPP Authentication Request frame attributes */
-       attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + wpabuf_len(pi) +
+       attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + (pi ? wpabuf_len(pi) : 0) +
                4 + sizeof(wrapped_data);
 #ifdef CONFIG_TESTING_OPTIONS
        if (dpp_test == DPP_TEST_AFTER_WRAPPED_DATA_AUTH_REQ)
@@ -1414,33 +1362,34 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
 #endif /* CONFIG_TESTING_OPTIONS */
        msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ, attr_len);
        if (!msg)
-               goto fail;
-       auth->req_msg = msg;
+               return NULL;
 
        attr_start = wpabuf_put(msg, 0);
 
        /* Responder Bootstrapping Key Hash */
-       wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
-       wpabuf_put_le16(msg, SHA256_MAC_LEN);
-       wpabuf_put_data(msg, auth->peer_bi->pubkey_hash, SHA256_MAC_LEN);
+       if (r_pubkey_hash) {
+               wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
+               wpabuf_put_le16(msg, SHA256_MAC_LEN);
+               wpabuf_put_data(msg, r_pubkey_hash, SHA256_MAC_LEN);
+       }
 
        /* Initiator Bootstrapping Key Hash */
-       wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
-       wpabuf_put_le16(msg, SHA256_MAC_LEN);
-       if (auth->own_bi)
-               wpabuf_put_data(msg, auth->own_bi->pubkey_hash, SHA256_MAC_LEN);
-       else
-               os_memset(wpabuf_put(msg, SHA256_MAC_LEN), 0, SHA256_MAC_LEN);
+       if (i_pubkey_hash) {
+               wpabuf_put_le16(msg, DPP_ATTR_I_BOOTSTRAP_KEY_HASH);
+               wpabuf_put_le16(msg, SHA256_MAC_LEN);
+               wpabuf_put_data(msg, i_pubkey_hash, SHA256_MAC_LEN);
+       }
 
        /* Initiator Protocol Key */
-       wpabuf_put_le16(msg, DPP_ATTR_I_PROTOCOL_KEY);
-       wpabuf_put_le16(msg, wpabuf_len(pi));
-       wpabuf_put_buf(msg, pi);
-       wpabuf_free(pi);
-       pi = NULL;
+       if (pi) {
+               wpabuf_put_le16(msg, DPP_ATTR_I_PROTOCOL_KEY);
+               wpabuf_put_le16(msg, wpabuf_len(pi));
+               wpabuf_put_buf(msg, pi);
+       }
 
        /* Wrapped data ({I-nonce, I-capabilities}k1) */
        pos = clear;
+
        /* I-nonce */
        WPA_PUT_LE16(pos, DPP_ATTR_I_NONCE);
        pos += 2;
@@ -1448,12 +1397,13 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        pos += 2;
        os_memcpy(pos, auth->i_nonce, nonce_len);
        pos += nonce_len;
+
        /* I-capabilities */
        WPA_PUT_LE16(pos, DPP_ATTR_I_CAPABILITIES);
        pos += 2;
        WPA_PUT_LE16(pos, 1);
        pos += 2;
-       auth->i_capab = configurator ? DPP_CAPAB_CONFIGURATOR :
+       auth->i_capab = auth->configurator ? DPP_CAPAB_CONFIGURATOR :
                DPP_CAPAB_ENROLLEE;
        *pos++ = auth->i_capab;
 #ifdef CONFIG_TESTING_OPTIONS
@@ -1478,8 +1428,10 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        siv_len = pos - clear;
        wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
        if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
-                           2, addr, len, wrapped_data) < 0)
-               goto fail;
+                           2, addr, len, wrapped_data) < 0) {
+               wpabuf_free(msg);
+               return NULL;
+       }
        siv_len += AES_BLOCK_SIZE;
        wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
                    wrapped_data, siv_len);
@@ -1499,12 +1451,94 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
        wpa_hexdump_buf(MSG_DEBUG,
                        "DPP: Authentication Request frame attributes", msg);
 
-       return auth;
-fail:
+       return msg;
+}
+
+
+struct dpp_authentication * dpp_auth_init(void *msg_ctx,
+                                         struct dpp_bootstrap_info *peer_bi,
+                                         struct dpp_bootstrap_info *own_bi,
+                                         int configurator)
+{
+       struct dpp_authentication *auth;
+       size_t nonce_len;
+       EVP_PKEY_CTX *ctx = NULL;
+       size_t secret_len;
+       struct wpabuf *pi = NULL;
+       u8 zero[SHA256_MAC_LEN];
+       const u8 *r_pubkey_hash, *i_pubkey_hash;
+
+       auth = os_zalloc(sizeof(*auth));
+       if (!auth)
+               return NULL;
+       auth->msg_ctx = msg_ctx;
+       auth->initiator = 1;
+       auth->configurator = configurator;
+       auth->peer_bi = peer_bi;
+       auth->own_bi = own_bi;
+       auth->curve = peer_bi->curve;
+
+       nonce_len = auth->curve->nonce_len;
+       if (random_get_bytes(auth->i_nonce, nonce_len)) {
+               wpa_printf(MSG_ERROR, "DPP: Failed to generate I-nonce");
+               goto fail;
+       }
+       wpa_hexdump(MSG_DEBUG, "DPP: I-nonce", auth->i_nonce, nonce_len);
+
+       auth->own_protocol_key = dpp_gen_keypair(auth->curve);
+       if (!auth->own_protocol_key)
+               goto fail;
+
+       pi = dpp_get_pubkey_point(auth->own_protocol_key, 0);
+       if (!pi)
+               goto fail;
+
+       /* ECDH: M = pI * BR */
+       ctx = EVP_PKEY_CTX_new(auth->own_protocol_key, NULL);
+       if (!ctx ||
+           EVP_PKEY_derive_init(ctx) != 1 ||
+           EVP_PKEY_derive_set_peer(ctx, auth->peer_bi->pubkey) != 1 ||
+           EVP_PKEY_derive(ctx, NULL, &secret_len) != 1 ||
+           secret_len > DPP_MAX_SHARED_SECRET_LEN ||
+           EVP_PKEY_derive(ctx, auth->Mx, &secret_len) != 1) {
+               wpa_printf(MSG_ERROR,
+                          "DPP: Failed to derive ECDH shared secret: %s",
+                          ERR_error_string(ERR_get_error(), NULL));
+               goto fail;
+       }
+       auth->secret_len = secret_len;
+       EVP_PKEY_CTX_free(ctx);
+       ctx = NULL;
+
+       wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (M.x)",
+                       auth->Mx, auth->secret_len);
+
+       if (dpp_derive_k1(auth->Mx, auth->secret_len, auth->k1,
+                         auth->curve->hash_len) < 0)
+               goto fail;
+
+       r_pubkey_hash = auth->peer_bi->pubkey_hash;
+
+       if (auth->own_bi) {
+               i_pubkey_hash = auth->own_bi->pubkey_hash;
+       } else {
+               os_memset(zero, 0, SHA256_MAC_LEN);
+               i_pubkey_hash = zero;
+       }
+
+       auth->req_msg = dpp_auth_build_req(auth, pi, nonce_len, r_pubkey_hash,
+                                          i_pubkey_hash);
+       if (!auth->req_msg)
+               goto fail;
+
+out:
        wpabuf_free(pi);
        EVP_PKEY_CTX_free(ctx);
+       return auth;
+fail:
        dpp_auth_deinit(auth);
-       return NULL;
+       auth = NULL;
+       goto out;
 }