Ciphering context: each opened session relates to a cipehring operation.
configure the AES flavour from a command.
load key from a command (here the key is provided by the REE)
reset init vector (here IV is provided by the REE)
cipher a buffer frame (here input and output buffers are non-secure)
*/
/*
Few routines to convert IDs from TA API into IDs from OP-TEE.
/
TEE_Result sm4_ta2tee_algo_id(uint32_t param, uint32_t algo)
{
DMSG("----------sm4_ta2tee_algo_id param=%d\n", param);
switch (param)
{
一 以下代码是模仿aes实现的sm4设置key和iv,然后进行ctr模式加密。
include
include
include
include
define AES128_KEY_BIT_SIZE 128
define AES128_KEY_BYTE_SIZE (AES128_KEY_BIT_SIZE / 8) // 只有128位
/*
/*
Few routines to convert IDs from TA API into IDs from OP-TEE. / TEE_Result sm4_ta2tee_algo_id(uint32_t param, uint32_t algo) { DMSG("----------sm4_ta2tee_algo_id param=%d\n", param); switch (param) {
case TA_SM4_ALGO_ECB: algo = TEE_ALG_SM4_ECB_NOPAD; return TEE_SUCCESS; case TA_SM4_ALGO_CBC: algo = TEE_ALG_SM4_CBC_NOPAD; return TEE_SUCCESS; case TA_SM4_ALGO_CTR: algo = TEE_ALG_SM4_CTR; return TEE_SUCCESS; default: EMSG("Invalid algo %u", param); return TEE_ERROR_BAD_PARAMETERS; } } TEE_Result sm4_ta2tee_key_size(uint32_t param, uint32_t key_size) { switch (param) { case AES128_KEY_BYTE_SIZE: DMSG("sm4_ta2tee_key_size-----------------param=%d\n", param); key_size = param; return TEE_SUCCESS; default: EMSG("Invalid key size %u", param); return TEE_ERROR_BAD_PARAMETERS; } } TEE_Result sm4_ta2tee_mode_id(uint32_t param, uint32_t mode) { switch (param) { case TA_SM4_MODE_ENCODE: mode = TEE_MODE_ENCRYPT; return TEE_SUCCESS; case TA_SM4_MODE_DECODE: mode = TEE_MODE_DECRYPT; return TEE_SUCCESS; default: EMSG("Invalid mode %u", param); return TEE_ERROR_BAD_PARAMETERS; } }
/*
/ Get ciphering context from session ID / DMSG("Session %p: get ciphering resources", session); sess = (struct sm4_cipher *)session;
/ Safely get the invocation parameters / if (param_types != exp_param_types) return TEE_ERROR_BAD_PARAMETERS;
res = sm4_ta2tee_algo_id(params[0].value.a, &sess->algo); if (res != TEE_SUCCESS) return res;
res = sm4_ta2tee_key_size(params[1].value.a, &sess->key_size); if (res != TEE_SUCCESS) return res;
res = sm4_ta2tee_mode_id(params[2].value.a, &sess->mode); if (res != TEE_SUCCESS) return res;
/*
/ Free potential previous operation / if (sess->op_handle != TEE_HANDLE_NULL) TEE_FreeOperation(sess->op_handle);
/ Allocate operation: AES/CTR, mode and size from params / res = TEE_AllocateOperation(&sess->op_handle, sess->algo, sess->mode, sess->key_size * 8); if (res != TEE_SUCCESS) { EMSG("Failed to allocate operation"); sess->op_handle = TEE_HANDLE_NULL; goto err; }
/ Free potential previous transient object / if (sess->key_handle != TEE_HANDLE_NULL) TEE_FreeTransientObject(sess->key_handle);
/ Allocate transient object according to target key size / res = TEE_AllocateTransientObject(TEE_TYPE_SM4, sess->key_size * 8, &sess->key_handle); if (res != TEE_SUCCESS) { EMSG("Failed to allocate transient object"); sess->key_handle = TEE_HANDLE_NULL; goto err; }
/*
TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, sess->key_size);
res = TEE_PopulateTransientObject(sess->key_handle, &attr, 1); if (res != TEE_SUCCESS) { EMSG("TEE_PopulateTransientObject failed, %x", res); goto err; }
res = TEE_SetOperationKey(sess->op_handle, sess->key_handle); if (res != TEE_SUCCESS) { EMSG("TEE_SetOperationKey failed %x", res); goto err; }
return res;
err: if (sess->op_handle != TEE_HANDLE_NULL) TEE_FreeOperation(sess->op_handle); sess->op_handle = TEE_HANDLE_NULL;
}
/*
Process command TA_AES_CMD_SET_KEY. API in aes_ta.h / TEE_Result sm4_set_aes_key(void session, uint32_t param_types, TEE_Param params[4]) { const uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); struct sm4_cipher sess; TEE_Attribute attr; TEE_Result res; uint32_t key_sz; char key;
/ Get ciphering context from session ID / DMSG("Session %p: load key material", session); sess = (struct sm4_cipher *)session;
/ Safely get the invocation parameters / if (param_types != exp_param_types) { // DMSG("TEE_ERROR_BAD_PARAMETERS-------------------------------------\n"); return TEE_ERROR_BAD_PARAMETERS; }
key = params[0].memref.buffer; key_sz = params[0].memref.size;
DMSG("-----进入setkey以后KEY %s::::::key_sz %d", key, key_sz);
if (key_sz != sess->key_size) { EMSG("Wrong key size %" PRIu32 ", expect %" PRIu32 " bytes", key_sz, sess->key_size); return TEE_ERROR_BAD_PARAMETERS; }
/*
TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_sz);
TEE_ResetTransientObject(sess->key_handle); res = TEE_PopulateTransientObject(sess->key_handle, &attr, 1); if (res != TEE_SUCCESS) { EMSG("TEE_PopulateTransientObject failed, %x", res); return res; }
TEE_ResetOperation(sess->op_handle); res = TEE_SetOperationKey(sess->op_handle, sess->key_handle); if (res != TEE_SUCCESS) { EMSG("TEE_SetOperationKey failed %x", res); return res; }
return res; }
/*
Process command TA_AES_CMD_SET_IV. API in aes_ta.h / TEE_Result sm4_reset_aes_iv(void session, uint32_t param_types, TEE_Param params[4]) { const uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); struct sm4_cipher sess; size_t iv_sz; char iv;
/ Get ciphering context from session ID / DMSG("Session %p: reset initial vector", session); sess = (struct sm4_cipher *)session;
/ Safely get the invocation parameters / if (param_types != exp_param_types) return TEE_ERROR_BAD_PARAMETERS;
iv = params[0].memref.buffer; iv_sz = params[0].memref.size;
DMSG("-----进入iv以后iv %s::::::iv_sz %d", iv, iv_sz);
/*
return TEE_SUCCESS; }
/*
Process command TA_AES_CMD_CIPHER. API in aes_ta.h / TEE_Result sm4_cipher_buffer(void session, uint32_t param_types, TEE_Param params[4]) { const uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); struct sm4_cipher *sess;
/ Get ciphering context from session ID / DMSG("Session %p: cipher buffer", session); sess = (struct sm4_cipher *)session;
/ Safely get the invocation parameters / if (param_types != exp_param_types) return TEE_ERROR_BAD_PARAMETERS;
if (params[1].memref.size < params[0].memref.size) { EMSG("Bad sizes: in %d, out %d", params[0].memref.size, params[1].memref.size); return TEE_ERROR_BAD_PARAMETERS; }
if (sess->op_handle == TEE_HANDLE_NULL) return TEE_ERROR_BAD_STATE;
/*
TEE_Result sm4_read_raw_objectSetKey(void session, uint32_t param_types, TEE_Param params[4]) { const uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); TEE_ObjectHandle object; TEE_ObjectInfo object_info; TEE_Result res; uint32_t read_bytes; char obj_id; size_t obj_id_sz; char *data; size_t data_sz;
exit: TEE_CloseObject(object); TEE_Free(obj_id); TEE_Free(data); return res; }
TEE_Result sm4_read_raw_objectSetIv(void session, uint32_t param_types, TEE_Param params[4]) { const uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); TEE_ObjectHandle object; TEE_ObjectInfo object_info; TEE_Result res; uint32_t read_bytes; char obj_id; size_t obj_id_sz; char *data; size_t data_sz;
exit: TEE_CloseObject(object); TEE_Free(obj_id); TEE_Free(data); return TEE_SUCCESS; }
二 实际结果 加密的字符串是helloworld helloworld, 加密的key和iv 是C5438CB49497AF0704D66D88871FAD0E。 通过上述方法加密得到的结果是942078CAE85B0B51374F13534F6CA80200000000,与实际加密结果942078CAE85B0B51374F13534F6CA802B0CE4A80,最后几位不一致。尝试了其他字符串 也是最后几位不一致!!!
请问这个是哪里的问题呢? 通过上述方法加密得到的结果是