From: Tobias Brunner Date: Fri, 22 Jun 2012 07:39:09 +0000 (+0200) Subject: Simple wrappers for HMAC based prf_t and signer_t implementations added X-Git-Tag: 5.0.0~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57ff4be87477680d8b5be4acf6ec3009256a1513;p=thirdparty%2Fstrongswan.git Simple wrappers for HMAC based prf_t and signer_t implementations added --- diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index af11f11e28..80b55f207f 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -13,6 +13,9 @@ asn1/oid.c asn1/oid.h \ bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \ crypto/crypters/crypter.c crypto/crypters/crypter.h \ crypto/hashers/hasher.h crypto/hashers/hasher.c \ +crypto/hmacs/hmac.h \ +crypto/hmacs/hmac_prf.h crypto/hmacs/hmac_prf.c \ +crypto/hmacs/hmac_signer.h crypto/hmacs/hmac_signer.c \ crypto/pkcs7.c crypto/pkcs7.h \ crypto/pkcs9.c crypto/pkcs9.h \ crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords.h \ diff --git a/src/libstrongswan/crypto/hmacs/hmac.h b/src/libstrongswan/crypto/hmacs/hmac.h new file mode 100644 index 0000000000..dd71713cc3 --- /dev/null +++ b/src/libstrongswan/crypto/hmacs/hmac.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 . + * + * 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 crypto + */ + +#ifndef HMAC_H_ +#define HMAC_H_ + +typedef struct hmac_t hmac_t; + +#include + +/** + * Generic interface for message authentication using hash functions. + * + * Classes implementing this interface can use the PRF and signer wrappers. + */ +struct hmac_t { + + /** + * Generate message authentication code. + * + * If out is NULL, no result is given back. A next call will + * append the data to already supplied data. If out is not NULL, + * the mac of all apended data is calculated, written to out and the + * internal state is reset. + * + * @param data chunk of data to authenticate + * @param out pointer where the generated bytes will be written + */ + void (*get_mac)(hmac_t *this, chunk_t data, u_int8_t *out); + + /** + * Get the size of the resulting MAC (i.e. the output size of the + * underlying hash function). + * + * @return block size in bytes + */ + size_t (*get_mac_size)(hmac_t *this); + + /** + * Set the key to be used for the HMAC. + * + * Any key length must be 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); +}; + +#endif /** HMAC_H_ @}*/ diff --git a/src/libstrongswan/crypto/hmacs/hmac_prf.c b/src/libstrongswan/crypto/hmacs/hmac_prf.c new file mode 100644 index 0000000000..315f45e542 --- /dev/null +++ b/src/libstrongswan/crypto/hmacs/hmac_prf.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 . + * + * 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 "hmac_prf.h" + +typedef struct private_prf_t private_prf_t; + +/** + * Private data of a hmac_prf_t object. + */ +struct private_prf_t { + + /** + * Public interface + */ + prf_t public; + + /** + * HMAC to use + */ + hmac_t *hmac; +}; + +METHOD(prf_t, get_bytes, void, + private_prf_t *this, chunk_t seed, u_int8_t *buffer) +{ + this->hmac->get_mac(this->hmac, seed, buffer); +} + +METHOD(prf_t, allocate_bytes, void, + private_prf_t *this, chunk_t seed, chunk_t *chunk) +{ + if (!chunk) + { + this->hmac->get_mac(this->hmac, seed, NULL); + } + else + { + *chunk = chunk_alloc(this->hmac->get_mac_size(this->hmac)); + this->hmac->get_mac(this->hmac, seed, chunk->ptr); + } +} + +METHOD(prf_t, get_block_size, size_t, + private_prf_t *this) +{ + return this->hmac->get_mac_size(this->hmac); +} + +METHOD(prf_t, get_key_size, size_t, + private_prf_t *this) +{ + /* for HMAC PRFs, IKEv2 uses MAC size as key size */ + return this->hmac->get_mac_size(this->hmac); +} + +METHOD(prf_t, set_key, void, + private_prf_t *this, chunk_t key) +{ + this->hmac->set_key(this->hmac, key); +} + +METHOD(prf_t, destroy, void, + private_prf_t *this) +{ + this->hmac->destroy(this->hmac); + free(this); +} + +/* + * Described in header. + */ +prf_t *hmac_prf_create(hmac_t *hmac) +{ + private_prf_t *this; + + INIT(this, + .public = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .get_block_size = _get_block_size, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + .hmac = hmac, + ); + + return &this->public; +} diff --git a/src/libstrongswan/crypto/hmacs/hmac_prf.h b/src/libstrongswan/crypto/hmacs/hmac_prf.h new file mode 100644 index 0000000000..742cf70ba6 --- /dev/null +++ b/src/libstrongswan/crypto/hmacs/hmac_prf.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 hmac_prf hmac_prf + * @{ @ingroup hmac + */ + +#ifndef HMAC_PRF_H_ +#define HMAC_PRF_H_ + +#include +#include + +/** + * Creates an implementation of the prf_t interface using the provided hmac_t + * implementation. Basically a simple wrapper to map the interface. + * + * @param hmac hmac_t implementation + * @return prf_t object + */ +prf_t *hmac_prf_create(hmac_t *hmac); + +#endif /** HMAC_PRF_H_ @}*/ diff --git a/src/libstrongswan/crypto/hmacs/hmac_signer.c b/src/libstrongswan/crypto/hmacs/hmac_signer.c new file mode 100644 index 0000000000..4fc0bc18ed --- /dev/null +++ b/src/libstrongswan/crypto/hmacs/hmac_signer.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 . + * + * 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 "hmac_signer.h" + +typedef struct private_signer_t private_signer_t; + +/** + * Private data of a hmac_signer_t object. + */ +struct private_signer_t { + + /** + * Public interface + */ + signer_t public; + + /** + * HMAC to use + */ + hmac_t *hmac; + + /** + * Truncation of HMAC output + */ + size_t truncation; +}; + +METHOD(signer_t, get_signature, void, + private_signer_t *this, chunk_t data, u_int8_t *buffer) +{ + if (buffer == NULL) + { + this->hmac->get_mac(this->hmac, data, NULL); + } + else + { + u_int8_t mac[this->hmac->get_mac_size(this->hmac)]; + + this->hmac->get_mac(this->hmac, data, mac); + memcpy(buffer, mac, this->truncation); + } +} + +METHOD(signer_t, allocate_signature, void, + private_signer_t *this, chunk_t data, chunk_t *chunk) +{ + if (chunk == NULL) + { + this->hmac->get_mac(this->hmac, data, NULL); + } + else + { + u_int8_t mac[this->hmac->get_mac_size(this->hmac)]; + + this->hmac->get_mac(this->hmac, data, mac); + + *chunk = chunk_alloc(this->truncation); + memcpy(chunk->ptr, mac, this->truncation); + } +} + +METHOD(signer_t, verify_signature, bool, + private_signer_t *this, chunk_t data, chunk_t signature) +{ + u_int8_t mac[this->hmac->get_mac_size(this->hmac)]; + + if (signature.len != this->truncation) + { + return FALSE; + } + this->hmac->get_mac(this->hmac, data, mac); + return memeq(signature.ptr, mac, this->truncation); +} + +METHOD(signer_t, get_key_size, size_t, + private_signer_t *this) +{ + return this->hmac->get_mac_size(this->hmac); +} + +METHOD(signer_t, get_block_size, size_t, + private_signer_t *this) +{ + return this->truncation; +} + +METHOD(signer_t, set_key, void, + private_signer_t *this, chunk_t key) +{ + this->hmac->set_key(this->hmac, key); +} + +METHOD(signer_t, destroy, void, + private_signer_t *this) +{ + this->hmac->destroy(this->hmac); + free(this); +} + +/* + * Described in header + */ +signer_t *hmac_signer_create(hmac_t *hmac, size_t len) +{ + private_signer_t *this; + + INIT(this, + .public = { + .get_signature = _get_signature, + .allocate_signature = _allocate_signature, + .verify_signature = _verify_signature, + .get_block_size = _get_block_size, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + .truncation = min(len, hmac->get_mac_size(hmac)), + .hmac = hmac, + ); + + return &this->public; +} + diff --git a/src/libstrongswan/crypto/hmacs/hmac_signer.h b/src/libstrongswan/crypto/hmacs/hmac_signer.h new file mode 100644 index 0000000000..6db7f6079d --- /dev/null +++ b/src/libstrongswan/crypto/hmacs/hmac_signer.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 hmac_signer hmac_signer + * @{ @ingroup hmac + */ + +#ifndef HMAC_SIGNER_H_ +#define HMAC_SIGNER_H_ + +typedef struct hmac_signer_t hmac_signer_t; + +#include +#include + +/** + * Creates an implementation of the signer_t interface using the provided hmac_t + * implementation and truncation length. + * + * @note len will be set to hmac_t.get_mac_size() if it is greater than that. + * + * @param hmac hmac_t implementation + * @param len length of resulting signature + * @return hmac_signer_t + */ +signer_t *hmac_signer_create(hmac_t *hmac, size_t len); + +#endif /** HMAC_SIGNER_H_ @}*/