All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support
@ 2017-07-04  8:56 Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 01/18] crypto: cipher: introduce context free function Longpeng(Mike)
                   ` (18 more replies)
  0 siblings, 19 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

The AF_ALG socket family is the userspace interface for linux
crypto API, users can use it to access hardware accelerators.

This patchset adds a afalg-backend for qemu crypto subsystem. Currently
when performs encrypt/decrypt, we'll try afalg-backend first and will
back to libiary-backend if it failed.

In the next step, It would support a command parameter to specifies
which backends prefer to and some other improvements.

I measured the performance about the afalg-backend impls, I tested
how many data could be encrypted in 5 seconds.

NOTE: If we use specific hardware crypto cards, I think afalg-backend
      would even faster.

test-environment: Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz

*sha256*
chunk_size(bytes)   MB/sec(afalg:sha256-ssse3)  MB/sec(nettle)
512                 93.03                       185.87
1024                146.32                      201.78
2048                213.32                      210.93
4096                275.48                      215.26
8192                321.77                      217.49
16384               349.60                      219.26
32768               363.59                      219.73
65536               375.79                      219.99

*hmac(sha256)*
chunk_size(bytes)   MB/sec(afalg:sha256-ssse3)  MB/sec(nettle)
512                 71.26                       165.55
1024                117.43                      189.15
2048                180.96                      203.24
4096                247.60                      211.38
8192                301.99                      215.65
16384               340.79                      218.22
32768               365.51                      219.49
65536               377.92                      220.24

*cbc(aes128)*
chunk_size(bytes)   MB/sec(afalg:cbc-aes-aesni)  MB/sec(nettle)
512                 371.76                       188.41
1024                559.86                       189.64
2048                768.66                       192.11
4096                939.15                       192.40
8192                1029.48                      192.49
16384               1072.79                      190.52
32768               1109.38                      190.41
65536               1102.38                      190.40

---
Changes since v3:
    - add "Reviewed-by: Daniel P. Berrange <berrange@redhat.com>" in
      commit messages of PATCH 1/2/3/4/5/7/8/9/10/11.
    - PATCH 12: use strlen() instead of qemu_strnlen() in qcrypto_afalg_build_saddr(). [Daniel]
    - PATCH 12: rather than indenting the entire method, just return immediately
                if afalg=NULL. [Daniel]
    - PATCH 13: use g_strdup_printf() instead of g_new0+snprintf() and remove
                redundant bounds check in qcrypto_afalg_cipher_format_name(). [Daniel]
    - PATCH 13: s/except_niv/expect_niv  s/origin_contorllen/origin_controllen. [Daniel]
    - PATCH 13: use '%zu' to print 'size_t' in qcrypto_afalg_cipher_setiv(). [Daniel]
    - PATCH 13: remove qcrypto_cipher_using_afalg_drv(). [Daniel]
    - PATCH 13: refactor the qcrypto_cipher_new() as Daniel's suggestion. [Daniel]
    - PATCH 13: correct the ->cmsg initialization int qcrypto_afalg_cipher_ctx_new() to
                avoid different behaviour in test_cipher_null_iv(). [Daniel]
    - PATCH 14: use g_strdup_printf() instead of g_new0+snprintf() and remove
                edundant bounds check in qcrypto_afalg_hash_format_name(). [Daniel]
    - PATCH 14: s/except_len/expect_len. [Daniel]
    - PATCH 14: free 'errp' if afalg_driver.hash_bytesv() failed. [Daniel]
    - PATCH 14: maybe some afalg errors should be treated as fatal, but we
                have no idea yet, so add a "TODO" comment.
    - PATCH 15: refactor the qcrypto_hmac_new() as Daniel's suggestion. [Daniel]

Changes since v2:
    - init sockaddr_alg object when it's defined. [Gonglei]
    - fix some superfluous initialization. [Gonglei]
    - s/opeartion/operation/g in crypto/afalgpriv.h. [Gonglei]
    - check 'niv' in qcrypto_afalg_cipher_setiv. [Gonglei]

Changes since v1:
    - use "make check-speed" to testing the performance. [Daniel]
    - put private definations into crypto/***priv.h. [Daniel]
    - remove afalg socket from qapi-schema, put them into crypto/. [Daniel]
    - some Error report change. [Daniel]
    - s/QCryptoAfalg/QCryptoAFAlg. [Daniel]
    - use snprintf with bounds checking instead of sprintf. [Daniel]
    - use "qcrypto_afalg_" prefix and "qcrypto_nettle(gcrypt,glib,builtin)_" prefix. [Daniel]
    - add testing results in cover-letter. [Gonglei]

---
Longpeng(Mike) (18):
  crypto: cipher: introduce context free function
  crypto: cipher: introduce qcrypto_cipher_ctx_new for gcrypt-backend
  crypto: cipher: introduce qcrypto_cipher_ctx_new for nettle-backend
  crypto: cipher: introduce qcrypto_cipher_ctx_new for builtin-backend
  crypto: cipher: add cipher driver framework
  crypto: hash: add hash driver framework
  crypto: hmac: move crypto/hmac.h into include/crypto/
  crypto: hmac: introduce qcrypto_hmac_ctx_new for gcrypt-backend
  crypto: hmac: introduce qcrypto_hmac_ctx_new for nettle-backend
  crypto: hmac: introduce qcrypto_hmac_ctx_new for glib-backend
  crypto: hmac: add hmac driver framework
  crypto: introduce some common functions for af_alg backend
  crypto: cipher: add afalg-backend cipher support
  crypto: hash: add afalg-backend hash support
  crypto: hmac: add af_alg hmac support
  tests: crypto: add cipher speed benchmark support
  tests: crypto: add hash speed benchmark support
  tests: crypto: add hmac speed benchmark support

 configure                       |  22 ++++
 crypto/Makefile.objs            |   3 +
 crypto/afalg.c                  | 118 +++++++++++++++++++++
 crypto/afalgpriv.h              |  65 ++++++++++++
 crypto/cipher-afalg.c           | 223 ++++++++++++++++++++++++++++++++++++++++
 crypto/cipher-builtin.c         | 125 +++++++++++-----------
 crypto/cipher-gcrypt.c          | 105 ++++++++++---------
 crypto/cipher-nettle.c          |  84 ++++++++-------
 crypto/cipher.c                 |  80 ++++++++++++++
 crypto/cipherpriv.h             |  56 ++++++++++
 crypto/hash-afalg.c             | 217 ++++++++++++++++++++++++++++++++++++++
 crypto/hash-gcrypt.c            |  19 ++--
 crypto/hash-glib.c              |  19 ++--
 crypto/hash-nettle.c            |  19 ++--
 crypto/hash.c                   |  30 ++++++
 crypto/hashpriv.h               |  39 +++++++
 crypto/hmac-gcrypt.c            |  42 ++++----
 crypto/hmac-glib.c              |  63 ++++++------
 crypto/hmac-nettle.c            |  42 ++++----
 crypto/hmac.c                   |  58 +++++++++++
 crypto/hmac.h                   | 166 ------------------------------
 crypto/hmacpriv.h               |  48 +++++++++
 include/crypto/cipher.h         |   1 +
 include/crypto/hmac.h           | 167 ++++++++++++++++++++++++++++++
 tests/Makefile.include          |  13 ++-
 tests/benchmark-crypto-cipher.c |  88 ++++++++++++++++
 tests/benchmark-crypto-hash.c   |  67 ++++++++++++
 tests/benchmark-crypto-hmac.c   |  94 +++++++++++++++++
 28 files changed, 1662 insertions(+), 411 deletions(-)
 create mode 100644 crypto/afalg.c
 create mode 100644 crypto/afalgpriv.h
 create mode 100644 crypto/cipher-afalg.c
 create mode 100644 crypto/cipherpriv.h
 create mode 100644 crypto/hash-afalg.c
 create mode 100644 crypto/hashpriv.h
 delete mode 100644 crypto/hmac.h
 create mode 100644 crypto/hmacpriv.h
 create mode 100644 include/crypto/hmac.h
 create mode 100644 tests/benchmark-crypto-cipher.c
 create mode 100644 tests/benchmark-crypto-hash.c
 create mode 100644 tests/benchmark-crypto-hmac.c

-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 01/18] crypto: cipher: introduce context free function
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 02/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for gcrypt-backend Longpeng(Mike)
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Refactors the qcrypto_cipher_free(), splits it into two parts. One
is gcrypt/nettle__cipher_free_ctx() to free the special context.

This makes code more clear, what's more, it would be used by the
later patch.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/cipher-gcrypt.c | 31 ++++++++++++++++++-------------
 crypto/cipher-nettle.c | 18 ++++++++++++++----
 2 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index 6487eca..0ecffa2 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -64,6 +64,22 @@ struct QCryptoCipherGcrypt {
     uint8_t *iv;
 };
 
+static void gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
+                                   QCryptoCipherMode mode)
+{
+    if (!ctx) {
+        return;
+    }
+
+    gcry_cipher_close(ctx->handle);
+    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
+        gcry_cipher_close(ctx->tweakhandle);
+    }
+    g_free(ctx->iv);
+    g_free(ctx);
+}
+
+
 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                                   QCryptoCipherMode mode,
                                   const uint8_t *key, size_t nkey,
@@ -228,11 +244,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
     return cipher;
 
  error:
-    gcry_cipher_close(ctx->handle);
-    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
-        gcry_cipher_close(ctx->tweakhandle);
-    }
-    g_free(ctx);
+    gcrypt_cipher_free_ctx(ctx, mode);
     g_free(cipher);
     return NULL;
 }
@@ -240,17 +252,10 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
 
 void qcrypto_cipher_free(QCryptoCipher *cipher)
 {
-    QCryptoCipherGcrypt *ctx;
     if (!cipher) {
         return;
     }
-    ctx = cipher->opaque;
-    gcry_cipher_close(ctx->handle);
-    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
-        gcry_cipher_close(ctx->tweakhandle);
-    }
-    g_free(ctx->iv);
-    g_free(ctx);
+    gcrypt_cipher_free_ctx(cipher->opaque, cipher->mode);
     g_free(cipher);
 }
 
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index dfc9030..e04e3a1 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -249,6 +249,19 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
 }
 
 
+static void nettle_cipher_free_ctx(QCryptoCipherNettle *ctx)
+{
+    if (!ctx) {
+        return;
+    }
+
+    g_free(ctx->iv);
+    g_free(ctx->ctx);
+    g_free(ctx->ctx_tweak);
+    g_free(ctx);
+}
+
+
 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                                   QCryptoCipherMode mode,
                                   const uint8_t *key, size_t nkey,
@@ -440,10 +453,7 @@ void qcrypto_cipher_free(QCryptoCipher *cipher)
     }
 
     ctx = cipher->opaque;
-    g_free(ctx->iv);
-    g_free(ctx->ctx);
-    g_free(ctx->ctx_tweak);
-    g_free(ctx);
+    nettle_cipher_free_ctx(ctx);
     g_free(cipher);
 }
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 02/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for gcrypt-backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 01/18] crypto: cipher: introduce context free function Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 03/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for nettle-backend Longpeng(Mike)
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Extracts qcrypto_cipher_ctx_new() from qcrypto_cipher_new() for
gcrypt-backend impls.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/cipher-gcrypt.c | 50 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index 0ecffa2..4939386 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -80,12 +80,12 @@ static void gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
 }
 
 
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
-                                  QCryptoCipherMode mode,
-                                  const uint8_t *key, size_t nkey,
-                                  Error **errp)
+static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+                                                   QCryptoCipherMode mode,
+                                                   const uint8_t *key,
+                                                   size_t nkey,
+                                                   Error **errp)
 {
-    QCryptoCipher *cipher;
     QCryptoCipherGcrypt *ctx;
     gcry_error_t err;
     int gcryalg, gcrymode;
@@ -162,10 +162,6 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         return NULL;
     }
 
-    cipher = g_new0(QCryptoCipher, 1);
-    cipher->alg = alg;
-    cipher->mode = mode;
-
     ctx = g_new0(QCryptoCipherGcrypt, 1);
 
     err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
@@ -174,7 +170,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                    gcry_strerror(err));
         goto error;
     }
-    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
+    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
         err = gcry_cipher_open(&ctx->tweakhandle, gcryalg, gcrymode, 0);
         if (err != 0) {
             error_setg(errp, "Cannot initialize cipher: %s",
@@ -183,7 +179,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         }
     }
 
-    if (cipher->alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
+    if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
         /* We're using standard DES cipher from gcrypt, so we need
          * to munge the key so that the results are the same as the
          * bizarre RFB variant of DES :-)
@@ -193,7 +189,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         g_free(rfbkey);
         ctx->blocksize = 8;
     } else {
-        if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
+        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
             nkey /= 2;
             err = gcry_cipher_setkey(ctx->handle, key, nkey);
             if (err != 0) {
@@ -210,7 +206,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                        gcry_strerror(err));
             goto error;
         }
-        switch (cipher->alg) {
+        switch (alg) {
         case QCRYPTO_CIPHER_ALG_AES_128:
         case QCRYPTO_CIPHER_ALG_AES_192:
         case QCRYPTO_CIPHER_ALG_AES_256:
@@ -230,7 +226,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         }
     }
 
-    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
+    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
         if (ctx->blocksize != XTS_BLOCK_SIZE) {
             error_setg(errp,
                        "Cipher block size %zu must equal XTS block size %d",
@@ -240,12 +236,10 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         ctx->iv = g_new0(uint8_t, ctx->blocksize);
     }
 
-    cipher->opaque = ctx;
-    return cipher;
+    return ctx;
 
  error:
     gcrypt_cipher_free_ctx(ctx, mode);
-    g_free(cipher);
     return NULL;
 }
 
@@ -385,3 +379,25 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
 
     return 0;
 }
+
+
+QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
+                                  QCryptoCipherMode mode,
+                                  const uint8_t *key, size_t nkey,
+                                  Error **errp)
+{
+    QCryptoCipher *cipher;
+    QCryptoCipherGcrypt *ctx;
+
+    ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    cipher = g_new0(QCryptoCipher, 1);
+    cipher->alg = alg;
+    cipher->mode = mode;
+    cipher->opaque = ctx;
+
+    return cipher;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 03/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for nettle-backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 01/18] crypto: cipher: introduce context free function Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 02/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for gcrypt-backend Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 04/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for builtin-backend Longpeng(Mike)
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Extracts qcrypto_cipher_ctx_new() from qcrypto_cipher_new() for
nettle-backend impls.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/cipher-nettle.c | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index e04e3a1..e6d6e6c 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -262,12 +262,12 @@ static void nettle_cipher_free_ctx(QCryptoCipherNettle *ctx)
 }
 
 
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
-                                  QCryptoCipherMode mode,
-                                  const uint8_t *key, size_t nkey,
-                                  Error **errp)
+static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+                                                   QCryptoCipherMode mode,
+                                                   const uint8_t *key,
+                                                   size_t nkey,
+                                                   Error **errp)
 {
-    QCryptoCipher *cipher;
     QCryptoCipherNettle *ctx;
     uint8_t *rfbkey;
 
@@ -287,12 +287,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         return NULL;
     }
 
-    cipher = g_new0(QCryptoCipher, 1);
-    cipher->alg = alg;
-    cipher->mode = mode;
-
     ctx = g_new0(QCryptoCipherNettle, 1);
-    cipher->opaque = ctx;
 
     switch (alg) {
     case QCRYPTO_CIPHER_ALG_DES_RFB:
@@ -436,10 +431,10 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
 
     ctx->iv = g_new0(uint8_t, ctx->blocksize);
 
-    return cipher;
+    return ctx;
 
  error:
-    qcrypto_cipher_free(cipher);
+    nettle_cipher_free_ctx(ctx);
     return NULL;
 }
 
@@ -561,3 +556,25 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
     memcpy(ctx->iv, iv, niv);
     return 0;
 }
+
+
+QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
+                                  QCryptoCipherMode mode,
+                                  const uint8_t *key, size_t nkey,
+                                  Error **errp)
+{
+    QCryptoCipher *cipher;
+    QCryptoCipherNettle *ctx;
+
+    ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    cipher = g_new0(QCryptoCipher, 1);
+    cipher->alg = alg;
+    cipher->mode = mode;
+    cipher->opaque = ctx;
+
+    return cipher;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 04/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for builtin-backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (2 preceding siblings ...)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 03/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for nettle-backend Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 05/18] crypto: cipher: add cipher driver framework Longpeng(Mike)
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Extracts qcrypto_cipher_ctx_new() from qcrypto_cipher_new() for
builtin-backend impls.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/cipher-builtin.c | 101 ++++++++++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 46 deletions(-)

diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index b4bc2b9..4ecd15e 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -235,23 +235,24 @@ static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
 
 
 
-static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
-                                   const uint8_t *key, size_t nkey,
-                                   Error **errp)
+static QCryptoCipherBuiltin *
+qcrypto_cipher_init_aes(QCryptoCipherMode mode,
+                        const uint8_t *key, size_t nkey,
+                        Error **errp)
 {
     QCryptoCipherBuiltin *ctxt;
 
-    if (cipher->mode != QCRYPTO_CIPHER_MODE_CBC &&
-        cipher->mode != QCRYPTO_CIPHER_MODE_ECB &&
-        cipher->mode != QCRYPTO_CIPHER_MODE_XTS) {
+    if (mode != QCRYPTO_CIPHER_MODE_CBC &&
+        mode != QCRYPTO_CIPHER_MODE_ECB &&
+        mode != QCRYPTO_CIPHER_MODE_XTS) {
         error_setg(errp, "Unsupported cipher mode %s",
-                   QCryptoCipherMode_lookup[cipher->mode]);
-        return -1;
+                   QCryptoCipherMode_lookup[mode]);
+        return NULL;
     }
 
     ctxt = g_new0(QCryptoCipherBuiltin, 1);
 
-    if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
+    if (mode == QCRYPTO_CIPHER_MODE_XTS) {
         if (AES_set_encrypt_key(key, nkey * 4, &ctxt->state.aes.key.enc) != 0) {
             error_setg(errp, "Failed to set encryption key");
             goto error;
@@ -291,13 +292,11 @@ static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
     ctxt->encrypt = qcrypto_cipher_encrypt_aes;
     ctxt->decrypt = qcrypto_cipher_decrypt_aes;
 
-    cipher->opaque = ctxt;
-
-    return 0;
+    return ctxt;
 
  error:
     g_free(ctxt);
-    return -1;
+    return NULL;
 }
 
 
@@ -370,16 +369,17 @@ static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
 }
 
 
-static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
-                                       const uint8_t *key, size_t nkey,
-                                       Error **errp)
+static QCryptoCipherBuiltin *
+qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode,
+                            const uint8_t *key, size_t nkey,
+                            Error **errp)
 {
     QCryptoCipherBuiltin *ctxt;
 
-    if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
+    if (mode != QCRYPTO_CIPHER_MODE_ECB) {
         error_setg(errp, "Unsupported cipher mode %s",
-                   QCryptoCipherMode_lookup[cipher->mode]);
-        return -1;
+                   QCryptoCipherMode_lookup[mode]);
+        return NULL;
     }
 
     ctxt = g_new0(QCryptoCipherBuiltin, 1);
@@ -394,9 +394,7 @@ static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
     ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
     ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
 
-    cipher->opaque = ctxt;
-
-    return 0;
+    return ctxt;
 }
 
 
@@ -426,12 +424,13 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
 }
 
 
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
-                                  QCryptoCipherMode mode,
-                                  const uint8_t *key, size_t nkey,
-                                  Error **errp)
+static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+                                                    QCryptoCipherMode mode,
+                                                    const uint8_t *key,
+                                                    size_t nkey,
+                                                    Error **errp)
 {
-    QCryptoCipher *cipher;
+    QCryptoCipherBuiltin *ctxt;
 
     switch (mode) {
     case QCRYPTO_CIPHER_MODE_ECB:
@@ -444,39 +443,27 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         return NULL;
     }
 
-    cipher = g_new0(QCryptoCipher, 1);
-    cipher->alg = alg;
-    cipher->mode = mode;
-
     if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
-        goto error;
+        return NULL;
     }
 
-    switch (cipher->alg) {
+    switch (alg) {
     case QCRYPTO_CIPHER_ALG_DES_RFB:
-        if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) {
-            goto error;
-        }
+        ctxt = qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
         break;
     case QCRYPTO_CIPHER_ALG_AES_128:
     case QCRYPTO_CIPHER_ALG_AES_192:
     case QCRYPTO_CIPHER_ALG_AES_256:
-        if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) {
-            goto error;
-        }
+        ctxt = qcrypto_cipher_init_aes(mode, key, nkey, errp);
         break;
     default:
         error_setg(errp,
                    "Unsupported cipher algorithm %s",
-                   QCryptoCipherAlgorithm_lookup[cipher->alg]);
-        goto error;
+                   QCryptoCipherAlgorithm_lookup[alg]);
+        return NULL;
     }
 
-    return cipher;
-
- error:
-    g_free(cipher);
-    return NULL;
+    return ctxt;
 }
 
 void qcrypto_cipher_free(QCryptoCipher *cipher)
@@ -537,3 +524,25 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
 
     return ctxt->setiv(cipher, iv, niv, errp);
 }
+
+
+QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
+                                  QCryptoCipherMode mode,
+                                  const uint8_t *key, size_t nkey,
+                                  Error **errp)
+{
+    QCryptoCipher *cipher;
+    QCryptoCipherBuiltin *ctxt;
+
+    ctxt = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
+    if (!ctxt) {
+        return NULL;
+    }
+
+    cipher = g_new0(QCryptoCipher, 1);
+    cipher->alg = alg;
+    cipher->mode = mode;
+    cipher->opaque = ctxt;
+
+    return cipher;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 05/18] crypto: cipher: add cipher driver framework
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (3 preceding siblings ...)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 04/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for builtin-backend Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 06/18] crypto: hash: add hash " Longpeng(Mike)
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

1) makes the public APIs in cipher-nettle/gcrypt/builtin static,
   and rename them with "nettle/gcrypt/builtin" prefix.

2) introduces cipher framework, including QCryptoCipherDriver
   and new public APIs.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/cipher-builtin.c | 64 +++++++++++++++++--------------------------
 crypto/cipher-gcrypt.c  | 72 +++++++++++++++++++++----------------------------
 crypto/cipher-nettle.c  | 71 ++++++++++++++++++++----------------------------
 crypto/cipher.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++
 crypto/cipherpriv.h     | 40 +++++++++++++++++++++++++++
 include/crypto/cipher.h |  1 +
 6 files changed, 190 insertions(+), 123 deletions(-)
 create mode 100644 crypto/cipherpriv.h

diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index 4ecd15e..16a36d4 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -22,6 +22,7 @@
 #include "crypto/aes.h"
 #include "crypto/desrfb.h"
 #include "crypto/xts.h"
+#include "cipherpriv.h"
 
 typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
 struct QCryptoCipherBuiltinAESContext {
@@ -466,25 +467,22 @@ static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
     return ctxt;
 }
 
-void qcrypto_cipher_free(QCryptoCipher *cipher)
+static void
+qcrypto_builtin_cipher_ctx_free(QCryptoCipher *cipher)
 {
     QCryptoCipherBuiltin *ctxt;
 
-    if (!cipher) {
-        return;
-    }
-
     ctxt = cipher->opaque;
     ctxt->free(cipher);
-    g_free(cipher);
 }
 
 
-int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
-                           const void *in,
-                           void *out,
-                           size_t len,
-                           Error **errp)
+static int
+qcrypto_builtin_cipher_encrypt(QCryptoCipher *cipher,
+                               const void *in,
+                               void *out,
+                               size_t len,
+                               Error **errp)
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
 
@@ -498,11 +496,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 }
 
 
-int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
-                           const void *in,
-                           void *out,
-                           size_t len,
-                           Error **errp)
+static int
+qcrypto_builtin_cipher_decrypt(QCryptoCipher *cipher,
+                               const void *in,
+                               void *out,
+                               size_t len,
+                               Error **errp)
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
 
@@ -516,9 +515,10 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
 }
 
 
-int qcrypto_cipher_setiv(QCryptoCipher *cipher,
-                         const uint8_t *iv, size_t niv,
-                         Error **errp)
+static int
+qcrypto_builtin_cipher_setiv(QCryptoCipher *cipher,
+                             const uint8_t *iv, size_t niv,
+                             Error **errp)
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
 
@@ -526,23 +526,9 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
 }
 
 
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
-                                  QCryptoCipherMode mode,
-                                  const uint8_t *key, size_t nkey,
-                                  Error **errp)
-{
-    QCryptoCipher *cipher;
-    QCryptoCipherBuiltin *ctxt;
-
-    ctxt = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
-    if (!ctxt) {
-        return NULL;
-    }
-
-    cipher = g_new0(QCryptoCipher, 1);
-    cipher->alg = alg;
-    cipher->mode = mode;
-    cipher->opaque = ctxt;
-
-    return cipher;
-}
+static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
+    .cipher_encrypt = qcrypto_builtin_cipher_encrypt,
+    .cipher_decrypt = qcrypto_builtin_cipher_decrypt,
+    .cipher_setiv = qcrypto_builtin_cipher_setiv,
+    .cipher_free = qcrypto_builtin_cipher_ctx_free,
+};
diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index 4939386..0489147 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "crypto/xts.h"
+#include "cipherpriv.h"
 
 #include <gcrypt.h>
 
@@ -64,8 +65,9 @@ struct QCryptoCipherGcrypt {
     uint8_t *iv;
 };
 
-static void gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
-                                   QCryptoCipherMode mode)
+static void
+qcrypto_gcrypt_cipher_free_ctx(QCryptoCipherGcrypt *ctx,
+                               QCryptoCipherMode mode)
 {
     if (!ctx) {
         return;
@@ -239,18 +241,15 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
     return ctx;
 
  error:
-    gcrypt_cipher_free_ctx(ctx, mode);
+    qcrypto_gcrypt_cipher_free_ctx(ctx, mode);
     return NULL;
 }
 
 
-void qcrypto_cipher_free(QCryptoCipher *cipher)
+static void
+qcrypto_gcrypt_cipher_ctx_free(QCryptoCipher *cipher)
 {
-    if (!cipher) {
-        return;
-    }
-    gcrypt_cipher_free_ctx(cipher->opaque, cipher->mode);
-    g_free(cipher);
+    qcrypto_gcrypt_cipher_free_ctx(cipher->opaque, cipher->mode);
 }
 
 
@@ -274,11 +273,12 @@ static void qcrypto_gcrypt_xts_decrypt(const void *ctx,
     g_assert(err == 0);
 }
 
-int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
-                           const void *in,
-                           void *out,
-                           size_t len,
-                           Error **errp)
+static int
+qcrypto_gcrypt_cipher_encrypt(QCryptoCipher *cipher,
+                              const void *in,
+                              void *out,
+                              size_t len,
+                              Error **errp)
 {
     QCryptoCipherGcrypt *ctx = cipher->opaque;
     gcry_error_t err;
@@ -309,11 +309,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 }
 
 
-int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
-                           const void *in,
-                           void *out,
-                           size_t len,
-                           Error **errp)
+static int
+qcrypto_gcrypt_cipher_decrypt(QCryptoCipher *cipher,
+                              const void *in,
+                              void *out,
+                              size_t len,
+                              Error **errp)
 {
     QCryptoCipherGcrypt *ctx = cipher->opaque;
     gcry_error_t err;
@@ -343,9 +344,10 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
     return 0;
 }
 
-int qcrypto_cipher_setiv(QCryptoCipher *cipher,
-                         const uint8_t *iv, size_t niv,
-                         Error **errp)
+static int
+qcrypto_gcrypt_cipher_setiv(QCryptoCipher *cipher,
+                            const uint8_t *iv, size_t niv,
+                            Error **errp)
 {
     QCryptoCipherGcrypt *ctx = cipher->opaque;
     gcry_error_t err;
@@ -381,23 +383,9 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
 }
 
 
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
-                                  QCryptoCipherMode mode,
-                                  const uint8_t *key, size_t nkey,
-                                  Error **errp)
-{
-    QCryptoCipher *cipher;
-    QCryptoCipherGcrypt *ctx;
-
-    ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
-    if (!ctx) {
-        return NULL;
-    }
-
-    cipher = g_new0(QCryptoCipher, 1);
-    cipher->alg = alg;
-    cipher->mode = mode;
-    cipher->opaque = ctx;
-
-    return cipher;
-}
+static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
+    .cipher_encrypt = qcrypto_gcrypt_cipher_encrypt,
+    .cipher_decrypt = qcrypto_gcrypt_cipher_decrypt,
+    .cipher_setiv = qcrypto_gcrypt_cipher_setiv,
+    .cipher_free = qcrypto_gcrypt_cipher_ctx_free,
+};
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index e6d6e6c..c51f119 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "crypto/xts.h"
+#include "cipherpriv.h"
 
 #include <nettle/nettle-types.h>
 #include <nettle/aes.h>
@@ -249,7 +250,8 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
 }
 
 
-static void nettle_cipher_free_ctx(QCryptoCipherNettle *ctx)
+static void
+qcrypto_nettle_cipher_free_ctx(QCryptoCipherNettle *ctx)
 {
     if (!ctx) {
         return;
@@ -434,30 +436,27 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
     return ctx;
 
  error:
-    nettle_cipher_free_ctx(ctx);
+    qcrypto_nettle_cipher_free_ctx(ctx);
     return NULL;
 }
 
 
-void qcrypto_cipher_free(QCryptoCipher *cipher)
+static void
+qcrypto_nettle_cipher_ctx_free(QCryptoCipher *cipher)
 {
     QCryptoCipherNettle *ctx;
 
-    if (!cipher) {
-        return;
-    }
-
     ctx = cipher->opaque;
-    nettle_cipher_free_ctx(ctx);
-    g_free(cipher);
+    qcrypto_nettle_cipher_free_ctx(ctx);
 }
 
 
-int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
-                           const void *in,
-                           void *out,
-                           size_t len,
-                           Error **errp)
+static int
+qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher,
+                              const void *in,
+                              void *out,
+                              size_t len,
+                              Error **errp)
 {
     QCryptoCipherNettle *ctx = cipher->opaque;
 
@@ -499,11 +498,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 }
 
 
-int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
-                           const void *in,
-                           void *out,
-                           size_t len,
-                           Error **errp)
+static int
+qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher,
+                              const void *in,
+                              void *out,
+                              size_t len,
+                              Error **errp)
 {
     QCryptoCipherNettle *ctx = cipher->opaque;
 
@@ -543,9 +543,10 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
     return 0;
 }
 
-int qcrypto_cipher_setiv(QCryptoCipher *cipher,
-                         const uint8_t *iv, size_t niv,
-                         Error **errp)
+static int
+qcrypto_nettle_cipher_setiv(QCryptoCipher *cipher,
+                            const uint8_t *iv, size_t niv,
+                            Error **errp)
 {
     QCryptoCipherNettle *ctx = cipher->opaque;
     if (niv != ctx->blocksize) {
@@ -558,23 +559,9 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
 }
 
 
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
-                                  QCryptoCipherMode mode,
-                                  const uint8_t *key, size_t nkey,
-                                  Error **errp)
-{
-    QCryptoCipher *cipher;
-    QCryptoCipherNettle *ctx;
-
-    ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
-    if (!ctx) {
-        return NULL;
-    }
-
-    cipher = g_new0(QCryptoCipher, 1);
-    cipher->alg = alg;
-    cipher->mode = mode;
-    cipher->opaque = ctx;
-
-    return cipher;
-}
+static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = {
+    .cipher_encrypt = qcrypto_nettle_cipher_encrypt,
+    .cipher_decrypt = qcrypto_nettle_cipher_decrypt,
+    .cipher_setiv = qcrypto_nettle_cipher_setiv,
+    .cipher_free = qcrypto_nettle_cipher_ctx_free,
+};
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 5a96489..0a3d2e5 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/cipher.h"
+#include "cipherpriv.h"
 
 
 static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
@@ -155,3 +156,67 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
 #else
 #include "crypto/cipher-builtin.c"
 #endif
+
+QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
+                                  QCryptoCipherMode mode,
+                                  const uint8_t *key, size_t nkey,
+                                  Error **errp)
+{
+    QCryptoCipher *cipher;
+    void *ctx;
+
+    ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    cipher = g_new0(QCryptoCipher, 1);
+    cipher->alg = alg;
+    cipher->mode = mode;
+    cipher->opaque = ctx;
+    cipher->driver = (void *)&qcrypto_cipher_lib_driver;
+
+    return cipher;
+}
+
+
+int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
+                           const void *in,
+                           void *out,
+                           size_t len,
+                           Error **errp)
+{
+    QCryptoCipherDriver *drv = cipher->driver;
+    return drv->cipher_encrypt(cipher, in, out, len, errp);
+}
+
+
+int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
+                           const void *in,
+                           void *out,
+                           size_t len,
+                           Error **errp)
+{
+    QCryptoCipherDriver *drv = cipher->driver;
+    return drv->cipher_decrypt(cipher, in, out, len, errp);
+}
+
+
+int qcrypto_cipher_setiv(QCryptoCipher *cipher,
+                         const uint8_t *iv, size_t niv,
+                         Error **errp)
+{
+    QCryptoCipherDriver *drv = cipher->driver;
+    return drv->cipher_setiv(cipher, iv, niv, errp);
+}
+
+
+void qcrypto_cipher_free(QCryptoCipher *cipher)
+{
+    QCryptoCipherDriver *drv;
+    if (cipher) {
+        drv = cipher->driver;
+        drv->cipher_free(cipher);
+        g_free(cipher);
+    }
+}
diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h
new file mode 100644
index 0000000..4af5e85
--- /dev/null
+++ b/crypto/cipherpriv.h
@@ -0,0 +1,40 @@
+/*
+ * QEMU Crypto cipher driver supports
+ *
+ * Copyright (c) 2017 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.
+ *
+ */
+
+#ifndef QCRYPTO_CIPHERPRIV_H
+#define QCRYPTO_CIPHERPRIV_H
+
+typedef struct QCryptoCipherDriver QCryptoCipherDriver;
+
+struct QCryptoCipherDriver {
+    int (*cipher_encrypt)(QCryptoCipher *cipher,
+                          const void *in,
+                          void *out,
+                          size_t len,
+                          Error **errp);
+
+    int (*cipher_decrypt)(QCryptoCipher *cipher,
+                          const void *in,
+                          void *out,
+                          size_t len,
+                          Error **errp);
+
+    int (*cipher_setiv)(QCryptoCipher *cipher,
+                        const uint8_t *iv, size_t niv,
+                        Error **errp);
+
+    void (*cipher_free)(QCryptoCipher *cipher);
+};
+
+#endif
diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h
index bec9f41..984fb82 100644
--- a/include/crypto/cipher.h
+++ b/include/crypto/cipher.h
@@ -80,6 +80,7 @@ struct QCryptoCipher {
     QCryptoCipherAlgorithm alg;
     QCryptoCipherMode mode;
     void *opaque;
+    void *driver;
 };
 
 /**
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 06/18] crypto: hash: add hash driver framework
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (4 preceding siblings ...)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 05/18] crypto: cipher: add cipher driver framework Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 07/18] crypto: hmac: move crypto/hmac.h into include/crypto/ Longpeng(Mike)
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

1) makes the public APIs in hash-nettle/gcrypt/glib static,
   and rename them with "nettle/gcrypt/glib" prefix.

2) introduces hash framework, including QCryptoHashDriver
   and new public APIs.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hash-gcrypt.c | 19 +++++++++++++------
 crypto/hash-glib.c   | 19 +++++++++++++------
 crypto/hash-nettle.c | 19 +++++++++++++------
 crypto/hash.c        | 13 +++++++++++++
 crypto/hashpriv.h    | 31 +++++++++++++++++++++++++++++++
 5 files changed, 83 insertions(+), 18 deletions(-)
 create mode 100644 crypto/hashpriv.h

diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c
index 7690690..972beaa 100644
--- a/crypto/hash-gcrypt.c
+++ b/crypto/hash-gcrypt.c
@@ -22,6 +22,7 @@
 #include <gcrypt.h>
 #include "qapi/error.h"
 #include "crypto/hash.h"
+#include "hashpriv.h"
 
 
 static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
@@ -44,12 +45,13 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
 }
 
 
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
-                        const struct iovec *iov,
-                        size_t niov,
-                        uint8_t **result,
-                        size_t *resultlen,
-                        Error **errp)
+static int
+qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgorithm alg,
+                           const struct iovec *iov,
+                           size_t niov,
+                           uint8_t **result,
+                           size_t *resultlen,
+                           Error **errp)
 {
     int i, ret;
     gcry_md_hd_t md;
@@ -107,3 +109,8 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
     gcry_md_close(md);
     return -1;
 }
+
+
+QCryptoHashDriver qcrypto_hash_lib_driver = {
+    .hash_bytesv = qcrypto_gcrypt_hash_bytesv,
+};
diff --git a/crypto/hash-glib.c b/crypto/hash-glib.c
index ec99ac9..a5871cc 100644
--- a/crypto/hash-glib.c
+++ b/crypto/hash-glib.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hash.h"
+#include "hashpriv.h"
 
 
 static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
@@ -47,12 +48,13 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
 }
 
 
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
-                        const struct iovec *iov,
-                        size_t niov,
-                        uint8_t **result,
-                        size_t *resultlen,
-                        Error **errp)
+static int
+qcrypto_glib_hash_bytesv(QCryptoHashAlgorithm alg,
+                         const struct iovec *iov,
+                         size_t niov,
+                         uint8_t **result,
+                         size_t *resultlen,
+                         Error **errp)
 {
     int i, ret;
     GChecksum *cs;
@@ -95,3 +97,8 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
     g_checksum_free(cs);
     return -1;
 }
+
+
+QCryptoHashDriver qcrypto_hash_lib_driver = {
+    .hash_bytesv = qcrypto_glib_hash_bytesv,
+};
diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
index 6a206dc..96f186f 100644
--- a/crypto/hash-nettle.c
+++ b/crypto/hash-nettle.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hash.h"
+#include "hashpriv.h"
 #include <nettle/md5.h>
 #include <nettle/sha.h>
 #include <nettle/ripemd160.h>
@@ -103,12 +104,13 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
 }
 
 
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
-                        const struct iovec *iov,
-                        size_t niov,
-                        uint8_t **result,
-                        size_t *resultlen,
-                        Error **errp)
+static int
+qcrypto_nettle_hash_bytesv(QCryptoHashAlgorithm alg,
+                           const struct iovec *iov,
+                           size_t niov,
+                           uint8_t **result,
+                           size_t *resultlen,
+                           Error **errp)
 {
     int i;
     union qcrypto_hash_ctx ctx;
@@ -152,3 +154,8 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
 
     return 0;
 }
+
+
+QCryptoHashDriver qcrypto_hash_lib_driver = {
+    .hash_bytesv = qcrypto_nettle_hash_bytesv,
+};
diff --git a/crypto/hash.c b/crypto/hash.c
index 0f1ceac..c43fd87 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -21,6 +21,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hash.h"
+#include "hashpriv.h"
 
 static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = {
     [QCRYPTO_HASH_ALG_MD5] = 16,
@@ -38,6 +39,18 @@ size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg)
     return qcrypto_hash_alg_size[alg];
 }
 
+int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
+                        const struct iovec *iov,
+                        size_t niov,
+                        uint8_t **result,
+                        size_t *resultlen,
+                        Error **errp)
+{
+    return qcrypto_hash_lib_driver.hash_bytesv(alg, iov, niov,
+                                               result, resultlen,
+                                               errp);
+}
+
 
 int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
                        const char *buf,
diff --git a/crypto/hashpriv.h b/crypto/hashpriv.h
new file mode 100644
index 0000000..5e505e0
--- /dev/null
+++ b/crypto/hashpriv.h
@@ -0,0 +1,31 @@
+/*
+ * QEMU Crypto hash driver supports
+ *
+ * Copyright (c) 2017 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.
+ *
+ */
+
+#ifndef QCRYPTO_HASHPRIV_H
+#define QCRYPTO_HASHPRIV_H
+
+typedef struct QCryptoHashDriver QCryptoHashDriver;
+
+struct QCryptoHashDriver {
+    int (*hash_bytesv)(QCryptoHashAlgorithm alg,
+                       const struct iovec *iov,
+                       size_t niov,
+                       uint8_t **result,
+                       size_t *resultlen,
+                       Error **errp);
+};
+
+extern QCryptoHashDriver qcrypto_hash_lib_driver;
+
+#endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 07/18] crypto: hmac: move crypto/hmac.h into include/crypto/
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (5 preceding siblings ...)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 06/18] crypto: hash: add hash " Longpeng(Mike)
@ 2017-07-04  8:56 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 08/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for gcrypt-backend Longpeng(Mike)
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:56 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Moves crypto/hmac.h into include/crypto/, likes cipher.h and hash.h

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hmac.h         | 166 --------------------------------------------------
 include/crypto/hmac.h | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+), 166 deletions(-)
 delete mode 100644 crypto/hmac.h
 create mode 100644 include/crypto/hmac.h

diff --git a/crypto/hmac.h b/crypto/hmac.h
deleted file mode 100644
index 0d3acd7..0000000
--- a/crypto/hmac.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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
diff --git a/include/crypto/hmac.h b/include/crypto/hmac.h
new file mode 100644
index 0000000..0d3acd7
--- /dev/null
+++ b/include/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] 29+ messages in thread

* [Qemu-devel] [PATCH v4 08/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for gcrypt-backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (6 preceding siblings ...)
  2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 07/18] crypto: hmac: move crypto/hmac.h into include/crypto/ Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 09/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for nettle-backend Longpeng(Mike)
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

1) Fix a handle-leak problem in qcrypto_hmac_new(), didn't free
   ctx->handle if gcry_mac_setkey fails.

2) Extracts qcrypto_hmac_ctx_new() from qcrypto_hmac_new() for
   gcrypt-backend impls.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hmac-gcrypt.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
index 21189e6..372ad7f 100644
--- a/crypto/hmac-gcrypt.c
+++ b/crypto/hmac-gcrypt.c
@@ -42,11 +42,11 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
+static QCryptoHmacGcrypt *
+qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                     const uint8_t *key, size_t nkey,
+                     Error **errp)
 {
-    QCryptoHmac *hmac;
     QCryptoHmacGcrypt *ctx;
     gcry_error_t err;
 
@@ -56,9 +56,6 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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],
@@ -73,15 +70,14 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
     if (err != 0) {
         error_setg(errp, "Cannot set key: %s",
                    gcry_strerror(err));
+        gcry_mac_close(ctx->handle);
         goto error;
     }
 
-    hmac->opaque = ctx;
-    return hmac;
+    return ctx;
 
 error:
     g_free(ctx);
-    g_free(hmac);
     return NULL;
 }
 
@@ -150,3 +146,22 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
 
     return 0;
 }
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
+                              const uint8_t *key, size_t nkey,
+                              Error **errp)
+{
+    QCryptoHmac *hmac;
+    QCryptoHmacGcrypt *ctx;
+
+    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    hmac = g_new0(QCryptoHmac, 1);
+    hmac->alg = alg;
+    hmac->opaque = ctx;
+
+    return hmac;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 09/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for nettle-backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (7 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 08/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for gcrypt-backend Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 10/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for glib-backend Longpeng(Mike)
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Extracts qcrypto_hmac_ctx_new() from qcrypto_hmac_new() for
nettle-backend impls.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hmac-nettle.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
index 4a9e6b2..000dfd9 100644
--- a/crypto/hmac-nettle.c
+++ b/crypto/hmac-nettle.c
@@ -97,11 +97,11 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
+static QCryptoHmacNettle *
+qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                     const uint8_t *key, size_t nkey,
+                     Error **errp)
 {
-    QCryptoHmac *hmac;
     QCryptoHmacNettle *ctx;
 
     if (!qcrypto_hmac_supports(alg)) {
@@ -110,16 +110,11 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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;
+    return ctx;
 }
 
 void qcrypto_hmac_free(QCryptoHmac *hmac)
@@ -173,3 +168,22 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
 
     return 0;
 }
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
+                              const uint8_t *key, size_t nkey,
+                              Error **errp)
+{
+    QCryptoHmac *hmac;
+    QCryptoHmacNettle *ctx;
+
+    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    hmac = g_new0(QCryptoHmac, 1);
+    hmac->alg = alg;
+    hmac->opaque = ctx;
+
+    return hmac;
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 10/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for glib-backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (8 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 09/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for nettle-backend Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 11/18] crypto: hmac: add hmac driver framework Longpeng(Mike)
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Extracts qcrypto_hmac_ctx_new() from qcrypto_hmac_new() for
glib-backend impls.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hmac-glib.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c
index 08a1fdd..f0ccfd6 100644
--- a/crypto/hmac-glib.c
+++ b/crypto/hmac-glib.c
@@ -49,11 +49,11 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
+static QCryptoHmacGlib *
+qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                     const uint8_t *key, size_t nkey,
+                     Error **errp)
 {
-    QCryptoHmac *hmac;
     QCryptoHmacGlib *ctx;
 
     if (!qcrypto_hmac_supports(alg)) {
@@ -62,9 +62,6 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm 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],
@@ -74,12 +71,10 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
         goto error;
     }
 
-    hmac->opaque = ctx;
-    return hmac;
+    return ctx;
 
 error:
     g_free(ctx);
-    g_free(hmac);
     return NULL;
 }
 
@@ -134,6 +129,25 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
     return 0;
 }
 
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
+                              const uint8_t *key, size_t nkey,
+                              Error **errp)
+{
+    QCryptoHmac *hmac;
+    QCryptoHmacGlib *ctx;
+
+    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    hmac = g_new0(QCryptoHmac, 1);
+    hmac->alg = alg;
+    hmac->opaque = ctx;
+
+    return hmac;
+}
+
 #else
 
 bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 11/18] crypto: hmac: add hmac driver framework
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (9 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 10/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for glib-backend Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend Longpeng(Mike)
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

1) makes the public APIs in hmac-nettle/gcrypt/glib static,
   and rename them with "nettle/gcrypt/glib" prefix.

2) introduces hmac framework, including QCryptoHmacDriver
   and new public APIs.

Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hmac-gcrypt.c  | 51 ++++++++++++-----------------------
 crypto/hmac-glib.c    | 75 +++++++++++++++++++++------------------------------
 crypto/hmac-nettle.c  | 52 ++++++++++++-----------------------
 crypto/hmac.c         | 44 ++++++++++++++++++++++++++++++
 crypto/hmacpriv.h     | 36 +++++++++++++++++++++++++
 include/crypto/hmac.h |  1 +
 6 files changed, 145 insertions(+), 114 deletions(-)
 create mode 100644 crypto/hmacpriv.h

diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
index 372ad7f..76ca61b 100644
--- a/crypto/hmac-gcrypt.c
+++ b/crypto/hmac-gcrypt.c
@@ -15,6 +15,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hmac.h"
+#include "hmacpriv.h"
 #include <gcrypt.h>
 
 static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
@@ -42,10 +43,9 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-static QCryptoHmacGcrypt *
-qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
-                     const uint8_t *key, size_t nkey,
-                     Error **errp)
+void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                           const uint8_t *key, size_t nkey,
+                           Error **errp)
 {
     QCryptoHmacGcrypt *ctx;
     gcry_error_t err;
@@ -81,27 +81,24 @@ error:
     return NULL;
 }
 
-void qcrypto_hmac_free(QCryptoHmac *hmac)
+static void
+qcrypto_gcrypt_hmac_ctx_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)
+static int
+qcrypto_gcrypt_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;
@@ -147,21 +144,7 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
     return 0;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
-{
-    QCryptoHmac *hmac;
-    QCryptoHmacGcrypt *ctx;
-
-    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
-    if (!ctx) {
-        return NULL;
-    }
-
-    hmac = g_new0(QCryptoHmac, 1);
-    hmac->alg = alg;
-    hmac->opaque = ctx;
-
-    return hmac;
-}
+QCryptoHmacDriver qcrypto_hmac_lib_driver = {
+    .hmac_bytesv = qcrypto_gcrypt_hmac_bytesv,
+    .hmac_free = qcrypto_gcrypt_hmac_ctx_free,
+};
diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c
index f0ccfd6..8cf6b22 100644
--- a/crypto/hmac-glib.c
+++ b/crypto/hmac-glib.c
@@ -15,6 +15,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hmac.h"
+#include "hmacpriv.h"
 
 /* Support for HMAC Algos has been added in GLib 2.30 */
 #if GLIB_CHECK_VERSION(2, 30, 0)
@@ -49,10 +50,9 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-static QCryptoHmacGlib *
-qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
-                     const uint8_t *key, size_t nkey,
-                     Error **errp)
+void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                           const uint8_t *key, size_t nkey,
+                           Error **errp)
 {
     QCryptoHmacGlib *ctx;
 
@@ -78,27 +78,24 @@ error:
     return NULL;
 }
 
-void qcrypto_hmac_free(QCryptoHmac *hmac)
+static void
+qcrypto_glib_hmac_ctx_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)
+static int
+qcrypto_glib_hmac_bytesv(QCryptoHmac *hmac,
+                         const struct iovec *iov,
+                         size_t niov,
+                         uint8_t **result,
+                         size_t *resultlen,
+                         Error **errp)
 {
     QCryptoHmacGlib *ctx;
     int i, ret;
@@ -129,25 +126,6 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
     return 0;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
-{
-    QCryptoHmac *hmac;
-    QCryptoHmacGlib *ctx;
-
-    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
-    if (!ctx) {
-        return NULL;
-    }
-
-    hmac = g_new0(QCryptoHmac, 1);
-    hmac->alg = alg;
-    hmac->opaque = ctx;
-
-    return hmac;
-}
-
 #else
 
 bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
@@ -155,26 +133,33 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
+void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                           const uint8_t *key, size_t nkey,
+                           Error **errp)
 {
     return NULL;
 }
 
-void qcrypto_hmac_free(QCryptoHmac *hmac)
+static void
+qcrypto_glib_hmac_ctx_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)
+static int
+qcrypto_glib_hmac_bytesv(QCryptoHmac *hmac,
+                         const struct iovec *iov,
+                         size_t niov,
+                         uint8_t **result,
+                         size_t *resultlen,
+                         Error **errp)
 {
     return -1;
 }
 
 #endif
+
+QCryptoHmacDriver qcrypto_hmac_lib_driver = {
+    .hmac_bytesv = qcrypto_glib_hmac_bytesv,
+    .hmac_free = qcrypto_glib_hmac_ctx_free,
+};
diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
index 000dfd9..1d5a915 100644
--- a/crypto/hmac-nettle.c
+++ b/crypto/hmac-nettle.c
@@ -15,6 +15,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hmac.h"
+#include "hmacpriv.h"
 #include <nettle/hmac.h>
 
 typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx,
@@ -97,10 +98,9 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
     return false;
 }
 
-static QCryptoHmacNettle *
-qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
-                     const uint8_t *key, size_t nkey,
-                     Error **errp)
+void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                           const uint8_t *key, size_t nkey,
+                           Error **errp)
 {
     QCryptoHmacNettle *ctx;
 
@@ -117,26 +117,22 @@ qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
     return ctx;
 }
 
-void qcrypto_hmac_free(QCryptoHmac *hmac)
+static void
+qcrypto_nettle_hmac_ctx_free(QCryptoHmac *hmac)
 {
     QCryptoHmacNettle *ctx;
 
-    if (!hmac) {
-        return;
-    }
-
     ctx = hmac->opaque;
-
     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)
+static int
+qcrypto_nettle_hmac_bytesv(QCryptoHmac *hmac,
+                           const struct iovec *iov,
+                           size_t niov,
+                           uint8_t **result,
+                           size_t *resultlen,
+                           Error **errp)
 {
     QCryptoHmacNettle *ctx;
     int i;
@@ -169,21 +165,7 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
     return 0;
 }
 
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
-                              const uint8_t *key, size_t nkey,
-                              Error **errp)
-{
-    QCryptoHmac *hmac;
-    QCryptoHmacNettle *ctx;
-
-    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
-    if (!ctx) {
-        return NULL;
-    }
-
-    hmac = g_new0(QCryptoHmac, 1);
-    hmac->alg = alg;
-    hmac->opaque = ctx;
-
-    return hmac;
-}
+QCryptoHmacDriver qcrypto_hmac_lib_driver = {
+    .hmac_bytesv = qcrypto_nettle_hmac_bytesv,
+    .hmac_free = qcrypto_nettle_hmac_ctx_free,
+};
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 5750405..a4690e3 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -12,9 +12,22 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "crypto/hmac.h"
+#include "hmacpriv.h"
 
 static const char hex[] = "0123456789abcdef";
 
+int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
+                        const struct iovec *iov,
+                        size_t niov,
+                        uint8_t **result,
+                        size_t *resultlen,
+                        Error **errp)
+{
+    QCryptoHmacDriver *drv = hmac->driver;
+
+    return drv->hmac_bytesv(hmac, iov, niov, result, resultlen, errp);
+}
+
 int qcrypto_hmac_bytes(QCryptoHmac *hmac,
                        const char *buf,
                        size_t len,
@@ -70,3 +83,34 @@ int qcrypto_hmac_digest(QCryptoHmac *hmac,
 
     return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp);
 }
+
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
+                              const uint8_t *key, size_t nkey,
+                              Error **errp)
+{
+    QCryptoHmac *hmac;
+    void *ctx;
+
+    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
+    if (!ctx) {
+        return NULL;
+    }
+
+    hmac = g_new0(QCryptoHmac, 1);
+    hmac->alg = alg;
+    hmac->opaque = ctx;
+    hmac->driver = (void *)&qcrypto_hmac_lib_driver;
+
+    return hmac;
+}
+
+void qcrypto_hmac_free(QCryptoHmac *hmac)
+{
+    QCryptoHmacDriver *drv;
+
+    if (hmac) {
+        drv = hmac->driver;
+        drv->hmac_free(hmac);
+        g_free(hmac);
+    }
+}
diff --git a/crypto/hmacpriv.h b/crypto/hmacpriv.h
new file mode 100644
index 0000000..2be389a
--- /dev/null
+++ b/crypto/hmacpriv.h
@@ -0,0 +1,36 @@
+/*
+ * QEMU Crypto hmac driver supports
+ *
+ * Copyright (c) 2017 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.
+ *
+ */
+
+#ifndef QCRYPTO_HMACPRIV_H
+#define QCRYPTO_HMACPRIV_H
+
+typedef struct QCryptoHmacDriver QCryptoHmacDriver;
+
+struct QCryptoHmacDriver {
+    int (*hmac_bytesv)(QCryptoHmac *hmac,
+                       const struct iovec *iov,
+                       size_t niov,
+                       uint8_t **result,
+                       size_t *resultlen,
+                       Error **errp);
+
+    void (*hmac_free)(QCryptoHmac *hmac);
+};
+
+extern void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                                  const uint8_t *key, size_t nkey,
+                                  Error **errp);
+extern QCryptoHmacDriver qcrypto_hmac_lib_driver;
+
+#endif
diff --git a/include/crypto/hmac.h b/include/crypto/hmac.h
index 0d3acd7..5e88905 100644
--- a/include/crypto/hmac.h
+++ b/include/crypto/hmac.h
@@ -18,6 +18,7 @@ typedef struct QCryptoHmac QCryptoHmac;
 struct QCryptoHmac {
     QCryptoHashAlgorithm alg;
     void *opaque;
+    void *driver;
 };
 
 /**
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (10 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 11/18] crypto: hmac: add hmac driver framework Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-11 12:28   ` Daniel P. Berrange
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support Longpeng(Mike)
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

The AF_ALG socket family is the userspace interface for linux
crypto API, this patch adds af_alg family support and some common
functions for af_alg backend. It'll be used by afalg-backend crypto
latter.

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 configure            |  22 ++++++++++
 crypto/Makefile.objs |   1 +
 crypto/afalg.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/afalgpriv.h   |  55 ++++++++++++++++++++++++
 4 files changed, 196 insertions(+)
 create mode 100644 crypto/afalg.c
 create mode 100644 crypto/afalgpriv.h

diff --git a/configure b/configure
index c571ad1..0b3e6c1 100755
--- a/configure
+++ b/configure
@@ -4744,6 +4744,24 @@ if compile_prog "" "" ; then
     have_af_vsock=yes
 fi
 
+##########################################
+# check for usable AF_ALG environment
+hava_af_alg=no
+cat > $TMPC << EOF
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/if_alg.h>
+int main(void) {
+    int sock;
+    sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
+    return sock;
+}
+EOF
+if compile_prog "" "" ; then
+    have_af_alg=yes
+fi
+
 #################################################
 # Sparc implicitly links with --relax, which is
 # incompatible with -r, so --no-relax should be
@@ -5855,6 +5873,10 @@ if test "$have_af_vsock" = "yes" ; then
   echo "CONFIG_AF_VSOCK=y" >> $config_host_mak
 fi
 
+if test "$have_af_alg" = "yes" ; then
+  echo "CONFIG_AF_ALG=y" >> $config_host_mak
+fi
+
 if test "$have_sysmacros" = "yes" ; then
   echo "CONFIG_SYSMACROS=y" >> $config_host_mak
 fi
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 1f749f2..2be5a3a 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -10,6 +10,7 @@ crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) += hmac-glib
 crypto-obj-y += aes.o
 crypto-obj-y += desrfb.o
 crypto-obj-y += cipher.o
+crypto-obj-$(CONFIG_AF_ALG) += afalg.o
 crypto-obj-y += tlscreds.o
 crypto-obj-y += tlscredsanon.o
 crypto-obj-y += tlscredsx509.o
diff --git a/crypto/afalg.c b/crypto/afalg.c
new file mode 100644
index 0000000..337d8a8
--- /dev/null
+++ b/crypto/afalg.c
@@ -0,0 +1,118 @@
+/*
+ * QEMU Crypto af_alg support
+ *
+ * Copyright (c) 2017 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 "qemu/cutils.h"
+#include "qemu/sockets.h"
+#include "qapi/error.h"
+#include "afalgpriv.h"
+
+static bool
+qcrypto_afalg_build_saddr(const char *type, const char *name,
+                          struct sockaddr_alg *salg, Error **errp)
+{
+    salg->salg_family = AF_ALG;
+
+    if (strnlen(type, SALG_TYPE_LEN_MAX) >= SALG_TYPE_LEN_MAX) {
+        error_setg(errp, "Afalg type(%s) is larger than %d bytes",
+                   type, SALG_TYPE_LEN_MAX);
+        return false;
+    }
+
+    if (strnlen(name, SALG_NAME_LEN_MAX) >= SALG_NAME_LEN_MAX) {
+        error_setg(errp, "Afalg name(%s) is larger than %d bytes",
+                   name, SALG_NAME_LEN_MAX);
+        return false;
+    }
+
+    pstrcpy((char *)salg->salg_type, SALG_TYPE_LEN_MAX, type);
+    pstrcpy((char *)salg->salg_name, SALG_NAME_LEN_MAX, name);
+
+    return true;
+}
+
+static int
+qcrypto_afalg_socket_bind(const char *type, const char *name,
+                          Error **errp)
+{
+    int sbind;
+    struct sockaddr_alg salg = {0};
+
+    if (!qcrypto_afalg_build_saddr(type, name, &salg, errp)) {
+        return -1;
+    }
+
+    sbind = qemu_socket(AF_ALG, SOCK_SEQPACKET, 0);
+    if (sbind < 0) {
+        error_setg_errno(errp, errno, "Failed to create socket");
+        return -1;
+    }
+
+    if (bind(sbind, (const struct sockaddr *)&salg, sizeof(salg)) != 0) {
+        error_setg_errno(errp, errno, "Failed to bind socket");
+        closesocket(sbind);
+        return -1;
+    }
+
+    return sbind;
+}
+
+QCryptoAFAlg *
+qcrypto_afalg_comm_alloc(const char *type, const char *name,
+                         Error **errp)
+{
+    QCryptoAFAlg *afalg;
+
+    afalg = g_new0(QCryptoAFAlg, 1);
+    /* initilize crypto API socket */
+    afalg->opfd = -1;
+    afalg->tfmfd = qcrypto_afalg_socket_bind(type, name, errp);
+    if (afalg->tfmfd == -1) {
+        goto error;
+    }
+
+    afalg->opfd = qemu_accept(afalg->tfmfd, NULL, 0);
+    if (afalg->opfd == -1) {
+        error_setg_errno(errp, errno, "Failed to accept socket");
+        goto error;
+    }
+
+    return afalg;
+
+error:
+    qcrypto_afalg_comm_free(afalg);
+    return NULL;
+}
+
+void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg)
+{
+    if (!afalg) {
+        return;
+    }
+
+    if (afalg->msg) {
+        g_free(afalg->msg->msg_control);
+        g_free(afalg->msg);
+    }
+
+    g_free(afalg->name);
+
+    if (afalg->tfmfd != -1) {
+        closesocket(afalg->tfmfd);
+    }
+
+    if (afalg->opfd != -1) {
+        closesocket(afalg->opfd);
+    }
+
+    g_free(afalg);
+}
diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
new file mode 100644
index 0000000..d21160c
--- /dev/null
+++ b/crypto/afalgpriv.h
@@ -0,0 +1,55 @@
+/*
+ * QEMU Crypto af_alg support
+ *
+ * Copyright (c) 2017 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.
+ */
+
+#ifndef QCRYPTO_AFALGPRIV_H
+#define QCRYPTO_AFALGPRIV_H
+
+#include <linux/if_alg.h>
+
+#define SALG_TYPE_LEN_MAX 14
+#define SALG_NAME_LEN_MAX 64
+
+typedef struct QCryptoAFAlg QCryptoAFAlg;
+
+struct QCryptoAFAlg {
+    int tfmfd;
+    int opfd;
+    char *name;
+    struct msghdr *msg;
+    struct cmsghdr *cmsg;
+};
+
+/**
+ * qcrypto_afalg_comm_alloc:
+ * @type: the type of crypto operation
+ * @name: the name of crypto operation
+ *
+ * Allocate a QCryptoAFAlg object and bind itself to
+ * a AF_ALG socket.
+ *
+ * Returns:
+ *  a new QCryptoAFAlg object, or NULL in error.
+ */
+QCryptoAFAlg *
+qcrypto_afalg_comm_alloc(const char *type, const char *name,
+                         Error **errp);
+
+/**
+ * afalg_comm_free:
+ * @afalg: the QCryptoAFAlg object
+ *
+ * Free the @afalg.
+ */
+void qcrypto_afalg_comm_free(QCryptoAFAlg *afalg);
+
+#endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (11 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-11 12:20   ` Daniel P. Berrange
  2017-07-11 12:29   ` Daniel P. Berrange
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 14/18] crypto: hash: add afalg-backend hash support Longpeng(Mike)
                   ` (5 subsequent siblings)
  18 siblings, 2 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

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

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/Makefile.objs  |   1 +
 crypto/afalgpriv.h    |   9 ++
 crypto/cipher-afalg.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/cipher.c       |  23 +++++-
 crypto/cipherpriv.h   |  16 ++++
 5 files changed, 268 insertions(+), 4 deletions(-)
 create mode 100644 crypto/cipher-afalg.c

diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 2be5a3a..d2e8fa8 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -11,6 +11,7 @@ crypto-obj-y += aes.o
 crypto-obj-y += desrfb.o
 crypto-obj-y += cipher.o
 crypto-obj-$(CONFIG_AF_ALG) += afalg.o
+crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
 crypto-obj-y += tlscreds.o
 crypto-obj-y += tlscredsanon.o
 crypto-obj-y += tlscredsx509.o
diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
index d21160c..a4a7b97 100644
--- a/crypto/afalgpriv.h
+++ b/crypto/afalgpriv.h
@@ -19,6 +19,15 @@
 #define SALG_TYPE_LEN_MAX 14
 #define SALG_NAME_LEN_MAX 64
 
+#ifndef SOL_ALG
+#define SOL_ALG 279
+#endif
+
+#define AFALG_TYPE_CIPHER "skcipher"
+
+#define ALG_OPTYPE_LEN 4
+#define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len))
+
 typedef struct QCryptoAFAlg QCryptoAFAlg;
 
 struct QCryptoAFAlg {
diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
new file mode 100644
index 0000000..c5d1d5d
--- /dev/null
+++ b/crypto/cipher-afalg.c
@@ -0,0 +1,223 @@
+/*
+ * QEMU Crypto af_alg-backend cipher support
+ *
+ * Copyright (c) 2017 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 "qemu/sockets.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "crypto/cipher.h"
+#include "cipherpriv.h"
+
+
+static char *
+qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg,
+                                 QCryptoCipherMode mode,
+                                 Error **errp)
+{
+    char *name;
+    const char *alg_name;
+    const char *mode_name;
+
+    switch (alg) {
+    case QCRYPTO_CIPHER_ALG_AES_128:
+    case QCRYPTO_CIPHER_ALG_AES_192:
+    case QCRYPTO_CIPHER_ALG_AES_256:
+        alg_name = "aes";
+        break;
+    case QCRYPTO_CIPHER_ALG_CAST5_128:
+        alg_name = "cast5";
+        break;
+    case QCRYPTO_CIPHER_ALG_SERPENT_128:
+    case QCRYPTO_CIPHER_ALG_SERPENT_192:
+    case QCRYPTO_CIPHER_ALG_SERPENT_256:
+        alg_name = "serpent";
+        break;
+    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
+    case QCRYPTO_CIPHER_ALG_TWOFISH_192:
+    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
+        alg_name = "twofish";
+        break;
+
+    default:
+        error_setg(errp, "Unsupported cipher algorithm %d", alg);
+        return NULL;
+    }
+
+    mode_name = QCryptoCipherMode_lookup[mode];
+    name = g_strdup_printf("%s(%s)", mode_name, alg_name);
+
+    return name;
+}
+
+QCryptoAFAlg *
+qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+                             QCryptoCipherMode mode,
+                             const uint8_t *key,
+                             size_t nkey, Error **errp)
+{
+    QCryptoAFAlg *afalg;
+    size_t expect_niv;
+    char *name;
+
+    name = qcrypto_afalg_cipher_format_name(alg, mode, errp);
+    if (!name) {
+        return NULL;
+    }
+
+    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_CIPHER, name, errp);
+    if (!afalg) {
+        g_free(name);
+        return NULL;
+    }
+    afalg->name = name;
+
+    /* setkey */
+    if (qemu_setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY, key,
+                        nkey) != 0) {
+        error_setg_errno(errp, errno, "Set key failed");
+        qcrypto_afalg_comm_free(afalg);
+        return NULL;
+    }
+
+    /* prepare msg header */
+    afalg->msg = g_new0(struct msghdr, 1);
+    afalg->msg->msg_controllen += CMSG_SPACE(ALG_OPTYPE_LEN);
+    expect_niv = qcrypto_cipher_get_iv_len(alg, mode);
+    if (expect_niv) {
+        afalg->msg->msg_controllen += CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
+    }
+    afalg->msg->msg_control = g_new0(uint8_t, afalg->msg->msg_controllen);
+
+    /* We use 1st msghdr for crypto-info and 2nd msghdr for IV-info */
+    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
+    afalg->cmsg->cmsg_type = ALG_SET_OP;
+    afalg->cmsg->cmsg_len = CMSG_SPACE(ALG_OPTYPE_LEN);
+    if (expect_niv) {
+        afalg->cmsg = CMSG_NXTHDR(afalg->msg, afalg->cmsg);
+        afalg->cmsg->cmsg_type = ALG_SET_IV;
+        afalg->cmsg->cmsg_len = CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
+    }
+    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
+
+    return afalg;
+}
+
+static int
+qcrypto_afalg_cipher_setiv(QCryptoCipher *cipher,
+                           const uint8_t *iv,
+                           size_t niv, Error **errp)
+{
+    struct af_alg_iv *alg_iv;
+    size_t expect_niv;
+    QCryptoAFAlg *afalg = cipher->opaque;
+
+    expect_niv = qcrypto_cipher_get_iv_len(cipher->alg, cipher->mode);
+    if (niv != expect_niv) {
+        error_setg(errp, "Set IV len(%zu) not match expected(%zu)",
+                   niv, expect_niv);
+        return -1;
+    }
+
+    /* move ->cmsg to next msghdr, for IV-info */
+    afalg->cmsg = CMSG_NXTHDR(afalg->msg, afalg->cmsg);
+
+    /* build setiv msg */
+    afalg->cmsg->cmsg_level = SOL_ALG;
+    alg_iv = (struct af_alg_iv *)CMSG_DATA(afalg->cmsg);
+    alg_iv->ivlen = niv;
+    memcpy(alg_iv->iv, iv, niv);
+
+    return 0;
+}
+
+static int
+qcrypto_afalg_cipher_op(QCryptoAFAlg *afalg,
+                        const void *in, void *out,
+                        size_t len, bool do_encrypt,
+                        Error **errp)
+{
+    uint32_t *type = NULL;
+    struct iovec iov;
+    size_t ret, done = 0;
+    uint32_t origin_controllen;
+
+    origin_controllen = afalg->msg->msg_controllen;
+    /* movev ->cmsg to first header, for crypto-info */
+    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
+
+    /* build encrypt msg */
+    afalg->cmsg->cmsg_level = SOL_ALG;
+    afalg->msg->msg_iov = &iov;
+    afalg->msg->msg_iovlen = 1;
+    type = (uint32_t *)CMSG_DATA(afalg->cmsg);
+    if (do_encrypt) {
+        *type = ALG_OP_ENCRYPT;
+    } else {
+        *type = ALG_OP_DECRYPT;
+    }
+
+    do {
+        iov.iov_base = (void *)in + done;
+        iov.iov_len = len - done;
+
+        /* send info to AF_ALG core */
+        ret = sendmsg(afalg->opfd, afalg->msg, 0);
+        if (ret == -1) {
+            error_setg_errno(errp, errno, "Send data to AF_ALG core failed");
+            return -1;
+        }
+
+        /* encrypto && get result */
+        if (ret != read(afalg->opfd, out, ret)) {
+            error_setg_errno(errp, errno, "Get result from AF_ALG core failed");
+            return -1;
+        }
+
+        /* do not update IV for following chunks */
+        afalg->msg->msg_controllen = 0;
+        done += ret;
+    } while (done < len);
+
+    afalg->msg->msg_controllen = origin_controllen;
+
+    return 0;
+}
+
+static int
+qcrypto_afalg_cipher_encrypt(QCryptoCipher *cipher,
+                             const void *in, void *out,
+                             size_t len, Error **errp)
+{
+    return qcrypto_afalg_cipher_op(cipher->opaque, in, out,
+                                   len, true, errp);
+}
+
+static int
+qcrypto_afalg_cipher_decrypt(QCryptoCipher *cipher,
+                             const void *in, void *out,
+                             size_t len, Error **errp)
+{
+    return qcrypto_afalg_cipher_op(cipher->opaque, in, out,
+                                   len, false, errp);
+}
+
+static void qcrypto_afalg_comm_ctx_free(QCryptoCipher *cipher)
+{
+    qcrypto_afalg_comm_free(cipher->opaque);
+}
+
+struct QCryptoCipherDriver qcrypto_cipher_afalg_driver = {
+    .cipher_encrypt = qcrypto_afalg_cipher_encrypt,
+    .cipher_decrypt = qcrypto_afalg_cipher_decrypt,
+    .cipher_setiv = qcrypto_afalg_cipher_setiv,
+    .cipher_free = qcrypto_afalg_comm_ctx_free,
+};
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 0a3d2e5..a487270 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -163,18 +163,33 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                                   Error **errp)
 {
     QCryptoCipher *cipher;
-    void *ctx;
+    void *ctx = NULL;
+    Error *err2 = NULL;
+    QCryptoCipherDriver *drv;
+
+#ifdef CONFIG_AF_ALG
+    ctx = qcrypto_afalg_cipher_ctx_new(alg, mode, key, nkey, &err2);
+    if (ctx) {
+        drv = &qcrypto_cipher_afalg_driver;
+    }
+#endif
 
-    ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
     if (!ctx) {
-        return NULL;
+        ctx = qcrypto_cipher_ctx_new(alg, mode, key, nkey, errp);
+        if (!ctx) {
+            error_free(err2);
+            return NULL;
+        }
+
+        drv = &qcrypto_cipher_lib_driver;
+        error_free(err2);
     }
 
     cipher = g_new0(QCryptoCipher, 1);
     cipher->alg = alg;
     cipher->mode = mode;
     cipher->opaque = ctx;
-    cipher->driver = (void *)&qcrypto_cipher_lib_driver;
+    cipher->driver = (void *)drv;
 
     return cipher;
 }
diff --git a/crypto/cipherpriv.h b/crypto/cipherpriv.h
index 4af5e85..77da4c2 100644
--- a/crypto/cipherpriv.h
+++ b/crypto/cipherpriv.h
@@ -15,6 +15,8 @@
 #ifndef QCRYPTO_CIPHERPRIV_H
 #define QCRYPTO_CIPHERPRIV_H
 
+#include "qapi-types.h"
+
 typedef struct QCryptoCipherDriver QCryptoCipherDriver;
 
 struct QCryptoCipherDriver {
@@ -37,4 +39,18 @@ struct QCryptoCipherDriver {
     void (*cipher_free)(QCryptoCipher *cipher);
 };
 
+#ifdef CONFIG_AF_ALG
+
+#include "afalgpriv.h"
+
+extern QCryptoAFAlg *
+qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
+                             QCryptoCipherMode mode,
+                             const uint8_t *key,
+                             size_t nkey, Error **errp);
+
+extern struct QCryptoCipherDriver qcrypto_cipher_afalg_driver;
+
+#endif
+
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 14/18] crypto: hash: add afalg-backend hash support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (12 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-11 12:32   ` Daniel P. Berrange
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 15/18] crypto: hmac: add af_alg hmac support Longpeng(Mike)
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

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

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/Makefile.objs |   1 +
 crypto/afalgpriv.h   |   1 +
 crypto/hash-afalg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/hash.c        |  17 +++++++
 crypto/hashpriv.h    |   8 +++
 5 files changed, 166 insertions(+)
 create mode 100644 crypto/hash-afalg.c

diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index d2e8fa8..2b99e08 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -12,6 +12,7 @@ crypto-obj-y += desrfb.o
 crypto-obj-y += cipher.o
 crypto-obj-$(CONFIG_AF_ALG) += afalg.o
 crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
+crypto-obj-$(CONFIG_AF_ALG) += hash-afalg.o
 crypto-obj-y += tlscreds.o
 crypto-obj-y += tlscredsanon.o
 crypto-obj-y += tlscredsx509.o
diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
index a4a7b97..9d42ba9 100644
--- a/crypto/afalgpriv.h
+++ b/crypto/afalgpriv.h
@@ -24,6 +24,7 @@
 #endif
 
 #define AFALG_TYPE_CIPHER "skcipher"
+#define AFALG_TYPE_HASH "hash"
 
 #define ALG_OPTYPE_LEN 4
 #define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len))
diff --git a/crypto/hash-afalg.c b/crypto/hash-afalg.c
new file mode 100644
index 0000000..a19847e
--- /dev/null
+++ b/crypto/hash-afalg.c
@@ -0,0 +1,139 @@
+/*
+ * QEMU Crypto af_alg-backend hash support
+ *
+ * Copyright (c) 2017 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 "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "crypto/hash.h"
+#include "hashpriv.h"
+
+static char *
+qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg,
+                               Error **errp)
+{
+    char *name;
+    const char *alg_name;
+
+    switch (alg) {
+    case QCRYPTO_HASH_ALG_MD5:
+        alg_name = "md5";
+        break;
+    case QCRYPTO_HASH_ALG_SHA1:
+        alg_name = "sha1";
+        break;
+    case QCRYPTO_HASH_ALG_SHA224:
+        alg_name = "sha224";
+        break;
+    case QCRYPTO_HASH_ALG_SHA256:
+        alg_name = "sha256";
+        break;
+    case QCRYPTO_HASH_ALG_SHA384:
+        alg_name = "sha384";
+        break;
+    case QCRYPTO_HASH_ALG_SHA512:
+        alg_name = "sha512";
+        break;
+    case QCRYPTO_HASH_ALG_RIPEMD160:
+        alg_name = "rmd160";
+        break;
+
+    default:
+        error_setg(errp, "Unsupported hash algorithm %d", alg);
+        return NULL;
+    }
+
+    name = g_strdup_printf("%s", alg_name);
+
+    return name;
+}
+
+static QCryptoAFAlg *
+qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, Error **errp)
+{
+    QCryptoAFAlg *afalg;
+    char *name;
+
+    name = qcrypto_afalg_hash_format_name(alg, errp);
+    if (!name) {
+        return NULL;
+    }
+
+    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_HASH, name, errp);
+    if (!afalg) {
+        g_free(name);
+        return NULL;
+    }
+    afalg->name = name;
+
+    /* prepare msg header */
+    afalg->msg = g_new0(struct msghdr, 1);
+
+    return afalg;
+}
+
+static int
+qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
+                          const struct iovec *iov,
+                          size_t niov, uint8_t **result,
+                          size_t *resultlen,
+                          Error **errp)
+{
+    QCryptoAFAlg *afalg;
+    struct iovec outv;
+    int ret = 0;
+    const int expect_len = qcrypto_hash_digest_len(alg);
+
+    if (*resultlen == 0) {
+        *resultlen = expect_len;
+        *result = g_new0(uint8_t, *resultlen);
+    } else if (*resultlen != expect_len) {
+        error_setg(errp,
+                   "Result buffer size %zu is not match hash %d",
+                   *resultlen, expect_len);
+        return -1;
+    }
+
+    afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
+    if (!afalg) {
+        return -1;
+    }
+
+    /* send data to kernel's crypto core */
+    ret = iov_send_recv(afalg->opfd, iov, niov,
+                        0, iov_size(iov, niov), true);
+    if (ret < 0) {
+        error_setg_errno(errp, errno, "Send data to afalg-core failed");
+        goto out;
+    }
+
+    /* hash && get result */
+    outv.iov_base = *result;
+    outv.iov_len = *resultlen;
+    afalg->msg->msg_iov = &outv;
+    afalg->msg->msg_iovlen = 1;
+    ret = recvmsg(afalg->opfd, afalg->msg, 0);
+    if (ret != -1) {
+        ret = 0;
+    } else {
+        error_setg_errno(errp, errno, "Recv result from afalg-core failed");
+    }
+
+out:
+    qcrypto_afalg_comm_free(afalg);
+    return ret;
+}
+
+QCryptoHashDriver qcrypto_hash_afalg_driver = {
+    .hash_bytesv = qcrypto_afalg_hash_bytesv,
+};
diff --git a/crypto/hash.c b/crypto/hash.c
index c43fd87..ac59c63 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -46,6 +46,23 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
                         size_t *resultlen,
                         Error **errp)
 {
+#ifdef CONFIG_AF_ALG
+    int ret;
+
+    ret = qcrypto_hash_afalg_driver.hash_bytesv(alg, iov, niov,
+                                                result, resultlen,
+                                                errp);
+    if (ret == 0) {
+        return ret;
+    }
+
+    /*
+     * TODO:
+     * Maybe we should treat some afalg errors as fatal
+     */
+    error_free(*errp);
+#endif
+
     return qcrypto_hash_lib_driver.hash_bytesv(alg, iov, niov,
                                                result, resultlen,
                                                errp);
diff --git a/crypto/hashpriv.h b/crypto/hashpriv.h
index 5e505e0..cee26cc 100644
--- a/crypto/hashpriv.h
+++ b/crypto/hashpriv.h
@@ -28,4 +28,12 @@ struct QCryptoHashDriver {
 
 extern QCryptoHashDriver qcrypto_hash_lib_driver;
 
+#ifdef CONFIG_AF_ALG
+
+#include "afalgpriv.h"
+
+extern QCryptoHashDriver qcrypto_hash_afalg_driver;
+
+#endif
+
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 15/18] crypto: hmac: add af_alg hmac support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (13 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 14/18] crypto: hash: add afalg-backend hash support Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 16/18] tests: crypto: add cipher speed benchmark support Longpeng(Mike)
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

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

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 crypto/hash-afalg.c | 104 +++++++++++++++++++++++++++++++++++++++++++++-------
 crypto/hmac.c       |  22 +++++++++--
 crypto/hmacpriv.h   |  12 ++++++
 3 files changed, 121 insertions(+), 17 deletions(-)

diff --git a/crypto/hash-afalg.c b/crypto/hash-afalg.c
index a19847e..1ccb49e 100644
--- a/crypto/hash-afalg.c
+++ b/crypto/hash-afalg.c
@@ -1,5 +1,5 @@
 /*
- * QEMU Crypto af_alg-backend hash support
+ * QEMU Crypto af_alg-backend hash/hmac support
  *
  * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
  *
@@ -16,10 +16,13 @@
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "crypto/hash.h"
+#include "crypto/hmac.h"
 #include "hashpriv.h"
+#include "hmacpriv.h"
 
 static char *
 qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg,
+                               bool is_hmac,
                                Error **errp)
 {
     char *name;
@@ -53,18 +56,24 @@ qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg,
         return NULL;
     }
 
-    name = g_strdup_printf("%s", alg_name);
+    if (is_hmac) {
+        name = g_strdup_printf("hmac(%s)", alg_name);
+    } else {
+        name = g_strdup_printf("%s", alg_name);
+    }
 
     return name;
 }
 
 static QCryptoAFAlg *
-qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, Error **errp)
+qcrypto_afalg_hash_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                                const uint8_t *key, size_t nkey,
+                                bool is_hmac, Error **errp)
 {
     QCryptoAFAlg *afalg;
     char *name;
 
-    name = qcrypto_afalg_hash_format_name(alg, errp);
+    name = qcrypto_afalg_hash_format_name(alg, is_hmac, errp);
     if (!name) {
         return NULL;
     }
@@ -76,22 +85,49 @@ qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, Error **errp)
     }
     afalg->name = name;
 
+    /* HMAC needs setkey */
+    if (is_hmac) {
+        if (qemu_setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY,
+                            key, nkey) != 0) {
+            error_setg_errno(errp, errno, "Set hmac key failed");
+            qcrypto_afalg_comm_free(afalg);
+            return NULL;
+        }
+    }
+
     /* prepare msg header */
     afalg->msg = g_new0(struct msghdr, 1);
 
     return afalg;
 }
 
+static QCryptoAFAlg *
+qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg,
+                           Error **errp)
+{
+    return qcrypto_afalg_hash_hmac_ctx_new(alg, NULL, 0, false, errp);
+}
+
+QCryptoAFAlg *
+qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                           const uint8_t *key, size_t nkey,
+                           Error **errp)
+{
+    return qcrypto_afalg_hash_hmac_ctx_new(alg, key, nkey, true, errp);
+}
+
 static int
-qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
-                          const struct iovec *iov,
-                          size_t niov, uint8_t **result,
-                          size_t *resultlen,
-                          Error **errp)
+qcrypto_afalg_hash_hmac_bytesv(QCryptoAFAlg *hmac,
+                               QCryptoHashAlgorithm alg,
+                               const struct iovec *iov,
+                               size_t niov, uint8_t **result,
+                               size_t *resultlen,
+                               Error **errp)
 {
     QCryptoAFAlg *afalg;
     struct iovec outv;
     int ret = 0;
+    bool is_hmac = (hmac != NULL) ? true : false;
     const int expect_len = qcrypto_hash_digest_len(alg);
 
     if (*resultlen == 0) {
@@ -104,9 +140,13 @@ qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
         return -1;
     }
 
-    afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
-    if (!afalg) {
-        return -1;
+    if (is_hmac) {
+        afalg = hmac;
+    } else {
+        afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
+        if (!afalg) {
+            return -1;
+        }
     }
 
     /* send data to kernel's crypto core */
@@ -130,10 +170,48 @@ qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
     }
 
 out:
-    qcrypto_afalg_comm_free(afalg);
+    if (!is_hmac) {
+        qcrypto_afalg_comm_free(afalg);
+    }
     return ret;
 }
 
+static int
+qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
+                          const struct iovec *iov,
+                          size_t niov, uint8_t **result,
+                          size_t *resultlen,
+                          Error **errp)
+{
+    return qcrypto_afalg_hash_hmac_bytesv(NULL, alg, iov, niov, result,
+                                          resultlen, errp);
+}
+
+static int
+qcrypto_afalg_hmac_bytesv(QCryptoHmac *hmac,
+                          const struct iovec *iov,
+                          size_t niov, uint8_t **result,
+                          size_t *resultlen,
+                          Error **errp)
+{
+    return qcrypto_afalg_hash_hmac_bytesv(hmac->opaque, hmac->alg,
+                                          iov, niov, result, resultlen,
+                                          errp);
+}
+
+static void qcrypto_afalg_hmac_ctx_free(QCryptoHmac *hmac)
+{
+    QCryptoAFAlg *afalg;
+
+    afalg = hmac->opaque;
+    qcrypto_afalg_comm_free(afalg);
+}
+
 QCryptoHashDriver qcrypto_hash_afalg_driver = {
     .hash_bytesv = qcrypto_afalg_hash_bytesv,
 };
+
+QCryptoHmacDriver qcrypto_hmac_afalg_driver = {
+    .hmac_bytesv = qcrypto_afalg_hmac_bytesv,
+    .hmac_free = qcrypto_afalg_hmac_ctx_free,
+};
diff --git a/crypto/hmac.c b/crypto/hmac.c
index a4690e3..37e2af2 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -89,17 +89,31 @@ QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
                               Error **errp)
 {
     QCryptoHmac *hmac;
-    void *ctx;
+    void *ctx = NULL;
+    Error *err2 = NULL;
+    QCryptoHmacDriver *drv;
+
+#ifdef CONFIG_AF_ALG
+    ctx = qcrypto_afalg_hmac_ctx_new(alg, key, nkey, &err2);
+    if (ctx) {
+        drv = &qcrypto_hmac_afalg_driver;
+    }
+#endif
 
-    ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
     if (!ctx) {
-        return NULL;
+        ctx = qcrypto_hmac_ctx_new(alg, key, nkey, errp);
+        if (!ctx) {
+            return NULL;
+        }
+
+        drv = &qcrypto_hmac_lib_driver;
+        error_free(err2);
     }
 
     hmac = g_new0(QCryptoHmac, 1);
     hmac->alg = alg;
     hmac->opaque = ctx;
-    hmac->driver = (void *)&qcrypto_hmac_lib_driver;
+    hmac->driver = (void *)drv;
 
     return hmac;
 }
diff --git a/crypto/hmacpriv.h b/crypto/hmacpriv.h
index 2be389a..4387ca2 100644
--- a/crypto/hmacpriv.h
+++ b/crypto/hmacpriv.h
@@ -33,4 +33,16 @@ extern void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
                                   Error **errp);
 extern QCryptoHmacDriver qcrypto_hmac_lib_driver;
 
+#ifdef CONFIG_AF_ALG
+
+#include "afalgpriv.h"
+
+extern QCryptoAFAlg *
+qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
+                           const uint8_t *key, size_t nkey,
+                           Error **errp);
+extern QCryptoHmacDriver qcrypto_hmac_afalg_driver;
+
+#endif
+
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 16/18] tests: crypto: add cipher speed benchmark support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (14 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 15/18] crypto: hmac: add af_alg hmac support Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 17/18] tests: crypto: add hash " Longpeng(Mike)
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

Now we have two qcrypto backends, libiary-backend and afalg-backend,
but which one is faster? This patch add a cipher speed benchmark, it
helps us to measure the performance by using "make check-speed" or
using "./tests/benchmark-crypto-cipher" directly.

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 tests/Makefile.include          |  9 ++++-
 tests/benchmark-crypto-cipher.c | 88 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 2 deletions(-)
 create mode 100644 tests/benchmark-crypto-cipher.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index ae889ca..7bf7277 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -99,6 +99,7 @@ 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-speed-y += tests/benchmark-crypto-cipher$(EXESUF)
 check-unit-y += tests/test-crypto-secret$(EXESUF)
 check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
 check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
@@ -531,6 +532,7 @@ test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y)
 test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \
 	tests/test-qapi-event.o tests/test-qmp-introspect.o \
 	$(test-qom-obj-y)
+benchmark-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
 test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
 test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
 test-block-obj-y = $(block-obj-y) $(test-io-obj-y) tests/iothread.o
@@ -634,6 +636,7 @@ tests/test-bitcnt$(EXESUF): tests/test-bitcnt.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/benchmark-crypto-cipher$(EXESUF): tests/benchmark-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)
 
@@ -801,6 +804,7 @@ check-help:
 	@echo " make check-qtest-TARGET   Run qtest tests for given target"
 	@echo " make check-qtest          Run qtest tests"
 	@echo " make check-unit           Run qobject tests"
+	@echo " make check-speed          Run qobject speed tests"
 	@echo " make check-qapi-schema    Run QAPI schema tests"
 	@echo " make check-block          Run block tests"
 	@echo " make check-report.html    Generates an HTML test report"
@@ -831,8 +835,8 @@ $(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y)
 	  $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \
 	done,)
 
-.PHONY: $(patsubst %, check-%, $(check-unit-y))
-$(patsubst %, check-%, $(check-unit-y)): check-%: %
+.PHONY: $(patsubst %, check-%, $(check-unit-y) $(check-speed-y))
+$(patsubst %, check-%, $(check-unit-y) $(check-speed-y)): check-%: %
 	$(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,)
 	$(call quiet-command, \
 		MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \
@@ -891,6 +895,7 @@ check-tests/qapi-schema/doc-good.texi: tests/qapi-schema/doc-good.test.texi
 check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y)) check-tests/qapi-schema/doc-good.texi
 check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
 check-unit: $(patsubst %,check-%, $(check-unit-y))
+check-speed: $(patsubst %,check-%, $(check-speed-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
 check: check-qapi-schema check-unit check-qtest
 check-clean:
diff --git a/tests/benchmark-crypto-cipher.c b/tests/benchmark-crypto-cipher.c
new file mode 100644
index 0000000..c6a4092
--- /dev/null
+++ b/tests/benchmark-crypto-cipher.c
@@ -0,0 +1,88 @@
+/*
+ * QEMU Crypto cipher speed benchmark
+ *
+ * Copyright (c) 2017 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/cipher.h"
+
+static void test_cipher_speed(const void *opaque)
+{
+    QCryptoCipher *cipher;
+    Error *err = NULL;
+    double total = 0.0;
+    size_t chunk_size = (size_t)opaque;
+    uint8_t *key = NULL, *iv = NULL;
+    uint8_t *plaintext = NULL, *ciphertext = NULL;
+    size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALG_AES_128);
+    size_t niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128,
+                                           QCRYPTO_CIPHER_MODE_CBC);
+
+    key = g_new0(uint8_t, nkey);
+    memset(key, g_test_rand_int(), nkey);
+
+    iv = g_new0(uint8_t, niv);
+    memset(iv, g_test_rand_int(), niv);
+
+    ciphertext = g_new0(uint8_t, chunk_size);
+
+    plaintext = g_new0(uint8_t, chunk_size);
+    memset(plaintext, g_test_rand_int(), chunk_size);
+
+    cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
+                                QCRYPTO_CIPHER_MODE_CBC,
+                                key, nkey, &err);
+    g_assert(cipher != NULL);
+
+    g_assert(qcrypto_cipher_setiv(cipher,
+                                  iv, niv,
+                                  &err) == 0);
+
+    g_test_timer_start();
+    do {
+        g_assert(qcrypto_cipher_encrypt(cipher,
+                                        plaintext,
+                                        ciphertext,
+                                        chunk_size,
+                                        &err) == 0);
+        total += chunk_size;
+    } while (g_test_timer_elapsed() < 5.0);
+
+    total /= 1024 * 1024; /* to MB */
+
+    g_print("cbc(aes128): ");
+    g_print("Testing chunk_size %ld bytes ", chunk_size);
+    g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
+    g_print("%.2f MB/sec\n", total / g_test_timer_last());
+
+    qcrypto_cipher_free(cipher);
+    g_free(plaintext);
+    g_free(ciphertext);
+    g_free(iv);
+    g_free(key);
+}
+
+int main(int argc, char **argv)
+{
+    size_t i;
+    char name[64];
+
+    g_test_init(&argc, &argv, NULL);
+    g_assert(qcrypto_init(NULL) == 0);
+
+    for (i = 512; i <= (64 * 1204); i *= 2) {
+        memset(name, 0 , sizeof(name));
+        snprintf(name, sizeof(name), "/crypto/cipher/speed-%lu", i);
+        g_test_add_data_func(name, (void *)i, test_cipher_speed);
+    }
+
+    return g_test_run();
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 17/18] tests: crypto: add hash speed benchmark support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (15 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 16/18] tests: crypto: add cipher speed benchmark support Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 18/18] tests: crypto: add hmac " Longpeng(Mike)
  2017-07-06 14:06 ` [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Daniel P. Berrange
  18 siblings, 0 replies; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

This patch add a hash speed benchmark, it helps us to
measure the performance by using "make check-speed" or
using "./tests/benchmark-crypto-cipher" directly.

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 tests/Makefile.include        |  2 ++
 tests/benchmark-crypto-hash.c | 67 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 tests/benchmark-crypto-hash.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 7bf7277..e83eb6b 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -97,6 +97,7 @@ gcov-files-test-keyval-y = util/keyval.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-speed-y += tests/benchmark-crypto-hash$(EXESUF)
 check-unit-y += tests/test-crypto-hmac$(EXESUF)
 check-unit-y += tests/test-crypto-cipher$(EXESUF)
 check-speed-y += tests/benchmark-crypto-cipher$(EXESUF)
@@ -634,6 +635,7 @@ 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-bitcnt$(EXESUF): tests/test-bitcnt.o $(test-util-obj-y)
 tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
+tests/benchmark-crypto-hash$(EXESUF): tests/benchmark-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/benchmark-crypto-cipher$(EXESUF): tests/benchmark-crypto-cipher.o $(test-crypto-obj-y)
diff --git a/tests/benchmark-crypto-hash.c b/tests/benchmark-crypto-hash.c
new file mode 100644
index 0000000..6769d2a
--- /dev/null
+++ b/tests/benchmark-crypto-hash.c
@@ -0,0 +1,67 @@
+/*
+ * QEMU Crypto hash speed benchmark
+ *
+ * Copyright (c) 2017 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/hash.h"
+
+static void test_hash_speed(const void *opaque)
+{
+    size_t chunk_size = (size_t)opaque;
+    uint8_t *in = NULL, *out = NULL;
+    size_t out_len = 0;
+    double total = 0.0;
+    struct iovec iov;
+    int ret;
+
+    in = g_new0(uint8_t, chunk_size);
+    memset(in, g_test_rand_int(), chunk_size);
+
+    iov.iov_base = (char *)in;
+    iov.iov_len = chunk_size;
+
+    g_test_timer_start();
+    do {
+        ret = qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256,
+                                  &iov, 1, &out, &out_len,
+                                  NULL);
+        g_assert(ret == 0);
+
+        total += chunk_size;
+    } while (g_test_timer_elapsed() < 5.0);
+
+    total /= 1024 * 1024; /* to MB */
+    g_print("sha256: ");
+    g_print("Testing chunk_size %ld bytes ", chunk_size);
+    g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
+    g_print("%.2f MB/sec\n", total / g_test_timer_last());
+
+    g_free(out);
+    g_free(in);
+}
+
+int main(int argc, char **argv)
+{
+    size_t i;
+    char name[64];
+
+    g_test_init(&argc, &argv, NULL);
+    g_assert(qcrypto_init(NULL) == 0);
+
+    for (i = 512; i <= (64 * 1204); i *= 2) {
+        memset(name, 0 , sizeof(name));
+        snprintf(name, sizeof(name), "/crypto/hash/speed-%lu", i);
+        g_test_add_data_func(name, (void *)i, test_hash_speed);
+    }
+
+    return g_test_run();
+}
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v4 18/18] tests: crypto: add hmac speed benchmark support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (16 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 17/18] tests: crypto: add hash " Longpeng(Mike)
@ 2017-07-04  8:57 ` Longpeng(Mike)
  2017-07-11 12:34   ` Daniel P. Berrange
  2017-07-06 14:06 ` [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Daniel P. Berrange
  18 siblings, 1 reply; 29+ messages in thread
From: Longpeng(Mike) @ 2017-07-04  8:57 UTC (permalink / raw)
  To: berrange
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel,
	longpeng.mike, Longpeng(Mike)

This patch add a hmac speed benchmark, it helps us to
measure the performance by using "make check-speed" or
using "./tests/benchmark-crypto-hmac" directly.

Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
---
 tests/Makefile.include        |  2 +
 tests/benchmark-crypto-hmac.c | 94 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)
 create mode 100644 tests/benchmark-crypto-hmac.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index e83eb6b..258bcbc 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -99,6 +99,7 @@ gcov-files-test-write-threshold-y = block/write-threshold.c
 check-unit-y += tests/test-crypto-hash$(EXESUF)
 check-speed-y += tests/benchmark-crypto-hash$(EXESUF)
 check-unit-y += tests/test-crypto-hmac$(EXESUF)
+check-speed-y += tests/benchmark-crypto-hmac$(EXESUF)
 check-unit-y += tests/test-crypto-cipher$(EXESUF)
 check-speed-y += tests/benchmark-crypto-cipher$(EXESUF)
 check-unit-y += tests/test-crypto-secret$(EXESUF)
@@ -637,6 +638,7 @@ tests/test-bitcnt$(EXESUF): tests/test-bitcnt.o $(test-util-obj-y)
 tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
 tests/benchmark-crypto-hash$(EXESUF): tests/benchmark-crypto-hash.o $(test-crypto-obj-y)
 tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
+tests/benchmark-crypto-hmac$(EXESUF): tests/benchmark-crypto-hmac.o $(test-crypto-obj-y)
 tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
 tests/benchmark-crypto-cipher$(EXESUF): tests/benchmark-crypto-cipher.o $(test-crypto-obj-y)
 tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
diff --git a/tests/benchmark-crypto-hmac.c b/tests/benchmark-crypto-hmac.c
new file mode 100644
index 0000000..05b02a5
--- /dev/null
+++ b/tests/benchmark-crypto-hmac.c
@@ -0,0 +1,94 @@
+/*
+ * QEMU Crypto hmac speed benchmark
+ *
+ * Copyright (c) 2017 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 KEY "monkey monkey monkey monkey"
+
+static void test_hmac_speed(const void *opaque)
+{
+    size_t chunk_size = (size_t)opaque;
+    QCryptoHmac *hmac = NULL;
+    uint8_t *in = NULL, *out = NULL;
+    size_t out_len = 0;
+    double total = 0.0;
+    struct iovec iov;
+    Error *err = NULL;
+    int ret;
+
+    if (!qcrypto_hmac_supports(QCRYPTO_HASH_ALG_SHA256)) {
+        return;
+    }
+
+    hmac = qcrypto_hmac_new(QCRYPTO_HASH_ALG_SHA256, (const uint8_t *)KEY,
+                            strlen(KEY), &err);
+    g_assert(err == NULL);
+    g_assert(hmac != NULL);
+
+    in = g_new0(uint8_t, chunk_size);
+    memset(in, g_test_rand_int(), chunk_size);
+
+    iov.iov_base = (char *)in;
+    iov.iov_len = chunk_size;
+
+    g_test_timer_start();
+    do {
+        ret = qcrypto_hmac_bytesv(hmac, &iov, 1, &out, &out_len, &err);
+        g_assert(ret == 0);
+        g_assert(err == NULL);
+
+#if !defined(CONFIG_NETTLE) && !defined(CONFIG_GCRYPT)
+        /*
+         * qcrypto_hmac_bytesv() uses g_checksum_get_digest() to get the
+         * digest. Once this function has been called, the #GChecksum is
+         * closed and can no longer be updated with g_checksum_update().
+         * So...we must free glib-backend hmac object and renew one here.
+         */
+        qcrypto_hmac_free(hmac);
+        hmac = qcrypto_hmac_new(QCRYPTO_HASH_ALG_SHA256, (const uint8_t *)KEY,
+                                strlen(KEY), &err);
+        g_assert(err == NULL);
+        g_assert(hmac != NULL);
+#endif
+        total += chunk_size;
+    } while (g_test_timer_elapsed() < 5.0);
+
+    total /= 1024 * 1024; /* to MB */
+
+    g_print("hmac(sha256): ");
+    g_print("Testing chunk_size %ld bytes ", chunk_size);
+    g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
+    g_print("%.2f MB/sec\n", total / g_test_timer_last());
+
+    qcrypto_hmac_free(hmac);
+    g_free(out);
+    g_free(in);
+}
+
+int main(int argc, char **argv)
+{
+    size_t i;
+    char name[64];
+
+    g_test_init(&argc, &argv, NULL);
+    g_assert(qcrypto_init(NULL) == 0);
+
+    for (i = 512; i <= (64 * 1204); i *= 2) {
+        memset(name, 0 , sizeof(name));
+        snprintf(name, sizeof(name), "/crypto/hmac/speed-%lu", i);
+        g_test_add_data_func(name, (void *)i, test_hmac_speed);
+    }
+
+    return g_test_run();
+}
-- 
1.8.3.1

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

* Re: [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support
  2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
                   ` (17 preceding siblings ...)
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 18/18] tests: crypto: add hmac " Longpeng(Mike)
@ 2017-07-06 14:06 ` Daniel P. Berrange
  18 siblings, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-06 14:06 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel, longpeng.mike

On Tue, Jul 04, 2017 at 04:56:52PM +0800, Longpeng(Mike) wrote:
> The AF_ALG socket family is the userspace interface for linux
> crypto API, users can use it to access hardware accelerators.
> 
> This patchset adds a afalg-backend for qemu crypto subsystem. Currently
> when performs encrypt/decrypt, we'll try afalg-backend first and will
> back to libiary-backend if it failed.
> 
> In the next step, It would support a command parameter to specifies
> which backends prefer to and some other improvements.
> 
> I measured the performance about the afalg-backend impls, I tested
> how many data could be encrypted in 5 seconds.
> 
> NOTE: If we use specific hardware crypto cards, I think afalg-backend
>       would even faster.
> 
> test-environment: Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
> 
> *sha256*
> chunk_size(bytes)   MB/sec(afalg:sha256-ssse3)  MB/sec(nettle)
> 512                 93.03                       185.87
> 1024                146.32                      201.78
> 2048                213.32                      210.93
> 4096                275.48                      215.26
> 8192                321.77                      217.49
> 16384               349.60                      219.26
> 32768               363.59                      219.73
> 65536               375.79                      219.99
> 
> *hmac(sha256)*
> chunk_size(bytes)   MB/sec(afalg:sha256-ssse3)  MB/sec(nettle)
> 512                 71.26                       165.55
> 1024                117.43                      189.15
> 2048                180.96                      203.24
> 4096                247.60                      211.38
> 8192                301.99                      215.65
> 16384               340.79                      218.22
> 32768               365.51                      219.49
> 65536               377.92                      220.24
> 
> *cbc(aes128)*
> chunk_size(bytes)   MB/sec(afalg:cbc-aes-aesni)  MB/sec(nettle)
> 512                 371.76                       188.41
> 1024                559.86                       189.64
> 2048                768.66                       192.11
> 4096                939.15                       192.40
> 8192                1029.48                      192.49
> 16384               1072.79                      190.52
> 32768               1109.38                      190.41
> 65536               1102.38                      190.40

Thanks for the updated series. I've not had time to look at it yet, but
its on my todo list. I'd like to aim to get this mergable in time for
the 2.10 soft freeze on July 18th.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support Longpeng(Mike)
@ 2017-07-11 12:20   ` Daniel P. Berrange
  2017-07-11 12:23     ` Daniel P. Berrange
  2017-07-11 12:29   ` Daniel P. Berrange
  1 sibling, 1 reply; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-11 12:20 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel, longpeng.mike

On Tue, Jul 04, 2017 at 04:57:05PM +0800, Longpeng(Mike) wrote:
> Adds afalg-backend cipher support: introduces some private APIs
> firstly, and then intergrates them into qcrypto_cipher_afalg_driver.
> 
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
>  crypto/Makefile.objs  |   1 +
>  crypto/afalgpriv.h    |   9 ++
>  crypto/cipher-afalg.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  crypto/cipher.c       |  23 +++++-
>  crypto/cipherpriv.h   |  16 ++++
>  5 files changed, 268 insertions(+), 4 deletions(-)
>  create mode 100644 crypto/cipher-afalg.c
> 
> diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
> index 2be5a3a..d2e8fa8 100644
> --- a/crypto/Makefile.objs
> +++ b/crypto/Makefile.objs
> @@ -11,6 +11,7 @@ crypto-obj-y += aes.o
>  crypto-obj-y += desrfb.o
>  crypto-obj-y += cipher.o
>  crypto-obj-$(CONFIG_AF_ALG) += afalg.o
> +crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
>  crypto-obj-y += tlscreds.o
>  crypto-obj-y += tlscredsanon.o
>  crypto-obj-y += tlscredsx509.o
> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
> index d21160c..a4a7b97 100644
> --- a/crypto/afalgpriv.h
> +++ b/crypto/afalgpriv.h
> @@ -19,6 +19,15 @@
>  #define SALG_TYPE_LEN_MAX 14
>  #define SALG_NAME_LEN_MAX 64
>  
> +#ifndef SOL_ALG
> +#define SOL_ALG 279
> +#endif
> +
> +#define AFALG_TYPE_CIPHER "skcipher"
> +
> +#define ALG_OPTYPE_LEN 4
> +#define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len))
> +
>  typedef struct QCryptoAFAlg QCryptoAFAlg;
>  
>  struct QCryptoAFAlg {
> diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
> new file mode 100644
> index 0000000..c5d1d5d
> --- /dev/null
> +++ b/crypto/cipher-afalg.c
> @@ -0,0 +1,223 @@
> +/*
> + * QEMU Crypto af_alg-backend cipher support
> + *
> + * Copyright (c) 2017 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 "qemu/sockets.h"
> +#include "qemu-common.h"
> +#include "qapi/error.h"
> +#include "crypto/cipher.h"
> +#include "cipherpriv.h"
> +
> +
> +static char *
> +qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg,
> +                                 QCryptoCipherMode mode,
> +                                 Error **errp)
> +{
> +    char *name;
> +    const char *alg_name;
> +    const char *mode_name;
> +
> +    switch (alg) {
> +    case QCRYPTO_CIPHER_ALG_AES_128:
> +    case QCRYPTO_CIPHER_ALG_AES_192:
> +    case QCRYPTO_CIPHER_ALG_AES_256:
> +        alg_name = "aes";
> +        break;
> +    case QCRYPTO_CIPHER_ALG_CAST5_128:
> +        alg_name = "cast5";
> +        break;
> +    case QCRYPTO_CIPHER_ALG_SERPENT_128:
> +    case QCRYPTO_CIPHER_ALG_SERPENT_192:
> +    case QCRYPTO_CIPHER_ALG_SERPENT_256:
> +        alg_name = "serpent";
> +        break;
> +    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> +    case QCRYPTO_CIPHER_ALG_TWOFISH_192:
> +    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> +        alg_name = "twofish";
> +        break;
> +
> +    default:
> +        error_setg(errp, "Unsupported cipher algorithm %d", alg);
> +        return NULL;
> +    }
> +
> +    mode_name = QCryptoCipherMode_lookup[mode];
> +    name = g_strdup_printf("%s(%s)", mode_name, alg_name);
> +
> +    return name;
> +}
> +
> +QCryptoAFAlg *
> +qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> +                             QCryptoCipherMode mode,
> +                             const uint8_t *key,
> +                             size_t nkey, Error **errp)
> +{
> +    QCryptoAFAlg *afalg;
> +    size_t expect_niv;
> +    char *name;
> +
> +    name = qcrypto_afalg_cipher_format_name(alg, mode, errp);
> +    if (!name) {
> +        return NULL;
> +    }
> +
> +    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_CIPHER, name, errp);
> +    if (!afalg) {
> +        g_free(name);
> +        return NULL;
> +    }
> +    afalg->name = name;

How about moving the qcrypto_afalg_cipher_format_name() method into the
afalg.c file. THen instead of passing 'name' into qcrypto_afalg_comm_alloc,
you can just pass 'alg' & 'mode'.  Then qcrypto_afalg_comm_alloc can be
responsible for setting afalg->name too.

> +
> +    /* setkey */
> +    if (qemu_setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY, key,
> +                        nkey) != 0) {
> +        error_setg_errno(errp, errno, "Set key failed");
> +        qcrypto_afalg_comm_free(afalg);
> +        return NULL;
> +    }
> +
> +    /* prepare msg header */
> +    afalg->msg = g_new0(struct msghdr, 1);
> +    afalg->msg->msg_controllen += CMSG_SPACE(ALG_OPTYPE_LEN);
> +    expect_niv = qcrypto_cipher_get_iv_len(alg, mode);
> +    if (expect_niv) {
> +        afalg->msg->msg_controllen += CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
> +    }
> +    afalg->msg->msg_control = g_new0(uint8_t, afalg->msg->msg_controllen);
> +static int
> +qcrypto_afalg_cipher_op(QCryptoAFAlg *afalg,
> +                        const void *in, void *out,
> +                        size_t len, bool do_encrypt,
> +                        Error **errp)
> +{
> +    uint32_t *type = NULL;
> +    struct iovec iov;
> +    size_t ret, done = 0;
> +    uint32_t origin_controllen;
> +
> +    origin_controllen = afalg->msg->msg_controllen;
> +    /* movev ->cmsg to first header, for crypto-info */
> +    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
> +
> +    /* build encrypt msg */
> +    afalg->cmsg->cmsg_level = SOL_ALG;
> +    afalg->msg->msg_iov = &iov;
> +    afalg->msg->msg_iovlen = 1;
> +    type = (uint32_t *)CMSG_DATA(afalg->cmsg);
> +    if (do_encrypt) {
> +        *type = ALG_OP_ENCRYPT;
> +    } else {
> +        *type = ALG_OP_DECRYPT;
> +    }
> +
> +    do {
> +        iov.iov_base = (void *)in + done;
> +        iov.iov_len = len - done;
> +
> +        /* send info to AF_ALG core */
> +        ret = sendmsg(afalg->opfd, afalg->msg, 0);
> +        if (ret == -1) {
> +            error_setg_errno(errp, errno, "Send data to AF_ALG core failed");
> +            return -1;
> +        }
> +
> +        /* encrypto && get result */
> +        if (ret != read(afalg->opfd, out, ret)) {
> +            error_setg_errno(errp, errno, "Get result from AF_ALG core failed");

There are two error scenarios here. If 'ret' is set to -1 then
errnor is valid, but if 'ret' is set to a non-zero value that
is smaller than the input size, errno is not valid. So you need
to have distinct error reporting for the error scenario, vs the
short read scenario.  Unless something guarantees we won't ever
get a short read, in which case do a check for 'ret == -1' before
reporting an error, and then assert() that we don't have a short
read.

> +            return -1;
> +        }
> +
> +        /* do not update IV for following chunks */
> +        afalg->msg->msg_controllen = 0;
> +        done += ret;
> +    } while (done < len);
> +
> +    afalg->msg->msg_controllen = origin_controllen;
> +
> +    return 0;
> +}


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support
  2017-07-11 12:20   ` Daniel P. Berrange
@ 2017-07-11 12:23     ` Daniel P. Berrange
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-11 12:23 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: wangxinxin.wang, arei.gonglei, weidong.huang, qemu-devel, longpeng.mike

On Tue, Jul 11, 2017 at 01:20:35PM +0100, Daniel P. Berrange wrote:
> On Tue, Jul 04, 2017 at 04:57:05PM +0800, Longpeng(Mike) wrote:
> > Adds afalg-backend cipher support: introduces some private APIs
> > firstly, and then intergrates them into qcrypto_cipher_afalg_driver.
> > 
> > Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> > ---
> >  crypto/Makefile.objs  |   1 +
> >  crypto/afalgpriv.h    |   9 ++
> >  crypto/cipher-afalg.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  crypto/cipher.c       |  23 +++++-
> >  crypto/cipherpriv.h   |  16 ++++
> >  5 files changed, 268 insertions(+), 4 deletions(-)
> >  create mode 100644 crypto/cipher-afalg.c
> > 
> > diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
> > index 2be5a3a..d2e8fa8 100644
> > --- a/crypto/Makefile.objs
> > +++ b/crypto/Makefile.objs
> > @@ -11,6 +11,7 @@ crypto-obj-y += aes.o
> >  crypto-obj-y += desrfb.o
> >  crypto-obj-y += cipher.o
> >  crypto-obj-$(CONFIG_AF_ALG) += afalg.o
> > +crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
> >  crypto-obj-y += tlscreds.o
> >  crypto-obj-y += tlscredsanon.o
> >  crypto-obj-y += tlscredsx509.o
> > diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
> > index d21160c..a4a7b97 100644
> > --- a/crypto/afalgpriv.h
> > +++ b/crypto/afalgpriv.h
> > @@ -19,6 +19,15 @@
> >  #define SALG_TYPE_LEN_MAX 14
> >  #define SALG_NAME_LEN_MAX 64
> >  
> > +#ifndef SOL_ALG
> > +#define SOL_ALG 279
> > +#endif
> > +
> > +#define AFALG_TYPE_CIPHER "skcipher"
> > +
> > +#define ALG_OPTYPE_LEN 4
> > +#define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len))
> > +
> >  typedef struct QCryptoAFAlg QCryptoAFAlg;
> >  
> >  struct QCryptoAFAlg {
> > diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
> > new file mode 100644
> > index 0000000..c5d1d5d
> > --- /dev/null
> > +++ b/crypto/cipher-afalg.c
> > @@ -0,0 +1,223 @@
> > +/*
> > + * QEMU Crypto af_alg-backend cipher support
> > + *
> > + * Copyright (c) 2017 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 "qemu/sockets.h"
> > +#include "qemu-common.h"
> > +#include "qapi/error.h"
> > +#include "crypto/cipher.h"
> > +#include "cipherpriv.h"
> > +
> > +
> > +static char *
> > +qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg,
> > +                                 QCryptoCipherMode mode,
> > +                                 Error **errp)
> > +{
> > +    char *name;
> > +    const char *alg_name;
> > +    const char *mode_name;
> > +
> > +    switch (alg) {
> > +    case QCRYPTO_CIPHER_ALG_AES_128:
> > +    case QCRYPTO_CIPHER_ALG_AES_192:
> > +    case QCRYPTO_CIPHER_ALG_AES_256:
> > +        alg_name = "aes";
> > +        break;
> > +    case QCRYPTO_CIPHER_ALG_CAST5_128:
> > +        alg_name = "cast5";
> > +        break;
> > +    case QCRYPTO_CIPHER_ALG_SERPENT_128:
> > +    case QCRYPTO_CIPHER_ALG_SERPENT_192:
> > +    case QCRYPTO_CIPHER_ALG_SERPENT_256:
> > +        alg_name = "serpent";
> > +        break;
> > +    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> > +    case QCRYPTO_CIPHER_ALG_TWOFISH_192:
> > +    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> > +        alg_name = "twofish";
> > +        break;
> > +
> > +    default:
> > +        error_setg(errp, "Unsupported cipher algorithm %d", alg);
> > +        return NULL;
> > +    }
> > +
> > +    mode_name = QCryptoCipherMode_lookup[mode];
> > +    name = g_strdup_printf("%s(%s)", mode_name, alg_name);
> > +
> > +    return name;
> > +}
> > +
> > +QCryptoAFAlg *
> > +qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> > +                             QCryptoCipherMode mode,
> > +                             const uint8_t *key,
> > +                             size_t nkey, Error **errp)
> > +{
> > +    QCryptoAFAlg *afalg;
> > +    size_t expect_niv;
> > +    char *name;
> > +
> > +    name = qcrypto_afalg_cipher_format_name(alg, mode, errp);
> > +    if (!name) {
> > +        return NULL;
> > +    }
> > +
> > +    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_CIPHER, name, errp);
> > +    if (!afalg) {
> > +        g_free(name);
> > +        return NULL;
> > +    }
> > +    afalg->name = name;
> 
> How about moving the qcrypto_afalg_cipher_format_name() method into the
> afalg.c file. THen instead of passing 'name' into qcrypto_afalg_comm_alloc,
> you can just pass 'alg' & 'mode'.  Then qcrypto_afalg_comm_alloc can be
> responsible for setting afalg->name too.

Oh actually ignore this. I've just remembered that qcrypto_afalg_comm_alloc
method is used for multiple places, so we can't pass in alg & mode directly.

We can however make qcrypto_afalg_comm_alloc initializet he 'afalg->name'
field.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend Longpeng(Mike)
@ 2017-07-11 12:28   ` Daniel P. Berrange
  2017-07-13  3:30     ` long mike
  0 siblings, 1 reply; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-11 12:28 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel, longpeng.mike

On Tue, Jul 04, 2017 at 04:57:04PM +0800, Longpeng(Mike) wrote:
> The AF_ALG socket family is the userspace interface for linux
> crypto API, this patch adds af_alg family support and some common
> functions for af_alg backend. It'll be used by afalg-backend crypto
> latter.
> 
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
>  configure            |  22 ++++++++++
>  crypto/Makefile.objs |   1 +
>  crypto/afalg.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  crypto/afalgpriv.h   |  55 ++++++++++++++++++++++++
>  4 files changed, 196 insertions(+)
>  create mode 100644 crypto/afalg.c
>  create mode 100644 crypto/afalgpriv.h
> 
> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
> new file mode 100644
> index 0000000..d21160c
> --- /dev/null
> +++ b/crypto/afalgpriv.h
> @@ -0,0 +1,55 @@

> +
> +struct QCryptoAFAlg {
> +    int tfmfd;
> +    int opfd;
> +    char *name;

What actually uses this 'name' field ?  I'm not seing anything in the
patch series that ever reads it, once set. So can we just delete it
perhaps ?

> +    struct msghdr *msg;
> +    struct cmsghdr *cmsg;
> +};

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support Longpeng(Mike)
  2017-07-11 12:20   ` Daniel P. Berrange
@ 2017-07-11 12:29   ` Daniel P. Berrange
  2017-07-13  9:55     ` long mike
  1 sibling, 1 reply; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-11 12:29 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel, longpeng.mike

On Tue, Jul 04, 2017 at 04:57:05PM +0800, Longpeng(Mike) wrote:
> Adds afalg-backend cipher support: introduces some private APIs
> firstly, and then intergrates them into qcrypto_cipher_afalg_driver.
> 
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
>  crypto/Makefile.objs  |   1 +
>  crypto/afalgpriv.h    |   9 ++
>  crypto/cipher-afalg.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  crypto/cipher.c       |  23 +++++-
>  crypto/cipherpriv.h   |  16 ++++
>  5 files changed, 268 insertions(+), 4 deletions(-)
>  create mode 100644 crypto/cipher-afalg.c
> 
> diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
> index 2be5a3a..d2e8fa8 100644
> --- a/crypto/Makefile.objs
> +++ b/crypto/Makefile.objs
> @@ -11,6 +11,7 @@ crypto-obj-y += aes.o
>  crypto-obj-y += desrfb.o
>  crypto-obj-y += cipher.o
>  crypto-obj-$(CONFIG_AF_ALG) += afalg.o
> +crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
>  crypto-obj-y += tlscreds.o
>  crypto-obj-y += tlscredsanon.o
>  crypto-obj-y += tlscredsx509.o
> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
> index d21160c..a4a7b97 100644
> --- a/crypto/afalgpriv.h
> +++ b/crypto/afalgpriv.h
> @@ -19,6 +19,15 @@
>  #define SALG_TYPE_LEN_MAX 14
>  #define SALG_NAME_LEN_MAX 64
>  
> +#ifndef SOL_ALG
> +#define SOL_ALG 279
> +#endif
> +
> +#define AFALG_TYPE_CIPHER "skcipher"
> +
> +#define ALG_OPTYPE_LEN 4
> +#define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len))
> +
>  typedef struct QCryptoAFAlg QCryptoAFAlg;
>  
>  struct QCryptoAFAlg {
> diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c
> new file mode 100644
> index 0000000..c5d1d5d
> --- /dev/null
> +++ b/crypto/cipher-afalg.c
> @@ -0,0 +1,223 @@
> +/*
> + * QEMU Crypto af_alg-backend cipher support
> + *
> + * Copyright (c) 2017 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 "qemu/sockets.h"
> +#include "qemu-common.h"
> +#include "qapi/error.h"
> +#include "crypto/cipher.h"
> +#include "cipherpriv.h"
> +
> +
> +static char *
> +qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg,
> +                                 QCryptoCipherMode mode,
> +                                 Error **errp)
> +{
> +    char *name;
> +    const char *alg_name;
> +    const char *mode_name;
> +
> +    switch (alg) {
> +    case QCRYPTO_CIPHER_ALG_AES_128:
> +    case QCRYPTO_CIPHER_ALG_AES_192:
> +    case QCRYPTO_CIPHER_ALG_AES_256:
> +        alg_name = "aes";
> +        break;
> +    case QCRYPTO_CIPHER_ALG_CAST5_128:
> +        alg_name = "cast5";
> +        break;
> +    case QCRYPTO_CIPHER_ALG_SERPENT_128:
> +    case QCRYPTO_CIPHER_ALG_SERPENT_192:
> +    case QCRYPTO_CIPHER_ALG_SERPENT_256:
> +        alg_name = "serpent";
> +        break;
> +    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> +    case QCRYPTO_CIPHER_ALG_TWOFISH_192:
> +    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> +        alg_name = "twofish";
> +        break;
> +
> +    default:
> +        error_setg(errp, "Unsupported cipher algorithm %d", alg);
> +        return NULL;
> +    }
> +
> +    mode_name = QCryptoCipherMode_lookup[mode];
> +    name = g_strdup_printf("%s(%s)", mode_name, alg_name);
> +
> +    return name;
> +}
> +
> +QCryptoAFAlg *
> +qcrypto_afalg_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> +                             QCryptoCipherMode mode,
> +                             const uint8_t *key,
> +                             size_t nkey, Error **errp)
> +{
> +    QCryptoAFAlg *afalg;
> +    size_t expect_niv;
> +    char *name;
> +
> +    name = qcrypto_afalg_cipher_format_name(alg, mode, errp);
> +    if (!name) {
> +        return NULL;
> +    }
> +
> +    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_CIPHER, name, errp);
> +    if (!afalg) {
> +        g_free(name);
> +        return NULL;
> +    }
> +    afalg->name = name;
> +
> +    /* setkey */
> +    if (qemu_setsockopt(afalg->tfmfd, SOL_ALG, ALG_SET_KEY, key,
> +                        nkey) != 0) {
> +        error_setg_errno(errp, errno, "Set key failed");
> +        qcrypto_afalg_comm_free(afalg);
> +        return NULL;
> +    }
> +
> +    /* prepare msg header */
> +    afalg->msg = g_new0(struct msghdr, 1);
> +    afalg->msg->msg_controllen += CMSG_SPACE(ALG_OPTYPE_LEN);
> +    expect_niv = qcrypto_cipher_get_iv_len(alg, mode);
> +    if (expect_niv) {
> +        afalg->msg->msg_controllen += CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
> +    }
> +    afalg->msg->msg_control = g_new0(uint8_t, afalg->msg->msg_controllen);
> +
> +    /* We use 1st msghdr for crypto-info and 2nd msghdr for IV-info */
> +    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
> +    afalg->cmsg->cmsg_type = ALG_SET_OP;
> +    afalg->cmsg->cmsg_len = CMSG_SPACE(ALG_OPTYPE_LEN);
> +    if (expect_niv) {
> +        afalg->cmsg = CMSG_NXTHDR(afalg->msg, afalg->cmsg);
> +        afalg->cmsg->cmsg_type = ALG_SET_IV;
> +        afalg->cmsg->cmsg_len = CMSG_SPACE(ALG_MSGIV_LEN(expect_niv));
> +    }
> +    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
> +
> +    return afalg;
> +}
> +
> +static int
> +qcrypto_afalg_cipher_setiv(QCryptoCipher *cipher,
> +                           const uint8_t *iv,
> +                           size_t niv, Error **errp)
> +{
> +    struct af_alg_iv *alg_iv;
> +    size_t expect_niv;
> +    QCryptoAFAlg *afalg = cipher->opaque;
> +
> +    expect_niv = qcrypto_cipher_get_iv_len(cipher->alg, cipher->mode);
> +    if (niv != expect_niv) {
> +        error_setg(errp, "Set IV len(%zu) not match expected(%zu)",
> +                   niv, expect_niv);
> +        return -1;
> +    }
> +
> +    /* move ->cmsg to next msghdr, for IV-info */
> +    afalg->cmsg = CMSG_NXTHDR(afalg->msg, afalg->cmsg);
> +
> +    /* build setiv msg */
> +    afalg->cmsg->cmsg_level = SOL_ALG;
> +    alg_iv = (struct af_alg_iv *)CMSG_DATA(afalg->cmsg);
> +    alg_iv->ivlen = niv;
> +    memcpy(alg_iv->iv, iv, niv);
> +
> +    return 0;
> +}
> +
> +static int
> +qcrypto_afalg_cipher_op(QCryptoAFAlg *afalg,
> +                        const void *in, void *out,
> +                        size_t len, bool do_encrypt,
> +                        Error **errp)
> +{
> +    uint32_t *type = NULL;
> +    struct iovec iov;
> +    size_t ret, done = 0;
> +    uint32_t origin_controllen;
> +
> +    origin_controllen = afalg->msg->msg_controllen;
> +    /* movev ->cmsg to first header, for crypto-info */
> +    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
> +
> +    /* build encrypt msg */
> +    afalg->cmsg->cmsg_level = SOL_ALG;
> +    afalg->msg->msg_iov = &iov;
> +    afalg->msg->msg_iovlen = 1;
> +    type = (uint32_t *)CMSG_DATA(afalg->cmsg);
> +    if (do_encrypt) {
> +        *type = ALG_OP_ENCRYPT;
> +    } else {
> +        *type = ALG_OP_DECRYPT;
> +    }
> +
> +    do {
> +        iov.iov_base = (void *)in + done;
> +        iov.iov_len = len - done;
> +
> +        /* send info to AF_ALG core */
> +        ret = sendmsg(afalg->opfd, afalg->msg, 0);
> +        if (ret == -1) {
> +            error_setg_errno(errp, errno, "Send data to AF_ALG core failed");
> +            return -1;
> +        }
> +
> +        /* encrypto && get result */
> +        if (ret != read(afalg->opfd, out, ret)) {
> +            error_setg_errno(errp, errno, "Get result from AF_ALG core failed");
> +            return -1;
> +        }
> +
> +        /* do not update IV for following chunks */
> +        afalg->msg->msg_controllen = 0;
> +        done += ret;
> +    } while (done < len);

In the next patch you use iov_send_recv() which provides the
while()  loop automatically upon short write. Lets just use
that method here too.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 14/18] crypto: hash: add afalg-backend hash support
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 14/18] crypto: hash: add afalg-backend hash support Longpeng(Mike)
@ 2017-07-11 12:32   ` Daniel P. Berrange
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-11 12:32 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel, longpeng.mike

On Tue, Jul 04, 2017 at 04:57:06PM +0800, Longpeng(Mike) wrote:
> Adds afalg-backend hash support: introduces some private APIs
> firstly, and then intergrates them into qcrypto_hash_afalg_driver.
> 
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
>  crypto/Makefile.objs |   1 +
>  crypto/afalgpriv.h   |   1 +
>  crypto/hash-afalg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  crypto/hash.c        |  17 +++++++
>  crypto/hashpriv.h    |   8 +++
>  5 files changed, 166 insertions(+)
>  create mode 100644 crypto/hash-afalg.c
> 
> diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
> index d2e8fa8..2b99e08 100644
> --- a/crypto/Makefile.objs
> +++ b/crypto/Makefile.objs
> @@ -12,6 +12,7 @@ crypto-obj-y += desrfb.o
>  crypto-obj-y += cipher.o
>  crypto-obj-$(CONFIG_AF_ALG) += afalg.o
>  crypto-obj-$(CONFIG_AF_ALG) += cipher-afalg.o
> +crypto-obj-$(CONFIG_AF_ALG) += hash-afalg.o
>  crypto-obj-y += tlscreds.o
>  crypto-obj-y += tlscredsanon.o
>  crypto-obj-y += tlscredsx509.o
> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
> index a4a7b97..9d42ba9 100644
> --- a/crypto/afalgpriv.h
> +++ b/crypto/afalgpriv.h
> @@ -24,6 +24,7 @@
>  #endif
>  
>  #define AFALG_TYPE_CIPHER "skcipher"
> +#define AFALG_TYPE_HASH "hash"
>  
>  #define ALG_OPTYPE_LEN 4
>  #define ALG_MSGIV_LEN(len) (sizeof(struct af_alg_iv) + (len))
> diff --git a/crypto/hash-afalg.c b/crypto/hash-afalg.c
> new file mode 100644
> index 0000000..a19847e
> --- /dev/null
> +++ b/crypto/hash-afalg.c
> @@ -0,0 +1,139 @@
> +/*
> + * QEMU Crypto af_alg-backend hash support
> + *
> + * Copyright (c) 2017 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 "qemu/iov.h"
> +#include "qemu/sockets.h"
> +#include "qemu-common.h"
> +#include "qapi/error.h"
> +#include "crypto/hash.h"
> +#include "hashpriv.h"
> +
> +static char *
> +qcrypto_afalg_hash_format_name(QCryptoHashAlgorithm alg,
> +                               Error **errp)
> +{
> +    char *name;
> +    const char *alg_name;
> +
> +    switch (alg) {
> +    case QCRYPTO_HASH_ALG_MD5:
> +        alg_name = "md5";
> +        break;
> +    case QCRYPTO_HASH_ALG_SHA1:
> +        alg_name = "sha1";
> +        break;
> +    case QCRYPTO_HASH_ALG_SHA224:
> +        alg_name = "sha224";
> +        break;
> +    case QCRYPTO_HASH_ALG_SHA256:
> +        alg_name = "sha256";
> +        break;
> +    case QCRYPTO_HASH_ALG_SHA384:
> +        alg_name = "sha384";
> +        break;
> +    case QCRYPTO_HASH_ALG_SHA512:
> +        alg_name = "sha512";
> +        break;
> +    case QCRYPTO_HASH_ALG_RIPEMD160:
> +        alg_name = "rmd160";
> +        break;
> +
> +    default:
> +        error_setg(errp, "Unsupported hash algorithm %d", alg);
> +        return NULL;
> +    }
> +
> +    name = g_strdup_printf("%s", alg_name);
> +
> +    return name;
> +}
> +
> +static QCryptoAFAlg *
> +qcrypto_afalg_hash_ctx_new(QCryptoHashAlgorithm alg, Error **errp)
> +{
> +    QCryptoAFAlg *afalg;
> +    char *name;
> +
> +    name = qcrypto_afalg_hash_format_name(alg, errp);
> +    if (!name) {
> +        return NULL;
> +    }
> +
> +    afalg = qcrypto_afalg_comm_alloc(AFALG_TYPE_HASH, name, errp);
> +    if (!afalg) {
> +        g_free(name);
> +        return NULL;
> +    }
> +    afalg->name = name;
> +
> +    /* prepare msg header */
> +    afalg->msg = g_new0(struct msghdr, 1);
> +
> +    return afalg;
> +}
> +
> +static int
> +qcrypto_afalg_hash_bytesv(QCryptoHashAlgorithm alg,
> +                          const struct iovec *iov,
> +                          size_t niov, uint8_t **result,
> +                          size_t *resultlen,
> +                          Error **errp)
> +{
> +    QCryptoAFAlg *afalg;
> +    struct iovec outv;
> +    int ret = 0;
> +    const int expect_len = qcrypto_hash_digest_len(alg);
> +
> +    if (*resultlen == 0) {
> +        *resultlen = expect_len;
> +        *result = g_new0(uint8_t, *resultlen);
> +    } else if (*resultlen != expect_len) {
> +        error_setg(errp,
> +                   "Result buffer size %zu is not match hash %d",
> +                   *resultlen, expect_len);
> +        return -1;
> +    }
> +
> +    afalg = qcrypto_afalg_hash_ctx_new(alg, errp);
> +    if (!afalg) {
> +        return -1;
> +    }
> +
> +    /* send data to kernel's crypto core */
> +    ret = iov_send_recv(afalg->opfd, iov, niov,
> +                        0, iov_size(iov, niov), true);
> +    if (ret < 0) {
> +        error_setg_errno(errp, errno, "Send data to afalg-core failed");
> +        goto out;
> +    }
> +
> +    /* hash && get result */
> +    outv.iov_base = *result;
> +    outv.iov_len = *resultlen;
> +    afalg->msg->msg_iov = &outv;
> +    afalg->msg->msg_iovlen = 1;
> +    ret = recvmsg(afalg->opfd, afalg->msg, 0);
> +    if (ret != -1) {
> +        ret = 0;

Are we guaranteed that short read can't happen ?  If so, then assert
that ret == expect_len, otherwise use iov_send_recv to loop to catch
all output data

> +    } else {
> +        error_setg_errno(errp, errno, "Recv result from afalg-core failed");
> +    }



> +
> +out:
> +    qcrypto_afalg_comm_free(afalg);
> +    return ret;
> +}
> +
> +QCryptoHashDriver qcrypto_hash_afalg_driver = {
> +    .hash_bytesv = qcrypto_afalg_hash_bytesv,
> +};

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 18/18] tests: crypto: add hmac speed benchmark support
  2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 18/18] tests: crypto: add hmac " Longpeng(Mike)
@ 2017-07-11 12:34   ` Daniel P. Berrange
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-11 12:34 UTC (permalink / raw)
  To: Longpeng(Mike)
  Cc: arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel, longpeng.mike

On Tue, Jul 04, 2017 at 04:57:10PM +0800, Longpeng(Mike) wrote:
> This patch add a hmac speed benchmark, it helps us to
> measure the performance by using "make check-speed" or
> using "./tests/benchmark-crypto-hmac" directly.
> 
> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> ---
>  tests/Makefile.include        |  2 +
>  tests/benchmark-crypto-hmac.c | 94 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 96 insertions(+)
>  create mode 100644 tests/benchmark-crypto-hmac.c
> 
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index e83eb6b..258bcbc 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -99,6 +99,7 @@ gcov-files-test-write-threshold-y = block/write-threshold.c
>  check-unit-y += tests/test-crypto-hash$(EXESUF)
>  check-speed-y += tests/benchmark-crypto-hash$(EXESUF)
>  check-unit-y += tests/test-crypto-hmac$(EXESUF)
> +check-speed-y += tests/benchmark-crypto-hmac$(EXESUF)
>  check-unit-y += tests/test-crypto-cipher$(EXESUF)
>  check-speed-y += tests/benchmark-crypto-cipher$(EXESUF)
>  check-unit-y += tests/test-crypto-secret$(EXESUF)
> @@ -637,6 +638,7 @@ tests/test-bitcnt$(EXESUF): tests/test-bitcnt.o $(test-util-obj-y)
>  tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
>  tests/benchmark-crypto-hash$(EXESUF): tests/benchmark-crypto-hash.o $(test-crypto-obj-y)
>  tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
> +tests/benchmark-crypto-hmac$(EXESUF): tests/benchmark-crypto-hmac.o $(test-crypto-obj-y)
>  tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
>  tests/benchmark-crypto-cipher$(EXESUF): tests/benchmark-crypto-cipher.o $(test-crypto-obj-y)
>  tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
> diff --git a/tests/benchmark-crypto-hmac.c b/tests/benchmark-crypto-hmac.c
> new file mode 100644
> index 0000000..05b02a5
> --- /dev/null
> +++ b/tests/benchmark-crypto-hmac.c
> @@ -0,0 +1,94 @@
> +/*
> + * QEMU Crypto hmac speed benchmark
> + *
> + * Copyright (c) 2017 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 KEY "monkey monkey monkey monkey"
> +
> +static void test_hmac_speed(const void *opaque)
> +{
> +    size_t chunk_size = (size_t)opaque;
> +    QCryptoHmac *hmac = NULL;
> +    uint8_t *in = NULL, *out = NULL;
> +    size_t out_len = 0;
> +    double total = 0.0;
> +    struct iovec iov;
> +    Error *err = NULL;
> +    int ret;
> +
> +    if (!qcrypto_hmac_supports(QCRYPTO_HASH_ALG_SHA256)) {
> +        return;
> +    }
> +
> +    hmac = qcrypto_hmac_new(QCRYPTO_HASH_ALG_SHA256, (const uint8_t *)KEY,
> +                            strlen(KEY), &err);
> +    g_assert(err == NULL);
> +    g_assert(hmac != NULL);

Just push these lines down into the start of the while loop

> +
> +    in = g_new0(uint8_t, chunk_size);
> +    memset(in, g_test_rand_int(), chunk_size);
> +
> +    iov.iov_base = (char *)in;
> +    iov.iov_len = chunk_size;
> +
> +    g_test_timer_start();
> +    do {
> +        ret = qcrypto_hmac_bytesv(hmac, &iov, 1, &out, &out_len, &err);
> +        g_assert(ret == 0);
> +        g_assert(err == NULL);
> +
> +#if !defined(CONFIG_NETTLE) && !defined(CONFIG_GCRYPT)
> +        /*
> +         * qcrypto_hmac_bytesv() uses g_checksum_get_digest() to get the
> +         * digest. Once this function has been called, the #GChecksum is
> +         * closed and can no longer be updated with g_checksum_update().
> +         * So...we must free glib-backend hmac object and renew one here.
> +         */
> +        qcrypto_hmac_free(hmac);
> +        hmac = qcrypto_hmac_new(QCRYPTO_HASH_ALG_SHA256, (const uint8_t *)KEY,
> +                                strlen(KEY), &err);
> +        g_assert(err == NULL);
> +        g_assert(hmac != NULL);
> +#endif

And get rid of this - just have an unconditional qcrypto_hmac_free call.

> +        total += chunk_size;
> +    } while (g_test_timer_elapsed() < 5.0);
> +
> +    total /= 1024 * 1024; /* to MB */
> +
> +    g_print("hmac(sha256): ");
> +    g_print("Testing chunk_size %ld bytes ", chunk_size);
> +    g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
> +    g_print("%.2f MB/sec\n", total / g_test_timer_last());
> +
> +    qcrypto_hmac_free(hmac);

So this won't be needed either.

> +    g_free(out);
> +    g_free(in);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    size_t i;
> +    char name[64];
> +
> +    g_test_init(&argc, &argv, NULL);
> +    g_assert(qcrypto_init(NULL) == 0);
> +
> +    for (i = 512; i <= (64 * 1204); i *= 2) {
> +        memset(name, 0 , sizeof(name));
> +        snprintf(name, sizeof(name), "/crypto/hmac/speed-%lu", i);
> +        g_test_add_data_func(name, (void *)i, test_hmac_speed);
> +    }
> +
> +    return g_test_run();
> +}
> -- 
> 1.8.3.1
> 
> 

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

* Re: [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend
  2017-07-11 12:28   ` Daniel P. Berrange
@ 2017-07-13  3:30     ` long mike
  0 siblings, 0 replies; 29+ messages in thread
From: long mike @ 2017-07-13  3:30 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Longpeng(Mike), arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel

2017-07-11 20:28 GMT+08:00 Daniel P. Berrange <berrange@redhat.com>:
> On Tue, Jul 04, 2017 at 04:57:04PM +0800, Longpeng(Mike) wrote:
>> The AF_ALG socket family is the userspace interface for linux
>> crypto API, this patch adds af_alg family support and some common
>> functions for af_alg backend. It'll be used by afalg-backend crypto
>> latter.
>>
>> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
>> ---
>>  configure            |  22 ++++++++++
>>  crypto/Makefile.objs |   1 +
>>  crypto/afalg.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  crypto/afalgpriv.h   |  55 ++++++++++++++++++++++++
>>  4 files changed, 196 insertions(+)
>>  create mode 100644 crypto/afalg.c
>>  create mode 100644 crypto/afalgpriv.h
>>
>> diff --git a/crypto/afalgpriv.h b/crypto/afalgpriv.h
>> new file mode 100644
>> index 0000000..d21160c
>> --- /dev/null
>> +++ b/crypto/afalgpriv.h
>> @@ -0,0 +1,55 @@
>
>> +
>> +struct QCryptoAFAlg {
>> +    int tfmfd;
>> +    int opfd;
>> +    char *name;
>
> What actually uses this 'name' field ?  I'm not seing anything in the
> patch series that ever reads it, once set. So can we just delete it
> perhaps ?
>
Hi Daniel,

I'm on vacation so I can just replay messages through my personal
email account these days.

Yes, the 'name' field isn't used by others, it just for debug, it's
convenient.  But if you don't like it, I'll remove it.

PS: I'll have a close look at your other suggestions and send v5 as
soon as possible. Thanks :)

Reards,
Longpeng

>> +    struct msghdr *msg;
>> +    struct cmsghdr *cmsg;
>> +};
>
> Regards,
> Daniel
> --
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



-- 
Reards,
Longpeng

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

* Re: [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support
  2017-07-11 12:29   ` Daniel P. Berrange
@ 2017-07-13  9:55     ` long mike
  2017-07-13 10:06       ` Daniel P. Berrange
  0 siblings, 1 reply; 29+ messages in thread
From: long mike @ 2017-07-13  9:55 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: Longpeng(Mike), arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel

2017-07-11 20:29 GMT+08:00 Daniel P. Berrange <berrange@redhat.com>:
> On Tue, Jul 04, 2017 at 04:57:05PM +0800, Longpeng(Mike) wrote:
>> Adds afalg-backend cipher support: introduces some private APIs
>> firstly, and then intergrates them into qcrypto_cipher_afalg_driver.
>>
>> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
>> ---
>>  crypto/Makefile.objs  |   1 +
>>  crypto/afalgpriv.h    |   9 ++
>>  crypto/cipher-afalg.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  crypto/cipher.c       |  23 +++++-
>>  crypto/cipherpriv.h   |  16 ++++
>>  5 files changed, 268 insertions(+), 4 deletions(-)
>>  create mode 100644 crypto/cipher-afalg.c
>>
[...]

>> +
>> +static int
>> +qcrypto_afalg_cipher_op(QCryptoAFAlg *afalg,
>> +                        const void *in, void *out,
>> +                        size_t len, bool do_encrypt,
>> +                        Error **errp)
>> +{
>> +    uint32_t *type = NULL;
>> +    struct iovec iov;
>> +    size_t ret, done = 0;
>> +    uint32_t origin_controllen;
>> +
>> +    origin_controllen = afalg->msg->msg_controllen;
>> +    /* movev ->cmsg to first header, for crypto-info */
>> +    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
>> +
>> +    /* build encrypt msg */
>> +    afalg->cmsg->cmsg_level = SOL_ALG;
>> +    afalg->msg->msg_iov = &iov;
>> +    afalg->msg->msg_iovlen = 1;
>> +    type = (uint32_t *)CMSG_DATA(afalg->cmsg);
>> +    if (do_encrypt) {
>> +        *type = ALG_OP_ENCRYPT;
>> +    } else {
>> +        *type = ALG_OP_DECRYPT;
>> +    }
>> +
>> +    do {
>> +        iov.iov_base = (void *)in + done;
>> +        iov.iov_len = len - done;
>> +
>> +        /* send info to AF_ALG core */
>> +        ret = sendmsg(afalg->opfd, afalg->msg, 0);
>> +        if (ret == -1) {
>> +            error_setg_errno(errp, errno, "Send data to AF_ALG core failed");
>> +            return -1;
>> +        }
>> +
>> +        /* encrypto && get result */
>> +        if (ret != read(afalg->opfd, out, ret)) {
>> +            error_setg_errno(errp, errno, "Get result from AF_ALG core failed");
>> +            return -1;
>> +        }
>> +
>> +        /* do not update IV for following chunks */
>> +        afalg->msg->msg_controllen = 0;
>> +        done += ret;
>> +    } while (done < len);
>
> In the next patch you use iov_send_recv() which provides the
> while()  loop automatically upon short write. Lets just use
> that method here too.
>

Hi Daniel,

I'm afraid we couldn't use  iov_send_recv() here.

For the AF_ALG API of cipher, it needs some additional control info
in 'struct msghdr', while iov_send_recv-->do_send_recv would set a
local msghdr object and there's no opportunity for caller to pass any
control info.

For hash/hmac, it doesn't need any control info when send/recv, so
we can use iov_send_recv there.

Currently the 'struct QCryptoAFAlg' is:
struct QCryptoAFAlg {
    int tfmfd;
    int opfd;
    char *name;  [ will be removed in V5 ]
    struct msghdr *msg;
    struct cmsghdr *cmsg;
};

So I think we don't need alloc msg/cmsg when new hash/hmac
context, maybe I should remove g_new0(struct msghdr, 1) in
qcrypto_afalg_hash_ctx_new().

Do you have any suggestion?

Regards,
Longpeng

>
> Regards,
> Daniel
> --
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



-- 
Reards,
Longpeng

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

* Re: [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support
  2017-07-13  9:55     ` long mike
@ 2017-07-13 10:06       ` Daniel P. Berrange
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel P. Berrange @ 2017-07-13 10:06 UTC (permalink / raw)
  To: long mike
  Cc: Longpeng(Mike), arei.gonglei, weidong.huang, wangxinxin.wang, qemu-devel

On Thu, Jul 13, 2017 at 05:55:00PM +0800, long mike wrote:
> 2017-07-11 20:29 GMT+08:00 Daniel P. Berrange <berrange@redhat.com>:
> > On Tue, Jul 04, 2017 at 04:57:05PM +0800, Longpeng(Mike) wrote:
> >> Adds afalg-backend cipher support: introduces some private APIs
> >> firstly, and then intergrates them into qcrypto_cipher_afalg_driver.
> >>
> >> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
> >> ---
> >>  crypto/Makefile.objs  |   1 +
> >>  crypto/afalgpriv.h    |   9 ++
> >>  crypto/cipher-afalg.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  crypto/cipher.c       |  23 +++++-
> >>  crypto/cipherpriv.h   |  16 ++++
> >>  5 files changed, 268 insertions(+), 4 deletions(-)
> >>  create mode 100644 crypto/cipher-afalg.c
> >>
> [...]
> 
> >> +
> >> +static int
> >> +qcrypto_afalg_cipher_op(QCryptoAFAlg *afalg,
> >> +                        const void *in, void *out,
> >> +                        size_t len, bool do_encrypt,
> >> +                        Error **errp)
> >> +{
> >> +    uint32_t *type = NULL;
> >> +    struct iovec iov;
> >> +    size_t ret, done = 0;
> >> +    uint32_t origin_controllen;
> >> +
> >> +    origin_controllen = afalg->msg->msg_controllen;
> >> +    /* movev ->cmsg to first header, for crypto-info */
> >> +    afalg->cmsg = CMSG_FIRSTHDR(afalg->msg);
> >> +
> >> +    /* build encrypt msg */
> >> +    afalg->cmsg->cmsg_level = SOL_ALG;
> >> +    afalg->msg->msg_iov = &iov;
> >> +    afalg->msg->msg_iovlen = 1;
> >> +    type = (uint32_t *)CMSG_DATA(afalg->cmsg);
> >> +    if (do_encrypt) {
> >> +        *type = ALG_OP_ENCRYPT;
> >> +    } else {
> >> +        *type = ALG_OP_DECRYPT;
> >> +    }
> >> +
> >> +    do {
> >> +        iov.iov_base = (void *)in + done;
> >> +        iov.iov_len = len - done;
> >> +
> >> +        /* send info to AF_ALG core */
> >> +        ret = sendmsg(afalg->opfd, afalg->msg, 0);
> >> +        if (ret == -1) {
> >> +            error_setg_errno(errp, errno, "Send data to AF_ALG core failed");
> >> +            return -1;
> >> +        }
> >> +
> >> +        /* encrypto && get result */
> >> +        if (ret != read(afalg->opfd, out, ret)) {
> >> +            error_setg_errno(errp, errno, "Get result from AF_ALG core failed");
> >> +            return -1;
> >> +        }
> >> +
> >> +        /* do not update IV for following chunks */
> >> +        afalg->msg->msg_controllen = 0;
> >> +        done += ret;
> >> +    } while (done < len);
> >
> > In the next patch you use iov_send_recv() which provides the
> > while()  loop automatically upon short write. Lets just use
> > that method here too.
> >
> 
> Hi Daniel,
> 
> I'm afraid we couldn't use  iov_send_recv() here.
> 
> For the AF_ALG API of cipher, it needs some additional control info
> in 'struct msghdr', while iov_send_recv-->do_send_recv would set a
> local msghdr object and there's no opportunity for caller to pass any
> control info.

[snip]

> Do you have any suggestion?

Ah, I missed that subtle point - just ignore my comment and leave your
code as-is. Just consider the error handling for read() possibly returning
less bytes than requested.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

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

end of thread, other threads:[~2017-07-13 10:06 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-04  8:56 [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 01/18] crypto: cipher: introduce context free function Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 02/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for gcrypt-backend Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 03/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for nettle-backend Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 04/18] crypto: cipher: introduce qcrypto_cipher_ctx_new for builtin-backend Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 05/18] crypto: cipher: add cipher driver framework Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 06/18] crypto: hash: add hash " Longpeng(Mike)
2017-07-04  8:56 ` [Qemu-devel] [PATCH v4 07/18] crypto: hmac: move crypto/hmac.h into include/crypto/ Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 08/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for gcrypt-backend Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 09/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for nettle-backend Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 10/18] crypto: hmac: introduce qcrypto_hmac_ctx_new for glib-backend Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 11/18] crypto: hmac: add hmac driver framework Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 12/18] crypto: introduce some common functions for af_alg backend Longpeng(Mike)
2017-07-11 12:28   ` Daniel P. Berrange
2017-07-13  3:30     ` long mike
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 13/18] crypto: cipher: add afalg-backend cipher support Longpeng(Mike)
2017-07-11 12:20   ` Daniel P. Berrange
2017-07-11 12:23     ` Daniel P. Berrange
2017-07-11 12:29   ` Daniel P. Berrange
2017-07-13  9:55     ` long mike
2017-07-13 10:06       ` Daniel P. Berrange
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 14/18] crypto: hash: add afalg-backend hash support Longpeng(Mike)
2017-07-11 12:32   ` Daniel P. Berrange
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 15/18] crypto: hmac: add af_alg hmac support Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 16/18] tests: crypto: add cipher speed benchmark support Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 17/18] tests: crypto: add hash " Longpeng(Mike)
2017-07-04  8:57 ` [Qemu-devel] [PATCH v4 18/18] tests: crypto: add hmac " Longpeng(Mike)
2017-07-11 12:34   ` Daniel P. Berrange
2017-07-06 14:06 ` [Qemu-devel] [PATCH v4 00/18] crypto: add afalg-backend support Daniel P. Berrange

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.