From 3484f092e50969858ca4a3145fd364ec123e4dff Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Mon, 14 May 2018 13:19:12 +0100 Subject: [PATCH] krb5: Add _krb5_evp_hmac_iov Add a function which will perform an HMAC over a set of iovecs, using the hcrypto provided HMAC functions. Join contiguous iovecs together before passing them to the hash function so we make as few calls into the hash as possible. --- lib/krb5/crypto-evp.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/lib/krb5/crypto-evp.c b/lib/krb5/crypto-evp.c index 636df6be0..387e5672f 100644 --- a/lib/krb5/crypto-evp.c +++ b/lib/krb5/crypto-evp.c @@ -104,6 +104,49 @@ out: return ret; } +krb5_error_code +_krb5_evp_hmac_iov(krb5_context context, + struct _krb5_key_data *key, + const struct krb5_crypto_iov *iov, + int niov, + void *hmac, + unsigned int *hmaclen, + const EVP_MD *md, + ENGINE *engine) +{ + HMAC_CTX *ctx; + krb5_data current = {0, 0}; + int i; + + ctx = HMAC_CTX_new(); + if (ctx == NULL) + return krb5_enomem(context); + + HMAC_Init_ex(ctx, key->key->keyvalue.data, key->key->keyvalue.length, + md, engine); + + for (i = 0; i < niov; i++) { + if (_krb5_crypto_iov_should_sign(&iov[i])) { + if ((char *)current.data + current.length == iov[i].data.data) { + current.length += iov[i].data.length; + } else { + if (current.data) + HMAC_Update(ctx, current.data, current.length); + current = iov[i].data; + } + } + } + + if (current.data) + HMAC_Update(ctx, current.data, current.length); + + HMAC_Final(ctx, hmac, hmaclen); + + HMAC_CTX_free(ctx); + + return 0; +} + krb5_error_code _krb5_evp_encrypt(krb5_context context, struct _krb5_key_data *key,