mirror of
https://github.com/neocturne/fastd.git
synced 2025-05-14 20:25:08 +02:00
Make implementations used for AES128-CTR and GHASH configurable.
This commit is contained in:
parent
7305c53351
commit
ce1b13c5ea
6 changed files with 129 additions and 59 deletions
29
src/config.c
29
src/config.c
|
@ -37,6 +37,7 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <strings.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -85,6 +86,8 @@ static void default_config(fastd_config *conf) {
|
||||||
conf->secret = NULL;
|
conf->secret = NULL;
|
||||||
conf->key_valid = 3600; /* 60 minutes */
|
conf->key_valid = 3600; /* 60 minutes */
|
||||||
conf->key_refresh = 3300; /* 55 minutes */
|
conf->key_refresh = 3300; /* 55 minutes */
|
||||||
|
conf->alg_impl_aes128ctr = ALG_IMPL_DEFAULT;
|
||||||
|
conf->alg_impl_ghash = ALG_IMPL_DEFAULT;
|
||||||
|
|
||||||
conf->peer_dirs = NULL;
|
conf->peer_dirs = NULL;
|
||||||
conf->peers = NULL;
|
conf->peers = NULL;
|
||||||
|
@ -174,6 +177,32 @@ bool fastd_config_method(fastd_context *ctx, fastd_config *conf, const char *nam
|
||||||
exit_bug(ctx, "MAX_METHODS too low");
|
exit_bug(ctx, "MAX_METHODS too low");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fastd_config_algorithm(fastd_context *ctx, fastd_config *conf, const char *alg, const char *impl) {
|
||||||
|
if (!strcasecmp(alg, "aes128-ctr") || !strcasecmp(alg, "aes128") || !strcasecmp(alg, "aes-ctr") || !strcasecmp(alg, "aes")) {
|
||||||
|
if (!strcasecmp(impl, "default"))
|
||||||
|
conf->alg_impl_aes128ctr = ALG_IMPL_DEFAULT;
|
||||||
|
else if (!strcasecmp(impl, "algif"))
|
||||||
|
conf->alg_impl_aes128ctr = ALG_IMPL_ALGIF;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!strcasecmp(alg, "ghash")) {
|
||||||
|
if (!strcasecmp(impl, "default"))
|
||||||
|
conf->alg_impl_ghash = ALG_IMPL_DEFAULT;
|
||||||
|
else if (!strcasecmp(impl, "algif"))
|
||||||
|
conf->alg_impl_ghash = ALG_IMPL_ALGIF;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level) {
|
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level) {
|
||||||
char *name2 = strdup(name);
|
char *name2 = strdup(name);
|
||||||
char *name3 = strdup(name);
|
char *name3 = strdup(name);
|
||||||
|
|
|
@ -97,6 +97,8 @@ yes { TOKEN(TOK_YES); }
|
||||||
no { TOKEN(TOK_NO); }
|
no { TOKEN(TOK_NO); }
|
||||||
port { TOKEN(TOK_PORT); }
|
port { TOKEN(TOK_PORT); }
|
||||||
float { TOKEN(TOK_FLOAT); }
|
float { TOKEN(TOK_FLOAT); }
|
||||||
|
algorithm { TOKEN(TOK_ALGORITHM); }
|
||||||
|
use { TOKEN(TOK_USE); }
|
||||||
|
|
||||||
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
|
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
|
||||||
UPDATE_LOCATION;
|
UPDATE_LOCATION;
|
||||||
|
|
11
src/config.y
11
src/config.y
|
@ -95,6 +95,8 @@
|
||||||
%token TOK_NO
|
%token TOK_NO
|
||||||
%token TOK_PORT
|
%token TOK_PORT
|
||||||
%token TOK_FLOAT
|
%token TOK_FLOAT
|
||||||
|
%token TOK_ALGORITHM
|
||||||
|
%token TOK_USE
|
||||||
|
|
||||||
%token <addr> TOK_ADDR
|
%token <addr> TOK_ADDR
|
||||||
%token <addr6> TOK_ADDR6
|
%token <addr6> TOK_ADDR6
|
||||||
|
@ -136,6 +138,7 @@ statement: TOK_LOG log ';'
|
||||||
| TOK_MODE mode ';'
|
| TOK_MODE mode ';'
|
||||||
| TOK_PROTOCOL protocol ';'
|
| TOK_PROTOCOL protocol ';'
|
||||||
| TOK_METHOD method ';'
|
| TOK_METHOD method ';'
|
||||||
|
| TOK_ALGORITHM algorithm ';'
|
||||||
| TOK_SECRET secret ';'
|
| TOK_SECRET secret ';'
|
||||||
| TOK_ON TOK_UP on_up ';'
|
| TOK_ON TOK_UP on_up ';'
|
||||||
| TOK_ON TOK_DOWN on_down ';'
|
| TOK_ON TOK_DOWN on_down ';'
|
||||||
|
@ -226,6 +229,14 @@ method: TOK_STRING {
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
algorithm: TOK_STRING TOK_USE TOK_STRING {
|
||||||
|
if (!fastd_config_algorithm(ctx, conf, $1->str, $3->str)) {
|
||||||
|
fastd_config_error(&@$, ctx, conf, filename, depth, "invalid algorithm/implementation");
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); }
|
secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,8 @@ struct _fastd_config {
|
||||||
char *secret;
|
char *secret;
|
||||||
unsigned key_valid;
|
unsigned key_valid;
|
||||||
unsigned key_refresh;
|
unsigned key_refresh;
|
||||||
|
fastd_alg_impl alg_impl_aes128ctr;
|
||||||
|
fastd_alg_impl alg_impl_ghash;
|
||||||
|
|
||||||
fastd_string_stack *peer_dirs;
|
fastd_string_stack *peer_dirs;
|
||||||
fastd_peer_config *peers;
|
fastd_peer_config *peers;
|
||||||
|
@ -247,6 +249,7 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen
|
||||||
|
|
||||||
bool fastd_config_protocol(fastd_context *ctx, fastd_config *conf, const char *name);
|
bool fastd_config_protocol(fastd_context *ctx, fastd_config *conf, const char *name);
|
||||||
bool fastd_config_method(fastd_context *ctx, fastd_config *conf, const char *name);
|
bool fastd_config_method(fastd_context *ctx, fastd_config *conf, const char *name);
|
||||||
|
bool fastd_config_algorithm(fastd_context *ctx, fastd_config *conf, const char *alg, const char *impl);
|
||||||
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level);
|
bool fastd_config_add_log_file(fastd_context *ctx, fastd_config *conf, const char *name, int level);
|
||||||
void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]);
|
void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]);
|
||||||
void fastd_reconfigure(fastd_context *ctx, fastd_config *conf);
|
void fastd_reconfigure(fastd_context *ctx, fastd_config *conf);
|
||||||
|
|
139
src/linux_alg.c
139
src/linux_alg.c
|
@ -36,38 +36,60 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void fastd_linux_alg_init(fastd_context *ctx) {
|
static int init_aesctr(fastd_context *ctx) {
|
||||||
ctx->algfd_ghash = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||||
if (ctx->algfd_ghash < 0)
|
if (fd < 0)
|
||||||
goto ghash_done;
|
goto error;
|
||||||
|
|
||||||
|
struct sockaddr_alg sa = {};
|
||||||
|
sa.salg_family = AF_ALG;
|
||||||
|
strcpy((char*)sa.salg_type, "skcipher");
|
||||||
|
strcpy((char*)sa.salg_name, "ctr(aes)");
|
||||||
|
if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
pr_info(ctx, "no kernel support for AES-CTR was found, falling back to userspace implementation");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init_ghash(fastd_context *ctx) {
|
||||||
|
int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
struct sockaddr_alg sa = {};
|
struct sockaddr_alg sa = {};
|
||||||
sa.salg_family = AF_ALG;
|
sa.salg_family = AF_ALG;
|
||||||
strcpy((char*)sa.salg_type, "hash");
|
strcpy((char*)sa.salg_type, "hash");
|
||||||
strcpy((char*)sa.salg_name, "ghash");
|
strcpy((char*)sa.salg_name, "ghash");
|
||||||
if (bind(ctx->algfd_ghash, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
|
if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0)
|
||||||
close(ctx->algfd_ghash);
|
goto error;
|
||||||
ctx->algfd_ghash = -1;
|
|
||||||
}
|
return fd;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
|
||||||
ghash_done:
|
|
||||||
if (ctx->algfd_ghash < 0)
|
|
||||||
pr_info(ctx, "no kernel support for GHASH was found, falling back to userspace implementation");
|
pr_info(ctx, "no kernel support for GHASH was found, falling back to userspace implementation");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->algfd_aesctr = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
void fastd_linux_alg_init(fastd_context *ctx) {
|
||||||
if (ctx->algfd_aesctr < 0)
|
if (ctx->conf->alg_impl_aes128ctr == ALG_IMPL_ALGIF)
|
||||||
goto aesctr_done;
|
ctx->algfd_aesctr = init_aesctr(ctx);
|
||||||
|
else
|
||||||
strcpy((char*)sa.salg_type, "skcipher");
|
|
||||||
strcpy((char*)sa.salg_name, "ctr(aes)");
|
|
||||||
if (bind(ctx->algfd_aesctr, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
|
|
||||||
close(ctx->algfd_aesctr);
|
|
||||||
ctx->algfd_aesctr = -1;
|
ctx->algfd_aesctr = -1;
|
||||||
}
|
|
||||||
|
|
||||||
aesctr_done:
|
if (ctx->conf->alg_impl_ghash == ALG_IMPL_ALGIF)
|
||||||
if (ctx->algfd_aesctr < 0)
|
ctx->algfd_ghash = init_ghash(ctx);
|
||||||
pr_info(ctx, "no kernel support for AES-CTR was found, falling back to userspace implementation");
|
else
|
||||||
|
ctx->algfd_ghash = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fastd_linux_alg_close(fastd_context *ctx) {
|
void fastd_linux_alg_close(fastd_context *ctx) {
|
||||||
|
@ -78,43 +100,6 @@ void fastd_linux_alg_close(fastd_context *ctx) {
|
||||||
close(ctx->algfd_aesctr);
|
close(ctx->algfd_aesctr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int fastd_linux_alg_ghash_init(fastd_context *ctx, uint8_t key[16]) {
|
|
||||||
if (ctx->algfd_ghash < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (setsockopt(ctx->algfd_ghash, SOL_ALG, ALG_SET_KEY, key, 16) < 0) {
|
|
||||||
pr_error_errno(ctx, "fastd_linux_alg_ghash_init: setsockopt");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = accept(ctx->algfd_ghash, NULL, NULL);
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_error_errno(ctx, "fastd_linux_alg_ghash_init: accept");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fastd_linux_alg_ghash(fastd_context *ctx, int fd, uint8_t out[16], const void *data, size_t len) {
|
|
||||||
if (!len)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (write(fd, data, len) < 0) {
|
|
||||||
pr_error_errno(ctx, "fastd_linux_alg_ghash: write");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read(fd, out, 16) < 16) {
|
|
||||||
pr_error_errno(ctx, "fastd_linux_alg_ghash: read");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fastd_linux_alg_aesctr_init(fastd_context *ctx, uint8_t *key, size_t keylen) {
|
int fastd_linux_alg_aesctr_init(fastd_context *ctx, uint8_t *key, size_t keylen) {
|
||||||
if (ctx->algfd_aesctr < 0)
|
if (ctx->algfd_aesctr < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -173,3 +158,39 @@ bool fastd_linux_alg_aesctr(fastd_context *ctx, int fd, void *out, const void *i
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fastd_linux_alg_ghash_init(fastd_context *ctx, uint8_t key[16]) {
|
||||||
|
if (ctx->algfd_ghash < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (setsockopt(ctx->algfd_ghash, SOL_ALG, ALG_SET_KEY, key, 16) < 0) {
|
||||||
|
pr_error_errno(ctx, "fastd_linux_alg_ghash_init: setsockopt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = accept(ctx->algfd_ghash, NULL, NULL);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_error_errno(ctx, "fastd_linux_alg_ghash_init: accept");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fastd_linux_alg_ghash(fastd_context *ctx, int fd, uint8_t out[16], const void *data, size_t len) {
|
||||||
|
if (!len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, data, len) < 0) {
|
||||||
|
pr_error_errno(ctx, "fastd_linux_alg_ghash: write");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read(fd, out, 16) < 16) {
|
||||||
|
pr_error_errno(ctx, "fastd_linux_alg_ghash: read");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,10 @@ typedef enum _fastd_mode {
|
||||||
MODE_TUN,
|
MODE_TUN,
|
||||||
} fastd_mode;
|
} fastd_mode;
|
||||||
|
|
||||||
|
typedef enum _fastd_alg_impl {
|
||||||
|
ALG_IMPL_DEFAULT,
|
||||||
|
ALG_IMPL_ALGIF,
|
||||||
|
} fastd_alg_impl;
|
||||||
|
|
||||||
typedef struct _fastd_buffer fastd_buffer;
|
typedef struct _fastd_buffer fastd_buffer;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue