qemu/crypto/hash.c
<<
>>
Prefs
   1/*
   2 * QEMU Crypto hash algorithms
   3 *
   4 * Copyright (c) 2015 Red Hat, Inc.
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 *
  19 */
  20
  21#include "qemu/osdep.h"
  22#include "qapi/error.h"
  23#include "crypto/hash.h"
  24
  25static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = {
  26    [QCRYPTO_HASH_ALG_MD5] = 16,
  27    [QCRYPTO_HASH_ALG_SHA1] = 20,
  28    [QCRYPTO_HASH_ALG_SHA224] = 28,
  29    [QCRYPTO_HASH_ALG_SHA256] = 32,
  30    [QCRYPTO_HASH_ALG_SHA384] = 48,
  31    [QCRYPTO_HASH_ALG_SHA512] = 64,
  32    [QCRYPTO_HASH_ALG_RIPEMD160] = 20,
  33};
  34
  35size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg)
  36{
  37    assert(alg < G_N_ELEMENTS(qcrypto_hash_alg_size));
  38    return qcrypto_hash_alg_size[alg];
  39}
  40
  41
  42int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
  43                       const char *buf,
  44                       size_t len,
  45                       uint8_t **result,
  46                       size_t *resultlen,
  47                       Error **errp)
  48{
  49    struct iovec iov = { .iov_base = (char *)buf,
  50                         .iov_len = len };
  51    return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp);
  52}
  53
  54static const char hex[] = "0123456789abcdef";
  55
  56int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
  57                         const struct iovec *iov,
  58                         size_t niov,
  59                         char **digest,
  60                         Error **errp)
  61{
  62    uint8_t *result = NULL;
  63    size_t resultlen = 0;
  64    size_t i;
  65
  66    if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
  67        return -1;
  68    }
  69
  70    *digest = g_new0(char, (resultlen * 2) + 1);
  71    for (i = 0 ; i < resultlen ; i++) {
  72        (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
  73        (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
  74    }
  75    (*digest)[resultlen * 2] = '\0';
  76    g_free(result);
  77    return 0;
  78}
  79
  80int qcrypto_hash_digest(QCryptoHashAlgorithm alg,
  81                        const char *buf,
  82                        size_t len,
  83                        char **digest,
  84                        Error **errp)
  85{
  86    struct iovec iov = { .iov_base = (char *)buf, .iov_len = len };
  87
  88    return qcrypto_hash_digestv(alg, &iov, 1, digest, errp);
  89}
  90
  91int qcrypto_hash_base64v(QCryptoHashAlgorithm alg,
  92                         const struct iovec *iov,
  93                         size_t niov,
  94                         char **base64,
  95                         Error **errp)
  96{
  97    uint8_t *result = NULL;
  98    size_t resultlen = 0;
  99
 100    if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) {
 101        return -1;
 102    }
 103
 104    *base64 = g_base64_encode(result, resultlen);
 105    g_free(result);
 106    return 0;
 107}
 108
 109int qcrypto_hash_base64(QCryptoHashAlgorithm alg,
 110                        const char *buf,
 111                        size_t len,
 112                        char **base64,
 113                        Error **errp)
 114{
 115    struct iovec iov = { .iov_base = (char *)buf, .iov_len = len };
 116
 117    return qcrypto_hash_base64v(alg, &iov, 1, base64, errp);
 118}
 119