diff options
author | Martin Willi <martin@revosec.ch> | 2010-11-08 10:02:35 +0000 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-12-20 09:52:02 +0100 |
commit | 06eb35efb0e2d22bf8421965928c6e45aa19a0a3 (patch) | |
tree | 468a77193c6ed484e1b56405829f9b3caff936f1 /src/libstrongswan/plugins/af_alg/af_alg_crypter.c | |
parent | 1b5de7ce3bddedab12703c578b7c8fe90bea116e (diff) | |
download | strongswan-06eb35efb0e2d22bf8421965928c6e45aa19a0a3.tar.bz2 strongswan-06eb35efb0e2d22bf8421965928c6e45aa19a0a3.tar.xz |
Use the AF_ALG wrapper in hasher, crypter and signer
Diffstat (limited to 'src/libstrongswan/plugins/af_alg/af_alg_crypter.c')
-rw-r--r-- | src/libstrongswan/plugins/af_alg/af_alg_crypter.c | 127 |
1 files changed, 15 insertions, 112 deletions
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c index cfb359063..e7a46a7cf 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c @@ -14,21 +14,7 @@ */ #include "af_alg_crypter.h" - -#include <unistd.h> -#include <errno.h> -#include <linux/socket.h> -#include <linux/if_alg.h> - -#include <debug.h> - -#ifndef AF_ALG -#define AF_ALG 38 -#endif /* AF_ALG */ - -#ifndef SOL_ALG -#define SOL_ALG 279 -#endif /* SOL_ALG */ +#include "af_alg_ops.h" typedef struct private_af_alg_crypter_t private_af_alg_crypter_t; @@ -43,9 +29,9 @@ struct private_af_alg_crypter_t { af_alg_crypter_t public; /** - * Transform fd + * AF_ALG operations */ - int tfm; + af_alg_ops_t *ops; /** * Size of the truncated signature @@ -66,7 +52,7 @@ struct private_af_alg_crypter_t { /** * Get the kernel algorithm string and block/key size for our identifier */ -static size_t lookup_alg(encryption_algorithm_t algo, char *name, +static size_t lookup_alg(encryption_algorithm_t algo, char **name, size_t key_size, size_t *keymat_size, size_t *iv_size) { static struct { @@ -101,7 +87,7 @@ static size_t lookup_alg(encryption_algorithm_t algo, char *name, if (algs[i].id == algo && (key_size == 0 || algs[i].key_size == key_size)) { - strcpy(name, algs[i].name); + *name = algs[i].name; *keymat_size = algs[i].keymat_size; *iv_size = algs[i].iv_size; return algs[i].block_size; @@ -110,85 +96,17 @@ static size_t lookup_alg(encryption_algorithm_t algo, char *name, return 0; } -/** - * Do the en-/decryption operation - */ -static void crypt(private_af_alg_crypter_t *this, u_int32_t type, chunk_t iv, - chunk_t in, char *out) -{ - struct msghdr msg = {}; - struct cmsghdr *cmsg; - struct af_alg_iv *ivm; - struct iovec iov; - char buf[CMSG_SPACE(sizeof(type)) + - CMSG_SPACE(offsetof(struct af_alg_iv, iv) + iv.len)]; - ssize_t len; - int op; - - while ((op = accept(this->tfm, NULL, 0)) == -1) - { - DBG1(DBG_LIB, "accepting AF_ALG crypter failed: %s", strerror(errno)); - sleep(1); - } - - memset(buf, 0, sizeof(buf)); - - msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_OP; - cmsg->cmsg_len = CMSG_LEN(sizeof(type)); - *(u_int32_t*)CMSG_DATA(cmsg) = type; - - cmsg = CMSG_NXTHDR(&msg, cmsg); - cmsg->cmsg_level = SOL_ALG; - cmsg->cmsg_type = ALG_SET_IV; - cmsg->cmsg_len = CMSG_LEN(offsetof(struct af_alg_iv, iv) + iv.len); - ivm = (void*)CMSG_DATA(cmsg); - ivm->ivlen = iv.len; - memcpy(ivm->iv, iv.ptr, iv.len); - - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - while (in.len) - { - iov.iov_base = in.ptr; - iov.iov_len = in.len; - - len = sendmsg(op, &msg, 0); - if (len == -1) - { - DBG1(DBG_LIB, "writing to AF_ALG crypter failed: %s", - strerror(errno)); - sleep(1); - continue; - } - if (read(op, out, len) != len) - { - DBG1(DBG_LIB, "reading from AF_ALG crypter failed: %s", - strerror(errno)); - } - in = chunk_skip(in, len); - /* no IV for subsequent data chunks */ - msg.msg_controllen = 0; - } - close(op); -} - METHOD(crypter_t, decrypt, void, private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { if (dst) { *dst = chunk_alloc(data.len); - crypt(this, ALG_OP_DECRYPT, iv, data, dst->ptr); + this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, dst->ptr); } else { - crypt(this, ALG_OP_DECRYPT, iv, data, data.ptr); + this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, data.ptr); } } @@ -198,11 +116,11 @@ METHOD(crypter_t, encrypt, void, if (dst) { *dst = chunk_alloc(data.len); - crypt(this, ALG_OP_ENCRYPT, iv, data, dst->ptr); + this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, dst->ptr); } else { - crypt(this, ALG_OP_ENCRYPT, iv, data, data.ptr); + this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr); } } @@ -227,16 +145,13 @@ METHOD(crypter_t, get_key_size, size_t, METHOD(crypter_t, set_key, void, private_af_alg_crypter_t *this, chunk_t key) { - if (setsockopt(this->tfm, SOL_ALG, ALG_SET_KEY, key.ptr, key.len) == -1) - { - DBG1(DBG_LIB, "setting AF_ALG key %B failed: %s", &key, strerror(errno)); - } + this->ops->set_key(this->ops, key); } METHOD(crypter_t, destroy, void, private_af_alg_crypter_t *this) { - close(this->tfm); + this->ops->destroy(this->ops); free(this); } @@ -247,14 +162,10 @@ af_alg_crypter_t *af_alg_crypter_create(encryption_algorithm_t algo, size_t key_size) { private_af_alg_crypter_t *this; - struct sockaddr_alg sa = { - .salg_family = AF_ALG, - .salg_type = "skcipher", - }; size_t block_size, keymat_size, iv_size; + char *name; - block_size = lookup_alg(algo, sa.salg_name, key_size, - &keymat_size, &iv_size); + block_size = lookup_alg(algo, &name, key_size, &keymat_size, &iv_size); if (!block_size) { /* not supported by kernel */ return NULL; @@ -275,21 +186,13 @@ af_alg_crypter_t *af_alg_crypter_create(encryption_algorithm_t algo, .block_size = block_size, .keymat_size = keymat_size, .iv_size = iv_size, - .tfm = socket(AF_ALG, SOCK_SEQPACKET, 0), + .ops = af_alg_ops_create("skcipher", name), ); - if (this->tfm == -1) + if (!this->ops) { - DBG1(DBG_LIB, "opening AF_ALG socket failed: %s", strerror(errno)); free(this); return NULL; } - if (bind(this->tfm, (struct sockaddr*)&sa, sizeof(sa)) == -1) - { - DBG1(DBG_LIB, "binding AF_ALG socket for '%s' failed: %s", - sa.salg_name, strerror(errno)); - destroy(this); - return NULL; - } return &this->public; } |