From: Cedric Izoard <cedric.izoard@xxxxxxxxxxx> Move code of dpp_get_pubkey_point to a crypto lib specific function crypto_ec_key_get_pubkey_point. Also complete crypto_ec_key_group with brainpool curves. Signed-off-by: Cedric Izoard <cedric.izoard@xxxxxxxxxxxx> --- src/common/dpp.c | 4 +- src/common/dpp_auth.c | 4 +- src/common/dpp_crypto.c | 85 +++++++++---------------------------- src/common/dpp_i.h | 1 - src/common/dpp_pkex.c | 20 ++++----- src/common/dpp_reconfig.c | 8 ++-- src/crypto/crypto.h | 9 ++++ src/crypto/crypto_openssl.c | 57 ++++++++++++++++++++++++- tests/hwsim/test_dpp.py | 20 ++++----- 9 files changed, 112 insertions(+), 96 deletions(-) diff --git a/src/common/dpp.c b/src/common/dpp.c index f85eb2d4d..a2a686211 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -1367,7 +1367,7 @@ int dpp_build_jwk(struct wpabuf *buf, const char *name, struct crypto_ec_key *ke const u8 *pos; int ret = -1; - pub = dpp_get_pubkey_point(key, 0); + pub = crypto_ec_key_get_pubkey_point(key, 0); if (!pub) goto fail; @@ -3422,7 +3422,7 @@ static int dpp_configurator_gen_kid(struct dpp_configurator *conf) size_t len[1]; int res; - csign_pub = dpp_get_pubkey_point(conf->csign, 1); + csign_pub = crypto_ec_key_get_pubkey_point(conf->csign, 1); if (!csign_pub) { wpa_printf(MSG_INFO, "DPP: Failed to extract C-sign-key"); return -1; diff --git a/src/common/dpp_auth.c b/src/common/dpp_auth.c index 6c8ea8dc7..2f5f47459 100644 --- a/src/common/dpp_auth.c +++ b/src/common/dpp_auth.c @@ -475,7 +475,7 @@ static int dpp_auth_build_resp_ok(struct dpp_authentication *auth) if (!auth->own_protocol_key) goto fail; - pr = dpp_get_pubkey_point(auth->own_protocol_key, 0); + pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); if (!pr) goto fail; @@ -1235,7 +1235,7 @@ struct dpp_authentication * dpp_auth_init(struct dpp_global *dpp, void *msg_ctx, if (!auth->own_protocol_key) goto fail; - pi = dpp_get_pubkey_point(auth->own_protocol_key, 0); + pi = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); if (!pi) goto fail; diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c index 222d15368..5e7cd76ea 100644 --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c @@ -375,53 +375,6 @@ int dpp_bn2bin_pad(const BIGNUM *bn, u8 *pos, size_t len) } -struct wpabuf * dpp_get_pubkey_point(struct crypto_ec_key *key, int prefix) -{ - int len, res; - EC_KEY *eckey; - struct wpabuf *buf; - unsigned char *pos; - - eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *)key); - if (!eckey) - return NULL; - EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED); - len = i2o_ECPublicKey(eckey, NULL); - if (len <= 0) { - wpa_printf(MSG_ERROR, - "DDP: Failed to determine public key encoding length"); - EC_KEY_free(eckey); - return NULL; - } - - buf = wpabuf_alloc(len); - if (!buf) { - EC_KEY_free(eckey); - return NULL; - } - - pos = wpabuf_put(buf, len); - res = i2o_ECPublicKey(eckey, &pos); - EC_KEY_free(eckey); - if (res != len) { - wpa_printf(MSG_ERROR, - "DDP: Failed to encode public key (res=%d/%d)", - res, len); - wpabuf_free(buf); - return NULL; - } - - if (!prefix) { - /* Remove 0x04 prefix to match DPP definition */ - pos = wpabuf_mhead(buf); - os_memmove(pos, pos + 1, len - 1); - buf->used--; - } - - return buf; -} - - struct crypto_ec_key * dpp_set_pubkey_point_group(const EC_GROUP *group, const u8 *buf_x, const u8 *buf_y, size_t len) @@ -1166,7 +1119,7 @@ static int dpp_check_pubkey_match(struct crypto_ec_key *pub, struct wpabuf *r_ha if (wpabuf_len(r_hash) != SHA256_MAC_LEN) return -1; - uncomp = dpp_get_pubkey_point(pub, 1); + uncomp = crypto_ec_key_get_pubkey_point(pub, 1); if (!uncomp) return -1; addr[0] = wpabuf_head(uncomp); @@ -1397,21 +1350,21 @@ int dpp_gen_r_auth(struct dpp_authentication *auth, u8 *r_auth) nonce_len = auth->curve->nonce_len; if (auth->initiator) { - pix = dpp_get_pubkey_point(auth->own_protocol_key, 0); - prx = dpp_get_pubkey_point(auth->peer_protocol_key, 0); + pix = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); + prx = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key, 0); if (auth->own_bi) - bix = dpp_get_pubkey_point(auth->own_bi->pubkey, 0); + bix = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0); else bix = NULL; - brx = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0); + brx = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0); } else { - pix = dpp_get_pubkey_point(auth->peer_protocol_key, 0); - prx = dpp_get_pubkey_point(auth->own_protocol_key, 0); + pix = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key, 0); + prx = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); if (auth->peer_bi) - bix = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0); + bix = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0); else bix = NULL; - brx = dpp_get_pubkey_point(auth->own_bi->pubkey, 0); + brx = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0); } if (!pix || !prx || !brx) goto fail; @@ -1476,25 +1429,25 @@ int dpp_gen_i_auth(struct dpp_authentication *auth, u8 *i_auth) nonce_len = auth->curve->nonce_len; if (auth->initiator) { - pix = dpp_get_pubkey_point(auth->own_protocol_key, 0); - prx = dpp_get_pubkey_point(auth->peer_protocol_key, 0); + pix = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); + prx = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key, 0); if (auth->own_bi) - bix = dpp_get_pubkey_point(auth->own_bi->pubkey, 0); + bix = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0); else bix = NULL; if (!auth->peer_bi) goto fail; - brx = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0); + brx = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0); } else { - pix = dpp_get_pubkey_point(auth->peer_protocol_key, 0); - prx = dpp_get_pubkey_point(auth->own_protocol_key, 0); + pix = crypto_ec_key_get_pubkey_point(auth->peer_protocol_key, 0); + prx = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); if (auth->peer_bi) - bix = dpp_get_pubkey_point(auth->peer_bi->pubkey, 0); + bix = crypto_ec_key_get_pubkey_point(auth->peer_bi->pubkey, 0); else bix = NULL; if (!auth->own_bi) goto fail; - brx = dpp_get_pubkey_point(auth->own_bi->pubkey, 0); + brx = crypto_ec_key_get_pubkey_point(auth->own_bi->pubkey, 0); } if (!pix || !prx || !brx) goto fail; @@ -1704,8 +1657,8 @@ int dpp_derive_pmkid(const struct dpp_curve_params *curve, u8 hash[SHA256_MAC_LEN]; /* PMKID = Truncate-128(H(min(NK.x, PK.x) | max(NK.x, PK.x))) */ - nkx = dpp_get_pubkey_point(own_key, 0); - pkx = dpp_get_pubkey_point(peer_key, 0); + nkx = crypto_ec_key_get_pubkey_point(own_key, 0); + pkx = crypto_ec_key_get_pubkey_point(peer_key, 0); if (!nkx || !pkx) goto fail; addr[0] = wpabuf_head(nkx); diff --git a/src/common/dpp_i.h b/src/common/dpp_i.h index 6deb34737..6f9f489f2 100644 --- a/src/common/dpp_i.h +++ b/src/common/dpp_i.h @@ -76,7 +76,6 @@ const struct dpp_curve_params * dpp_get_curve_nid(int nid); const struct dpp_curve_params * dpp_get_curve_ike_group(u16 group); int dpp_bi_pubkey_hash(struct dpp_bootstrap_info *bi, const u8 *data, size_t data_len); -struct wpabuf * dpp_get_pubkey_point(struct crypto_ec_key *key, int prefix); struct crypto_ec_key * dpp_set_pubkey_point_group(const EC_GROUP *group, const u8 *buf_x, const u8 *buf_y, size_t len); diff --git a/src/common/dpp_pkex.c b/src/common/dpp_pkex.c index cde46ac39..24f7536a8 100644 --- a/src/common/dpp_pkex.c +++ b/src/common/dpp_pkex.c @@ -812,9 +812,9 @@ struct wpabuf * dpp_pkex_rx_exchange_resp(struct dpp_pkex *pkex, Jx, Jx_len); /* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x) */ - A_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0); - Y_pub = dpp_get_pubkey_point(pkex->y, 0); - X_pub = dpp_get_pubkey_point(pkex->x, 0); + A_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0); + Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0); + X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0); if (!A_pub || !Y_pub || !X_pub) goto fail; addr[0] = pkex->own_mac; @@ -1078,9 +1078,9 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex, Jx, Jx_len); /* u' = HMAC(J'.x, MAC-Initiator | A'.x | Y.x | X'.x) */ - A_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0); - Y_pub = dpp_get_pubkey_point(pkex->y, 0); - X_pub = dpp_get_pubkey_point(pkex->x, 0); + A_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0); + Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0); + X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0); if (!A_pub || !Y_pub || !X_pub) goto fail; addr[0] = pkex->peer_mac; @@ -1115,7 +1115,7 @@ struct wpabuf * dpp_pkex_rx_commit_reveal_req(struct dpp_pkex *pkex, Lx, Lx_len); /* v = HMAC(L.x, MAC-Responder | B.x | X'.x | Y.x) */ - B_pub = dpp_get_pubkey_point(pkex->own_bi->pubkey, 0); + B_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0); if (!B_pub) goto fail; addr[0] = pkex->own_mac; @@ -1240,9 +1240,9 @@ int dpp_pkex_rx_commit_reveal_resp(struct dpp_pkex *pkex, const u8 *hdr, Lx, Lx_len); /* v' = HMAC(L.x, MAC-Responder | B'.x | X.x | Y'.x) */ - B_pub = dpp_get_pubkey_point(pkex->peer_bootstrap_key, 0); - X_pub = dpp_get_pubkey_point(pkex->x, 0); - Y_pub = dpp_get_pubkey_point(pkex->y, 0); + B_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0); + X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0); + Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0); if (!B_pub || !X_pub || !Y_pub) goto fail; addr[0] = pkex->peer_mac; diff --git a/src/common/dpp_reconfig.c b/src/common/dpp_reconfig.c index a6959c1bc..03235d27e 100644 --- a/src/common/dpp_reconfig.c +++ b/src/common/dpp_reconfig.c @@ -69,7 +69,7 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key, goto fail; } - uncomp = dpp_get_pubkey_point(csign, 1); + uncomp = crypto_ec_key_get_pubkey_point(csign, 1); crypto_ec_key_deinit(csign); if (!uncomp) goto fail; @@ -88,8 +88,8 @@ struct wpabuf * dpp_build_reconfig_announcement(const u8 *csign_key, goto fail; } - a_nonce = dpp_get_pubkey_point(id->a_nonce, 0); - e_id = dpp_get_pubkey_point(id->e_prime_id, 0); + a_nonce = crypto_ec_key_get_pubkey_point(id->a_nonce, 0); + e_id = crypto_ec_key_get_pubkey_point(id->e_prime_id, 0); if (!a_nonce || !e_id) goto fail; @@ -341,7 +341,7 @@ static int dpp_reconfig_build_resp(struct dpp_authentication *auth, wpabuf_put_le16(clear, wpabuf_len(conn_status)); wpabuf_put_buf(clear, conn_status); - pr = dpp_get_pubkey_point(auth->own_protocol_key, 0); + pr = crypto_ec_key_get_pubkey_point(auth->own_protocol_key, 0); if (!pr) goto fail; diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index b4e3ae530..e5d40fb09 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -1023,6 +1023,15 @@ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key); struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, bool include_pub); +/** + * crypto_ec_key_get_pubkey_point - Get Public Key Point coordinates + * @key: EC key from crypto_ec_key_parse/set_pub() or crypto_ec_key_parse_priv() + * @prefix: Whether output buffer should include the octect to indicate coordinate + * form (as defined for SubjectPublicKeyInfo) + * Returns: Buffer with coordinates of Public key in uncompressed form or %NULL on failure + */ +struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int prefix); + /** * crypto_ec_key_sign - Sign a buffer with an EC key * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen() diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index a10746f41..11aa4c744 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -2359,6 +2359,54 @@ struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, } buf = wpabuf_alloc_copy(der, der_len); OPENSSL_free(der); + + return buf; +} + + +struct wpabuf * crypto_ec_key_get_pubkey_point(struct crypto_ec_key *key, int prefix) +{ + int len, res; + EC_KEY *eckey; + struct wpabuf *buf; + unsigned char *pos; + + eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *)key); + if (!eckey) + return NULL; + EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED); + len = i2o_ECPublicKey(eckey, NULL); + if (len <= 0) { + wpa_printf(MSG_ERROR, + "OpenSSL: Failed to determine public key encoding length"); + EC_KEY_free(eckey); + return NULL; + } + + buf = wpabuf_alloc(len); + if (!buf) { + EC_KEY_free(eckey); + return NULL; + } + + pos = wpabuf_put(buf, len); + res = i2o_ECPublicKey(eckey, &pos); + EC_KEY_free(eckey); + if (res != len) { + wpa_printf(MSG_ERROR, + "OpenSSL: Failed to encode public key (res=%d/%d)", + res, len); + wpabuf_free(buf); + return NULL; + } + + if (!prefix) { + /* Remove 0x04 prefix if requested */ + pos = wpabuf_mhead(buf); + os_memmove(pos, pos + 1, len - 1); + buf->used--; + } + return buf; } @@ -2433,7 +2481,14 @@ int crypto_ec_key_group(struct crypto_ec_key *key) return 20; case NID_secp521r1: return 21; - } + case NID_brainpoolP256r1: + return 28; + case NID_brainpoolP384r1: + return 29; + case NID_brainpoolP512r1: + return 30; + } + wpa_printf(MSG_ERROR, "OpenSSL: Unsupported curve (nid=%d) in EC key", nid); return -1; } diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py index 71df7fc64..50827b816 100644 --- a/tests/hwsim/test_dpp.py +++ b/tests/hwsim/test_dpp.py @@ -2482,7 +2482,7 @@ def test_dpp_pkex_commit_reveal_req_processing_failure(dev, apdev): dev[0].dpp_pkex_resp(2437, identifier="test", code="secret") with alloc_fail(dev[0], 1, - "dpp_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"): + "crypto_ec_key_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"): dev[1].dpp_pkex_init(identifier="test", code="secret") wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") @@ -4138,7 +4138,7 @@ def test_dpp_pkex_alloc_fail(dev, apdev): id1 = None # Local error cases on the Initiator - tests = [(1, "dpp_get_pubkey_point"), + tests = [(1, "crypto_ec_key_get_pubkey_point"), (1, "dpp_alloc_msg;dpp_pkex_build_exchange_req"), (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_req"), (1, "dpp_alloc_msg;dpp_auth_build_req"), @@ -4168,9 +4168,9 @@ def test_dpp_pkex_alloc_fail(dev, apdev): (3, "dpp_pkex_init"), (1, "dpp_pkex_derive_z"), (1, "=dpp_pkex_rx_commit_reveal_resp"), - (1, "dpp_get_pubkey_point;dpp_build_jwk"), - (2, "dpp_get_pubkey_point;dpp_build_jwk"), - (1, "dpp_get_pubkey_point;dpp_auth_init")] + (1, "crypto_ec_key_get_pubkey_point;dpp_build_jwk"), + (2, "crypto_ec_key_get_pubkey_point;dpp_build_jwk"), + (1, "crypto_ec_key_get_pubkey_point;dpp_auth_init")] for count, func in tests: dev[0].request("DPP_STOP_LISTEN") dev[1].request("DPP_STOP_LISTEN") @@ -4191,11 +4191,11 @@ def test_dpp_pkex_alloc_fail(dev, apdev): dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3) # Local error cases on the Responder - tests = [(1, "dpp_get_pubkey_point"), + tests = [(1, "crypto_ec_key_get_pubkey_point"), (1, "dpp_alloc_msg;dpp_pkex_build_exchange_resp"), (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_resp"), (1, "dpp_alloc_msg;dpp_auth_build_resp"), - (1, "dpp_get_pubkey_point;dpp_auth_build_resp_ok"), + (1, "crypto_ec_key_get_pubkey_point;dpp_auth_build_resp_ok"), (1, "dpp_alloc_auth"), (1, "=dpp_auth_req_rx"), (1, "=dpp_auth_conf_rx"), @@ -4206,7 +4206,7 @@ def test_dpp_pkex_alloc_fail(dev, apdev): (1, "json_parse;dpp_parse_connector"), (1, "dpp_parse_jwk;dpp_parse_connector"), (1, "dpp_parse_jwk;dpp_parse_cred_dpp"), - (1, "dpp_get_pubkey_point;dpp_check_pubkey_match"), + (1, "crypto_ec_key_get_pubkey_point;dpp_check_pubkey_match"), (1, "base64_gen_decode;dpp_process_signed_connector"), (1, "dpp_parse_jws_prot_hdr;dpp_process_signed_connector"), (2, "base64_gen_decode;dpp_process_signed_connector"), @@ -4219,7 +4219,7 @@ def test_dpp_pkex_alloc_fail(dev, apdev): (2, "=dpp_pkex_rx_exchange_req"), (3, "=dpp_pkex_rx_exchange_req"), (1, "=dpp_pkex_rx_commit_reveal_req"), - (1, "dpp_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"), + (1, "crypto_ec_key_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"), (1, "dpp_bootstrap_key_hash")] for count, func in tests: dev[0].request("DPP_STOP_LISTEN") @@ -4650,7 +4650,7 @@ def test_dpp_invalid_configurator_key(dev, apdev): if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256): raise Exception("Error not reported") - with alloc_fail(dev[0], 1, "dpp_get_pubkey_point;dpp_keygen_configurator"): + with alloc_fail(dev[0], 1, "crypto_ec_key_get_pubkey_point;dpp_keygen_configurator"): if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256): raise Exception("Error not reported") -- 2.17.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap