sm3.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. * SM3 Hash alogrith
  3. * thanks to Xyssl
  4. * author:goldboar
  5. * email:[email protected]
  6. * 2011-10-26
  7. */
  8. //Testing data from SM3 Standards
  9. //http://www.oscca.gov.cn/News/201012/News_1199.htm
  10. // Sample 1
  11. // Input:"abc"
  12. // Output:66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0
  13. // Sample 2
  14. // Input:"abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
  15. // Outpuf:debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732
  16. #include "sm3.h"
  17. #include <string.h>
  18. #include <stdio.h>
  19. /*
  20. * 32-bit integer manipulation macros (big endian)
  21. */
  22. #ifndef GET_ULONG_BE
  23. #define GET_ULONG_BE(n,b,i) \
  24. { \
  25. (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
  26. | ( (unsigned long) (b)[(i) + 1] << 16 ) \
  27. | ( (unsigned long) (b)[(i) + 2] << 8 ) \
  28. | ( (unsigned long) (b)[(i) + 3] ); \
  29. }
  30. #endif
  31. #ifndef PUT_ULONG_BE
  32. #define PUT_ULONG_BE(n,b,i) \
  33. { \
  34. (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
  35. (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
  36. (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
  37. (b)[(i) + 3] = (unsigned char) ( (n) ); \
  38. }
  39. #endif
  40. /*
  41. * SM3 context setup
  42. */
  43. void sm3_starts( sm3_context *ctx )
  44. {
  45. ctx->total[0] = 0;
  46. ctx->total[1] = 0;
  47. ctx->state[0] = 0x7380166F;
  48. ctx->state[1] = 0x4914B2B9;
  49. ctx->state[2] = 0x172442D7;
  50. ctx->state[3] = 0xDA8A0600;
  51. ctx->state[4] = 0xA96F30BC;
  52. ctx->state[5] = 0x163138AA;
  53. ctx->state[6] = 0xE38DEE4D;
  54. ctx->state[7] = 0xB0FB0E4E;
  55. }
  56. static void sm3_process( sm3_context *ctx, unsigned char data[64] )
  57. {
  58. unsigned long SS1, SS2, TT1, TT2, W[68],W1[64];
  59. unsigned long A, B, C, D, E, F, G, H;
  60. unsigned long T[64];
  61. unsigned long Temp1,Temp2,Temp3,Temp4,Temp5;
  62. int j;
  63. #ifdef _DEBUG
  64. int i;
  65. #endif
  66. // for(j=0; j < 68; j++)
  67. // W[j] = 0;
  68. // for(j=0; j < 64; j++)
  69. // W1[j] = 0;
  70. for(j = 0; j < 16; j++)
  71. T[j] = 0x79CC4519;
  72. for(j =16; j < 64; j++)
  73. T[j] = 0x7A879D8A;
  74. GET_ULONG_BE( W[ 0], data, 0 );
  75. GET_ULONG_BE( W[ 1], data, 4 );
  76. GET_ULONG_BE( W[ 2], data, 8 );
  77. GET_ULONG_BE( W[ 3], data, 12 );
  78. GET_ULONG_BE( W[ 4], data, 16 );
  79. GET_ULONG_BE( W[ 5], data, 20 );
  80. GET_ULONG_BE( W[ 6], data, 24 );
  81. GET_ULONG_BE( W[ 7], data, 28 );
  82. GET_ULONG_BE( W[ 8], data, 32 );
  83. GET_ULONG_BE( W[ 9], data, 36 );
  84. GET_ULONG_BE( W[10], data, 40 );
  85. GET_ULONG_BE( W[11], data, 44 );
  86. GET_ULONG_BE( W[12], data, 48 );
  87. GET_ULONG_BE( W[13], data, 52 );
  88. GET_ULONG_BE( W[14], data, 56 );
  89. GET_ULONG_BE( W[15], data, 60 );
  90. #ifdef _DEBUG
  91. printf("Message with padding:\n");
  92. for(i=0; i< 8; i++)
  93. printf("%08x ",W[i]);
  94. printf("\n");
  95. for(i=8; i< 16; i++)
  96. printf("%08x ",W[i]);
  97. printf("\n");
  98. #endif
  99. #define FF0(x,y,z) ( (x) ^ (y) ^ (z))
  100. #define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))
  101. #define GG0(x,y,z) ( (x) ^ (y) ^ (z))
  102. #define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )
  103. #define SHL(x,n) (((x) & 0xFFFFFFFF) << n)
  104. #define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))
  105. #define P0(x) ((x) ^ ROTL((x),9) ^ ROTL((x),17))
  106. #define P1(x) ((x) ^ ROTL((x),15) ^ ROTL((x),23))
  107. for(j = 16; j < 68; j++ )
  108. {
  109. //W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ ROTL(W[j - 13],7 ) ^ W[j-6];
  110. //Why thd release's result is different with the debug's ?
  111. //Below is okay. Interesting, Perhaps VC6 has a bug of Optimizaiton.
  112. Temp1 = W[j-16] ^ W[j-9];
  113. Temp2 = ROTL(W[j-3],15);
  114. Temp3 = Temp1 ^ Temp2;
  115. Temp4 = P1(Temp3);
  116. Temp5 = ROTL(W[j - 13],7 ) ^ W[j-6];
  117. W[j] = Temp4 ^ Temp5;
  118. }
  119. #ifdef _DEBUG
  120. printf("Expanding message W0-67:\n");
  121. for(i=0; i<68; i++)
  122. {
  123. printf("%08x ",W[i]);
  124. if(((i+1) % 8) == 0) printf("\n");
  125. }
  126. printf("\n");
  127. #endif
  128. for(j = 0; j < 64; j++)
  129. {
  130. W1[j] = W[j] ^ W[j+4];
  131. }
  132. #ifdef _DEBUG
  133. printf("Expanding message W'0-63:\n");
  134. for(i=0; i<64; i++)
  135. {
  136. printf("%08x ",W1[i]);
  137. if(((i+1) % 8) == 0) printf("\n");
  138. }
  139. printf("\n");
  140. #endif
  141. A = ctx->state[0];
  142. B = ctx->state[1];
  143. C = ctx->state[2];
  144. D = ctx->state[3];
  145. E = ctx->state[4];
  146. F = ctx->state[5];
  147. G = ctx->state[6];
  148. H = ctx->state[7];
  149. #ifdef _DEBUG
  150. printf("j A B C D E F G H\n");
  151. printf(" %08x %08x %08x %08x %08x %08x %08x %08x\n",A,B,C,D,E,F,G,H);
  152. #endif
  153. for(j =0; j < 16; j++)
  154. {
  155. SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
  156. SS2 = SS1 ^ ROTL(A,12);
  157. TT1 = FF0(A,B,C) + D + SS2 + W1[j];
  158. TT2 = GG0(E,F,G) + H + SS1 + W[j];
  159. D = C;
  160. C = ROTL(B,9);
  161. B = A;
  162. A = TT1;
  163. H = G;
  164. G = ROTL(F,19);
  165. F = E;
  166. E = P0(TT2);
  167. #ifdef _DEBUG
  168. printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",j,A,B,C,D,E,F,G,H);
  169. #endif
  170. }
  171. for(j =16; j < 64; j++)
  172. {
  173. SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
  174. SS2 = SS1 ^ ROTL(A,12);
  175. TT1 = FF1(A,B,C) + D + SS2 + W1[j];
  176. TT2 = GG1(E,F,G) + H + SS1 + W[j];
  177. D = C;
  178. C = ROTL(B,9);
  179. B = A;
  180. A = TT1;
  181. H = G;
  182. G = ROTL(F,19);
  183. F = E;
  184. E = P0(TT2);
  185. #ifdef _DEBUG
  186. printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",j,A,B,C,D,E,F,G,H);
  187. #endif
  188. }
  189. ctx->state[0] ^= A;
  190. ctx->state[1] ^= B;
  191. ctx->state[2] ^= C;
  192. ctx->state[3] ^= D;
  193. ctx->state[4] ^= E;
  194. ctx->state[5] ^= F;
  195. ctx->state[6] ^= G;
  196. ctx->state[7] ^= H;
  197. #ifdef _DEBUG
  198. printf(" %08x %08x %08x %08x %08x %08x %08x %08x\n",ctx->state[0],ctx->state[1],ctx->state[2],
  199. ctx->state[3],ctx->state[4],ctx->state[5],ctx->state[6],ctx->state[7]);
  200. #endif
  201. }
  202. /*
  203. * SM3 process buffer
  204. */
  205. void sm3_update( sm3_context *ctx, unsigned char *input, int ilen )
  206. {
  207. int fill;
  208. unsigned long left;
  209. if( ilen <= 0 )
  210. return;
  211. left = ctx->total[0] & 0x3F;
  212. fill = 64 - left;
  213. ctx->total[0] += ilen;
  214. ctx->total[0] &= 0xFFFFFFFF;
  215. if( ctx->total[0] < (unsigned long) ilen )
  216. ctx->total[1]++;
  217. if( left && ilen >= fill )
  218. {
  219. memcpy( (void *) (ctx->buffer + left),
  220. (void *) input, fill );
  221. sm3_process( ctx, ctx->buffer );
  222. input += fill;
  223. ilen -= fill;
  224. left = 0;
  225. }
  226. while( ilen >= 64 )
  227. {
  228. sm3_process( ctx, input );
  229. input += 64;
  230. ilen -= 64;
  231. }
  232. if( ilen > 0 )
  233. {
  234. memcpy( (void *) (ctx->buffer + left),
  235. (void *) input, ilen );
  236. }
  237. }
  238. static const unsigned char sm3_padding[64] =
  239. {
  240. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  241. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  242. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  243. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  244. };
  245. /*
  246. * SM3 final digest
  247. */
  248. void sm3_finish( sm3_context *ctx, unsigned char output[32] )
  249. {
  250. unsigned long last, padn;
  251. unsigned long high, low;
  252. unsigned char msglen[8];
  253. high = ( ctx->total[0] >> 29 )
  254. | ( ctx->total[1] << 3 );
  255. low = ( ctx->total[0] << 3 );
  256. PUT_ULONG_BE( high, msglen, 0 );
  257. PUT_ULONG_BE( low, msglen, 4 );
  258. last = ctx->total[0] & 0x3F;
  259. padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
  260. sm3_update( ctx, (unsigned char *) sm3_padding, padn );
  261. sm3_update( ctx, msglen, 8 );
  262. PUT_ULONG_BE( ctx->state[0], output, 0 );
  263. PUT_ULONG_BE( ctx->state[1], output, 4 );
  264. PUT_ULONG_BE( ctx->state[2], output, 8 );
  265. PUT_ULONG_BE( ctx->state[3], output, 12 );
  266. PUT_ULONG_BE( ctx->state[4], output, 16 );
  267. PUT_ULONG_BE( ctx->state[5], output, 20 );
  268. PUT_ULONG_BE( ctx->state[6], output, 24 );
  269. PUT_ULONG_BE( ctx->state[7], output, 28 );
  270. }
  271. /*
  272. * output = SM3( input buffer )
  273. */
  274. void sm3( unsigned char *input, int ilen,
  275. unsigned char output[32] )
  276. {
  277. sm3_context ctx;
  278. sm3_starts( &ctx );
  279. sm3_update( &ctx, input, ilen );
  280. sm3_finish( &ctx, output );
  281. memset( &ctx, 0, sizeof( sm3_context ) );
  282. }
  283. /*
  284. * output = SM3( file contents )
  285. */
  286. int sm3_file( char *path, unsigned char output[32] )
  287. {
  288. FILE *f;
  289. size_t n;
  290. sm3_context ctx;
  291. unsigned char buf[1024];
  292. if( ( f = fopen( path, "rb" ) ) == NULL )
  293. return( 1 );
  294. sm3_starts( &ctx );
  295. while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
  296. sm3_update( &ctx, buf, (int) n );
  297. sm3_finish( &ctx, output );
  298. memset( &ctx, 0, sizeof( sm3_context ) );
  299. if( ferror( f ) != 0 )
  300. {
  301. fclose( f );
  302. return( 2 );
  303. }
  304. fclose( f );
  305. return( 0 );
  306. }
  307. /*
  308. * SM3 HMAC context setup
  309. */
  310. void sm3_hmac_starts( sm3_context *ctx, unsigned char *key, int keylen )
  311. {
  312. int i;
  313. unsigned char sum[32];
  314. if( keylen > 64 )
  315. {
  316. sm3( key, keylen, sum );
  317. keylen = 32;
  318. //keylen = ( is224 ) ? 28 : 32;
  319. key = sum;
  320. }
  321. memset( ctx->ipad, 0x36, 64 );
  322. memset( ctx->opad, 0x5C, 64 );
  323. for( i = 0; i < keylen; i++ )
  324. {
  325. ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
  326. ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
  327. }
  328. sm3_starts( ctx);
  329. sm3_update( ctx, ctx->ipad, 64 );
  330. memset( sum, 0, sizeof( sum ) );
  331. }
  332. /*
  333. * SM3 HMAC process buffer
  334. */
  335. void sm3_hmac_update( sm3_context *ctx, unsigned char *input, int ilen )
  336. {
  337. sm3_update( ctx, input, ilen );
  338. }
  339. /*
  340. * SM3 HMAC final digest
  341. */
  342. void sm3_hmac_finish( sm3_context *ctx, unsigned char output[32] )
  343. {
  344. int hlen;
  345. unsigned char tmpbuf[32];
  346. //is224 = ctx->is224;
  347. hlen = 32;
  348. sm3_finish( ctx, tmpbuf );
  349. sm3_starts( ctx );
  350. sm3_update( ctx, ctx->opad, 64 );
  351. sm3_update( ctx, tmpbuf, hlen );
  352. sm3_finish( ctx, output );
  353. memset( tmpbuf, 0, sizeof( tmpbuf ) );
  354. }
  355. /*
  356. * output = HMAC-SM#( hmac key, input buffer )
  357. */
  358. void sm3_hmac( unsigned char *key, int keylen,
  359. unsigned char *input, int ilen,
  360. unsigned char output[32] )
  361. {
  362. sm3_context ctx;
  363. sm3_hmac_starts( &ctx, key, keylen);
  364. sm3_hmac_update( &ctx, input, ilen );
  365. sm3_hmac_finish( &ctx, output );
  366. memset( &ctx, 0, sizeof( sm3_context ) );
  367. }