gcrypt crypter implementation

This commit is contained in:
Martin Willi
2009-06-09 11:18:56 +02:00
parent f908ff9f91
commit 80862c4637
4 changed files with 321 additions and 0 deletions
@@ -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
@@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <gcrypt.h>
#include <debug.h>
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;
}
@@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <crypto/crypters/crypter.h>
/**
* 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_ @}*/
@@ -16,6 +16,7 @@
#include "gcrypt_plugin.h"
#include "gcrypt_hasher.h"
#include "gcrypt_crypter.h"
#include <library.h>
#include <debug.h>
@@ -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;
}