diff options
Diffstat (limited to 'src/linux_alg.c')
-rw-r--r-- | src/linux_alg.c | 137 |
1 files changed, 79 insertions, 58 deletions
diff --git a/src/linux_alg.c b/src/linux_alg.c index 9591ce8..ab08cab 100644 --- a/src/linux_alg.c +++ b/src/linux_alg.c @@ -36,83 +36,68 @@ #endif -void fastd_linux_alg_init(fastd_context *ctx) { - ctx->algfd_ghash = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (ctx->algfd_ghash < 0) - goto ghash_done; +static int init_aesctr(fastd_context *ctx) { + int fd = socket(AF_ALG, SOCK_SEQPACKET, 0); + if (fd < 0) + goto error; struct sockaddr_alg sa = {}; sa.salg_family = AF_ALG; - strcpy((char*)sa.salg_type, "hash"); - strcpy((char*)sa.salg_name, "ghash"); - if (bind(ctx->algfd_ghash, (struct sockaddr*)&sa, sizeof(sa)) < 0) { - close(ctx->algfd_ghash); - ctx->algfd_ghash = -1; - } - - ghash_done: - if (ctx->algfd_ghash < 0) - pr_info(ctx, "no kernel support for GHASH was found, falling back to userspace implementation"); - - ctx->algfd_aesctr = socket(AF_ALG, SOCK_SEQPACKET, 0); - if (ctx->algfd_aesctr < 0) - goto aesctr_done; - 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; - } + if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) + goto error; - aesctr_done: - if (ctx->algfd_aesctr < 0) - pr_info(ctx, "no kernel support for AES-CTR was found, falling back to userspace implementation"); -} + return fd; -void fastd_linux_alg_close(fastd_context *ctx) { - if (ctx->algfd_ghash >= 0) - close(ctx->algfd_ghash); + error: + if (fd >= 0) + close(fd); - if (ctx->algfd_aesctr >= 0) - close(ctx->algfd_aesctr); + 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; -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; - } + struct sockaddr_alg sa = {}; + sa.salg_family = AF_ALG; + strcpy((char*)sa.salg_type, "hash"); + strcpy((char*)sa.salg_name, "ghash"); + if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) + goto error; - int ret = accept(ctx->algfd_ghash, NULL, NULL); + return fd; - if (ret < 0) { - pr_error_errno(ctx, "fastd_linux_alg_ghash_init: accept"); - return -1; - } + error: + if (fd >= 0) + close(fd); - return ret; + pr_info(ctx, "no kernel support for GHASH was found, falling back to userspace implementation"); + return -1; } -bool fastd_linux_alg_ghash(fastd_context *ctx, int fd, uint8_t out[16], const void *data, size_t len) { - if (!len) - return false; +void fastd_linux_alg_init(fastd_context *ctx) { + if (ctx->conf->alg_impl_aes128ctr == ALG_IMPL_ALGIF) + ctx->algfd_aesctr = init_aesctr(ctx); + else + ctx->algfd_aesctr = -1; - if (write(fd, data, len) < 0) { - pr_error_errno(ctx, "fastd_linux_alg_ghash: write"); - return false; - } + if (ctx->conf->alg_impl_ghash == ALG_IMPL_ALGIF) + ctx->algfd_ghash = init_ghash(ctx); + else + ctx->algfd_ghash = -1; +} - if (read(fd, out, 16) < 16) { - pr_error_errno(ctx, "fastd_linux_alg_ghash: read"); - return false; - } +void fastd_linux_alg_close(fastd_context *ctx) { + if (ctx->algfd_ghash >= 0) + close(ctx->algfd_ghash); - return true; + if (ctx->algfd_aesctr >= 0) + close(ctx->algfd_aesctr); } int fastd_linux_alg_aesctr_init(fastd_context *ctx, uint8_t *key, size_t keylen) { @@ -173,3 +158,39 @@ bool fastd_linux_alg_aesctr(fastd_context *ctx, int fd, void *out, const void *i 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; +} |