From 80862c463719ac73bbb0e8bd17f5348d3f07dafb Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 4 Jun 2009 17:06:43 +0200 Subject: [PATCH] gcrypt crypter implementation --- src/libstrongswan/plugins/gcrypt/Makefile.am | 1 + src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c | 246 ++++++++++++++++++++++ src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h | 49 +++++ src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c | 25 +++ 4 files changed, 321 insertions(+) create mode 100644 src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c create mode 100644 src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.am b/src/libstrongswan/plugins/gcrypt/Makefile.am index 94edcc5..6f1f53c 100644 --- a/src/libstrongswan/plugins/gcrypt/Makefile.am +++ b/src/libstrongswan/plugins/gcrypt/Makefile.am @@ -6,6 +6,7 @@ AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-gcrypt.la libstrongswan_gcrypt_la_SOURCES = gcrypt_plugin.h gcrypt_plugin.c \ + gcrypt_crypter.h gcrypt_crypter.c \ gcrypt_hasher.h gcrypt_hasher.c libstrongswan_gcrypt_la_LDFLAGS = -module diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c new file mode 100644 index 0000000..4d68f1b --- /dev/null +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "gcrypt_crypter.h" + +#include + +#include + +typedef struct private_gcrypt_crypter_t private_gcrypt_crypter_t; + +/** + * Private data of gcrypt_crypter_t + */ +struct private_gcrypt_crypter_t { + + /** + * Public part of this class. + */ + gcrypt_crypter_t public; + + /** + * gcrypt cipher handle + */ + gcry_cipher_hd_t h; + + /** + * gcrypt algorithm identifier + */ + int alg; +}; + +/** + * Implementation of crypter_t.decrypt. + */ +static void decrypt(private_gcrypt_crypter_t *this, chunk_t data, + chunk_t iv, chunk_t *dst) +{ + gcry_cipher_setiv(this->h, iv.ptr, iv.len); + + if (dst) + { + *dst = chunk_alloc(data.len); + gcry_cipher_decrypt(this->h, dst->ptr, dst->len, data.ptr, data.len); + } + else + { + gcry_cipher_decrypt(this->h, data.ptr, data.len, NULL, 0); + } +} + +/** + * Implementation of crypter_t.encrypt. + */ +static void encrypt(private_gcrypt_crypter_t *this, chunk_t data, + chunk_t iv, chunk_t *dst) +{ + gcry_cipher_setiv(this->h, iv.ptr, iv.len); + + if (dst) + { + *dst = chunk_alloc(data.len); + gcry_cipher_encrypt(this->h, dst->ptr, dst->len, data.ptr, data.len); + } + else + { + gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0); + } +} + +/** + * Implementation of crypter_t.get_block_size. + */ +static size_t get_block_size(private_gcrypt_crypter_t *this) +{ + size_t len = 0; + + gcry_cipher_algo_info(this->alg, GCRYCTL_GET_BLKLEN, NULL, &len); + return len; +} + +/** + * Implementation of crypter_t.get_key_size. + */ +static size_t get_key_size(private_gcrypt_crypter_t *this) +{ + size_t len = 0; + + gcry_cipher_algo_info(this->alg, GCRYCTL_GET_KEYLEN, NULL, &len); + return len; +} + +/** + * Implementation of crypter_t.set_key. + */ +static void set_key(private_gcrypt_crypter_t *this, chunk_t key) +{ + gcry_cipher_setkey(this->h, key.ptr, key.len); +} + +/** + * Implementation of crypter_t.destroy. + */ +static void destroy (private_gcrypt_crypter_t *this) +{ + gcry_cipher_close(this->h); + free(this); +} + +/* + * Described in header + */ +gcrypt_crypter_t *gcrypt_crypter_create(encryption_algorithm_t algo, + size_t key_size) +{ + private_gcrypt_crypter_t *this; + int gcrypt_alg; + int mode = GCRY_CIPHER_MODE_CBC; + gcry_error_t err; + + switch (algo) + { + case ENCR_DES: + gcrypt_alg = GCRY_CIPHER_DES; + break; + case ENCR_DES_ECB: + gcrypt_alg = GCRY_CIPHER_DES; + mode = GCRY_CIPHER_MODE_ECB; + break; + case ENCR_3DES: + gcrypt_alg = GCRY_CIPHER_3DES; + break; + case ENCR_IDEA: + gcrypt_alg = GCRY_CIPHER_IDEA; + break; + case ENCR_CAST: + gcrypt_alg = GCRY_CIPHER_CAST5; + break; + case ENCR_BLOWFISH: + gcrypt_alg = GCRY_CIPHER_BLOWFISH; + break; + /* case ENCR_AES_CTR: + mode = GCRY_CIPHER_MODE_CTR; */ + /* fall */ + case ENCR_AES_CBC: + switch (key_size) + { + case 16: + gcrypt_alg = GCRY_CIPHER_AES128; + break; + case 24: + gcrypt_alg = GCRY_CIPHER_AES192; + break; + case 32: + gcrypt_alg = GCRY_CIPHER_AES256; + break; + default: + return NULL; + } + break; + /* case ENCR_CAMELLIA_CTR: + mode = GCRY_CIPHER_MODE_CTR; */ + /* fall */ + case ENCR_CAMELLIA_CBC: + switch (key_size) + { + case 16: + gcrypt_alg = GCRY_CIPHER_CAMELLIA128; + break; + case 24: + gcrypt_alg = GCRY_CIPHER_CAMELLIA192; + break; + case 32: + gcrypt_alg = GCRY_CIPHER_CAMELLIA256; + break; + default: + return NULL; + } + break; + case ENCR_SERPENT_CBC: + switch (key_size) + { + case 16: + gcrypt_alg = GCRY_CIPHER_SERPENT128; + break; + case 24: + gcrypt_alg = GCRY_CIPHER_SERPENT192; + break; + case 32: + gcrypt_alg = GCRY_CIPHER_SERPENT256; + break; + default: + return NULL; + } + break; + case ENCR_TWOFISH_CBC: + switch (key_size) + { + case 16: + gcrypt_alg = GCRY_CIPHER_TWOFISH128; + break; + case 32: + gcrypt_alg = GCRY_CIPHER_TWOFISH; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + + this = malloc_thing(private_gcrypt_crypter_t); + + this->alg = gcrypt_alg; + err = gcry_cipher_open(&this->h, gcrypt_alg, mode, 0); + if (err) + { + DBG1("grcy_cipher_open(%N) failed: %s", + encryption_algorithm_names, algo, gpg_strerror(err)); + free(this); + return NULL; + } + + this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *))encrypt; + this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *))decrypt; + this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *))get_block_size; + this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *))get_key_size; + this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t))set_key; + this->public.crypter_interface.destroy = (void (*) (crypter_t *))destroy; + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h new file mode 100644 index 0000000..c5a5e67 --- /dev/null +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup gcrypt_crypter gcrypt_crypter + * @{ @ingroup gcrypt_p + */ + +#ifndef GCRYPT_CRYPTER_H_ +#define GCRYPT_CRYPTER_H_ + +typedef struct gcrypt_crypter_t gcrypt_crypter_t; + +#include + +/** + * Implementation of crypters using gcrypt. + */ +struct gcrypt_crypter_t { + + /** + * The crypter_t interface. + */ + crypter_t crypter_interface; +}; + +/** + * Constructor to create gcrypt_crypter_t. + * + * @param algo algorithm to implement + * @param key_size key size in bytes + * @return gcrypt_crypter_t, NULL if not supported + */ +gcrypt_crypter_t *gcrypt_crypter_create(encryption_algorithm_t algo, + size_t key_size); + +#endif /** GCRYPT_CRYPTER_H_ @}*/ diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c index 062e890..5568de8 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c @@ -16,6 +16,7 @@ #include "gcrypt_plugin.h" #include "gcrypt_hasher.h" +#include "gcrypt_crypter.h" #include #include @@ -49,6 +50,8 @@ static void destroy(private_gcrypt_plugin_t *this) { lib->crypto->remove_hasher(lib->crypto, (hasher_constructor_t)gcrypt_hasher_create); + lib->crypto->remove_crypter(lib->crypto, + (crypter_constructor_t)gcrypt_crypter_create); free(this); } @@ -91,6 +94,28 @@ plugin_t *plugin_create() lib->crypto->add_hasher(lib->crypto, HASH_SHA512, (hasher_constructor_t)gcrypt_hasher_create); + /* crypters */ + lib->crypto->add_crypter(lib->crypto, ENCR_3DES, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_IDEA, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_CAST, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_DES, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_SERPENT_CBC, + (crypter_constructor_t)gcrypt_crypter_create); + lib->crypto->add_crypter(lib->crypto, ENCR_TWOFISH_CBC, + (crypter_constructor_t)gcrypt_crypter_create); + return &this->public.plugin; } -- 2.7.4