diff options
Diffstat (limited to 'src/libstrongswan/crypto/signers')
-rw-r--r-- | src/libstrongswan/crypto/signers/hmac_signer.c | 50 | ||||
-rw-r--r-- | src/libstrongswan/crypto/signers/hmac_signer.h | 19 | ||||
-rw-r--r-- | src/libstrongswan/crypto/signers/signer.c | 17 | ||||
-rw-r--r-- | src/libstrongswan/crypto/signers/signer.h | 12 |
4 files changed, 55 insertions, 43 deletions
diff --git a/src/libstrongswan/crypto/signers/hmac_signer.c b/src/libstrongswan/crypto/signers/hmac_signer.c index c4a6173b5..76e1ce50e 100644 --- a/src/libstrongswan/crypto/signers/hmac_signer.c +++ b/src/libstrongswan/crypto/signers/hmac_signer.c @@ -27,11 +27,6 @@ #include <crypto/prfs/hmac_prf.h> -/** - * This class represents a hmac signer with 12 byte (96 bit) output. - */ -#define BLOCK_SIZE 12 - typedef struct private_hmac_signer_t private_hmac_signer_t; /** @@ -43,10 +38,15 @@ struct private_hmac_signer_t { */ hmac_signer_t public; - /* + /** * Assigned hmac function. */ prf_t *hmac_prf; + + /** + * Block size (truncation of HMAC Hash) + */ + size_t block_size; }; /** @@ -56,10 +56,10 @@ static void get_signature (private_hmac_signer_t *this, chunk_t data, u_int8_t * { u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)]; - this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac); + this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac); - /* copy mac aka signature :-) */ - memcpy(buffer,full_mac,BLOCK_SIZE); + /* copy MAC depending on truncation */ + memcpy(buffer, full_mac, this->block_size); } /** @@ -72,11 +72,11 @@ static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac); - signature.ptr = malloc(BLOCK_SIZE); - signature.len = BLOCK_SIZE; + signature.ptr = malloc(this->block_size); + signature.len = this->block_size; /* copy signature */ - memcpy(signature.ptr,full_mac,BLOCK_SIZE); + memcpy(signature.ptr, full_mac, this->block_size); *chunk = signature; } @@ -84,19 +84,19 @@ static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk /** * Implementation of signer_t.verify_signature. */ -static bool verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t signature) +static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t signature) { u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)]; - this->hmac_prf->get_bytes(this->hmac_prf,data,full_mac); + this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac); - if (signature.len != BLOCK_SIZE) + if (signature.len != this->block_size) { return FALSE; } /* compare mac aka signature :-) */ - if (memcmp(signature.ptr,full_mac,BLOCK_SIZE) == 0) + if (memcmp(signature.ptr, full_mac, this->block_size) == 0) { return TRUE; } @@ -109,7 +109,7 @@ static bool verify_signature (private_hmac_signer_t *this, chunk_t data, chunk_t /** * Implementation of signer_t.get_key_size. */ -static size_t get_key_size (private_hmac_signer_t *this) +static size_t get_key_size(private_hmac_signer_t *this) { /* for HMAC signer, IKEv2 uses block size as key size */ return this->hmac_prf->get_block_size(this->hmac_prf); @@ -118,17 +118,17 @@ static size_t get_key_size (private_hmac_signer_t *this) /** * Implementation of signer_t.get_block_size. */ -static size_t get_block_size (private_hmac_signer_t *this) +static size_t get_block_size(private_hmac_signer_t *this) { - return BLOCK_SIZE; + return this->block_size; } /** * Implementation of signer_t.set_key. */ -static void set_key (private_hmac_signer_t *this, chunk_t key) +static void set_key(private_hmac_signer_t *this, chunk_t key) { - this->hmac_prf->set_key(this->hmac_prf,key); + this->hmac_prf->set_key(this->hmac_prf, key); } /** @@ -144,12 +144,12 @@ static status_t destroy(private_hmac_signer_t *this) /* * Described in header */ -hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm) +hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size) { + size_t hmac_block_size; private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t); this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm); - if (this->hmac_prf == NULL) { /* algorithm not supported */ @@ -157,6 +157,10 @@ hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm) return NULL; } + /* prevent invalid truncation */ + hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf); + this->block_size = min(block_size, hmac_block_size); + /* 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; diff --git a/src/libstrongswan/crypto/signers/hmac_signer.h b/src/libstrongswan/crypto/signers/hmac_signer.h index 5b9549086..2449069bd 100644 --- a/src/libstrongswan/crypto/signers/hmac_signer.h +++ b/src/libstrongswan/crypto/signers/hmac_signer.h @@ -30,9 +30,11 @@ typedef struct hmac_signer_t hmac_signer_t; #include <crypto/hashers/hasher.h> /** - * @brief Implementation of signer_t interface using the - * HMAC algorithm in combination with either MD5 or SHA1. - * + * @brief Implementation of signer_t interface using HMAC. + * + * HMAC uses a standard hash function implemented in a hasher_t to build + * a MAC. + * * @ingroup signers */ struct hmac_signer_t { @@ -45,15 +47,22 @@ struct hmac_signer_t { /** * @brief 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 hash_algoritm Hash algorithm to use with signer + * @param block_size Size of resulting signature (truncated to block_size) * @return * - hmac_signer_t * - NULL if hash algorithm not supported * * @ingroup signers */ -hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm); +hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, + size_t block_size); #endif /*HMAC_SIGNER_H_*/ diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c index d6037c545..250d64b71 100644 --- a/src/libstrongswan/crypto/signers/signer.c +++ b/src/libstrongswan/crypto/signers/signer.c @@ -25,9 +25,10 @@ #include <crypto/signers/hmac_signer.h> -ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_UNDEFINED, - "UNDEFINED"); -ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_AES_XCBC_96, AUTH_UNDEFINED, +ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128, + "UNDEFINED", + "AUTH_HMAC_SHA1_128"); +ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_AES_XCBC_96, AUTH_HMAC_SHA1_128, "HMAC_MD5_96", "HMAC_SHA1_96", "DES_MAC", @@ -43,13 +44,11 @@ signer_t *signer_create(integrity_algorithm_t integrity_algorithm) switch(integrity_algorithm) { case AUTH_HMAC_SHA1_96: - { - return ((signer_t *) hmac_signer_create(HASH_SHA1)); - } + return (signer_t *)hmac_signer_create(HASH_SHA1, 12); + case AUTH_HMAC_SHA1_128: + return (signer_t *)hmac_signer_create(HASH_SHA1, 16); case AUTH_HMAC_MD5_96: - { - return ((signer_t *) hmac_signer_create(HASH_MD5)); - } + return (signer_t *)hmac_signer_create(HASH_MD5, 12); default: return NULL; } diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h index 57f7d8fe6..436161a66 100644 --- a/src/libstrongswan/crypto/signers/signer.h +++ b/src/libstrongswan/crypto/signers/signer.h @@ -31,11 +31,9 @@ typedef struct signer_t signer_t; /** * @brief Integrity algorithm, as in IKEv2 RFC 3.3.2. - * - * Currently only the following algorithms are implemented and therefore supported: - * - AUTH_HMAC_MD5_96 - * - AUTH_HMAC_SHA1_96 - * + * + * Algorithms not specified in IKEv2 are allocated in private use space. + * * @ingroup signers */ enum integrity_algorithm_t { @@ -46,7 +44,9 @@ enum integrity_algorithm_t { AUTH_HMAC_SHA1_96 = 2, AUTH_DES_MAC = 3, AUTH_KPDK_MD5 = 4, - AUTH_AES_XCBC_96 = 5 + AUTH_AES_XCBC_96 = 5, + /** Implemented via hmac_signer_t */ + AUTH_HMAC_SHA1_128 = 1025, }; /** |