qemu/crypto-Introduce-SM3-hash-hmac-pbkdf-algorithm.patch

404 lines
13 KiB
Diff
Raw Normal View History

QEMU update to version 8.2.0-18: - hw/loongarch/virt: Fix FDT memory node address width - hw/loongarch: Fix fdt memory node wrong 'reg' - load_elf: fix iterator's type for elf file processing - migration/colo: Fix bdrv_graph_rdlock_main_loop: Assertion `!qemu_in_… - target/i386: no single-step exception after MOV or POP SS - char-stdio: Restore blocking mode of stdout on exit - backends/cryptodev-builtin: Fix local_error leaks - target/loongarch: fix a wrong print in cpu dump - virtio-pci: fix use of a released vector - target/arm: Disable SVE extensions when SVE is disabled - hw/misc/bcm2835_property: Fix handling of FRAMEBUFFER_SET_PALETTE - target/i386: Introduce SapphireRapids-v3 to add missing features - virtio-net: Ensure queue index fits with RSS (CVE-2024-6505) - nbd/server: CVE-2024-7409: Avoid use-after-free when closing server - update io/trace-events. Parameters should remain consistent. - update docs/tools/virtfs-proxy-helper.rst. This place is spelled wrong. - kvm: Add support for CSV2 reboot - target/i386/kvm: Fix the resettable info when emulate Hygon CSV2 guest - target/i386: get/set/migrate GHCB state - target/i386: csv: Add support for migrate VMSA for CSV2 guest - migration/ram: Accelerate the loading of CSV guest's encrypted pages - migration/ram: Accelerate the transmission of CSV guest's encrypted pages - target/i386: csv: add support to load incoming encrypted pages queued in the CMD list - target/i386: csv: add support to queue the incoming page into a list - target/i386: csv: add support to encrypt the outgoing pages in the list queued before. - target/i386: csv: add support to queue the outgoing page into a list - target/i386: csv: Read cert chain from file when prepared for CSV live migration - target/i386: Introduce header file csv.h - migration/ram: Fix calculation of gfn correpond to a page in ramblock - target/i386: sev: Clear shared_regions_list when reboot CSV Guest - migration/ram: Force encrypted status for VGA vram - target/i386: sev: Return 0 if sev_send_get_packet_len() fails - kvm: Add support for userspace MSR filtering and handling of MSR_KVM_MIGRATION_CONTROL. - migration/ram: Force encrypted status for flash0 & flash1 devices. - migration/ram: add support to send encrypted pages - migration: add support to migrate shared regions list - kvm: Add support for SEV shared regions list and KVM_EXIT_HYPERCALL. - target/i386: sev: add support to load incoming encrypted page - target/i386: sev: add support to encrypt the outgoing page - target/i386: sev: do not create launch context for an incoming guest - target/i386: sev: provide callback to setup outgoing context - confidential guest support: introduce ConfidentialGuestMemoryEncryptionOps for encrypted VMs - migration.json: add AMD SEV specific migration parameters - doc: update AMD SEV to include Live migration flow - crypto/tlscredspsk: Free username on finalize - hw/nvme: fix leak of uninitialized memory in io_mgmt_recv - hw/display/vhost-user-gpu.c: fix vhost_user_gpu_chr_read() - cvm : Implement command blacklist for cvm security enhancement - crypto: Introduce SM3 hash hmac pbkdf algorithm - virtio-net: Use virtual time for RSC timers - vvfat: Fix bug in writing to middle of file - hw/core/ptimer: fix timer zero period condition for freq > 1GHz - hw/misc: support vpsp Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
2024-09-18 15:20:53 +08:00
From 7b7742e137fbf9283cbbfb823fcf2ebe14df3154 Mon Sep 17 00:00:00 2001
From: gaochuanji <gaochuanji@inspur.com>
Date: Mon, 19 Aug 2024 10:52:49 +0800
Subject: [PATCH] crypto: Introduce SM3 hash hmac pbkdf algorithm
Introduce the SM3 cryptographic hash algorithm (GB/T 32905-2016).
SM3 (GB/T 32905-2016) is a cryptographic standard issued by the
Organization of State Commercial Cryptography Administration (OSCCA)
as an authorized cryptographic algorithm for use within China.
Detect the SM3 cryptographic hash algorithm and enable the feature silently
if it is available.
Signed-off-by: cheliequan <cheliequan@inspur.com>
---
crypto/hash-gcrypt.c | 3 +++
crypto/hash-nettle.c | 14 ++++++++++++
crypto/hash.c | 3 +++
crypto/hmac-gcrypt.c | 3 +++
crypto/hmac-nettle.c | 11 ++++++++++
crypto/pbkdf-gcrypt.c | 6 ++++++
crypto/pbkdf-nettle.c | 13 ++++++++++++
meson.build | 39 ++++++++++++++++++++++++++++++++++
qapi/crypto.json | 4 +++-
tests/unit/test-crypto-hash.c | 16 ++++++++++++++
tests/unit/test-crypto-hmac.c | 8 +++++++
tests/unit/test-crypto-pbkdf.c | 16 ++++++++++++++
12 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c
index 829e48258d..d3bdfe5633 100644
--- a/crypto/hash-gcrypt.c
+++ b/crypto/hash-gcrypt.c
@@ -33,6 +33,9 @@ static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = {
[QCRYPTO_HASH_ALG_SHA384] = GCRY_MD_SHA384,
[QCRYPTO_HASH_ALG_SHA512] = GCRY_MD_SHA512,
[QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MD_RMD160,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = GCRY_MD_SM3,
+#endif
};
gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
index 1ca1a41062..0c2f8ce86c 100644
--- a/crypto/hash-nettle.c
+++ b/crypto/hash-nettle.c
@@ -25,6 +25,9 @@
#include <nettle/md5.h>
#include <nettle/sha.h>
#include <nettle/ripemd160.h>
+#ifdef CONFIG_CRYPTO_SM3
+#include <nettle/sm3.h>
+#endif
typedef void (*qcrypto_nettle_init)(void *ctx);
typedef void (*qcrypto_nettle_write)(void *ctx,
@@ -42,6 +45,9 @@ union qcrypto_hash_ctx {
struct sha384_ctx sha384;
struct sha512_ctx sha512;
struct ripemd160_ctx ripemd160;
+#ifdef CONFIG_CRYPTO_SM3
+ struct sm3_ctx sm3;
+#endif
};
struct qcrypto_hash_alg {
@@ -92,6 +98,14 @@ struct qcrypto_hash_alg {
.result = (qcrypto_nettle_result)ripemd160_digest,
.len = RIPEMD160_DIGEST_SIZE,
},
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = {
+ .init = (qcrypto_nettle_init)sm3_init,
+ .write = (qcrypto_nettle_write)sm3_update,
+ .result = (qcrypto_nettle_result)sm3_digest,
+ .len = SM3_DIGEST_SIZE,
+ },
+#endif
};
gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg)
diff --git a/crypto/hash.c b/crypto/hash.c
index b0f8228bdc..8f1502ce68 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -30,6 +30,9 @@ static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = {
[QCRYPTO_HASH_ALG_SHA384] = 48,
[QCRYPTO_HASH_ALG_SHA512] = 64,
[QCRYPTO_HASH_ALG_RIPEMD160] = 20,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = 32,
+#endif
};
size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg)
diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c
index 0c6f979711..888afb86ed 100644
--- a/crypto/hmac-gcrypt.c
+++ b/crypto/hmac-gcrypt.c
@@ -26,6 +26,9 @@ static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = {
[QCRYPTO_HASH_ALG_SHA384] = GCRY_MAC_HMAC_SHA384,
[QCRYPTO_HASH_ALG_SHA512] = GCRY_MAC_HMAC_SHA512,
[QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MAC_HMAC_RMD160,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = GCRY_MAC_HMAC_SM3,
+#endif
};
typedef struct QCryptoHmacGcrypt QCryptoHmacGcrypt;
diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c
index 1ad6c4f253..e51e3319ab 100644
--- a/crypto/hmac-nettle.c
+++ b/crypto/hmac-nettle.c
@@ -38,6 +38,9 @@ struct QCryptoHmacNettle {
struct hmac_sha256_ctx sha256_ctx; /* equals hmac_sha224_ctx */
struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */
struct hmac_ripemd160_ctx ripemd160_ctx;
+#ifdef CONFIG_CRYPTO_SM3
+ struct hmac_sm3_ctx ctx;
+#endif
} u;
};
@@ -89,6 +92,14 @@ struct qcrypto_nettle_hmac_alg {
.digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest,
.len = RIPEMD160_DIGEST_SIZE,
},
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = {
+ .setkey = (qcrypto_nettle_hmac_setkey)hmac_sm3_set_key,
+ .update = (qcrypto_nettle_hmac_update)hmac_sm3_update,
+ .digest = (qcrypto_nettle_hmac_digest)hmac_sm3_digest,
+ .len = SM3_DIGEST_SIZE,
+ },
+#endif
};
bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg)
diff --git a/crypto/pbkdf-gcrypt.c b/crypto/pbkdf-gcrypt.c
index a8d8e64f4d..09b38d0d6e 100644
--- a/crypto/pbkdf-gcrypt.c
+++ b/crypto/pbkdf-gcrypt.c
@@ -33,6 +33,9 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
case QCRYPTO_HASH_ALG_SHA384:
case QCRYPTO_HASH_ALG_SHA512:
case QCRYPTO_HASH_ALG_RIPEMD160:
+#ifdef CONFIG_CRYPTO_SM3
+ case QCRYPTO_HASH_ALG_SM3:
+#endif
return true;
default:
return false;
@@ -54,6 +57,9 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
[QCRYPTO_HASH_ALG_SHA384] = GCRY_MD_SHA384,
[QCRYPTO_HASH_ALG_SHA512] = GCRY_MD_SHA512,
[QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MD_RMD160,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = GCRY_MD_SM3,
+#endif
};
int ret;
diff --git a/crypto/pbkdf-nettle.c b/crypto/pbkdf-nettle.c
index d6293c25a1..5fea570bd3 100644
--- a/crypto/pbkdf-nettle.c
+++ b/crypto/pbkdf-nettle.c
@@ -34,6 +34,9 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
case QCRYPTO_HASH_ALG_SHA384:
case QCRYPTO_HASH_ALG_SHA512:
case QCRYPTO_HASH_ALG_RIPEMD160:
+#ifdef CONFIG_CRYPTO_SM3
+ case QCRYPTO_HASH_ALG_SM3:
+#endif
return true;
default:
return false;
@@ -55,6 +58,9 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
struct hmac_sha384_ctx sha384;
struct hmac_sha512_ctx sha512;
struct hmac_ripemd160_ctx ripemd160;
+#ifdef CONFIG_CRYPTO_SM3
+ struct hmac_sm3_ctx sm3;
+#endif
} ctx;
if (iterations > UINT_MAX) {
@@ -106,6 +112,13 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
PBKDF2(&ctx.ripemd160, hmac_ripemd160_update, hmac_ripemd160_digest,
RIPEMD160_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
break;
+#ifdef CONFIG_CRYPTO_SM3
+ case QCRYPTO_HASH_ALG_SM3:
+ hmac_sm3_set_key(&ctx.sm3, nkey, key);
+ PBKDF2(&ctx.sm3, hmac_sm3_update, hmac_sm3_digest,
+ SM3_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
+ break;
+#endif
default:
error_setg_errno(errp, ENOSYS,
diff --git a/meson.build b/meson.build
index 089f45d386..4024f9a4bb 100644
--- a/meson.build
+++ b/meson.build
@@ -1486,6 +1486,7 @@ gcrypt = not_found
nettle = not_found
hogweed = not_found
crypto_sm4 = not_found
+crypto_sm3 = not_found
xts = 'none'
if get_option('nettle').enabled() and get_option('gcrypt').enabled()
@@ -1522,6 +1523,17 @@ if not gnutls_crypto.found()
}''', dependencies: gcrypt)
crypto_sm4 = not_found
endif
+ crypto_sm3 = gcrypt
+ # SM3 ALG is available in libgcrypt >= 1.8
+ if gcrypt.found() and not cc.links('''
+ #include <gcrypt.h>
+ int main(void) {
+ gcry_md_hd_t handler;
+ gcry_md_open(&handler, GCRY_MD_SM3, 0);
+ return 0;
+ }''', dependencies: gcrypt)
+ crypto_sm3 = not_found
+ endif
endif
if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
nettle = dependency('nettle', version: '>=3.4',
@@ -1542,6 +1554,31 @@ if not gnutls_crypto.found()
}''', dependencies: nettle)
crypto_sm4 = not_found
endif
+ crypto_sm3 = nettle
+ # SM3 ALG is available in nettle >= 3.4
+ if nettle.found() and not cc.links('''
+ #include <nettle/sm3.h>
+ #include <nettle/hmac.h>
+ int main(void) {
+ struct sm3_ctx ctx;
+ struct hmac_sm3_ctx hmac_ctx;
+ unsigned char data[64] = {0};
+ unsigned char output[32];
+
+ // SM3 hash function test
+ sm3_init(&ctx);
+ sm3_update(&ctx, 64, data);
+ sm3_digest(&ctx, 32, data);
+
+ // HMAC-SM3 test
+ hmac_sm3_set_key(&hmac_ctx, 32, data);
+ hmac_sm3_update(&hmac_ctx, 64, data);
+ hmac_sm3_digest(&hmac_ctx, 32, output);
+
+ return 0;
+ }''', dependencies: nettle)
+ crypto_sm3 = not_found
+ endif
endif
endif
@@ -2229,6 +2266,7 @@ 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_CRYPTO_SM3', crypto_sm3.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 +4344,7 @@ if nettle.found()
summary_info += {' XTS': xts != 'private'}
endif
summary_info += {'SM4 ALG support': crypto_sm4}
+summary_info += {'SM3 ALG support': crypto_sm3}
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 2f2aeff5fd..af38f0a4bd 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -58,11 +58,13 @@
#
# @ripemd160: RIPEMD-160. (since 2.7)
#
+# @sm3: SM3. (since 8.2.0)
+#
# Since: 2.6
##
{ 'enum': 'QCryptoHashAlgorithm',
'prefix': 'QCRYPTO_HASH_ALG',
- 'data': ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'ripemd160']}
+ 'data': ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'ripemd160', 'sm3']}
##
# @QCryptoCipherAlgorithm:
diff --git a/tests/unit/test-crypto-hash.c b/tests/unit/test-crypto-hash.c
index 1f4abb822b..61908e1769 100644
--- a/tests/unit/test-crypto-hash.c
+++ b/tests/unit/test-crypto-hash.c
@@ -42,6 +42,9 @@
"63b54e4cb2d2032b393994aa263c0dbb" \
"e00a9f2fe9ef6037352232a1eec55ee7"
#define OUTPUT_RIPEMD160 "f3d658fad3fdfb2b52c9369cf0d441249ddfa8a0"
+#ifdef CONFIG_CRYPTO_SM3
+#define OUTPUT_SM3 "d4a97db105b477b84c4f20ec9c31a6c814e2705a0b83a5a89748d75f0ef456a1"
+#endif
#define OUTPUT_MD5_B64 "Yo0gY3FWMDWrjvYvSSveyQ=="
#define OUTPUT_SHA1_B64 "sudPJnWKOkIeUJzuBFJEt4dTzAI="
@@ -54,6 +57,10 @@
"7sVe5w=="
#define OUTPUT_RIPEMD160_B64 "89ZY+tP9+ytSyTac8NRBJJ3fqKA="
+#ifdef CONFIG_CRYPTO_SM3
+#define OUTPUT_SM3_B64 "1Kl9sQW0d7hMTyDsnDGmyBTicFoLg6Wol0jXXw70VqE="
+#endif
+
static const char *expected_outputs[] = {
[QCRYPTO_HASH_ALG_MD5] = OUTPUT_MD5,
[QCRYPTO_HASH_ALG_SHA1] = OUTPUT_SHA1,
@@ -62,6 +69,9 @@ static const char *expected_outputs[] = {
[QCRYPTO_HASH_ALG_SHA384] = OUTPUT_SHA384,
[QCRYPTO_HASH_ALG_SHA512] = OUTPUT_SHA512,
[QCRYPTO_HASH_ALG_RIPEMD160] = OUTPUT_RIPEMD160,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = OUTPUT_SM3,
+#endif
};
static const char *expected_outputs_b64[] = {
[QCRYPTO_HASH_ALG_MD5] = OUTPUT_MD5_B64,
@@ -71,6 +81,9 @@ static const char *expected_outputs_b64[] = {
[QCRYPTO_HASH_ALG_SHA384] = OUTPUT_SHA384_B64,
[QCRYPTO_HASH_ALG_SHA512] = OUTPUT_SHA512_B64,
[QCRYPTO_HASH_ALG_RIPEMD160] = OUTPUT_RIPEMD160_B64,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = OUTPUT_SM3_B64,
+#endif
};
static const int expected_lens[] = {
[QCRYPTO_HASH_ALG_MD5] = 16,
@@ -80,6 +93,9 @@ static const int expected_lens[] = {
[QCRYPTO_HASH_ALG_SHA384] = 48,
[QCRYPTO_HASH_ALG_SHA512] = 64,
[QCRYPTO_HASH_ALG_RIPEMD160] = 20,
+#ifdef CONFIG_CRYPTO_SM3
+ [QCRYPTO_HASH_ALG_SM3] = 32,
+#endif
};
static const char hex[] = "0123456789abcdef";
diff --git a/tests/unit/test-crypto-hmac.c b/tests/unit/test-crypto-hmac.c
index 23eb724d94..b1d04e9fcc 100644
--- a/tests/unit/test-crypto-hmac.c
+++ b/tests/unit/test-crypto-hmac.c
@@ -76,6 +76,14 @@ static QCryptoHmacTestData test_data[] = {
"94964ed4c1155b62b668c241d67279e5"
"8a711676",
},
+#ifdef CONFIG_CRYPTO_SM3
+ {
+ .alg = QCRYPTO_HASH_ALG_SM3,
+ .hex_digest =
+ "760e3799332bc913819b930085360ddb"
+ "c05529261313d5b15b75bab4fd7ae91e",
+ },
+#endif
};
static const char hex[] = "0123456789abcdef";
diff --git a/tests/unit/test-crypto-pbkdf.c b/tests/unit/test-crypto-pbkdf.c
index 43c417f6b4..3d76593c86 100644
--- a/tests/unit/test-crypto-pbkdf.c
+++ b/tests/unit/test-crypto-pbkdf.c
@@ -326,6 +326,22 @@ static QCryptoPbkdfTestData test_data[] = {
"\xce\xbf\x91\x14\x8b\x5c\x48\x41",
.nout = 32
},
+#ifdef CONFIG_CRYPTO_SM3
+ {
+ .path = "/crypto/pbkdf/nonrfc/sm3/iter2",
+ .hash = QCRYPTO_HASH_ALG_SM3,
+ .iterations = 2,
+ .key = "password",
+ .nkey = 8,
+ .salt = "ATHENA.MIT.EDUraeburn",
+ .nsalt = 21,
+ .out = "\x48\x71\x1b\x58\xa3\xcb\xce\x06"
+ "\xba\xad\x77\xa8\xb5\xb9\xd8\x07"
+ "\x6a\xe2\xb3\x5b\x95\xce\xc8\xce"
+ "\xe7\xb1\xcb\xee\x61\xdf\x04\xea",
+ .nout = 32
+ },
+#endif
#if 0
{
.path = "/crypto/pbkdf/nonrfc/whirlpool/iter1200",
--
2.41.0.windows.1