static void popu_rsa_pub_key() { printf(" #### popu_rsa_pub_key ####\n"); TEE_Result ret; TEE_ObjectHandle rsa_pubkey; size_t key_size = 512; TEE_Attribute *params; size_t param_count = 2; ret = TEE_AllocateTransientObject(TEE_TYPE_RSA_PUBLIC_KEY, key_size, &rsa_pubkey); if (ret == TEE_ERROR_OUT_OF_MEMORY) { printf("Fail: no mem\n"); goto err; } if (ret == TEE_ERROR_NOT_SUPPORTED) { printf("Fail: no sup\n"); goto err; } params = TEE_Malloc(param_count * sizeof(TEE_Attribute), 0); if (params == NULL) goto err; // modulo params[0].attributeID = TEE_ATTR_RSA_MODULUS; params[0].content.ref.buffer = TEE_Malloc(KEY_IN_BYTES(key_size), 0); if (params[0].content.ref.buffer == NULL) goto err; RAND_bytes(params[0].content.ref.buffer, KEY_IN_BYTES(key_size)); params[0].content.ref.length = KEY_IN_BYTES(key_size); // pub exp params[1].attributeID = TEE_ATTR_RSA_PUBLIC_EXPONENT; params[1].content.ref.buffer = TEE_Malloc(KEY_IN_BYTES(key_size), 0); if (params[1].content.ref.buffer == NULL) goto err; RAND_bytes(params[1].content.ref.buffer, KEY_IN_BYTES(key_size)); params[1].content.ref.length = KEY_IN_BYTES(key_size); ret = TEE_PopulateTransientObject(rsa_pubkey, params, param_count); if (ret != TEE_SUCCESS) { printf("Fail: popu\n"); goto err; } err: free_attr(params, param_count); free(params); TEE_FreeTransientObject(rsa_pubkey); }
void *lws_zalloc(size_t size, const char *reason) { void *ptr = TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO); if (ptr) memset(ptr, 0, size); return ptr; }
TEE_Result TA_EXPORT TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[4], void **sessionContext) { TEE_Result tee_rv = TEE_SUCCESS; OT_LOG(LOG_INFO, "Calling the Open session entry point"); tee_rv = handle_params(paramTypes, params); if (tee_rv != TEE_SUCCESS) return tee_rv; if (storage_test(2)) return TEE_ERROR_GENERIC; if (crypto_test(2)) return TEE_ERROR_GENERIC; if (*sessionContext != NULL) { OT_LOG(LOG_ERR, "Session context should be NULL"); return TEE_ERROR_BAD_PARAMETERS; } *sessionContext = TEE_Malloc(SIZE_OF_VEC(out_vector), 0); if (*sessionContext == NULL) { OT_LOG(LOG_ERR, "Can not malloc space for session context"); return TEE_ERROR_OUT_OF_MEMORY; } TEE_MemMove(*sessionContext, out_vector, SIZE_OF_VEC(out_vector)); return tee_rv; }
static TEE_Result unpack_attrs(const uint8_t *buf, size_t blen, TEE_Attribute **attrs, uint32_t *attr_count) { TEE_Result res = TEE_SUCCESS; TEE_Attribute *a = NULL; const struct attr_packed *ap; size_t num_attrs = 0; const size_t num_attrs_size = sizeof(uint32_t); if (blen == 0) goto out; if (((uintptr_t)buf & 0x3) != 0 || blen < num_attrs_size) return TEE_ERROR_BAD_PARAMETERS; num_attrs = *(uint32_t *) (void *)buf; if ((blen - num_attrs_size) < (num_attrs * sizeof(*ap))) return TEE_ERROR_BAD_PARAMETERS; ap = (const struct attr_packed *)(const void *)(buf + num_attrs_size); if (num_attrs > 0) { size_t n; a = TEE_Malloc(num_attrs * sizeof(TEE_Attribute), 0); if (!a) return TEE_ERROR_OUT_OF_MEMORY; for (n = 0; n < num_attrs; n++) { uintptr_t p; a[n].attributeID = ap[n].id; #define TEE_ATTR_BIT_VALUE (1 << 29) if (ap[n].id & TEE_ATTR_BIT_VALUE) { a[n].content.value.a = ap[n].a; a[n].content.value.b = ap[n].b; continue; } a[n].content.ref.length = ap[n].b; p = (uintptr_t)ap[n].a; if (p) { if ((p + a[n].content.ref.length) > blen) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } p += (uintptr_t)buf; } a[n].content.ref.buffer = (void *)p; } } res = TEE_SUCCESS; out: if (res == TEE_SUCCESS) { *attrs = a; *attr_count = num_attrs; } else { TEE_Free(a); } return res; }
static TEE_Result unpack_attrs(const uint8_t *buf, size_t blen, TEE_Attribute **attrs, uint32_t *attr_count) { TEE_Result res = TEE_SUCCESS; TEE_Attribute *a = NULL; size_t num_attrs = 0; const size_t num_attrs_size = sizeof(uint32_t); if (blen == 0) goto out; if (((uint32_t) buf & 0x3) != 0 || blen < num_attrs_size) return TEE_ERROR_BAD_PARAMETERS; num_attrs = *(uint32_t *) (void *)buf; if ((blen - num_attrs_size) < (num_attrs * sizeof(TEE_Attribute))) return TEE_ERROR_BAD_PARAMETERS; if (num_attrs > 0) { size_t n; a = TEE_Malloc(num_attrs * sizeof(TEE_Attribute), 0); if (a == NULL) return TEE_ERROR_OUT_OF_MEMORY; TEE_MemMove(a, buf + num_attrs_size, num_attrs * sizeof(TEE_Attribute)); for (n = 0; n < num_attrs; n++) { uintptr_t p; #define TEE_ATTR_BIT_VALUE (1 << 29) if ((a[n].attributeID & TEE_ATTR_BIT_VALUE) != 0) continue; /* Only memrefs need to be updated */ p = (uintptr_t) a[n].content.ref.buffer; if (p == 0) continue; if ((p + a[n].content.ref.length) > blen) { res = TEE_ERROR_BAD_PARAMETERS; goto out; } p += (uintptr_t) buf; a[n].content.ref.buffer = (void *)p; } } res = TEE_SUCCESS; out: if (res == TEE_SUCCESS) { *attrs = a; *attr_count = num_attrs; } else { TEE_Free(a); } return res; }
/*------------------------------------------------------------ * * test_BigIntInit * */ static void test_BigIntInit(void) { TEE_BigInt *a; size_t aLen; TB_INFO("Testing BigIntInit"); /* Testing normal allocation and initialization */ aLen = TEE_BigIntSizeInU32(512); a = (TEE_BigInt *) TEE_Malloc(aLen * sizeof(TEE_BigInt), 0); TEE_BigIntInit(a, aLen); TEE_Free(a); /* Testing zero allocation */ aLen = TEE_BigIntSizeInU32(0); a = (TEE_BigInt *) TEE_Malloc(aLen * sizeof(TEE_BigInt), 0); TEE_BigIntInit(a, aLen); TEE_Free(a); /* Testing too large */ aLen = TEE_BigIntSizeInU32(4096); a = (TEE_BigInt *) TEE_Malloc(aLen * sizeof(TEE_BigInt), 0); TEE_BigIntInit(a, aLen); TEE_Free(a); /* Testing boundaries */ aLen = TEE_BigIntSizeInU32(2048); a = (TEE_BigInt *) TEE_Malloc(aLen * sizeof(TEE_BigInt), 0); TEE_BigIntInit(a, aLen); TEE_Free(a); aLen = TEE_BigIntSizeInU32(2049); a = (TEE_BigInt *) TEE_Malloc(aLen * sizeof(TEE_BigInt), 0); TEE_BigIntInit(a, aLen); TEE_Free(a); }
TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle *enumerator) { struct prop_enumerator *pe; if (enumerator == NULL) return TEE_ERROR_BAD_PARAMETERS; pe = TEE_Malloc(sizeof(struct prop_enumerator), TEE_USER_MEM_HINT_NO_FILL_ZERO); if (pe == NULL) return TEE_ERROR_OUT_OF_MEMORY; *enumerator = (TEE_PropSetHandle) pe; TEE_ResetPropertyEnumerator(*enumerator); return TEE_SUCCESS; }
void *lws_malloc(size_t size, const char *reason) { return TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO); }
TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, uint32_t algorithm, uint32_t mode, uint32_t maxKeySize) { TEE_Result res; TEE_OperationHandle op = TEE_HANDLE_NULL; uint32_t handle_state = 0; size_t block_size = 1; uint32_t req_key_usage; bool with_private_key = false; bool buffer_two_blocks = false; if (!operation) TEE_Panic(0); if (algorithm == TEE_ALG_AES_XTS) handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; /* Check algorithm max key size */ switch (algorithm) { case TEE_ALG_DSA_SHA1: if (maxKeySize < 512) return TEE_ERROR_NOT_SUPPORTED; if (maxKeySize > 1024) return TEE_ERROR_NOT_SUPPORTED; if (maxKeySize % 64 != 0) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_DSA_SHA224: if (maxKeySize != 2048) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_DSA_SHA256: if (maxKeySize != 2048 && maxKeySize != 3072) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_ECDSA_P192: case TEE_ALG_ECDH_P192: if (maxKeySize != 192) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_ECDSA_P224: case TEE_ALG_ECDH_P224: if (maxKeySize != 224) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_ECDSA_P256: case TEE_ALG_ECDH_P256: if (maxKeySize != 256) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_ECDSA_P384: case TEE_ALG_ECDH_P384: if (maxKeySize != 384) return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_ECDSA_P521: case TEE_ALG_ECDH_P521: if (maxKeySize != 521) return TEE_ERROR_NOT_SUPPORTED; break; default: break; } /* Check algorithm mode */ switch (algorithm) { case TEE_ALG_AES_CTS: case TEE_ALG_AES_XTS: buffer_two_blocks = true; /*FALLTHROUGH*/ case TEE_ALG_AES_ECB_NOPAD: case TEE_ALG_AES_CBC_NOPAD: case TEE_ALG_AES_CTR: case TEE_ALG_AES_CCM: case TEE_ALG_AES_GCM: case TEE_ALG_DES_ECB_NOPAD: case TEE_ALG_DES_CBC_NOPAD: case TEE_ALG_DES3_ECB_NOPAD: case TEE_ALG_DES3_CBC_NOPAD: if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES) block_size = TEE_AES_BLOCK_SIZE; else block_size = TEE_DES_BLOCK_SIZE; if (mode == TEE_MODE_ENCRYPT) req_key_usage = TEE_USAGE_ENCRYPT; else if (mode == TEE_MODE_DECRYPT) req_key_usage = TEE_USAGE_DECRYPT; else return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: case TEE_ALG_DSA_SHA1: case TEE_ALG_DSA_SHA224: case TEE_ALG_DSA_SHA256: case TEE_ALG_ECDSA_P192: case TEE_ALG_ECDSA_P224: case TEE_ALG_ECDSA_P256: case TEE_ALG_ECDSA_P384: case TEE_ALG_ECDSA_P521: if (mode == TEE_MODE_SIGN) { with_private_key = true; req_key_usage = TEE_USAGE_SIGN; } else if (mode == TEE_MODE_VERIFY) { req_key_usage = TEE_USAGE_VERIFY; } else { return TEE_ERROR_NOT_SUPPORTED; } break; case TEE_ALG_RSAES_PKCS1_V1_5: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: if (mode == TEE_MODE_ENCRYPT) { req_key_usage = TEE_USAGE_ENCRYPT; } else if (mode == TEE_MODE_DECRYPT) { with_private_key = true; req_key_usage = TEE_USAGE_DECRYPT; } else { return TEE_ERROR_NOT_SUPPORTED; } break; case TEE_ALG_RSA_NOPAD: if (mode == TEE_MODE_ENCRYPT) { req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; } else if (mode == TEE_MODE_DECRYPT) { with_private_key = true; req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; } else { return TEE_ERROR_NOT_SUPPORTED; } break; case TEE_ALG_DH_DERIVE_SHARED_SECRET: case TEE_ALG_ECDH_P192: case TEE_ALG_ECDH_P224: case TEE_ALG_ECDH_P256: case TEE_ALG_ECDH_P384: case TEE_ALG_ECDH_P521: case TEE_ALG_HKDF_MD5_DERIVE_KEY: case TEE_ALG_HKDF_SHA1_DERIVE_KEY: case TEE_ALG_HKDF_SHA224_DERIVE_KEY: case TEE_ALG_HKDF_SHA256_DERIVE_KEY: case TEE_ALG_HKDF_SHA384_DERIVE_KEY: case TEE_ALG_HKDF_SHA512_DERIVE_KEY: case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY: case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY: case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY: case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY: case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY: case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY: if (mode != TEE_MODE_DERIVE) return TEE_ERROR_NOT_SUPPORTED; with_private_key = true; req_key_usage = TEE_USAGE_DERIVE; break; case TEE_ALG_MD5: case TEE_ALG_SHA1: case TEE_ALG_SHA224: case TEE_ALG_SHA256: case TEE_ALG_SHA384: case TEE_ALG_SHA512: if (mode != TEE_MODE_DIGEST) return TEE_ERROR_NOT_SUPPORTED; /* v1.1: flags always set for digest operations */ handle_state |= TEE_HANDLE_FLAG_KEY_SET; req_key_usage = 0; break; case TEE_ALG_DES_CBC_MAC_NOPAD: case TEE_ALG_AES_CBC_MAC_NOPAD: case TEE_ALG_AES_CBC_MAC_PKCS5: case TEE_ALG_AES_CMAC: case TEE_ALG_DES_CBC_MAC_PKCS5: case TEE_ALG_DES3_CBC_MAC_NOPAD: case TEE_ALG_DES3_CBC_MAC_PKCS5: case TEE_ALG_HMAC_MD5: case TEE_ALG_HMAC_SHA1: case TEE_ALG_HMAC_SHA224: case TEE_ALG_HMAC_SHA256: case TEE_ALG_HMAC_SHA384: case TEE_ALG_HMAC_SHA512: if (mode != TEE_MODE_MAC) return TEE_ERROR_NOT_SUPPORTED; req_key_usage = TEE_USAGE_MAC; break; default: return TEE_ERROR_NOT_SUPPORTED; } op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO); if (!op) return TEE_ERROR_OUT_OF_MEMORY; op->info.algorithm = algorithm; op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); op->info.mode = mode; op->info.maxKeySize = maxKeySize; op->info.requiredKeyUsage = req_key_usage; op->info.handleState = handle_state; if (block_size > 1) { size_t buffer_size = block_size; if (buffer_two_blocks) buffer_size *= 2; op->buffer = TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); if (op->buffer == NULL) { res = TEE_ERROR_OUT_OF_MEMORY; goto out; } } op->block_size = block_size; op->buffer_two_blocks = buffer_two_blocks; if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { uint32_t mks = maxKeySize; TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, with_private_key); /* * If two keys are expected the max key size is the sum of * the size of both keys. */ if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) mks /= 2; res = TEE_AllocateTransientObject(key_type, mks, &op->key1); if (res != TEE_SUCCESS) goto out; if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { res = TEE_AllocateTransientObject(key_type, mks, &op->key2); if (res != TEE_SUCCESS) goto out; } } res = utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1, (unsigned long)op->key2, &op->state); if (res != TEE_SUCCESS) goto out; /* * Initialize digest operations * Other multi-stage operations initialized w/ TEE_xxxInit functions * Non-applicable on asymmetric operations */ if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) { res = utee_hash_init(op->state, NULL, 0); if (res != TEE_SUCCESS) goto out; /* v1.1: flags always set for digest operations */ op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; } op->operationState = TEE_OPERATION_STATE_INITIAL; *operation = op; out: if (res != TEE_SUCCESS) { if (res != TEE_ERROR_OUT_OF_MEMORY && res != TEE_ERROR_NOT_SUPPORTED) TEE_Panic(0); if (op) { if (op->state) { TEE_FreeOperation(op); } else { TEE_Free(op->buffer); TEE_FreeTransientObject(op->key1); TEE_FreeTransientObject(op->key2); TEE_Free(op); } } } return res; }
static TEE_Result ta_stroage_benchmark_chunk_access_test(uint32_t nCommandID, uint32_t param_types, TEE_Param params[4]) { TEE_Result res; size_t data_size; size_t chunk_size; TEE_ObjectHandle object = TEE_HANDLE_NULL; uint8_t *chunk_buf; uint32_t *spent_time_in_ms = ¶ms[2].value.a; bool do_verify; ASSERT_PARAM_TYPE(param_types, TEE_PARAM_TYPES( TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_VALUE_OUTPUT, TEE_PARAM_TYPE_NONE)); data_size = params[0].value.a; chunk_size = params[0].value.b; do_verify = params[1].value.a; if (data_size == 0) data_size = DEFAULT_DATA_SIZE; if (chunk_size == 0) chunk_size = DEFAULT_CHUNK_SIZE; IMSG("command id: %u, test data size: %zd, chunk size: %zd\n", nCommandID, data_size, chunk_size); chunk_buf = TEE_Malloc(chunk_size, TEE_MALLOC_FILL_ZERO); if (!chunk_buf) { EMSG("Failed to allocate memory"); res = TEE_ERROR_OUT_OF_MEMORY; goto exit; } fill_buffer(chunk_buf, chunk_size); res = prepare_test_file(data_size, chunk_buf, chunk_size); if (res != TEE_SUCCESS) { EMSG("Failed to create test file, res=0x%08x", res); goto exit_free_chunk_buf; } res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, filename, sizeof(filename), TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE | TEE_DATA_FLAG_ACCESS_WRITE_META | TEE_DATA_FLAG_OVERWRITE, &object); if (res != TEE_SUCCESS) { EMSG("Failed to open persistent object, res=0x%08x", res); goto exit_remove_object; } switch (nCommandID) { case TA_STORAGE_BENCHMARK_CMD_TEST_READ: res = test_read(object, data_size, chunk_buf, chunk_size, spent_time_in_ms); break; case TA_STORAGE_BENCHMARK_CMD_TEST_WRITE: res = test_write(object, data_size, chunk_buf, chunk_size, spent_time_in_ms); break; case TA_STORAGE_BENCHMARK_CMD_TEST_REWRITE: res = test_rewrite(object, data_size, chunk_buf, chunk_size, spent_time_in_ms); break; default: res = TEE_ERROR_BAD_PARAMETERS; } if (res != TEE_SUCCESS) goto exit_remove_object; if (do_verify) res = verify_file_data(object, data_size, chunk_buf, chunk_size); exit_remove_object: TEE_CloseAndDeletePersistentObject1(object); exit_free_chunk_buf: TEE_Free(chunk_buf); exit: return res; }
/** * @brief */ void test_storage_api() { uint32_t storageID=TEE_OBJECT_STORAGE_PRIVATE, r_flags=TEE_DATA_FLAG_ACCESS_READ, w_flags=TEE_DATA_FLAG_ACCESS_WRITE, rw_flags=(TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE), a_attribute_val=0x00000005,b_attribute_val=0x00000007, pop_ret_val,attribute_cnt=0x00000003,seek_ret_val,open_seek_retval, crt_ret_val,write_ret_val,open_write_retval,read_ret_val, open_read_retval,open_ret_val,open_delete_retval,allocate1_ret_val, allocate2_ret_val,rd_trunc_cnt=0x00000000,open_truncate_retval, trunc_size=0x0000000A,truncate_ret_val,rdtest_truncated_retval, optest_truncated_retval,rdtest_written_retval, optest_written_retval,rd_write_cnt=0x00000000,read_cnt=0x00000000, trunc_cnt=0x00000000,open_rename_retval,de_a, rd_rename_cnt=0x00000000,optest_renamed_retval,rename_ret_val, rdtest_renamed_retval,optest_deleted_retval; typedef signed int int32_t; int32_t offset=0x00000003; size_t objectIDLen=0x00000040,read_size=0x0000000F,rd_trunc_size=0x0000000A, rd_write_size=0x0000002C,rd_rename_size=0x0000000C; void* open_objectID="/test.dir/test.txt"; void* rename_objectID="/test.dir/new.txt"; void* initialData="This a sierraware created sample initial data\n"; void* create_objectID="/test.dir/crt.txt"; void* read_objectID="/test.dir/read.txt"; void* write_objectID="/test.dir/write.txt"; void* seek_objectID="/test.dir/seek.txt"; void* delete_objectID="/test.dir/delete.txt"; void* trunc_objectID="/test.dir/truncate.txt"; char wrie_buffer[255]={"This a sierraware created sample test string\n"}; char read_buffer[255],rd_trunc_buffer[255],rd_write_buffer[255], rd_rename_buffer[255]; void* attrsbuffer="This will get populated sometimes in the test fn\n"; void* p_buffer="And finally we tested GP_INTERNAL_STORAGE APP\n"; TEE_ObjectHandle crtattributes; TEE_ObjectHandle *first_object; TEE_ObjectHandle *second_object; TEE_Whence whence; whence=0x00000000; sw_printf("-----------Allocating Memory For Create Object--------------\n"); first_object=(TEE_ObjectHandle*)TEE_Malloc(sizeof(TEE_ObjectHandle),0); sw_printf("-------Allocating Memory For Create Object members----------\n"); allocate1_ret_val=TEE_AllocateTransientObject(TEE_TYPE_AES,0x00000800, first_object); sw_printf("the allocate transient function returns value is %x \n", allocate1_ret_val); crt_ret_val=TEE_CreatePersistentObject(storageID,create_objectID, objectIDLen,w_flags,crtattributes,initialData, (size_t)(sw_strlen((char*)initialData)),first_object); sw_printf("The create Persistent object funtion \ returns value is %x \n \n",crt_ret_val); sw_printf("------------Allocating Memory For open Object---------------\n"); second_object=(TEE_ObjectHandle*)TEE_Malloc(sizeof(TEE_ObjectHandle),0); sw_printf("------------Allocating Memory For open Object members-------\n"); allocate2_ret_val=TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, 0x00000800,second_object); sw_printf("the allocate transient function returns value is %x \n", allocate2_ret_val); open_ret_val=TEE_OpenPersistentObject(storageID,open_objectID,objectIDLen, r_flags,second_object); sw_printf("The open Persistent object funtion returns value is %x \n \n", open_ret_val); sw_printf("*****Reset the open object***** \n"); TEE_ResetTransientObject(*second_object); open_read_retval=TEE_OpenPersistentObject(storageID,read_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_read_retval); read_ret_val=TEE_ReadObjectData(*second_object,(void*)&read_buffer, read_size,&read_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", read_ret_val); sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_write_retval=TEE_OpenPersistentObject(storageID,write_objectID, objectIDLen,w_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_write_retval); write_ret_val=TEE_WriteObjectData(*second_object,(void*)&wrie_buffer, (size_t)(sw_strlen((char*)&wrie_buffer))); sw_printf("The write Persistent funtion returns value is %x \n \n", write_ret_val); sw_printf("*****Reset the write object***** \n"); TEE_ResetTransientObject(*second_object); optest_written_retval=TEE_OpenPersistentObject(storageID,write_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_written_retval); rdtest_written_retval=TEE_ReadObjectData(*second_object, (void*)&rd_write_buffer,rd_write_size, &rd_write_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", rdtest_written_retval); sw_printf("******TESTING:write persistent object*******\n"); if(rdtest_written_retval==1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILURE \n"); } sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_truncate_retval=TEE_OpenPersistentObject(storageID,trunc_objectID, objectIDLen,w_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_truncate_retval); truncate_ret_val=TEE_TruncateObjectData(*second_object,trunc_size); sw_printf("The truncate Persistent funtion returns value is %x \n \n", truncate_ret_val); sw_printf("*****Reset the truncate object***** \n"); TEE_ResetTransientObject(*second_object); optest_truncated_retval=TEE_OpenPersistentObject(storageID,trunc_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_truncated_retval); rdtest_truncated_retval=TEE_ReadObjectData(*second_object, (void*)&rd_trunc_buffer,rd_trunc_size, &rd_trunc_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", rdtest_truncated_retval); sw_printf("******TESTING:truncate persistent object*******\n"); if(rdtest_truncated_retval==1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILS \n"); } sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_rename_retval=TEE_OpenPersistentObject(storageID,open_objectID, objectIDLen,rw_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_rename_retval); rename_ret_val=TEE_RenamePersistentObject(*second_object,rename_objectID, objectIDLen); sw_printf("The rename Persistent funtion returns value is %x \n \n", rename_ret_val); sw_printf("*****Reset the rename object***** \n"); TEE_ResetTransientObject(*second_object); optest_renamed_retval=TEE_OpenPersistentObject(storageID,rename_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_renamed_retval); rdtest_renamed_retval=TEE_ReadObjectData(*second_object, (void*)&rd_rename_buffer,rd_rename_size, &rd_rename_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", rdtest_renamed_retval); sw_printf("******TESTING:rename persistent object*******\n"); if(rdtest_renamed_retval==1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILS \n"); } sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_seek_retval=TEE_OpenPersistentObject(storageID,seek_objectID, objectIDLen,rw_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_seek_retval); seek_ret_val=TEE_SeekObjectData(*second_object,offset,whence); sw_printf("The seek Persistent funtion returns value is %x \n \n", seek_ret_val); sw_printf("*****Reset the seek object***** \n"); TEE_ResetTransientObject(*second_object); open_delete_retval=TEE_OpenPersistentObject(storageID,delete_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion returns value is %x \n", open_delete_retval); TEE_CloseAndDeletePersistentObject(*second_object); sw_printf("*****Reset the close object***** \n"); TEE_ResetTransientObject(*second_object); optest_deleted_retval=TEE_OpenPersistentObject(storageID,delete_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_deleted_retval); sw_printf("******TESTING:close and delete persistent object*******\n"); if(optest_deleted_retval!=1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILS\n"); } sw_printf("*****Reset the seek object***** \n"); TEE_ResetTransientObject(*second_object); TEE_Attribute* attref; attref=(TEE_Attribute*)TEE_Malloc(sizeof(TEE_Attribute),0); TEE_InitRefAttribute(attref,0x00000001,p_buffer, (size_t)(sw_strlen((char*)p_buffer))); TEE_Free((void*)attref); TEE_Attribute* attval; attval=(TEE_Attribute*)TEE_Malloc(sizeof(TEE_Attribute),0); TEE_InitValueAttribute(attval,0x20000000,a_attribute_val,b_attribute_val); TEE_Free((void*)attval); TEE_Attribute attributes[3]; attributes[0].attributeID=0x20000000; attributes[0].content.value.a=0x0000000A; attributes[0].content.value.b=0x0000000B; attributes[1].attributeID=0x00000275; attributes[1].content.ref.length=(size_t)(sw_strlen((char*)attrsbuffer)); attributes[1].content.ref.buffer=TEE_Malloc (attributes[1].content.ref.length,0); TEE_MemCpy(attributes[1].content.ref.buffer,attrsbuffer, (u32)(attributes[1].content.ref.length)); attributes[2].attributeID=0x23425676; attributes[2].content.value.a=0x0000001E; attributes[2].content.value.b=0x0000001F; pop_ret_val=TEE_PopulateTransientObject(*second_object,attributes, attribute_cnt); sw_printf("the populate transient function returns value is %x \n", pop_ret_val); sw_printf("*****Reset the populate object***** \n"); TEE_ResetTransientObject(*second_object); TEE_CopyObjectAttributes(*second_object,*first_object); sw_printf("*****free the create object by call TEE_FreeTransientObject \ fn***** \n"); TEE_FreeTransientObject(*first_object); sw_printf("*****free the common object by call TEE_FreeTransientObject \ fn***** \n"); TEE_FreeTransientObject(*second_object); sw_printf("--------------Program Successfully Terminated--------------\n"); }
static TEE_Result rpc_call_cryp(bool sec_mem, uint32_t nParamTypes, TEE_Param pParams[4], uint32_t cmd) { TEE_TASessionHandle cryp_session; TEE_Result res; uint32_t origin; TEE_Param params[4]; size_t n; uint32_t types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE); TEE_MemFill(params, 0, sizeof(TEE_Param) * 4); res = TEE_OpenTASession(&cryp_uuid, 0, types, params, &cryp_session, &origin); if (res != TEE_SUCCESS) { EMSG("rpc_sha256 - TEE_OpenTASession returned 0x%x\n", (unsigned int)res); return res; } types = nParamTypes; if (sec_mem) { TEE_MemFill(params, 0, sizeof(params)); for (n = 0; n < 4; n++) { switch (TEE_PARAM_TYPE_GET(types, n)) { case TEE_PARAM_TYPE_VALUE_INPUT: case TEE_PARAM_TYPE_VALUE_INOUT: params[n].value = pParams[n].value; break; case TEE_PARAM_TYPE_MEMREF_INPUT: case TEE_PARAM_TYPE_MEMREF_OUTPUT: case TEE_PARAM_TYPE_MEMREF_INOUT: params[n].memref.buffer = TEE_Malloc(pParams[n].memref.size, 0); if (!params[n].memref.buffer) TEE_Panic(0); params[n].memref.size = pParams[n].memref.size; if (TEE_PARAM_TYPE_GET(types, n) != TEE_PARAM_TYPE_MEMREF_OUTPUT) TEE_MemMove(params[n].memref.buffer, pParams[n].memref.buffer, pParams[n].memref.size); break; default: break; } } } else { TEE_MemMove(params, pParams, sizeof(params)); } res = TEE_InvokeTACommand(cryp_session, 0, cmd, types, params, &origin); if (res != TEE_SUCCESS) { EMSG("rpc_call_cryp - TEE_InvokeTACommand returned 0x%x\n", (unsigned int)res); } TEE_CloseTASession(cryp_session); if (sec_mem) { for (n = 0; n < 4; n++) { switch (TEE_PARAM_TYPE_GET(types, n)) { case TEE_PARAM_TYPE_VALUE_INOUT: case TEE_PARAM_TYPE_VALUE_OUTPUT: pParams[n].value = params[n].value; break; case TEE_PARAM_TYPE_MEMREF_INPUT: case TEE_PARAM_TYPE_MEMREF_OUTPUT: case TEE_PARAM_TYPE_MEMREF_INOUT: if (TEE_PARAM_TYPE_GET(types, n) != TEE_PARAM_TYPE_MEMREF_INPUT) TEE_MemMove(pParams[n].memref.buffer, params[n].memref.buffer, params[n].memref.size); pParams[n].memref.size = params[n].memref.size; TEE_Free(params[n].memref.buffer); break; default: break; } } } return res; }
TEE_Result TA_EXPORT TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID, uint32_t paramTypes, TEE_Param params[4]) { sessionContext = sessionContext; paramTypes = paramTypes; OT_LOG(LOG_ERR, "Calling the Invoke command entry point"); if (commandID == TEST_PERSISTENT) { int count = params[0].value.a; while (count--) ta_storage_test(params[0].value.b); } else if (commandID == TEST_MSG) { int count2 = params[0].value.a; while (count2--) { int count = params[0].value.b; while (count--) { TEE_Result retVal = TEE_SUCCESS; struct com_mgr_invoke_cmd_payload payload, returnPayload; payload.size = count; payload.data = TEE_Malloc(payload.size, 0); TEE_MemFill(payload.data, 0x77, payload.size); if (payload.data) { retVal = TEE_InvokeMGRCommand(TEE_TIMEOUT_INFINITE, COM_MGR_CMD_ID_TEST_COMM, &payload, &returnPayload); if ((retVal == TEE_SUCCESS) && (returnPayload.size-sizeof(struct com_mgr_invoke_cmd_payload)) == payload.size) { bool check = true; unsigned int n; for (n = 0; n < payload.size && check; n++) { char *s = payload.data; char *r = returnPayload.data; check = s[n] == r[payload.size-1-n]; } TEE_Free(returnPayload.data); if (!check) return TEE_ERROR_COMMUNICATION; } else if (retVal == TEE_SUCCESS && returnPayload.size == 0 && returnPayload.size == payload.size) { /* this is ok */ } else { return TEE_ERROR_COMMUNICATION; } TEE_Free(payload.data); } } } } else { OT_LOG(LOG_ERR, "Unknow command ID"); } return TEE_SUCCESS; }
int main(int argc, char **argv) { TEE_Result res; uint32_t crypt_mode; // TEE_MODE_ENCRYPT or TEE_MODE_DECRYPT unsigned char mess[] = \ "\x01\x23\x45\x67\x89\xAB\xCD\xEF" \ "\xFE\xDC\xBA\x98\x76\x54\x32\x10" \ "2222222222222222"\ "5555555555555555"\ "3333333333333333"\ "0000000000000000"\ "7777777777777777"\ "4444444444444444"\ "8888888888888888"\ "6666666666666666"\ "1111111111111111"\ "9999999999999999"; size_t mess_len = 96; // multiples of Aes algorithm key block_size (block_size of AES is 16 Bytes) unsigned char key[] = "\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10"\ "\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10"; size_t key_len = 16; // 128bits = 16Bytes, 192bits = 24Bytes, 256bits = 32Bytes unsigned char IV[] = "\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10"\ "\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFE\xDC\xBA\x98\x76\x54\x32\x10"; size_t IV_len = key_len; /* [0x01] Init crypt context */ if(TEE_InitCryptContext() != TEE_SUCCESS) { TEE_Printf("[err] TEE_InitCryptContext\n"); return 0; } TEE_Printf("\n============================TEE_MODE_ENCRYPT============================\n"); /* [0x02] Encrypt: aes-128-cbc */ size_t cipher_len = mess_len; void *cipher = TEE_Malloc(cipher_len, 0); if(!cipher) { TEE_Printf("[err] TEE_Malloc\n"); return 0; } crypt_mode = TEE_MODE_ENCRYPT; res = crypt_cipher_aes_cbc((const void *)mess, mess_len, (const void *)key, key_len, cipher, &cipher_len, IV, IV_len, crypt_mode); if(res != TEE_SUCCESS) { TEE_Printf("[err] crypt_cipher_aes_cbc::TEE_MODE_ENCRYPT\n"); return 0; } if( cipher_len > 0) { TEE_Hexdump("crypt_cipher_aes_cbc::plain", mess, mess_len, 16, true); TEE_Hexdump("crypt_cipher_aes_cbc::key", key, key_len, 16, true); TEE_Hexdump("crypt_cipher_aes_cbc::IV", IV, IV_len, 16, true); TEE_Hexdump("crypt_cipher_aes_cbc::cipher", cipher, cipher_len, 16, true); } TEE_Printf("\n============================TEE_MODE_DECRYPT============================\n"); /* [0x03] Decrypt : aes-128-cbc */ size_t plain_len = cipher_len; void *plain = TEE_Malloc(plain_len, 0); if(!plain) { TEE_Printf("[err] TEE_Malloc\n"); return 0; } crypt_mode = TEE_MODE_DECRYPT; res = crypt_cipher_aes_cbc((const void *)cipher, cipher_len, (const void *)key, key_len, plain, &plain_len, IV, IV_len, crypt_mode); if(res != TEE_SUCCESS) { TEE_Printf("[err] crypt_cipher_aes_cbc::TEE_MODE_DECRYPT\n"); return 0; } if( plain_len > 0) { TEE_Hexdump("crypt_cipher_aes_cbc::cipher", cipher, cipher_len, 16, true); TEE_Hexdump("crypt_cipher_aes_cbc::key", key, key_len, 16, true); TEE_Hexdump("crypt_cipher_aes_cbc::IV", IV, IV_len, 16, true); TEE_Hexdump("crypt_cipher_aes_cbc::plain", plain, plain_len, 16, true); } /* [0x04] Cleanup crypt context */ if(TEE_FiniCryptContext() != TEE_SUCCESS) { TEE_Printf("[err] TEE_FiniCryptContext\n"); } exit(0); return 0; }
TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, uint32_t algorithm, uint32_t mode, uint32_t maxKeySize) { TEE_Result res; TEE_OperationHandle op = TEE_HANDLE_NULL; uint32_t handle_state = 0; size_t block_size = 1; uint32_t req_key_usage; bool with_private_key = false; bool buffer_two_blocks = false; if (operation == NULL) TEE_Panic(0); if (algorithm == TEE_ALG_AES_XTS) handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; switch (algorithm) { case TEE_ALG_AES_CTS: case TEE_ALG_AES_XTS: buffer_two_blocks = true; /*FALLTHROUGH*/ case TEE_ALG_AES_ECB_NOPAD: case TEE_ALG_AES_CBC_NOPAD: case TEE_ALG_AES_CTR: case TEE_ALG_AES_CCM: case TEE_ALG_AES_GCM: case TEE_ALG_DES_ECB_NOPAD: case TEE_ALG_DES_CBC_NOPAD: case TEE_ALG_DES3_ECB_NOPAD: case TEE_ALG_DES3_CBC_NOPAD: if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES) block_size = TEE_AES_BLOCK_SIZE; else block_size = TEE_DES_BLOCK_SIZE; if (mode == TEE_MODE_ENCRYPT) req_key_usage = TEE_USAGE_ENCRYPT; else if (mode == TEE_MODE_DECRYPT) req_key_usage = TEE_USAGE_DECRYPT; else return TEE_ERROR_NOT_SUPPORTED; break; case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: case TEE_ALG_DSA_SHA1: if (mode == TEE_MODE_SIGN) { with_private_key = true; req_key_usage = TEE_USAGE_SIGN; } else if (mode == TEE_MODE_VERIFY) { req_key_usage = TEE_USAGE_VERIFY; } else { return TEE_ERROR_NOT_SUPPORTED; } break; case TEE_ALG_RSAES_PKCS1_V1_5: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: if (mode == TEE_MODE_ENCRYPT) { req_key_usage = TEE_USAGE_ENCRYPT; } else if (mode == TEE_MODE_DECRYPT) { with_private_key = true; req_key_usage = TEE_USAGE_DECRYPT; } else { return TEE_ERROR_NOT_SUPPORTED; } break; case TEE_ALG_RSA_NOPAD: if (mode == TEE_MODE_ENCRYPT) { req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; } else if (mode == TEE_MODE_DECRYPT) { with_private_key = true; req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; } else { return TEE_ERROR_NOT_SUPPORTED; } break; case TEE_ALG_DH_DERIVE_SHARED_SECRET: if (mode != TEE_MODE_DERIVE) return TEE_ERROR_NOT_SUPPORTED; with_private_key = true; req_key_usage = TEE_USAGE_DERIVE; break; case TEE_ALG_MD5: case TEE_ALG_SHA1: case TEE_ALG_SHA224: case TEE_ALG_SHA256: case TEE_ALG_SHA384: case TEE_ALG_SHA512: if (mode != TEE_MODE_DIGEST) return TEE_ERROR_NOT_SUPPORTED; handle_state |= TEE_HANDLE_FLAG_KEY_SET; req_key_usage = 0; break; case TEE_ALG_DES_CBC_MAC_NOPAD: case TEE_ALG_AES_CBC_MAC_NOPAD: case TEE_ALG_AES_CBC_MAC_PKCS5: case TEE_ALG_AES_CMAC: case TEE_ALG_DES_CBC_MAC_PKCS5: case TEE_ALG_DES3_CBC_MAC_NOPAD: case TEE_ALG_DES3_CBC_MAC_PKCS5: case TEE_ALG_HMAC_MD5: case TEE_ALG_HMAC_SHA1: case TEE_ALG_HMAC_SHA224: case TEE_ALG_HMAC_SHA256: case TEE_ALG_HMAC_SHA384: case TEE_ALG_HMAC_SHA512: if (mode != TEE_MODE_MAC) return TEE_ERROR_NOT_SUPPORTED; req_key_usage = TEE_USAGE_MAC; break; default: return TEE_ERROR_NOT_SUPPORTED; } op = TEE_Malloc(sizeof(*op), 0); if (op == NULL) return TEE_ERROR_OUT_OF_MEMORY; op->info.algorithm = algorithm; op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); op->info.mode = mode; op->info.maxKeySize = maxKeySize; op->info.requiredKeyUsage = req_key_usage; op->info.handleState = handle_state; if (block_size > 1) { size_t buffer_size = block_size; if (buffer_two_blocks) buffer_size *= 2; op->buffer = TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); if (op->buffer == NULL) { res = TEE_ERROR_OUT_OF_MEMORY; goto out; } } op->block_size = block_size; op->buffer_two_blocks = buffer_two_blocks; if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { uint32_t mks = maxKeySize; TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, with_private_key); /* * If two keys are expected the max key size is the sum of * the size of both keys. */ if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) mks /= 2; res = TEE_AllocateTransientObject(key_type, mks, &op->key1); if (res != TEE_SUCCESS) goto out; if ((op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 0) { res = TEE_AllocateTransientObject(key_type, mks, &op->key2); if (res != TEE_SUCCESS) goto out; } } res = utee_cryp_state_alloc(algorithm, mode, (uint32_t) op->key1, (uint32_t) op->key2, &op->state); if (res != TEE_SUCCESS) goto out; /* For multi-stage operation do an "init". */ TEE_ResetOperation(op); *operation = op; out: if (res != TEE_SUCCESS) { TEE_FreeTransientObject(op->key1); TEE_FreeTransientObject(op->key2); TEE_FreeOperation(op); } return res; }