All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module
@ 2015-10-21 10:47 Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 1/4] crypto: allow use of nettle/gcrypt to be selected explicitly Daniel P. Berrange
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Daniel P. Berrange @ 2015-10-21 10:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

The following changes since commit ee9dfed242610ecb91418270fd46b875ed56e201:

  Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20151020-1' into staging (2015-10-20 12:56:45 +0100)

are available in the git repository at:

  https://github.com/berrange/qemu.git tags/qcrypto-fixes-pull-20151021-1

for you to fetch changes up to 635b2807565e0724e4aed73f8ca54f14df051499:

  configure: avoid polluting global CFLAGS with tasn1 flags (2015-10-21 11:42:42 +0100)

----------------------------------------------------------------
Merge qcrypto-fixes 2015/10/21

----------------------------------------------------------------
Daniel P. Berrange (4):
  crypto: allow use of nettle/gcrypt to be selected explicitly
  crypto: don't let builtin aes crash if no IV is provided
  crypto: add sanity checking of plaintext/ciphertext length
  configure: avoid polluting global CFLAGS with tasn1 flags

 configure                  | 94 +++++++++++++++++++++++++++++++++++++---------
 crypto/cipher-builtin.c    | 29 +++++++++-----
 crypto/cipher-gcrypt.c     | 61 ++++++++++++++++++++++--------
 crypto/cipher-nettle.c     | 28 ++++++++++----
 crypto/cipher.c            |  8 ++--
 crypto/init.c              | 26 ++++++-------
 tests/Makefile             | 10 ++++-
 tests/test-crypto-cipher.c | 80 +++++++++++++++++++++++++++++++++++++++
 8 files changed, 266 insertions(+), 70 deletions(-)

-- 
2.4.3

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

* [Qemu-devel] [PULL v1 1/4] crypto: allow use of nettle/gcrypt to be selected explicitly
  2015-10-21 10:47 [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Daniel P. Berrange
@ 2015-10-21 10:47 ` Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 2/4] crypto: don't let builtin aes crash if no IV is provided Daniel P. Berrange
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrange @ 2015-10-21 10:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

Currently the choice of whether to use nettle or gcrypt is
made based on what gnutls is linked to. There are times
when it is desirable to be able to force build against a
specific library. For example, if testing changes to QEMU's
crypto code all 3 possible backends need to be checked
regardless of what the local gnutls uses.

It is also desirable to be able to enable nettle/gcrypt
for cipher/hash algorithms, without enabling gnutls
for TLS support.

This gives two new configure flags, which allow the
following possibilities

Automatically determine nettle vs gcrypt from what
gnutls links to (recommended to minimize number of
crypto libraries linked to)

 ./configure

Automatically determine nettle vs gcrypt based on
which is installed

 ./configure --disable-gnutls

Force use of nettle

 ./configure --enable-nettle

Force use of gcrypt

 ./configure --enable-gcrypt

Force use of built-in AES & crippled-DES

 ./configure --disable-nettle --disable-gcrypt

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 configure       | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 crypto/cipher.c |  8 +++---
 crypto/init.c   | 26 +++++++++---------
 3 files changed, 89 insertions(+), 28 deletions(-)

diff --git a/configure b/configure
index 07eee3d..58f6fc1 100755
--- a/configure
+++ b/configure
@@ -331,6 +331,8 @@ gtkabi=""
 gtk_gl="no"
 gnutls=""
 gnutls_hash=""
+nettle=""
+gcrypt=""
 vte=""
 virglrenderer=""
 tpm="yes"
@@ -1114,6 +1116,14 @@ for opt do
   ;;
   --enable-gnutls) gnutls="yes"
   ;;
+  --disable-nettle) nettle="no"
+  ;;
+  --enable-nettle) nettle="yes"
+  ;;
+  --disable-gcrypt) gcrypt="no"
+  ;;
+  --enable-gcrypt) gcrypt="yes"
+  ;;
   --enable-rdma) rdma="yes"
   ;;
   --disable-rdma) rdma="no"
@@ -1324,6 +1334,8 @@ disabled with --disable-FEATURE, default is enabled if available:
   sparse          sparse checker
 
   gnutls          GNUTLS cryptography support
+  nettle          nettle cryptography support
+  gcrypt          libgcrypt cryptography support
   sdl             SDL UI
   --with-sdlabi     select preferred SDL ABI 1.2 or 2.0
   gtk             gtk UI
@@ -2254,20 +2266,61 @@ else
     gnutls_hash="no"
 fi
 
-if test "$gnutls_gcrypt" != "no"; then
+
+# If user didn't give a --disable/enable-gcrypt flag,
+# then mark as disabled if user requested nettle
+# explicitly, otherwise pick based on gnutls linkage
+if test -z "$gcrypt"
+then
+    if test "$nettle" = "yes"
+    then
+        gcrypt="no"
+    else
+        if test "$gnutls" = "yes"
+        then
+            gcrypt=$gnutls_gcrypt
+        fi
+    fi
+fi
+
+# If user didn't give a --disable/enable-nettle flag,
+# then mark as disabled if user requested gcrypt
+# explicitly, otherwise pick based on gnutls linkage
+if test -z "$nettle"
+then
+    if test "$gcrypt" = "yes"
+    then
+        nettle="no"
+    else
+        if test "$gnutls" = "yes"
+        then
+            nettle=$gnutls_nettle
+        fi
+    fi
+fi
+
+if test "$gcrypt" != "no"; then
     if has "libgcrypt-config"; then
         gcrypt_cflags=`libgcrypt-config --cflags`
         gcrypt_libs=`libgcrypt-config --libs`
         libs_softmmu="$gcrypt_libs $libs_softmmu"
         libs_tools="$gcrypt_libs $libs_tools"
         QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
+        gcrypt="yes"
+        if test -z "$nettle"; then
+           nettle="no"
+        fi
     else
-        feature_not_found "gcrypt" "Install gcrypt devel"
+        if test "$gcrypt" = "yes"; then
+            feature_not_found "gcrypt" "Install gcrypt devel"
+        else
+            gcrypt="no"
+        fi
     fi
 fi
 
 
-if test "$gnutls_nettle" != "no"; then
+if test "$nettle" != "no"; then
     if $pkg_config --exists "nettle"; then
         nettle_cflags=`$pkg_config --cflags nettle`
         nettle_libs=`$pkg_config --libs nettle`
@@ -2275,11 +2328,21 @@ if test "$gnutls_nettle" != "no"; then
         libs_softmmu="$nettle_libs $libs_softmmu"
         libs_tools="$nettle_libs $libs_tools"
         QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
+        nettle="yes"
     else
-        feature_not_found "nettle" "Install nettle devel"
+        if test "$nettle" = "yes"; then
+            feature_not_found "nettle" "Install nettle devel"
+        else
+            nettle="no"
+        fi
     fi
 fi
 
+if test "$gcrypt" = "yes" && test "$nettle" = "yes"
+then
+    error_exit "Only one of gcrypt & nettle can be enabled"
+fi
+
 ##########################################
 # libtasn1 - only for the TLS creds/session test suite
 
@@ -4605,8 +4668,8 @@ echo "GTK support       $gtk"
 echo "GTK GL support    $gtk_gl"
 echo "GNUTLS support    $gnutls"
 echo "GNUTLS hash       $gnutls_hash"
-echo "GNUTLS gcrypt     $gnutls_gcrypt"
-echo "GNUTLS nettle     $gnutls_nettle ${gnutls_nettle+($nettle_version)}"
+echo "libgcrypt         $gcrypt"
+echo "nettle            $nettle ${nettle+($nettle_version)}"
 echo "libtasn1          $tasn1"
 echo "VTE support       $vte"
 echo "curses support    $curses"
@@ -4972,11 +5035,11 @@ fi
 if test "$gnutls_hash" = "yes" ; then
   echo "CONFIG_GNUTLS_HASH=y" >> $config_host_mak
 fi
-if test "$gnutls_gcrypt" = "yes" ; then
-  echo "CONFIG_GNUTLS_GCRYPT=y" >> $config_host_mak
+if test "$gcrypt" = "yes" ; then
+  echo "CONFIG_GCRYPT=y" >> $config_host_mak
 fi
-if test "$gnutls_nettle" = "yes" ; then
-  echo "CONFIG_GNUTLS_NETTLE=y" >> $config_host_mak
+if test "$nettle" = "yes" ; then
+  echo "CONFIG_NETTLE=y" >> $config_host_mak
   echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
 fi
 if test "$tasn1" = "yes" ; then
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 024a00c..c8bd180 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -47,7 +47,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
     return true;
 }
 
-#if defined(CONFIG_GNUTLS_GCRYPT) || defined(CONFIG_GNUTLS_NETTLE)
+#if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE)
 static uint8_t *
 qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
                                  size_t nkey)
@@ -63,11 +63,11 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
     }
     return ret;
 }
-#endif /* CONFIG_GNUTLS_GCRYPT || CONFIG_GNUTLS_NETTLE */
+#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
 
-#ifdef CONFIG_GNUTLS_GCRYPT
+#ifdef CONFIG_GCRYPT
 #include "crypto/cipher-gcrypt.c"
-#elif defined CONFIG_GNUTLS_NETTLE
+#elif defined CONFIG_NETTLE
 #include "crypto/cipher-nettle.c"
 #else
 #include "crypto/cipher-builtin.c"
diff --git a/crypto/init.c b/crypto/init.c
index 7447882..d94faac 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -24,8 +24,9 @@
 #ifdef CONFIG_GNUTLS
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
+#endif
 
-#ifdef CONFIG_GNUTLS_GCRYPT
+#ifdef CONFIG_GCRYPT
 #include <gcrypt.h>
 #endif
 
@@ -37,6 +38,7 @@
  *  - When GNUTLS >= 2.12, we must not initialize gcrypt threading
  *    because GNUTLS will do that itself
  *  - When GNUTLS < 2.12 we must always initialize gcrypt threading
+ *  - When GNUTLS is disabled we must always initialize gcrypt threading
  *
  * But....
  *
@@ -47,12 +49,15 @@
  *
  *   - gcrypt < 1.6.0
  * AND
- *   - gnutls < 2.12
+ *      - gnutls < 2.12
+ *   OR
+ *      - gnutls is disabled
  *
  */
 
-#if (defined(CONFIG_GNUTLS_GCRYPT) &&           \
-     (!defined(GNUTLS_VERSION_NUMBER) ||        \
+#if (defined(CONFIG_GCRYPT) &&                  \
+     (!defined(CONFIG_GNUTLS) ||                \
+      !defined(GNUTLS_VERSION_NUMBER) ||       \
       (GNUTLS_VERSION_NUMBER < 0x020c00)) &&    \
      (!defined(GCRYPT_VERSION_NUMBER) ||        \
       (GCRYPT_VERSION_NUMBER < 0x010600)))
@@ -113,6 +118,7 @@ static struct gcry_thread_cbs qcrypto_gcrypt_thread_impl = {
 
 int qcrypto_init(Error **errp)
 {
+#ifdef CONFIG_GNUTLS
     int ret;
     ret = gnutls_global_init();
     if (ret < 0) {
@@ -125,8 +131,9 @@ int qcrypto_init(Error **errp)
     gnutls_global_set_log_level(10);
     gnutls_global_set_log_function(qcrypto_gnutls_log);
 #endif
+#endif
 
-#ifdef CONFIG_GNUTLS_GCRYPT
+#ifdef CONFIG_GCRYPT
     if (!gcry_check_version(GCRYPT_VERSION)) {
         error_setg(errp, "Unable to initialize gcrypt");
         return -1;
@@ -139,12 +146,3 @@ int qcrypto_init(Error **errp)
 
     return 0;
 }
-
-#else /* ! CONFIG_GNUTLS */
-
-int qcrypto_init(Error **errp G_GNUC_UNUSED)
-{
-    return 0;
-}
-
-#endif /* ! CONFIG_GNUTLS */
-- 
2.4.3

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

* [Qemu-devel] [PULL v1 2/4] crypto: don't let builtin aes crash if no IV is provided
  2015-10-21 10:47 [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 1/4] crypto: allow use of nettle/gcrypt to be selected explicitly Daniel P. Berrange
@ 2015-10-21 10:47 ` Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 3/4] crypto: add sanity checking of plaintext/ciphertext length Daniel P. Berrange
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrange @ 2015-10-21 10:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

If no IV is provided, then use a default IV of all-zeros
instead of crashing. This gives parity with gcrypt and
nettle backends.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 crypto/cipher-builtin.c    | 14 +++++---------
 tests/test-crypto-cipher.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index 30f4853..37e1a19 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -25,8 +25,7 @@ typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
 struct QCryptoCipherBuiltinAES {
     AES_KEY encrypt_key;
     AES_KEY decrypt_key;
-    uint8_t *iv;
-    size_t niv;
+    uint8_t iv[AES_BLOCK_SIZE];
 };
 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
 struct QCryptoCipherBuiltinDESRFB {
@@ -61,7 +60,6 @@ static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
 
-    g_free(ctxt->state.aes.iv);
     g_free(ctxt);
     cipher->opaque = NULL;
 }
@@ -145,15 +143,13 @@ static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
                                      Error **errp)
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
-    if (niv != 16) {
-        error_setg(errp, "IV must be 16 bytes not %zu", niv);
+    if (niv != AES_BLOCK_SIZE) {
+        error_setg(errp, "IV must be %d bytes not %zu",
+                   AES_BLOCK_SIZE, niv);
         return -1;
     }
 
-    g_free(ctxt->state.aes.iv);
-    ctxt->state.aes.iv = g_new0(uint8_t, niv);
-    memcpy(ctxt->state.aes.iv, iv, niv);
-    ctxt->state.aes.niv = niv;
+    memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE);
 
     return 0;
 }
diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c
index 9d38d26..1b60c34 100644
--- a/tests/test-crypto-cipher.c
+++ b/tests/test-crypto-cipher.c
@@ -287,6 +287,32 @@ static void test_cipher(const void *opaque)
     qcrypto_cipher_free(cipher);
 }
 
+
+static void test_cipher_null_iv(void)
+{
+    QCryptoCipher *cipher;
+    uint8_t key[32] = { 0 };
+    uint8_t plaintext[32] = { 0 };
+    uint8_t ciphertext[32] = { 0 };
+
+    cipher = qcrypto_cipher_new(
+        QCRYPTO_CIPHER_ALG_AES_256,
+        QCRYPTO_CIPHER_MODE_CBC,
+        key, sizeof(key),
+        &error_abort);
+    g_assert(cipher != NULL);
+
+    /* Don't call qcrypto_cipher_setiv */
+
+    qcrypto_cipher_encrypt(cipher,
+                           plaintext,
+                           ciphertext,
+                           sizeof(plaintext),
+                           &error_abort);
+
+    qcrypto_cipher_free(cipher);
+}
+
 int main(int argc, char **argv)
 {
     size_t i;
@@ -298,5 +324,9 @@ int main(int argc, char **argv)
     for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
         g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
     }
+
+    g_test_add_func("/crypto/cipher/null-iv",
+                    test_cipher_null_iv);
+
     return g_test_run();
 }
-- 
2.4.3

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

* [Qemu-devel] [PULL v1 3/4] crypto: add sanity checking of plaintext/ciphertext length
  2015-10-21 10:47 [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 1/4] crypto: allow use of nettle/gcrypt to be selected explicitly Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 2/4] crypto: don't let builtin aes crash if no IV is provided Daniel P. Berrange
@ 2015-10-21 10:47 ` Daniel P. Berrange
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 4/4] configure: avoid polluting global CFLAGS with tasn1 flags Daniel P. Berrange
  2015-10-21 20:21 ` [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Peter Maydell
  4 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrange @ 2015-10-21 10:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

When encrypting/decrypting data, the plaintext/ciphertext
buffers are required to be a multiple of the cipher block
size. If this is not done, nettle will abort and gcrypt
will report an error. To get consistent behaviour add
explicit checks upfront for the buffer sizes.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 crypto/cipher-builtin.c    | 15 ++++++++++++
 crypto/cipher-gcrypt.c     | 61 ++++++++++++++++++++++++++++++++++------------
 crypto/cipher-nettle.c     | 28 +++++++++++++++------
 tests/test-crypto-cipher.c | 50 +++++++++++++++++++++++++++++++++++++
 4 files changed, 130 insertions(+), 24 deletions(-)

diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index 37e1a19..39e31a7 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -39,6 +39,7 @@ struct QCryptoCipherBuiltin {
         QCryptoCipherBuiltinAES aes;
         QCryptoCipherBuiltinDESRFB desrfb;
     } state;
+    size_t blocksize;
     void (*free)(QCryptoCipher *cipher);
     int (*setiv)(QCryptoCipher *cipher,
                  const uint8_t *iv, size_t niv,
@@ -181,6 +182,7 @@ static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
         goto error;
     }
 
+    ctxt->blocksize = AES_BLOCK_SIZE;
     ctxt->free = qcrypto_cipher_free_aes;
     ctxt->setiv = qcrypto_cipher_setiv_aes;
     ctxt->encrypt = qcrypto_cipher_encrypt_aes;
@@ -282,6 +284,7 @@ static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
     memcpy(ctxt->state.desrfb.key, key, nkey);
     ctxt->state.desrfb.nkey = nkey;
 
+    ctxt->blocksize = 8;
     ctxt->free = qcrypto_cipher_free_des_rfb;
     ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
     ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
@@ -370,6 +373,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
 
+    if (len % ctxt->blocksize) {
+        error_setg(errp, "Length %zu must be a multiple of block size %zu",
+                   len, ctxt->blocksize);
+        return -1;
+    }
+
     return ctxt->encrypt(cipher, in, out, len, errp);
 }
 
@@ -382,6 +391,12 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
 {
     QCryptoCipherBuiltin *ctxt = cipher->opaque;
 
+    if (len % ctxt->blocksize) {
+        error_setg(errp, "Length %zu must be a multiple of block size %zu",
+                   len, ctxt->blocksize);
+        return -1;
+    }
+
     return ctxt->decrypt(cipher, in, out, len, errp);
 }
 
diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index 8cfc562..c4f8114 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -34,6 +34,11 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
     }
 }
 
+typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt;
+struct QCryptoCipherGcrypt {
+    gcry_cipher_hd_t handle;
+    size_t blocksize;
+};
 
 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                                   QCryptoCipherMode mode,
@@ -41,7 +46,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
                                   Error **errp)
 {
     QCryptoCipher *cipher;
-    gcry_cipher_hd_t handle;
+    QCryptoCipherGcrypt *ctx;
     gcry_error_t err;
     int gcryalg, gcrymode;
 
@@ -87,7 +92,9 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
     cipher->alg = alg;
     cipher->mode = mode;
 
-    err = gcry_cipher_open(&handle, gcryalg, gcrymode, 0);
+    ctx = g_new0(QCryptoCipherGcrypt, 1);
+
+    err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0);
     if (err != 0) {
         error_setg(errp, "Cannot initialize cipher: %s",
                    gcry_strerror(err));
@@ -100,10 +107,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
          * bizarre RFB variant of DES :-)
          */
         uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
-        err = gcry_cipher_setkey(handle, rfbkey, nkey);
+        err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
         g_free(rfbkey);
+        ctx->blocksize = 8;
     } else {
-        err = gcry_cipher_setkey(handle, key, nkey);
+        err = gcry_cipher_setkey(ctx->handle, key, nkey);
+        ctx->blocksize = 16;
     }
     if (err != 0) {
         error_setg(errp, "Cannot set key: %s",
@@ -111,11 +120,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         goto error;
     }
 
-    cipher->opaque = handle;
+    cipher->opaque = ctx;
     return cipher;
 
  error:
-    gcry_cipher_close(handle);
+    gcry_cipher_close(ctx->handle);
+    g_free(ctx);
     g_free(cipher);
     return NULL;
 }
@@ -123,12 +133,13 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
 
 void qcrypto_cipher_free(QCryptoCipher *cipher)
 {
-    gcry_cipher_hd_t handle;
+    QCryptoCipherGcrypt *ctx;
     if (!cipher) {
         return;
     }
-    handle = cipher->opaque;
-    gcry_cipher_close(handle);
+    ctx = cipher->opaque;
+    gcry_cipher_close(ctx->handle);
+    g_free(ctx);
     g_free(cipher);
 }
 
@@ -139,10 +150,16 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
                            size_t len,
                            Error **errp)
 {
-    gcry_cipher_hd_t handle = cipher->opaque;
+    QCryptoCipherGcrypt *ctx = cipher->opaque;
     gcry_error_t err;
 
-    err = gcry_cipher_encrypt(handle,
+    if (len % ctx->blocksize) {
+        error_setg(errp, "Length %zu must be a multiple of block size %zu",
+                   len, ctx->blocksize);
+        return -1;
+    }
+
+    err = gcry_cipher_encrypt(ctx->handle,
                               out, len,
                               in, len);
     if (err != 0) {
@@ -161,10 +178,16 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
                            size_t len,
                            Error **errp)
 {
-    gcry_cipher_hd_t handle = cipher->opaque;
+    QCryptoCipherGcrypt *ctx = cipher->opaque;
     gcry_error_t err;
 
-    err = gcry_cipher_decrypt(handle,
+    if (len % ctx->blocksize) {
+        error_setg(errp, "Length %zu must be a multiple of block size %zu",
+                   len, ctx->blocksize);
+        return -1;
+    }
+
+    err = gcry_cipher_decrypt(ctx->handle,
                               out, len,
                               in, len);
     if (err != 0) {
@@ -180,11 +203,17 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
                          const uint8_t *iv, size_t niv,
                          Error **errp)
 {
-    gcry_cipher_hd_t handle = cipher->opaque;
+    QCryptoCipherGcrypt *ctx = cipher->opaque;
     gcry_error_t err;
 
-    gcry_cipher_reset(handle);
-    err = gcry_cipher_setiv(handle, iv, niv);
+    if (niv != ctx->blocksize) {
+        error_setg(errp, "Expected IV size %zu not %zu",
+                   ctx->blocksize, niv);
+        return -1;
+    }
+
+    gcry_cipher_reset(ctx->handle);
+    err = gcry_cipher_setiv(ctx->handle, iv, niv);
     if (err != 0) {
         error_setg(errp, "Cannot set IV: %s",
                    gcry_strerror(err));
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index b01cb1c..7449338 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -69,7 +69,7 @@ struct QCryptoCipherNettle {
     nettle_cipher_func *alg_encrypt;
     nettle_cipher_func *alg_decrypt;
     uint8_t *iv;
-    size_t niv;
+    size_t blocksize;
 };
 
 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
@@ -125,7 +125,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         ctx->alg_encrypt = des_encrypt_wrapper;
         ctx->alg_decrypt = des_decrypt_wrapper;
 
-        ctx->niv = DES_BLOCK_SIZE;
+        ctx->blocksize = DES_BLOCK_SIZE;
         break;
 
     case QCRYPTO_CIPHER_ALG_AES_128:
@@ -140,14 +140,14 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
         ctx->alg_encrypt = aes_encrypt_wrapper;
         ctx->alg_decrypt = aes_decrypt_wrapper;
 
-        ctx->niv = AES_BLOCK_SIZE;
+        ctx->blocksize = AES_BLOCK_SIZE;
         break;
     default:
         error_setg(errp, "Unsupported cipher algorithm %d", alg);
         goto error;
     }
 
-    ctx->iv = g_new0(uint8_t, ctx->niv);
+    ctx->iv = g_new0(uint8_t, ctx->blocksize);
     cipher->opaque = ctx;
 
     return cipher;
@@ -184,6 +184,12 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 {
     QCryptoCipherNettle *ctx = cipher->opaque;
 
+    if (len % ctx->blocksize) {
+        error_setg(errp, "Length %zu must be a multiple of block size %zu",
+                   len, ctx->blocksize);
+        return -1;
+    }
+
     switch (cipher->mode) {
     case QCRYPTO_CIPHER_MODE_ECB:
         ctx->alg_encrypt(ctx->ctx_encrypt, len, out, in);
@@ -191,7 +197,7 @@ int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 
     case QCRYPTO_CIPHER_MODE_CBC:
         cbc_encrypt(ctx->ctx_encrypt, ctx->alg_encrypt,
-                    ctx->niv, ctx->iv,
+                    ctx->blocksize, ctx->iv,
                     len, out, in);
         break;
     default:
@@ -211,6 +217,12 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
 {
     QCryptoCipherNettle *ctx = cipher->opaque;
 
+    if (len % ctx->blocksize) {
+        error_setg(errp, "Length %zu must be a multiple of block size %zu",
+                   len, ctx->blocksize);
+        return -1;
+    }
+
     switch (cipher->mode) {
     case QCRYPTO_CIPHER_MODE_ECB:
         ctx->alg_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,
@@ -219,7 +231,7 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
 
     case QCRYPTO_CIPHER_MODE_CBC:
         cbc_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,
-                    ctx->alg_decrypt, ctx->niv, ctx->iv,
+                    ctx->alg_decrypt, ctx->blocksize, ctx->iv,
                     len, out, in);
         break;
     default:
@@ -235,9 +247,9 @@ int qcrypto_cipher_setiv(QCryptoCipher *cipher,
                          Error **errp)
 {
     QCryptoCipherNettle *ctx = cipher->opaque;
-    if (niv != ctx->niv) {
+    if (niv != ctx->blocksize) {
         error_setg(errp, "Expected IV size %zu not %zu",
-                   ctx->niv, niv);
+                   ctx->blocksize, niv);
         return -1;
     }
     memcpy(ctx->iv, iv, niv);
diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c
index 1b60c34..f4946a0 100644
--- a/tests/test-crypto-cipher.c
+++ b/tests/test-crypto-cipher.c
@@ -313,6 +313,53 @@ static void test_cipher_null_iv(void)
     qcrypto_cipher_free(cipher);
 }
 
+static void test_cipher_short_plaintext(void)
+{
+    Error *err = NULL;
+    QCryptoCipher *cipher;
+    uint8_t key[32] = { 0 };
+    uint8_t plaintext1[20] = { 0 };
+    uint8_t ciphertext1[20] = { 0 };
+    uint8_t plaintext2[40] = { 0 };
+    uint8_t ciphertext2[40] = { 0 };
+    int ret;
+
+    cipher = qcrypto_cipher_new(
+        QCRYPTO_CIPHER_ALG_AES_256,
+        QCRYPTO_CIPHER_MODE_CBC,
+        key, sizeof(key),
+        &error_abort);
+    g_assert(cipher != NULL);
+
+    /* Should report an error as plaintext is shorter
+     * than block size
+     */
+    ret = qcrypto_cipher_encrypt(cipher,
+                                 plaintext1,
+                                 ciphertext1,
+                                 sizeof(plaintext1),
+                                 &err);
+    g_assert(ret == -1);
+    g_assert(err != NULL);
+
+    error_free(err);
+    err = NULL;
+
+    /* Should report an error as plaintext is larger than
+     * block size, but not a multiple of block size
+     */
+    ret = qcrypto_cipher_encrypt(cipher,
+                                 plaintext2,
+                                 ciphertext2,
+                                 sizeof(plaintext2),
+                                 &err);
+    g_assert(ret == -1);
+    g_assert(err != NULL);
+
+    error_free(err);
+    qcrypto_cipher_free(cipher);
+}
+
 int main(int argc, char **argv)
 {
     size_t i;
@@ -328,5 +375,8 @@ int main(int argc, char **argv)
     g_test_add_func("/crypto/cipher/null-iv",
                     test_cipher_null_iv);
 
+    g_test_add_func("/crypto/cipher/short-plaintext",
+                    test_cipher_short_plaintext);
+
     return g_test_run();
 }
-- 
2.4.3

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

* [Qemu-devel] [PULL v1 4/4] configure: avoid polluting global CFLAGS with tasn1 flags
  2015-10-21 10:47 [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Daniel P. Berrange
                   ` (2 preceding siblings ...)
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 3/4] crypto: add sanity checking of plaintext/ciphertext length Daniel P. Berrange
@ 2015-10-21 10:47 ` Daniel P. Berrange
  2015-10-21 20:21 ` [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Peter Maydell
  4 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrange @ 2015-10-21 10:47 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

The previous commit

  commit 9a2fd4347c40321f5cbb4ab4220e759fcbf87d03
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Mon Apr 13 14:01:39 2015 +0100

    crypto: add sanity checking of TLS x509 credentials

defined new variables $TEST_LIBS and $TEST_CFLAGS and
used them in tests/Makefile to augment $LIBS and $CFLAGS.

Unfortunately this overlooks the fact that tests/Makefile
is not executed via recursive-make, it is just pulled into
the top level Makefile via an include statement. So rather
than just augmenting the compiler/linker flags for tests
it polluted the global flags.

This is thought to be behind a reported failure when
building the pixman module as a sub-module, since global
$CFLAGS are passed down to configure in pixman.

This change removes the $TEST_LIBS and $TEST_CFLAGS
replacing them with $TASN1_LIBS and $TASN1_CFLAGS,
setting only against specific objects/executables
that need them.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 configure      | 11 ++++-------
 tests/Makefile | 10 ++++++++--
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index 58f6fc1..263dff2 100755
--- a/configure
+++ b/configure
@@ -419,9 +419,6 @@ if test "$debug_info" = "yes"; then
     LDFLAGS="-g $LDFLAGS"
 fi
 
-test_cflags=""
-test_libs=""
-
 # make source path absolute
 source_path=`cd "$source_path"; pwd`
 
@@ -2347,11 +2344,11 @@ fi
 # libtasn1 - only for the TLS creds/session test suite
 
 tasn1=yes
+tasn1_cflags=""
+tasn1_libs=""
 if $pkg_config --exists "libtasn1"; then
     tasn1_cflags=`$pkg_config --cflags libtasn1`
     tasn1_libs=`$pkg_config --libs libtasn1`
-    test_cflags="$test_cflags $tasn1_cflags"
-    test_libs="$test_libs $tasn1_libs"
 else
     tasn1=no
 fi
@@ -5374,8 +5371,8 @@ echo "EXESUF=$EXESUF" >> $config_host_mak
 echo "DSOSUF=$DSOSUF" >> $config_host_mak
 echo "LDFLAGS_SHARED=$LDFLAGS_SHARED" >> $config_host_mak
 echo "LIBS_QGA+=$libs_qga" >> $config_host_mak
-echo "TEST_LIBS=$test_libs" >> $config_host_mak
-echo "TEST_CFLAGS=$test_cflags" >> $config_host_mak
+echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak
+echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak
 echo "POD2MAN=$POD2MAN" >> $config_host_mak
 echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak
 if test "$gcov" = "yes" ; then
diff --git a/tests/Makefile b/tests/Makefile
index 0531b30..9341498 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -444,8 +444,16 @@ tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
 tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
 tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
 tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
+
+tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS)
+tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS)
+tests/pkix_asn1_tab.o-cflags := $(TASN1_CFLAGS)
+
+tests/test-crypto-tlscredsx509.o-cflags := $(TASN1_CFLAGS)
 tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \
 	tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
+
+tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS)
 tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \
 	tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
 
@@ -518,8 +526,6 @@ tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
 ifeq ($(CONFIG_POSIX),y)
 LIBS += -lutil
 endif
-LIBS += $(TEST_LIBS)
-CFLAGS += $(TEST_CFLAGS)
 
 # QTest rules
 
-- 
2.4.3

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

* Re: [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module
  2015-10-21 10:47 [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Daniel P. Berrange
                   ` (3 preceding siblings ...)
  2015-10-21 10:47 ` [Qemu-devel] [PULL v1 4/4] configure: avoid polluting global CFLAGS with tasn1 flags Daniel P. Berrange
@ 2015-10-21 20:21 ` Peter Maydell
  2015-10-22 10:13   ` Daniel P. Berrange
  4 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2015-10-21 20:21 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: QEMU Developers

On 21 October 2015 at 11:47, Daniel P. Berrange <berrange@redhat.com> wrote:
> The following changes since commit ee9dfed242610ecb91418270fd46b875ed56e201:
>
>   Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20151020-1' into staging (2015-10-20 12:56:45 +0100)
>
> are available in the git repository at:
>
>   https://github.com/berrange/qemu.git tags/qcrypto-fixes-pull-20151021-1
>
> for you to fetch changes up to 635b2807565e0724e4aed73f8ca54f14df051499:
>
>   configure: avoid polluting global CFLAGS with tasn1 flags (2015-10-21 11:42:42 +0100)
>
> ----------------------------------------------------------------
> Merge qcrypto-fixes 2015/10/21
>
> ----------------------------------------------------------------

Hi. I'm afraid this fails to build on w32:

/home/petmay01/linaro/qemu-for-merges/crypto/init.c:30:20: error:
gcrypt.h: No such file or directory
/home/petmay01/linaro/qemu-for-merges/crypto/init.c:108: error:
variable ‘qcrypto_gcrypt_thread_impl’ has initializer but incomplete
type
/home/petmay01/linaro/qemu-for-merges/crypto/init.c:109: error:
‘GCRY_THREAD_OPTION_PTHREAD’ undeclared here (not in a function)
/home/petmay01/linaro/qemu-for-merges/crypto/init.c:109: error:
‘GCRY_THREAD_OPTION_VERSION’ undeclared here (not in a function)

(and then a large pile of other errors that you'd expect from
failing to find gcrypt.h.)

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module
  2015-10-21 20:21 ` [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Peter Maydell
@ 2015-10-22 10:13   ` Daniel P. Berrange
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel P. Berrange @ 2015-10-22 10:13 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On Wed, Oct 21, 2015 at 09:21:05PM +0100, Peter Maydell wrote:
> On 21 October 2015 at 11:47, Daniel P. Berrange <berrange@redhat.com> wrote:
> > The following changes since commit ee9dfed242610ecb91418270fd46b875ed56e201:
> >
> >   Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20151020-1' into staging (2015-10-20 12:56:45 +0100)
> >
> > are available in the git repository at:
> >
> >   https://github.com/berrange/qemu.git tags/qcrypto-fixes-pull-20151021-1
> >
> > for you to fetch changes up to 635b2807565e0724e4aed73f8ca54f14df051499:
> >
> >   configure: avoid polluting global CFLAGS with tasn1 flags (2015-10-21 11:42:42 +0100)
> >
> > ----------------------------------------------------------------
> > Merge qcrypto-fixes 2015/10/21
> >
> > ----------------------------------------------------------------
> 
> Hi. I'm afraid this fails to build on w32:
> 
> /home/petmay01/linaro/qemu-for-merges/crypto/init.c:30:20: error:
> gcrypt.h: No such file or directory
> /home/petmay01/linaro/qemu-for-merges/crypto/init.c:108: error:
> variable ‘qcrypto_gcrypt_thread_impl’ has initializer but incomplete
> type
> /home/petmay01/linaro/qemu-for-merges/crypto/init.c:109: error:
> ‘GCRY_THREAD_OPTION_PTHREAD’ undeclared here (not in a function)
> /home/petmay01/linaro/qemu-for-merges/crypto/init.c:109: error:
> ‘GCRY_THREAD_OPTION_VERSION’ undeclared here (not in a function)
> 
> (and then a large pile of other errors that you'd expect from
> failing to find gcrypt.h.)

Oh, fun, a pre-existing bug in configure, which we now trigger more
often. We look for 'libgcrypt-config' in $PATH, but don't bother to
check whether the one we found is for native builds or cross builds.
I'll fix configure to run 'libgcrypt-config --host' to make sure
we match the cross prefix.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

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

end of thread, other threads:[~2015-10-22 10:13 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-21 10:47 [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Daniel P. Berrange
2015-10-21 10:47 ` [Qemu-devel] [PULL v1 1/4] crypto: allow use of nettle/gcrypt to be selected explicitly Daniel P. Berrange
2015-10-21 10:47 ` [Qemu-devel] [PULL v1 2/4] crypto: don't let builtin aes crash if no IV is provided Daniel P. Berrange
2015-10-21 10:47 ` [Qemu-devel] [PULL v1 3/4] crypto: add sanity checking of plaintext/ciphertext length Daniel P. Berrange
2015-10-21 10:47 ` [Qemu-devel] [PULL v1 4/4] configure: avoid polluting global CFLAGS with tasn1 flags Daniel P. Berrange
2015-10-21 20:21 ` [Qemu-devel] [PULL v1 0/4] Misc fixes for crypto code module Peter Maydell
2015-10-22 10:13   ` 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.