diff options
author | Jerome Forissier <jerome@forissier.org> | 2019-12-17 09:19:56 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome@forissier.org> | 2020-01-07 14:14:36 +0100 |
commit | 91fc6bd89309eebdfbe3d7203a046958b8c5a3eb (patch) | |
tree | 9a216c84c284809895210d04bc2b3bba7768a338 | |
parent | f9a78287dd1217877e079f0c3cc83f6181a51dc7 (diff) |
core: crypto: add support for SM2 PKE
Adds SM2 Public Key Encryption [1] using LibTomCrypt. The TA interface
complies with the GlobalPlatform TEE Internal Core API version 1.2.
SM2 is enabled with CFG_CRYPTO_SM2_PKE=y (default y) which currently
requires that CFG_CRYPTOLIB_NAME=tomcrypt. An Mbed TLS implementation
could be added later if needed.
[1] http://www.gmbz.org.cn/main/postDetail.html?id=20180724110812
Signed-off-by: Jerome Forissier <jerome@forissier.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
-rw-r--r-- | core/crypto.mk | 10 | ||||
-rw-r--r-- | core/crypto/crypto.c | 20 | ||||
-rw-r--r-- | core/include/crypto/crypto.h | 6 | ||||
-rw-r--r-- | core/lib/libtomcrypt/ecc.c | 7 | ||||
-rw-r--r-- | core/tee/tee_svc_cryp.c | 37 | ||||
-rw-r--r-- | lib/libutee/include/tee_api_defines.h | 5 | ||||
-rw-r--r-- | lib/libutee/include/utee_defines.h | 44 | ||||
-rw-r--r-- | lib/libutee/tee_api_operations.c | 2 |
8 files changed, 124 insertions, 7 deletions
diff --git a/core/crypto.mk b/core/crypto.mk index e9ae3b9a..d7b5a074 100644 --- a/core/crypto.mk +++ b/core/crypto.mk @@ -37,7 +37,14 @@ CFG_CRYPTO_SM3 ?= y CFG_CRYPTO_DSA ?= y CFG_CRYPTO_RSA ?= y CFG_CRYPTO_DH ?= y +# ECC includes ECDSA and ECDH CFG_CRYPTO_ECC ?= y +ifeq ($(CFG_CRYPTOLIB_NAME),tomcrypt) +CFG_CRYPTO_SM2_PKE ?= y +endif +ifeq ($(CFG_CRYPTOLIB_NAME)-$(CFG_CRYPTO_SM2_PKE),mbedtls-y) +$(error Error: CFG_CRYPTO_SM2_PKE=y requires CFG_CRYPTOLIB_NAME=tomcrypt) +endif # Authenticated encryption CFG_CRYPTO_CCM ?= y @@ -128,6 +135,8 @@ $(eval $(call cryp-dep-one, GCM, AES)) $(eval $(call cryp-dep-one, AES, ECB CBC CTR CTS XTS)) # If no DES cipher mode is left, disable DES $(eval $(call cryp-dep-one, DES, ECB CBC)) +# SM2 is Elliptic Curve Cryptography, it uses some generic ECC functions +$(eval $(call cryp-dep-one, SM2_PKE, ECC)) ############################################################### # libtomcrypt (LTC) specifics, phase #1 @@ -158,6 +167,7 @@ core-ltc-vars += AES_ARM64_CE AES_ARM32_CE core-ltc-vars += SHA1_ARM32_CE SHA1_ARM64_CE core-ltc-vars += SHA256_ARM32_CE SHA256_ARM64_CE core-ltc-vars += SIZE_OPTIMIZATION +core-ltc-vars += SM2_PKE # Assigned selected CFG_CRYPTO_xxx as _CFG_CORE_LTC_xxx $(foreach v, $(core-ltc-vars), $(eval _CFG_CORE_LTC_$(v) := $(CFG_CRYPTO_$(v)))) _CFG_CORE_LTC_MPI := $(CFG_CORE_MBEDTLS_MPI) diff --git a/core/crypto/crypto.c b/core/crypto/crypto.c index e4cbd6b3..eeaa269b 100644 --- a/core/crypto/crypto.c +++ b/core/crypto/crypto.c @@ -691,3 +691,23 @@ crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key __unused, return TEE_ERROR_NOT_IMPLEMENTED; } #endif /*!CFG_CRYPTO_ECC*/ + +#if !defined(CFG_CRYPTO_SM2_PKE) +TEE_Result crypto_acipher_sm2_pke_decrypt(struct ecc_keypair *key __unused, + const uint8_t *src __unused, + size_t src_len __unused, + uint8_t *dst __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} + +TEE_Result crypto_acipher_sm2_pke_encrypt(struct ecc_public_key *key __unused, + const uint8_t *src __unused, + size_t src_len __unused, + uint8_t *dst __unused, + size_t *dst_len __unused) +{ + return TEE_ERROR_NOT_IMPLEMENTED; +} +#endif /* !CFG_CRYPTO_SM2_PKE */ diff --git a/core/include/crypto/crypto.h b/core/include/crypto/crypto.h index 1ca44d2b..7da74461 100644 --- a/core/include/crypto/crypto.h +++ b/core/include/crypto/crypto.h @@ -238,6 +238,12 @@ TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, struct ecc_public_key *public_key, void *secret, unsigned long *secret_len); +TEE_Result crypto_acipher_sm2_pke_decrypt(struct ecc_keypair *key, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len); +TEE_Result crypto_acipher_sm2_pke_encrypt(struct ecc_public_key *key, + const uint8_t *src, size_t src_len, + uint8_t *dst, size_t *dst_len); /* * Verifies a SHA-256 hash, doesn't require crypto_init() to be called in diff --git a/core/lib/libtomcrypt/ecc.c b/core/lib/libtomcrypt/ecc.c index 8322ba2e..051da77e 100644 --- a/core/lib/libtomcrypt/ecc.c +++ b/core/lib/libtomcrypt/ecc.c @@ -124,6 +124,13 @@ static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo, (algo != TEE_ALG_ECDH_P521)) return TEE_ERROR_BAD_PARAMETERS; break; + case TEE_ECC_CURVE_SM2: + size_bits = 256; + size_bytes = 32; + name = "SM2"; + if ((algo != 0) && (algo != TEE_ALG_SM2_PKE)) + return TEE_ERROR_BAD_PARAMETERS; + break; default: return TEE_ERROR_NOT_SUPPORTED; } diff --git a/core/tee/tee_svc_cryp.c b/core/tee/tee_svc_cryp.c index 80892f29..622fd299 100644 --- a/core/tee/tee_svc_cryp.c +++ b/core/tee/tee_svc_cryp.c @@ -486,6 +486,14 @@ static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = { PROP(TEE_TYPE_ECDH_KEYPAIR, 1, 192, 521, sizeof(struct ecc_keypair), tee_cryp_obj_ecc_keypair_attrs), + + PROP(TEE_TYPE_SM2_PKE_PUBLIC_KEY, 1, 256, 256, + sizeof(struct ecc_public_key), + tee_cryp_obj_ecc_pub_key_attrs), + + PROP(TEE_TYPE_SM2_PKE_KEYPAIR, 1, 256, 256, + sizeof(struct ecc_keypair), + tee_cryp_obj_ecc_keypair_attrs), }; struct attr_ops { @@ -1137,6 +1145,9 @@ TEE_Result tee_obj_attr_copy_from(struct tee_obj *o, const struct tee_obj *src) } else if (o->info.objectType == TEE_TYPE_ECDH_PUBLIC_KEY) { if (src->info.objectType != TEE_TYPE_ECDH_KEYPAIR) return TEE_ERROR_BAD_PARAMETERS; + } else if (o->info.objectType == TEE_TYPE_SM2_PKE_PUBLIC_KEY) { + if (src->info.objectType != TEE_TYPE_SM2_PKE_KEYPAIR) + return TEE_ERROR_BAD_PARAMETERS; } else { return TEE_ERROR_BAD_PARAMETERS; } @@ -1225,11 +1236,13 @@ TEE_Result tee_obj_set_type(struct tee_obj *o, uint32_t obj_type, break; case TEE_TYPE_ECDSA_PUBLIC_KEY: case TEE_TYPE_ECDH_PUBLIC_KEY: + case TEE_TYPE_SM2_PKE_PUBLIC_KEY: res = crypto_acipher_alloc_ecc_public_key(o->attr, max_key_size); break; case TEE_TYPE_ECDSA_KEYPAIR: case TEE_TYPE_ECDH_KEYPAIR: + case TEE_TYPE_SM2_PKE_KEYPAIR: res = crypto_acipher_alloc_ecc_keypair(o->attr, max_key_size); break; default: @@ -1480,6 +1493,9 @@ static TEE_Result get_ec_key_size(uint32_t curve, size_t *key_size) case TEE_ECC_CURVE_NIST_P521: *key_size = 521; break; + case TEE_ECC_CURVE_SM2: + *key_size = 256; + break; default: return TEE_ERROR_NOT_SUPPORTED; } @@ -1880,6 +1896,7 @@ TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size, case TEE_TYPE_ECDSA_KEYPAIR: case TEE_TYPE_ECDH_KEYPAIR: + case TEE_TYPE_SM2_PKE_KEYPAIR: res = tee_svc_obj_generate_key_ecc(o, type_props, key_size, params, param_count); if (res != TEE_SUCCESS) @@ -2010,6 +2027,12 @@ static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o, case TEE_MAIN_ALGO_ECDH: req_key_type = TEE_TYPE_ECDH_KEYPAIR; break; + case TEE_MAIN_ALGO_SM2_PKE: + if (mode == TEE_MODE_ENCRYPT) + req_key_type = TEE_TYPE_SM2_PKE_PUBLIC_KEY; + else + req_key_type = TEE_TYPE_SM2_PKE_KEYPAIR; + break; #if defined(CFG_CRYPTO_HKDF) case TEE_MAIN_ALGO_HKDF: req_key_type = TEE_TYPE_HKDF_IKM; @@ -3402,6 +3425,20 @@ TEE_Result syscall_asymm_operate(unsigned long state, } break; + case TEE_ALG_SM2_PKE: + if (cs->mode == TEE_MODE_ENCRYPT) { + res = crypto_acipher_sm2_pke_encrypt(o->attr, src_data, + src_len, dst_data, + &dlen); + } else if (cs->mode == TEE_MODE_DECRYPT) { + res = crypto_acipher_sm2_pke_decrypt(o->attr, src_data, + src_len, dst_data, + &dlen); + } else { + res = TEE_ERROR_GENERIC; + } + break; + case TEE_ALG_RSAES_PKCS1_V1_5: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: diff --git a/lib/libutee/include/tee_api_defines.h b/lib/libutee/include/tee_api_defines.h index 0da76de2..d60c03be 100644 --- a/lib/libutee/include/tee_api_defines.h +++ b/lib/libutee/include/tee_api_defines.h @@ -20,6 +20,7 @@ #define TEE_ERROR_CORRUPT_OBJECT_2 0xF0100002 #define TEE_ERROR_STORAGE_NOT_AVAILABLE 0xF0100003 #define TEE_ERROR_STORAGE_NOT_AVAILABLE_2 0xF0100004 +#define TEE_ERROR_CIPHERTEXT_INVALID 0xF0100006 #define TEE_ERROR_GENERIC 0xFFFF0000 #define TEE_ERROR_ACCESS_DENIED 0xFFFF0001 #define TEE_ERROR_CANCEL 0xFFFF0002 @@ -195,6 +196,7 @@ #define TEE_ALG_ECDH_P256 0x80003042 #define TEE_ALG_ECDH_P384 0x80004042 #define TEE_ALG_ECDH_P521 0x80005042 +#define TEE_ALG_SM2_PKE 0x80000045 #define TEE_ALG_SM3 0x50000007 /* Object Types */ @@ -219,6 +221,8 @@ #define TEE_TYPE_ECDSA_KEYPAIR 0xA1000041 #define TEE_TYPE_ECDH_PUBLIC_KEY 0xA0000042 #define TEE_TYPE_ECDH_KEYPAIR 0xA1000042 +#define TEE_TYPE_SM2_PKE_PUBLIC_KEY 0xA0000047 +#define TEE_TYPE_SM2_PKE_KEYPAIR 0xA1000047 #define TEE_TYPE_GENERIC_SECRET 0xA0000000 #define TEE_TYPE_CORRUPTED_OBJECT 0xA00000BE #define TEE_TYPE_DATA 0xA00000BF @@ -261,6 +265,7 @@ #define TEE_ECC_CURVE_NIST_P256 0x00000003 #define TEE_ECC_CURVE_NIST_P384 0x00000004 #define TEE_ECC_CURVE_NIST_P521 0x00000005 +#define TEE_ECC_CURVE_SM2 0x00000300 /* Panicked Functions Identification */ diff --git a/lib/libutee/include/utee_defines.h b/lib/libutee/include/utee_defines.h index 74a0e925..6255d1b2 100644 --- a/lib/libutee/include/utee_defines.h +++ b/lib/libutee/include/utee_defines.h @@ -6,6 +6,7 @@ #define UTEE_DEFINES_H #include <compiler.h> +#include <tee_api_defines.h> #include <types_ext.h> /* @@ -29,6 +30,7 @@ #define TEE_MAIN_ALGO_DH 0x32 #define TEE_MAIN_ALGO_ECDSA 0x41 #define TEE_MAIN_ALGO_ECDH 0x42 +#define TEE_MAIN_ALGO_SM2_PKE 0x47 /* Not in v1.2 spec */ #define TEE_MAIN_ALGO_HKDF 0xC0 /* OP-TEE extension */ #define TEE_MAIN_ALGO_CONCAT_KDF 0xC1 /* OP-TEE extension */ #define TEE_MAIN_ALGO_PBKDF2 0xC2 /* OP-TEE extension */ @@ -45,15 +47,30 @@ #define TEE_CHAIN_MODE_GCM 0x8 #define TEE_CHAIN_MODE_PKCS1_PSS_MGF1 0x9 /* ??? */ - /* Bits [31:28] */ -#define TEE_ALG_GET_CLASS(algo) (((algo) >> 28) & 0xF) -#define TEE_ALG_GET_KEY_TYPE(algo, with_private_key) \ - (TEE_ALG_GET_MAIN_ALG(algo) | \ - ((with_private_key) ? 0xA1000000 : 0xA0000000)) +static inline uint32_t __tee_alg_get_class(uint32_t algo) +{ + if (algo == TEE_ALG_SM2_PKE) + return TEE_OPERATION_ASYMMETRIC_CIPHER; + + return (algo >> 28) & 0xF; /* Bits [31:28] */ +} + +#define TEE_ALG_GET_CLASS(algo) __tee_alg_get_class(algo) + +static inline uint32_t __tee_alg_get_main_alg(uint32_t algo) +{ + switch (algo) { + case TEE_ALG_SM2_PKE: + return TEE_MAIN_ALGO_SM2_PKE; + default: + break; + } + + return algo & 0xff; +} - /* Bits [7:0] */ -#define TEE_ALG_GET_MAIN_ALG(algo) ((algo) & 0xFF) +#define TEE_ALG_GET_MAIN_ALG(algo) __tee_alg_get_main_alg(algo) /* Bits [11:8] */ #define TEE_ALG_GET_CHAIN_MODE(algo) (((algo) >> 8) & 0xF) @@ -64,6 +81,19 @@ /* Bits [23:20] */ #define TEE_ALG_GET_INTERNAL_HASH(algo) (((algo) >> 20) & 0x7) +static inline uint32_t __tee_alg_get_key_type(uint32_t algo, bool with_priv) +{ + uint32_t key_type = 0xA0000000 | TEE_ALG_GET_MAIN_ALG(algo); + + if (with_priv) + key_type |= 0x01000000; + + return key_type; +} + +#define TEE_ALG_GET_KEY_TYPE(algo, with_private_key) \ + __tee_alg_get_key_type(algo, with_private_key) + /* Return hash algorithm based on main hash */ #define TEE_ALG_HASH_ALGO(main_hash) \ (TEE_OPERATION_DIGEST << 28 | (main_hash)) diff --git a/lib/libutee/tee_api_operations.c b/lib/libutee/tee_api_operations.c index 64a5e3d3..e3368f90 100644 --- a/lib/libutee/tee_api_operations.c +++ b/lib/libutee/tee_api_operations.c @@ -84,6 +84,7 @@ TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, case TEE_ALG_ECDSA_P256: case TEE_ALG_ECDH_P256: + case TEE_ALG_SM2_PKE: if (maxKeySize != 256) return TEE_ERROR_NOT_SUPPORTED; break; @@ -175,6 +176,7 @@ TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: + case TEE_ALG_SM2_PKE: if (mode == TEE_MODE_ENCRYPT) { req_key_usage = TEE_USAGE_ENCRYPT; } else if (mode == TEE_MODE_DECRYPT) { |