qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

crypto: hmac: add af_alg-backend hmac support

Adds afalg-backend hmac support: introduces some private APIs
firstly, and then intergrates them into qcrypto_hmac_afalg_driver.

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

authored by

Longpeng(Mike) and committed by
Daniel P. Berrange
42e7e15f 9a059773

+121 -17
+91 -13
crypto/hash-afalg.c
··· 1 1 /* 2 - * QEMU Crypto af_alg-backend hash support 2 + * QEMU Crypto af_alg-backend hash/hmac support 3 3 * 4 4 * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD. 5 5 * ··· 16 16 #include "qemu-common.h" 17 17 #include "qapi/error.h" 18 18 #include "crypto/hash.h" 19 + #include "crypto/hmac.h" 19 20 #include "hashpriv.h" 21 + #include "hmacpriv.h" 20 22 21 23 static char * 22 24 qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg, 25 + bool is_hmac, 23 26 Error **errp) 24 27 { 25 28 char *name; ··· 53 56 return NULL; 54 57 } 55 58 56 - name = g_strdup_printf("%s", alg_name); 59 + if (is_hmac) { 60 + name = g_strdup_printf("hmac(%s)", alg_name); 61 + } else { 62 + name = g_strdup_printf("%s", alg_name); 63 + } 57 64 58 65 return name; 59 66 } 60 67 61 68 static QCryptoAFAlg * 62 - qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, Error **errp) 69 + qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgorithm alg, 70 + const uint8_t *key, size_t nkey, 71 + bool is_hmac, Error **errp) 63 72 { 64 73 QCryptoAFAlg *afalg; 65 74 char *name; 66 75 67 - name = qcrypto_afalg_hash_format_name(alg, errp); 76 + name = qcrypto_afalg_hash_format_name(alg, is_hmac, errp); 68 77 if (!name) { 69 78 return NULL; 70 79 } ··· 77 86 78 87 g_free(name); 79 88 89 + /* HMAC needs setkey */ 90 + if (is_hmac) { 91 + if (qemu_setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY, 92 + key, nkey) != 0) { 93 + error_setg_errno(errp, errno, "Set hmac key failed"); 94 + qcrypto_afalg_comm_free(afalg); 95 + return NULL; 96 + } 97 + } 98 + 80 99 return afalg; 81 100 } 82 101 102 + static QCryptoAFAlg * 103 + qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, 104 + Error **errp) 105 + { 106 + return qcrypto_afalg_hash_hmac_ctx_new(alg, NULL, 0, false, errp); 107 + } 108 + 109 + QCryptoAFAlg * 110 + qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg, 111 + const uint8_t *key, size_t nkey, 112 + Error **errp) 113 + { 114 + return qcrypto_afalg_hash_hmac_ctx_new(alg, key, nkey, true, errp); 115 + } 116 + 83 117 static int 84 - qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg, 85 - const struct iovec *iov, 86 - size_t niov, uint8_t **result, 87 - size_t *resultlen, 88 - Error **errp) 118 + qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlg *hmac, 119 + QCryptoHashAlgorithm alg, 120 + const struct iovec *iov, 121 + size_t niov, uint8_t **result, 122 + size_t *resultlen, 123 + Error **errp) 89 124 { 90 125 QCryptoAFAlg *afalg; 91 126 struct iovec outv; 92 127 int ret = 0; 128 + bool is_hmac = (hmac != NULL) ? true : false; 93 129 const int expect_len = qcrypto_hash_digest_len(alg); 94 130 95 131 if (*resultlen == 0) { ··· 102 138 return -1; 103 139 } 104 140 105 - afalg = qcrypto_afalg_hash_ctx_new(alg, errp); 106 - if (!afalg) { 107 - return -1; 141 + if (is_hmac) { 142 + afalg = hmac; 143 + } else { 144 + afalg = qcrypto_afalg_hash_ctx_new(alg, errp); 145 + if (!afalg) { 146 + return -1; 147 + } 108 148 } 109 149 110 150 /* send data to kernel's crypto core */ ··· 127 167 } 128 168 129 169 out: 130 - qcrypto_afalg_comm_free(afalg); 170 + if (!is_hmac) { 171 + qcrypto_afalg_comm_free(afalg); 172 + } 131 173 return ret; 132 174 } 133 175 176 + static int 177 + qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg, 178 + const struct iovec *iov, 179 + size_t niov, uint8_t **result, 180 + size_t *resultlen, 181 + Error **errp) 182 + { 183 + return qcrypto_afalg_hash_hmac_bytesv(NULL, alg, iov, niov, result, 184 + resultlen, errp); 185 + } 186 + 187 + static int 188 + qcrypto_afalg_hmac_bytesv(QCryptoHmac *hmac, 189 + const struct iovec *iov, 190 + size_t niov, uint8_t **result, 191 + size_t *resultlen, 192 + Error **errp) 193 + { 194 + return qcrypto_afalg_hash_hmac_bytesv(hmac->opaque, hmac->alg, 195 + iov, niov, result, resultlen, 196 + errp); 197 + } 198 + 199 + static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac *hmac) 200 + { 201 + QCryptoAFAlg *afalg; 202 + 203 + afalg = hmac->opaque; 204 + qcrypto_afalg_comm_free(afalg); 205 + } 206 + 134 207 QCryptoHashDriver qcrypto_hash_afalg_driver = { 135 208 .hash_bytesv = qcrypto_afalg_hash_bytesv, 136 209 }; 210 + 211 + QCryptoHmacDriver qcrypto_hmac_afalg_driver = { 212 + .hmac_bytesv = qcrypto_afalg_hmac_bytesv, 213 + .hmac_free = qcrypto_afalg_hmac_ctx_free, 214 + };
+18 -4
crypto/hmac.c
··· 89 89 Error **errp) 90 90 { 91 91 QCryptoHmac *hmac; 92 - void *ctx; 92 + void *ctx = NULL; 93 + Error *err2 = NULL; 94 + QCryptoHmacDriver *drv = NULL; 93 95 94 - ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp); 96 + #ifdef CONFIG_AF_ALG 97 + ctx = qcrypto_afalg_hmac_ctx_new(alg, key, nkey, &err2); 98 + if (ctx) { 99 + drv = &qcrypto_hmac_afalg_driver; 100 + } 101 + #endif 102 + 95 103 if (!ctx) { 96 - return NULL; 104 + ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp); 105 + if (!ctx) { 106 + return NULL; 107 + } 108 + 109 + drv = &qcrypto_hmac_lib_driver; 110 + error_free(err2); 97 111 } 98 112 99 113 hmac = g_new0(QCryptoHmac, 1); 100 114 hmac->alg = alg; 101 115 hmac->opaque = ctx; 102 - hmac->driver = (void *)&qcrypto_hmac_lib_driver; 116 + hmac->driver = (void *)drv; 103 117 104 118 return hmac; 105 119 }
+12
crypto/hmacpriv.h
··· 33 33 Error **errp); 34 34 extern QCryptoHmacDriver qcrypto_hmac_lib_driver; 35 35 36 + #ifdef CONFIG_AF_ALG 37 + 38 + #include "afalgpriv.h" 39 + 40 + extern QCryptoAFAlg * 41 + qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg, 42 + const uint8_t *key, size_t nkey, 43 + Error **errp); 44 + extern QCryptoHmacDriver qcrypto_hmac_afalg_driver; 45 + 46 + #endif 47 + 36 48 #endif