]> git.proxmox.com Git - mirror_qemu.git/blame - crypto/hash-afalg.c
crypto: hash: add afalg-backend hash support
[mirror_qemu.git] / crypto / hash-afalg.c
CommitLineData
9a059773
LM
1/*
2 * QEMU Crypto af_alg-backend hash support
3 *
4 * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
5 *
6 * Authors:
7 * Longpeng(Mike) <longpeng2@huawei.com>
8 *
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.
12 */
13#include "qemu/osdep.h"
14#include "qemu/iov.h"
15#include "qemu/sockets.h"
16#include "qemu-common.h"
17#include "qapi/error.h"
18#include "crypto/hash.h"
19#include "hashpriv.h"
20
21static char *
22qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg,
23 Error **errp)
24{
25 char *name;
26 const char *alg_name;
27
28 switch (alg) {
29 case QCRYPTO_HASH_ALG_MD5:
30 alg_name = "md5";
31 break;
32 case QCRYPTO_HASH_ALG_SHA1:
33 alg_name = "sha1";
34 break;
35 case QCRYPTO_HASH_ALG_SHA224:
36 alg_name = "sha224";
37 break;
38 case QCRYPTO_HASH_ALG_SHA256:
39 alg_name = "sha256";
40 break;
41 case QCRYPTO_HASH_ALG_SHA384:
42 alg_name = "sha384";
43 break;
44 case QCRYPTO_HASH_ALG_SHA512:
45 alg_name = "sha512";
46 break;
47 case QCRYPTO_HASH_ALG_RIPEMD160:
48 alg_name = "rmd160";
49 break;
50
51 default:
52 error_setg(errp, "Unsupported hash algorithm %d", alg);
53 return NULL;
54 }
55
56 name = g_strdup_printf("%s", alg_name);
57
58 return name;
59}
60
61static QCryptoAFAlg *
62qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, Error **errp)
63{
64 QCryptoAFAlg *afalg;
65 char *name;
66
67 name = qcrypto_afalg_hash_format_name(alg, errp);
68 if (!name) {
69 return NULL;
70 }
71
72 afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_HASH, name, errp);
73 if (!afalg) {
74 g_free(name);
75 return NULL;
76 }
77
78 g_free(name);
79
80 return afalg;
81}
82
83static int
84qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
85 const struct iovec *iov,
86 size_t niov, uint8_t **result,
87 size_t *resultlen,
88 Error **errp)
89{
90 QCryptoAFAlg *afalg;
91 struct iovec outv;
92 int ret = 0;
93 const int expect_len = qcrypto_hash_digest_len(alg);
94
95 if (*resultlen == 0) {
96 *resultlen = expect_len;
97 *result = g_new0(uint8_t, *resultlen);
98 } else if (*resultlen != expect_len) {
99 error_setg(errp,
100 "Result buffer size %zu is not match hash %d",
101 *resultlen, expect_len);
102 return -1;
103 }
104
105 afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
106 if (!afalg) {
107 return -1;
108 }
109
110 /* send data to kernel's crypto core */
111 ret = iov_send_recv(afalg->opfd, iov, niov,
112 0, iov_size(iov, niov), true);
113 if (ret < 0) {
114 error_setg_errno(errp, errno, "Send data to afalg-core failed");
115 goto out;
116 }
117
118 /* hash && get result */
119 outv.iov_base = *result;
120 outv.iov_len = *resultlen;
121 ret = iov_send_recv(afalg->opfd, &outv, 1,
122 0, iov_size(&outv, 1), false);
123 if (ret < 0) {
124 error_setg_errno(errp, errno, "Recv result from afalg-core failed");
125 } else {
126 ret = 0;
127 }
128
129out:
130 qcrypto_afalg_comm_free(afalg);
131 return ret;
132}
133
134QCryptoHashDriver qcrypto_hash_afalg_driver = {
135 .hash_bytesv = qcrypto_afalg_hash_bytesv,
136};