summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt19
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/config.c27
-rw-r--r--src/config.y9
-rw-r--r--src/crypto.h56
-rw-r--r--src/crypto/CMakeLists.txt7
-rw-r--r--src/crypto/mac/CMakeLists.txt34
-rw-r--r--src/crypto/mac/ghash/CMakeLists.txt18
-rw-r--r--src/crypto/mac/ghash/builtin/CMakeLists.txt6
-rw-r--r--src/crypto/mac/ghash/builtin/ghash_builtin.c (renamed from src/crypto.c)49
-rw-r--r--src/crypto/mac/macs.c.in117
-rw-r--r--src/fastd.c14
-rw-r--r--src/fastd.h46
-rw-r--r--src/methods/generic_gcm/generic_gcm.c20
-rw-r--r--src/types.h11
15 files changed, 259 insertions, 175 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 12daafa..70a17c9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,8 @@ set(WITH_CMDLINE_COMMANDS TRUE CACHE BOOL "Include support for setting handler s
set(WITH_CIPHER_AES128_CTR TRUE CACHE BOOL "Include the AES128-CTR cipher algorithm")
set(WITH_CIPHER_AES128_CTR_NACL TRUE CACHE BOOL "Include the AES128-CTR implementation from the NaCl library")
-set(WITH_CRYPTO_GHASH_BUILTIN TRUE CACHE BOOL "Include the built-in GHASH implementation")
+set(WITH_MAC_GHASH TRUE CACHE BOOL "Include the GHASH MAC algorithm")
+set(WITH_MAC_GHASH_BUILTIN TRUE CACHE BOOL "Include the built-in GHASH implementation")
set(WITH_METHOD_XSALSA20_POLY1305 TRUE CACHE BOOL "Include xsalsa20-poly1305 method")
set(WITH_METHOD_GENERIC_GCM TRUE CACHE BOOL "Include generic gcm method")
@@ -44,25 +45,9 @@ set(USE_LIBSODIUM FALSE CACHE BOOL "Use libsodium instead of NaCl")
set(MAX_CONFIG_DEPTH 10 CACHE STRING "Maximum config include depth")
-if(WITH_CRYPTO_GHASH_BUILTIN)
- set(WITH_CRYPTO_GHASH TRUE)
-endif(WITH_CRYPTO_GHASH_BUILTIN)
-
-
# Ensure the value is numeric
math(EXPR MAX_CONFIG_DEPTH_NUM ${MAX_CONFIG_DEPTH})
-set(USE_CRYPTO_GHASH FALSE)
-
-if(WITH_METHOD_AES128_GCM)
- set(USE_CRYPTO_GHASH TRUE)
-endif(WITH_METHOD_AES128_GCM)
-
-
-if(USE_CRYPTO_GHASH AND NOT WITH_CRYPTO_GHASH)
- MESSAGE(FATAL_ERROR "No GHASH implementation was selected, but a selected method needs it.")
-endif(USE_CRYPTO_GHASH AND NOT WITH_CRYPTO_GHASH)
-
find_package(BISON 2.5 REQUIRED)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 68b077e..ebc6c37 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -16,7 +16,6 @@ add_executable(fastd
fastd.c
capabilities.c
config.c
- crypto.c
handshake.c
hkdf_sha256.c
lex.c
diff --git a/src/config.c b/src/config.c
index 8cf0dcb..f9d2ae1 100644
--- a/src/config.c
+++ b/src/config.c
@@ -43,10 +43,6 @@
extern const fastd_protocol_t fastd_protocol_ec25519_fhmqvc;
-#ifdef USE_CRYPTO_GHASH
-extern const fastd_crypto_ghash_t fastd_crypto_ghash_builtin;
-#endif
-
static void default_config(fastd_config_t *conf) {
memset(conf, 0, sizeof(fastd_config_t));
@@ -74,15 +70,12 @@ static void default_config(fastd_config_t *conf) {
conf->key_refresh = 3300; /* 55 minutes */
conf->key_refresh_splay = 300; /* 5 minutes */
-#ifdef USE_CRYPTO_GHASH
- conf->crypto_ghash = &fastd_crypto_ghash_builtin;
-#endif
-
conf->peer_group = calloc(1, sizeof(fastd_peer_group_config_t));
conf->peer_group->name = strdup("default");
conf->peer_group->max_connections = -1;
conf->ciphers = fastd_cipher_config_alloc();
+ conf->macs = fastd_mac_config_alloc();
}
bool fastd_config_protocol(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *name) {
@@ -112,23 +105,6 @@ bool fastd_config_method(fastd_context_t *ctx, fastd_config_t *conf, const char
return true;
}
-bool fastd_config_crypto(fastd_context_t *ctx UNUSED, fastd_config_t *conf UNUSED, const char *alg UNUSED, const char *impl UNUSED) {
-#ifdef USE_CRYPTO_GHASH
- if (!strcasecmp(alg, "ghash")) {
- if (!strcasecmp(impl, "default"))
- conf->crypto_ghash = &fastd_crypto_ghash_builtin;
- else if (!strcasecmp(impl, "builtin"))
- conf->crypto_ghash = &fastd_crypto_ghash_builtin;
- else
- return false;
-
- return true;
- }
- else
-#endif
- return false;
-}
-
bool fastd_config_bind_address(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const fastd_peer_address_t *address, const char *bindtodev, bool default_v4, bool default_v6) {
#ifndef USE_BINDTODEVICE
if (bindtodev)
@@ -671,6 +647,7 @@ void fastd_config_release(fastd_context_t *ctx, fastd_config_t *conf) {
fastd_string_stack_free(conf->methods);
+ fastd_mac_config_free(conf->macs);
fastd_cipher_config_free(conf->ciphers);
free(conf->user);
diff --git a/src/config.y b/src/config.y
index ffc719d..ca2d8de 100644
--- a/src/config.y
+++ b/src/config.y
@@ -177,7 +177,6 @@ statement: peer_group_statement
| TOK_MODE mode ';'
| TOK_PROTOCOL protocol ';'
| TOK_METHOD method ';'
- | TOK_CRYPTO crypto ';'
| TOK_SECRET secret ';'
| TOK_ON TOK_PRE_UP on_pre_up ';'
| TOK_ON TOK_UP on_up ';'
@@ -357,14 +356,6 @@ method: TOK_STRING {
}
;
-crypto: TOK_STRING TOK_USE TOK_STRING {
- if (!fastd_config_crypto(ctx, conf, $1->str, $3->str)) {
- fastd_config_error(&@$, ctx, conf, filename, depth, "invalid crypto algorithm/implementation");
- YYERROR;
- }
- }
- ;
-
secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); }
;
diff --git a/src/crypto.h b/src/crypto.h
deleted file mode 100644
index b954651..0000000
--- a/src/crypto.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- Copyright (c) 2012-2013, Matthias Schiffer <mschiffer@universe-factory.net>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef _FASTD_CRYPTO_H_
-#define _FASTD_CRYPTO_H_
-
-#include "types.h"
-
-
-#ifdef USE_CRYPTO_GHASH
-struct fastd_crypto_ghash {
- const char *name;
-
- fastd_crypto_ghash_context_t* (*init)(fastd_context_t *ctx);
- fastd_crypto_ghash_state_t* (*set_h)(fastd_context_t *ctx, const fastd_crypto_ghash_context_t *cctx, const fastd_block128_t *h);
- bool (*hash)(fastd_context_t *ctx, const fastd_crypto_ghash_state_t *cstate, fastd_block128_t *out, const fastd_block128_t *in, size_t n_blocks);
-
- void (*free_state)(fastd_context_t *ctx, fastd_crypto_ghash_state_t *cstate);
- void (*free)(fastd_context_t *ctx, fastd_crypto_ghash_context_t *cctx);
-};
-#endif
-
-
-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];
- x->qw[1] = a->qw[1] ^ b->qw[1];
-}
-
-static inline void xor_a(fastd_block128_t *x, const fastd_block128_t *a) {
- xor(x, x, a);
-}
-
-#endif /* _FASTD_CRYPTO_H_ */
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 1c78e03..94ff3b4 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -1,3 +1,8 @@
add_subdirectory(cipher)
+add_subdirectory(mac)
-set(CRYPTO_SOURCES "${CIPHER_SOURCES}" PARENT_SCOPE)
+set(CRYPTO_SOURCES "")
+list(APPEND CRYPTO_SOURCES ${CIPHER_SOURCES})
+list(APPEND CRYPTO_SOURCES ${MAC_SOURCES})
+
+set(CRYPTO_SOURCES "${CRYPTO_SOURCES}" PARENT_SCOPE)
diff --git a/src/crypto/mac/CMakeLists.txt b/src/crypto/mac/CMakeLists.txt
new file mode 100644
index 0000000..7f8664c
--- /dev/null
+++ b/src/crypto/mac/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(MACS "")
+
+if(WITH_MAC_GHASH)
+ list(APPEND MACS ghash)
+endif(WITH_MAC_GHASH)
+
+set(MAC_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/macs.c")
+
+set(MAC_DEFINITIONS "")
+set(MAC_IMPLS "")
+set(MAC_LIST "")
+
+foreach(mac ${MACS})
+ add_subdirectory(${mac})
+
+ list(APPEND MAC_SOURCES ${IMPL_SOURCES})
+
+ set(MAC_LIST "${MAC_LIST}\n{\"${MAC_NAME}\", mac_${mac}_impls},")
+ set(MAC_IMPLS "${MAC_IMPLS}\nstatic const fastd_mac_t *const mac_${mac}_impls[] = {")
+
+ foreach(impl ${IMPLS})
+ set(MAC_DEFINITIONS "${MAC_DEFINITIONS}\nextern const fastd_mac_t fastd_mac_${mac}_${impl};")
+ set(MAC_IMPLS "${MAC_IMPLS}&fastd_mac_${mac}_${impl}, ")
+ endforeach(impl)
+
+ set(MAC_IMPLS "${MAC_IMPLS}NULL};")
+
+endforeach(mac)
+
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macs.c.in ${CMAKE_CURRENT_BINARY_DIR}/macs.c)
+
+
+set(MAC_SOURCES "${MAC_SOURCES}" PARENT_SCOPE)
diff --git a/src/crypto/mac/ghash/CMakeLists.txt b/src/crypto/mac/ghash/CMakeLists.txt
new file mode 100644
index 0000000..7d697e8
--- /dev/null
+++ b/src/crypto/mac/ghash/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(IMPLS "")
+
+if(WITH_MAC_GHASH_BUILTIN)
+ list(APPEND IMPLS builtin)
+endif(WITH_MAC_GHASH_BUILTIN)
+
+set(IMPL_SOURCES "")
+
+foreach(impl ${IMPLS})
+ add_subdirectory(${impl})
+
+ list(APPEND IMPL_SOURCES $<TARGET_OBJECTS:mac_ghash_${impl}>)
+endforeach(impl)
+
+
+set(MAC_NAME "ghash" PARENT_SCOPE)
+set(IMPLS "${IMPLS}" PARENT_SCOPE)
+set(IMPL_SOURCES "${IMPL_SOURCES}" PARENT_SCOPE)
diff --git a/src/crypto/mac/ghash/builtin/CMakeLists.txt b/src/crypto/mac/ghash/builtin/CMakeLists.txt
new file mode 100644
index 0000000..7951d58
--- /dev/null
+++ b/src/crypto/mac/ghash/builtin/CMakeLists.txt
@@ -0,0 +1,6 @@
+include_directories(${FASTD_SOURCE_DIR}/src ${FASTD_BINARY_DIR})
+
+add_library(mac_ghash_builtin OBJECT
+ ghash_builtin.c
+)
+set_property(TARGET mac_ghash_builtin PROPERTY COMPILE_FLAGS "${FASTD_CFLAGS}")
diff --git a/src/crypto.c b/src/crypto/mac/ghash/builtin/ghash_builtin.c
index 1583349..2eb7fed 100644
--- a/src/crypto.c
+++ b/src/crypto/mac/ghash/builtin/ghash_builtin.c
@@ -24,14 +24,10 @@
*/
-#include "fastd.h"
-#include "crypto.h"
+#include "../../../../fastd.h"
-#ifdef USE_CRYPTO_GHASH
-#ifdef WITH_CRYPTO_GHASH_BUILTIN
-
-struct fastd_crypto_ghash_state {
+struct fastd_mac_state {
fastd_block128_t H[32][16];
};
@@ -52,7 +48,7 @@ static inline uint8_t shr(fastd_block128_t *out, const fastd_block128_t *in, int
return (c >> (8-n));
}
-static inline void mulH_a(fastd_block128_t *x, const fastd_crypto_ghash_state_t *cstate) {
+static inline void mulH_a(fastd_block128_t *x, const fastd_mac_state_t *cstate) {
fastd_block128_t out = {};
int i;
@@ -65,17 +61,17 @@ static inline void mulH_a(fastd_block128_t *x, const fastd_crypto_ghash_state_t
}
-static fastd_crypto_ghash_context_t* ghash_init(fastd_context_t *ctx UNUSED) {
- return (fastd_crypto_ghash_context_t*)1;
+static fastd_mac_context_t* ghash_initialize(fastd_context_t *ctx UNUSED) {
+ return NULL;
}
-static fastd_crypto_ghash_state_t* ghash_set_h(fastd_context_t *ctx UNUSED, const fastd_crypto_ghash_context_t *cctx UNUSED, const fastd_block128_t *h) {
- fastd_crypto_ghash_state_t *cstate = malloc(sizeof(fastd_crypto_ghash_state_t));
+static fastd_mac_state_t* ghash_init_state(fastd_context_t *ctx UNUSED, const fastd_mac_context_t *mctx UNUSED, const uint8_t *key) {
+ fastd_mac_state_t *state = malloc(sizeof(fastd_mac_state_t));
fastd_block128_t Hbase[4];
fastd_block128_t Rbase[4];
- Hbase[0] = *h;
+ memcpy(&Hbase[0], key, sizeof(fastd_block128_t));
Rbase[0] = r;
int i;
@@ -88,14 +84,14 @@ static fastd_crypto_ghash_state_t* ghash_set_h(fastd_context_t *ctx UNUSED, cons
}
fastd_block128_t R[16];
- memset(cstate->H, 0, sizeof(cstate->H));
+ memset(state->H, 0, sizeof(state->H));
memset(R, 0, sizeof(R));
for (i = 0; i < 16; i++) {
int j;
for (j = 0; j < 4; j++) {
if (i & (8 >> j)) {
- xor_a(&cstate->H[0][i], &Hbase[j]);
+ xor_a(&state->H[0][i], &Hbase[j]);
xor_a(&R[i], &Rbase[j]);
}
}
@@ -105,43 +101,40 @@ static fastd_crypto_ghash_state_t* ghash_set_h(fastd_context_t *ctx UNUSED, cons
int j;
for (j = 0; j < 16; j++) {
- uint8_t carry = shr(&cstate->H[i][j], &cstate->H[i-1][j], 4);
- xor_a(&cstate->H[i][j], &R[carry]);
+ uint8_t carry = shr(&state->H[i][j], &state->H[i-1][j], 4);
+ xor_a(&state->H[i][j], &R[carry]);
}
}
- return cstate;
+ return state;
}
-static bool ghash_hash(fastd_context_t *ctx UNUSED, const fastd_crypto_ghash_state_t *cstate, fastd_block128_t *out, const fastd_block128_t *in, size_t n_blocks) {
+static bool ghash_hash(fastd_context_t *ctx UNUSED, const fastd_mac_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t n_blocks) {
memset(out, 0, sizeof(fastd_block128_t));
size_t i;
for (i = 0; i < n_blocks; i++) {
xor_a(out, &in[i]);
- mulH_a(out, cstate);
+ mulH_a(out, state);
}
return true;
}
-static void ghash_free_state(fastd_context_t *ctx UNUSED, fastd_crypto_ghash_state_t *cstate) {
- free(cstate);
+static void ghash_free_state(fastd_context_t *ctx UNUSED, fastd_mac_state_t *state) {
+ free(state);
}
-static void ghash_free(fastd_context_t *ctx UNUSED, fastd_crypto_ghash_context_t *cctx UNUSED) {
+static void ghash_free(fastd_context_t *ctx UNUSED, fastd_mac_context_t *mctx UNUSED) {
}
-const fastd_crypto_ghash_t fastd_crypto_ghash_builtin = {
+const fastd_mac_t fastd_mac_ghash_builtin = {
.name = "builtin",
- .init = ghash_init,
- .set_h = ghash_set_h,
+ .initialize = ghash_initialize,
+ .init_state = ghash_init_state,
.hash = ghash_hash,
.free_state = ghash_free_state,
.free = ghash_free,
};
-
-#endif
-#endif
diff --git a/src/crypto/mac/macs.c.in b/src/crypto/mac/macs.c.in
new file mode 100644
index 0000000..e591935
--- /dev/null
+++ b/src/crypto/mac/macs.c.in
@@ -0,0 +1,117 @@
+/*
+ Copyright (c) 2012-2013, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <fastd.h>
+
+
+@MAC_DEFINITIONS@
+
+typedef struct mac_impl_list {
+ const char *name;
+ const fastd_mac_t *const *impls;
+} mac_impl_list_t;
+
+@MAC_IMPLS@
+
+static const mac_impl_list_t macs[] = { @MAC_LIST@
+};
+
+
+const fastd_mac_t** fastd_mac_config_alloc(void) {
+ const fastd_mac_t **mac_conf = calloc(array_size(macs), sizeof(const fastd_mac_t*));
+
+ size_t i;
+ for (i = 0; i < array_size(macs); i++)
+ mac_conf[i] = macs[i].impls[0];
+
+ return mac_conf;
+}
+
+void fastd_mac_config_free(const fastd_mac_t **mac_conf) {
+ free(mac_conf);
+}
+
+bool fastd_mac_config(const fastd_mac_t **mac_conf, const char *name, const char *impl) {
+ size_t i;
+ for (i = 0; i < array_size(macs); i++) {
+ if (!strcmp(macs[i].name, name)) {
+ size_t j;
+ for (j = 0; macs[i].impls[j]; j++) {
+ if (!strcmp(macs[i].impls[j]->name, impl)) {
+ mac_conf[i] = macs[i].impls[j];
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ return false;
+}
+
+void fastd_mac_init(fastd_context_t *ctx) {
+ ctx->mac_contexts = calloc(array_size(macs), sizeof(fastd_mac_context_t*));
+
+ size_t i;
+ for (i = 0; i < array_size(macs); i++) {
+ if (ctx->conf->macs[i])
+ ctx->mac_contexts[i] = ctx->conf->macs[i]->initialize(ctx);
+ }
+}
+
+void fastd_mac_free(fastd_context_t *ctx) {
+ size_t i;
+ for (i = 0; i < array_size(macs); i++)
+ ctx->conf->macs[i]->free(ctx, ctx->mac_contexts[i]);
+
+ free(ctx->mac_contexts);
+}
+
+bool fastd_mac_available(const char *name) {
+ size_t i;
+ for (i = 0; i < array_size(macs); i++) {
+ if (!strcmp(macs[i].name, name)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+const fastd_mac_t* fastd_mac_get_by_name(fastd_context_t *ctx, const char *name, fastd_mac_context_t **cctx) {
+ size_t i;
+ for (i = 0; i < array_size(macs); i++) {
+ if (!strcmp(macs[i].name, name)) {
+ if (cctx)
+ *cctx = ctx->mac_contexts[i];
+
+ return ctx->conf->macs[i];
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/fastd.c b/src/fastd.c
index 534a30e..175dc00 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -25,7 +25,6 @@
#include "fastd.h"
-#include "crypto.h"
#include "handshake.h"
#include "peer.h"
#include <fastd_version.h>
@@ -147,20 +146,11 @@ static void close_log(fastd_context_t *ctx) {
static void crypto_init(fastd_context_t *ctx) {
fastd_cipher_init(ctx);
-
-#ifdef USE_CRYPTO_GHASH
- ctx->crypto_ghash = ctx->conf->crypto_ghash->init(ctx);
- if (!ctx->crypto_ghash)
- exit_error(ctx, "Unable to initialize GHASH implementation");
-#endif
+ fastd_mac_init(ctx);
}
static void crypto_free(fastd_context_t *ctx UNUSED) {
-#ifdef USE_CRYPTO_GHASH
- ctx->conf->crypto_ghash->free(ctx, ctx->crypto_ghash);
- ctx->crypto_ghash = NULL;
-#endif
-
+ fastd_mac_free(ctx);
fastd_cipher_free(ctx);
}
diff --git a/src/fastd.h b/src/fastd.h
index 6f0bd19..573da1b 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -105,12 +105,23 @@ struct fastd_cipher {
fastd_cipher_context_t* (*initialize)(fastd_context_t *ctx);
fastd_cipher_state_t* (*init_state)(fastd_context_t *ctx, const fastd_cipher_context_t *cctx, const uint8_t *key);
- bool (*crypt)(fastd_context_t *ctx, const fastd_cipher_state_t *cstate, fastd_block128_t *out, const fastd_block128_t *in, size_t len, const fastd_block128_t *iv);
+ bool (*crypt)(fastd_context_t *ctx, const fastd_cipher_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t len, const fastd_block128_t *iv);
- void (*free_state)(fastd_context_t *ctx, fastd_cipher_state_t *cstate);
+ void (*free_state)(fastd_context_t *ctx, fastd_cipher_state_t *state);
void (*free)(fastd_context_t *ctx, fastd_cipher_context_t *cctx);
};
+struct fastd_mac {
+ const char *name;
+
+ fastd_mac_context_t* (*initialize)(fastd_context_t *ctx);
+ fastd_mac_state_t* (*init_state)(fastd_context_t *ctx, const fastd_mac_context_t *mctx, const uint8_t *key);
+ bool (*hash)(fastd_context_t *ctx, const fastd_mac_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t n_blocks);
+
+ void (*free_state)(fastd_context_t *ctx, fastd_mac_state_t *state);
+ void (*free)(fastd_context_t *ctx, fastd_mac_context_t *mctx);
+};
+
union fastd_peer_address {
struct sockaddr sa;
struct sockaddr_in in;
@@ -237,10 +248,7 @@ struct fastd_config {
unsigned key_refresh_splay;
const fastd_cipher_t **ciphers;
-
-#ifdef USE_CRYPTO_GHASH
- const fastd_crypto_ghash_t *crypto_ghash;
-#endif
+ const fastd_mac_t **macs;
fastd_peer_group_config_t *peer_group;
fastd_peer_config_t *peers;
@@ -316,10 +324,7 @@ struct fastd_context {
fastd_stats_t tx_error;
fastd_cipher_context_t **cipher_contexts;
-
-#ifdef USE_CRYPTO_GHASH
- fastd_crypto_ghash_context_t *crypto_ghash;
-#endif
+ fastd_mac_context_t **mac_contexts;
size_t eth_addr_size;
size_t n_eth_addr;
@@ -359,7 +364,6 @@ void fastd_logf(const fastd_context_t *ctx, fastd_loglevel_t level, const char *
void fastd_add_peer_dir(fastd_context_t *ctx, fastd_config_t *conf, const char *dir);
bool fastd_read_config(fastd_context_t *ctx, fastd_config_t *conf, const char *filename, bool peer_config, int depth);
-bool fastd_cipher_available(const char *name);
const fastd_method_t* fastd_method_get_by_name(const char *name);
const fastd_cipher_t** fastd_cipher_config_alloc(void);
@@ -368,11 +372,20 @@ bool fastd_cipher_config(const fastd_cipher_t **cipher_conf, const char *name, c
void fastd_cipher_init(fastd_context_t *ctx);
void fastd_cipher_free(fastd_context_t *ctx);
+bool fastd_cipher_available(const char *name);
const fastd_cipher_t* fastd_cipher_get_by_name(fastd_context_t *ctx, const char *name, fastd_cipher_context_t **cctx);
+const fastd_mac_t** fastd_mac_config_alloc(void);
+void fastd_mac_config_free(const fastd_mac_t **mac_conf);
+bool fastd_mac_config(const fastd_mac_t **mac_conf, const char *name, const char *impl);
+
+void fastd_mac_init(fastd_context_t *ctx);
+void fastd_mac_free(fastd_context_t *ctx);
+bool fastd_mac_available(const char *name);
+const fastd_mac_t* fastd_mac_get_by_name(fastd_context_t *ctx, const char *name, fastd_mac_context_t **cctx);
+
bool fastd_config_protocol(fastd_context_t *ctx, fastd_config_t *conf, const char *name);
bool fastd_config_method(fastd_context_t *ctx, fastd_config_t *conf, const char *name);
-bool fastd_config_crypto(fastd_context_t *ctx, fastd_config_t *conf, const char *alg, const char *impl);
bool fastd_config_add_log_file(fastd_context_t *ctx, fastd_config_t *conf, const char *name, fastd_loglevel_t level);
bool fastd_config_bind_address(fastd_context_t *ctx, fastd_config_t *conf, const fastd_peer_address_t *address, const char *bindtodev, bool default_v4, bool default_v6);
void fastd_config_peer_group_push(fastd_context_t *ctx, fastd_config_t *conf, const char *name);
@@ -546,4 +559,13 @@ static inline void secure_memzero(void *s, size_t n) {
asm volatile("" : : "m"(s));
}
+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];
+ x->qw[1] = a->qw[1] ^ b->qw[1];
+}
+
+static inline void xor_a(fastd_block128_t *x, const fastd_block128_t *a) {
+ xor(x, x, a);
+}
+
#endif /* _FASTD_FASTD_H_ */
diff --git a/src/methods/generic_gcm/generic_gcm.c b/src/methods/generic_gcm/generic_gcm.c
index 479ea83..ba8729a 100644
--- a/src/methods/generic_gcm/generic_gcm.c
+++ b/src/methods/generic_gcm/generic_gcm.c
@@ -25,7 +25,6 @@
#include "../../fastd.h"
-#include "../../crypto.h"
#include "../common.h"
@@ -36,11 +35,16 @@ struct fastd_method_session_state {
fastd_cipher_context_t *cipher_ctx;
fastd_cipher_state_t *cipher_state;
- fastd_crypto_ghash_state_t *cstate_ghash;
+ const fastd_mac_t *ghash;
+ fastd_mac_context_t *ghash_ctx;
+ fastd_mac_state_t *ghash_state;
};
static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_cipher_t **cipher, fastd_cipher_context_t **cctx) {
+ if (!fastd_mac_available("ghash"))
+ return false;
+
size_t len = strlen(name);
if (len < 4)
@@ -108,7 +112,11 @@ static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, c
session->cipher->crypt(ctx, session->cipher_state, &H, &zeroblock, sizeof(fastd_block128_t), &zeroblock);
- session->cstate_ghash = ctx->conf->crypto_ghash->set_h(ctx, ctx->crypto_ghash, &H);
+ session->ghash = fastd_mac_get_by_name(ctx, "ghash", &session->ghash_ctx);
+ if (!session->ghash)
+ exit_bug(ctx, "generic-gcm: can't instanciate ghash mac");
+
+ session->ghash_state = session->ghash->init_state(ctx, session->ghash_ctx, H.b);
return session;
}
@@ -139,7 +147,7 @@ static void method_session_superseded(fastd_context_t *ctx, fastd_method_session
static void method_session_free(fastd_context_t *ctx, fastd_method_session_state_t *session) {
if (session) {
session->cipher->free_state(ctx, session->cipher_state);
- ctx->conf->crypto_ghash->free_state(ctx, session->cstate_ghash);
+ session->ghash->free_state(ctx, session->ghash_state);
secure_memzero(session, sizeof(fastd_method_session_state_t));
free(session);
@@ -184,7 +192,7 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast
put_size(&outblocks[n_blocks], in.len-sizeof(fastd_block128_t));
- ok = ctx->conf->crypto_ghash->hash(ctx, session->cstate_ghash, &sig, outblocks+1, n_blocks);
+ ok = session->ghash->hash(ctx, session->ghash_state, &sig, outblocks+1, n_blocks);
}
if (!ok) {
@@ -240,7 +248,7 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
put_size(&inblocks[n_blocks], in.len-sizeof(fastd_block128_t));
- ok = ctx->conf->crypto_ghash->hash(ctx, session->cstate_ghash, &sig, inblocks+1, n_blocks);
+ ok = session->ghash->hash(ctx, session->ghash_state, &sig, inblocks+1, n_blocks);
}
if (!ok || memcmp(&sig, &outblocks[0], sizeof(fastd_block128_t)) != 0) {
diff --git a/src/types.h b/src/types.h
index 894b2af..352bf7c 100644
--- a/src/types.h
+++ b/src/types.h
@@ -115,6 +115,7 @@ typedef struct fastd_context fastd_context_t;
typedef struct fastd_protocol fastd_protocol_t;
typedef struct fastd_method fastd_method_t;
typedef struct fastd_cipher fastd_cipher_t;
+typedef struct fastd_mac fastd_mac_t;
typedef struct fastd_handshake fastd_handshake_t;
@@ -123,10 +124,6 @@ typedef struct fastd_string_stack fastd_string_stack_t;
typedef struct fastd_resolve_return fastd_resolve_return_t;
-#ifdef USE_CRYPTO_GHASH
-typedef struct fastd_crypto_ghash fastd_crypto_ghash_t;
-#endif
-
typedef union fastd_block128 {
uint8_t b[16];
@@ -145,9 +142,7 @@ typedef struct fastd_method_session_state fastd_method_session_state_t;
typedef struct fastd_cipher_context fastd_cipher_context_t;
typedef struct fastd_cipher_state fastd_cipher_state_t;
-#ifdef USE_CRYPTO_GHASH
-typedef struct fastd_crypto_ghash_context fastd_crypto_ghash_context_t;
-typedef struct fastd_crypto_ghash_state fastd_crypto_ghash_state_t;
-#endif
+typedef struct fastd_mac_context fastd_mac_context_t;
+typedef struct fastd_mac_state fastd_mac_state_t;
#endif /* _FASTD_TYPES_H_ */