# HG changeset patch # User Aki Tuomi # Date 1480454336 -7200 # Node ID b861c0860dd2bd93bf333c56646cc26cb85e7d92 # Parent d082c99cbc65b234874dc895bef51a0ac2e574c6 lib: Add hmac helpers These run hmac for given data with given parameters and returns stack allocated buffer. They are helpful when doing lots of HMACs, such as the AWS4 signing protocol. diff -r d082c99cbc65 -r b861c0860dd2 src/lib/hmac.c --- a/src/lib/hmac.c Thu Nov 24 18:12:00 2016 +0200 +++ b/src/lib/hmac.c Tue Nov 29 23:18:56 2016 +0200 @@ -10,6 +10,7 @@ #include "lib.h" #include "hmac.h" #include "safe-memset.h" +#include "buffer.h" void hmac_init(struct hmac_context *_ctx, const unsigned char *key, size_t key_len, const struct hash_method *meth) @@ -59,3 +60,36 @@ ctx->hash->loop(ctx->ctxo, digest, ctx->hash->digest_size); ctx->hash->result(ctx->ctxo, digest); } + +buffer_t *t_hmac_data(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const void *data, size_t data_len) +{ + struct hmac_context ctx; + i_assert(meth != NULL); + i_assert(key != NULL && key_len > 0); + i_assert(data != NULL || data_len == 0); + + buffer_t *res = buffer_create_dynamic(pool_datastack_create(), meth->digest_size); + hmac_init(&ctx, key, key_len, meth); + if (data_len > 0) + hmac_update(&ctx, data, data_len); + unsigned char *buf = buffer_get_space_unsafe(res, 0, meth->digest_size); + hmac_final(&ctx, buf); + return res; +} + +buffer_t *t_hmac_buffer(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const buffer_t *data) +{ + return t_hmac_data(meth, key, key_len, data->data, data->used); +} + +buffer_t *t_hmac_str(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const char *data) +{ + return t_hmac_data(meth, key, key_len, data, strlen(data)); +} + diff -r d082c99cbc65 -r b861c0860dd2 src/lib/hmac.h --- a/src/lib/hmac.h Thu Nov 24 18:12:00 2016 +0200 +++ b/src/lib/hmac.h Tue Nov 29 23:18:56 2016 +0200 @@ -32,4 +32,14 @@ ctx->hash->loop(ctx->ctx, data, size); } +buffer_t *t_hmac_data(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const void *data, size_t data_len); +buffer_t *t_hmac_buffer(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const buffer_t *data); +buffer_t *t_hmac_str(const struct hash_method *meth, + const unsigned char *key, size_t key_len, + const char *data); + #endif