TEE_Result set_spec_key_method(const void *key, size_t kelen) { TEE_Result res; TEE_OperationHandle operation; uint32_t algorithm = TEE_ALG_HMAC_MD5; uint32_t mode = TEE_MODE_MAC; uint32_t maxKeySize = 512; uint32_t attributeID = TEE_ATTR_SECRET_VALUE; res = TEE_AllocateOperation(&operation, algorithm, mode, maxKeySize); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_AllocateOperation\n"); goto _ret_; } res = set_key_value(operation->key1, key, kelen, attributeID); if(res != TEE_SUCCESS) { TEE_Printf("[err] set_key_value\n"); goto _ret_; } _ret_: if (operation) { TEE_FreeOperation(operation); } return res; }
TEE_Result get_random_key_method1() { TEE_Result res; TEE_OperationHandle operation = TEE_HANDLE_NULL; uint32_t algorithm = TEE_ALG_HMAC_MD5; uint32_t mode = TEE_MODE_MAC; uint32_t maxKeySize = 512; res = TEE_AllocateOperation(&operation, algorithm, mode, maxKeySize); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_AllocateOperation\n"); goto _ret_; } uint32_t maxKeyObjectSize = maxKeySize; //TEE_Attribute params; //uint32_t paramCount = 0; res = TEE_GenerateKey(operation->key1, maxKeyObjectSize, NULL, 0); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_GenerateKey\n"); return 0; } _ret_: if (operation) { TEE_FreeOperation(operation); } return res; }
TEE_Result ta_entry_free_operation(uint32_t param_type, TEE_Param params[4]) { ASSERT_PARAM_TYPE(TEE_PARAM_TYPES (TEE_PARAM_TYPE_VALUE_INPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)); TEE_FreeOperation((TEE_OperationHandle) params[0].value.a); return TEE_SUCCESS; }
TEE_Result crypt_cipher_aes_cbc(const void *message, size_t message_len, const void *key, size_t key_len, void *cipher, size_t *cipher_len, const void *IV, size_t IVLen, uint32_t mode) { TEE_Result res = TEE_ERROR_GENERIC; TEE_OperationHandle operation = TEE_HANDLE_NULL; uint32_t algorithm = TEE_ALG_AES_CBC_NOPAD; uint32_t maxKeySize = 256; /* valid sizes 128, 192, 256 */ res = TEE_AllocateOperation(&operation, algorithm, mode, maxKeySize); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_AllocateOperation\n"); goto _ret_; } if(!key || 0 >= key_len) { res = TEE_ERROR_BAD_PARAMETERS; goto _ret_; } // set crypt key TEE_Attribute attr_list[1]; uint32_t attributeID = TEE_ATTR_SECRET_VALUE; TEE_MemFill(&attr_list[0], sizeof(attr_list[0]), 0); TEE_InitRefAttribute(&attr_list[0], attributeID /* TEE_ATTR_SECRET_VALUE */, (void *)key, key_len ); res = TEE_PopulateTransientObject(operation->key1, &attr_list[0], sizeof(attr_list)/sizeof(attr_list[0])); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_PopulateTransientObject\n"); goto _ret_; } // do crypt res = crypt_cipher_interface(operation, (const void *)message, message_len, cipher, cipher_len, IV, IVLen); if(res != TEE_SUCCESS) { TEE_Printf("[err] crypt_cipher_interface\n"); goto _ret_; } _ret_: if (operation) { TEE_FreeOperation(operation); } if(res != TEE_SUCCESS) { TEE_Panic(res); } return res; }
static TEE_Result invoke_generate_hash(uint32_t param_types, TEE_Param params[4]) { TEE_Result res = TEE_ERROR_BAD_PARAMETERS; void *message = NULL; size_t message_len; void *digest = NULL; size_t digest_len; TEE_OperationHandle operation; 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); DMSG("has been called"); if (param_types != exp_param_types) return TEE_ERROR_BAD_PARAMETERS; message = params[0].memref.buffer; message_len = params[0].memref.size; digest = params[1].memref.buffer; digest_len = params[1].memref.size; res = TEE_AllocateOperation(&operation, TEE_ALG_SHA1, TEE_MODE_DIGEST, 0); if (res != TEE_SUCCESS) { DMSG("TEE_AllocateOperation failed! res: 0x%x", res); goto out; } res = TEE_DigestDoFinal(operation, message, message_len, digest, &digest_len); if (res != TEE_SUCCESS) { DMSG("TEE_DigestDoFinal failed! res: 0x%x", res); } out: if (operation) TEE_FreeOperation(operation); return res; }
TEE_Result get_random_key_method2() { TEE_Result res; TEE_OperationHandle operation = TEE_HANDLE_NULL; uint32_t algorithm = TEE_ALG_HMAC_MD5; uint32_t mode = TEE_MODE_MAC; uint32_t maxKeySize = 512; res = TEE_AllocateOperation(&operation, algorithm, mode, maxKeySize); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_AllocateOperation\n"); goto _ret_; } TEE_ObjectHandle hKeyObject = TEE_HANDLE_NULL; TEE_ObjectType keyObjectType = TEE_TYPE_HMAC_MD5; uint32_t maxKeyObjectSize = maxKeySize; res = TEE_NewRandomKeyObject(keyObjectType, maxKeyObjectSize, &hKeyObject); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_AllocateTransientObject\n"); return 0; } res = TEE_SetOperationKey(operation, hKeyObject); if(res != TEE_SUCCESS) { TEE_Printf("[err] TEE_SetOperationKey\n"); goto _ret_; } _ret_: if (operation) { TEE_FreeOperation(operation); } if(hKeyObject) { TEE_FreeTransientObject(hKeyObject); } return res; }
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; }
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; }