qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

hash-glib.c (2776B)


      1 /*
      2  * QEMU Crypto hash algorithms
      3  *
      4  * Copyright (c) 2016 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.1 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 #include "hashpriv.h"
     25 
     26 
     27 static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
     28     [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5,
     29     [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1,
     30     [QCRYPTO_HASH_ALG_SHA224] = -1,
     31     [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256,
     32     [QCRYPTO_HASH_ALG_SHA384] = -1,
     33     [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512,
     34     [QCRYPTO_HASH_ALG_RIPEMD160] = -1,
     35 };
     36 
     37 gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
     38 {
     39     if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) &&
     40         qcrypto_hash_alg_map[alg] != -1) {
     41         return true;
     42     }
     43     return false;
     44 }
     45 
     46 
     47 static int
     48 qcrypto_glib_hash_bytesv(QCryptoHashAlgorithm alg,
     49                          const struct iovec *iov,
     50                          size_t niov,
     51                          uint8_t **result,
     52                          size_t *resultlen,
     53                          Error **errp)
     54 {
     55     int i, ret;
     56     GChecksum *cs;
     57 
     58     if (!qcrypto_hash_supports(alg)) {
     59         error_setg(errp,
     60                    "Unknown hash algorithm %d",
     61                    alg);
     62         return -1;
     63     }
     64 
     65     cs = g_checksum_new(qcrypto_hash_alg_map[alg]);
     66 
     67     for (i = 0; i < niov; i++) {
     68         g_checksum_update(cs, iov[i].iov_base, iov[i].iov_len);
     69     }
     70 
     71     ret = g_checksum_type_get_length(qcrypto_hash_alg_map[alg]);
     72     if (ret < 0) {
     73         error_setg(errp, "%s",
     74                    "Unable to get hash length");
     75         goto error;
     76     }
     77     if (*resultlen == 0) {
     78         *resultlen = ret;
     79         *result = g_new0(uint8_t, *resultlen);
     80     } else if (*resultlen != ret) {
     81         error_setg(errp,
     82                    "Result buffer size %zu is smaller than hash %d",
     83                    *resultlen, ret);
     84         goto error;
     85     }
     86 
     87     g_checksum_get_digest(cs, *result, resultlen);
     88 
     89     g_checksum_free(cs);
     90     return 0;
     91 
     92  error:
     93     g_checksum_free(cs);
     94     return -1;
     95 }
     96 
     97 
     98 QCryptoHashDriver qcrypto_hash_lib_driver = {
     99     .hash_bytesv = qcrypto_glib_hash_bytesv,
    100 };