mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 08:56:17 +08:00
2338 lines
48 KiB
C
Executable File
2338 lines
48 KiB
C
Executable File
/*
|
||
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||
* not use this file except in compliance with the License.
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*/
|
||
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <gmssl/sm2.h>
|
||
#include <gmssl/sm3.h>
|
||
#include <gmssl/sm4_cbc_mac.h>
|
||
#include <gmssl/rand.h>
|
||
#include <gmssl/error.h>
|
||
#include "../sgd.h"
|
||
#include "sdf.h"
|
||
|
||
#define SDR_GMSSLERR (SDR_BASE + 0x00000100)
|
||
|
||
|
||
|
||
#define SOFTSDF_MAX_KEY_SIZE 64
|
||
|
||
struct SOFTSDF_KEY {
|
||
uint8_t key[SOFTSDF_MAX_KEY_SIZE];
|
||
size_t key_size;
|
||
struct SOFTSDF_KEY *next;
|
||
};
|
||
|
||
typedef struct SOFTSDF_KEY SOFTSDF_KEY;
|
||
|
||
|
||
struct SOFTSDF_CONTAINER {
|
||
unsigned int key_index;
|
||
SM2_KEY sign_key;
|
||
SM2_KEY enc_key;
|
||
struct SOFTSDF_CONTAINER *next;
|
||
};
|
||
typedef struct SOFTSDF_CONTAINER SOFTSDF_CONTAINER;
|
||
|
||
struct SOFTSDF_SESSION {
|
||
SOFTSDF_CONTAINER *container_list;
|
||
SOFTSDF_KEY *key_list;
|
||
SM3_CTX sm3_ctx;
|
||
struct SOFTSDF_SESSION *next;
|
||
};
|
||
typedef struct SOFTSDF_SESSION SOFTSDF_SESSION;
|
||
|
||
struct SOFTSDF_DEVICE {
|
||
SOFTSDF_SESSION *session_list;
|
||
};
|
||
typedef struct SOFTSDF_DEVICE SOFTSDF_DEVICE;
|
||
|
||
SOFTSDF_DEVICE *deviceHandle = NULL;
|
||
|
||
|
||
|
||
#define FILENAME_MAX_LEN 256
|
||
|
||
|
||
|
||
int SDF_OpenDevice(
|
||
void **phDeviceHandle)
|
||
{
|
||
if (phDeviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (deviceHandle != NULL) {
|
||
error_print();
|
||
return SDR_OPENDEVICE;
|
||
}
|
||
|
||
deviceHandle = (SOFTSDF_DEVICE *)malloc(sizeof(SOFTSDF_DEVICE));
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_OPENDEVICE;
|
||
}
|
||
memset(deviceHandle, 0, sizeof(SOFTSDF_DEVICE));
|
||
|
||
*phDeviceHandle = deviceHandle;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_CloseDevice(
|
||
void *hDeviceHandle)
|
||
{
|
||
if (hDeviceHandle != deviceHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (deviceHandle != NULL) {
|
||
while (deviceHandle->session_list) {
|
||
if (SDF_CloseSession(deviceHandle->session_list) != SDR_OK) {
|
||
error_print();
|
||
}
|
||
}
|
||
}
|
||
|
||
memset(deviceHandle, 0, sizeof(SOFTSDF_DEVICE));
|
||
free(deviceHandle);
|
||
deviceHandle = NULL;
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
|
||
int SDF_OpenSession(
|
||
void *hDeviceHandle,
|
||
void **phSessionHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
|
||
if (hDeviceHandle == NULL || hDeviceHandle != deviceHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (phSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (!(session = (SOFTSDF_SESSION *)malloc(sizeof(*session)))) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(session, 0, sizeof(*session));
|
||
|
||
// append session to session_list
|
||
if (deviceHandle->session_list == NULL) {
|
||
deviceHandle->session_list = session;
|
||
} else {
|
||
SOFTSDF_SESSION *current = deviceHandle->session_list;
|
||
while (current->next != NULL) {
|
||
current = current->next;
|
||
}
|
||
current->next = session;
|
||
}
|
||
|
||
*phSessionHandle = session;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_CloseSession(
|
||
void *hSessionHandle)
|
||
{
|
||
SOFTSDF_SESSION *current_session;
|
||
SOFTSDF_SESSION *next_session;
|
||
SOFTSDF_SESSION *prev_session;
|
||
SOFTSDF_CONTAINER *current_container;
|
||
SOFTSDF_CONTAINER *next_container;
|
||
SOFTSDF_KEY *current_key;
|
||
SOFTSDF_KEY *next_key;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// find hSessionHandle in session_list
|
||
current_session = deviceHandle->session_list;
|
||
prev_session = NULL;
|
||
while (current_session != NULL && current_session != hSessionHandle) {
|
||
prev_session = current_session;
|
||
current_session = current_session->next;
|
||
}
|
||
if (current_session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// free container_list
|
||
current_container = current_session->container_list;
|
||
while (current_container != NULL) {
|
||
next_container = current_container->next;
|
||
memset(current_container, 0, sizeof(*current_container));
|
||
free(current_container);
|
||
current_container = next_container;
|
||
}
|
||
|
||
// free key_list
|
||
current_key = current_session->key_list;
|
||
while (current_key != NULL) {
|
||
next_key = current_key->next;
|
||
memset(current_key, 0, sizeof(*current_key));
|
||
free(current_key);
|
||
current_key = next_key;
|
||
}
|
||
|
||
// delete current_session from session_list
|
||
if (prev_session == NULL) {
|
||
deviceHandle->session_list = current_session->next;
|
||
} else {
|
||
prev_session->next = current_session->next;
|
||
}
|
||
memset(current_session, 0, sizeof(*current_session));
|
||
free(current_session);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
#define SOFTSDF_DEV_DATE "20231227"
|
||
#define SOFTSDF_DEV_BATCH_NUM "001"
|
||
#define SOFTSDF_DEV_SERIAL_NUM "00123"
|
||
#define SOFTSDF_DEV_SERIAL SOFTSDF_DEV_DATE \
|
||
SOFTSDF_DEV_BATCH_NUM \
|
||
SOFTSDF_DEV_SERIAL_NUM
|
||
|
||
int SDF_GetDeviceInfo(
|
||
void *hSessionHandle,
|
||
DEVICEINFO *pstDeviceInfo)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pstDeviceInfo == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo));
|
||
strncpy((char *)pstDeviceInfo->IssuerName, "GmSSL Project (http://gmssl.org)",
|
||
sizeof(pstDeviceInfo->IssuerName));
|
||
strncpy((char *)pstDeviceInfo->DeviceName, "Soft SDF",
|
||
sizeof(pstDeviceInfo->DeviceName));
|
||
strncpy((char *)pstDeviceInfo->DeviceSerial, SOFTSDF_DEV_SERIAL,
|
||
sizeof(pstDeviceInfo->DeviceSerial));
|
||
pstDeviceInfo->DeviceVersion = 1;
|
||
pstDeviceInfo->StandardVersion = 1;
|
||
pstDeviceInfo->AsymAlgAbility[0] = SGD_SM2_1|SGD_SM2_3;
|
||
pstDeviceInfo->AsymAlgAbility[1] = 256;
|
||
pstDeviceInfo->SymAlgAbility = SGD_SM4|SGD_CBC|SGD_MAC;
|
||
pstDeviceInfo->HashAlgAbility = SGD_SM3;
|
||
pstDeviceInfo->BufferSize = 256*1024;
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_GenerateRandom(
|
||
void *hSessionHandle,
|
||
unsigned int uiLength,
|
||
unsigned char *pucRandom)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucRandom == NULL || uiLength == 0) {
|
||
error_puts("Invalid output buffer or length");
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiLength > RAND_BYTES_MAX_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (rand_bytes(pucRandom, uiLength) != 1) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_GetPrivateKeyAccessRight(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
unsigned char *pucPassword,
|
||
unsigned int uiPwdLength)
|
||
{
|
||
int ret = SDR_OK;
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container = NULL;
|
||
char *pass = NULL;
|
||
char filename[FILENAME_MAX_LEN];
|
||
FILE *file = NULL;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPassword == NULL || uiPwdLength == 0) {
|
||
error_puts("Invalid password or password length");
|
||
return SDR_INARGERR;
|
||
}
|
||
pass = (char *)malloc(uiPwdLength + 1);
|
||
if (pass == NULL) {
|
||
error_print();
|
||
return SDR_NOBUFFER;
|
||
}
|
||
memcpy(pass, pucPassword, uiPwdLength);
|
||
pass[uiPwdLength] = 0;
|
||
if (strlen(pass) != uiPwdLength) {
|
||
error_print();
|
||
ret = SDR_INARGERR;
|
||
goto end;
|
||
}
|
||
|
||
// create container
|
||
container = (SOFTSDF_CONTAINER *)malloc(sizeof(*container));
|
||
if (container == NULL) {
|
||
error_print();
|
||
ret = SDR_NOBUFFER;
|
||
goto end;
|
||
}
|
||
memset(container, 0, sizeof(*container));
|
||
container->key_index = uiKeyIndex;
|
||
|
||
// load sign_key
|
||
snprintf(filename, FILENAME_MAX_LEN, "sm2sign-%u.pem", uiKeyIndex);
|
||
file = fopen(filename, "r");
|
||
if (file == NULL) {
|
||
error_print();
|
||
perror("Error opening file");
|
||
fprintf(stderr, "open failure %s\n", filename);
|
||
ret = SDR_KEYNOTEXIST;
|
||
goto end;
|
||
}
|
||
if (sm2_private_key_info_decrypt_from_pem(&container->sign_key, pass, file) != 1) {
|
||
error_print();
|
||
ret = SDR_GMSSLERR;
|
||
goto end;
|
||
}
|
||
fclose(file);
|
||
|
||
// load enc_key
|
||
snprintf(filename, FILENAME_MAX_LEN, "sm2enc-%u.pem", uiKeyIndex);
|
||
file = fopen(filename, "r");
|
||
if (file == NULL) {
|
||
perror("Error opening file");
|
||
ret = SDR_KEYNOTEXIST;
|
||
goto end;
|
||
}
|
||
if (sm2_private_key_info_decrypt_from_pem(&container->enc_key, pass, file) != 1) {
|
||
error_print();
|
||
ret = SDR_GMSSLERR;
|
||
goto end;
|
||
}
|
||
|
||
// append container to container_list
|
||
if (session->container_list == NULL) {
|
||
session->container_list = container;
|
||
} else {
|
||
SOFTSDF_CONTAINER *current = session->container_list;
|
||
while (current->next != NULL) {
|
||
current = current->next;
|
||
}
|
||
current->next = container;
|
||
}
|
||
|
||
container = NULL;
|
||
ret = SDR_OK;
|
||
end:
|
||
if (container) {
|
||
memset(container, 0, sizeof(*container));
|
||
free(container);
|
||
}
|
||
if (pass) {
|
||
memset(pass, 0, uiPwdLength);
|
||
free(pass);
|
||
}
|
||
if (file) fclose(file);
|
||
return ret;
|
||
}
|
||
|
||
int SDF_ReleasePrivateKeyAccessRight(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *current_container;
|
||
SOFTSDF_CONTAINER *prev_container;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// delete container in container_list with uiKeyIndex
|
||
current_container = session->container_list;
|
||
prev_container = NULL;
|
||
while (current_container != NULL && current_container->key_index != uiKeyIndex) {
|
||
prev_container = current_container;
|
||
current_container = current_container->next;
|
||
}
|
||
if (current_container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (prev_container == NULL) {
|
||
session->container_list = current_container->next;
|
||
} else {
|
||
prev_container->next = current_container->next;
|
||
}
|
||
memset(current_container, 0, sizeof(*current_container));
|
||
free(current_container);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ExportSignPublicKey_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
RSArefPublicKey *pucPublicKey)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_ExportEncPublicKey_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
RSArefPublicKey *pucPublicKey)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_GenerateKeyPair_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyBits,
|
||
RSArefPublicKey *pucPublicKey,
|
||
RSArefPrivateKey *pucPrivateKey)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_GenerateKeyWithIPK_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiIPKIndex,
|
||
unsigned int uiKeyBits,
|
||
unsigned char *pucKey,
|
||
unsigned int *puiKeyLength,
|
||
void **phKeyHandle)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_GenerateKeyWithEPK_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyBits,
|
||
RSArefPublicKey *pucPublicKey,
|
||
unsigned char *pucKey,
|
||
unsigned int *puiKeyLength,
|
||
void **phKeyHandle)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_ImportKeyWithISK_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiISKIndex,
|
||
unsigned char *pucKey,
|
||
unsigned int uiKeyLength,
|
||
void **phKeyHandle)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_ExchangeDigitEnvelopeBaseOnRSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
RSArefPublicKey *pucPublicKey,
|
||
unsigned char *pucDEInput,
|
||
unsigned int uiDELength,
|
||
unsigned char *pucDEOutput,
|
||
unsigned int *puiDELength)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
|
||
int SDF_ExportSignPublicKey_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
ECCrefPublicKey *pucPublicKey)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
container = session->container_list;
|
||
while (container != NULL && container->key_index != uiKeyIndex) {
|
||
container = container->next;
|
||
}
|
||
if (container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
memset(pucPublicKey, 0, sizeof(*pucPublicKey));
|
||
pucPublicKey->bits = 256;
|
||
memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, container->sign_key.public_key.x, 32);
|
||
memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, container->sign_key.public_key.y, 32);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ExportEncPublicKey_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
ECCrefPublicKey *pucPublicKey)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
container = session->container_list;
|
||
while (container != NULL && container->key_index != uiKeyIndex) {
|
||
container = container->next;
|
||
}
|
||
if (container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
memset(pucPublicKey, 0, sizeof(*pucPublicKey));
|
||
pucPublicKey->bits = 256;
|
||
memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, container->enc_key.public_key.x, 32);
|
||
memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, container->enc_key.public_key.y, 32);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_GenerateKeyPair_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiAlgID,
|
||
unsigned int uiKeyBits,
|
||
ECCrefPublicKey *pucPublicKey,
|
||
ECCrefPrivateKey *pucPrivateKey)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SM2_KEY sm2_key;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM2_1 && uiAlgID != SGD_SM2_3) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiKeyBits != 256) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey == NULL || pucPrivateKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (sm2_key_generate(&sm2_key) != 1) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
memset(pucPublicKey, 0, sizeof(*pucPublicKey));
|
||
pucPublicKey->bits = 256;
|
||
memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, sm2_key.public_key.x, 32);
|
||
memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, sm2_key.public_key.y, 32);
|
||
|
||
memset(pucPrivateKey, 0, sizeof(*pucPrivateKey));
|
||
pucPrivateKey->bits = 256;
|
||
memcpy(pucPrivateKey->K + ECCref_MAX_LEN - 32, sm2_key.private_key, 32);
|
||
|
||
memset(&sm2_key, 0, sizeof(sm2_key));
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_GenerateKeyWithIPK_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiIPKIndex,
|
||
unsigned int uiKeyBits,
|
||
ECCCipher *pucKey,
|
||
void **phKeyHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container;
|
||
SOFTSDF_KEY *key;
|
||
SM2_CIPHERTEXT ctxt;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
container = session->container_list;
|
||
while (container != NULL && container->key_index != uiIPKIndex) {
|
||
container = container->next;
|
||
}
|
||
if (container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiKeyBits%8 != 0 || uiKeyBits/8 > SOFTSDF_MAX_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (phKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// generate key
|
||
key = (SOFTSDF_KEY *)malloc(sizeof(*key));
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_NOBUFFER;
|
||
}
|
||
memset(key, 0, sizeof(*key));
|
||
if (rand_bytes(key->key, uiKeyBits/8) != 1) {
|
||
error_print();
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
key->key_size = uiKeyBits/8;
|
||
|
||
// encrypt key with container
|
||
if (sm2_do_encrypt(&container->enc_key, key->key, key->key_size, &ctxt) != 1) {
|
||
error_print();
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(pucKey, 0, sizeof(*pucKey));
|
||
memcpy(pucKey->x + ECCref_MAX_LEN - 32, ctxt.point.x, 32);
|
||
memcpy(pucKey->y + ECCref_MAX_LEN - 32, ctxt.point.y, 32);
|
||
memcpy(pucKey->M, ctxt.hash, 32);
|
||
pucKey->L = ctxt.ciphertext_size;
|
||
memcpy(pucKey->C, ctxt.ciphertext, ctxt.ciphertext_size);
|
||
|
||
// append key to key_list
|
||
if (session->key_list == NULL) {
|
||
session->key_list = key;
|
||
} else {
|
||
SOFTSDF_KEY *current = session->key_list;
|
||
while (current->next != NULL) {
|
||
current = current->next;
|
||
}
|
||
current->next = key;
|
||
}
|
||
|
||
*phKeyHandle = key;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_GenerateKeyWithEPK_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyBits,
|
||
unsigned int uiAlgID,
|
||
ECCrefPublicKey *pucPublicKey,
|
||
ECCCipher *pucKey,
|
||
void **phKeyHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SM2_KEY sm2_key;
|
||
SOFTSDF_KEY *key;
|
||
SM2_CIPHERTEXT ctxt;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiKeyBits%8 != 0 || uiKeyBits/8 > SOFTSDF_MAX_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM2_3) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey == NULL || pucKey == NULL || phKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// load public key
|
||
memset(&sm2_key, 0, sizeof(sm2_key));
|
||
memcpy(sm2_key.public_key.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(sm2_key.public_key.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);
|
||
if (sm2_point_is_on_curve(&sm2_key.public_key) != 1) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// generate key
|
||
key = (SOFTSDF_KEY *)malloc(sizeof(*key));
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_NOBUFFER;
|
||
}
|
||
memset(key, 0, sizeof(*key));
|
||
if (rand_bytes(key->key, uiKeyBits/8) != 1) {
|
||
error_print();
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
key->key_size = uiKeyBits/8;
|
||
|
||
// encrypt key with external public key
|
||
if (sm2_do_encrypt(&sm2_key, key->key, key->key_size, &ctxt) != 1) {
|
||
error_print();
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(pucKey, 0, sizeof(*pucKey));
|
||
memcpy(pucKey->x + ECCref_MAX_LEN - 32, ctxt.point.x, 32);
|
||
memcpy(pucKey->y + ECCref_MAX_LEN - 32, ctxt.point.y, 32);
|
||
memcpy(pucKey->M, ctxt.hash, 32);
|
||
pucKey->L = ctxt.ciphertext_size;
|
||
memcpy(pucKey->C, ctxt.ciphertext, ctxt.ciphertext_size);
|
||
|
||
*phKeyHandle = key;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ImportKeyWithISK_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiISKIndex,
|
||
ECCCipher *pucKey,
|
||
void **phKeyHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container;
|
||
SM2_CIPHERTEXT ctxt;
|
||
SOFTSDF_KEY *key;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_puts("Invalid session handle");
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
container = session->container_list;
|
||
while (container != NULL && container->key_index != uiISKIndex) {
|
||
container = container->next;
|
||
}
|
||
if (container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (pucKey->L > SM2_MAX_PLAINTEXT_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (pucKey->L > SOFTSDF_MAX_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (phKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// create key
|
||
key = (SOFTSDF_KEY *)malloc(sizeof(*key));
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_NOBUFFER;
|
||
}
|
||
memset(key, 0, sizeof(*key));
|
||
|
||
// decrypt key
|
||
memset(&ctxt, 0, sizeof(ctxt));
|
||
memcpy(ctxt.point.x, pucKey->x + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(ctxt.point.y, pucKey->y + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(ctxt.hash, pucKey->M, 32);
|
||
memcpy(ctxt.ciphertext, pucKey->C, pucKey->L);
|
||
ctxt.ciphertext_size = pucKey->L;
|
||
|
||
if (sm2_do_decrypt(&container->enc_key, &ctxt, key->key, &key->key_size) != 1) {
|
||
error_print();
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
// append key to key_list
|
||
if (session->key_list == NULL) {
|
||
session->key_list = key;
|
||
} else {
|
||
SOFTSDF_KEY *current = session->key_list;
|
||
while (current->next != NULL) {
|
||
current = current->next;
|
||
}
|
||
current->next = key;
|
||
}
|
||
|
||
*phKeyHandle = key;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_GenerateAgreementDataWithECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiISKIndex,
|
||
unsigned int uiKeyBits,
|
||
unsigned char *pucSponsorID,
|
||
unsigned int uiSponsorIDLength,
|
||
ECCrefPublicKey *pucSponsorPublicKey,
|
||
ECCrefPublicKey *pucSponsorTmpPublicKey,
|
||
void **phAgreementHandle)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_GenerateKeyWithECC(
|
||
void *hSessionHandle,
|
||
unsigned char *pucResponseID,
|
||
unsigned int uiResponseIDLength,
|
||
ECCrefPublicKey *pucResponsePublicKey,
|
||
ECCrefPublicKey *pucResponseTmpPublicKey,
|
||
void *hAgreementHandle,
|
||
void **phKeyHandle)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
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)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_ExchangeDigitEnvelopeBaseOnECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
unsigned int uiAlgID,
|
||
ECCrefPublicKey *pucPublicKey,
|
||
ECCCipher *pucEncDataIn,
|
||
ECCCipher *pucEncDataOut)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_GenerateKeyWithKEK(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyBits,
|
||
unsigned int uiAlgID, // SGD_SM4_CBC, 用于加密生成的密钥
|
||
unsigned int uiKEKIndex, // 这是一个本地文件
|
||
unsigned char *pucKey, // CBC秘闻
|
||
unsigned int *puiKeyLength,
|
||
void **phKeyHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
char filename[FILENAME_MAX_LEN];
|
||
FILE *file;
|
||
uint8_t kek[16];
|
||
SM4_KEY sm4_key;
|
||
uint8_t *iv;
|
||
uint8_t *enced;
|
||
size_t enced_len;
|
||
SOFTSDF_KEY *key;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiKeyBits % 8 != 0 || uiKeyBits/8 > SOFTSDF_MAX_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM4_CBC) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// load KEK file with index
|
||
snprintf(filename, FILENAME_MAX_LEN, "kek-%u.key", uiKEKIndex);
|
||
file = fopen(filename, "rb");
|
||
if (file == NULL) {
|
||
error_print();
|
||
return SDR_KEYNOTEXIST;
|
||
}
|
||
if (fread(kek, 1, sizeof(kek), file) != sizeof(kek)) {
|
||
error_print();
|
||
fclose(file);
|
||
return SDR_INARGERR;
|
||
}
|
||
fclose(file);
|
||
|
||
if (pucKey == NULL || puiKeyLength == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (phKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// generate key
|
||
key = (SOFTSDF_KEY *)malloc(sizeof(SOFTSDF_KEY));
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(key, 0, sizeof(*key));
|
||
|
||
iv = pucKey;
|
||
enced = pucKey + SM4_BLOCK_SIZE;
|
||
|
||
if (rand_bytes(iv, SM4_BLOCK_SIZE) != 1) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
key->key_size = uiKeyBits/8;
|
||
if (rand_bytes(key->key, key->key_size) != 1) {
|
||
error_print();
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
sm4_set_encrypt_key(&sm4_key, kek);
|
||
if (sm4_cbc_padding_encrypt(&sm4_key, iv, key->key, key->key_size, enced, &enced_len) != 1) {
|
||
error_print();
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
*puiKeyLength = enced_len;
|
||
|
||
// append key to key_list
|
||
if (session->key_list == NULL) {
|
||
session->key_list = key;
|
||
} else {
|
||
SOFTSDF_KEY *current = session->key_list;
|
||
while (current->next != NULL) {
|
||
current = current->next;
|
||
}
|
||
current->next = key;
|
||
}
|
||
|
||
*phKeyHandle = key;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ImportKeyWithKEK(
|
||
void *hSessionHandle,
|
||
unsigned int uiAlgID, // 这是对称加密算法,应该使用什么算法呢?实际上我们整个只支持一个带填充的SM4_CBC
|
||
unsigned int uiKEKIndex,
|
||
unsigned char *pucKey,
|
||
unsigned int uiKeyLength,
|
||
void **phKeyHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
char filename[FILENAME_MAX_LEN];
|
||
FILE *file;
|
||
uint8_t kek[16];
|
||
SM4_KEY sm4_key;
|
||
const uint8_t *iv;
|
||
const uint8_t *enced;
|
||
size_t enced_len;
|
||
SOFTSDF_KEY *key;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM4_CBC) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// load KEK file with index
|
||
snprintf(filename, FILENAME_MAX_LEN, "kek-%u.key", uiKEKIndex);
|
||
file = fopen(filename, "rb");
|
||
if (file == NULL) {
|
||
error_print();
|
||
return SDR_KEYNOTEXIST;
|
||
}
|
||
if (fread(kek, 1, sizeof(kek), file) != sizeof(kek)) {
|
||
error_print();
|
||
fclose(file);
|
||
return SDR_INARGERR;
|
||
}
|
||
fclose(file);
|
||
|
||
|
||
// decrypt SM4-CBC encrypted pucKey
|
||
if (pucKey == NULL || uiKeyLength <= SM4_BLOCK_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiKeyLength > SM4_BLOCK_SIZE + SOFTSDF_MAX_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
key = (SOFTSDF_KEY *)malloc(sizeof(SOFTSDF_KEY));
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(key, 0, sizeof(*key));
|
||
|
||
iv = pucKey;
|
||
enced = pucKey + SM4_BLOCK_SIZE;
|
||
enced_len = uiKeyLength - SM4_BLOCK_SIZE;
|
||
|
||
sm4_set_decrypt_key(&sm4_key, kek);
|
||
if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced, enced_len, key->key, &key->key_size) != 1) {
|
||
error_print();
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
free(key);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
|
||
// append key to key_list
|
||
if (session->key_list == NULL) {
|
||
session->key_list = key;
|
||
} else {
|
||
SOFTSDF_KEY *current = session->key_list;
|
||
while (current->next != NULL) {
|
||
current = current->next;
|
||
}
|
||
current->next = key;
|
||
}
|
||
|
||
*phKeyHandle = key;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_DestroyKey(
|
||
void *hSessionHandle,
|
||
void *hKeyHandle)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_KEY *current;
|
||
SOFTSDF_KEY *prev;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (hKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
current = session->key_list;
|
||
prev = NULL;
|
||
while (current != NULL && current != (SOFTSDF_KEY *)hKeyHandle) {
|
||
prev = current;
|
||
current = current->next;
|
||
}
|
||
if (current == NULL) {
|
||
error_print();
|
||
return SDR_KEYNOTEXIST;
|
||
}
|
||
if (prev == NULL) {
|
||
session->key_list = current->next;
|
||
} else {
|
||
prev->next = current->next;
|
||
}
|
||
memset(current, 0, sizeof(SOFTSDF_KEY));
|
||
free(current);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ExternalPublicKeyOperation_RSA(
|
||
void *hSessionHandle,
|
||
RSArefPublicKey *pucPublicKey,
|
||
unsigned char *pucDataInput,
|
||
unsigned int uiInputLength,
|
||
unsigned char *pucDataOutput,
|
||
unsigned int *puiOutputLength)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_ExternalPrivateKeyOperation_RSA(
|
||
void *hSessionHandle,
|
||
RSArefPrivateKey *pucPrivateKey,
|
||
unsigned char *pucDataInput,
|
||
unsigned int uiInputLength,
|
||
unsigned char *pucDataOutput,
|
||
unsigned int *puiOutputLength)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_InternalPrivateKeyOperation_RSA(
|
||
void *hSessionHandle,
|
||
unsigned int uiKeyIndex,
|
||
unsigned char *pucDataInput,
|
||
unsigned int uiInputLength,
|
||
unsigned char *pucDataOutput,
|
||
unsigned int *puiOutputLength)
|
||
{
|
||
error_print();
|
||
return SDR_NOTSUPPORT;
|
||
}
|
||
|
||
int SDF_ExternalVerify_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiAlgID,
|
||
ECCrefPublicKey *pucPublicKey,
|
||
unsigned char *pucDataInput,
|
||
unsigned int uiInputLength,
|
||
ECCSignature *pucSignature)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SM2_KEY sm2_key;
|
||
SM2_SIGNATURE sig;
|
||
unsigned int i;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM2_1) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey->bits != 256) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
memset(&sm2_key, 0, sizeof(sm2_key));
|
||
memcpy(sm2_key.public_key.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(sm2_key.public_key.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);
|
||
if (sm2_point_is_on_curve(&sm2_key.public_key) != 1) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucDataInput == NULL || uiInputLength != 32) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucSignature == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
for (i = 0; i < ECCref_MAX_LEN - 32; i++) {
|
||
if (pucSignature->r[i] != 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
}
|
||
for (i = 0; i < ECCref_MAX_LEN - 32; i++) {
|
||
if (pucSignature->s[i] != 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
}
|
||
|
||
memcpy(sig.r, pucSignature->r + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(sig.s, pucSignature->s + ECCref_MAX_LEN - 32, 32);
|
||
|
||
if (sm2_do_verify(&sm2_key, pucDataInput, &sig) != 1) {
|
||
error_print();
|
||
return SDR_VERIFYERR;
|
||
}
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_InternalSign_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiISKIndex,
|
||
unsigned char *pucData,
|
||
unsigned int uiDataLength,
|
||
ECCSignature *pucSignature)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container;
|
||
SM2_SIGNATURE sig;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (!hSessionHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// find container with key index
|
||
container = session->container_list;
|
||
while (container != NULL && container->key_index != uiISKIndex) {
|
||
container = container->next;
|
||
}
|
||
if (container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucData == NULL || uiDataLength != SM3_DIGEST_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucSignature == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (sm2_do_sign(&container->sign_key, pucData, &sig) != 1) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
memset(pucSignature, 0, sizeof(*pucSignature));
|
||
memcpy(pucSignature->r + ECCref_MAX_LEN - 32, sig.r, 32);
|
||
memcpy(pucSignature->s + ECCref_MAX_LEN - 32, sig.s, 32);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_InternalVerify_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiIPKIndex,
|
||
unsigned char *pucData,
|
||
unsigned int uiDataLength,
|
||
ECCSignature *pucSignature)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_CONTAINER *container;
|
||
SM2_SIGNATURE sig;
|
||
unsigned int i;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (!hSessionHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// find container with key index
|
||
container = session->container_list;
|
||
while (container != NULL && container->key_index != uiIPKIndex) {
|
||
container = container->next;
|
||
}
|
||
if (container == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucData == NULL || uiDataLength != SM3_DIGEST_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucSignature == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
for (i = 0; i < ECCref_MAX_LEN - 32; i++) {
|
||
if (pucSignature->r[i] != 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
}
|
||
for (i = 0; i < ECCref_MAX_LEN - 32; i++) {
|
||
if (pucSignature->s[i] != 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
}
|
||
|
||
memcpy(sig.r, pucSignature->r + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(sig.s, pucSignature->s + ECCref_MAX_LEN - 32, 32);
|
||
|
||
if (sm2_do_verify(&container->sign_key, pucData, &sig) != 1) {
|
||
error_print();
|
||
return SDR_VERIFYERR;
|
||
}
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ExternalEncrypt_ECC(
|
||
void *hSessionHandle,
|
||
unsigned int uiAlgID,
|
||
ECCrefPublicKey *pucPublicKey,
|
||
unsigned char *pucData,
|
||
unsigned int uiDataLength,
|
||
ECCCipher *pucEncData)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SM2_KEY sm2_key;
|
||
SM2_CIPHERTEXT ctxt;
|
||
unsigned int i;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (!hSessionHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM2_3) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucPublicKey->bits != 256) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
for (i = 0; i < ECCref_MAX_LEN - 32; i++) {
|
||
if (pucPublicKey->x[i] != 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
}
|
||
for (i = 0; i < ECCref_MAX_LEN - 32; i++) {
|
||
if (pucPublicKey->y[i] != 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
}
|
||
|
||
memset(&sm2_key, 0, sizeof(sm2_key));
|
||
memcpy(sm2_key.public_key.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);
|
||
memcpy(sm2_key.public_key.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);
|
||
|
||
if (!pucData) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if(uiDataLength <=0 || uiDataLength > SM2_MAX_PLAINTEXT_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (sm2_do_encrypt(&sm2_key, pucData, uiDataLength, &ctxt) != 1) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
memset(pucEncData, 0, sizeof(*pucEncData));
|
||
memcpy(pucEncData->x + ECCref_MAX_LEN - 32, ctxt.point.x, 32);
|
||
memcpy(pucEncData->y + ECCref_MAX_LEN - 32, ctxt.point.y, 32);
|
||
memcpy(pucEncData->M, ctxt.hash, 32);
|
||
pucEncData->L = ctxt.ciphertext_size;
|
||
memcpy(pucEncData->C, ctxt.ciphertext, ctxt.ciphertext_size);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
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)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_KEY *key;
|
||
SM4_KEY sm4_key;
|
||
size_t outlen;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (!hSessionHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (hKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
key = session->key_list;
|
||
while (key != NULL && key != (SOFTSDF_KEY *)hKeyHandle) {
|
||
key = key->next;
|
||
}
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (key->key_size < SM4_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM4_CBC) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucIV == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucData == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (puiEncDataLength == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// FIXME: calculate *puiEncDataLength if pucEncData is NULL
|
||
if (pucEncData == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
|
||
sm4_set_encrypt_key(&sm4_key, key->key);
|
||
if (sm4_cbc_padding_encrypt(&sm4_key, pucIV, pucData, uiDataLength, pucEncData, &outlen) != 1) {
|
||
error_print();
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
|
||
*puiEncDataLength = (unsigned int)outlen;
|
||
return SDR_OK;
|
||
}
|
||
|
||
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)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_KEY *key;
|
||
SM4_KEY sm4_key;
|
||
size_t outlen;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (!hSessionHandle) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (hKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
key = session->key_list;
|
||
while (key != NULL && key != (SOFTSDF_KEY *)hKeyHandle) {
|
||
key = key->next;
|
||
}
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (key->key_size < SM4_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM4_CBC) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucIV == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucEncData == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (puiDataLength == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// FIXME: calculate *puiDataLength if pucData is NULL
|
||
if (pucData == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
sm4_set_decrypt_key(&sm4_key, key->key);
|
||
if (sm4_cbc_padding_decrypt(&sm4_key, pucIV, pucEncData, uiEncDataLength, pucData, &outlen) != 1) {
|
||
error_print();
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
return SDR_GMSSLERR;
|
||
}
|
||
memset(&sm4_key, 0, sizeof(sm4_key));
|
||
|
||
*puiDataLength = (unsigned int)outlen;
|
||
return SDR_OK;
|
||
}
|
||
|
||
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)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
SOFTSDF_KEY *key;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (hKeyHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
key = session->key_list;
|
||
while (key != NULL && key != (SOFTSDF_KEY *)hKeyHandle) {
|
||
key = key->next;
|
||
}
|
||
if (key == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucIV != NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucData == NULL || uiDataLength <= 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (puiMACLength == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID == SGD_SM3) {
|
||
SM3_HMAC_CTX hmac_ctx;
|
||
|
||
if (key->key_size < 12) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
*puiMACLength = SM3_HMAC_SIZE;
|
||
|
||
if (!pucMAC) {
|
||
return SDR_OK;
|
||
}
|
||
|
||
sm3_hmac_init(&hmac_ctx, key->key, key->key_size);
|
||
sm3_hmac_update(&hmac_ctx, pucData, uiDataLength);
|
||
sm3_hmac_finish(&hmac_ctx, pucMAC);
|
||
|
||
memset(&hmac_ctx, 0, sizeof(hmac_ctx));
|
||
|
||
} else if (uiAlgID == SGD_SM4_MAC) {
|
||
SM4_CBC_MAC_CTX cbc_mac_ctx;
|
||
|
||
if (key->key_size < SM4_KEY_SIZE) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
*puiMACLength = SM4_CBC_MAC_SIZE;
|
||
|
||
if (!pucMAC) {
|
||
return SDR_OK;
|
||
}
|
||
|
||
sm4_cbc_mac_init(&cbc_mac_ctx, key->key);
|
||
sm4_cbc_mac_update(&cbc_mac_ctx, pucData, uiDataLength);
|
||
sm4_cbc_mac_finish(&cbc_mac_ctx, pucMAC);
|
||
|
||
memset(&cbc_mac_ctx, 0, sizeof(cbc_mac_ctx));
|
||
|
||
} else {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
// 这个函数真正涉及Session!
|
||
int SDF_HashInit(
|
||
void *hSessionHandle,
|
||
unsigned int uiAlgID,
|
||
ECCrefPublicKey *pucPublicKey,
|
||
unsigned char *pucID,
|
||
unsigned int uiIDLength)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (uiAlgID != SGD_SM3) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
// FIXME: check step or return SDR_STEPERR;
|
||
sm3_init(&session->sm3_ctx);
|
||
|
||
if (pucPublicKey != NULL) {
|
||
SM2_POINT point;
|
||
uint8_t z[32];
|
||
|
||
if (pucID == NULL || uiIDLength <= 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (sm2_compute_z(z, &point, (const char *)pucID, uiIDLength) != 1) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
sm3_update(&session->sm3_ctx, z, sizeof(z));
|
||
}
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_HashUpdate(
|
||
void *hSessionHandle,
|
||
unsigned char *pucData,
|
||
unsigned int uiDataLength)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucData == NULL || uiDataLength <= 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
sm3_update(&session->sm3_ctx, pucData, uiDataLength);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_HashFinal(void *hSessionHandle,
|
||
unsigned char *pucHash,
|
||
unsigned int *puiHashLength)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucHash == NULL || puiHashLength == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
sm3_finish(&session->sm3_ctx, pucHash);
|
||
|
||
*puiHashLength = SM3_DIGEST_SIZE;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_CreateFile(
|
||
void *hSessionHandle,
|
||
unsigned char *pucFileName,
|
||
unsigned int uiNameLen,
|
||
unsigned int uiFileSize)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
char filename[FILENAME_MAX_LEN];
|
||
FILE *file = NULL;
|
||
uint8_t buf[1024] = {0};
|
||
size_t i;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucFileName == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
memcpy(filename, pucFileName, uiNameLen);
|
||
filename[uiNameLen] = 0;
|
||
if (strlen(filename) != uiNameLen) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
strcat(filename, ".file");
|
||
|
||
if (uiFileSize > 64 * 1024) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
file = fopen(filename, "wb");
|
||
if (file == NULL) {
|
||
error_puts("Failed to create file");
|
||
return SDR_GMSSLERR;
|
||
}
|
||
for (i = 0; i < uiFileSize/sizeof(buf); i++) {
|
||
fwrite(buf, 1, sizeof(buf), file);
|
||
}
|
||
fwrite(buf, 1, uiFileSize % sizeof(buf), file);
|
||
fclose(file);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_ReadFile(
|
||
void *hSessionHandle,
|
||
unsigned char *pucFileName,
|
||
unsigned int uiNameLen,
|
||
unsigned int uiOffset,
|
||
unsigned int *puiReadLength,
|
||
unsigned char *pucBuffer)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
char filename[FILENAME_MAX_LEN];
|
||
FILE *file = NULL;
|
||
size_t bytesRead;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucFileName == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
memcpy(filename, pucFileName, uiNameLen);
|
||
filename[uiNameLen] = 0;
|
||
if (strlen(filename) != uiNameLen) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
strcat(filename, ".file");
|
||
|
||
if (puiReadLength == NULL || *puiReadLength <= 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucBuffer == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
file = fopen(filename, "rb");
|
||
if (file == NULL) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
if (fseek(file, uiOffset, SEEK_SET) != 0) {
|
||
fclose(file);
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
bytesRead = fread(pucBuffer, 1, *puiReadLength, file);
|
||
if (bytesRead == 0) {
|
||
error_print();
|
||
fclose(file);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
fclose(file);
|
||
|
||
*puiReadLength = bytesRead;
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_WriteFile(
|
||
void *hSessionHandle,
|
||
unsigned char *pucFileName,
|
||
unsigned int uiNameLen,
|
||
unsigned int uiOffset,
|
||
unsigned int uiWriteLength,
|
||
unsigned char *pucBuffer)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
char filename[FILENAME_MAX_LEN];
|
||
FILE *file = NULL;
|
||
size_t bytesWritten;
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucFileName == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
memcpy(filename, pucFileName, uiNameLen);
|
||
filename[uiNameLen] = 0;
|
||
if (strlen(filename) != uiNameLen) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
strcat(filename, ".file");
|
||
|
||
if (uiWriteLength <= 0) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiWriteLength > 64 * 1024) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucBuffer == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
file = fopen(filename, "wb");
|
||
if (file == NULL) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
if (fseek(file, uiOffset, SEEK_SET) != 0) {
|
||
error_print();
|
||
fclose(file);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
bytesWritten = fwrite(pucBuffer, 1, uiWriteLength, file);
|
||
if (bytesWritten != uiWriteLength) {
|
||
error_print();
|
||
fclose(file);
|
||
return SDR_GMSSLERR;
|
||
}
|
||
fclose(file);
|
||
|
||
return SDR_OK;
|
||
}
|
||
|
||
int SDF_DeleteFile(
|
||
void *hSessionHandle,
|
||
unsigned char *pucFileName,
|
||
unsigned int uiNameLen)
|
||
{
|
||
SOFTSDF_SESSION *session;
|
||
char filename[FILENAME_MAX_LEN];
|
||
|
||
if (deviceHandle == NULL) {
|
||
error_print();
|
||
return SDR_STEPERR;
|
||
}
|
||
|
||
if (hSessionHandle == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
session = deviceHandle->session_list;
|
||
while (session != NULL && session != hSessionHandle) {
|
||
session = session->next;
|
||
}
|
||
if (session == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
|
||
if (pucFileName == NULL) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
memcpy(filename, pucFileName, uiNameLen);
|
||
filename[uiNameLen] = 0;
|
||
if (strlen(filename) != uiNameLen) {
|
||
error_print();
|
||
return SDR_INARGERR;
|
||
}
|
||
strcat(filename, ".file");
|
||
|
||
if (remove(filename) != 0) {
|
||
error_print();
|
||
return SDR_GMSSLERR;
|
||
}
|
||
|
||
return SDR_OK;
|
||
}
|