qemu/crypto/hmac.c
<<
>>
Prefs
   1/*
   2 * QEMU Crypto hmac algorithms
   3 *
   4 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or
   7 * (at your option) any later version.  See the COPYING file in the
   8 * top-level directory.
   9 *
  10 */
  11
  12#include "qemu/osdep.h"
  13#include "crypto/hmac.h"
  14#include "hmacpriv.h"
  15
  16static const char hex[] = "0123456789abcdef";
  17
  18int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
  19                        const struct iovec *iov,
  20                        size_t niov,
  21                        uint8_t **result,
  22                        size_t *resultlen,
  23                        Error **errp)
  24{
  25    QCryptoHmacDriver *drv = hmac->driver;
  26
  27    return drv->hmac_bytesv(hmac, iov, niov, result, resultlen, errp);
  28}
  29
  30int qcrypto_hmac_bytes(QCryptoHmac *hmac,
  31                       const char *buf,
  32                       size_t len,
  33                       uint8_t **result,
  34                       size_t *resultlen,
  35                       Error **errp)
  36{
  37    struct iovec iov = {
  38            .iov_base = (char *)buf,
  39            .iov_len = len
  40    };
  41
  42    return qcrypto_hmac_bytesv(hmac, &iov, 1, result, resultlen, errp);
  43}
  44
  45int qcrypto_hmac_digestv(QCryptoHmac *hmac,
  46                         const struct iovec *iov,
  47                         size_t niov,
  48                         char **digest,
  49                         Error **errp)
  50{
  51    uint8_t *result = NULL;
  52    size_t resultlen = 0;
  53    size_t i;
  54
  55    if (qcrypto_hmac_bytesv(hmac, iov, niov, &result, &resultlen, errp) < 0) {
  56        return -1;
  57    }
  58
  59    *digest = g_new0(char, (resultlen * 2) + 1);
  60
  61    for (i = 0 ; i < resultlen ; i++) {
  62        (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
  63        (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
  64    }
  65
  66    (*digest)[resultlen * 2] = '\0';
  67
  68    g_free(result);
  69    return 0;
  70}
  71
  72int qcrypto_hmac_digest(QCryptoHmac *hmac,
  73                        const char *buf,
  74                        size_t len,
  75                        char **digest,
  76                        Error **errp)
  77{
  78    struct iovec iov = {
  79            .iov_base = (char *)buf,
  80            .iov_len = len
  81    };
  82
  83    return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp);
  84}
  85
  86QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
  87                              const uint8_t *key, size_t nkey,
  88                              Error **errp)
  89{
  90    QCryptoHmac *hmac;
  91    void *ctx = NULL;
  92    QCryptoHmacDriver *drv = NULL;
  93
  94#ifdef CONFIG_AF_ALG
  95    ctx = qcrypto_afalg_hmac_ctx_new(alg, key, nkey, NULL);
  96    if (ctx) {
  97        drv = &qcrypto_hmac_afalg_driver;
  98    }
  99#endif
 100
 101    if (!ctx) {
 102        ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
 103        if (!ctx) {
 104            return NULL;
 105        }
 106
 107        drv = &qcrypto_hmac_lib_driver;
 108    }
 109
 110    hmac = g_new0(QCryptoHmac, 1);
 111    hmac->alg = alg;
 112    hmac->opaque = ctx;
 113    hmac->driver = (void *)drv;
 114
 115    return hmac;
 116}
 117
 118void qcrypto_hmac_free(QCryptoHmac *hmac)
 119{
 120    QCryptoHmacDriver *drv;
 121
 122    if (hmac) {
 123        drv = hmac->driver;
 124        drv->hmac_free(hmac);
 125        g_free(hmac);
 126    }
 127}
 128