文章目录
前言
本文主要有两部分,第一部分是主要是总结一些算法的特点,
第二部分是源代码,主要是基于GMSSL库的正确性测试和性能测试
GmSSL项目是OpenSSL项目的分支,并与OpenSSL保持接口兼容。因此GmSSL可以替代应用中的OpenSSL组件,并使应用自动具备基于国密的安全能力。
一、对称算法
这些东西网上已经很多总结的比较精炼的,我这里直接引用,也不做赘述
1.1对称加密算法常用的五种分组模式(ECB/CBC/CFB/OFB/CTR)
讲的很通俗易懂,很详细 大家可以直接跳转阅读
详解
1.2 3DES对称算法之双倍长密钥算法和三倍长密钥算法
二、RSA
2.1 算法描述
1. 选择两个大素数,q,p 对外保密,
2.计算 n = q * p, n公开
3.∮(n) = (p?1)?(q?1), ∮(n)保密
4.随机选一个e值 e由于是作加密使用,故推荐使用小值,一般使用65537(216+1),65537只有两个bit,加密做幂运算的时候速度比较快
5.ed = 1* mod(∮(n)); 得出d值
6.公钥(n,e) 私钥(n,d)
明文 c = m^e * mod(n);
密文m = c^e * mod(n);
2.2 中国剩余定理
作用:RSA解密操作中最耗时的地方就是解密计算c^d ,该定理主要作用就是通过降幂来一定程度下降低解密耗时
重新计算私钥:
dp = d \mod {p-1}
dq = d \mod {q-1}
qinv = q^{-1} \mod p
这样最后的私钥就是(p,q,d,dp,dq,qinv)
解密
m1=c^dp * mod§
m2=c^dq * mod(q)
h=qinv(m1?m2)mod§
m=m2+hq m即为明文
这样做虽然要计算两次模幂,但效率依然要比直接计算高得多。因为不管是指数还是模数都要小得多.
2.3特性
- 密钥长度增长一倍,公钥操作所需时间增加约4倍,私钥操作所需时间增加约8倍,公私钥生成时间约增长16倍。
- 一次能加密的密文长度与公钥长度成正比,如RSA1024,一次能加密的内容长度为 1024/8 =128byte(包含填充字节)。所 以非对称加密一般都用于加密对称加密算法的密钥,而不是直接加密内容。
- 加密后密文的长度为公钥的长度,例如公钥长度为1024Bit(128Byte),最后生成的密文固定为 1024Bit(128Byte)。
三、哈希
(此处以sha1为例),哈希算法使用起来很简单 可以直接调用sha1函数计算摘要,他使用起来很简单,
但是在32位系统下可以访问的内存空间不能超过4G, 所以openssl还提供另一套API
调用流程如下:
int SHA1_Init(SHA_CTX *c);
int SHA1_Update(SHA_CTX *c, const void *data, unsigned long len);
int SHA1_Final(unsigned char *md, SHA_CTX *c);
SHA1_Init主要是用来初始化SHA_CTX 结构体,该结构体里存储了一些计算散列值的参数和基本相信,可以不关心。
32位情况下,当需要计算摘要的文件大小为5个G的时候,我们可以把文件分割为若干个小块,
在分别调用SHA1_Update函数,最后在调用SHA1_Final生成散列值即可,
看一下例子
byte buffer[10] = {"123456789"};
//假如我们要需要计算buffer的散列值
char md[SHA_DIGEST_LENGTH];
SHA_CTX shactx;
SHA1_Init(&shactx);
SHA1_Update(&shactx, buffer,5);
SHA1_Update(&shactx, buffer+5, 4);
SHA1_Final(md, &shactx);
//上述代码等价于
char md[SHA_DIGEST_LENGTH];
SHA_CTX shactx;
SHA1_Init(&shactx);
SHA1_Update(&shactx, buffer,9);
SHA1_Final(md, &shactx);
四、 代码
主要包含了 对称算法:sm4 ,des,3des,aes, 非对称算法:sm2,rsa , 哈希算法的正确性验证和性能测试。
#include <pthread.h>
#include "openssl/sms4.h"
#include "openssl/des.h"
#include "openssl/aes.h"
#include "openssl/sm2.h"
#include "openssl/rsa.h"
#include "openssl/sm3.h"
#include "openssl/md4.h"
#include "openssl/md5.h"
#include "openssl/sha.h"
#include "openssl/err.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#define sleep(n) usleep(n * 1000)
typedef unsigned char byte;
long getms(struct timeval begin,struct timeval end);
//ascii to hex
int asciitohex(const byte *pIn, int iInLen, byte *pOut)
{
int i = 0;
uint8_t highByte, lowByte;
if (iInLen < 2)
{
return 0;
}
int len = iInLen / 2;
for (i = 0; i < iInLen; i += 2)
{
highByte = toupper(pIn[i]);
lowByte = toupper(pIn[i + 1]);
if (highByte > 0x39)
{
highByte -= 0x37;
}
else
{
highByte -= 0x30;
}
if (lowByte > 0x39)
{
lowByte -= 0x37;
}
else
{
lowByte -= 0x30;
}
pOut[i / 2] = (highByte << 4) | lowByte;
}
return len;
}
int hextoascii(const byte* pIn, int iInLen, byte* pOut)
{
int i, j;
for (i = 0, j = 0; j < iInLen; j++, i=i+2)
{
if ( (pIn[j]/16) > 9 )
{
pOut[i] = (pIn[j]/16) + '0' + 7;
}
else
{
pOut[i] = (pIn[j]/16) + '0';
}
if ( (pIn[j]%16) > 9 )
{
pOut[i+1] = (pIn[j]%16) + '0' + 7;
}
else
{
pOut[i+1] = (pIn[j]%16) + '0';
}
}
pOut[iInLen * 2] = '\0';
return iInLen * 2;
}
//加密填充,不足16字节末尾填充全0至
int sms4_padding(const byte * input, int inputlen, byte * output, int * outputlen)
{
if(NULL == input || inputlen <= 0 || NULL == output || NULL == outputlen)
{
return -1;
}
*outputlen = inputlen;
memcpy(output, input, inputlen);
if(inputlen % 16 != 0)
{
int paddlen = 16 - inputlen % 16;
printf("paddlen:%d\n", paddlen);
*outputlen += paddlen;
const byte * c_zore = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
//const byte * c_zore = "0000000000000000";
memcpy(output + inputlen, c_zore, paddlen);
}
return 0;
}
int test_des_ecb(byte * intput, int inlen, byte* output, int * outlen, int nmode);
int test_des_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_3des_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_3des_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_sm4_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_sm4_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_aes128_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_aes128_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_aes256_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_aes256_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_sm2_enc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_sm2_sign(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_rsa_enc(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_rsa_sign(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_sm3(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_md4(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_md5(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_sha1(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_sha256(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_sha384(byte * input, int inlen, byte* output, int * outlen, int nmode);
int test_hash_sha512(byte * input, int inlen, byte* output, int * outlen, int nmode);
struct timeval begin;
struct timeval end;
//#define TEST_FUNCTION 1 //测试加解密功能 则打开该宏,
#define TEST_TIME 1 //统计加解密时间 打开该宏
#define SIZE 32 //输入数据长度
//测试算法
#define TEST_FUN_NAME test_sm2_enc
void test_unhash_algorithm()
{
byte inputbuffer[SIZE + 1] = {0};
memset(inputbuffer, 0x31,SIZE);
byte enc_outputbuffer[10240] = {0};
int enc_outlen = 0;
int i = 0;
#ifdef TEST_FUNCTION
printf("加密输入:");
i = 0;
while(i < SIZE)
{
printf("%02x", inputbuffer[i]);
++i;
}
printf("\n");
#endif
TEST_FUN_NAME(inputbuffer, SIZE, enc_outputbuffer, &enc_outlen, 1);
#ifdef TEST_FUNCTION
printf("加密输出:");
i = 0;
while(i < enc_outlen)
{
printf("%02x", enc_outputbuffer[i]);
++i;
}
printf("\n");
#endif
printf("******************************\n");
byte * decinput = enc_outputbuffer;
int decinputlen = enc_outlen;
byte dec_outputbuffer[10240] = {0};
int dec_outlen = 0;
#ifdef TEST_FUNCTION
printf("解密输入:");
i = 0;
while(i < decinputlen)
{
printf("%02x", decinput[i]);
++i;
}
printf("\n");
#endif
TEST_FUN_NAME(decinput, decinputlen, dec_outputbuffer, &dec_outlen, 0);
#ifdef TEST_FUNCTION
printf("解密输出:");
i = 0;
while(i < dec_outlen)
{
printf("%02x", dec_outputbuffer[i]);
++i;
}
printf("\n");
#endif
}
typedef int (*pFn_testfun)(byte * , int , byte* , int * , int );
struct cmd
{
const char *name;
pFn_testfun ptestfun;
int type; //0 加密 1 签名 2哈希
};
#define TYPE_ENC_DEC 0
#define TYPE_SIGN_VERIFY 1
#define TYPE_HASH 2
#define MUTEX pthread_mutex_t
#define MUTEXINIT(m) pthread_mutex_init(m,NULL)
#define MUTEXLOCK(m) pthread_mutex_lock(m)
#define MUTEXUNLOCK(m) pthread_mutex_unlock(m)
#define MUTEXDESTROY(m) pthread_mutex_destroy(m)
MUTEX g_mutex_timeoutflga;
#define TIMEWAITFLAG 0
#define TIMEBEGIN 1
#define TIMEOUTFLAG 2
int timeoutflag = TIMEWAITFLAG;
int gettimeoutflag()
{
int tempflag = 0;
MUTEXLOCK(&g_mutex_timeoutflga);
tempflag = timeoutflag;
MUTEXUNLOCK(&g_mutex_timeoutflga);
return tempflag;
}
void settimeoutflag(int tempflag)
{
MUTEXLOCK(&g_mutex_timeoutflga);
timeoutflag = tempflag;
MUTEXUNLOCK(&g_mutex_timeoutflga);
}
void* time_proc(void * parm)
{
settimeoutflag(TIMEBEGIN);
sleep(1000);
settimeoutflag(TIMEOUTFLAG);
}
struct PARM
{
struct cmd * pcmd;
int nmode;
};
void* rundata_proc(void * parm)
{
struct PARM * pparm = (struct PARM*)parm;
byte inputbuffer[SIZE + 1] = {0};
memset(inputbuffer, 0x31,SIZE);
byte enc_outputbuffer[10240] = {0};
int enc_outlen = 0;
int i = 0;
#ifdef TEST_FUNCTION
printf("加密输入:");
i = 0;
while(i < SIZE)
{
printf("%02x", inputbuffer[i]);
++i;
}
printf("\n");
#endif
pparm->pcmd->ptestfun(inputbuffer, SIZE, enc_outputbuffer, &enc_outlen, pparm->nmode );
#ifdef TEST_FUNCTION
printf("加密输出:");
i = 0;
while(i < enc_outlen)
{
printf("%02x", enc_outputbuffer[i]);
++i;
}
printf("\n");
#endif
printf("******************************\n");
return NULL;
}
int main()
{
#if TEST_FUNCTION
test_unhash_algorithm();
return 0;
#else
MUTEXINIT(&g_mutex_timeoutflga);
struct cmd cmdlist[] =
{
{"des_ecb", test_des_ecb, TYPE_ENC_DEC},
{"des_cbc", test_des_cbc, TYPE_ENC_DEC},
{"3des_ecb", test_3des_ecb, TYPE_ENC_DEC},
{"3des_cbc", test_3des_cbc, TYPE_ENC_DEC},
{"sm4_ecb", test_sm4_ecb, TYPE_ENC_DEC},
{"sm4_cbc", test_sm4_cbc, TYPE_ENC_DEC},
{"aes128_ecb", test_aes128_ecb, TYPE_ENC_DEC},
{"aes128_cbc", test_aes128_cbc, TYPE_ENC_DEC},
{"aes256_ecb", test_aes256_ecb, TYPE_ENC_DEC},
{"aes256_cbc", test_aes256_cbc, TYPE_ENC_DEC},
{"sm2_enc", test_sm2_enc, TYPE_ENC_DEC},
{"sm2_sign", test_sm2_sign, TYPE_SIGN_VERIFY},
{"rsa_enc", test_rsa_enc, TYPE_ENC_DEC},
{"rsa_sign", test_rsa_sign, TYPE_SIGN_VERIFY},
{"hash_sm3", test_hash_sm3, TYPE_HASH},
{"hash_md4", test_hash_md4, TYPE_HASH},
{"hash_md5", test_hash_md5, TYPE_HASH},
{"hash_sha1", test_hash_sha1, TYPE_HASH},
{"hash_sha256", test_hash_sha256, TYPE_HASH},
{"hash_sha384", test_hash_sha384, TYPE_HASH},
{"hash_sha512", test_hash_sha512, TYPE_HASH},
{NULL, NULL, 0}
};
while(1)
{
struct cmd * pCmd = cmdlist;
int i = 1;
printf("%2d %s\n",0, "退出");
while(pCmd->name != NULL)
{
printf("%2d %s\n",i, pCmd->name);
++i;
++pCmd;
}
int algorithmcount = 0;
while(1)
{
printf("请输入需要测试的算法:");
scanf("%d", &algorithmcount);
if(0 == algorithmcount)
{
printf("退出\n");
return;
}
if(algorithmcount > 0 && algorithmcount < (sizeof(cmdlist) / sizeof(struct cmd)))
{
break;
}
else
{
printf("输入错误\n");
}
}
--algorithmcount;
struct PARM parm;
parm.pcmd = &(cmdlist[algorithmcount]);
pthread_t time_id;
pthread_t rundata_id;
parm.nmode = 1;
pthread_create(&rundata_id, NULL, rundata_proc, (void*)&parm);
assert(rundata_id);
sleep(1000);
pthread_create(&time_id, NULL, time_proc, NULL);
assert(time_id);
if(cmdlist[algorithmcount].type != TYPE_HASH)
{
sleep (2000);
parm.nmode = 0;
pthread_create(&rundata_id, NULL, rundata_proc, (void*)&parm);
assert(rundata_id);
sleep(1000);
pthread_create(&time_id, NULL, time_proc, NULL);
assert(time_id);
}
sleep (2000);
getchar();
i = 1;
}
#endif
}
//nmode = DES_ENCRYPT 加密, DES_ENCRYPT:解密
int test_des_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_des_ecb\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
return -1;
}
DES_cblock key;
DES_random_key (&key);
DES_string_to_key ("pass", &key);
int i = 0;
#ifdef TEST_FUNCTION
printf("key:");
while(i < sizeof(key))
{
printf("%02x", key[i]);
++i;
}
printf("\n");
#endif
DES_key_schedule schedule;
DES_set_key_checked (&key, &schedule);
i = 0;
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
DES_ecb_encrypt ((const_DES_cblock*)(input), (DES_cblock*)(output), &schedule, nmode);
datacount += 8;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_des_ecb %s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
while(i < inlen)
{
DES_ecb_encrypt((const_DES_cblock*)(input + i), (DES_cblock*)(output + i), &schedule, nmode);
i += 8;
}
*outlen = inlen;
#endif
return 0;
}
int test_des_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_des_cbc\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
DES_cblock key;
DES_random_key (&key);
DES_string_to_key ("pass", &key);
long i = 0;
#ifdef TEST_FUNCTION
printf("key:");
while(i < sizeof(key))
{
printf("%02x", key[i]);
++i;
}
printf("\n");
#endif
DES_key_schedule schedule;
DES_set_key_checked (&key, &schedule);
DES_cblock iv = {"\x00\x00\x00\x00\x00\x00\x00\x00"};
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
DES_cbc_encrypt (input, output, inlen, &schedule, &iv, nmode);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_des_cbc %s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
DES_cbc_encrypt (input, output, inlen, &schedule, &iv, nmode);
*outlen = inlen;
#endif
return 0;
}
int test_aes128_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_aes128_ecb\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
AES_KEY key;
const int keylen = 128;
byte userkey[64] = {0};
memset(userkey, 0x11, 64);
if(AES_ENCRYPT ==nmode)
{
AES_set_encrypt_key(userkey, keylen, &key);
}
else if(AES_DECRYPT == nmode)
{
AES_set_decrypt_key(userkey, keylen, &key);
}
else
{
printf("模式错误\n");
return -1;
}
int i = 0;
#ifdef TEST_FUNCTION
printf("keylen:%d, key:", keylen);
while(i < (keylen / 8))
{
printf("%02x", userkey[i]);
++i;
}
printf("\n");
#endif
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
AES_ecb_encrypt(input, output, &key, nmode);
datacount += 16;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_aes128_ecb%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
i = 0;
while(i <inlen)
{
AES_ecb_encrypt(input + i, output + i, &key, nmode);
i += 16;
}
*outlen = inlen;
#endif
return 0;
}
int test_aes128_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_aes128_cbc\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
AES_KEY key;
const int keylen = 128;
byte userkey[64] = {0};
memset(userkey, 0x11, 64);
if(AES_ENCRYPT ==nmode)
{
AES_set_encrypt_key(userkey, keylen, &key);
}
else if(AES_DECRYPT == nmode)
{
AES_set_decrypt_key(userkey, keylen, &key);
}
else
{
printf("模式错误\n");
return -1;
}
int i = 0;
#ifdef TEST_FUNCTION
printf("keylen:%d, key:", keylen);
while(i < (keylen / 8))
{
printf("%02x", userkey[i]);
++i;
}
printf("\n");
#endif
byte iv[16] = {0};
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
AES_cbc_encrypt(input, output, 16, &key, iv, nmode);
datacount += 16;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_aes128_cbc%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
AES_cbc_encrypt(input, output, inlen, &key, iv, nmode);
*outlen = inlen;
#endif
return 0;
}
int test_aes256_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_aes256_ecb\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
AES_KEY key;
const int keylen = 256;
byte userkey[64] = {0};
memset(userkey, 0x11, 64);
if(AES_ENCRYPT ==nmode)
{
AES_set_encrypt_key(userkey, keylen, &key);
}
else if(AES_DECRYPT == nmode)
{
AES_set_decrypt_key(userkey, keylen, &key);
}
else
{
printf("模式错误\n");
return -1;
}
int i = 0;
#ifdef TEST_FUNCTION
printf("keylen:%d, key:", keylen);
while(i < (keylen / 8))
{
printf("%02x", userkey[i]);
++i;
}
printf("\n");
#endif
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
AES_ecb_encrypt(input, output, &key, nmode);
datacount += 16;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_aes256_ecb%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
i = 0;
while(i <inlen)
{
AES_ecb_encrypt(input + i, output + i, &key, nmode);
i += 16;
}
*outlen = inlen;
#endif
return 0;
}
int test_aes256_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_aes256_cbc\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
AES_KEY key;
const int keylen = 256;
byte userkey[64] = {0};
memset(userkey, 0x11, 64);
if(AES_ENCRYPT ==nmode)
{
AES_set_encrypt_key(userkey, keylen, &key);
}
else if(AES_DECRYPT == nmode)
{
AES_set_decrypt_key(userkey, keylen, &key);
}
else
{
printf("模式错误\n");
return -1;
}
int i = 0;
#ifdef TEST_FUNCTION
printf("keylen:%d, key:", keylen);
while(i < (keylen / 8))
{
printf("%02x", userkey[i]);
++i;
}
printf("\n");
#endif
byte iv[16] = {0};
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
AES_cbc_encrypt(input, output, inlen, &key, iv, nmode);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_aes256_cbc%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
AES_cbc_encrypt(input, output, inlen, &key, iv, nmode);
*outlen = inlen;
#endif
return 0;
}
int test_3des_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_3des_ecb\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
DES_key_schedule schedule1;
DES_key_schedule schedule2;
DES_key_schedule schedule3;
//DES_set_key_checked会校验密钥的奇偶校验位和密钥强度,自定义密钥很容易校验不通过从而密钥设置失败,所以直接使用DES_set_key_unchecked
const byte * keylist[3] =
{
"\xb9\x86\x4f\x73\xf7\x23\x08\x6b",
"\xb9\x86\x4f\x73\xf7\x23\x08\x6b",
"\x11\x11\x11\x11\x11\x11\x11\x11"
};
DES_set_key_unchecked((const_DES_cblock*)keylist[0], &schedule1);
DES_set_key_unchecked((const_DES_cblock*)keylist[1], &schedule2);
DES_set_key_unchecked((const_DES_cblock*)keylist[2], &schedule3);
int i= 0;
#ifdef TEST_FUNCTION
printf("key1:");
i = 0;
while(i < strlen(keylist[0]))
{
printf("%02x", keylist[0][i]);
++i;
}
printf("\n");
printf("key2:");
i = 0;
while(i < strlen(keylist[1]))
{
printf("%02x", keylist[1][i]);
++i;
}
printf("\n");
printf("key3:");
i = 0;
while(i < strlen(keylist[2]))
{
printf("%02x", keylist[2][i]);
++i;
}
printf("\n");
#endif
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
DES_ecb3_encrypt ((const_DES_cblock*)(input + i), (const_DES_cblock*)(output + i), &schedule1, &schedule2, &schedule3, nmode);
datacount += 8;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_3des_ecb%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
i = 0;
while(i < inlen)
{
DES_ecb3_encrypt ((const_DES_cblock*)(input + i), (const_DES_cblock*)(output + i), &schedule1, &schedule2, &schedule3, nmode);
i += 8;
}
*outlen = inlen;
#endif
return 0;
}
int test_3des_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_3des_cbc\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
DES_key_schedule schedule1;
DES_key_schedule schedule2;
DES_key_schedule schedule3;
//DES_set_key_checked会校验密钥的奇偶校验位和密钥强度,自定义密钥很容易校验不通过从而密钥设置失败,所以直接使用DES_set_key_unchecked
const byte * keylist[3] =
{
"\xb9\x86\x4f\x73\xf7\x23\x08\x6b",
"\xb9\x86\x4f\x73\xf7\x23\x08\x6b",
"\x11\x11\x11\x11\x11\x11\x11\x11"
};
DES_set_key_unchecked ((const_DES_cblock*)keylist[0], &schedule1);
DES_set_key_unchecked ((const_DES_cblock*)keylist[1], &schedule2);
DES_set_key_unchecked ((const_DES_cblock*)keylist[2], &schedule3);
int i= 0;
#ifdef TEST_FUNCTION
printf("key1:");
i = 0;
while(i < strlen(keylist[0]))
{
printf("%02x", keylist[0][i]);
++i;
}
printf("\n");
printf("key2:");
i = 0;
while(i < strlen(keylist[1]))
{
printf("%02x", keylist[1][i]);
++i;
}
printf("\n");
printf("key3:");
i = 0;
while(i < strlen(keylist[2]))
{
printf("%02x", keylist[2][i]);
++i;
}
printf("\n");
#endif
DES_cblock iv = {"\x00\x00\x00\x00\x00\x00\x00\x00"};
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
DES_ede3_cbc_encrypt(input, output, inlen, &schedule1, &schedule2, &schedule3, &iv, nmode);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_3des_cbc%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
DES_ede3_cbc_encrypt(input, output, inlen, &schedule1, &schedule2, &schedule3, &iv, nmode);
*outlen = inlen;
#endif
return 0;
}
int test_sm4_ecb(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_sm4_ecb\n");
if(NULL == input || inlen <= 0 || NULL == output || NULL == outlen || ((0 != nmode) && (1 != nmode)))
{
printf("参数错误\n");
return -1;
}
const byte * key = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F";
int i= 0;
#ifdef TEST_FUNCTION
printf("key:");
i = 0;
while(i < strlen(key))
{
printf("%02x", key[i]);
++i;
}
printf("\n");
#endif
sms4_key_t sms4Key;
int encmode = 0;
if(1 == nmode)//enc 加密
{
sms4_set_encrypt_key (&sms4Key, key);
encmode = 0;
}
else if(0 == nmode)//解密
{
sms4_set_decrypt_key(&sms4Key, key);
encmode = 1;
}
else
{
printf("模式错误\n");
return -1;
}
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
sms4_ecb_encrypt(input + i, output + i, &sms4Key, encmode);
datacount += 16;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_sm4_ecb%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
i = 0;
while(i < inlen)
{
sms4_ecb_encrypt(input + i, output + i, &sms4Key, encmode);
i += 16;
}
*outlen = inlen;
#endif
return 0;
}
int test_sm4_cbc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_sm4_cbc\n");
if(NULL == input || inlen <= 0 || NULL == output || NULL == outlen || ((0 != nmode) && (1 != nmode)))
{
printf("参数错误\n");
return -1;
}
const byte * key = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F";
byte iv[16] = {0};
int i= 0;
#ifdef TEST_FUNCTION
printf("key:");
i = 0;
while(i < strlen(key))
{
printf("%02x", key[i]);
++i;
}
printf("\n");
#endif
sms4_key_t sms4Key;
int encmode = 0;
if(1 == nmode)//enc 加密
{
sms4_set_encrypt_key (&sms4Key, key);
encmode = 0;
}
else if(0 == nmode)//解密
{
sms4_set_decrypt_key(&sms4Key, key);
encmode = 1;
}
else
{
printf("模式错误\n");
return -1;
}
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
sms4_cbc_encrypt(input, output, inlen, &sms4Key, iv, encmode);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_sm4_cbc%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
sms4_cbc_encrypt(input, output, inlen, &sms4Key, iv, encmode);
*outlen = inlen;
#endif
return 0;
}
int getsm2key(EC_KEY** ppkeypair, EC_GROUP** ppgroup)
{
static EC_KEY *keypair = NULL;
static EC_GROUP* group = NULL;
if(EC_KEY_check_key(keypair))
{
*ppkeypair = keypair;
*ppgroup = group;
return 0;
}
int ret1,ret2;
keypair = EC_KEY_new();
group = EC_GROUP_new_by_curve_name (NID_sm2p256v1);
ret1 = EC_KEY_set_group (keypair, group);
ret2 = EC_KEY_generate_key (keypair);
*ppkeypair = keypair;
*ppgroup = group;
return 0;
}
int test_sm2_enc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_sm2_enc\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
EC_KEY *keypair = NULL;
EC_GROUP* group1 = NULL;
getsm2key(&keypair, &group1);
int i = 0;
#ifdef TEST_FUNCTION
const EC_POINT * eckey_public = EC_KEY_get0_public_key (keypair);
const BIGNUM * eckey_private = EC_KEY_get0_private_key (keypair);
byte printfbuffer[1024] = {0};
int nprivatekeylen = BN_num_bits (eckey_private);
BN_bn2bin (eckey_private, printfbuffer);
printf("privatekeylen:%d, privatekey:",nprivatekeylen);
i = 0;
while(i < nprivatekeylen)
{
printf("%02x", printfbuffer[i]);
++i;
}
printf("\n");
#endif
byte miwen[10240] = {0};
int miwenlen = 0;
byte* pstr = miwen;
const EVP_MD *md = EVP_sm3();
#ifdef TEST_TIME
if(1 == nmode)
{
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
SM2CiphertextValue* cv = SM2_do_encrypt(md, input, inlen, keypair);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_sm2_enc%s 执行时间:%ld(ws), 执行数据%ld(byte), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
return 0;
}
#endif
SM2CiphertextValue* cv = SM2_do_encrypt(md, input, inlen, keypair);
const EC_GROUP* group = EC_KEY_get0_group (keypair);
miwenlen = i2o_SM2CiphertextValue (group1, cv, &pstr);
#ifdef TEST_FUNCTION
printf("miwenlen:%d, miwen:", miwenlen);
i = 0;
while(i < miwenlen)
{
printf("%02x", miwen[i]);
++i;
}
printf("\n");
#endif
size_t miwenoutlen = 0;
#ifdef TEST_TIME
if(0 == nmode)
{
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
SM2_do_decrypt(md,cv, output, &miwenoutlen, keypair);
datacount += (miwenlen - 1);
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_sm2_enc%s 执行时间:%ld(ws), 执行数据%ld(bit), 速度:%ld(kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
}
#else
SM2_do_decrypt(md,cv, output, &miwenoutlen, keypair);
*outlen = miwenoutlen;
#endif
return 0;
}
int test_sm2_sign(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_sm2_sign\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
EC_KEY *keypair = NULL;
EC_GROUP* group1 = NULL;
getsm2key(&keypair, &group1);
int i = 0;
#ifdef TEST_FUNCTION
const EC_POINT * eckey_public = EC_KEY_get0_public_key (keypair);
const BIGNUM * eckey_private = EC_KEY_get0_private_key (keypair);
byte printfbuffer[1024] = {0};
int nprivatekeylen = BN_num_bits (eckey_private);
BN_bn2bin (eckey_private, printfbuffer);
printf("len:%d, privatekey:",nprivatekeylen);
i = 0;
while(i < nprivatekeylen)
{
printf("%02x", printfbuffer[i]);
++i;
}
printf("\n");
#endif
#ifdef TEST_TIME
if(1 == nmode)
{
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
ECDSA_SIG* ec_sig = SM2_do_sign(input, inlen, keypair);
++datacount;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_sm2_sign%s 执行时间:%ld(ws), 签名%d字节数据 %ld次数, 速度:%ld(次/s)\n", nmode == 1?"签名":"验签", time, inlen, datacount, datacount * 1000000 / getms(begin, end));
return 0;
}
#endif
ECDSA_SIG* ec_sig = SM2_do_sign(input, inlen, keypair);
#ifdef TEST_TIME
if(0 == nmode)
{
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
int ret = SM2_do_verify(input,inlen,ec_sig, keypair);
++datacount;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_sm2_sign%s 执行时间:%ld(ws), 验签 %ld次数, 速度:%ld(次/s)\n", nmode == 1?"签名":"验签", time, datacount, datacount * 1000000 / getms(begin, end));
}
#else
int ret = SM2_do_verify(input,inlen,ec_sig, keypair);
#endif
#ifdef TEST_FUNCTION
printf("SM2_do_verify result: %d\n", ret);
#endif
return 0;
}
RSA * get_RSA()
{
RSA* r = RSA_new();
// rsa1024
#if 1
byte e[] = {"00010001"};
byte n[] = {"D4019BC61BB9AD30DCF031D0666A8DCA8DDF18B29368FD18161DA2C0C2A280C9085A70BB7C20D5510593EDDA7D50714FC62404E8B2B90B003940CDE6C4F29AF692CFE6A5B240BBCA6A7BBEF26CBEBE6952B3DAB409EB8561E7A29A74D2BCF3552485686B9E5275938D4886A1F1BD6E9182870F1E40879F61DAAABF2626900E09"};
byte d[] = {"C015F100AF102D764F4825AA2F912D852FC3CA49CA3BDECD1B04A0F8CBA096D50E877B0AB3EDBFB8D837EED2FEA58AF4FF8E95100D16917C1363BEEAEED8ED4303173DC714139631BDBA7670B82A3E3F2CAF723D95ADC6180A47922A3AF6170FFCE24A5B6ADA5175B132F4B9FF92E44F2D04BA211500879DF3E4EC539B21DACD"};
byte p[] = {"EAE657604EC3A7B24DAE0DEB34E7661F104C6C62AB7711AF9BF838A01BC687255204104CA477C6BEFE93872300575200149BD227A2AD98FBD37DD2F2EA041FF3"};
byte q[] = {"E70CD16453BA5BA4966A599ECF1DA7E9D8A9A5F8DDFF9DF3C3E333F8FC2A7FA160A6CB9BD6B02D3501BABA61BDC6A6853902DD05502F7B0E3D4743805F425513"};
byte dp[] = {"E50EB6979856DC5957BC69A039978812B48F0185FA1402F00E94AF8B196AAF70AA1882586A6CCE268313134D0351230A270E8790D4E6996EBF9E4BAD4A9BB917"};
byte dq[] = {"928DFCDBA88852CCE963F808D5D337C90AD74121C49EF92FC01703C6711CFBEBFF048DAE01D5AA372F2BA4418F40CC2B40E8620D96B92752F6E797177C54F4E5"};
byte qinv[] = {"CDEF5E7C93F0FA0EF4DB1A5F99F9F663BC9E5BA890F892B77300EF4A12BFC6C5861FC422BBDBFAC83D848DADE3D348C8DC108F2FF201534B2D6255CB603FC96B"};
#else
//rsa2048
byte e[] = {"00010001"};
byte n[] = {"C13BDDB8814473439489275D13578B7B19FAE07F8BD21B71D40B42127B0EF66A55CC993088E7C74DB798A6C8AD28D5768FB337C9CC0160182AB6F9FE52A4E9E5FA81B72B799D5E3DE1879669F39BE34DC2C00F04818FE9820748209A49AEFFCF53CB6C7A196D42F36C05A0812C1D447DE3E5BCD7A7E1A76811E877B63235BBA05C694F3E1DBF521DA0384CC4145715FCD8424024840AB376AB3EAE35536A7DBD869559FBEE27E11DBD5CCA7794FB59B4FFEB9B509AB0FF1127F4B6FEB6122D1B91995D57E1A0101522F51593EC211D456436ED45CBBEB6DE4D9C77C1C4E1071C46F12A45C7073B185E93FADB3F91DF6D261E8E1CB773218D419351450C3C5C59"};
byte d[] = {"00A309E009CD07F439111AA81BE035FD79E071CCF9D0FF762894C0EAFEACD5F313C550DBF0179378961A52B2669FB3D46834D7023B41E5E72E7CDBE612AFA875B195ABDCE0D1BBF5C8408226673F2448A553ACB8FF145258B35D717E10B01AF7BBF6F7AC8F58E4D7988B8C33E0C957E8724FD7877E6E27F717D8044CFD6D5FE8EDEC1FF2B69D55AFACA1D688A5BE5B9E46F67AFF6E5B25BCDF3E7428DF109A2C3886A6852A7CF09CE032A698933AAD39BB537C5ACBDC817FA1E3BE1FB2B9D5C78236BFE2807F9C72196EE624F54642DDDCF42A6F60ED6D25702D6D19151C53A5A396073E4A2703A9B47183DA607E25B569639B13C3865DCA6D4D6A25C57EAA61"};
byte p[] = {"F3E234B127CF142D3C7B62715507E0507ABBD17132557DB51E51F107D42D57470D51C51D6C03471A127ACA534AB77F74A2BC1F7D15A29684293029002193C55F94C31CCDFA832D05EE9563D16493BFB8C7773860DD6EAD2F24FB08E1350F349E42BC740722F65D437C072346E1DD8687425A88BA3231F8606A4B85A75A3B108B"};
byte q[] = {"CAD57ABE125370E4290E7F14C9F8432490C67AA83BB05BA8AEE8B47F023BAEF804154DF9C2047B6B00C6FC5188C80DEA607BB6C04CFE930DB865B952E8028C11543C0FA5E49BC496758F9A39BCA02940F928BA2CCC2C651AA07EBC7F211CC6AE55315BCB357BC088E837284CD857AA03674CF32B49D74E292CCD3022DC275F2B"};
byte dp[] = {"11DAD7BCB88B6290C542CB3C3CDB6CC2B7999485D3078B427D4BC677AA42FF86C624DC678106E467B63EA31D61F4F931D2D02F05FB5581EB7F10758FFAE554A7E0BE40179C658A204B0D48D785A3837FC5AAA6C800AE1FA3B9F35EFD0DE36518C90DFEF89EC8A69F502F3D97ECE548FA12138ABB06FDBD8F6178D1FA2492FA6D"};
byte dq[] = {"5E86AA9315DB490B2B8F13EE4E49A290D1DF8D9E056324F431BF450EC3ADA8D6F0A0351CA62C8C8FCB66F083D6E8D4835BBF8BE5867C456FE9758EAE726D6D754DFA47989A3775A060DD3194A2B149487C555C9E2FF0A89586224A1A3D063A19589E8E16DFAFF2845B240965F694B428ADE59095A5EDEF01055E0286DC6E84CD"};
byte qinv[] = {"84D3109839E1167D7AF13F4D55015060D3BAEBE8DF1AE404B1DB985960A5515B840AA809CC7D1D978DB38AFE1B9B16686AC9ED23F640229C61EE6F13E74864E417F120E326F22AABE0B8EA0A31E8EA2DD282CE1943CD6B528E85AD2B11B64D31045A950F0E136A2BE00BF2E905E5B320481DE72C10B5E2AF9503FA9C40CFC7D2"};
#endif
BIGNUM * bignum_e = BN_new();
BIGNUM * bignum_n = BN_new();
BIGNUM * bignum_d = BN_new();
BIGNUM * bignum_p = BN_new();
BIGNUM * bignum_q = BN_new();
BIGNUM * bignum_dp = BN_new();
BIGNUM * bignum_dq= BN_new();
BIGNUM * bignum_qinv = BN_new();
BN_hex2bn (&bignum_e, e);
BN_hex2bn (&bignum_n, n);
BN_hex2bn (&bignum_d, d);
BN_hex2bn (&bignum_p, p);
BN_hex2bn (&bignum_q, q);
BN_hex2bn (&bignum_dp, dp);
BN_hex2bn (&bignum_dq, dq);
BN_hex2bn (&bignum_qinv, qinv);
RSA_set0_key(r, bignum_n, bignum_e, bignum_d);
RSA_set0_factors(r, bignum_p, bignum_q);
RSA_set0_crt_params(r,bignum_dp, bignum_dq, bignum_qinv);
if(1 != RSA_check_key(r))
{
unsigned long ulerr = ERR_get_error();
char szErrMsg[1024] = {0};
char * pTemp = NULL;
pTemp = ERR_error_string (ulerr,szErrMsg);
printf("errorid:%04x \n errmsg:%s\n", ulerr, szErrMsg);
ERR_reason_error_string (ulerr);
printf(" ERR_reason:%s\n", szErrMsg);
return NULL;
}
return r;
}
int test_rsa_enc(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_rsa_enc\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
RSA * r = get_RSA();
if(NULL == r)
{
return;
}
int i = 0;
if(1 == nmode)
{
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
byte inpurbuffer[256] = {0};
memset(inpurbuffer, 0x31,256);
gettimeofday(&begin, NULL);
while(1)
{
RSA_public_encrypt(128, inpurbuffer,output , r, RSA_NO_PADDING);
datacount += 128;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_rsa_enc%s 执行时间:%ld(ws), 执行数据%ld(byte), 速度:%ld(Kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
RSA_public_encrypt(inlen, input,output , r, RSA_NO_PADDING);
#endif
}
else if(0 == nmode)
{
#ifdef TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
byte inpurbuffer[256] = {"41102679341F49180CDFA2214221FF0B9AE24BE0FF4D4637BFD21914AC1BB3F9D1C9F4570A612CDD8DF1CB8D10F8FD917868966B470526FDB24E98658345C4994409564CBD369DD461DA95F39BE4BCADFCB8E35987B1AAFB2F2AE1E90FE7C6596EB13795D65408D94339E513647315F2F7B85A180405032A1E8DBD809F12CBAF"};
gettimeofday(&begin, NULL);
while(1)
{
RSA_private_decrypt(inlen, input, output, r, RSA_NO_PADDING);
datacount += 128;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_rsa_enc%s 执行时间:%ld(ws), 执行数据%ld(byte), 速度:%ld(Kbps)\n", nmode == 1?"加密":"解密", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
RSA_private_decrypt(inlen, input, output, r, RSA_NO_PADDING);
#endif
}
else
{
printf("模式错误\n");
}
*outlen = 1024 / 8;
RSA_free(r);
}
int test_rsa_sign(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_rsa_sign\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen || (nmode != 0 && nmode != 1))
{
printf("参数错误\n");
return -1;
}
RSA * r = get_RSA();
if(NULL == r)
{
return;
}
byte sigret[1024] = {0};
int siglen = 0;
#if TEST_TIME
if(1 == nmode)
{
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
byte inpurbuffer[256] = {0};
memset(inpurbuffer, 0x31,256);
gettimeofday(&begin, NULL);
while(1)
{
RSA_sign(NID_sha1, inpurbuffer, 64, sigret, &siglen, r);
++datacount;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_rsa_sign%s 执行时间:%ld(ws),签名%d字节数据 %ld次数, 速度:%ld(次/s)\n", nmode == 1?"签名":"验签", time, 64, datacount, datacount * 1000000 / getms(begin, end));
return 0;
}
#else
RSA_sign(NID_sha1, input, inlen / 2, sigret, &siglen, r);
#endif
int i = 0;
#ifdef TEST_FUNCTION
printf("siglen:%d, sigret:", siglen);
i = 0;
while(i < siglen)
{
printf("%02x", sigret[i]);
++i;
}
printf("\n");
#endif
#if TEST_TIME
if(0 == nmode)
{
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
int ret = RSA_verify(NID_sha1, input, 64, sigret, siglen, r);
++datacount;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_rsa_sign%s 执行时间:%ld(ws),验签%ld次数, 速度:%ld(次/s)\n", nmode == 1?"签名":"验签", time, datacount, datacount * 1000000 / getms(begin, end));
return 0;
}
#else
int ret = RSA_verify(NID_sha1, input, inlen / 2, sigret, siglen, r);
#endif
#ifdef TEST_FUNCTION
printf("RSA_verify result : %d\n", ret);
#endif
RSA_free(r);
return 0;
}
int test_hash_sm3(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_sm3\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen)
{
printf("参数错误\n");
return -1;
}
sm3_ctx_t ctx;
sm3_init(&ctx);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
sm3_update(&ctx, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
sm3_final(&ctx, output);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_sm3%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
sm3_update(&ctx, input, inlen);
sm3_final(&ctx, output);
#endif
*outlen = SM3_DIGEST_LENGTH;
return 0;
}
int test_hash_md4(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_md4\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen)
{
printf("参数错误\n");
return -1;
}
MD4_CTX ctx;
MD4_Init(&ctx);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
MD4_Update(&ctx, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
MD4_Final(output, &ctx);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_md4%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
MD4_Update(&ctx, input, inlen);
MD4_Final(output, &ctx);
#endif
*outlen = MD4_DIGEST_LENGTH;
return 0;
}
int test_hash_md5(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_md5\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen)
{
printf("参数错误\n");
return -1;
}
MD5_CTX ctx;
MD5_Init(&ctx);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
MD5_Update(&ctx, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
MD5_Final(output, &ctx);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_md4%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
MD5_Update(&ctx, input, inlen);
MD5_Final(output, &ctx);
#endif
*outlen = MD5_DIGEST_LENGTH;
return 0;
}
int test_hash_sha1(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_sha1\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen)
{
printf("参数错误\n");
return -1;
}
byte md[SHA_DIGEST_LENGTH] = {0};
SHA_CTX c;
SHA1_Init(&c);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
SHA1_Update (&c, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
SHA1_Final(output, &c);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_sha1%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
SHA1_Update (&c, input, inlen);
SHA1_Final(output, &c);
#endif
*outlen = SHA_DIGEST_LENGTH;
return 0;
}
int test_hash_sha256(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_sha256\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen)
{
printf("参数错误\n");
return -1;
}
SHA256_CTX c;
SHA256_Init(&c);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
SHA256_Update (&c, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
SHA256_Final(output, &c);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_sha256%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
SHA256_Update (&c, input, inlen);
SHA256_Final(output, &c);
#endif
*outlen = SHA256_DIGEST_LENGTH;
return 0;
}
int test_hash_sha384(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_sha384\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen )
{
printf("参数错误\n");
return -1;
}
SHA512_CTX c;
SHA384_Init(&c);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
SHA384_Update (&c, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
SHA384_Final(output, &c);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_sha384%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
SHA384_Update (&c, input, inlen);
SHA384_Final(output, &c);
#endif
*outlen = SHA384_DIGEST_LENGTH;
return 0;
}
int test_hash_sha512(byte * input, int inlen, byte* output, int * outlen, int nmode)
{
printf("test_hash_sha512\n");
if(NULL == input || 0 >= inlen || NULL == output || NULL == outlen)
{
printf("参数错误\n");
return -1;
}
SHA512_CTX c;
SHA512_Init(&c);
#if TEST_TIME
long datacount = 0;
while(1)
{
if(TIMEBEGIN == gettimeoutflag()) //
{
break;
}
sleep (1);
}
gettimeofday(&begin, NULL);
while(1)
{
SHA512_Update (&c, input, inlen);
datacount += inlen;
if(TIMEOUTFLAG == gettimeoutflag()) //时间到了就退出
{
break;
}
}
SHA512_Final(output, &c);
gettimeofday(&end, NULL);
long time = getms(begin, end);
printf("test_hash_sha512%s,执行时间:%ld(ws),执行数据%ld(byte), 速度:%ld(kbps)\n", "计算摘要", time, datacount, datacount * 1000000 / getms(begin, end) / 1024 * 8);
#else
SHA512_Update (&c, input, inlen);
SHA512_Final(output, &c);
#endif
*outlen = SHA512_DIGEST_LENGTH;
return 0;
}
long getms(struct timeval begin,struct timeval end)
{
//tv_sec tv_usec
if(end.tv_usec >= begin.tv_usec)
{
return (end.tv_sec - begin.tv_sec) * 1000 * 1000 + (end.tv_usec - begin.tv_usec);
}
else
{
return (end.tv_sec - begin.tv_sec) * 1000 * 1000 - (begin.tv_usec - end.tv_usec);
}
}