qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support
@ 2016-12-13 10:42 Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 1/6] configure: add CONFIG_GCRYPT_HMAC item Longpeng(Mike)
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:42 UTC (permalink / raw)
  To: berrange; +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 v3:
    - s/glibc/glib in patch 4. [Daniel]
    - fix build failure with glib older than 2.30.0. [build test]

Changes since v2:
    - remove QCryptoHmacAlgorithm defination in qapi, just use
      QCryptoHashAlgorithm as some funcs first para. [Daniel]
    - fix alignment of the lines wrt to the "(". [Daniel]
    - fix typos in the configure. [Daniel]
    - rename gcrypy_support_hmac to gcrypy_hmac. [Daniel]
    - use CONFIG_GCRYPT_HMAC in crypto/Makefile.objs to
      decide whether compiled gcrypt-backed impls. [Daniel]
    - implement all 7 hash algorithms. [Daniel]
    - cover all 7 hash algorithms in testcase. [Daniel]
    - cover qcrypto_hmac_bytesv and qcrypto_hmac_digest. [Daniel]
    - rewrite testcase based on test-crypto-hash. [Daniel]

Changes since v1:
    - check whether algorithm is supported in testcase [build test]

---
Longpeng(Mike) (6):
  configure: add CONFIG_GCRYPT_HMAC item
  crypto: add HMAC algorithms framework
  crypto: support HMAC algorithms based on libgcrypt
  crypto: support HMAC algorithms based on glib
  crypto: support HMAC algorithms based on nettle
  crypto: add HMAC algorithms testcases

 configure                |  17 +++
 crypto/Makefile.objs     |   4 +
 crypto/hmac-gcrypt.c     | 152 +++++++++++++++++++++++++++
 crypto/hmac-glib.c       | 166 +++++++++++++++++++++++++++++
 crypto/hmac-nettle.c     | 175 +++++++++++++++++++++++++++++++
 crypto/hmac.c            |  72 +++++++++++++
 crypto/hmac.h            | 166 +++++++++++++++++++++++++++++
 tests/Makefile.include   |   2 +
 tests/test-crypto-hmac.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 1020 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] 8+ messages in thread

* [Qemu-devel] [PATCH for-2.9 v4 1/6] configure: add CONFIG_GCRYPT_HMAC item
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
@ 2016-12-13 10:42 ` Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 2/6] crypto: add HMAC algorithms framework Longpeng(Mike)
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:42 UTC (permalink / raw)
  To: berrange; +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 | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/configure b/configure
index 3770d7c..f30aa1b 100755
--- a/configure
+++ b/configure
@@ -313,6 +313,7 @@ gnutls_rnd=""
 nettle=""
 nettle_kdf="no"
 gcrypt=""
+gcrypt_hmac="no"
 gcrypt_kdf="no"
 vte=""
 virglrenderer=""
@@ -2417,6 +2418,19 @@ 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
+            gcrypt_hmac=yes
+        fi
     else
         if test "$gcrypt" = "yes"; then
             feature_not_found "gcrypt" "Install gcrypt devel"
@@ -5387,6 +5401,9 @@ if test "$gnutls_rnd" = "yes" ; then
 fi
 if test "$gcrypt" = "yes" ; then
   echo "CONFIG_GCRYPT=y" >> $config_host_mak
+  if test "$gcrypt_hmac" = "yes" ; then
+    echo "CONFIG_GCRYPT_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] 8+ messages in thread

* [Qemu-devel] [PATCH for-2.9 v4 2/6] crypto: add HMAC algorithms framework
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 1/6] configure: add CONFIG_GCRYPT_HMAC item Longpeng(Mike)
@ 2016-12-13 10:42 ` Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 3/6] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:42 UTC (permalink / raw)
  To: berrange; +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 |  45 ++++++++++++++
 crypto/hmac-glib.c   |  44 ++++++++++++++
 crypto/hmac-nettle.c |  45 ++++++++++++++
 crypto/hmac.c        |  72 ++++++++++++++++++++++
 crypto/hmac.h        | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 376 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..1f749f2 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-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
+crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),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..6e07415
--- /dev/null
+++ b/crypto/hmac-gcrypt.c
@@ -0,0 +1,45 @@
+/*
+ * 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"
+#include <gcrypt.h>
+
+bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
+{
+    return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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..3e2a933
--- /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(QCryptoHashAlgorithm alg)
+{
+    return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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..95f3dcc
--- /dev/null
+++ b/crypto/hmac-nettle.c
@@ -0,0 +1,45 @@
+/*
+ * 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"
+#include <nettle/hmac.h>
+
+bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
+{
+    return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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..0d3acd7
--- /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 {
+    QCryptoHashAlgorithm 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(QCryptoHashAlgorithm 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(QCryptoHashAlgorithm 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] 8+ messages in thread

* [Qemu-devel] [PATCH for-2.9 v4 3/6] crypto: support HMAC algorithms based on libgcrypt
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 1/6] configure: add CONFIG_GCRYPT_HMAC item Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 2/6] crypto: add HMAC algorithms framework Longpeng(Mike)
@ 2016-12-13 10:42 ` Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 4/6] crypto: support HMAC algorithms based on glib Longpeng(Mike)
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:42 UTC (permalink / raw)
  To: berrange; +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 | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 109 insertions(+), 2 deletions(-)

diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
index 6e07415..21189e6 100644
--- a/crypto/hmac-gcrypt.c
+++ b/crypto/hmac-gcrypt.c
@@ -17,8 +17,28 @@
 #include "crypto/hmac.h"
 #include <gcrypt.h>
 
+static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
+    [QCRYPTO_HASH_ALG_MD5] = GCRY_MAC_HMAC_MD5,
+    [QCRYPTO_HASH_ALG_SHA1] = GCRY_MAC_HMAC_SHA1,
+    [QCRYPTO_HASH_ALG_SHA224] = GCRY_MAC_HMAC_SHA224,
+    [QCRYPTO_HASH_ALG_SHA256] = GCRY_MAC_HMAC_SHA256,
+    [QCRYPTO_HASH_ALG_SHA384] = GCRY_MAC_HMAC_SHA384,
+    [QCRYPTO_HASH_ALG_SHA512] = GCRY_MAC_HMAC_SHA512,
+    [QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MAC_HMAC_RMD160,
+};
+
+typedef struct QCryptoHmacGcrypt QCryptoHmacGcrypt;
+struct QCryptoHmacGcrypt {
+    gcry_mac_hd_t handle;
+};
+
 bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
 {
+    if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
+        qcrypto_hmac_alg_map[alg] != GCRY_MAC_NONE) {
+        return true;
+    }
+
     return false;
 }
 
@@ -26,12 +46,58 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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",
+                   QCryptoHashAlgorithm_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)
 {
-    return;
+    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,
@@ -41,5 +107,46 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
                         size_t *resultlen,
                         Error **errp)
 {
-    return -1;
+    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;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH for-2.9 v4 4/6] crypto: support HMAC algorithms based on glib
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
                   ` (2 preceding siblings ...)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 3/6] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
@ 2016-12-13 10:42 ` Longpeng(Mike)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 5/6] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:42 UTC (permalink / raw)
  To: berrange; +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel, Longpeng(Mike)

This patch add glib-backed HMAC algorithms support

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hmac-glib.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c
index 3e2a933..08a1fdd 100644
--- a/crypto/hmac-glib.c
+++ b/crypto/hmac-glib.c
@@ -16,6 +16,126 @@
 #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
+    [QCRYPTO_HASH_ALG_SHA224] = -1,
+    [QCRYPTO_HASH_ALG_SHA384] = -1,
+    [QCRYPTO_HASH_ALG_RIPEMD160] = -1,
+};
+
+typedef struct QCryptoHmacGlib QCryptoHmacGlib;
+struct QCryptoHmacGlib {
+    GHmac *ghmac;
+};
+
+bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
+{
+    if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
+        qcrypto_hmac_alg_map[alg] != -1) {
+        return true;
+    }
+
+    return false;
+}
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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",
+                   QCryptoHashAlgorithm_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(QCryptoHashAlgorithm alg)
 {
     return false;
@@ -42,3 +162,5 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
 {
     return -1;
 }
+
+#endif
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH for-2.9 v4 5/6] crypto: support HMAC algorithms based on nettle
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
                   ` (3 preceding siblings ...)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 4/6] crypto: support HMAC algorithms based on glib Longpeng(Mike)
@ 2016-12-13 10:42 ` Longpeng(Mike)
  2016-12-13 10:43 ` [Qemu-devel] [PATCH for-2.9 v4 6/6] crypto: add HMAC algorithms testcases Longpeng(Mike)
  2016-12-14 16:38 ` [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Daniel P. Berrange
  6 siblings, 0 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:42 UTC (permalink / raw)
  To: berrange; +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 | 136 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 133 insertions(+), 3 deletions(-)

diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
index 95f3dcc..4a9e6b2 100644
--- a/crypto/hmac-nettle.c
+++ b/crypto/hmac-nettle.c
@@ -17,8 +17,83 @@
 #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; /* equals hmac_sha224_ctx */
+        struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */
+        struct hmac_ripemd160_ctx ripemd160_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_HASH_ALG__MAX] = {
+    [QCRYPTO_HASH_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_HASH_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_HASH_ALG_SHA224] = {
+        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha224_set_key,
+        .update = (qcrypto_nettle_hmac_update)hmac_sha224_update,
+        .digest = (qcrypto_nettle_hmac_digest)hmac_sha224_digest,
+        .len = SHA224_DIGEST_SIZE,
+    },
+    [QCRYPTO_HASH_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_HASH_ALG_SHA384] = {
+        .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha384_set_key,
+        .update = (qcrypto_nettle_hmac_update)hmac_sha384_update,
+        .digest = (qcrypto_nettle_hmac_digest)hmac_sha384_digest,
+        .len = SHA384_DIGEST_SIZE,
+    },
+    [QCRYPTO_HASH_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,
+    },
+    [QCRYPTO_HASH_ALG_RIPEMD160] = {
+        .setkey = (qcrypto_nettle_hmac_setkey)hmac_ripemd160_set_key,
+        .update = (qcrypto_nettle_hmac_update)hmac_ripemd160_update,
+        .digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest,
+        .len = RIPEMD160_DIGEST_SIZE,
+    },
+};
+
 bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
 {
+    if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) &&
+        qcrypto_hmac_alg_map[alg].setkey != NULL) {
+        return true;
+    }
+
     return false;
 }
 
@@ -26,12 +101,39 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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",
+                   QCryptoHashAlgorithm_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,
@@ -41,5 +143,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] 8+ messages in thread

* [Qemu-devel] [PATCH for-2.9 v4 6/6] crypto: add HMAC algorithms testcases
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
                   ` (4 preceding siblings ...)
  2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 5/6] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
@ 2016-12-13 10:43 ` Longpeng(Mike)
  2016-12-14 16:38 ` [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Daniel P. Berrange
  6 siblings, 0 replies; 8+ messages in thread
From: Longpeng(Mike) @ 2016-12-13 10:43 UTC (permalink / raw)
  To: berrange; +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 | 266 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 268 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..ee55382
--- /dev/null
+++ b/tests/test-crypto-hmac.c
@@ -0,0 +1,266 @@
+/*
+ * 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"
+
+#define INPUT_TEXT1 "ABCDEFGHIJKLMNOPQRSTUVWXY"
+#define INPUT_TEXT2 "Zabcdefghijklmnopqrstuvwx"
+#define INPUT_TEXT3 "yz0123456789"
+#define INPUT_TEXT INPUT_TEXT1 \
+              INPUT_TEXT2 \
+              INPUT_TEXT3
+
+#define KEY "monkey monkey monkey monkey"
+
+typedef struct QCryptoHmacTestData QCryptoHmacTestData;
+struct QCryptoHmacTestData {
+    QCryptoHashAlgorithm alg;
+    const char *hex_digest;
+};
+
+static QCryptoHmacTestData test_data[] = {
+    {
+        .alg = QCRYPTO_HASH_ALG_MD5,
+        .hex_digest =
+            "ede9cb83679ba82d88fbeae865b3f8fc",
+    },
+    {
+        .alg = QCRYPTO_HASH_ALG_SHA1,
+        .hex_digest =
+            "c7b5a631e3aac975c4ededfcd346e469"
+            "dbc5f2d1",
+    },
+    {
+        .alg = QCRYPTO_HASH_ALG_SHA224,
+        .hex_digest =
+            "5f768179dbb29ca722875d0f461a2e2f"
+            "597d0210340a84df1a8e9c63",
+    },
+    {
+        .alg = QCRYPTO_HASH_ALG_SHA256,
+        .hex_digest =
+            "3798f363c57afa6edaffe39016ca7bad"
+            "efd1e670afb0e3987194307dec3197db",
+    },
+    {
+        .alg = QCRYPTO_HASH_ALG_SHA384,
+        .hex_digest =
+            "d218680a6032d33dccd9882d6a6a7164"
+            "64f26623be257a9b2919b185294f4a49"
+            "9e54b190bfd6bc5cedd2cd05c7e65e82",
+    },
+    {
+        .alg = QCRYPTO_HASH_ALG_SHA512,
+        .hex_digest =
+            "835a4f5b3750b4c1fccfa88da2f746a4"
+            "900160c9f18964309bb736c13b59491b"
+            "8e32d37b724cc5aebb0f554c6338a3b5"
+            "94c4ba26862b2dadb59b7ede1d08d53e",
+    },
+    {
+        .alg = QCRYPTO_HASH_ALG_RIPEMD160,
+        .hex_digest =
+            "94964ed4c1155b62b668c241d67279e5"
+            "8a711676",
+    },
+};
+
+static const char hex[] = "0123456789abcdef";
+
+static void test_hmac_alloc(void)
+{
+    size_t i;
+
+    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
+        QCryptoHmacTestData *data = &test_data[i];
+        QCryptoHmac *hmac = NULL;
+        uint8_t *result = NULL;
+        size_t resultlen = 0;
+        Error *err = NULL;
+        const char *exp_output = NULL;
+        int ret;
+        size_t j;
+
+        if (!qcrypto_hmac_supports(data->alg)) {
+            return;
+        }
+
+        exp_output = data->hex_digest;
+
+        hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY,
+                                strlen(KEY), &err);
+        g_assert(err == NULL);
+        g_assert(hmac != NULL);
+
+        ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT,
+                                 strlen(INPUT_TEXT), &result,
+                                 &resultlen, &err);
+        g_assert(err == NULL);
+        g_assert(ret == 0);
+
+        for (j = 0; j < resultlen; j++) {
+            g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]);
+            g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]);
+        }
+
+        qcrypto_hmac_free(hmac);
+
+        g_free(result);
+    }
+}
+
+static void test_hmac_prealloc(void)
+{
+    size_t i;
+
+    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
+        QCryptoHmacTestData *data = &test_data[i];
+        QCryptoHmac *hmac = NULL;
+        uint8_t *result = NULL;
+        size_t resultlen = 0;
+        Error *err = NULL;
+        const char *exp_output = NULL;
+        int ret;
+        size_t j;
+
+        if (!qcrypto_hmac_supports(data->alg)) {
+            return;
+        }
+
+        exp_output = data->hex_digest;
+
+        resultlen = strlen(exp_output) / 2;
+        result = g_new0(uint8_t, resultlen);
+
+        hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY,
+                                strlen(KEY), &err);
+        g_assert(err == NULL);
+        g_assert(hmac != NULL);
+
+        ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT,
+                                 strlen(INPUT_TEXT), &result,
+                                 &resultlen, &err);
+        g_assert(err == NULL);
+        g_assert(ret == 0);
+
+        exp_output = data->hex_digest;
+        for (j = 0; j < resultlen; j++) {
+            g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]);
+            g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]);
+        }
+
+        qcrypto_hmac_free(hmac);
+
+        g_free(result);
+    }
+}
+
+static void test_hmac_iov(void)
+{
+    size_t i;
+
+    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
+        QCryptoHmacTestData *data = &test_data[i];
+        QCryptoHmac *hmac = NULL;
+        uint8_t *result = NULL;
+        size_t resultlen = 0;
+        Error *err = NULL;
+        const char *exp_output = NULL;
+        int ret;
+        size_t j;
+        struct iovec iov[3] = {
+            { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) },
+            { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) },
+            { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) },
+        };
+
+        if (!qcrypto_hmac_supports(data->alg)) {
+            return;
+        }
+
+        exp_output = data->hex_digest;
+
+        hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY,
+                                strlen(KEY), &err);
+        g_assert(err == NULL);
+        g_assert(hmac != NULL);
+
+        ret = qcrypto_hmac_bytesv(hmac, iov, 3, &result,
+                                  &resultlen, &err);
+        g_assert(err == NULL);
+        g_assert(ret == 0);
+
+        for (j = 0; j < resultlen; j++) {
+            g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]);
+            g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]);
+        }
+
+        qcrypto_hmac_free(hmac);
+
+        g_free(result);
+    }
+}
+
+static void test_hmac_digest(void)
+{
+    size_t i;
+
+    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
+        QCryptoHmacTestData *data = &test_data[i];
+        QCryptoHmac *hmac = NULL;
+        uint8_t *result = NULL;
+        Error *err = NULL;
+        const char *exp_output = NULL;
+        int ret;
+
+        if (!qcrypto_hmac_supports(data->alg)) {
+            return;
+        }
+
+        exp_output = data->hex_digest;
+
+        hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY,
+                                strlen(KEY), &err);
+        g_assert(err == NULL);
+        g_assert(hmac != NULL);
+
+        ret = qcrypto_hmac_digest(hmac, (const char *)INPUT_TEXT,
+                                  strlen(INPUT_TEXT), (char **)&result,
+                                  &err);
+        g_assert(err == NULL);
+        g_assert(ret == 0);
+
+        g_assert_cmpstr((const char *)result, ==, exp_output);
+
+        qcrypto_hmac_free(hmac);
+
+        g_free(result);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    g_assert(qcrypto_init(NULL) == 0);
+
+    g_test_add_func("/crypto/hmac/iov", test_hmac_iov);
+    g_test_add_func("/crypto/hmac/alloc", test_hmac_alloc);
+    g_test_add_func("/crypto/hmac/prealloc", test_hmac_prealloc);
+    g_test_add_func("/crypto/hmac/digest", test_hmac_digest);
+
+    return g_test_run();
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support
  2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
                   ` (5 preceding siblings ...)
  2016-12-13 10:43 ` [Qemu-devel] [PATCH for-2.9 v4 6/6] crypto: add HMAC algorithms testcases Longpeng(Mike)
@ 2016-12-14 16:38 ` Daniel P. Berrange
  6 siblings, 0 replies; 8+ messages in thread
From: Daniel P. Berrange @ 2016-12-14 16:38 UTC (permalink / raw)
  To: Longpeng(Mike); +Cc: wu.wubin, jianjay.zhou, arei.gonglei, qemu-devel

On Tue, Dec 13, 2016 at 06:42:54PM +0800, Longpeng(Mike) wrote:
> 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.

Thanks, this all looks good, so I've queued this series for 2.9


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] 8+ messages in thread

end of thread, other threads:[~2016-12-14 16:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-13 10:42 [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Longpeng(Mike)
2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 1/6] configure: add CONFIG_GCRYPT_HMAC item Longpeng(Mike)
2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 2/6] crypto: add HMAC algorithms framework Longpeng(Mike)
2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 3/6] crypto: support HMAC algorithms based on libgcrypt Longpeng(Mike)
2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 4/6] crypto: support HMAC algorithms based on glib Longpeng(Mike)
2016-12-13 10:42 ` [Qemu-devel] [PATCH for-2.9 v4 5/6] crypto: support HMAC algorithms based on nettle Longpeng(Mike)
2016-12-13 10:43 ` [Qemu-devel] [PATCH for-2.9 v4 6/6] crypto: add HMAC algorithms testcases Longpeng(Mike)
2016-12-14 16:38 ` [Qemu-devel] [PATCH for-2.9 v4 0/6] crypto: add HMAC algorithms support Daniel P. Berrange

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).