TEE_ObjectHandle在Crypto中的使用
Storage API和Crypto API中都會依賴TEE_ObjectHandle,該結構體可用于存儲:
- Secret key、Public keys、key-paris
- Persistent data、Transient data
TEE_ObjectHandle在Crypto中的使用
TEE_ObjectHandle key;
res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, key_size, &key);
調用TEE_AllocateTransientObject,填充的TEE_ObjectHandle ,指向在TEE底層的struct tee_obj結構體。
事實上在TEE底層分配tee_obj結構體,然后將數據拷貝到user層的,如copy_kaddr_to_uref(obj, o), obj就被上層的TEE_ObjectHandle 所指向,o指向的TEE OS中的struct tee_obj結構體
struct tee_obj結構體的原型如下所示,void *attr有指向KEY數組,根據key_type的不同選擇不同的數據類型
其實對于對稱的密碼算法,在底層對應的都是tee_cryp_obj_secret結構體:
也就是當我們調用TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, key_size, &key), 在TEE底層就根據key_type/key_size為我們分配好了數據類型.
那么如何獲取和填充這些結構體呢? 可以使用TEE_GetObjectBufferAttribute和TEE_InitRefAttribute兩個函數.
TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,uint32_t attributeID, void *buffer,uint32_t *size);TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,uint32_t attributeID, uint32_t *a,uint32_t *b);void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,const void *buffer, uint32_t length);void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,uint32_t a, uint32_t b);
例如這樣調用,從TEE_ObjectHandle rsa_key 中獲取d因子
res = TEE_GetObjectBufferAttribute(rsa_key, TEE_ATTR_RSA_MODULUS, addr, &read_bytes);
再例如使用TEE_ATTR_SECRET_VALUE將字符串類型的aeskey填入到TEE_ObjectHandle 結構體的使用示例:
TEE_ObjectHandle gen_key_aes_##name(char *key, size_t *key_sz) { TEE_Result res; TEE_Attribute attr; TEE_ObjectHandle aes_key; *key_sz = name / 8; generate_random(key, *key_sz); TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, name / 8); res = TEE_AllocateTransientObject(TEE_TYPE_AES, name, &aes_key); if(res != TEE_SUCCESS) {return res;}res = TEE_PopulateTransientObject(aes_key, &attr, 1); if(res != TEE_SUCCESS) {return res;}return (res == TEE_SUCCESS) ? aes_key : NULL; }上面的示例中調用TEE_InitRefAttribute函數填充TEE_Attribute attr屬性,事實上也可以直接填充,如下面這個示例;
attr.attributeID = TEE_ATTR_SECRET_VALUE;attr.content.ref.buffer = aes_key;attr.content.ref.length = keysize / 8;res = TEE_PopulateTransientObject(hkey, &attr, 1); (示例參考 : https://github.com/OP-TEE/optee_test/blob/master/ta/aes_perf/ta_aes_perf.c)有關TEE_Attribute屬性,原型如下:
(optee_os-3.12/out/arm/export-ta_arm64/include/tee_api_types.h) typedef struct {uint32_t attributeID;union {struct {void *buffer;uint32_t length;} ref;struct {uint32_t a, b;} value;} content; } TEE_Attribute;前面的兩個例子中分別:
- 使用TEE_InitRefAttribute構造了一個TEE_Attribute,然后再使用TEE_PopulateTransientObject轉換成TEE_ObjectHandle
- 直接填充TEE_Attribute,然后再使用TEE_PopulateTransientObject轉換成TEE_ObjectHandle
關于Transient Object類的API這里也做一個總結:
以下為代碼導讀
(optee_os-3.12/core/include/tee/tee_obj.h) struct tee_obj {TAILQ_ENTRY(tee_obj) link;TEE_ObjectInfo info;bool busy; /* true if used by an operation */uint32_t have_attrs; /* bitfield identifying set properties */void *attr;size_t ds_pos;struct tee_pobj *pobj; /* ptr to persistant object */struct tee_file_handle *fh; };(optee_os-3.12/out/arm/export-ta_arm64/include/tee_api_types.h) typedef struct {uint32_t objectType;__extension__ union {uint32_t keySize; /* used in 1.1 spec */uint32_t objectSize; /* used in 1.1.1 spec */};__extension__ union {uint32_t maxKeySize; /* used in 1.1 spec */uint32_t maxObjectSize; /* used in 1.1.1 spec */};uint32_t objectUsage;uint32_t dataSize;uint32_t dataPosition;uint32_t handleFlags; } TEE_ObjectInfo; (optee_os-3.12/lib/libutee/tee_api_objects.c) TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,uint32_t maxKeySize,TEE_ObjectHandle *object) {TEE_Result res;uint32_t obj;__utee_check_out_annotation(object, sizeof(*object));res = _utee_cryp_obj_alloc(objectType, maxKeySize, &obj);if (res != TEE_SUCCESS &&res != TEE_ERROR_OUT_OF_MEMORY &&res != TEE_ERROR_NOT_SUPPORTED)TEE_Panic(res);if (res == TEE_SUCCESS)*object = (TEE_ObjectHandle)(uintptr_t)obj;return res; }(optee_os-3.12/core/tee/tee_svc_cryp.c) TEE_Result syscall_cryp_obj_alloc(unsigned long obj_type,unsigned long max_key_size, uint32_t *obj) {struct ts_session *sess = ts_get_current_session();TEE_Result res = TEE_SUCCESS;struct tee_obj *o = NULL;o = tee_obj_alloc();if (!o)return TEE_ERROR_OUT_OF_MEMORY;res = tee_obj_set_type(o, obj_type, max_key_size);if (res != TEE_SUCCESS) {tee_obj_free(o);return res;}tee_obj_add(to_user_ta_ctx(sess->ctx), o);res = copy_kaddr_to_uref(obj, o);if (res != TEE_SUCCESS)tee_obj_close(to_user_ta_ctx(sess->ctx), o);return res; }(optee_os-3.12/core/include/tee/tee_obj.h) struct tee_obj {TAILQ_ENTRY(tee_obj) link;TEE_ObjectInfo info;bool busy; /* true if used by an operation */uint32_t have_attrs; /* bitfield identifying set properties */void *attr;size_t ds_pos;struct tee_pobj *pobj; /* ptr to persistant object */struct tee_file_handle *fh; };總結
以上是生活随笔為你收集整理的TEE_ObjectHandle在Crypto中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GPTEE中定义的RSA的Algorit
- 下一篇: GPTEE中的Storage API的使