* [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support
@ 2016-12-12 8:08 Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms Longpeng(Mike)
` (6 more replies)
0 siblings, 7 replies; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
Since QEMU has been supported cryptodev, so it is necessary to support
more crypto algorithms(i.e. hmac,aead) in QEMU backend.
This patchset add HMAC algorithms support.
---
Changes since v1:
- check whether algorithm is supported in testcase [build test]
---
Longpeng(Mike) (7):
qapi: crypto: add defination about HMAC algorithms
crypto: add HMAC algorithms framework
configure: add CONFIG_GCRYPT_SUPPORT_HMAC item
crypto: support HMAC algorithms based on libgcrypt
crypto: support HMAC algorithms based on glibc
crypto: support HMAC algorithms based on nettle
crypto: add HMAC algorithms testcases
configure | 18 +++++
crypto/Makefile.objs | 4 ++
crypto/hmac-gcrypt.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++
crypto/hmac-glib.c | 163 ++++++++++++++++++++++++++++++++++++++++++
crypto/hmac-nettle.c | 156 ++++++++++++++++++++++++++++++++++++++++
crypto/hmac.c | 72 +++++++++++++++++++
crypto/hmac.h | 166 ++++++++++++++++++++++++++++++++++++++++++
qapi/crypto.json | 17 +++++
tests/Makefile.include | 2 +
tests/test-crypto-hmac.c | 166 ++++++++++++++++++++++++++++++++++++++++++
10 files changed, 946 insertions(+)
create mode 100644 crypto/hmac-gcrypt.c
create mode 100644 crypto/hmac-glib.c
create mode 100644 crypto/hmac-nettle.c
create mode 100644 crypto/hmac.c
create mode 100644 crypto/hmac.h
create mode 100644 tests/test-crypto-hmac.c
--
1.8.3.1
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 10:13 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 2/7] crypto: add HMAC algorithms framework Longpeng(Mike)
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch introduce HMAC algorithms relevant defination, they will
be used by the following patch.
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
qapi/crypto.json | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/qapi/crypto.json b/qapi/crypto.json
index f4fd93b..e63862a 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -55,6 +55,23 @@
##
+# @QCryptoHmacAlgorithm:
+#
+# The supported algorithms for hash-based message authentication code
+#
+# @md5: HMAC-MD5
+# @sha1: HMAC-SHA1
+# @sha256: HMAC-SHA256
+# @sha512: HMAC-SHA512
+#
+# Since 2.9
+##
+{ 'enum': 'QCryptoHmacAlgorithm',
+ 'prefix': 'QCRYPTO_HMAC_ALG',
+ 'data': ['md5', 'sha1', 'sha256', 'sha512']}
+
+
+##
# @QCryptoCipherAlgorithm:
#
# The supported algorithms for content encryption ciphers
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 2/7] crypto: add HMAC algorithms framework
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 10:18 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 3/7] configure: add CONFIG_GCRYPT_SUPPORT_HMAC item Longpeng(Mike)
` (4 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch introduce HMAC algorithms framework.
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/Makefile.objs | 4 ++
crypto/hmac-gcrypt.c | 44 ++++++++++++++
crypto/hmac-glib.c | 44 ++++++++++++++
crypto/hmac-nettle.c | 44 ++++++++++++++
crypto/hmac.c | 72 ++++++++++++++++++++++
crypto/hmac.h | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 374 insertions(+)
create mode 100644 crypto/hmac-gcrypt.c
create mode 100644 crypto/hmac-glib.c
create mode 100644 crypto/hmac-nettle.c
create mode 100644 crypto/hmac.c
create mode 100644 crypto/hmac.h
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index a36d2d9..7978a46 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -3,6 +3,10 @@ crypto-obj-y += hash.o
crypto-obj-$(CONFIG_NETTLE) += hash-nettle.o
crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o
crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o
+crypto-obj-y += hmac.o
+crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o
+crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hmac-gcrypt.o
+crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hmac-glib.o
crypto-obj-y += aes.o
crypto-obj-y += desrfb.o
crypto-obj-y += cipher.o
diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
new file mode 100644
index 0000000..26f42bc
--- /dev/null
+++ b/crypto/hmac-gcrypt.c
@@ -0,0 +1,44 @@
+/*
+ * QEMU Crypto hmac algorithms (based on libgcrypt)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/hmac.h"
+
+bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
+{
+ return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ return NULL;
+}
+
+void qcrypto_hmac_free(QCryptoHmac *hmac)
+{
+ return;
+}
+
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ return -1;
+}
diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c
new file mode 100644
index 0000000..42f63c6
--- /dev/null
+++ b/crypto/hmac-glib.c
@@ -0,0 +1,44 @@
+/*
+ * QEMU Crypto hmac algorithms (based on glib)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/hmac.h"
+
+bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
+{
+ return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ return NULL;
+}
+
+void qcrypto_hmac_free(QCryptoHmac *hmac)
+{
+ return;
+}
+
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ return -1;
+}
diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
new file mode 100644
index 0000000..7a9cd2e
--- /dev/null
+++ b/crypto/hmac-nettle.c
@@ -0,0 +1,44 @@
+/*
+ * QEMU Crypto hmac algorithms (based on nettle)
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/hmac.h"
+
+bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
+{
+ return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ return NULL;
+}
+
+void qcrypto_hmac_free(QCryptoHmac *hmac)
+{
+ return;
+}
+
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ return -1;
+}
diff --git a/crypto/hmac.c b/crypto/hmac.c
new file mode 100644
index 0000000..5750405
--- /dev/null
+++ b/crypto/hmac.c
@@ -0,0 +1,72 @@
+/*
+ * QEMU Crypto hmac algorithms
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "crypto/hmac.h"
+
+static const char hex[] = "0123456789abcdef";
+
+int qcrypto_hmac_bytes(QCryptoHmac *hmac,
+ const char *buf,
+ size_t len,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ struct iovec iov = {
+ .iov_base = (char *)buf,
+ .iov_len = len
+ };
+
+ return qcrypto_hmac_bytesv(hmac, &iov, 1, result, resultlen, errp);
+}
+
+int qcrypto_hmac_digestv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ char **digest,
+ Error **errp)
+{
+ uint8_t *result = NULL;
+ size_t resultlen = 0;
+ size_t i;
+
+ if (qcrypto_hmac_bytesv(hmac, iov, niov, &result, &resultlen, errp) < 0) {
+ return -1;
+ }
+
+ *digest = g_new0(char, (resultlen * 2) + 1);
+
+ for (i = 0 ; i < resultlen ; i++) {
+ (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
+ (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
+ }
+
+ (*digest)[resultlen * 2] = '\0';
+
+ g_free(result);
+ return 0;
+}
+
+int qcrypto_hmac_digest(QCryptoHmac *hmac,
+ const char *buf,
+ size_t len,
+ char **digest,
+ Error **errp)
+{
+ struct iovec iov = {
+ .iov_base = (char *)buf,
+ .iov_len = len
+ };
+
+ return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp);
+}
diff --git a/crypto/hmac.h b/crypto/hmac.h
new file mode 100644
index 0000000..88b4d05
--- /dev/null
+++ b/crypto/hmac.h
@@ -0,0 +1,166 @@
+/*
+ * QEMU Crypto hmac algorithms
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#ifndef QCRYPTO_HMAC_H
+#define QCRYPTO_HMAC_H
+
+#include "qapi-types.h"
+
+typedef struct QCryptoHmac QCryptoHmac;
+struct QCryptoHmac {
+ QCryptoHmacAlgorithm alg;
+ void *opaque;
+};
+
+/**
+ * qcrypto_hmac_supports:
+ * @alg: the hmac algorithm
+ *
+ * Determine if @alg hmac algorithm is supported by
+ * the current configured build
+ *
+ * Returns:
+ * true if the algorithm is supported, false otherwise
+ */
+bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg);
+
+/**
+ * qcrypto_hmac_new:
+ * @alg: the hmac algorithm
+ * @key: the key bytes
+ * @nkey: the length of @key
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Creates a new hmac object with the algorithm @alg
+ *
+ * The @key parameter provides the bytes representing
+ * the secret key to use. The @nkey parameter specifies
+ * the length of @key in bytes
+ *
+ * Note: must use qcrypto_hmac_free() to release the
+ * returned hmac object when no longer required
+ *
+ * Returns:
+ * a new hmac object, or NULL on error
+ */
+QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp);
+
+/**
+ * qcrypto_hmac_free:
+ * @hmac: the hmac object
+ *
+ * Release the memory associated with @hmac that was
+ * previously allocated by qcrypto_hmac_new()
+ */
+void qcrypto_hmac_free(QCryptoHmac *hmac);
+
+/**
+ * qcrypto_hmac_bytesv:
+ * @hmac: the hmac object
+ * @iov: the array of memory regions to hmac
+ * @niov: the length of @iov
+ * @result: pointer to hold output hmac
+ * @resultlen: pointer to hold length of @result
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hmac across all the memory regions
+ * present in @iov. The @result pointer will be
+ * filled with raw bytes representing the computed
+ * hmac, which will have length @resultlen. The
+ * memory pointer in @result must be released
+ * with a call to g_free() when no longer required.
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ */
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp);
+
+/**
+ * qcrypto_hmac_bytes:
+ * @hmac: the hmac object
+ * @buf: the memory region to hmac
+ * @len: the length of @buf
+ * @result: pointer to hold output hmac
+ * @resultlen: pointer to hold length of @result
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hmac across all the memory region
+ * @buf of length @len. The @result pointer will be
+ * filled with raw bytes representing the computed
+ * hmac, which will have length @resultlen. The
+ * memory pointer in @result must be released
+ * with a call to g_free() when no longer required.
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ */
+int qcrypto_hmac_bytes(QCryptoHmac *hmac,
+ const char *buf,
+ size_t len,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp);
+
+/**
+ * qcrypto_hmac_digestv:
+ * @hmac: the hmac object
+ * @iov: the array of memory regions to hmac
+ * @niov: the length of @iov
+ * @digest: pointer to hold output hmac
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hmac across all the memory regions
+ * present in @iov. The @digest pointer will be
+ * filled with the printable hex digest of the computed
+ * hmac, which will be terminated by '\0'. The
+ * memory pointer in @digest must be released
+ * with a call to g_free() when no longer required.
+ *
+ * Returns:
+ * 0 on success, -1 on error
+ */
+int qcrypto_hmac_digestv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ char **digest,
+ Error **errp);
+
+/**
+ * qcrypto_hmac_digest:
+ * @hmac: the hmac object
+ * @buf: the memory region to hmac
+ * @len: the length of @buf
+ * @digest: pointer to hold output hmac
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hmac across all the memory region
+ * @buf of length @len. The @digest pointer will be
+ * filled with the printable hex digest of the computed
+ * hmac, which will be terminated by '\0'. The
+ * memory pointer in @digest must be released
+ * with a call to g_free() when no longer required.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hmac_digest(QCryptoHmac *hmac,
+ const char *buf,
+ size_t len,
+ char **digest,
+ Error **errp);
+
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 3/7] configure: add CONFIG_GCRYPT_SUPPORT_HMAC item
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 2/7] crypto: add HMAC algorithms framework Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 10:19 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 4/7] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
` (3 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This item will be used for support libcrypt-backed HMAC algorithms.
Support for hmac has been added in Libgcrypt 1.6.0, but we cannot
use pkg-config to get libcrypt's version. However we can make a
in configure to know whether current libcrypt support hmac.
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
configure | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/configure b/configure
index 3770d7c..6eb5f5c 100755
--- a/configure
+++ b/configure
@@ -2417,6 +2417,21 @@ EOF
if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
gcrypt_kdf=yes
fi
+
+ cat > $TMPC << EOF
+#include <gcrypt.h>
+int main(void) {
+ gcry_mac_hd_t handle;
+ gcry_mac_open(&handle, GCRY_MAC_HMAC_MD5,
+ GCRY_MAC_FLAG_SECURE, NULL);
+ return 0;
+}
+EOF
+ if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
+ gcrypy_support_hmac="yes"
+ else
+ gcrypy_support_hmac="no"
+ fi
else
if test "$gcrypt" = "yes"; then
feature_not_found "gcrypt" "Install gcrypt devel"
@@ -5387,6 +5402,9 @@ if test "$gnutls_rnd" = "yes" ; then
fi
if test "$gcrypt" = "yes" ; then
echo "CONFIG_GCRYPT=y" >> $config_host_mak
+ if test "gcrypy_support_hmac" = "yes" ; then
+ echo "CONFIG_GCRYPT_SUPPORT_HMAC=y" >> $config_host_mak
+ fi
if test "$gcrypt_kdf" = "yes" ; then
echo "CONFIG_GCRYPT_KDF=y" >> $config_host_mak
fi
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 4/7] crypto: support HMAC algorithms based on libgcrypt
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
` (2 preceding siblings ...)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 3/7] configure: add CONFIG_GCRYPT_SUPPORT_HMAC item Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 10:25 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 5/7] crypto: support HMAC algorithms based on glibc Longpeng(Mike)
` (2 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add HMAC algorithms based on libgcrypt support
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/hmac-gcrypt.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 138 insertions(+)
diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
index 26f42bc..6cf3046 100644
--- a/crypto/hmac-gcrypt.c
+++ b/crypto/hmac-gcrypt.c
@@ -15,6 +15,142 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "crypto/hmac.h"
+#include <gcrypt.h>
+
+#ifdef CONFIG_GCRYPT_SUPPORT_HMAC
+
+static int qcrypto_hmac_alg_map[QCRYPTO_HMAC_ALG__MAX] = {
+ [QCRYPTO_HMAC_ALG_MD5] = GCRY_MAC_HMAC_MD5,
+ [QCRYPTO_HMAC_ALG_SHA1] = GCRY_MAC_HMAC_SHA1,
+ [QCRYPTO_HMAC_ALG_SHA256] = GCRY_MAC_HMAC_SHA256,
+ [QCRYPTO_HMAC_ALG_SHA512] = GCRY_MAC_HMAC_SHA512,
+};
+
+typedef struct QCryptoHmacGcrypt QCryptoHmacGcrypt;
+struct QCryptoHmacGcrypt {
+ gcry_mac_hd_t handle;
+};
+
+bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
+{
+ if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
+ qcrypto_hmac_alg_map[alg] != GCRY_MAC_NONE) {
+ return true;
+ }
+
+ return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ QCryptoHmac *hmac;
+ QCryptoHmacGcrypt *ctx;
+ gcry_error_t err;
+
+ if (!qcrypto_hmac_supports(alg)) {
+ error_setg(errp, "Unsupported hmac algorithm %s",
+ QCryptoHmacAlgorithm_lookup[alg]);
+ return NULL;
+ }
+
+ hmac = g_new0(QCryptoHmac, 1);
+ hmac->alg = alg;
+
+ ctx = g_new0(QCryptoHmacGcrypt, 1);
+
+ err = gcry_mac_open(&ctx->handle, qcrypto_hmac_alg_map[alg],
+ GCRY_MAC_FLAG_SECURE, NULL);
+ if (err != 0) {
+ error_setg(errp, "Cannot initialize hmac: %s",
+ gcry_strerror(err));
+ goto error;
+ }
+
+ err = gcry_mac_setkey(ctx->handle, (const void *)key, nkey);
+ if (err != 0) {
+ error_setg(errp, "Cannot set key: %s",
+ gcry_strerror(err));
+ goto error;
+ }
+
+ hmac->opaque = ctx;
+ return hmac;
+
+error:
+ g_free(ctx);
+ g_free(hmac);
+ return NULL;
+}
+
+void qcrypto_hmac_free(QCryptoHmac *hmac)
+{
+ QCryptoHmacGcrypt *ctx;
+
+ if (!hmac) {
+ return;
+ }
+
+ ctx = hmac->opaque;
+ gcry_mac_close(ctx->handle);
+
+ g_free(ctx);
+ g_free(hmac);
+}
+
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ QCryptoHmacGcrypt *ctx;
+ gcry_error_t err;
+ uint32_t ret;
+ int i;
+
+ ctx = hmac->opaque;
+
+ for (i = 0; i < niov; i++) {
+ gcry_mac_write(ctx->handle, iov[i].iov_base, iov[i].iov_len);
+ }
+
+ ret = gcry_mac_get_algo_maclen(qcrypto_hmac_alg_map[hmac->alg]);
+ if (ret <= 0) {
+ error_setg(errp, "Unable to get hmac length: %s",
+ gcry_strerror(ret));
+ return -1;
+ }
+
+ if (*resultlen == 0) {
+ *resultlen = ret;
+ *result = g_new0(uint8_t, *resultlen);
+ } else if (*resultlen != ret) {
+ error_setg(errp, "Result buffer size %zu is smaller than hmac %d",
+ *resultlen, ret);
+ return -1;
+ }
+
+ err = gcry_mac_read(ctx->handle, *result, resultlen);
+ if (err != 0) {
+ error_setg(errp, "Cannot get result: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ err = gcry_mac_reset(ctx->handle);
+ if (err != 0) {
+ error_setg(errp, "Cannot reset hmac context: %s",
+ gcry_strerror(err));
+ return -1;
+ }
+
+ return 0;
+}
+
+#else
bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
{
@@ -42,3 +178,5 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
{
return -1;
}
+
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 5/7] crypto: support HMAC algorithms based on glibc
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
` (3 preceding siblings ...)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 4/7] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 6/7] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases Longpeng(Mike)
6 siblings, 0 replies; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add glibc-backed HMAC algorithms support
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/hmac-glib.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c
index 42f63c6..6a5f722 100644
--- a/crypto/hmac-glib.c
+++ b/crypto/hmac-glib.c
@@ -16,6 +16,123 @@
#include "qapi/error.h"
#include "crypto/hmac.h"
+/* Support for HMAC Algos has been added in GLib 2.30 */
+#if GLIB_CHECK_VERSION(2, 30, 0)
+
+static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
+ [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5,
+ [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1,
+ [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256,
+/* Support for HMAC SHA-512 in GLib 2.42 */
+#if GLIB_CHECK_VERSION(2, 42, 0)
+ [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512,
+#else
+ [QCRYPTO_HASH_ALG_SHA512] = -1,
+#endif
+};
+
+typedef struct QCryptoHmacGlib QCryptoHmacGlib;
+struct QCryptoHmacGlib {
+ GHmac *ghmac;
+};
+
+bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
+{
+ if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
+ qcrypto_hmac_alg_map[alg] != -1) {
+ return true;
+ }
+
+ return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp)
+{
+ QCryptoHmac *hmac;
+ QCryptoHmacGlib *ctx;
+
+ if (!qcrypto_hmac_supports(alg)) {
+ error_setg(errp, "Unsupported hmac algorithm %s",
+ QCryptoHmacAlgorithm_lookup[alg]);
+ return NULL;
+ }
+
+ hmac = g_new0(QCryptoHmac, 1);
+ hmac->alg = alg;
+
+ ctx = g_new0(QCryptoHmacGlib, 1);
+
+ ctx->ghmac = g_hmac_new(qcrypto_hmac_alg_map[alg],
+ (const uint8_t *)key, nkey);
+ if (!ctx->ghmac) {
+ error_setg(errp, "Cannot initialize hmac and set key");
+ goto error;
+ }
+
+ hmac->opaque = ctx;
+ return hmac;
+
+error:
+ g_free(ctx);
+ g_free(hmac);
+ return NULL;
+}
+
+void qcrypto_hmac_free(QCryptoHmac *hmac)
+{
+ QCryptoHmacGlib *ctx;
+
+ if (!hmac) {
+ return;
+ }
+
+ ctx = hmac->opaque;
+ g_hmac_unref(ctx->ghmac);
+
+ g_free(ctx);
+ g_free(hmac);
+}
+
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+ const struct iovec *iov,
+ size_t niov,
+ uint8_t **result,
+ size_t *resultlen,
+ Error **errp)
+{
+ QCryptoHmacGlib *ctx;
+ int i, ret;
+
+ ctx = hmac->opaque;
+
+ for (i = 0; i < niov; i++) {
+ g_hmac_update(ctx->ghmac, iov[i].iov_base, iov[i].iov_len);
+ }
+
+ ret = g_checksum_type_get_length(qcrypto_hmac_alg_map[hmac->alg]);
+ if (ret < 0) {
+ error_setg(errp, "Unable to get hmac length");
+ return -1;
+ }
+
+ if (*resultlen == 0) {
+ *resultlen = ret;
+ *result = g_new0(uint8_t, *resultlen);
+ } else if (*resultlen != ret) {
+ error_setg(errp, "Result buffer size %zu is smaller than hmac %d",
+ *resultlen, ret);
+ return -1;
+ }
+
+ g_hmac_get_digest(ctx->ghmac, *result, resultlen);
+
+ return 0;
+}
+
+#else
+
bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
{
return false;
@@ -42,3 +159,5 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
{
return -1;
}
+
+#endif
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 6/7] crypto: support HMAC algorithms based on nettle
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
` (4 preceding siblings ...)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 5/7] crypto: support HMAC algorithms based on glibc Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 10:28 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases Longpeng(Mike)
6 siblings, 1 reply; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add nettle-backed HMAC algorithms support
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
crypto/hmac-nettle.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 115 insertions(+), 3 deletions(-)
diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
index 7a9cd2e..a082bc0 100644
--- a/crypto/hmac-nettle.c
+++ b/crypto/hmac-nettle.c
@@ -15,9 +15,66 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "crypto/hmac.h"
+#include <nettle/hmac.h>
+
+typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx,
+ size_t key_length, const uint8_t *key);
+
+typedef void (*qcrypto_nettle_hmac_update)(void *ctx,
+ size_t length, const uint8_t *data);
+
+typedef void (*qcrypto_nettle_hmac_digest)(void *ctx,
+ size_t length, uint8_t *digest);
+
+typedef struct QCryptoHmacNettle QCryptoHmacNettle;
+struct QCryptoHmacNettle {
+ union qcrypto_nettle_hmac_ctx {
+ struct hmac_md5_ctx md5_ctx;
+ struct hmac_sha1_ctx sha1_ctx;
+ struct hmac_sha256_ctx sha256_ctx;
+ struct hmac_sha512_ctx sha512_ctx;
+ } u;
+};
+
+struct qcrypto_nettle_hmac_alg {
+ qcrypto_nettle_hmac_setkey setkey;
+ qcrypto_nettle_hmac_update update;
+ qcrypto_nettle_hmac_digest digest;
+ size_t len;
+} qcrypto_hmac_alg_map[QCRYPTO_HMAC_ALG__MAX] = {
+ [QCRYPTO_HMAC_ALG_MD5] = {
+ .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key,
+ .update = (qcrypto_nettle_hmac_update)hmac_md5_update,
+ .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest,
+ .len = MD5_DIGEST_SIZE,
+ },
+ [QCRYPTO_HMAC_ALG_SHA1] = {
+ .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key,
+ .update = (qcrypto_nettle_hmac_update)hmac_sha1_update,
+ .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest,
+ .len = SHA1_DIGEST_SIZE,
+ },
+ [QCRYPTO_HMAC_ALG_SHA256] = {
+ .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key,
+ .update = (qcrypto_nettle_hmac_update)hmac_sha256_update,
+ .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest,
+ .len = SHA256_DIGEST_SIZE,
+ },
+ [QCRYPTO_HMAC_ALG_SHA512] = {
+ .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key,
+ .update = (qcrypto_nettle_hmac_update)hmac_sha512_update,
+ .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest,
+ .len = SHA512_DIGEST_SIZE,
+ },
+};
bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
{
+ if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
+ qcrypto_hmac_alg_map[alg].setkey != NULL) {
+ return true;
+ }
+
return false;
}
@@ -25,12 +82,39 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
const uint8_t *key, size_t nkey,
Error **errp)
{
- return NULL;
+ QCryptoHmac *hmac;
+ QCryptoHmacNettle *ctx;
+
+ if (!qcrypto_hmac_supports(alg)) {
+ error_setg(errp, "Unsupported hmac algorithm %s",
+ QCryptoHmacAlgorithm_lookup[alg]);
+ return NULL;
+ }
+
+ hmac = g_new0(QCryptoHmac, 1);
+ hmac->alg = alg;
+
+ ctx = g_new0(QCryptoHmacNettle, 1);
+
+ qcrypto_hmac_alg_map[alg].setkey(&ctx->u, nkey, key);
+
+ hmac->opaque = ctx;
+
+ return hmac;
}
void qcrypto_hmac_free(QCryptoHmac *hmac)
{
- return;
+ QCryptoHmacNettle *ctx;
+
+ if (!hmac) {
+ return;
+ }
+
+ ctx = hmac->opaque;
+
+ g_free(ctx);
+ g_free(hmac);
}
int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
@@ -40,5 +124,33 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
size_t *resultlen,
Error **errp)
{
- return -1;
+ QCryptoHmacNettle *ctx;
+ int i;
+
+ ctx = (QCryptoHmacNettle *)hmac->opaque;
+
+ for (i = 0; i < niov; ++i) {
+ size_t len = iov[i].iov_len;
+ uint8_t *base = iov[i].iov_base;
+ while (len) {
+ size_t shortlen = MIN(len, UINT_MAX);
+ qcrypto_hmac_alg_map[hmac->alg].update(&ctx->u, len, base);
+ len -= shortlen;
+ base += len;
+ }
+ }
+
+ if (*resultlen == 0) {
+ *resultlen = qcrypto_hmac_alg_map[hmac->alg].len;
+ *result = g_new0(uint8_t, *resultlen);
+ } else if (*resultlen != qcrypto_hmac_alg_map[hmac->alg].len) {
+ error_setg(errp,
+ "Result buffer size %zu is smaller than hash %zu",
+ *resultlen, qcrypto_hmac_alg_map[hmac->alg].len);
+ return -1;
+ }
+
+ qcrypto_hmac_alg_map[hmac->alg].digest(&ctx->u, *resultlen, *result);
+
+ return 0;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
` (5 preceding siblings ...)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 6/7] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
@ 2016-12-12 8:08 ` Longpeng(Mike)
2016-12-12 10:31 ` Daniel P. Berrange
6 siblings, 1 reply; 15+ messages in thread
From: Longpeng(Mike) @ 2016-12-12 8:08 UTC (permalink / raw)
To: eblake, armbru, berrange, stefanha
Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)
This patch add HMAC algorithms testcases
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
tests/Makefile.include | 2 +
tests/test-crypto-hmac.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 168 insertions(+)
create mode 100644 tests/test-crypto-hmac.c
diff --git a/tests/Makefile.include b/tests/Makefile.include
index e98d3b6..4841d58 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -91,6 +91,7 @@ gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
check-unit-y += tests/test-write-threshold$(EXESUF)
gcov-files-test-write-threshold-y = block/write-threshold.c
check-unit-y += tests/test-crypto-hash$(EXESUF)
+check-unit-y += tests/test-crypto-hmac$(EXESUF)
check-unit-y += tests/test-crypto-cipher$(EXESUF)
check-unit-y += tests/test-crypto-secret$(EXESUF)
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
@@ -571,6 +572,7 @@ tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
+tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
diff --git a/tests/test-crypto-hmac.c b/tests/test-crypto-hmac.c
new file mode 100644
index 0000000..678df52
--- /dev/null
+++ b/tests/test-crypto-hmac.c
@@ -0,0 +1,166 @@
+/*
+ * QEMU Crypto hmac algorithms tests
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ * Longpeng(Mike) <longpeng2@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "crypto/init.h"
+#include "crypto/hmac.h"
+
+typedef struct QCryptoHmacTestData QCryptoHmacTestData;
+struct QCryptoHmacTestData {
+ const char *path;
+ QCryptoHmacAlgorithm alg;
+ const char *key;
+ const char *message;
+ const char *digest;
+};
+
+static QCryptoHmacTestData test_data[] = {
+ {
+ .path = "/crypto/hmac/hmac-md5",
+ .alg = QCRYPTO_HMAC_ALG_MD5,
+ .key =
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ .message =
+ "4869205468657265",
+ .digest =
+ "9294727a3638bb1c13f48ef8158bfc9d",
+ },
+ {
+ .path = "/crypto/hmac/hmac-sha1",
+ .alg = QCRYPTO_HMAC_ALG_SHA1,
+ .key =
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
+ "0b0b0b0b",
+ .message =
+ "4869205468657265",
+ .digest =
+ "b617318655057264e28bc0b6fb378c8e"
+ "f146be00",
+ },
+};
+
+static inline int unhex(char c)
+{
+ if (c >= 'a' && c <= 'f') {
+ return 10 + (c - 'a');
+ }
+ if (c >= 'A' && c <= 'F') {
+ return 10 + (c - 'A');
+ }
+ return c - '0';
+}
+
+static inline char hex(int i)
+{
+ if (i < 10) {
+ return '0' + i;
+ }
+ return 'a' + (i - 10);
+}
+
+static size_t unhex_string(const char *hexstr,
+ uint8_t **data)
+{
+ size_t len;
+ size_t i;
+
+ if (!hexstr) {
+ *data = NULL;
+ return 0;
+ }
+
+ len = strlen(hexstr);
+ *data = g_new0(uint8_t, len / 2);
+
+ for (i = 0; i < len; i += 2) {
+ (*data)[i / 2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i + 1]);
+ }
+ return len / 2;
+}
+
+static char *hex_string(const uint8_t *bytes,
+ size_t len)
+{
+ char *hexstr = g_new0(char, len * 2 + 1);
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ hexstr[i * 2] = hex((bytes[i] >> 4) & 0xf);
+ hexstr[i * 2 + 1] = hex(bytes[i] & 0xf);
+ }
+ hexstr[len * 2] = '\0';
+
+ return hexstr;
+}
+
+static void test_hmac(const void *opaque)
+{
+ const QCryptoHmacTestData *data = opaque;
+ size_t nkey, digest_len, msg_len;
+ uint8_t *key = NULL;
+ uint8_t *message = NULL;
+ uint8_t *digest = NULL;
+ uint8_t *output = NULL;
+ char *outputhex = NULL;
+ QCryptoHmac *hmac = NULL;
+ Error *err = NULL;
+ int ret;
+
+ if (!qcrypto_hmac_supports(data->alg)) {
+ return;
+ }
+
+ nkey = unhex_string(data->key, &key);
+ digest_len = unhex_string(data->digest, &digest);
+ msg_len = unhex_string(data->message, &message);
+
+ output = g_new0(uint8_t, digest_len);
+
+ hmac = qcrypto_hmac_new(data->alg, key, nkey, &err);
+ g_assert(err == NULL);
+ g_assert(hmac != NULL);
+
+ ret = qcrypto_hmac_bytes(hmac, (const char *)message,
+ msg_len, &output, &digest_len, &err);
+
+ g_assert(ret == 0);
+
+ outputhex = hex_string(output, digest_len);
+
+ g_assert_cmpstr(outputhex, ==, data->digest);
+
+ qcrypto_hmac_free(hmac);
+
+ g_free(outputhex);
+ g_free(output);
+ g_free(message);
+ g_free(digest);
+ g_free(key);
+}
+
+int main(int argc, char **argv)
+{
+ size_t i;
+
+ g_test_init(&argc, &argv, NULL);
+
+ g_assert(qcrypto_init(NULL) == 0);
+
+ for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
+ g_test_add_data_func(test_data[i].path,
+ &test_data[i], test_hmac);
+ }
+
+ return g_test_run();
+}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms Longpeng(Mike)
@ 2016-12-12 10:13 ` Daniel P. Berrange
0 siblings, 0 replies; 15+ messages in thread
From: Daniel P. Berrange @ 2016-12-12 10:13 UTC (permalink / raw)
To: Longpeng(Mike)
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
On Mon, Dec 12, 2016 at 04:08:06PM +0800, Longpeng(Mike) wrote:
> This patch introduce HMAC algorithms relevant defination, they will
> be used by the following patch.
>
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
> qapi/crypto.json | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/qapi/crypto.json b/qapi/crypto.json
> index f4fd93b..e63862a 100644
> --- a/qapi/crypto.json
> +++ b/qapi/crypto.json
> @@ -55,6 +55,23 @@
>
>
> ##
> +# @QCryptoHmacAlgorithm:
> +#
> +# The supported algorithms for hash-based message authentication code
> +#
> +# @md5: HMAC-MD5
> +# @sha1: HMAC-SHA1
> +# @sha256: HMAC-SHA256
> +# @sha512: HMAC-SHA512
> +#
> +# Since 2.9
> +##
> +{ 'enum': 'QCryptoHmacAlgorithm',
> + 'prefix': 'QCRYPTO_HMAC_ALG',
> + 'data': ['md5', 'sha1', 'sha256', 'sha512']}
There's not actually any concept of hmac algorithms - you have standard
hash algorithms used in the hmac calculation. IOW, you don't need to
add this enum. The hmac APIs should just use QCryptoHashAlgorithm as
their input.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 2/7] crypto: add HMAC algorithms framework
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 2/7] crypto: add HMAC algorithms framework Longpeng(Mike)
@ 2016-12-12 10:18 ` Daniel P. Berrange
0 siblings, 0 replies; 15+ messages in thread
From: Daniel P. Berrange @ 2016-12-12 10:18 UTC (permalink / raw)
To: Longpeng(Mike)
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
On Mon, Dec 12, 2016 at 04:08:07PM +0800, Longpeng(Mike) wrote:
> This patch introduce HMAC algorithms framework.
>
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
> crypto/Makefile.objs | 4 ++
> crypto/hmac-gcrypt.c | 44 ++++++++++++++
> crypto/hmac-glib.c | 44 ++++++++++++++
> crypto/hmac-nettle.c | 44 ++++++++++++++
> crypto/hmac.c | 72 ++++++++++++++++++++++
> crypto/hmac.h | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 374 insertions(+)
> create mode 100644 crypto/hmac-gcrypt.c
> create mode 100644 crypto/hmac-glib.c
> create mode 100644 crypto/hmac-nettle.c
> create mode 100644 crypto/hmac.c
> create mode 100644 crypto/hmac.h
>
> diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
> new file mode 100644
> index 0000000..26f42bc
> --- /dev/null
> +++ b/crypto/hmac-gcrypt.c
> @@ -0,0 +1,44 @@
> +/*
> + * QEMU Crypto hmac algorithms (based on libgcrypt)
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * Authors:
> + * Longpeng(Mike) <longpeng2@huawei.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "crypto/hmac.h"
> +
> +bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
> +{
> + return false;
> +}
> +
> +QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
> + const uint8_t *key, size_t nkey,
> + Error **errp)
Nitpick, can you fix alignment of the lines wrt to the "("
> +{
> + return NULL;
> +}
> +
> +void qcrypto_hmac_free(QCryptoHmac *hmac)
> +{
> + return;
> +}
> +
> +int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
> + const struct iovec *iov,
> + size_t niov,
> + uint8_t **result,
> + size_t *resultlen,
> + Error **errp)
> +{
> + return -1;
> +}
> diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c
> new file mode 100644
> index 0000000..42f63c6
> --- /dev/null
> +++ b/crypto/hmac-glib.c
> @@ -0,0 +1,44 @@
> +/*
> + * QEMU Crypto hmac algorithms (based on glib)
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * Authors:
> + * Longpeng(Mike) <longpeng2@huawei.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "crypto/hmac.h"
> +
> +bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
> +{
> + return false;
> +}
> +
> +QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
> + const uint8_t *key, size_t nkey,
> + Error **errp)
Nitpick, can you fix alignment of the lines wrt to the "("
> +{
> + return NULL;
> +}
> +
> +void qcrypto_hmac_free(QCryptoHmac *hmac)
> +{
> + return;
> +}
> +
> +int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
> + const struct iovec *iov,
> + size_t niov,
> + uint8_t **result,
> + size_t *resultlen,
> + Error **errp)
> +{
> + return -1;
> +}
> diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
> new file mode 100644
> index 0000000..7a9cd2e
> --- /dev/null
> +++ b/crypto/hmac-nettle.c
> @@ -0,0 +1,44 @@
> +/*
> + * QEMU Crypto hmac algorithms (based on nettle)
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * Authors:
> + * Longpeng(Mike) <longpeng2@huawei.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "crypto/hmac.h"
> +
> +bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
> +{
> + return false;
> +}
> +
> +QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
> + const uint8_t *key, size_t nkey,
> + Error **errp)
Nitpick, can you fix alignment of the lines wrt to the "("
> +{
> + return NULL;
> +}
> +
> +void qcrypto_hmac_free(QCryptoHmac *hmac)
> +{
> + return;
> +}
> +
> +int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
> + const struct iovec *iov,
> + size_t niov,
> + uint8_t **result,
> + size_t *resultlen,
> + Error **errp)
> +{
> + return -1;
> +}
> diff --git a/crypto/hmac.c b/crypto/hmac.c
> new file mode 100644
> index 0000000..5750405
> --- /dev/null
> +++ b/crypto/hmac.c
> @@ -0,0 +1,72 @@
> +/*
> + * QEMU Crypto hmac algorithms
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
> +#include "crypto/hmac.h"
> +
> +static const char hex[] = "0123456789abcdef";
> +
> +int qcrypto_hmac_bytes(QCryptoHmac *hmac,
> + const char *buf,
> + size_t len,
> + uint8_t **result,
> + size_t *resultlen,
> + Error **errp)
> +{
> + struct iovec iov = {
> + .iov_base = (char *)buf,
> + .iov_len = len
> + };
> +
> + return qcrypto_hmac_bytesv(hmac, &iov, 1, result, resultlen, errp);
> +}
> +
> +int qcrypto_hmac_digestv(QCryptoHmac *hmac,
> + const struct iovec *iov,
> + size_t niov,
> + char **digest,
> + Error **errp)
> +{
> + uint8_t *result = NULL;
> + size_t resultlen = 0;
> + size_t i;
> +
> + if (qcrypto_hmac_bytesv(hmac, iov, niov, &result, &resultlen, errp) < 0) {
> + return -1;
> + }
> +
> + *digest = g_new0(char, (resultlen * 2) + 1);
> +
> + for (i = 0 ; i < resultlen ; i++) {
> + (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf];
> + (*digest)[(i * 2) + 1] = hex[result[i] & 0xf];
> + }
> +
> + (*digest)[resultlen * 2] = '\0';
> +
> + g_free(result);
> + return 0;
> +}
> +
> +int qcrypto_hmac_digest(QCryptoHmac *hmac,
> + const char *buf,
> + size_t len,
> + char **digest,
> + Error **errp)
> +{
> + struct iovec iov = {
> + .iov_base = (char *)buf,
> + .iov_len = len
> + };
> +
> + return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp);
> +}
> diff --git a/crypto/hmac.h b/crypto/hmac.h
> new file mode 100644
> index 0000000..88b4d05
> --- /dev/null
> +++ b/crypto/hmac.h
> @@ -0,0 +1,166 @@
> +/*
> + * QEMU Crypto hmac algorithms
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + *
> + */
> +
> +#ifndef QCRYPTO_HMAC_H
> +#define QCRYPTO_HMAC_H
> +
> +#include "qapi-types.h"
> +
> +typedef struct QCryptoHmac QCryptoHmac;
> +struct QCryptoHmac {
> + QCryptoHmacAlgorithm alg;
> + void *opaque;
> +};
> +
> +/**
> + * qcrypto_hmac_supports:
> + * @alg: the hmac algorithm
> + *
> + * Determine if @alg hmac algorithm is supported by
> + * the current configured build
> + *
> + * Returns:
> + * true if the algorithm is supported, false otherwise
> + */
> +bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg);
> +
> +/**
> + * qcrypto_hmac_new:
> + * @alg: the hmac algorithm
> + * @key: the key bytes
> + * @nkey: the length of @key
> + * @errp: pointer to a NULL-initialized error object
> + *
> + * Creates a new hmac object with the algorithm @alg
> + *
> + * The @key parameter provides the bytes representing
> + * the secret key to use. The @nkey parameter specifies
> + * the length of @key in bytes
> + *
> + * Note: must use qcrypto_hmac_free() to release the
> + * returned hmac object when no longer required
> + *
> + * Returns:
> + * a new hmac object, or NULL on error
> + */
> +QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
> + const uint8_t *key, size_t nkey,
> + Error **errp);
Nitpick, can you fix alignment of the lines wrt to the "("
Also change it to use QCryptoHashAlgorithm in first parameter.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 3/7] configure: add CONFIG_GCRYPT_SUPPORT_HMAC item
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 3/7] configure: add CONFIG_GCRYPT_SUPPORT_HMAC item Longpeng(Mike)
@ 2016-12-12 10:19 ` Daniel P. Berrange
0 siblings, 0 replies; 15+ messages in thread
From: Daniel P. Berrange @ 2016-12-12 10:19 UTC (permalink / raw)
To: Longpeng(Mike)
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
On Mon, Dec 12, 2016 at 04:08:08PM +0800, Longpeng(Mike) wrote:
> This item will be used for support libcrypt-backed HMAC algorithms.
>
> Support for hmac has been added in Libgcrypt 1.6.0, but we cannot
> use pkg-config to get libcrypt's version. However we can make a
> in configure to know whether current libcrypt support hmac.
>
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
> configure | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/configure b/configure
> index 3770d7c..6eb5f5c 100755
> --- a/configure
> +++ b/configure
> @@ -2417,6 +2417,21 @@ EOF
> if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
> gcrypt_kdf=yes
> fi
> +
> + cat > $TMPC << EOF
> +#include <gcrypt.h>
> +int main(void) {
> + gcry_mac_hd_t handle;
> + gcry_mac_open(&handle, GCRY_MAC_HMAC_MD5,
> + GCRY_MAC_FLAG_SECURE, NULL);
> + return 0;
> +}
> +EOF
> + if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
> + gcrypy_support_hmac="yes"
Typo, s/gcrypy/gcrypt/, and repeated a few lines later too
> + else
> + gcrypy_support_hmac="no"
> + fi
For consistency with the KDF probe, just remove the word 'support_'
from this
> else
> if test "$gcrypt" = "yes"; then
> feature_not_found "gcrypt" "Install gcrypt devel"
> @@ -5387,6 +5402,9 @@ if test "$gnutls_rnd" = "yes" ; then
> fi
> if test "$gcrypt" = "yes" ; then
> echo "CONFIG_GCRYPT=y" >> $config_host_mak
> + if test "gcrypy_support_hmac" = "yes" ; then
> + echo "CONFIG_GCRYPT_SUPPORT_HMAC=y" >> $config_host_mak
> + fi
And again s/support//
> if test "$gcrypt_kdf" = "yes" ; then
> echo "CONFIG_GCRYPT_KDF=y" >> $config_host_mak
> fi
> --
> 1.8.3.1
>
>
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 4/7] crypto: support HMAC algorithms based on libgcrypt
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 4/7] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
@ 2016-12-12 10:25 ` Daniel P. Berrange
0 siblings, 0 replies; 15+ messages in thread
From: Daniel P. Berrange @ 2016-12-12 10:25 UTC (permalink / raw)
To: Longpeng(Mike)
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
On Mon, Dec 12, 2016 at 04:08:09PM +0800, Longpeng(Mike) wrote:
> This patch add HMAC algorithms based on libgcrypt support
>
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
> crypto/hmac-gcrypt.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 138 insertions(+)
>
> diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
> index 26f42bc..6cf3046 100644
> --- a/crypto/hmac-gcrypt.c
> +++ b/crypto/hmac-gcrypt.c
> @@ -15,6 +15,142 @@
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> #include "crypto/hmac.h"
> +#include <gcrypt.h>
> +
> +#ifdef CONFIG_GCRYPT_SUPPORT_HMAC
You shouldn't use this conditional in the code. Instead, you should
use it in crypto/Makefile.objs, so that this file is only ever
compiled when CONFIG_GCRYPTO_HMAC is set - see the way we deal
with CONFIG_NETTLE_KDF for example.
> +static int qcrypto_hmac_alg_map[QCRYPTO_HMAC_ALG__MAX] = {
> + [QCRYPTO_HMAC_ALG_MD5] = GCRY_MAC_HMAC_MD5,
> + [QCRYPTO_HMAC_ALG_SHA1] = GCRY_MAC_HMAC_SHA1,
> + [QCRYPTO_HMAC_ALG_SHA256] = GCRY_MAC_HMAC_SHA256,
> + [QCRYPTO_HMAC_ALG_SHA512] = GCRY_MAC_HMAC_SHA512,
> +};
Since I requested use of existing QCRYPTO_HASH_ALG_* constants,
can you expand this to handle all 7 hash algoriths we have defined
for qemu
> +QCryptoHmac *qcrypto_hmac_new(QCryptoHmacAlgorithm alg,
> + const uint8_t *key, size_t nkey,
> + Error **errp)
Nitpick, indentation wrt '('
> +{
> + QCryptoHmac *hmac;
> + QCryptoHmacGcrypt *ctx;
> + gcry_error_t err;
> +
> + if (!qcrypto_hmac_supports(alg)) {
> + error_setg(errp, "Unsupported hmac algorithm %s",
> + QCryptoHmacAlgorithm_lookup[alg]);
Again, nitpick on indentation wrt '('
> + return NULL;
> + }
> +
> + hmac = g_new0(QCryptoHmac, 1);
> + hmac->alg = alg;
> +
> + ctx = g_new0(QCryptoHmacGcrypt, 1);
> +
> + err = gcry_mac_open(&ctx->handle, qcrypto_hmac_alg_map[alg],
> + GCRY_MAC_FLAG_SECURE, NULL);
Again, nitpick on indentation
> + if (err != 0) {
> + error_setg(errp, "Cannot initialize hmac: %s",
> + gcry_strerror(err));
Again
> + goto error;
> + }
> +
> + err = gcry_mac_setkey(ctx->handle, (const void *)key, nkey);
> + if (err != 0) {
> + error_setg(errp, "Cannot set key: %s",
> + gcry_strerror(err));
Again. I'll stop repeating this now - just fix up all indentation
through this file and all remaining patches in the series.
> + goto error;
> + }
> +
> + hmac->opaque = ctx;
> + return hmac;
> +
> +error:
> + g_free(ctx);
> + g_free(hmac);
> + return NULL;
> +}
> +
> +void qcrypto_hmac_free(QCryptoHmac *hmac)
> +{
> + QCryptoHmacGcrypt *ctx;
> +
> + if (!hmac) {
> + return;
> + }
> +
> + ctx = hmac->opaque;
> + gcry_mac_close(ctx->handle);
> +
> + g_free(ctx);
> + g_free(hmac);
> +}
> +
> +int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
> + const struct iovec *iov,
> + size_t niov,
> + uint8_t **result,
> + size_t *resultlen,
> + Error **errp)
> +{
> + QCryptoHmacGcrypt *ctx;
> + gcry_error_t err;
> + uint32_t ret;
> + int i;
> +
> + ctx = hmac->opaque;
> +
> + for (i = 0; i < niov; i++) {
> + gcry_mac_write(ctx->handle, iov[i].iov_base, iov[i].iov_len);
> + }
> +
> + ret = gcry_mac_get_algo_maclen(qcrypto_hmac_alg_map[hmac->alg]);
> + if (ret <= 0) {
> + error_setg(errp, "Unable to get hmac length: %s",
> + gcry_strerror(ret));
> + return -1;
> + }
> +
> + if (*resultlen == 0) {
> + *resultlen = ret;
> + *result = g_new0(uint8_t, *resultlen);
> + } else if (*resultlen != ret) {
> + error_setg(errp, "Result buffer size %zu is smaller than hmac %d",
> + *resultlen, ret);
> + return -1;
> + }
> +
> + err = gcry_mac_read(ctx->handle, *result, resultlen);
> + if (err != 0) {
> + error_setg(errp, "Cannot get result: %s",
> + gcry_strerror(err));
> + return -1;
> + }
> +
> + err = gcry_mac_reset(ctx->handle);
> + if (err != 0) {
> + error_setg(errp, "Cannot reset hmac context: %s",
> + gcry_strerror(err));
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +#else
>
> bool qcrypto_hmac_supports(QCryptoHmacAlgorithm alg)
> {
> @@ -42,3 +178,5 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
> {
> return -1;
> }
> +
> +#endif
You shouldn't need this else block either, since we should never
compile any no-op code - we want to compile hmac-glib instead
if gcrypt doesn't do hmac
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 6/7] crypto: support HMAC algorithms based on nettle
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 6/7] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
@ 2016-12-12 10:28 ` Daniel P. Berrange
0 siblings, 0 replies; 15+ messages in thread
From: Daniel P. Berrange @ 2016-12-12 10:28 UTC (permalink / raw)
To: Longpeng(Mike)
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
On Mon, Dec 12, 2016 at 04:08:11PM +0800, Longpeng(Mike) wrote:
> This patch add nettle-backed HMAC algorithms support
>
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
> crypto/hmac-nettle.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 115 insertions(+), 3 deletions(-)
>
> diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
> index 7a9cd2e..a082bc0 100644
> --- a/crypto/hmac-nettle.c
> +++ b/crypto/hmac-nettle.c
> @@ -15,9 +15,66 @@
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> #include "crypto/hmac.h"
> +#include <nettle/hmac.h>
> +
> +typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx,
> + size_t key_length, const uint8_t *key);
> +
> +typedef void (*qcrypto_nettle_hmac_update)(void *ctx,
> + size_t length, const uint8_t *data);
> +
> +typedef void (*qcrypto_nettle_hmac_digest)(void *ctx,
> + size_t length, uint8_t *digest);
> +
> +typedef struct QCryptoHmacNettle QCryptoHmacNettle;
> +struct QCryptoHmacNettle {
> + union qcrypto_nettle_hmac_ctx {
> + struct hmac_md5_ctx md5_ctx;
> + struct hmac_sha1_ctx sha1_ctx;
> + struct hmac_sha256_ctx sha256_ctx;
> + struct hmac_sha512_ctx sha512_ctx;
> + } u;
> +};
> +
> +struct qcrypto_nettle_hmac_alg {
> + qcrypto_nettle_hmac_setkey setkey;
> + qcrypto_nettle_hmac_update update;
> + qcrypto_nettle_hmac_digest digest;
> + size_t len;
> +} qcrypto_hmac_alg_map[QCRYPTO_HMAC_ALG__MAX] = {
> + [QCRYPTO_HMAC_ALG_MD5] = {
> + .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key,
> + .update = (qcrypto_nettle_hmac_update)hmac_md5_update,
> + .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest,
> + .len = MD5_DIGEST_SIZE,
> + },
> + [QCRYPTO_HMAC_ALG_SHA1] = {
> + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key,
> + .update = (qcrypto_nettle_hmac_update)hmac_sha1_update,
> + .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest,
> + .len = SHA1_DIGEST_SIZE,
> + },
> + [QCRYPTO_HMAC_ALG_SHA256] = {
> + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key,
> + .update = (qcrypto_nettle_hmac_update)hmac_sha256_update,
> + .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest,
> + .len = SHA256_DIGEST_SIZE,
> + },
> + [QCRYPTO_HMAC_ALG_SHA512] = {
> + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key,
> + .update = (qcrypto_nettle_hmac_update)hmac_sha512_update,
> + .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest,
> + .len = SHA512_DIGEST_SIZE,
> + },
> +};
Can you implement all 7 hash algorithms supported by QEMU.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases Longpeng(Mike)
@ 2016-12-12 10:31 ` Daniel P. Berrange
2016-12-13 7:06 ` Longpeng (Mike)
0 siblings, 1 reply; 15+ messages in thread
From: Daniel P. Berrange @ 2016-12-12 10:31 UTC (permalink / raw)
To: Longpeng(Mike)
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
On Mon, Dec 12, 2016 at 04:08:12PM +0800, Longpeng(Mike) wrote:
> This patch add HMAC algorithms testcases
>
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
> tests/Makefile.include | 2 +
> tests/test-crypto-hmac.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 168 insertions(+)
> create mode 100644 tests/test-crypto-hmac.c
>
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index e98d3b6..4841d58 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -91,6 +91,7 @@ gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
> check-unit-y += tests/test-write-threshold$(EXESUF)
> gcov-files-test-write-threshold-y = block/write-threshold.c
> check-unit-y += tests/test-crypto-hash$(EXESUF)
> +check-unit-y += tests/test-crypto-hmac$(EXESUF)
> check-unit-y += tests/test-crypto-cipher$(EXESUF)
> check-unit-y += tests/test-crypto-secret$(EXESUF)
> check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
> @@ -571,6 +572,7 @@ tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
> tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
> tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
> tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
> +tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
> tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
> tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
> tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
> diff --git a/tests/test-crypto-hmac.c b/tests/test-crypto-hmac.c
> new file mode 100644
> index 0000000..678df52
> --- /dev/null
> +++ b/tests/test-crypto-hmac.c
> @@ -0,0 +1,166 @@
> +/*
> + * QEMU Crypto hmac algorithms tests
> + *
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + *
> + * Authors:
> + * Longpeng(Mike) <longpeng2@huawei.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * (at your option) any later version. See the COPYING file in the
> + * top-level directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "crypto/init.h"
> +#include "crypto/hmac.h"
> +
> +typedef struct QCryptoHmacTestData QCryptoHmacTestData;
> +struct QCryptoHmacTestData {
> + const char *path;
> + QCryptoHmacAlgorithm alg;
> + const char *key;
> + const char *message;
> + const char *digest;
> +};
> +
> +static QCryptoHmacTestData test_data[] = {
> + {
> + .path = "/crypto/hmac/hmac-md5",
> + .alg = QCRYPTO_HMAC_ALG_MD5,
> + .key =
> + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
> + .message =
> + "4869205468657265",
> + .digest =
> + "9294727a3638bb1c13f48ef8158bfc9d",
> + },
> + {
> + .path = "/crypto/hmac/hmac-sha1",
> + .alg = QCRYPTO_HMAC_ALG_SHA1,
> + .key =
> + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
> + "0b0b0b0b",
> + .message =
> + "4869205468657265",
> + .digest =
> + "b617318655057264e28bc0b6fb378c8e"
> + "f146be00",
> + },
> +};
This is quite weak test coverage - it needs to cover all 7 hash algorithms
> +
> +static inline int unhex(char c)
> +{
> + if (c >= 'a' && c <= 'f') {
> + return 10 + (c - 'a');
> + }
> + if (c >= 'A' && c <= 'F') {
> + return 10 + (c - 'A');
> + }
> + return c - '0';
> +}
> +
> +static inline char hex(int i)
> +{
> + if (i < 10) {
> + return '0' + i;
> + }
> + return 'a' + (i - 10);
> +}
> +
> +static size_t unhex_string(const char *hexstr,
> + uint8_t **data)
> +{
> + size_t len;
> + size_t i;
> +
> + if (!hexstr) {
> + *data = NULL;
> + return 0;
> + }
> +
> + len = strlen(hexstr);
> + *data = g_new0(uint8_t, len / 2);
> +
> + for (i = 0; i < len; i += 2) {
> + (*data)[i / 2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i + 1]);
> + }
> + return len / 2;
> +}
> +
> +static char *hex_string(const uint8_t *bytes,
> + size_t len)
> +{
> + char *hexstr = g_new0(char, len * 2 + 1);
> + size_t i;
> +
> + for (i = 0; i < len; i++) {
> + hexstr[i * 2] = hex((bytes[i] >> 4) & 0xf);
> + hexstr[i * 2 + 1] = hex(bytes[i] & 0xf);
> + }
> + hexstr[len * 2] = '\0';
> +
> + return hexstr;
> +}
> +
> +static void test_hmac(const void *opaque)
> +{
> + const QCryptoHmacTestData *data = opaque;
> + size_t nkey, digest_len, msg_len;
> + uint8_t *key = NULL;
> + uint8_t *message = NULL;
> + uint8_t *digest = NULL;
> + uint8_t *output = NULL;
> + char *outputhex = NULL;
> + QCryptoHmac *hmac = NULL;
> + Error *err = NULL;
> + int ret;
> +
> + if (!qcrypto_hmac_supports(data->alg)) {
> + return;
> + }
> +
> + nkey = unhex_string(data->key, &key);
> + digest_len = unhex_string(data->digest, &digest);
> + msg_len = unhex_string(data->message, &message);
> +
> + output = g_new0(uint8_t, digest_len);
> +
> + hmac = qcrypto_hmac_new(data->alg, key, nkey, &err);
> + g_assert(err == NULL);
> + g_assert(hmac != NULL);
> +
> + ret = qcrypto_hmac_bytes(hmac, (const char *)message,
> + msg_len, &output, &digest_len, &err);
> +
> + g_assert(ret == 0);
> +
> + outputhex = hex_string(output, digest_len);
> +
> + g_assert_cmpstr(outputhex, ==, data->digest);
> +
> + qcrypto_hmac_free(hmac);
> +
> + g_free(outputhex);
> + g_free(output);
> + g_free(message);
> + g_free(digest);
> + g_free(key);
> +}
We need to cover qcrypto_hmac_bytesv and qcrypto_hmac_digest
methods too.
IOW, can you simply copy the test-crypto-hash.c test suite entirely
but remove the base64 part of it.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases
2016-12-12 10:31 ` Daniel P. Berrange
@ 2016-12-13 7:06 ` Longpeng (Mike)
0 siblings, 0 replies; 15+ messages in thread
From: Longpeng (Mike) @ 2016-12-13 7:06 UTC (permalink / raw)
To: Daniel P. Berrange
Cc: eblake, armbru, stefanha, wu.wubin, jianjay.zhou, arei.gonglei,
qemu-devel
Hi Daniel,
Thanks for your review, and I fix them as your suggestion in V3,
please review V3 when you're free. :)
Regards,
On 2016/12/12 18:31, Daniel P. Berrange wrote:
> On Mon, Dec 12, 2016 at 04:08:12PM +0800, Longpeng(Mike) wrote:
>> This patch add HMAC algorithms testcases
>>
>> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
>> ---
>> tests/Makefile.include | 2 +
>> tests/test-crypto-hmac.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 168 insertions(+)
>> create mode 100644 tests/test-crypto-hmac.c
>>
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index e98d3b6..4841d58 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -91,6 +91,7 @@ gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
>> check-unit-y += tests/test-write-threshold$(EXESUF)
>> gcov-files-test-write-threshold-y = block/write-threshold.c
>> check-unit-y += tests/test-crypto-hash$(EXESUF)
>> +check-unit-y += tests/test-crypto-hmac$(EXESUF)
>> check-unit-y += tests/test-crypto-cipher$(EXESUF)
>> check-unit-y += tests/test-crypto-secret$(EXESUF)
>> check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
>> @@ -571,6 +572,7 @@ tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
>> tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
>> tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
>> tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
>> +tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
>> tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
>> tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
>> tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
>> diff --git a/tests/test-crypto-hmac.c b/tests/test-crypto-hmac.c
>> new file mode 100644
>> index 0000000..678df52
>> --- /dev/null
>> +++ b/tests/test-crypto-hmac.c
>> @@ -0,0 +1,166 @@
>> +/*
>> + * QEMU Crypto hmac algorithms tests
>> + *
>> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
>> + *
>> + * Authors:
>> + * Longpeng(Mike) <longpeng2@huawei.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or
>> + * (at your option) any later version. See the COPYING file in the
>> + * top-level directory.
>> + *
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "crypto/init.h"
>> +#include "crypto/hmac.h"
>> +
>> +typedef struct QCryptoHmacTestData QCryptoHmacTestData;
>> +struct QCryptoHmacTestData {
>> + const char *path;
>> + QCryptoHmacAlgorithm alg;
>> + const char *key;
>> + const char *message;
>> + const char *digest;
>> +};
>> +
>> +static QCryptoHmacTestData test_data[] = {
>> + {
>> + .path = "/crypto/hmac/hmac-md5",
>> + .alg = QCRYPTO_HMAC_ALG_MD5,
>> + .key =
>> + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
>> + .message =
>> + "4869205468657265",
>> + .digest =
>> + "9294727a3638bb1c13f48ef8158bfc9d",
>> + },
>> + {
>> + .path = "/crypto/hmac/hmac-sha1",
>> + .alg = QCRYPTO_HMAC_ALG_SHA1,
>> + .key =
>> + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
>> + "0b0b0b0b",
>> + .message =
>> + "4869205468657265",
>> + .digest =
>> + "b617318655057264e28bc0b6fb378c8e"
>> + "f146be00",
>> + },
>> +};
>
> This is quite weak test coverage - it needs to cover all 7 hash algorithms
>
>
>> +
>> +static inline int unhex(char c)
>> +{
>> + if (c >= 'a' && c <= 'f') {
>> + return 10 + (c - 'a');
>> + }
>> + if (c >= 'A' && c <= 'F') {
>> + return 10 + (c - 'A');
>> + }
>> + return c - '0';
>> +}
>> +
>> +static inline char hex(int i)
>> +{
>> + if (i < 10) {
>> + return '0' + i;
>> + }
>> + return 'a' + (i - 10);
>> +}
>> +
>> +static size_t unhex_string(const char *hexstr,
>> + uint8_t **data)
>> +{
>> + size_t len;
>> + size_t i;
>> +
>> + if (!hexstr) {
>> + *data = NULL;
>> + return 0;
>> + }
>> +
>> + len = strlen(hexstr);
>> + *data = g_new0(uint8_t, len / 2);
>> +
>> + for (i = 0; i < len; i += 2) {
>> + (*data)[i / 2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i + 1]);
>> + }
>> + return len / 2;
>> +}
>> +
>> +static char *hex_string(const uint8_t *bytes,
>> + size_t len)
>> +{
>> + char *hexstr = g_new0(char, len * 2 + 1);
>> + size_t i;
>> +
>> + for (i = 0; i < len; i++) {
>> + hexstr[i * 2] = hex((bytes[i] >> 4) & 0xf);
>> + hexstr[i * 2 + 1] = hex(bytes[i] & 0xf);
>> + }
>> + hexstr[len * 2] = '\0';
>> +
>> + return hexstr;
>> +}
>> +
>> +static void test_hmac(const void *opaque)
>> +{
>> + const QCryptoHmacTestData *data = opaque;
>> + size_t nkey, digest_len, msg_len;
>> + uint8_t *key = NULL;
>> + uint8_t *message = NULL;
>> + uint8_t *digest = NULL;
>> + uint8_t *output = NULL;
>> + char *outputhex = NULL;
>> + QCryptoHmac *hmac = NULL;
>> + Error *err = NULL;
>> + int ret;
>> +
>> + if (!qcrypto_hmac_supports(data->alg)) {
>> + return;
>> + }
>> +
>> + nkey = unhex_string(data->key, &key);
>> + digest_len = unhex_string(data->digest, &digest);
>> + msg_len = unhex_string(data->message, &message);
>> +
>> + output = g_new0(uint8_t, digest_len);
>> +
>> + hmac = qcrypto_hmac_new(data->alg, key, nkey, &err);
>> + g_assert(err == NULL);
>> + g_assert(hmac != NULL);
>> +
>> + ret = qcrypto_hmac_bytes(hmac, (const char *)message,
>> + msg_len, &output, &digest_len, &err);
>> +
>> + g_assert(ret == 0);
>> +
>> + outputhex = hex_string(output, digest_len);
>> +
>> + g_assert_cmpstr(outputhex, ==, data->digest);
>> +
>> + qcrypto_hmac_free(hmac);
>> +
>> + g_free(outputhex);
>> + g_free(output);
>> + g_free(message);
>> + g_free(digest);
>> + g_free(key);
>> +}
>
>
> We need to cover qcrypto_hmac_bytesv and qcrypto_hmac_digest
> methods too.
>
> IOW, can you simply copy the test-crypto-hash.c test suite entirely
> but remove the base64 part of it.
>
> Regards,
> Daniel
--
Regards,
Longpeng(Mike)
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2016-12-13 7:07 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-12 8:08 [Qemu-devel] [PATCH for-2.9 v2 0/7] crypto: add HMAC algorithms support Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 1/7] qapi: crypto: add defination about HMAC algorithms Longpeng(Mike)
2016-12-12 10:13 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 2/7] crypto: add HMAC algorithms framework Longpeng(Mike)
2016-12-12 10:18 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 3/7] configure: add CONFIG_GCRYPT_SUPPORT_HMAC item Longpeng(Mike)
2016-12-12 10:19 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 4/7] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
2016-12-12 10:25 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 5/7] crypto: support HMAC algorithms based on glibc Longpeng(Mike)
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 6/7] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
2016-12-12 10:28 ` Daniel P. Berrange
2016-12-12 8:08 ` [Qemu-devel] [PATCH for-2.9 v2 7/7] crypto: add HMAC algorithms testcases Longpeng(Mike)
2016-12-12 10:31 ` Daniel P. Berrange
2016-12-13 7:06 ` Longpeng (Mike)
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.