2 * QEMU Crypto af_alg-backend hash/hmac support
4 * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
7 * Longpeng(Mike) <longpeng2@huawei.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or
10 * (at your option) any later version. See the COPYING file in the
11 * top-level directory.
13 #include "qemu/osdep.h"
15 #include "qemu/sockets.h"
16 #include "qemu-common.h"
17 #include "qapi/error.h"
18 #include "crypto/hash.h"
19 #include "crypto/hmac.h"
24 qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg
,
32 case QCRYPTO_HASH_ALG_MD5
:
35 case QCRYPTO_HASH_ALG_SHA1
:
38 case QCRYPTO_HASH_ALG_SHA224
:
41 case QCRYPTO_HASH_ALG_SHA256
:
44 case QCRYPTO_HASH_ALG_SHA384
:
47 case QCRYPTO_HASH_ALG_SHA512
:
50 case QCRYPTO_HASH_ALG_RIPEMD160
:
55 error_setg(errp
, "Unsupported hash algorithm %d", alg
);
60 name
= g_strdup_printf("hmac(%s)", alg_name
);
62 name
= g_strdup_printf("%s", alg_name
);
69 qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgorithm alg
,
70 const uint8_t *key
, size_t nkey
,
71 bool is_hmac
, Error
**errp
)
76 name
= qcrypto_afalg_hash_format_name(alg
, is_hmac
, errp
);
81 afalg
= qcrypto_afalg_comm_alloc(AFALG_TYPE_HASH
, name
, errp
);
89 /* HMAC needs setkey */
91 if (qemu_setsockopt(afalg
->tfmfd
, SOL_ALG
, ALG_SET_KEY
,
93 error_setg_errno(errp
, errno
, "Set hmac key failed");
94 qcrypto_afalg_comm_free(afalg
);
102 static QCryptoAFAlg
*
103 qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg
,
106 return qcrypto_afalg_hash_hmac_ctx_new(alg
, NULL
, 0, false, errp
);
110 qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg
,
111 const uint8_t *key
, size_t nkey
,
114 return qcrypto_afalg_hash_hmac_ctx_new(alg
, key
, nkey
, true, errp
);
118 qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlg
*hmac
,
119 QCryptoHashAlgorithm alg
,
120 const struct iovec
*iov
,
121 size_t niov
, uint8_t **result
,
128 bool is_hmac
= (hmac
!= NULL
) ? true : false;
129 const int expect_len
= qcrypto_hash_digest_len(alg
);
131 if (*resultlen
== 0) {
132 *resultlen
= expect_len
;
133 *result
= g_new0(uint8_t, *resultlen
);
134 } else if (*resultlen
!= expect_len
) {
136 "Result buffer size %zu is not match hash %d",
137 *resultlen
, expect_len
);
144 afalg
= qcrypto_afalg_hash_ctx_new(alg
, errp
);
150 /* send data to kernel's crypto core */
151 ret
= iov_send_recv(afalg
->opfd
, iov
, niov
,
152 0, iov_size(iov
, niov
), true);
154 error_setg_errno(errp
, errno
, "Send data to afalg-core failed");
158 /* hash && get result */
159 outv
.iov_base
= *result
;
160 outv
.iov_len
= *resultlen
;
161 ret
= iov_send_recv(afalg
->opfd
, &outv
, 1,
162 0, iov_size(&outv
, 1), false);
164 error_setg_errno(errp
, errno
, "Recv result from afalg-core failed");
171 qcrypto_afalg_comm_free(afalg
);
177 qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg
,
178 const struct iovec
*iov
,
179 size_t niov
, uint8_t **result
,
183 return qcrypto_afalg_hash_hmac_bytesv(NULL
, alg
, iov
, niov
, result
,
188 qcrypto_afalg_hmac_bytesv(QCryptoHmac
*hmac
,
189 const struct iovec
*iov
,
190 size_t niov
, uint8_t **result
,
194 return qcrypto_afalg_hash_hmac_bytesv(hmac
->opaque
, hmac
->alg
,
195 iov
, niov
, result
, resultlen
,
199 static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac
*hmac
)
203 afalg
= hmac
->opaque
;
204 qcrypto_afalg_comm_free(afalg
);
207 QCryptoHashDriver qcrypto_hash_afalg_driver
= {
208 .hash_bytesv
= qcrypto_afalg_hash_bytesv
,
211 QCryptoHmacDriver qcrypto_hmac_afalg_driver
= {
212 .hmac_bytesv
= qcrypto_afalg_hmac_bytesv
,
213 .hmac_free
= qcrypto_afalg_hmac_ctx_free
,