可在STM32上使用的国密算法 SM 2 3 4

  • SM2
  • SM3
  • SM4

下面直接给出代码,有问题可评论,自己改动的,测试不到的地方可能有bug,欢迎指正。

SM2

由于SM2算法牵扯到一些较为复杂的数理计算,需要依靠数学运算库,在嵌入式设备上实现得到方法主要有两种:移植openssl或miracl库,再者就是使用硬件的加密芯片。
我使用的是移植了miracl库来实现,编译所需文件为lib库,在工程中引用。下面贴出主要代码:
sm2.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miracl.h"
#include "sm2.h"
#include "sm3.h"
#include "global_variable.h" //这个头文件用于提供在滴答计时器中我的一个全局计数变量sysTick给//irand使用产生随机数#define SM2_PAD_ZERO TRUE
//#define SM2_PAD_ZERO FALSE#define SM2_DEBUG   0
/*
#define QBITS 256
#define PBITS 3072
#define MAX_ECC_KEY_LEN     256
#define MAX_ECC_KEY_SIZE    (MAX_ECC_KEY_LEN/8)
*/struct FPECC{char *p;
char *a;
char *b;
char *n;
char *x;
char *y;
};void PrintBuf(unsigned char *buf, int buflen)
{int i;printf("\r\n");printf("len = %d\r\n", buflen);for(i=0; i<buflen; i++) {if (i % 32 != 31)printf("%02x", buf[i]);elseprintf("%02x\r\n", buf[i]);}printf("\r\n");return;
}void Printch(unsigned char *buf, int   buflen)
{int i;for (i = 0; i < buflen; i++) {if (i % 32 != 31)printf("%c", buf[i]);elseprintf("%c\n", buf[i]);}printf("\n");//return 0;
}
#if SM2_DEBUGvoid PrintBig(big data)
{int len=0;unsigned char buf[10240];len=big_to_bytes(0,data,(char *)buf,0);PrintBuf(buf,len);
}unsigned char radom[]  = {0x6C,0xB2,0x8D,0x99,0x38,0x5C,0x17,0x5C,0x94,0xF9,0x4E,0x93,0x48,0x17,0x66,0x3F,0xC1,0x76,0xD9,0x25,0xDD,0x72,0xB7,0x27,0x26,0x0D,0xBA,0xAE,0x1F,0xB2,0xF9,0x6F};
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};
unsigned char randkey[] = {0x83,0xA2,0xC9,0xC8,0xB9,0x6E,0x5A,0xF7,0x0B,0xD4,0x80,0xB4,0x72,0x40,0x9A,0x9A,0x32,0x72,0x57,0xF1,0xEB,0xB7,0x3F,0x5B,0x07,0x33,0x54,0xB2,0x48,0x66,0x85,0x63};
unsigned char randkeyb[]= {0x33,0xFE,0x21,0x94,0x03,0x42,0x16,0x1C,0x55,0x61,0x9C,0x4A,0x0C,0x06,0x02,0x93,0xD5,0x43,0xC8,0x0A,0xF1,0x97,0x48,0xCE,0x17,0x6D,0x83,0x47,0x7D,0xE7,0x1C,0x80};struct FPECC Ecc256={"8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",
"787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",
"63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",
"8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",
"421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",
"0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2",
};
unsigned char sm2_par_dig[128] = {0x78,0x79,0x68,0xB4,0xFA,0x32,0xC3,0xFD,0x24,0x17,0x84,0x2E,0x73,0xBB,0xFE,0xFF,
0x2F,0x3C,0x84,0x8B,0x68,0x31,0xD7,0xE0,0xEC,0x65,0x22,0x8B,0x39,0x37,0xE4,0x98,
0x63,0xE4,0xC6,0xD3,0xB2,0x3B,0x0C,0x84,0x9C,0xF8,0x42,0x41,0x48,0x4B,0xFE,0x48,
0xF6,0x1D,0x59,0xA5,0xB1,0x6B,0xA0,0x6E,0x6E,0x12,0xD1,0xDA,0x27,0xC5,0x24,0x9A,
0x42,0x1D,0xEB,0xD6,0x1B,0x62,0xEA,0xB6,0x74,0x64,0x34,0xEB,0xC3,0xCC,0x31,0x5E,
0x32,0x22,0x0B,0x3B,0xAD,0xD5,0x0B,0xDC,0x4C,0x4E,0x6C,0x14,0x7F,0xED,0xD4,0x3D,
0x06,0x80,0x51,0x2B,0xCB,0xB4,0x2C,0x07,0xD4,0x73,0x49,0xD2,0x15,0x3B,0x70,0xC4,
0xE5,0xD7,0xFD,0xFC,0xBF,0xA3,0x6E,0xA1,0xA8,0x58,0x41,0xB9,0xE4,0x6E,0x09,0xA2,
};#else
/*SM2*/
struct FPECC Ecc256={"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0",
};unsigned char sm2_par_dig[128] = {0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
0x28,0xE9,0xFA,0x9E,0x9D,0x9F,0x5E,0x34,0x4D,0x5A,0x9E,0x4B,0xCF,0x65,0x09,0xA7,
0xF3,0x97,0x89,0xF5,0x15,0xAB,0x8F,0x92,0xDD,0xBC,0xBD,0x41,0x4D,0x94,0x0E,0x93,
0x32,0xC4,0xAE,0x2C,0x1F,0x19,0x81,0x19,0x5F,0x99,0x04,0x46,0x6A,0x39,0xC9,0x94,
0x8F,0xE3,0x0B,0xBF,0xF2,0x66,0x0B,0xE1,0x71,0x5A,0x45,0x89,0x33,0x4C,0x74,0xC7,
0xBC,0x37,0x36,0xA2,0xF4,0xF6,0x77,0x9C,0x59,0xBD,0xCE,0xE3,0x6B,0x69,0x21,0x53,
0xD0,0xA9,0x87,0x7C,0xC6,0x2A,0x47,0x40,0x02,0xDF,0x32,0xE5,0x21,0x39,0xF0,0xA0,
};unsigned char enkey[32] = {0xB1,0x6B,0xA0,0xDA,0x27,0xC5,0x24,0x9A,0xF6,0x1D,0x6E,0x6E,0x12,0xD1,0x59,0xA5,
0xB6,0x74,0x64,0x34,0xEB,0xD6,0x1B,0x62,0xEA,0xEB,0xC3,0xCC,0x31,0x5E,0x42,0x1D,
};
#endif#define SEED_CONST 0x1BD8C95A/*** @brief 生成SM2公私钥对* @param wx:         公钥的X坐标,不足32字节在前面加0x00* @param wxlen:       wx的字节数,32* @param wy:         公钥的Y坐标,不足32字节在前面加0x00* @param wylen:       wy的字节数,32* @param privkey:    私钥,不足32字节在前面加0x00* @param privkeylen: privkey的字节数,32* @retval void*/
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 instance;miracl *mip = &instance;char mem[MR_BIG_RESERVE(7)];memset(mem, 0, MR_BIG_RESERVE(7));mip = mirsys(mip, 20, 0);   /* Use Hex Internally */mip->IOBASE = 16;p = mirvar_mem(mip, mem, 0);a = mirvar_mem(mip, mem, 1);b = mirvar_mem(mip, mem, 2);n = mirvar_mem(mip, mem, 3);x = mirvar_mem(mip, mem, 4);y = mirvar_mem(mip, mem, 5);key1 = mirvar_mem(mip, mem, 6);cinstr(mip, p, cfig->p);cinstr(mip, a, cfig->a);cinstr(mip, b, cfig->b);cinstr(mip, n, cfig->n);cinstr(mip, x, cfig->x);cinstr(mip, y, cfig->y);ecurve_init(mip, a, b, p, MR_PROJECTIVE);char mem1[MR_ECP_RESERVE(1)]; memset(mem1 ,0, MR_ECP_RESERVE(1));g = epoint_init_mem(mip, mem1, 0);epoint_set(mip, x, y, 0, g);irand(mip, sysTick);/* generate public/private keys */bigrand(mip, n, key1);ecurve_mult(mip, key1,g,g);epoint_get(mip, g,x,y); /* compress point */*wxlen = big_to_bytes(mip, 32, x, (char *)wx, TRUE);*wylen = big_to_bytes(mip, 32, y, (char *)wy, TRUE);*privkeylen = big_to_bytes(mip, 32, key1, (char *)privkey, TRUE);/* clear all memory used */memset(mem,0,MR_BIG_RESERVE(7));memset(mem1,0,MR_ECP_RESERVE(1));mirexit(mip);
}/*** @brief  密钥派生函数* @param  zl  要处理的数据——list(x)* @param  zr  要处理的数据——row(y)* @param  keylen  需要派生得到的长度* @param  kbuf    计算后返回的内容(二进制值),分配空间至少为需要keylen* @retval 0:成功 其他失败*/
int kdf(unsigned char *zl, unsigned char *zr, int klen, unsigned char *kbuf)
{unsigned char buf[70];unsigned char digest[32];unsigned int ct = 0x00000001; //初始化一个32比特构成的计数器ct=0x00000001int 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;SM3Calc(buf, 68, p);p += 32;ct++;}if(n != 0){buf[64] = (ct >> 24) & 0xFF;buf[65] = (ct >> 16) & 0xFF;buf[66] = (ct >> 8) & 0xFF;buf[67] = ct & 0xFF;SM3Calc(buf, 68, digest);}memcpy(p, digest, n);for(i = 0; i < klen; i++){if(kbuf[i] != 0)break;}if(i < klen)return 1;elsereturn 0;
}/*** @brief  SM2加密* @param  msg:    要加密的明文数据* @param  msglen: 明文数据长度* @param  wx:     公钥的x坐标* @param  wxlen:  公钥的x坐标长度,不超过32* @param  wy:     公钥的y坐标* @param  wylen:  公钥的y坐标长度,不超过32* @param  outmsg: 加密后密文 长度为明文 + 96* @retval -1:失败 msglen + 96:成功*/
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 instance;miracl *mip = &instance;tmp = malloc(msglen+64);if(tmp == NULL)return -1;mip = mirsys(mip, 20, 0);   /* Use Hex Internally */mip->IOBASE = 16;char mem[MR_BIG_RESERVE(11)];memset(mem, 0, MR_BIG_RESERVE(11));p= mirvar_mem(mip, mem, 0);a=mirvar_mem(mip, mem, 1);b=mirvar_mem(mip, mem, 2);n=mirvar_mem(mip, mem, 3);x=mirvar_mem(mip, mem, 4);y=mirvar_mem(mip, mem, 5);k=mirvar_mem(mip, mem, 6);x2=mirvar_mem(mip, mem, 7);y2=mirvar_mem(mip, mem, 8);c1=mirvar_mem(mip, mem, 9);c2=mirvar_mem(mip, mem, 10);cinstr(mip, p,cfig->p);cinstr(mip, a,cfig->a);cinstr(mip, b,cfig->b);cinstr(mip, n,cfig->n);cinstr(mip, x,cfig->x);cinstr(mip, y,cfig->y);ecurve_init(mip, a,b,p,MR_PROJECTIVE);char mem1[MR_ECP_RESERVE(2)]; memset(mem1 ,0, MR_ECP_RESERVE(2));g = epoint_init_mem(mip, mem1,0);w = epoint_init_mem(mip, mem1,1);epoint_set(mip, x,y,0,g);bytes_to_big(mip, wxlen,(char *)wx,x);bytes_to_big(mip, wylen,(char *)wy,y);epoint_set(mip, x,y,0,w);irand(mip, sysTick);
sm2_encrypt_again:
#if SM2_DEBUGbytes_to_big(32, (char *)radom1, k);
#elsedo{bigrand(mip, n, k);} while (k->len == 0);
#endifecurve_mult(mip, k, g, g);epoint_get(mip, g, c1, c2);big_to_bytes(mip, 32, c1, (char *)outmsg, TRUE);big_to_bytes(mip, 32, c2, (char *)outmsg+32, TRUE);//计算椭圆曲线点C1if(point_at_infinity(w))goto exit_sm2_encrypt;//计算椭圆曲线点Securve_mult(mip, k, w, w);epoint_get(mip, w, x2, y2);big_to_bytes(mip, 32, x2, (char *)zl, TRUE);big_to_bytes(mip, 32, y2, (char *)zr, TRUE);//计算椭圆曲线点[k]PBif (kdf(zl, zr, msglen, outmsg+64) == 0)goto sm2_encrypt_again;//计算t = KDF,如果t全零,返回A1for(i = 0; i < msglen; i++){outmsg[64+i] ^= msg[i];}//计算C2memcpy(tmp, zl, 32);memcpy(tmp+32, msg, msglen);memcpy(tmp+32+msglen, zr, 32);SM3Calc(tmp, 64+msglen, &outmsg[64+msglen]);//计算C3ret = msglen+64+32;exit_sm2_encrypt:memset(mem,0,MR_BIG_RESERVE(11));memset(mem1,0,MR_ECP_RESERVE(2));mirexit(mip);free(tmp);return ret;
}/**
* @brief  SM2解密
* @param  msg:        要解密的密文数据
* @param  msglen:     密文数据长度
* @param  privkey:    私钥
* @param  privkeylen: 私钥长度
* @param  outmsg: 解密后的明文 长度为明文 - 96
* @retval -1:失败 msglen - 96:成功
*/
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 instance;miracl *mip = &instance;if(msglen < 96)return 0;msglen -= 96;tmp = malloc(msglen+64);if(tmp == NULL)return 0;mip = mirsys(mip, 20, 0);   /* Use Hex Internally */mip->IOBASE = 16;char mem[MR_BIG_RESERVE(11)];memset(mem, 0, MR_BIG_RESERVE(11));x2 = mirvar_mem(mip, mem, 0);y2 = mirvar_mem(mip, mem, 1);c = mirvar_mem(mip, mem, 2);k = mirvar_mem(mip, mem, 3);p = mirvar_mem(mip, mem, 4);a = mirvar_mem(mip, mem, 5);b = mirvar_mem(mip, mem, 6);n = mirvar_mem(mip, mem, 7);x = mirvar_mem(mip, mem, 8);y = mirvar_mem(mip, mem, 9);key1 = mirvar_mem(mip, mem, 10);bytes_to_big(mip, privkeylen,(char *)privkey,key1);cinstr(mip, p,cfig->p);cinstr(mip, a,cfig->a);cinstr(mip, b,cfig->b);cinstr(mip, n,cfig->n);cinstr(mip, x,cfig->x);cinstr(mip, y,cfig->y);ecurve_init(mip, a,b,p,MR_PROJECTIVE);char mem1[MR_ECP_RESERVE(1)]; memset(mem1 ,0, MR_ECP_RESERVE(1));g = epoint_init_mem(mip, mem1,0);bytes_to_big(mip, 32, (char *)msg, x);bytes_to_big(mip, 32, (char *)msg+32, y);if(!epoint_set(mip, x,y,0,g))goto exit_sm2_decrypt;  //检验是否为椭圆曲线if(point_at_infinity(g))goto exit_sm2_decrypt;  //计算Securve_mult(mip, key1, g, g);epoint_get(mip, g, x2, y2); big_to_bytes(mip, 32, x2, (char *)zl, TRUE);big_to_bytes(mip, 32, y2, (char *)zr, TRUE); //计算[db]c1if (kdf(zl, zr, msglen, outmsg) == 0)goto exit_sm2_decrypt;    //计算tfor(i = 0; i < msglen; i++){outmsg[i] ^= msg[i+64];}   //计算M到outsmgmemcpy(tmp, zl, 32);memcpy(tmp+32, outmsg, msglen);memcpy(tmp+32+msglen, zr, 32);SM3Calc(tmp, 64+msglen, c3);//计算uif(memcmp(c3, msg+64+msglen, 32) != 0){goto exit_sm2_decrypt;}ret =  msglen;
exit_sm2_decrypt:memset(mem,0,MR_BIG_RESERVE(11));memset(mem1,0,MR_ECP_RESERVE(1));mirexit(mip);free(tmp);return ret;
}int sm2_encrypt_test(void)
{   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[25] = {0x16,0x49,0xAB,0x77,0xA0,0x06,0x37,0xBD,0x5E,0x2E,0x16,0x49,0xAB,0x77,0xA0,0x06,0x37,0xBD,0x5E,0x2E};unsigned char etx[256];unsigned char mtx[256];int wxlen, wylen, privkeylen,len,ret;sm2_keygen(xB, &wxlen, yB, &wylen, dB, &privkeylen);printf("dB: ");PrintBuf(dB, 32);printf("xB: ");PrintBuf(xB, 32);printf("yB: ");PrintBuf(yB, 32);len = 20;printf("\n``````````````````before encrypt```````````````````\n");PrintBuf(tx, len);printf("\n``````````````````this is encrypt```````````````````\n");sm2_encrypt(tx,len,xB,32,yB,32,etx);PrintBuf(etx, 64 +len + 32);printf("\n``````````````````this is decrypt```````````````````\n");ret = sm2_decrypt(etx,64+len+32,dB,32,mtx);if( ret < 0)printf("sm2_decrypt error!\n");else{PrintBuf(mtx, len);} return 0;
}
int sm2_encrypt_test(void)
{   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[25] = {0x16,0x49,0xAB,0x77,0xA0,0x06,0x37,0xBD,0x5E,0x2E,0x16,0x49,0xAB,0x77,0xA0,0x06,0x37,0xBD,0x5E,0x2E};unsigned char etx[256];unsigned char mtx[256];int wxlen, wylen, privkeylen,len,ret;sm2_keygen(xB, &wxlen, yB, &wylen, dB, &privkeylen);printf("dB: ");PrintBuf(dB, 32);printf("xB: ");PrintBuf(xB, 32);printf("yB: ");PrintBuf(yB, 32);len = 20;printf("\n``````````````````before encrypt```````````````````\n");PrintBuf(tx, len);printf("\n``````````````````this is encrypt```````````````````\n");sm2_encrypt(tx,len,xB,32,yB,32,etx);PrintBuf(etx, 64 +len + 32);printf("\n``````````````````this is decrypt```````````````````\n");ret = sm2_decrypt(etx,64+len+32,dB,32,mtx);if( ret < 0)printf("sm2_decrypt error!\n");else{PrintBuf(mtx, len);} return 0;
}

很重要的头文件:mirdef.h 用于编译产生适合于stm32的lib库

/* *   MIRACL compiler/hardware definitions - mirdef.h*   This version suitable for use with most 32-bit computers*   e.g. 80386+ PC, VAX, ARM etc. Assembly language versions of muldiv,*   muldvm, muldvd and muldvd2 will be necessary. See mrmuldv.any **   Also suitable for DJGPP GNU C Compiler*   ... but change __int64 to long long*//**   MIRACL compiler/hardware definitions - mirdef.h*/#define MIRACL 32
#define MR_LITTLE_ENDIAN      /* or possibly
#define MR_BIG_ENDIAN
*/#define mr_utype int
#define MR_IBITS 32
#define mr_dltype __int64
#define mr_unsign32 unsigned int
#define mr_unsign64 unsigned __int64
#define MAXBASE ((mr_small)1<<(MIRACL-1))
#define MR_STATIC 20
#define MR_GENERIC_MT
#define MR_NOASM

其中关于sm3的算法SM3Calc()在sm3部分给出。
和其他平台的区别可行比较琢磨。
给出直接编译好的lib库:https://download.csdn.net/download/weixin_44522056/12483974

SM3

直接给出代码,和其他平台的区别自行比较学习
sm3.c

/*
* sm3.c
*/
#include <stdio.h>
#include "string.h"
#include "sm3.h"/*
* 判断运行环境是否为小端
*/
static const int endianTest = 1;
#define IsLittleEndian() (*(char *)&endianTest == 1)/*
* 向左循环移位
*/
//#define LeftRotate(word, bits) ( (word) << (bits) | (word) >> (32 - (bits)) )#define SHL(x,n) (((x) & 0xFFFFFFFF) << n%32)
#define LeftRotate(x,n) (SHL((x),n) | ((x) >> (32 - n%32)))
/*
* 反转四字节整型字节序
*/
unsigned int *ReverseWord(unsigned int *word)
{unsigned char *byte, temp;byte = (unsigned char *)word;temp = byte[0];byte[0] = byte[3];byte[3] = temp;temp = byte[1];byte[1] = byte[2];byte[2] = temp;return word;
}/*
* T
*/
unsigned int T(int i)
{if (i >= 0 && i <= 15)return 0x79CC4519;else if (i >= 16 && i <= 63)return 0x7A879D8A;elsereturn 0;
}/*
* FF
*/
unsigned int FF(unsigned int X, unsigned int Y, unsigned int Z, int i)
{if (i >= 0 && i <= 15)return X ^ Y ^ Z;else if (i >= 16 && i <= 63)return (X & Y) | (X & Z) | (Y & Z);elsereturn 0;
}/*
* GG
*/
unsigned int GG(unsigned int X, unsigned int Y, unsigned int Z, int i)
{if (i >= 0 && i <= 15)return X ^ Y ^ Z;else if (i >= 16 && i <= 63)return (X & Y) | (~X & Z);elsereturn 0;
}/*
* P0
*/
unsigned int P0(unsigned int X)
{return X ^ LeftRotate(X, 9) ^ LeftRotate(X, 17);
}/*
* P1
*/
unsigned int P1(unsigned int X)
{return X ^ LeftRotate(X, 15) ^ LeftRotate(X, 23);
}/*
* 初始化函数
*/
void SM3Init(SM3Context *context)
{context->intermediateHash[0] = 0x7380166F;context->intermediateHash[1] = 0x4914B2B9;context->intermediateHash[2] = 0x172442D7;context->intermediateHash[3] = 0xDA8A0600;context->intermediateHash[4] = 0xA96F30BC;context->intermediateHash[5] = 0x163138AA;context->intermediateHash[6] = 0xE38DEE4D;context->intermediateHash[7] = 0xB0FB0E4E;
}/*
* 处理消息块
*/
void SM3ProcessMessageBlock(SM3Context *context)
{int i;unsigned int W[68];unsigned int W_[64];unsigned int A, B, C, D, E, F, G, H, SS1, SS2, TT1, TT2;/* 消息扩展 */for (i = 0; i < 16; i++){W[i] = *(unsigned int *)(context->messageBlock + i * 4);if (IsLittleEndian())ReverseWord(W + i);//printf("%d: %x\n", i, W[i]);    }for (i = 16; i < 68; i++){W[i] = P1(W[i - 16] ^ W[i - 9] ^ LeftRotate(W[i - 3], 15))^ LeftRotate(W[i - 13], 7)^ W[i - 6];//printf("%d: %x\n", i, W[i]);    }for (i = 0; i < 64; i++){W_[i] = W[i] ^ W[i + 4];//printf("%d: %x\n", i, W_[i]);    }/* 消息压缩 */A = context->intermediateHash[0];B = context->intermediateHash[1];C = context->intermediateHash[2];D = context->intermediateHash[3];E = context->intermediateHash[4];F = context->intermediateHash[5];G = context->intermediateHash[6];H = context->intermediateHash[7];for (i = 0; i < 64; i++){SS1 = LeftRotate((LeftRotate(A, 12) + E + LeftRotate(T(i), i)), 7);SS2 = SS1 ^ LeftRotate(A, 12);TT1 = FF(A, B, C, i) + D + SS2 + W_[i];TT2 = GG(E, F, G, i) + H + SS1 + W[i];D = C;C = LeftRotate(B, 9);B = A;A = TT1;H = G;G = LeftRotate(F, 19);F = E;E = P0(TT2);}context->intermediateHash[0] ^= A;context->intermediateHash[1] ^= B;context->intermediateHash[2] ^= C;context->intermediateHash[3] ^= D;context->intermediateHash[4] ^= E;context->intermediateHash[5] ^= F;context->intermediateHash[6] ^= G;context->intermediateHash[7] ^= H;
}/*
* SM3算法主函数
*/
unsigned char *SM3Calc(const unsigned char *message,unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE])
{SM3Context context;unsigned int i, remainder, bitLen;/* 初始化上下文 */SM3Init(&context);/* 对前面的消息分组进行处理 */for (i = 0; i < messageLen / 64; i++){memcpy(context.messageBlock, message + i * 64, 64);SM3ProcessMessageBlock(&context);}/* 填充消息分组,并处理 */bitLen = messageLen * 8;if (IsLittleEndian())ReverseWord(&bitLen);remainder = messageLen % 64;memcpy(context.messageBlock, message + i * 64, remainder);context.messageBlock[remainder] = 0x80;if (remainder <= 55){/* 长度按照大端法占8个字节,该程序只考虑长度在 2**32 - 1(单位:比特)以内的情况,* 故将高 4 个字节赋为 0 。*/memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1 - 8 + 4);memcpy(context.messageBlock + 64 - 4, &bitLen, 4);SM3ProcessMessageBlock(&context);}else{memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1);SM3ProcessMessageBlock(&context);/* 长度按照大端法占8个字节,该程序只考虑长度在 2**32 - 1(单位:比特)以内的情况,* 故将高 4 个字节赋为 0 。*/memset(context.messageBlock, 0, 64 - 4);memcpy(context.messageBlock + 64 - 4, &bitLen, 4);SM3ProcessMessageBlock(&context);}/* 返回结果 */if (IsLittleEndian())for (i = 0; i < 8; i++)ReverseWord(context.intermediateHash + i);memcpy(digest, context.intermediateHash, SM3_HASH_SIZE);return digest;
}

sm3.h

/*
* sm3.h
*
* 为使此算法兼容32位、64位下Linux或Windows系统,
* 选择 int 来表示 32 位整数。
* 消息长度最大限定为 2**32 - 1(单位:比特),
* 且为 8 的倍数(消息的最小单元为字节)。
*/
#ifndef _SM3_H_
#define _SM3_H_/*
* SM3算法产生的哈希值大小(单位:字节)
*/
#define SM3_HASH_SIZE 32 /*
* SM3上下文
*/
typedef struct SM3Context
{unsigned int intermediateHash[SM3_HASH_SIZE / 4];unsigned char messageBlock[64];
} SM3Context;/*
* SM3计算函数
*/
unsigned char *SM3Calc(const unsigned char *message,unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE]);#endif // _SM3_H_

SM4

sm4.c
加解密函数函数名_old的为基本加解密函数,不带的为封装了pkcs7填充函数后的加解密函数

/** SM4 Encryption alogrithm (SMS4 algorithm)* GM/T 0002-2012 Chinese National Standard ref:http://www.oscca.gov.cn/ * thanks to Xyssl* thnaks and refers to http://hi.baidu.com/numax/blog/item/80addfefddfb93e4cf1b3e61.html* author:goldboar* email:goldboar@163.com* 2012-4-20*/// Test vector 1
// plain: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// key:   01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
//     round key and temp computing result:
//     rk[ 0] = f12186f9 X[ 0] = 27fad345
//         rk[ 1] = 41662b61 X[ 1] = a18b4cb2
//         rk[ 2] = 5a6ab19a X[ 2] = 11c1e22a
//         rk[ 3] = 7ba92077 X[ 3] = cc13e2ee
//         rk[ 4] = 367360f4 X[ 4] = f87c5bd5
//         rk[ 5] = 776a0c61 X[ 5] = 33220757
//         rk[ 6] = b6bb89b3 X[ 6] = 77f4c297
//         rk[ 7] = 24763151 X[ 7] = 7a96f2eb
//         rk[ 8] = a520307c X[ 8] = 27dac07f
//         rk[ 9] = b7584dbd X[ 9] = 42dd0f19
//         rk[10] = c30753ed X[10] = b8a5da02
//         rk[11] = 7ee55b57 X[11] = 907127fa
//         rk[12] = 6988608c X[12] = 8b952b83
//         rk[13] = 30d895b7 X[13] = d42b7c59
//         rk[14] = 44ba14af X[14] = 2ffc5831
//         rk[15] = 104495a1 X[15] = f69e6888
//         rk[16] = d120b428 X[16] = af2432c4
//         rk[17] = 73b55fa3 X[17] = ed1ec85e
//         rk[18] = cc874966 X[18] = 55a3ba22
//         rk[19] = 92244439 X[19] = 124b18aa
//         rk[20] = e89e641f X[20] = 6ae7725f
//         rk[21] = 98ca015a X[21] = f4cba1f9
//         rk[22] = c7159060 X[22] = 1dcdfa10
//         rk[23] = 99e1fd2e X[23] = 2ff60603
//         rk[24] = b79bd80c X[24] = eff24fdc
//         rk[25] = 1d2115b0 X[25] = 6fe46b75
//         rk[26] = 0e228aeb X[26] = 893450ad
//         rk[27] = f1780c81 X[27] = 7b938f4c
//         rk[28] = 428d3654 X[28] = 536e4246
//         rk[29] = 62293496 X[29] = 86b3e94f
//         rk[30] = 01cf72e5 X[30] = d206965e
//         rk[31] = 9124a012 X[31] = 681edf34
// cypher: 68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46
//
// test vector 2
// the same key and plain 1000000 times coumpting
// plain:  01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// key:    01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
// cypher: 59 52 98 c7 c6 fd 27 1f 04 02 f8 04 c3 3d 3f 66#include "sm4.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>/** 32-bit integer manipulation macros (big endian)*/
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \(n) = ( (unsigned long) (b)[(i)    ] << 24 )        \| ( (unsigned long) (b)[(i) + 1] << 16 )        \| ( (unsigned long) (b)[(i) + 2] <<  8 )        \| ( (unsigned long) (b)[(i) + 3]       );       \
}
#endif#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i)                             \
{                                                       \(b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \(b)[(i) + 3] = (unsigned char) ( (n)       );       \
}
#endif/**rotate shift left marco definition**/
#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n%32)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n%32)))#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
/** Expanded SM4 S-boxes* Sbox table: 8bits input convert to 8 bits output*/static const unsigned char SboxTable[16][16] =
{{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},
{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},
{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},
{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},
{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},
{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},
{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},
{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},
{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},
{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},
{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},
{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},
{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},
{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},
{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},
{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}
};/* System parameter */
static const unsigned long FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc};/* fixed parameter */
static const unsigned long CK[32] =
{0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
0x30373e45,0x4c535a61,0x686f767d,0x848b9299,
0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
0x10171e25,0x2c333a41,0x484f565d,0x646b7279
};/** private function:* look up in SboxTable and get the related value.* args:    [in] inch: 0x00~0xFF (8 bits unsigned value).*/
static unsigned char sm4Sbox(unsigned char inch)
{unsigned char *pTable = (unsigned char *)SboxTable;unsigned char retVal = (unsigned char)(pTable[inch]);return retVal;
}/** private F(Lt) function:* "T algorithm" == "L algorithm" + "t algorithm".* args:    [in] a: a is a 32 bits unsigned value;* return: c: c is calculated with line algorithm "L" and nonline algorithm "t"*/
static unsigned long sm4Lt(unsigned long ka)
{unsigned long bb = 0;unsigned long c = 0;unsigned char a[4];unsigned char b[4];PUT_ULONG_BE(ka,a,0)b[0] = sm4Sbox(a[0]);b[1] = sm4Sbox(a[1]);b[2] = sm4Sbox(a[2]);b[3] = sm4Sbox(a[3]);GET_ULONG_BE(bb,b,0)c =bb^(ROTL(bb, 2))^(ROTL(bb, 10))^(ROTL(bb, 18))^(ROTL(bb, 24));return c;
}/** private F function:* Calculating and getting encryption/decryption contents.* args:    [in] x0: original contents;* args:    [in] x1: original contents;* args:    [in] x2: original contents;* args:    [in] x3: original contents;* args:    [in] rk: encryption/decryption key;* return the contents of encryption/decryption contents.*/
static unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk)
{return (x0^sm4Lt(x1^x2^x3^rk));
}/* private function:* Calculating round encryption key.* args:    [in] a: a is a 32 bits unsigned value;* return: sk[i]: i{0,1,2,3,...31}.*/
static unsigned long sm4CalciRK(unsigned long ka)
{unsigned long bb = 0;unsigned long rk = 0;unsigned char a[4];unsigned char b[4];PUT_ULONG_BE(ka,a,0)b[0] = sm4Sbox(a[0]);b[1] = sm4Sbox(a[1]);b[2] = sm4Sbox(a[2]);b[3] = sm4Sbox(a[3]);GET_ULONG_BE(bb,b,0)rk = bb^(ROTL(bb, 13))^(ROTL(bb, 23));return rk;
}static void sm4_setkey( unsigned long SK[32], unsigned char key[16] )
{unsigned long MK[4];unsigned long k[36];unsigned long i = 0;GET_ULONG_BE( MK[0], key, 0 );GET_ULONG_BE( MK[1], key, 4 );GET_ULONG_BE( MK[2], key, 8 );GET_ULONG_BE( MK[3], key, 12 );k[0] = MK[0]^FK[0];k[1] = MK[1]^FK[1];k[2] = MK[2]^FK[2];k[3] = MK[3]^FK[3];for(; i<32; i++){k[i+4] = k[i] ^ (sm4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i]));SK[i] = k[i+4];}}/** SM4 standard one round processing**/
static void sm4_one_round( unsigned long sk[32],unsigned char input[16],unsigned char output[16] )
{unsigned long i = 0;unsigned long ulbuf[36];memset(ulbuf, 0, sizeof(ulbuf));GET_ULONG_BE( ulbuf[0], input, 0 )GET_ULONG_BE( ulbuf[1], input, 4 )GET_ULONG_BE( ulbuf[2], input, 8 )GET_ULONG_BE( ulbuf[3], input, 12 )while(i<32){ulbuf[i+4] = sm4F(ulbuf[i], ulbuf[i+1], ulbuf[i+2], ulbuf[i+3], sk[i]);
// #ifdef _DEBUG
//          printf("rk(%02d) = 0x%08x,  X(%02d) = 0x%08x \n",i,sk[i], i, ulbuf[i+4] );
// #endifi++;}PUT_ULONG_BE(ulbuf[35],output,0);PUT_ULONG_BE(ulbuf[34],output,4);PUT_ULONG_BE(ulbuf[33],output,8);PUT_ULONG_BE(ulbuf[32],output,12);
}/** SM4 key schedule (128-bit, encryption)*/
void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] )
{ctx->mode = SM4_ENCRYPT;sm4_setkey( ctx->sk, key );
}/** SM4 key schedule (128-bit, decryption)*/
void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] )
{int i;ctx->mode = SM4_DECRYPT;sm4_setkey( ctx->sk, key );for( i = 0; i < 16; i ++ ){SWAP( ctx->sk[ i ], ctx->sk[ 31-i] );}
}/** SM4-ECB block encryption/decryption*/void sm4_crypt_ecb_old( sm4_context *ctx,int mode,int length,unsigned char *input,unsigned char *output)
{while( length > 0 ){sm4_one_round( ctx->sk, input, output );input  += 16;output += 16;length -= 16;}}/** SM4-CBC buffer encryption/decryption*/
void sm4_crypt_cbc_old( sm4_context *ctx,int mode,int length,unsigned char iv[16],unsigned char *input,unsigned char *output )
{int i;unsigned char temp[16];if( mode == SM4_ENCRYPT ){while( length > 0 ){for( i = 0; i < 16; i++ )output[i] = (unsigned char)( input[i] ^ iv[i] );sm4_one_round( ctx->sk, output, output );memcpy( iv, output, 16 );input  += 16;output += 16;length -= 16;}}else /* SM4_DECRYPT */{while( length > 0 ){memcpy( temp, input, 16 );sm4_one_round( ctx->sk, input, output );for( i = 0; i < 16; i++ )output[i] = (unsigned char)( output[i] ^ iv[i] );memcpy( iv, temp, 16 );input  += 16;output += 16;length -= 16;}}
}/*** @brief SM4-ECB + PKCS7算法* @param ctx:      SM4结构体,主要是包含初始秘钥(对于ECB模式的加密来说,不同之处就在于它的初始化时秘钥的初始方法不同,加密操作都是一样的)* @param mode:     加密:SM4_ENCRYPT 解密:SM4_DECRYPT* @param length:   需要处理的数据长度指针* @param input:    需要处理的数据* @param output:   处理完的数据* @attention:     1、length参数类型为指针,在此函数内部,该参数会被修改为加解密后数据的实际长度。2、对于input参数,要求其必须富裕出最少16字节的空间以供填充数据。3、对于解密的output,并未真正去除掉填充的数据,只是对数据长度进行去填充长度操作,请按length长度取值* @retval void*/
void sm4_crypt_ecb( sm4_context *ctx, int mode, unsigned int *length, \unsigned char *input, unsigned char *output)
{/* 填充长度及填充值 */int padding_value;if(mode == SM4_ENCRYPT){ padding_value = 16 - (*length % 16);/* 填充 */memset(input + *length, padding_value, padding_value);/* 填充后长度 */*length += padding_value;/* 加密 */sm4_crypt_ecb_old(ctx, mode, *length, input, output);}else //SM4_DECRYPT{sm4_crypt_ecb_old(ctx, mode, *length, input, output);    /* 去掉填充长度 */*length -= output[*length - 1];}
}/*** @brief          SM4-CBC + PKCS7算法* @param ctx      SM4 context* @param mode     加密:SM4_ENCRYPT 解密:SM4_DECRYPT* @param length   需要处理的数据长度指针* @param iv       初始化向量(使用后更新)* @param input:   需要处理的数据* @param output:  处理完的数据* @attention:    1、length参数类型为指针,在此函数内部,该参数会被修改为加解密后数据的实际长度。2、对于input参数,要求其必须富裕出最少16字节的空间以供填充数据。3、对于解密的output,并未真正去除掉填充的数据,只是对数据长度进行去填充长度操作,请按length长度取值* @retval void*/
void sm4_crypt_cbc( sm4_context *ctx, int mode, int *length, unsigned char iv[16], \unsigned char *input, unsigned char *output )
{/* 填充长度及填充值 */int padding_value;if(mode == SM4_ENCRYPT){padding_value = 16 - (*length % 16);/* 填充 */memset(input + *length, padding_value, padding_value);*length += padding_value;sm4_crypt_cbc_old(ctx, mode, *length, iv, input, output);}else //SM4_DECRYPT{sm4_crypt_cbc_old(ctx, mode, *length, iv, input, output);*length -= output[*length - 1];}
}
/*** \file sm4.h*/
#ifndef XYSSL_SM4_H
#define XYSSL_SM4_H#define SM4_ENCRYPT     1
#define SM4_DECRYPT     0/*** \brief          SM4 context structure*/
typedef struct
{int mode;                   /*!<  encrypt/decrypt   */unsigned long sk[32];       /*!<  SM4 subkeys       */
}
sm4_context;#ifdef __cplusplus
extern "C" {#endif/*** \brief          SM4 key schedule (128-bit, encryption)** \param ctx      SM4 context to be initialized* \param key      16-byte secret key*/
void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] );/*** \brief          SM4 key schedule (128-bit, decryption)** \param ctx      SM4 context to be initialized* \param key      16-byte secret key*/
void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] );/*** @brief SM4 + PKCS7算法* @param ctx:      SM4结构体,主要是包含初始秘钥(对于ECB模式的加密来说,不同之处就在于它的初始化时秘钥的初始方法不同,加密操作都是一样的)* @param mode:     加密:SM4_ENCRYPT 解密:SM4_DECRYPT* @param length:   需要处理的数据长度指针* @param input:    需要处理的数据* @param output:   处理完的数据* @attention:     1、length参数类型为指针,在此函数内部,该参数会被修改为加解密后数据的实际长度。2、对于input参数,要求其必须富裕出至少16字节的空间以供填充数据。3、对于解密的output,并未真正去除掉填充的数据,只是对数据长度进行去填充长度操作,请按length长度取值* @retval void*/
void sm4_crypt_ecb( sm4_context *ctx, int mode, unsigned int *length, \unsigned char *input, unsigned char *output);/*** @brief          SM4-CBC + PKCS7算法* @param ctx      SM4 context* @param mode     加密:SM4_ENCRYPT 解密:SM4_DECRYPT* @param length   需要处理的数据长度指针* @param iv       初始化向量(使用后更新)* @param input:   需要处理的数据* @param output:  处理完的数据* @attention:    1、length参数类型为指针,在此函数内部,该参数会被修改为加解密后数据的实际长度。2、对于input参数,要求其必须富裕出至少16字节的空间以供填充数据。3、对于解密的output,并未真正去除掉填充的数据,只是对数据长度进行去填充长度操作,请按length长度取值* @retval void*/
void sm4_crypt_cbc( sm4_context *ctx,int mode,int *length, unsigned char iv[16], \unsigned char *input,unsigned char *output );#ifdef __cplusplus
}
#endif#endif /* sm4.h */

STM32上可用的的SM 2 3 4国密算法相关推荐

  1. SM系列国密算法(转)

    原文地址:科普一下SM系列国密算法(从零开始学区块链 189) 众所周知,为了保障商用密码的安全性,国家商用密码管理办公室制定了一系列密码标准,包括SM1(SCB2).SM2.SM3.SM4.SM7. ...

  2. “云上贵州”成全国首个国密算法应用试点项目 阿里政务云实现“国家级”安全保护...

    11月22日,阿里云联合国家密码管理局.贵州省密码管理局.数据通信科学技术研究所.云上贵州大数据产业发展有限公司共同宣布:"云上贵州"成为国内首个国家商用密码算法应用试点项目. 据 ...

  3. SM国密算法(三)-- SM2算法

    目录 一.简介 二.数学公式 获取公私钥: 密钥对的生成: SM签名 SM验签 SM加密 SM解密 加解密中C1,C2,C3 一.简介 SM2非对称加密算法.由国家密码管理局于2010年12月17日发 ...

  4. 在达梦数据库上使用密码设备上的国密算法详细操作指南

    达梦数据库目前与山东渔翁的SJK1861-G 5.0密码卡兼容良好,下面详细描述其适配操作步骤. 1.密码卡设备安装 机器断电(彻底拔除电源线)冷却5分钟后,将密码卡设备固定在机箱内的PCI-E插槽里 ...

  5. 一文搞懂国密SM加密(VIP典藏版)

    目录 一.前言 加密概述 对称算法(分组密码算法):AES/DES/3DES/SM4/SM4 非对称算法(公钥密码算法):RSA/DSA/ECC/SM2 摘要算法(杂凑算法):MD5/SHA-I/SM ...

  6. 国密SM算法、RSA加密算法笔记

    一.国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4.目前SM1算法没有公开,只能集成在芯片中.目前应用较多的是SM2.SM3和SM4算法,这三者用法不一. SM2公钥加密算法 ...

  7. mavlink协议详解_MAVLink通讯协议在STM32上移植,并自定义协议

    mavlink全称是(Micro Air Vehicle Message Marshalling Library),从名字可以看出,mavlink是主要面向飞控的一种开源通信协议.因此它默认定义了很多 ...

  8. ChibiOS系列:二、在STM32上开发:介绍ChibiStudio

    本文翻译自:http://www.playembedded.org/blog/developing-stm32-chibistudio/ 在STM32上开发:介绍ChibiStudio 发表于 201 ...

  9. stm32硬件消抖_在 STM32 上使用 C++ 指南

    结识更多同行,共同讨论"嵌入式"技术.欢迎添加社区客服微信,备注发送"电源+公司名(学校)+职位(专业)"拉您入群. 简介 本文描述了如何使用在搭载了 RT-T ...

最新文章

  1. 【UGV】Arduino Mega2560 获取小车角度信息,传感器JY60
  2. 攻防世界php2_攻防世界-web2
  3. JSP简单练习-javaBean的简单应用
  4. 一个 Cobol 程序员的告白
  5. EF Core 数据库 Provider 一览
  6. 博文强识|进阶企业大咖
  7. 桌面虚拟化之用户行为审计
  8. 企业软件介绍主页html模板
  9. mysql client version_下载mysqlclient问题报错
  10. 牛客网Java刷题知识点之ArrayList 、LinkedList 、Vector 的底层实现和区别
  11. PCB解决(Failed to add class member)问题
  12. linux搭建sftp服务器
  13. python 根据x的值和函数y=20+x2,计算y_new,算出y_new和y的差,记为delta_y。¶绘制x和delt_y的点图,并计算y的方差。有关方差的计算参阅数学资料。
  14. 学it需要学历吗_低学历者是否适合学IT?IT行业对学历要求高吗
  15. 根据RGB​值判断颜色是否深浅色(附深浅色颜色集合)
  16. JAVA基础03-Object类,常用类,基本的数据结构, Collection常用体系,泛型-泛型通配符
  17. windows下vscode安装kubernetes环境并打开阿里云CSK
  18. 梦想中的办公之所!华为云(莲湖)联合发展中心用四招让幸福工作成为可能
  19. 【Unity3D实现自定义调色板】
  20. 【jeeWeb】jeeWeb在Tomcat跑起来

热门文章

  1. EMG信号的低通滤波器的matlab仿真实现
  2. Coinbase去年业务增长3倍,计划推出杠杆交易
  3. 【心学思维】内心没有定见的人,无论做什么都得不到真正的安宁
  4. Ubuntu中sudo命令
  5. spring 配置sqlite的方式
  6. 【高级数据库】第一章 第02讲 DBMS概述
  7. 【推荐谷歌地球替代软件——图新地球简介(LocaSpace Viewer)】
  8. DRGDIP分组云平台2.0版,自有知识产权
  9. Linux基本命令(开发常用的、电脑常用的)
  10. 我和媳妇儿欠了几万网贷,工资加起来才一万,看不到未来,怎么办?