/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 * Copyright (c) 2020, Linaro Limited
 */

#ifndef XML_TIMEARITHM_API_H_
#define XML_TIMEARITHM_API_H_

#include <assert.h>
#include <openssl/bn.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <tee_api_defines.h>
#include <tee_client_api.h>
#include <unistd.h>

#include "xml_common_api.h"
#include "xtest_helpers.h"
#include "xtest_test.h"

#define Invoke_GetSystemTime Invoke_Simple_Function
#define Invoke_GetREETime Invoke_Simple_Function
#define Invoke_SetTAPersistentTime_and_GetTAPersistentTime_Overflow \
	Invoke_Simple_Function
#define Invoke_SetTAPersistentTime_and_GetTAPersistentTime \
	Invoke_Simple_Function
#define Invoke_BigIntConvertToOctetStringOverflow Invoke_Simple_Function
#define Invoke_BigIntConvertFromOctetStringOverflow Invoke_Simple_Function
#define Invoke_GetTAPersistentTime_NotSet_and_SetTAPersistentTime \
	Invoke_Simple_Function
#define Test_Tool_Erase_Persistent_Time Invoke_Simple_Function

#define CMD_TEE_BigIntAdd			0x00000010
#define CMD_TEE_BigIntAddMod			0x00000011
#define CMD_TEE_BigIntCmp			0x00000012
#define CMD_TEE_BigIntCmpS32			0x00000013
#define CMD_TEE_BigIntComputeExtendedGcd	0x00000014
#define CMD_TEE_BigIntDiv			0x00000018
#define CMD_TEE_BigIntGetBit			0x00000020
#define CMD_TEE_BigIntGetBitCount		0x00000021
#define CMD_TEE_BigIntInvMod			0x00000023
#define CMD_TEE_BigIntIsProbablePrime		0x00000024
#define CMD_TEE_BigIntMod			0x00000025
#define CMD_TEE_BigIntMul			0x00000026
#define CMD_TEE_BigIntMulMod			0x00000027
#define CMD_TEE_BigIntNeg			0x00000028
#define CMD_TEE_BigIntRelativePrime		0x00000029
#define CMD_TEE_BigIntShiftRight		0x00000030
#define CMD_TEE_BigIntSquare			0x00000031
#define CMD_TEE_BigIntSquareMod			0x00000032
#define CMD_TEE_BigIntSub			0x00000033
#define CMD_TEE_BigIntSubMod			0x00000034
#define CMD_Arithm_TTA_Store_Value_S32		0x00000038
#define CMD_Arithm_TTA_New_BigInt		0x00000039
#define CMD_Arithm_BigIntConvertToOctetString	0x00000040
#define CMD_Arithm_BigIntComputeFMM		0x00000041
#define CMD_Arithm_BigIntConvertFromFMM		0x00000042
#define CMD_Arithm_BigIntConvertToFMM		0x00000043
#define CMD_Arithm_BigIntInitFMMContext		0x00000044
#define CMD_Arithm_TTA_New_BigIntFMM		0x00000045
#define CMD_Arithm_BigIntConvertFromOctetString 0x00000046
#define CMD_Arithm_BigIntConvertToS32		0x00000047
#define CMD_Arithm_BigIntConvertFromS32		0x00000048

#define CMD_TEE_GetSystemTime                                        0x00000010
#define CMD_TEE_Wait                                                 0x00000011
#define CMD_TEE_SetTAPersistentTime_and_GetTAPersistentTime          0x00000012
#define CMD_TEE_GetREETime                                           0x00000013
#define CMD_TEE_SetTAPersistentTime_and_GetTAPersistentTimeOverflow  0x00000014
#define CMD_TEE_GetTAPersistentTimeNotSetAndSetTAPersistentTime      0x00000015


static TEEC_Session session01;
static TEEC_Session *SESSION01 = &session01;
static TEEC_Context context01;
static TEEC_Context *CONTEXT01 = &context01;
static TEEC_Context context02;
static TEEC_Context *CONTEXT02 = &context02;
static TEEC_Operation operation01;
static TEEC_Operation *OPERATION01 = &operation01;

#define CMD_TEE_SetTAPersistentTime_and_GetTAPersistentTime_Overflow \
	CMD_TEE_SetTAPersistentTime_and_GetTAPersistentTimeOverflow

#define CLIENT_APP01                    NULL

#define TEEC_UNDEFINED_ERROR 0xDEADDEAD

#define TEEC_ORIGIN_ANY_NOT_TRUSTED_APP  0x00000005
/* same as TEE_ORIGIN_NOT_TRUSTED_APP */

static uint32_t saved_octet_string_sign;
static void *saved_octet_string;
static size_t saved_octet_string_size;

/*Test data defines*/
static pthread_t THREAD02;

#define BIT0_MASK 1
#define BIT1_MASK 2
#define BIT2_MASK 4

#define NEGATIVE 0
#define POSITIVE 1

#define RESULT_NOT_A_PRIME_SURE		0
#define RESULT_PRIME_SURE_OR_MAYBE	1

#define RESULT_NOT_A_PRIME 0
#define RESULT_PRIME 1

#define RESULT_EQUAL 0
#define RESULT_INTEGER_GREATER_THAN_ZERO 1
#define RESULT_INTEGER_LOWER_THAN_ZERO 2

#define CASE_WAIT_CANCELLED 1
#define CASE_WAIT_SUCCESS 2


#define STORED_VALUE_BIG_INT_1			0
#define STORED_VALUE_BIG_INT_2			1
#define STORED_VALUE_BIG_INT_3			8
#define STORED_VALUE_BIG_INT_4			9
#define STORED_VALUE_FMM_BIG_INT_1		310
#define STORED_VALUE_FMM_BIG_INT_2		311
#define STORED_VALUE_FMM_CONTEXT_1		300
#define STORED_VALUE_FMM_RESULT			312
#define STORED_VALUE_MODULUS			2
#define STORED_VALUE_RESULT			3
#define STORED_VALUE_RESULT_4			6
#define STORED_VALUE_RESULT_5			7
#define STORED_VALUE_RESULT_FMM_CONVERTED	10
#define STORED_VALUE_RESULT_U			4
#define STORED_VALUE_RESULT_V			5
#define STORED_VALUE_SHORT_VAL_1		100
#define STORED_VALUE_NULL			200

static uint32_t CONFIDENCE_LEVEL_80 = 80;

static uint8_t BIG_VALUE1_SIZE_64_BITS[] = {
	0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE11_SIZE_2048_BITS_PRIME_WITH_VALUE5[] = {
	0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE20_SIZE_2048_BITS_PRIME_WITH_VALUE18[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
};

static uint8_t BIG_VALUE2_SIZE_64_BITS[] = {
	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE3_SIZE_32_BITS[] = {
	0x0F, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE4_SIZE_32_BITS[] = {
	0x01, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE5_SIZE_2048_BITS[] = {
	0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE6_SIZE_2048_BITS[] = {
	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE7_SIZE_1024_BITS[] = {
	0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE10_SIZE_32_BITS_PRIME_WITH_VALUE3[] = {
	0x0E, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE13_SIZE_32_BITS_PRIME[] = {
	0x00, 0x00, 0x0D, 0x69,
};

static uint8_t BIG_VALUE14_SIZE_32_BITS_NOT_PRIME[] = {
	0x00, 0x00, 0x0D, 0x68,
};

static uint8_t BIG_VALUE15_SIZE_32_BITS[] = {
	0x00, 0x00, 0x00, 0x03,
};

static uint8_t BIG_VALUE16_SIZE_64_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
};

static uint8_t BIG_VALUE17_SIZE_1024_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03,
};

static uint8_t BIG_VALUE18_SIZE_2048_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x03,
};

static uint8_t BIG_VALUE19_SIZE_32_BITS_PRIME_WITH_VALUE15[] = {
	0x00, 0x00, 0x00, 0x04,
};

static uint8_t BIG_VALUE9_SIZE_64_BITS_PRIME_WITH_VALUE1[] = {
	0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};

static uint8_t BIG_VALUE_ONE_SIZE_64_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
};

static uint8_t BIG_VALUE_TWO_SIZE_1024_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
};

static uint8_t BIG_VALUE_ZERO_SIZE_32_BITS[] = {
	0x00, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE_ZERO_SIZE_64_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE_ZERO_SIZE_2048_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE_TWO_SIZE_2048_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
};

static uint8_t BIG_VALUE25_SIZE_2048_BITS[] = {
	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
};

static uint8_t BIG_VALUE_TWO_SIZE_32_BITS[] = {
	0x00, 0x00, 0x00, 0x02,
};

static uint8_t BIG_VALUE23_SIZE_32_BITS[] = {
	0x01, 0x00, 0x00, 0x01,
};

static uint8_t BIG_VALUE22_SIZE_32_BITS_LIMIT_INT32[] = {
	0x80, 0x00, 0x00, 0x00,
};

static uint8_t BIG_VALUE_TWO_SIZE_64_BITS[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
};

static uint8_t BIG_VALUE24_SIZE_64_BITS[] = {
	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
};

static uint8_t BIG_VALUE21_SIZE_64_BITS[] = {
	0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
};

/** ALL_TEEC_UUID
 *
 * These constants are the UUID of existing
 * Trusted Applications
 */
/* "SMARTCLSARITHMET" */
static TEEC_UUID UUID_TTA_testingInternalAPI_Arithmetique = {
	0x534D4152, 0x5443, 0x4C53,
	{ 0x41, 0x52, 0x49, 0x54, 0x48, 0x4D, 0x45, 0x54 }
};
/* "SMARTCSL_TIMEAPI" */
static TEEC_UUID UUID_TTA_testingInternalAPI_Time = {
	0x534D4152, 0x5443, 0x534C,
	{ 0x5F, 0x54, 0x49, 0x4D, 0x45, 0x41, 0x50, 0x49 }
};

/*Helper functions/macros*/

#define BN_DECLARE_AND_INIT(exit_label) \
	BN_CTX *ctx = NULL; \
	BIGNUM *a = NULL, *b = NULL, *s = NULL, *d = NULL, \
		*m = NULL, *l = NULL, \
	*r = NULL; \
	ctx = BN_CTX_new(); \
	if (ctx == NULL) { \
		goto exit_label; \
	} \
	a = BN_new(); \
	b = BN_new(); \
	s = BN_new(); \
	d = BN_new(); \
	m = BN_new(); \
	l = BN_new(); \
	r = BN_new();

#define BN_FREE() \
	BN_free(a); \
	BN_free(b); \
	BN_free(s); \
	BN_free(d); \
	BN_free(m); \
	BN_free(l); \
	BN_free(r); \
	if (ctx) { \
		BN_CTX_free(ctx); \
	}

static void *cancellation_thread(void *arg)
{
	TEEC_RequestCancellation((TEEC_Operation *)arg);
	return NULL;
}

#define RequestCancellation(op) \
	(void)ADBG_EXPECT(c, 0, \
			  pthread_create(&THREAD02, NULL, cancellation_thread, \
					 (void *)op)); \
	(void)ADBG_EXPECT(c, 0, pthread_join(THREAD02, NULL));

static TEEC_Result Invoke_BigIntCmpS32(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd_id, uint32_t op,
				       uint32_t short_value,
				       uint32_t exp_cmp_res)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, exp_cmp_res, 0,
					 op, short_value);
}

static TEEC_Result Invoke_BigIntCmp(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd_id, uint32_t op1,
				    uint32_t op2, uint32_t exp_cmp_res)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, exp_cmp_res, 0,
					 op1, op2);
}

static TEEC_Result Invoke_BigIntComputeExtendedGcd(ADBG_Case_t *c,
						   TEEC_Session *sess,
						   uint32_t cmd_id,
						   uint32_t gcd, uint32_t dst_u,
						   uint32_t dst_v, uint32_t op1,
						   uint32_t op2)
{
	return Invoke_Simple_Function_v3(c, sess, cmd_id, gcd, 0, dst_u, dst_v,
					 op1, op2);
}

static TEEC_Result Invoke_BigIntAddMod(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd_id, uint32_t dest,
				       uint32_t op1, uint32_t op2, uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, dest, mod, op1, op2);
}

static TEEC_Result Invoke_BigIntAdd(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd_id, uint32_t dest,
				    uint32_t op1, uint32_t op2)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, dest, 0, op1, op2);
}

static TEEC_Result Invoke_BigIntMul(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd_id, uint32_t dest,
				    uint32_t op1, uint32_t op2)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, dest, 0, op1, op2);
}

static TEEC_Result Invoke_BigIntMulMod(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd_id, uint32_t dst,
				       uint32_t op1, uint32_t op2, uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, dst, mod, op1, op2);
}

static TEEC_Result Invoke_StoreS32(ADBG_Case_t *c, TEEC_Session *sess,
				   uint32_t cmd_id, uint32_t dest,
				   uint32_t sign, const uint8_t *value,
				   size_t value_size)
{
	uint32_t v = 0;
	size_t n = 0;

	if (value_size > 4)
		return TEEC_ERROR_BAD_PARAMETERS;

	for (n = 0; n < value_size; n++) {
		v <<= 8;
		v |= value[n];
	}
	return Invoke_Simple_Function_v2(c, sess, cmd_id, dest, sign, v, 0);
}


static TEEC_Result Invoke_BigIntConvertFromS32(ADBG_Case_t *c,
					       TEEC_Session *sess,
					       uint32_t cmd_id, uint32_t dst,
					       uint32_t short_val)
{
	return Invoke_Simple_Function_v1(c, sess, cmd_id, dst, short_val);
}

static TEEC_Result Invoke_BigIntConvertToS32(ADBG_Case_t *c,
					     TEEC_Session *sess,
					     uint32_t cmd_id, uint32_t dst,
					     uint32_t src)
{
	return Invoke_Simple_Function_v1(c, sess, cmd_id, src, dst);
}

static TEEC_Result Invoke_BigIntGetBit(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd, uint32_t src,
				       uint32_t bit_idx, uint32_t exp_result)
{
	TEEC_Result res = TEEC_SUCCESS;
	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
	uint32_t org;

	op.params[0].value.a = src;
	op.params[0].value.b = bit_idx;

	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
					 TEEC_NONE, TEEC_NONE);

	res = TEEC_InvokeCommand(sess, cmd, &op, &org);

	if (!res && !ADBG_EXPECT_COMPARE_UNSIGNED(c, exp_result, ==,
						  op.params[1].value.a))
		res = TEEC_ERROR_GENERIC;

	return res;
}

static TEEC_Result Invoke_BigIntGetBitCount(ADBG_Case_t *c, TEEC_Session *sess,
					    uint32_t cmd, uint32_t src,
					    uint32_t exp_bit_count)
{
	TEEC_Result res = TEEC_SUCCESS;
	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
	uint32_t org;

	op.params[0].value.a = src;

	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
					 TEEC_NONE, TEEC_NONE);

	res = TEEC_InvokeCommand(sess, cmd, &op, &org);

	if (!res && !ADBG_EXPECT_COMPARE_UNSIGNED(c, exp_bit_count, ==,
						  op.params[1].value.a))
		res = TEEC_ERROR_GENERIC;

	return res;
}

static TEEC_Result Invoke_Wait(ADBG_Case_t *c, TEEC_Session *sess,
			       uint32_t cmdId, uint32_t Case)
{
	return Invoke_Simple_Function_v1(c, sess, cmdId, Case, 0);
}

static TEEC_Result Invoke_BigIntInitFMMContext(ADBG_Case_t *c,
					       TEEC_Session *sess,
					       uint32_t cmd_id, uint32_t ctx,
					       uint32_t mod_size, uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, ctx, mod, mod_size,
					 0);
}

static TEEC_Result Invoke_NewBigIntFMM(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd_id, uint32_t role,
				       uint32_t mod_size)
{
	return Invoke_Simple_Function_v1(c, sess, cmd_id, role, mod_size);
}

static TEEC_Result Invoke_BigIntConvertToFMM(ADBG_Case_t *c, TEEC_Session *sess,
					     uint32_t cmd_id, uint32_t dst,
					     uint32_t src, uint32_t mod,
					     uint32_t ctx)
{
	return Invoke_Simple_Function_v3(c, sess, cmd_id, ctx, mod, dst, 0,
					 src, 0);
}

static TEEC_Result Invoke_BigIntConvertFromFMM(ADBG_Case_t *c,
					       TEEC_Session *sess,
					       uint32_t cmd_id, uint32_t dst,
					       uint32_t src, uint32_t mod,
					       uint32_t ctx)
{
	return Invoke_Simple_Function_v3(c, sess, cmd_id, ctx, mod, dst, 0,
					 src, 0);
}

static TEEC_Result Invoke_BigIntComputeFMM(ADBG_Case_t *c, TEEC_Session *sess,
					   uint32_t cmd_id, uint32_t dst,
					   uint32_t op1, uint32_t op2,
					   uint32_t mod, uint32_t ctx)
{
	return Invoke_Simple_Function_v3(c, sess, cmd_id, ctx, mod, dst, 0,
					 op1, op2);
}

static TEEC_Result Invoke_BigIntDiv(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd_id, uint32_t q, uint32_t r,
				    uint32_t op1, uint32_t op2)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, q, r, op1, op2);
}

static TEEC_Result Invoke_BigIntMod(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd_id, uint32_t dst, uint32_t op,
				    uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd_id, dst, mod, op, 0);
}

static TEEC_Result Invoke_BigIntInvMod(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd, uint32_t dst, uint32_t op,
				       uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, mod, op, 0);
}

static TEEC_Result Invoke_BigIntIsProbablePrime(ADBG_Case_t *c,
						TEEC_Session *sess,
						uint32_t cmd, uint32_t op,
						uint32_t conf_lvl,
						uint32_t exp_result)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, exp_result, 0, op,
					 conf_lvl);
}

static TEEC_Result Invoke_BigIntNeg(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd, uint32_t dst, uint32_t op)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, 0, op, 0);
}

static TEEC_Result Invoke_BigIntRelativePrime(ADBG_Case_t *c,
					      TEEC_Session *sess, uint32_t cmd,
					      uint32_t op1, uint32_t op2,
					      bool exp_result)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, exp_result, 0, op1, op2);
}

static TEEC_Result Invoke_BigIntShiftRight(ADBG_Case_t *c, TEEC_Session *sess,
					   uint32_t cmd, uint32_t dst,
					   uint32_t op, uint32_t bits)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, op, bits, 0);
}

static TEEC_Result Invoke_BigIntSquareMod(ADBG_Case_t *c, TEEC_Session *sess,
					  uint32_t cmd, uint32_t dst,
					  uint32_t op, uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, mod, op, 0);
}

static TEEC_Result Invoke_BigIntSquare(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd, uint32_t dst, uint32_t op)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, 0, op, 0);
}

static TEEC_Result Invoke_BigIntSubMod(ADBG_Case_t *c, TEEC_Session *sess,
				       uint32_t cmd, uint32_t dst, uint32_t op1,
				       uint32_t op2, uint32_t mod)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, mod, op1, op2);
}

static TEEC_Result Invoke_BigIntSub(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd, uint32_t dst, uint32_t op1,
				    uint32_t op2)
{
	return Invoke_Simple_Function_v2(c, sess, cmd, dst, 0, op1, op2);
}

static TEEC_Result Invoke_NewBigInt(ADBG_Case_t *c, TEEC_Session *sess,
				    uint32_t cmd_id, uint32_t role,
				    uint32_t size)
{
	return Invoke_Simple_Function_v1(c, sess, cmd_id, role, size);
}

static TEEC_Result Macro_StoreBigInt(ADBG_Case_t *c, TEEC_Session *sess,
				     uint32_t role, uint32_t size,
				     uint32_t sign, const uint8_t *value,
				     size_t value_size)
{
	TEEC_Result res = TEE_SUCCESS;
	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
	uint32_t org;
	TEEC_SharedMemory shm_value = {
		.size = value_size,
		.flags = TEEC_MEM_INPUT,
	};

	res = Invoke_NewBigInt(c, sess, CMD_Arithm_TTA_New_BigInt, role, size);
	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
		return res;

	res = TEEC_AllocateSharedMemory(sess->ctx, &shm_value);
	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
		return res;
	memcpy(shm_value.buffer, value, value_size);

	op.params[0].value.a = role;
	op.params[0].value.b = size;
	op.params[1].value.a = sign;
	SET_SHARED_MEMORY_OPERATION_PARAMETER(2, 0, &shm_value,
					      shm_value.size);
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
					 TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE);
	res = TEEC_InvokeCommand(sess, CMD_Arithm_BigIntConvertFromOctetString,
				 &op, &org);
	TEEC_ReleaseSharedMemory(&shm_value);
	return res;
}

static TEEC_Result Invoke_BigIntConvertToOctetString(ADBG_Case_t *c,
						     TEEC_Session *sess,
						     uint32_t cmd_id,
						     uint32_t bigint,
						     size_t size)
{
	TEEC_Result res = TEE_SUCCESS;
	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
	uint32_t org;
	TEEC_SharedMemory shm = {
		.size = (size + 7) / 8,
		.flags = TEEC_MEM_OUTPUT,
	};

	res = TEEC_AllocateSharedMemory(sess->ctx, &shm);
	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
		return res;

	op.params[0].value.a = bigint;
	SET_SHARED_MEMORY_OPERATION_PARAMETER(2, 0, &shm, shm.size);

	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT,
					 TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE);

	res = TEEC_InvokeCommand(sess, cmd_id, &op, &org);

	if (!res) {
		size_t sz = op.params[2].memref.size;

		saved_octet_string = malloc(sz);
		memcpy(saved_octet_string, shm.buffer, sz);
		saved_octet_string_size = sz;
		saved_octet_string_sign = op.params[1].value.a;

	}
	TEEC_ReleaseSharedMemory(&shm);
	return res;
}

static TEEC_Result Invoke_BigIntConvertFromOctetString(ADBG_Case_t *c,
						       TEEC_Session *sess,
						       uint32_t cmd_id,
						       uint32_t dst,
						       size_t size,
						       uint32_t sign,
						       const uint8_t *value,
						       size_t value_size)
{
	TEEC_Result res = TEE_SUCCESS;
	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
	uint32_t org;
	TEEC_SharedMemory shm = {
		.size = (size + 7) / 8,
		.flags = TEEC_MEM_INPUT,
	};

	if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, value_size, <=, shm.size))
		return TEEC_ERROR_BAD_PARAMETERS;

	res = TEEC_AllocateSharedMemory(sess->ctx, &shm);
	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
		return res;
	memcpy(shm.buffer, value, value_size);

	op.params[0].value.a = dst;
	op.params[1].value.a = sign;
	SET_SHARED_MEMORY_OPERATION_PARAMETER(2, 0, &shm, shm.size);

	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
					 TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE);

	res = TEEC_InvokeCommand(sess, cmd_id, &op, &org);

	TEEC_ReleaseSharedMemory(&shm);
	return res;
}
#endif /* XML_TIMEARITHM_API_H_ */
