Files
microser/misc/SM4.cpp
2025-01-16 16:17:01 +08:00

159 lines
3.6 KiB
C++
Raw Permalink Blame History

#include <stdlib.h>
#include <apr_strings.h>
#include "SM4.h"
SM4::SM4(void)
{
}
SM4::~SM4(void)
{
}
unsigned char sm4_key[16];
//unsigned char *sm4_key="@XsdHUfb2ZajLeH3";
unsigned char kk_buf[]={0x20,0x38,0x53,0x44,0x28,0x35,0x46,0x42,0x12,0x3a,0x41,0x4a,0x2c,0x45,0x28,0x13};
/*
* SM4 key schedule (128-bit, encryption)
*/
void SM4::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::sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] )
{
int i;
ctx->mode = SM4_ENCRYPT;
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::sm4_crypt_ecb( 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::sm4_crypt_cbc( 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;
}
}
}
//SM4<4D><34><EFBFBD><EFBFBD>
void SM4::sm4_enc(char *str,int nStrLen,char *result_out,unsigned char *smkey)
{
unsigned int i;
unsigned char full_str[128];
unsigned char tmpbuf[64];
unsigned char output[64];
sm4_context ctx;
if(smkey==0) {for(i=0;i<16;i++) sm4_key[i]=kk_buf[i]+0x20;}
else {for(i=0;i<16;i++) sm4_key[i]=smkey[i];}
memset(full_str,0,100); //<2F><><EFBFBD><EFBFBD>16<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>0
memcpy(full_str,str, nStrLen);
sm4_setkey_enc(&ctx,sm4_key);
for(i=0,result_out[0]=0;i<((nStrLen +15)/16);i++)
{
sm4_crypt_ecb(&ctx,1,16,&full_str[i*16],output);
apr_snprintf((char*)tmpbuf,sizeof(tmpbuf), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
output[0],output[1],output[2],output[3],output[4],output[5],output[6],output[7],
output[8],output[9],output[10],output[11],output[12],output[13],output[14],output[15]);
strcat(result_out,(char*)tmpbuf);
}
}
//SM4<4D><34><EFBFBD><EFBFBD>
void SM4::sm4_dec(char *str,char *result_out,unsigned char *smkey)
{
unsigned int i,j;
sm4_context ctx;
unsigned char input[64];
unsigned char output[64];
char convs[4]={0};
if(smkey==0) {for(i=0;i<16;i++) sm4_key[i]=kk_buf[i]+0x20;}
else {for(i=0;i<16;i++) sm4_key[i]=smkey[i];}
sm4_setkey_dec(&ctx,sm4_key);
for(i=0;i<strlen(str)/32;i++)
{
for(j=0;j<16;j++)
{
convs[0]=str[i*32+j*2+0];
convs[1]=str[i*32+j*2+1];
input[j]=strtol(convs,NULL,16);
}
sm4_crypt_ecb(&ctx,0,16,input,output);
memcpy(&result_out[i*16],output,16);
}
result_out[i*16]=0;
}