159 lines
3.6 KiB
C++
159 lines
3.6 KiB
C++
|
||
#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;
|
||
}
|
||
|