diff --git a/src/ecdh.c b/src/ecdh.c index 062bdfa9..3b2a4583 100644 --- a/src/ecdh.c +++ b/src/ecdh.c @@ -85,9 +85,6 @@ bool ecdh_generate_key_pair(void *private, size_t priv_len, return false; } - ecc_native2be(pub.x); - ecc_native2be(pub.y); - memcpy(public, &pub, pub_len); return true; @@ -132,6 +129,7 @@ bool ecdh_generate_shared_secret(const void *private, const void *other_public, if (secret_len > 32) return false; + /* * TODO: Once other ECC groups are added this will need to be modified * to check for 1/2 the full public key lengths @@ -142,7 +140,6 @@ bool ecdh_generate_shared_secret(const void *private, const void *other_public, * be decoded. */ memcpy(x, other_public, 32); - ecc_be2native(x); if (!decode_point(x, &public)) { l_error("could not decode compressed public key"); @@ -150,9 +147,6 @@ bool ecdh_generate_shared_secret(const void *private, const void *other_public, } } else if (pub_len == 64) { memcpy(&public, other_public, 64); - - ecc_be2native(public.x); - ecc_be2native(public.y); } else { l_error("unsupported public key length %ld", pub_len); return false; @@ -164,8 +158,6 @@ bool ecdh_generate_shared_secret(const void *private, const void *other_public, ecc_point_mult(&product, &public, (uint64_t *)private, z, vli_num_bits(private)); - ecc_native2be(product.x); - memcpy(secret, product.x, secret_len); return true; diff --git a/src/ecdh.h b/src/ecdh.h index 502fbab8..e0837251 100644 --- a/src/ecdh.h +++ b/src/ecdh.h @@ -20,8 +20,15 @@ * */ +/* + * Generate a private/public key pair. All inputs are expected in little-endian. + */ bool ecdh_generate_key_pair(void *private, size_t priv_len, void *public, size_t pub_len); +/* + * Generate a shared secret from a private/public key. All inputs are expected + * in little-endian. + */ bool ecdh_generate_shared_secret(const void *private, const void *other_public, size_t pub_len, void *secret, size_t secret_len); diff --git a/src/owe.c b/src/owe.c index e702d478..3ff8ee3e 100644 --- a/src/owe.c +++ b/src/owe.c @@ -60,6 +60,13 @@ struct owe_sm *owe_sm_new(struct handshake_state *hs, return NULL; } + /* + * Store our own public key in BE ordering since all future uses + * will need it. + */ + ecc_native2be(owe->public_key); + ecc_native2be(owe->public_key + 4); + return owe; } @@ -113,16 +120,20 @@ void owe_rx_authenticate(struct owe_sm *owe) static bool owe_compute_keys(struct owe_sm *owe, const void *public_key, size_t pub_len) { - uint8_t shared_secret[32]; + uint64_t shared_secret[4]; uint8_t prk[32]; uint8_t pmk[32]; uint8_t pmkid[16]; uint8_t key[32 + 32 + 2]; + uint64_t public_native[4]; struct iovec iov[2]; struct l_checksum *sha; + memcpy(public_native, public_key, 32); + ecc_be2native(public_native); + /* z = F(DH(x, Y)) */ - if (!ecdh_generate_shared_secret(owe->private, public_key, pub_len, + if (!ecdh_generate_shared_secret(owe->private, public_native, pub_len, shared_secret, 32)) return false; @@ -130,6 +141,8 @@ static bool owe_compute_keys(struct owe_sm *owe, const void *public_key, memcpy(key + 32, public_key, 32); l_put_le16(19, key + 64); + ecc_native2be(shared_secret); + /* prk = HKDF-extract(C | A | group, z) */ if (!hkdf_extract_sha256(key, 66, 1, prk, shared_secret, 32)) goto failed;