20221320—馮泰瑞—課上測試:商用密碼接口實現
20221320—馮泰瑞—課上測試:商用密碼接口實現
完成下面任務
1 在 Ubuntu 或 openEuler 中完成任務(推薦openEuler)
2 參考GM/T0018 2023和實驗代碼,說明SDF接口調用的一般過程是什么
SDF接口調用的一般過程涉及與密碼設備進行交互的一系列步驟,包括設備管理、密鑰管理、算法運算等。以下是根據GM/T0018-2023《密碼設備應用接口規范》和實驗三代碼總結的SDF接口調用的一般過程:
-
打開設備(SDF_OpenDevice):
- 調用
SDF_OpenDevice函數打開密碼設備,獲取設備句柄。 - 參數:
void** phDeviceHandle,用于返回設備句柄。 - 返回值:成功返回0,失敗返回錯誤代碼。
- 調用
-
創建會話(SDF_OpenSession):
- 使用設備句柄調用
SDF_OpenSession函數創建與密碼設備的會話,獲取會話句柄。 - 參數:
void* hDeviceHandle,已打開的設備句柄;void** phSessionHandle,用于返回會話句柄。 - 返回值:成功返回0,失敗返回錯誤代碼。
- 使用設備句柄調用
-
獲取設備信息(SDF_GetDeviceInfo):
- 使用會話句柄調用
SDF_GetDeviceInfo函數獲取密碼設備的能力描述信息。 - 參數:
void* hSessionHandle,與設備建立的會話句柄;DEVICEINFO* pstDeviceInfo,設備能力描述信息。 - 返回值:成功返回0,失敗返回錯誤代碼。
- 使用會話句柄調用
-
密鑰管理:
- 根據需要執行密鑰管理操作,如導出公鑰、生成密鑰對、導入密鑰等。
-
算法運算:
- 執行所需的密碼學算法運算,如加密、解密、簽名、驗證等。
- 例如,使用
SDF_Encrypt進行對稱加密,SDF_Decrypt進行對稱解密,SDF_InternalSign_ECC進行ECC簽名等。
-
關閉會話(SDF_CloseSession):
- 使用會話句柄調用
SDF_CloseSession函數關閉與密碼設備的會話。 - 參數:
void* hSessionHandle,與密碼設備已建立的會話句柄。 - 返回值:成功返回0,失敗返回錯誤代碼。
- 使用會話句柄調用
-
關閉設備(SDF_CloseDevice):
- 使用設備句柄調用
SDF_CloseDevice函數關閉密碼設備,并釋放相關資源。 - 參數:
void* hDeviceHandle,已打開的設備句柄。 - 返回值:成功返回0,失敗返回錯誤代碼。
- 使用設備句柄調用
-
錯誤處理:
- 在每個步驟中,如果函數返回非0值,需要根據返回的錯誤代碼進行錯誤處理。
3 參考課程代碼sdfproject,使用gmssl定義一個私有函數 static int getRandom(char *r, int length), 獲取length個字節的隨機數
static int getRandom(char *r, int length) {
rand_bytes((unsigned char *)r, length);
return 0; // 成功
}
4 把上述函數集成到src中的sdf.c中的SDF_GenerateRandom中,實現相關代碼
sdf.h原碼
#ifndef __SDF_H
#define __SDF_H
//定義設備信息結構
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;
// Error Code
#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);
#ifndef __SDF_H
#define __SDF_H
// ... 其他定義 ...
// 錯誤代碼
#define SDR_OK 0x0
#define SDR_BASE 0x01000000
#define SDR_INARGERR SDR_BASE + 0x0000001 // 輸入參數錯誤
#define SDR_RANDERR SDR_BASE + 0x00000017 // 隨機數產生失敗
// ... 其他定義 ...
#endif
sdf.c原碼
// sdf.c
#include "sdf.h"
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <gmssl/rand.h>
//********************************
//設備管理
//********************************
int SDF_OpenDevice(void ** phDeviceHandle){
return SDR_OK;
}
int SDF_CloseDevice(void *hDeviceHandle){
return SDR_OK;
}
int SDF_GetDeviceInfo( void * hSessionHandle, DEVICEINFO * pstDeviceInfo) {
DEVICEINFO di;
strcpy(di.IssuerName,"RocSDF");
strcpy(di.DeviceName,"SDFBESTI181x");
strcpy(di.DeviceSerial,"2021040001");
di.DeviceVersion = 1;
//...
//pstDevicelnfo = &di;
*pstDeviceInfo = di;
return SDR_OK;
}
static int getRandom(char *r, int length) {
rand_bytes((unsigned char *)r, length);
return 0; // 成功
}
int SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, unsigned char *pucRandom) {
return getRandom((char *)pucRandom, uiLength);
}
main.c原碼
// main.c
#include "sdf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
void **pdh;
pdh = (void **)malloc(sizeof(void *));
int ret;
ret = SDF_OpenDevice(pdh);
if (ret != SDR_OK) {
printf("error!\n");
} else {
printf("device opened!\n");
}
DEVICEINFO testdi;
ret = SDF_GetDeviceInfo(*pdh, &testdi);
if (ret != SDR_OK) {
printf("error!\n");
} else {
printf("Issuer Name: %s\n", testdi.IssuerName);
printf("Device Name: %s\n", testdi.DeviceName);
printf("Device Serial: %s\n", testdi.DeviceSerial);
printf("Device Version: %d\n", testdi.DeviceVersion);
}
// 測試生成隨機數
unsigned char randomBytes[20]; // 用于存儲隨機數的緩沖區
// 測試1個字節
ret = SDF_GenerateRandom(*pdh, 1, randomBytes);
if (ret == SDR_OK) {
printf("1 byte of random: %x\n", randomBytes[0]);
} else {
printf("Generate random error!\n");
}
// 測試5個字節
memset(randomBytes, 0, sizeof(randomBytes)); // 清空緩沖區
ret = SDF_GenerateRandom(*pdh, 5, randomBytes);
printf("5 byte of random: ");
if (ret == SDR_OK) {
for (int i = 0; i < 5; i++) {
printf("%x ", randomBytes[i]);
}
printf("\n");
} else {
printf("Generate random error!\n");
}
// 測試20個字節
memset(randomBytes, 0, sizeof(randomBytes)); // 清空緩沖區
ret = SDF_GenerateRandom(*pdh, 20, randomBytes);
printf("20 byte of random: ");
if (ret == SDR_OK) {
for (int i = 0; i < 20; i++) {
printf("%x ", randomBytes[i]);
}
printf("\n");
} else {
printf("Generate random error!\n");
}
ret = SDF_CloseDevice(*pdh);
if (ret != SDR_OK) {
printf("error!\n");
} else {
free(pdh);
printf("device closed!\n");
}
return 0;
}
5 在test中的main.c調用SDF_GenerateRandom進行測試,至少測試1個字節,5個字節,20個字節三種情況
fengtairui@fengtairui-virtual-machine:~$ gcc -o test main.c sdf.c utils.c -lgmssl
fengtairui@fengtairui-virtual-machine:~$ ./test
device opened!
Issuer Name: RocSDF
Device Name: SDFBESTI181x
Device Serial: 2021040001
Device Version: 1
1 byte of random: c9
5 byte of random: 8a da 8e 43 d4
20 byte of random: 93 9d 59 de 7b fc ee b6 a8 dd ea 72 29 b7 a4 1a 78 b3 5f 85
device closed!
6 提交git log結果
fengtairui@fengtairui-virtual-machine:~$ git add sdf.h sdf.c main.c test
fengtairui@fengtairui-virtual-machine:~$ git commit -m "random"
[master 3f9e4d5] random
4 files changed, 171 insertions(+), 20 deletions(-)
create mode 100644 main.c
create mode 100755 sdf.h
create mode 100755 test
fengtairui@fengtairui-virtual-machine:~$ git log
commit 3f9e4d5873486a68477fedd41291c655d9aa89ff (HEAD -> master)
Author: fengtairui <1978274655@qq.com>
Date: Tue Dec 17 13:59:01 2024 +0800
random