diff --git a/Hygon-Add-support-for-udev-to-create-tcm-de.patch b/Hygon-Add-support-for-udev-to-create-tcm-de.patch new file mode 100644 index 0000000000000000000000000000000000000000..58e045ca43266066622e33530b9761a992a49b22 --- /dev/null +++ b/Hygon-Add-support-for-udev-to-create-tcm-de.patch @@ -0,0 +1,22 @@ +From 61a3e15944eff1acb7f17528ea71d30db09405b5 Mon Sep 17 00:00:00 2001 +From: chench +Date: Fri, 5 Jul 2024 16:25:08 +0800 +Subject: [PATCH] [newfeature][tcm] Add support for udev to create tcm devices + +Change-Id: I15958fd5864a7688655d8b2933280237c63c4e86 +--- + dist/tpm-udev.rules | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/dist/tpm-udev.rules b/dist/tpm-udev.rules +index d7745b4..fde36bb 100644 +--- a/dist/tpm-udev.rules ++++ b/dist/tpm-udev.rules +@@ -2,3 +2,5 @@ + # group members can access tpmrm devices + KERNEL=="tpm[0-9]*", TAG+="systemd", MODE="0660", OWNER="tss" + KERNEL=="tpmrm[0-9]*", TAG+="systemd", MODE="0660", GROUP="tss" ++KERNEL=="tcm[0-9]*", TAG+="systemd", MODE="0660", OWNER="tss" ++KERNEL=="tcmrm[0-9]*", TAG+="systemd", MODE="0660", GROUP="tss" +-- +2.17.1 diff --git a/add-bootstrap-file-from-upstream.patch b/add-bootstrap-file-from-upstream.patch new file mode 100644 index 0000000000000000000000000000000000000000..be863999a770233734b14108a15854639d7aaedd --- /dev/null +++ b/add-bootstrap-file-from-upstream.patch @@ -0,0 +1,113 @@ +From ba537356b598515ede5d18952117a7f5d183549a Mon Sep 17 00:00:00 2001 +From: chench +Date: Fri, 29 Dec 2023 12:07:37 +0800 +Subject: [PATCH] add bootstrap file + +--- + bootstrap | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 95 insertions(+) + create mode 100755 bootstrap + +diff --git a/bootstrap b/bootstrap +new file mode 100755 +index 0000000..c25c9a3 +--- /dev/null ++++ b/bootstrap +@@ -0,0 +1,95 @@ ++#!/bin/sh ++set -e ++ ++#git describe --tags --always --dirty > VERSION ++ ++# generate list of source files for use in Makefile.am ++# if you add new source files, you must run ./bootstrap again ++src_listvar () { ++ basedir=$1 ++ suffix=$2 ++ var=$3 ++ ++ find "${basedir}" -name "${suffix}" | LC_ALL=C sort | tr '\n' ' ' | (printf "${var} = " && cat) ++ echo "" ++} ++ ++# remove source files from list if their usage depends on a configure option ++remove_src () { ++ files=$1 ++ shift ++ for x in $* ++ do ++ x=$(echo "$x" | sed 's/\//\\\//g') ++ files=$(echo $files | sed -e "s/$x//") ++ done ++ echo $files ++} ++ ++# generate list of eys source files for use in Makefile.am ++# if you add new source files, you must run ./bootstrap again ++# files after the var name will be elimenated from list list ++src_esys_listvar () { ++ basedir=$1; ++ shift; ++ suffix=$1 ++ shift; ++ var=$1 ++ shift; ++ ++ files=$(find "${basedir}" -name "${suffix}" | LC_ALL=C sort | tr '\n' ' ') ++ files=$(remove_src "${files}" $*) ++ printf "${var} = ${files}" ++ echo "" ++} ++ ++VARS_FILE=src_vars.mk ++AUTORECONF=${AUTORECONF:-autoreconf} ++ ++echo "Generating file lists: ${VARS_FILE}" ++( ++ src_listvar "src/util" "*.c" "UTIL_C" ++ src_listvar "src/util" "*.h" "UTIL_H" ++ printf "UTIL_SRC = \$(UTIL_C) \$(UTIL_H)\n" ++ ++ src_listvar "src/tss2-sys/" "*.c" "TSS2_SYS_C" ++ src_listvar "src/tss2-sys/" "*.h" "TSS2_SYS_H" ++ printf "TSS2_SYS_SRC = \$(TSS2_SYS_H) \$(TSS2_SYS_C)\n" ++ ++ src_esys_listvar "src/tss2-esys/" "*.h" "TSS2_ESYS_H" src/tss2-esys/esys_crypto_ossl.h src/tss2-esys/esys_crypto_mbed.h ++ src_esys_listvar "src/tss2-esys/" "*.c" "TSS2_ESYS_C" src/tss2-esys/esys_crypto_ossl.c src/tss2-esys/esys_crypto_mbed.c ++ printf "TSS2_ESYS_SRC = \$(TSS2_ESYS_H) \$(TSS2_ESYS_C)\n" ++ ++ src_listvar "src/tss2-fapi/" "*.h" "TSS2_FAPI_H" ++ src_listvar "src/tss2-fapi/" "*.c" "TSS2_FAPI_C" ++ printf "TSS2_FAPI_SRC = \$(TSS2_FAPI_H) \$(TSS2_FAPI_C)\n" ++ ++ src_listvar "src/tss2-mu" "*.c" "TSS2_MU_C" ++ src_listvar "src/tss2-mu" "*.h" "TSS2_MU_H" ++ printf "TSS2_MU_SRC = \$(TSS2_MU_C) \$(TSS2_MU_H)\n" ++ ++ src_listvar "src/tss2-rc" "*.c" "TSS2_RC_C" ++ src_listvar "src/tss2-rc" "*.h" "TSS2_RC_H" ++ printf "TSS2_RC_SRC = \$(TSS2_RC_C) \$(TSS2_RC_H)\n" ++ ++ src_listvar "src/tss2-policy" "*.c" "TSS2_POLICY_C" ++ src_listvar "src/tss2-policy" "*.h" "TSS2_POLICY_H" ++ printf "TSS2_POLICY_SRC = \$(TSS2_POLICY_C) \$(TSS2_POLICY_H)" ++) > ${VARS_FILE} ++ ++# Do not generate fuzz tests unless environment variable GEN_FUZZ is set to 1 ++rm -rf Makefile-fuzz-generated.am ++if test "${GEN_FUZZ}0" -eq 10; then ++ echo "Generating fuzz tests" ++ script/gen_fuzz.py ++else ++ touch Makefile-fuzz-generated.am ++fi ++ ++${AUTORECONF} --install --sym $@ ++ ++if grep "Invalid policy. Valid policies: git-directory, minor-version." configure >/dev/null; then ++ echo "ERROR: ax_is_release.m4 is outdated. ./configure will fail." ++ echo "Please download from http://ftpmirror.gnu.org/autoconf-archive/autoconf-archive-2019.01.06.tar.xz" ++ exit 1 ++fi +-- +2.27.0 diff --git a/backport-esys-add-SM4-algorithm-support.patch b/backport-esys-add-SM4-algorithm-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..17952830f227e7b9f56d3754e11447b52f8aca25 --- /dev/null +++ b/backport-esys-add-SM4-algorithm-support.patch @@ -0,0 +1,688 @@ +From 0288dda4cec03e39a89f48333702a9301fb1ce80 Mon Sep 17 00:00:00 2001 +From: mayuanchen <94815698+mayuanchenma@users.noreply.github.com> +Date: Fri, 25 Nov 2022 18:59:26 +0800 +Subject: [PATCH] esys: add SM4 algorithm support. + +commit 75e68b77b5c2ddce424ae41f859616b4e8d2b240 upstream. + +Signed-off-by: mayuanchen <94815698+mayuanchenma@users.noreply.github.com> +Change-Id: I63f61888b92dcf06fb921aec08b40ca00c40ecdf +--- + configure.ac | 3 + + include/tss2/tss2_esys.h | 54 ++++++++++ + src/tss2-esys/esys_crypto.c | 53 ++++++++++ + src/tss2-esys/esys_crypto.h | 23 +++++ + src/tss2-esys/esys_crypto_mbed.h | 2 + + src/tss2-esys/esys_crypto_ossl.c | 158 +++++++++++++++++++++++++++++ + src/tss2-esys/esys_crypto_ossl.h | 29 ++++++ + src/tss2-esys/esys_iutil.c | 66 +++++++++++- + test/integration/esys-crypto.int.c | 6 ++ + test/unit/esys-crypto.c | 62 +++++++++++ + 10 files changed, 454 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b655027..f6c254a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -191,6 +191,9 @@ AS_IF([test "x$enable_esys" = xyes], + AC_CHECK_LIB(crypto,[EVP_sm3], [ + AC_DEFINE([HAVE_EVP_SM3], [1], [Support EVP_sm3 in openssl])], + []) ++ AC_CHECK_LIB(crypto, [EVP_sm4_cfb128], [ ++ AC_DEFINE([HAVE_EVP_SM4_CFB], [1], [Support EVP_sm4_cfb in openssl])], ++ []) + TSS2_ESYS_CFLAGS_CRYPTO="$CRYPTO_CFLAGS" + TSS2_ESYS_LDFLAGS_CRYPTO="$CRYPTO_LIBS" + ], [test "x$with_crypto" = xmbed], [ +diff --git a/include/tss2/tss2_esys.h b/include/tss2/tss2_esys.h +index 6ef910e..6641f8d 100644 +--- a/include/tss2/tss2_esys.h ++++ b/include/tss2/tss2_esys.h +@@ -315,6 +315,58 @@ typedef TSS2_RC + uint8_t *iv, + void *userdata); + ++/** Encrypt data with SM4. ++ * ++ * @param[in] key key used for SM4. ++ * @param[in] tpm_sym_alg SM4 type in TSS2 notation (must be TPM2_ALG_SM4). ++ * @param[in] key_bits Key size in bits. ++ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB). ++ * For parameter encryption only CFB can be used. ++ * @param[in,out] buffer Data to be encrypted. The encrypted date will be stored ++ * in this buffer. ++ * @param[in] buffer_size size of data to be encrypted. ++ * @param[in] iv The initialization vector. ++ * @param[in/out] userdata information. ++ * @retval TSS2_RC_SUCCESS on success ++ * @retval USER_DEFINED user defined errors on failure. ++ */ ++typedef TSS2_RC ++ (*ESYS_CRYPTO_SM4_ENCRYPT_FNP)( ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *buffer, ++ size_t buffer_size, ++ uint8_t *iv, ++ void *userdata); ++ ++/** Decrypt data with SM4. ++ * ++ * @param[in] key key used for SM4. ++ * @param[in] tpm_sym_alg SM4 type in TSS2 notation (must be TPM2_ALG_SM4). ++ * @param[in] key_bits Key size in bits. ++ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB). ++ * For parameter encryption only CFB can be used. ++ * @param[in,out] buffer Data to be decrypted. The decrypted date will be stored ++ * in this buffer. ++ * @param[in] buffer_size size of data to be encrypted. ++ * @param[in] iv The initialization vector. ++ * @param[in/out] userdata information. ++ * @retval TSS2_RC_SUCCESS on success ++ * @retval USER_DEFINED user defined errors on failure. ++ */ ++typedef TSS2_RC ++ (*ESYS_CRYPTO_SM4_DECRYPT_FNP)( ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *buffer, ++ size_t buffer_size, ++ uint8_t *iv, ++ void *userdata); ++ + /** Encryption of a buffer using a public (RSA) key. + * + * Encrypting a buffer using a public key is used for example during +@@ -367,6 +419,8 @@ struct ESYS_CRYPTO_CALLBACKS { + ESYS_CRYPTO_GET_ECDH_POINT_FNP get_ecdh_point; + ESYS_CRYPTO_AES_ENCRYPT_FNP aes_encrypt; + ESYS_CRYPTO_AES_DECRYPT_FNP aes_decrypt; ++ ESYS_CRYPTO_SM4_ENCRYPT_FNP sm4_encrypt; ++ ESYS_CRYPTO_SM4_DECRYPT_FNP sm4_decrypt; + ESYS_CRYPTO_INIT_FNP init; + void *userdata; + }; +diff --git a/src/tss2-esys/esys_crypto.c b/src/tss2-esys/esys_crypto.c +index e54c95c..8cfc97a 100644 +--- a/src/tss2-esys/esys_crypto.c ++++ b/src/tss2-esys/esys_crypto.c +@@ -280,6 +280,46 @@ TSS2_RC iesys_crypto_aes_decrypt( + iv); + } + ++TSS2_RC iesys_crypto_sm4_encrypt( ++ ESYS_CRYPTO_CALLBACKS *crypto_cb, ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *buffer, ++ size_t buffer_size, ++ uint8_t *iv) ++{ ++ DO_CALLBACK(sm4_encrypt, ++ key, ++ tpm_sym_alg, ++ key_bits, ++ tpm_mode, ++ buffer, ++ buffer_size, ++ iv); ++} ++ ++TSS2_RC iesys_crypto_sm4_decrypt( ++ ESYS_CRYPTO_CALLBACKS *crypto_cb, ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *buffer, ++ size_t buffer_size, ++ uint8_t *iv) ++{ ++ DO_CALLBACK(sm4_decrypt, ++ key, ++ tpm_sym_alg, ++ key_bits, ++ tpm_mode, ++ buffer, ++ buffer_size, ++ iv); ++} ++ + /** Compute the command or response parameter hash. + * + * These hashes are needed for the computation of the HMAC used for the +@@ -782,6 +822,8 @@ TSS2_RC + crypto_cb->userdata = NULL; + crypto_cb->aes_decrypt = _iesys_crypto_aes_decrypt; + crypto_cb->aes_encrypt = _iesys_crypto_aes_encrypt; ++ crypto_cb->sm4_decrypt = _iesys_crypto_sm4_decrypt; ++ crypto_cb->sm4_encrypt = _iesys_crypto_sm4_encrypt; + crypto_cb->get_ecdh_point = _iesys_crypto_get_ecdh_point; + crypto_cb->hash_abort = _iesys_crypto_hash_abort; + crypto_cb->hash_finish = _iesys_crypto_hash_finish; +@@ -799,6 +841,17 @@ TSS2_RC + + TEST_AND_SET_CALLBACK(crypto_cb, user_cb, aes_decrypt); + TEST_AND_SET_CALLBACK(crypto_cb, user_cb, aes_encrypt); ++ // sm4 is optional ++ if (user_cb->sm4_encrypt) { ++ crypto_cb->sm4_encrypt = user_cb->sm4_encrypt; ++ } else { ++ crypto_cb->sm4_encrypt = _iesys_crypto_sm4_encrypt; ++ } ++ if (user_cb->sm4_decrypt) { ++ crypto_cb->sm4_decrypt = user_cb->sm4_decrypt; ++ } else { ++ crypto_cb->sm4_decrypt = _iesys_crypto_sm4_decrypt; ++ } + TEST_AND_SET_CALLBACK(crypto_cb, user_cb, get_ecdh_point); + TEST_AND_SET_CALLBACK(crypto_cb, user_cb, get_random2b); + TEST_AND_SET_CALLBACK(crypto_cb, user_cb, rsa_pk_encrypt); +diff --git a/src/tss2-esys/esys_crypto.h b/src/tss2-esys/esys_crypto.h +index 8798bc6..c6efac1 100644 +--- a/src/tss2-esys/esys_crypto.h ++++ b/src/tss2-esys/esys_crypto.h +@@ -16,6 +16,8 @@ + #else + #define _iesys_crypto_aes_decrypt NULL; + #define _iesys_crypto_aes_encrypt NULL; ++#define _iesys_crypto_sm4_decrypt NULL; ++#define _iesys_crypto_sm4_encrypt NULL; + #define _iesys_crypto_get_ecdh_point NULL; + #define _iesys_crypto_hash_abort NULL; + #define _iesys_crypto_hash_finish NULL; +@@ -35,6 +37,7 @@ extern "C" { + #endif + + #define AES_BLOCK_SIZE_IN_BYTES 16 ++#define SM4_BLOCK_SIZE_IN_BYTES 16 + + TSS2_RC iesys_crypto_hash_get_digest_size(TPM2_ALG_ID hashAlg, size_t *size); + +@@ -163,6 +166,26 @@ TSS2_RC iesys_crypto_aes_decrypt( + size_t buffer_size, + uint8_t *iv); + ++TSS2_RC iesys_crypto_sm4_encrypt( ++ ESYS_CRYPTO_CALLBACKS *crypto_cb, ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *buffer, ++ size_t buffer_size, ++ uint8_t *iv); ++ ++TSS2_RC iesys_crypto_sm4_decrypt( ++ ESYS_CRYPTO_CALLBACKS *crypto_cb, ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *buffer, ++ size_t buffer_size, ++ uint8_t *iv); ++ + TSS2_RC iesys_crypto_authHmac( + ESYS_CRYPTO_CALLBACKS *crypto_cb, + TPM2_ALG_ID alg, +diff --git a/src/tss2-esys/esys_crypto_mbed.h b/src/tss2-esys/esys_crypto_mbed.h +index 24b1d8e..40a976b 100644 +--- a/src/tss2-esys/esys_crypto_mbed.h ++++ b/src/tss2-esys/esys_crypto_mbed.h +@@ -120,6 +120,8 @@ TSS2_RC iesys_cryptmbed_init(void *userdata); + #define _iesys_crypto_get_ecdh_point iesys_cryptmbed_get_ecdh_point + #define _iesys_crypto_aes_encrypt iesys_cryptmbed_sym_aes_encrypt + #define _iesys_crypto_aes_decrypt iesys_cryptmbed_sym_aes_decrypt ++#define _iesys_crypto_sm4_encrypt NULL ++#define _iesys_crypto_sm4_decrypt NULL + + #define _iesys_crypto_init iesys_cryptmbed_init + +diff --git a/src/tss2-esys/esys_crypto_ossl.c b/src/tss2-esys/esys_crypto_ossl.c +index 89d312f..a92ecc4 100644 +--- a/src/tss2-esys/esys_crypto_ossl.c ++++ b/src/tss2-esys/esys_crypto_ossl.c +@@ -1212,6 +1212,164 @@ iesys_cryptossl_sym_aes_decrypt(uint8_t * key, + return r; + } + ++#if HAVE_EVP_SM4_CFB && !defined(OPENSSL_NO_SM4) ++/** Encrypt data with SM4. ++ * ++ * @param[in] key key used for SM4. ++ * @param[in] tpm_sym_alg SM4 type in TSS2 notation (must be TPM2_ALG_SM4). ++ * @param[in] key_bits Key size in bits. ++ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB). ++ * For parameter encryption only CFB can be used. ++ * @param[in,out] buffer Data to be encrypted. The encrypted date will be stored ++ * in this buffer. ++ * @param[in] buffer_size size of data to be encrypted. ++ * @param[in] iv The initialization vector. ++ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and ++ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters, ++ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. ++ */ ++TSS2_RC ++iesys_cryptossl_sym_sm4_encrypt(uint8_t * key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t * buffer, ++ size_t buffer_size, ++ uint8_t * iv, ++ void *userdata) ++{ ++ UNUSED(userdata); ++ ++ TSS2_RC r = TSS2_RC_SUCCESS; ++ const EVP_CIPHER *cipher_alg = NULL; ++ EVP_CIPHER_CTX *ctx = NULL; ++ int cipher_len; ++ ++ if (key == NULL || buffer == NULL) { ++ return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Bad reference"); ++ } ++ ++ LOGBLOB_TRACE(buffer, buffer_size, "IESYS SM4 input"); ++ ++ if (key_bits == 128 && tpm_mode == TPM2_ALG_CFB) ++ cipher_alg = EVP_sm4_cfb128(); ++ else { ++ goto_error(r, TSS2_ESYS_RC_BAD_VALUE, ++ "SM4 algorithm not implemented or illegal mode (CFB expected).", ++ cleanup); ++ } ++ ++ if (tpm_sym_alg != TPM2_ALG_SM4) { ++ goto_error(r, TSS2_ESYS_RC_BAD_VALUE, ++ "SM4 encrypt called with wrong algorithm.", cleanup); ++ } ++ ++ /* Create and initialize the context */ ++ if(!(ctx = EVP_CIPHER_CTX_new())) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, ++ "Initialize cipher context", cleanup); ++ } ++ ++ if (1 != EVP_EncryptInit(ctx, cipher_alg, key, iv)) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, ++ "Initialize cipher operation", cleanup); ++ } ++ ++ /* Perform the encryption */ ++ if (1 != EVP_EncryptUpdate(ctx, buffer, &cipher_len, buffer, buffer_size)) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt update", cleanup); ++ } ++ ++ if (1 != EVP_EncryptFinal(ctx, buffer, &cipher_len)) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt final", cleanup); ++ } ++ LOGBLOB_TRACE(buffer, buffer_size, "IESYS SM4 output"); ++ ++cleanup: ++ ++ OSSL_FREE(ctx,EVP_CIPHER_CTX); ++ ++ return r; ++} ++ ++/** Decrypt data with SM4. ++ * ++ * @param[in] key key used for SM4. ++ * @param[in] tpm_sym_alg SM4 type in TSS2 notation (must be TPM2_ALG_SM4). ++ * @param[in] key_bits Key size in bits. ++ * @param[in] tpm_mode Block cipher mode of opertion in TSS2 notation (CFB). ++ * For parameter encryption only CFB can be used. ++ * @param[in,out] buffer Data to be decrypted. The decrypted date will be stored ++ * in this buffer. ++ * @param[in] buffer_size size of data to be encrypted. ++ * @param[in] iv The initialization vector. ++ * @retval TSS2_RC_SUCCESS on success, or TSS2_ESYS_RC_BAD_VALUE and ++ * @retval TSS2_ESYS_RC_BAD_REFERENCE for invalid parameters, ++ * @retval TSS2_ESYS_RC_GENERAL_FAILURE for errors of the crypto library. ++ */ ++TSS2_RC ++iesys_cryptossl_sym_sm4_decrypt(uint8_t * key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t * buffer, ++ size_t buffer_size, ++ uint8_t * iv, ++ void *userdata) ++{ ++ UNUSED(userdata); ++ ++ TSS2_RC r = TSS2_RC_SUCCESS; ++ const EVP_CIPHER *cipher_alg = NULL; ++ EVP_CIPHER_CTX *ctx = NULL; ++ int cipher_len = 0; ++ ++ if (key == NULL || buffer == NULL) { ++ return_error(TSS2_ESYS_RC_BAD_REFERENCE, "Bad reference"); ++ } ++ ++ if (tpm_sym_alg != TPM2_ALG_SM4) { ++ goto_error(r, TSS2_ESYS_RC_BAD_VALUE, ++ "SM4 decrypt called with wrong algorithm.", cleanup); ++ } ++ ++ if (key_bits == 128 && tpm_mode == TPM2_ALG_CFB) ++ cipher_alg = EVP_sm4_cfb128(); ++ else { ++ goto_error(r, TSS2_ESYS_RC_BAD_VALUE, ++ "SM4 algorithm not implemented or illegal mode (CFB expected).", ++ cleanup); ++ } ++ ++ /* Create and initialize the context */ ++ if(!(ctx = EVP_CIPHER_CTX_new())) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, ++ "Initialize cipher context", cleanup); ++ } ++ ++ LOGBLOB_TRACE(buffer, buffer_size, "IESYS SM4 input"); ++ ++ if (1 != EVP_DecryptInit(ctx, cipher_alg, key, iv)) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, ++ "Initialize cipher operation", cleanup); ++ } ++ ++ /* Perform the decryption */ ++ if (1 != EVP_DecryptUpdate(ctx, buffer, &cipher_len, buffer, buffer_size)) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt update", cleanup); ++ } ++ ++ if (1 != EVP_DecryptFinal(ctx, buffer, &cipher_len)) { ++ goto_error(r, TSS2_ESYS_RC_GENERAL_FAILURE, "Encrypt final", cleanup); ++ } ++ LOGBLOB_TRACE(buffer, buffer_size, "IESYS SM4 output"); ++ ++cleanup: ++ ++ OSSL_FREE(ctx,EVP_CIPHER_CTX); ++ return r; ++} ++#endif + + /** Initialize OpenSSL crypto backend. + * +diff --git a/src/tss2-esys/esys_crypto_ossl.h b/src/tss2-esys/esys_crypto_ossl.h +index ae3c33a..d8e84d6 100644 +--- a/src/tss2-esys/esys_crypto_ossl.h ++++ b/src/tss2-esys/esys_crypto_ossl.h +@@ -109,6 +109,28 @@ TSS2_RC iesys_cryptossl_sym_aes_decrypt( + uint8_t *iv, + void *userdata); + ++#if HAVE_EVP_SM4_CFB && !defined(OPENSSL_NO_SM4) ++TSS2_RC iesys_cryptossl_sym_sm4_encrypt( ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *dst, ++ size_t dst_size, ++ uint8_t *iv, ++ void *userdata); ++ ++TSS2_RC iesys_cryptossl_sym_sm4_decrypt( ++ uint8_t *key, ++ TPM2_ALG_ID tpm_sym_alg, ++ TPMI_SM4_KEY_BITS key_bits, ++ TPM2_ALG_ID tpm_mode, ++ uint8_t *dst, ++ size_t dst_size, ++ uint8_t *iv, ++ void *userdata); ++#endif ++ + TSS2_RC iesys_cryptossl_get_ecdh_point( + TPM2B_PUBLIC *key, + size_t max_out_size, +@@ -122,6 +144,13 @@ TSS2_RC iesys_cryptossl_get_ecdh_point( + #define _iesys_crypto_get_ecdh_point iesys_cryptossl_get_ecdh_point + #define _iesys_crypto_aes_encrypt iesys_cryptossl_sym_aes_encrypt + #define _iesys_crypto_aes_decrypt iesys_cryptossl_sym_aes_decrypt ++#if HAVE_EVP_SM4_CFB && !defined(OPENSSL_NO_SM4) ++#define _iesys_crypto_sm4_encrypt iesys_cryptossl_sym_sm4_encrypt ++#define _iesys_crypto_sm4_decrypt iesys_cryptossl_sym_sm4_decrypt ++#else ++#define _iesys_crypto_sm4_encrypt NULL ++#define _iesys_crypto_sm4_decrypt NULL ++#endif + + TSS2_RC iesys_cryptossl_init(void *userdata); + +diff --git a/src/tss2-esys/esys_iutil.c b/src/tss2-esys/esys_iutil.c +index c8346b3..79e6143 100644 +--- a/src/tss2-esys/esys_iutil.c ++++ b/src/tss2-esys/esys_iutil.c +@@ -745,6 +745,31 @@ iesys_encrypt_param(ESYS_CONTEXT * esys_context, + &encrypt_buffer[0], paramSize, + &symKey[aes_off]); + return_if_error(r, "AES encryption not possible"); ++ } else if (symDef->algorithm == TPM2_ALG_SM4) { ++ /* SM4 encryption with key derived with KDFa */ ++ if (symDef->mode.sm4 != TPM2_ALG_CFB) { ++ return_error(TSS2_ESYS_RC_BAD_VALUE, ++ "Invalid symmetric mode (must be CFB)"); ++ } ++ r = iesys_crypto_KDFa(&esys_context->crypto_backend, rsrc_session->authHash, ++ &rsrc_session->sessionValue[0], ++ rsrc_session->sizeSessionValue, "CFB", ++ &rsrc_session->nonceCaller, ++ &rsrc_session->nonceTPM, ++ symDef->keyBits.sm4 + SM4_BLOCK_SIZE_IN_BYTES * 8, ++ NULL, &symKey[0], FALSE); ++ return_if_error(r, "while computing KDFa"); ++ ++ size_t sm4_off = ( symDef->keyBits.sm4 + 7) / 8; ++ r = iesys_crypto_sm4_encrypt( ++ &esys_context->crypto_backend, ++ &symKey[0], ++ symDef->algorithm, ++ symDef->keyBits.sm4, ++ symDef->mode.sm4, ++ &encrypt_buffer[0], paramSize, ++ &symKey[sm4_off]); ++ return_if_error(r, "SM4 encryption not possible"); + } + /* XOR obfuscation of parameter */ + else if (symDef->algorithm == TPM2_ALG_XOR) { +@@ -760,7 +785,7 @@ iesys_encrypt_param(ESYS_CONTEXT * esys_context, + + } else { + return_error(TSS2_ESYS_RC_BAD_VALUE, +- "Invalid symmetric algorithm (should be XOR or AES)"); ++ "Invalid symmetric algorithm (should be XOR, AES, or SM4)"); + } + r = Tss2_Sys_SetDecryptParam(esys_context->sys, paramSize, + &encrypt_buffer[0]); +@@ -848,6 +873,43 @@ iesys_decrypt_param(ESYS_CONTEXT * esys_context) + &symKey[aes_off]); + return_if_error(r, "Decryption error"); + ++ r = Tss2_Sys_SetEncryptParam(esys_context->sys, p2BSize, &plaintext[0]); ++ return_if_error(r, "Setting plaintext"); ++ } else if (symDef->algorithm == TPM2_ALG_SM4) { ++ /* Parameter decryption with a symmetric SM4 key derived by KDFa */ ++ if (symDef->mode.sm4 != TPM2_ALG_CFB) { ++ return_error(TSS2_ESYS_RC_BAD_VALUE, ++ "Invalid symmetric mode (must be CFB)"); ++ } ++ LOGBLOB_DEBUG(&rsrc_session->sessionKey.buffer[0], ++ rsrc_session->sessionKey.size, ++ "IESYS encrypt session key"); ++ ++ r = iesys_crypto_KDFa(&esys_context->crypto_backend, rsrc_session->authHash, ++ &rsrc_session->sessionValue[0], ++ rsrc_session->sizeSessionValue, ++ "CFB", &rsrc_session->nonceTPM, ++ &rsrc_session->nonceCaller, ++ symDef->keyBits.sm4 ++ + SM4_BLOCK_SIZE_IN_BYTES * 8, NULL, ++ &symKey[0], FALSE); ++ return_if_error(r, "KDFa error"); ++ LOGBLOB_DEBUG(&symKey[0], ++ ((symDef->keyBits.sm4 + ++ SM4_BLOCK_SIZE_IN_BYTES * 8) + 7) / 8, ++ "IESYS encrypt KDFa key"); ++ ++ size_t sm4_off = ( symDef->keyBits.sm4 + 7) / 8; ++ r = iesys_crypto_sm4_decrypt( ++ &esys_context->crypto_backend, ++ &symKey[0], ++ symDef->algorithm, ++ symDef->keyBits.sm4, ++ symDef->mode.sm4, ++ &plaintext[0], p2BSize, ++ &symKey[sm4_off]); ++ return_if_error(r, "Decryption error"); ++ + r = Tss2_Sys_SetEncryptParam(esys_context->sys, p2BSize, &plaintext[0]); + return_if_error(r, "Setting plaintext"); + } else if (symDef->algorithm == TPM2_ALG_XOR) { +@@ -866,7 +928,7 @@ iesys_decrypt_param(ESYS_CONTEXT * esys_context) + return_if_error(r, "Setting plaintext"); + } else { + return_error(TSS2_ESYS_RC_BAD_VALUE, +- "Invalid symmetric algorithm (should be XOR or AES)"); ++ "Invalid symmetric algorithm (should be XOR, AES, or SM4)"); + } + return TSS2_RC_SUCCESS; + } +diff --git a/test/integration/esys-crypto.int.c b/test/integration/esys-crypto.int.c +index 1618e9c..7969f54 100644 +--- a/test/integration/esys-crypto.int.c ++++ b/test/integration/esys-crypto.int.c +@@ -61,6 +61,8 @@ test_invoke_esys(ESYS_CONTEXT *esys_context) + + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, aes_decrypt); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, aes_encrypt); ++ CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, sm4_decrypt); ++ CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, sm4_encrypt); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, get_ecdh_point); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, get_random2b); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, rsa_pk_encrypt); +@@ -68,6 +70,8 @@ test_invoke_esys(ESYS_CONTEXT *esys_context) + ESYS_CRYPTO_CALLBACKS callbacks = { + .aes_decrypt = TEST_FN_PTR, + .aes_encrypt = TEST_FN_PTR, ++ .sm4_decrypt = TEST_FN_PTR, ++ .sm4_encrypt = TEST_FN_PTR, + .get_ecdh_point = TEST_FN_PTR, + .get_random2b = TEST_FN_PTR, + .rsa_pk_encrypt = TEST_FN_PTR, +@@ -123,6 +127,8 @@ test_invoke_esys(ESYS_CONTEXT *esys_context) + + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, aes_decrypt); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, aes_encrypt); ++ CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, sm4_decrypt); ++ CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, sm4_encrypt); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, get_ecdh_point); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, get_random2b); + CHECK_BACKEND_FN_NOT_TEST(esys_context->crypto_backend, rsa_pk_encrypt); +diff --git a/test/unit/esys-crypto.c b/test/unit/esys-crypto.c +index b47cfdd..4901b91 100644 +--- a/test/unit/esys-crypto.c ++++ b/test/unit/esys-crypto.c +@@ -258,6 +258,61 @@ check_aes_encrypt(void **state) + assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); + } + ++#if HAVE_EVP_SM4_CFB && !defined(OPENSSL_NO_SM4) ++static void ++check_sm4_encrypt(void **state) ++{ ++ TSS2_RC rc; ++ uint8_t key[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; ++ uint8_t buffer[5] = { 1, 2, 3, 4, 5 }; ++ size_t size = sizeof(buffer); ++ ++ ESYS_CRYPTO_CALLBACKS crypto_cb = { 0 }; ++ rc = iesys_initialize_crypto_backend(&crypto_cb, NULL); ++ assert_int_equal (rc, TSS2_RC_SUCCESS); ++ ++ rc = iesys_crypto_sm4_encrypt(&crypto_cb, NULL, TPM2_ALG_SM4, 128, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_REFERENCE); ++ ++ rc = iesys_crypto_sm4_encrypt(&crypto_cb, &key[0], 0, 128, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); ++ ++ rc = iesys_crypto_sm4_encrypt(&crypto_cb, &key[0], TPM2_ALG_SM4, 128, 0, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); ++ ++ rc = iesys_crypto_sm4_encrypt(&crypto_cb, &key[0], TPM2_ALG_SM4, 999, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); ++ ++ rc = iesys_crypto_sm4_encrypt(&crypto_cb, &key[0], TPM2_ALG_SM4, 128, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_RC_SUCCESS); ++ ++ rc = iesys_crypto_sm4_decrypt(&crypto_cb, NULL, TPM2_ALG_SM4, 128, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_REFERENCE); ++ ++ rc = iesys_crypto_sm4_decrypt(&crypto_cb, &key[0], 0, 128, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); ++ ++ rc = iesys_crypto_sm4_decrypt(&crypto_cb, &key[0], TPM2_ALG_SM4, 128, 0, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); ++ ++ rc = iesys_crypto_sm4_decrypt(&crypto_cb, &key[0], TPM2_ALG_SM4, 999, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_ESYS_RC_BAD_VALUE); ++ ++ rc = iesys_crypto_sm4_decrypt(&crypto_cb, &key[0], TPM2_ALG_SM4, 128, TPM2_ALG_CFB, ++ &buffer[0], size, &key[0]); ++ assert_int_equal (rc, TSS2_RC_SUCCESS); ++} ++#endif ++ + static void + check_free(void **state) + { +@@ -320,6 +375,8 @@ static void test_backend_set(void **state) { + + CHECK_BACKEND_FN(crypto_cb, aes_decrypt); + CHECK_BACKEND_FN(crypto_cb, aes_encrypt); ++ CHECK_BACKEND_FN(crypto_cb, sm4_decrypt); ++ CHECK_BACKEND_FN(crypto_cb, sm4_encrypt); + CHECK_BACKEND_FN(crypto_cb, get_ecdh_point); + CHECK_BACKEND_FN(crypto_cb, get_random2b); + CHECK_BACKEND_FN(crypto_cb, rsa_pk_encrypt); +@@ -328,6 +385,8 @@ static void test_backend_set(void **state) { + ESYS_CRYPTO_CALLBACKS user_cb = { + .aes_decrypt = (void *)0xBADCC0DE, + .aes_encrypt = (void *)0xBADCC0DE, ++ .sm4_decrypt = (void *)0xBADCC0DE, ++ .sm4_encrypt = (void *)0xBADCC0DE, + .get_ecdh_point = (void *)0xBADCC0DE, + .get_random2b = (void *)0xBADCC0DE, + .rsa_pk_encrypt = (void *)0xBADCC0DE, +@@ -377,6 +436,9 @@ main(int argc, char *argv[]) + cmocka_unit_test(check_random), + cmocka_unit_test(check_pk_encrypt), + cmocka_unit_test(check_aes_encrypt), ++#if HAVE_EVP_SM4_CFB && !defined(OPENSSL_NO_SM4) ++ cmocka_unit_test(check_sm4_encrypt), ++#endif + cmocka_unit_test(check_free), + cmocka_unit_test(check_get_sys_context), + cmocka_unit_test(test_backend_set) +-- +2.17.1 diff --git a/tpm2-tss.spec b/tpm2-tss.spec index b57c08bb90952f03d7020a105b35162c8429f626..64b53f58bca7ad57bfac50ebdd6b6c8eed69eb67 100644 --- a/tpm2-tss.spec +++ b/tpm2-tss.spec @@ -1,6 +1,6 @@ Name: tpm2-tss Version: 4.0.1 -Release: 2 +Release: 3 Summary: TPM2.0 Software Stack License: BSD URL: https://github.com/tpm2-software/tpm2-tss @@ -8,6 +8,9 @@ Source0: https://github.com/tpm2-software/tpm2-tss/releases/download/%{ver Patch0001: backport-FAPI-Skip-test-fapi-fix-provisioning-with-template-i.patch Patch0002: backport-CVE-2024-29040-FAPI-Fix-check-of-magic-.patch +Patch0003: backport-esys-add-SM4-algorithm-support.patch +Patch0004: Hygon-Add-support-for-udev-to-create-tcm-de.patch +Patch0005: add-bootstrap-file-from-upstream.patch BuildRequires: gcc-c++ autoconf-archive libtool pkgconfig systemd libgcrypt-devel openssl-devel doxygen json-c-devel libcurl-devel util-linux-devel BuildRequires: curl >= 7.80.0 libcmocka-devel iproute uthash-devel swtpm @@ -31,6 +34,7 @@ Obsoletes: %{name}-static %autosetup -n %{name}-%{version} -p1 %build +./bootstrap %configure --disable-static --disable-silent-rules --with-udevrulesdir=%{_udevrulesdir} --with-udevrulesprefix=80- \ --with-runstatedir=%{_rundir} --with-tmpfilesdir=%{_tmpfilesdir} --with-sysusersdir=%{_sysusersdir} \ --enable-unit --enable-integration @@ -74,6 +78,14 @@ make check %{_mandir}/man*/* %changelog +* Fri Aug 2 2024 chench - 4.0.1-3 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC:add SM4 algorithm support + - Add support for udev to create tcm devices + - add bootstrap file from upstream + * Wed May 8 2024 jinlun - 4.0.1-2 - fix CVE-2024-29040 and fix test check error