linaro-swg / optee_examples

OP-TEE Sample Applications
Other
163 stars 140 forks source link

完全模仿aes实现sm4算法,加密结果最后几位不正确 #113

Closed hallowsman closed 3 months ago

hallowsman commented 3 months ago

一 以下代码是模仿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位

/*

/*

/*

err: if (sess->op_handle != TEE_HANDLE_NULL) TEE_FreeOperation(sess->op_handle); sess->op_handle = TEE_HANDLE_NULL;

if (sess->key_handle != TEE_HANDLE_NULL)
    TEE_FreeTransientObject(sess->key_handle);
sess->key_handle = TEE_HANDLE_NULL;

return res;

}

/*

/*

/*

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;

/*
 * Safely get the invocation parameters
 */
if (param_types != exp_param_types)
    return TEE_ERROR_BAD_PARAMETERS;

obj_id_sz = params[0].memref.size;
obj_id = TEE_Malloc(obj_id_sz, 0);
if (!obj_id)
    return TEE_ERROR_OUT_OF_MEMORY;

TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);

data_sz = 32; // 修改的地方
data = TEE_Malloc(data_sz, 0);
if (!data)
    return TEE_ERROR_OUT_OF_MEMORY;

/*
 * Check the object exist and can be dumped into output buffer
 * then dump it.
 */
res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
                               obj_id, obj_id_sz,
                               TEE_DATA_FLAG_ACCESS_READ |
                                   TEE_DATA_FLAG_SHARE_READ,
                               &object);
if (res != TEE_SUCCESS)
{
    EMSG("Failed to open persistent object, res=0x%08x", res);
    TEE_Free(obj_id);
    TEE_Free(data);
    return res;
}

res = TEE_GetObjectInfo1(object, &object_info);
if (res != TEE_SUCCESS)
{
    EMSG("Failed to create persistent object, res=0x%08x", res);
    goto exit;
}

if (object_info.dataSize > data_sz)
{
    /*
     * Provided buffer is too short.
     * Return the expected size together with status "short buffer"
     */
    // params[1].memref.size = object_info.dataSize;
    res = TEE_ERROR_SHORT_BUFFER;
    goto exit;
}

res = TEE_ReadObjectData(object, data, object_info.dataSize,
                         &read_bytes);
// if (res == TEE_SUCCESS) 修改的地方
//  TEE_MemMove(params[1].memref.buffer, data, read_bytes);
if (res != TEE_SUCCESS || read_bytes != object_info.dataSize)
{
    EMSG("TEE_ReadObjectData failed 0x%08x, read %" PRIu32 " over %u",
         res, read_bytes, object_info.dataSize);
    goto exit;
}

// /* Return the number of byte effectively filled */
// params[1].memref.size = read_bytes;

//////////////////////setkey////////////////////////////////////////
// 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 = 16;
// 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;
}

// DMSG("---------------------%s,sz=%d", data, data_sz);
//  TEE_MemMove(key, data, data_sz);

// DMSG("---------------------%s,sz=%d", key);
// // key = data;         // 修改的地方
// key_sz = data_sz; // 修改的地方

DMSG("-----进入setkey以后KEY %s::::::key_sz %d", data, data_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;
}

/*
 * Load the key material into the configured operation
 * - create a secret key attribute with the key material
 *   TEE_InitRefAttribute()
 * - reset transient object and load attribute data
 *   TEE_ResetTransientObject()
 *   TEE_PopulateTransientObject()
 * - load the key (transient object) into the ciphering operation
 *   TEE_SetOperationKey()
 *
 * TEE_SetOperationKey() requires operation to be in "initial state".
 * We can use TEE_ResetOperation() to reset the operation but this
 * API cannot be used on operation with key(s) not yet set. Hence,
 * when allocating the operation handle, we load a dummy key.
 * Thus, set_key sequence always reset then set key on operation.
 */

TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, data, 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;
}

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;

/*
 * Safely get the invocation parameters
 */
if (param_types != exp_param_types)
    return TEE_ERROR_BAD_PARAMETERS;

obj_id_sz = params[0].memref.size;
obj_id = TEE_Malloc(obj_id_sz, 0);
if (!obj_id)
    return TEE_ERROR_OUT_OF_MEMORY;

TEE_MemMove(obj_id, params[0].memref.buffer, obj_id_sz);

data_sz = 32; // 修改的地方
data = TEE_Malloc(data_sz, 0);
if (!data)
    return TEE_ERROR_OUT_OF_MEMORY;

/*
 * Check the object exist and can be dumped into output buffer
 * then dump it.
 */
res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE,
                               obj_id, obj_id_sz,
                               TEE_DATA_FLAG_ACCESS_READ |
                                   TEE_DATA_FLAG_SHARE_READ,
                               &object);
if (res != TEE_SUCCESS)
{
    EMSG("Failed to open persistent object, res=0x%08x", res);
    TEE_Free(obj_id);
    TEE_Free(data);
    return res;
}

res = TEE_GetObjectInfo1(object, &object_info);
if (res != TEE_SUCCESS)
{
    EMSG("Failed to create persistent object, res=0x%08x", res);
    goto exit;
}

if (object_info.dataSize > data_sz)
{
    /*
     * Provided buffer is too short.
     * Return the expected size together with status "short buffer"
     */
    // params[1].memref.size = object_info.dataSize;
    res = TEE_ERROR_SHORT_BUFFER;
    goto exit;
}

res = TEE_ReadObjectData(object, data, object_info.dataSize,
                         &read_bytes);
// if (res == TEE_SUCCESS)  修改的地方
//  TEE_MemMove(params[1].memref.buffer, data, read_bytes);
if (res != TEE_SUCCESS || read_bytes != object_info.dataSize)
{
    EMSG("TEE_ReadObjectData failed 0x%08x, read %" PRIu32 " over %u",
         res, read_bytes, object_info.dataSize);
    goto exit;
}

// /* Return the number of byte effectively filled */
// params[1].memref.size = read_bytes;

//////////////////////setiv////////////////////////////////////////
// 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 = 16;
// 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;

// strcpy(iv, data);
// // iv = data;         // 修改的地方
// iv_sz = data_sz; // 修改的地方

DMSG("-----进入iv以后iv %s::::::iv_sz %d", data, data_sz);

/*
 * Init cipher operation with the initialization vector.
 */
TEE_CipherInit(sess->op_handle, data, iv_sz);

exit: TEE_CloseObject(object); TEE_Free(obj_id); TEE_Free(data); return TEE_SUCCESS; }

二 实际结果 加密的字符串是helloworld helloworld, 加密的key和iv 是C5438CB49497AF0704D66D88871FAD0E。 通过上述方法加密得到的结果是942078CAE85B0B51374F13534F6CA80200000000,与实际加密结果942078CAE85B0B51374F13534F6CA802B0CE4A80,最后几位不一致。尝试了其他字符串 也是最后几位不一致!!!

请问这个是哪里的问题呢? 通过上述方法加密得到的结果是