diff options
Diffstat (limited to 'src/libstrongswan/plugins/hmac')
-rw-r--r-- | src/libstrongswan/plugins/hmac/Makefile.am | 11 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac.c | 214 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac.h | 93 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac_plugin.c | 84 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac_plugin.h | 47 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac_prf.c | 137 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac_prf.h | 51 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac_signer.c | 199 | ||||
-rw-r--r-- | src/libstrongswan/plugins/hmac/hmac_signer.h | 55 |
9 files changed, 891 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/hmac/Makefile.am b/src/libstrongswan/plugins/hmac/Makefile.am new file mode 100644 index 000000000..89e0638f3 --- /dev/null +++ b/src/libstrongswan/plugins/hmac/Makefile.am @@ -0,0 +1,11 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-hmac.la + +libstrongswan_hmac_la_SOURCES = hmac_plugin.h hmac_plugin.c hmac.h hmac.c \ + hmac_prf.h hmac_prf.c hmac_signer.h hmac_signer.c +libstrongswan_hmac_la_LDFLAGS = -module + diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c new file mode 100644 index 000000000..2b41bf4aa --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac.c @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General hmac 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 hmac License + * for more details. + * + * $Id$ + */ + +#include <string.h> + +#include "hmac.h" + + +typedef struct private_hmac_t private_hmac_t; + +/** + * Private data of a hmac_t object. + * + * The variable names are the same as in the RFC. + */ +struct private_hmac_t { + /** + * Public hmac_t interface. + */ + hmac_t hmac; + + /** + * Block size, as in RFC. + */ + u_int8_t b; + + /** + * Hash function. + */ + hasher_t *h; + + /** + * Previously xor'ed key using opad. + */ + chunk_t opaded_key; + + /** + * Previously xor'ed key using ipad. + */ + chunk_t ipaded_key; +}; + +/** + * Implementation of hmac_t.get_mac. + */ +static void get_mac(private_hmac_t *this, chunk_t data, u_int8_t *out) +{ + /* H(K XOR opad, H(K XOR ipad, text)) + * + * if out is NULL, we append text to the inner hash. + * else, we complete the inner and do the outer. + * + */ + + u_int8_t buffer[this->h->get_hash_size(this->h)]; + chunk_t inner; + + if (out == NULL) + { + /* append data to inner */ + this->h->get_hash(this->h, data, NULL); + } + else + { + /* append and do outer hash */ + inner.ptr = buffer; + inner.len = this->h->get_hash_size(this->h); + + /* complete inner */ + this->h->get_hash(this->h, data, buffer); + + /* do outer */ + this->h->get_hash(this->h, this->opaded_key, NULL); + this->h->get_hash(this->h, inner, out); + + /* reinit for next call */ + this->h->get_hash(this->h, this->ipaded_key, NULL); + } +} + +/** + * Implementation of hmac_t.allocate_mac. + */ +static void allocate_mac(private_hmac_t *this, chunk_t data, chunk_t *out) +{ + /* allocate space and use get_mac */ + if (out == NULL) + { + /* append mode */ + this->hmac.get_mac(&(this->hmac), data, NULL); + } + else + { + out->len = this->h->get_hash_size(this->h); + out->ptr = malloc(out->len); + this->hmac.get_mac(&(this->hmac), data, out->ptr); + } +} + +/** + * Implementation of hmac_t.get_block_size. + */ +static size_t get_block_size(private_hmac_t *this) +{ + return this->h->get_hash_size(this->h); +} + +/** + * Implementation of hmac_t.set_key. + */ +static void set_key(private_hmac_t *this, chunk_t key) +{ + int i; + u_int8_t buffer[this->b]; + + memset(buffer, 0, this->b); + + if (key.len > this->b) + { + /* if key is too long, it will be hashed */ + this->h->get_hash(this->h, key, buffer); + } + else + { + /* if not, just copy it in our pre-padded k */ + memcpy(buffer, key.ptr, key.len); + } + + /* apply ipad and opad to key */ + for (i = 0; i < this->b; i++) + { + this->ipaded_key.ptr[i] = buffer[i] ^ 0x36; + this->opaded_key.ptr[i] = buffer[i] ^ 0x5C; + } + + /* begin hashing of inner pad */ + this->h->reset(this->h); + this->h->get_hash(this->h, this->ipaded_key, NULL); +} + +/** + * Implementation of hmac_t.destroy. + */ +static void destroy(private_hmac_t *this) +{ + this->h->destroy(this->h); + free(this->opaded_key.ptr); + free(this->ipaded_key.ptr); + free(this); +} + +/* + * Described in header + */ +hmac_t *hmac_create(hash_algorithm_t hash_algorithm) +{ + private_hmac_t *this = malloc_thing(private_hmac_t); + + /* set hmac_t methods */ + this->hmac.get_mac = (void (*)(hmac_t *,chunk_t,u_int8_t*))get_mac; + this->hmac.allocate_mac = (void (*)(hmac_t *,chunk_t,chunk_t*))allocate_mac; + this->hmac.get_block_size = (size_t (*)(hmac_t *))get_block_size; + this->hmac.set_key = (void (*)(hmac_t *,chunk_t))set_key; + this->hmac.destroy = (void (*)(hmac_t *))destroy; + + /* set b, according to hasher */ + switch (hash_algorithm) + { + case HASH_SHA1: + case HASH_MD5: + case HASH_SHA256: + this->b = 64; + break; + case HASH_SHA384: + case HASH_SHA512: + this->b = 128; + break; + default: + free(this); + return NULL; + } + + /* build the hasher */ + this->h = lib->crypto->create_hasher(lib->crypto, hash_algorithm); + if (this->h == NULL) + { + free(this); + return NULL; + } + + /* build ipad and opad */ + this->opaded_key.ptr = malloc(this->b); + this->opaded_key.len = this->b; + + this->ipaded_key.ptr = malloc(this->b); + this->ipaded_key.len = this->b; + + return &(this->hmac); +} diff --git a/src/libstrongswan/plugins/hmac/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h new file mode 100644 index 000000000..5f266e133 --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005 Jan Hutter + * 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 hmac hmac + * @{ @ingroup hmac_p + */ + +#ifndef HMAC_H_ +#define HMAC_H_ + +typedef struct hmac_t hmac_t; + +#include <crypto/hashers/hasher.h> + +/** + * Message authentication using hash functions. + * + * This class implements the message authenticaion algorithm + * described in RFC2104. It uses a hash function, wich must + * be implemented as a hasher_t class. + */ +struct hmac_t { + /** + * Generate message authentication code. + * + * If buffer is NULL, no result is given back. A next call will + * append the data to already supplied data. If buffer is not NULL, + * the mac of all apended data is calculated, returned and the + * state of the hmac_t is reseted. + * + * @param data chunk of data to authenticate + * @param buffer pointer where the generated bytes will be written + */ + void (*get_mac) (hmac_t *this, chunk_t data, u_int8_t *buffer); + + /** + * Generates message authentication code and allocate space for them. + * + * If chunk is NULL, no result is given back. A next call will + * append the data to already supplied. If chunk is not NULL, + * the mac of all apended data is calculated, returned and the + * state of the hmac_t reset; + * + * @param data chunk of data to authenticate + * @param chunk chunk which will hold generated bytes + */ + void (*allocate_mac) (hmac_t *this, chunk_t data, chunk_t *chunk); + + /** + * Get the block size of this hmac_t object. + * + * @return block size in bytes + */ + size_t (*get_block_size) (hmac_t *this); + + /** + * Set the key for this hmac_t object. + * + * Any key length is accepted. + * + * @param key key to set + */ + void (*set_key) (hmac_t *this, chunk_t key); + + /** + * Destroys a hmac_t object. + */ + void (*destroy) (hmac_t *this); +}; + +/** + * Creates a new hmac_t object. + * + * @param hash_algorithm hash algorithm to use + * @return hmac_t object, NULL if not supported + */ +hmac_t *hmac_create(hash_algorithm_t hash_algorithm); + +#endif /*HMAC_H_ @}*/ diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c new file mode 100644 index 000000000..246fbb031 --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac_plugin.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008 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. + * + * $Id$ + */ + +#include "hmac_plugin.h" + +#include <library.h> +#include "hmac_signer.h" +#include "hmac_prf.h" + +typedef struct private_hmac_plugin_t private_hmac_plugin_t; + +/** + * private data of hmac_plugin + */ +struct private_hmac_plugin_t { + + /** + * public functions + */ + hmac_plugin_t public; +}; + +/** + * Implementation of hmac_plugin_t.hmactroy + */ +static void destroy(private_hmac_plugin_t *this) +{ + lib->crypto->remove_prf(lib->crypto, + (prf_constructor_t)hmac_prf_create); + lib->crypto->remove_signer(lib->crypto, + (signer_constructor_t)hmac_signer_create); + free(this); +} + +/* + * see header file + */ +plugin_t *plugin_create() +{ + private_hmac_plugin_t *this = malloc_thing(private_hmac_plugin_t); + + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + + lib->crypto->add_prf(lib->crypto, PRF_HMAC_MD5, + (prf_constructor_t)hmac_prf_create); + lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA1, + (prf_constructor_t)hmac_prf_create); + lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_256, + (prf_constructor_t)hmac_prf_create); + lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_384, + (prf_constructor_t)hmac_prf_create); + lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_512, + (prf_constructor_t)hmac_prf_create); + + lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96, + (signer_constructor_t)hmac_signer_create); + lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_96, + (signer_constructor_t)hmac_signer_create); + lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_128, + (signer_constructor_t)hmac_signer_create); + lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_128, + (signer_constructor_t)hmac_signer_create); + lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_192, + (signer_constructor_t)hmac_signer_create); + lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_512_256, + (signer_constructor_t)hmac_signer_create); + + return &this->public.plugin; +} + diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.h b/src/libstrongswan/plugins/hmac/hmac_plugin.h new file mode 100644 index 000000000..55ba0b5f4 --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac_plugin.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 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 hmac_p hmac + * @ingroup plugins + * + * @defgroup hmac_plugin hmac_plugin + * @{ @ingroup hmac_p + */ + +#ifndef HMAC_PLUGIN_H_ +#define HMAC_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct hmac_plugin_t hmac_plugin_t; + +/** + * Plugin implementing HMAC algorithm to prvoide hash based PRF and signers. + */ +struct hmac_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a hmac_plugin instance. + */ +plugin_t *plugin_create(); + +#endif /* HMAC_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.c b/src/libstrongswan/plugins/hmac/hmac_prf.c new file mode 100644 index 000000000..02159bb1b --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac_prf.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * 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. + * + * $Id$ + */ + +#include "hmac_prf.h" + +#include "hmac.h" + + +typedef struct private_hmac_prf_t private_hmac_prf_t; + +/** + * Private data of a hma_prf_t object. + */ +struct private_hmac_prf_t { + /** + * Public hmac_prf_t interface. + */ + hmac_prf_t public; + + /** + * Hmac to use for generation. + */ + hmac_t *hmac; +}; + +/** + * Implementation of prf_t.get_bytes. + */ +static void get_bytes(private_hmac_prf_t *this, chunk_t seed, u_int8_t *buffer) +{ + this->hmac->get_mac(this->hmac, seed, buffer); +} + +/** + * Implementation of prf_t.allocate_bytes. + */ +static void allocate_bytes(private_hmac_prf_t *this, chunk_t seed, chunk_t *chunk) +{ + this->hmac->allocate_mac(this->hmac, seed, chunk); +} + +/** + * Implementation of prf_t.get_block_size. + */ +static size_t get_block_size(private_hmac_prf_t *this) +{ + return this->hmac->get_block_size(this->hmac); +} + +/** + * Implementation of prf_t.get_block_size. + */ +static size_t get_key_size(private_hmac_prf_t *this) +{ + /* for HMAC prfs, IKEv2 uses block size as key size */ + return this->hmac->get_block_size(this->hmac); +} + +/** + * Implementation of prf_t.set_key. + */ +static void set_key(private_hmac_prf_t *this, chunk_t key) +{ + this->hmac->set_key(this->hmac, key); +} + +/** + * Implementation of prf_t.destroy. + */ +static void destroy(private_hmac_prf_t *this) +{ + this->hmac->destroy(this->hmac); + free(this); +} + +/* + * Described in header. + */ +hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo) +{ + private_hmac_prf_t *this; + hash_algorithm_t hash; + + switch (algo) + { + case PRF_HMAC_SHA1: + hash = HASH_SHA1; + break; + case PRF_HMAC_MD5: + hash = HASH_MD5; + break; + case PRF_HMAC_SHA2_256: + hash = HASH_SHA256; + break; + case PRF_HMAC_SHA2_384: + hash = HASH_SHA384; + break; + case PRF_HMAC_SHA2_512: + hash = HASH_SHA512; + break; + default: + return NULL; + } + + this = malloc_thing(private_hmac_prf_t); + this->hmac = hmac_create(hash); + if (this->hmac == NULL) + { + free(this); + return NULL; + } + + this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes; + this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes; + this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size; + this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size; + this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key; + this->public.prf_interface.destroy = (void (*) (prf_t *))destroy; + + return &(this->public); +} + diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.h b/src/libstrongswan/plugins/hmac/hmac_prf.h new file mode 100644 index 000000000..46d05f03a --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac_prf.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008 Martin Willi + * Copyright (C) 2005 Jan Hutter + * 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 hmac_prf hmac_prf + * @{ @ingroup hmac_p + */ + +#ifndef PRF_HMAC_H_ +#define PRF_HMAC_H_ + +typedef struct hmac_prf_t hmac_prf_t; + +#include <crypto/prfs/prf.h> + +/** + * Implementation of prf_t interface using the HMAC algorithm. + * + * This simply wraps a hmac_t in a prf_t. More a question of + * interface matching. + */ +struct hmac_prf_t { + + /** + * Generic prf_t interface for this hmac_prf_t class. + */ + prf_t prf_interface; +}; + +/** + * Creates a new hmac_prf_t object. + * + * @param algo algorithm to implement + * @return hmac_prf_t object, NULL if hash not supported + */ +hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo); + +#endif /*PRF_HMAC_SHA1_H_ @}*/ diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.c b/src/libstrongswan/plugins/hmac/hmac_signer.c new file mode 100644 index 000000000..1b6f80d7b --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac_signer.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005 Jan Hutter + * 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. + * + * $Id$ + */ + +#include <string.h> + +#include "hmac_signer.h" +#include "hmac.h" + +typedef struct private_hmac_signer_t private_hmac_signer_t; + +/** + * Private data structure with signing context. + */ +struct private_hmac_signer_t { + /** + * Public interface of hmac_signer_t. + */ + hmac_signer_t public; + + /** + * Assigned hmac function. + */ + hmac_t *hmac; + + /** + * Block size (truncation of HMAC Hash) + */ + size_t block_size; +}; + +/** + * Implementation of signer_t.get_signature. + */ +static void get_signature(private_hmac_signer_t *this, + chunk_t data, u_int8_t *buffer) +{ + if (buffer == NULL) + { /* append mode */ + this->hmac->get_mac(this->hmac, data, NULL); + } + else + { + u_int8_t mac[this->hmac->get_block_size(this->hmac)]; + + this->hmac->get_mac(this->hmac, data, mac); + memcpy(buffer, mac, this->block_size); + } +} + +/** + * Implementation of signer_t.allocate_signature. + */ +static void allocate_signature (private_hmac_signer_t *this, + chunk_t data, chunk_t *chunk) +{ + if (chunk == NULL) + { /* append mode */ + this->hmac->get_mac(this->hmac, data, NULL); + } + else + { + u_int8_t mac[this->hmac->get_block_size(this->hmac)]; + + this->hmac->get_mac(this->hmac, data, mac); + + chunk->ptr = malloc(this->block_size); + chunk->len = this->block_size; + + memcpy(chunk->ptr, mac, this->block_size); + } +} + +/** + * Implementation of signer_t.verify_signature. + */ +static bool verify_signature(private_hmac_signer_t *this, + chunk_t data, chunk_t signature) +{ + u_int8_t mac[this->hmac->get_block_size(this->hmac)]; + + this->hmac->get_mac(this->hmac, data, mac); + + if (signature.len != this->block_size) + { + return FALSE; + } + return memeq(signature.ptr, mac, this->block_size); +} + +/** + * Implementation of signer_t.get_key_size. + */ +static size_t get_key_size(private_hmac_signer_t *this) +{ + return this->hmac->get_block_size(this->hmac); +} + +/** + * Implementation of signer_t.get_block_size. + */ +static size_t get_block_size(private_hmac_signer_t *this) +{ + return this->block_size; +} + +/** + * Implementation of signer_t.set_key. + */ +static void set_key(private_hmac_signer_t *this, chunk_t key) +{ + this->hmac->set_key(this->hmac, key); +} + +/** + * Implementation of signer_t.destroy. + */ +static status_t destroy(private_hmac_signer_t *this) +{ + this->hmac->destroy(this->hmac); + free(this); + return SUCCESS; +} + +/* + * Described in header + */ +hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo) +{ + private_hmac_signer_t *this; + size_t trunc; + hash_algorithm_t hash; + + switch (algo) + { + case AUTH_HMAC_SHA1_96: + hash = HASH_SHA1; + trunc = 12; + break; + case AUTH_HMAC_SHA1_128: + hash = HASH_SHA1; + trunc = 16; + break; + case AUTH_HMAC_MD5_96: + hash = HASH_MD5; + trunc = 12; + break; + case AUTH_HMAC_SHA2_256_128: + hash = HASH_SHA256; + trunc = 16; + break; + case AUTH_HMAC_SHA2_384_192: + hash = HASH_SHA384; + trunc = 24; + break; + case AUTH_HMAC_SHA2_512_256: + hash = HASH_SHA512; + trunc = 32; + break; + default: + return NULL; + } + + this = malloc_thing(private_hmac_signer_t); + this->hmac = hmac_create(hash); + if (this->hmac == NULL) + { + free(this); + return NULL; + } + /* prevent invalid truncation */ + this->block_size = min(trunc, this->hmac->get_block_size(this->hmac)); + + /* interface functions */ + this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature; + this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature; + this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature; + this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size; + this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size; + this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key; + this->public.signer_interface.destroy = (void (*) (signer_t*))destroy; + + return &(this->public); +} + diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.h b/src/libstrongswan/plugins/hmac/hmac_signer.h new file mode 100644 index 000000000..969f482e7 --- /dev/null +++ b/src/libstrongswan/plugins/hmac/hmac_signer.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2005-2008 Martin Willi + * Copyright (C) 2005 Jan Hutter + * 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 hmac_signer hmac_signer + * @{ @ingroup hmac_p + */ + +#ifndef HMAC_SIGNER_H_ +#define HMAC_SIGNER_H_ + +typedef struct hmac_signer_t hmac_signer_t; + +#include <crypto/signers/signer.h> + +/** + * Implementation of signer_t interface using HMAC. + * + * HMAC uses a standard hash function implemented in a hasher_t to build a MAC. + */ +struct hmac_signer_t { + + /** + * generic signer_t interface for this signer + */ + signer_t signer_interface; +}; + +/** + * Creates a new hmac_signer_t. + * + * HMAC signatures are often truncated to shorten them to a more usable, but + * still secure enough length. + * Block size must be equal or smaller then the hash algorithms + * hash. + * + * @param algo algorithm to implement + * @return hmac_signer_t, NULL if not supported + */ +hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo); + +#endif /*HMAC_SIGNER_H_ @}*/ |