ios平台上国密sm3的实现,iphone4s,5,6,6s验证通过

工作需要用到了sm3,上网一搜goldboar的版本被引用最多的,可这个版本却有问题,搜了些别人的版本都不如他的好,有的甚至移植过来编译不过。最后还是用goldboar版本修改了。

ios平台上国密sm3的实现,iphone4s,5,6,6s验证通过_第1张图片

上图是我用goldboar和Odzhan提供的版本在不同环境下计算“abc”的结果,两个版本均无法在iphone6s上计算正确,最后跟踪发现是iphone6s上long形为8字节导致的。遂修改代码中原有的unsigned long 类型为uint32_t 。问题即得到解决,现将代码贴此,需者取之。

/*
 本代码在goldboar提供的版本的基础上进行修改,http://blog.csdn.net/goldboar/article/details/6932274
 包括
 1,参照网上的说法修改shl rotl宏 http://blog.csdn.net/wak0408/article/details/50372386
 2,在iphone6上long是8字节的,实际需要4字节的,导致iphone6s上计算结果不正确,所以把代码中的unsigned long 改成了 uint32_t

 mender:swibyn
 email:swibyn@qq.com
 */
/**
 * \file sm3.h
 * thanks to Xyssl
 * SM3 standards:http://www.oscca.gov.cn/News/201012/News_1199.htm
 * author:goldboar
 * email:goldboar@163.com
 * 2011-10-26
 */
#ifndef XYSSL_SM3_H_cc
#define XYSSL_SM3_H_cc


/**
 * \brief          SM3 context structure
 */
typedef struct
{
    uint32_t total[2];     /*!< number of bytes processed  */
    uint32_t state[8];     /*!< intermediate digest state  */
    unsigned char buffer[64];   /*!< data block being processed */

    unsigned char ipad[64];     /*!< HMAC: inner padding        */
    unsigned char opad[64];     /*!< HMAC: outer padding        */

}
sm3_context_cc;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief          SM3 context setup
 *
 * \param ctx      context to be initialized
 */
void sm3_starts( sm3_context_cc *ctx );

/**
 * \brief          SM3 process buffer
 *
 * \param ctx      SM3 context
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 */
void sm3_update( sm3_context_cc *ctx, unsigned char *input, int ilen );

/**
 * \brief          SM3 final digest
 *
 * \param ctx      SM3 context
 */
void sm3_finish( sm3_context_cc *ctx, unsigned char output[32] );

/**
 * \brief          Output = SM3( input buffer )
 *
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 * \param output   SM3 checksum result
 */
void goldboar_cc_sm3( unsigned char *input, int ilen,
           unsigned char output[32]);

/**
 * \brief          Output = SM3( file contents )
 *
 * \param path     input file name
 * \param output   SM3 checksum result
 *
 * \return         0 if successful, 1 if fopen failed,
 *                 or 2 if fread failed
 */
int sm3_file( char *path, unsigned char output[32] );

/**
 * \brief          SM3 HMAC context setup
 *
 * \param ctx      HMAC context to be initialized
 * \param key      HMAC secret key
 * \param keylen   length of the HMAC key
 */
void sm3_hmac_starts( sm3_context_cc *ctx, unsigned char *key, int keylen);

/**
 * \brief          SM3 HMAC process buffer
 *
 * \param ctx      HMAC context
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 */
void sm3_hmac_update( sm3_context_cc *ctx, unsigned char *input, int ilen );

/**
 * \brief          SM3 HMAC final digest
 *
 * \param ctx      HMAC context
 * \param output   SM3 HMAC checksum result
 */
void sm3_hmac_finish( sm3_context_cc *ctx, unsigned char output[32] );

/**
 * \brief          Output = HMAC-SM3( hmac key, input buffer )
 *
 * \param key      HMAC secret key
 * \param keylen   length of the HMAC key
 * \param input    buffer holding the  data
 * \param ilen     length of the input data
 * \param output   HMAC-SM3 result
 */
void sm3_hmac( unsigned char *key, int keylen,
                unsigned char *input, int ilen,
                unsigned char output[32] );


#ifdef __cplusplus
}
#endif

#endif /* sm3.h */
/*
 本代码在goldboar提供的版本的基础上进行修改,包括
 1,参照网上的说法修改shl rotl宏 http://blog.csdn.net/wak0408/article/details/50372386
 2,在iphone6上long是8字节的,实际需要4字节的,导致iphone6s上计算结果不正确,所以把代码中的unsigned long 改成了 uint32_t

 mender:swibyn
 email:swibyn@qq.com
 */

/*
 * SM3 Hash alogrith  
 * thanks to Xyssl 
 * author:goldboar 
 * email:goldboar@163.com 
 * 2011-10-26 
 */


//Testing data from SM3 Standards  
//http://www.oscca.gov.cn/News/201012/News_1199.htm   
// Sample 1  
// Input:"abc"    
// Output:66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0  

// Sample 2   
// Input:"abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"  
// Outpuf:debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732  

//#include "stdafx.h"
#include   
#include 

#include "sm3.h"

#undef _DEBUG
//#define _DEBUG

/* 
 * 32-bit integer manipulation macros (big endian) 
 */  
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \
    (n) = ( (uint32_t) (b)[(i)    ] << 24 )        \
        | ( (uint32_t) (b)[(i) + 1] << 16 )        \
        | ( (uint32_t) (b)[(i) + 2] <<  8 )        \
        | ( (uint32_t) (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  

#define FF0(x,y,z) ( (x) ^ (y) ^ (z))   
#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))  

#define GG0(x,y,z) ( (x) ^ (y) ^ (z))   
#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )  


#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n%32)
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n%32)))

#define P0(x) ((x) ^  ROTL((x),9) ^ ROTL((x),17))   
#define P1(x) ((x) ^  ROTL((x),15) ^ ROTL((x),23))   


/* 
 * SM3 context setup 
 */  
void sm3_starts( sm3_context_cc *ctx )  
{  

    ctx->total[0] = 0;  
    ctx->total[1] = 0;  

    ctx->state[0] = 0x7380166F;  
    ctx->state[1] = 0x4914B2B9;  
    ctx->state[2] = 0x172442D7;  
    ctx->state[3] = 0xDA8A0600;  
    ctx->state[4] = 0xA96F30BC;  
    ctx->state[5] = 0x163138AA;  
    ctx->state[6] = 0xE38DEE4D;  
    ctx->state[7] = 0xB0FB0E4E;  

}  

static void sm3_process( sm3_context_cc *ctx, unsigned char data[64] )  
{  
    uint32_t SS1, SS2, TT1, TT2, W[68],W1[64];  
    uint32_t A, B, C, D, E, F, G, H;  
    uint32_t T[64];  
    uint32_t Temp1,Temp2,Temp3,Temp4,Temp5;  
    int j;  
#ifdef _DEBUG  
    int i;  
#endif  

//  for(j=0; j < 68; j++)  
//      W[j] = 0;  
//  for(j=0; j < 64; j++)  
//      W1[j] = 0;  

    for(j = 0; j < 16; j++)  
        T[j] = 0x79CC4519;  
    for(j =16; j < 64; j++)  
        T[j] = 0x7A879D8A;  

    GET_ULONG_BE( W[ 0], data,  0 );  
    GET_ULONG_BE( W[ 1], data,  4 );  
    GET_ULONG_BE( W[ 2], data,  8 );  
    GET_ULONG_BE( W[ 3], data, 12 );  
    GET_ULONG_BE( W[ 4], data, 16 );  
    GET_ULONG_BE( W[ 5], data, 20 );  
    GET_ULONG_BE( W[ 6], data, 24 );  
    GET_ULONG_BE( W[ 7], data, 28 );  
    GET_ULONG_BE( W[ 8], data, 32 );  
    GET_ULONG_BE( W[ 9], data, 36 );  
    GET_ULONG_BE( W[10], data, 40 );  
    GET_ULONG_BE( W[11], data, 44 );  
    GET_ULONG_BE( W[12], data, 48 );  
    GET_ULONG_BE( W[13], data, 52 );  
    GET_ULONG_BE( W[14], data, 56 );  
    GET_ULONG_BE( W[15], data, 60 );  

#ifdef _DEBUG   
    printf("Message with padding:\n");  
    for(i=0; i< 8; i++)  
        printf("%08x ",W[i]);  
    printf("\n");  
    for(i=8; i< 16; i++)  
        printf("%08x ",W[i]);  
    printf("\n");  
#endif  

    for(j = 16; j < 68; j++ )  
    {  
        //W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ ROTL(W[j - 13],7 ) ^ W[j-6];  
        //Why thd release's result is different with the debug's ?  
        //Below is okay. Interesting, Perhaps VC6 has a bug of Optimizaiton.  

        Temp1 = W[j-16] ^ W[j-9];  
        Temp2 = ROTL(W[j-3],15);  
        Temp3 = Temp1 ^ Temp2;  
        Temp4 = P1(Temp3);  
        Temp5 =  ROTL(W[j - 13],7 ) ^ W[j-6];  
        W[j] = Temp4 ^ Temp5;
//        printf("%08x %08x %08x %08x %08x\n",Temp1,Temp2,Temp3,Temp4,Temp5);
    }

#ifdef _DEBUG   
    printf("Expanding message W0-67:\n");  
    for(i=0; i<68; i++)  
    {  
        printf("%08x ",W[i]);  
        if(((i+1) % 8) == 0) printf("\n");  
    }  
    printf("\n");  
#endif  

    for(j =  0; j < 64; j++)  
    {  
        W1[j] = W[j] ^ W[j+4];  
    }  

#ifdef _DEBUG   
    printf("Expanding message W'0-63:\n");  
    for(i=0; i<64; i++)  
    {  
        printf("%08x ",W1[i]);  
        if(((i+1) % 8) == 0) printf("\n");  
    }  
    printf("\n");  
#endif  

    A = ctx->state[0];  
    B = ctx->state[1];  
    C = ctx->state[2];  
    D = ctx->state[3];  
    E = ctx->state[4];  
    F = ctx->state[5];  
    G = ctx->state[6];  
    H = ctx->state[7];  
#ifdef _DEBUG         
    printf("j     A       B        C         D         E        F        G       H\n");  
    printf("   %08x %08x %08x %08x %08x %08x %08x %08x\n",A,B,C,D,E,F,G,H);  
#endif  

    for(j =0; j < 16; j++)  
    {  
        SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);   
        SS2 = SS1 ^ ROTL(A,12);  
        TT1 = FF0(A,B,C) + D + SS2 + W1[j];  
        TT2 = GG0(E,F,G) + H + SS1 + W[j];  
        D = C;  
        C = ROTL(B,9);  
        B = A;  
        A = TT1;  
        H = G;  
        G = ROTL(F,19);  
        F = E;  
        E = P0(TT2);  
#ifdef _DEBUG   
        printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",j,A,B,C,D,E,F,G,H);  
#endif  
    }  

    for(j =16; j < 64; j++)  
    {  
        SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);   
        SS2 = SS1 ^ ROTL(A,12);  
        TT1 = FF1(A,B,C) + D + SS2 + W1[j];  
        TT2 = GG1(E,F,G) + H + SS1 + W[j];  
        D = C;  
        C = ROTL(B,9);  
        B = A;  
        A = TT1;  
        H = G;  
        G = ROTL(F,19);  
        F = E;  
        E = P0(TT2);  
#ifdef _DEBUG   
        printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",j,A,B,C,D,E,F,G,H);  
#endif    
    }  

    ctx->state[0] ^= A;  
    ctx->state[1] ^= B;  
    ctx->state[2] ^= C;  
    ctx->state[3] ^= D;  
    ctx->state[4] ^= E;  
    ctx->state[5] ^= F;  
    ctx->state[6] ^= G;  
    ctx->state[7] ^= H;  
#ifdef _DEBUG   
       printf("   %08x %08x %08x %08x %08x %08x %08x %08x\n",ctx->state[0],ctx->state[1],ctx->state[2],  
                                  ctx->state[3],ctx->state[4],ctx->state[5],ctx->state[6],ctx->state[7]);  
#endif  
}  

/* 
 * SM3 process buffer 
 */  
void sm3_update( sm3_context_cc *ctx, unsigned char *input, int ilen )  
{  
    int fill;  
    uint32_t left;  

    if( ilen <= 0 )  
        return;  

    left = ctx->total[0] & 0x3F;  
    fill = 64 - left;  

    ctx->total[0] += ilen;  
    ctx->total[0] &= 0xFFFFFFFF;  

    if( ctx->total[0] < (uint32_t) ilen )  
        ctx->total[1]++;  

    if( left && ilen >= fill )  
    {  
        memcpy( (void *) (ctx->buffer + left),  
                (void *) input, fill );  
        sm3_process( ctx, ctx->buffer );  
        input += fill;  
        ilen  -= fill;  
        left = 0;  
    }  

    while( ilen >= 64 )  
    {  
        sm3_process( ctx, input );  
        input += 64;  
        ilen  -= 64;  
    }  

    if( ilen > 0 )  
    {  
        memcpy( (void *) (ctx->buffer + left),  
                (void *) input, ilen );  
    }  
}  

static const unsigned char sm3_padding[64] =  
{  
 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  
};  

/* 
 * SM3 final digest 
 */  
void sm3_finish( sm3_context_cc *ctx, unsigned char output[32] )  
{  
    uint32_t last, padn;  
    uint32_t high, low;  
    unsigned char msglen[8];  

    high = ( ctx->total[0] >> 29 )  
         | ( ctx->total[1] <<  3 );  
    low  = ( ctx->total[0] <<  3 );  

    PUT_ULONG_BE( high, msglen, 0 );  
    PUT_ULONG_BE( low,  msglen, 4 );  

    last = ctx->total[0] & 0x3F;  
    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );  

    sm3_update( ctx, (unsigned char *) sm3_padding, padn );  
    sm3_update( ctx, msglen, 8 );  

    PUT_ULONG_BE( ctx->state[0], output,  0 );  
    PUT_ULONG_BE( ctx->state[1], output,  4 );  
    PUT_ULONG_BE( ctx->state[2], output,  8 );  
    PUT_ULONG_BE( ctx->state[3], output, 12 );  
    PUT_ULONG_BE( ctx->state[4], output, 16 );  
    PUT_ULONG_BE( ctx->state[5], output, 20 );  
    PUT_ULONG_BE( ctx->state[6], output, 24 );  
    PUT_ULONG_BE( ctx->state[7], output, 28 );  
}  

/* 
 * output = SM3( input buffer ) 
 */  
void goldboar_cc_sm3( unsigned char *input, int ilen,  
           unsigned char output[32] )  
{  
    sm3_context_cc ctx;  

    sm3_starts( &ctx );  
    sm3_update( &ctx, input, ilen );  
    sm3_finish( &ctx, output );  

    memset( &ctx, 0, sizeof( sm3_context_cc ) );  
}  

/* 
 * output = SM3( file contents ) 
 */  
int sm3_file( char *path, unsigned char output[32] )  
{  
    FILE *f;  
    size_t n;  
    sm3_context_cc ctx;  
    unsigned char buf[1024];  

    if( ( f = fopen( path, "rb" ) ) == NULL )  
        return( 1 );  

    sm3_starts( &ctx );  

    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )  
        sm3_update( &ctx, buf, (int) n );  

    sm3_finish( &ctx, output );  

    memset( &ctx, 0, sizeof( sm3_context_cc ) );  

    if( ferror( f ) != 0 )  
    {  
        fclose( f );  
        return( 2 );  
    }  

    fclose( f );  
    return( 0 );  
}  

/* 
 * SM3 HMAC context setup 
 */  
void sm3_hmac_starts( sm3_context_cc *ctx, unsigned char *key, int keylen )  
{  
    int i;  
    unsigned char sum[32];  

    if( keylen > 64 )  
    {  
        goldboar_cc_sm3( key, keylen, sum );  
        keylen = 32;  
        //keylen = ( is224 ) ? 28 : 32;  
        key = sum;  
    }  

    memset( ctx->ipad, 0x36, 64 );  
    memset( ctx->opad, 0x5C, 64 );  

    for( i = 0; i < keylen; i++ )  
    {  
        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );  
        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );  
    }  

    sm3_starts( ctx);  
    sm3_update( ctx, ctx->ipad, 64 );  

    memset( sum, 0, sizeof( sum ) );  
}  

/* 
 * SM3 HMAC process buffer 
 */  
void sm3_hmac_update( sm3_context_cc *ctx, unsigned char *input, int ilen )  
{  
    sm3_update( ctx, input, ilen );  
}  

/* 
 * SM3 HMAC final digest 
 */  
void sm3_hmac_finish( sm3_context_cc *ctx, unsigned char output[32] )  
{  
    int hlen;  
    unsigned char tmpbuf[32];  

    //is224 = ctx->is224;  
    hlen =  32;  

    sm3_finish( ctx, tmpbuf );  
    sm3_starts( ctx );  
    sm3_update( ctx, ctx->opad, 64 );  
    sm3_update( ctx, tmpbuf, hlen );  
    sm3_finish( ctx, output );  

    memset( tmpbuf, 0, sizeof( tmpbuf ) );  
}  

/* 
 * output = HMAC-SM#( hmac key, input buffer ) 
 */  
void sm3_hmac( unsigned char *key, int keylen,  
                unsigned char *input, int ilen,  
                unsigned char output[32] )  
{  
    sm3_context_cc ctx;  

    sm3_hmac_starts( &ctx, key, keylen);  
    sm3_hmac_update( &ctx, input, ilen );  
    sm3_hmac_finish( &ctx, output );  

    memset( &ctx, 0, sizeof( sm3_context_cc ) );  
} 

//———20170824追加——-
sm3 计算调用接口

1,传入缓存指针的方式
void goldboar_cc_sm3( unsigned char *input, int ilen,
unsigned char output[32]);
2,传入文件路径的方式
int sm3_file( char *path, unsigned char output[32] );

你可能感兴趣的:(ios摸爬滚打)