TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation,
				    TEE_Attribute *params,
				    uint32_t paramCount, void *digest,
				    uint32_t digestLen, void *signature,
				    uint32_t *signatureLen)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];
	uint64_t sl;

	if (operation == TEE_HANDLE_NULL ||
	    (digest == NULL && digestLen != 0) ||
	    signature == NULL || signatureLen == NULL)
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.operationClass !=
	    TEE_OPERATION_ASYMMETRIC_SIGNATURE)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_SIGN)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	sl = *signatureLen;
	res = utee_asymm_operate(operation->state, ua, paramCount, digest,
				 digestLen, signature, &sl);
	*signatureLen = sl;

	if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);

	return res;
}
TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle op,
				 const TEE_Attribute *params,
				 uint32_t paramCount, const void *srcData,
				 size_t srcLen, void *destData,
				 size_t *destLen)
{
	TEE_Result res;

	if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
	    destLen == NULL || (destData == NULL && *destLen != 0))
		TEE_Panic(0);
	if (paramCount != 0 && params == NULL)
		TEE_Panic(0);
	if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
		TEE_Panic(0);
	if (op->info.mode != TEE_MODE_ENCRYPT)
		TEE_Panic(0);

	res = utee_asymm_operate(op->state, params, paramCount, srcData, srcLen,
				 destData, destLen);
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER &&
	    res != TEE_ERROR_BAD_PARAMETERS)
		TEE_Panic(res);
	return res;
}
TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation,
				 TEE_Attribute *params,
				 uint32_t paramCount, void *srcData,
				 uint32_t srcLen, void *destData,
				 uint32_t *destLen)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];
	uint64_t dl;

	if (operation == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) ||
	    destLen == NULL || (destData == NULL && *destLen != 0))
		TEE_Panic(0);
	if (params == NULL && paramCount != 0)
		TEE_Panic(0);
	if (!operation->key1)
		TEE_Panic(0);
	if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
		TEE_Panic(0);
	if (operation->info.mode != TEE_MODE_DECRYPT)
		TEE_Panic(0);

	__utee_from_attr(ua, params, paramCount);
	dl = *destLen;
	res = utee_asymm_operate(operation->state, ua, paramCount, srcData,
				 srcLen, destData, &dl);
	*destLen = dl;

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_SHORT_BUFFER &&
	    res != TEE_ERROR_BAD_PARAMETERS)
		TEE_Panic(res);

	return res;
}
TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle op,
				    const TEE_Attribute *params,
				    uint32_t paramCount, const void *digest,
				    size_t digestLen, void *signature,
				    size_t *signatureLen)
{
	TEE_Result res;

	if (op == TEE_HANDLE_NULL || (digest == NULL && digestLen != 0) ||
	    signature == NULL || signatureLen == NULL)
		TEE_Panic(0);
	if (paramCount != 0 && params == NULL)
		TEE_Panic(0);
	if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE)
		TEE_Panic(0);
	if (op->info.mode != TEE_MODE_SIGN)
		TEE_Panic(0);

	res =
	    utee_asymm_operate(op->state, params, paramCount, digest, digestLen,
			       signature, signatureLen);
	if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)
		TEE_Panic(res);
	return res;
}