From f11b14362b05f5965b0d1e6b9af1c48945884b9e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 9 Jan 2015 11:55:07 +0100 Subject: ec25519-fhmqvc: unpack peers' keys only once --- src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c | 26 +++++++-- src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h | 7 ++- src/protocols/ec25519_fhmqvc/handshake.c | 79 +++++++++++---------------- src/protocols/ec25519_fhmqvc/util.c | 2 +- 4 files changed, 58 insertions(+), 56 deletions(-) (limited to 'src/protocols') diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c index c60ce67..17f8268 100644 --- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c +++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c @@ -78,14 +78,32 @@ static fastd_protocol_config_t * protocol_init(void) { static fastd_protocol_key_t * protocol_read_key(const char *key) { fastd_protocol_key_t *ret = fastd_new(fastd_protocol_key_t); - if (!read_key(ret->key.u8, key) || !fastd_protocol_ec25519_fhmqvc_check_key(&ret->key.int256)) { - free(ret); - return NULL; + if (read_key(ret->key.u8, key)) { + if (ecc_25519_load_packed(&ret->unpacked, &ret->key.int256)) { + if (fastd_protocol_ec25519_fhmqvc_check_key(&ret->unpacked)) + return ret; + } } - return ret; + free(ret); + return NULL; +} + +/** Checks if an ecc25519 work structure represents a valid curve point */ +bool fastd_protocol_ec25519_fhmqvc_check_key(const ecc_25519_work_t *key) { + ecc_25519_work_t work; + + if (ecc_25519_is_identity(key)) + return false; + + ecc_25519_scalarmult(&work, &ecc_25519_gf_order, key); + if (!ecc_25519_is_identity(&work)) + return false; + + return true; } + /** Checks if a peer is configured using our own key */ static bool protocol_check_peer(const fastd_peer_t *peer) { if (memcmp(conf.protocol_config->key.public.u8, peer->key->key.u8, PUBLICKEYBYTES) == 0) { diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h index 087cf35..8dd8456 100644 --- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h +++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h @@ -56,7 +56,7 @@ typedef union aligned_int256 { /** A keypair */ typedef struct keypair { - ecc_int256_t secret; /**< The section key */ + ecc_int256_t secret; /**< The secret key */ aligned_int256_t public; /**< The public key */ } keypair_t; @@ -68,8 +68,10 @@ struct fastd_protocol_config { /** A peer's public key */ struct fastd_protocol_key { aligned_int256_t key; /**< The peer's public key */ + ecc_25519_work_t unpacked; /**< The peer's public key (unpacked) */ }; + /** Session state */ typedef struct protocol_session { /** @@ -119,8 +121,7 @@ fastd_peer_t * fastd_protocol_ec25519_fhmqvc_find_peer(const fastd_protocol_key_ void fastd_protocol_ec25519_fhmqvc_generate_key(void); void fastd_protocol_ec25519_fhmqvc_show_key(void); - -bool fastd_protocol_ec25519_fhmqvc_check_key(const ecc_int256_t *key); +bool fastd_protocol_ec25519_fhmqvc_check_key(const ecc_25519_work_t *key); void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const fastd_peer_t *peer); bool fastd_protocol_ec25519_fhmqvc_describe_peer(const fastd_peer_t *peer, char *buf, size_t len); diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c index 0b547f4..02df2ee 100644 --- a/src/protocols/ec25519_fhmqvc/handshake.c +++ b/src/protocols/ec25519_fhmqvc/handshake.c @@ -204,50 +204,35 @@ static inline bool secure_handshake(const fastd_handshake_t *handshake) { } -/** Checks if an ecc25519 work structure represents a valid curve point */ -static bool check_key(const ecc_25519_work_t *key) { - ecc_25519_work_t work; - - if (ecc_25519_is_identity(key)) - return false; - - ecc_25519_scalarmult(&work, &ecc_25519_gf_order, key); - if (!ecc_25519_is_identity(&work)) - return false; - - return true; -} - -/** Checks if public key is a valid curve point */ -bool fastd_protocol_ec25519_fhmqvc_check_key(const ecc_int256_t *key) { - ecc_25519_work_t work; - - if (!ecc_25519_load_packed(&work, key)) - return false; - - return check_key(&work); -} - - /** Derives the shares handshake key for computing the MACs used in the handshake */ -static bool make_shared_handshake_key(const ecc_int256_t *handshake_key, bool initiator, - const aligned_int256_t *A, const aligned_int256_t *B, - const aligned_int256_t *X, const aligned_int256_t *Y, +static bool make_shared_handshake_key(bool initiator, const keypair_t *handshake_key, + const fastd_protocol_key_t *peer_key, const aligned_int256_t *peer_handshake_key, aligned_int256_t *sigma, fastd_sha256_t *shared_handshake_key, fastd_sha256_t *shared_handshake_key_compat) { static const uint32_t zero_salt[FASTD_HMACSHA256_KEY_WORDS] = {}; + const aligned_int256_t *A, *B, *X, *Y; ecc_25519_work_t work, workXY; - if (!ecc_25519_load_packed(&workXY, initiator ? &Y->int256 : &X->int256)) + if (!ecc_25519_load_packed(&workXY, &peer_handshake_key->int256)) return false; - if (!check_key(&workXY)) + if (!fastd_protocol_ec25519_fhmqvc_check_key(&workXY)) return false; - if (!ecc_25519_load_packed(&work, initiator ? &B->int256 : &A->int256)) - return false; + if (initiator) { + A = &conf.protocol_config->key.public; + B = &peer_key->key; + X = &handshake_key->public; + Y = peer_handshake_key; + } + else { + A = &peer_key->key; + B = &conf.protocol_config->key.public; + X = peer_handshake_key; + Y = &handshake_key->public; + } fastd_sha256_t hashbuf; fastd_sha256_blocks(&hashbuf, Y->u32, X->u32, B->u32, A->u32, NULL); @@ -263,16 +248,16 @@ static bool make_shared_handshake_key(const ecc_int256_t *handshake_key, bool in if (initiator) { ecc_int256_t da; ecc_25519_gf_mult(&da, &d, &conf.protocol_config->key.secret); - ecc_25519_gf_add(&s, &da, handshake_key); + ecc_25519_gf_add(&s, &da, &handshake_key->secret); - ecc_25519_scalarmult(&work, &e, &work); + ecc_25519_scalarmult(&work, &e, &peer_key->unpacked); } else { ecc_int256_t eb; ecc_25519_gf_mult(&eb, &e, &conf.protocol_config->key.secret); - ecc_25519_gf_add(&s, &eb, handshake_key); + ecc_25519_gf_add(&s, &eb, &handshake_key->secret); - ecc_25519_scalarmult(&work, &d, &work); + ecc_25519_scalarmult(&work, &d, &peer_key->unpacked); } ecc_25519_add(&work, &workXY, &work); @@ -301,11 +286,9 @@ static bool update_shared_handshake_key(const fastd_peer_t *peer, const handshak bool compat = !conf.secure_handshakes; - if (!make_shared_handshake_key(&handshake_key->key.secret, false, - &peer->key->key, - &conf.protocol_config->key.public, + if (!make_shared_handshake_key(false, &handshake_key->key, + peer->key, peer_handshake_key, - &handshake_key->key.public, &peer->protocol_state->sigma, &peer->protocol_state->shared_handshake_key, compat ? &peer->protocol_state->shared_handshake_key_compat : NULL)) @@ -367,10 +350,8 @@ static void finish_handshake(fastd_socket_t *sock, const fastd_peer_address_t *l aligned_int256_t sigma; fastd_sha256_t shared_handshake_key, shared_handshake_key_compat; - if (!make_shared_handshake_key(&handshake_key->key.secret, true, - &conf.protocol_config->key.public, - &peer->key->key, - &handshake_key->key.public, + if (!make_shared_handshake_key(true, &handshake_key->key, + peer->key, peer_handshake_key, &sigma, compat ? NULL : &shared_handshake_key, @@ -583,9 +564,11 @@ static fastd_peer_t * add_dynamic(fastd_socket_t *sock, const fastd_peer_address return NULL; } - aligned_int256_t peer_key; - memcpy(&peer_key, key, PUBLICKEYBYTES); - if (!fastd_protocol_ec25519_fhmqvc_check_key(&peer_key.int256)) { + fastd_protocol_key_t peer_key; + memcpy(&peer_key.key, key, PUBLICKEYBYTES); + + if (!ecc_25519_load_packed(&peer_key.unpacked, &peer_key.key.int256) + || !fastd_protocol_ec25519_fhmqvc_check_key(&peer_key.unpacked)) { pr_debug("ignoring handshake from %I (invalid key)", addr); return NULL; } @@ -595,7 +578,7 @@ static fastd_peer_t * add_dynamic(fastd_socket_t *sock, const fastd_peer_address peer->config_state = CONFIG_DYNAMIC; peer->key = fastd_new(fastd_protocol_key_t); - peer->key->key = peer_key; + *peer->key = peer_key; if (!fastd_peer_add(peer)) exit_bug("failed to add dynamic peer"); diff --git a/src/protocols/ec25519_fhmqvc/util.c b/src/protocols/ec25519_fhmqvc/util.c index 712669c..dbe541d 100644 --- a/src/protocols/ec25519_fhmqvc/util.c +++ b/src/protocols/ec25519_fhmqvc/util.c @@ -34,7 +34,7 @@ /** Prints a private or public key on stdout with an optional descriptive text */ -static inline void print_hexdump(const char *desc, unsigned char d[32]) { +static inline void print_hexdump(const char *desc, const unsigned char d[32]) { char buf[65]; hexdump(buf, d); -- cgit v1.2.3