2 * QEMU Crypto hash algorithms
4 * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
5 * Copyright (c) 2016 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 "qapi/error.h"
24 #include "crypto/hash.h"
26 #include <nettle/md5.h>
27 #include <nettle/sha.h>
28 #include <nettle/ripemd160.h>
30 typedef void (*qcrypto_nettle_init
)(void *ctx
);
31 typedef void (*qcrypto_nettle_write
)(void *ctx
,
34 typedef void (*qcrypto_nettle_result
)(void *ctx
,
38 union qcrypto_hash_ctx
{
41 struct sha224_ctx sha224
;
42 struct sha256_ctx sha256
;
43 struct sha384_ctx sha384
;
44 struct sha512_ctx sha512
;
45 struct ripemd160_ctx ripemd160
;
48 struct qcrypto_hash_alg
{
49 qcrypto_nettle_init init
;
50 qcrypto_nettle_write write
;
51 qcrypto_nettle_result result
;
53 } qcrypto_hash_alg_map
[] = {
54 [QCRYPTO_HASH_ALGO_MD5
] = {
55 .init
= (qcrypto_nettle_init
)md5_init
,
56 .write
= (qcrypto_nettle_write
)md5_update
,
57 .result
= (qcrypto_nettle_result
)md5_digest
,
58 .len
= MD5_DIGEST_SIZE
,
60 [QCRYPTO_HASH_ALGO_SHA1
] = {
61 .init
= (qcrypto_nettle_init
)sha1_init
,
62 .write
= (qcrypto_nettle_write
)sha1_update
,
63 .result
= (qcrypto_nettle_result
)sha1_digest
,
64 .len
= SHA1_DIGEST_SIZE
,
66 [QCRYPTO_HASH_ALGO_SHA224
] = {
67 .init
= (qcrypto_nettle_init
)sha224_init
,
68 .write
= (qcrypto_nettle_write
)sha224_update
,
69 .result
= (qcrypto_nettle_result
)sha224_digest
,
70 .len
= SHA224_DIGEST_SIZE
,
72 [QCRYPTO_HASH_ALGO_SHA256
] = {
73 .init
= (qcrypto_nettle_init
)sha256_init
,
74 .write
= (qcrypto_nettle_write
)sha256_update
,
75 .result
= (qcrypto_nettle_result
)sha256_digest
,
76 .len
= SHA256_DIGEST_SIZE
,
78 [QCRYPTO_HASH_ALGO_SHA384
] = {
79 .init
= (qcrypto_nettle_init
)sha384_init
,
80 .write
= (qcrypto_nettle_write
)sha384_update
,
81 .result
= (qcrypto_nettle_result
)sha384_digest
,
82 .len
= SHA384_DIGEST_SIZE
,
84 [QCRYPTO_HASH_ALGO_SHA512
] = {
85 .init
= (qcrypto_nettle_init
)sha512_init
,
86 .write
= (qcrypto_nettle_write
)sha512_update
,
87 .result
= (qcrypto_nettle_result
)sha512_digest
,
88 .len
= SHA512_DIGEST_SIZE
,
90 [QCRYPTO_HASH_ALGO_RIPEMD160
] = {
91 .init
= (qcrypto_nettle_init
)ripemd160_init
,
92 .write
= (qcrypto_nettle_write
)ripemd160_update
,
93 .result
= (qcrypto_nettle_result
)ripemd160_digest
,
94 .len
= RIPEMD160_DIGEST_SIZE
,
98 gboolean
qcrypto_hash_supports(QCryptoHashAlgo alg
)
100 if (alg
< G_N_ELEMENTS(qcrypto_hash_alg_map
) &&
101 qcrypto_hash_alg_map
[alg
].init
!= NULL
) {
108 QCryptoHash
*qcrypto_nettle_hash_new(QCryptoHashAlgo alg
, Error
**errp
)
112 hash
= g_new(QCryptoHash
, 1);
114 hash
->opaque
= g_new(union qcrypto_hash_ctx
, 1);
116 qcrypto_hash_alg_map
[alg
].init(hash
->opaque
);
121 void qcrypto_nettle_hash_free(QCryptoHash
*hash
)
123 union qcrypto_hash_ctx
*ctx
= hash
->opaque
;
130 int qcrypto_nettle_hash_update(QCryptoHash
*hash
,
131 const struct iovec
*iov
,
135 union qcrypto_hash_ctx
*ctx
= hash
->opaque
;
137 for (int i
= 0; i
< niov
; i
++) {
138 qcrypto_hash_alg_map
[hash
->alg
].write(ctx
,
147 int qcrypto_nettle_hash_finalize(QCryptoHash
*hash
,
152 union qcrypto_hash_ctx
*ctx
= hash
->opaque
;
154 *result_len
= qcrypto_hash_alg_map
[hash
->alg
].len
;
155 *result
= g_new(uint8_t, *result_len
);
157 qcrypto_hash_alg_map
[hash
->alg
].result(ctx
, *result_len
, *result
);
162 QCryptoHashDriver qcrypto_hash_lib_driver
= {
163 .hash_new
= qcrypto_nettle_hash_new
,
164 .hash_update
= qcrypto_nettle_hash_update
,
165 .hash_finalize
= qcrypto_nettle_hash_finalize
,
166 .hash_free
= qcrypto_nettle_hash_free
,