summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-08-31 16:21:24 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-08-31 16:21:24 +0200
commit9225a4550abebd26ff3642d8f5ed4f96b2e4bff7 (patch)
tree5afffac11e8dff1dda0004df3ac5bed56a6bdd87
parent46a82c570cf940479be968864eb9638407d7d84f (diff)
downloadfastd-9225a4550abebd26ff3642d8f5ed4f96b2e4bff7.tar
fastd-9225a4550abebd26ff3642d8f5ed4f96b2e4bff7.zip
Replace memcmp with a constant-time version in some places
-rw-r--r--src/crypto.h22
-rw-r--r--src/methods/composed_gmac/composed_gmac.c2
-rw-r--r--src/methods/composed_umac/composed_umac.c2
-rw-r--r--src/methods/generic_gmac/generic_gmac.c2
-rw-r--r--src/methods/generic_umac/generic_umac.c2
-rw-r--r--src/protocols/ec25519_fhmqvc/handshake.c13
-rw-r--r--src/sha256.c5
7 files changed, 36 insertions, 12 deletions
diff --git a/src/crypto.h b/src/crypto.h
index 07b7d46..561eb27 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -96,6 +96,28 @@ static inline void secure_memzero(void *s, size_t n) {
__asm__ volatile("" : : "m"(s));
}
+static inline bool secure_memequal(const void *s1, const void *s2, size_t n) {
+ uint8_t v = 0;
+ const uint8_t *i1 = s1, *i2 = s2;
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ v |= i1[i] ^ i2[i];
+
+ return (v == 0);
+}
+
+static inline bool block_equal(const fastd_block128_t *a, const fastd_block128_t *b) {
+ uint32_t v = 0;
+
+ v |= a->dw[0] ^ b->dw[0];
+ v |= a->dw[1] ^ b->dw[1];
+ v |= a->dw[2] ^ b->dw[2];
+ v |= a->dw[3] ^ b->dw[3];
+
+ return (v == 0);
+}
+
/** XORs two blocks of data */
static inline void xor(fastd_block128_t *x, const fastd_block128_t *a, const fastd_block128_t *b) {
x->qw[0] = a->qw[0] ^ b->qw[0];
diff --git a/src/methods/composed_gmac/composed_gmac.c b/src/methods/composed_gmac/composed_gmac.c
index 72f5c8b..86ae66b 100644
--- a/src/methods/composed_gmac/composed_gmac.c
+++ b/src/methods/composed_gmac/composed_gmac.c
@@ -301,7 +301,7 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
ok = session->ghash->digest(session->ghash_state, &tag, inblocks+1, n_blocks*sizeof(fastd_block128_t));
}
- if (!ok || memcmp(&tag, &outblocks[0], sizeof(fastd_block128_t)) != 0) {
+ if (!ok || !block_equal(&tag, &outblocks[0])) {
fastd_buffer_free(*out);
return false;
}
diff --git a/src/methods/composed_umac/composed_umac.c b/src/methods/composed_umac/composed_umac.c
index 02fdda6..6c01bff 100644
--- a/src/methods/composed_umac/composed_umac.c
+++ b/src/methods/composed_umac/composed_umac.c
@@ -265,7 +265,7 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
ok = session->uhash->digest(session->uhash_state, &tag, inblocks+1, in_len);
}
- if (!ok || memcmp(&tag, &outblocks[0], sizeof(fastd_block128_t)) != 0) {
+ if (!ok || !block_equal(&tag, &outblocks[0])) {
fastd_buffer_free(*out);
return false;
}
diff --git a/src/methods/generic_gmac/generic_gmac.c b/src/methods/generic_gmac/generic_gmac.c
index 30a2f2f..519c354 100644
--- a/src/methods/generic_gmac/generic_gmac.c
+++ b/src/methods/generic_gmac/generic_gmac.c
@@ -261,7 +261,7 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
ok = session->ghash->digest(session->ghash_state, &tag, inblocks+1, n_blocks*sizeof(fastd_block128_t));
}
- if (!ok || memcmp(&tag, &outblocks[0], sizeof(fastd_block128_t)) != 0) {
+ if (!ok || !block_equal(&tag, &outblocks[0])) {
fastd_buffer_free(*out);
return false;
}
diff --git a/src/methods/generic_umac/generic_umac.c b/src/methods/generic_umac/generic_umac.c
index aaaf9e7..167ee79 100644
--- a/src/methods/generic_umac/generic_umac.c
+++ b/src/methods/generic_umac/generic_umac.c
@@ -224,7 +224,7 @@ static bool method_decrypt(fastd_peer_t *peer, fastd_method_session_state_t *ses
if (ok)
ok = session->uhash->digest(session->uhash_state, &tag, inblocks+1, in_len);
- if (!ok || memcmp(&tag, &outblocks[0], sizeof(fastd_block128_t)) != 0) {
+ if (!ok || !block_equal(&tag, &outblocks[0])) {
fastd_buffer_free(*out);
return false;
}
diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c
index 7487100..d7b7bfc 100644
--- a/src/protocols/ec25519_fhmqvc/handshake.c
+++ b/src/protocols/ec25519_fhmqvc/handshake.c
@@ -30,6 +30,7 @@
*/
#include "handshake.h"
+#include "../../crypto.h"
#include "../../handshake.h"
#include "../../hkdf_sha256.h"
#include "../../verify.h"
@@ -270,7 +271,7 @@ static bool make_shared_handshake_key(const ecc_int256_t *handshake_key, bool in
/** Checks if the currently cached shared handshake key is valid and generates a new one otherwise */
static bool update_shared_handshake_key(const fastd_peer_t *peer, const handshake_key_t *handshake_key, const aligned_int256_t *peer_handshake_key) {
if (peer->protocol_state->last_handshake_serial == handshake_key->serial) {
- if (memcmp(&peer->protocol_state->peer_handshake_key, peer_handshake_key, PUBLICKEYBYTES) == 0)
+ if (secure_memequal(&peer->protocol_state->peer_handshake_key, peer_handshake_key, PUBLICKEYBYTES))
return true;
}
@@ -442,7 +443,7 @@ static fastd_peer_t * find_key(const uint8_t key[PUBLICKEYBYTES], const fastd_pe
if (address && !fastd_peer_is_enabled(peer))
continue;
- if (memcmp(&peer->key->key, key, PUBLICKEYBYTES) == 0) {
+ if (secure_memequal(&peer->key->key, key, PUBLICKEYBYTES)) {
if (!address)
return peer;
@@ -480,7 +481,7 @@ static fastd_peer_t * match_sender_key(const fastd_socket_t *sock, const fastd_p
exit_bug("packet without correct peer set on dynamic socket");
if (peer) {
- if (memcmp(&peer->key->key, key, PUBLICKEYBYTES) == 0)
+ if (secure_memequal(&peer->key->key, key, PUBLICKEYBYTES))
return peer;
if (fastd_peer_owns_address(peer, address)) {
@@ -658,7 +659,7 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_socket_t *sock, const
}
if (has_field(handshake, RECORD_RECIPIENT_KEY, PUBLICKEYBYTES)) {
- if (memcmp(&conf.protocol_config->key.public, handshake->records[RECORD_RECIPIENT_KEY].data, PUBLICKEYBYTES) != 0) {
+ if (!secure_memequal(&conf.protocol_config->key.public, handshake->records[RECORD_RECIPIENT_KEY].data, PUBLICKEYBYTES)) {
pr_debug("received protocol handshake with wrong recipient key from %P[%I]", peer, remote_addr);
return;
}
@@ -708,11 +709,11 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_socket_t *sock, const
handshake_key_t *handshake_key;
if (is_handshake_key_valid(&ctx.protocol_state->handshake_key) &&
- memcmp(&ctx.protocol_state->handshake_key.key.public, handshake->records[RECORD_RECIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES) == 0) {
+ secure_memequal(&ctx.protocol_state->handshake_key.key.public, handshake->records[RECORD_RECIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES)) {
handshake_key = &ctx.protocol_state->handshake_key;
}
else if (is_handshake_key_valid(&ctx.protocol_state->prev_handshake_key) &&
- memcmp(&ctx.protocol_state->prev_handshake_key.key.public, handshake->records[RECORD_RECIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES) == 0) {
+ secure_memequal(&ctx.protocol_state->prev_handshake_key.key.public, handshake->records[RECORD_RECIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES)) {
handshake_key = &ctx.protocol_state->prev_handshake_key;
}
else {
diff --git a/src/sha256.c b/src/sha256.c
index 3d6401f..2e9a7a7 100644
--- a/src/sha256.c
+++ b/src/sha256.c
@@ -31,6 +31,7 @@
#include "sha256.h"
+#include "crypto.h"
#include <stdarg.h>
#include <string.h>
@@ -261,7 +262,7 @@ bool fastd_hmacsha256_blocks_verify(const uint8_t mac[FASTD_SHA256_HASH_BYTES],
hmacsha256_blocks_va(&out, key, ap);
va_end(ap);
- return !memcmp(out.b, mac, FASTD_SHA256_HASH_BYTES);
+ return secure_memequal(out.b, mac, FASTD_SHA256_HASH_BYTES);
}
/** Computes the HMAC-SHA256 of an arbitraty input buffer */
@@ -280,5 +281,5 @@ bool fastd_hmacsha256_verify(const uint8_t mac[FASTD_SHA256_HASH_BYTES], const u
fastd_sha256_t out;
fastd_hmacsha256(&out, key, in, len);
- return !memcmp(out.b, mac, FASTD_SHA256_HASH_BYTES);
+ return secure_memequal(out.b, mac, FASTD_SHA256_HASH_BYTES);
}