summaryrefslogtreecommitdiffstats
path: root/src/methods
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2013-11-30 03:19:38 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2013-11-30 03:36:22 +0100
commit8088a82a2a91d29967cef920ba780eecdf72518e (patch)
treed30768bff5805e1209d64e9c0e7e87c38cce0042 /src/methods
parent1111dc8e5e9e78254c1a7a891d961713e1be9db0 (diff)
downloadfastd-8088a82a2a91d29967cef920ba780eecdf72518e.tar
fastd-8088a82a2a91d29967cef920ba780eecdf72518e.zip
Perform string-based lookup of method-related information only once
Diffstat (limited to 'src/methods')
-rw-r--r--src/methods/cipher_test/cipher_test.c80
-rw-r--r--src/methods/composed_gmac/composed_gmac.c138
-rw-r--r--src/methods/generic_gcm/generic_gcm.c102
-rw-r--r--src/methods/generic_gmac/generic_gmac.c99
-rw-r--r--src/methods/generic_poly1305/generic_poly1305.c77
-rw-r--r--src/methods/methods.c.in12
-rw-r--r--src/methods/null/null.c21
-rw-r--r--src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c20
8 files changed, 255 insertions, 294 deletions
diff --git a/src/methods/cipher_test/cipher_test.c b/src/methods/cipher_test/cipher_test.c
index 067835e..fcf58e6 100644
--- a/src/methods/cipher_test/cipher_test.c
+++ b/src/methods/cipher_test/cipher_test.c
@@ -25,21 +25,27 @@
#include "../../crypto.h"
+#include "../../method.h"
#include "../common.h"
+struct fastd_method_context {
+ const fastd_cipher_info_t *cipher_info;
+};
+
struct fastd_method_session_state {
fastd_method_common_t common;
- const fastd_cipher_info_t *cipher_info;
+ const fastd_method_context_t *ctx;
const fastd_cipher_t *cipher;
fastd_cipher_state_t *cipher_state;
};
-static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_cipher_info_t **info, const fastd_cipher_t **cipher) {
- size_t len = strlen(name);
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx) {
+ fastd_method_context_t ctx;
+ size_t len = strlen(name);
if (len < 12)
return false;
@@ -50,46 +56,30 @@ static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_ciphe
memcpy(cipher_name, name, len-12);
cipher_name[len-12] = 0;
- const fastd_cipher_info_t *cipher_info = NULL;
-
- if (ctx) {
- *cipher = fastd_cipher_get_by_name(ctx, cipher_name, &cipher_info);
- if (!*cipher)
- return false;
- }
- else {
- cipher_info = fastd_cipher_info_get_by_name(cipher_name);
- if (!cipher_info)
- return false;
- }
+ ctx.cipher_info = fastd_cipher_info_get_by_name(cipher_name);
+ if (!ctx.cipher_info)
+ return false;
- if (info)
- *info = cipher_info;
+ *method_ctx = malloc(sizeof(fastd_method_context_t));
+ **method_ctx = ctx;
return true;
}
-
-static bool method_provides(const char *name) {
- return cipher_get(NULL, name, NULL, NULL);
+static void method_destroy(fastd_method_context_t *method_ctx) {
+ free(method_ctx);
}
-static size_t method_key_length(fastd_context_t *ctx, const char *name) {
- const fastd_cipher_info_t *info;
- if (!cipher_get(NULL, name, &info, NULL))
- exit_bug(ctx, "cipher-test: can't get cipher key length");
-
- return info->key_length;
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx) {
+ return method_ctx->cipher_info->key_length;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const char *name, const uint8_t *secret, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
fastd_method_common_init(ctx, &session->common, initiator);
-
- if (!cipher_get(ctx, name, &session->cipher_info, &session->cipher))
- exit_bug(ctx, "cipher-test: can't instanciate cipher");
-
+ session->ctx = method_ctx;
+ session->cipher = fastd_cipher_get(ctx, session->ctx->cipher_info);
session->cipher_state = session->cipher->init(ctx, secret);
pr_warn(ctx, "using cipher-test method; this method must be used for testing and benchmarks only");
@@ -127,11 +117,12 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast
if (tail_len)
memset(in.data+in.len, 0, tail_len);
- uint8_t nonce[session->cipher_info->iv_length];
- if (session->cipher_info->iv_length) {
- memset(nonce, 0, session->cipher_info->iv_length);
- memcpy(nonce, session->common.send_nonce, min_size_t(COMMON_NONCEBYTES, session->cipher_info->iv_length));
- nonce[session->cipher_info->iv_length-1] = 1;
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ if (iv_length) {
+ memset(nonce, 0, iv_length);
+ memcpy(nonce, session->common.send_nonce, min_size_t(COMMON_NONCEBYTES, iv_length));
+ nonce[iv_length-1] = 1;
}
int n_blocks = block_count(in.len, sizeof(fastd_block128_t));
@@ -170,11 +161,12 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
if (common_nonce[COMMON_NONCEBYTES]) /* flags */
return false;
- uint8_t nonce[session->cipher_info->iv_length];
- if (session->cipher_info->iv_length) {
- memset(nonce, 0, session->cipher_info->iv_length);
- memcpy(nonce, common_nonce, min_size_t(COMMON_NONCEBYTES, session->cipher_info->iv_length));
- nonce[session->cipher_info->iv_length-1] = 1;
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ if (iv_length) {
+ memset(nonce, 0, iv_length);
+ memcpy(nonce, common_nonce, min_size_t(COMMON_NONCEBYTES, iv_length));
+ nonce[iv_length-1] = 1;
}
int64_t age;
@@ -209,15 +201,17 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
}
const fastd_method_t fastd_method_cipher_test = {
- .provides = method_provides,
-
.max_overhead = COMMON_HEADBYTES,
.min_encrypt_head_space = 0,
.min_decrypt_head_space = 0,
.min_encrypt_tail_space = sizeof(fastd_block128_t)-1,
.min_decrypt_tail_space = sizeof(fastd_block128_t)-1,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
.session_is_valid = method_session_is_valid,
.session_is_initiator = method_session_is_initiator,
diff --git a/src/methods/composed_gmac/composed_gmac.c b/src/methods/composed_gmac/composed_gmac.c
index 0705b7d..d1627ee 100644
--- a/src/methods/composed_gmac/composed_gmac.c
+++ b/src/methods/composed_gmac/composed_gmac.c
@@ -25,36 +25,43 @@
#include "../../crypto.h"
+#include "../../method.h"
#include "../common.h"
static const fastd_block128_t ZERO_BLOCK = {};
+
+struct fastd_method_context {
+ const fastd_cipher_info_t *cipher_info;
+ const fastd_cipher_info_t *gmac_cipher_info;
+ const fastd_mac_info_t *ghash_info;
+};
+
struct fastd_method_session_state {
fastd_method_common_t common;
- const fastd_cipher_info_t *cipher_info;
+ const fastd_method_context_t *ctx;
+
const fastd_cipher_t *cipher;
fastd_cipher_state_t *cipher_state;
- const fastd_cipher_info_t *gmac_cipher_info;
const fastd_cipher_t *gmac_cipher;
fastd_cipher_state_t *gmac_cipher_state;
- const fastd_mac_info_t *ghash_info;
const fastd_mac_t *ghash;
fastd_mac_state_t *ghash_state;
};
-static bool cipher_get(fastd_context_t *ctx, const char *name,
- const fastd_cipher_info_t **cipher_info, const fastd_cipher_t **cipher,
- const fastd_cipher_info_t **gmac_cipher_info, const fastd_cipher_t **gmac_cipher) {
- if (!fastd_mac_info_get_by_name("ghash"))
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx) {
+ fastd_method_context_t ctx;
+
+ ctx.ghash_info = fastd_mac_info_get_by_name("ghash");
+ if (!ctx.ghash_info)
return false;
size_t len = strlen(name);
-
if (len < 5)
return false;
@@ -73,76 +80,52 @@ static bool cipher_get(fastd_context_t *ctx, const char *name,
*gmac_cipher_name = 0;
gmac_cipher_name++;
- const fastd_cipher_info_t *info = NULL;
- const fastd_cipher_info_t *gmac_info = NULL;
-
- if (ctx) {
- *cipher = fastd_cipher_get_by_name(ctx, cipher_name, &info);
- *gmac_cipher = fastd_cipher_get_by_name(ctx, gmac_cipher_name, &gmac_info);
- if (!(*cipher && *gmac_cipher))
- return false;
- }
- else {
- info = fastd_cipher_info_get_by_name(cipher_name);
- gmac_info = fastd_cipher_info_get_by_name(gmac_cipher_name);
- if (!(info && gmac_info))
- return false;
- }
-
- if (cipher_info)
- *cipher_info = info;
-
- if (gmac_cipher_info)
- *gmac_cipher_info = gmac_info;
-
- return true;
-}
-
+ ctx.cipher_info = fastd_cipher_info_get_by_name(cipher_name);
+ if (!ctx.cipher_info)
+ return false;
-static bool method_provides(const char *name) {
- const fastd_cipher_info_t *gmac_cipher_info;
+ if (ctx.cipher_info->iv_length && ctx.cipher_info->iv_length <= COMMON_NONCEBYTES)
+ return false;
- if (!cipher_get(NULL, name, NULL, NULL, &gmac_cipher_info, NULL))
+ ctx.gmac_cipher_info = fastd_cipher_info_get_by_name(gmac_cipher_name);
+ if (!ctx.gmac_cipher_info)
return false;
- if (gmac_cipher_info->iv_length <= COMMON_NONCEBYTES)
+ if (ctx.gmac_cipher_info->iv_length <= COMMON_NONCEBYTES)
return false;
+ *method_ctx = malloc(sizeof(fastd_method_context_t));
+ **method_ctx = ctx;
+
return true;
}
-static size_t method_key_length(fastd_context_t *ctx, const char *name) {
- const fastd_cipher_info_t *cipher_info;
- const fastd_cipher_info_t *gmac_cipher_info;
+static void method_destroy(fastd_method_context_t *method_ctx) {
+ free(method_ctx);
+}
- if (!cipher_get(NULL, name, &cipher_info, NULL, &gmac_cipher_info, NULL))
- exit_bug(ctx, "composed-gmac: can't get cipher key length");
- return cipher_info->key_length + gmac_cipher_info->key_length;
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx) {
+ return method_ctx->cipher_info->key_length + method_ctx->gmac_cipher_info->key_length;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const char *name, const uint8_t *secret, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
fastd_method_common_init(ctx, &session->common, initiator);
+ session->ctx = method_ctx;
- if (!cipher_get(ctx, name,
- &session->cipher_info, &session->cipher,
- &session->gmac_cipher_info, &session->gmac_cipher))
- exit_bug(ctx, "composed-gmac: can't instanciate cipher");
-
+ session->cipher = fastd_cipher_get(ctx, session->ctx->cipher_info);
session->cipher_state = session->cipher->init(ctx, secret);
- if (session->cipher_info->iv_length && session->cipher_info->iv_length <= COMMON_NONCEBYTES)
- exit_bug(ctx, "composed-gmac: iv_length to small");
- session->gmac_cipher_state = session->gmac_cipher->init(ctx, secret + session->cipher_info->key_length);
- if (session->gmac_cipher_info->iv_length <= COMMON_NONCEBYTES)
- exit_bug(ctx, "composed-gmac: GMAC cipher iv_length to small");
+ session->gmac_cipher = fastd_cipher_get(ctx, session->ctx->gmac_cipher_info);
+ session->gmac_cipher_state = session->gmac_cipher->init(ctx, secret + session->ctx->cipher_info->key_length);
fastd_block128_t H;
- uint8_t zeroiv[session->gmac_cipher_info->iv_length];
- memset(zeroiv, 0, session->gmac_cipher_info->iv_length);
+ size_t gmac_iv_length = session->ctx->gmac_cipher_info->iv_length;
+ uint8_t zeroiv[gmac_iv_length];
+ memset(zeroiv, 0, gmac_iv_length);
if (!session->gmac_cipher->crypt(ctx, session->gmac_cipher_state, &H, &ZERO_BLOCK, sizeof(fastd_block128_t), zeroiv)) {
session->cipher->free(ctx, session->cipher_state);
@@ -152,10 +135,7 @@ static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, c
return NULL;
}
- session->ghash = fastd_mac_get_by_name(ctx, "ghash", &session->ghash_info);
- if (!session->ghash)
- exit_bug(ctx, "composed-gmac: can't instanciate ghash mac");
-
+ session->ghash = fastd_mac_get(ctx, session->ctx->ghash_info);
session->ghash_state = session->ghash->init(ctx, H.b);
return session;
@@ -209,19 +189,21 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast
fastd_block128_t *outblocks = out->data;
fastd_block128_t sig;
- uint8_t gmac_nonce[session->gmac_cipher_info->iv_length];
- memset(gmac_nonce, 0, session->gmac_cipher_info->iv_length);
+ size_t gmac_iv_length = session->ctx->gmac_cipher_info->iv_length;
+ uint8_t gmac_nonce[gmac_iv_length];
+ memset(gmac_nonce, 0, gmac_iv_length);
memcpy(gmac_nonce, session->common.send_nonce, COMMON_NONCEBYTES);
- gmac_nonce[session->gmac_cipher_info->iv_length-1] = 1;
+ gmac_nonce[gmac_iv_length-1] = 1;
bool ok = session->gmac_cipher->crypt(ctx, session->gmac_cipher_state, outblocks, &ZERO_BLOCK, sizeof(fastd_block128_t), gmac_nonce);
if (ok) {
- uint8_t nonce[session->cipher_info->iv_length];
- if (session->cipher_info->iv_length) {
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ if (iv_length) {
+ memset(nonce, 0, iv_length);
memcpy(nonce, session->common.send_nonce, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
}
ok = session->cipher->crypt(ctx, session->cipher_state, outblocks+1, inblocks, n_blocks*sizeof(fastd_block128_t), nonce);
@@ -271,16 +253,18 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
if (!fastd_method_is_nonce_valid(ctx, &session->common, common_nonce, &age))
return false;
- uint8_t gmac_nonce[session->gmac_cipher_info->iv_length];
- memset(gmac_nonce, 0, session->gmac_cipher_info->iv_length);
+ size_t gmac_iv_length = session->ctx->gmac_cipher_info->iv_length;
+ uint8_t gmac_nonce[gmac_iv_length];
+ memset(gmac_nonce, 0, gmac_iv_length);
memcpy(gmac_nonce, common_nonce, COMMON_NONCEBYTES);
- gmac_nonce[session->gmac_cipher_info->iv_length-1] = 1;
+ gmac_nonce[gmac_iv_length-1] = 1;
- uint8_t nonce[session->cipher_info->iv_length];
- if (session->cipher_info->iv_length) {
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ if (iv_length) {
+ memset(nonce, 0, iv_length);
memcpy(nonce, common_nonce, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
}
fastd_buffer_push_head(ctx, &in, COMMON_HEADBYTES);
@@ -326,15 +310,17 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
}
const fastd_method_t fastd_method_composed_gmac = {
- .provides = method_provides,
-
.max_overhead = COMMON_HEADBYTES + sizeof(fastd_block128_t),
.min_encrypt_head_space = 0,
.min_decrypt_head_space = 0,
.min_encrypt_tail_space = sizeof(fastd_block128_t)-1,
.min_decrypt_tail_space = 2*sizeof(fastd_block128_t)-1,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
.session_is_valid = method_session_is_valid,
.session_is_initiator = method_session_is_initiator,
diff --git a/src/methods/generic_gcm/generic_gcm.c b/src/methods/generic_gcm/generic_gcm.c
index 52065eb..3490f8b 100644
--- a/src/methods/generic_gcm/generic_gcm.c
+++ b/src/methods/generic_gcm/generic_gcm.c
@@ -25,91 +25,82 @@
#include "../../crypto.h"
+#include "../../method.h"
#include "../common.h"
+struct fastd_method_context {
+ const fastd_cipher_info_t *cipher_info;
+ const fastd_mac_info_t *ghash_info;
+};
+
struct fastd_method_session_state {
fastd_method_common_t common;
- const fastd_cipher_info_t *cipher_info;
+ const fastd_method_context_t *ctx;
+
const fastd_cipher_t *cipher;
fastd_cipher_state_t *cipher_state;
- const fastd_mac_info_t *ghash_info;
const fastd_mac_t *ghash;
fastd_mac_state_t *ghash_state;
};
-static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_cipher_info_t **cipher_info, const fastd_cipher_t **cipher) {
- if (!fastd_mac_info_get_by_name("ghash"))
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx) {
+ fastd_method_context_t ctx;
+
+ ctx.ghash_info = fastd_mac_info_get_by_name("ghash");
+ if (!ctx.ghash_info)
return false;
size_t len = strlen(name);
-
if (len < 4)
return false;
if (strcmp(name+len-4, "-gcm"))
return false;
- char name_ctr[len+1];
- memcpy(name_ctr, name, len-3);
- strncpy(name_ctr+len-3, "ctr", 4);
+ char cipher_name[len+1];
+ memcpy(cipher_name, name, len-3);
+ strncpy(cipher_name+len-3, "ctr", 4);
- const fastd_cipher_info_t *info = NULL;
-
- if (ctx) {
- *cipher = fastd_cipher_get_by_name(ctx, name_ctr, &info);
- if (!*cipher)
- return false;
- }
- else {
- info = fastd_cipher_info_get_by_name(name_ctr);
- if (!info)
- return false;
- }
+ ctx.cipher_info = fastd_cipher_info_get_by_name(cipher_name);
+ if (!ctx.cipher_info)
+ return false;
- if (info->iv_length <= COMMON_NONCEBYTES)
+ if (ctx.cipher_info->iv_length <= COMMON_NONCEBYTES)
return false;
- if (cipher_info)
- *cipher_info = info;
+ *method_ctx = malloc(sizeof(fastd_method_context_t));
+ **method_ctx = ctx;
return true;
}
-
-static bool method_provides(const char *name) {
- return cipher_get(NULL, name, NULL, NULL);
+static void method_destroy(fastd_method_context_t *method_ctx) {
+ free(method_ctx);
}
-static size_t method_key_length(fastd_context_t *ctx, const char *name) {
- const fastd_cipher_info_t *cipher_info;
- if (!cipher_get(NULL, name, &cipher_info, NULL))
- exit_bug(ctx, "generic-gcm: can't get cipher key length");
-
- return cipher_info->key_length;
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx) {
+ return method_ctx->cipher_info->key_length;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const char *name, const uint8_t *secret, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
fastd_method_common_init(ctx, &session->common, initiator);
+ session->ctx = method_ctx;
- if (!cipher_get(ctx, name, &session->cipher_info, &session->cipher))
- exit_bug(ctx, "generic-gcm: can't instanciate cipher");
-
+ session->cipher = fastd_cipher_get(ctx, session->ctx->cipher_info);
session->cipher_state = session->cipher->init(ctx, secret);
static const fastd_block128_t zeroblock = {};
fastd_block128_t H;
- if (session->cipher_info->iv_length <= COMMON_NONCEBYTES)
- exit_bug(ctx, "generic-gcm: iv_length to small");
-
- uint8_t zeroiv[session->cipher_info->iv_length];
- memset(zeroiv, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t zeroiv[iv_length];
+ memset(zeroiv, 0, iv_length);
if (!session->cipher->crypt(ctx, session->cipher_state, &H, &zeroblock, sizeof(fastd_block128_t), zeroiv)) {
session->cipher->free(ctx, session->cipher_state);
@@ -117,20 +108,17 @@ static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, c
return NULL;
}
- session->ghash = fastd_mac_get_by_name(ctx, "ghash", &session->ghash_info);
- if (!session->ghash)
- exit_bug(ctx, "generic-gcm: can't instanciate ghash mac");
-
+ session->ghash = fastd_mac_get(ctx, session->ctx->ghash_info);
session->ghash_state = session->ghash->init(ctx, H.b);
return session;
}
-static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const char *name, const uint8_t *secret, size_t length, bool initiator) {
+static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, size_t length, bool initiator) {
if (length < sizeof(fastd_block128_t))
exit_bug(ctx, "generic-gcm: tried to init with short secret");
- return method_session_init(ctx, name, secret, initiator);
+ return method_session_init(ctx, method_ctx, secret, initiator);
}
static bool method_session_is_valid(fastd_context_t *ctx, fastd_method_session_state_t *session) {
@@ -177,10 +165,11 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast
if (tail_len)
memset(in.data+in.len, 0, tail_len);
- uint8_t nonce[session->cipher_info->iv_length];
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ memset(nonce, 0, iv_length);
memcpy(nonce, session->common.send_nonce, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
int n_blocks = block_count(in.len, sizeof(fastd_block128_t));
@@ -230,10 +219,11 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
if (((const uint8_t*)in.data)[COMMON_NONCEBYTES]) /* flags */
return false;
- uint8_t nonce[session->cipher_info->iv_length];
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ memset(nonce, 0, iv_length);
memcpy(nonce, in.data, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
int64_t age;
if (!fastd_method_is_nonce_valid(ctx, &session->common, nonce, &age))
@@ -279,15 +269,17 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
}
const fastd_method_t fastd_method_generic_gcm = {
- .provides = method_provides,
-
.max_overhead = COMMON_HEADBYTES + sizeof(fastd_block128_t),
.min_encrypt_head_space = sizeof(fastd_block128_t),
.min_decrypt_head_space = 0,
.min_encrypt_tail_space = sizeof(fastd_block128_t)-1,
.min_decrypt_tail_space = 2*sizeof(fastd_block128_t)-1,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
.session_init_compat = method_session_init_compat,
.session_is_valid = method_session_is_valid,
diff --git a/src/methods/generic_gmac/generic_gmac.c b/src/methods/generic_gmac/generic_gmac.c
index 4de7ad8..91b96cb 100644
--- a/src/methods/generic_gmac/generic_gmac.c
+++ b/src/methods/generic_gmac/generic_gmac.c
@@ -25,28 +25,37 @@
#include "../../crypto.h"
+#include "../../method.h"
#include "../common.h"
+struct fastd_method_context {
+ const fastd_cipher_info_t *cipher_info;
+ const fastd_mac_info_t *ghash_info;
+};
+
+
struct fastd_method_session_state {
fastd_method_common_t common;
- const fastd_cipher_info_t *cipher_info;
+ const fastd_method_context_t *ctx;
+
const fastd_cipher_t *cipher;
fastd_cipher_state_t *cipher_state;
- const fastd_mac_info_t *ghash_info;
const fastd_mac_t *ghash;
fastd_mac_state_t *ghash_state;
};
-static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_cipher_info_t **cipher_info, const fastd_cipher_t **cipher) {
- if (!fastd_mac_info_get_by_name("ghash"))
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx) {
+ fastd_method_context_t ctx;
+
+ ctx.ghash_info = fastd_mac_info_get_by_name("ghash");
+ if (!ctx.ghash_info)
return false;
size_t len = strlen(name);
-
if (len < 5)
return false;
@@ -60,70 +69,42 @@ static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_ciphe
memcpy(cipher_name, name, len-5);
cipher_name[len-5] = 0;
- const fastd_cipher_info_t *info = NULL;
-
- if (ctx) {
- *cipher = fastd_cipher_get_by_name(ctx, cipher_name, &info);
- if (!*cipher)
- return false;
- }
- else {
- info = fastd_cipher_info_get_by_name(cipher_name);
- if (!info)
- return false;
- }
+ ctx.cipher_info = fastd_cipher_info_get_by_name(cipher_name);
+ if (!ctx.cipher_info)
+ return false;
- if (info->iv_length <= COMMON_NONCEBYTES)
+ if (ctx.cipher_info->iv_length <= COMMON_NONCEBYTES)
return false;
- if (cipher_info)
- *cipher_info = info;
+ *method_ctx = malloc(sizeof(fastd_method_context_t));
+ **method_ctx = ctx;
return true;
}
-
-static bool method_provides(const char *name) {
- return cipher_get(NULL, name, NULL, NULL);
+static void method_destroy(fastd_method_context_t *method_ctx) {
+ free(method_ctx);
}
-static size_t method_key_length(fastd_context_t *ctx, const char *name) {
- const fastd_cipher_info_t *cipher_info;
- if (!cipher_get(NULL, name, &cipher_info, NULL))
- exit_bug(ctx, "generic-gmac: can't get cipher key length");
-
- return cipher_info->key_length + sizeof(fastd_block128_t);
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx) {
+ return method_ctx->cipher_info->key_length + method_ctx->ghash_info->key_length;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const char *name, const uint8_t *secret, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
fastd_method_common_init(ctx, &session->common, initiator);
+ session->ctx = method_ctx;
- if (!cipher_get(ctx, name, &session->cipher_info, &session->cipher))
- exit_bug(ctx, "generic-gmac: can't instanciate cipher");
-
+ session->cipher = fastd_cipher_get(ctx, session->ctx->cipher_info);
session->cipher_state = session->cipher->init(ctx, secret);
- if (session->cipher_info->iv_length <= COMMON_NONCEBYTES)
- exit_bug(ctx, "generic-gmac: iv_length to small");
-
- session->ghash = fastd_mac_get_by_name(ctx, "ghash", &session->ghash_info);
- if (!session->ghash)
- exit_bug(ctx, "generic-gmac: can't instanciate ghash mac");
-
- session->ghash_state = session->ghash->init(ctx, secret + session->cipher_info->key_length);
+ session->ghash = fastd_mac_get(ctx, session->ctx->ghash_info);
+ session->ghash_state = session->ghash->init(ctx, secret + session->ctx->cipher_info->key_length);
return session;
}
-static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const char *name, const uint8_t *secret, size_t length, bool initiator) {
- if (length < sizeof(fastd_block128_t))
- exit_bug(ctx, "generic-gmac: tried to init with short secret");
-
- return method_session_init(ctx, name, secret, initiator);
-}
-
static bool method_session_is_valid(fastd_context_t *ctx, fastd_method_session_state_t *session) {
return (session && fastd_method_session_common_is_valid(ctx, &session->common));
}
@@ -168,10 +149,11 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast
if (tail_len)
memset(in.data+in.len, 0, tail_len);
- uint8_t nonce[session->cipher_info->iv_length];
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ memset(nonce, 0, iv_length);
memcpy(nonce, session->common.send_nonce, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
int n_blocks = block_count(in.len, sizeof(fastd_block128_t));
@@ -221,10 +203,12 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
if (((const uint8_t*)in.data)[COMMON_NONCEBYTES]) /* flags */
return false;
- uint8_t nonce[session->cipher_info->iv_length];
- memset(nonce, 0, session->cipher_info->iv_length);
+
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ memset(nonce, 0, iv_length);
memcpy(nonce, in.data, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
int64_t age;
if (!fastd_method_is_nonce_valid(ctx, &session->common, nonce, &age))
@@ -270,17 +254,18 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
}
const fastd_method_t fastd_method_generic_gmac = {
- .provides = method_provides,
-
.max_overhead = COMMON_HEADBYTES + sizeof(fastd_block128_t),
.min_encrypt_head_space = sizeof(fastd_block128_t),
.min_decrypt_head_space = 0,
.min_encrypt_tail_space = sizeof(fastd_block128_t)-1,
.min_decrypt_tail_space = 2*sizeof(fastd_block128_t)-1,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
- .session_init_compat = method_session_init_compat,
.session_is_valid = method_session_is_valid,
.session_is_initiator = method_session_is_initiator,
.session_want_refresh = method_session_want_refresh,
diff --git a/src/methods/generic_poly1305/generic_poly1305.c b/src/methods/generic_poly1305/generic_poly1305.c
index c40e70f..f84046e 100644
--- a/src/methods/generic_poly1305/generic_poly1305.c
+++ b/src/methods/generic_poly1305/generic_poly1305.c
@@ -25,6 +25,7 @@
#include "../../crypto.h"
+#include "../../method.h"
#include "../common.h"
#include <crypto_onetimeauth_poly1305.h>
@@ -33,18 +34,23 @@
#define AUTHBLOCKS 2
+struct fastd_method_context {
+ const fastd_cipher_info_t *cipher_info;
+};
+
struct fastd_method_session_state {
fastd_method_common_t common;
- const fastd_cipher_info_t *cipher_info;
+ const fastd_method_context_t *ctx;
const fastd_cipher_t *cipher;
fastd_cipher_state_t *cipher_state;
};
-static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_cipher_info_t **cipher_info, const fastd_cipher_t **cipher) {
- size_t len = strlen(name);
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx) {
+ fastd_method_context_t ctx;
+ size_t len = strlen(name);
if (len < 9)
return false;
@@ -55,54 +61,35 @@ static bool cipher_get(fastd_context_t *ctx, const char *name, const fastd_ciphe
memcpy(cipher_name, name, len-9);
cipher_name[len-9] = 0;
- const fastd_cipher_info_t *info = NULL;
-
- if (ctx) {
- *cipher = fastd_cipher_get_by_name(ctx, cipher_name, &info);
- if (!*cipher)
- return false;
- }
- else {
- info = fastd_cipher_info_get_by_name(cipher_name);
- if (!info)
- return false;
- }
+ ctx.cipher_info = fastd_cipher_info_get_by_name(cipher_name);
+ if (!ctx.cipher_info)
+ return false;
- if (info->iv_length <= COMMON_NONCEBYTES)
+ if (ctx.cipher_info->iv_length <= COMMON_NONCEBYTES)
return false;
- if (cipher_info)
- *cipher_info = info;
+ *method_ctx = malloc(sizeof(fastd_method_context_t));
+ **method_ctx = ctx;
return true;
}
-
-static bool method_provides(const char *name) {
- return cipher_get(NULL, name, NULL, NULL);
+static void method_destroy(fastd_method_context_t *method_ctx) {
+ free(method_ctx);
}
-static size_t method_key_length(fastd_context_t *ctx, const char *name) {
- const fastd_cipher_info_t *cipher_info;
- if (!cipher_get(NULL, name, &cipher_info, NULL))
- exit_bug(ctx, "generic-poly1305: can't get cipher key length");
-
- return cipher_info->key_length;
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx) {
+ return method_ctx->cipher_info->key_length;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const char *name, const uint8_t *secret, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
fastd_method_common_init(ctx, &session->common, initiator);
-
- if (!cipher_get(ctx, name, &session->cipher_info, &session->cipher))
- exit_bug(ctx, "generic-poly1305: can't instanciate cipher");
-
+ session->ctx = method_ctx;
+ session->cipher = fastd_cipher_get(ctx, session->ctx->cipher_info);
session->cipher_state = session->cipher->init(ctx, secret);
- if (session->cipher_info->iv_length <= COMMON_NONCEBYTES)
- exit_bug(ctx, "generic-poly1305: iv_length to small");
-
return session;
}
@@ -139,10 +126,11 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast
if (tail_len)
memset(in.data+in.len, 0, tail_len);
- uint8_t nonce[session->cipher_info->iv_length];
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ memset(nonce, 0, iv_length);
memcpy(nonce, session->common.send_nonce, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
int n_blocks = block_count(in.len, sizeof(fastd_block128_t));
@@ -186,10 +174,11 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
if (((const uint8_t*)in.data)[COMMON_NONCEBYTES]) /* flags */
return false;
- uint8_t nonce[session->cipher_info->iv_length];
- memset(nonce, 0, session->cipher_info->iv_length);
+ size_t iv_length = session->ctx->cipher_info->iv_length;
+ uint8_t nonce[iv_length];
+ memset(nonce, 0, iv_length);
memcpy(nonce, in.data, COMMON_NONCEBYTES);
- nonce[session->cipher_info->iv_length-1] = 1;
+ nonce[iv_length-1] = 1;
int64_t age;
if (!fastd_method_is_nonce_valid(ctx, &session->common, nonce, &age))
@@ -245,15 +234,17 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
}
const fastd_method_t fastd_method_generic_poly1305 = {
- .provides = method_provides,
-
.max_overhead = COMMON_HEADBYTES + crypto_onetimeauth_poly1305_BYTES,
.min_encrypt_head_space = AUTHBLOCKS*sizeof(fastd_block128_t),
.min_decrypt_head_space = AUTHBLOCKS*sizeof(fastd_block128_t) - crypto_onetimeauth_poly1305_BYTES,
.min_encrypt_tail_space = sizeof(fastd_block128_t)-1,
.min_decrypt_tail_space = sizeof(fastd_block128_t)-1,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
.session_is_valid = method_session_is_valid,
.session_is_initiator = method_session_is_initiator,
diff --git a/src/methods/methods.c.in b/src/methods/methods.c.in
index 2a8d9fb..a2c7963 100644
--- a/src/methods/methods.c.in
+++ b/src/methods/methods.c.in
@@ -24,7 +24,7 @@
*/
-#include <src/fastd.h>
+#include <src/method.h>
@METHOD_DEFINITIONS@
@@ -33,12 +33,14 @@ static const fastd_method_t *const methods[] = { @METHOD_LIST@
};
-const fastd_method_t* fastd_method_get_by_name(const char *name) {
+bool fastd_method_create_by_name(const char *name, const fastd_method_t **method, fastd_method_context_t **method_ctx) {
size_t i;
for (i = 0; i < array_size(methods); i++) {
- if (methods[i]->provides(name))
- return methods[i];
+ if (methods[i]->create_by_name(name, method_ctx)) {
+ *method = methods[i];
+ return true;
+ }
}
- return NULL;
+ return false;
}
diff --git a/src/methods/null/null.c b/src/methods/null/null.c
index 3f23866..f4784c8 100644
--- a/src/methods/null/null.c
+++ b/src/methods/null/null.c
@@ -24,7 +24,7 @@
*/
-#include "../../fastd.h"
+#include "../../method.h"
struct fastd_method_session_state {
@@ -33,15 +33,18 @@ struct fastd_method_session_state {
};
-static bool method_provides(const char *name) {
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx UNUSED) {
return !strcmp(name, "null");
}
-static size_t method_key_length(fastd_context_t *ctx UNUSED, const char *name UNUSED) {
+static void method_destroy(fastd_method_context_t *method_ctx UNUSED) {
+}
+
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx UNUSED) {
return 0;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx UNUSED, const char *name UNUSED, const uint8_t *secret UNUSED, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx UNUSED, const uint8_t *secret UNUSED, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
session->valid = true;
@@ -50,8 +53,8 @@ static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx UN
return session;
}
-static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const char *name, const uint8_t *secret, size_t length UNUSED, bool initiator) {
- return method_session_init(ctx, name, secret, initiator);
+static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, size_t length UNUSED, bool initiator) {
+ return method_session_init(ctx, method_ctx, secret, initiator);
}
static bool method_session_is_valid(fastd_context_t *ctx UNUSED, fastd_method_session_state_t *session) {
@@ -80,15 +83,17 @@ static bool method_passthrough(fastd_context_t *ctx UNUSED, fastd_peer_t *peer U
}
const fastd_method_t fastd_method_null = {
- .provides = method_provides,
-
.max_overhead = 0,
.min_encrypt_head_space = 0,
.min_decrypt_head_space = 0,
.min_encrypt_tail_space = 0,
.min_decrypt_tail_space = 0,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
.session_init_compat = method_session_init_compat,
.session_is_valid = method_session_is_valid,
diff --git a/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c b/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c
index c6e22fb..88a0525 100644
--- a/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c
+++ b/src/methods/xsalsa20_poly1305/xsalsa20_poly1305.c
@@ -24,7 +24,7 @@
*/
-#include "../../fastd.h"
+#include "../../method.h"
#include "../common.h"
#include <crypto_secretbox_xsalsa20poly1305.h>
@@ -37,15 +37,18 @@ struct fastd_method_session_state {
};
-static bool method_provides(const char *name) {
+static bool method_create_by_name(const char *name, fastd_method_context_t **method_ctx UNUSED) {
return !strcmp(name, "xsalsa20-poly1305");
}
-static size_t method_key_length(fastd_context_t *ctx UNUSED, const char *name UNUSED) {
+static void method_destroy(fastd_method_context_t *method_ctx UNUSED) {
+}
+
+static size_t method_key_length(fastd_context_t *ctx UNUSED, const fastd_method_context_t *method_ctx UNUSED) {
return crypto_secretbox_xsalsa20poly1305_KEYBYTES;
}
-static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const char *name UNUSED, const uint8_t *secret, bool initiator) {
+static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, const fastd_method_context_t *method_ctx UNUSED, const uint8_t *secret, bool initiator) {
fastd_method_session_state_t *session = malloc(sizeof(fastd_method_session_state_t));
fastd_method_common_init(ctx, &session->common, initiator);
@@ -55,11 +58,11 @@ static fastd_method_session_state_t* method_session_init(fastd_context_t *ctx, c
return session;
}
-static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const char *name, const uint8_t *secret, size_t length, bool initiator) {
+static fastd_method_session_state_t* method_session_init_compat(fastd_context_t *ctx, const fastd_method_context_t *method_ctx, const uint8_t *secret, size_t length, bool initiator) {
if (length < crypto_secretbox_xsalsa20poly1305_KEYBYTES)
exit_bug(ctx, "xsalsa20-poly1305: tried to init with short secret");
- return method_session_init(ctx, name, secret, initiator);
+ return method_session_init(ctx, method_ctx, secret, initiator);
}
static bool method_session_is_valid(fastd_context_t *ctx, fastd_method_session_state_t *session) {
@@ -153,7 +156,6 @@ static bool method_decrypt(fastd_context_t *ctx, fastd_peer_t *peer, fastd_metho
}
const fastd_method_t fastd_method_xsalsa20_poly1305 = {
- .provides = method_provides,
.max_overhead = COMMON_HEADBYTES + crypto_secretbox_xsalsa20poly1305_ZEROBYTES - crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES,
.min_encrypt_head_space = crypto_secretbox_xsalsa20poly1305_ZEROBYTES,
@@ -161,7 +163,11 @@ const fastd_method_t fastd_method_xsalsa20_poly1305 = {
.min_encrypt_tail_space = 0,
.min_decrypt_tail_space = 0,
+ .create_by_name = method_create_by_name,
+ .destroy = method_destroy,
+
.key_length = method_key_length,
+
.session_init = method_session_init,
.session_init_compat = method_session_init_compat,
.session_is_valid = method_session_is_valid,