/* * QEMU Crypto hmac algorithms * * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. * * This work is licensed under the terms of the GNU GPL, version 2 or * (at your option) any later version. See the COPYING file in the * top-level directory. * */ #include "qemu/osdep.h" #include "crypto/hmac.h" #include "hmacpriv.h" static const char hex[] = "0123456789abcdef"; int qcrypto_hmac_bytesv(QCryptoHmac *hmac, const struct iovec *iov, size_t niov, uint8_t **result, size_t *resultlen, Error **errp) { QCryptoHmacDriver *drv = hmac->driver; return drv->hmac_bytesv(hmac, iov, niov, result, resultlen, errp); } int qcrypto_hmac_bytes(QCryptoHmac *hmac, const char *buf, size_t len, uint8_t **result, size_t *resultlen, Error **errp) { struct iovec iov = { .iov_base = (char *)buf, .iov_len = len }; return qcrypto_hmac_bytesv(hmac, &iov, 1, result, resultlen, errp); } int qcrypto_hmac_digestv(QCryptoHmac *hmac, const struct iovec *iov, size_t niov, char **digest, Error **errp) { uint8_t *result = NULL; size_t resultlen = 0; size_t i; if (qcrypto_hmac_bytesv(hmac, iov, niov, &result, &resultlen, errp) < 0) { return -1; } *digest = g_new0(char, (resultlen * 2) + 1); for (i = 0 ; i < resultlen ; i++) { (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf]; (*digest)[(i * 2) + 1] = hex[result[i] & 0xf]; } (*digest)[resultlen * 2] = '\0'; g_free(result); return 0; } int qcrypto_hmac_digest(QCryptoHmac *hmac, const char *buf, size_t len, char **digest, Error **errp) { struct iovec iov = { .iov_base = (char *)buf, .iov_len = len }; return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp); } QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, const uint8_t *key, size_t nkey, Error **errp) { QCryptoHmac *hmac; void *ctx = NULL; QCryptoHmacDriver *drv = NULL; #ifdef CONFIG_AF_ALG ctx = qcrypto_afalg_hmac_ctx_new(alg, key, nkey, NULL); if (ctx) { drv = &qcrypto_hmac_afalg_driver; } #endif if (!ctx) { ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp); if (!ctx) { return NULL; } drv = &qcrypto_hmac_lib_driver; } hmac = g_new0(QCryptoHmac, 1); hmac->alg = alg; hmac->opaque = ctx; hmac->driver = (void *)drv; return hmac; } void qcrypto_hmac_free(QCryptoHmac *hmac) { QCryptoHmacDriver *drv; if (hmac) { drv = hmac->driver; drv->hmac_free(hmac); g_free(hmac); } }