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 | |
parent | 1b5de7ce3bddedab12703c578b7c8fe90bea116e (diff) | |
download | strongswan-06eb35efb0e2d22bf8421965928c6e45aa19a0a3.tar.bz2 strongswan-06eb35efb0e2d22bf8421965928c6e45aa19a0a3.tar.xz |
Use the AF_ALG wrapper in hasher, crypter and signer
-rw-r--r-- | src/libstrongswan/plugins/af_alg/af_alg_crypter.c | 127 | ||||
-rw-r--r-- | src/libstrongswan/plugins/af_alg/af_alg_hasher.c | 93 | ||||
-rw-r--r-- | src/libstrongswan/plugins/af_alg/af_alg_signer.c | 97 |
3 files changed, 39 insertions, 278 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; } diff --git a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c index 46bbdb331..262771514 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c @@ -14,17 +14,7 @@ */ #include "af_alg_hasher.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 */ +#include "af_alg_ops.h" typedef struct private_af_alg_hasher_t private_af_alg_hasher_t; @@ -39,14 +29,9 @@ struct private_af_alg_hasher_t { af_alg_hasher_t public; /** - * Transform fd - */ - int tfm; - - /** - * Current operation fd, -1 if none + * AF_ALG operations */ - int op; + af_alg_ops_t *ops; /** * Size of the hash @@ -57,7 +42,7 @@ struct private_af_alg_hasher_t { /** * Get the kernel algorithm string and hash size for our identifier */ -static size_t lookup_alg(hash_algorithm_t algo, char *name) +static size_t lookup_alg(hash_algorithm_t algo, char **name) { static struct { hash_algorithm_t id; @@ -78,7 +63,7 @@ static size_t lookup_alg(hash_algorithm_t algo, char *name) { if (algs[i].id == algo) { - strcpy(name, algs[i].name); + *name = algs[i].name; return algs[i].size; } } @@ -94,50 +79,13 @@ METHOD(hasher_t, get_hash_size, size_t, METHOD(hasher_t, reset, void, private_af_alg_hasher_t *this) { - if (this->op != -1) - { - close(this->op); - this->op = -1; - } + this->ops->reset(this->ops); } METHOD(hasher_t, get_hash, void, private_af_alg_hasher_t *this, chunk_t chunk, u_int8_t *hash) { - ssize_t len; - - while (this->op == -1) - { - this->op = accept(this->tfm, NULL, 0); - if (this->op == -1) - { - DBG1(DBG_LIB, "opening AF_ALG hasher failed: %s", strerror(errno)); - sleep(1); - } - } - do - { - len = send(this->op, chunk.ptr, chunk.len, hash ? 0 : MSG_MORE); - if (len == -1) - { - DBG1(DBG_LIB, "writing to AF_ALG hasher failed: %s", strerror(errno)); - sleep(1); - } - else - { - chunk = chunk_skip(chunk, len); - } - } - while (chunk.len); - if (hash) - { - while (read(this->op, hash, this->size) != this->size) - { - DBG1(DBG_LIB, "reading AF_ALG hasher failed: %s", strerror(errno)); - sleep(1); - } - reset(this); - } + this->ops->hash(this->ops, chunk, hash, this->size); } METHOD(hasher_t, allocate_hash, void, @@ -157,11 +105,7 @@ METHOD(hasher_t, allocate_hash, void, METHOD(hasher_t, destroy, void, private_af_alg_hasher_t *this) { - if (this->op != -1) - { - close(this->op); - } - close(this->tfm); + this->ops->destroy(this->ops); free(this); } @@ -171,13 +115,10 @@ METHOD(hasher_t, destroy, void, af_alg_hasher_t *af_alg_hasher_create(hash_algorithm_t algo) { private_af_alg_hasher_t *this; - struct sockaddr_alg sa = { - .salg_family = AF_ALG, - .salg_type = "hash", - }; + char *name; size_t size; - size = lookup_alg(algo, sa.salg_name); + size = lookup_alg(algo, &name); if (!size) { /* not supported by kernel */ return NULL; @@ -193,23 +134,13 @@ af_alg_hasher_t *af_alg_hasher_create(hash_algorithm_t algo) .destroy = _destroy, }, }, - .tfm = socket(AF_ALG, SOCK_SEQPACKET, 0), - .op = -1, + .ops = af_alg_ops_create("hash", name), .size = size, ); - - 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; } diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c index 6b9e9d58a..7818db492 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c @@ -14,21 +14,7 @@ */ #include "af_alg_signer.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_signer_t private_af_alg_signer_t; @@ -43,14 +29,9 @@ struct private_af_alg_signer_t { af_alg_signer_t public; /** - * Transform fd + * AF_ALG operations */ - int tfm; - - /** - * Current operation fd, -1 if none - */ - int op; + af_alg_ops_t *ops; /** * Size of the truncated signature @@ -66,7 +47,7 @@ struct private_af_alg_signer_t { /** * Get the kernel algorithm string and block/key size for our identifier */ -static size_t lookup_alg(integrity_algorithm_t algo, char *name, +static size_t lookup_alg(integrity_algorithm_t algo, char **name, size_t *key_size) { static struct { @@ -95,7 +76,7 @@ static size_t lookup_alg(integrity_algorithm_t algo, char *name, { if (algs[i].id == algo) { - strcpy(name, algs[i].name); + *name = algs[i].name; *key_size = algs[i].key_size; return algs[i].block_size; } @@ -106,41 +87,7 @@ static size_t lookup_alg(integrity_algorithm_t algo, char *name, METHOD(signer_t, get_signature, void, private_af_alg_signer_t *this, chunk_t data, u_int8_t *buffer) { - ssize_t len; - - while (this->op == -1) - { - this->op = accept(this->tfm, NULL, 0); - if (this->op == -1) - { - DBG1(DBG_LIB, "opening AF_ALG signer failed: %s", strerror(errno)); - sleep(1); - } - } - do - { - len = send(this->op, data.ptr, data.len, buffer ? 0 : MSG_MORE); - if (len == -1) - { - DBG1(DBG_LIB, "writing to AF_ALG signer failed: %s", strerror(errno)); - sleep(1); - } - else - { - data = chunk_skip(data, len); - } - } - while (data.len); - if (buffer) - { - while (read(this->op, buffer, this->block_size) != this->block_size) - { - DBG1(DBG_LIB, "reading AF_ALG signer failed: %s", strerror(errno)); - sleep(1); - } - close(this->op); - this->op = -1; - } + this->ops->hash(this->ops, data, buffer, this->block_size); } METHOD(signer_t, allocate_signature, void, @@ -185,20 +132,13 @@ METHOD(signer_t, get_block_size, size_t, METHOD(signer_t, set_key, void, private_af_alg_signer_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 failed: %s", strerror(errno)); - } + this->ops->set_key(this->ops, key); } METHOD(signer_t, destroy, void, private_af_alg_signer_t *this) { - if (this->op != -1) - { - close(this->op); - } - close(this->tfm); + this->ops->destroy(this->ops); free(this); } @@ -208,13 +148,10 @@ METHOD(signer_t, destroy, void, af_alg_signer_t *af_alg_signer_create(integrity_algorithm_t algo) { private_af_alg_signer_t *this; - struct sockaddr_alg sa = { - .salg_family = AF_ALG, - .salg_type = "hash", - }; size_t block_size, key_size; + char *name; - block_size = lookup_alg(algo, sa.salg_name, &key_size); + block_size = lookup_alg(algo, &name, &key_size); if (!block_size) { /* not supported by kernel */ return NULL; @@ -232,24 +169,14 @@ af_alg_signer_t *af_alg_signer_create(integrity_algorithm_t algo) .destroy = _destroy, }, }, - .tfm = socket(AF_ALG, SOCK_SEQPACKET, 0), - .op = -1, + .ops = af_alg_ops_create("hash", name), .block_size = block_size, .key_size = key_size, ); - - 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; } |