实验3-2
4-6 学时实践要求(30 分)
- 在 Ubuntu或openEuler中(推荐 openEuler)中调用GmSSL代码,至少实现SM2,SM3,SM4相关密码算法接口,使用Markdown记录详细记录实践过程,每完成一项功能或者一个函数git commit 一次。(10分)
- 在 Ubuntu或openEuler中(推荐 openEuler)中调用GmSSL代码,实现SM2,SM4相关接口密钥管理功能及其他必要接口。使用Markdown记录详细记录实践过程,每完成一项功能或者一个函数git commit 一次。(10分)
- 使用 Rust 实现相关接口(选做,10 分)
- 实验记录中提交 gitee 课程项目链接,提交本次实验相关 git log运行结果。
- 提交要求:
- 提交实践过程Markdown和转化的PDF文件
- 代码,文档托管到gitee或github等,推荐 gitclone
- 记录实验过程中遇到的问题,解决过程,反思等内容,用于后面实验报告
- 实验过程文档GitHub链接
完成gmt0018中对称加密解密,非对称加密解密,签名验签,hash运算,MAC运算接口(5选1)
接口放入sdf.h,实现内容实现sdf.c,testsdf.c
1.实践完成hash运算接口
参考代码来源
- 测试代码可用性
user@user-VirtualBox:~/shiyan/shiyan3/SoftSDF-main$ gcc -o test softsdftest.c softsdf.c -lgmssl
user@user-VirtualBox:~/shiyan/shiyan3/SoftSDF-main$ ./test
test ok
SDF_HashInit 声明与实现(初始化哈希上下文)
- 声明
int SDF_HashInit(
void *hSessionHandle,
unsigned int uiAlgID,
ECCrefPublicKey *pucPublicKey,
unsigned char *pucID,
unsigned int uiIDLength);
- 实现
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;
}
SDF_HashUpdate 声明与实现(更新哈希数据)
- 声明
int SDF_HashUpdate(
void *hSessionHandle,
unsigned char *pucData,
unsigned int uiDataLength);
- 实现
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;
}
SDF_HashFinal 声明与实现(完成哈希计算并获取最终结果)
- 声明
int SDF_HashFinal(void *hSessionHandle,
unsigned char *pucHash,
unsigned int *puiHashLength);
- 实现
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;
}
测试结果
- 测试代码
#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 gmssl
sm3_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;
}
- 结果
user@user-VirtualBox:~/shiyan/shiyan3/SoftSDF-main$ ls
CMakeLists.txt README.md sgd.h softsdf.exp softsdf.lds test
LICENSE sdf.h softsdf.c softsdfinit.c softsdftest.c
user@user-VirtualBox:~/shiyan/shiyan3/SoftSDF-main$ gcc -o test softsdftest.c softsdf.c -lgmssl
user@user-VirtualBox:~/shiyan/shiyan3/SoftSDF-main$ ./test
test ok
- 结果说明
通过 SoftSDF 库实现的 SM3 哈希计算功能与 GMSSL 库中直接使用 SM3 算法计算得到的哈希值完全一致,从而验证了 SoftSDF 库中哈希运算相关接口(SDF_HashInit、SDF_HashUpdate、SDF_HashFinal)的正确性和可靠性。
2.实践实现MAC运算接口
SDF_CalculateMAC函数声明与实现
- 声明
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);
- 实现
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;
}