qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
@ 2023-12-07 15:47 Hyman Huang
  2023-12-07 16:02 ` Philippe Mathieu-Daudé
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Hyman Huang @ 2023-12-07 15:47 UTC (permalink / raw)
  To: qemu-devel
  Cc: Daniel P . Berrangé, Paolo Bonzini, Marc-André Lureau,
	Thomas Huth, Philippe Mathieu-Daudé, Eric Blake,
	Markus Armbruster, yong.huang

Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).

SM4 (GBT.32907-2016) is a cryptographic standard issued by the
Organization of State Commercial Administration of China (OSCCA)
as an authorized cryptographic algorithms for the use within China.

Detect the SM4 cipher algorithms and enable the feature silently
if it is available.

Signed-off-by: Hyman Huang <yong.huang@smartx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 crypto/block-luks.c             | 11 ++++++++
 crypto/cipher-gcrypt.c.inc      |  8 ++++++
 crypto/cipher-nettle.c.inc      | 49 +++++++++++++++++++++++++++++++++
 crypto/cipher.c                 |  6 ++++
 meson.build                     | 26 +++++++++++++++++
 qapi/crypto.json                |  5 +++-
 tests/unit/test-crypto-cipher.c | 13 +++++++++
 7 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index fb01ec38bb..f0813d69b4 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -95,12 +95,23 @@ qcrypto_block_luks_cipher_size_map_twofish[] = {
     { 0, 0 },
 };
 
+#ifdef CONFIG_CRYPTO_SM4
+static const QCryptoBlockLUKSCipherSizeMap
+qcrypto_block_luks_cipher_size_map_sm4[] = {
+    { 16, QCRYPTO_CIPHER_ALG_SM4},
+    { 0, 0 },
+};
+#endif
+
 static const QCryptoBlockLUKSCipherNameMap
 qcrypto_block_luks_cipher_name_map[] = {
     { "aes", qcrypto_block_luks_cipher_size_map_aes },
     { "cast5", qcrypto_block_luks_cipher_size_map_cast5 },
     { "serpent", qcrypto_block_luks_cipher_size_map_serpent },
     { "twofish", qcrypto_block_luks_cipher_size_map_twofish },
+#ifdef CONFIG_CRYPTO_SM4
+    { "sm4", qcrypto_block_luks_cipher_size_map_sm4},
+#endif
 };
 
 QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index a6a0117717..1377cbaf14 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -35,6 +35,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
     case QCRYPTO_CIPHER_ALG_SERPENT_256:
     case QCRYPTO_CIPHER_ALG_TWOFISH_128:
     case QCRYPTO_CIPHER_ALG_TWOFISH_256:
+#ifdef CONFIG_CRYPTO_SM4
+    case QCRYPTO_CIPHER_ALG_SM4:
+#endif
         break;
     default:
         return false;
@@ -219,6 +222,11 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
     case QCRYPTO_CIPHER_ALG_TWOFISH_256:
         gcryalg = GCRY_CIPHER_TWOFISH;
         break;
+#ifdef CONFIG_CRYPTO_SM4
+    case QCRYPTO_CIPHER_ALG_SM4:
+        gcryalg = GCRY_CIPHER_SM4;
+        break;
+#endif
     default:
         error_setg(errp, "Unsupported cipher algorithm %s",
                    QCryptoCipherAlgorithm_str(alg));
diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
index 24cc61f87b..42b39e18a2 100644
--- a/crypto/cipher-nettle.c.inc
+++ b/crypto/cipher-nettle.c.inc
@@ -33,6 +33,9 @@
 #ifndef CONFIG_QEMU_PRIVATE_XTS
 #include <nettle/xts.h>
 #endif
+#ifdef CONFIG_CRYPTO_SM4
+#include <nettle/sm4.h>
+#endif
 
 static inline bool qcrypto_length_check(size_t len, size_t blocksize,
                                         Error **errp)
@@ -426,6 +429,30 @@ DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
                        QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
                        twofish_encrypt_native, twofish_decrypt_native)
 
+#ifdef CONFIG_CRYPTO_SM4
+typedef struct QCryptoNettleSm4 {
+    QCryptoCipher base;
+    struct sm4_ctx key[2];
+} QCryptoNettleSm4;
+
+static void sm4_encrypt_native(void *ctx, size_t length,
+                               uint8_t *dst, const uint8_t *src)
+{
+    struct sm4_ctx *keys = ctx;
+    sm4_crypt(&keys[0], length, dst, src);
+}
+
+static void sm4_decrypt_native(void *ctx, size_t length,
+                               uint8_t *dst, const uint8_t *src)
+{
+    struct sm4_ctx *keys = ctx;
+    sm4_crypt(&keys[1], length, dst, src);
+}
+
+DEFINE_ECB(qcrypto_nettle_sm4,
+           QCryptoNettleSm4, SM4_BLOCK_SIZE,
+           sm4_encrypt_native, sm4_decrypt_native)
+#endif
 
 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
                              QCryptoCipherMode mode)
@@ -443,6 +470,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
     case QCRYPTO_CIPHER_ALG_TWOFISH_128:
     case QCRYPTO_CIPHER_ALG_TWOFISH_192:
     case QCRYPTO_CIPHER_ALG_TWOFISH_256:
+#ifdef CONFIG_CRYPTO_SM4
+    case QCRYPTO_CIPHER_ALG_SM4:
+#endif
         break;
     default:
         return false;
@@ -701,6 +731,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
 
             return &ctx->base;
         }
+#ifdef CONFIG_CRYPTO_SM4
+    case QCRYPTO_CIPHER_ALG_SM4:
+        {
+            QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
+
+            switch (mode) {
+            case QCRYPTO_CIPHER_MODE_ECB:
+                ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
+                break;
+            default:
+                goto bad_cipher_mode;
+            }
+
+            sm4_set_encrypt_key(&ctx->key[0], key);
+            sm4_set_decrypt_key(&ctx->key[1], key);
+
+            return &ctx->base;
+        }
+#endif
 
     default:
         error_setg(errp, "Unsupported cipher algorithm %s",
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 74b09a5b26..5f512768ea 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -38,6 +38,9 @@ static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
     [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
     [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24,
     [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
+#ifdef CONFIG_CRYPTO_SM4
+    [QCRYPTO_CIPHER_ALG_SM4] = 16,
+#endif
 };
 
 static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
@@ -53,6 +56,9 @@ static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
     [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
     [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16,
     [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
+#ifdef CONFIG_CRYPTO_SM4
+    [QCRYPTO_CIPHER_ALG_SM4] = 16,
+#endif
 };
 
 static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
diff --git a/meson.build b/meson.build
index d2c4c2adb3..52f2f85b5a 100644
--- a/meson.build
+++ b/meson.build
@@ -1480,6 +1480,7 @@ endif
 gcrypt = not_found
 nettle = not_found
 hogweed = not_found
+crypto_sm4 = not_found
 xts = 'none'
 
 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
@@ -1505,6 +1506,17 @@ if not gnutls_crypto.found()
          cc.find_library('gpg-error', required: true)],
         version: gcrypt.version())
     endif
+    crypto_sm4 = gcrypt
+    # SM4 ALG is available in libgcrypt >= 1.9
+    if gcrypt.found() and not cc.links('''
+      #include <gcrypt.h>
+      int main(void) {
+        gcry_cipher_hd_t handler;
+        gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
+        return 0;
+      }''', dependencies: gcrypt)
+      crypto_sm4 = not_found
+    endif
   endif
   if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
     nettle = dependency('nettle', version: '>=3.4',
@@ -1513,6 +1525,18 @@ if not gnutls_crypto.found()
     if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
       xts = 'private'
     endif
+    crypto_sm4 = nettle
+    # SM4 ALG is available in nettle >= 3.9
+    if nettle.found() and not cc.links('''
+      #include <nettle/sm4.h>
+      int main(void) {
+        struct sm4_ctx ctx;
+        unsigned char key[16] = {0};
+        sm4_set_encrypt_key(&ctx, key);
+        return 0;
+      }''', dependencies: nettle)
+      crypto_sm4 = not_found
+    endif
   endif
 endif
 
@@ -2199,6 +2223,7 @@ config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
 config_host_data.set('CONFIG_TASN1', tasn1.found())
 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
 config_host_data.set('CONFIG_NETTLE', nettle.found())
+config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
@@ -4274,6 +4299,7 @@ summary_info += {'nettle':            nettle}
 if nettle.found()
    summary_info += {'  XTS':             xts != 'private'}
 endif
+summary_info += {'SM4 ALG support':   crypto_sm4}
 summary_info += {'AF_ALG support':    have_afalg}
 summary_info += {'rng-none':          get_option('rng_none')}
 summary_info += {'Linux keyring':     have_keyring}
diff --git a/qapi/crypto.json b/qapi/crypto.json
index fd3d46ebd1..2f2aeff5fd 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -94,6 +94,8 @@
 #
 # @twofish-256: Twofish with 256 bit / 32 byte keys
 #
+# @sm4: SM4 with 128 bit / 16 byte keys (since 9.0)
+#
 # Since: 2.6
 ##
 { 'enum': 'QCryptoCipherAlgorithm',
@@ -102,7 +104,8 @@
            'des', '3des',
            'cast5-128',
            'serpent-128', 'serpent-192', 'serpent-256',
-           'twofish-128', 'twofish-192', 'twofish-256']}
+           'twofish-128', 'twofish-192', 'twofish-256',
+           'sm4']}
 
 ##
 # @QCryptoCipherMode:
diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
index d9d9d078ff..11ab1a54fc 100644
--- a/tests/unit/test-crypto-cipher.c
+++ b/tests/unit/test-crypto-cipher.c
@@ -382,6 +382,19 @@ static QCryptoCipherTestData test_data[] = {
         .plaintext = "90afe91bb288544f2c32dc239b2635e6",
         .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
     },
+#ifdef CONFIG_CRYPTO_SM4
+    {
+        /* SM4, GB/T 32907-2016, Appendix A.1 */
+        .path = "/crypto/cipher/sm4",
+        .alg = QCRYPTO_CIPHER_ALG_SM4,
+        .mode = QCRYPTO_CIPHER_MODE_ECB,
+        .key = "0123456789abcdeffedcba9876543210",
+        .plaintext  =
+            "0123456789abcdeffedcba9876543210",
+        .ciphertext =
+            "681edf34d206965e86b3e94f536e4246",
+    },
+#endif
     {
         /* #1 32 byte key, 32 byte PTX */
         .path = "/crypto/cipher/aes-xts-128-1",
-- 
2.39.1



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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2023-12-07 15:47 [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm Hyman Huang
@ 2023-12-07 16:02 ` Philippe Mathieu-Daudé
  2023-12-08  2:10   ` Yong Huang
  2023-12-08  9:33 ` Daniel P. Berrangé
  2024-03-08 20:30 ` Thomas Huth
  2 siblings, 1 reply; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-12-07 16:02 UTC (permalink / raw)
  To: Hyman Huang, qemu-devel
  Cc: Daniel P . Berrangé, Paolo Bonzini, Marc-André Lureau,
	Thomas Huth, Eric Blake, Markus Armbruster

Hi Hyman,

On 7/12/23 16:47, Hyman Huang wrote:
> Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
> 
> SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> Organization of State Commercial Administration of China (OSCCA)
> as an authorized cryptographic algorithms for the use within China.
> 
> Detect the SM4 cipher algorithms and enable the feature silently
> if it is available.
> 
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---

What are the changes since v4/v5?

>   crypto/block-luks.c             | 11 ++++++++
>   crypto/cipher-gcrypt.c.inc      |  8 ++++++
>   crypto/cipher-nettle.c.inc      | 49 +++++++++++++++++++++++++++++++++
>   crypto/cipher.c                 |  6 ++++
>   meson.build                     | 26 +++++++++++++++++
>   qapi/crypto.json                |  5 +++-
>   tests/unit/test-crypto-cipher.c | 13 +++++++++
>   7 files changed, 117 insertions(+), 1 deletion(-)
> 
> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index fb01ec38bb..f0813d69b4 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -95,12 +95,23 @@ qcrypto_block_luks_cipher_size_map_twofish[] = {
>       { 0, 0 },
>   };
>   
> +#ifdef CONFIG_CRYPTO_SM4
> +static const QCryptoBlockLUKSCipherSizeMap
> +qcrypto_block_luks_cipher_size_map_sm4[] = {
> +    { 16, QCRYPTO_CIPHER_ALG_SM4},
> +    { 0, 0 },
> +};
> +#endif
> +
>   static const QCryptoBlockLUKSCipherNameMap
>   qcrypto_block_luks_cipher_name_map[] = {
>       { "aes", qcrypto_block_luks_cipher_size_map_aes },
>       { "cast5", qcrypto_block_luks_cipher_size_map_cast5 },
>       { "serpent", qcrypto_block_luks_cipher_size_map_serpent },
>       { "twofish", qcrypto_block_luks_cipher_size_map_twofish },
> +#ifdef CONFIG_CRYPTO_SM4
> +    { "sm4", qcrypto_block_luks_cipher_size_map_sm4},
> +#endif
>   };
>   
>   QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
> diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
> index a6a0117717..1377cbaf14 100644
> --- a/crypto/cipher-gcrypt.c.inc
> +++ b/crypto/cipher-gcrypt.c.inc
> @@ -35,6 +35,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
>       case QCRYPTO_CIPHER_ALG_SERPENT_256:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +#endif
>           break;
>       default:
>           return false;
> @@ -219,6 +222,11 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
>       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
>           gcryalg = GCRY_CIPHER_TWOFISH;
>           break;
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +        gcryalg = GCRY_CIPHER_SM4;
> +        break;
> +#endif
>       default:
>           error_setg(errp, "Unsupported cipher algorithm %s",
>                      QCryptoCipherAlgorithm_str(alg));
> diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
> index 24cc61f87b..42b39e18a2 100644
> --- a/crypto/cipher-nettle.c.inc
> +++ b/crypto/cipher-nettle.c.inc
> @@ -33,6 +33,9 @@
>   #ifndef CONFIG_QEMU_PRIVATE_XTS
>   #include <nettle/xts.h>
>   #endif
> +#ifdef CONFIG_CRYPTO_SM4
> +#include <nettle/sm4.h>
> +#endif
>   
>   static inline bool qcrypto_length_check(size_t len, size_t blocksize,
>                                           Error **errp)
> @@ -426,6 +429,30 @@ DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
>                          QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
>                          twofish_encrypt_native, twofish_decrypt_native)
>   
> +#ifdef CONFIG_CRYPTO_SM4
> +typedef struct QCryptoNettleSm4 {
> +    QCryptoCipher base;
> +    struct sm4_ctx key[2];
> +} QCryptoNettleSm4;
> +
> +static void sm4_encrypt_native(void *ctx, size_t length,
> +                               uint8_t *dst, const uint8_t *src)
> +{
> +    struct sm4_ctx *keys = ctx;
> +    sm4_crypt(&keys[0], length, dst, src);
> +}
> +
> +static void sm4_decrypt_native(void *ctx, size_t length,
> +                               uint8_t *dst, const uint8_t *src)
> +{
> +    struct sm4_ctx *keys = ctx;
> +    sm4_crypt(&keys[1], length, dst, src);
> +}
> +
> +DEFINE_ECB(qcrypto_nettle_sm4,
> +           QCryptoNettleSm4, SM4_BLOCK_SIZE,
> +           sm4_encrypt_native, sm4_decrypt_native)
> +#endif
>   
>   bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
>                                QCryptoCipherMode mode)
> @@ -443,6 +470,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
>       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_192:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +#endif
>           break;
>       default:
>           return false;
> @@ -701,6 +731,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
>   
>               return &ctx->base;
>           }
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +        {
> +            QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
> +
> +            switch (mode) {
> +            case QCRYPTO_CIPHER_MODE_ECB:
> +                ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
> +                break;
> +            default:
> +                goto bad_cipher_mode;
> +            }
> +
> +            sm4_set_encrypt_key(&ctx->key[0], key);
> +            sm4_set_decrypt_key(&ctx->key[1], key);
> +
> +            return &ctx->base;
> +        }
> +#endif
>   
>       default:
>           error_setg(errp, "Unsupported cipher algorithm %s",
> diff --git a/crypto/cipher.c b/crypto/cipher.c
> index 74b09a5b26..5f512768ea 100644
> --- a/crypto/cipher.c
> +++ b/crypto/cipher.c
> @@ -38,6 +38,9 @@ static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
>       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
> +#ifdef CONFIG_CRYPTO_SM4
> +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> +#endif
>   };
>   
>   static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> @@ -53,6 +56,9 @@ static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
>       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
> +#ifdef CONFIG_CRYPTO_SM4
> +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> +#endif
>   };
>   
>   static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
> diff --git a/meson.build b/meson.build
> index d2c4c2adb3..52f2f85b5a 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1480,6 +1480,7 @@ endif
>   gcrypt = not_found
>   nettle = not_found
>   hogweed = not_found
> +crypto_sm4 = not_found
>   xts = 'none'
>   
>   if get_option('nettle').enabled() and get_option('gcrypt').enabled()
> @@ -1505,6 +1506,17 @@ if not gnutls_crypto.found()
>            cc.find_library('gpg-error', required: true)],
>           version: gcrypt.version())
>       endif
> +    crypto_sm4 = gcrypt
> +    # SM4 ALG is available in libgcrypt >= 1.9
> +    if gcrypt.found() and not cc.links('''
> +      #include <gcrypt.h>
> +      int main(void) {
> +        gcry_cipher_hd_t handler;
> +        gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
> +        return 0;
> +      }''', dependencies: gcrypt)
> +      crypto_sm4 = not_found
> +    endif
>     endif
>     if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
>       nettle = dependency('nettle', version: '>=3.4',
> @@ -1513,6 +1525,18 @@ if not gnutls_crypto.found()
>       if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
>         xts = 'private'
>       endif
> +    crypto_sm4 = nettle
> +    # SM4 ALG is available in nettle >= 3.9
> +    if nettle.found() and not cc.links('''
> +      #include <nettle/sm4.h>
> +      int main(void) {
> +        struct sm4_ctx ctx;
> +        unsigned char key[16] = {0};
> +        sm4_set_encrypt_key(&ctx, key);
> +        return 0;
> +      }''', dependencies: nettle)
> +      crypto_sm4 = not_found
> +    endif
>     endif
>   endif
>   
> @@ -2199,6 +2223,7 @@ config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
>   config_host_data.set('CONFIG_TASN1', tasn1.found())
>   config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
>   config_host_data.set('CONFIG_NETTLE', nettle.found())
> +config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
>   config_host_data.set('CONFIG_HOGWEED', hogweed.found())
>   config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
>   config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
> @@ -4274,6 +4299,7 @@ summary_info += {'nettle':            nettle}
>   if nettle.found()
>      summary_info += {'  XTS':             xts != 'private'}
>   endif
> +summary_info += {'SM4 ALG support':   crypto_sm4}
>   summary_info += {'AF_ALG support':    have_afalg}
>   summary_info += {'rng-none':          get_option('rng_none')}
>   summary_info += {'Linux keyring':     have_keyring}
> diff --git a/qapi/crypto.json b/qapi/crypto.json
> index fd3d46ebd1..2f2aeff5fd 100644
> --- a/qapi/crypto.json
> +++ b/qapi/crypto.json
> @@ -94,6 +94,8 @@
>   #
>   # @twofish-256: Twofish with 256 bit / 32 byte keys
>   #
> +# @sm4: SM4 with 128 bit / 16 byte keys (since 9.0)
> +#
>   # Since: 2.6
>   ##
>   { 'enum': 'QCryptoCipherAlgorithm',
> @@ -102,7 +104,8 @@
>              'des', '3des',
>              'cast5-128',
>              'serpent-128', 'serpent-192', 'serpent-256',
> -           'twofish-128', 'twofish-192', 'twofish-256']}
> +           'twofish-128', 'twofish-192', 'twofish-256',
> +           'sm4']}
>   
>   ##
>   # @QCryptoCipherMode:
> diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
> index d9d9d078ff..11ab1a54fc 100644
> --- a/tests/unit/test-crypto-cipher.c
> +++ b/tests/unit/test-crypto-cipher.c
> @@ -382,6 +382,19 @@ static QCryptoCipherTestData test_data[] = {
>           .plaintext = "90afe91bb288544f2c32dc239b2635e6",
>           .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
>       },
> +#ifdef CONFIG_CRYPTO_SM4
> +    {
> +        /* SM4, GB/T 32907-2016, Appendix A.1 */
> +        .path = "/crypto/cipher/sm4",
> +        .alg = QCRYPTO_CIPHER_ALG_SM4,
> +        .mode = QCRYPTO_CIPHER_MODE_ECB,
> +        .key = "0123456789abcdeffedcba9876543210",
> +        .plaintext  =
> +            "0123456789abcdeffedcba9876543210",
> +        .ciphertext =
> +            "681edf34d206965e86b3e94f536e4246",
> +    },
> +#endif
>       {
>           /* #1 32 byte key, 32 byte PTX */
>           .path = "/crypto/cipher/aes-xts-128-1",



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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2023-12-07 16:02 ` Philippe Mathieu-Daudé
@ 2023-12-08  2:10   ` Yong Huang
  0 siblings, 0 replies; 8+ messages in thread
From: Yong Huang @ 2023-12-08  2:10 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-devel, Daniel P . Berrangé, Paolo Bonzini,
	Marc-André Lureau, Thomas Huth, Eric Blake,
	Markus Armbruster

[-- Attachment #1: Type: text/plain, Size: 12050 bytes --]

I'll post the changelog between versions in the next version if needed. :)

v6:
- modify the comment about how to enable sm4 crypto feature
v5:
- drop the crypto-sm4 option in build system
v4
- refactor the error report info, change "sm4"->"libsm4"

On Fri, Dec 8, 2023 at 12:02 AM Philippe Mathieu-Daudé <philmd@linaro.org>
wrote:

> Hi Hyman,
>
> On 7/12/23 16:47, Hyman Huang wrote:
> > Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
> >
> > SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> > Organization of State Commercial Administration of China (OSCCA)
> > as an authorized cryptographic algorithms for the use within China.
> >
> > Detect the SM4 cipher algorithms and enable the feature silently
> > if it is available.
> >
> > Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> > Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> > ---
>
> What are the changes since v4/v5?
>
> >   crypto/block-luks.c             | 11 ++++++++
> >   crypto/cipher-gcrypt.c.inc      |  8 ++++++
> >   crypto/cipher-nettle.c.inc      | 49 +++++++++++++++++++++++++++++++++
> >   crypto/cipher.c                 |  6 ++++
> >   meson.build                     | 26 +++++++++++++++++
> >   qapi/crypto.json                |  5 +++-
> >   tests/unit/test-crypto-cipher.c | 13 +++++++++
> >   7 files changed, 117 insertions(+), 1 deletion(-)
> >
> > diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> > index fb01ec38bb..f0813d69b4 100644
> > --- a/crypto/block-luks.c
> > +++ b/crypto/block-luks.c
> > @@ -95,12 +95,23 @@ qcrypto_block_luks_cipher_size_map_twofish[] = {
> >       { 0, 0 },
> >   };
> >
> > +#ifdef CONFIG_CRYPTO_SM4
> > +static const QCryptoBlockLUKSCipherSizeMap
> > +qcrypto_block_luks_cipher_size_map_sm4[] = {
> > +    { 16, QCRYPTO_CIPHER_ALG_SM4},
> > +    { 0, 0 },
> > +};
> > +#endif
> > +
> >   static const QCryptoBlockLUKSCipherNameMap
> >   qcrypto_block_luks_cipher_name_map[] = {
> >       { "aes", qcrypto_block_luks_cipher_size_map_aes },
> >       { "cast5", qcrypto_block_luks_cipher_size_map_cast5 },
> >       { "serpent", qcrypto_block_luks_cipher_size_map_serpent },
> >       { "twofish", qcrypto_block_luks_cipher_size_map_twofish },
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    { "sm4", qcrypto_block_luks_cipher_size_map_sm4},
> > +#endif
> >   };
> >
> >   QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
> > diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
> > index a6a0117717..1377cbaf14 100644
> > --- a/crypto/cipher-gcrypt.c.inc
> > +++ b/crypto/cipher-gcrypt.c.inc
> > @@ -35,6 +35,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm
> alg,
> >       case QCRYPTO_CIPHER_ALG_SERPENT_256:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +#endif
> >           break;
> >       default:
> >           return false;
> > @@ -219,6 +222,11 @@ static QCryptoCipher
> *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> >           gcryalg = GCRY_CIPHER_TWOFISH;
> >           break;
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +        gcryalg = GCRY_CIPHER_SM4;
> > +        break;
> > +#endif
> >       default:
> >           error_setg(errp, "Unsupported cipher algorithm %s",
> >                      QCryptoCipherAlgorithm_str(alg));
> > diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
> > index 24cc61f87b..42b39e18a2 100644
> > --- a/crypto/cipher-nettle.c.inc
> > +++ b/crypto/cipher-nettle.c.inc
> > @@ -33,6 +33,9 @@
> >   #ifndef CONFIG_QEMU_PRIVATE_XTS
> >   #include <nettle/xts.h>
> >   #endif
> > +#ifdef CONFIG_CRYPTO_SM4
> > +#include <nettle/sm4.h>
> > +#endif
> >
> >   static inline bool qcrypto_length_check(size_t len, size_t blocksize,
> >                                           Error **errp)
> > @@ -426,6 +429,30 @@ DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
> >                          QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
> >                          twofish_encrypt_native, twofish_decrypt_native)
> >
> > +#ifdef CONFIG_CRYPTO_SM4
> > +typedef struct QCryptoNettleSm4 {
> > +    QCryptoCipher base;
> > +    struct sm4_ctx key[2];
> > +} QCryptoNettleSm4;
> > +
> > +static void sm4_encrypt_native(void *ctx, size_t length,
> > +                               uint8_t *dst, const uint8_t *src)
> > +{
> > +    struct sm4_ctx *keys = ctx;
> > +    sm4_crypt(&keys[0], length, dst, src);
> > +}
> > +
> > +static void sm4_decrypt_native(void *ctx, size_t length,
> > +                               uint8_t *dst, const uint8_t *src)
> > +{
> > +    struct sm4_ctx *keys = ctx;
> > +    sm4_crypt(&keys[1], length, dst, src);
> > +}
> > +
> > +DEFINE_ECB(qcrypto_nettle_sm4,
> > +           QCryptoNettleSm4, SM4_BLOCK_SIZE,
> > +           sm4_encrypt_native, sm4_decrypt_native)
> > +#endif
> >
> >   bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> >                                QCryptoCipherMode mode)
> > @@ -443,6 +470,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm
> alg,
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_192:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +#endif
> >           break;
> >       default:
> >           return false;
> > @@ -701,6 +731,25 @@ static QCryptoCipher
> *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> >
> >               return &ctx->base;
> >           }
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +        {
> > +            QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
> > +
> > +            switch (mode) {
> > +            case QCRYPTO_CIPHER_MODE_ECB:
> > +                ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
> > +                break;
> > +            default:
> > +                goto bad_cipher_mode;
> > +            }
> > +
> > +            sm4_set_encrypt_key(&ctx->key[0], key);
> > +            sm4_set_decrypt_key(&ctx->key[1], key);
> > +
> > +            return &ctx->base;
> > +        }
> > +#endif
> >
> >       default:
> >           error_setg(errp, "Unsupported cipher algorithm %s",
> > diff --git a/crypto/cipher.c b/crypto/cipher.c
> > index 74b09a5b26..5f512768ea 100644
> > --- a/crypto/cipher.c
> > +++ b/crypto/cipher.c
> > @@ -38,6 +38,9 @@ static const size_t
> alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> > +#endif
> >   };
> >
> >   static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> > @@ -53,6 +56,9 @@ static const size_t
> alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> > +#endif
> >   };
> >
> >   static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
> > diff --git a/meson.build b/meson.build
> > index d2c4c2adb3..52f2f85b5a 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -1480,6 +1480,7 @@ endif
> >   gcrypt = not_found
> >   nettle = not_found
> >   hogweed = not_found
> > +crypto_sm4 = not_found
> >   xts = 'none'
> >
> >   if get_option('nettle').enabled() and get_option('gcrypt').enabled()
> > @@ -1505,6 +1506,17 @@ if not gnutls_crypto.found()
> >            cc.find_library('gpg-error', required: true)],
> >           version: gcrypt.version())
> >       endif
> > +    crypto_sm4 = gcrypt
> > +    # SM4 ALG is available in libgcrypt >= 1.9
> > +    if gcrypt.found() and not cc.links('''
> > +      #include <gcrypt.h>
> > +      int main(void) {
> > +        gcry_cipher_hd_t handler;
> > +        gcry_cipher_open(&handler, GCRY_CIPHER_SM4,
> GCRY_CIPHER_MODE_ECB, 0);
> > +        return 0;
> > +      }''', dependencies: gcrypt)
> > +      crypto_sm4 = not_found
> > +    endif
> >     endif
> >     if (not get_option('nettle').auto() or have_system) and not
> gcrypt.found()
> >       nettle = dependency('nettle', version: '>=3.4',
> > @@ -1513,6 +1525,18 @@ if not gnutls_crypto.found()
> >       if nettle.found() and not cc.has_header('nettle/xts.h',
> dependencies: nettle)
> >         xts = 'private'
> >       endif
> > +    crypto_sm4 = nettle
> > +    # SM4 ALG is available in nettle >= 3.9
> > +    if nettle.found() and not cc.links('''
> > +      #include <nettle/sm4.h>
> > +      int main(void) {
> > +        struct sm4_ctx ctx;
> > +        unsigned char key[16] = {0};
> > +        sm4_set_encrypt_key(&ctx, key);
> > +        return 0;
> > +      }''', dependencies: nettle)
> > +      crypto_sm4 = not_found
> > +    endif
> >     endif
> >   endif
> >
> > @@ -2199,6 +2223,7 @@ config_host_data.set('CONFIG_GNUTLS_CRYPTO',
> gnutls_crypto.found())
> >   config_host_data.set('CONFIG_TASN1', tasn1.found())
> >   config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
> >   config_host_data.set('CONFIG_NETTLE', nettle.found())
> > +config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
> >   config_host_data.set('CONFIG_HOGWEED', hogweed.found())
> >   config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
> >   config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
> > @@ -4274,6 +4299,7 @@ summary_info += {'nettle':            nettle}
> >   if nettle.found()
> >      summary_info += {'  XTS':             xts != 'private'}
> >   endif
> > +summary_info += {'SM4 ALG support':   crypto_sm4}
> >   summary_info += {'AF_ALG support':    have_afalg}
> >   summary_info += {'rng-none':          get_option('rng_none')}
> >   summary_info += {'Linux keyring':     have_keyring}
> > diff --git a/qapi/crypto.json b/qapi/crypto.json
> > index fd3d46ebd1..2f2aeff5fd 100644
> > --- a/qapi/crypto.json
> > +++ b/qapi/crypto.json
> > @@ -94,6 +94,8 @@
> >   #
> >   # @twofish-256: Twofish with 256 bit / 32 byte keys
> >   #
> > +# @sm4: SM4 with 128 bit / 16 byte keys (since 9.0)
> > +#
> >   # Since: 2.6
> >   ##
> >   { 'enum': 'QCryptoCipherAlgorithm',
> > @@ -102,7 +104,8 @@
> >              'des', '3des',
> >              'cast5-128',
> >              'serpent-128', 'serpent-192', 'serpent-256',
> > -           'twofish-128', 'twofish-192', 'twofish-256']}
> > +           'twofish-128', 'twofish-192', 'twofish-256',
> > +           'sm4']}
> >
> >   ##
> >   # @QCryptoCipherMode:
> > diff --git a/tests/unit/test-crypto-cipher.c
> b/tests/unit/test-crypto-cipher.c
> > index d9d9d078ff..11ab1a54fc 100644
> > --- a/tests/unit/test-crypto-cipher.c
> > +++ b/tests/unit/test-crypto-cipher.c
> > @@ -382,6 +382,19 @@ static QCryptoCipherTestData test_data[] = {
> >           .plaintext = "90afe91bb288544f2c32dc239b2635e6",
> >           .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
> >       },
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    {
> > +        /* SM4, GB/T 32907-2016, Appendix A.1 */
> > +        .path = "/crypto/cipher/sm4",
> > +        .alg = QCRYPTO_CIPHER_ALG_SM4,
> > +        .mode = QCRYPTO_CIPHER_MODE_ECB,
> > +        .key = "0123456789abcdeffedcba9876543210",
> > +        .plaintext  =
> > +            "0123456789abcdeffedcba9876543210",
> > +        .ciphertext =
> > +            "681edf34d206965e86b3e94f536e4246",
> > +    },
> > +#endif
> >       {
> >           /* #1 32 byte key, 32 byte PTX */
> >           .path = "/crypto/cipher/aes-xts-128-1",
>
>
Thanks,
Yong

-- 
Best regards

[-- Attachment #2: Type: text/html, Size: 16508 bytes --]

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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2023-12-07 15:47 [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm Hyman Huang
  2023-12-07 16:02 ` Philippe Mathieu-Daudé
@ 2023-12-08  9:33 ` Daniel P. Berrangé
  2024-03-08 20:30 ` Thomas Huth
  2 siblings, 0 replies; 8+ messages in thread
From: Daniel P. Berrangé @ 2023-12-08  9:33 UTC (permalink / raw)
  To: Hyman Huang
  Cc: qemu-devel, Paolo Bonzini, Marc-André Lureau, Thomas Huth,
	Philippe Mathieu-Daudé, Eric Blake, Markus Armbruster

On Thu, Dec 07, 2023 at 11:47:35PM +0800, Hyman Huang wrote:
> Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
> 
> SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> Organization of State Commercial Administration of China (OSCCA)
> as an authorized cryptographic algorithms for the use within China.
> 
> Detect the SM4 cipher algorithms and enable the feature silently
> if it is available.
> 
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>  crypto/block-luks.c             | 11 ++++++++
>  crypto/cipher-gcrypt.c.inc      |  8 ++++++
>  crypto/cipher-nettle.c.inc      | 49 +++++++++++++++++++++++++++++++++
>  crypto/cipher.c                 |  6 ++++
>  meson.build                     | 26 +++++++++++++++++
>  qapi/crypto.json                |  5 +++-
>  tests/unit/test-crypto-cipher.c | 13 +++++++++
>  7 files changed, 117 insertions(+), 1 deletion(-)

Ok, queued this version instead of v5.


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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2023-12-07 15:47 [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm Hyman Huang
  2023-12-07 16:02 ` Philippe Mathieu-Daudé
  2023-12-08  9:33 ` Daniel P. Berrangé
@ 2024-03-08 20:30 ` Thomas Huth
  2024-03-11  9:32   ` Daniel P. Berrangé
  2 siblings, 1 reply; 8+ messages in thread
From: Thomas Huth @ 2024-03-08 20:30 UTC (permalink / raw)
  To: Hyman Huang, qemu-devel, Daniel P . Berrangé
  Cc: Paolo Bonzini, Marc-André Lureau,
	Philippe Mathieu-Daudé, Eric Blake, Markus Armbruster

On 07/12/2023 16.47, Hyman Huang wrote:
> Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
> 
> SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> Organization of State Commercial Administration of China (OSCCA)
> as an authorized cryptographic algorithms for the use within China.
> 
> Detect the SM4 cipher algorithms and enable the feature silently
> if it is available.
> 
> Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---

FYI, starting with this commit, tests/unit/test-crypto-cipher is now failing 
on s390x hosts (i.e. big endian machines)... could be that there is maybe an 
endianess issue somewhere in here...

  Thomas



> diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> index fb01ec38bb..f0813d69b4 100644
> --- a/crypto/block-luks.c
> +++ b/crypto/block-luks.c
> @@ -95,12 +95,23 @@ qcrypto_block_luks_cipher_size_map_twofish[] = {
>       { 0, 0 },
>   };
>   
> +#ifdef CONFIG_CRYPTO_SM4
> +static const QCryptoBlockLUKSCipherSizeMap
> +qcrypto_block_luks_cipher_size_map_sm4[] = {
> +    { 16, QCRYPTO_CIPHER_ALG_SM4},
> +    { 0, 0 },
> +};
> +#endif
> +
>   static const QCryptoBlockLUKSCipherNameMap
>   qcrypto_block_luks_cipher_name_map[] = {
>       { "aes", qcrypto_block_luks_cipher_size_map_aes },
>       { "cast5", qcrypto_block_luks_cipher_size_map_cast5 },
>       { "serpent", qcrypto_block_luks_cipher_size_map_serpent },
>       { "twofish", qcrypto_block_luks_cipher_size_map_twofish },
> +#ifdef CONFIG_CRYPTO_SM4
> +    { "sm4", qcrypto_block_luks_cipher_size_map_sm4},
> +#endif
>   };
>   
>   QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
> diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
> index a6a0117717..1377cbaf14 100644
> --- a/crypto/cipher-gcrypt.c.inc
> +++ b/crypto/cipher-gcrypt.c.inc
> @@ -35,6 +35,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
>       case QCRYPTO_CIPHER_ALG_SERPENT_256:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +#endif
>           break;
>       default:
>           return false;
> @@ -219,6 +222,11 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
>       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
>           gcryalg = GCRY_CIPHER_TWOFISH;
>           break;
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +        gcryalg = GCRY_CIPHER_SM4;
> +        break;
> +#endif
>       default:
>           error_setg(errp, "Unsupported cipher algorithm %s",
>                      QCryptoCipherAlgorithm_str(alg));
> diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
> index 24cc61f87b..42b39e18a2 100644
> --- a/crypto/cipher-nettle.c.inc
> +++ b/crypto/cipher-nettle.c.inc
> @@ -33,6 +33,9 @@
>   #ifndef CONFIG_QEMU_PRIVATE_XTS
>   #include <nettle/xts.h>
>   #endif
> +#ifdef CONFIG_CRYPTO_SM4
> +#include <nettle/sm4.h>
> +#endif
>   
>   static inline bool qcrypto_length_check(size_t len, size_t blocksize,
>                                           Error **errp)
> @@ -426,6 +429,30 @@ DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
>                          QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
>                          twofish_encrypt_native, twofish_decrypt_native)
>   
> +#ifdef CONFIG_CRYPTO_SM4
> +typedef struct QCryptoNettleSm4 {
> +    QCryptoCipher base;
> +    struct sm4_ctx key[2];
> +} QCryptoNettleSm4;
> +
> +static void sm4_encrypt_native(void *ctx, size_t length,
> +                               uint8_t *dst, const uint8_t *src)
> +{
> +    struct sm4_ctx *keys = ctx;
> +    sm4_crypt(&keys[0], length, dst, src);
> +}
> +
> +static void sm4_decrypt_native(void *ctx, size_t length,
> +                               uint8_t *dst, const uint8_t *src)
> +{
> +    struct sm4_ctx *keys = ctx;
> +    sm4_crypt(&keys[1], length, dst, src);
> +}
> +
> +DEFINE_ECB(qcrypto_nettle_sm4,
> +           QCryptoNettleSm4, SM4_BLOCK_SIZE,
> +           sm4_encrypt_native, sm4_decrypt_native)
> +#endif
>   
>   bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
>                                QCryptoCipherMode mode)
> @@ -443,6 +470,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
>       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_192:
>       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +#endif
>           break;
>       default:
>           return false;
> @@ -701,6 +731,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
>   
>               return &ctx->base;
>           }
> +#ifdef CONFIG_CRYPTO_SM4
> +    case QCRYPTO_CIPHER_ALG_SM4:
> +        {
> +            QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
> +
> +            switch (mode) {
> +            case QCRYPTO_CIPHER_MODE_ECB:
> +                ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
> +                break;
> +            default:
> +                goto bad_cipher_mode;
> +            }
> +
> +            sm4_set_encrypt_key(&ctx->key[0], key);
> +            sm4_set_decrypt_key(&ctx->key[1], key);
> +
> +            return &ctx->base;
> +        }
> +#endif
>   
>       default:
>           error_setg(errp, "Unsupported cipher algorithm %s",
> diff --git a/crypto/cipher.c b/crypto/cipher.c
> index 74b09a5b26..5f512768ea 100644
> --- a/crypto/cipher.c
> +++ b/crypto/cipher.c
> @@ -38,6 +38,9 @@ static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
>       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
> +#ifdef CONFIG_CRYPTO_SM4
> +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> +#endif
>   };
>   
>   static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> @@ -53,6 +56,9 @@ static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
>       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16,
>       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
> +#ifdef CONFIG_CRYPTO_SM4
> +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> +#endif
>   };
>   
>   static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
> diff --git a/meson.build b/meson.build
> index d2c4c2adb3..52f2f85b5a 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1480,6 +1480,7 @@ endif
>   gcrypt = not_found
>   nettle = not_found
>   hogweed = not_found
> +crypto_sm4 = not_found
>   xts = 'none'
>   
>   if get_option('nettle').enabled() and get_option('gcrypt').enabled()
> @@ -1505,6 +1506,17 @@ if not gnutls_crypto.found()
>            cc.find_library('gpg-error', required: true)],
>           version: gcrypt.version())
>       endif
> +    crypto_sm4 = gcrypt
> +    # SM4 ALG is available in libgcrypt >= 1.9
> +    if gcrypt.found() and not cc.links('''
> +      #include <gcrypt.h>
> +      int main(void) {
> +        gcry_cipher_hd_t handler;
> +        gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
> +        return 0;
> +      }''', dependencies: gcrypt)
> +      crypto_sm4 = not_found
> +    endif
>     endif
>     if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
>       nettle = dependency('nettle', version: '>=3.4',
> @@ -1513,6 +1525,18 @@ if not gnutls_crypto.found()
>       if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
>         xts = 'private'
>       endif
> +    crypto_sm4 = nettle
> +    # SM4 ALG is available in nettle >= 3.9
> +    if nettle.found() and not cc.links('''
> +      #include <nettle/sm4.h>
> +      int main(void) {
> +        struct sm4_ctx ctx;
> +        unsigned char key[16] = {0};
> +        sm4_set_encrypt_key(&ctx, key);
> +        return 0;
> +      }''', dependencies: nettle)
> +      crypto_sm4 = not_found
> +    endif
>     endif
>   endif
>   
> @@ -2199,6 +2223,7 @@ config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
>   config_host_data.set('CONFIG_TASN1', tasn1.found())
>   config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
>   config_host_data.set('CONFIG_NETTLE', nettle.found())
> +config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
>   config_host_data.set('CONFIG_HOGWEED', hogweed.found())
>   config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
>   config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
> @@ -4274,6 +4299,7 @@ summary_info += {'nettle':            nettle}
>   if nettle.found()
>      summary_info += {'  XTS':             xts != 'private'}
>   endif
> +summary_info += {'SM4 ALG support':   crypto_sm4}
>   summary_info += {'AF_ALG support':    have_afalg}
>   summary_info += {'rng-none':          get_option('rng_none')}
>   summary_info += {'Linux keyring':     have_keyring}
> diff --git a/qapi/crypto.json b/qapi/crypto.json
> index fd3d46ebd1..2f2aeff5fd 100644
> --- a/qapi/crypto.json
> +++ b/qapi/crypto.json
> @@ -94,6 +94,8 @@
>   #
>   # @twofish-256: Twofish with 256 bit / 32 byte keys
>   #
> +# @sm4: SM4 with 128 bit / 16 byte keys (since 9.0)
> +#
>   # Since: 2.6
>   ##
>   { 'enum': 'QCryptoCipherAlgorithm',
> @@ -102,7 +104,8 @@
>              'des', '3des',
>              'cast5-128',
>              'serpent-128', 'serpent-192', 'serpent-256',
> -           'twofish-128', 'twofish-192', 'twofish-256']}
> +           'twofish-128', 'twofish-192', 'twofish-256',
> +           'sm4']}
>   
>   ##
>   # @QCryptoCipherMode:
> diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
> index d9d9d078ff..11ab1a54fc 100644
> --- a/tests/unit/test-crypto-cipher.c
> +++ b/tests/unit/test-crypto-cipher.c
> @@ -382,6 +382,19 @@ static QCryptoCipherTestData test_data[] = {
>           .plaintext = "90afe91bb288544f2c32dc239b2635e6",
>           .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
>       },
> +#ifdef CONFIG_CRYPTO_SM4
> +    {
> +        /* SM4, GB/T 32907-2016, Appendix A.1 */
> +        .path = "/crypto/cipher/sm4",
> +        .alg = QCRYPTO_CIPHER_ALG_SM4,
> +        .mode = QCRYPTO_CIPHER_MODE_ECB,
> +        .key = "0123456789abcdeffedcba9876543210",
> +        .plaintext  =
> +            "0123456789abcdeffedcba9876543210",
> +        .ciphertext =
> +            "681edf34d206965e86b3e94f536e4246",
> +    },
> +#endif
>       {
>           /* #1 32 byte key, 32 byte PTX */
>           .path = "/crypto/cipher/aes-xts-128-1",



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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2024-03-08 20:30 ` Thomas Huth
@ 2024-03-11  9:32   ` Daniel P. Berrangé
  2024-03-11 10:14     ` Daniel P. Berrangé
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel P. Berrangé @ 2024-03-11  9:32 UTC (permalink / raw)
  To: Thomas Huth
  Cc: Hyman Huang, qemu-devel, Paolo Bonzini, Marc-André Lureau,
	Philippe Mathieu-Daudé, Eric Blake, Markus Armbruster

On Fri, Mar 08, 2024 at 09:30:52PM +0100, Thomas Huth wrote:
> On 07/12/2023 16.47, Hyman Huang wrote:
> > Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
> > 
> > SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> > Organization of State Commercial Administration of China (OSCCA)
> > as an authorized cryptographic algorithms for the use within China.
> > 
> > Detect the SM4 cipher algorithms and enable the feature silently
> > if it is available.
> > 
> > Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> > Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> > ---
> 
> FYI, starting with this commit, tests/unit/test-crypto-cipher is now failing
> on s390x hosts (i.e. big endian machines)... could be that there is maybe an
> endianess issue somewhere in here...

Or more worringly the issue could be in nettle's impl of SM4, as
I'm not seeing an obvious place in this QEMU glue layer which
could cause endianness mistakes.

> 
>  Thomas
> 
> 
> 
> > diff --git a/crypto/block-luks.c b/crypto/block-luks.c
> > index fb01ec38bb..f0813d69b4 100644
> > --- a/crypto/block-luks.c
> > +++ b/crypto/block-luks.c
> > @@ -95,12 +95,23 @@ qcrypto_block_luks_cipher_size_map_twofish[] = {
> >       { 0, 0 },
> >   };
> > +#ifdef CONFIG_CRYPTO_SM4
> > +static const QCryptoBlockLUKSCipherSizeMap
> > +qcrypto_block_luks_cipher_size_map_sm4[] = {
> > +    { 16, QCRYPTO_CIPHER_ALG_SM4},
> > +    { 0, 0 },
> > +};
> > +#endif
> > +
> >   static const QCryptoBlockLUKSCipherNameMap
> >   qcrypto_block_luks_cipher_name_map[] = {
> >       { "aes", qcrypto_block_luks_cipher_size_map_aes },
> >       { "cast5", qcrypto_block_luks_cipher_size_map_cast5 },
> >       { "serpent", qcrypto_block_luks_cipher_size_map_serpent },
> >       { "twofish", qcrypto_block_luks_cipher_size_map_twofish },
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    { "sm4", qcrypto_block_luks_cipher_size_map_sm4},
> > +#endif
> >   };
> >   QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48);
> > diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
> > index a6a0117717..1377cbaf14 100644
> > --- a/crypto/cipher-gcrypt.c.inc
> > +++ b/crypto/cipher-gcrypt.c.inc
> > @@ -35,6 +35,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> >       case QCRYPTO_CIPHER_ALG_SERPENT_256:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +#endif
> >           break;
> >       default:
> >           return false;
> > @@ -219,6 +222,11 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> >           gcryalg = GCRY_CIPHER_TWOFISH;
> >           break;
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +        gcryalg = GCRY_CIPHER_SM4;
> > +        break;
> > +#endif
> >       default:
> >           error_setg(errp, "Unsupported cipher algorithm %s",
> >                      QCryptoCipherAlgorithm_str(alg));
> > diff --git a/crypto/cipher-nettle.c.inc b/crypto/cipher-nettle.c.inc
> > index 24cc61f87b..42b39e18a2 100644
> > --- a/crypto/cipher-nettle.c.inc
> > +++ b/crypto/cipher-nettle.c.inc
> > @@ -33,6 +33,9 @@
> >   #ifndef CONFIG_QEMU_PRIVATE_XTS
> >   #include <nettle/xts.h>
> >   #endif
> > +#ifdef CONFIG_CRYPTO_SM4
> > +#include <nettle/sm4.h>
> > +#endif
> >   static inline bool qcrypto_length_check(size_t len, size_t blocksize,
> >                                           Error **errp)
> > @@ -426,6 +429,30 @@ DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
> >                          QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
> >                          twofish_encrypt_native, twofish_decrypt_native)
> > +#ifdef CONFIG_CRYPTO_SM4
> > +typedef struct QCryptoNettleSm4 {
> > +    QCryptoCipher base;
> > +    struct sm4_ctx key[2];
> > +} QCryptoNettleSm4;
> > +
> > +static void sm4_encrypt_native(void *ctx, size_t length,
> > +                               uint8_t *dst, const uint8_t *src)
> > +{
> > +    struct sm4_ctx *keys = ctx;
> > +    sm4_crypt(&keys[0], length, dst, src);
> > +}
> > +
> > +static void sm4_decrypt_native(void *ctx, size_t length,
> > +                               uint8_t *dst, const uint8_t *src)
> > +{
> > +    struct sm4_ctx *keys = ctx;
> > +    sm4_crypt(&keys[1], length, dst, src);
> > +}
> > +
> > +DEFINE_ECB(qcrypto_nettle_sm4,
> > +           QCryptoNettleSm4, SM4_BLOCK_SIZE,
> > +           sm4_encrypt_native, sm4_decrypt_native)
> > +#endif
> >   bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> >                                QCryptoCipherMode mode)
> > @@ -443,6 +470,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_128:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_192:
> >       case QCRYPTO_CIPHER_ALG_TWOFISH_256:
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +#endif
> >           break;
> >       default:
> >           return false;
> > @@ -701,6 +731,25 @@ static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> >               return &ctx->base;
> >           }
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    case QCRYPTO_CIPHER_ALG_SM4:
> > +        {
> > +            QCryptoNettleSm4 *ctx = g_new0(QCryptoNettleSm4, 1);
> > +
> > +            switch (mode) {
> > +            case QCRYPTO_CIPHER_MODE_ECB:
> > +                ctx->base.driver = &qcrypto_nettle_sm4_driver_ecb;
> > +                break;
> > +            default:
> > +                goto bad_cipher_mode;
> > +            }
> > +
> > +            sm4_set_encrypt_key(&ctx->key[0], key);
> > +            sm4_set_decrypt_key(&ctx->key[1], key);
> > +
> > +            return &ctx->base;
> > +        }
> > +#endif
> >       default:
> >           error_setg(errp, "Unsupported cipher algorithm %s",
> > diff --git a/crypto/cipher.c b/crypto/cipher.c
> > index 74b09a5b26..5f512768ea 100644
> > --- a/crypto/cipher.c
> > +++ b/crypto/cipher.c
> > @@ -38,6 +38,9 @@ static const size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32,
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> > +#endif
> >   };
> >   static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> > @@ -53,6 +56,9 @@ static const size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16,
> >       [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16,
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    [QCRYPTO_CIPHER_ALG_SM4] = 16,
> > +#endif
> >   };
> >   static const bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = {
> > diff --git a/meson.build b/meson.build
> > index d2c4c2adb3..52f2f85b5a 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -1480,6 +1480,7 @@ endif
> >   gcrypt = not_found
> >   nettle = not_found
> >   hogweed = not_found
> > +crypto_sm4 = not_found
> >   xts = 'none'
> >   if get_option('nettle').enabled() and get_option('gcrypt').enabled()
> > @@ -1505,6 +1506,17 @@ if not gnutls_crypto.found()
> >            cc.find_library('gpg-error', required: true)],
> >           version: gcrypt.version())
> >       endif
> > +    crypto_sm4 = gcrypt
> > +    # SM4 ALG is available in libgcrypt >= 1.9
> > +    if gcrypt.found() and not cc.links('''
> > +      #include <gcrypt.h>
> > +      int main(void) {
> > +        gcry_cipher_hd_t handler;
> > +        gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
> > +        return 0;
> > +      }''', dependencies: gcrypt)
> > +      crypto_sm4 = not_found
> > +    endif
> >     endif
> >     if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
> >       nettle = dependency('nettle', version: '>=3.4',
> > @@ -1513,6 +1525,18 @@ if not gnutls_crypto.found()
> >       if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
> >         xts = 'private'
> >       endif
> > +    crypto_sm4 = nettle
> > +    # SM4 ALG is available in nettle >= 3.9
> > +    if nettle.found() and not cc.links('''
> > +      #include <nettle/sm4.h>
> > +      int main(void) {
> > +        struct sm4_ctx ctx;
> > +        unsigned char key[16] = {0};
> > +        sm4_set_encrypt_key(&ctx, key);
> > +        return 0;
> > +      }''', dependencies: nettle)
> > +      crypto_sm4 = not_found
> > +    endif
> >     endif
> >   endif
> > @@ -2199,6 +2223,7 @@ config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
> >   config_host_data.set('CONFIG_TASN1', tasn1.found())
> >   config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
> >   config_host_data.set('CONFIG_NETTLE', nettle.found())
> > +config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
> >   config_host_data.set('CONFIG_HOGWEED', hogweed.found())
> >   config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
> >   config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
> > @@ -4274,6 +4299,7 @@ summary_info += {'nettle':            nettle}
> >   if nettle.found()
> >      summary_info += {'  XTS':             xts != 'private'}
> >   endif
> > +summary_info += {'SM4 ALG support':   crypto_sm4}
> >   summary_info += {'AF_ALG support':    have_afalg}
> >   summary_info += {'rng-none':          get_option('rng_none')}
> >   summary_info += {'Linux keyring':     have_keyring}
> > diff --git a/qapi/crypto.json b/qapi/crypto.json
> > index fd3d46ebd1..2f2aeff5fd 100644
> > --- a/qapi/crypto.json
> > +++ b/qapi/crypto.json
> > @@ -94,6 +94,8 @@
> >   #
> >   # @twofish-256: Twofish with 256 bit / 32 byte keys
> >   #
> > +# @sm4: SM4 with 128 bit / 16 byte keys (since 9.0)
> > +#
> >   # Since: 2.6
> >   ##
> >   { 'enum': 'QCryptoCipherAlgorithm',
> > @@ -102,7 +104,8 @@
> >              'des', '3des',
> >              'cast5-128',
> >              'serpent-128', 'serpent-192', 'serpent-256',
> > -           'twofish-128', 'twofish-192', 'twofish-256']}
> > +           'twofish-128', 'twofish-192', 'twofish-256',
> > +           'sm4']}
> >   ##
> >   # @QCryptoCipherMode:
> > diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
> > index d9d9d078ff..11ab1a54fc 100644
> > --- a/tests/unit/test-crypto-cipher.c
> > +++ b/tests/unit/test-crypto-cipher.c
> > @@ -382,6 +382,19 @@ static QCryptoCipherTestData test_data[] = {
> >           .plaintext = "90afe91bb288544f2c32dc239b2635e6",
> >           .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
> >       },
> > +#ifdef CONFIG_CRYPTO_SM4
> > +    {
> > +        /* SM4, GB/T 32907-2016, Appendix A.1 */
> > +        .path = "/crypto/cipher/sm4",
> > +        .alg = QCRYPTO_CIPHER_ALG_SM4,
> > +        .mode = QCRYPTO_CIPHER_MODE_ECB,
> > +        .key = "0123456789abcdeffedcba9876543210",
> > +        .plaintext  =
> > +            "0123456789abcdeffedcba9876543210",
> > +        .ciphertext =
> > +            "681edf34d206965e86b3e94f536e4246",
> > +    },
> > +#endif
> >       {
> >           /* #1 32 byte key, 32 byte PTX */
> >           .path = "/crypto/cipher/aes-xts-128-1",
> 

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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2024-03-11  9:32   ` Daniel P. Berrangé
@ 2024-03-11 10:14     ` Daniel P. Berrangé
  2024-03-11 12:00       ` Thomas Huth
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel P. Berrangé @ 2024-03-11 10:14 UTC (permalink / raw)
  To: Thomas Huth, Hyman Huang, qemu-devel, Paolo Bonzini,
	Marc-André Lureau, Philippe Mathieu-Daudé, Eric Blake,
	Markus Armbruster

On Mon, Mar 11, 2024 at 09:32:32AM +0000, Daniel P. Berrangé wrote:
> On Fri, Mar 08, 2024 at 09:30:52PM +0100, Thomas Huth wrote:
> > On 07/12/2023 16.47, Hyman Huang wrote:
> > > Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
> > > 
> > > SM4 (GBT.32907-2016) is a cryptographic standard issued by the
> > > Organization of State Commercial Administration of China (OSCCA)
> > > as an authorized cryptographic algorithms for the use within China.
> > > 
> > > Detect the SM4 cipher algorithms and enable the feature silently
> > > if it is available.
> > > 
> > > Signed-off-by: Hyman Huang <yong.huang@smartx.com>
> > > Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> > > ---
> > 
> > FYI, starting with this commit, tests/unit/test-crypto-cipher is now failing
> > on s390x hosts (i.e. big endian machines)... could be that there is maybe an
> > endianess issue somewhere in here...
> 
> Or more worringly the issue could be in nettle's impl of SM4, as
> I'm not seeing an obvious place in this QEMU glue layer which
> could cause endianness mistakes.

This is not a s390x problem in fact, it happens on all arches.

For unknown reasons RHEL has disabled build of the SM4 cipher
algorithm in libgcrypt.

If building QEMU with nettle you won't see the problem, as the
nettle in RHEL is too old currently.

If building QEMU with gnutls you won't see the issue as gnutls
doesn't support SM4 cipher at all.

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

* Re: [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm
  2024-03-11 10:14     ` Daniel P. Berrangé
@ 2024-03-11 12:00       ` Thomas Huth
  0 siblings, 0 replies; 8+ messages in thread
From: Thomas Huth @ 2024-03-11 12:00 UTC (permalink / raw)
  To: Daniel P. Berrangé, Hyman Huang, qemu-devel, Paolo Bonzini,
	Marc-André Lureau, Philippe Mathieu-Daudé, Eric Blake,
	Markus Armbruster

On 11/03/2024 11.14, Daniel P. Berrangé wrote:
> On Mon, Mar 11, 2024 at 09:32:32AM +0000, Daniel P. Berrangé wrote:
>> On Fri, Mar 08, 2024 at 09:30:52PM +0100, Thomas Huth wrote:
>>> On 07/12/2023 16.47, Hyman Huang wrote:
>>>> Introduce the SM4 cipher algorithms (OSCCA GB/T 32907-2016).
>>>>
>>>> SM4 (GBT.32907-2016) is a cryptographic standard issued by the
>>>> Organization of State Commercial Administration of China (OSCCA)
>>>> as an authorized cryptographic algorithms for the use within China.
>>>>
>>>> Detect the SM4 cipher algorithms and enable the feature silently
>>>> if it is available.
>>>>
>>>> Signed-off-by: Hyman Huang <yong.huang@smartx.com>
>>>> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>>>> ---
>>>
>>> FYI, starting with this commit, tests/unit/test-crypto-cipher is now failing
>>> on s390x hosts (i.e. big endian machines)... could be that there is maybe an
>>> endianess issue somewhere in here...
>>
>> Or more worringly the issue could be in nettle's impl of SM4, as
>> I'm not seeing an obvious place in this QEMU glue layer which
>> could cause endianness mistakes.
> 
> This is not a s390x problem in fact, it happens on all arches.

Agreed, I can reproduce it on x86 on RHEL as well, so it's indeed a problem 
with the libgcrypt there.

I guess we need a test in "configure" to make sure that SM4 is really available?

  Thomas




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

end of thread, other threads:[~2024-03-11 12:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-07 15:47 [PATCH v6] crypto: Introduce SM4 symmetric cipher algorithm Hyman Huang
2023-12-07 16:02 ` Philippe Mathieu-Daudé
2023-12-08  2:10   ` Yong Huang
2023-12-08  9:33 ` Daniel P. Berrangé
2024-03-08 20:30 ` Thomas Huth
2024-03-11  9:32   ` Daniel P. Berrangé
2024-03-11 10:14     ` Daniel P. Berrangé
2024-03-11 12:00       ` Thomas Huth

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