GmSSL介绍
GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法。
从 GmSSL 官网处得到的下载链接为 GitHub - guanzhi/GmSSL: 支持国密SM2/SM3/SM4/SM9/SSL的密码工具箱
GmSSL的下载编译如下:
# git clone https://github.com/guanzhi/GmSSL.git
# cd GmSSL
# mkdir build
# cd build/
# cmake ..
# make
# ls bin/
aeadtest demo_sm2_encrypt demo_sm2_sign_ctx demo_sm4_cbc_encrypt_update demo_sm9_sign hash_drbgtest libsdf_dummy.so pemtest sm3test x509_exttest
aestest demo_sm2_keygen demo_sm3 demo_sm4_cbc_padding demo_zuc hextest libsdf_dummy.so.3 pkcs8test sm4test x509_oidtest
asn1test demo_sm2_keyparse demo_sm3_hmac demo_sm4_ctr digesttest hkdftest libsdf_dummy.so.3.1 sha224test sm9test x509_reqtest
base64test demo_sm2_private_key demo_sm3_kdf demo_sm4_ctr_encrypt_update ectest hmactest libskf_dummy.so sha256test tls13test x509_strtest
block_ciphertest demo_sm2_private_key_parse demo_sm4 demo_sm4_gcm gcmtest libgmssl.so libskf_dummy.so.3 sha384test tlstest x509test
chacha20test demo_sm2_public_key demo_sm4_cbc demo_sm9_encrypt gf128test libgmssl.so.3 libskf_dummy.so.3.1 sha512test x509_algtest zuctest
cmstest demo_sm2_sign demo_sm4_cbc_decrypt_update demo_sm9_keygen gmssl libgmssl.so.3.1 pbkdf2test sm2test x509_crltest
在编译过程中会遇到报错,为小错误,请自行修改
/home/GMSSL/GmSSL/src/sm9_alg.c: In function ‘sm9_fn_from_hash’:
/home/GMSSL/GmSSL/src/sm9_alg.c:2318:11: error: redeclaration of ‘i’ with no linkage
for (int i = 0; i < 10; i++) {
^
/home/GMSSL/GmSSL/src/sm9_alg.c:2315:6: note: previous declaration of ‘i’ was here
int i, j;
^
/home/GMSSL/GmSSL/src/sm9_alg.c:2318:2: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int i = 0; i < 10; i++) {
^
/home/GMSSL/GmSSL/src/sm9_alg.c:2318:2: note: use option -std=c99 or -std=gnu99 to compile your code
/home/GMSSL/GmSSL/src/sm9_alg.c:2319:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int j = 0; j < 4; j++) {
^
ZUC算法介绍
ZUC算法是一个面向字的流加密算法。算法介绍可见 ZUC-256 流密码算法
根据include/gmssl/zuc.h头文件里提供的算法接口,主要的算法接口有算法初始化,产生密钥流,加密。计算校验值等。其中ZUC根据塞入的key和iv,产生密钥流,算法加密即是将密钥流与明文进行异或操作得到密文,解密即是将密钥流与密文进行异或操作得到明文。接口分为zuc 128位算法与zuc 256位算法,即塞入的key与iv长度差异。
ZUC256算法实例
工程目录:
# ls
libgmssl.so libgmssl.so.3 Makefile test.c zuc.h
其中库和头文件是从上述编译好的GmSSL里拿出来的。
test.c
#include <stdio.h>
#include <string.h>
#include "zuc.h"
void dump_buf(char *info, uint8_t *buf, uint32_t len)
{
int i;
printf("%s[%d]", info, len);
for (i = 0; i < len; i++) {
printf("%s%02X%s", i % 16 == 0 ? "\n ":" ",
buf[i], i == len - 1 ? "\n":"");
}
}
int main()
{
int ret;
uint8_t key[32], iv[32];
uint32_t out[32];
uint8_t mac_out[4];
uint8_t msg[32];
ZUC256_STATE state;
ZUC256_MAC_CTX ctx;
/* stream */
memset(&state, 0x0, sizeof(ZUC256_STATE));
memset(key, 0x0, 32);
memset(iv, 0x0, 32);
memset(msg, 0xFF, 32);
zuc256_init(&state, key, iv);
zuc256_generate_keystream(&state, 32, out);
dump_buf("keystream out:", out, 32*4);
/* MAC */
memset(&ctx, 0x0, sizeof(ZUC256_MAC_CTX));
memset(key, 0x0, 32);
memset(iv, 0x0, 32);
memset(msg, 0xFF, 32);
zuc256_mac_init(&ctx, key, iv, ZUC256_MAC32_SIZE*8);
zuc256_mac_update(&ctx, msg, 32);
zuc256_mac_finish(&ctx, NULL, 0, mac_out);
dump_buf("mac32 out:", mac_out, 4);
return 0;
}
Makefile
test:
gcc -g test.c -I. -L. -lgmssl -o test
clean:
rm -rf test
编译并测试
# make
gcc -g test.c -I. -L. -lgmssl -o test
test.c: In function ‘main’:
test.c:37:5: warning: passing argument 2 of ‘dump_buf’ from incompatible pointer type [enabled by default]
dump_buf("keystream out:", out, 32*4);
^
test.c:6:6: note: expected ‘uint8_t *’ but argument is of type ‘uint32_t *’
void dump_buf(char *info, uint8_t *buf, uint32_t len)
^
# ./test
keystream out:[128]
D6 3A D0 58 E2 2C 03 2E 3A 68 FC DA 03 CB BD 39
67 BC A2 52 74 DE B7 F1 A1 E3 3C 16 58 55 EF 01
5B D7 39 96 1B 68 FA 95 F7 0D 09 7F CC 1C 39 56
12 76 3B 90 4C 54 4D 74 AD 3F BC 17 08 3B 16 8B
0B 7C 78 21 B8 5B 77 97 BB C6 43 49 FD 8A AD E8
B1 B2 FC 7D AB C9 CB 2B 2E FD 1B F4 FF 10 C8 16
DE 11 AB 8F 67 6C A6 76 DE 7C 50 45 E0 4B F0 21
62 75 FD 63 4E 84 80 62 5C 9E 8D D8 D9 8C 04 10
mac32 out:[4]
88 0D 51 7C