mirror of https://github.com/xemu-project/xemu.git
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. 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> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
fdd51403a3
commit
52ed9f455e
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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] = {
|
||||
|
|
26
meson.build
26
meson.build
|
@ -1633,6 +1633,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()
|
||||
|
@ -1658,6 +1659,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',
|
||||
|
@ -1666,6 +1678,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
|
||||
|
||||
|
@ -2267,6 +2291,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)
|
||||
|
@ -4306,6 +4331,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}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue