Commit 050b2da5 authored by hezhengjun's avatar hezhengjun

Initial commit for tass hsm

parents
[SECTION]
filePath = 0
timeout = 10
.PHONY: ctrl sdf clean
default: ctrl
ctrl:
@g++ PCIeCtl_Test.cpp -o ctrl -I../include/ -std=c++11 -L ../linux64/ -lTassSDF4PCIeSM -lTassCtlAPI4PCIeSM -ltass_pcie_api
sdf:
@g++ PCIeSDF_Test.cpp -o sdf -I../include/ -std=c++11 -L ../linux64/ -lTassSDF4PCIeSM -lTassCtlAPI4PCIeSM -ltass_pcie_api -Wformat
clean:
@rm -f ctrl sdf
#include "TassCtlAPI4PCIeSM.h"
#include "TassType4PCIeSM.h"
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <iomanip>
#if defined(_WIN32) || defined(_WIN64)
#include <io.h >
#include <sys\timeb.h>
#include <windows.h>
#else
#include <unistd.h>
#include <arpa/inet.h>
#include <curses.h>
#include <sys/time.h>
#include <dlfcn.h>
#endif
#define TTY_PATH "/dev/tty"
#define STTY_CLOSE "stty raw -echo -F "
#define STTY_OPEN "stty -raw echo -F "
#define INPUT_ADMIN_PIN() system(STTY_CLOSE TTY_PATH);\
printf("\n请输入管理员口令:");\
cin >> pwd;\
system(STTY_OPEN TTY_PATH);\
#define STR(msg) #msg
static int isLogin = 0;
unsigned char g_pwdHashCipher[128] = { 0 };
unsigned char g_encKey[128] = { 0 };
#define CheckRt(func, rt)\
do{\
if (rt != 0) {\
printf("Function [%s] run failed, rt = [%d | %#010X]\n", #func, rt, rt);\
return rt;\
}\
else {\
printf("Function [%s] run success\n", #func);\
}\
} while (0)
#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)
#define PRINT_STR(func, str)\
do{\
/*printf("Function [%s] -> %s [strlen(%s) = %d|%#010X]:\n\t%s\n", #func, #str, #str, strlen(str), strlen(str), str);*/\
} while (0)
#define PRINT_NUM(func, len)\
do{\
/*printf("Function [%s] -> %s = %d|%#010X\n", #func, #len, len, len);*/\
} while (0)
#define PRINT_STRUCT_ITEM(st, item)\
do{\
/*printf("[%s] -> [%s %d|%#010X]:\n\t%s\n", #st, #item, sizeof(st.item), sizeof(st.item), Utility::Bin2String(st.item, sizeof(st.item), true).c_str()); */\
}while(0);
using namespace std;
char g_pwdKeyManager[32] = { 0 };
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);
}
int WriteFileData(const char* pPath, const char* pBuf, int dataLen)
{
if (pPath == NULL)
{
return -1;
}
FILE* fp = fopen(pPath, "ab");
if (fp != NULL)
{
fwrite(pBuf, 1, dataLen, fp);
fclose(fp);
}
else
{
return -1;
}
return 0;
}
int ReadFileData(const char* pPath, char* pBuf, int* dataLen)
{
if (access(pPath, 0) != 0)
return -1;
FILE* fp = fopen(pPath, "r");
if (fp == NULL)
return -1;
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
rewind(fp);
*dataLen = size;
int len = fread(pBuf, 1, size, fp);;
fclose(fp);
return 0;
}
int DeviceFormat_InitRestoreFactory(void* hDev, unsigned char* encPk)
{
char pwd[32] = { 0 };
system(STTY_CLOSE TTY_PATH);
printf("\n请输入管理员口令:");
cin >> pwd; //默认固定为admin,可在初始化为生产状态时出入新的口令
system(STTY_OPEN TTY_PATH);
printf("\n正在准备设备格式化、初始化为出厂状态,请稍等...\n");
unsigned char pwdHashCipher[128] = { 0 };
auto rt = TassCtlEncryptPwdHash(hDev, encPk, pwd, pwdHashCipher);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDev, "admin", pwdHashCipher);
CheckRt(TassCtlLogin, rt);
rt = TassCtlDeviceFormat(hDev, pwdHashCipher);
CheckRt(TassCtlDeviceFormat, rt);
//格式化会清除登录状态,需要重新使用默认口令登录设备管理员
char adminPwd[32] = { 0 };
system(STTY_CLOSE TTY_PATH);
printf("\n格式化成功,出厂设置需要重新输入管理员默认口令登录:");
cin >> adminPwd; //默认固定为admin
system(STTY_OPEN TTY_PATH);
unsigned char adminPwdHash[128] = { 0 };
rt = TassCtlEncryptPwdHash(hDev, encPk, adminPwd, adminPwdHash);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDev, "admin", adminPwdHash);
CheckRt(TassCtlLogin, rt);
rt = TassCtlDeviceInitRestoreFactory(hDev, (const unsigned char*)"\x00\x02\x04\x41", 1800);
CheckRt(TassCtlDeviceInitRestoreFactory, rt);
rt = TassCtlLogout(hDev);
CheckRt(TassCtlLogout, rt);
printf("\n出厂状态设置完成!\n\n");
return 0;
}
int DeviceFormat_Init(void* hDev, unsigned char* encPk)
{
char pwd[32] = { 0 };
printf("\n正在准备设备格式化、初始化为生产状态,请稍等...\n");
INPUT_ADMIN_PIN();
unsigned char pwdHashCipher[128] = { 0 };
auto rt = TassCtlEncryptPwdHash(hDev, encPk, pwd, pwdHashCipher);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDev, "admin", pwdHashCipher);
CheckRt(TassCtlLogin, rt);
rt = TassCtlDeviceFormat(hDev, pwdHashCipher);
CheckRt(TassCtlDeviceFormat, rt);
//格式化会清除登录状态,需要重新使用默认口令登录设备管理员
rt = TassCtlLogin(hDev, "admin", pwdHashCipher);
CheckRt(TassCtlLogin, rt);
char newPwd[32] = { 0 };
//system(STTY_CLOSE TTY_PATH);
printf("格式化成功,生产状态设置请输入新的管理员口令,之后登录均使用该口令: ");
cin >> newPwd;
//system(STTY_OPEN TTY_PATH);
unsigned char newPwdHash[128] = { 0 };
rt = TassCtlEncryptPwdHash(hDev, encPk, newPwd, newPwdHash);
CheckRt(TassCtlEncryptPwdHash, rt);
unsigned char kekCv[16] = { 0 };
rt = TassCtlDeviceInit(hDev, newPwdHash, TA_BOOL_FALSE, (const unsigned char*)"\x00\x02\x04\x41", 1800, kekCv);
CheckRt(TassCtlDeviceInit, rt);
PRINT_BUF(TassCtlDeviceInit, kekCv, sizeof(kekCv));
//格式化会清除登录状态,需要用新口令登录设备管理员
rt = TassCtlLogin(hDev, "admin", newPwdHash);
CheckRt(TassCtlLogin, rt);
rt = TassCtlLogout(hDev);
CheckRt(TassCtlLogout, rt);
printf("\n生产状态设置完成!\n\n");
return 0;
}
int DeviceBackup(void* hDev, unsigned char* encPk)
{
char pwd[32] = { 0 };
unsigned char pwdHashCipher[128] = { 0 };
INPUT_ADMIN_PIN();
printf("\n正在准备备份数据,请稍等...\n");
auto rt = TassCtlEncryptPwdHash(hDev, encPk, pwd, pwdHashCipher);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDev, "admin", pwdHashCipher); //暂用设备管理员登录
CheckRt(TassCtlLogin, rt);
unsigned char devInfo[1024 * 1024] = { 0 };
unsigned int devInfoLen = sizeof(devInfo);
rt = TassCtlBackup(hDev, NULL, pwdHashCipher, devInfo, &devInfoLen);
CheckRt(TassCtlBackup, rt);
rt = WriteFileData("devInfoList", (char*)devInfo, devInfoLen);
CheckRt(WriteFileData, rt);
rt = TassCtlLogout(hDev);
CheckRt(TassCtlLogout, rt);
printf("\n备份数据完成!\n\n");
return 0;
}
int DeviceRecover(void* hDev, unsigned char* encPk)
{
char pwd[32] = { 0 };
unsigned char pwdHashCipher[128] = { 0 };
INPUT_ADMIN_PIN();
printf("\n正在复制恢复数据,请稍等...\n");
auto rt = TassCtlEncryptPwdHash(hDev, encPk, pwd, pwdHashCipher);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDev, "admin", pwdHashCipher); //暂用设备管理员登录
CheckRt(TassCtlLogin, rt);
unsigned char devInfo[1024 * 1024] = { 0 };
int devInfoLen = sizeof(devInfo);
rt = ReadFileData("devInfoList", (char*)devInfo, &devInfoLen);
CheckRt(ReadFileData, rt);
rt = TassCtlCheckBackupInfoValid(hDev, pwdHashCipher, devInfo, devInfoLen);
CheckRt(TassCtlCheckBackupInfoValid, rt);
rt = TassCtlDeviceFormat(hDev, pwdHashCipher);
CheckRt(TassCtlDeviceFormat, rt);
//格式化会清除登录状态,需要重新使用默认口令登录设备管理员
char adminPwd[32] = { 0 };
system(STTY_CLOSE TTY_PATH);
printf("\n格式化成功,出厂设置需要重新输入管理员默认口令登录:");
cin >> adminPwd; //默认固定为admin
system(STTY_OPEN TTY_PATH);
unsigned char adminPwdHash[128] = { 0 };
rt = TassCtlEncryptPwdHash(hDev, encPk, adminPwd, adminPwdHash);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDev, "admin", adminPwdHash);
CheckRt(TassCtlLogin, rt);
rt = TassCtlRecover(hDev, adminPwdHash, devInfo, devInfoLen);
CheckRt(TassCtlRecover, rt);
rt = TassCtlLogin(hDev, "admin", adminPwdHash);
CheckRt(TassCtlLogin, rt);
rt = TassCtlLogout(hDev);
CheckRt(TassCtlLogout, rt);
printf("\n恢复数据完成!\n\n");
return 0;
}
int ScanfKey(void* hDev)
{
int alg = 0;
unsigned char info[256] = { 0 };
unsigned int infoLen = sizeof(info);
TassKeyInfo infos[64];
int len = sizeof(TassKeyInfo);
while (1)
{
printf("请输入要查询的密钥类型,0-SM4, 1-SM1,2-SM2,3-ECC_SECP_256R1, 4-RSA, 5-AES, 6-DES,7-SM7, 8-ECC_SECP_256K1, 9-HMAC: ");
cin >> alg;
if (alg == 0 || alg == 1 || alg == 2 || alg == 3 || alg == 4 || alg == 5 || alg == 6 || alg == 7 || alg == 8 || alg == 9)
break;
else
printf("该类型不支持!\n");
}
int rt = TassCtlListKey(hDev, (TassAlg)alg, infos, &len);
CheckRt(TassCtlListKey, rt);
printf("密钥个数 = %d\n", len / sizeof(TassKeyInfo));
for(int i = 0; i < len / sizeof(TassKeyInfo); i++)
printf("index = %d, pk_kcv: %s\nsk_key: %s\n", infos[i].index, Bin2String(infos[i].pk_kcv, infos[i].pk_kcvLen, true).data(), Bin2String(infos[i].sk_key, infos[i].sk_keyLen, true).data());
printf("\n");
return 0;
}
int DeleteKey(void* hDev)
{
unsigned int index = 0, alg = 0;
while (1)
{
printf("请输入要删除的密钥类型,0-SM4, 1-SM1,2-SM2,3-ECC_SECP_256R1, 4-RSA, 5-AES, 6-DES,7-SM7, 8-ECC_SECP_256K1, 9-HMAC: ");
cin >> alg;
if (alg == 0 || alg == 1 || alg == 2 || alg == 3 || alg == 4 || alg == 5 || alg == 6 || alg == 7 || alg == 8 || alg == 9)
break;
else
printf("该类型不支持!\n");
}
printf("请输入要删除的密钥索引号:");
cin >> index;
int rt = TassCtlDestroyKey(hDev, (TassAlg)alg, index);
CheckRt(TassCtlDestroyKey, rt);
printf("\n删除密钥成功!\n\n");
return 0;
}
int GenerateKey(void* hDev)
{
int alg, index = 0, keyBits;
while (1)
{
printf("请输入要生成的密钥类型,0-SM4, 1-SM1,2-SM2,3-ECC_SECP_256R1, 4-RSA, 5-AES, 6-DES,7-SM7, 8-ECC_SECP_256K1, 9-HMAC: ");
cin >> alg;
if (alg == 0 || alg == 1 || alg == 2 || alg == 3 || alg == 4 || alg == 5 || alg == 6 || alg == 7 || alg == 8 || alg == 9)
break;
else
printf("该类型不支持!\n");
}
if ((TassAlg)alg == TA_ALG_RSA)
keyBits = 2048;
if ((TassAlg)alg == TA_ALG_SM2 || (TassAlg)alg == TA_ALG_ECC_SECP_256R1 || (TassAlg)alg == TA_ALG_ECC_SECP_256K1)
keyBits = 256;
if ((TassAlg)alg == TA_ALG_SM1 || (TassAlg)alg == TA_ALG_AES || (TassAlg)alg == TA_ALG_DES || (TassAlg)alg == TA_ALG_SM4 || (TassAlg)alg == TA_ALG_SM7)
keyBits = 128;
if ((TassAlg)alg == TA_ALG_HMAC)
{
while (1)
{
printf("请输入要生成的HMAC密钥的模长 128、256、384、512:");
cin >> keyBits;
if (keyBits == 128 || keyBits == 256 || keyBits == 384 || keyBits == 512)
break;
else
printf("该模长不支持!\n");
}
}
printf("请输入要存储的密钥索引号:");
cin >> index;
unsigned char sk_key[1024] = { 0 };
unsigned int sk_keyLen = sizeof(sk_key);
unsigned char pk_kcv[1024] = { 0 };
unsigned int pk_kcvLen = sizeof(pk_kcv);
int rt = TassCtlGenerateKey(hDev,
(TassAlg)alg,
keyBits,
index,
NULL, NULL,
sk_key, &sk_keyLen,
pk_kcv, &pk_kcvLen);
CheckRt(TassCtlGenerateKey, rt);
printf("sk_keyLen = %d, sk_key = %s\n", sk_keyLen, Bin2String(sk_key, sk_keyLen, true).data());
printf("pk_kcvLen = %d, pk_kcv = %s\n", pk_kcvLen, Bin2String(pk_kcv, pk_kcvLen, true).data());
printf("\n生成密钥成功!\n\n");
}
int Device_KeyManager(void* hDev)
{
while (true) {
int idx = 0;
printf("[%d] 查询密钥\n", ++idx);
printf("[%d] 删除密钥\n", ++idx);
printf("[%d] 生成密钥\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: ScanfKey(hDev); break;
case 2: DeleteKey(hDev); break;
case 3: GenerateKey(hDev); break;
case 0: {
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
return 0;
}
int Device_ImporPlaintKey(void* hDev)
{
int rt = 0;
//string sm2Pk = "AECF38A316B43733881971C685CA33B3A1E69A27FCEB13A01D593373DC5D032ECFCC4601C815D653ABC2012EF30E1E6D8BC9D00E0B90634E0630C0D5923557D9";
//string sm2Sk = "FC0249EF1FBDB1B31CAE486AE1E54F7BF21B23A9CA87DED96EDEBA67BB1DC75D";
string sm2Pk;
string sm2Sk;
printf("请输入SM2的公钥:");
cin >> sm2Pk;
printf("请输入SM2的私钥:");
cin >> sm2Sk;
string sm2Pub = String2Bin(sm2Pk);
string sm2Pri = String2Bin(sm2Sk);
int indexSm2 = 0;
printf("SM2\n");
printf("请输入导入SM2的密钥索引号:");
cin >> indexSm2;
rt = TassCtlImportPlainKey(hDev,
TA_ALG_SM2,
indexSm2,
NULL,
NULL,
(unsigned char*)sm2Pri.data(), sm2Pri.size(),
(unsigned char*)sm2Pub.data(), sm2Pub.size());
CheckRt(TassCtlImportPlainKey, rt);
printf("SM4\n");
/*string sm4 = "RBF9B62F18E83907304870A3433493C81";
string sm4Kcv = "01F0E5EA25028A88";*/
/*unsigned char sk_key[128] = { 0 };
unsigned int sk_keyLen = sizeof(sk_key);
unsigned char pk_kcv[128] = { 0 };
unsigned int pk_kcvLen = sizeof(pk_kcv);
rt = TassCtlGenerateKey(hDev,
TA_ALG_SM4,
128,
1,
NULL, NULL,
sk_key, &sk_keyLen,
pk_kcv, &pk_kcvLen);
CheckRt(TassCtlGenerateKey, rt);*/
string sm4;
printf("请输入SM4的密钥:");
cin >> sm4;
string sm4Key = String2Bin(sm4);
/*string kcv = String2Bin(sm4Kcv);*/
int indexSm4 = 0;
printf("请输入导入SM4的密钥索引号:");
cin >> indexSm4;
rt = TassCtlImportPlainKey(hDev,
TA_ALG_SM4,
indexSm4,
NULL,
NULL,
(unsigned char*)sm4Key.data(), sm4Key.size(),
(unsigned char*)"", 0);
CheckRt(TassCtlImportPlainKey, rt);
return 0;
}
int Device_FormatOperation(void *hDev, unsigned char* encPk)
{
int rt = 0;
while (true) {
int idx = 0;
printf("[%d] 设备格式化、初始化为出厂状态\n", ++idx);
printf("[%d] 设备格式化、初始化为生产状态\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: DeviceFormat_InitRestoreFactory(hDev, encPk); break;
case 2: DeviceFormat_Init(hDev, encPk); break;
case 0: {
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
}
int Device_BackupRecover(void* hDev, unsigned char* encPk)
{
int rt = 0;
while (true) {
int idx = 0;
printf("[%d] 备份设备信息\n", ++idx);
printf("[%d] 恢复设备信息\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: DeviceBackup(hDev, encPk); break;
case 2: DeviceRecover(hDev, encPk); break;
case 0: {
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
}
int Device_ChangePrikeyPwd(void* hDev)
{
int rt = 0;
unsigned int alg = 0;
while (1)
{
printf("请输入修改私钥权限的密钥类型:2-SM2,3-ECC_SECP_256R1, 4-RSA, 8-ECC_SECP_256K1: ");
cin >> alg;
if (alg == 2 || alg == 3 || alg == 4 || alg == 8)
break;
else
printf("该类型不支持!\n");
}
unsigned int index = 0;
printf("请输入要修改私钥权限口令的索引:");
cin >> index;
string privateKeyPwd;
printf("请输入新的私钥权限口令:");
cin >> privateKeyPwd;
rt = TassCtlChangePrivateKeyAccessRight(hDev,
(TassAlg)alg, index,
(unsigned char*)privateKeyPwd.data(), privateKeyPwd.size());
CheckRt(TassCtlChangePrivateKeyAccessRight, rt);
printf("\n修改私钥权限口令成功!\n\n");
}
int Device_LoginAndGetEncKey(void** hDev)
{
int rt = 0;
unsigned int idLen = 0;
rt = TassCtlScanDevice(nullptr, &idLen);
CheckRt(TassCtlScanDevice, rt);
char ids[256] = { 0 };
TassCtlScanDevice(ids, &idLen);
int i = 0;
auto* p = ids;
while (strlen(p) != 0) {
//printf("Device ID[%d]: %s\n", ++i, p);
p += strlen(p) + 1;
}
void* hDevTmp = nullptr;
rt = TassCtlOpenDevice(ids, &hDevTmp);
CheckRt(TassCtlOpenDevice, rt);
*hDev = hDevTmp;
unsigned int infoLen = 0;
rt = TassCtlListAdmin(hDevTmp, NULL, &infoLen);
CheckRt(TassCtlListAdmin, rt);
TassAdminInfo info[5];
TassCtlListAdmin(hDevTmp, info, &infoLen);
for (int i = 0; i < infoLen / sizeof(TassAdminInfo); ++i) {
//PRINT_STRUCT_ITEM(info[i], name);
//PRINT_STR(TassCtlListAdmin, info[i].name);
}
rt = TassCtlRequestPwdHashEncPublicKey(hDevTmp, g_encKey);
CheckRt(TassCtlRequestPwdHashEncPublicKey, rt);
#if defined(_WIN32) || defined(_WIN64)
Sleep(1000);
#else
sleep(1);
#endif
//PRINT_BUF(TassCtlRequestPwdHashEncPublicKey, g_encKey, 64);
char pwd[32] = { 0 };
//INPUT_ADMIN_PIN();
system(STTY_CLOSE TTY_PATH);
printf("\n请输入管理员口令:");
cin >> pwd; //默认固定为admin,可在初始化为生产状态时出入新的口令
system(STTY_OPEN TTY_PATH);
rt = TassCtlEncryptPwdHash(hDevTmp, g_encKey, pwd, g_pwdHashCipher);
CheckRt(TassCtlEncryptPwdHash, rt);
rt = TassCtlLogin(hDevTmp, "admin", g_pwdHashCipher);
if (rt == 0)
{
printf("TassCtlLogin run success!\n");
isLogin = 1;
return rt;
}
else
{
printf("TassCtlLogin run failed, rt = [%d | %#010X]\n", rt, rt);
isLogin = 0;
return rt;
}
}
int OpenDeviceAndGetEncKey(void** hDev, unsigned char* encKey)
{
int rt = 0;
unsigned int idLen = 0;
rt = TassCtlScanDevice(nullptr, &idLen);
CheckRt(TassCtlScanDevice, rt);
char ids[256] = { 0 };
TassCtlScanDevice(ids, &idLen);
int i = 0;
auto* p = ids;
while (strlen(p) != 0) {
//printf("Device ID[%d]: %s\n", ++i, p);
p += strlen(p) + 1;
}
void* hDevTmp = nullptr;
rt = TassCtlOpenDevice(ids, &hDevTmp);
CheckRt(TassCtlOpenDevice, rt);
*hDev = hDevTmp;
unsigned int infoLen = 0;
rt = TassCtlListAdmin(hDevTmp, NULL, &infoLen);
CheckRt(TassCtlListAdmin, rt);
TassAdminInfo info[5];
TassCtlListAdmin(hDevTmp, info, &infoLen);
for (int i = 0; i < infoLen / sizeof(TassAdminInfo); ++i) {
//PRINT_STRUCT_ITEM(info[i], name);
//PRINT_STR(TassCtlListAdmin, info[i].name);
}
rt = TassCtlRequestPwdHashEncPublicKey(hDevTmp, encKey);
CheckRt(TassCtlRequestPwdHashEncPublicKey, rt);
#if defined(_WIN32) || defined(_WIN64)
Sleep(1000);
#else
sleep(1);
#endif
//PRINT_BUF(TassCtlRequestPwdHashEncPublicKey, encKey, sizeof(encKey));
}
int ImportAsymKey(void* hDev)
{
int rt = 0;
string sm2PriKey;
printf("请输入SM2的保护私钥: ");
cin >> sm2PriKey;
string sm2Sk = String2Bin(sm2PriKey);
string symmKeyCipher;
printf("请输入随机对称密钥: ");
cin >> symmKeyCipher;
string symmKey = String2Bin(symmKeyCipher);
string pubKey;
printf("请输入要导入的公钥: ");
cin >> pubKey;
string pk = String2Bin(pubKey);
string priKey;
printf("请输入要导入的私钥: ");
cin >> priKey;
string sk = String2Bin(priKey);
int importedKeyAlg = 0;
while (1)
{
printf("请输入要导入密钥的类型:2-SM2,3-ECC_SECP_256R1, 4-RSA, 8-ECC_SECP_256K1: ");
cin >> importedKeyAlg;
if (importedKeyAlg == 2 || importedKeyAlg == 3 || importedKeyAlg == 4 || importedKeyAlg == 8)
break;
else
printf("该类型不支持!\n");
}
unsigned int importedKeyIndex = 0;
printf("请输入要导入密钥的索引:");
cin >> importedKeyIndex;
rt = TassCtlImportKey(hDev,
(unsigned char*)sm2Sk.data(),
(TassAlg)importedKeyAlg,
importedKeyIndex,
(unsigned char*)"",
0,
(unsigned char*)symmKey.data(),
symmKey.size(),
(unsigned char*)pk.data(),
pk.size(),
(unsigned char*)sk.data(),
sk.size());
CheckRt(TassCtlImportKey, rt);
printf("导入非对称密钥成功!\n");
}
int ExportAsymKey(void* hDev)
{
int rt = 0;
unsigned char symmKeyCipher[1024] = { 0 };
unsigned int symmKeyCipherLen = sizeof(symmKeyCipher);
unsigned char exportedPk[1024] = { 0 };
unsigned int exportedPkLen = sizeof(exportedPk);
unsigned char exportedKeyCipherByPk[1024] = { 0 };
unsigned int exportedKeyCipherByPkLen = sizeof(exportedKeyCipherByPk);
string sm2PubKey;
printf("请输入SM2的保护公钥: ");
cin >> sm2PubKey;
string sm2Pk = String2Bin(sm2PubKey);
int exportedKeyAlg = 0;
while (1)
{
printf("请输入导出密钥的类型:2-SM2,3-ECC_SECP_256R1, 4-RSA, 8-ECC_SECP_256K1: ");
cin >> exportedKeyAlg;
if (exportedKeyAlg == 2 || exportedKeyAlg == 3 || exportedKeyAlg == 4 || exportedKeyAlg == 8)
break;
else
printf("该类型不支持!\n");
}
unsigned int exportedKeyIndex = 0;
printf("请输入要导出密钥的索引:");
cin >> exportedKeyIndex;
rt = TassCtlExportKey(hDev,
(unsigned char*)sm2Pk.data(),
(TassAlg)exportedKeyAlg,
exportedKeyIndex,
g_pwdHashCipher,
symmKeyCipher,
&symmKeyCipherLen,
exportedPk,
&exportedPkLen,
exportedKeyCipherByPk,
&exportedKeyCipherByPkLen);
CheckRt(TassCtlExportKey, rt);
printf("导出非对称密钥成功!\n");
printf("随机对称密钥:symmKeyCipherLen = %d, symmKeyCipher: %s\n\n", symmKeyCipherLen, Bin2String(symmKeyCipher, symmKeyCipherLen, true).data());
printf("导出的公钥:exportedPkLen = %d, exportedPk: %s\n", exportedPkLen, Bin2String(exportedPk, exportedPkLen, true).data());
printf("导出的私钥:exportedKeyCipherByPk = %d, exportedKeyCipherByPkLen: %s\n", exportedKeyCipherByPkLen, Bin2String(exportedKeyCipherByPk, exportedKeyCipherByPkLen, true).data());
}
int Device_ImportAndExportAsymKey(void* hDev)
{
while (true) {
int idx = 0;
printf("[%d] 导出非对称密钥\n", ++idx);
printf("[%d] 导入非对称密钥\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: ExportAsymKey(hDev); break;
case 2: ImportAsymKey(hDev); break;
case 0: {
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
}
int DevManager()
{
void* hDev = nullptr;
unsigned char encPk[128] = { 0 };
auto rt = OpenDeviceAndGetEncKey(&hDev, encPk);
CheckRt(OpenDeviceAndGetEncKey, rt);
while (true) {
int idx = 0;
printf("[%d] 设备格式化操作\n", ++idx);
printf("[%d] 备份和恢复设备信息\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: Device_FormatOperation(hDev, encPk); break;
case 2: Device_BackupRecover(hDev, encPk); break;
case 0: {
TassCtlLogout(hDev);
TassCtlCloseDevice(hDev);
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
return 0;
}
int KeyManager()
{
void* hDev = nullptr;
auto rt = Device_LoginAndGetEncKey(&hDev);
CheckRt(Device_LoginAndGetEncKey, rt);
while (true) {
int idx = 0;
printf("[%d] 应用密钥管理(增加、查询、删除)\n", ++idx);
printf("[%d] 导入外部明文密钥到设备\n", ++idx);
printf("[%d] 修改私钥使用权限口令\n", ++idx);
printf("[%d] 导入导出非对称密钥\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: Device_KeyManager(hDev); break;
case 2: Device_ImporPlaintKey(hDev); break;
case 3: Device_ChangePrikeyPwd(hDev); break;
case 4: Device_ImportAndExportAsymKey(hDev); break;
case 0: {
TassCtlLogout(hDev);
TassCtlCloseDevice(hDev);
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
return 0;
}
int main()
{
while (true) {
int idx = 0;
printf("[%d] 密钥管理\n", ++idx);
printf("[%d] 设备管理\n", ++idx);
printf("[0] 退出\n");
cin >> idx;
switch (idx) {
case 1: KeyManager(); break;
case 2: DevManager(); break;
case 0: {
return 0;
};
default: {
printf("输入错误!");
continue;
};
}
}
return 0;
}
\ No newline at end of file
#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;
}
File added
File added
/**
* Copyright (C) 2010-2023 TASS
* @file TassSDF4PCIECrypotoCard.h
* @brief 根据GM/T 0018 《密码设备应用接口规范》声明相关函数
* @detail 本文件为实现SDF接口提供了相应的模板,使用者可根据该模板完成
* 特定设备的SDF接口开发
* @author Lgl
* @version 1.0.0
* @date 2021/02/19
* Change History :
* <Date> | <Version> | <Author> | <Description>
*---------------------------------------------------------------------
* 2021/02/19 | 1.0.0 | Lgl | Create file
*---------------------------------------------------------------------
* 2021/09/19 | 2.0.0 | Lgl | Optimized interface function
*---------------------------------------------------------------------
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
*分组密码算法标识
*/
#define SGD_SM1_ECB 0X00000101 //SM1算法ECB加密模式
#define SGD_SM1_CBC 0X00000102 //SM1算法CBC加密模式
#define SGD_SM1_CFB 0X00000104 //SM1算法CFB加密模式
#define SGD_SM1_OFB 0X00000108 //SM1算法OFB加密模式
#define SGD_SM1_MAC 0X00000110 //SM1算法MAC运算
#define SGD_SSF33_ECB 0X00000201 //SSF33算法ECB加密模式
#define SGD_SSF33_CBC 0X00000202 //SSF33算法CBC加密模式
#define SGD_SSF33_CFB 0X00000204 //SSF33算法CFB加密模式
#define SGD_SSF33_OFB 0X00000208 //SSF33算法OFB加密模式
#define SGD_SSF33_MAC 0X00000210 //SSF33算法MAC运算
#define SGD_SM4_ECB 0X00000401 //SM4算法ECB加密模式
#define SGD_SM4_CBC 0X00000402 //SM4算法CBC加密模式
#define SGD_SM4_CFB 0X00000404 //SM4算法CFB加密模式
#define SGD_SM4_OFB 0X00000408 //SM4算法OFB加密模式
#define SGD_SM4_MAC 0X00000410 //SM4算法MAC运算
#define SGD_ZUC_EEA3 0X00000801 //ZUC祖冲之机密性算法128-EEA3算法
#define SGD_ZUC_EIA3 0X00000802 //ZUC祖冲之机密性算法128-EIA3算法
/*TASS扩展*/
#define SGD_DES_ECB 0x80000101 // DES算法ECB加密模式
#define SGD_DES_CBC 0x80000102 // DES算法CBC加密模式
#define SGD_DES_CFB 0x80000104 // DES算法CFB加密模式
#define SGD_DES_OFB 0x80000108 // DES算法OFB加密模式
#define SGD_DES_MAC 0X80000110 // DES算法MAC运算
#define SGD_AES_ECB 0x80000201 // AES算法ECB加密模式
#define SGD_AES_CBC 0x80000202 // AES算法CBC加密模式
#define SGD_AES_CFB 0x80000204 // AES算法CFB加密模式
#define SGD_AES_OFB 0x80000208 // AES算法OFB加密模式
#define SGD_AES_MAC 0x80000210 // AES算法MAC运算
/**
*非对称密码算法标识
*/
#define SGD_RSA 0X00010000 //RSA算法
#define SGD_SM2 0X00020100 //SM2椭圆曲线密码算法
#define SGD_SM2_1 0X00020200 //SM2椭圆曲线签名算法
#define SGD_SM2_2 0X00020400 //SM2椭圆曲线密钥交换协议
#define SGD_SM2_3 0X00020800 //SM2椭圆曲线加密算法
/**
*密码杂凑算法标识
*/
#define SGD_SM3 0X00000001 //SM3杂凑算法
#define SGD_SHA256 0X00000004 //SHA_256杂凑算法
typedef struct DeviceInfo_st {
unsigned char IssuerName[40];//设备生产厂商名称
unsigned char DeviceName[16];//设备型号
unsigned char DeviceSerial[16];//设备编号,包含日期(8字符)、批次号(3字符)、流水号(5字符)
unsigned int DeviceVersion;//密码设备内部软件版本号
unsigned int StandardVersion;//密码设备支持的接口规范版本号
unsigned int AsymAlgAbility[2];///<非对称算法能力,前4字节表示支持的算法,非对称算法标识按位异或,后4字节表示算法的最大模长,表示方法为支持模长按位异或的结果
unsigned int SymAlgAbility;//对称算法能力,对称算法标识按位异或
unsigned int HashAlgAbility;//杂凑算法能力,杂凑算法标识按位异或
unsigned int BufferSize;//支持的最大文件存储空间(单位字节)
}DEVICEINFO;
#define RSAref_MAX_BITS 2048//4096
#define RSAref_MAX_LEN ((RSAref_MAX_BITS + 7) / 8)
#define RSAref_MAX_PBITS ((RSAref_MAX_BITS + 1) / 2)
#define RSAref_MAX_PLEN ((RSAref_MAX_PBITS + 7) / 8)
typedef struct RSArefPublicKey_st {
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
}RSArefPublicKey;
typedef struct RSArefPrivateKey_st {
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
unsigned char d[RSAref_MAX_LEN];
unsigned char prime[2][RSAref_MAX_PLEN];
unsigned char pexp[2][RSAref_MAX_PLEN];
unsigned char coef[RSAref_MAX_PLEN];
}RSArefPrivateKey;
#define ECCref_MAX_BITS 512
#define ECCref_MAX_LEN ((ECCref_MAX_BITS + 7) / 8)
typedef struct ECCrefPublicKey_st {
unsigned int bits;
unsigned char x[ECCref_MAX_LEN];
unsigned char y[ECCref_MAX_LEN];
}ECCrefPublicKey;
typedef struct ECCrefPrivateKey_st {
unsigned int bits;
unsigned char K[ECCref_MAX_LEN];
}ECCrefPrivateKey;
typedef struct ECCCipher_st {
unsigned char x[ECCref_MAX_LEN];
unsigned char y[ECCref_MAX_LEN];
unsigned char M[32];
unsigned int L;
unsigned char C[1024];
}ECCCipher;
typedef struct ECCSignature_st {
unsigned char r[ECCref_MAX_LEN];
unsigned char s[ECCref_MAX_LEN];
}ECCSignature;
/**
*@brief GMT 0018-2012 未定义ECCCIPHERBLOB/ECCPUBLICKEYBLOB,推测使用如下定义
*/
typedef ECCCipher ECCCIPHERBLOB;
typedef ECCrefPublicKey ECCPUBLICKEYBLOB;
typedef struct SDF_ENVELOPEDKEYBLOB {
unsigned long ulAsymmAlgID;
unsigned long ulSymmAlgID;
ECCCIPHERBLOB ECCCipherBlob;
ECCPUBLICKEYBLOB PubKey;
unsigned char cbEncryptedPriKey[ECCref_MAX_LEN];
}ENVELOPEDKEYBLOB, * PENVELOPEDKEYBLOB;
/**
*以下设备管理类函数
*/
/**
* @brief 打开密码设备
* @param phDeviceHandle [OUT] 返回设备句柄
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note phDeviceHandle由函数初始化并填写内容
*/
int SDF_OpenDevice(void** phDeviceHandle);
/**
* @brief 关闭密码设备,并释放相关资源
* @param hDeviceHandle [IN] 已打开的设备句柄
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_CloseDevice(void* hDeviceHandle);
/**
* @brief 创建与密码设备的会话
* @param hDeviceHandle [IN] 已打开的设备句柄
* @param phSessionHandle [OUT] 返回与密码设备建立的新会话句柄
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_OpenSession(void* hDeviceHandle, void** phSessionHandle);
/**
* @brief 关闭与密码设备已建立的会话,并释放相关资源
* @param hSessionHandle [IN] 与密码设备已建立的会话句柄
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_CloseSession(void* hSessionHandle);
/**
* @brief 获取密码设备能力描述
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pstDeviceInfo [OUT] 设备能力描述信息
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_GetDeviceInfo(
void* hSessionHandle,
DEVICEINFO* pstDeviceInfo);
/**
* @brief 产生随机数
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiLength [IN] 欲获取的随机数长度
* @param pucRandom [OUT] 缓冲区指针,用于存放获取的随机数
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_GenerateRandom(
void* hSessionHandle,
unsigned int uiLength,
unsigned char* pucRandom);
/**
* @brief 获取密码设备内部存储的指定索引私钥的使用权
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储私钥的索引值
* TASS补充:正数获取SM2密钥权限,负数获取RSA密钥权限
* @param pucPassword [IN] 使用私钥权限的识别码,默认为a1234567
* @param uiPwdLength [IN] 私钥访问控制码长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 本标准涉及密码设备存储的密钥对索引值的起始索引值为1,最大为n,
* 密码设备的实际存储容量决定n值
*/
int SDF_GetPrivateKeyAccessRight(
void* hSessionHandle,
unsigned int uiKeyIndex,
unsigned char* pucPassword,
unsigned int uiPwdLength);
/**
* @brief 释放密码设备存储的指定索引私钥的使用授权
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储私钥的索引值
* TASS补充:正数释放SM2密钥权限,负数释放RSA密钥权限
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ReleasePrivateKeyAccessRight(
void* hSessionHandle,
unsigned int uiKeyIndex);
/**
*以下密钥管理类函数
*/
/**
* @brief 导出密码设备内部存储的指定索引位置的签名公钥
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储的RSA密钥对索引值
* @param pucPublicKey [OUT] RSA公钥结构
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ExportSignPublicKey_RSA(
void* hSessionHandle,
unsigned int uiKeyIndex,
RSArefPublicKey* pucPublicKey);
/**
* @brief 导出密码设备内部存储的指定索引位置的加密公钥
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储的RSA密钥对索引值
* @param pucPublicKey [OUT] RSA公钥结构
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ExportEncPublicKey_RSA(
void* hSessionHandle,
unsigned int uiKeyIndex,
RSArefPublicKey* pucPublicKey);
/**
* @brief 请求密码设备产生指定模长的RSA密钥对(明文)
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 指定密钥模长
* @param pucPublicKey [OUT] RSA公钥结构
* TASS补充:若需要保存到加密机内部加密密钥对
* 可设置pucPublicKey->bits为索引值,此时不输出pucPrivateKey
* @param pucPrivateKey [OUT] RSA私钥结构(pucPublicKey->bits输出为私钥实际长度,可从私钥结构体的成员m、e、d依次拷贝pucPublicKey->bits长度的数据,即为真实的私钥密文数据)
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_GenerateKeyPair_RSA(
void* hSessionHandle,
unsigned int uiKeyBits,
RSArefPublicKey* pucPublicKey,
RSArefPrivateKey* pucPrivateKey);
/**
* @brief 生成会话密钥并用指定索引的内部加密公钥加密输出,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiIPKIndex [IN] 密码设备内部存储公钥的索引值
* @param uiKeyBits [IN] 指定产生的会话密钥长度,支持2048bits(256字节)
* @param pucKey [OUT] 缓冲区指针,用于存放返回的密钥密文
* @param puiKeyLength [IN/OUT] 返回的密钥密文长度
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 公钥加密数据是填充方式按照PKCS#1 v1.5的要求进行
*/
int SDF_GenerateKeyWithIPK_RSA(
void* hSessionHandle,
unsigned int uiIPKIndex,
unsigned int uiKeyBits,
unsigned char* pucKey,
unsigned int* puiKeyLength,
void** phKeyHandle);
/**
* @brief 生成会话密钥并用外部公钥加密输出,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyBits [IN] 指定产生的会话密钥长度,仅支持128(16字节)
* @param pucPublicKey [IN] 输入的外部RSA公钥结构
* @param pucKey [OUT] 缓冲区指针,用于存放返回的密钥密文
* @param puiKeyLength [OUT] 返回的密钥密文长度
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 公钥加密数据是填充方式按照PKCS#1 v1.5的要求进行
*/
int SDF_GenerateKeyWithEPK_RSA(
void* hSessionHandle,
unsigned int uiKeyBits,
RSArefPublicKey* pucPublicKey,
unsigned char* pucKey,
unsigned int* puiKeyLength,
void** phKeyHandle);
/**
* @brief 导入会话密钥并用内部私钥解密,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiISKIndex [IN] 密码设备内部存储加密私钥的索引值,对应于加密时的公钥
* @param pucKey [IN] 缓冲区指针,用于存放输入的密钥密文
* @param puiKeyLength [IN] 输入密钥密文长度
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 填充方式与公钥加密时相同
*/
int SDF_ImportKeyWithISK_RSA(
void* hSessionHandle,
unsigned int uiISKIndex,
unsigned char* pucKey,
unsigned int uiKeyLength,
void** phKeyHandle);
/**
* @brief 将由内部公钥加密的会话密钥转换为由外部指定的公钥加密,可用于数字信封转换
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储的内部RSA密钥对索引值
* @param pucPublicKey [IN] 外部RSA公钥结构
* @param pucDEInput [IN] 缓冲区指针,用于存放输入的会话密钥密文
* @param uiDELength [IN] 输入的会话密钥密文长度
* @param pucDEOuput [OUT] 缓冲区指针,用于存放输出的会话密钥密文
* @param puiDELength [OUT] 输出的会话密钥密文长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 填充方式与公钥加密时相同
*/
int SDF_ExchangeDigitEnvelopeBaseOnRSA(
void* hSessionHandle,
unsigned int uiKeyIndex,
RSArefPublicKey* pucPublicKey,
unsigned char* pucDEInput,
unsigned int uiDELength,
unsigned char* pucDEOuput,
unsigned int* puiDELength);
/**
* @brief 导出密码设备内部存储的指定索引位置的签名公钥
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储的ECC密钥对索引值
* @param pucPublicKey [OUT] ECC公钥结构
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ExportSignPublicKey_ECC(
void* hSessionHandle,
unsigned int uiKeyIndex,
ECCrefPublicKey* pucPublicKey);
/**
* @brief 导出密码设备内部存储的指定索引位置的加密公钥
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储的ECC密钥对索引值
* @param pucPublicKey [OUT] ECC公钥结构
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ExportEncPublicKey_ECC(
void* hSessionHandle,
unsigned int uiKeyIndex,
ECCrefPublicKey* pucPublicKey);
/**
* @brief 请求密码设备产生指定和模长的ECC密钥对
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 指定算法标识
* @param uiKeyBits [IN] 指定密钥模长,只支持256bit(32字节)
* @param pucPublicKey [OUT] ECC公钥结构
* TASS补充:若需要保存到加密机内部加密密钥对
* 可设置pucPublicKey->bits为索引值,此时不输出pucPrivateKey
* @param pucPrivateKey [OUT] RSA私钥结构
* TASS补充:若需要保存到加密机内部签名密钥对,
* 可设置pucPrivateKey->bits为索引值,此时不输出pucPrivateKey
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_GenerateKeyPair_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
unsigned int uiKeyBits,
ECCrefPublicKey* pucPublicKey,
ECCrefPrivateKey* pucPrivateKey);
/**
* @brief 生成会话密钥并用指定索引的内部ECC加密公钥加密输出,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiIPKIndex [IN] 密码设备内部存储公钥的索引值
* @param uiKeyBits [IN] 指定产生的会话密钥长度,支持128bits(16字节)
* @param pucKey [OUT] 缓冲区指针,用于存放返回的密钥密文
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 公钥加密数据是填充方式按照PKCS#1 v1.5的要求进行
*/
int SDF_GenerateKeyWithIPK_ECC(
void* hSessionHandle,
unsigned int uiIPKIndex,
unsigned int uiKeyBits,
ECCCipher* pucKey,
void** phKeyHandle);
/**
* @brief 生成会话密钥并用外部ECC公钥加密输出,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyBits [IN] 指定产生的会话密钥长度,支持128bits(16字节)
* @param uiAlgID [IN] 外部ECC公钥的算法标识
* @param pucPublicKey [IN] 输入的外部ECC公钥结构
* @param pucKey [OUT] 缓冲区指针,用于存放返回的密钥密文
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 公钥加密数据是填充方式按照PKCS#1 v1.5的要求进行
*/
int SDF_GenerateKeyWithEPK_ECC(
void* hSessionHandle,
unsigned int uiKeyBits,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
ECCCipher* pucKey,
void** phKeyHandle);
/**
* @brief 导入会话密钥并用内部ECC加密私钥解密,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiISKIndex [IN] 密码设备内部存储加密私钥的索引值,对应于加密时的公钥
* @param pucKey [IN] 缓冲区指针,用于存放输入的密钥密文
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 填充方式与公钥加密时相同
*/
int SDF_ImportKeyWithISK_ECC(
void* hSessionHandle,
unsigned int uiISKIndex,
ECCCipher* pucKey,
void** phKeyHandle);
/**
* @brief 使用ECC密钥协商算法,为计算会话密钥而产生协商参数,同时返回指定索引位置的ECC公钥、临时ECC密钥对的公钥及协商句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiISKIndex [IN] 密码设备内部存储加密私钥的索引值,该私钥用于参与密钥协商
* @param uiKeyBits [IN] 要求协商的密钥长度,支持128bits(16字节)
* @param pucSponsorID [IN] 参与密钥协商的发起方ID值
* @param uiSponsorIDLength [IN] 发起方ID长度
* @param pucSponsorPublicKey [OUT] 返回的发起方ECC公钥结构
* @param pucSponsorTmpPublicKey [OUT] 返回的发起方临时ECC公钥结构
* @param phAgreementHandle [OUT] 返回的协商句柄,用于计算协商密钥
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 为协商会话密钥,协商的发起方应首先调用本函数
*/
int SDF_GenerateAgreementDataWithECC(
void* hSessionHandle,
unsigned int uiISKIndex,
unsigned int uiKeyBits,
unsigned char* pucSponsorID,
unsigned int uiSponsorIDLength,
ECCrefPublicKey* pucSponsorPublicKey,
ECCrefPublicKey* pucSponsorTmpPublicKey,
void** phAgreementHandle);
/**
* @brief 使用ECC密钥协商算法,使用自身协商句柄和响应方的协商参数计算会话密钥,同时返回会话密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucResponseID [IN] 外部输入的响应方ID值
* @param uiResponseIDLength [IN] 外部输入的响应方ID长度
* @param pucResponsePublicKey [IN] 外部输入的响应方ECC公钥结构
* @param pucResponseTmpPublicKey [IN] 外部输入的响应方临时ECC公钥结构
* @param hAgreementHandle [IN] 协商句柄,用于计算协商密钥
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 协商的发起方获得响应方的协商参数后调用本函数,计算会话密钥,使用SM2算法计算会话密钥的过程见GM/T 0009
*/
int SDF_GenerateKeyWithECC(
void* hSessionHandle,
unsigned char* pucResponseID,
unsigned int uiResponseIDLength,
ECCrefPublicKey* pucResponsePublicKey,
ECCrefPublicKey* pucResponseTmpPublicKey,
void* hAgreementHandle,
void** phKeyHandle);
/**
* @brief 使用ECC密钥协商算法,产生协商参数并计算会话密钥,同时返回产生的协商参数和密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiISKIndex [IN] 密码设备内部存储加密私钥的索引值,该私钥用于参与密钥协商
* @param uiKeyBits [IN] 要求协商的密钥长度,支持128bits(16字节)
* @param pucResponseID [IN] 响应方ID值
* @param uiResponseIDLength [IN] 响应方ID长度
* @param pucSponsorID [IN] 发起方ID值
* @param uiSponsorIDLength [IN] 发起方ID长度
* @param pucSponsorPublicKey [IN] 外部输入的发起方ECC公钥结构
* @param pucSponsorTmpPublicKey [IN] 外部输入的发起方临时ECC公钥结构
* @param pucResponsePublicKey [OUT] 返回的响应方ECC公钥结构
* @param pucResponseTmpPublicKey [OUT] 返回的响应方临时ECC公钥结构
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 本函数由响应方调用。使用SM2算法计算会话密钥的过程见GM/T 0009
*/
int SDF_GenerateAgreementDataAndKeyWithECC(
void* hSessionHandle,
unsigned int uiISKIndex,
unsigned int uiKeyBits,
unsigned char* pucResponseID,
unsigned int uiResponseIDLength,
unsigned char* pucSponsorID,
unsigned int uiSponsorIDLength,
ECCrefPublicKey* pucSponsorPublicKey,
ECCrefPublicKey* pucSponsorTmpPublicKey,
ECCrefPublicKey* pucResponsePublicKey,
ECCrefPublicKey* pucResponseTmpPublicKey,
void** phKeyHandle);
/**
* @brief 将由内部公钥加密的会话密钥转换为由外部指定的公钥加密,可用于数字信封转换
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储的内部ECC密钥对索引值
* @param uiAlgID [IN] 外部ECC公钥的算法标识
* @param pucPublicKey [IN] 外部ECC公钥结构
* @param pucEncDataIn [IN] 缓冲区指针,用于存放输入的会话密钥密文
* @param pucEncDataOut [OUT] 缓冲区指针,用于存放输出的会话密钥密文
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 填充方式与公钥加密时相同
*/
int SDF_ExchangeDigitEnvelopeBaseOnECC(
void* hSessionHandle,
unsigned int uiKeyIndex,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
ECCCipher* pucEncDataIn,
ECCCipher* pucEncDataOut);
/**
* @brief 生成会话密钥并用密钥加密密钥加密输出,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyBits [IN] 指定产生的会话密钥长度,支持128bits(16字节)
* @param uiAlgID [IN] 算法标识,指定对称加密算法,仅支持SGD_SM1_ECB
* @param uiKEKIndex [IN] 密码设备内部存储的加密密钥的索引值
* @param pucKey [OUT] 缓冲区指针,用于存放返回的密钥密文
* @param puiKeyLength [OUT] 返回的密钥密文长度
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* TASS补充:若需要保存到加密机内部,可使用如下方式
* 如保存到1号索引密钥(仅支持SM4算法),则int idx = 1; void* pIdx = &idx; 传入 &pIdx 即可
* uiKeyBits=128,导入SM4算法
* 此时phKeyHandle不能调用SDF_DestroyKey释放
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 加密模式使用ECB模式
*/
int SDF_GenerateKeyWithKEK(
void* hSessionHandle,
unsigned int uiKeyBits,
unsigned int uiAlgID,
unsigned int uiKEKIndex,
unsigned char* pucKey,
unsigned int* puiKeyLength,
void** phKeyHandle);
/**
* @brief 导入会话密钥并用密钥加密密钥解密,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 算法标识,指定对称加密算法
* @param uiKEKIndex [IN] 密码设备内部存储的加密密钥的索引值
* @param pucKey [IN] 缓冲区指针,用于存放输入的密钥密文
* @param puiKeyLength [IN] 返回的密钥密文长度
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* TASS补充:若需要保存到加密机内部(仅支持SM4算法),可使用如下方式
* 如保存到1号索引密钥,则int idx = 1; void* pIdx = &idx; 传入 &pIdx 即可
* uiKeyBits=128,导入SM4算法
* 此时phKeyHandle不能调用SDF_DestroyKey释放
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 加密模式使用ECB模式
*/
int SDF_ImportKeyWithKEK(
void* hSessionHandle,
unsigned int uiAlgID,
unsigned int uiKEKIndex,
unsigned char* pucKey,
unsigned int uiKeyLength,
void** phKeyHandle);
/**
* @brief 导入明文会话密钥,同时返回密钥句柄
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucKey [IN] 缓冲区指针,用于存放输入的密钥明文
* @param puiKeyLength [IN] 输入的密钥明文长度
* @param phKeyHandle [OUT] 返回的密钥句柄,传入前需先赋值为NULL
* TASS补充:若需要保存到加密机内部(仅支持SM4算法),可使用如下方式
* 如保存到1号索引密钥,则int idx = 1; void* pIdx = &idx; 传入 &pIdx 即可
* uiKeyBits=128,导入SM4算法
* 此时phKeyHandle不能调用SDF_DestroyKey释放
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ImportKey(
void* hSessionHandle,
unsigned char* pucKey,
unsigned int uiKeyLength,
void** phKeyHandle);
/**
* @brief 销毁会话密钥,并释放为密钥句柄分配的内存等资源
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param hKeyHandle [IN] 输入的密钥句柄,若输入指向索引的指针则删除该内部对称密钥
* TASS补充:若需要删除加密机内部密钥,可使用如下方式
* 如删除1号索引密钥,则int idx = 1; 传入 &idx 即可
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 在对称算法运算完成后,应调用本函数销毁会话密钥
*/
int SDF_DestroyKey(
void* hSessionHandle,
void* hKeyHandle);
/**
*以下非对称算法运算类函数
*/
/**
* @brief 指定使用外部公钥对数据进行运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucPublicKey [IN] 外部RSA公钥结构
* @param pucDataInput [IN] 缓冲区指针,用于存放输入的数据
* @param uiInputLength [IN] 输入的数据长度
* @param pucDataOutput [OUT] 缓冲区指针,用于存放输出的数据
* @param puiOutputLength [OUT] 输出的数据长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 数据格式由应用层封装
*/
int SDF_ExternalPublicKeyOperation_RSA(
void* hSessionHandle,
RSArefPublicKey* pucPublicKey,
unsigned char* pucDataInput,
unsigned int uiInputLength,
unsigned char* pucDataOutput,
unsigned int* puiOutputLength);
/**
* @brief 使用内部指定索引的公钥对数据进行运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备内部存储公钥的索引值
* @param pucDataInput [IN] 缓冲区指针,用于存放输入的数据
* @param uiInputLength [IN] 输入的数据长度
* @param pucDataOutput [OUT] 缓冲区指针,用于存放输出的数据
* @param puiOutputLength [OUT] 输出的数据长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 索引范围仅限于内部签名密钥对,数据格式由应用层封装
*/
int SDF_InternalPublicKeyOperation_RSA(
void* hSessionHandle,
unsigned int uiKeyIndex,
unsigned char* pucDataInput,
unsigned int uiInputLength,
unsigned char* pucDataOutput,
unsigned int* puiOutputLength);
/**
* @brief 使用内部指定索引的私钥对数据进行运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备内部存储私钥的索引值
* @param pucDataInput [IN] 缓冲区指针,用于存放输入的数据
* @param uiInputLength [IN] 输入的数据长度
* @param pucDataOutput [OUT] 缓冲区指针,用于存放输出的数据
* @param puiOutputLength [OUT] 输出的数据长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 索引范围仅限于内部签名密钥对,数据格式由应用层封装
*/
int SDF_InternalPrivateKeyOperation_RSA(
void* hSessionHandle,
unsigned int uiKeyIndex,
unsigned char* pucDataInput,
unsigned int uiInputLength,
unsigned char* pucDataOutput,
unsigned int* puiOutputLength);
/**
* @brief 使用外部 ECC 私钥对数据进行签名运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 算法标识,指定使用的ECC算法
* @param pucPrivateKey [IN] 外部 ECC 私钥结构
* @param pucData [IN] 缓冲区指针,用于存放外部输入的数据
* @param uiDataLength [IN] 输入的数据长度
* @param pucSignature [OUT] 缓冲区指针,用于存放输入的签名值数据
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 输入数据为待签数据的杂凑值。当使用 SM2 算法时,该输入数据为待签数据经过SM2 签名预处理的结果,预处理过程见 GM/T AAAA。
*/
int SDF_ExternalSign_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPrivateKey* pucPrivateKey,
unsigned char* pucData,
unsigned int uiDataLength,
ECCSignature* pucSignature);
/**
* @brief 使用外部ECC公钥对ECC签名值进行验证运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 算法标识,指定使用的ECC算法
* @param pucPublicKey [IN] 外部ECC公钥结构
* @param pucData [IN] 缓冲区指针,用于存放输入的数据
* @param uiDataLength [IN] 输入的数据长度
* @param pucSignature [IN] 缓冲区指针,用于存放输入的签名值数据
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 输入数据为待签数据的杂凑值。当使用SM2算法时,该输入数据位待签数据经过SM2签名预处理的结果,预处理过程见GM/T0009
*/
int SDF_ExternalVerify_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
unsigned char* pucData,
unsigned int uiDataLength,
ECCSignature* pucSignature);
/**
* @brief 使用内部ECC公钥对ECC签名值进行验证运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiISKIndex [IN] 密码设备内部存储的ECC签名私钥的索引值
* @param pucData [IN] 缓冲区指针,用于存放外部输入的数据
* @param uiDataLength [IN] 输入的数据长度
* @param pucSignature [OUT] 缓冲区指针,用于存放输出的签名值数据
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 输入数据为待签数据的杂凑值。当使用SM2算法时,该输入数据位待签数据经过SM2签名预处理的结果,预处理过程见GM/T0009
*/
int SDF_InternalSign_ECC(
void* hSessionHandle,
unsigned int uiISKIndex,
unsigned char* pucData,
unsigned int uiDataLength,
ECCSignature* pucSignature);
/**
* @brief 使用内部ECC公钥对ECC签名值进行验证运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiIPKIndex [IN] 密码设备内部存储的ECC签名公钥的索引值
* @param pucData [IN] 缓冲区指针,用于存放外部输入的数据
* @param uiDataLength [IN] 输入的数据长度
* @param pucSignature [IN] 缓冲区指针,用于存放输入的签名值数据
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 输入数据为待签数据的杂凑值。当使用SM2算法时,该输入数据位待签数据经过SM2签名预处理的结果,预处理过程见GM/T0009
*/
int SDF_InternalVerify_ECC(
void* hSessionHandle,
unsigned int uiIPKIndex,
unsigned char* pucData,
unsigned int uiDataLength,
ECCSignature* pucSignature);
/**
* @brief 使用外部ECC公钥对数据进行加密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 算法标识,指定使用的ECC算法
* @param pucPublicKey [IN] 外部ECC公钥结构
* @param pucData [IN] 缓冲区指针,用于存放输入的数据
* @param uiDataLength [IN] 输入的数据长度
* @param pucEncData [OUT] 缓冲区指针,用于存放输出的数据密文
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ExternalEncrypt_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
unsigned char* pucData,
unsigned int uiDataLength,
ECCCipher* pucEncData);
/**
* @brief 使用外部 ECC 私钥进行解密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 算法标识,指定使用的ECC算法
* @param pucPrivateKey [IN] 外部ECC私钥结构
* @param pucEncData [IN] 缓冲区指针,用于存放输入的数据密文
* @param pucData [OUT] 缓冲区指针,用于存放输出的数据明文
* @param puiDataLength [OUT] 缓冲区指针,输出的数据明文长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ExternalDecrypt_ECC(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPrivateKey* pucPrivateKey,
ECCCipher* pucEncData,
unsigned char* pucData,
unsigned int* puiDataLength);
/**
*以下函数并未包含在GM/T 0018中,但从功能完整性考虑,定义为扩展实现
*/
/**
* @brief 使用内部ECC私钥对数据进行解密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiISKIndex [IN] 密码设备内部存储的ECC解密私钥的索引值
* @param pucEncData [IN] 缓冲区指针,用于存放输入的数据密文
* @param pucData [OUT] 缓冲区指针,用于存放输出的数据
* @param uiDataLength [OUT] 输出的数据长度
*
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_InternalDecrypt_ECC(
void* hSessionHandle,
unsigned int uiISKIndex,
ECCCipher* pucEncData,
unsigned char* pucData,
unsigned int* puiDataLength);
/**
* @brief 使用内部ECC公钥对数据进行加密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiIPKIndex [IN] 密码设备内部存储的ECC加密公钥的索引值
* @param pucData [IN] 缓冲区指针,用于存放输入的数据
* @param uiDataLength [IN] 输入的数据长度
* @param pucEncData [OUT] 缓冲区指针,用于存放输出的数据密文
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_InternalEncrypt_ECC(
void* hSessionHandle,
unsigned int uiIPKIndex,
unsigned char* pucData,
unsigned int uiDataLength,
ECCCipher* pucEncData);
/**
*对称算法运算类函数
*/
/**
* @brief 使用指定的密钥句柄和IV对数据进行对称加密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param hKeyHandle [IN] 指定的密钥句柄
* TASS补充:若需要使用加密机内部索引的对称密钥,可使用如下方式
* 如使用1号索引密钥,则int idx = 1; 传入 &idx 即可
* @param uiAlgID [IN] 算法标识,指定的对称加密算法
* @param pucIV [IN/OUT] 缓冲区指针,用于存放输入和返回的IV数据
* @param pucData [IN] 缓冲区指针,用于存放输入的数据明文
* @param uiDataLength [IN] 输入的数据明文长度
* @param pucEncData [OUT] 缓冲区指针,用于存放输出的数据密文
* @param puiEncDataLength [OUT] 输出的数据密文长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 此函数不对数据进行填充处理,输入的数据必须是指定算法分组长度的整数倍
*/
int SDF_Encrypt(
void* hSessionHandle,
void* hKeyHandle,
unsigned int uiAlgID,
unsigned char* pucIV,
unsigned char* pucData,
unsigned int uiDataLength,
unsigned char* pucEncData,
unsigned int* puiEncDataLength);
/**
* @brief 使用指定的密钥句柄和IV对数据进行对称解密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param hKeyHandle [IN] 指定的密钥句柄
* TASS补充:若需要使用加密机内部索引的对称密钥,可使用如下方式
* 如使用1号索引密钥,则int idx = 1; 传入 &idx 即可
* @param uiAlgID [IN] 算法标识,指定的对称加密算法
* @param pucIV [IN/OUT] 缓冲区指针,用于存放输入和返回的IV数据
* @param pucEncData [IN] 缓冲区指针,用于存放输入的数据密文
* @param puiEncDataLength [IN] 输入的数据密文长度
* @param pucData [OUT] 缓冲区指针,用于存放输出的数据明文
* @param puiDataLength [OUT] 输出的数据明文长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 此函数不对数据进行填充处理,输入的数据必须是指定算法分组长度的整数倍
*/
int SDF_Decrypt(
void* hSessionHandle,
void* hKeyHandle,
unsigned int uiAlgID,
unsigned char* pucIV,
unsigned char* pucEncData,
unsigned int uiEncDataLength,
unsigned char* pucData,
unsigned int* puiDataLength);
/**
* @brief 使用指定的密钥句柄和IV对数据进行对称加密运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param hKeyHandle [IN] 指定的密钥句柄
* TASS补充:若需要使用加密机内部索引的密钥,可使用如下方式
* 如使用1号索引密钥,则int idx = 1; 传入 &idx 即可
* @param uiAlgID [IN] 算法标识,指定的对称加密算法
* @param pucIV [IN/OUT] 缓冲区指针,用于存放输入和返回的IV数据
* @param pucData [IN] 缓冲区指针,用于存放输入的数据明文
* @param uiDataLength [IN] 输入的数据明文长度
* @param pucMAC [OUT] 缓冲区指针,用于存放输出的MAC值
* @param puiMACLength [OUT] 输出的MAC值长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 此函数不对数据进行填充处理,输入的数据必须是指定算法分组长度的整数倍
*/
int SDF_CalculateMAC(
void* hSessionHandle,
void* hKeyHandle,
unsigned int uiAlgID,
unsigned char* pucIV,
unsigned char* pucData,
unsigned int uiDataLength,
unsigned char* pucMAC,
unsigned int* puiMACLength);
/**
*杂凑运算类函数
*/
/**
* @brief 三步式数据杂凑运算第一步
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiAlgID [IN] 指定杂凑算法标识
* @param pucPublicKey [IN] 签名者公钥。当uiAlgID位SGD_SM3时有效
* @param pucID [IN] 签名者的ID值。当uiAlgID位SGD_SM3时有效
* @param uiIDLength [IN] 签名者ID长度。当uiAlgID位SGD_SM3时有效
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note uiIDLength非零且uiAlgID为SGD_SM3时,函数执行SM2的预处理1操作。计算过程见GM/T 0009
*/
int SDF_HashInit(
void* hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey* pucPublicKey,
unsigned char* pucID,
unsigned int uiIDLength);
/**
* @brief 三步式数据杂凑运算第二步,对输入的明文进行杂凑运算
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucData [IN] 缓冲区指针,用于存放输入的数据明文
* @param uiDataLength [IN] 输入的数据明文长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_HashUpdate(
void* hSessionHandle,
unsigned char* pucData,
unsigned int uiDataLength);
/**
* @brief 三步式数据杂凑运算第三步,杂凑运算结束返回杂凑数据并清除中间数据
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucHash [OUT] 缓冲区指针,用于存放输出的杂凑数据
* @param puiHashLength [OUT] 返回的杂凑数据长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_HashFinal(
void* hSessionHandle,
unsigned char* pucHash,
unsigned int* puiHashLength);
/**
*用户文件操作类函数
*/
/**
* @brief 在密码设备内部创建用于存储用户数据的文件
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucFileName [IN] 缓冲区指针,用于存放输入的文件名,最大长度128字节。
* @param uiNameLen [IN] 文件名长度
* @param uiFileSize [IN] 文件所占存储空间的长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_CreateFile(
void* hSessionHandle,
unsigned char* pucFileName,
unsigned int uiNameLen,
unsigned int uiFileSize);
/**
* @brief 读取在密码设备内部存储用户数据的文件的内容
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucFileName [IN] 缓冲区指针,用于存放输入的文件名,最大长度128字节
* @param uiNameLen [IN] 文件名长度
* @param uiOffset [IN] 指定读取文件时的偏移值
* @param puiFileLength [IN/OUT] 入参时指定读取文件内容的长度;出参时返回实际读取文件内容的长度
* @param pucBuffer [OUT] 缓冲区指针,用于存放读取的文件数据
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_ReadFile(
void* hSessionHandle,
unsigned char* pucFileName,
unsigned int uiNameLen,
unsigned int uiOffset,
unsigned int* puiFileLength,
unsigned char* pucBuffer);
/**
* @brief 向密码设备内部存储用户数据的文件中写入内容
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucFileName [IN] 缓冲区指针,用于存放输入的文件名,最大长度128字节
* @param uiNameLen [IN] 文件名长度
* @param uiOffset [IN] 指定写入文件时的偏移值
* @param uiFileLength [IN] 指定写入文件内容的长度
* @param pucBuffer [IN] 缓冲区指针,用于存放输入的写文件数据
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_WriteFile(
void* hSessionHandle,
unsigned char* pucFileName,
unsigned int uiNameLen,
unsigned int uiOffset,
unsigned int uiFileLength,
unsigned char* pucBuffer);
/**
* @brief 在密码设备内部创建用于存储用户数据的文件
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param pucFileName [IN] 缓冲区指针,用于存放输入的文件名,最大长度128字节
* @param uiNameLen [IN] 文件名长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
*/
int SDF_DeleteFile(
void* hSessionHandle,
unsigned char* pucFileName,
unsigned int uiNameLen);
/*
* 以下接口仅作为扩展功能使用
*/
/**
* @brief 通过指定id打开设备,并获取设备句柄
*
* @param id [in] 要打开的设备ID
* @param phDevice [out] 返回设备句柄
*
* @return 成功返回0,失败返回非0
*
*/
int TassGetDeviceHandleByID(unsigned char id[16], void** phDevice);
/**
* @brief 设置配置文件路径
* @param cfgPath [IN] 配置文件路径,不包含配置文件名字
*
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note cfgPath只传路径,不用传配置文件的名字
*/
int TassSetCfgPath(const char* cfgPath);
/**
*函数返回代码定义
*/
#define SDR_OK 0X0 //操作成功
#define SDR_BASE 0X01000000 //错误码基础值
#define SDR_UNKNOWERR SDR_BASE + 0X00000001 //未知错误
#define SDR_NOTSUPPORT SDR_BASE + 0X00000002 //不支持的接口调用
#define SDR_COMMFAIL SDR_BASE + 0X00000003 //与设备通讯失败
#define SDR_HARDFAIL SDR_BASE + 0X00000004 //运算模块无响应
#define SDR_OPENDEVICE SDR_BASE + 0X00000005 //打开设备失败
#define SDR_OPENSESSION SDR_BASE + 0X00000006 //创建会话失败
#define SDR_PARDENY SDR_BASE + 0X00000007 //无私钥使用权限
#define SDR_KEYNOTEXIST SDR_BASE + 0X00000008 //不存在的密钥调用
#define SDR_ALGNOTSUPPORT SDR_BASE + 0X00000009 //不支持的算法调用
#define SDR_ALGMODNOTSUPPORT SDR_BASE + 0X0000000A //不支持的算法模式调用
#define SDR_PKOPERR SDR_BASE + 0X0000000B //公钥运算失败
#define SDR_SKOPERR SDR_BASE + 0X0000000C //私钥运算失败
#define SDR_SIGNERR SDR_BASE + 0X0000000D //签名运算失败
#define SDR_VERIFYERR SDR_BASE + 0X0000000E //验证签名失败
#define SDR_SYMOPERR SDR_BASE + 0X0000000F //对称算法运算失败
#define SDR_STEPERR SDR_BASE + 0X00000010 //多步运算步骤错误
#define SDR_FILESIZEERR SDR_BASE + 0X00000011 //文件长度超出限制
#define SDR_FILENOEXIST SDR_BASE + 0X00000012 //指定的文件不存在
#define SDR_FILEOFSERR SDR_BASE + 0X00000013 //文件起始位置错误
#define SDR_KEYTYPEERR SDR_BASE + 0X00000014 //密钥类型错误
#define SDR_KEYERR SDR_BASE + 0X00000015 //密钥错误
#define SDR_ENCDATAERR SDR_BASE + 0X00000016 //ECC加密数据错误
#define SDR_RANDERR SDR_BASE + 0X00000017 //随机数产生失败
#define SDR_PRKRERR SDR_BASE + 0X00000018 //私钥使用权限获取失败
#define SDR_MACERR SDR_BASE + 0X00000019 //MAC运算失败
#define SDR_FILEEXISTS SDR_BASE + 0X0000001A //指定文件已存在
#define SDR_FILEWERR SDR_BASE + 0X0000001B //文件写入失败
#define SDR_NOBUFFER SDR_BASE + 0X0000001C //存储空间不足
#define SDR_INARGERR SDR_BASE + 0X0000001D //输入参数错误
#define SDR_OUTARGERR SDR_BASE + 0X0000001E //输出参数错误
#define TASSR_OK 0X0 //操作成功
#define TASSR_BASE 0X02000000 //天安错误码基础值
#define TASSR_UNKNOWERR TASSR_BASE + 0X00000001 //未知错误
#define TASSR_BUFFTOOSMALL TASSR_BASE + 0X00000002 //缓冲区不足
#ifdef __cplusplus
}
#endif
#pragma once
#include "TassType4PCIeSM.h"
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief 搜索设备
*
* @param id [out] 设备句柄集合
* @param idLen [in|out] 输入时,标识id缓冲区大小
* 输出时,标识输出id长度,通过 *idLen / TA_DEVICE_ID_SIZE 获取设备数量
*
* @return 成功返回0,失败返回非0
*
*/
int TassScanDevice(unsigned char* id, unsigned int* idLen);
/**
* @brief 打开设备
*
* @param id [in] 要打开的设备ID
* @param phDevice [out] 返回设备句柄
*
* @return 成功返回0,失败返回非0
*
*/
int TassOpenDevice(unsigned char id[TA_DEVICE_ID_SIZE], void** phDevice);
/**
* @brief 关闭设备
*
* @param pDevice [in] 已打开的设备句柄
*
* @return 成功返回0,失败返回非0
*
*/
int TassCloseDevice(void* hDevice);
/**
* @brief 打开会话
*
* @param pDevice [in] 已打开的设备句柄
* @param hSess [out] 打开的会话句柄
*
* @return 成功返回0,失败返回非0
*
*/
int TassOpenSession(void* hDevice, void** phSess);
/**
* @brief 关闭会话
*
* @param hSess [in] 已打开的会话句柄
*
* @return 成功返回0,失败返回非0
*
*/
int TassCloseSession(void* hSess);
/**
* @brief 设置超时时间
*
* @param timout [in] 超时时间,毫秒
*
* @return 成功返回0,失败返回非0
*
*/
int TassSetTimeout(void* hDevice, int timout);
/**
* @brief 获取超时时间
*
* @param timout [out] 超时时间,毫秒
*
* @return 成功返回0,失败返回非0
*
*/
int TassGetTimeout(void* hDevice, int* timout);
/**
* @brief 获取错误码描述信息
*
* @param err [in] 错误码
*
* @return 错误码描述信息
*
*/
const char* TassGetErrorDesc(int err);
/*
* 设备管理类指令
*/
/**
* @brief 获取密码卡信息
*
* @param hSess [in] 会话句柄
* @param devInfo [out] 设备信息
*
* @return 成功返回0,失败返回非0
*
*/
int TassGetDeviceInfo(void* hSess, TassDevInfo* devInfo);
/**
* @brief 设备自检
*
* @param hSess [in] 会话句柄
* @param res [in] 自检结果
* 1B:SM4 IP结果
* 1B:SM2 IP结果
* 1B:密管芯片结果
* 1B:WNG8芯片结果
*
* @return
* @retval 成功返回0,失败返回非0
*
*/
int TassDeviceSelfCheck(void* hSess,
unsigned char res[4]);
/**
* @brief 恢复出厂设置
*
* @param hSess [in] 会话句柄
* @param cb [in] 管理平台私钥签名回调函数
*
* @return
* @retval 成功返回0,失败返回非0
*
*/
int TassRestoreFactory(void* hSess,
const TassSignCb cb);
/**
* @brief 设置设备基础信息
*
* @param hSess [in] 会话句柄
* @param devSn [in] 设备序列号
* @param selfCheckCycle [in] 自检周期
* @param cb [in] 管理平台私钥签名回调函数
*
* @return
* @retval 成功返回0,失败返回非0
*
*/
int TassSetDeviceBaseInfo(void* hSess,
const unsigned char devSn[4],
unsigned int selfCheckCycle,
const TassSignCb cb);
/*
* 设备密钥管理类指令
*/
/**
* @brief 生成设备密钥
*
* @param hSess [in] 会话句柄
* @param type [in] 生成的设备密钥类型
* TA_DEV_SIGN/TA_DEV_ENC/TA_DEV_KEK有效
* @param keyInfo [in] 密钥信息
* @param bootAuth [in] 是否开机认证,0--否,非0--是
* type=TA_DEV_KEK时有效
* @param kekcv [out] KEK校验值,为NULL时不输出
* type=TA_DEV_KEK时有效
*
* @retval 成功返回0,失败返回非0
*
*/
int TassGenDeviceKey(void* hSess,
TassDevKeyType type,
const unsigned char keyInfo[4],
TassBool bootAuth,
unsigned char kekcv[16]);
/**
* @brief 获取设备公钥
*
* @param hSess [in] 会话句柄
* @param type [in] 获取的设备密钥类型
* TA_DEV_KEY_PLATFORM/TA_DEV_KEY_SIGN/TA_DEV_KEY_ENC有效
* @param keyInfo [out] 密钥信息,为NULL时不输出
* @param pk [out] 公钥
*
* @retval 成功返回0,失败返回非0
*
*/
int TassGetDevicePublicKey(void* hSess,
TassDevKeyType type,
unsigned char keyInfo[4],
unsigned char pk[64]);
/**
* @brief 设置平台公钥
*
* @param hSess [in] 会话句柄
* @param keyInfo [in] 密钥信息
* @param pk [in] 公钥
*
* @retval 成功返回0,失败返回非0
*
*/
int TassSetPlatformPublicKey(void* hSess,
const unsigned char keyInfo[4],
const unsigned char pk[64]);
/**
* @brief 导入管理员公钥
*
* @param hSess [in] 会话句柄
* @param keyInfo [in] 密钥信息
* @param pk [in] 导入的公钥
* @param cb [in] (管理平台私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassImportAdminPublicKey(void* hSess,
const unsigned char keyInfo[4],
const unsigned char pk[64],
const TassSignCb cb);
/**
* @brief 增加管理员公钥
*
* @param hSess [in] 会话句柄
* @param keyInfo [in] 密钥信息
* @param pk [in] 增加的公钥
* @param adminPk [in] (已经存在的)管理员公钥
* @param cb [in] (adminPk对应私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassAddAdminPublicKey(void* hSess,
const unsigned char keyInfo[4],
const unsigned char pk[64],
const unsigned char adminPk[64],
const TassSignCb cb);
/**
* @brief 删除管理员公钥
*
* @param hSess [in] 会话句柄
* @param keyInfo [in] 密钥信息
* @param pk [in] 删除的公钥
* @param adminPk [in] (已经存在的)管理员公钥,可以与pubKey相同
* @param cb [in] (adminPk对应私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassDeleteAdminPublicKey(void* hSess,
const unsigned char keyInfo[4],
const unsigned char pk[64],
const unsigned char adminPk[64],
const TassSignCb cb);
/**
* @brief 导出设备加密密钥对
*
* @param hSess [in] 会话句柄
* @param protectPk [in] 保护公钥,一般为另一个密码卡的签名公钥
* @param adminPk [in] 管理员公钥
* @param adminCb [in] (adminPk对应私钥)签名回调
* @param platformCb [in] (平台公钥对应私钥)签名回调
* @param keyInfo [out] 密钥信息,为NULL时不输出
* @param devEncPk [out] 设备加密公钥,为NULL时不输出
* @param devEncSkEnvelopByProtectPk [out] 设备加密私钥信封,通过protectPk加密
*
* @retval 成功返回0,失败返回非0
*
*/
int TassExportDeviceEncKeyPair(void* hSess,
const unsigned char protectPk[64],
const unsigned char adminPk[64], const TassSignCb adminCb,
const TassSignCb platformCb,
unsigned char keyInfo[4],
unsigned char devEncPk[64],
unsigned char devEncSkEnvelopByProtectPk[144]);
/**
* @brief 导出设备KEK
*
* @param hSess [in] 会话句柄
* @param protectPk [in] 保护公钥,一般为另一个密码卡的加密公钥
* @param adminPk [in] 管理员公钥
* @param adminCb [in] (adminPk对应私钥)签名回调
* @param platformCb [in] (平台公钥对应私钥)签名回调
* @param keyInfo [out] 密钥信息,为NULL时不输出
* @param kekCipherByProtectPk [out] 设备KEK密文,通过protectPk加密
*
* @retval 成功返回0,失败返回非0
*
*/
int TassExportDeviceKEK(void* hSess,
const unsigned char protectPk[64],
const unsigned char adminPk[64], const TassSignCb adminCb,
const TassSignCb platformCb,
unsigned char keyInfo[4],
unsigned char kekCipherByProtectPk[112]);
/**
* @brief 导入设备加密密钥对
*
* @param hSess [in] 会话句柄
* @param keyInfo [in] 密钥信息
* @param pk [in] 公钥
* @param skEnvelopByDevSignPk [in] 设备签名公钥加密的私钥私钥信封
* @param cb [in] (平台公钥对应私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassImportDeviceEncKeyPair(void* hSess,
const unsigned char keyInfo[4],
const unsigned char pk[64],
const unsigned char skEnvelopByDevSignPk[144],
const TassSignCb cb);
/**
* @brief 导入设备KEK
*
* @param hSess [in] 会话句柄
* @param bootAuth [in] 是否开机认证,0--否,非0--是
* @param keyInfo [in] 密钥信息
* @param kekCipherByDevEncPk [in] 设备加密密钥对加密的KEK密文
* @param cb [in] (平台公钥对应私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassImportDeviceKEK(void* hSess,
TassBool bootAuth,
const unsigned char keyInfo[4],
const unsigned char kekCipherByDevEncPk[112],
const TassSignCb cb);
/**
* @brief 开机认证
*
* @param hSess [in] 会话句柄
* @param cb [in] (平台公钥对应私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassBootAuth(void* hSess, const TassSignCb cb);
/**
* @brief 开机认证
*
* @param hSess [in] 会话句柄
* @param state [in] 要设置的工作状态
* TA_DEV_STATE_WORK/TA_DEV_STATE_MNG有效
* @param cb [in] (平台公钥对应私钥)签名回调
*
* @retval 成功返回0,失败返回非0
*
*/
int TassSetDeviceState(void* hSess, TassDevState state, const TassSignCb cb);
/*
* 应用密钥管理类指令
*/
/*
3.3.1
后续废弃,仅用于测试。
仅在管理状态下可用
*/
int TassAuthSM2PublicKey(void* hSess,
const unsigned char pk[64],
unsigned char authCode[4]);
/*
3.3.1
* @brief 扩展认证保护密钥
*
* @param hSess [in] 会话句柄
* @param alg [in] 保护密钥类型, 0–SM4,2-SM2,4–RSA
* @param protectKey [in] 保护密钥,当保护密钥类型是 0 时,保护密钥是16字节的 SM4 密钥;
* 当保护密钥类型是 2 时,保护密钥是 64字节 SM2 公钥;
* 当保护密钥类型是 4 时,保护密钥是RSA2048公钥,此时是4字节的公钥长度+公钥内容
* @param protectKeyLen [in] 保护密钥长度
* @param cb [in] (平台公钥对应私钥)签名回调
* @param authCode [out] 认证码
*
* @retval 成功返回0,失败返回非0
*
*/
int TassAuthPortectKey(void* hSess,
TassAlg alg,
const unsigned char* protectKey, unsigned int protectKeyLen,
const TassSignCb cb,
unsigned char authCode[4]);
/*
3.3.3
同时适用于19150
*/
int TassGenSM2KeyPair(void* hSess,
unsigned char skCipherByKek[32],
unsigned char pk[64]);
/*
3.3.4
同时适用于19150
密钥信息校验值,为NULL时不输出
*/
int TassGenSM4Key(void* hSess,
unsigned char keyCipherByKek[16],
unsigned char kcv[16]);
/*
3.3.7
同时适用于19150
密钥信息校验值,为NULL时不输出
*/
int TassGen_ExportSM4KeyBySM4Key(void* hSess,
const unsigned char protectKeyCipherByKek[16],
unsigned char keyCipherByProtectKey[16],
unsigned char keyCipherByKek[16],
unsigned char kcv[16]);
/*
3.3.8
同时适用于19150
*/
int TassExportSM2PrivateKeyBySM2PublicKey(void* hSess,
const unsigned char protectPk[64],
const unsigned char authCode[4],
const unsigned char skCipherByKek[32],
unsigned char skEnvelopByProtectPk[144]);
/*
3.3.9
同时适用于19150
*/
int TassImportSM2PrivateKeyBySM2PrivateKey(void* hSess,
const unsigned char protectSkCipherByKek[32],
const unsigned char skEnvelopByProtectPk[144],
unsigned char skCipherByKek[32]);
/*
3.3.12
同时适用于19150
密钥信息校验值,为NULL时不输出
*/
int TassExportSM4KeyBySM2PublicKey(void* hSess,
const unsigned char protectPk[64],
const unsigned char authCode[4],
const unsigned char keyCipherByKek[16],
unsigned char keyCipherByProtectPk[112],
unsigned char kcv[16]);
/*
3.3.13
同时适用于19150
*/
int TassImportSM4KeyBySM2PrivateKey(void* hSess,
const unsigned char protectSkCipherByKek[32],
const unsigned char keyCipherByProtectPk[112],
const unsigned char kcv[16],
unsigned char keyCipherByKek[16]);
/*
3.3.16
同时适用于19150
*/
int TassImportSM4KeyBySM4Key(void* hSess,
const unsigned char protectKeyCipherByKek[16],
const unsigned char keyCipherByProtectKey[16],
const unsigned char kcv[16],
unsigned char keyCipherByKek[16]);
/*
3.3.17
密钥信息校验值,为NULL时不输出
仅导出SM2和SM4密钥
*/
int TassExportKeyBySM4Key(void* hSess,
const unsigned char protectKeyCipherByKek[16],
const unsigned char authCode[4],
TassAlg alg,
const unsigned char* keyCipherByKek, unsigned int keyCipherByKekLen,
unsigned char* keyCipherByProtectKey, unsigned int* keyCipherByProtectKeyLen,
unsigned char kcv[16]);
/*
3.3.4
*/
int TassGenSymmKey(void* hSess,
TassAlg keyAlg,
unsigned int keyBits, //密钥类型为 9 时,支持模长是128、256、384、512bit,其他类型仅支持 128(0x00000080)
unsigned char* keyCipherByKek, unsigned int* keyCipherByKekLen,
unsigned char kcv[16]);
/*
3.3.5
* @brief 生成非对称密钥
*
* @param hSess [in] 会话句柄
* @param keyAlg [in] 密钥类型, 2-SM2, 3–SECP_256R1, 4–RSA,8-SECP_256K1
* @param keyBits [in] 模长, 密钥类型是2或3 时都只支持256,密钥类型是4时只支持 2048
* @param rsaE [in] 公钥指数
* @param skCipherByKek [out] 私钥密文
* @param skCipherByKekLen [out] 私钥密文长度
* @param pk [out] 公钥
* @param pkLen [out] 公钥长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassGenAsymKeyPair(void* hSess,
TassAlg keyAlg,
unsigned int keyBits,
TassRSA_E rsaE,
unsigned char* skCipherByKek, unsigned int* skCipherByKekLen,
unsigned char* pk, unsigned int* pkLen);
/*
3.3.9
* @brief 将非对称私钥转加密(本地保护密钥 KEK 加密转为SM2加密)
*
* @param hSess [in] 会话句柄
* @param protectPk [in] 经认证的SM2公钥
* @param authCode [in] 认证码
* @param keyAlg [in] 密钥类型,2-SM2、3–ECC(SECP 256r1)、4–RSA、8–ECC(SECP 256k1)
* @param keyBits [in] 模长
* @param skCipherByKek [in] 私钥密文
* @param skCipherByKekLen [in] 私钥密文长度
* @param symmKeyCipher [out] 随机对称密钥密文
* @param symmKeyCipherLen [out] 随机对称密钥密文长度
* @param skEnvelopByProtectPk [out] 业务密钥私钥密文
* @param skEnvelopByProtectPkLen [out] 业务密钥私钥密文长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassExportAsymPrivateKeyBySM2PublicKey(void* hSess,
const unsigned char protectPk[64],
const unsigned char authCode[4],
TassAlg keyAlg,
unsigned int keyBits,
const unsigned char* skCipherByKek, unsigned int skCipherByKekLen,
unsigned char* symmKeyCipher, unsigned int *symmKeyCipherLen,
unsigned char* skEnvelopByProtectPk, unsigned int* skEnvelopByProtectPkLen);
/*
3.3.11
* @brief 将非对称私钥转加密(SM2加密转为本地保护密钥KEK加密)
*
* @param hSess [in] 会话句柄
* @param protectSkCipherByKek [in] 解密私钥密文
* @param keyAlg [in] 密钥类型, 2-SM2, 3–ECC 256r1, 4–RSA,8-ECC 256k1
* @param keyBits [in] 模长, 密钥类型是2或3 时都只支持256,密钥类型是4时只支持 2048
* @param symmKeyCipher [in] 随机对称密钥密文
* @param symmKeyCipherLen [in] 随机对称密钥密文长度
* @param skEnvelopByProtectPk [in] 业务密钥私钥密文,(数字信封)
* @param skEnvelopByProtectPkLen [in] 业务密钥私钥密文长度
* @param skCipherByKek [out] KEK加密的业务密钥私钥密文
* @param skCipherByKekLen [out] KEK加密的业务密钥私钥密文长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassImportAsymPrivateKeyBySM2PrivateKey(void* hSess,
const unsigned char protectSkCipherByKek[32],
TassAlg keyAlg,
unsigned int keyBits,
const unsigned char* symmKeyCipher, unsigned int symmKeyCipherLen,
const unsigned char* skEnvelopByProtectPk, unsigned int skEnvelopByProtectPkLen,
unsigned char* skCipherByKek, unsigned int* skCipherByKekLen);
/*
3.3.14
*/
int TassExportSymmKey(void* hSess,
TassAlg protectKeyAlg,
unsigned int protectKeyBits,
const unsigned char* protectKey, unsigned int protectKeyLen,
const unsigned char authCode[4],
TassAlg keyAlg,
unsigned int keyBits,
const unsigned char* keyCipherByKek, unsigned int keyCipherByKekLen,
unsigned char* keyCipherByProtectKey, unsigned int* keyCipherByProtectKeyLen,
unsigned char kcv[16]);
/*
3.3.15
* @brief 将对称密钥转加密(外部密钥加密转为本地保护密钥 KEK 加密)
*
* @param hSess [in] 会话句柄
* @param protectKeyAlg [in] 外部保护密钥类型,0-SM4,2-SM2, 4–RSA
* @param protectKeyBits [in] 外部保护密钥模长
* @param protectKey [in] 外部保护密钥
* @param protectKeyLen [in] 外部保护密钥长度
* @param keyAlg [in] 对称密钥类型,0-SM4,1-SM1,5--AES,6-DES,7-SM7
* @param keyBits [in] 对称密钥模长,当前仅支持 128
* @param keyCipherByProtectKey [in] 业务密钥密文(即被公钥加密的对称密钥密文)
* @param keyCipherByProtectKeyLen [in] 业务密钥密文长度
* @param kcv [in] 密钥校验值
* @param keyCipherByKek [out] 外部密钥密文(即公钥对应的私钥或者 SM4 密钥密文)
* @param keyCipherByKekLen [out] 外部密钥密文长度
*
* @retval 成功返回0,失败返回非0
*/
int TassImportSymmKey(void* hSess,
TassAlg protectKeyAlg,
unsigned int protectKeyBits,
const unsigned char* protectKey, unsigned int protectKeyLen,
TassAlg keyAlg,
unsigned int keyBits,
const unsigned char* keyCipherByProtectKey, unsigned int keyCipherByProtectKeyLen,
const unsigned char kcv[16],
unsigned char* keyCipherByKek, unsigned int* keyCipherByKekLen);
/*
* 密码运算类指令
*/
int TassGenRandom(void* hSess,
unsigned int randomLen,
unsigned char* random);
/*
3.4.2 + 4.2.1
同时适用于19150
*/
int TassSM2PrivateKeySign(void* hSess,
unsigned int index,
const unsigned char skCipherByKek[32],
const unsigned char hash[32],
unsigned char sig[64]);
/*
3.4.3 + 4.2.2
同时适用于19150
*/
int TassSM2PublicKeyVerify(void* hSess,
unsigned int index,
const unsigned char pk[64],
const unsigned char hash[32],
const unsigned char sig[64]);
/*
3.4.4 + 4.2.3
同时适用于19150
*/
int TassSM2PublicKeyEncrypt(void* hSess,
unsigned int index,
const unsigned char pk[64],
const unsigned char* plain, unsigned int plainLen,
unsigned char* cipher, unsigned int* cipherLen);
/*
3.4.5 + 4.2.4
同时适用于19150
*/
int TassSM2PrivateKeyDecrypt(void* hSess,
unsigned int index,
const unsigned char skCipherByKek[32],
const unsigned char* cipher, unsigned int cipherLen,
unsigned char* plain, unsigned int* plainLen);
/*
3.4.6 + 4.2.5
同时适用于19150
*/
int TassSM2KeyExchange(void* hSess,
TassBool sponsor,
unsigned int selfIndex,
const unsigned char selfSkCipherByKek[32],
const unsigned char selfPk[64],
const unsigned char selfTmpSkCipherByKek[32],
const unsigned char selfTmpPk[64],
const unsigned char* selfId, unsigned int selfIdLen,
const unsigned char peerPk[64],
const unsigned char peerTmpPk[64],
const unsigned char* peerId, unsigned int peerIdLen,
unsigned int keyBytes,
TassBool genPlainKey,
unsigned char* key);
/*
* @brief ECC私钥签名
*
* @param hSess [in] 会话句柄
* @param alg [in] ECC密钥类型
* @param index [in] 索引
* @param keyBits [in] 模长,ECC_256R1和ECC_256K1均为256,索引为0时有效
* @param skCipherByKek [in] 签名私钥,索引为0时有效
* @param skCipherByKekLen [in] 签名私钥长度,索引为0时有效
* @param hash [in] 哈希值
* @param hashLen [in] 哈希值长度
* @param sig [out] 签名值
* @param sigLen [in/out] 签名值长度
*
* @retval 成功返回0,失败返回非0
*/
int TassECCPrivateKeySign(void* hSess,
TassAlg alg,
unsigned int index,
unsigned int keyBits,
const unsigned char* skCipherByKek, unsigned int skCipherByKekLen,
const unsigned char* hash, unsigned int hashLen,
unsigned char* sig, unsigned int* sigLen);
/*
* @brief ECC私钥签名(为复杂美项目特殊需求定制)
*
* @param hSess [in] 会话句柄
* @param alg [in] ECC密钥类型
* @param index [in] 索引
* @param keyBits [in] 模长,ECC_256R1和ECC_256K1均为256,索引为0时有效
* @param skCipherByKek [in] 签名私钥,索引为0时有效
* @param skCipherByKekLen [in] 签名私钥长度,索引为0时有效
* @param hash [in] 哈希值
* @param hashLen [in] 哈希值长度
* @param sig [out] 签名值
* @param sigLen [in/out] 签名值长度
*
* @retval 成功返回0,失败返回非0
*/
int TassECCPrivateKeySign_Eth(void* hSess,
TassAlg alg,
unsigned int index,
unsigned int keyBits,
const unsigned char* skCipherByKek, unsigned int skCipherByKekLen,
const unsigned char* hash, unsigned int hashLen,
unsigned char* sig, unsigned int* sigLen);
/*
* @brief ECC公钥验签
*
* @param hSess [in] 会话句柄
* @param alg [in] ECC密钥类型
* @param index [in] 索引
* @param keyBits [in] 模长,ECC_256R1和ECC_256K1均为256,索引为0时有效
* @param pk [in] 验签公钥,索引为0时有效
* @param pkLen [in] 验签公钥长度,索引为0时有效
* @param hash [in] 哈希值
* @param hashLen [in] 哈希值长度
* @param sig [out] 签名值
* @param sigLen [in/out]签名值长度
*
* @retval 成功返回0,失败返回非0
*/
int TassECCPublicKeyVerify(void* hSess,
TassAlg alg,
unsigned int index,
unsigned int keyBits,
const unsigned char* pk, unsigned int pkLen,
const unsigned char* hash, unsigned int hashLen,
const unsigned char* sig, unsigned int sigLen);
/*
3.4.9
*/
int TassECCKeyAgreement(void* hSess,
TassAlg alg,
unsigned int keyBits,
const unsigned char* selfSkCipherByKek, unsigned int selfSkCipherByKekLen,
const unsigned char* peerPk, unsigned int peerPkLen,
TassBool genPlainKey,
unsigned char* key, unsigned int* keyLen);
/*
3.4.10 + 4.2.9
*/
int TassRSAPrivateKeyOperate(void* hSess,
unsigned int index,
unsigned int keyBits,
const unsigned char* skCipherByKek, unsigned int skCipherByKekLen,
const unsigned char* inData, unsigned int inDataLen,
unsigned char* outData);
/*
3.4.11 + 4.2.10
*/
int TassRSAPublicKeyOperate(void* hSess,
unsigned int index,
unsigned int keyBits,
const unsigned char* pk, unsigned int pkLen,
const unsigned char* inData, unsigned int inDataLen,
unsigned char* outData);
/*
3.4.12 + 4.2.6
同时适用于19150
*/
int TassSM4KeyOperate(void* hSess,
TassSymmOp op,
unsigned int index,
const unsigned char keyCipherByKek[16],
unsigned char* iv,
const unsigned char* inData, unsigned int dataLen,
unsigned char* outData);
/*
3.4.13 + 4.2.11
*/
int TassSymmKeyOperate(void* hSess,
TassAlg alg,
unsigned int keyBits,
TassSymmOp op,
unsigned int index,
const unsigned char* keyCipherByKek, unsigned int keyCipherByKekLen,
unsigned char* iv,
const unsigned char* inData, unsigned int inDataLen,
unsigned char* outData, unsigned int* outDataLen);
int TassSM3Single(void* hSess,
const unsigned char pk[64],
const unsigned char* id, unsigned int idLen,
const unsigned char* data, unsigned int dataLen,
unsigned char hash[32]);
int TassSM3Init(void* hSess,
unsigned int uiAlgID,
const unsigned char pk[64],
const unsigned char* id, unsigned int idLen,
unsigned char ctx[112]);
int TassSM3Update(void* hSess,
const unsigned char* data, unsigned int dataLen,
unsigned char ctx[112]);
int TassSM3Final(void* hSess,
const unsigned char ctx[112],
unsigned char hash[32]);
/*
* PKI扩展命令
*/
/*
* 密钥管理命令
*/
/*
4.1.1
同时适用19150
*/
int TassGetIndexInfo(void* hSess,
TassAlg alg,
unsigned char* info, unsigned int* infoLen);
/*
4.1.2
同时适用19150
*/
int TassSetLabel(void* hSess,
TassAlg alg,
unsigned int index,
const unsigned char* label, unsigned int labelLen);
/*
4.1.3
同时适用19150
*/
int TassGetLabel(void* hSess,
TassAlg alg,
unsigned int index,
unsigned char* label, unsigned int* labelLen);
/*
4.1.4
同时适用19150
*/
int TassGetIndex(void* hSess,
TassAlg alg,
const unsigned char* label, unsigned int labelLen,
unsigned int* index);
/*
4.1.5
同时适用19150
*/
/*
* @brief 依据索引设置密钥属性
*
* @param hSess [in] 会话句柄
* @param alg [in] 密钥类型
* @param index [in] 密钥索引
* @param sk [in] 公私钥标识,0–私钥,1–公钥
* @param attr [in] 密钥属性
* @param attrLen [in] 密钥属性长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassSetAttr(void* hSess,
TassAlg alg,
unsigned int index,
TassBool sk,
const unsigned char* attr, unsigned int attrLen);
/*
4.1.6
同时适用19150
*/
/*
* @brief 依据索引获取密钥属性
*
* @param hSess [in] 会话句柄
* @param alg [in] 密钥类型
* @param index [in] 密钥索引
* @param sk [in] 公私钥标识,0–私钥,1–公钥
* @param attr [out] 密钥属性
* @param attrLen [out] 密钥属性长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassGetAttr(void* hSess,
TassAlg alg,
unsigned int index,
TassBool sk,
unsigned char* attr, unsigned int* attrLen);
/*
4.1.10
同时适用19150
*/
int TassStoreSM2KeyPair(void* hSess,
unsigned int index,
const unsigned char* label, unsigned int labelLen,
TassAsymKeyUsage usage,
const unsigned char skCipherByKek[32],
const unsigned char pk[64]);
/**
4.1.11
* @brief 导入非对称密钥到密码卡
*
* @param hSess [in] 会话句柄
* @param alg [in] 密钥类型
* @param index [in] 密钥索引,0-64,当密钥类型是 RSA 是为 0-4
* @param label [in] 密钥标签
* @param labelLen [in] 密钥标签长度
* @param usage [in] 0-签名密钥,1-加密密钥,2-密钥协商密钥
* @param skCipherByKek [in] 私钥密文
* @param skCipherByKekLen [in] 私钥密文长度
* @param pk [in] 公钥
* @param pkLen [in] 公钥长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassStoreAsymKeyPair(void* hSess,
TassAlg alg,
unsigned int index,
const unsigned char* label, unsigned int labelLen,
TassAsymKeyUsage usage,
const unsigned char* skCipherByKek, unsigned int skCipherByKekLen,
const unsigned char* pk, unsigned int pkLen);
/*
4.1.12
同时适用19150
*/
int TassStoreSM4Key(void* hSess,
unsigned int index,
const unsigned char* label, unsigned int labelLen,
const unsigned char keyCipherByKek[16],
const unsigned char kcv[16]);
/*
4.1.13
*/
int TassStoreSymmKey(void* hSess,
TassAlg alg,
unsigned int index,
const unsigned char* label, unsigned int labelLen,
const unsigned char* keyCipherByKek, unsigned int keyCipherByKekLen,
const unsigned char kcv[16]);
/*
4.1.14
同时适用19150
*/
int TassDestroyKey(void* hSess,
TassAlg alg,
TassAsymKeyUsage usage,
unsigned int index);
/*
4.1.8
同时适用19150
*/
int TassGetSM2PublicKey(void* hSess,
unsigned int index,
TassAsymKeyUsage usage,
unsigned char pk[64]);
int TassGetAsymPublicKey(void* hSess,
TassAlg alg,
unsigned int index,
TassAsymKeyUsage usage,
unsigned char* pk, unsigned int* pkLen);
/*
4.1.14
同时适用19150
*/
/*
* @brief 依据索引设置密钥属性
*
* @param hSess [in] 会话句柄
* @param alg [in] 密钥类型
* @param index [in] 密钥索引
* @param usage [in] 密钥用途,0–签名密钥,1–加密密钥, 2-密钥协商密钥
* @param sk_keyCipherByKek [out] 私钥
* @param sk_keyCipherByKekLen [in/out]私钥长度
* @param sk_keyCipherByKek [out] 公钥
* @param sk_keyCipherByKekLen [in/out]公钥长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassGetKey(void* hSess,
TassAlg alg,
unsigned int index,
TassAsymKeyUsage usage,
unsigned char* sk_keyCipherByKek, unsigned int* sk_keyCipherByKekLen,
unsigned char* pk_kcv, unsigned int* pk_kcvLen);
/*
4.1.16 + 4.1.17
2K FLASH 操作同时适用19150
*/
int TassFlashOperate(void* hSess,
TassFlashFlag flag,
TassFlashOp op,
unsigned int offset,
unsigned int dataLen,
unsigned char* data);
/**
4.2.10
* @brief ECC 密钥协商
*
* @param hSess [in] 会话句柄
* @param alg [in] 密钥类型, 3–ECC_SECP_256R1, 8-ECC_SECP_256K1
* @param index [in] 密钥索引,1-64
* @param pk [in] 对方公钥
* @param pkLen [in] 对方公钥长度
* @param agreementData [out] 协商结果
* @param agreementDataLen [out] 协商结果长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassGenerateAgreementDataWithECC(void* hSess,
TassAlg alg,
unsigned int index,
unsigned char* pk, unsigned int pkLen,
unsigned char* agreementData, unsigned int* agreementDataLen);
/*
* HMAC计算
*/
/**
3.4.20、4.2.14
* @brief HMAC单包计算
*
* @param hSess [in] 会话句柄
* @param index [in] 密钥索引
* @param key [in] 密钥密文,索引为0时有效
* @param keyLen [in] 密钥密文长度,16/32/48/64,最大 64 字节,索引为0时有效
* @param data [in] 数据
* @param dataLen [in] 数据长度,最大不超过2000字节
* @param hmac [out] HMAC 结果
* @param hmacLen [out] HMAC 结果长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassHmacSingle(void* hSess,
unsigned int index,
unsigned char* key, unsigned int keyLen,
unsigned char* data, unsigned int dataLen,
unsigned char* hmac, unsigned int* hmacLen);
/**
3.4.21、4.2.15
* @brief HMAC多包计算init
*
* @param hSess [in] 会话句柄
* @param index [in] 密钥索引,仅支持HMAC密钥
* @param key [in] 密钥密文,索引为0时有效,仅支持HMAC密钥
* @param keyLen [in] 密钥密文长度,16/32/48/64,最大 64 字节,索引为0时有效,仅支持HMAC密钥
*
* @retval 成功返回0,失败返回非0
*
*/
int TassHmacInit(void* hSess,
unsigned int index,
unsigned char* key, unsigned int keyLen);
/**
3.4.22
* @brief HMAC多包计算update
*
* @param hSess [in] 会话句柄
* @param data [in] 数据
* @param dataLen [in] 数据长度,长度只能是64 字节的倍数
*
* @retval 成功返回0,失败返回非0
*
*/
int TassHmacUpdate(void* hSess, unsigned char* data, unsigned int dataLen);
/**
3.4.23、4.2.16
* @brief HMAC多包计算final
*
* @param hSess [in] 会话句柄
* @param hmac [out] HMAC 结果
* @param hmacLen [out] HMAC 结果长度
*
* @retval 成功返回0,失败返回非0
*
*/
int TassHmacFinal(void* hSess, unsigned char* hmac, unsigned int* hmacLen);
/**
* @brief 获取密码设备内部存储的指定索引私钥的使用权
* @param hSessionHandle [IN] 与设备建立的会话句柄
* @param uiKeyIndex [IN] 密码设备存储私钥的索引值
* @param uiAlgID [IN] 密钥类型
* @param pucPassword [IN] 使用私钥权限的识别码,默认为a1234567
* @param uiPwdLength [IN] 私钥访问控制码长度
* @return
* @retval 0 成功
* @retval 非0 失败,返回错误代码
* @note 本标准涉及密码设备存储的密钥对索引值的起始索引值为1,最大为n,
* 密码设备的实际存储容量决定n值
*/
int TassGetPrivateKeyAccessRight(void* hSessionHandle,
unsigned int uiKeyIndex,
TassAlg uiAlgID,
unsigned char* pucPassword,
unsigned int uiPwdLength);
#ifdef __cplusplus
}
#endif
#pragma once
#include "TassType4PCIeSM.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TASS_DEV_ADMIN_NAME "admin" //设备管理员名称
#define TASS_DEV_ID_STR_SIZE 32 //设备ID长度
#define TASS_NAME_SIZE_MAX 8 //管理员名称最大长度
#define TASS_UKEY_SN_SIZE 5 //UKey序列号长度
#define TASS_KEY_LABEL_SIZE_MAX 128 //密钥标签最大长度
#define TASS_KEY_ATTR_SIZE_MAX 1024 //密钥属性最大长度
#define TASS_SK_SIZE_MAX 4096 //私钥最大长度
#define TASS_PK_SIZE_MAX 1024 //公钥最大长度
#define TASS_KEY_SIZE_MAX 64 //对称密钥最大长度
#define TASS_KCV_SIZE 16 //密钥校验值长度
#define TASS_DEV_ADMIN_CNT_MAX 1 //设备管理员数量
#define TASS_KEY_ADMIN_CNT_MAX 4 //密钥管理员最大数量
#define TASS_ECC_INDEX_MAX 64
#define TASS_SYMM_INDEX_MAX 64
typedef enum {
TA_DEV_ADMIN = 0, //设备管理员
TA_KEY_ADMIN = 1, //密钥管理员
}TassAdminType;
typedef struct {
TassAdminType type;
char name[TASS_NAME_SIZE_MAX + 1]; //名称
char ukeySn[TASS_UKEY_SN_SIZE + 1]; //UKey序列号,制作UKey后有效
}TassAdminInfo;
typedef struct {
TassAlg alg; //算法
int index; //索引
char label[TASS_KEY_LABEL_SIZE_MAX + 1]; //标签
unsigned char sk_key[TASS_SK_SIZE_MAX]; //私钥/对称密钥密文
unsigned int sk_keyLen; //私钥/对称密钥密文长度
unsigned char sk_keyAttr[TASS_KEY_ATTR_SIZE_MAX]; //私钥/对称密钥属性
unsigned int sk_keyAttrLen; //私钥/对称密钥属性长度
unsigned char pk_kcv[TASS_PK_SIZE_MAX]; //公钥/对称密钥校验值
unsigned int pk_kcvLen; //公钥/对称密钥校验值长度
unsigned char pkAttr[TASS_KEY_ATTR_SIZE_MAX]; //公钥属性,非对称时有效
unsigned int pkAttrLen; //公钥属性长度
}TassKeyInfo;
/**
* @brief 搜索设备
*
* @param id [in] 设备ID缓冲区,传NULL时通过len返回需要的缓冲区大小
* @param idLen [in|out] 输入时标识id缓冲区大小
* 输出时标识id实际长度
* 多个设备ID间以‘\0’分隔,最后以两个'\0'结尾
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlScanDevice(char* id, unsigned int* idLen);
/**
* @brief 打开设备
*
* @param id [in] 要打开的设备ID,通过TassScan获取
* @param phDevice [out] 设备句柄
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlOpenDevice(const char id[TASS_DEV_ID_STR_SIZE + 1], void** phDevice);
/**
* @brief 关闭设备
*
* @param hDevice [in] 已打开的设备句柄
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlCloseDevice(void* hDevice);
/**
* @brief 管理员管理功能
*
* @func TassListAdmin
* @func TassLogin
* @func TassLogout
* @func TassMakeAdminUKey
* @func TassUpdatePWD
* @func TassAddAdmin
* @func TassRemoveAdmin
*
*/
/**
* @brief 获取用户列表
* @param hDevice [in] 已打开的设备句柄
* @param info [in] 管理员信息,传NULL时通过len返回需要的缓冲区大小
* @param infoLen [in|out] 输入时标识info缓冲区大小
* 输出时标识info实际长度
* 用户数量可通过计算“len / sizeof(TassAdminInfo)”获取
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 打开设备后必须首先执行登录接口,才能执行其他操作
*/
int TassCtlListAdmin(void* hDevice,
TassAdminInfo* info, unsigned int* infoLen);
/**
* @brief 申请口令哈希加密公钥
*
* @param hDevice [in] 已打开的设备句柄
* @param pk [out] 用于加密口令哈希的公钥
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 打开设备后必须首先执行登录接口,才能执行其他操作
*/
int TassCtlRequestPwdHashEncPublicKey(void* hDevice, unsigned char pk[64]);
/**
* @brief 通过哈希加密公钥加密口令hash值得到哈希值密文
*
* @param hDevice [in] 已打开的设备句柄
* @param pk [in] 用于加密口令哈希的公钥
* @param pwd [in] 用户登录口令
* @param pwdHashCipher [out] 管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlEncryptPwdHash(void* hDevice, const unsigned char pk[64], const char* pwd, unsigned char pwdHashCipher[128]);
/**
* @brief 登录
*
* @param hDevice [in] 已打开的设备句柄
* @param name [in] 管理员名称,设备管理员固定为“admin”
* @param pwdHashCipher [in] 管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 打开设备后必须首先执行登录接口,才能执行其他操作
*/
int TassCtlLogin(void* hDevice,
const char* name,
const unsigned char pwdHashCipher[128]);
/**
* @brief 登出
*
* @param hDevice [in] 已打开的设备句柄
*
* @return
* @retval 0 成功
* @retval other 失败
*/
int TassCtlLogout(void* hDevice);
/**
* @brief 修改口令
*
* @param hDevice [in] 已打开的设备句柄
* @param name [in] 已登录的用户名
* @param oldPwdHashCipher [in] 旧管理员口令的哈希值密文
* @param newPwdHashCipher [in] 新管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlUpdatePwdHash(void* hDevice,
const char* name,
const unsigned char oldPwdHashCipher[128],
const unsigned char newPwdHashCipher[128]);
/**
* @brief 绑定UKey(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param name [in] 已登录的用户名称
* @param pwdHashCipher [in] 管理员口令的哈希值密文
* @param ukeyId [in] UKey序号
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 制作UKey后,登录时必须插入该UKey
*/
int TassCtlBindUKey(void* hDevice,
const char* name,
const char pwdHashCipher[128],
const char* ukeyId);
/**
* @brief 添加密钥管理员(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param devPwdHashCipher [in] 设备管理员口令的哈希值密文
* @param name [in] 增加的密钥管理员名称,不能与已存在管理员名称相同
* @param pwdHashCipher [in] 增加的密钥管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlAddKeyAdmin(void* hDevice,
const unsigned char devPwdHashCipher[128],
const char* name,
const unsigned char pwdHashCipher[128]);
/**
* @brief 删除密钥管理员(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param devPwdHashCipher [in] 设备管理员口令的哈希值密文
* @param name [in] 删除的密钥管理员名称
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlRemoveKeyAdmin(void* hDevice,
const unsigned char devPwdHashCipher[128],
const char* name);
/**
* @brief 设备管理功能
*
* @func TassCtlDeviceFormat
* @func TassCtlDeviceInit
* @func TassCtlDeviceInitRestoreFactory
* @func TassCtlBootAuth
* @func TassGetInfo
* @func TassSetInfo
* @func TassSelfCheck
* @func TassRestoreFactory
* @func TassInitialize
* @func TassBootAuth
* @func TassExportDevEncKeyPair
* @func TassExportDevKEK
* @func TassImportDevKEK
*
*/
/**
* @brief 设备格式化
* 清除设备中的全部数据,包括设备密钥FLASH数据等
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note
* 1. 需要设备管理员登录
* 2. 执行成功后会清除登录状态,需要使用默认设备管理员口令登录
*/
int TassCtlDeviceFormat(void* hDevice,
const unsigned char pwdHashCipher[128]);
/**
* @brief 设备初始化
* 使用随机密钥初始化设备
*
* @param hDevice [in] 已打开的设备句柄
* @param newPwdHashCipher [in] 新的设备管理员口令密文
* @param bootAuth [in] 是否开机认证
* @param devSn [in] 设备序列号,可以从设备表面标签或包装盒外部标签获取
* @param selfCheckCycle [in] 设备自检周期,暂时不启用
* @param kekCv [out] 设备本地保护密钥校验值,为NULL时不输出
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note
* 1. 设备必须为格式化状态(TassCtlDeviceFormat成功)
* 2. 需要设备管理员登录
* 3. 执行成功后会清除登录状态,需要使用新的设备管理员口令登录
*/
int TassCtlDeviceInit(void* hDevice,
const unsigned char newPwdHashCipher[128],
TassBool bootAuth,
const unsigned char devSn[4], unsigned int selfCheckCycle,
unsigned char kekCv[16]);
/**
* @brief 设备初始化恢复出厂
* 使用出厂默认密钥初始化设备
*
* @param hDevice [in] 已打开的设备句柄
* @param devSn [in] 设备序列号,可以从设备表面标签或包装盒外部标签获取
* @param selfCheckCycle [in] 设备自检周期,暂时不启用
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note
* 1. 设备必须为格式化状态(TassCtlDeviceFormat成功)
* 2. 需要设备管理员登录
*/
int TassCtlDeviceInitRestoreFactory(void* hDevice,
const unsigned char devSn[4],
unsigned int selfCheckCycle);
/**
* @brief 获取密码卡信息(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param info [in] 信息类型,详见TassInfoType说明
* @param buf [out] 具体信息,传NULL时通过len返回需要的缓冲区大小
* @param len [in|out] 输入时标识buf缓冲区大小
* 输出时标识buf实际长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlGetInfo(void* hDevice,
TassDevInfo info,
void* buf, unsigned int* len);
/**
* @brief 设置密码卡信息(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param info [in] 信息类型,仅TA_DEV_SN和TA_SELF_CHECK_CYCLE有效
* @param buf [in] 具体信息
* @param len [in] 信息长度
* @param sig [in] 管理员私钥对函数名和除hDevice及sig之外所有入参的签名
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlSetInfo(void* hDevice,
TassDevInfo info,
void* buf, unsigned int len,
const unsigned char sig[64]);
/**
* @brief 自检(暂未启用)
* 使用随机密钥替换密码卡默认密钥
*
* @param hDevice [in] 已打开的设备句柄
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlSelfCheck(void* hDevice);
/**
* @brief 恢复出厂设置
* 恢复密码卡默认密钥和状态
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlRestoreFactory(void* hDevice,
const unsigned char pwdHashCipher[128]);
/**
* @brief 生成设备加密密钥对(暂未启用)
*
*
* @param hDevice [in] 已打开的设备句柄
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlGenDevEncKeyPair(void* hDevice);
/**
* @brief 生成设备本地保护密钥(暂未启用)
*
*
* @param hDevice [in] 已打开的设备句柄
* @param bootAuth [in] 是否开机认证
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlGenDevKEK(void* hDevice,
TassBool bootAuth);
/**
* @brief 导入设备加密密钥对(暂未启用)
*
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
* @param pk [in] 设备加密密钥对公钥
* @param skEnvelopByDevSignPk [in] 设备签名密钥对封装的设备加密密钥对私钥信封
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlImportDevEncKeyPair(void* hDevice,
const unsigned char pwdHashCipher[128],
const unsigned char pk[64],
const unsigned char skEnvelopByDevSignPk[144]);
/**
* @brief 导入设备本地保护密钥(暂未启用)
*
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
* @param bootAuth [in] 是否开机认证
* @param kekCipherByDevEncPk [in] 设备加密密钥对加密的设备本地保护密钥密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlImportDevKEK(void* hDevice,
const unsigned char pwdHashCipher[128],
TassBool bootAuth,
const unsigned char kekCipherByDevEncPk[112]);
/**
* @brief 开机认证
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*/
int TassCtlBootAuth(void* hDevice,
const unsigned char pwdHashCipher[128]);
/**
* @brief 导出设备加密密钥对(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param keyPwdHashCipher [in] 密钥管理员口令的哈希值密文
* @param devPwdHashCipher [in] 设备管理员口令的哈希值密文
* @param pk [in] 加密公钥,通常为另一个设备的签名公钥
* @param encPk [out] 设备加密密钥对公钥
* @param encSkEnvelopByPk [out] 加密公钥封装的设备加密密钥对私钥信封
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录密钥管理员,同时需要设备管理员口令进行授权
*/
int TassCtlExportDevEncKeyPair(void* hDevice,
const unsigned char keyPwdHashCipher[128],
const unsigned char devPwdHashCipher[128],
const unsigned char pk[64],
unsigned char encPk[64],
unsigned char encSkEnvelopByPk[144]);
/**
* @brief 导出设备本地保护密钥(暂未启用)
*
* @param hDevice [in] 已打开的设备句柄
* @param keyPwdHashCipher [in] 密钥管理员口令的哈希值密文
* @param devPwdHashCipher [in] 设备管理员口令的哈希值密文
* @param pk [in] 加密公钥,通常为另一个设备的加密公钥
* @param encKek [out] 加密公钥加密的设备本地保护密钥密文
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录密钥管理员,同时需要设备管理员口令进行授权
*/
int TassCtlExportDevKEK(void* hDevice,
const unsigned char keyPwdHashCipher[128],
const unsigned char devPwdHashCipher[128],
const unsigned char pk[64],
unsigned char encKek[112]);
/**
* @brief 用户密钥管理
*
* @func TassListKey
* @func TassGenerateKey
* @func TassDestroyKey
* @func TassImportPlainKey
* @func TassBackup
* @func TassRecover
*
*/
/**
* @brief 获取密钥列表
*
* @param hDevice [in] 已打开的设备句柄
* @param alg [in] 密钥列表的算法
* @param info [out] 密钥信息,传NULL时通过len返回需要的缓冲区大小
* @param len [in|out] 输入时标识info缓冲区大小
* 输出时标识info实际长度
* 密钥数量可通过计算“len / sizeof(TassKeyInfo)”获取
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlListKey(void* hDevice,
TassAlg alg,
TassKeyInfo* info, int* len);
/**
* @brief 生成密钥
*
* @param hDevice [in] 已打开的设备句柄
* @param alg [in] 密钥类型
* @param keyBits [in] 模长,
* 密钥类型为 2-SM2、3-ECC_256R1、8-ECC_256K1时,模长只支持256
* 密钥类型为 4-RSA时,模长只支持2048
* 密钥类型为 9-HMAC时,支持模长是128、256、384、512bit,
* 类型为0-SM4、1-SM1、5-AES、6-DES、7-SM7时,仅模长仅支持128
* @param index [in] 密钥索引,为0时根据标签存储密钥,为-1时不存储
* @param label [in] 密钥标签
* @param pwd [in] 私钥口令,当前未启用
* type为非对称密钥时有效
* @param sk_key [out] 私钥密文或对称密钥密文,传NULL时通过sk_keyLen返回需要的缓冲区大小
* @param sk_keyLen [in|out] 输入时标识sk_key缓冲区大小
* 输出时标识sk_key实际长度
* @param pk_kcv [out] 公钥,传NULL时通过pk_kcvLen返回需要的缓冲区大小
* @param pk_kcvLen [in|out] 输入时标识pk_kcv缓冲区大小
* 输出时标识pk_kcv实际长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlGenerateKey(void* hDevice,
TassAlg alg,
unsigned int keyBits,
unsigned int index,
const char* label,
const char* pwd,
unsigned char* sk_key, unsigned int* sk_keyLen,
unsigned char* pk_kcv, unsigned int* pk_kcvLen);
/**
* @brief 导入明文密钥
*
* @param hDevice [in] 已打开的设备句柄
* @param alg [in] 导入的密钥算法,暂时仅支持TA_ALG_SM2和TA_ALG_SM4
* @param index [in] 导入的密钥索引,为0时根据标签存储密钥,为-1时不存储
* @param label [in] 导入的密钥标签
* @param pwd [in] 私钥口令,当前未启用
* type为非对称密钥时有效
* @param sk_key [in] 私钥或对称密钥明文
* @param sk_keyLen [in] sk_key长度
* @param pk_kcv [in] 公钥
* type为非对称密钥时有效
* @param pk_kcvLen [in] 公钥长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlImportPlainKey(void* hDevice,
TassAlg alg,
unsigned int index,
const char* label,
const char* pwd,
const unsigned char* sk_key, unsigned int sk_keyLen,
const unsigned char* pk_kcv, unsigned int pk_kcvLen);
/**
* @brief 通过sm2密钥保护导出非对称密钥
*
* @param hDevice [in] 已打开的设备句柄
* @param sm2Pk [in] SM2保护公钥
* @param exportedKeyAlg [in] 待导出的密钥算法,支持SM2/ECC_SECP_256R1/RSA/ECC_SECP_256K1
* @param exportedKeyIndex [in] 待导出的密钥索引
* @param devPwdHashCipher [in] 设备管理员口令的哈希值密文
* @param symmKeyCipher [out]随机对称密钥密文
* @param symmKeyCipherkLen [out]随机对称密钥密文长度
* @param exportedPk [out] 待导出的公钥
* @param exportedPkLen [out] 待导出的公钥长度
* @param exportedKeyCipherByPk [out] SM2公钥加密的待导出私钥密钥密文
* @param exportedKeyCipherByPkLen [out] SM2公钥加密的待导出私钥密钥密文长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlExportKey(void* hDevice,
const unsigned char sm2Pk[64],
TassAlg exportedKeyAlg,
unsigned int exportedKeyIndex,
const unsigned char devPwdHashCipher[128],
unsigned char* symmKeyCipher,
unsigned int* symmKeyCipherLen,
unsigned char* exportedPk,
unsigned int* exportedPkLen,
unsigned char* exportedKeyCipherByPk,
unsigned int* exportedKeyCipherByPkLen);
/**
* @brief 通过sm2密钥保护导入非对称密钥
*
* @param hDevice [in] 已打开的设备句柄
* @param sm2Sk [in] SM2私钥
* @param importedKeyAlg [in] 待导入的密钥算法,支持SM2/ECC_SECP_256R1/RSA/ECC_SECP_256K1
* @param importedKeyIndex [in] 待导入的密钥索引
* @param importedKeyLabel [in] 待导入的密钥标签
* @param importedKeyLabelLen [in] 待导入的密钥标签长度
* @param symmKeyCipher [in] 随机对称密钥密文
* @param symmKeyCipherkLen [in] 随机对称密钥密文长度
* @param importedPk [in] 待导入的公钥
* @param importedPkLen [in] 待导入的公钥长度
* @param importedKeyCipherByPk [in] SM2公钥加密的待导入私钥密钥密文
* @param importedKeyCipherByPkLen [in] SM2公钥加密的待导入私钥密钥密文长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlImportKey(void* hDevice,
const unsigned char sm2Sk[32],
TassAlg importedKeyAlg,
unsigned int importedKeyIndex,
const unsigned char* importedKeyLabel,
unsigned int importedKeyLabelLen,
unsigned char* symmKeyCipher,
unsigned int symmKeyCipherLen,
const unsigned char* importedPk,
unsigned int importedPkLen,
const unsigned char* importedKeyCipherByPk,
unsigned int importedKeyCipherByPkLen);
/**
* @brief 删除密钥
*
* @param hDevice [in] 已打开的设备句柄
* @param alg [in] 密钥算法
* @param index [in] 密钥索引
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlDestroyKey(void* hDevice,
TassAlg alg,
unsigned int index);
/**
* @brief 修改私钥权限口令
*
* @param hDevice [in] 已打开的设备句柄
* @param alg [in] 密钥算法,只支持非对称密钥
* @param index [in] 密钥索引
* @param privateKeyPwd [in] 私钥口令
* @param privateKeyPwdLen [in] 私钥口令长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
*/
int TassCtlChangePrivateKeyAccessRight(void* hDevice,
TassAlg alg, unsigned int index,
const unsigned char* privateKeyPwd,
unsigned int privateKeyPwdLen);
/**
* @brief 备份,包括设备信息、密钥和FLASH索引信息
*
* @param hDevice [in] 已打开的设备句柄
* @param keyPwdHashCipher [in] 密钥管理员口令的哈希值密文
* @param devPwdHashCipher [in] 设备管理员口令的哈希值密文
* @param info [out] 备份信息,传NULL时通过infoLen返回需要的缓冲区大小
* @param infoLen [in|out] 输入时标识info缓冲区大小
* 输出时标识info实际长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录密钥管理员,同时需要设备管理员口令进行授权
*
*/
int TassCtlBackup(void* hDevice,
const unsigned char keyPwdHashCipher[128],
const unsigned char devPwdHashCipher[128],
unsigned char* info, unsigned int* infoLen);
/**
* @brief 恢复设备信息
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
* @param info [in] 备份的设备信息
* @param infoLen [in] info长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlRecover(void* hDevice,
const unsigned char pwdHashCipher[128],
const unsigned char* info, unsigned int infoLen);
/**
* @brief 校验备份数据信息的有效性
*
* @param hDevice [in] 已打开的设备句柄
* @param pwdHashCipher [in] 设备管理员口令的哈希值密文
* @param info [in] 备份的设备信息
* @param infoLen [in] info长度
*
* @return
* @retval 0 成功
* @retval other 失败
*
* @note 须先登录设备管理员
*
*/
int TassCtlCheckBackupInfoValid(void* hDevice,
const unsigned char pwdHashCipher[128],
const unsigned char* info, unsigned int infoLen);
#ifdef __cplusplus
}
#endif
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define TA_DEVICE_ID_SIZE 16
typedef enum {
TA_DEV_STATE_INIT = 0x0, //初始状态,无密钥
TA_DEV_STATE_WORK = 0x1, //工作状态
TA_DEV_STATE_MNG = 0x2, //管理状态
}TassDevState;
typedef enum {
TA_BOOL_FALSE = 0, //私钥
TA_BOOL_TRUE = !TA_BOOL_FALSE, //公钥
}TassBool;
typedef enum {
TA_DEV_KEY_PLATFORM = 0, //管理平台密钥(公钥)
TA_DEV_KEY_SIGN = 1, //设备签名密钥
TA_DEV_KEY_ENC = 2, //设备加密密钥
TA_DEV_KEY_KEK = 3, //设备KEK
}TassDevKeyType;
typedef enum {
TA_ALG_SM4 = 0,
TA_ALG_SM1 = 1,
TA_ALG_AES = 5,
TA_ALG_DES = 6,
TA_ALG_SM7 = 7,
TA_ALG_SM2 = 2,
TA_ALG_ECC_SECP_256R1 = 3,
TA_ALG_ECC_SECP_256K1 = 8,
TA_ALG_RSA = 4,
TA_ALG_HMAC = 9,
}TassAlg;
typedef enum {
TA_RSA_E_3 = 3,
TA_RSA_E_65537 = 65537,
}TassRSA_E;
typedef enum {
TA_SYMM_ECB_ENC = 0x00000000,
TA_SYMM_ECB_DEC = 0x00000001,
TA_SYMM_CBC_ENC = 0x00000100,
TA_SYMM_CBC_DEC = 0x10000101,
TA_SYMM_CFB_ENC = 0x00000200,
TA_SYMM_CFB_DEC = 0x10000201,
TA_SYMM_OFB_ENC = 0x00000300,
TA_SYMM_OFB_DEC = 0x10000301,
TA_SYMM_MAC = 0x00000400,
}TassSymmOp;
typedef enum {
TA_SM2_KEY_EXCHANGE_SPONSOR = 0,
TA_SM2_KEY_EXCHANGE_RESPONSE = 1,
}TassSM2KeyExchangeRole;
typedef enum {
TA_ASYM_SIGN = 0,
TA_ASYM_ENC = 1,
TA_ASYM_KEY_EX = 2,
}TassAsymKeyUsage;
typedef enum {
TA_ASYM_ENCRYPT = 0,
TA_ASYM_DECRYPT = 1,
}TassSymmKeyUsage;
typedef enum {
TA_FLASH_2K = 0,
TA_FLASH_32K = 1,
}TassFlashFlag;
typedef enum {
TA_FLASH_GET_SIZE = 0,
TA_FLASH_READ = 1,
TA_FLASH_WRITE = 2,
TA_FLASH_ERASE = 3,
}TassFlashOp;
typedef struct {
unsigned char sigHead[16]; //签名数据头
unsigned char hwVer[4]; //硬件版本
unsigned char fpgaVer[4]; //FPGA版本
unsigned char keyMngChipVer[4]; //密管芯片版本
unsigned char devId[16]; //设备唯一标识,不可指定
unsigned char devSn[4]; //设备序列号,可指定
unsigned char fpgaHwCv[32]; //FPGA固件校验值
unsigned char devSignKeyPairInfo[4]; //设备签名密钥对信息
unsigned char platformPkInfo[4]; //管理平台公钥信息
unsigned char devEncKeyPairInfo[4]; //设备加密密钥对信息
unsigned char devKEKInfo[4]; //设备本地保护密钥信息
unsigned char kekCv[16]; //设备本地保护密钥校验值
unsigned char adminPkAblity[4]; //管理员公钥存储能力,大端格式
unsigned char curAdminPkNum[4]; //当前管理员公钥个数,大端格式
unsigned char adminPkInfo[5][4]; //管理员公钥信息5 * 4Bytes= 20Bytes
unsigned char devState[4]; //设备状态,大端格式
unsigned char temp[8]; //温度
unsigned char valtage[8]; //电压
unsigned char current[8]; //电流
unsigned char selfCheckCycle[4]; //自检周期,大端格式
unsigned char lastSelfCheckInfo[8]; //上次自检信息
unsigned char channelNum[4]; //通道总数,大端格式
unsigned char channelAlg[256]; //通道算法
unsigned char sig[64]; //设备签名公钥对上述数据的签名
}TassDevInfo;
/**
* @brief 签名回调函数,用于需要私钥签名的接口调用
*
* @param data [in] 待签名数据
* @param dataLen [in] data长度
* @param sig [out] 签名值
*
* @return 成功返回0,失败返回非0
*
*/
typedef int (*TassSignCb)(const unsigned char* data, int len, unsigned char sig[64]);
#ifdef __cplusplus
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment