《密码系统设计》实验
实验三 密码模块实现 基于商⽤密码标准的密码模块的实现 1.理解密码系统固件、接⼝等的设计和开发流程;2.参考《GMT 0018-2023密码设备应⽤接⼝规范》等商⽤密码标准设计实现密码算法进⾏加密/解密、签名/验签、密钥⽣成/导出等的接⼝;3.与其他商⽤密码模块进⾏兼容性测试。
GMT0018
SDF.h
#ifndef __SDF_H
#define __SDF_H
#define ECCref_MAX_BITS 512
#define ECCref_MAX_LEN ((ECCref_MAX_BITS + 7) / 8)
#define SDR_OK 0x0
#define SDR_BASE 0x01000000
#define SGD_SM3 0x00000001
#define SDR_INARGERR (SDR_BASE + 0x0000001D)
#define SDR_STEPERR (SDR_BASE + 0x00000010)
//定义设备信息结构
typedef struct DeviceInfo_st{
unsigned char IssuerName[40]; //设备生产厂商名称
unsigned char DeviceName[16];
unsigned char DeviceSerial[16];
unsigned int DeviceVersion;
unsigned int StandardVersion;
unsigned int AsymAlgAbility[2];
unsigned int SymAlgAbilty;
unsigned int HashAlgAbility;
unsigned int BufferSize;
}DEVICEINFO;
typedef unsigned char BYTE; //—— 定义了BYTE为无符号8位字符类型。
typedef unsigned char CHAR; //—— 定义了CHAR为无符号8位字符类型。
typedef int LONG; //—— 定义了LONG为有符号32位整数类型(注意:原图中描述为typedef int LONG,而非typedef unsigned int LONG)。
typedef unsigned int ULONG; //—— 定义了ULONG为无符号32位整数类型。
typedef unsigned int FLAGS; //—— 定义了FLAGS为无符号32位整数类型,通常用作标志位。
typedef CHAR * LPSTR; //—— 定义了LPSTR为8位字符串指针,字符串按照UTF-8格式存储及交换。
typedef void * HANDLE; //—— 定义了HANDLE为句柄类型,指向任意数据对象的起始地址。
// Error Code
typedef struct ECCrefPublicKey_st
{
ULONG bits; // 公钥的位数
BYTE x[ECCref_MAX_LEN]; // 公钥点的x坐标
BYTE y[ECCref_MAX_LEN]; // 公钥点的y坐标
} ECCrefPublicKey;
#define SDR_OK 0x0 //操作成功
//********************************
//设备管理
//********************************
/*
功能:打开密码设备。
参数∶
phDeviceHandle[out] 返回设备句柄
返回值∶
0 成功
非0 失败,返回错误代码
*/
int SDF_OpenDevice(void ** phDeviceHandle);
/*
功能∶关闭密码设备,并释放相关资源。
参数∶
hDeviceHandle[in] 已打开的设备句柄
返回值∶
0(SDR_OK) 成功
非0 失败,返回错误代码
*/
int SDF_CloseDevice(void *hDeviceHandle);
/*
功能∶获取密码设备能力描述。;
参数∶
hSesionHandle[in]与设备建立的会话句柄
pstDevceInfo [out]设备能力描述信息,内容及格式见设备信息定义
返回值∶
0(SDR_OK) 成功
非0 失败,返回错误代码
*/
int SDF_GetDeviceInfo( void * hSessionHandle,
DEVICEINFO * pstDeviceInfo);
/*
功能:获取指定长度的随机数
参数:
uiLength[in] 欲获取的随机数长度
pucRandom[ out] 缓冲区指针,用于存放获取的随机数
返回值∶
00(SDR_OK) 成功
非0 失败,返回错误代码
*/
int SDF_GenerateRandom (void * hSessionHandle, unsigned int uiLength, unsigned char * pucRandom);
int SDF_HashInit(
void *hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey *pucPublicKey,
unsigned char *pucID,
unsigned int uiIDLength);
int SDF_HashUpdate(
void *hSessionHandle,
unsigned char *pucData,
unsigned int uiDataLength);
int SDF_HashFinal(void *hSessionHandle,
unsigned char *pucHash,
unsigned int *puiHashLength);
int SDF_OpenSession(
void *hDeviceHandle,
void **phSessionHandle);
int SDF_CloseSession(
void *hSessionHandle);
#endif
SDF.c
#include “sdf.h”
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.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>
#define SDR_GMSSLERR (SDR_BASE + 0x00000100)
static const uint8_t zeros[ECCref_MAX_LEN - 32] = {0};
#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 *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;
}
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 (pstDeviceInfo == NULL) {
error_print();
return SDR_INARGERR;
}
memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo));
strncpy((char *)pstDeviceInfo->IssuerName, “RocSDF”,
sizeof(pstDeviceInfo->IssuerName));
strncpy((char *)pstDeviceInfo->DeviceName, “SDFBESTI181x”,
sizeof(pstDeviceInfo->DeviceName));
strncpy((char *)pstDeviceInfo->DeviceSerial, “2021040001”,
sizeof(pstDeviceInfo->DeviceSerial));
pstDeviceInfo->DeviceVersion=1;
return SDR_OK;
}
static int myRandom(){
srand((unsigned)time(NULL));
return rand();
}
int SDF_GenerateRandom (void * hSessionHandle, unsigned int uiLength, unsigned char * pucRandom){
for(int i=0; i<uiLength; i++){
sleep(2);
*(pucRandom+i) = myRandom();
// pucRandom[i] = i;
}
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;
}
hash.c
#include<stdio.h>
#include <string.h>
#include"sdf.h"
#include<pthread.h>
#include<sys/time.h>
#include<sys/types.h>
#include <gmssl/sm3.h>
#include <stdlib.h>
#define ROOTKEY “\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10”
#define DEVSN “hs_0000000000001”
#define MAX (4000)
int SM3(unsigned char* data, unsigned char* hash, unsigned int* hash_len){
HANDLE phDeviceHandle;
HANDLE phSessionHandle;
int rv = SDF_OpenDevice(&phDeviceHandle);
if(rv != SDR_OK)
{
printf(“open devces fail\n”);
return 1;
}
printf(“open device success!\n”);
rv = SDF_OpenSession(phDeviceHandle, &phSessionHandle);
if(rv != SDR_OK)
{
SDF_CloseDevice(phDeviceHandle);
printf(“open session fail\n”);
return 1;
}
printf(“open session success!\n”);
rv = SDF_HashInit(phSessionHandle,SGD_SM3,NULL,NULL,0);
if(SDR_OK != rv)
{
return rv;
}
rv = SDF_HashUpdate(phSessionHandle,data, strlen(data));
if(SDR_OK != rv)
{
return rv;
}
rv = SDF_HashFinal(phSessionHandle,hash,hash_len);
if(SDR_OK != rv)
{
printf(“3 %d \n”, rv);
return rv;
}
if(rv != SDR_OK)
{
printf(“SGD_SM3Hash fail\n”);
SDF_CloseSession(phSessionHandle);
SDF_CloseDevice(phDeviceHandle);
return 1;
}
printf(“SGD_SM3Hash success\n”);
SDF_CloseSession(phSessionHandle);
SDF_CloseDevice(phDeviceHandle);
return 0;
}
//#define MAX (1536)
int main(int argc, char *argv[])
{
unsigned char * text = “Hello”;
unsigned char hash[256];
unsigned int len = 32;
int rv = 0;
rv = SM3(text, hash, &len);
if(rv != 0){
printf(“Error SM3”);
}
for(int i = 0; i < len; i++){
printf(“%02x”, hash[i]);
}
printf(“\n”);
printf(“Use GmSSL to Check Hash:\n”);
unsigned char sm3hash[256];
SM3_CTX ctx;
sm3_init(&ctx); // Initialize the hash context
sm3_update(&ctx, text, strlen(text)); // Hash the data
sm3_finish(&ctx, sm3hash); // Finalize the hash
printf(“SM3 hash: “);
for (int i = 0; i < SM3_DIGEST_SIZE; i++) {
printf(”%02x”, sm3hash[i]);
}
printf(“\n”);
int result = strcmp(hash, sm3hash);
if (result == 0){
printf(“Check ok\n”);
}else{
printf(“Check error\n”);
}
return 0;
}
运行结果
$ ./hash
open device success!
open session success!
pOutRand:
42bd80f3 35a028d2 c7a1fadc 130a7b99
SDF_GenerateRandom success!
SN:hs_00000000000014209�
CosVer: 4.2.09
open device success!
open session success!
SGD_SM3Hash success
dc74f051ad5bc19ba721bf0023e10de03bae29bbe013c43988bae55828bcebbc
Use GmSSL to Check Hash:
SM3 hash: dc74f051ad5bc19ba721bf0023e10de03bae29bbe013c43988bae55828bcebbc
Check ok
git log
commit 1e685d383458f950ae588d92794e227a87653c86 (HEAD -> master)
Author: zhanhe lzj@outlook.com
Date: Tue Nov 26 22:18:02 2024 +0800
test
commit 14fbf0b15c9d014088a96052766633e3858e4645
Author: zhanhe lzj@outlook.com
Date: Tue Nov 26 22:17:20 2024 +0800
sdf
commit a76cfd0338ac6e38769677966c632cd03051746c
Author: zhanhe lzj@outlook.com
Date: Tue Nov 26 21:06:25 2024 +0800
sm3
提交要求:
提交实践过程Markdown和转化的PDF文件
代码,文档托管到gitee或github等,推荐 gitclone
记录实验过程中遇到的问题,解决过程,反思等内容,完成实验报告相关内容