SM4算法软件实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SM4算法实现
说明:该SM4算法是8位单片机Keil C51纯软件实现
目录
SM4算法手册 (1)
目录 (2)
1.数据类型定义 (3)
2.函数接口说明 (3)
3.1 初始化SM4模块 (3)
3.2 关闭SM4模块 (4)
3.3 SM4加解密 (4)
SM4算法的工作模式图解 (5)
源码SM4算法例程 (7)
1.数据类型定义
typedef unsigned char U8;
typedef singed char S8;
typedef unsigned int U16;
typedef signed int S16;
typedef unsigned long U32;
typedef signed long S32;
2.函数接口说明
SM4算法库包含的函数列表如下:
表2-1 SM4算法库函数表
3.1初始化SM4模块
初始化SM4模块
函数原型void SM4_Init( U8 *key)
参数说明
key 输入,指向密钥的指针
注意事项SM4加解密前,先调用此函数,进行密钥扩展
例程见附录一SM4算法库函数调用例程。

3.2关闭SM4模块
关闭SM4模块
函数原型void SM4_Close(void)
参数说明
注意事项SM4加解密后,调用此函数
例程见附录一SM4算法库函数调用例程。

3.3S M4加解密
SM4加解密
函数原型void SM4_Crypto(U8*in, U32 inLen, U8 En_De, U8 mode, U8 *iv,U8*out)
参数说明
in 输入,指向输入数组的指针
inLen 输入,输入的字节长度,必须为16的倍数,否则填充in使其长度为16的倍数
En_De 输入,指加密或是解密0:加密1:解密
mode 输入,0--ECB模式,1--CBC模式
iv 输入,指向扰乱向量的指针
out 输出,指向输出的指针
注意事项:大量数据分多块进行CBC模式加密或解密时,需注意:
(1) 若是加密,则第X块数据(X>1)调用本函数进行加密,使用的初始向量IV 一定要更新为第X-1块数据调用本函数进行加密得到的密文的最后一个分组(16字节)。

(2) 若是解密,则第X块数据(X>1)调用本函数进行解密,使用的初始向量IV 一定要更新为第X-1块数据的最后一个分组(16字节)。

图解分析详如下
SM4算法的工作模式图解
SM4算法的工作模式有以下两种:
1.ECB(Electronic Code Book)
图 1 ECB模式的运算流程图
2.CBC(Cipher Block Chaining)
图 2 CBC模式的运算流程图
源码SM4算法例程(main.c, SM4.c, SM4.h)
SM4.h
// SMS4.h
//#pragma once
#ifndef SM4_H
#define SM4_H
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
#define SM4_BLOCK_SIZE 16
#define SM4_MAX_LEN 512
#define SM4_MODE_CBC 1
#define SM4_MODE_ECB 0
typedef struct {
unsigned long rk[32];
}SM4_KEY;
void SM4_Init( UINT8 *key);
void SM4_Crypto(UINT8*in, U32 inLen, UINT8 En_De, UINT8 mode, UINT8 *iv,UINT8*out);
void SM4_Close(void);
#endif
Main.c
#include <stdio.h>
#include <string.h>
#include "SM4.h"
说明:print_buf函数需要根据所用单片机来实现,主要是观察数据使用,不影响算法,故注释掉。

//void print_buf(char *buf,int len, char *name)
//{
// int i;
// printf("%s: \r\n", name);
// for(i=0;i<len;i++)
// if((i&0x0f)==0xf)
// printf("0x%02bx,\r\n",buf[i]);
// else
// printf("0x%02bx,",buf[i]);
// printf("\r\n");
//}
/***************** SM4 standard data ***********************
plain: 0B0B2B4F5405FEF1E8A264FC89AB210A0B0B2B4F5405FEF1E8A264FC89AB210A key: B122AD0A7A362EC3ABA1DDEFB3AF4915
iv: 11111111d1a16c2067708acbd1a16c20
ECB cipher: 70DC8D6965DA2A367CDBA4631C39A38470DC8D6965DA2A367CDBA4631C39A384 CBC cipher: 33910DD4617BF43B17FC7C4C7C99719C6A85D9077F958793049EB0CDA97AA9AD
*********************************************************/
void main()
{
U32 xdata time1 = 0, time2 = 0, count = 0, k=0x12345678;
U8 xdata sm4plain[32] =
{0x0B,0x0B,0x2B,0x4F,0x54,0x05,0xFE,0xF1,0xE8,0xA2,0x64,0xFC,0x89,0xAB,0x21,0x0A,
0x0B,0x0B,0x2B,0x4F,0x54,0x05,0xFE,0xF1,0xE8,0xA2,0x64,0xFC,0x89,0xAB,0x21,0x0A};
U8 xdata sm4key[16] =
{0xB1,0x22,0xAD,0x0A,0x7A,0x36,0x2E,0xC3,0xAB,0xA1,0xDD,0xEF,0xB3,0xAF,0x49,0x15};
U8 xdata sm4iv[16] =
{0x11,0x11,0x11,0x11,0xd1,0xa1,0x6c,0x20,0x67,0x70,0x8a,0xcb,0xd1,0xa1,0x6c,0x20};
U8 xdata buffer1[32];
U8 xdata buffer2[32];
// UartInit();
//SM4 ECB 正确性测试
//Encrypt
// printf("\r\n\r\nSM4 ECB MODE\r\n");
// print_buf(sm4plain,32,"plain");
// print_buf(sm4key,16,"key");
SM4_Init(sm4key);
SM4_Crypto(sm4plain, 32, 0, 0, NULL,buffer1);
SM4_Close();
// print_buf(buffer1,32,"cipher");
//Decrypt
//printbuf8(sm4key,16,"key");
SM4_Init(sm4key);
SM4_Crypto(buffer1, 32, 1, 0, NULL,buffer2);
SM4_Close();
// print_buf(buffer2,32,"re-plain");
// if(memcmp(sm4plain, buffer2, 32))
// {
// printf("\r\n ECB mode error!\r\n");
// time1++;
// }
//SM4 CBC 正确性测试
//Encrypt
// printf("SM4 CBC MODE\r\n");
// print_buf(sm4plain,32,"plain");
// print_buf(sm4key,16,"key");
// print_buf(sm4iv,16,"iv");
SM4_Init(sm4key);
SM4_Crypto(sm4plain, 32, 0, 1, sm4iv, buffer1);
SM4_Close();
// print_buf(buffer1,32,"cipher");
//Decrypt
//printbuf8(sm4key,16,"key");
SM4_Init(sm4key);
SM4_Crypto(buffer1, 32, 1, 1, sm4iv, buffer2);
SM4_Close();
// print_buf(buffer2,32,"re-plain");
// if(memcmp(sm4plain, buffer2, 32))
// {
// printf("\r\n CBC mode error!\r\n");
// time2++;
// }
// count++;
// printf("time1 = %d, time2=%d, count=%d\r\n",time1,time2,count);
while(1);
}
SM4.c
#include <stdio.h>
#include <string.h>
#include "stdlib.h"
#include "SM4.h"
U8 xdata S_M_S4_ke_y[16];
U32 Unpack_32(U8 * src)
{
return (((UINT32) src[3]) << 24
| ((UINT32) src[2]) << 16
| ((UINT32) src[1]) << 8
| (UINT32) src[0]);
}
/* ROTATE_LEFT rotates x left n bits.*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* S box data */
U8 code SBX[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};
U8 SBox(U8 into)
{
UINT8 xdata h = into>>4;
return SBX[h][into^(h<<4)];
}
/* data convertion */
U32 T(U32 A)
{
UINT32 xdata b0,b1,b2,b3,B,B1,B2,B3,B4,C;
b0 = SBox((U8)(A>>24));
b1 = SBox((U8)(A>>16));
b2 = SBox((U8)(A>>8));
b3 = SBox((U8)A);
B = (b3<<24) | (b2<<16) | (b1<<8) | b0; //UINT32 B = (b0<<24) | (b1<<16) | (b2<<8) | b3;
B1 = ROTATE_LEFT(B,2);
B2 = ROTATE_LEFT(B,10);
B3 = ROTATE_LEFT(B,18);
B4 = ROTATE_LEFT(B,24);
C = B^B1^B2^B3^B4;
return Unpack_32((U8 *)(&C)); //return C;
}
U32 code FK[4] = {0xC6BAB1A3,0x5033AA56,0x97917D67,0xDC2270B2};
U32 code CK[32] = {
0x150e0700, 0x312a231c, 0x4d463f38, 0x69625b54,
0x857e7770, 0xa19a938c, 0xbdb6afa8, 0xd9d2cbc4,
0xf5eee7e0, 0x110a03fc, 0x2d261f18, 0x49423b34,
0x655e5750, 0x817a736c, 0x9d968f88, 0xb9b2aba4,
0xd5cec7c0, 0xf1eae3dc, 0x0d06fff8, 0x29221b14,
0x453e3730, 0x615a534c, 0x7d766f68, 0x99928b84,
0xb5aea7a0, 0xd1cac3bc, 0xede6dfd8, 0x0902fbf4,
0x251e1710, 0x413a332c, 0x5d564f48, 0x79726b64};
/* key convertion */
U32 KT(U32 A)
{
U32 xdata b0,b1,b2,b3;
U32 xdata B,B1,B2,C;
b0 = SBox((U8)(A>>24));
b1 = SBox((U8)(A>>16));
b2 = SBox((U8)(A>>8));
b3 = SBox((U8)A);
B = (b3<<24) | (b2<<16) | (b1<<8) | b0; //B = (b0<<24) | (b1<<16) | (b2<<8) | b3;
//print32(B);
B1 = ROTATE_LEFT(B,13);
B2 = ROTATE_LEFT(B,23);
C = B^B1^B2;
return Unpack_32((U8 *)(&C)); //return C;
}
/* Key expantions */
void SMS4Key(U32 MK[4], SM4_KEY *pSmsKey)
{
int xdata i;
U32 xdata tmpMK[4];
UINT32 xdata K[36];
tmpMK[0] = Unpack_32((UINT8 *)&MK[0]);
tmpMK[1] = Unpack_32((UINT8 *)&MK[1]);
tmpMK[2] = Unpack_32((UINT8 *)&MK[2]);
tmpMK[3] = Unpack_32((UINT8 *)&MK[3]);
K[0] = tmpMK[0]^FK[0];
K[1] = tmpMK[1]^FK[1];
K[2] = tmpMK[2]^FK[2];
K[3] = tmpMK[3]^FK[3];
for(i=0;i<32;i++)
{
pSmsKey->rk[i] = K[i]^KT(K[i+1]^K[i+2]^K[i+3]^CK[i]);
K[i+4] = pSmsKey->rk[i];
}
return ;
}
/* SMS4 Encrypt data*/
/* Input : UINT32 Plain
Output: UINT32 Cipher */
void SMS4Enc (UINT32 Plain[4],UINT32 Cipher[4], SM4_KEY *pSmsKey) {
int xdata i;
UINT32 xdata tmpPlain[4];
UINT32 xdata X[36];
tmpPlain[0] = Unpack_32((UINT8 *)&Plain[0]);
tmpPlain[1] = Unpack_32((UINT8 *)&Plain[1]);
tmpPlain[2] = Unpack_32((UINT8 *)&Plain[2]);
tmpPlain[3] = Unpack_32((UINT8 *)&Plain[3]);
X[0] = tmpPlain[0];
X[1] = tmpPlain[1];
X[2] = tmpPlain[2];
X[3] = tmpPlain[3];
for(i=0;i<32;i++)
{
X[i] = X[i]^T(X[i+1]^X[i+2]^X[i+3]^pSmsKey->rk[i]);
X[i+4] = X[i];
}
Cipher[0] = Unpack_32((UINT8 *)&X[35]);
Cipher[1] = Unpack_32((UINT8 *)&X[34]);
Cipher[2] = Unpack_32((UINT8 *)&X[33]);
Cipher[3] = Unpack_32((UINT8 *)&X[32]);
//Nosa- printf("Cipher[0] =%X \n",Cipher[0]);
return;
}
/* SMS4 Decrypt data*/
void SMS4Dec (UINT32 Cipher[4],UINT32 Plain[4], SM4_KEY *pSmsKey) {
int xdata i;
UINT32 xdata tmpCipher[4] ;
UINT32 xdata X[36];
tmpCipher[0] = Unpack_32((UINT8 *)&Cipher[0]);
tmpCipher[1] = Unpack_32((UINT8 *)&Cipher[1]);
tmpCipher[2] = Unpack_32((UINT8 *)&Cipher[2]);
tmpCipher[3] = Unpack_32((UINT8 *)&Cipher[3]);
X[0] = tmpCipher[0];
X[1] = tmpCipher[1];
X[2] = tmpCipher[2];
X[3] = tmpCipher[3];
for(i=0;i<32;i++)
{
// X[i] = X[i]^T(X[i+1]^X[i+2]^X[i+3]^smsKey.rk[i]);
X[i] = X[i]^T(X[i+1]^X[i+2]^X[i+3]^pSmsKey->rk[31-i]);
X[i+4] = X[i];
}
Plain[0] = Unpack_32((UINT8 *)&X[35]);
Plain[1] = Unpack_32((UINT8 *)&X[34]);
Plain[2] = Unpack_32((UINT8 *)&X[33]);
Plain[3] = Unpack_32((UINT8 *)&X[32]);
return;
}
/*
* func : sms4CBC_xor()
* Input :
* UINT8 * str1 : 异或源地址1
* UINT8 * str2 : 异或源地址2
* UINT8 * outStr:异或输出地址
* UINT32 len:异或长度
* Output :
* 0 : 异或失败
* Len : 异或长度
* Func Desp : CBC模式的异或运算
*/
UINT32 sms4CBC_xor(UINT8 * str1, UINT8 * str2, UINT8 * outStr, UINT32 len)
{
UINT32 xdata i;
for (i = 0; i < len; i++)
{
outStr[i] = str1[i] ^ str2[i];
// printf("outStr[%d] = %x\n",i,outStr[i]);
}
return len;
}
/*
* func : Sms4CBC_E()
* Input :
* UINT8 *IV : IV,和密钥长度一样,128bits
* UINT8 *M : 明文地址
* UINT32 mLen: 明文长度
* UINT8 *S:密文地址
* UINT8 *pucKey : 密钥
* Output :
* -1 : 加密失败
* Len : 加密后长度
* Func Desp : CBC模式的加密运算
*/
UINT32 Sms4CBC_E(UINT8 *IV, UINT8 *M, UINT32 mLen, UINT8 *S, UINT8 *pucKey) {
SM4_KEY xdata smsKey = {0};
UINT32 xdata i = 0;
UINT8 xdata sms4Buff[SM4_BLOCK_SIZE];
UINT8 xdata *tmpM, *tmpS;
tmpM = M;
tmpS = S;
SMS4Key((UINT32 *)pucKey, &smsKey);
memcpy(sms4Buff, IV, SM4_BLOCK_SIZE);
while((mLen - i) > 0)
{
sms4CBC_xor(tmpM, sms4Buff, sms4Buff, SM4_BLOCK_SIZE); //先异或
SMS4Enc((UINT32 *)sms4Buff, (UINT32 *)tmpS, &smsKey); //再加密
memcpy(sms4Buff, tmpS, SM4_BLOCK_SIZE); //保留上一轮的加密结果
tmpS = tmpS + SM4_BLOCK_SIZE;
tmpM = tmpM + SM4_BLOCK_SIZE;
i = i + SM4_BLOCK_SIZE;
}
return i;
}
/*
* func : Sms4CBC_D()
* Input :
* UINT8 *IV : IV,和密钥长度一样,128bits
* UINT8 *M : 明文地址
* UINT32 mLen: 密文长度
* UINT8 *S:密文地址
* UINT8 *pucKey : 密钥
* Output :
* -1 : 解密失败
* Len : 解密后长度
* Func Desp : CBC模式的解密运算
*/
UINT32 Sms4CBC_D(UINT8 *IV, UINT8 *M, UINT32 mLen, UINT8 *S, UINT8 *pucKey)
{
SM4_KEY xdata smsKey = {0};
UINT32 xdata i = 0;
UINT8 xdata sms4Buff[SM4_BLOCK_SIZE];
UINT8 xdata *tmpM, *tmpS;
tmpM = M;
tmpS = S;
SMS4Key((UINT32 *)pucKey, &smsKey);
memcpy(sms4Buff, IV, SM4_BLOCK_SIZE);
while((mLen - i) > 0)
{
SMS4Dec((UINT32 *)tmpS, (UINT32 *)tmpM, &smsKey); //先解密sms4CBC_xor(tmpM, sms4Buff, tmpM, SM4_BLOCK_SIZE); //再异或
memcpy(sms4Buff, tmpS, SM4_BLOCK_SIZE); //保留上一轮结果
tmpS = tmpS + SM4_BLOCK_SIZE;
tmpM = tmpM + SM4_BLOCK_SIZE;
i = i + SM4_BLOCK_SIZE;
}
return i;
}
/*
* func : Sms4ECB_E()
* Input :
* UINT8 *M : 明文地址
* UINT32 mLen: 明文长度
* UINT8 *S:密文地址
* UINT8 *pucKey : 密钥
* Output :
* -1 : 加密失败
* Len : 加密后长度
* Func Desp : CBC模式的加密运算
*/
UINT32 Sms4ECB_E(UINT8 *M, UINT32 mLen, UINT8 *S, UINT8 *pucKey)
{
SM4_KEY xdata smsKey = {0};
UINT32 xdata i = 0;
UINT8 xdata *tmpM, *tmpS;
tmpM = M;
tmpS = S;
SMS4Key((UINT32 *)pucKey, &smsKey);
while((mLen - i) > 0)
{
SMS4Enc((UINT32 *)tmpM, (UINT32 *)tmpS, &smsKey); //加密
tmpS = tmpS + SM4_BLOCK_SIZE;
tmpM = tmpM + SM4_BLOCK_SIZE;
i = i + SM4_BLOCK_SIZE;
}
return i;
}
/*
* func : Sms4ECB_D()
* Input :
* UINT8 *M : 明文地址
* UINT32 mLen: 密文长度
* UINT8 *S:密文地址
* UINT8 *pucKey : 密钥
* Output :
* -1 : 解密失败
* Len : 解密后长度
* Func Desp : CBC模式的解密运算
*/
UINT32 Sms4ECB_D(UINT8 *M, UINT32 mLen, UINT8 *S, UINT8 *pucKey)
{
SM4_KEY xdata smsKey = {0};
UINT32 xdata i = 0;
UINT8 xdata *tmpM, *tmpS;
tmpM = M;
tmpS = S;
SMS4Key((UINT32 *)pucKey, &smsKey);
//printf("tempS = %X\n",*tmpS);
while((mLen - i) > 0)
{
SMS4Dec((UINT32 *)tmpS, (UINT32 *)tmpM, &smsKey); //解密
tmpS = tmpS + SM4_BLOCK_SIZE;
tmpM = tmpM + SM4_BLOCK_SIZE;
i = i + SM4_BLOCK_SIZE;
}
return i;
}
#if 1
/*
* func : SMS4_fill()
* Input :
* UINT8 *in : 源地址
* UINT8 *len : 源长度
* Output :
* Func Desp : 填充函数
*/
void SMS4_fill(UINT8 *in, UINT32 *len)
{
UINT32 xdata tmpLen = 0;
UINT8 xdata fillByte = 0;
UINT8 xdata *p = NULL;
tmpLen = *len;
p = in;
if (tmpLen & 0x0f) //不是16的整数倍
{
fillByte = 16 - (tmpLen & 0x0f);
memset(p + tmpLen, fillByte, fillByte);
}
else //16的整数倍
{
fillByte = 0;
}
*len = *len + fillByte;
}
#endif
#if 0
/*
* func : SMS4_fill()
* Input :
* UINT8 *in : 源地址
* UINT8 *len : 源长度
* Output :
* Func Desp : 填充函数
*/
void SMS4_fill(UINT8 *in, INT32 *len)
{
INT32 xdata tmpLen;
UINT8 xdata *p,fillByte;
tmpLen = *len;
p = in;
if (tmpLen & 0x0f) //不是16的整数倍
{
fillByte = 16 - (tmpLen & 0x0f);
}else //16的整数倍
{
fillByte = 16;
}
memset(p + tmpLen, fillByte, fillByte);
*len = *len + fillByte;
}
#endif
/*
* func : SMS4_E()
* Input :
* UINT8 *IV : IV,和密钥长度一样,128bits,如果是ECB模式,可以填0
* UINT8 *M : 明文地址
* UINT32 mLen: 明文长度
* UINT8 *S:密文地址
* UINT8 *key : 密钥
* UINT8 mode:SMS4模式选择0 ecb 1:cbc
* Output :
* -1 : 加密失败
* Len : 加密后长度
* Func Desp : SMS4的加密运算
*/
UINT32 SMS4_E(UINT8 *IV, UINT8 *M, UINT32 mLen, UINT8 *S, UINT8 *key, UINT8 mode) {
UINT32 xdata tmpLen = mLen;
if (!M || !S || !key || mLen <= 0 || mLen > SM4_MAX_LEN)
return -1;
SMS4_fill(M, &tmpLen);
if (tmpLen & 0x0f || tmpLen > (SM4_MAX_LEN + SM4_BLOCK_SIZE))
return -1;
switch (mode)
{
case SM4_MODE_ECB:
return Sms4ECB_E(M, tmpLen, S, key);
break;
case SM4_MODE_CBC:
if (!IV)
return -1;
return Sms4CBC_E(IV, M, tmpLen, S, key);
break;
default:
return -1;
}
}
/*
* func : SMS4_D()
* Input :
* UINT8 *IV : IV,和密钥长度一样,128bits,如果是ECB模式,可以填0
* UINT8 *M : 明文地址
* UINT32 mLen: 密文长度
* UINT8 *S:密文地址
* UINT8 *key : 密钥
* UINT8 mode:SMS4模式选择
* Output :
* -1 : 加密失败
* Len : 加密后长度
* Func Desp : SMS4的解密运算
*/
UINT32 SMS4_D(UINT8 *IV, UINT8 *M, UINT32 mLen, UINT8 *S, UINT8 *key, UINT8 mode) {
UINT32 xdata tmpLen = mLen;
if (!M || !S || !key || mLen <= 0)
return -1;
if (mLen & 0x0f || mLen > (SM4_MAX_LEN + SM4_BLOCK_SIZE))
return -1;
switch (mode)
{
case SM4_MODE_ECB:
{
tmpLen = Sms4ECB_D(M, mLen, S, key);
break;
}
case SM4_MODE_CBC:
{
if (!IV)
return -1;
tmpLen = Sms4CBC_D(IV, M, mLen, S, key);
break;
}
default:
return -1;
}
return tmpLen;
}
void SM4_Init(UINT8 * key)
{
memcpy(S_M_S4_ke_y, key, 16);
//return 0;
}
void SM4_Crypto(UINT8*in, U32 inLen, UINT8 En_De, UINT8 mode, UINT8 *iv,UINT8*out) {
if(En_De)
{
SMS4_D(iv, out, inLen, in, S_M_S4_ke_y, mode);
}
else
{
SMS4_E(iv, in, inLen, out, S_M_S4_ke_y, mode);
}
//return 0;
}
void SM4_Close()
{
//return 0;
}。

相关文档
最新文档