• sm2,sm3,sm4国密算法的纯c语言版本,使用于任何嵌入式平台


    国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。

    SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。

    SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。

    SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。

    SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

    由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。

    SM2,SM3,SM4的相关文档可以参考如下链接:

    http://218.241.108.63/wiki/index.php/首页

    SM2,SM3,SM4的C代码如下:使用了openssl开源库。

    http://files.cnblogs.com/files/TaiYangXiManYouZhe/Sm2_sm3_sm4_c%E8%AF%AD%E8%A8%80%E5%AE%9E%E7%8E%B0.zip

    当使用特定的芯片进行SM1或其他国密算法加密时,若用多个线程调用加密卡的API时,要考虑芯片对于多线程的支持情况。

    以下为不使用openssl库的另一种实现方案,基于Miracl大数运算库,可移植。

    主要难点就是移植Miracl库,裁剪配置,测试加解密算法。针对不同平台如32位或64位,以及平台的大小端进行配置。

    如果Miracl库移植ok了,那么基于Miracl库的sm2算法应没多大问题。

    Miracl库里文件较多,且从官网下载的代码,在linux系统上是很容易编译。

    但是想用在单片机上,需要一些移植和配置。

    只需要包含需要的文件就行了。

    以下是编译过程。

     

    然后需要新建一个sm2.c文件、sm2.h,用于实现sm2功能函数;一个sm3.c文件、一个sm3.h文件,用于实现sm3功能函数(之所以要增加sm3的功能是因为sm2算法中需要sm3计算hash值功能。 下面给出生成密钥对的示例:

    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #include <memory.h>
    #include <time.h>
    #include "sm2.h"
    
    #define SM2_PAD_ZERO TRUE
    #define SM2_DEBUG   0
    struct FPECC{
    char *p;
    char *a;
    char *b;
    char *n;
    char *x;
    char *y;
    };
    /*SM2*/
    struct FPECC Ecc256 = {
    "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",
    "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",
    "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",
    "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",
    "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",
    "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2",
    };
    unsigned char radom1[] = { 0x4C,0x62,0xEE,0xFD,0x6E,0xCF,0xC2,0xB9,0x5B,0x92,0xFD,0x6C,0x3D,0x95,0x75,0x14,0x8A,0xFA,0x17,0x42,0x55,0x46,0xD4,0x90,0x18,0xE5,0x38,0x8D,0x49,0xDD,0x7B,0x4F };
    void PrintBuf(unsigned char *buf, int	buflen)
    {
    	int i;
    	for (i = 0; i < buflen; i++) {
    		if (i % 32 != 31)
    			printf("%02x", buf[i]);
    		else
    			printf("%02x
    ", buf[i]);
    	}
    	printf("
    ");
    	//return 0;
    }
    void Printch(unsigned char *buf, int	buflen)
    {
    	int i;
    	for (i = 0; i < buflen; i++) {
    		if (i % 32 != 31)
    			printf("%c", buf[i]);
    		else
    			printf("%c
    ", buf[i]);
    	}
    	printf("
    ");
    	//return 0;
    }
    
    void sm2_keygen(unsigned char *wx, int *wxlen, unsigned char *wy, int *wylen,unsigned char *privkey, int *privkeylen)
    {
    
    	struct FPECC *cfig = &Ecc256;
    	epoint *g;
        big a,b,p,n,x,y,key1;
        miracl *mip = mirsys(20,0);
        mip->IOBASE = 16;
        p = mirvar(0);
    	a = mirvar(0);
        b = mirvar(0);
        n = mirvar(0);
        x = mirvar(0);
        y = mirvar(0);
        key1 = mirvar(0);
        cinstr(p,cfig->p);
    	cinstr(a,cfig->a);
        cinstr(b,cfig->b);
    	cinstr(n,cfig->n);
    	cinstr(x,cfig->x);
        cinstr(y,cfig->y);
    	ecurve_init(a,b,p,MR_PROJECTIVE);
        g = epoint_init();
        epoint_set(x,y,0,g); 
        irand(time(NULL));
        bigrand(n,key1);   ////私钥db
        ecurve_mult(key1,g,g); //计算Pb
        epoint_get(g,x,y);
        *wxlen = big_to_bytes(32, x, (char *)wx, TRUE);
       	*wylen = big_to_bytes(32, y, (char *)wy, TRUE);
    	*privkeylen = big_to_bytes(32, key1, (char *)privkey, TRUE);
    	mirkill(key1);
    	mirkill(p);
    	mirkill(a);
    	mirkill(b);
    	mirkill(n);
    	mirkill(x);
    	mirkill(y);
    	epoint_free(g);
    	mirexit();
    }
    int kdf(unsigned char *zl, unsigned char *zr, int klen, unsigned char *kbuf)
    {
    	/*
    	return 0: kbuf = 0, 不可
    		   1: kbuf 可
    	*/
    	unsigned char buf[70];
    	unsigned char digest[32];
    	unsigned int ct = 0x00000001; //初始化一个32比特构成的计数器ct=0x00000001
    	int i, m, n;
    	unsigned char *p;
    	memcpy(buf, zl, 32);
    	memcpy(buf+32, zr, 32);
    	m = klen / 32;
    	n = klen % 32;
    	p = kbuf;
    	for(i = 0; i < m; i++)
    	{
    		buf[64] = (ct >> 24) & 0xFF;
    		buf[65] = (ct >> 16) & 0xFF;
    		buf[66] = (ct >> 8) & 0xFF;
    		buf[67] = ct & 0xFF;
    		sm3(buf, 68, p);
    		p += 32;
    		ct++;
    	}
    	/*对i从1到?klen/v?执行:b.1)计算Hai=Hv(Z ∥ ct);b.2) ct++*/
    	if(n != 0)
    	{
    		buf[64] = (ct >> 24) & 0xFF;
    		buf[65] = (ct >> 16) & 0xFF;
    		buf[66] = (ct >> 8) & 0xFF;
    		buf[67] = ct & 0xFF;
    		sm3(buf, 68, digest);
    	}
    	/*若klen/v是整数,令Ha!?klen/v? = Ha?klen/v?,否则令Ha!?klen/v?为Ha?klen/v?最左边的(klen ?
    (v × ?klen/v?))比特*/
    	memcpy(p, digest, n);
    	/*令K = Ha1||Ha2||  ||*/
    	for(i = 0; i < klen; i++)
    	{
    		if(kbuf[i] != 0)
    			break;
    	}
    
    	if(i < klen)
    		return 1;
    	else
    		return 0;
    
    }
    
    int sm2_encrypt(unsigned char *msg,int msglen, unsigned char *wx,int wxlen, unsigned char *wy,int wylen, unsigned char *outmsg)
    {
    
    	struct FPECC *cfig = &Ecc256;
        big x2, y2, c1, c2, k;
        big a,b,p,n,x,y;
        epoint *g, *w;
    	int ret = -1;
    	int i;
    	unsigned char zl[32], zr[32];
    	unsigned char *tmp;
        miracl *mip;
    	tmp = malloc(msglen+64);
    	if(tmp == NULL)
    		return -1;
    	mip = mirsys(20, 0);
    	mip->IOBASE = 16;
        p=mirvar(0);
    	a=mirvar(0);
        b=mirvar(0);
        n=mirvar(0);
        x=mirvar(0);
        y=mirvar(0);
    	k=mirvar(0);
    	x2=mirvar(0); 
    	y2=mirvar(0); 
    	c1=mirvar(0); 
    	c2=mirvar(0); 
        cinstr(p,cfig->p);
    	cinstr(a,cfig->a);
        cinstr(b,cfig->b);
    	cinstr(n,cfig->n);
    	cinstr(x,cfig->x);
        cinstr(y,cfig->y);
    	ecurve_init(a,b,p,MR_PROJECTIVE);
        g=epoint_init();
    	w=epoint_init();
        epoint_set(x,y,0,g);
    	bytes_to_big(wxlen,(char *)wx,x);
    	bytes_to_big(wylen,(char *)wy,y);
    	epoint_set(x,y,0,w);
        irand(time(NULL));
    sm2_encrypt_again:
    #if SM2_DEBUG
    	bytes_to_big(32, (char *)radom1, k);
    #else
    	do
    	{
    		bigrand(n, k);
    	} 
    	while (k->len == 0);
    #endif
    	ecurve_mult(k, g, g);
    	epoint_get(g, c1, c2);
    	big_to_bytes(32, c1, (char *)outmsg, TRUE);
    	big_to_bytes(32, c2, (char *)outmsg+32, TRUE);
    	//计算椭圆曲线点C1
    	if(point_at_infinity(w))
    		goto exit_sm2_encrypt;
    	//计算椭圆曲线点S
    	ecurve_mult(k, w, w);
    	epoint_get(w, x2, y2);
    	big_to_bytes(32, x2, (char *)zl, TRUE);
    	big_to_bytes(32, y2, (char *)zr, TRUE);
    	//计算椭圆曲线点[k]PB
    	if (kdf(zl, zr, msglen, outmsg+64) == 0)
    		goto sm2_encrypt_again;
    	//计算t = KDF,如果t全零,返回A1
    	for(i = 0; i < msglen; i++)
    	{
    		outmsg[64+i] ^= msg[i];
    	}
    	//计算C2
    	memcpy(tmp, zl, 32);
    	memcpy(tmp+32, msg, msglen);
    	memcpy(tmp+32+msglen, zr, 32);
    	sm3(tmp, 64+msglen, &outmsg[64+msglen]);
    	//计算C3
    	ret = msglen+64+32;
    	printf("key:");
    	cotnum(k, stdout);
    	//输出C,C在outmsg
    exit_sm2_encrypt:
    	mirkill(x2);  
    	mirkill(y2);  
    	mirkill(c1);  
    	mirkill(c2);  
    	mirkill(k);
    	mirkill(a);  
    	mirkill(b);
        mirkill(p);  
    	mirkill(n);  
    	mirkill(x);
    	mirkill(y);
        epoint_free(g); 
    	epoint_free(w);
    	mirexit();
    	free(tmp);
    	return ret;
    }
    
    
    int sm2_decrypt(unsigned char *msg,int msglen, unsigned char *privkey, int privkeylen, unsigned char *outmsg)
    {
    
    	struct FPECC *cfig = &Ecc256;
        big x2, y2, c, k;
        big a,b,p,n,x,y,key1;
        epoint *g;
    	unsigned char c3[32];
    	unsigned char zl[32], zr[32];
    	int i, ret = -1;
    	unsigned char *tmp;
        miracl *mip;
    	if(msglen < 96)
    		return 0;
    	msglen -= 96;
    	tmp = malloc(msglen+64);
    	if(tmp == NULL)
    		return 0;
    	mip = mirsys(20, 0);
    	mip->IOBASE = 16;
    	x2=mirvar(0); 
    	y2=mirvar(0); 
    	c=mirvar(0); 
    	k = mirvar(0);
        p = mirvar(0);
    	a = mirvar(0);
        b = mirvar(0);
        n = mirvar(0);
        x = mirvar(0);
        y = mirvar(0);
        key1 = mirvar(0);
        bytes_to_big(privkeylen,(char *)privkey,key1);
        cinstr(p,cfig->p);
    	cinstr(a,cfig->a);
        cinstr(b,cfig->b);
    	cinstr(n,cfig->n);
    	cinstr(x,cfig->x);
        cinstr(y,cfig->y);
    	ecurve_init(a,b,p,MR_PROJECTIVE);
        g = epoint_init();
    	bytes_to_big(32, (char *)msg, x);
    	bytes_to_big(32, (char *)msg+32, y);
        if(!epoint_set(x,y,0,g))
    		goto exit_sm2_decrypt;  //检验是否为椭圆曲线
    	if(point_at_infinity(g))
    		goto exit_sm2_decrypt;  //计算S
    	ecurve_mult(key1, g, g);
    	epoint_get(g, x2, y2);	
    	big_to_bytes(32, x2, (char *)zl, TRUE);
    	big_to_bytes(32, y2, (char *)zr, TRUE); //计算[db]c1
    	if (kdf(zl, zr, msglen, outmsg) == 0)
    		goto exit_sm2_decrypt;    //计算t
    	for(i = 0; i < msglen; i++)
    	{
    		outmsg[i] ^= msg[i+64];
    	}   //计算M到outsmg
    	memcpy(tmp, zl, 32);
    	memcpy(tmp+32, outmsg, msglen);
    	memcpy(tmp+32+msglen, zr, 32);
    	sm3(tmp, 64+msglen, c3);//计算u
    	if(memcmp(c3, msg+64+msglen, 32) != 0)
    		goto exit_sm2_decrypt;
    	ret =  msglen;
    exit_sm2_decrypt:
    	mirkill(x2);  
    	mirkill(y2);  
    	mirkill(c);  
    	mirkill(k);
    	mirkill(p);
    	mirkill(a); 
    	mirkill(b); 
    	mirkill(n); 
    	mirkill(x); 
    	mirkill(y); 
    	mirkill(key1);
        epoint_free(g);
    	mirexit();
    	free(tmp);
    	return ret;
    }
    int main()
    {
    	printf("sm2 test....
    ");
    	
    	
    	unsigned char dB[] = { 0x16,0x49,0xAB,0x77,0xA0,0x06,0x37,0xBD,0x5E,0x2E,0xFE,0x28,0x3F,0xBF,0x35,0x35,0x34,0xAA,0x7F,0x7C,0xB8,0x94,0x63,0xF2,0x08,0xDD,0xBC,0x29,0x20,0xBB,0x0D,0xA0 };
    	unsigned char xB[] = { 0x43,0x5B,0x39,0xCC,0xA8,0xF3,0xB5,0x08,0xC1,0x48,0x8A,0xFC,0x67,0xBE,0x49,0x1A,0x0F,0x7B,0xA0,0x7E,0x58,0x1A,0x0E,0x48,0x49,0xA5,0xCF,0x70,0x62,0x8A,0x7E,0x0A };
    	unsigned char yB[] = { 0x75,0xDD,0xBA,0x78,0xF1,0x5F,0xEE,0xCB,0x4C,0x78,0x95,0xE2,0xC1,0xCD,0xF5,0xFE,0x01,0xDE,0xBB,0x2C,0xDB,0xAD,0xF4,0x53,0x99,0xCC,0xF7,0x7B,0xBA,0x07,0x6A,0x42 };
    	unsigned char tx[256];
    	unsigned char etx[256];
    	unsigned char mtx[256];
    	FILE *fp=0;
    	int wxlen, wylen, privkeylen,len;
    	//fopen(&fp, "5.txt", "r");
    	//len=fread_s(tx, 256,sizeof(unsigned char), 256, fp);
    	fp = fopen("5.txt","r");
    	len=fread(tx,1,256,fp);
    	tx[len] = "";
    	sm2_keygen(xB, &wxlen, yB, &wylen, dB, &privkeylen);
    	printf("dB: ");
    	PrintBuf(dB, 32);
    	printf("xB: ");
    	PrintBuf(xB, 32);
    	printf("yB: ");
    	PrintBuf(yB, 32);
    	sm2_encrypt(tx,len,xB,32,yB,32,etx);
    	printf("
    ``````````````````this is encrypt```````````````````
    ");
    	PrintBuf(etx, 64 +len + 32);
    	printf("
    ``````````````````this is decrypt```````````````````
    ");
    	sm2_decrypt(etx,64+len+32,dB,32,mtx);
    	if(sm2_decrypt(etx,64+len+32,dB,32,mtx) < 0)
    		printf("sm2_decrypt error!
    ");
    	else
    	{
    		PrintBuf(mtx, len);
    		Printch(mtx, len);
    	}
    
    	printf("
    ``````````````````this is end```````````````````````
    ");
    	return 0;
    }
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    
    #include "sm3.h"
    
    #define nl2c(l,c)	(*((c)++) = (unsigned char)(((l) >> 24) & 0xff), 
    					 *((c)++) = (unsigned char)(((l) >> 16) & 0xff), 
    					 *((c)++) = (unsigned char)(((l) >> 8)  & 0xff), 
    					 *((c)++) = (unsigned char)(((l)    )   & 0xff))
    
    #define c_2_nl(c)	((*(c) << 24) | (*(c+1) << 16) | (*(c+2) << 8) | *(c+3))
    #define ROTATE(X, C) (((X) << (C)) | ((X) >> (32 - (C))))
    
    #define TH 0x79cc4519
    #define TL 0x7a879d8a
    #define FFH(X, Y, Z) ((X) ^ (Y) ^ (Z))
    #define FFL(X, Y, Z) (((X) & (Y)) | ((X) & (Z)) | ((Y) & (Z)))
    #define GGH(X, Y, Z) ((X) ^ (Y) ^ (Z))
    #define GGL(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
    #define P0(X)  ((X) ^ (((X) << 9) | ((X) >> 23)) ^ (((X) << 17) | ((X) >> 15)))
    #define P1(X)  ((X) ^ (((X) << 15) | ((X) >> 17)) ^ (((X) << 23) | ((X) >> 9)))
    
    #define DEBUG_SM3 0
    
    
    void sm3_block(SM3_CTX *ctx)
    {
    	register int j, k;
    	register unsigned long t;
    	register unsigned long ss1, ss2, tt1, tt2;
    	register unsigned long a, b, c, d, e, f, g, h;
    	unsigned long w[132];
    
    
    	for(j = 0; j < 16; j++)
    		w[j] = ctx->data[j];
    
    	for(j = 16; j < 68; j++)
    	{
    		t = w[j-16] ^ w[j-9] ^ ROTATE(w[j-3], 15);
    		w[j] = P1(t) ^ ROTATE(w[j-13], 7) ^ w[j-6];
    	}
    
    
    	for(j = 0, k = 68; j < 64; j++, k++)
    	{
    		w[k] = w[j] ^ w[j+4];
    	}
    
    
    	a = ctx->h[0];
    	b = ctx->h[1];
    	c = ctx->h[2];
    	d = ctx->h[3];
    	e = ctx->h[4];
    	f = ctx->h[5];
    	g = ctx->h[6];
    	h = ctx->h[7];
    
    	for(j = 0; j < 16; j++)
    	{
    		ss1 = ROTATE(ROTATE(a, 12) +  e + ROTATE(TH, j), 7);
    		ss2 = ss1 ^ ROTATE(a, 12);
    		tt1 = FFH(a, b, c) + d + ss2 + w[68 + j];
    		tt2 = GGH(e, f, g) + h + ss1 + w[j];
    
    		d = c; 
    		c = ROTATE(b, 9);
    		b = a;
    		a = tt1;
    
    		h = g;
    		g = ROTATE(f, 19);
    		f = e;
    		e = P0(tt2);
    	}
    
    
    	for(j = 16; j < 33; j++)
    	{
    		ss1 = ROTATE(ROTATE(a, 12) +  e + ROTATE(TL, j), 7);
    		ss2 = ss1 ^ ROTATE(a, 12);
    		tt1 = FFL(a, b, c) + d + ss2 + w[68 + j];
    		tt2 = GGL(e, f, g) + h + ss1 + w[j];
    
    		d = c;
    		c = ROTATE(b, 9);
    		b = a;
    		a = tt1;
    
    		h = g;
    		g = ROTATE(f, 19);
    		f = e;
    		e = P0(tt2);
    	}
    
    	for(j = 33; j < 64; j++)
    	{
    		ss1 = ROTATE(ROTATE(a, 12) +  e + ROTATE(TL, (j-32)), 7);
    		ss2 = ss1 ^ ROTATE(a, 12);
    		tt1 = FFL(a, b, c) + d + ss2 + w[68 + j];
    		tt2 = GGL(e, f, g) + h + ss1 + w[j];
    
    		d = c;
    		c = ROTATE(b, 9);
    		b = a;
    		a = tt1;
    
    		h = g;
    		g = ROTATE(f, 19);
    		f = e;
    		e = P0(tt2);
    	}
    
    	ctx->h[0]  ^=  a ;
    	ctx->h[1]  ^=  b ;
    	ctx->h[2]  ^=  c ;
    	ctx->h[3]  ^=  d ;
    	ctx->h[4]  ^=  e ;
    	ctx->h[5]  ^=  f ;
    	ctx->h[6]  ^=  g ;
    	ctx->h[7]  ^=  h ;
    
    }
    
    
    void SM3_Init (SM3_CTX *ctx)
    {
    	ctx->h[0] = 0x7380166fUL;
    	ctx->h[1] = 0x4914b2b9UL;
    	ctx->h[2] = 0x172442d7UL;
    	ctx->h[3] = 0xda8a0600UL;
    	ctx->h[4] = 0xa96f30bcUL;
    	ctx->h[5] = 0x163138aaUL;
    	ctx->h[6] = 0xe38dee4dUL;
    	ctx->h[7] = 0xb0fb0e4eUL;
    	ctx->Nl   = 0;
    	ctx->Nh   = 0;
    	ctx->num  = 0;
    }
    
    void SM3_Update(SM3_CTX *ctx, const void *data, unsigned int len)
    {
    	unsigned char *d;
    	unsigned long l;
    	int i, sw, sc;
    
    
    	if (len == 0)
    		return;
    
    	l = (ctx->Nl + (len << 3)) & 0xffffffffL;
    	if (l < ctx->Nl) /* overflow */
    		ctx->Nh++;
    	ctx->Nh += (len >> 29);
    	ctx->Nl = l;
    
    	d = (unsigned char *)data;
    
    	while (len >= SM3_CBLOCK)
    	{
    		ctx->data[0] = c_2_nl(d);
    		d += 4;
    		ctx->data[1] = c_2_nl(d);
    		d += 4;
    		ctx->data[2] = c_2_nl(d);
    		d += 4;
    		ctx->data[3] = c_2_nl(d);
    		d += 4;
    		ctx->data[4] = c_2_nl(d);
    		d += 4;
    		ctx->data[5] = c_2_nl(d);
    		d += 4;
    		ctx->data[6] = c_2_nl(d);
    		d += 4;
    		ctx->data[7] = c_2_nl(d);
    		d += 4;
    		ctx->data[8] = c_2_nl(d);
    		d += 4;
    		ctx->data[9] = c_2_nl(d);
    		d += 4;
    		ctx->data[10] = c_2_nl(d);
    		d += 4;
    		ctx->data[11] = c_2_nl(d);
    		d += 4;
    		ctx->data[12] = c_2_nl(d);
    		d += 4;
    		ctx->data[13] = c_2_nl(d);
    		d += 4;
    		ctx->data[14] = c_2_nl(d);
    		d += 4;
    		ctx->data[15] = c_2_nl(d);
    		d += 4;
    
    		sm3_block(ctx);
    		len -= SM3_CBLOCK;
    	}
    
    	if(len > 0)
    	{
    		memset(ctx->data, 0, 64);
    		ctx->num = len + 1;
    		sw = len >> 2;
    		sc = len & 0x3;
    
    		for(i = 0; i < sw; i++)
    		{
    			ctx->data[i] = c_2_nl(d);
    			d += 4;
    		}
    
    		switch(sc)
    		{
    			case 0:
    				ctx->data[i] = 0x80000000;
    				break;
    			case 1:
    				ctx->data[i] = (d[0] << 24) | 0x800000;
    				break;
    			case 2:
    				ctx->data[i] = (d[0] << 24) | (d[1] << 16) | 0x8000;
    				break;
    			case 3:
    				ctx->data[i] = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | 0x80;
    				break;
    		}
    
    	}
    
    
    }
    
    void SM3_Final(unsigned char *md, SM3_CTX *ctx)
    {
    
    	if(ctx->num == 0)
    	{
    		memset(ctx->data, 0, 64);
    		ctx->data[0] = 0x80000000;
    		ctx->data[14] = ctx->Nh;
    		ctx->data[15] = ctx->Nl;
    	}
    	else
    	{
    		if(ctx->num <= SM3_LAST_BLOCK)
    		{
    			ctx->data[14] = ctx->Nh;
    			ctx->data[15] = ctx->Nl;
    		}
    		else
    		{
    			sm3_block(ctx);
    			memset(ctx->data, 0, 56);
    			ctx->data[14] = ctx->Nh;
    			ctx->data[15] = ctx->Nl;
    		}
    	}
    
    	sm3_block(ctx);
    	nl2c(ctx->h[0], md);
    	nl2c(ctx->h[1], md);
    	nl2c(ctx->h[2], md);
    	nl2c(ctx->h[3], md);
    	nl2c(ctx->h[4], md);
    	nl2c(ctx->h[5], md);
    	nl2c(ctx->h[6], md);
    	nl2c(ctx->h[7], md);
    }
    
    unsigned char *sm3(const unsigned char *d, unsigned int n, unsigned char *md)
    {
    	SM3_CTX ctx;
    
    	SM3_Init(&ctx);
    	SM3_Update(&ctx, d, n);
    	SM3_Final(md, &ctx);
    	memset(&ctx, 0, sizeof(ctx));
    	return(md);
    }

    makefile文件:

    ############################################################################
    #makefile
    ############################################################################
    
    #****************************************************************************
    # Cross complie path
    #****************************************************************************
    #GCC_PATH=D:msysgitmingw
    #CHAIN_ROOT=/home/yang/imax283/ctools/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin
    
    #CROSS_COMPILE=$(CHAIN_ROOT)/arm-none-linux-gnueabi-
    
    #CHAIN_ROOT= /home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin
    #CROSS_COMPILE=$(CHAIN_ROOT)/arm-linux-gnueabihf-
    CROSS_COMPILE = 
    
    CC     := $(CROSS_COMPILE)gcc
    CXX    := $(CROSS_COMPILE)g++
    AS       := $(CROSS_COMPILE)as
    AR     := $(CROSS_COMPILE)ar 
    LD     := $(CROSS_COMPILE)ld
    RANLIB := $(CROSS_COMPILE)ranlib
    OBJDUMP:= $(CROSS_COMPILE)objdump
    OBJCOPY:= $(CROSS_COMPILE)objcopy
    STRIP  := $(CROSS_COMPILE)strip
    
    #****************************************************************************
    # Flags
    #****************************************************************************
    
    CFLAGS= 
    LDSCRIPT= -L./ -lsm2
    LDFLAGS= 
    
    
    #****************************************************************************
    # Source files
    #****************************************************************************
    SRC_C=$(shell find . -name "*.c")
    
    OBJ_C=$(patsubst %.c, %.o, $(SRC_C))
    
    SRCS := $(SRC_C) $(SRC_C)
    
    OBJS := $(OBJ_C) 
    
    
    #****************************************************************************
    # Targets of the build
    #****************************************************************************
    TARGET       := test
    
    .PHONY: clean
    all:  prebuild  $(TARGET)
    
    #****************************************************************************
    # TARGET
    #****************************************************************************
    prebuild:
        @echo Building exe...
    
    $(TARGET) : $(OBJS)
        @echo Generating exe...
        $(CC) -o  $(TARGET)  $(OBJS) $(LDSCRIPT)
        @echo OK!
    
    %.o : %.c
        $(CC) -c  $(CFLAGS) $< -o  $@
        
    clean:
        @echo The following files:
        rm  -f  $(TARGET) *.so
        find . -name "*.[od]" |xargs rm
        @echo Removed!

    测试结果:

    本文参与腾讯云自媒体分享计划,欢迎正在阅

  • 相关阅读:
    golang学习 ---并发获取多个URL
    MySQL的my.cnf文件(解决5.7.18下没有my-default.cnf)
    Python ElasticSearch API
    linux 输出重定向 何时会写文件
    Linux top命令的用法详细详解
    mysql 5.7.13 安装配置方法(linux)-后期部分运维
    linux下各目录的作用
    MySQL 获得当前日期时间 函数
    mysql导入大批量数据出现MySQL server has gone away的解决方法
    python之MySQL学习——防止SQL注入
  • 原文地址:https://www.cnblogs.com/telwanggs/p/15065778.html
Copyright © 2020-2023  润新知