DPP: Use crypto API for reconfig part
Rewrite functions related to reconfig feature using EC point/bignum primitives defined in crypto.h API. Signed-off-by: Cedric Izoard <cedric.izoard@ceva-dsp.com>
This commit is contained in:
parent
eac41656ee
commit
f5334f9b5b
5 changed files with 187 additions and 215 deletions
|
@ -8,7 +8,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
#include <openssl/opensslv.h>
|
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/asn1.h>
|
#include <openssl/asn1.h>
|
||||||
#include <openssl/asn1t.h>
|
#include <openssl/asn1t.h>
|
||||||
|
@ -26,20 +25,6 @@
|
||||||
#include "dpp_i.h"
|
#include "dpp_i.h"
|
||||||
|
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
|
|
||||||
(defined(LIBRESSL_VERSION_NUMBER) && \
|
|
||||||
LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
|
||||||
/* Compatibility wrappers for older versions. */
|
|
||||||
|
|
||||||
static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
|
|
||||||
{
|
|
||||||
if (pkey->type != EVP_PKEY_EC)
|
|
||||||
return NULL;
|
|
||||||
return pkey->pkey.ec;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct dpp_curve_params dpp_curves[] = {
|
static const struct dpp_curve_params dpp_curves[] = {
|
||||||
/* The mandatory to support and the default NIST P-256 curve needs to
|
/* The mandatory to support and the default NIST P-256 curve needs to
|
||||||
* be the first entry on this list. */
|
* be the first entry on this list. */
|
||||||
|
@ -1874,15 +1859,12 @@ int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||||
size_t net_access_key_len,
|
size_t net_access_key_len,
|
||||||
struct json_token *peer_net_access_key)
|
struct json_token *peer_net_access_key)
|
||||||
{
|
{
|
||||||
BN_CTX *bnctx = NULL;
|
|
||||||
struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
|
struct crypto_ec_key *own_key = NULL, *peer_key = NULL;
|
||||||
BIGNUM *sum = NULL, *q = NULL, *mx = NULL;
|
struct crypto_bignum *sum = NULL;
|
||||||
EC_POINT *m = NULL;
|
const struct crypto_bignum *q, *cR, *pR;
|
||||||
const EC_KEY *cR, *pR;
|
struct crypto_ec *ec = NULL;
|
||||||
const EC_GROUP *group;
|
struct crypto_ec_point *M = NULL;
|
||||||
const BIGNUM *cR_bn, *pR_bn;
|
const struct crypto_ec_point *CI;
|
||||||
const EC_POINT *CI_point;
|
|
||||||
const EC_KEY *CI;
|
|
||||||
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
||||||
u8 prk[DPP_MAX_HASH_LEN];
|
u8 prk[DPP_MAX_HASH_LEN];
|
||||||
const struct dpp_curve_params *curve;
|
const struct dpp_curve_params *curve;
|
||||||
|
@ -1920,37 +1902,23 @@ int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||||
auth->e_nonce, auth->curve->nonce_len);
|
auth->e_nonce, auth->curve->nonce_len);
|
||||||
|
|
||||||
/* M = { cR + pR } * CI */
|
/* M = { cR + pR } * CI */
|
||||||
cR = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) own_key);
|
ec = crypto_ec_init(curve->ike_group);
|
||||||
pR = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) auth->own_protocol_key);
|
if (!ec)
|
||||||
if (!pR)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
group = EC_KEY_get0_group(pR);
|
|
||||||
bnctx = BN_CTX_new();
|
sum = crypto_bignum_init();
|
||||||
sum = BN_new();
|
q = crypto_ec_get_order(ec);
|
||||||
mx = BN_new();
|
M = crypto_ec_point_init(ec);
|
||||||
q = BN_new();
|
cR = crypto_ec_key_get_private_key(own_key);
|
||||||
m = EC_POINT_new(group);
|
pR = crypto_ec_key_get_private_key(auth->own_protocol_key);
|
||||||
if (!cR || !bnctx || !sum || !mx || !q || !m)
|
CI = crypto_ec_key_get_public_key(peer_key);
|
||||||
goto fail;
|
if (!sum || !q || !M || !cR || !pR || !CI ||
|
||||||
cR_bn = EC_KEY_get0_private_key(cR);
|
crypto_bignum_addmod(cR, pR, q, sum) ||
|
||||||
pR_bn = EC_KEY_get0_private_key(pR);
|
crypto_ec_point_mul(ec, CI, sum, M) ||
|
||||||
if (!cR_bn || !pR_bn)
|
crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
|
||||||
goto fail;
|
wpa_printf(MSG_ERROR, "DPP: Error during M computation");
|
||||||
CI = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) peer_key);
|
|
||||||
CI_point = EC_KEY_get0_public_key(CI);
|
|
||||||
if (EC_GROUP_get_order(group, q, bnctx) != 1 ||
|
|
||||||
BN_mod_add(sum, cR_bn, pR_bn, q, bnctx) != 1 ||
|
|
||||||
EC_POINT_mul(group, m, NULL, CI_point, sum, bnctx) != 1 ||
|
|
||||||
EC_POINT_get_affine_coordinates_GFp(group, m, mx, NULL,
|
|
||||||
bnctx) != 1) {
|
|
||||||
wpa_printf(MSG_ERROR,
|
|
||||||
"OpenSSL: failed: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpp_bn2bin_pad(mx, Mx, curve->prime_len) < 0)
|
|
||||||
goto fail;
|
|
||||||
wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
|
wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
|
||||||
|
|
||||||
/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
|
/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
|
||||||
|
@ -1978,13 +1946,11 @@ int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||||
fail:
|
fail:
|
||||||
forced_memzero(prk, sizeof(prk));
|
forced_memzero(prk, sizeof(prk));
|
||||||
forced_memzero(Mx, sizeof(Mx));
|
forced_memzero(Mx, sizeof(Mx));
|
||||||
EC_POINT_clear_free(m);
|
crypto_ec_point_deinit(M, 1);
|
||||||
BN_free(q);
|
crypto_bignum_deinit(sum, 1);
|
||||||
BN_clear_free(mx);
|
|
||||||
BN_clear_free(sum);
|
|
||||||
crypto_ec_key_deinit(own_key);
|
crypto_ec_key_deinit(own_key);
|
||||||
crypto_ec_key_deinit(peer_key);
|
crypto_ec_key_deinit(peer_key);
|
||||||
BN_CTX_free(bnctx);
|
crypto_ec_deinit(ec);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1993,14 +1959,11 @@ int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
|
||||||
const u8 *r_proto, u16 r_proto_len,
|
const u8 *r_proto, u16 r_proto_len,
|
||||||
struct json_token *net_access_key)
|
struct json_token *net_access_key)
|
||||||
{
|
{
|
||||||
BN_CTX *bnctx = NULL;
|
|
||||||
struct crypto_ec_key *pr = NULL, *peer_key = NULL;
|
struct crypto_ec_key *pr = NULL, *peer_key = NULL;
|
||||||
EC_POINT *sum = NULL, *m = NULL;
|
const struct crypto_ec_point *CR, *PR;
|
||||||
BIGNUM *mx = NULL;
|
const struct crypto_bignum *cI;
|
||||||
const EC_KEY *cI, *CR, *PR;
|
struct crypto_ec *ec = NULL;
|
||||||
const EC_GROUP *group;
|
struct crypto_ec_point *sum = NULL, *M = NULL;
|
||||||
const EC_POINT *CR_point, *PR_point;
|
|
||||||
const BIGNUM *cI_bn;
|
|
||||||
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
||||||
u8 prk[DPP_MAX_HASH_LEN];
|
u8 prk[DPP_MAX_HASH_LEN];
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
@ -2030,25 +1993,23 @@ int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* M = cI * { CR + PR } */
|
/* M = cI * { CR + PR } */
|
||||||
cI = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) auth->conf->connector_key);
|
ec = crypto_ec_init(curve->ike_group);
|
||||||
cI_bn = EC_KEY_get0_private_key(cI);
|
if (!ec)
|
||||||
group = EC_KEY_get0_group(cI);
|
|
||||||
bnctx = BN_CTX_new();
|
|
||||||
sum = EC_POINT_new(group);
|
|
||||||
m = EC_POINT_new(group);
|
|
||||||
mx = BN_new();
|
|
||||||
CR = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) peer_key);
|
|
||||||
PR = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) auth->peer_protocol_key);
|
|
||||||
CR_point = EC_KEY_get0_public_key(CR);
|
|
||||||
PR_point = EC_KEY_get0_public_key(PR);
|
|
||||||
if (!bnctx || !sum || !m || !mx ||
|
|
||||||
EC_POINT_add(group, sum, CR_point, PR_point, bnctx) != 1 ||
|
|
||||||
EC_POINT_mul(group, m, NULL, sum, cI_bn, bnctx) != 1 ||
|
|
||||||
EC_POINT_get_affine_coordinates_GFp(group, m, mx, NULL,
|
|
||||||
bnctx) != 1 ||
|
|
||||||
dpp_bn2bin_pad(mx, Mx, curve->prime_len) < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
cI = crypto_ec_key_get_private_key(auth->conf->connector_key);
|
||||||
|
sum = crypto_ec_point_init(ec);
|
||||||
|
M = crypto_ec_point_init(ec);
|
||||||
|
CR = crypto_ec_key_get_public_key(peer_key);
|
||||||
|
PR = crypto_ec_key_get_public_key(auth->peer_protocol_key);
|
||||||
|
if (!cI || !sum || !M || !CR || !PR ||
|
||||||
|
crypto_ec_point_add(ec, CR, PR, sum) ||
|
||||||
|
crypto_ec_point_mul(ec, sum, cI, M) ||
|
||||||
|
crypto_ec_point_to_bin(ec, M, Mx, NULL)) {
|
||||||
|
wpa_printf(MSG_ERROR, "DPP: Error during M computation");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
|
wpa_hexdump_key(MSG_DEBUG, "DPP: M.x", Mx, curve->prime_len);
|
||||||
|
|
||||||
/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
|
/* ke = HKDF(C-nonce | E-nonce, "dpp reconfig key", M.x) */
|
||||||
|
@ -2075,10 +2036,9 @@ fail:
|
||||||
forced_memzero(Mx, sizeof(Mx));
|
forced_memzero(Mx, sizeof(Mx));
|
||||||
crypto_ec_key_deinit(pr);
|
crypto_ec_key_deinit(pr);
|
||||||
crypto_ec_key_deinit(peer_key);
|
crypto_ec_key_deinit(peer_key);
|
||||||
EC_POINT_clear_free(sum);
|
crypto_ec_point_deinit(sum, 1);
|
||||||
EC_POINT_clear_free(m);
|
crypto_ec_point_deinit(M, 1);
|
||||||
BN_clear_free(mx);
|
crypto_ec_deinit(ec);
|
||||||
BN_CTX_free(bnctx);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2599,50 +2559,46 @@ struct dpp_reconfig_id * dpp_gen_reconfig_id(const u8 *csign_key,
|
||||||
const u8 *pp_key,
|
const u8 *pp_key,
|
||||||
size_t pp_key_len)
|
size_t pp_key_len)
|
||||||
{
|
{
|
||||||
const unsigned char *p;
|
|
||||||
struct crypto_ec_key *csign = NULL, *ppkey = NULL;
|
struct crypto_ec_key *csign = NULL, *ppkey = NULL;
|
||||||
struct dpp_reconfig_id *id = NULL;
|
struct dpp_reconfig_id *id = NULL;
|
||||||
BN_CTX *ctx = NULL;
|
struct crypto_ec *ec = NULL;
|
||||||
BIGNUM *bn = NULL, *q = NULL;
|
const struct crypto_bignum *q;
|
||||||
const EC_KEY *eckey;
|
struct crypto_bignum *bn = NULL;
|
||||||
const EC_GROUP *group;
|
struct crypto_ec_point *e_id = NULL;
|
||||||
EC_POINT *e_id = NULL;
|
const struct crypto_ec_point *generator;
|
||||||
|
|
||||||
p = csign_key;
|
csign = crypto_ec_key_parse_pub(csign_key, csign_key_len);
|
||||||
csign = (struct crypto_ec_key *) d2i_PUBKEY(NULL, &p, csign_key_len);
|
|
||||||
if (!csign)
|
if (!csign)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!pp_key)
|
if (!pp_key)
|
||||||
goto fail;
|
goto fail;
|
||||||
p = pp_key;
|
ppkey = crypto_ec_key_parse_pub(pp_key, pp_key_len);
|
||||||
ppkey = (struct crypto_ec_key *) d2i_PUBKEY(NULL, &p, pp_key_len);
|
|
||||||
if (!ppkey)
|
if (!ppkey)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) csign);
|
ec = crypto_ec_init(crypto_ec_key_group(csign));
|
||||||
if (!eckey)
|
if (!ec)
|
||||||
goto fail;
|
|
||||||
group = EC_KEY_get0_group(eckey);
|
|
||||||
if (!group)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
e_id = EC_POINT_new(group);
|
e_id = crypto_ec_point_init(ec);
|
||||||
ctx = BN_CTX_new();
|
bn = crypto_bignum_init();
|
||||||
bn = BN_new();
|
q = crypto_ec_get_order(ec);
|
||||||
q = BN_new();
|
generator = crypto_ec_get_generator(ec);
|
||||||
if (!e_id || !ctx || !bn || !q ||
|
if (!e_id || !bn || !q || !generator ||
|
||||||
!EC_GROUP_get_order(group, q, ctx) ||
|
crypto_bignum_rand(bn, q) ||
|
||||||
!BN_rand_range(bn, q) ||
|
crypto_ec_point_mul(ec, generator, bn, e_id))
|
||||||
!EC_POINT_mul(group, e_id, bn, NULL, NULL, ctx))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
dpp_debug_print_point("DPP: Generated random point E-id", group, e_id);
|
crypto_ec_point_debug_print(ec, e_id,
|
||||||
|
"DPP: Generated random point E-id");
|
||||||
|
|
||||||
id = os_zalloc(sizeof(*id));
|
id = os_zalloc(sizeof(*id));
|
||||||
if (!id)
|
if (!id)
|
||||||
goto fail;
|
goto fail;
|
||||||
id->group = group;
|
|
||||||
|
id->ec = ec;
|
||||||
|
ec = NULL;
|
||||||
id->e_id = e_id;
|
id->e_id = e_id;
|
||||||
e_id = NULL;
|
e_id = NULL;
|
||||||
id->csign = csign;
|
id->csign = csign;
|
||||||
|
@ -2650,93 +2606,58 @@ struct dpp_reconfig_id * dpp_gen_reconfig_id(const u8 *csign_key,
|
||||||
id->pp_key = ppkey;
|
id->pp_key = ppkey;
|
||||||
ppkey = NULL;
|
ppkey = NULL;
|
||||||
fail:
|
fail:
|
||||||
EC_POINT_free(e_id);
|
crypto_ec_point_deinit(e_id, 1);
|
||||||
crypto_ec_key_deinit(csign);
|
crypto_ec_key_deinit(csign);
|
||||||
crypto_ec_key_deinit(ppkey);
|
crypto_ec_key_deinit(ppkey);
|
||||||
BN_clear_free(bn);
|
crypto_bignum_deinit(bn, 1);
|
||||||
BN_CTX_free(ctx);
|
crypto_ec_deinit(ec);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct crypto_ec_key * dpp_pkey_from_point(const EC_GROUP *group,
|
|
||||||
const EC_POINT *point)
|
|
||||||
{
|
|
||||||
EC_KEY *eckey;
|
|
||||||
EVP_PKEY *pkey = NULL;
|
|
||||||
|
|
||||||
eckey = EC_KEY_new();
|
|
||||||
if (!eckey ||
|
|
||||||
EC_KEY_set_group(eckey, group) != 1 ||
|
|
||||||
EC_KEY_set_public_key(eckey, point) != 1) {
|
|
||||||
wpa_printf(MSG_ERROR,
|
|
||||||
"DPP: Failed to set EC_KEY: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
|
|
||||||
|
|
||||||
pkey = EVP_PKEY_new();
|
|
||||||
if (!pkey || EVP_PKEY_set1_EC_KEY(pkey, eckey) != 1) {
|
|
||||||
wpa_printf(MSG_ERROR, "DPP: Could not create EVP_PKEY");
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
pkey = NULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
EC_KEY_free(eckey);
|
|
||||||
return (struct crypto_ec_key *) pkey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int dpp_update_reconfig_id(struct dpp_reconfig_id *id)
|
int dpp_update_reconfig_id(struct dpp_reconfig_id *id)
|
||||||
{
|
{
|
||||||
BN_CTX *ctx = NULL;
|
const struct crypto_bignum *q;
|
||||||
BIGNUM *bn = NULL, *q = NULL;
|
struct crypto_bignum *bn;
|
||||||
EC_POINT *e_prime_id = NULL, *a_nonce = NULL;
|
const struct crypto_ec_point *pp, *generator;
|
||||||
|
struct crypto_ec_point *e_prime_id, *a_nonce;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
const EC_KEY *pp;
|
|
||||||
const EC_POINT *pp_point;
|
|
||||||
|
|
||||||
pp = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) id->pp_key);
|
pp = crypto_ec_key_get_public_key(id->pp_key);
|
||||||
if (!pp)
|
e_prime_id = crypto_ec_point_init(id->ec);
|
||||||
goto fail;
|
a_nonce = crypto_ec_point_init(id->ec);
|
||||||
pp_point = EC_KEY_get0_public_key(pp);
|
bn = crypto_bignum_init();
|
||||||
e_prime_id = EC_POINT_new(id->group);
|
q = crypto_ec_get_order(id->ec);
|
||||||
a_nonce = EC_POINT_new(id->group);
|
generator = crypto_ec_get_generator(id->ec);
|
||||||
ctx = BN_CTX_new();
|
|
||||||
bn = BN_new();
|
|
||||||
q = BN_new();
|
|
||||||
/* Generate random 0 <= a-nonce < q
|
/* Generate random 0 <= a-nonce < q
|
||||||
* A-NONCE = a-nonce * G
|
* A-NONCE = a-nonce * G
|
||||||
* E'-id = E-id + a-nonce * P_pk */
|
* E'-id = E-id + a-nonce * P_pk */
|
||||||
if (!pp_point || !e_prime_id || !a_nonce || !ctx || !bn || !q ||
|
if (!pp || !e_prime_id || !a_nonce || !bn || !q || !generator ||
|
||||||
!EC_GROUP_get_order(id->group, q, ctx) ||
|
crypto_bignum_rand(bn, q) || /* bn = a-nonce */
|
||||||
!BN_rand_range(bn, q) || /* bn = a-nonce */
|
crypto_ec_point_mul(id->ec, generator, bn, a_nonce) ||
|
||||||
!EC_POINT_mul(id->group, a_nonce, bn, NULL, NULL, ctx) ||
|
crypto_ec_point_mul(id->ec, pp, bn, e_prime_id) ||
|
||||||
!EC_POINT_mul(id->group, e_prime_id, NULL, pp_point, bn, ctx) ||
|
crypto_ec_point_add(id->ec, id->e_id, e_prime_id, e_prime_id))
|
||||||
!EC_POINT_add(id->group, e_prime_id, id->e_id, e_prime_id, ctx))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
dpp_debug_print_point("DPP: Generated A-NONCE", id->group, a_nonce);
|
crypto_ec_point_debug_print(id->ec, a_nonce,
|
||||||
dpp_debug_print_point("DPP: Encrypted E-id to E'-id",
|
"DPP: Generated A-NONCE");
|
||||||
id->group, e_prime_id);
|
crypto_ec_point_debug_print(id->ec, e_prime_id,
|
||||||
|
"DPP: Encrypted E-id to E'-id");
|
||||||
|
|
||||||
crypto_ec_key_deinit(id->a_nonce);
|
crypto_ec_key_deinit(id->a_nonce);
|
||||||
crypto_ec_key_deinit(id->e_prime_id);
|
crypto_ec_key_deinit(id->e_prime_id);
|
||||||
id->a_nonce = dpp_pkey_from_point(id->group, a_nonce);
|
id->a_nonce = crypto_ec_key_set_pub_point(id->ec, a_nonce);
|
||||||
id->e_prime_id = dpp_pkey_from_point(id->group, e_prime_id);
|
id->e_prime_id = crypto_ec_key_set_pub_point(id->ec, e_prime_id);
|
||||||
if (!id->a_nonce || !id->e_prime_id)
|
if (!id->a_nonce || !id->e_prime_id)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
EC_POINT_free(e_prime_id);
|
crypto_ec_point_deinit(e_prime_id, 1);
|
||||||
EC_POINT_free(a_nonce);
|
crypto_ec_point_deinit(a_nonce, 1);
|
||||||
BN_clear_free(bn);
|
crypto_bignum_deinit(bn, 1);
|
||||||
BN_CTX_free(ctx);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2744,56 +2665,50 @@ fail:
|
||||||
void dpp_free_reconfig_id(struct dpp_reconfig_id *id)
|
void dpp_free_reconfig_id(struct dpp_reconfig_id *id)
|
||||||
{
|
{
|
||||||
if (id) {
|
if (id) {
|
||||||
EC_POINT_clear_free(id->e_id);
|
crypto_ec_point_deinit(id->e_id, 1);
|
||||||
crypto_ec_key_deinit(id->csign);
|
crypto_ec_key_deinit(id->csign);
|
||||||
crypto_ec_key_deinit(id->a_nonce);
|
crypto_ec_key_deinit(id->a_nonce);
|
||||||
crypto_ec_key_deinit(id->e_prime_id);
|
crypto_ec_key_deinit(id->e_prime_id);
|
||||||
crypto_ec_key_deinit(id->pp_key);
|
crypto_ec_key_deinit(id->pp_key);
|
||||||
|
crypto_ec_deinit(id->ec);
|
||||||
os_free(id);
|
os_free(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EC_POINT * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
|
struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
|
||||||
struct crypto_ec_key *a_nonce,
|
struct crypto_ec_key *a_nonce,
|
||||||
struct crypto_ec_key *e_prime_id)
|
struct crypto_ec_key *e_prime_id)
|
||||||
{
|
{
|
||||||
const EC_KEY *pp_ec, *a_nonce_ec, *e_prime_id_ec;
|
struct crypto_ec *ec;
|
||||||
const BIGNUM *pp_bn;
|
const struct crypto_bignum *pp;
|
||||||
const EC_GROUP *group;
|
struct crypto_ec_point *e_id = NULL;
|
||||||
EC_POINT *e_id = NULL;
|
const struct crypto_ec_point *a_nonce_point, *e_prime_id_point;
|
||||||
const EC_POINT *a_nonce_point, *e_prime_id_point;
|
|
||||||
BN_CTX *ctx = NULL;
|
|
||||||
|
|
||||||
if (!ppkey)
|
if (!ppkey)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* E-id = E'-id - s_C * A-NONCE */
|
/* E-id = E'-id - s_C * A-NONCE */
|
||||||
pp_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) ppkey);
|
ec = crypto_ec_init(crypto_ec_key_group(ppkey));
|
||||||
a_nonce_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) a_nonce);
|
if (!ec)
|
||||||
e_prime_id_ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *) e_prime_id);
|
|
||||||
if (!pp_ec || !a_nonce_ec || !e_prime_id_ec)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
pp_bn = EC_KEY_get0_private_key(pp_ec);
|
|
||||||
group = EC_KEY_get0_group(pp_ec);
|
pp = crypto_ec_key_get_private_key(ppkey);
|
||||||
a_nonce_point = EC_KEY_get0_public_key(a_nonce_ec);
|
a_nonce_point = crypto_ec_key_get_public_key(a_nonce);
|
||||||
e_prime_id_point = EC_KEY_get0_public_key(e_prime_id_ec);
|
e_prime_id_point = crypto_ec_key_get_public_key(e_prime_id);
|
||||||
ctx = BN_CTX_new();
|
e_id = crypto_ec_point_init(ec);
|
||||||
if (!pp_bn || !group || !a_nonce_point || !e_prime_id_point || !ctx)
|
if (!pp || !a_nonce_point || !e_prime_id_point || !e_id ||
|
||||||
goto fail;
|
crypto_ec_point_mul(ec, a_nonce_point, pp, e_id) ||
|
||||||
e_id = EC_POINT_new(group);
|
crypto_ec_point_invert(ec, e_id) ||
|
||||||
if (!e_id ||
|
crypto_ec_point_add(ec, e_id, e_prime_id_point, e_id)) {
|
||||||
!EC_POINT_mul(group, e_id, NULL, a_nonce_point, pp_bn, ctx) ||
|
crypto_ec_point_deinit(e_id, 1);
|
||||||
!EC_POINT_invert(group, e_id, ctx) ||
|
|
||||||
!EC_POINT_add(group, e_id, e_prime_id_point, e_id, ctx)) {
|
|
||||||
EC_POINT_clear_free(e_id);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
dpp_debug_print_point("DPP: Decrypted E-id", group, e_id);
|
crypto_ec_point_debug_print(ec, e_id, "DPP: Decrypted E-id");
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
BN_CTX_free(ctx);
|
crypto_ec_deinit(ec);
|
||||||
return e_id;
|
return e_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,17 +134,17 @@ int dpp_reconfig_derive_ke_responder(struct dpp_authentication *auth,
|
||||||
int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
|
int dpp_reconfig_derive_ke_initiator(struct dpp_authentication *auth,
|
||||||
const u8 *r_proto, u16 r_proto_len,
|
const u8 *r_proto, u16 r_proto_len,
|
||||||
struct json_token *net_access_key);
|
struct json_token *net_access_key);
|
||||||
EC_POINT * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
|
struct crypto_ec_point * dpp_decrypt_e_id(struct crypto_ec_key *ppkey,
|
||||||
struct crypto_ec_key *a_nonce,
|
struct crypto_ec_key *a_nonce,
|
||||||
struct crypto_ec_key *e_prime_id);
|
struct crypto_ec_key *e_prime_id);
|
||||||
char * dpp_sign_connector(struct dpp_configurator *conf,
|
char * dpp_sign_connector(struct dpp_configurator *conf,
|
||||||
const struct wpabuf *dppcon);
|
const struct wpabuf *dppcon);
|
||||||
int dpp_test_gen_invalid_key(struct wpabuf *msg,
|
int dpp_test_gen_invalid_key(struct wpabuf *msg,
|
||||||
const struct dpp_curve_params *curve);
|
const struct dpp_curve_params *curve);
|
||||||
|
|
||||||
struct dpp_reconfig_id {
|
struct dpp_reconfig_id {
|
||||||
const EC_GROUP *group;
|
struct crypto_ec *ec;
|
||||||
EC_POINT *e_id; /* E-id */
|
struct crypto_ec_point *e_id; /* E-id */
|
||||||
struct crypto_ec_key *csign;
|
struct crypto_ec_key *csign;
|
||||||
struct crypto_ec_key *a_nonce; /* A-NONCE */
|
struct crypto_ec_key *a_nonce; /* A-NONCE */
|
||||||
struct crypto_ec_key *e_prime_id; /* E'-id */
|
struct crypto_ec_key *e_prime_id; /* E'-id */
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
#include <openssl/opensslv.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
|
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
#include "utils/json.h"
|
#include "utils/json.h"
|
||||||
|
@ -229,7 +227,7 @@ dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||||
struct dpp_authentication *auth;
|
struct dpp_authentication *auth;
|
||||||
const struct dpp_curve_params *curve;
|
const struct dpp_curve_params *curve;
|
||||||
struct crypto_ec_key *a_nonce, *e_prime_id;
|
struct crypto_ec_key *a_nonce, *e_prime_id;
|
||||||
EC_POINT *e_id;
|
struct crypto_ec_point *e_id;
|
||||||
|
|
||||||
curve = dpp_get_curve_ike_group(group);
|
curve = dpp_get_curve_ike_group(group);
|
||||||
if (!curve) {
|
if (!curve) {
|
||||||
|
@ -273,7 +271,7 @@ dpp_reconfig_init(struct dpp_global *dpp, void *msg_ctx,
|
||||||
* Enrollee has already been started and is waiting for updated
|
* Enrollee has already been started and is waiting for updated
|
||||||
* configuration instead of replying again before such configuration
|
* configuration instead of replying again before such configuration
|
||||||
* becomes available */
|
* becomes available */
|
||||||
EC_POINT_clear_free(e_id);
|
crypto_ec_point_deinit(e_id, 1);
|
||||||
|
|
||||||
auth = dpp_alloc_auth(dpp, msg_ctx);
|
auth = dpp_alloc_auth(dpp, msg_ctx);
|
||||||
if (!auth)
|
if (!auth)
|
||||||
|
|
|
@ -713,6 +713,14 @@ int crypto_bignum_legendre(const struct crypto_bignum *a,
|
||||||
*/
|
*/
|
||||||
struct crypto_ec;
|
struct crypto_ec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct crypto_ec_point - Elliptic curve point
|
||||||
|
*
|
||||||
|
* Internal data structure for EC implementation to represent a point. The
|
||||||
|
* contents is specific to the used crypto library.
|
||||||
|
*/
|
||||||
|
struct crypto_ec_point;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_init - Initialize elliptic curve context
|
* crypto_ec_init - Initialize elliptic curve context
|
||||||
* @group: Identifying number for the ECC group (IANA "Group Description"
|
* @group: Identifying number for the ECC group (IANA "Group Description"
|
||||||
|
@ -777,12 +785,11 @@ const struct crypto_bignum * crypto_ec_get_a(struct crypto_ec *e);
|
||||||
const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
|
const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct crypto_ec_point - Elliptic curve point
|
* crypto_ec_get_generator - Get generator point of the EC group's curve
|
||||||
*
|
* @e: EC context from crypto_ec_init()
|
||||||
* Internal data structure for EC implementation to represent a point. The
|
* Returns: Pointer to generator point
|
||||||
* contents is specific to the used crypto library.
|
|
||||||
*/
|
*/
|
||||||
struct crypto_ec_point;
|
const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_point_init - Initialize data for an EC point
|
* crypto_ec_point_init - Initialize data for an EC point
|
||||||
|
@ -1018,6 +1025,16 @@ struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len);
|
||||||
struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
|
struct crypto_ec_key * crypto_ec_key_set_pub(int group, const u8 *x,
|
||||||
const u8 *y, size_t len);
|
const u8 *y, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crypto_ec_key_set_pub_point - Initialize an EC public key from EC point
|
||||||
|
* @e: EC context from crypto_ec_init()
|
||||||
|
* @pub: Public key point
|
||||||
|
* Returns: EC key or %NULL on failure
|
||||||
|
*/
|
||||||
|
struct crypto_ec_key *
|
||||||
|
crypto_ec_key_set_pub_point(struct crypto_ec *e,
|
||||||
|
const struct crypto_ec_point *pub);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_ec_key_gen - Generate EC key pair
|
* crypto_ec_key_gen - Generate EC key pair
|
||||||
* @group: Identifying number for the ECC group
|
* @group: Identifying number for the ECC group
|
||||||
|
|
|
@ -1795,6 +1795,13 @@ const struct crypto_bignum * crypto_ec_get_b(struct crypto_ec *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const struct crypto_ec_point * crypto_ec_get_generator(struct crypto_ec *e)
|
||||||
|
{
|
||||||
|
return (const struct crypto_ec_point *)
|
||||||
|
EC_GROUP_get0_generator(e->group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
|
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
|
||||||
{
|
{
|
||||||
if (clear)
|
if (clear)
|
||||||
|
@ -2371,6 +2378,41 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct crypto_ec_key *
|
||||||
|
crypto_ec_key_set_pub_point(struct crypto_ec *ec,
|
||||||
|
const struct crypto_ec_point *pub)
|
||||||
|
{
|
||||||
|
EC_KEY *eckey;
|
||||||
|
EVP_PKEY *pkey = NULL;
|
||||||
|
|
||||||
|
eckey = EC_KEY_new();
|
||||||
|
if (!eckey ||
|
||||||
|
EC_KEY_set_group(eckey, ec->group) != 1 ||
|
||||||
|
EC_KEY_set_public_key(eckey, (const EC_POINT *) pub) != 1) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"OpenSSL: Failed to set EC_KEY: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
|
||||||
|
|
||||||
|
pkey = EVP_PKEY_new();
|
||||||
|
if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, eckey) != 1) {
|
||||||
|
wpa_printf(MSG_ERROR, "OpenSSL: Could not create EVP_PKEY");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return (struct crypto_ec_key *) pkey;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
EC_KEY_free(eckey);
|
||||||
|
pkey = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct crypto_ec_key * crypto_ec_key_gen(int group)
|
struct crypto_ec_key * crypto_ec_key_gen(int group)
|
||||||
{
|
{
|
||||||
EVP_PKEY_CTX *kctx = NULL;
|
EVP_PKEY_CTX *kctx = NULL;
|
||||||
|
|
Loading…
Reference in a new issue