1.7 加密解密示例代码
#include <string.h>
#include "openssl/evp.h"
typedef struct sm4_test_vector_st
{
int enc_time;//反复加密次数
int pt_ct_len;
const EVP_CIPHER *mode;
unsigned char key[16];//16 bytes
unsigned char iv[16]; //16 bytes
unsigned char pt[32];
unsigned char ct[32];
}sm4_test_vector;
int test_sm4()
{
EVP_CIPHER_CTX ctx;
const EVP_CIPHER *cipher = NULL;
unsigned char ct[256]={0}, pt[256]={0};
unsigned char *p_in = NULL, *p_in_cst = NULL, *p_out = NULL, *p_out_calc = NULL;
int b_enc;
int ret, i,j, k, inlen,outlen,ctlen, totallen=0, operate_len;
sm4_test_vector vct[]={
{/*测试向量*/
/*次数*/ 1, /*长度*/ 16, /*mode*/ EVP_sm4_ecb(),
/*密钥*/ { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10},
/* IV */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
/*明文*/ { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10},
/*密文*/ { 0x68,0x1e,0xdf,0x34,0xd2,0x06,0x96,0x5e,0x86,0xb3,0xe9,0x4f,0x53,0x6e,0x42,0x46},
},
{/*测试向量*/
/*次数*/ 1, /*长度*/ 32, /*mode*/ EVP_sm4_cbc(),
/*密钥*/ { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10},
/* IV */ { 0XEB,0XEE,0XC5,0X68,0X58,0XE6,0X04,0XD8,0X32,0X7B,0X9B,0X3C,0X10,0XC9,0X0C,0XA7},
/*明文*/ { 0X01,0X23,0X45,0X67,0X89,0XAB,0XCD,0XEF,0XFE,0XDC,0XBA,0X98,0X76,0X54,0X32,0X10,
/* */ 0X29,0XBE,0XE1,0XD6,0X52,0X49,0XF1,0XE9,0XB3,0XDB,0X87,0X3E,0X24,0X0D,0X06,0X47 },
/*密文*/ { 0X3F,0X1E,0X73,0XC3,0XDF,0XD5,0XA1,0X32,0X88,0X2F,0XE6,0X9D,0X99,0X6C,0XDE,0X93,
/* */ 0X54,0X99,0X09,0X5D,0XDE,0X68,0X99,0X5B,0X4D,0X70,0XF2,0X30,0X9F,0X2E,0XF1,0XB7},
}
};
printf("\n************************************************************\n");
printf("开始测试SM4算法\n\n");
cipher = EVP_sm4_ecb();
EVP_CIPHER_CTX_init(&ctx);
for (i = 0;i<sizeof(vct)/sizeof(vct[0]);i++)
{
printf("---------------------------------------------\n" );
for (k = 0;k<2;k++)//k==0 是加密,否则是解密
{
printf(".............................\n" );
b_enc = (k==0);
p_out = p_out_calc = b_enc ? ct : pt;
p_in = p_in_cst = b_enc ? vct[i].pt : ct;
operate_len = b_enc ? vct[i].pt_ct_len : ctlen;
inlen = operate_len;//1; //16
ret = b_enc ?
EVP_EncryptInit_ex(&ctx, vct[i].mode, NULL, vct[i].key, vct[i].iv)
: EVP_DecryptInit_ex(&ctx, vct[i].mode, NULL, vct[i].key, vct[i].iv);
for(j=0;j < operate_len; j += inlen)
{
ret = b_enc ?
EVP_EncryptUpdate(&ctx,p_out,&outlen,p_in,inlen)
: EVP_DecryptUpdate(&ctx,p_out,&outlen,p_in,inlen);
p_in += inlen;
p_out += outlen;
}
ret = b_enc ?
EVP_EncryptFinal_ex(&ctx,p_out,&outlen)
: EVP_DecryptFinal_ex(&ctx,p_out,&outlen);
p_out += outlen;
ctlen = totallen = p_out - p_out_calc;
ret = EVP_CIPHER_CTX_cleanup(&ctx);
ret = ( memcmp( b_enc?vct[i].ct:vct[i].pt, p_out_calc, vct[i].pt_ct_len ) == 0 );
printf("结果正确:%s\n", (ret==1) ? "yes":"no");
if(ret!=1)
{
printf("%s结果长度:%d\n",b_enc? "加密":"解密", totallen);
print_dbg_data( p_in_cst, operate_len, "input" );
print_dbg_data( b_enc?vct[i].ct:vct[i].pt, vct[i].pt_ct_len, "right output" );
print_dbg_data( p_out_calc, totallen, "calc output" );
}
}
}
printf("SM4算法测试完毕\n\n");
return 0;
}