#include <cstring>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <stdlib.h>

#if defined(_WIN32) || defined(_WIN64)
#include <sys\timeb.h>
#else
#include <sys/time.h>
#include <dlfcn.h>
#endif

#include "SDF4PCIeSM.h"
#include "TassAPI4PCIeSM.h"

using namespace std;

#define THREADNUMS 5000
#define BUFLITTLE  32
#define BUFSMALL   128
#define BUF        1024

static void *g_hKey = NULL;

#define TaZero(buf, length)				memset(buf, 0, length)

static unsigned char pwd[] = "a1234567";
static int pwdLen = strlen((char*)pwd);

static void printHex(const char* title, unsigned char* buf, int len)
{
	int i;
	printf("%s[length = %d]:\n\t", title == NULL ? "" : title, len);
	for (i = 0; i < len; ++i)
		printf("%02X", buf[i]);
	printf("\n");
}

string String2Bin(const string& str)
{
	string bRt = "";
	for (int i = 0; i < (int)str.length() / 2 * 2; i += 2) {
		std::stringstream ss(str.substr(i, 2));
		int tmp = -1;
		ss >> std::hex >> tmp;
		bRt.append(1, (char)(tmp & 0xFF));
	}
	return bRt;
}

int String2Bin(const string& str, unsigned char* bin, unsigned int* size) {
	if (bin == NULL)
		return -1;
	if (size == NULL)
		return str.length() / 2;
	if (*size < str.length() / 2)
		return str.length() / 2;
	string bBin = String2Bin(str);
	*size = bBin.length();
	memcpy(bin, bBin.data(), *size);
	return *size;
}

string Bin2String(const unsigned char* bin, const unsigned int len, bool upper) {
	if (bin == NULL || len == 0)
		return "";
	std::stringstream ss;
	for (int i = 0; i < (int)len; ++i) {
		if (upper)
			ss.setf(std::ios::uppercase);
		ss << std::hex << std::setw(2) << std::setfill('0') << (bin[i] & 0xff);
	}
	return ss.str();
}

string Bin2String(const string& bBin, bool upper)
{
	return Bin2String((unsigned char*)bBin.data(), bBin.length(), upper);
}

#define PRINT_BUF(func, buf, len)\
do{\
	printf("Function [%s] -> %s [%s = %d|%#010X]:\n\t%s\n", #func, #buf, #len, len, len, Bin2String(buf, len, true).c_str());\
} while (0)

void HashOperationData(void * hSess, unsigned char* data, unsigned int dataLen, unsigned char* hash, unsigned int* hashLen)
{
	ECCrefPublicKey pubKey = { 0 };
	unsigned char ID[BUF] = { 0 };
	unsigned int IDLen = 0;
	unsigned int len = *hashLen;
	unsigned int algID = SGD_SHA256;

	auto rt = SDF_HashInit(hSess, algID, NULL, ID, IDLen);
	if (rt)
	{
		printf("\nSDF_HashInit failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
		printf("\nSDF_HashInit success\n");

	rt = SDF_HashUpdate(hSess, data, dataLen);
	if (rt)
		return;
	else
		printf("\nSDF_HashUpdate success\n");

	rt = SDF_HashFinal(hSess, hash, &len);
	if (rt)
		return;
	else
		printf("\nhash: %s\n", Bin2String(hash, len, true).data());
	*hashLen = len;
}

int T_SDF_GenerateRandom(void *hDev)
{
	void* hSess = NULL;
	auto rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		SDF_CloseDevice(hDev);
		return -1;
	}

	unsigned char random[BUFLITTLE + 1] = { 0 };
	int randomLen = 16;
	rt = SDF_GenerateRandom(hSess, randomLen, random);
	if (rt)
	{
		printf("\nSDF_GenerateRandom failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
	{
		printf("\nSDF_GenerateRandom success\n");
		printf("randomLen = %d, random: %s\n", randomLen, Bin2String(random, randomLen, true).data());
	}
	rt = SDF_CloseSession(hSess);
	if (rt) {
		printf("SDF_CloseSession failed %#08x\n", rt);
		return -1;
	}

	return 0;
}

static unsigned int g_keyAsymIndex = 1;
int T_SDF_ExportPublicKey_ECC(void* hSess)
{
	ECCrefPublicKey signPubKey = { 0 };
	ECCrefPublicKey encPubKey = { 0 };

	int rt = SDF_ExportSignPublicKey_ECC(hSess, g_keyAsymIndex, &signPubKey);
	if (rt)
	{
		printf("\nSDF_ExportSignPublicKey_ECC failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
	{
		printf("\nSDF_ExportSignPublicKey_ECC success\n");
		printf("SignPubKey.bits: %d\n", signPubKey.bits);
		printf("SignPubKey.x: %s\n", Bin2String(signPubKey.x, sizeof(signPubKey.x), true).data());
		printf("SignPubKey.y: %s\n", Bin2String(signPubKey.y, sizeof(signPubKey.y), true).data());
	}

	rt = SDF_ExportEncPublicKey_ECC(hSess, g_keyAsymIndex, &encPubKey);
	if (rt)
	{
		printf("\nSDF_ExportEncPublicKey_ECC failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
	{
		printf("\nSDF_ExportEncPublicKey_ECC success\n");
		printf("EncPubKey.bits: %d\n", encPubKey.bits);
		printf("EncPubKey.x: %s\n", Bin2String(encPubKey.x, sizeof(encPubKey.x), true).data());
		printf("EncPubKey.y: %s\n", Bin2String(encPubKey.y, sizeof(encPubKey.y), true).data());
	}

	return 0;
}

int T_SDF_GenerateKeyPair_ECC(void* hSess)
{
	ECCrefPublicKey pubKey = { 0 };
	ECCrefPrivateKey priKey = { 0 };
	unsigned int algID = SGD_SM2;

	int rt = SDF_GenerateKeyPair_ECC(hSess, algID, 256, &pubKey, &priKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_ECC failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
	{
		printf("\nSDF_GenerateKeyPair_ECC success\n");
		printf("PubKey.bits: %d\n", pubKey.bits);
		printf("PubKey.x: %s\n", Bin2String(pubKey.x, sizeof(pubKey.x), true).data());
		printf("PubKey.y: %s\n", Bin2String(pubKey.y, sizeof(pubKey.y), true).data());
		printf("PriKey.bits: %d\n", priKey.bits);
		printf("PriKey.K: %s\n", Bin2String(priKey.K, sizeof(priKey.K), true).data());
	}

	return 0;
}

int T_SDF_GenerateKey_And_Import_ECC(void* hSess)
{
	ECCrefPublicKey pubKey = { 0 };
	ECCrefPrivateKey priKey = { 0 };

	//生成非对称密钥
	int rt = SDF_GenerateKeyPair_ECC(hSess, SGD_SM2, 256, &pubKey, &priKey);
	if (rt) {
		printf("SDF_GenerateKeyPair_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyPair_ECC success\n");
	printf("PubKey.bits: %d\n", pubKey.bits);
	printf("PubKey.x: %s\n", Bin2String(pubKey.x, sizeof(pubKey.x), true).data());
	printf("PubKey.y: %s\n", Bin2String(pubKey.y, sizeof(pubKey.y), true).data());
	printf("PriKey.bits: %d\n", priKey.bits);
	printf("PriKey.K: %s\n", Bin2String(priKey.K, sizeof(priKey.K), true).data());

	ECCCipher cipher = { 0 };
	void* hKeyHdl = NULL;

	rt = SDF_GenerateKeyWithEPK_ECC(hSess, 16 * 8, SGD_SM2, &pubKey, &cipher, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateKeyWithEPK_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyWithEPK_ECC success\n");
	printf("Cipher.x: %s\n", Bin2String(cipher.x, sizeof(cipher.x), true).data());
	printf("Cipher.y: %s\n", Bin2String(cipher.y, sizeof(cipher.y), true).data());
	printf("Cipher.M: %s\n", Bin2String(cipher.M, sizeof(cipher.M), true).data());
	printf("Cipher.C: %s\n", Bin2String(cipher.C, cipher.L, true).data());

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt) {
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	TaZero(&cipher, sizeof(cipher));

	/*int idx = 5;
	void* pIdx = &idx;*/
	//rt = SDF_GenerateKeyWithIPK_ECC(g_hSess, 1, 16 * 8, &cipher, &pIdx);
	rt = SDF_GenerateKeyWithIPK_ECC(hSess, 1, 16 * 8, &cipher, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateKeyWithIPK_ECC failed rt = %d\n", rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyWithIPK_ECC success\n");
	printf("cipher.x: %s\n", Bin2String(cipher.x, sizeof(cipher.x), true).data());
	printf("cipher.y: %s\n", Bin2String(cipher.y, sizeof(cipher.y), true).data());
	printf("cipher.M: %s\n", Bin2String(cipher.M, sizeof(cipher.M), true).data());
	printf("cipher.L: %d\n", cipher.L);
	printf("cipher.C: %s\n", Bin2String(cipher.C, cipher.L, true).data());

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt) {
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	//获取私钥授权
	rt = SDF_GetPrivateKeyAccessRight(hSess, g_keyAsymIndex, pwd, pwdLen);
	if (rt)
	{
		printf("\nSDF_GetPrivateKeyAccessRight failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
		printf("\nSDF_GetPrivateKeyAccessRight success\n");

	rt = SDF_ImportKeyWithISK_ECC(hSess, g_keyAsymIndex, &cipher, &hKeyHdl);
	if (rt) {
		printf("SDF_ImportKeyWithISK_ECC failed %#08x\n", rt);
		SDF_ReleasePrivateKeyAccessRight(hSess, g_keyAsymIndex);
		return rt;
	}
	printf("\nSDF_ImportKeyWithISK_ECC success\n");

	SDF_ReleasePrivateKeyAccessRight(hSess, g_keyAsymIndex);

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt) {
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	//hKeyHdl = NULL;

	unsigned char keyCipherByKek[128] = { 0 };
	unsigned int keyCipehrByKekLen = sizeof(keyCipherByKek);
	hKeyHdl = NULL;

	/*int idx1 = 6;
	void* pIdx1 = &idx1;*/
	int testIndex = 2;

	rt = SDF_GenerateKeyWithKEK(hSess, 16 * 8, SGD_SM4_ECB, testIndex, keyCipherByKek, &keyCipehrByKekLen, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateKeyWithKEK failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyWithKEK success\n");
	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt) {
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	rt = SDF_ImportKeyWithKEK(hSess, SGD_SM4_ECB, testIndex, keyCipherByKek, keyCipehrByKekLen, &hKeyHdl);
	if (rt) {
		printf("SDF_ImportKeyWithKEK failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_ImportKeyWithKEK success\n");

	unsigned char iv[64] = "\x11\x22\x33\x44\x55\x66\x77\x88\x11\x22\x33\x44\x55\x66\x77\x88";
	unsigned char outData[8192 * 2] = { 0 };
	unsigned int len = sizeof(outData);

	string str = "12345678123456781234567812345678";
	string dataBin = String2Bin(str);

	rt = SDF_Encrypt(hSess, hKeyHdl, SGD_SM4_ECB, iv, (unsigned char*)dataBin.c_str(), dataBin.size(), outData, &len);
	if (rt) {
		printf("SDF_Encrypt failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_Encrypt success. inData = %s, out iv = %s\n", str.c_str(), Bin2String(iv, 16, true).c_str());
	printf("outData = %s, len = %d\n", Bin2String(outData, len, true).data(), len);

	unsigned char deOutData[1024] = { 0 };
	unsigned int len2 = sizeof(deOutData);
	rt = SDF_Decrypt(hSess, hKeyHdl, SGD_SM4_ECB, iv, outData, len, deOutData, &len2);
	if (rt) {
		printf("\nSDF_Decrypt  failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_Decrypt success, outData = %s, out iv = %s, len2 = %d\n", Bin2String(deOutData, len, true).data(), Bin2String(iv, 16, true).c_str(), len2);

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt) {
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	return 0;
}

int T_SDF_Agreement_And_GenerateKey_WithECC(void * hSess)
{
	void* hAgreeHdl = NULL;
	ECCrefPublicKey reqPubKey = { 0 }, reqTmpPubKey = { 0 }, rspPubKey = { 0 }, rspTmpPubKey = { 0 };
	int rt = SDF_GenerateAgreementDataWithECC(hSess, 1, 16 * 8, (unsigned char*)"112233", 6, &reqPubKey, &reqTmpPubKey, &hAgreeHdl);
	if (rt) {
		printf("SDF_GenerateAgreementDataWithECC failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_GenerateAgreementDataWithECC success\n");
	printf("ReqPubKey.bits: %d\n", reqPubKey.bits);
	printf("ReqPubKey.x: %s\n", Bin2String(reqPubKey.x, sizeof(reqPubKey.x), true).data());
	printf("ReqPubKey.y: %s\n", Bin2String(reqPubKey.y, sizeof(reqPubKey.y), true).data());
	printf("ReqTmpPubKey.bits: %d\n", reqTmpPubKey.bits);
	printf("ReqTmpPubKey.x: %s\n", Bin2String(reqTmpPubKey.x, sizeof(reqTmpPubKey.x), true).data());
	printf("ReqTmpPubKey.y: %s\n", Bin2String(reqTmpPubKey.y, sizeof(reqTmpPubKey.y), true).data());

	/*rt = SDF_GenerateAgreementDataAndKeyWithECC(hSess, 11, 16 * 8, (unsigned char*)"332211", 6, (unsigned char*)"112233", 6,
		&reqPubKey, &reqTmpPubKey, &rspPubKey, &rspTmpPubKey, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateAgreementDataAndKeyWithECC failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_GenerateAgreementDataAndKeyWithECC success\n");
	printf("RspPubKey.bits: %d\n", rspPubKey.bits);
	printf("RspPubKey.x: %s\n", Utility::Bin2String(rspPubKey.x, sizeof(rspPubKey.x), true).data());
	printf("RspPubKey.y: %s\n", Utility::Bin2String(rspPubKey.y, sizeof(rspPubKey.y), true).data());
	printf("RspTmpPubKey.bits: %d\n", rspTmpPubKey.bits);
	printf("RspTmpPubKey.x: %s\n", Utility::Bin2String(rspTmpPubKey.x, sizeof(rspTmpPubKey.x), true).data());
	printf("RspTmpPubKey.y: %s\n", Utility::Bin2String(rspTmpPubKey.y, sizeof(rspTmpPubKey.y), true).data());*/


	/*rt = SDF_GenerateKeyWithECC(g_hSess, (unsigned char*)"332211", 6, &rspPubKey, &rspTmpPubKey, hAgreeHdl, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateKeyWithECC failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_GenerateKeyWithECC success\n");*/

	return 0;
}

int T_SDF_ExchangeDigitEnvelopeBaseOnECC(void * hSess)
{
	ECCrefPublicKey encPubKey = { 0 };
	int rt = SDF_ExportEncPublicKey_ECC(hSess, 1, &encPubKey);
	if (rt) {
		printf("SDF_ExportEncPublicKey_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_ExportEncPublicKey_ECC success\n");
	printf("EncPubKey.bits: %d\n", encPubKey.bits);
	printf("EncPubKey.x: %s\n", Bin2String(encPubKey.x, sizeof(encPubKey.x), true).data());
	printf("EncPubKey.y: %s\n", Bin2String(encPubKey.y, sizeof(encPubKey.y), true).data());

	void *hKeyHdl = NULL;
	ECCCipher cipherByInPubKey = { 0 };

	rt = SDF_GenerateKeyWithIPK_ECC(hSess, 1, 16 * 8, &cipherByInPubKey, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateKeyWithIPK_ECC failed rt = %d\n", rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyWithIPK_ECC success\n");
	printf("cipherByInPubKey.x: %s\n", Bin2String(cipherByInPubKey.x, sizeof(cipherByInPubKey.x), true).data());
	printf("cipherByInPubKey.y: %s\n", Bin2String(cipherByInPubKey.y, sizeof(cipherByInPubKey.y), true).data());
	printf("cipherByInPubKey.M: %s\n", Bin2String(cipherByInPubKey.M, sizeof(cipherByInPubKey.M), true).data());
	printf("cipherByInPubKey.L: %d\n", cipherByInPubKey.L);
	printf("cipherByInPubKey.C: %s\n", Bin2String(cipherByInPubKey.C, cipherByInPubKey.L, true).data());

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt)
	{
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	ECCCipher cipherOut = { 0 };
	rt = SDF_ExchangeDigitEnvelopeBaseOnECC(hSess, 1, SGD_SM2, &encPubKey, &cipherByInPubKey, &cipherOut);
	if (rt) {
		printf("SDF_ExchangeDigitEnvelopeBaseOnECC failed %08x\n", rt);
		return rt;
	}
	printf("SDF_ExchangeDigitEnvelopeBaseOnECC success\n");
	printf("cipherOut.x: %s\n", Bin2String(cipherOut.x, sizeof(cipherOut.x), true).data());
	printf("cipherOut.y: %s\n", Bin2String(cipherOut.y, sizeof(cipherOut.y), true).data());
	printf("cipherOut.M: %s\n", Bin2String(cipherOut.M, sizeof(cipherOut.M), true).data());
	printf("cipherOut.C: %s\n", Bin2String(cipherOut.C, cipherOut.L, true).data());

	return 0;
}

int T_SDF_GenerateKey_And_Import_KEK(void * hSess)
{
	unsigned char keyCipherByKek[128] = { 0 };
	unsigned int keyCipehrByKekLen = sizeof(keyCipherByKek);
	void* hKeyHdl = NULL;

	auto rt = SDF_GenerateKeyWithKEK(hSess, 16 * 8, SGD_SM4_ECB, 1, keyCipherByKek, &keyCipehrByKekLen, &hKeyHdl);
	if (rt) {
		printf("SDF_GenerateKeyWithKEK failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyWithKEK success\n");
	printf("len = %d, encKey: %s\n", keyCipehrByKekLen, Bin2String(keyCipherByKek, keyCipehrByKekLen, true).data());
	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt)
	{
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	return 0;
}

/*---------------------------密钥管理类函数测试-------------------------*/
void T_SDF_ExportPublicKey_RSA(void* hSess)
{
	RSArefPublicKey rsaSignPubKey = { 0 };
	RSArefPublicKey rsaEncPubKey = { 0 };

	int rt = SDF_ExportSignPublicKey_RSA(hSess, 1, &rsaSignPubKey);
	if (rt)
	{
		printf("\nSDF_ExportSignPublicKey_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_ExportSignPublicKey_RSA success\n");
		printf("SignPubKey.bits: %d\n", rsaSignPubKey.bits);
		printf("SignPubKey.m: %s\n", Bin2String(rsaSignPubKey.m, sizeof(rsaSignPubKey.m), true).data());
		printf("SignPubKey.e: %s\n", Bin2String(rsaSignPubKey.e, sizeof(rsaSignPubKey.e), true).data());
	}

	rt = SDF_ExportEncPublicKey_RSA(hSess, 1, &rsaEncPubKey);
	if (rt)
	{
		printf("\nSDF_ExportEncPublicKey_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_ExportEncPublicKey_RSA success\n");
		printf("EncPubKey.bits: %d\n", rsaEncPubKey.bits);
		printf("EncPubKey.m: %s\n", Bin2String(rsaEncPubKey.m, sizeof(rsaEncPubKey.m), true).data());
		printf("EncPubKey.e: %s\n", Bin2String(rsaEncPubKey.e, sizeof(rsaEncPubKey.e), true).data());
	}
}

void T_SDF_GenerateKeyPair_RSA(void * hSess)
{
	RSArefPublicKey rsaPubKey = { 0 };
	RSArefPrivateKey rsaPriKey = { 0 };

	int rt = SDF_GenerateKeyPair_RSA(hSess, 2048, &rsaPubKey, &rsaPriKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_GenerateKeyPair_RSA success\n");
		printf("PubKey.bits: %d\n", rsaPubKey.bits);
		printf("PubKey.m: %s\n", Bin2String(rsaPubKey.m, sizeof(rsaPubKey.m), true).data());
		printf("PubKey.e: %s\n", Bin2String(rsaPubKey.e, sizeof(rsaPubKey.e), true).data());
		printf("PriKey.bits: %d\n", rsaPriKey.bits);
		printf("PriKey.m: %s\n", Bin2String(rsaPriKey.m, sizeof(rsaPriKey.m), true).data());
		printf("PriKey.e: %s\n", Bin2String(rsaPriKey.e, sizeof(rsaPriKey.e), true).data());
		printf("PriKey.d: %s\n", Bin2String(rsaPriKey.d, sizeof(rsaPriKey.d), true).data());
		printf("PriKey.prime[0]: %s\n", Bin2String(rsaPriKey.prime[0], sizeof(rsaPriKey.prime[0]), true).data());
		printf("PriKey.prime[1]: %s\n", Bin2String(rsaPriKey.prime[1], sizeof(rsaPriKey.prime[1]), true).data());
		printf("PriKey.pexp[0]: %s\n", Bin2String(rsaPriKey.pexp[0], sizeof(rsaPriKey.pexp[0]), true).data());
		printf("PriKey.pexp[1]: %s\n", Bin2String(rsaPriKey.pexp[1], sizeof(rsaPriKey.pexp[1]), true).data());
		printf("PriKey.coef: %s\n", Bin2String(rsaPriKey.coef, sizeof(rsaPriKey.coef), true).data());
	}
	TaZero(&rsaPubKey, sizeof(rsaPubKey));
	TaZero(&rsaPriKey, sizeof(rsaPriKey));

	//存储签名、加密，密钥对
	rsaPubKey.bits = 3;
	rsaPriKey.bits = 3;

	rt = SDF_GenerateKeyPair_RSA(hSess, 2048, &rsaPubKey, &rsaPriKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_GenerateKeyPair_RSA success\n");
		printf("PubKey.bits: %d\n", rsaPubKey.bits);
		printf("PubKey.m: %s\n", Bin2String(rsaPubKey.m, sizeof(rsaPubKey.m), true).data());
		printf("PubKey.e: %s\n", Bin2String(rsaPubKey.e, sizeof(rsaPubKey.e), true).data());
	}
}

unsigned int g_keyBits[3] = { 128, 192, 256 };

void T_SDF_GenerateKey_And_Import_RSA(void *hSess)
{
	unsigned char encKey[BUF + 1] = { 0 };
	unsigned int encKeyLen = sizeof(encKey);
	RSArefPublicKey rsaPubKey = { 0 };
	RSArefPrivateKey rsaPriKey = { 0 };
	void* hKeyHdl = NULL;

	//for (int i = 0; i < 3; ++i)
	{
		//获取公钥
		rsaPubKey.bits = 1;
		rsaPriKey.bits = 1;
		int rt = SDF_GenerateKeyPair_RSA(hSess, 2048, &rsaPubKey, &rsaPriKey);
		if (rt)
		{
			printf("\nSDF_GenerateKeyPair_RSA failed %d | 0x%08x\n", rt, rt);
			return;
		}
		else
		{
			printf("\nSDF_GenerateKeyPair_RSA success\n");
			printf("PubKey.bits: %d\n", rsaPubKey.bits);
			printf("PubKey.m: %s\n", Bin2String(rsaPubKey.m, sizeof(rsaPubKey.m), true).data());
			printf("PubKey.e: %s\n", Bin2String(rsaPubKey.e, sizeof(rsaPubKey.e), true).data());
		}

		//生成会话密钥 外部公钥加密输出
		rt = SDF_GenerateKeyWithEPK_RSA(hSess, 128, &rsaPubKey, encKey, &encKeyLen, &hKeyHdl);
		if (rt)
		{
			printf("\nSDF_GenerateKeyWithEPK_RSA failed %d | 0x%08x\n", rt, rt);
			//return;
		}
		else
		{
			printf("\nSDF_GenerateKeyWithEPK_RSA success\n");
			printf("encKeyLen = %d, encKey: %s\n", encKeyLen, Bin2String(encKey, encKeyLen, true).data());

			rt = SDF_DestroyKey(hSess, hKeyHdl);
			if (rt)
			{
				printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
				//return;
			}
			printf("\nSDF_DestroyKey success\n");
			
		}
		hKeyHdl = NULL;
		TaZero(encKey, sizeof(encKey));

		//生成会话密钥 内部公钥加密输出
		rt = SDF_GenerateKeyWithIPK_RSA(hSess, 1, 2048, encKey, &encKeyLen, &hKeyHdl);
		if (rt)
		{
			printf("\nSDF_GenerateKeyWithIPK_RSA failed %d | 0x%08x\n", rt, rt);
			return;
		}
		else
		{
			printf("\nSDF_GenerateKeyWithIPK_RSA success\n");
			printf("encKeyLen = %d, encKey: %s\n", encKeyLen, Bin2String(encKey, encKeyLen, true).data());

			rt = SDF_DestroyKey(hSess, hKeyHdl);
			if (rt)
			{
				printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
				return;
			}
			printf("\nSDF_DestroyKey success\n");
			hKeyHdl = NULL;
		}

		//导入会话密钥 内部私钥解密，暂未实现
		/*rt = SDF_ImportKeyWithISK_RSA(g_hSess, 1, encKey, encKeyLen, &hKeyHdl);
		if (rt)
		{
			printf("\nSDF_ImportKeyWithISK_RSA failed %d | 0x%08x\n", rt, rt);
			return;
		}
		else
		{
			printf("\nSDF_ImportKeyWithISK_RSA success\n");

			rt = SDF_DestroyKey(g_hSess, hKeyHdl);
			if (rt)
			{
				printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
				return;
			}
			printf("\nSDF_DestroyKey success\n");
			hKeyHdl = NULL;
		}*/

		/**********以下逻辑，为上面接口密钥存储到加密机的调用方式**********/

		TaZero(encKey, sizeof(encKey));
		int idx = 1;
		void* pIdx = &idx;

		SDF_DestroyKey(hSess, &idx);

		//生成会话密钥 外部公钥加密输出，并存储到加密机内部
		rt = SDF_GenerateKeyWithEPK_RSA(hSess, 128, &rsaPubKey, encKey, &encKeyLen, &pIdx);
		if (rt)
		{
			printf("\nSDF_GenerateKeyWithEPK_RSA failed %d | 0x%08x\n", rt, rt);
			return;
		}
		else
		{
			printf("\nSDF_GenerateKeyWithEPK_RSA success\n");
			printf("key 1: %s\n", Bin2String(encKey, encKeyLen, true).data());
		}

		TaZero(encKey, sizeof(encKey));

		SDF_DestroyKey(hSess, &idx);
		//生成会话密钥 内部公钥加密输出，并存储到加密机内部
		rt = SDF_GenerateKeyWithIPK_RSA(hSess, 1, 2048, encKey, &encKeyLen, &pIdx);
		if (rt)
		{
			printf("\nSDF_GenerateKeyWithIPK_RSA failed %d | 0x%08x\n", rt, rt);
			return;
		}
		else
		{
			printf("\nSDF_GenerateKeyWithIPK_RSA success\n");
			printf("key 2: %s\n", Bin2String(encKey, encKeyLen, true).data());
		}


		SDF_DestroyKey(hSess, &idx);
		//导入会话密钥 内部私钥解密，并存储到加密机内部
		rt = SDF_ImportKeyWithISK_RSA(hSess, 1, encKey, encKeyLen, &pIdx);
		if (rt)
		{
			printf("\nSDF_ImportKeyWithISK_RSA %d | 0x%08x\n", rt, rt);
			return;
		}
		else
		{
			printf("\nSDF_ImportKeyWithISK_RSA success\n");
		}
	}
}

void T_SDF_ExchangeDigitEnvelopeBaseOnRSA(void* hSess)
{
	//获取公钥
	RSArefPublicKey rsaEncPubKey = { 0 };
	auto rt = SDF_ExportEncPublicKey_RSA(hSess, 1, &rsaEncPubKey);
	if (rt)
	{
		printf("\nSDF_ExportEncPublicKey_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_ExportEncPublicKey_RSA success\n");
		printf("EncPubKey.bits: %d\n", rsaEncPubKey.bits);
		printf("EncPubKey.m: %s\n", Bin2String(rsaEncPubKey.m, sizeof(rsaEncPubKey.m), true).data());
		printf("EncPubKey.e: %s\n", Bin2String(rsaEncPubKey.e, sizeof(rsaEncPubKey.e), true).data());
	}

	//生成会话密钥 内部公钥加密输出
	unsigned char encKey[BUF] = { 0 };
	unsigned int encKeyLen = sizeof(encKey) + 1;
	void* hKeyHdl = NULL;
	rt = SDF_GenerateKeyWithIPK_RSA(hSess, 1, 2048, encKey, &encKeyLen, &hKeyHdl);
	if (rt)
	{
		printf("\nSDF_GenerateKeyWithIPK_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_GenerateKeyWithIPK_RSA success\n");
		printf("key 2: %s\n", Bin2String(encKey, encKeyLen, true).data());

		rt = SDF_DestroyKey(hSess, hKeyHdl);
		if (rt) {
			printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
			return;
		}
		printf("\nSDF_DestroyKey success\n");
		hKeyHdl = NULL;
	}

	unsigned char cipherByPubKey[BUF] = { 0 };
	unsigned int cipherByPubKeyLen = sizeof(cipherByPubKey);
	rt = SDF_ExchangeDigitEnvelopeBaseOnRSA(hSess, 1, &rsaEncPubKey, encKey + 4, encKeyLen - 4, cipherByPubKey, &cipherByPubKeyLen);
	if (rt)
	{
		printf("\nSDF_ExchangeDigitEnvelopeBaseOnRSA %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_ExchangeDigitEnvelopeBaseOnRSA success\n");
		printf("cipherByPubKey: %s\n", Bin2String(cipherByPubKey, cipherByPubKeyLen, true).data());
	}
}

int T_KeyManagementFunctions(void *hDev)
{
	int n = 0, rt = 0;
	void* hSess = NULL;
	rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return -1;
	}

	while (1)
	{
		printf("\n");
		printf("------------T_KeyManagementFunctions-----------\n");
		printf("2.[1] T_SDF_ExportPublicKey_ECC\n");
		printf("2.[2] T_SDF_GenerateKeyPair_ECC\n");
		printf("2.[3] T_SDF_GenerateKey_And_Import_ECC\n");
		printf("2.[4] T_SDF_Agreement_WithECC\n");
		printf("2.[5] T_SDF_ExchangeDigitEnvelopeBaseOnECC\n");
		printf("2.[6] T_SDF_GenerateKey_And_Import_KEK\n");
		printf("2.[7] T_SDF_ExportPublicKey_RSA\n");
		printf("2.[8] T_SDF_GenerateKeyPair_RSA\n");
		printf("2.[9] T_SDF_GenerateKey_And_Import_RSA\n");
		printf("2.[10] T_SDF_ExchangeDigitEnvelopeBaseOnRSA\n");
		printf("2.[0] quit\n");
		printf("Test Command Num: ");
		int idx;
		cin >> idx;
		switch (idx) {
		case 1: 
			rt = T_SDF_ExportPublicKey_ECC(hSess);
			break;
		case 2: 
			rt = T_SDF_GenerateKeyPair_ECC(hSess);
			break;
		case 3: 
			rt = T_SDF_GenerateKey_And_Import_ECC(hSess);
			break;
		case 4: 
			rt = T_SDF_Agreement_And_GenerateKey_WithECC(hSess);
			break;
		case 5: 
			rt = T_SDF_ExchangeDigitEnvelopeBaseOnECC(hSess);
			break;
		case 6: 
			rt = T_SDF_GenerateKey_And_Import_KEK(hSess);
			break;
		case 7: T_SDF_ExportPublicKey_RSA(hSess); break;
		case 8: T_SDF_GenerateKeyPair_RSA(hSess); break;
		case 9: T_SDF_GenerateKey_And_Import_RSA(hSess); break;
		case 10: T_SDF_ExchangeDigitEnvelopeBaseOnRSA(hSess); break;
		case 0: 
			SDF_CloseSession(hSess);
			return 0;
		default: printf("Invalid input\n"); break;
		}
	}

	return rt;
}

int T_SDF_Sign_And_Verify_ECC(void *hSess)
{
	unsigned char data[128] = "112233445566112233445566112233445566112233445566";
	unsigned int dataLen = strlen((char*)data);
	unsigned char sm3Hash[128] = { 0 };
	unsigned int sm3Len = sizeof(sm3Hash);

	//对原文数据做hash
	HashOperationData(hSess, data, dataLen, sm3Hash, &sm3Len);

	//获取私钥授权
	int rt = SDF_GetPrivateKeyAccessRight(hSess, g_keyAsymIndex, pwd, pwdLen);
	if (rt)
	{
		printf("\nSDF_GetPrivateKeyAccessRight failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
		printf("\nSDF_GetPrivateKeyAccessRight success\n");

	ECCSignature sign = { 0 };
	rt = SDF_InternalSign_ECC(hSess, g_keyAsymIndex, sm3Hash, sm3Len, &sign);
	if (rt) {
		printf("SDF_InternalSign_ECC failed %#08x\n", rt);
		SDF_ReleasePrivateKeyAccessRight(hSess, g_keyAsymIndex);
		return rt;
	}
	printf("\nSDF_InternalSign_ECC success\n");
	printf("sign.r: %s\n", Bin2String(sign.r, sizeof(sign.r), true).data());
	printf("sign.s: %s\n", Bin2String(sign.s, sizeof(sign.s), true).data());

	SDF_ReleasePrivateKeyAccessRight(hSess, g_keyAsymIndex);

	rt = SDF_InternalVerify_ECC(hSess, 1, sm3Hash, sm3Len, &sign);
	if (rt) {
		printf("SDF_InternalVerify_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_InternalVerify_ECC success\n");

	ECCrefPublicKey signPubKey = { 0 };
	rt = SDF_ExportSignPublicKey_ECC(hSess, 1, &signPubKey);
	if (rt) {
		printf("SDF_ExportSignPublicKey_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_ExportSignPublicKey_ECC success\n");
	printf("PubKey.bits: %d\n", signPubKey.bits);
	printf("PubKey.x: %s\n", Bin2String(signPubKey.x, sizeof(signPubKey.x), true).data());
	printf("PubKey.y: %s\n", Bin2String(signPubKey.y, sizeof(signPubKey.y), true).data());

	ECCrefPublicKey pubKey = { 0 };
	ECCrefPrivateKey priKey = { 0 };
	unsigned int algID = SGD_SM2;

	rt = SDF_GenerateKeyPair_ECC(hSess, algID, 256, &pubKey, &priKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_ECC failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyPair_ECC success\n");
	printf("PubKey.bits: %d\n", pubKey.bits);
	printf("PubKey.x: %s\n", Bin2String(pubKey.x, sizeof(pubKey.x), true).data());
	printf("PubKey.y: %s\n", Bin2String(pubKey.y, sizeof(pubKey.y), true).data());
	printf("PriKey.bits: %d\n", priKey.bits);
	printf("PriKey.K: %s\n", Bin2String(priKey.K, sizeof(priKey.K), true).data());

	memset(&sign, 0, sizeof(ECCSignature));
	rt = SDF_ExternalSign_ECC(hSess, SGD_SM2, &priKey, sm3Hash, sm3Len, &sign);
	if (rt) {
		printf("SDF_ExternalSign_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\n SDF_ExternalSign_ECC success\n");
	printf("sign.r: %s\n", Bin2String(sign.r, sizeof(sign.r), true).data());
	printf("sign.s: %s\n", Bin2String(sign.s, sizeof(sign.s), true).data());

	rt = SDF_ExternalVerify_ECC(hSess, SGD_SM2, &pubKey, sm3Hash, sm3Len, &sign);
	if (rt) {
		printf("SDF_ExternalVerify_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_ExternalVerify_ECC success\n");

	return 0;
}

int T_SDF_Encrypt_And_Decrypt_ECC(void *hSess)
{
	ECCrefPublicKey encPubKey = { 0 };
	ECCCipher encData = { 0 };
	auto rt = SDF_ExportEncPublicKey_ECC(hSess, g_keyAsymIndex, &encPubKey);
	if (rt) {
		printf("SDF_ExportEncPublicKey_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_ExportEncPublicKey_ECC success\n");
	printf("encPubKey.bits: %d\n", encPubKey.bits);
	printf("encPubKey.x: %s\n", Bin2String(encPubKey.x, sizeof(encPubKey.x), true).data());
	printf("encPubKey.y: %s\n", Bin2String(encPubKey.y, sizeof(encPubKey.y), true).data());

	string datas = "1234567890abcdef";
	string inDatas = String2Bin(datas);

	ECCrefPublicKey pubKey = { 0 };
	ECCrefPrivateKey priKey = { 0 };
	unsigned int algID = SGD_SM2;

	rt = SDF_GenerateKeyPair_ECC(hSess, algID, 256, &pubKey, &priKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_ECC failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyPair_ECC success\n");
	printf("PubKey.bits: %d\n", pubKey.bits);
	printf("PubKey.x: %s\n", Bin2String(pubKey.x, sizeof(pubKey.x), true).data());
	printf("PubKey.y: %s\n", Bin2String(pubKey.y, sizeof(pubKey.y), true).data());
	printf("PriKey.bits: %d\n", priKey.bits);
	printf("PriKey.K: %s\n", Bin2String(priKey.K, sizeof(priKey.K), true).data());

	rt = SDF_ExternalEncrypt_ECC(hSess, SGD_SM2, &pubKey, (unsigned char*)inDatas.c_str(), inDatas.size(), &encData);
	if (rt) {
		printf("SDF_ExternalEncrypt_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_ExternalEncrypt_ECC success\n");
	printf("encData.x: %s\n", Bin2String(encData.x, sizeof(encData.x), true).data());
	printf("encData.y: %s\n", Bin2String(encData.y, sizeof(encData.y), true).data());
	printf("encData.M: %s\n", Bin2String(encData.M, sizeof(encData.M), true).data());
	printf("encData.L: %d\n", encData.L);
	printf("encData.C: %s\n", Bin2String(encData.C, encData.L, true).data());

	unsigned char outDec[1024] = { 0 };
	unsigned int len = sizeof(outDec);

	string strX = "B3028E46F8DF66EB50B452C4C25FC663FC20482EC915DCC50C27A7AB4D6071CE";
	string strY = "F27EA1F5137FDA2E59E43DA7305577F723452359F6801B7B02CA5E1FD10B50AC";
	string strM = "643D6BEE0AF0E47C20A555F4E271624DFD34C909EB2E19E510E1E69440A0A55B";
	string strC = "DFD0C0BCF6165BAC";

	string x = String2Bin(strX);
	string y = String2Bin(strY);
	string m = String2Bin(strM);
	string c = String2Bin(strC);

	ECCCipher encData1 = { 0 };
	memcpy(encData1.x, x.c_str(), x.size());
	memcpy(encData1.y, y.c_str(), y.size());
	memcpy(encData1.M, m.c_str(), m.size());
	memcpy(encData1.C, c.c_str(), c.size());
	encData1.L = c.size();

	ECCrefPrivateKey priKey1 = { 0 };
	string strK = "3FBEEA0DC7829CA6CA15EC18675A2A2449BFE75199FA0A95A1D8F10F1438C31A";
	string k = String2Bin(strK);
	memcpy(priKey1.K, k.c_str(), k.size());
	priKey1.bits = 256;

	rt = SDF_ExternalDecrypt_ECC(hSess, SGD_SM2_3, &priKey, &encData, outDec, &len);
	if (rt) {
		printf("SDF_ExternalDecrypt_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_ExternalDecrypt_ECC success\n");
	printf("dataOut  : %s\n", Bin2String(outDec, len, true).data());

	memset(&encData, 0, sizeof(ECCCipher));
	rt = SDF_InternalEncrypt_ECC(hSess, g_keyAsymIndex, (unsigned char*)inDatas.c_str(), inDatas.size(), &encData);
	if (rt) {
		printf("SDF_InternalEncrypt_ECC failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_InternalEncrypt_ECC success\n");
	printf("encData.x: %s\n", Bin2String(encData.x, sizeof(encData.x), true).data());
	printf("encData.y: %s\n", Bin2String(encData.y, sizeof(encData.y), true).data());
	printf("encData.M: %s\n", Bin2String(encData.M, sizeof(encData.M), true).data());
	printf("encData.L: %d\n", encData.L);
	printf("encData.C: %s\n", Bin2String(encData.C, encData.L, true).data());

	//获取私钥授权
	rt = SDF_GetPrivateKeyAccessRight(hSess, g_keyAsymIndex, pwd, pwdLen);
	if (rt)
	{
		printf("\nSDF_GetPrivateKeyAccessRight failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
		printf("\nSDF_GetPrivateKeyAccessRight success\n");

	memset(outDec, 0, 1024);
	len = sizeof(outDec);
	rt = SDF_InternalDecrypt_ECC(hSess, g_keyAsymIndex, &encData, outDec, &len);
	if (rt) {
		printf("SDF_InternalDecrypt_ECC failed %#08x\n", rt);
		SDF_ReleasePrivateKeyAccessRight(hSess, g_keyAsymIndex);
		return rt;
	}
	printf("\nSDF_InternalDecrypt_ECC success\n");
	printf("dataOut  : %s\n", Bin2String(outDec, len, true).data());

	SDF_ReleasePrivateKeyAccessRight(hSess, g_keyAsymIndex);

	return 0;
}

void T_SDF_KeyOperation_RSA(void *hSess)
{
	RSArefPublicKey rsaPubKey = { 0 };
	RSArefPrivateKey rsaPriKey = { 0 };
	unsigned char dataPlain[BUF] = { 0 };
	unsigned int dataPlainLen = 256;
	unsigned char dataEnc[BUF] = { 0 };
	unsigned int dataEncLen = sizeof(dataEnc);
	unsigned char dataOut[BUF] = { 0 };
	unsigned int dataOutLen = sizeof(dataOut);

	for (int i = 0; i < dataPlainLen; i++)
		dataPlain[i] = 'a';

	string str;
	str.append(512, '0');
	printf("str: %s\n", str.data());
	string data = String2Bin(str);
	printf("data.size() = %d\n", data.size());
	//获取公钥
	auto rt = SDF_GenerateKeyPair_RSA(hSess, RSAref_MAX_BITS, &rsaPubKey, &rsaPriKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_GenerateKeyPair_RSA success\n");
		printf("PubKey.bits: %d\n", rsaPubKey.bits);
		printf("PubKey.m: %s\n", Bin2String(rsaPubKey.m, sizeof(rsaPubKey.m), true).data());
		printf("PubKey.e: %s\n", Bin2String(rsaPubKey.e, sizeof(rsaPubKey.e), true).data());
	}

	rt = SDF_ExternalPublicKeyOperation_RSA(hSess, &rsaPubKey, (unsigned char*)data.data(), data.size(), dataEnc, &dataEncLen);
	if (rt)
	{
		printf("\nSDF_ExternalPublicKeyOperation_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_ExternalPublicKeyOperation_RSA success\n");
		printf("dataEnc: %s\n", Bin2String(dataEnc, dataEncLen, true).data());
	}

	TaZero(dataEnc, sizeof(dataEnc));
	dataEncLen = sizeof(dataEnc);
	
	rt = SDF_InternalPublicKeyOperation_RSA(hSess, g_keyAsymIndex, (unsigned char*)data.data(), data.size(), dataEnc, &dataEncLen);
	if (rt)
	{
		printf("\nSDF_InternalPublicKeyOperation_RSA failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
	{
		printf("\nSDF_InternalPublicKeyOperation_RSA success\n");
		printf("dataEncLen = %d, dataEnc: %s\n", dataEncLen, Bin2String(dataEnc, dataEncLen, true).data());
	}

	//获取私钥授权
	rt = SDF_GetPrivateKeyAccessRight(hSess, 0-g_keyAsymIndex, pwd, pwdLen);
	if (rt)
	{
		printf("\nSDF_GetPrivateKeyAccessRight failed %d | 0x%08x\n", rt, rt);
		return;
	}
	else
		printf("\nSDF_GetPrivateKeyAccessRight success\n");

	rt = SDF_InternalPrivateKeyOperation_RSA(hSess, g_keyAsymIndex, dataEnc, dataEncLen, dataOut, &dataOutLen);
	if (rt)
	{
		printf("\nSDF_InternalPrivateKeyOperation_RSA failed %d | 0x%08x\n", rt, rt);
		SDF_ReleasePrivateKeyAccessRight(hSess, 0-g_keyAsymIndex);
		return;
	}
	else
	{
		printf("\nSDF_InternalPrivateKeyOperation_RSA success\n");
		printf("dataOut: %s\n", Bin2String(dataOut, dataOutLen, false).data());
	}
	SDF_ReleasePrivateKeyAccessRight(hSess, 0 - g_keyAsymIndex);
}

int T_AsymOperationFunctions(void *hDev)
{
	int n = 0, rt = 0;
	void* hSess = NULL;
	rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return -1;
	}
	while (1)
	{
		printf("\n");
		printf("------------T_AsymOperationFunctions-----------\n");
		printf("3.[1] T_SDF_Sign_And_Verify_ECC\n");
		printf("3.[2] T_SDF_Encrypt_And_Decrypt_ECC\n");
		printf("3.[3] T_SDF_KeyOperation_RSA\n");
		printf("3.[0] quit\n");
		printf("Test Command Num: ");
		int idx;
		cin >> idx;
		switch (idx) {
		case 1: T_SDF_Sign_And_Verify_ECC(hSess); break;
		case 2: T_SDF_Encrypt_And_Decrypt_ECC(hSess); break;
		case 3: T_SDF_KeyOperation_RSA(hSess); break;
		case 0: 
			SDF_CloseSession(hSess);
			return 0;
		default: printf("Invalid input\n"); break;
		}
	}

	return rt;
}
int T_SDF_Encrypt_And_Decrypt_Type(void *hSess, unsigned int algID)
{
	void* hKeyHdl = NULL;
	unsigned char iv[32] = "1122334455667788";
	unsigned char outData[8192] = { 0 };
	unsigned int len = sizeof(outData);

	unsigned char random[64] = { 0 };
	int randomLen = 16;
	//string str = "12345678123456781234567812345678";
	string str;
	str.append('a', 64);
	string dataBin = String2Bin(str);
	unsigned char data[1024] = { 0 };
	unsigned int dataLen = sizeof(data);
	int rt = SDF_GenerateRandom(hSess, randomLen, random);
	if (rt)
	{
		printf("\nSDF_GenerateRandom failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_GenerateRandom success\n");

	rt = SDF_ImportKey(hSess, random, randomLen, &hKeyHdl);
	if (rt) {
		printf("SDF_ImportKey failed rt = [%d | %#010X]\n", rt, rt);
		return rt;
	}
	printf("\nSDF_ImportKey success\n");

	memset(data, 'a', 32);
	rt = SDF_Encrypt(hSess, hKeyHdl, algID, iv, data, 32, outData, &len);
	if (rt) {
		printf("SDF_Encrypt failed rt = [%d | %#010X]\n", rt, rt);
		return rt;
	}
	printf("Encrypt success, outData = %s, out iv = %s, len = %d\n", Bin2String(outData, len, true).data(), Bin2String(iv, 16, true).c_str(), len);

	memset(iv, 0, sizeof(iv));
	memcpy(iv, "1122334455667788", sizeof("1122334455667788"));

	unsigned char deOutData[1024] = { 0 };
	unsigned int len2 = sizeof(deOutData);
	rt = SDF_Decrypt(hSess, hKeyHdl, algID, iv, outData, len, deOutData, &len2);
	if (rt) {
		printf("\nSDF_Decrypt  failed rt = [%d | %#010X]\n", rt, rt);
		return rt;
	}
	printf("SDF_Decrypt success, outData = %s, out iv = %s, len2 = %d\n", deOutData, Bin2String(iv, 16, true).c_str(), len2);

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt)
	{
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	return 0;
}

int T_SDF_Encrypt_And_Decrypt(void *hSess)
{
	int rt = 0;
	unsigned int SM1[4] = { SGD_SM1_ECB, SGD_SM1_CBC, SGD_SM1_CFB, SGD_SM1_OFB };
	unsigned int SM4[4] = { SGD_SM4_ECB, SGD_SM4_CBC, SGD_SM4_CFB, SGD_SM4_OFB };
	//unsigned int AES[2] = { SGD_AES_ECB, SGD_AES_CBC };
	//unsigned int DES[2] = { SGD_DES_ECB, SGD_DES_CBC };
		

	while (1)
	{
		unsigned char outData[8192] = { 0 };
		unsigned int len = sizeof(outData);

		unsigned char data[1024] = { 0 };
		unsigned int dataLen = sizeof(data);

		int idx = 1;
		memset(data, 'a', 48);
		rt = SDF_Encrypt(hSess, &idx, SGD_SM4_ECB, NULL, data, 48, outData, &len);
		if (rt) {
			printf("SDF_Encrypt failed rt = [%d | %#010X]\n", rt, rt);
			return rt;
		}
		printf("Encrypt success, outData = %s, len = %d\n", Bin2String(outData, len, true).data(), len);

		unsigned char deOutData[1024] = { 0 };
		unsigned int len2 = sizeof(deOutData);
		rt = SDF_Decrypt(hSess, &idx, SGD_SM4_ECB, NULL, outData, len, deOutData, &len2);
		if (rt) {
			printf("\nSDF_Decrypt  failed rt = [%d | %#010X]\n", rt, rt);
			return rt;
		}
		printf("SDF_Decrypt success, outData = %s, len2 = %d\n", deOutData, len2);
	}


	//SM1
	for(int i = 0; i < 4; i++)
	{
		printf("SM1 Opeartion: i = %d\n", i);
		rt = T_SDF_Encrypt_And_Decrypt_Type(hSess, SM1[i]);
		if (rt)
		{
			printf("T_SDF_Encrypt_And_Decrypt_Type ailed! rt = [%d | %#010X]\n", rt, rt);
			return rt;
		}
	}

	/*rt = T_SDF_Encrypt_And_Decrypt_Type(SGD_SM4_CFB);
	if (rt)
	{
		printf("SGD_SM4_CFB: T_SDF_Encrypt_And_Decrypt_Type ailed! rt = [%d | %#010X]\n", rt, rt);
		return rt;
	}
	printf("SGD_SM4_CFB success!\n");*/

	//SM4
	for (int i = 0; i < 4; i++)
	{
		printf("SM4 Opeartion: i = %d\n", i);
		rt = T_SDF_Encrypt_And_Decrypt_Type(hSess, SM4[i]);
		if (rt)
		{
			printf("T_SDF_Encrypt_And_Decrypt_Type ailed! rt = [%d | %#010X]\n", rt, rt);
			return rt;
		}
	}

	//AES
	/*for (int i = 0; i < 2; i++)
	{
		printf("AES Opeartion:\n");
		rt = T_SDF_Encrypt_And_Decrypt_Type(AES[i]);
		if (rt)
			printf("T_SDF_Encrypt_And_Decrypt_Type ailed! rt = [%d | %#010X]\n", rt, rt);
	}*/

	//DES
	/*for (int i = 0; i < 2; i++)
	{
		printf("DES Opeartion:\n");
		rt = T_SDF_Encrypt_And_Decrypt_Type(DES[i]);
		if (rt)
			printf("T_SDF_Encrypt_And_Decrypt_Type ailed! rt = [%d | %#010X]\n", rt, rt);
	}*/
		
	return rt;
}

int T_SDF_CalculateMAC(void* hSess)
{
	void* hKeyHdl = NULL;
	unsigned char pucMAC[1024] = { 0 };
	unsigned int pucMACLen = 1024;
	unsigned char iv[32] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
	unsigned char plain[1024] = "11223344112233441122334411223344";
	unsigned int len = sizeof(plain);

	string str = "11223344112233441122334411223344";
	string dataBin = String2Bin(str);

	unsigned char random[64] = { 0 };
	int randomLen = 16;
	int rt = SDF_GenerateRandom(hSess, randomLen, random);
	if (rt)
	{
		printf("\nSDF_GenerateRandom failed %d | 0x%08x\n", rt, rt);
		return rt;
	}

	rt = SDF_ImportKey(hSess, random, randomLen, &hKeyHdl);
	if (rt)
	{
		printf("SDF_ImportKey Error %d | 0x%08x\n", rt, rt);
		return rt;
	}

	rt = SDF_CalculateMAC(hSess, hKeyHdl, SGD_SM4_MAC, iv, (unsigned char*)dataBin.c_str(), dataBin.size(), pucMAC, &pucMACLen);
	if (rt) {
		printf("SDF_CalculateMAC  failed rt = [%d | %#010X]\n", rt, rt);
		return rt;
	}
	printf("SDF_CalculateMAC success, outData = %s\n outIV = %s\n", Bin2String(pucMAC, pucMACLen, true).data(), Bin2String(iv, 16, true).data());

	rt = SDF_DestroyKey(hSess, hKeyHdl);
	if (rt)
	{
		printf("\nSDF_DestroyKey failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_DestroyKey success\n");
	hKeyHdl = NULL;

	return 0;
}


int T_SymOperationFunctions(void *hDev)
{
	int n = 0, rt = 0;
	void* hSess = NULL;
	rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return -1;
	}
	while (1)
	{
		printf("\n");
		printf("------------T_SymOperationFunctions-----------\n");
		printf("4.[1] T_SDF_Encrypt_And_Decrypt\n");
		printf("4.[2] T_SDF_CalculateMAC\n");
		printf("4.[0] quit\n");
		printf("Test Command Num: ");
		int idx;
		cin >> idx;
		switch (idx) {
		case 1: 
			rt = T_SDF_Encrypt_And_Decrypt(hSess);
			break;
		case 2: 
			rt = T_SDF_CalculateMAC(hSess);
			break;
		case 0: 
			SDF_CloseSession(hSess);
			return 0;;
		default: printf("Invalid input\n"); break;
		}
	}
	return rt;
}

int T_HashOperationFunctions(void *hDev)
{
	void* hSess = NULL;
	auto rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return -1;
	}
	ECCrefPublicKey pubKey = { 0 };
	ECCrefPrivateKey priKey = { 0 };

	rt = SDF_GenerateKeyPair_ECC(hSess, SGD_SM2, 256, &pubKey, &priKey);
	if (rt)
	{
		printf("\nSDF_GenerateKeyPair_ECC failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	printf("\nSDF_GenerateKeyPair_ECC success\n");
	printf("PubKey.bits: %d\n", pubKey.bits);
	printf("PubKey.x: %s\n", Bin2String(pubKey.x, sizeof(pubKey.x), true).data());
	printf("PubKey.y: %s\n", Bin2String(pubKey.y, sizeof(pubKey.y), true).data());
	printf("PriKey.bits: %d\n", priKey.bits);
	printf("PriKey.K: %s\n", Bin2String(priKey.K, sizeof(priKey.K), true).data());

	unsigned char pucID[128] = "\x11\x22\x33\x44\x55\x66\x77\x88\x11\x22\x33\x44\x55\x66\x77\x88";
	unsigned int uiIDLength = 16;
	unsigned char data[] = "112233445566112233445566112233445566112233445566";
	unsigned char sm3Hash[128] = { 0 };
	unsigned int sm3Len = sizeof(sm3Hash);
	printf("pucID = %s\n", Bin2String(pucID, 16, true).c_str());
	//rt = SDF_HashInit(g_hSess, SGD_SM3, NULL, NULL, 0);
	rt = SDF_HashInit(hSess, SGD_SM3, &pubKey, pucID, uiIDLength);
	if (rt) {
		printf("SDF_HashInit failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_HashInit success\n");

	string hex = String2Bin((char*)data);

	rt = SDF_HashUpdate(hSess, (unsigned char*)hex.c_str(), hex.size());
	if (rt) {
		printf("SDF_HashUpdate failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_HashUpdate success. data = %s\n", data);

	rt = SDF_HashFinal(hSess, sm3Hash, &sm3Len);
	if (rt) {
		printf("SDF_HashFinal failed %#08x\n", rt);
		return rt;
	}
	printf("\nSDF_HashFinal success! sm3Len = %d, sm3Hash = %s\n", sm3Len, Bin2String((unsigned char*)sm3Hash, (unsigned int)sm3Len, true).c_str());

	SDF_CloseSession(hSess);
	return 0;
}

int T_FileOperationFunctions(void *hDev)
{
	void* hSess = NULL;
	auto rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return -1;
	}

	unsigned char pucFileName[128] = "testFile";
	unsigned int uiFileSize = 1024;
	unsigned int uiNameLen = strlen((char*)pucFileName);

	unsigned int uiOffset = 0;

	rt = SDF_CreateFile(hSess, pucFileName, uiNameLen, uiFileSize);
	if (rt) {
		printf("SDF_CreateFile failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_CreateFile success!\n");

	unsigned char pucBuffer[64] = "123456789abcdef";
	unsigned int uiFileLength = strlen((char*)pucBuffer);
		
	rt = SDF_WriteFile(hSess, pucFileName, uiNameLen, uiOffset, strlen((char*)pucBuffer), pucBuffer);
	if (rt) {
		printf("SDF_WriteFile failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_WriteFile success!\n");
	
	unsigned char out[1024*14] = { 0 };
	unsigned int outLen = sizeof(out);
		
	rt = SDF_ReadFile(hSess, pucFileName, uiNameLen, uiOffset, &outLen, out);
	if (rt) {
		printf("SDF_ReadFile failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_ReadFile success! outLen = %d, out: %s\n\n\n", outLen, out);

	rt = SDF_DeleteFile(hSess, pucFileName, uiNameLen);
	if (rt) {
		printf("SDF_DeleteFile failed %#08x\n", rt);
		return rt;
	}
	printf("SDF_DeleteFile success!\n");
	SDF_CloseSession(hSess);

	return 0;
}

void T_SelfTest_KeyManagementFunctions(void* hDev)
{
	int rt = 0;
	void* hSess = NULL;
	rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return;
	}

	T_SDF_ExportPublicKey_ECC(hSess);
	T_SDF_GenerateKeyPair_ECC(hSess);
	T_SDF_GenerateKey_And_Import_ECC(hSess);
	T_SDF_Agreement_And_GenerateKey_WithECC(hSess);
	T_SDF_ExchangeDigitEnvelopeBaseOnECC(hSess);
	T_SDF_GenerateKey_And_Import_KEK(hSess);
	T_SDF_ExportPublicKey_RSA(hSess); 
	T_SDF_GenerateKeyPair_RSA(hSess); 
	T_SDF_GenerateKey_And_Import_RSA(hSess); 
	T_SDF_ExchangeDigitEnvelopeBaseOnRSA(hSess); 

	SDF_CloseSession(hSess);
}

void T_SelfTest_AsymOperationFunctions(void* hDev)
{
	void* hSess = NULL;
	int rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return;
	}

	T_SDF_Sign_And_Verify_ECC(hSess);
	T_SDF_Encrypt_And_Decrypt_ECC(hSess); 
	T_SDF_KeyOperation_RSA(hSess); 
		
	SDF_CloseSession(hSess);
}

void T_SelfTest_SymOperationFunctions(void *hDev)
{
	void* hSess = NULL;
	int rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return;
	}

	T_SDF_Encrypt_And_Decrypt(hSess);
	T_SDF_CalculateMAC(hSess);

	SDF_CloseSession(hSess);
}

void T_SelfTest(void* hDev)
{
	T_SDF_GenerateRandom(hDev);

	T_HashOperationFunctions(hDev);

	T_SelfTest_KeyManagementFunctions(hDev);

	T_SelfTest_AsymOperationFunctions(hDev);

	T_SelfTest_SymOperationFunctions(hDev);

	T_HashOperationFunctions(hDev);

	T_FileOperationFunctions(hDev);
}

int ECC256K1_ECC256R1_Sign_And_Verify_Index(void* hSess)
{
	unsigned int index = 1;
	TassAlg uiAlgID = TA_ALG_ECC_SECP_256K1;

	unsigned char data[] = "12345678123456781234567812345678";
	unsigned int dataLen = strlen((char*)data);

	const string hashInput = "472bbe83616e93d3c09a79103ae47d8f71e3d35a966d6e8b22f743218d04171d";
	
	unsigned char sm3Hash[128] = {0};
	unsigned int sm3Len = sizeof(sm3Hash);

    
	
	//获取私钥授权
	int rt = TassGetPrivateKeyAccessRight(hSess, index, uiAlgID, pwd, pwdLen);
	if (rt)
	{
		printf("\nTassGetPrivateKeyAccessRight failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
		printf("\nTassGetPrivateKeyAccessRight success\n");

	//对原文数据做hash
	//HashOperationData(hSess, data, dataLen, sm3Hash, &sm3Len);
	String2Bin(hashInput, sm3Hash, &sm3Len);
	printf("\nhash: %s\n", Bin2String(sm3Hash, sm3Len, false).data());

	unsigned int keyBits = 256;
	unsigned char sig[128] = { 0 };
	unsigned int sigLen = sizeof(sig);

	rt = TassECCPrivateKeySign_Eth(hSess,
		uiAlgID,
		index, keyBits,
		NULL, 0,
		sm3Hash, sm3Len,
		sig, &sigLen);
	if (rt)
	{
		printf("\nTassECCPrivateKeySign failed %d | 0x%08x\n", rt, rt);
		SDF_ReleasePrivateKeyAccessRight(hSess, index);
		return rt;
	}
	else
	{
		printf("\nTassECCPrivateKeySign success\n");
		PRINT_BUF(TassECCPrivateKeySign, sig, sigLen);
	}
	SDF_ReleasePrivateKeyAccessRight(hSess, index);

	rt = TassECCPublicKeyVerify(hSess,
		uiAlgID,
		index, keyBits,
		NULL, 0,
		sm3Hash, sm3Len,
		sig, sigLen);
	if (rt)
	{
		printf("\nTassECCPublicKeyVerify failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
		printf("\nTassECCPublicKeyVerify success\n");
	
	return 0;
}

int ECC256K1_ECC256R1_Sign_And_Verify_Key(void* hSess)
{
	unsigned int index = 10;
	TassAlg uiAlgID = TA_ALG_ECC_SECP_256K1;

	unsigned char data[] = "12345678123456781234567812345678";
	unsigned int dataLen = strlen((char*)data);
	unsigned char sm3Hash[128] = { 0 };
	unsigned int sm3Len = sizeof(sm3Hash);

	//对原文数据做hash
	HashOperationData(hSess, data, dataLen, sm3Hash, &sm3Len);

	unsigned char sk_key[256] = { 0 };
	unsigned char pk_kcv[256] = { 0 };
	unsigned int sk_keyLen = sizeof(sk_key);
	unsigned int pk_keyLen = sizeof(pk_kcv);

	int rt = TassGetKey(hSess, uiAlgID, index, TA_ASYM_SIGN, sk_key, &sk_keyLen, pk_kcv, &pk_keyLen);
	PRINT_BUF(TassGetKey, sk_key, sk_keyLen);
	PRINT_BUF(TassGetKey, pk_kcv, pk_keyLen);

	unsigned int keyBits = 256;
	unsigned char sig[128] = { 0 };
	unsigned int sigLen = sizeof(sig);

	rt = TassECCPrivateKeySign(hSess,
		uiAlgID,
		0, keyBits,
		sk_key, sk_keyLen,
		sm3Hash, sm3Len,
		sig, &sigLen);
	if (rt)
	{
		printf("\nTassECCPrivateKeySign failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
	{
		printf("\nTassECCPrivateKeySign success\n");
		PRINT_BUF(TassECCPrivateKeySign, sig, sigLen);
	}

	rt = TassECCPublicKeyVerify(hSess,
		uiAlgID,
		0, keyBits,
		pk_kcv, pk_keyLen,
		sm3Hash, sm3Len,
		sig, sigLen);
	if (rt)
	{
		printf("\nTassECCPublicKeyVerify failed %d | 0x%08x\n", rt, rt);
		return rt;
	}
	else
		printf("\nTassECCPublicKeyVerify success\n");

	return 0;
}

void T_ECC256K1_ECC256R1_Sign_And_Verify(void* hDev)
{
	void* hSess = NULL;
	int rt = SDF_OpenSession(hDev, &hSess);
	if (rt) {
		printf("SDF_OpenSession failed %#08x\n", rt);
		return;
	}

	//使用内部索引
	ECC256K1_ECC256R1_Sign_And_Verify_Index(hSess);
	//使用外传密钥
	ECC256K1_ECC256R1_Sign_And_Verify_Key(hSess);

	SDF_CloseSession(hSess);
}

int main(int argc, char* argv[])
{
	int rt = 0;
	void* hDev = NULL;
	/*rt = TassSetCfgPath("/root/lgl/cfg");
	if (rt) {
		printf("TassSetCfgPath failed %#08x\n", rt);
		return -1;
	}
	printf("TassSetCfgPath success!\n");*/

	rt = SDF_OpenDevice(&hDev);
	if (rt) {
		printf("SDF_OpenDevice failed %#08x\n", rt);
		return -1;
	}
	printf("SDF_OpenDevice success!\n");

	while (1) {
		printf("\n");
		printf("---------------------------SDF Functions Test-------------------------\n");
		printf("[1] T_SDF_GenerateRandom\n");
		printf("[2] T_KeyManagementFunction\n");
		printf("[3] T_AsymOperationFunctions\n");
		printf("[4] T_SymOperationFunctions\n");
		printf("[5] T_HashOperationFunctions\n");
		printf("[6] T_FileOperationFunctions\n");
		printf("[7] T_SelfTest\n");
		printf("[8] T_ECC256K1_ECC256R1_Sign_And_Verify\n");
		printf("[0] Exit\n");
		printf("Test Command Num: ");
		int idx, rt = 0;
		cin >> idx;
		switch (idx) {
		case 1: 
			rt = T_SDF_GenerateRandom(hDev);
			break;
		case 2: 
			rt = T_KeyManagementFunctions(hDev);
			break;
		case 3: 
			rt = T_AsymOperationFunctions(hDev);
			break;
		case 4: 
			rt = T_SymOperationFunctions(hDev);
			break;
		case 5: 
			rt = T_HashOperationFunctions(hDev);
			break;
		case 6:
			rt = T_FileOperationFunctions(hDev);
			break;
		case 7: 
			T_SelfTest(hDev);
			break;
		case 8:
			T_ECC256K1_ECC256R1_Sign_And_Verify(hDev);
			break;
		case 0:
			rt = SDF_CloseDevice(hDev);

			return 0;
		default: printf("Invalid input\n"); 
			break;
		}
	}

	system("pause");
	return 0;
}
