2 * QEMU Crypto hash algorithms
4 * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
5 * Copyright (c) 2021 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 #include "qemu/osdep.h"
23 #include <gnutls/crypto.h>
24 #include "qapi/error.h"
25 #include "crypto/hash.h"
29 static int qcrypto_hash_alg_map
[QCRYPTO_HASH_ALGO__MAX
] = {
30 [QCRYPTO_HASH_ALGO_MD5
] = GNUTLS_DIG_MD5
,
31 [QCRYPTO_HASH_ALGO_SHA1
] = GNUTLS_DIG_SHA1
,
32 [QCRYPTO_HASH_ALGO_SHA224
] = GNUTLS_DIG_SHA224
,
33 [QCRYPTO_HASH_ALGO_SHA256
] = GNUTLS_DIG_SHA256
,
34 [QCRYPTO_HASH_ALGO_SHA384
] = GNUTLS_DIG_SHA384
,
35 [QCRYPTO_HASH_ALGO_SHA512
] = GNUTLS_DIG_SHA512
,
36 [QCRYPTO_HASH_ALGO_RIPEMD160
] = GNUTLS_DIG_RMD160
,
39 gboolean
qcrypto_hash_supports(QCryptoHashAlgo alg
)
42 const gnutls_digest_algorithm_t
*algs
;
43 if (alg
>= G_N_ELEMENTS(qcrypto_hash_alg_map
) ||
44 qcrypto_hash_alg_map
[alg
] == GNUTLS_DIG_UNKNOWN
) {
47 algs
= gnutls_digest_list();
48 for (i
= 0; algs
[i
] != GNUTLS_DIG_UNKNOWN
; i
++) {
49 if (algs
[i
] == qcrypto_hash_alg_map
[alg
]) {
57 QCryptoHash
*qcrypto_gnutls_hash_new(QCryptoHashAlgo alg
, Error
**errp
)
62 hash
= g_new(QCryptoHash
, 1);
64 hash
->opaque
= g_new(gnutls_hash_hd_t
, 1);
66 ret
= gnutls_hash_init(hash
->opaque
, qcrypto_hash_alg_map
[alg
]);
69 "Unable to initialize hash algorithm: %s",
70 gnutls_strerror(ret
));
80 void qcrypto_gnutls_hash_free(QCryptoHash
*hash
)
82 gnutls_hash_hd_t
*ctx
= hash
->opaque
;
84 gnutls_hash_deinit(*ctx
, NULL
);
91 int qcrypto_gnutls_hash_update(QCryptoHash
*hash
,
92 const struct iovec
*iov
,
97 gnutls_hash_hd_t
*ctx
= hash
->opaque
;
99 for (int i
= 0; i
< niov
; i
++) {
100 ret
= gnutls_hash(*ctx
, iov
[i
].iov_base
, iov
[i
].iov_len
);
102 error_setg(errp
, "Failed to hash data: %s",
103 gnutls_strerror(ret
));
112 int qcrypto_gnutls_hash_finalize(QCryptoHash
*hash
,
117 gnutls_hash_hd_t
*ctx
= hash
->opaque
;
119 *result_len
= gnutls_hash_get_len(qcrypto_hash_alg_map
[hash
->alg
]);
120 if (*result_len
== 0) {
121 error_setg(errp
, "Unable to get hash length");
125 *result
= g_new(uint8_t, *result_len
);
126 gnutls_hash_output(*ctx
, *result
);
130 QCryptoHashDriver qcrypto_hash_lib_driver
= {
131 .hash_new
= qcrypto_gnutls_hash_new
,
132 .hash_update
= qcrypto_gnutls_hash_update
,
133 .hash_finalize
= qcrypto_gnutls_hash_finalize
,
134 .hash_free
= qcrypto_gnutls_hash_free
,