Re: [PATCH v3] crypto: Introduce SM4 symmetric cipher algorithm
On Thu, Dec 7, 2023 at 1:41 AM Daniel P. Berrangé wrote: > On Wed, Nov 29, 2023 at 11:17:49PM +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. > > > > Use the crypto-sm4 meson build option to explicitly control the > > feature, which would be detected by default. > > > > Signed-off-by: Hyman Huang > > --- > > crypto/block-luks.c | 11 > > crypto/cipher-gcrypt.c.inc | 8 ++ > > crypto/cipher-nettle.c.inc | 49 + > > crypto/cipher.c | 6 > > meson.build | 42 > > meson_options.txt | 2 ++ > > qapi/crypto.json| 5 +++- > > scripts/meson-buildoptions.sh | 3 ++ > > tests/unit/test-crypto-cipher.c | 13 + > > 9 files changed, 138 insertions(+), 1 deletion(-) > > > > > diff --git a/meson.build b/meson.build > > index ec01f8b138..765f9c9f50 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,28 @@ 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 > > + 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 > > + if get_option('crypto_sm4').enabled() > > +error('could not link sm4') > > + else > > +warning('could not link sm4, disabling') > > + endif > > IMHO we don't need to have an option for 'crypto_sm4', just > silently disable it if not present in the host provideed > library. OK, I don't insist on that and I'll drop the option in the next version. > > > +endif > > +if crypto_sm4.found() and get_option('prefer_static') > > + crypto_sm4 = declare_dependency(dependencies: [ > > +gcrypt, > > +cc.find_library('gpg-error', required: true)], > > +version: gcrypt.version()) > > +endif > > This last if/endif block is redundant. We already have earlier > logic that detects gpg-error, and we never use the 'crypto_sm4' > object after this point anyway > > >endif > >if (not get_option('nettle').auto() or have_system) and not > gcrypt.found() > > nettle = dependency('nettle', version: '>=3.4', > > @@ -1513,6 +1536,23 @@ 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 > > + 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 > > + if get_option('crypto_sm4').enabled() > > +error('could not link sm4') > > + else > > +warning('could not link sm4, disabling') > > + endif > > Likewise no need for an option, just silently disable it. > > > +endif > >endif > > endif > > > > @@ -2199,6 +2239,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) > > @@ -4273,6 +4314,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/meson_options.txt b/meson_options.txt > > index c9baeda639..db8de4ec5b 100644 > > --- a/meson_options.txt > > +++ b/meson_options.txt > > @@ -172,6 +172,8 @@ optio
Re: [PATCH v3] crypto: Introduce SM4 symmetric cipher algorithm
On Wed, Nov 29, 2023 at 11:17:49PM +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. > > Use the crypto-sm4 meson build option to explicitly control the > feature, which would be detected by default. > > Signed-off-by: Hyman Huang > --- > crypto/block-luks.c | 11 > crypto/cipher-gcrypt.c.inc | 8 ++ > crypto/cipher-nettle.c.inc | 49 + > crypto/cipher.c | 6 > meson.build | 42 > meson_options.txt | 2 ++ > qapi/crypto.json| 5 +++- > scripts/meson-buildoptions.sh | 3 ++ > tests/unit/test-crypto-cipher.c | 13 + > 9 files changed, 138 insertions(+), 1 deletion(-) > > diff --git a/meson.build b/meson.build > index ec01f8b138..765f9c9f50 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,28 @@ 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 > + 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 > + if get_option('crypto_sm4').enabled() > +error('could not link sm4') > + else > +warning('could not link sm4, disabling') > + endif IMHO we don't need to have an option for 'crypto_sm4', just silently disable it if not present in the host provideed library. > +endif > +if crypto_sm4.found() and get_option('prefer_static') > + crypto_sm4 = declare_dependency(dependencies: [ > +gcrypt, > +cc.find_library('gpg-error', required: true)], > +version: gcrypt.version()) > +endif This last if/endif block is redundant. We already have earlier logic that detects gpg-error, and we never use the 'crypto_sm4' object after this point anyway >endif >if (not get_option('nettle').auto() or have_system) and not gcrypt.found() > nettle = dependency('nettle', version: '>=3.4', > @@ -1513,6 +1536,23 @@ 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 > + 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 > + if get_option('crypto_sm4').enabled() > +error('could not link sm4') > + else > +warning('could not link sm4, disabling') > + endif Likewise no need for an option, just silently disable it. > +endif >endif > endif > > @@ -2199,6 +2239,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) > @@ -4273,6 +4314,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/meson_options.txt b/meson_options.txt > index c9baeda639..db8de4ec5b 100644 > --- a/meson_options.txt > +++ b/meson_options.txt > @@ -172,6 +172,8 @@ option('nettle', type : 'feature', value : 'auto', > description: 'nettle cryptography support') > option('gcrypt', type : 'feature', value : 'auto', > description: 'libgcrypt cryptography support') > +option('crypto_sm4', type : 'feature', value : 'auto', > + description: 'SM4 symmetric cipher algorithm support') Drop this. > option('crypto_afa
Re: [PATCH v3] crypto: Introduce SM4 symmetric cipher algorithm
On 29/11/23 16:17, 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. Use the crypto-sm4 meson build option to explicitly control the feature, which would be detected by default. Signed-off-by: Hyman Huang --- crypto/block-luks.c | 11 crypto/cipher-gcrypt.c.inc | 8 ++ crypto/cipher-nettle.c.inc | 49 + crypto/cipher.c | 6 meson.build | 42 meson_options.txt | 2 ++ qapi/crypto.json| 5 +++- scripts/meson-buildoptions.sh | 3 ++ tests/unit/test-crypto-cipher.c | 13 + 9 files changed, 138 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index ec01f8b138..765f9c9f50 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,28 @@ 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 + 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 + if get_option('crypto_sm4').enabled() +error('could not link sm4') 'could not link libsm4'? Up to the maintainer. + else +warning('could not link sm4, disabling') + endif +endif +if crypto_sm4.found() and get_option('prefer_static') + crypto_sm4 = declare_dependency(dependencies: [ +gcrypt, +cc.find_library('gpg-error', required: true)], +version: gcrypt.version()) +endif endif if (not get_option('nettle').auto() or have_system) and not gcrypt.found() nettle = dependency('nettle', version: '>=3.4', @@ -1513,6 +1536,23 @@ 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 + 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 + if get_option('crypto_sm4').enabled() +error('could not link sm4') Ditto, otherwise: Reviewed-by: Philippe Mathieu-Daudé + else +warning('could not link sm4, disabling') + endif +endif endif endif
[PATCH v3] crypto: Introduce SM4 symmetric cipher algorithm
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. Use the crypto-sm4 meson build option to explicitly control the feature, which would be detected by default. Signed-off-by: Hyman Huang --- crypto/block-luks.c | 11 crypto/cipher-gcrypt.c.inc | 8 ++ crypto/cipher-nettle.c.inc | 49 + crypto/cipher.c | 6 meson.build | 42 meson_options.txt | 2 ++ qapi/crypto.json| 5 +++- scripts/meson-buildoptions.sh | 3 ++ tests/unit/test-crypto-cipher.c | 13 + 9 files changed, 138 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 #endif +#ifdef CONFIG_CRYPTO_SM4 +#include +#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; +