密钥管理工具接口
为了方便客户定制化管理密钥,提供了密钥管理工具接口供用户调用。
- 管理工具创建session用户。
int ECM_OpenSession(void *hDeviceHandle, void **phSessionHandle);
表1 参数说明 参数
描述
hDeviceHandle[in]
已打开的设备句柄。
phSessionHandle[out]
与密码设备已建立的会话句柄。
表2 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 创建设备内置密钥并设置密码。
int ECM_GenerateKey(void *hSessionHandle, unsigned int uiKeyIndex, unsigned char *pucPassword, unsigned int uiPwdLength);
表3 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,包括密钥类型与索引下标。
pucPassword[in]
使用私钥权限的标识码。
uiPwdLength[in]
使用私钥权限标识码的长度,范围8-128字节。
表4 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 删除指定内置密钥。
int ECM_DeleteKey(void *hSessionHandle, unsigned int uiKeyIndex);
表5 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
表6 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 查询内置密钥状态。
int ECM_QueryKey(void *hSessionHandle, unsigned int uiKeyIndex, unsigned int *uiKeyInfo);
表7 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
uiKeyInfo[out]
密码设备内置密钥信息。
- 0:密钥存在。
- 非0:密钥不存在。
表8 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 修改指定私钥的权限标识码。
int ECM_ChangePassword(void *hSessionHandle, unsigned int uiKeyIndex, unsigned char *prePassword, unsigned int prePasswordLen, unsigned char *newPassword, unsigned int newPasswordLen);
表9 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
prePassword[in]
当前使用私钥权限的标识码。
prePasswordLen[in]
当前私钥权限标识码的长度,范围8-128字节。
newPassword[in]
新设置的私钥权限标识码。
newPasswordLen[in]
新设置的私钥权限标识码长度,范围8-128字节。
表10 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 导出对应内置密钥。
int ECM_ExportKey(void *hSessionHandle, unsigned int uiKeyIndex, unsigned char *keyFileBuffer, unsigned int *keyBufferLength, unsigned char *keySalt);
表11 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
keyFileBuffer[out]
缓冲区指针,用于存放导出的内置密钥密文。
keyBufferLength[out]
导出的内置密钥密文长度。
keySalt[in]
加密盐值,最大长度16字节。
表12 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 导入密钥到指定索引下标。
int ECM_ImportKey(void *hSessionHandle, unsigned int uiKeyIndex, unsigned char *keyFileBuffer, unsigned int keyBufferLength, unsigned char *keySalt);
表13 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
keyFileBuffer[in]
缓冲区指针,用于存放准备导入的密钥密文。
keyBufferLength[out]
待导入的密钥密文长度。
keySalt[in]
解密盐值,最大长度16字节。
表14 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 设置可以访问内置密钥的应用路径。
int ECM_SetAccessRight(void *hSessionHandle, unsigned int uiKeyIndex, unsigned char *pucAccessInfo, unsigned char *pucPassword, unsigned int uiPwdLength);
表15 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
pucAccessInfo[in]
缓冲区指针,用于存放允许访问的应用hash值,长度固定32字节。
pucPassword[out]
使用私钥权限的标识码。
uiPwdLength[in]
使用私钥权限标识码的长度,长度8-128字节。
表16 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
CA应用的hash值计算方式为:SHA256(CA的路径||用户名),即CA路径拼接上用户名,再计算SHA256得到的值。注意用户名长度需固定为256字节,长度不足时需补零。
- 删除可以访问内置密钥的应用路径。
int ECM_DelAccessRight(void *hSessionHandle, unsigned int uiKeyIndex, unsigned char *pucAccessInfo, unsigned char *pucPassword, unsigned int uiPwdLength);
表17 参数说明 参数
描述
hSessionHandle[in]
与设备建立的会话句柄。
uiKeyIndex[in]
密码设备存储私钥的索引值,由密钥类型与索引下标组成。
pucAccessInfo[in]
缓冲区指针,用于存放允许访问的应用hash值,长度固定32字节。
pucPassword[out]
使用私钥权限的标识码。
uiPwdLength[in]
使用私钥权限标识码的长度,长度8-128字节。
表18 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
- 恢复出厂设置。
int ECM_FactoryReset();
表19 返回值说明 返回值
说明
0
成功。
非0
失败,返回错误码。
规格限制
集成这些接口的应用应以root用户执行,并只能在host上运行。
密钥管理接口示例
如下提供示例代码演示了上述接口的使用方式,以SM2用户密钥为例,包括密钥的创建、密钥标识码的修改、密钥访问权限路径添加与删除、导出导入密钥,删除密钥。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/sha.h> #include "sdf.h" #define MAX_KEY_FILE_SIZE (1024 * 1024) #define EXPORT_SALT "123456789" #define CA_PATH "./test_sdf" #define USER_NAME "root" #define PASSWD "Huawei123." #define NEWPASSWD "Huawei321." #define ALG_FLAG_OFFSET 20 int generate_key(void *session, unsigned int key_id, unsigned char *password) { int ret; // sm2签名及加密密钥 unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id; unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id; ret = ECM_GenerateKey(session, sign_info, password, strlen(password)); if (ret != SDR_OK) { printf("ECM_GenerateKey sign key failed, ret = 0x%x\n", ret); return ret; } ret = ECM_GenerateKey(session, enc_info, password, strlen(password)); if (ret != SDR_OK) { printf("ECM_GenerateKey enc key failed, ret = 0x%x\n", ret); return ret; } return ret; } int delete_key(void *session, unsigned int key_id) { int ret; unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id; unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id; ret = ECM_DeleteKey(session, sign_info); if (ret != SDR_OK) { printf("ECM_DeleteKey key_index %d failed, ret = 0x%x\n", key_id, ret); return ret; } ret = ECM_DeleteKey(session, enc_info); if (ret != SDR_OK) { printf("ECM_DeleteKey key_index %d failed, ret = 0x%x\n", key_id, ret); } return ret; } int export_import_key(void *session, unsigned int key_id1, unsigned int key_id2) { int ret = -1; uint8_t *key_data = NULL; uint32_t key_data_len = MAX_KEY_FILE_SIZE; unsigned int sign_key_info1 = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id1; unsigned int sign_key_info2 = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id2; unsigned int enc_key_info1 = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id1; unsigned int enc_key_info2 = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id2; key_data = (uint8_t *)malloc(key_data_len); if (key_data == NULL) { printf("malloc failed\n"); return -1; } // 导出导入签名密钥 ret = ECM_ExportKey(session, sign_key_info1, key_data, &key_data_len, EXPORT_SALT); if (ret) { printf("ECM_ExportKey sign key failed, ret = 0x%x, %d\n", ret, key_data_len); goto free; } ret = ECM_ImportKey(session, sign_key_info2, key_data, key_data_len, EXPORT_SALT); if (ret) { printf("ECM_ImportKey sign key failed, ret = 0x%x\n", ret); goto free; } // 导出导入加密密钥 ret = ECM_ExportKey(session, enc_key_info1, key_data, &key_data_len, EXPORT_SALT); if (ret) { printf("ECM_ExportKey enc key failed, ret = 0x%x, %d\n", ret, key_data_len); goto free; } ret = ECM_ImportKey(session, enc_key_info2, key_data, key_data_len, EXPORT_SALT); if (ret) { printf("ECM_ImportKey enc key failed, ret = 0x%x\n", ret); goto free; } free: free(key_data); return ret; } int change_passwd(void *session, unsigned int key_id, char *passwd, char *new_passwd) { int ret; unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id; unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id; ret = ECM_ChangePassword(session, sign_info, passwd, strlen(passwd), new_passwd, strlen(new_passwd)); if (ret != SDR_OK) { printf("ECM_ChangePassword sign key failed, ret = 0x%x\n", ret); return ret; } ret = ECM_ChangePassword(session, enc_info, passwd, strlen(passwd), new_passwd, strlen(new_passwd)); if (ret != SDR_OK) { printf("ECM_ChangePassword sign key failed, ret = 0x%x\n", ret); } return ret; } void calculate_cainfo(const char *ca_path, const char *user_name, unsigned char hash[32]) { char plan[256] = {0}; memcpy(plan, user_name, strlen(user_name)); SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, ca_path, strlen(ca_path)); SHA256_Update(&sha256, plan, 256); SHA256_Final(hash, &sha256); for (size_t i = 0; i < 32; i++) { printf("%02x", hash[i]); } printf("\n"); } int set_ca_access_right(void *session, unsigned int key_id, char *ca_path, char *user_name, char *passwd) { int ret; unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id; unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id; unsigned char hash[32] = {0}; unsigned char hash2[32] = {0}; calculate_cainfo(ca_path, user_name, hash); ret = ECM_SetAccessRight(session, sign_info, hash, passwd, strlen(passwd)); if (ret != SDR_OK) { printf("ECM_SetAccessRight sign key failed, ret = 0x%x\n", ret); return ret; } ret = ECM_SetAccessRight(session, enc_info, hash, passwd, strlen(passwd)); if (ret != SDR_OK) { printf("ECM_SetAccessRight sign key failed, ret = 0x%x\n", ret); } return ret; } int delete_ca_access_right(void *session, unsigned int key_id, char *ca_path, char *user_name, char *passwd) { int ret; unsigned int sign_info = SDF_SM2_SIGN << ALG_FLAG_OFFSET | key_id; unsigned int enc_info = SDF_SM2_ENC << ALG_FLAG_OFFSET | key_id; unsigned char hash[32] = {0}; calculate_cainfo(ca_path, user_name, hash); ret = ECM_DelAccessRight(session, sign_info, hash, passwd, strlen(passwd)); if (ret != SDR_OK) { printf("ECM_SetAccessRight sign key failed, ret = 0x%x\n", ret); return ret; } ret = ECM_DelAccessRight(session, enc_info, hash, passwd, strlen(passwd)); if (ret != SDR_OK) { printf("ECM_SetAccessRight sign key failed, ret = 0x%x\n", ret); } return ret; } int main() { int ret = -1; int key_idx1 = 1, key_idx2 = 2; void *device = NULL, *session = NULL; ret = SDF_OpenDevice(&device); if (ret != SDR_OK) { printf("sdf open device failed, ret = 0x%x\n", ret); return ret; } ret = ECM_OpenSession(device, &session); if (ret != SDR_OK) { printf("sdf open session failed, ret = 0x%x\n", ret); goto close; } ret = generate_key(session, key_idx1, PASSWD); if (ret != SDR_OK) { printf("generate_key failed, ret = 0x%x\n", ret); goto close; } printf("generate key success\n"); // 修改密码 ret = change_passwd(session, key_idx1, PASSWD, NEWPASSWD); if (ret != SDR_OK) { printf("chage key passwd failed, ret = 0x%x\n", ret); goto close; } printf("change passwd success\n"); // 添加CA访问权限 ret = set_ca_access_right(session, key_idx1, CA_PATH, USER_NAME, NEWPASSWD); if (ret != SDR_OK) { printf("set ca access right failed, ret = 0x%x\n", ret); goto close; } printf("set ca path success\n"); // 删除CA访问权限。 ret = delete_ca_access_right(session, key_idx1, CA_PATH, USER_NAME, NEWPASSWD); if (ret != SDR_OK) { printf("delete ca access right failed, ret = 0x%x\n", ret); goto close; } printf("delete ca path success\n"); // 导入密钥到key_idx2 ret = export_import_key(session, key_idx1, key_idx2); if (ret != SDR_OK) { printf("export_import_key failed, ret = 0x%x\n", ret); goto close; } printf("export key %d, import to key %d success\n", key_idx1, key_idx2); ret = delete_key(session, key_idx1); if (ret != SDR_OK) { printf("ECM_DeleteKey failed, ret = 0x%x\n", ret); goto close; } ret = delete_key(session, key_idx2); if (ret != SDR_OK) { printf("ECM_DeleteKey failed, ret = 0x%x\n", ret); goto close; } printf("delete key success\n"); close: if (session != NULL) { (void)SDF_CloseSession(session); } if (device != NULL) { (void)SDF_CloseDevice(device); } return ret; }