当前位置: 首页 > news >正文

密码系统设计实验3-2

文章目录

  • 《密码系统设计》实验
    • 实验项目
    • 实验三 密码模块实现
      • 4-6 学时实践要求(30 分)

《密码系统设计》实验

实验项目

实验序号实验名称实验学时数实验目的实验内容实验类型学生学习预期成果
实验三密码模块实现6基于商用密码标准的密码模块的实现实现简单的密码引擎,能够提供对称密码算法、非对称密码算法、Hash算法等的密码服务。综合性1.理解密码系统固件、接口等的设计和开发流程;
2.参考《GMT 0018-2023密码设备应用接口规范》等商用密码标准设计实现密码算法进行加密/解密、签名/验签、密钥生成/导出等的接口;
3.与其他商用密码模块进行兼容性测试。

实验三 密码模块实现

4-6 学时实践要求(30 分)

  1. 在 Ubuntu或openEuler中(推荐 openEuler)中调用GmSSL代码,至少实现SM2,SM3,SM4相关密码算法接口,使用Markdown记录详细记录实践过程,每完成一项功能或者一个函数git commit 一次。。(10分)

  2. 在 Ubuntu或openEuler中(推荐 openEuler)中调用GmSSL代码,实现SM2,SM4相关接口密钥管理功能及其他必要接口。使用Markdown记录详细记录实践过程,每完成一项功能或者一个函数git commit 一次。(10分)

  3. 使用 Rust 实现相关接口(选做,10 分)

  4. 实验记录中提交 gitee 课程项目链接,提交本次实验相关 git log运行结果。

  5. 提交要求:

  • 提交实践过程Markdown和转化的PDF文件
  • 代码,文档托管到gitee或github等,推荐 gitclone
  • 记录实验过程中遇到的问题,解决过程,反思等内容,用于后面实验报告

实现gmt0018中,对称加解密、非对称加解密、签名验签、hash运算、MAC运算接口中的至少一类(5选一)

softsdf.c


/**  Copyright 2014-2024 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 <assert.h>
#include <gmssl/mem.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4_cbc_mac.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
#include "sdf.h"#define SDR_GMSSLERR	(SDR_BASE + 0x00000100)static const uint8_t zeros[ECCref_MAX_LEN - 32] = {0};#define SOFTSDF_MAX_KEY_SIZE	64struct 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 256int 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_listif (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 *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_listcurrent_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_listcurrent_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_listcurrent_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_listif (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	"20240622"
#define SOFTSDF_DEV_BATCH_NUM	"001" // as version.major
#define SOFTSDF_DEV_SERIAL_NUM	"0200" // as version.minor
#define SOFTSDF_DEV_SERIAL	SOFTSDF_DEV_DATE \SOFTSDF_DEV_BATCH_NUM \SOFTSDF_DEV_SERIAL_NUMint 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;
#if ENABLE_SM4_ECBpstDeviceInfo->SymAlgAbility |= SGD_ECB;
#endif
#if ENABLE_SM4_CFBpstDeviceInfo->SymAlgAbility |= SGD_CFB;
#endif
#if ENABLE_SM4_OFBpstDeviceInfo->SymAlgAbility |= SGD_OFB;
#endifpstDeviceInfo->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 containercontainer = (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_keysnprintf(filename, FILENAME_MAX_LEN, "sm2sign-%u.pem", uiKeyIndex);file = fopen(filename, "r");if (file == NULL) {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_keysnprintf(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_listif (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 uiKeyIndexcurrent_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;char filename[FILENAME_MAX_LEN];FILE *file = NULL;SM2_KEY sm2_key;SM2_POINT point;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;}snprintf(filename, FILENAME_MAX_LEN, "sm2signpub-%u.pem", uiKeyIndex);file = fopen(filename, "rb");if (file == NULL) {error_print();return SDR_KEYNOTEXIST;}if (sm2_public_key_info_from_pem(&sm2_key, file) != 1) {error_print();fclose(file);return SDR_KEYNOTEXIST;}fclose(file);if (pucPublicKey == NULL) {error_print();return SDR_INARGERR;}sm2_z256_point_to_bytes(&sm2_key.public_key, (uint8_t *)&point);pucPublicKey->bits = 256;memset(pucPublicKey->x, 0, ECCref_MAX_LEN - 32);memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, point.x, 32);memset(pucPublicKey->y, 0, ECCref_MAX_LEN - 32);memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, point.y, 32);return SDR_OK;
}int SDF_ExportEncPublicKey_ECC(void *hSessionHandle,unsigned int uiKeyIndex,ECCrefPublicKey *pucPublicKey)
{SOFTSDF_SESSION *session;char filename[FILENAME_MAX_LEN];FILE *file = NULL;SM2_KEY sm2_key;SM2_POINT point;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;}snprintf(filename, FILENAME_MAX_LEN, "sm2encpub-%u.pem", uiKeyIndex);file = fopen(filename, "rb");if (file == NULL) {error_print();return SDR_KEYNOTEXIST;}if (sm2_public_key_info_from_pem(&sm2_key, file) != 1) {error_print();fclose(file);return SDR_KEYNOTEXIST;}fclose(file);if (pucPublicKey == NULL) {error_print();return SDR_INARGERR;}sm2_z256_point_to_bytes(&sm2_key.public_key, (uint8_t *)&point);pucPublicKey->bits = 256;memset(pucPublicKey->x, 0, ECCref_MAX_LEN - 32);memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, point.x, 32);memset(pucPublicKey->y, 0, ECCref_MAX_LEN - 32);memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, point.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;SM2_POINT public_key;uint8_t private_key[32];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;}sm2_z256_to_bytes(sm2_key.private_key, private_key);sm2_z256_point_to_bytes(&sm2_key.public_key, (uint8_t *)&public_key);memset(pucPublicKey, 0, sizeof(*pucPublicKey));pucPublicKey->bits = 256;memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, public_key.x, 32);memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, public_key.y, 32);memset(pucPrivateKey, 0, sizeof(*pucPrivateKey));pucPrivateKey->bits = 256;memcpy(pucPrivateKey->K + ECCref_MAX_LEN - 32, private_key, 32);memset(&sm2_key, 0, sizeof(sm2_key));memset(private_key, 0, sizeof(private_key));return SDR_OK;
}int SDF_GenerateKeyWithIPK_ECC(void *hSessionHandle,unsigned int uiIPKIndex,unsigned int uiKeyBits,ECCCipher *pucKey,void **phKeyHandle)
{SOFTSDF_SESSION *session;char filename[FILENAME_MAX_LEN];FILE *file;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;}snprintf(filename, FILENAME_MAX_LEN, "sm2encpub-%u.pem", uiIPKIndex);file = fopen(filename, "rb");if (file == NULL) {error_print();return SDR_KEYNOTEXIST;}if (sm2_public_key_info_from_pem(&sm2_key, file) != 1) {error_print();fclose(file);return SDR_KEYNOTEXIST;}fclose(file);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 keykey = (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 containerif (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);// append key to key_listif (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_POINT point;SM2_Z256_POINT public_key;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 keymemset(&point, 0, sizeof(point));memcpy(point.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);memcpy(point.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);if (sm2_z256_point_from_bytes(&public_key, (uint8_t *)&point) != 1) {error_print();return SDR_INARGERR;}if (sm2_key_set_public_key(&sm2_key, &public_key) != 1) {error_print();return SDR_INARGERR;}// generate keykey = (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 keyif (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);// append key to key_listif (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_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_puts("ISK not loaded, call GetPrivateKeyAccess before use ISK\n");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 keykey = (SOFTSDF_KEY *)malloc(sizeof(*key));if (key == NULL) {error_print();return SDR_NOBUFFER;}memset(key, 0, sizeof(*key));// decrypt keymemset(&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_listif (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;
}// XXX: `SDF_GenerateKeyWithKEK` use CBC-Padding, so the `pucKey` can not be decrypted by `SDF_Decrypt`
int SDF_GenerateKeyWithKEK(void *hSessionHandle,unsigned int uiKeyBits,unsigned int uiAlgID,unsigned int uiKEKIndex,unsigned char *pucKey,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 indexsnprintf(filename, FILENAME_MAX_LEN, "kek-%u.key", uiKEKIndex);file = fopen(filename, "rb");if (file == NULL) {fprintf(stderr, "open file: %s\n", filename);error_print();return SDR_KEYNOTEXIST;}size_t rlen;if ((rlen = fread(kek, 1, sizeof(kek), file)) != sizeof(kek)) {printf("rlen = %zu\n", rlen);perror("fread");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 keykey = (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 = 16 + enced_len;// append key to key_listif (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,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 indexsnprintf(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 pucKeyif (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_listif (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;{assert(current != NULL);}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_POINT point;SM2_Z256_POINT public_key;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;}// load public keymemset(&point, 0, sizeof(point));memcpy(point.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);memcpy(point.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);if (sm2_z256_point_from_bytes(&public_key, (uint8_t *)&point) != 1) {error_print();return -1;}if (sm2_key_set_public_key(&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 indexcontainer = session->container_list;while (container != NULL && container->key_index != uiISKIndex) {container = container->next;}if (container == NULL) {error_print();return SDR_INARGERR;}if (pucData == NULL) {error_print();return SDR_INARGERR;}if (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;char filename[FILENAME_MAX_LEN];FILE *file = NULL;SM2_KEY sm2_key;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;}// load public key from filesnprintf(filename, FILENAME_MAX_LEN, "sm2signpub-%u.pem", uiIPKIndex);file = fopen(filename, "rb");if (file == NULL) {error_print();return SDR_KEYNOTEXIST;}if (sm2_public_key_info_from_pem(&sm2_key, file) != 1) {error_print();fclose(file);return SDR_KEYNOTEXIST;}fclose(file);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(&sm2_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_POINT point;SM2_Z256_POINT public_key;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;}}// parse public keymemset(&point, 0, sizeof(point));memcpy(point.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);memcpy(point.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);if (sm2_z256_point_from_bytes(&public_key, (uint8_t *)&point) != 1) {error_print();return SDR_INARGERR;}if (sm2_key_set_public_key(&sm2_key, &public_key) != 1) {error_print();return SDR_INARGERR;}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, // XXX: IV is updated after callingunsigned char *pucData,unsigned int uiDataLength,unsigned char *pucEncData,unsigned int *puiEncDataLength)
{SOFTSDF_SESSION *session;SOFTSDF_KEY *key;SM4_KEY sm4_key;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 (pucData == NULL) {error_print();return SDR_INARGERR;}if (puiEncDataLength == NULL) {error_print();return SDR_INARGERR;}switch (uiAlgID) {case SGD_SM4_CBC:if (pucIV == NULL) {error_print();return SDR_INARGERR;}if (uiDataLength % 16) {error_print();return SDR_INARGERR;}break;
#if ENABLE_SM4_ECBcase SGD_SM4_ECB:if (uiDataLength % 16) {error_print();return SDR_INARGERR;}break;
#endif
#if ENABLE_SM4_CFBcase SGD_SM4_CFB:if (pucIV == NULL) {error_print();return SDR_INARGERR;}break;
#endif
#if ENABLE_SM4_OFBcase SGD_SM4_OFB:if (pucIV == NULL) {error_print();return SDR_INARGERR;}break;
#endifdefault:error_print();return SDR_INARGERR;}// XXX: change this when add CBC-Padding mode*puiEncDataLength = uiDataLength;if (pucEncData == NULL) {return SDR_OK;}// TODO: cache `SM4_KEY` in `SOFTSDF_KEY`, reduce cost of calling `sm4_set_encrypt_key`sm4_set_encrypt_key(&sm4_key, key->key);switch (uiAlgID) {case SGD_SM4_CBC:sm4_cbc_encrypt_blocks(&sm4_key, pucIV, pucData, uiDataLength/16, pucEncData);break;
#if ENALBE_SM4_ECBcase SGD_SM4_ECB:sm4_encrypt_blocks(&sm4_key, pucData, uiDataLength/16, pucEncData);break;
#endif
#if ENALBE_SM4_CFBcase SGD_SM4_CFB:sm4_cfb_encrypt(&sm4_key, SM4_CFB_128, pucIV, pucData, uiDataLength, pucEncData);break;
#endif
#if ENALBE_SM4_OFBcase SGD_SM4_OFB:sm4_ofb_encrypt(&sm4_key, pucIV, pucData, uiDataLength, pucEncData);break;
#endifdefault:gmssl_secure_clear(&sm4_key, sizeof(sm4_key));error_print();return SDR_INARGERR;}gmssl_secure_clear(&sm4_key, sizeof(sm4_key));return SDR_OK;
}int SDF_Decrypt(void *hSessionHandle,void *hKeyHandle,unsigned int uiAlgID,unsigned char *pucIV, // XXX: IV is updated after callingunsigned char *pucEncData,unsigned int uiEncDataLength,unsigned char *pucData,unsigned int *puiDataLength)
{SOFTSDF_SESSION *session;SOFTSDF_KEY *key;SM4_KEY sm4_key;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 (pucEncData == NULL) {error_print();return SDR_INARGERR;}if (puiDataLength == NULL) {error_print();return SDR_INARGERR;}switch (uiAlgID) {case SGD_SM4_CBC:if (pucIV == NULL) {error_print();return SDR_INARGERR;}if (uiEncDataLength % 16) {error_print();return SDR_INARGERR;}break;
#if ENABLE_SM4_ECBcase SGD_SM4_ECB:if (uiEncDataLength % 16) {error_print();return SDR_INARGERR;}break;
#endif
#if ENABLE_SM4_CFBcase SGD_SM4_CFB:if (pucIV == NULL) {error_print();return SDR_INARGERR;}break;
#endif
#if ENABLE_SM4_OFBcase SGD_SM4_OFB:if (pucIV == NULL) {error_print();return SDR_INARGERR;}break;
#endifdefault:error_print();return SDR_INARGERR;}*puiDataLength = uiEncDataLength;if (pucData == NULL) {return SDR_OK;}// TODO: cache `SM4_KEY` in `SOFTSDF_KEY`, reduce cost of calling `sm4_set_encrypt_key`switch (uiAlgID) {case SGD_SM4_CBC:sm4_set_decrypt_key(&sm4_key, key->key);sm4_cbc_decrypt_blocks(&sm4_key, pucIV, pucEncData, uiEncDataLength/16, pucData);break;
#if ENABLE_SM4_ECBcase SGD_SM4_ECB:sm4_set_decrypt_key(&sm4_key, key->key);sm4_encrypt_blocks(&sm4_key, pucEncData, uiEncDataLength/16, pucData);break;
#endif
#if ENABLE_SM4_CFBcase SGD_SM4_CFB:sm4_set_encrypt_key(&sm4_key, key->key);sm4_cfb_decrypt(&sm4_key, SM4_CFB_128, pucIV, pucEncData, uiEncDataLength, pucData);break;
#endif
#if ENABLE_SM4_OFBcase SGD_SM4_OFB:sm4_set_encrypt_key(&sm4_key, key->key);sm4_ofb_encrypt(&sm4_key, pucIV, pucEncData, uiEncDataLength, pucData);break;
#endifdefault:gmssl_secure_clear(&sm4_key, sizeof(sm4_key));error_print();return SDR_INARGERR;}gmssl_secure_clear(&sm4_key, sizeof(sm4_key));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;
}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;SM2_Z256_POINT public_key;uint8_t z[32];if (pucID == NULL || uiIDLength <= 0) {error_print();return SDR_INARGERR;}memset(&point, 0, sizeof(point));memcpy(point.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32);memcpy(point.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32);if (sm2_z256_point_from_bytes(&public_key, (uint8_t *)&point) != 1) {error_print();return SDR_INARGERR;}if (sm2_compute_z(z, &public_key, (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;
}int SDF_InternalEncrypt_ECC(void *hSessionHandle,unsigned int uiIPKIndex,unsigned int uiAlgID,unsigned char *pucData,unsigned int uiDataLength,ECCCipher *pucEncData)
{SOFTSDF_SESSION *session;char filename[FILENAME_MAX_LEN];FILE *file = NULL;SM2_KEY sm2_key;SM2_CIPHERTEXT ciphertext;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;}// load public key by uiISKIndexsnprintf(filename, FILENAME_MAX_LEN, "sm2encpub-%u.pem", uiIPKIndex);file = fopen(filename, "rb");if (file == NULL) {error_print();return SDR_KEYNOTEXIST;}if (sm2_public_key_info_from_pem(&sm2_key, file) != 1) {error_print();fclose(file);return SDR_KEYNOTEXIST;}fclose(file);// check uiAlgIDif (uiAlgID != SGD_SM2_3) {error_print();return SDR_ALGNOTSUPPORT;}if (pucData == NULL) {error_print();return SDR_INARGERR;}if (uiDataLength > SM2_MAX_PLAINTEXT_SIZE) {error_print();return SDR_INARGERR;}if (pucEncData == NULL) {error_print();return SDR_INARGERR;}// encryptif (sm2_do_encrypt(&sm2_key, pucData, uiDataLength, &ciphertext) != 1) {error_print();return SDR_PKOPERR;}memset(pucEncData->x, 0, ECCref_MAX_LEN - 32);memcpy(pucEncData->x + ECCref_MAX_LEN - 32, ciphertext.point.x, 32);memset(pucEncData->y, 0, ECCref_MAX_LEN - 32);memcpy(pucEncData->y + ECCref_MAX_LEN - 32, ciphertext.point.y, 32);memcpy(pucEncData->M, ciphertext.hash, 32);memcpy(pucEncData->C, ciphertext.ciphertext, ciphertext.ciphertext_size);pucEncData->L = (unsigned int)ciphertext.ciphertext_size;return SDR_OK;
}int SDF_InternalDecrypt_ECC(void *hSessionHandle,unsigned int uiISKIndex,unsigned int uiAlgID,ECCCipher *pucEncData,unsigned char *pucData,unsigned int *puiDataLength)
{SOFTSDF_SESSION *session;SOFTSDF_CONTAINER *container;SM2_CIPHERTEXT ciphertext;size_t plaintext_len;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;}// load public key by uiISKIndexcontainer = session->container_list;while (container != NULL && container->key_index != uiISKIndex) {container = container->next;}if (container == NULL) {error_print();return SDR_INARGERR;}// check uiAlgIDif (uiAlgID != SGD_SM2_3) {error_print();return SDR_ALGNOTSUPPORT;}// check ciphertextif (pucEncData == NULL) {error_print();return SDR_INARGERR;}if (pucEncData->L > SM2_MAX_PLAINTEXT_SIZE) {error_print();return SDR_INARGERR;}// convert ECCCipher to SM2_CIPHERTEXTif (memcmp(pucEncData->x, zeros, ECCref_MAX_LEN - 32) != 0) {error_print();return SDR_INARGERR;}if (memcmp(pucEncData->y, zeros, ECCref_MAX_LEN - 32) != 0) {error_print();return SDR_INARGERR;}memcpy(ciphertext.point.x, pucEncData->x + ECCref_MAX_LEN - 32, 32);memcpy(ciphertext.point.y, pucEncData->y + ECCref_MAX_LEN - 32, 32);memcpy(ciphertext.hash, pucEncData->M, 32);memcpy(ciphertext.ciphertext, pucEncData->C, pucEncData->L);ciphertext.ciphertext_size = pucEncData->L;if (puiDataLength == NULL) {error_print();return SDR_INARGERR;}if (pucData == NULL) {*puiDataLength = pucEncData->L;return SDR_OK;}if (sm2_do_decrypt(&container->enc_key, &ciphertext, pucData, &plaintext_len) != 1) {error_print();return SDR_PKOPERR;}*puiDataLength = (unsigned int)plaintext_len;return SDR_OK;
}int SDF_InternalPublicKeyOperation_RSA(void *hSessionHandle,unsigned int uiKeyIndex,unsigned char *pucDataInput,unsigned int uiInputLength,unsigned char *pucDataOutput,unsigned int *puiOutputLength)
{error_print();return SDR_NOTSUPPORT;
}

softsdftest.c(实现hash运算验证)


/**  Copyright 2014-2024 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 <string.h>
#include <stdlib.h>
#include <gmssl/sm3.h>
#include "sdf.h"int main(void)
{void *hDeviceHandle = NULL;void *hSessionHandle = NULL;unsigned char ucData[3] = { 0x61, 0x62, 0x63 };unsigned int uiDataLength = (unsigned int)sizeof(ucData);unsigned char ucHash[32];unsigned int uiHashLength;int ret;SM3_CTX sm3_ctx;unsigned char dgst[32];ret = SDF_OpenDevice(&hDeviceHandle);if (ret != SDR_OK) {fprintf(stderr, "Error: SDF_OpenDevice: 0x%X\n", ret);return -1;}ret = SDF_OpenSession(hDeviceHandle, &hSessionHandle);if (ret != SDR_OK) {fprintf(stderr, "Error: SDF_OpenSession: 0x%X\n", ret);return -1;}ret = SDF_HashInit(hSessionHandle, SGD_SM3, NULL, NULL, 0);if (ret != SDR_OK) {fprintf(stderr, "Error: SDF_HashInit: 0x%X\n", ret);return -1;}ret = SDF_HashUpdate(hSessionHandle, ucData, uiDataLength);if (ret != SDR_OK) {fprintf(stderr, "Error: SDF_HashUpdate: 0x%X\n", ret);return -1;}ret = SDF_HashFinal(hSessionHandle, ucHash, &uiHashLength);if (ret != SDR_OK) {fprintf(stderr, "Error: SDF_HashFinal: 0x%X\n", ret);return -1;}SDF_CloseSession(hSessionHandle);SDF_CloseDevice(hDeviceHandle);// check with gmsslsm3_init(&sm3_ctx);sm3_update(&sm3_ctx, ucData, sizeof(ucData));sm3_finish(&sm3_ctx, dgst);if (uiHashLength != 32) {fprintf(stderr, "Error: error hash lenght\n");return -1;}if (memcmp(ucHash, dgst, 32) != 0) {fprintf(stderr, "Error: error hash value\n");return -1;}printf("test ok\n");return 0;
}

接口放入sdf.h,实现sdf.c testsdf.c

root@LAPTOP-PRC71A0C:~/SoftSDF-main#gcc -o sm4enc sm4enc.c softsdf.c -lgmssl
root@LAPTOP-PRC71A0C:~/SoftSDF-main#./softsdftest
test ok
root@LAPTOP-PRC71A0C:~/SoftSDF-main# git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
Initialized empty Git repository in /root/SoftSDF-main/.git/
root@LAPTOP-PRC71A0C:~/SoftSDF-main# git add softsdftest
root@LAPTOP-PRC71A0C:~/SoftSDF-main# git commit -m "验证hash算法结果"
[master (root-commit) 4b3c9c9] 验证hash算法结果Committer: root <root@LAPTOP-PRC71A0C>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:git config --global user.name "Your Name"git config --global user.email you@example.comAfter doing this, you may fix the identity used for this commit with:git commit --amend --reset-author1 file changed, 0 insertions(+), 0 deletions(-)create mode 100755 softsdftest

相关文章:

密码系统设计实验3-2

文章目录 《密码系统设计》实验实验项目实验三 密码模块实现4-6 学时实践要求&#xff08;30 分&#xff09; 《密码系统设计》实验 实验项目 实验序号实验名称实验学时数实验目的实验内容实验类型学生学习预期成果实验三密码模块实现6基于商用密码标准的密码模块的实现实现简…...

Spring Boot 与 Spring Cloud Alibaba 版本兼容对照

版本选择要点 Spring Boot 3.x 与 Spring Cloud Alibaba 2022.0.x Spring Boot 3.x 基于 Jakarta EE&#xff0c;javax.* 更换为 jakarta.*。 需要使用 Spring Cloud 2022.0.x 和 Spring Cloud Alibaba 2022.0.x。 Alibaba 2022.0.x 对 Spring Boot 3.x 的支持在其发行说明中…...

SVD 奇异值分解

SVD 是一种矩阵分解和降维的算法&#xff0c;通过分解矩阵找到奇异值&#xff0c;奇异值越大代表特征越重要。公式如下 A U Σ V T A U \Sigma V^T AUΣVT U : 左矩阵 ( m \times m ) Σ \Sigma Σ: 对角奇异值矩阵V&#xff1a;右矩阵( n \times n ) Sklearn 实现 S…...

C++设计模式-享元模式

动机(Motivation) 在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中&#xff0c;从而带来很高的运行时代价——主要指内存需求方面的代价。如何在避免大量细粒度对象问题的同时&#xff0c;让外部客户程序仍然能够透明地使用面向对象的方式来进行操作…...

AI加持,华为全屋智能品牌升级为“鸿蒙智家”

1.传统智能家居的困境&#xff1a;从便利到繁琐 近年来&#xff0c;智能家居因其便捷性和科技感受到消费者的青睐。然而&#xff0c;随着用户需求的多样化&#xff0c;传统智能家居的弊端逐渐显现&#xff1a; 设备连接复杂&#xff0c;品牌间兼容性不足&#xff0c;用户不得不…...

洛谷刷题之p1631

序列合并 题目入口 题目描述 有两个长度为 N N N 的单调不降序列 A , B A,B A,B&#xff0c;在 A , B A,B A,B 中各取一个数相加可以得到 N 2 N^2 N2 个和&#xff0c;求这 N 2 N^2 N2 个和中最小的 N N N 个。 输入格式 第一行一个正整数 N N N&#xff1b; 第二…...

uniapp前端开发,基于vue3,element plus组件库,以及axios通讯

简介 UniApp 是一个基于 Vue.js 的跨平台开发框架&#xff0c;旨在通过一次开发、编译后运行在多个平台上&#xff0c;如 iOS、Android、H5、以及小程序&#xff08;微信小程序、支付宝小程序、百度小程序等&#xff09;等。UniApp 为开发者提供了统一的开发体验&#xff0c;使…...

在Unity中实现物体动画的完整流程

在Unity中&#xff0c;动画是游戏开发中不可或缺的一部分。无论是2D还是3D游戏&#xff0c;动画都能为游戏增添生动的视觉效果。本文将详细介绍如何在Unity中为物体添加动画&#xff0c;包括资源的准备、播放组件的添加、动画控制器的创建以及动画片段的制作与调度。 1. 准备动…...

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”&#xff1f;三、为什么有必要采用纵深安全防御策略&#xff1f;四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…...

【Andriod ADB基本命令总结】

笔者工作当中遇到安卓机器的数据访问和上传,特来简单总结一下常用命令。 1、ADB命令简介与安装 简介: ADB (Android Debug Bridge) 是一个强大的命令行工具,用于与 Android 设备进行交互,常用于开发、调试、测试以及设备管理等操作。它是 Android 开发工具包(SDK)的一部…...

ChatGPT如何辅助academic writing?

今天想和大家分享一篇来自《Nature》杂志的文章《Three ways ChatGPT helps me in my academic writing》&#xff0c;如果您的日常涉及到学术论文的写作&#xff08;writing&#xff09;、编辑&#xff08;editing&#xff09;或者审稿&#xff08; peer review&#xff09;&a…...

Day 27 贪心算法 part01

贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其规律, 没有思路就立刻看题解。 基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。 学完贪心之后再去看动态规划,就会了解贪心和动规的区别。…...

使用Python实现目标追踪算法

引言 目标追踪是计算机视觉领域的一个重要任务&#xff0c;广泛应用于视频监控、自动驾驶、机器人导航、运动分析等多个领域。目标追踪的目标是在连续的视频帧中定位和跟踪感兴趣的物体。本文将详细介绍如何使用Python和OpenCV实现一个基本的目标追踪算法&#xff0c;并通过一…...

某科技研发公司培训开发体系设计项目成功案例纪实

某科技研发公司培训开发体系设计项目成功案例纪实 ——建立分层分类的培训体系&#xff0c;加强培训跟踪考核&#xff0c;促进培训成果实现 【客户行业】科技研发行业 【问题类型】培训开发体系 【客户背景】 某智能科技研发公司是一家专注于智能科技、计算机软件技术开发与…...

如何通过高效的缓存策略无缝加速湖仓查询

引言 本文将探讨如何利用开源项目 StarRocks 的缓存策略来加速湖仓查询&#xff0c;为企业提供更快速、更灵活的数据分析能力。作为 StarRocks 社区的主要贡献者和商业化公司&#xff0c;镜舟科技深度参与 StarRocks 项目开发&#xff0c;也为企业着手构建湖仓架构提供更多参考…...

Linux V4L2框架介绍

linux V4L2框架介绍 V4L2框架介绍 V4L2&#xff0c;全称Video for Linux 2&#xff0c;是Linux操作系统下用于视频数据采集设备的驱动框。它提供了一种标准化的方式使用户空间程序能够与视频设备进行通信和交互。通过V4L2接口&#xff0c;用户可以方便地实现视频图像数据的采…...

【前端】JavaScript 中 arguments、类数组与数组的深入解析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是 arguments 对象2.1 arguments 的定义2.2 arguments 的特性2.3 使用场景 &#x1f4af;深入了解 arguments 的结构3.1 arguments 的内部结构arguments 的关键属性…...

Android 布局菜单或按钮图标或Menu/Item设置可见和不可见

设置可见和不可见 即 设置 显示和隐藏&#xff1b;是双向设置&#xff1b;什么情况显示&#xff0c;什么情况隐藏分判断的条件 它不同于删除和屏蔽&#xff0c;删除和屏蔽&#xff0c;覆盖是单向的&#xff0c;不可逆转的。它间接等于单向的隐藏&#xff01;&#xff01;&…...

|| 与 ??的区别

?? : 空值合并运算符&#xff0c; 用于在左侧操作数为 null 或 undefined 时返回右侧操作数 let name null // null 或者 undefinedlet defaultName defaultNamelet displayName name ?? defaultNameconsole.log(displayName) // defaultName || : 逻辑或&#xff0c;…...

wordpress获取文章总数、分类总数、tag总数等

在制作wordpress模板的时候会要调用网站的文章总数分类总数tag总数等这个数值&#xff0c;如果直接用count查询数据库那就太过分了。好在wordpress内置了一些标签可以直接获取到这些数值&#xff0c;本文整理了一些常用的wordpress网站总数标签。 文章总数 <?php $count_…...

pytest 通过实例讲清单元测试、集成测试、测试覆盖率

1. 单元测试 概念 定义: 单元测试是对代码中最小功能单元的测试&#xff0c;通常是函数或类的方法。目标: 验证单个功能是否按照预期工作&#xff0c;而不依赖其他模块或外部资源。特点: 快速、独立&#xff0c;通常是开发者最先编写的测试。 示例&#xff1a;pytest 实现单…...

C#里怎么样自己实现10进制转换为二进制?

C#里怎么样自己实现10进制转换为二进制&#xff1f; 很多情况下&#xff0c;我们都是采用C#里类库来格式化输出二进制数。 如果有人要你自己手写一个10进制数转换为二进制数&#xff0c;并格式化输出&#xff0c; 就可以采用本文里的方法。 这里采用求模和除法来实现的。 下…...

Kafka-Consumer理论知识

一、上下文 之前的博客我们分析了Kafka的设计思想、Kafka的Producer端、Kafka的Server端的分析&#xff0c;为了完整性&#xff0c;我们接下来分析下Kafka的Consumer。《Kafka-代码示例》中有对应的Consumer示例代码&#xff0c;我们以它为入口进行分析 二、KafkaConsumer是什…...

Js-对象-04-Array

重点关注&#xff1a;Array String JSON BOM DOM Array Array对象时用来定义数组的。常用语法格式有如下2种&#xff1a; 方式1&#xff1a; var 变量名 new Array(元素列表); 例如&#xff1a; var arr new Array(1,2,3,4); //1,2,3,4 是存储在数组中的数据&#xff0…...

React 第八节组件生命周期钩子-类式组件,函数式组件模拟生命周期用法

概述 React组件的生命周期可以分为三个主要阶段&#xff1a; 挂载阶段&#xff08;Mounting&#xff09;&#xff1a;组件被创建&#xff0c;插入到DOM 树的过程&#xff1b; 更新阶段&#xff08;Updating&#xff09;&#xff1a;是组件中 props 以及state 发生变化时&#…...

Dubbo源码解析-服务调用(七)

一、服务调用流程 服务在订阅过程中&#xff0c;把notify 过来的urls 都转成了invoker&#xff0c;不知道大家是否还记得前面的rpc 过程&#xff0c;protocol也是在服务端和消费端各连接子一个invoker&#xff0c;如下图&#xff1a; 这张图主要展示rpc 主流程&#xff0c;消费…...

svn 崩溃、 cleanup失败 怎么办

在使用svn的过程中&#xff0c;可能出现整个svn崩溃&#xff0c; 例如cleanup 失败的情况&#xff0c;类似于 这时可以下载本贴资源文件并解压。 或者直接访问网站 SQLite Download Page 进行下载 解压后得到 sqlite3.exe 放到发生问题的svn根目录的.svn路径下 右键呼出pow…...

【Linux系列】NTP时间同步服务器搭建完整指南

在分布式系统和高可用环境中&#xff0c;时间同步是至关重要的。特别是对于银行、金融等关键业务系统&#xff0c;精准的时间同步不仅关系到系统的稳定性&#xff0c;还直接影响交易处理、日志管理、日终结算等功能。本文将介绍NTP&#xff08;Network Time Protocol&#xff0…...

go 结构体方法

在 Go 语言中&#xff0c;结构体方法是指附加到结构体类型上的函数。这些方法可以通过结构体的实例来调用。方法的接收者&#xff08;receiver&#xff09;指定了该方法属于哪个结构体类型。接收者可以是一个值类型或指针类型。 定义结构体方法 下面是如何为一个结构体定义方…...

DHCP服务(包含配置过程)

目录 一、 DHCP的定义 二、 使用DHCP的好处 三、 DHCP的分配方式 四、 DHCP的租约过程 1. 客户机请求IP 2. 服务器响应 3. 客户机选择IP 4. 服务器确定租约 5. 重新登录 6. 更新租约 五、 DHCP服务配置过程 一、 DHCP的定义 DHCP&#xff08;Dynamic Host Configur…...

网站建设接单/兰州seo技术优化排名公司

题目描述 给定n个点 给出他们的权值&#xff0c; 并且给出他们的父子关系 现在给他们染色&#xff0c; 一个节点染色的消耗为 T*a[i]&#xff0c; T为这个节点是第几次染色 a[i]为权值 根节点可以随时染色 问&#xff1a; 染色完需要全部节点的最小消耗样例 Sample Input 5 1…...

四海网络网站建设咨询/网盘资源免费观看

原标题&#xff1a;「Linux基础知识」grep文件内容筛选命令的使用grep命令用于从文档中抓取显示包含指定字符的行&#xff0c;grep命令的使用格式如下&#xff1a;grep [选项] 匹配模式 文件1 文件2 ......grep常见的选项有&#xff1a;-n 显示匹配文档行的行号-i 忽略大小写按…...

html5 网站布局应用教程/百度站长工具seo查询

现在我们继续这个新闻客户端的开发&#xff0c;今天分享的是下拉刷新的实现&#xff0c;我们都知道下拉刷新是一个应用很常见也很实用的功能。我这个应用是通过拉ListView来实现刷新的&#xff0c;先看一张刷新的原理图 从图中可知&#xff0c;手指移动的距离就是dy。 刷新分…...

日喀则网站seo/江苏做网站的公司有哪些

总结 splice()会改变原来的数组&#xff0c;返回的是被改变的内容&#xff0c;比如说通过splice删掉了某一项&#xff0c;那么返回的是删掉的这一项&#xff0c;当然还是会以数组的形式返回。 slice不会对原数组进行改变&#xff0c;会返回一个新的数组。利用slice同样也可以实…...

洛阳做网站公司汉狮价格/创建软件平台该怎么做

最近做U800电话的二次开发&#xff0c;需要调用厂商的C函数库来打电话&#xff0c;后来想加入通话录音功能&#xff0c;但发现程序默认生产的WAV文件过大&#xff0c;又找了个WAV转MP3的C函数库程序&#xff0c;出了点问题。下面是转MP3的程序接口&#xff08;头文件&#xff0…...

游戏网官网/怎样进行seo优化

无线网络发射器选址 题目描述 Description随着智能手机的日益普及&#xff0c;人们对无线网的需求日益增大。某城市决定对城市内的公共场所覆盖无线网。 假设该城市的布局为由严格平行的 129 条东西向街道和 129 条南北向街道所形成的网格状&#xff0c;并且相邻的平行街道之间…...