summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-08-15 02:44:26 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-08-15 02:44:26 +0200
commit1bb34487bfe7ecd074b42bafca055adfe89d14df (patch)
tree31eb030c11fa2d7c1422503e481bfb4b8d426d0c
parent6ecf69b6e67ff552aaf2ab8062be072aba062e0e (diff)
downloadfastd-1bb34487bfe7ecd074b42bafca055adfe89d14df.tar
fastd-1bb34487bfe7ecd074b42bafca055adfe89d14df.zip
Replace NaCl's HMAC implementation
-rw-r--r--src/protocol_ec25519_fhmqvc.c57
-rw-r--r--src/sha256.c111
-rw-r--r--src/sha256.h16
3 files changed, 121 insertions, 63 deletions
diff --git a/src/protocol_ec25519_fhmqvc.c b/src/protocol_ec25519_fhmqvc.c
index f6c170b..75ad055 100644
--- a/src/protocol_ec25519_fhmqvc.c
+++ b/src/protocol_ec25519_fhmqvc.c
@@ -32,17 +32,18 @@
#include <libuecc/ecc.h>
-#include <crypto_auth_hmacsha256.h>
#define PUBLICKEYBYTES 32
#define SECRETKEYBYTES 32
-#define HMACBYTES crypto_auth_hmacsha256_BYTES
+#define HMACWORDS FASTD_SHA256_HASH_WORDS
+#define HMACBYTES FASTD_SHA256_HASH_BYTES
+#define HASHWORDS FASTD_SHA256_HASH_WORDS
#define HASHBYTES FASTD_SHA256_HASH_BYTES
-#if HASHBYTES != crypto_auth_hmacsha256_KEYBYTES
-#error bug: HASHBYTES != crypto_auth_hmacsha256_KEYBYTES
+#if HASHWORDS != FASTD_HMACSHA256_KEY_WORDS
+#error bug: HASHWORDS != FASTD_HMACSHA256_KEY_WORDS
#endif
#if HASHBYTES != SECRETKEYBYTES
@@ -278,9 +279,8 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock,
const handshake_key_t *handshake_key, const ecc_int256_t *peer_handshake_key, const fastd_handshake_t *handshake, const fastd_method_t *method) {
pr_debug(ctx, "responding handshake with %P[%I]...", peer, remote_addr);
- uint8_t hashinput[2*PUBLICKEYBYTES];
- uint8_t hashbuf[HASHBYTES];
- uint8_t hmacbuf[HMACBYTES];
+ uint32_t hashbuf[HASHWORDS];
+ uint32_t hmacbuf[HMACWORDS];
fastd_sha256_blocks(hashbuf,
handshake_key->public_key.p,
@@ -292,7 +292,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock,
ecc_int256_t d = {{0}}, e = {{0}}, eb, s;
memcpy(d.p, hashbuf, HASHBYTES/2);
- memcpy(e.p, hashbuf+HASHBYTES/2, HASHBYTES/2);
+ memcpy(e.p, hashbuf+HASHWORDS/2, HASHBYTES/2);
d.p[15] |= 0x80;
e.p[15] |= 0x80;
@@ -321,7 +321,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock,
ecc_int256_t sigma;
ecc_25519_store_packed(&sigma, &work);
- uint8_t shared_handshake_key[HASHBYTES];
+ uint32_t shared_handshake_key[HASHWORDS];
fastd_sha256_blocks(shared_handshake_key,
handshake_key->public_key.p,
peer_handshake_key->p,
@@ -330,10 +330,7 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock,
sigma.p,
NULL);
- memcpy(hashinput, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
- memcpy(hashinput+PUBLICKEYBYTES, handshake_key->public_key.p, PUBLICKEYBYTES);
-
- crypto_auth_hmacsha256(hmacbuf, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key);
+ fastd_hmacsha256_blocks(hmacbuf, shared_handshake_key, ctx->conf->protocol_config->public_key.p, handshake_key->public_key.p, NULL);
fastd_buffer_t buffer = fastd_handshake_new_reply(ctx, handshake, method, 4*(4+PUBLICKEYBYTES) + 4+HMACBYTES);
@@ -373,14 +370,14 @@ static bool establish(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_meth
peer->protocol_state->old_session = (protocol_session_t){};
}
- uint8_t hash[HASHBYTES];
+ uint32_t hash[HASHWORDS];
fastd_sha256_blocks(hash, X->p, Y->p, A->p, B->p, sigma->p, NULL);
peer->protocol_state->session.established = ctx->now;
peer->protocol_state->session.handshakes_cleaned = false;
peer->protocol_state->session.refreshing = false;
peer->protocol_state->session.method = method;
- peer->protocol_state->session.method_state = method->session_init(ctx, hash, HASHBYTES, initiator);
+ peer->protocol_state->session.method_state = method->session_init(ctx, (uint8_t*)hash, HASHBYTES, initiator);
peer->protocol_state->last_serial = serial;
fastd_peer_seen(ctx, peer);
@@ -407,9 +404,8 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f
const fastd_handshake_t *handshake, const fastd_method_t *method) {
pr_debug(ctx, "finishing handshake with %P[%I]...", peer, remote_addr);
- uint8_t hashinput[2*PUBLICKEYBYTES];
- uint8_t hashbuf[HASHBYTES];
- uint8_t hmacbuf[HMACBYTES];
+ uint32_t hashbuf[HASHWORDS];
+ uint32_t hmacbuf[HMACWORDS];
fastd_sha256_blocks(hashbuf,
peer_handshake_key->p,
@@ -421,7 +417,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f
ecc_int256_t d = {{0}}, e = {{0}}, da, s;
memcpy(d.p, hashbuf, HASHBYTES/2);
- memcpy(e.p, hashbuf+HASHBYTES/2, HASHBYTES/2);
+ memcpy(e.p, hashbuf+HASHWORDS/2, HASHBYTES/2);
d.p[15] |= 0x80;
e.p[15] |= 0x80;
@@ -450,7 +446,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f
ecc_int256_t sigma;
ecc_25519_store_packed(&sigma, &work);
- uint8_t shared_handshake_key[HASHBYTES];
+ uint32_t shared_handshake_key[HASHWORDS];
fastd_sha256_blocks(shared_handshake_key,
peer_handshake_key->p,
handshake_key->public_key.p,
@@ -459,17 +455,12 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f
sigma.p,
NULL);
- memcpy(hashinput, peer->protocol_config->public_key.p, PUBLICKEYBYTES);
- memcpy(hashinput+PUBLICKEYBYTES, peer_handshake_key->p, PUBLICKEYBYTES);
-
- if(crypto_auth_hmacsha256_verify(handshake->records[RECORD_T].data, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key) != 0) {
+ if(!fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, shared_handshake_key, peer->protocol_config->public_key.p, peer_handshake_key->p, NULL)) {
pr_warn(ctx, "received invalid protocol handshake response from %P[%I]", peer, remote_addr);
return;
}
- memcpy(hashinput, ctx->conf->protocol_config->public_key.p, PUBLICKEYBYTES);
- memcpy(hashinput+PUBLICKEYBYTES, handshake_key->public_key.p, PUBLICKEYBYTES);
- crypto_auth_hmacsha256(hmacbuf, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key);
+ fastd_hmacsha256_blocks(hmacbuf, shared_handshake_key, ctx->conf->protocol_config->public_key.p, handshake_key->public_key.p, NULL);
if (!establish(ctx, peer, method, sock, local_addr, remote_addr, true, &handshake_key->public_key, peer_handshake_key, &ctx->conf->protocol_config->public_key,
&peer->protocol_config->public_key, &sigma, handshake_key->serial))
@@ -491,8 +482,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock,
const fastd_handshake_t *handshake, const fastd_method_t *method) {
pr_debug(ctx, "handling handshake finish with %P[%I]...", peer, remote_addr);
- uint8_t hashinput[2*PUBLICKEYBYTES];
- uint8_t hashbuf[HASHBYTES];
+ uint32_t hashbuf[HASHWORDS];
fastd_sha256_blocks(hashbuf,
handshake_key->public_key.p,
@@ -504,7 +494,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock,
ecc_int256_t d = {{0}}, e = {{0}}, eb, s;
memcpy(d.p, hashbuf, HASHBYTES/2);
- memcpy(e.p, hashbuf+HASHBYTES/2, HASHBYTES/2);
+ memcpy(e.p, hashbuf+HASHWORDS/2, HASHBYTES/2);
d.p[15] |= 0x80;
e.p[15] |= 0x80;
@@ -533,7 +523,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock,
ecc_int256_t sigma;
ecc_25519_store_packed(&sigma, &work);
- uint8_t shared_handshake_key[HASHBYTES];
+ uint32_t shared_handshake_key[HASHWORDS];
fastd_sha256_blocks(shared_handshake_key,
handshake_key->public_key.p,
peer_handshake_key->p,
@@ -542,10 +532,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock,
sigma.p,
NULL);
- memcpy(hashinput, peer->protocol_config->public_key.p, PUBLICKEYBYTES);
- memcpy(hashinput+PUBLICKEYBYTES, peer_handshake_key->p, PUBLICKEYBYTES);
-
- if(crypto_auth_hmacsha256_verify(handshake->records[RECORD_T].data, hashinput, 2*PUBLICKEYBYTES, shared_handshake_key) != 0) {
+ if (!fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, shared_handshake_key, peer->protocol_config->public_key.p, peer_handshake_key->p, NULL)) {
pr_warn(ctx, "received invalid protocol handshake finish from %P[%I]", peer, remote_addr);
return;
}
diff --git a/src/sha256.c b/src/sha256.c
index 639185c..4722272 100644
--- a/src/sha256.c
+++ b/src/sha256.c
@@ -27,7 +27,6 @@
#include "sha256.h"
#include <stdarg.h>
-#include <stdbool.h>
#include <string.h>
#include <arpa/inet.h>
@@ -37,7 +36,7 @@ static inline uint32_t rotr(uint32_t x, int r) {
return (x >> r) | (x << (32-r));
}
-void fastd_sha256_blocks(uint8_t out[FASTD_SHA256_HASH_BYTES], ...) {
+static void sha256_blocks_va(uint32_t out[FASTD_SHA256_HASH_WORDS], const uint32_t *in1, const uint32_t *in2, va_list ap) {
static const uint32_t k[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
@@ -59,28 +58,11 @@ void fastd_sha256_blocks(uint8_t out[FASTD_SHA256_HASH_BYTES], ...) {
0x1f83d9ab,
0x5be0cd19
};
- unsigned count = 0, i;
- va_list ap;
- const uint32_t *in1, *in2;
-
- va_start(ap, out);
+ unsigned count = in2 ? 2 : in1 ? 1 : 0, i;
- do {
+ while (true) {
uint32_t w[64], v[8];
- in1 = va_arg(ap, const uint32_t*);
-
- if (in1) {
- count++;
- in2 = va_arg(ap, const uint32_t*);
-
- if (in2)
- count++;
- }
- else {
- in2 = NULL;
- }
-
if (in1) {
for (i = 0; i < 8; i++)
w[i] = ntohl(in1[i]);
@@ -129,11 +111,90 @@ void fastd_sha256_blocks(uint8_t out[FASTD_SHA256_HASH_BYTES], ...) {
for (i = 0; i < 8; i++)
h[i] += v[i];
- } while (in1 && in2);
- va_end(ap);
+ if (!in2)
+ break;
+
+
+ in1 = va_arg(ap, const uint32_t*);
+ if (in1) {
+ count++;
+ in2 = va_arg(ap, const uint32_t*);
+
+ if (in2)
+ count++;
+ }
+ else {
+ in2 = NULL;
+ }
+ }
- uint32_t *out32 = (uint32_t*)out;
for (i = 0; i < 8; i++)
- out32[i] = htonl(h[i]);
+ out[i] = htonl(h[i]);
+}
+
+static void hmacsha256_blocks_va(uint32_t out[FASTD_SHA256_HASH_WORDS], const uint32_t key[FASTD_HMACSHA256_KEY_WORDS], va_list ap) {
+ static const uint32_t ipad2[8] = {
+ 0x36363636,
+ 0x36363636,
+ 0x36363636,
+ 0x36363636,
+ 0x36363636,
+ 0x36363636,
+ 0x36363636,
+ 0x36363636
+ };
+ static const uint32_t opad2[8] = {
+ 0x5c5c5c5c,
+ 0x5c5c5c5c,
+ 0x5c5c5c5c,
+ 0x5c5c5c5c,
+ 0x5c5c5c5c,
+ 0x5c5c5c5c,
+ 0x5c5c5c5c,
+ 0x5c5c5c5c
+ };
+
+ uint32_t ipad[8], opad[8];
+ unsigned i;
+
+ for (i = 0; i < 8; i++) {
+ ipad[i] = key[i] ^ 0x36363636;
+ opad[i] = key[i] ^ 0x5c5c5c5c;
+ }
+
+ uint32_t temp[8];
+ sha256_blocks_va(temp, ipad, ipad2, ap);
+
+ fastd_sha256_blocks(out, opad, opad2, temp, NULL);
+}
+
+
+void fastd_sha256_blocks(uint32_t out[FASTD_SHA256_HASH_WORDS], ...) {
+ va_list ap;
+
+ va_start(ap, out);
+ const uint32_t *in1 = va_arg(ap, const uint32_t*);
+ const uint32_t *in2 = in1 ? va_arg(ap, const uint32_t*) : NULL;
+ sha256_blocks_va(out, in1, in2, ap);
+ va_end(ap);
+}
+
+void fastd_hmacsha256_blocks(uint32_t out[FASTD_SHA256_HASH_WORDS], const uint32_t key[FASTD_HMACSHA256_KEY_WORDS], ...) {
+ va_list ap;
+
+ va_start(ap, key);
+ hmacsha256_blocks_va(out, key, ap);
+ va_end(ap);
+}
+
+bool fastd_hmacsha256_blocks_verify(const uint8_t mac[FASTD_SHA256_HASH_BYTES], const uint32_t key[FASTD_HMACSHA256_KEY_WORDS], ...) {
+ va_list ap;
+ uint32_t out[8];
+
+ va_start(ap, key);
+ hmacsha256_blocks_va(out, key, ap);
+ va_end(ap);
+
+ return !memcmp(out, mac, sizeof(out));
}
diff --git a/src/sha256.h b/src/sha256.h
index c6acadb..acafe7e 100644
--- a/src/sha256.h
+++ b/src/sha256.h
@@ -27,13 +27,23 @@
#ifndef _FASTD_SHA256_H_
#define _FASTD_SHA256_H_
+#include <stdbool.h>
#include <stdint.h>
-#define FASTD_SHA256_HASH_BYTES 32
-#define FASTD_SHA256_HASH_BLOCK_BYTES 32
+#define FASTD_SHA256_HASH_WORDS 8
+#define FASTD_SHA256_BLOCK_WORDS 8
+#define FASTD_HMACSHA256_KEY_WORDS 8
-void fastd_sha256_blocks(uint8_t out[FASTD_SHA256_HASH_BYTES], ...);
+#define FASTD_SHA256_HASH_BYTES (4*FASTD_SHA256_HASH_WORDS)
+#define FASTD_SHA256_BLOCK_BYTES (4*FASTD_SHA256_BLOCK_WORDS)
+
+#define FASTD_HMACSHA256_KEY_BYTES (4*FASTD_HMACSHA256_KEY_WORDS)
+
+
+void fastd_sha256_blocks(uint32_t out[FASTD_SHA256_HASH_WORDS], ...);
+void fastd_hmacsha256_blocks(uint32_t out[FASTD_SHA256_HASH_WORDS], const uint32_t key[FASTD_HMACSHA256_KEY_WORDS], ...);
+bool fastd_hmacsha256_blocks_verify(const uint8_t mac[FASTD_SHA256_HASH_BYTES], const uint32_t key[FASTD_HMACSHA256_KEY_WORDS], ...);
#endif /* _FASTD_SHA256_H_ */