
1. 概述
本文重要合用于已下载国民技术N32S003 芯片SM2国密算法的介绍,重要注明该类芯片中国密SM2算法接口和使用步骤。
1.1. 支持的算法
N32S003 芯片提供的算法如下:
? SM4: ECB/CBC 加密/解密
? SM3: 获取提要
? SM2: 加密/解密/署名/验证/密钥协商/密钥天生
? RNG: 随机数天生
1.2. 根基数据类型
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned INT64 uint64_t;
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed INT64 int64 t;
2. SM2算法API注明
2.1. 算法库使用步骤
算法库使用步骤如下:
1. 将 SM2.h、HASH.h、RNG.h、Common.h 参与头文件夹中,将 RNG.lib 、Common.lib、HASH.lib、SM2.lib 增长到工程中;
2. 按 3.3 节函数注明挪用函数,例程见附录二提供的 demo。
2.2. 数据类型界说
enum{
SM2_OK = 0x5a5a5a5a, // operation success
SM2_PointIsOnCrv_YES = 0x6a6a5a5a, //point is on elliptic curve
SM2_PointIsOnCrv_NOT = 0x5a5a6a6a, //point is not on elliptic curve
SM2_PRIKEY_ERR,//prikey error
SM2_PUBKEY_ERR,//pubkey error
SM2_CONVERTION_ERR,//data type transfer error
SM2_Verify_FAIL,//SM2 verify fail
SM2_LengthErr, //length error
SM2_AddrErr, //address error
SM2_ROLE_ERR,//Role in key exchange is error
SM2_ATTACKED, //SM2 subject to attack
};
2.3. 函数接口注明
SM2 算法库蕴含的函数列表如下:
表 2-1 SM2 算法库函数表
函数 | 描述 |
32_ | 初始化 uinttSM2_GetKey(uint8_t priKey[32], uint8_t pubKey[65])SM2 密钥对函数 |
3 | 由私钥获取公钥 |
32 | 判断点是否在曲线上 |
8 |
署名函数 |
| 验证函数 |
3, 88 8 |
密钥互换 |
32
| 身份标识杂凑值推算函数 |
32 8 | 消息的 uint2_t SM2_EncryptInit(uint8_t pubKey[65], uint8_t C1[65])SM 分步加密初始化函数 |
32 8 | 2 分步加密更新函数 |
| 2 分步加密实现函数 |
32 [65] |
单次加密函数 |
| 2uinttSM2_DecryptUpdate(uint8_t* C2, uint32_t C2ByteLen,uint_t* M)SMuint2_t SM2_DecryptDone(uint8_t C3[32])SMuint_t SM2_Decrypt(uint8_t * C, uint32_t CByteLen, uint8_tpriKey2], uint8_t * M, uint32_t *MByteLen)voidSM2_Close(void)SM2 函数 |
2 8 | 获取 SM2 算法库版本
|
2.3.1.初始化SM2?
SM2_Init | 初始化SM2? |
函数原型 | void SM2_Init(void) |
参数注明 |
|
返回值 | SM2_OK:初始化成功;其他值:初始化失败,详见枚举类型界说 |
当苦衷项 | 1. 进行SM2运算时,若还未初始化或已切换到其他算法,必须先挪用此函数来 开启SM2?。 |
2.3.2.密钥对天生
SM2_GetKey | 随机密钥对天生 |
函数原型 | uint32_t SM2_GetKey(uint8_t priKey[32], uint8_t pubKey[65]) |
参数注明 | priKey 输出,私钥,字节大端输出,即高位在前低位在后 pubKey 输出,公钥,字节大端输出,首字节是 0x04,而后别离是 x|y 坐标 |
返回值 | SM2_OK:运算正确;其他值:推算谬误,详见枚举类型界说 |
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ?; 2.私钥即一大数,要求必须在[1,n-2]中,n 是 SM2 曲线参数。 |
2.3.3.私钥天生公钥
SM2_GetPubKey | 私钥天生公钥 |
函数原型 | uint32_t SM2_GetPubKey(uint8_t priKey[32], uint8_t pubKey[65]) |
参数注明 | priKey 输入,私钥,字节大端输入,即高位在前低位在后 pubKey 输出,公钥,字节大端输出,首字节是 0x04,而后别离是 x|y 坐标 |
返回值 | SM2_OK:运算正确;其他值:推算谬误,详见枚举类型界说 |
当苦衷项 | 1.挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ? 2. 私钥即一大数,要求必须在[1,n-2]中,n 是 SM2 曲线参数
|
2.3.4. 判断点是否在曲线上
SM2_PointisOnCurve | 判断点是否在曲线上 |
函数原型 | uint32_t SM2_PointisOnCurve(uint8_t Point[64]) |
参数注明 | Point输入, 点坐标(x|y) ,x 与 y 均为字节大端输入 |
返回值 | SM2_PointIsOnCrv_YES :点在曲线上;其他值: 谬误,详见枚举类型界说 |
当苦衷项 | 1.挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ? |
2.3.5. 署名天生
SM2_Sign | 署名天生 |
函数原型 | uint32_t SM2_Sign(uint8_t E[32], uint8_t priKey[32], uint8_t r[32], uint8_t s[32]) |
参数注明 | E 输入,待署名新闻的 HASH 值 priKey 输入,署名者的私钥 r 输出,署名了局 s 输出,署名了局
|
返回值 | SM2_OK:运算正确;其他值:推算谬误,详见枚举类型界说 |
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ?; 2. E 或 prikey 存储介质可以为 RAM 或 FLASH; 3. 若 E 或 prikey 为 RAM 存储,则署名了局 r 和 s 能够复用此空间,但需保障空间足够; 4. prikey 要求必须在[1,n-1]中。 |
2.3.6. 署名验证
SM2_Verify | 署名验证 |
函数原型 | uint32_t SM2_Verify(uint8_t E[32], uint8_t pubKey[65], uint8_t r[32], uint8_t s[32]) |
参数注明 | E 输入,待署名新闻的 HASH 值 pubKey 输入,署名者的公钥 r 输入,署名了局 s 输入,署名了局
|
返回值 | SM2_OK:运算正确;其他值:推算谬误,详见枚举类型界说 |
当苦衷项 | 1.挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ? 2. E 或 pubKey 存储介质可以为 RAM 或 FLASH |
2.3.7. 密钥协商(互换)
SSM2_ExchangeKey | 密钥协商(互换) |
函数原型 | uint32_t SM2_ExchangeKey(uint8_t role, uint8_t *IDA, uint32_t IDAByteLen, uint8_t *IDB, uint32_t IDBByteLen, uint8_t dA[32], uint8_t PA[65],uint8_t PB[65], uint8_t rA[32], uint8_t RA[65], uint8_t RB[65], uint32_t kByteLen, uint8_t *KA, uint8_t S1[32], uint8_t SA[32]) |
参数注明 | role 输入,角色,1-提议者,0-接受者 IDA 输入,提议方 ID IDAByteLen 输入,IDB 的字节数 IDB 输入,接受方 ID IDBByteLen 输入,IDB 的字节数 dA[32] 输入,己方私钥 PA[65] 输入,己方公钥 PB[65] 输入,对方公钥 rA[32] 输入,己方一时私钥 RA[65] 输入,己方一时公钥 RB[65] 输入,对方一时公钥 kByteLen 输入,协商密钥字节长度 KA [kByteLen] 输出,协商密钥 S1 [32] 输出,己方 S1 值 SA [32] 输出,己方 SA 值 |
返回值 | SM2_OK:运算正确;其他值:推算谬误,详见枚举类型值界说 |
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ? 2. 若是推算后的 S1=SB,S2=SA,则密钥互换成功,协商后的密钥为 KA 3. dA、PB、rA、RA、RB、ZA、ZB 存储介质可以为 RAM 或 FLASH 4. 输出参数 KA、S1、SA 不能和输入参数 dA、PB、rA、RA、RB、ZA、ZB 使用统一 buffer。 |
2.3.8. 用户杂凑值
SSM2_GetZy | 用户身份标识杂凑值推算函数 |
函数原型 | uint32_t SM2_GetZ(uint8_t* ID, uint16_t IDByteLen, uint8_t pubKey[65], uint8_t Z[32])
|
参数注明 | ID 输入,用户 A 的 ID IDByteLen 输入,用户 A 的 ID 的字节数- 22 - Pubkey 输入,用户 A 的公钥,65 字节 Z[32] 输出,用户 A 的杂凑值,32 字节 |
返回值 | SM2_OK:推算成功,其他值:推算谬误,详见枚举类型值界说 |
当苦衷项 | 1.切合 SM2 算法尺度 2.挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ? 3.运算实现后,本函数内部已再次挪用 SM2_Init()启动 SM2 ?。 |
2.3.9. 新闻杂凑值
SSM2_GetEy | 新闻的杂凑值推算函数 |
函数原型 | uint32_t SM2_GetE(uint8_t* M, uint32_t MByteLen, uint8_t Z[32], uint8_t E[32])
|
参数注明 | M 输入,待署名验证新闻 MByteLen 输入,待署名验证新闻的字节数 Z 输入,署名者的 ID 杂凑值 E 输出,输入值 M 与 Z 的杂凑值,32 字节
|
返回值 | SM2_OK:推算成功, 其他值:推算谬误,详见枚举类型值界说 |
当苦衷项 | 1.切合 SM2 算法尺度; 2. 运算实现后,本函数内部已再次挪用 SM2_Init()启动 SM2 ?。 |
2.3.10. 分步加密初始化函数
SM2_EncryptInity | SM2 分步加密初始化函数 |
函数原型 | uint32_t SM2_EncryptInit(uint8_t pubKey[65], uint8_t C1[65]) |
参数注明 | Pubkey 输入,公钥 C1 输出,密文的第一组成部门
|
返回值 | SM2_OK:推算成功, 其他值:推算谬误,详见枚举类型值界说 |
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ?; 2. pubkey 存储介质可以为 RAM 或 FLASH; 3. pubkey 和 C1 也不能是统一 buffer; 4.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.11. 分步加密更新函数
SM2_EncryptUpdate | SM2 分步加密更新函数 |
函数原型 | uint32_t SM2_EncryptUpdate(uint8_t* M, uint32_t MByteLen, uint8_t* C2)
|
参数注明 | M 输入,待加密新闻 MByteLen 输入,新闻的字节数 C2 输出,密文的第二组成部门,长杜纂 MByteLen 一样
|
返回值 | SM2_OK:运算正确, 其他值:推算谬误,详见枚举类型值界说 |
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ?,且需与 SM2_EncryptInit 共同使用; 2. M 存储介质可以为 RAM 或 FLASH; 3. M 和 C2 可所以统一 buffer; 4.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.12. 分步加密实现函数
SM2_EncryptDone | SM2 分步加密实现函数 |
函数原型 | uint32_t SM2_EncryptDone(uint8_t C3[32]
|
参数注明 | C3 输出,密文的第三组成部门 |
返回值 | SM2_OK:加密正确; 其他值:推算谬误,详见枚举类型值界说
|
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ?,且需与 SM2_EncryptInit、SM2_EncryptUpdate 共同使用; 2.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。 |
2.3.13. 单次加密
SM2_Encrypt | SM2 单次加密函数 |
函数原型 | uint32_t SM2_Encrypt(uint8_t *M, uint32_t MByteLen, uint8_t pubKey[65], uint8_t *C, uint32_t *CByteLen) |
参数注明 | M 输入,明文 MByteLen 输入,明文的字节长度,0< MByteLen < (232 -97) Pubkey 输入,公钥 C 输出,密文 CByteLen 输出,密文的字节长度,应为(MByteLen +97)
|
返回值 | SM2_OK:运算正确; 其他值:推算谬误,详见枚举类型值界说
|
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ?; 2. M 或 pubkey 存储介质可以为 RAM 或 FLASH; 3. M 和 C 不能是统一 buffer;pubkey 和 C 也不能是统一 buffer; 4.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.14. 分步解密初始化函数
SSM2_DecryptInit | SM2 分步解密初始化函数 |
函数原型 | uint32_t SM2_DecryptInit(uint8_t priKey[32], uint8_t C1[65]) |
参数注明 | priKey 输入,私钥 C1 输入,密文的第一组成部门
|
返回值 | SM2_OK:运算正确; 其他值:推算谬误,详见枚举类型值界说
|
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ?; 2. priKey 存储介质可以为 RAM 或 FLASH; 3.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.15. 分步解密更新函数
SM2_DecrypUpdate | SM2 分步解密更新函数 |
函数原型 | uint32_t SM2_DecryptUpdate(uint8_t* C2, uint32_t C2ByteLen, uint8_t* M) |
参数注明 | C2 输入,密文的第二组成部门 C2ByteLen 输入,C2 的字节数 M 输出,新闻,长杜纂 C2ByteLen 一样
|
返回值 | SM2_OK:运算正确; 其他值:推算谬误,详见枚举类型值界说
|
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动 SM2 ?,且需与 SM2_DecryptInit 共同使用; 2. C2 存储介质可以为 RAM 或 FLASH; 3. M 和 C2 可所以统一 buffer; 4.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.16. 分步解密实现函数
SSM2_DecrypDone | SM2 分步解密实现函数 |
函数原型 | uint32_t SM2_DecryptDone(uint8_t C3[32]) |
参数注明 | C3 输入,密文的第三组成部门
|
返回值 | SM2_OK:解密正确; 其他值:推算谬误,详见枚举类型值界说
|
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ?,且需与 SM2_DecryptInit、SM2_DecryptUpdate 共同使用; 2.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.17. 单次解密
SSM2_Decrypt | SM2 单次解密 |
函数原型 | uint32_t SM2_DecryptDone(uint8_t C3[32]) |
参数注明 | C3 输入,密文的第三组成部门
|
返回值 | SM2_OK:解密正确; 其他值:推算谬误,详见枚举类型值界说
|
当苦衷项 | 1. 挪用本函数前,若还未初始化或已切换到其他算法,先挪用 SM2_Init()启动SM2 ?,且需与 SM2_DecryptInit、SM2_DecryptUpdate 共同使用; 2.依照新的国密规范,密文挨次从 C1||C2||C3 建改为 C1||C3||C2。
|
2.3.18. 关关SM2?
SSM2_Close | 关关 SM2 ? |
函数原型 |
|
参数注明 |
|
返回值 |
|
当苦衷项 | 1. SM2 运算完后,可挪用本函数关关 SM2 ?。 |
2.3.19. 获取SM2库版本信息
SSM2_Version | 获取 SM2 库版本信息 |
函数原型 | void SM2_Version(uint8_t *type, uint8_t *customer, uint8_t date[3], uint8_t*version) |
参数注明 | type 贸易或安全版本 customer 尺度或定造版本 date 年,月,日 version //版本 x.x
|
返回值 |
|
当苦衷项 | *type = 0x03; // 贸易和安全版 *customer = 0x00; // 尺度版本 date[0] = 18; //Year() date[1] = 12; //Month() date[2] = 28; //Day () *version = 0x10; //暗示版本 1.0
|
关注微信号,惊喜等你来
x