STM32上可用的的SM 2 3 4国密算法
可在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国密算法相关推荐
- SM系列国密算法(转)
原文地址:科普一下SM系列国密算法(从零开始学区块链 189) 众所周知,为了保障商用密码的安全性,国家商用密码管理办公室制定了一系列密码标准,包括SM1(SCB2).SM2.SM3.SM4.SM7. ...
- “云上贵州”成全国首个国密算法应用试点项目 阿里政务云实现“国家级”安全保护...
11月22日,阿里云联合国家密码管理局.贵州省密码管理局.数据通信科学技术研究所.云上贵州大数据产业发展有限公司共同宣布:"云上贵州"成为国内首个国家商用密码算法应用试点项目. 据 ...
- SM国密算法(三)-- SM2算法
目录 一.简介 二.数学公式 获取公私钥: 密钥对的生成: SM签名 SM验签 SM加密 SM解密 加解密中C1,C2,C3 一.简介 SM2非对称加密算法.由国家密码管理局于2010年12月17日发 ...
- 在达梦数据库上使用密码设备上的国密算法详细操作指南
达梦数据库目前与山东渔翁的SJK1861-G 5.0密码卡兼容良好,下面详细描述其适配操作步骤. 1.密码卡设备安装 机器断电(彻底拔除电源线)冷却5分钟后,将密码卡设备固定在机箱内的PCI-E插槽里 ...
- 一文搞懂国密SM加密(VIP典藏版)
目录 一.前言 加密概述 对称算法(分组密码算法):AES/DES/3DES/SM4/SM4 非对称算法(公钥密码算法):RSA/DSA/ECC/SM2 摘要算法(杂凑算法):MD5/SHA-I/SM ...
- 国密SM算法、RSA加密算法笔记
一.国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4.目前SM1算法没有公开,只能集成在芯片中.目前应用较多的是SM2.SM3和SM4算法,这三者用法不一. SM2公钥加密算法 ...
- mavlink协议详解_MAVLink通讯协议在STM32上移植,并自定义协议
mavlink全称是(Micro Air Vehicle Message Marshalling Library),从名字可以看出,mavlink是主要面向飞控的一种开源通信协议.因此它默认定义了很多 ...
- ChibiOS系列:二、在STM32上开发:介绍ChibiStudio
本文翻译自:http://www.playembedded.org/blog/developing-stm32-chibistudio/ 在STM32上开发:介绍ChibiStudio 发表于 201 ...
- stm32硬件消抖_在 STM32 上使用 C++ 指南
结识更多同行,共同讨论"嵌入式"技术.欢迎添加社区客服微信,备注发送"电源+公司名(学校)+职位(专业)"拉您入群. 简介 本文描述了如何使用在搭载了 RT-T ...
最新文章
- 【UGV】Arduino Mega2560 获取小车角度信息,传感器JY60
- 攻防世界php2_攻防世界-web2
- JSP简单练习-javaBean的简单应用
- 一个 Cobol 程序员的告白
- EF Core 数据库 Provider 一览
- 博文强识|进阶企业大咖
- 桌面虚拟化之用户行为审计
- 企业软件介绍主页html模板
- mysql client version_下载mysqlclient问题报错
- 牛客网Java刷题知识点之ArrayList 、LinkedList 、Vector 的底层实现和区别
- PCB解决(Failed to add class member)问题
- linux搭建sftp服务器
- python 根据x的值和函数y=20+x2,计算y_new,算出y_new和y的差,记为delta_y。¶绘制x和delt_y的点图,并计算y的方差。有关方差的计算参阅数学资料。
- 学it需要学历吗_低学历者是否适合学IT?IT行业对学历要求高吗
- 根据RGB​值判断颜色是否深浅色(附深浅色颜色集合)
- JAVA基础03-Object类,常用类,基本的数据结构, Collection常用体系,泛型-泛型通配符
- windows下vscode安装kubernetes环境并打开阿里云CSK
- 梦想中的办公之所!华为云(莲湖)联合发展中心用四招让幸福工作成为可能
- 【Unity3D实现自定义调色板】
- 【jeeWeb】jeeWeb在Tomcat跑起来