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 25 static 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 35 size_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 42 int 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 54 static const char hex[] = "0123456789abcdef"; 55 56 int 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 80 int 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 91 int 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 109 int 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