diff --git a/test/CA/rsa_demo/cloud/Makefile b/test/CA/rsa_demo/cloud/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..01f9144850a3fc294972b6cd842e12720b3eeb30 --- /dev/null +++ b/test/CA/rsa_demo/cloud/Makefile @@ -0,0 +1,23 @@ +CUR_DIR=$(shell pwd) +iTrustee_SDK_PATH=${CUR_DIR}/../../../../ + +TARGET_APP := rsa_demo + +APP_SOURCES := ../rsa_ca_demo.c + +APP_SOURCES += $(iTrustee_SDK_PATH)/src/CA/cloud/libteec_adaptor.c + +APP_CFLAGS += -fstack-protector-strong -fPIC + +APP_CFLAGS += -I$(iTrustee_SDK_PATH)/include/CA -I$(iTrustee_SDK_PATH)/thirdparty/open_source/libboundscheck/include + +APP_LDFLAGS += -ldl -lpthread + +APP_LDFLAGS += -z text -z now -z relro -z noexecstack -pie + +APP_OBJECTS := $(APP_SOURCES:.c=.o) +$(TARGET_APP): $(APP_SOURCES) + @$(CC) $(APP_CFLAGS) -o $@ $(APP_SOURCES) $(APP_LDFLAGS) + +clean: + rm -f *.o $(TARGET_APP) diff --git a/test/CA/rsa_demo/rsa_ca_demo.c b/test/CA/rsa_demo/rsa_ca_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..1483aee675690982bd792be30f754e697611044e --- /dev/null +++ b/test/CA/rsa_demo/rsa_ca_demo.c @@ -0,0 +1,478 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: rsa-demo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tee_client_api.h" + +/*-------------------------------------------------------------------* + * This Demo is only for demonstrate how RSA Crypto APIs works. + * CA should ONLY get touch with Encrypted data, + * and Original message (Decrypt Data) shold ONLY exist in + * TA or User's Server. + * ------------------------------------------------------------------*/ +/* RSA CRYPTO DEMO uuid: f68fd704-6eb1-4d14-b218-722850eb3ef0 */ +static const TEEC_UUID RSA_CRYPTO_uuid = { + 0xf68fd704, 0x6eb1, 0x4d14, + { 0xb2, 0x18, 0x72, 0x28, 0x50, 0xeb, 0x3e, 0xf0 } +}; + +#define TEEC_DEBUG +#define RSA_CRYPTO_DEMO_TA_PATH "/data/f68fd704-6eb1-4d14-b218-722850eb3ef0.sec" +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 // see rsa-demoTA.c, massage size has some limitation. +#define RSA_KEY_1 1 +#define RSA_ALG_OAEP_SHA512 1 // use TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512 mode for crypto +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define PRINTF_SIZE 32 + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 + +enum { + CMD_GENERATE_RANDOM = 0, + CMD_GENERATE_KEYPAIR, + CMD_SAVE_KEYPAIR, + CMD_READ_KEYPAIR, + CMD_ENC_OAEP_MGF1_SHA512, + CMD_DEC_OAEP_MGF1_SHA512, + CMD_SIGN_PSS_MGF1_SHA256, + CMD_VERIFY_PSS_MGF1_SHA256, +}; + +TEEC_Context g_context; +TEEC_Session g_session; + +#ifdef TEEC_DEBUG +void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} +#else +void DumpBuff(char *buffer, size_t bufLen) +{ + return; +} +#endif + +/* initialize context and opensession */ +TEEC_Result TeecInit(void) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + result = TEEC_InitializeContext(NULL, &g_context); + if (result != TEEC_SUCCESS) { + TEEC_Error("teec initial failed"); + return result; + } + + /* pass TA's FULLPATH to TEE, then OpenSession. */ + /* CA MUST use the TEEC_LOGIN_IDENTIFY mode to login. */ + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_NONE, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_INPUT); + g_context.ta_path = (uint8_t *)RSA_CRYPTO_DEMO_TA_PATH; + + result = TEEC_OpenSession(&g_context, &g_session, &RSA_CRYPTO_uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (result != TEEC_SUCCESS) { + printf("open session failed: result:%x orgin: %d.\n", (int)result, origin); + TEEC_FinalizeContext(&g_context); + return result; + } + + TEEC_Debug("teec init OK."); + return result; +} + +void TeecClose(void) +{ + TEEC_CloseSession(&g_session); + TEEC_FinalizeContext(&g_context); + + TEEC_Debug("teec uninit OK."); +} + +/* InvokeCommand - Generate Random number as a message to be encrypt later. */ +TEEC_Result GenerateRandomCmd(char* msgBuf, uint32_t bufLen) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || (bufLen < RSA_MASSAGE_SIZE)) { + TEEC_Error("invoke GenerateRandomCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_MEMREF_TEMP_OUTPUT, + TEEC_NONE, + TEEC_NONE, + TEEC_NONE); + + operation.params[0].tmpref.buffer = msgBuf; + operation.params[0].tmpref.size = RSA_MASSAGE_SIZE; + + result = TEEC_InvokeCommand(&g_session, CMD_GENERATE_RANDOM, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke GenerateRandomCmd failed, codes=0x%x, origin=0x%x", result, origin); + return result; + } + + if (operation.params[0].tmpref.size != RSA_MASSAGE_SIZE) { + TEEC_Error("invoke GenerateRandomCmd failed, returned size is %d.", operation.params[0].tmpref.size); + } else { + TEEC_Debug("invoke GenerateRandomCmd is successed."); + printf("random msg is : \n"); + DumpBuff(msgBuf, operation.params[0].tmpref.size); + } + + return result; +} + +/* InvokeCommand - Generate a RSA Keypair. */ +TEEC_Result RsaGenerateKeypairCmd(void) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_NONE, + TEEC_NONE); + + operation.params[0].value.a = RSA_KEY_SIZE; + operation.params[0].value.b = RSA_KEY_1; + + result = TEEC_InvokeCommand(&g_session, CMD_GENERATE_KEYPAIR, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaGenerateKeypairCmd failed, codes=0x%x, origin=0x%x", result, origin); + } + + return result; +} + +/* InvokeCommand - Save Keypair to secure storage. */ +TEEC_Result RsaSaveKeypairCmd(char* path, uint32_t pathLen) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (pathLen == 0) { + TEEC_Error("RsaSaveKeypairCmd: pathlen is 0."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_MEMREF_TEMP_INPUT, + TEEC_NONE, + TEEC_NONE); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[1].tmpref.buffer = path; + operation.params[1].tmpref.size = pathLen; + + result = TEEC_InvokeCommand(&g_session, CMD_SAVE_KEYPAIR, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSaveKeypairCmd failed, codes=0x%x, origin=0x%x", result, origin); + } + + return result; +} + +/* InvokeCommand - Read Keypair from secure storage. */ +TEEC_Result RsaReadKeypairCmd(char* path, uint32_t len) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_MEMREF_TEMP_INPUT, + TEEC_NONE, + TEEC_NONE); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[1].tmpref.buffer = path; + operation.params[1].tmpref.size = len; + + result = TEEC_InvokeCommand(&g_session, CMD_READ_KEYPAIR, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaReadKeypairCmd failed, codes=0x%x, origin=0x%x", result, origin); + } + + return result; +} + +TEEC_Result InitRsaOperation(TEEC_Operation *operation, char* msgBuf1, uint32_t msgLen1, + char* msgBuf2, uint32_t msgLen2) +{ + if (msgBuf1 == NULL || msgLen1 == 0 || msgBuf2 == NULL || msgLen2 == 0) { + TEEC_Error("InitRsaOperation has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation->started = 1; + operation->paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation->params[0].value.a = RSA_KEY_1; + operation->params[0].value.b = RSA_ALG_OAEP_SHA512; + operation->params[PARAMS_INDEX_2].tmpref.buffer = msgBuf1; + operation->params[PARAMS_INDEX_2].tmpref.size = msgLen1; + operation->params[PARAMS_INDEX_3].tmpref.buffer = msgBuf2; + operation->params[PARAMS_INDEX_3].tmpref.size = msgLen2; + + return TEEC_SUCCESS; +} + +/* InvokeCommand - Encrypt message with TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512. */ +TEEC_Result RsaEncryptCmd(char* msgBuf, uint32_t msgLen, char* encBuf, uint32_t bufLen) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + result = InitRsaOperation(&operation, msgBuf, msgLen, encBuf, bufLen); + if (result != TEEC_SUCCESS) { + return result; + } + + result = TEEC_InvokeCommand(&g_session, CMD_ENC_OAEP_MGF1_SHA512, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaEncryptCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaEncryptCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("encBuf is : \n"); + DumpBuff(encBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + } + + return result; +} + +/* InvokeCommand - Decrypt message with TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512. */ +TEEC_Result RsaDecryptCmd(char* encBuf, uint32_t encBufLen, char* decBuf, uint32_t decBufLen) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + result = InitRsaOperation(&operation, encBuf, encBufLen, decBuf, decBufLen); + if (result != TEEC_SUCCESS) { + return result; + } + + result = TEEC_InvokeCommand(&g_session, CMD_DEC_OAEP_MGF1_SHA512, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaDecryptCmd failed, codes=0x%x, origin=0x%x.", result, origin); + return result; + } + if (operation.params[PARAMS_INDEX_3].tmpref.size < RSA_MASSAGE_SIZE) { + TEEC_Error("invoke RsaDecryptCmd failed, returned Decrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + TEEC_Debug("invoke RsaDecryptCmd successed, returned Decrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + printf("derypted_buffer is : \n"); + DumpBuff(decBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + } + + return result; +} + +int VerifyRsaCrypto(const char* msgBuf, const char* decBuf, uint32_t len) +{ + if (msgBuf == NULL || decBuf == NULL) { + TEEC_Error("VerifyRsaCrypto has wrong params."); + return RSA_INPUT_ERROR_PARAMETER; + } + + return memcmp(msgBuf, decBuf, len); +} + +/* InvokeCommand - Sign message with TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512. */ +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(&g_session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +/* InvokeCommand - Sign message with TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512. */ +static TEEC_Result RsaVerifyCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t bufLen) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || (msgLen == 0) || signBuf == NULL || (bufLen == 0)) { + TEEC_Error("invoke RsaVerifyCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_INPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = bufLen; + + result = TEEC_InvokeCommand(&g_session, CMD_VERIFY_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaVerifyCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } + return result; +} + +int main(void) +{ + char msgBuf[RSA_KEY_SIZE] = {0}; + char encBuf[RSA_KEY_SIZE] = {0}; + char decBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + char keyStorePath[] = "sec_storage_data/rsa_demo/keypair_1"; + uint32_t pathLen = strlen(keyStorePath); + + if (TEEC_SUCCESS != TeecInit()) { + printf("TeecInit Failed!\n"); + return -1; + } + + /* Generate Random data */ + if (GenerateRandomCmd(msgBuf, bufLen) != TEEC_SUCCESS) { + goto out; + } + + /* Generate RSA keypair */ + if (RsaGenerateKeypairCmd() != TEEC_SUCCESS) { + goto out; + } + + /* save keypair to secure storage */ + if (RsaSaveKeypairCmd(keyStorePath, pathLen) != TEEC_SUCCESS) { + goto out; + } + + /* read keypair to secure storage */ + if (RsaReadKeypairCmd(keyStorePath, pathLen) != TEEC_SUCCESS) { + goto out; + } + + /* Encrypt */ + if (RsaEncryptCmd(msgBuf, RSA_MASSAGE_SIZE, encBuf, bufLen) != TEEC_SUCCESS) { + goto out; + } + + /* Decrypt */ + if (RsaDecryptCmd(encBuf, bufLen, decBuf, bufLen) != TEEC_SUCCESS) { + goto out; + } + + /* verify */ + if (VerifyRsaCrypto(msgBuf, decBuf, RSA_KEY_SIZE) < 0) { + printf("Error: rsa decBuf is not match msgBuf!\n"); + goto out; + } + + /* sign */ + if (RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen) != TEEC_SUCCESS) { + goto out; + } + + /* verify */ + if (RsaVerifyCmd(msgBuf, RSA_MASSAGE_SIZE, signature, bufLen) != TEEC_SUCCESS) { + printf("Error: rsa signature is not match msgBuf!\n"); + } else { + printf("Succeed to load and excute RSA crypto,sign and verify!\n"); + } + + TeecClose(); + return 0; +out: + TeecClose(); + return -1; +} diff --git a/test/TA/rsa_demo/cloud/Makefile b/test/TA/rsa_demo/cloud/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..69f2012cc2d7404e821b6d7ba16b18e477cf042b --- /dev/null +++ b/test/TA/rsa_demo/cloud/Makefile @@ -0,0 +1,31 @@ +include ../../../../build/mk/cloud/common.mk +include ../config.mk + +SRC += $(wildcard ./*.c) +SRC += ../rsa_ta_interface.c + +# set header directory +INCLUDEDIR += -I./include + +# set target +COBJS := $(SRC:%.c=%.o) +TARGET = $(COBJS) + +sec_binary:combine + cp ../manifest.txt ./ + cp ../config.mk ./ + python3 -B ${SIGNTOOL_DIR}/signtool_v3.py ${CUR_DIR} ${CUR_DIR} --config ./config_cloud.ini + +combine: $(TARGET) + $(LD) $(LDFLAGS) $(TARGET) $(EXTRAO) -o libcombine.so + +src/%.o: ./src/%.c + $(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@ + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@ + +clean: + rm -f $(COBJS) *.so + rm -f *.sec + rm -f manifest.txt config.mk diff --git a/test/TA/rsa_demo/cloud/TA_cert/readme.txt b/test/TA/rsa_demo/cloud/TA_cert/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..cd19d55b558b20252fe045cf71bbca3cbff0e285 --- /dev/null +++ b/test/TA/rsa_demo/cloud/TA_cert/readme.txt @@ -0,0 +1 @@ +The rsa private key of rsa_demo should be placed here. \ No newline at end of file diff --git a/test/TA/rsa_demo/cloud/config_cloud.ini b/test/TA/rsa_demo/cloud/config_cloud.ini new file mode 100644 index 0000000000000000000000000000000000000000..5ee812b72d949aaa796e02bdd026b84c14b4dbf6 --- /dev/null +++ b/test/TA/rsa_demo/cloud/config_cloud.ini @@ -0,0 +1,49 @@ +[config] +;0 means debug +;1 means release +;[fixed value] +releaseType = 1 +;;; +;0 means TA not installed by OTRP +;1 means TA installed by OTRP +otrpFlag = 0 +;;; +;server address for signing TA +serverIp= +;;; +;public key for encrypt TA +;[fixed value] +encryptKey = cloud/rsa_public_key_cloud.pem +;;; +;public key length +;[fixed value] +encryptKeyLen = 3072 +;;; +;0 means not sign +;1 means signed by local private +;2 means signed using native sign tool; +;3 means signed by CI +;[fixed value] +signType = 1 +;;; +;private key for signing TA +;[private key owned by yourself] +signKey = ../../test/TA/rsa_demo/cloud/TA_cert/private_key.pem +;;; +;private key length for signing TA +;[key length should be 4096 for security enhance] +signKeyLen = 4096 +;;; +;0 means SHA256 hash type +;1 means SHA512 hash type +;[set value to 0 by default] +hashType = 0 +;;; +;0 means padding type is pkcs1v15 +;1 means padding type is PSS +;[set value to 0 by default] +paddingType = 0 +;;; +;config file +;[signed config file by Huawei] +configPath= ../../test/TA/rsa_demo/cloud/signed_config/config diff --git a/test/TA/rsa_demo/cloud/signed_config/readme.txt b/test/TA/rsa_demo/cloud/signed_config/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..3dbc283016fecdd404c80fef9980d705cce98978 --- /dev/null +++ b/test/TA/rsa_demo/cloud/signed_config/readme.txt @@ -0,0 +1 @@ +The config binary signed by Huawei should be placed here. \ No newline at end of file diff --git a/test/TA/rsa_demo/config.mk b/test/TA/rsa_demo/config.mk new file mode 100644 index 0000000000000000000000000000000000000000..d9e9bc031098f7951ecef3b688bd10787bf4bb5b --- /dev/null +++ b/test/TA/rsa_demo/config.mk @@ -0,0 +1,11 @@ +# +# Copyright 2017, Huawei Co. Ltd. +# +# +# API_LEVEL which indicates the GP API version of TA +# API_LEVEL=1 indicates GP 1.0 which is the current version of itrustee +# API_LEVEL=2 indicates GP 1.1.1 which is the current version of the partner +# API_LEVEL=3 indicates GP 1.2 which is the version we both going to support +# If no API_LEVEL is specified, API of GP 1.0 will be taked +CFLAGS += -DAPI_LEVEL=1 +TARGET_IS_ARM64=y diff --git a/test/TA/rsa_demo/manifest.txt b/test/TA/rsa_demo/manifest.txt new file mode 100644 index 0000000000000000000000000000000000000000..e00aef5980a241ff321723a541b09b29ad7e0a2a --- /dev/null +++ b/test/TA/rsa_demo/manifest.txt @@ -0,0 +1,7 @@ +gpd.ta.appID: f68fd704-6eb1-4d14-b218-722850eb3ef0 +gpd.ta.service_name: rsa-demo +gpd.ta.singleInstance: true +gpd.ta.multiSession: false +gpd.ta.instanceKeepAlive: false +gpd.ta.dataSize: 67928064 +gpd.ta.stackSize: 40960 diff --git a/test/TA/rsa_demo/rsa_ta_interface.c b/test/TA/rsa_demo/rsa_ta_interface.c new file mode 100644 index 0000000000000000000000000000000000000000..7b47a5ada71660bf13428871343f7b96a4113cf8 --- /dev/null +++ b/test/TA/rsa_demo/rsa_ta_interface.c @@ -0,0 +1,848 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: RSA-TA + */ +#include "rsa_ta_interface.h" +#include +#include "tee_core_api.h" +#include "tee_defines.h" +#include "tee_log.h" +#include "tee_crypto_api.h" +#include "tee_object_api.h" +#include "tee_ext_api.h" + +// for trusted_storage_api +#define TEE_OBJECT_STORAGE_PRIVATE 0x00000001 +#define TEE_DATA_FLAG_ACCESS_READ 0x00000001 +#define TEE_DATA_FLAG_ACCESS_WRITE 0x00000002 + +extern TEE_Result TEE_CreatePersistentObject(); +extern TEE_Result TEE_OpenPersistentObject(); + +TEE_ObjectHandle g_rsaKeyObj1; +/********************************************************* + * 函数名: CmdRSAGenRandom + * 功能描述:调用硬件生成器生成一些随机数据 + * 参数 msgbuf:保存 随机数据的地址 + * msglen: 产生随机数据的长度 + * 返回值:TEE_SUCCESS 表示正常返回 + *********************************************************/ +TEE_Result CmdRSAGenRandom(char *msgbuf, uint32_t *msglen) +{ + TEE_Result ret; + uint32_t len; + if (msgbuf == NULL || msglen == NULL || *msglen == 0) { + SLogError("CmdRSAGenRandom: Bad expected parameters."); + return TEE_ERROR_BAD_PARAMETERS; + } + len = *msglen; + TEE_GenerateRandom(msgbuf, len); + + char *buf = (char *)TEE_Malloc(len, 0); + if (buf == NULL) { + SLogError("malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + + if (memcmp(msgbuf, buf, len) == 0) { + *msglen = 0; + ret = TEE_ERROR_GENERIC; + SLogError("CmdRSAGenRandom: TEE_GenerateRandom Failed."); + } else { + ret = TEE_SUCCESS; + } + TEE_Free(buf); + return ret; +} +/************************************************************** + * 函数名称: CmdRSAGenKeypair + * 功能描述: 随机产生一些的RSA秘钥数据 + * 参数 : keysize:秘钥数据的长度 + * num_key: 秘钥键值 + * 返回值:TEE_SUCCESS 表示随机生成秘钥数据成功 + **************************************************************/ +TEE_Result CmdRSAGenKeypair(uint32_t keySize, uint32_t numKey) +{ + TEE_Result ret; + TEE_ObjectHandle tmpKeyObj = NULL; + ret = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, keySize, &tmpKeyObj); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSAGenKeypair: TEE_AllocateTransientObject failed."); + return ret; + } + + ret = TEE_GenerateKey(tmpKeyObj, keySize, NULL, 0); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSAGenKeypair: TEE_GenerateKey failed."); + TEE_FreeTransientObject(tmpKeyObj); + return ret; + } + + switch (numKey) { + case RSA_KEY_1: + if (g_rsaKeyObj1 == NULL) { + ret = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, keySize, &g_rsaKeyObj1); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSAGenKeypair: TEE_AllocateTransientObject failed."); + break; + } + } + TEE_CopyObjectAttributes(g_rsaKeyObj1, tmpKeyObj); + break; + default: + SLogError("CmdRSAGenKeypair: key number: %d is not defined.", numKey); + ret = TEE_ERROR_BAD_PARAMETERS; + } + TEE_FreeTransientObject(tmpKeyObj); + return ret; +} + +/**************************************************************************** + * 函数名: CmdRSASaveKeypair + * 功能描述: 将秘钥数据保存到/data/sec_storage_data 路径内 + * 参数 :num_key :秘钥键值 + * path: 保存秘钥数据的路径 + * pathlen: 保存秘钥数据路径长度 + * 返回值:TEE_SUCCESS 表示秘钥数据保存成功 + ****************************************************************************/ +TEE_Result CmdRSASaveKeypair(uint32_t numKey, char *path, uint32_t pathlen) +{ + TEE_Result ret; + TEE_ObjectHandle tmpKeyObj = NULL; + + if ((pathlen < PATHLEN_LIMIT_START) || (pathlen >= PATHLEN_LIMIT_END)) { + SLogError("CMD_SAVE_KEYPAIR: Bad expected pathlen: %d.", pathlen); + return TEE_ERROR_BAD_PARAMETERS; + } + switch (numKey) { + case RSA_KEY_1: + ret = TEE_CreatePersistentObject(TEE_OBJECT_STORAGE_PRIVATE, path, pathlen, TEE_DATA_FLAG_ACCESS_WRITE, + g_rsaKeyObj1, NULL, 0, (&tmpKeyObj)); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSASaveKeypair: TEE_CreatePersistentObject failed. ret= %x", ret); + } + break; + default: + SLogError("CmdRSASaveKeypair: key number: %d is not defined.", numKey); + ret = TEE_ERROR_BAD_PARAMETERS; + } + + if (tmpKeyObj) { + TEE_CloseObject(tmpKeyObj); + } + return ret; +} +/************************************************************************** + * 函数名: CmdRSAReadKeypair + * 功能描述: 从/data/sec_storage_data读取秘钥数据 + * 参数 :num_key :秘钥键值 + * path: 保存秘钥数据的路径 + * pathlen: 保存秘钥数据路径长度 + * 返回值:TEE_SUCCESS 表示秘钥数据读取成功 + ***************************************************************************/ +TEE_Result CmdRSAReadKeypair(uint32_t numKey, char *path, uint32_t pathlen) +{ + TEE_Result ret; + TEE_ObjectHandle tmpKeyObj = NULL; + + if ((pathlen < PATHLEN_LIMIT_START) || (pathlen >= PATHLEN_LIMIT_END)) { + SLogError("CMD_READ_KEYPAIR: Bad expected pathlen: %d.", pathlen); + return TEE_ERROR_BAD_PARAMETERS; + } + switch (numKey) { + case RSA_KEY_1: + ret = TEE_OpenPersistentObject(TEE_OBJECT_STORAGE_PRIVATE, path, pathlen, + TEE_DATA_FLAG_ACCESS_READ, (&tmpKeyObj)); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSAReadKeypair: TEE_OpenPersistentObject failed."); + break; + } + if (g_rsaKeyObj1 == NULL) { + ret = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, RSA_KEY_SIZE, &g_rsaKeyObj1); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSAReadKeypair: TEE_AllocateTransientObject failed."); + break; + } + TEE_CopyObjectAttributes(g_rsaKeyObj1, tmpKeyObj); + } + break; + default: + SLogError("CmdRSAReadKeypair: key number: %d is not defined.", numKey); + ret = TEE_ERROR_BAD_PARAMETERS; + } + + if (tmpKeyObj) { + TEE_CloseObject(tmpKeyObj); + } + return ret; +} +/************************************************************************************************************ + * 函数名称:CmdRSACryptoParamCheck + * 功能描述:检测加密原文数据地址和加密数据的缓存的地址以及缓存大小是否存在 + * 参数 :Operation :TEE操作引擎 + * buf1: 原文数据存储地址 + * buf1_len: 原文长度 + * buf2: 密文数据存储地址 + * buf2_len 密文数据长度 + * cryptmode:加密模式 + * algorithm:加密算法的索引(即使用那种算法加密) + * 返回类型:TEE_SUCCESS表示 参数检查完毕,且无异常 + * **********************************************************************************************************/ +TEE_Result CmdRSACryptoParamCheck(TEE_OperationHandle *Operation, Buffer *buf1, Buffer *buf2, + uint32_t cryptmode, uint32_t algorithm) +{ + TEE_Result ret; + if ((buf1->buffer == NULL) || (buf1->size == 0) || (buf2->buffer == NULL) || (buf2->size == 0)) { + SLogError("CmdRSACrypto: buf is null, or bufLen is 0."); + return TEE_ERROR_BAD_PARAMETERS; + } + ret = TEE_AllocateOperation(Operation, algorithm, cryptmode, buf2->size); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_AllocateOperation failed."); + return ret; + } + return TEE_SUCCESS; +} +/***************************************************************************************************** + * 函数名称: CmdRSACrypto + * 功能描述: 用之前生成的秘钥去加密之前生成的数据 + * 参数 num_key: 键值 + * alg: 加密算法的索引 + * buf1: 原文数据存储地址 + * buf1_len: 原文长度 + * buf2: 密文数据存储地址 + * buf2_len 密文数据长度 + * cryptmode:加密模式 + * 返回值 :TEE_SUCCESS表示加密成功 + ***************************************************************************************************/ +TEE_Result CmdRSACrypto(uint32_t numKey, uint32_t alg, Buffer *buf1, Buffer *buf2, uint32_t cryptmode) +{ + TEE_Result ret; + TEE_OperationHandle Operation = NULL; + size_t outlen; + uint32_t algorithm; + algorithm = alg; + outlen = buf2->size; + + ret = CmdRSACryptoParamCheck(&Operation, buf1, buf2, cryptmode, algorithm); + if (ret != TEE_SUCCESS) { + return ret; + } + + switch (numKey) { + case RSA_KEY_1: + ret = TEE_SetOperationKey(Operation, g_rsaKeyObj1); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_SetOperationKey failed."); + TEE_FreeOperation(Operation); + return ret; + } + break; + default: + SLogError("CmdRSACrypto: key number: %d is not defined.", numKey); + ret = TEE_ERROR_BAD_PARAMETERS; + TEE_FreeOperation(Operation); + return ret; + } + if (cryptmode == TEE_MODE_ENCRYPT) { + ret = TEE_AsymmetricEncrypt(Operation, NULL, 0, buf1->buffer, buf1->size, buf2->buffer, &outlen); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_AsymmetricEncrypt failed. ret %x", ret); + } + } else if (cryptmode == TEE_MODE_DECRYPT) { + ret = TEE_AsymmetricDecrypt(Operation, NULL, 0, buf1->buffer, buf1->size, buf2->buffer, &outlen); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_AsymmetricDecrypt failed. ret %x", ret); + } + } else { + SLogError("CmdRSACrypto TEE_AsymmetricDecrypt unkown mode: %d.", cryptmode); + ret = TEE_ERROR_BAD_PARAMETERS; + } + if (ret == TEE_SUCCESS) { + buf2->size = outlen; + } else { + buf2->size = 0; + } + TEE_FreeOperation(Operation); + return ret; +} + +TEE_Result FreeOperationHandleParam(TEE_OperationHandle Operation1, TEE_OperationHandle Operation2, + TEE_Result ret) +{ + if (Operation1) { + TEE_FreeOperation(Operation1); + } + if (Operation2) { + TEE_FreeOperation(Operation2); + } + return ret; +} + +TEE_Result CheckRsaSha256Init(TEE_Result Sha256Result, TEE_Result TEE_DigestDoFinalResult, + TEE_Result returTEE_AllocateOperationnVlue2Result) +{ + if (Sha256Result != TEE_SUCCESS) { + SLogError("TEE_AllocateOperation sha256 failed, ret %x\n", Sha256Result); + return Sha256Result; + } + if (TEE_DigestDoFinalResult != TEE_SUCCESS) { + SLogError("TEE_DigestDoFinal failed, ret %x\n", TEE_DigestDoFinalResult); + return TEE_DigestDoFinalResult; + } + if (returTEE_AllocateOperationnVlue2Result != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_AllocateOperation failed."); + return returTEE_AllocateOperationnVlue2Result; + } + return TEE_SUCCESS; +} + +TEE_Result CheckRsaSha256Mode(TEE_Result TEE_AsymmetricSignDigest, TEE_Result TEE_AsymmetricVerifyDigest, + size_t *buf2_len, size_t outlen, uint32_t mode) +{ + if (mode == TEE_MODE_SIGN) { + if (TEE_AsymmetricSignDigest != TEE_SUCCESS) { + SLogError("CmdRSASignVerify TEE_AsymmetricSignDigest failed."); + return TEE_AsymmetricSignDigest; + } + *buf2_len = outlen; + } else if (mode == TEE_MODE_VERIFY) { + if (TEE_AsymmetricVerifyDigest != TEE_SUCCESS) { + SLogError("CmdRSASignVerify TEE_AsymmetricVerifyDigest failed."); + return TEE_AsymmetricVerifyDigest; + } + } else { + SLogError("CmdRSASignVerify unkown mode: %d", mode); + return TEE_ERROR_BAD_PARAMETERS; + } + return TEE_SUCCESS; +} +/****************************************************************************************** + * 函数名: CmdRSASignVerify + * 功能描述:用秘钥通过TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 去签名、验证明文数据 + * 参数: num_key: 秘钥键值 + * alg : 算法索引 + * buf1 : 存储原文数据地址 + * buf1_len :原文数据长度 + * buf2 :签名存储密文数据地址 + * buf2_len :签名密文数据长度 + * mode :签名加密模式 +*******************************************************************************************/ +TEE_Result CmdRSASignVerify(uint32_t numKey, uint32_t alg, Buffer *buf1, Buffer *buf2, uint32_t mode) +{ + TEE_Result ret, retSign, retVer; + TEE_OperationHandle Operation1 = NULL; + TEE_OperationHandle Operation2 = NULL; + size_t outlen; + uint32_t algorithm = alg; + char *buf[DIGEST_BUF_LEN] = {0}; + int bufLen = DIGEST_BUF_LEN; + + if ((buf1->buffer == NULL) || (buf1->size == 0) || (buf2->buffer == NULL) || (buf2->size == 0)) { + SLogError("CmdRSACrypto: buf is null, or bufLen is 0."); + return TEE_ERROR_BAD_PARAMETERS; + } + outlen = buf2->size; + buf2->size = 0; + /* SHA 256 签名初始化 */ + ret = CheckRsaSha256Init(TEE_AllocateOperation(&Operation1, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0), + TEE_DigestDoFinal(Operation1, buf1->buffer, buf1->size, buf, (size_t *)&bufLen), + TEE_AllocateOperation(&Operation2, algorithm, mode, RSA_KEY_SIZE)); + if (ret != TEE_SUCCESS) { + goto clear; + } + switch (numKey) { + case RSA_KEY_1: + ret = TEE_SetOperationKey(Operation2, g_rsaKeyObj1); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto TEE_SetOperationKey failed."); + goto clear; + } + break; + default: + SLogError("CmdRSACrypto: key number: %d is not defined.", numKey); + ret = TEE_ERROR_BAD_PARAMETERS; + goto clear; + } + if (mode == TEE_MODE_SIGN) { + retSign = TEE_AsymmetricSignDigest(Operation2, NULL, 0, buf1->buffer, buf1->size, buf2->buffer, &outlen); + retVer = TEE_SUCCESS; + } else if (mode == TEE_MODE_VERIFY) { + retSign = TEE_SUCCESS; + retVer = TEE_AsymmetricVerifyDigest(Operation2, NULL, 0, buf1->buffer, buf1->size, buf2->buffer, outlen); + } else { + SLogError("invalid mode=%x for Sign or Verify", mode); + goto clear; + } + ret = CheckRsaSha256Mode(retSign, retVer, &buf2->size, outlen, mode); + if (ret != TEE_SUCCESS) { + goto clear; + } +clear: + return FreeOperationHandleParam(Operation1, Operation2, ret); +} +/* ---------------------------------------------------------------------------- + * Trusted Application Entry Points + * ---------------------------------------------------------------------------- */ +/** + * Function TA_CreateEntryPoint + * Description: + * The function TA_CreateEntryPoint is the Trusted Application's constructor, + * which the Framework calls when it creates a new instance of the Trusted Application. + */ +TEE_Result TA_CreateEntryPoint(void) +{ + SLogTrace("----- TA_CreateEntryPoint ----- "); + SLogTrace("TA version: %s ", TA_RSA_CRYPTO_DEMO_VERSION); + + if (addcaller_ca_exec(CLIENT_APPLICATION_NAME, "root") == TEE_SUCCESS) { + SLogTrace("TA_CreateEntryPoint: AddCaller_CA_exec ok."); + } else { + SLogError("TA_CreateEntryPoint: AddCaller_CA_exec failed."); + return TEE_ERROR_GENERIC; + } + return TEE_SUCCESS; +} +/** + * 函数名称: TA_OpenSessionEntryPoint + * 功能描述: + * The Framework calls the function TA_OpenSessionEntryPoint + * when a client requests to open a session with the Trusted Application. + * The open session request may result in a new Trusted Application instance + * being created. + */ +TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4], void **sessionContext) +{ + TEE_Result ret = TEE_SUCCESS; + SLogTrace("---- TA_OpenSessionEntryPoint -------- "); + (void)paramTypes; + (void)params; + (void)sessionContext; + g_rsaKeyObj1 = NULL; + + return ret; +} + +TEE_Result CmdGenerateRandom(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + + if (TEE_PARAM_TYPE_MEMREF_OUTPUT != TEE_PARAM_TYPE_GET(paramTypes, 0)) { + SLogError("CMD_GENERATE_RANDOM: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + + uint32_t msglen = params[0].memref.size; + char *msgbuf = (char *)TEE_Malloc(msglen, 0); + if (msgbuf == NULL) { + SLogError("malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + ret = CmdRSAGenRandom(msgbuf, &msglen); + if (ret == TEE_SUCCESS) { + TEE_MemMove(params[0].memref.buffer, msgbuf, msglen); + params[0].memref.size = msglen; + } else { + params[0].memref.size = 0; + } + + TEE_Free(msgbuf); + return ret; +} + +TEE_Result CmdGeneratePair(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + if (TEE_PARAM_TYPE_VALUE_INPUT != TEE_PARAM_TYPE_GET(paramTypes, 0)) { + SLogError("CMD_GENERATE_KEYPAIR: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + + ret = CmdRSAGenKeypair(params[0].value.a, params[0].value.b); + return ret; +} + +TEE_Result CmdSaveKeyPair(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + + if (TEE_PARAM_TYPE_VALUE_INPUT != TEE_PARAM_TYPE_GET(paramTypes, 0) || + TEE_PARAM_TYPE_MEMREF_INPUT != TEE_PARAM_TYPE_GET(paramTypes, 1)) { + SLogError("CMD_SAVE_KEYPAIR: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + + uint32_t savepathlen = params[1].memref.size; + char *path = (char *)TEE_Malloc(savepathlen, 0); + if (path == NULL) { + SLogError("malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(path, params[1].memref.buffer, params[1].memref.size); + ret = CmdRSASaveKeypair(params[0].value.a, path, savepathlen); + + TEE_Free(path); + return ret; +} + +TEE_Result CmdReadKeyPair(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + + if (TEE_PARAM_TYPE_VALUE_INPUT != TEE_PARAM_TYPE_GET(paramTypes, 0) || + TEE_PARAM_TYPE_MEMREF_INPUT != TEE_PARAM_TYPE_GET(paramTypes, 1)) { + SLogError("CMD_READ_KEYPAIR: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + + uint32_t readpathlen = params[PARAMS_IDX1].memref.size; + char *path = (char *)TEE_Malloc(readpathlen, 0); + if (path == NULL) { + SLogError("malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(path, params[PARAMS_IDX1].memref.buffer, params[PARAMS_IDX1].memref.size); + ret = CmdRSAReadKeypair(params[PARAMS_IDX0].value.a, path, readpathlen); + TEE_Free(path); + + return ret; +} + +TEE_Result ParamCheckEncOaepMgf1SHA512(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4], int numkey) +{ + switch (numkey) { + case NUM_VALUE_0: + if ((TEE_PARAM_TYPE_VALUE_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX0)) || + (TEE_PARAM_TYPE_MEMREF_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX2)) || + (TEE_PARAM_TYPE_MEMREF_OUTPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX3))) { + SLogError("CMD_ENC_OAEP_MGF1_SHA512: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + default: + if (params[PARAMS_IDX0].value.b != RSA_ALG_OAEP_SHA512) { + SLogError("algorithm is invalid %d", params[PARAMS_IDX0].value.b); + return TEE_ERROR_BAD_PARAMETERS; + } + if (params[PARAMS_IDX3].memref.size < RSA_2048_OUTPUT_SIZE) { + SLogError("output size %d small than needed", params[PARAMS_IDX3].memref.size); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + } + return TEE_SUCCESS; +} +TEE_Result CmdEncOaepMgf1SHA512(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + Buffer msgbuf = {NULL, 0}; + Buffer encryptbuf = {NULL, 0}; + + if ((ret = ParamCheckEncOaepMgf1SHA512(paramTypes, params, 0)) != TEE_SUCCESS || + (ret = ParamCheckEncOaepMgf1SHA512(paramTypes, params, 1)) != TEE_SUCCESS) { + return ret; + } + + msgbuf.size = params[PARAMS_IDX2].memref.size; + msgbuf.buffer = (char *)TEE_Malloc(msgbuf.size, 0); + if (msgbuf.buffer == NULL) { + SLogError("malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(msgbuf.buffer, params[PARAMS_IDX2].memref.buffer, params[PARAMS_IDX2].memref.size); + encryptbuf.size = params[PARAMS_IDX3].memref.size; + encryptbuf.buffer = (char *)TEE_Malloc(encryptbuf.size, 0); + if (encryptbuf.buffer == NULL) { + SLogError("malloc failed"); + TEE_Free(msgbuf.buffer); + return TEE_ERROR_OUT_OF_MEMORY; + } + ret = CmdRSACrypto(params[PARAMS_IDX0].value.a, TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512, + &msgbuf, &encryptbuf, TEE_MODE_ENCRYPT); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSACrypto failed"); + params[PARAMS_IDX3].memref.size = 0; + } else { + TEE_MemMove(params[PARAMS_IDX3].memref.buffer, encryptbuf.buffer, encryptbuf.size); + params[PARAMS_IDX3].memref.size = encryptbuf.size; + } + + TEE_Free(msgbuf.buffer); + TEE_Free(encryptbuf.buffer); + return TEE_SUCCESS; +} + +TEE_Result ParamCheckDecOaepMgf1SHA512(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4], int numkey) +{ + switch (numkey) { + case NUM_VALUE_0: + if ((TEE_PARAM_TYPE_VALUE_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX0)) || + (TEE_PARAM_TYPE_MEMREF_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX2)) || + (TEE_PARAM_TYPE_MEMREF_OUTPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX3))) { + SLogError("CMD_DEC_OAEP_MGF1_SHA512: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + default: + if (params[PARAMS_IDX2].memref.size != RSA_2048_OUTPUT_SIZE) { + SLogError("encrypted buffer len %d invalid", params[PARAMS_IDX2].memref.size); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + } + return TEE_SUCCESS; +} + +TEE_Result DecOaepMgf1SHA512SLogError(char *encbuf, const char *strs) +{ + SLogError("%s", strs); + TEE_Free(encbuf); + return TEE_ERROR_OUT_OF_MEMORY; +} + +TEE_Result CmdDecOaepMgf1SHA512(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + Buffer encbuf = {NULL, 0}; + Buffer decryptbuf = {NULL, 0}; + + if ((ret = ParamCheckDecOaepMgf1SHA512(paramTypes, params, 0)) != TEE_SUCCESS || + (ret = ParamCheckDecOaepMgf1SHA512(paramTypes, params, 1)) != TEE_SUCCESS) { + return ret; + } + + encbuf.size = params[PARAMS_IDX2].memref.size; + encbuf.buffer = (char *)TEE_Malloc(encbuf.size, 0); + if (encbuf.buffer == NULL) { + SLogError("malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(encbuf.buffer, params[PARAMS_IDX2].memref.buffer, params[PARAMS_IDX2].memref.size); + decryptbuf.size = params[PARAMS_IDX3].memref.size; + decryptbuf.buffer = (char *)TEE_Malloc(decryptbuf.size, 0); + if (decryptbuf.buffer == NULL) { + return DecOaepMgf1SHA512SLogError(decryptbuf.buffer, "malloc failed"); + } + ret = CmdRSACrypto(params[0].value.a, TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512, + &encbuf, &decryptbuf, TEE_MODE_DECRYPT); + if (params[PARAMS_IDX3].memref.size < decryptbuf.size) { + SLogError("output size %d too small", params[PARAMS_IDX3].memref.size); + params[PARAMS_IDX3].memref.size = decryptbuf.size; + ret = TEE_ERROR_BAD_PARAMETERS; + } + if (ret != TEE_SUCCESS) { + params[PARAMS_IDX3].memref.size = 0; + } else { + TEE_MemMove(params[PARAMS_IDX3].memref.buffer, decryptbuf.buffer, decryptbuf.size); + params[PARAMS_IDX3].memref.size = decryptbuf.size; + } + + TEE_Free(encbuf.buffer); + TEE_Free(decryptbuf.buffer); + return ret; +} + +TEE_Result ParamCheckSignPssMgf1SHA256(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4], int numkey) +{ + switch (numkey) { + case NUM_VALUE_0: + if ((TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX0) != TEE_PARAM_TYPE_VALUE_INPUT) || + (TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX2) != TEE_PARAM_TYPE_MEMREF_INPUT) || + (TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX3)) != TEE_PARAM_TYPE_MEMREF_OUTPUT) { + SLogError("CMD_SIGN_PSS_MGF1_SHA256: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + case NUM_VALUE_1: + if (params[PARAMS_IDX0].value.b != RSA_ALG_PSS_SHA256) { + SLogError("algorithm is invalid %d", params[PARAMS_IDX0].value.b); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + default: + break; + } + return TEE_SUCCESS; +} + +TEE_Result PssMgf1SHA256SLogError(uint32_t signatureSize, char *input, int rc, int errKey) +{ + switch (errKey) { + case NUM_VALUE_0: + SLogError("memcpy_s failed, rc %d", rc); + TEE_Free(input); + return TEE_ERROR_OUT_OF_MEMORY; + case NUM_VALUE_1: + SLogError("signatureSize %d invalid", signatureSize); + TEE_Free(input); + return TEE_ERROR_BAD_PARAMETERS; + case NUM_VALUE_2: + SLogError("signature malloc failed"); + TEE_Free(input); + return TEE_ERROR_OUT_OF_MEMORY; + default: + break; + } + return TEE_SUCCESS; +} + +TEE_Result CmdSignPssMgf1SHA256(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + Buffer input = {NULL, 0}; + Buffer signature = {NULL, 0}; + + if ((ret = ParamCheckSignPssMgf1SHA256(paramTypes, params, 0)) != TEE_SUCCESS || + (ret = ParamCheckSignPssMgf1SHA256(paramTypes, params, 1)) != TEE_SUCCESS) { + return ret; + } + + uint32_t keyIndex = params[PARAMS_IDX0].value.a; + input.size = params[PARAMS_IDX2].memref.size; + input.buffer = (char *)TEE_Malloc(input.size, 0); + if (input.buffer == NULL) { + SLogError("CmdSignPssMgf1SHA256 input malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(input.buffer, params[PARAMS_IDX2].memref.buffer, params[PARAMS_IDX2].memref.size); + signature.size = params[PARAMS_IDX3].memref.size; + if (signature.size < RSA_2048_OUTPUT_SIZE) { + return (PssMgf1SHA256SLogError(signature.size, input.buffer, 0, NUM_VALUE_1)); + } + signature.buffer = (char *)TEE_Malloc(signature.size, 0); + if (signature.buffer == NULL) { + return (PssMgf1SHA256SLogError(0, input.buffer, 0, NUM_VALUE_2)); + } + ret = CmdRSASignVerify(keyIndex, TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, &input, &signature, TEE_MODE_SIGN); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSASignVerify failed, ret %x", ret); + } else { + TEE_MemMove(params[PARAMS_IDX3].memref.buffer, signature.buffer, signature.size); + params[PARAMS_IDX3].memref.size = signature.size; + } + + TEE_Free(input.buffer); + TEE_Free(signature.buffer); + return ret; +} + +TEE_Result ParamCheckVerifyPssMgf1SHA256(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4], int numkey) +{ + switch (numkey) { + case NUM_VALUE_0: + if ((TEE_PARAM_TYPE_VALUE_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX0)) || + (TEE_PARAM_TYPE_MEMREF_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX2)) || + (TEE_PARAM_TYPE_MEMREF_INPUT != TEE_PARAM_TYPE_GET(paramTypes, PARAMS_IDX3))) { + SLogError("CMD_VERIFY_PSS_MGF1_SHA256: Bad expected parameter types."); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + case NUM_VALUE_1: + if (params[0].value.b != RSA_ALG_PSS_SHA256) { + SLogError("algorithm is invalid %d", params[PARAMS_IDX0].value.b); + return TEE_ERROR_BAD_PARAMETERS; + } + break; + default: + break; + } + return TEE_SUCCESS; +} + +TEE_Result CmdVerifyPssMgf1SHA256(uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + Buffer input = {NULL, 0}; + Buffer signature = {NULL, 0}; + + if ((ret = ParamCheckVerifyPssMgf1SHA256(paramTypes, params, 0)) != TEE_SUCCESS || + (ret = ParamCheckVerifyPssMgf1SHA256(paramTypes, params, 1)) != TEE_SUCCESS) { + return ret; + } + uint32_t keyIndex = params[PARAMS_IDX0].value.a; + input.size = params[PARAMS_IDX2].memref.size; + input.buffer = (char *)TEE_Malloc(input.size, 0); + if (input.buffer == NULL) { + SLogError("CmdVerifyPssMgf1SHA256 input malloc failed"); + return TEE_ERROR_OUT_OF_MEMORY; + } + TEE_MemMove(input.buffer, params[PARAMS_IDX2].memref.buffer, params[PARAMS_IDX2].memref.size); + signature.size = params[PARAMS_IDX3].memref.size; + if (signature.size != RSA_2048_OUTPUT_SIZE) { + return PssMgf1SHA256SLogError(signature.size, input.buffer, 0, NUM_VALUE_1); + } + signature.buffer = (char *)TEE_Malloc(signature.size, 0); + if (signature.buffer == NULL) { + return PssMgf1SHA256SLogError(0, input.buffer, 0, NUM_VALUE_2); + } + TEE_MemMove(signature.buffer, params[PARAMS_IDX3].memref.buffer, params[PARAMS_IDX3].memref.size); + ret = CmdRSASignVerify(keyIndex, TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, &input, &signature, TEE_MODE_VERIFY); + if (ret != TEE_SUCCESS) { + SLogError("CmdRSASignVerify failed, ret %x", ret); + } + + TEE_Free(input.buffer); + TEE_Free(signature.buffer); + return TEE_SUCCESS; +} + +TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t cmdId, + uint32_t paramTypes, TEE_Param params[PARAMS_IDX4]) +{ + TEE_Result ret; + + SLogTrace("---- TA_InvokeCommandEntryPoint ----cmdid: %d------- ", cmdId); + (void)sessionContext; + switch (cmdId) { + case CMD_GENERATE_RANDOM: + ret = CmdGenerateRandom(paramTypes, params); + break; + + case CMD_GENERATE_KEYPAIR: + ret = CmdGeneratePair(paramTypes, params); + break; + + case CMD_SAVE_KEYPAIR: + ret = CmdSaveKeyPair(paramTypes, params); + break; + + case CMD_READ_KEYPAIR: + ret = CmdReadKeyPair(paramTypes, params); + break; + + case CMD_ENC_OAEP_MGF1_SHA512: + ret = CmdEncOaepMgf1SHA512(paramTypes, params); + break; + + case CMD_DEC_OAEP_MGF1_SHA512: + ret = CmdDecOaepMgf1SHA512(paramTypes, params); + break; + + case CMD_SIGN_PSS_MGF1_SHA256: + ret = CmdSignPssMgf1SHA256(paramTypes, params); + break; + + case CMD_VERIFY_PSS_MGF1_SHA256: + ret = CmdVerifyPssMgf1SHA256(paramTypes, params); + break; + + default: + SLogError("Unknown CMD ID: %d", cmdId); + ret = TEE_FAIL; + } + + return ret; +} + +void TA_CloseSessionEntryPoint(void *sessionContext) +{ + (void)sessionContext; + SLogTrace("---- TA_CloseSessionEntryPoint ----- "); + if (g_rsaKeyObj1 != NULL) + TEE_FreeTransientObject(g_rsaKeyObj1); +} + +void TA_DestroyEntryPoint(void) +{ + SLogTrace("---- TA_DestroyEntryPoint ---- "); +} diff --git a/test/TA/rsa_demo/rsa_ta_interface.h b/test/TA/rsa_demo/rsa_ta_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..a9d84614fcc1d1c429c3b04c6b4498b114f16e65 --- /dev/null +++ b/test/TA/rsa_demo/rsa_ta_interface.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: rsa_ta_interface.h + */ +#ifndef __RSA_TA_INTERFACE_H +#define __RSA_TA_INTERFACE_H + +#include +#include "tee_defines.h" + +#define TA_RSA_CRYPTO_DEMO_VERSION "V1_20151215" +#define CLIENT_APPLICATION_NAME "/vendor/bin/rsa_demo" + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_KEY_1 1 +#define RSA_ALG_OAEP_SHA512 1 // 用 TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512 模式加密 +#define RSA_ALG_PSS_SHA256 2 // 用 TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 模式去签名 + +#define RSA_CRYPTO_DEBUG +#define RSA_2048_OUTPUT_SIZE 256 +#define PATHLEN_LIMIT_START 21 +#define PATHLEN_LIMIT_END 127 +#define DIGEST_BUF_LEN 32 + +#define PARAMS_IDX0 0 // params参数的下标索引 0 +#define PARAMS_IDX1 1 // params参数的下标索引 1 +#define PARAMS_IDX2 2 // params参数的下标索引 2 +#define PARAMS_IDX3 3 // params参数的下标索引 3 +#define PARAMS_IDX4 4 // params参数的下标索引 4 + +#define NUM_VALUE_0 0 // 参数下标索引 0 +#define NUM_VALUE_1 1 // 参数下标索引 1 +#define NUM_VALUE_2 2 // 参数下标索引 2 +#define NUM_VALUE_3 3 // 参数下标索引 3 +#define NUM_VALUE_4 4 // 参数下标索引 4 +typedef enum { + CMD_GENERATE_RANDOM = 0, + CMD_GENERATE_KEYPAIR, + CMD_SAVE_KEYPAIR, + CMD_READ_KEYPAIR, + CMD_ENC_OAEP_MGF1_SHA512, + CMD_DEC_OAEP_MGF1_SHA512, + CMD_SIGN_PSS_MGF1_SHA256, + CMD_VERIFY_PSS_MGF1_SHA256, +} DEMO_RSA_CRYPTO_CMD; + +typedef struct { + char *buffer; + size_t size; +} Buffer; + + +#endif