Merge tag 'pull-loongarch-20241016' of https://gitlab.com/gaosong/qemu into staging
[qemu/armbru.git] / crypto / hash-nettle.c
blob3b847aa60e8a4a968e2c94462b25d3e828d5539a
1 /*
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"
25 #include "hashpriv.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,
32 size_t len,
33 const uint8_t *buf);
34 typedef void (*qcrypto_nettle_result)(void *ctx,
35 size_t len,
36 uint8_t *buf);
38 union qcrypto_hash_ctx {
39 struct md5_ctx md5;
40 struct sha1_ctx sha1;
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;
52 size_t len;
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) {
102 return true;
104 return false;
107 static
108 QCryptoHash *qcrypto_nettle_hash_new(QCryptoHashAlgo alg, Error **errp)
110 QCryptoHash *hash;
112 hash = g_new(QCryptoHash, 1);
113 hash->alg = alg;
114 hash->opaque = g_new(union qcrypto_hash_ctx, 1);
116 qcrypto_hash_alg_map[alg].init(hash->opaque);
117 return hash;
120 static
121 void qcrypto_nettle_hash_free(QCryptoHash *hash)
123 union qcrypto_hash_ctx *ctx = hash->opaque;
125 g_free(ctx);
126 g_free(hash);
129 static
130 int qcrypto_nettle_hash_update(QCryptoHash *hash,
131 const struct iovec *iov,
132 size_t niov,
133 Error **errp)
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,
139 iov[i].iov_len,
140 iov[i].iov_base);
143 return 0;
146 static
147 int qcrypto_nettle_hash_finalize(QCryptoHash *hash,
148 uint8_t **result,
149 size_t *result_len,
150 Error **errp)
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);
159 return 0;
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,