summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJerome Forissier <jerome@forissier.org>2019-12-17 09:19:56 +0100
committerJérôme Forissier <jerome@forissier.org>2020-01-07 14:14:36 +0100
commit91fc6bd89309eebdfbe3d7203a046958b8c5a3eb (patch)
tree9a216c84c284809895210d04bc2b3bba7768a338 /core
parentf9a78287dd1217877e079f0c3cc83f6181a51dc7 (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>
Diffstat (limited to 'core')
-rw-r--r--core/crypto.mk10
-rw-r--r--core/crypto/crypto.c20
-rw-r--r--core/include/crypto/crypto.h6
-rw-r--r--core/lib/libtomcrypt/ecc.c7
-rw-r--r--core/tee/tee_svc_cryp.c37
5 files changed, 80 insertions, 0 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: