diff options
author | Mattias Andrée <maandree@kth.se> | 2019-02-10 17:10:20 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2019-02-10 17:11:30 +0100 |
commit | 32a5ae4e65844615cb3e32aaefcdb7abe4af54c9 (patch) | |
tree | 0ecfa02766944f2568b184d8d5a8ba0edc71425f /hmac_init.c | |
parent | Use lowest bits rather than highest bits in complete byte, document this, and add tests (diff) | |
download | libsha2-32a5ae4e65844615cb3e32aaefcdb7abe4af54c9.tar.gz libsha2-32a5ae4e65844615cb3e32aaefcdb7abe4af54c9.tar.bz2 libsha2-32a5ae4e65844615cb3e32aaefcdb7abe4af54c9.tar.xz |
Add HMAC and use void * instead of char * for binary data
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'hmac_init.c')
-rw-r--r-- | hmac_init.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/hmac_init.c b/hmac_init.c new file mode 100644 index 0000000..4aee2c2 --- /dev/null +++ b/hmac_init.c @@ -0,0 +1,45 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +/** + * Initialise an HMAC state + * + * @param state The state that should be initialised + * @param algorithm The hashing algorithm + * @param key The key + * @param key_length The length of key, in bits + * @return Zero on success, -1 on error + */ +int +libsha2_hmac_init(struct libsha2_hmac_state *restrict state, enum libsha2_algorithm algorithm, + const void *restrict key_, size_t keylen) +{ + const unsigned char *restrict key = key_; + size_t i; + + state->sha2_state.algorithm = algorithm; + state->outsize = libsha2_algorithm_output_size(algorithm) * 8; + state->inited = 0; + + if (keylen <= state->sha2_state.chunk_size * 8) { + memset(state->ipad, 0x36, sizeof(state->ipad)); + memset(state->opad, 0x5C, sizeof(state->opad)); + for (i = 0, keylen /= 8; i < keylen; i++) { + state->ipad[i] ^= key[i]; + state->opad[i] ^= key[i]; + } + } else { + memset(state->ipad, 0, sizeof(state->ipad)); + if (libsha2_init(&state->sha2_state, algorithm)) + return -1; + libsha2_digest(&state->sha2_state, key, keylen, state->ipad); + memcpy(state->opad, state->ipad, sizeof(state->ipad)); + for (i = 0; i < sizeof(state->ipad); i++) { + state->ipad[i] ^= 0x36; + state->opad[i] ^= 0x5C; + } + } + + return 0; +} |