summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-01-09 11:55:07 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-01-09 11:55:07 +0100
commitf11b14362b05f5965b0d1e6b9af1c48945884b9e (patch)
tree5ed6c4a921bf47c4259cc8fa7a82a0475f30b116
parent020c28af111d7d0fc325fc9a55bd185368e049cd (diff)
downloadfastd-f11b14362b05f5965b0d1e6b9af1c48945884b9e.tar
fastd-f11b14362b05f5965b0d1e6b9af1c48945884b9e.zip
ec25519-fhmqvc: unpack peers' keys only once
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c26
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h7
-rw-r--r--src/protocols/ec25519_fhmqvc/handshake.c79
-rw-r--r--src/protocols/ec25519_fhmqvc/util.c2
4 files changed, 58 insertions, 56 deletions
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);