国密算法SM3 - 杂凑

1.SM3的大致原理

国密算法SM3 - 杂凑

 

国密算法SM3 - 杂凑

 

2.源码实现 (参考了openssl)

文件结构

国密算法SM3 - 杂凑

文件sm3.h

国密算法SM3 - 杂凑
 1 /*
 2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
 3  * Copyright 2017 Ribose Inc. All Rights Reserved.
 4  *
 5  * Licensed under the OpenSSL license (the "License").  You may not use
 6  * this file except in compliance with the License.  You can obtain a copy
 7  * in the file LICENSE in the source distribution or at
 8  * https://www.openssl.org/source/license.html
 9  */
10 
11 #ifndef OSSL_CRYPTO_SM3_H
12 # define OSSL_CRYPTO_SM3_H
13 
14 # ifdef OPENSSL_NO_SM3
15 #  error SM3 is disabled.
16 # endif
17 
18 # define SM3_DIGEST_LENGTH 32
19 # define SM3_WORD unsigned int
20 
21 # define SM3_CBLOCK      64
22 # define SM3_LBLOCK      (SM3_CBLOCK/4)
23 
24 typedef struct SM3state_st {
25    SM3_WORD A, B, C, D, E, F, G, H;
26    SM3_WORD Nl, Nh;
27    SM3_WORD data[SM3_LBLOCK];
28    unsigned int num;
29 } SM3_CTX;
30 
31 int sm3_init(SM3_CTX *c);
32 int sm3_update(SM3_CTX *c, const void *data, size_t len);
33 int sm3_final(unsigned char *md, SM3_CTX *c);
34 
35 void sm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
36 
37 #endif
sm3.h

文件sm3_local.h

国密算法SM3 - 杂凑
 1 /*
 2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
 3  * Copyright 2017 Ribose Inc. All Rights Reserved.
 4  * Ported from Ribose contributions from Botan.
 5  *
 6  * Licensed under the OpenSSL license (the "License").  You may not use
 7  * this file except in compliance with the License.  You can obtain a copy
 8  * in the file LICENSE in the source distribution or at
 9  * https://www.openssl.org/source/license.html
10  */
11 
12 #include <string.h>
13 #include "sm3.h"
14 
15 #define DATA_ORDER_IS_BIG_ENDIAN
16 
17 #define HASH_LONG               SM3_WORD
18 #define HASH_CTX                SM3_CTX
19 #define HASH_CBLOCK             SM3_CBLOCK
20 #define HASH_UPDATE             sm3_update
21 #define HASH_TRANSFORM          sm3_transform
22 #define HASH_FINAL              sm3_final
23 #define HASH_MAKE_STRING(c, s)              \
24       do {                                  \
25         unsigned long ll;                   \
26         ll=(c)->A; (void)HOST_l2c(ll, (s)); \
27         ll=(c)->B; (void)HOST_l2c(ll, (s)); \
28         ll=(c)->C; (void)HOST_l2c(ll, (s)); \
29         ll=(c)->D; (void)HOST_l2c(ll, (s)); \
30         ll=(c)->E; (void)HOST_l2c(ll, (s)); \
31         ll=(c)->F; (void)HOST_l2c(ll, (s)); \
32         ll=(c)->G; (void)HOST_l2c(ll, (s)); \
33         ll=(c)->H; (void)HOST_l2c(ll, (s)); \
34       } while (0)
35 #define HASH_BLOCK_DATA_ORDER   sm3_block_data_order
36 
37 void sm3_transform(SM3_CTX *c, const unsigned char *data);
38 
39 #include "md32_common.h"
40 
41 #define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17))
42 #define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23))
43 
44 #define FF0(X,Y,Z) (X ^ Y ^ Z)
45 #define GG0(X,Y,Z) (X ^ Y ^ Z)
46 
47 #define FF1(X,Y,Z) ((X & Y) | ((X | Y) & Z))
48 #define GG1(X,Y,Z) ((Z ^ (X & (Y ^ Z))))
49 
50 #define EXPAND(W0,W7,W13,W3,W10) \
51    (P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10)
52 
53 #define RND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF, GG)           \
54      do {                                                         \
55        const SM3_WORD A12 = ROTATE(A, 12);                        \
56        const SM3_WORD A12_SM = A12 + E + TJ;                      \
57        const SM3_WORD SS1 = ROTATE(A12_SM, 7);                    \
58        const SM3_WORD TT1 = FF(A, B, C) + D + (SS1 ^ A12) + (Wj); \
59        const SM3_WORD TT2 = GG(E, F, G) + H + SS1 + Wi;           \
60        B = ROTATE(B, 9);                                          \
61        D = TT1;                                                   \
62        F = ROTATE(F, 19);                                         \
63        H = P0(TT2);                                               \
64      } while(0)
65 
66 #define R1(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \
67    RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF0,GG0)
68 
69 #define R2(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \
70    RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF1,GG1)
71 
72 #define SM3_A 0x7380166fUL
73 #define SM3_B 0x4914b2b9UL
74 #define SM3_C 0x172442d7UL
75 #define SM3_D 0xda8a0600UL
76 #define SM3_E 0xa96f30bcUL
77 #define SM3_F 0x163138aaUL
78 #define SM3_G 0xe38dee4dUL
79 #define SM3_H 0xb0fb0e4eUL
sm3_local.h

文件sm3.c

国密算法SM3 - 杂凑
  1 /*
  2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
  3  * Copyright 2017 Ribose Inc. All Rights Reserved.
  4  * Ported from Ribose contributions from Botan.
  5  *
  6  * Licensed under the OpenSSL license (the "License").  You may not use
  7  * this file except in compliance with the License.  You can obtain a copy
  8  * in the file LICENSE in the source distribution or at
  9  * https://www.openssl.org/source/license.html
 10  */
 11 
 12 #include <openssl/e_os2.h>
 13 #include "sm3_local.h"
 14 
 15 int sm3_init(SM3_CTX *c)
 16 {
 17     memset(c, 0, sizeof(*c));
 18     c->A = SM3_A;
 19     c->B = SM3_B;
 20     c->C = SM3_C;
 21     c->D = SM3_D;
 22     c->E = SM3_E;
 23     c->F = SM3_F;
 24     c->G = SM3_G;
 25     c->H = SM3_H;
 26     return 1;
 27 }
 28 
 29 void sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num)
 30 {
 31     const unsigned char *data = p;
 32     register unsigned MD32_REG_T A, B, C, D, E, F, G, H;
 33 
 34     unsigned MD32_REG_T W00, W01, W02, W03, W04, W05, W06, W07,
 35         W08, W09, W10, W11, W12, W13, W14, W15;
 36 
 37     for (; num--;) {
 38 
 39         A = ctx->A;
 40         B = ctx->B;
 41         C = ctx->C;
 42         D = ctx->D;
 43         E = ctx->E;
 44         F = ctx->F;
 45         G = ctx->G;
 46         H = ctx->H;
 47 
 48         /*
 49         * We have to load all message bytes immediately since SM3 reads
 50         * them slightly out of order.
 51         */
 52         (void)HOST_c2l(data, W00);
 53         (void)HOST_c2l(data, W01);
 54         (void)HOST_c2l(data, W02);
 55         (void)HOST_c2l(data, W03);
 56         (void)HOST_c2l(data, W04);
 57         (void)HOST_c2l(data, W05);
 58         (void)HOST_c2l(data, W06);
 59         (void)HOST_c2l(data, W07);
 60         (void)HOST_c2l(data, W08);
 61         (void)HOST_c2l(data, W09);
 62         (void)HOST_c2l(data, W10);
 63         (void)HOST_c2l(data, W11);
 64         (void)HOST_c2l(data, W12);
 65         (void)HOST_c2l(data, W13);
 66         (void)HOST_c2l(data, W14);
 67         (void)HOST_c2l(data, W15);
 68 
 69         R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04);
 70         W00 = EXPAND(W00, W07, W13, W03, W10);
 71         R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05);
 72         W01 = EXPAND(W01, W08, W14, W04, W11);
 73         R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06);
 74         W02 = EXPAND(W02, W09, W15, W05, W12);
 75         R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07);
 76         W03 = EXPAND(W03, W10, W00, W06, W13);
 77         R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08);
 78         W04 = EXPAND(W04, W11, W01, W07, W14);
 79         R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09);
 80         W05 = EXPAND(W05, W12, W02, W08, W15);
 81         R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10);
 82         W06 = EXPAND(W06, W13, W03, W09, W00);
 83         R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11);
 84         W07 = EXPAND(W07, W14, W04, W10, W01);
 85         R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12);
 86         W08 = EXPAND(W08, W15, W05, W11, W02);
 87         R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13);
 88         W09 = EXPAND(W09, W00, W06, W12, W03);
 89         R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14);
 90         W10 = EXPAND(W10, W01, W07, W13, W04);
 91         R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15);
 92         W11 = EXPAND(W11, W02, W08, W14, W05);
 93         R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00);
 94         W12 = EXPAND(W12, W03, W09, W15, W06);
 95         R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01);
 96         W13 = EXPAND(W13, W04, W10, W00, W07);
 97         R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02);
 98         W14 = EXPAND(W14, W05, W11, W01, W08);
 99         R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03);
100         W15 = EXPAND(W15, W06, W12, W02, W09);
101         R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
102         W00 = EXPAND(W00, W07, W13, W03, W10);
103         R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
104         W01 = EXPAND(W01, W08, W14, W04, W11);
105         R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
106         W02 = EXPAND(W02, W09, W15, W05, W12);
107         R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
108         W03 = EXPAND(W03, W10, W00, W06, W13);
109         R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
110         W04 = EXPAND(W04, W11, W01, W07, W14);
111         R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
112         W05 = EXPAND(W05, W12, W02, W08, W15);
113         R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
114         W06 = EXPAND(W06, W13, W03, W09, W00);
115         R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
116         W07 = EXPAND(W07, W14, W04, W10, W01);
117         R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
118         W08 = EXPAND(W08, W15, W05, W11, W02);
119         R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
120         W09 = EXPAND(W09, W00, W06, W12, W03);
121         R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
122         W10 = EXPAND(W10, W01, W07, W13, W04);
123         R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
124         W11 = EXPAND(W11, W02, W08, W14, W05);
125         R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
126         W12 = EXPAND(W12, W03, W09, W15, W06);
127         R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
128         W13 = EXPAND(W13, W04, W10, W00, W07);
129         R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
130         W14 = EXPAND(W14, W05, W11, W01, W08);
131         R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
132         W15 = EXPAND(W15, W06, W12, W02, W09);
133         R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04);
134         W00 = EXPAND(W00, W07, W13, W03, W10);
135         R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05);
136         W01 = EXPAND(W01, W08, W14, W04, W11);
137         R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06);
138         W02 = EXPAND(W02, W09, W15, W05, W12);
139         R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07);
140         W03 = EXPAND(W03, W10, W00, W06, W13);
141         R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08);
142         W04 = EXPAND(W04, W11, W01, W07, W14);
143         R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09);
144         W05 = EXPAND(W05, W12, W02, W08, W15);
145         R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10);
146         W06 = EXPAND(W06, W13, W03, W09, W00);
147         R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11);
148         W07 = EXPAND(W07, W14, W04, W10, W01);
149         R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12);
150         W08 = EXPAND(W08, W15, W05, W11, W02);
151         R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13);
152         W09 = EXPAND(W09, W00, W06, W12, W03);
153         R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14);
154         W10 = EXPAND(W10, W01, W07, W13, W04);
155         R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15);
156         W11 = EXPAND(W11, W02, W08, W14, W05);
157         R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00);
158         W12 = EXPAND(W12, W03, W09, W15, W06);
159         R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01);
160         W13 = EXPAND(W13, W04, W10, W00, W07);
161         R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02);
162         W14 = EXPAND(W14, W05, W11, W01, W08);
163         R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03);
164         W15 = EXPAND(W15, W06, W12, W02, W09);
165         R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
166         W00 = EXPAND(W00, W07, W13, W03, W10);
167         R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
168         W01 = EXPAND(W01, W08, W14, W04, W11);
169         R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
170         W02 = EXPAND(W02, W09, W15, W05, W12);
171         R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
172         W03 = EXPAND(W03, W10, W00, W06, W13);
173         R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
174         R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
175         R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
176         R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
177         R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
178         R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
179         R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
180         R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
181         R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
182         R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
183         R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
184         R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
185 
186         ctx->A ^= A;
187         ctx->B ^= B;
188         ctx->C ^= C;
189         ctx->D ^= D;
190         ctx->E ^= E;
191         ctx->F ^= F;
192         ctx->G ^= G;
193         ctx->H ^= H;
194     }
195 }
sm3.c

文件md32_common.h

国密算法SM3 - 杂凑
  1 /*
  2  * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
  3  *
  4  * Licensed under the OpenSSL license (the "License").  You may not use
  5  * this file except in compliance with the License.  You can obtain a copy
  6  * in the file LICENSE in the source distribution or at
  7  * https://www.openssl.org/source/license.html
  8  */
  9 
 10 /*-
 11  * This is a generic 32 bit "collector" for message digest algorithms.
 12  * Whenever needed it collects input character stream into chunks of
 13  * 32 bit values and invokes a block function that performs actual hash
 14  * calculations.
 15  *
 16  * Porting guide.
 17  *
 18  * Obligatory macros:
 19  *
 20  * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
 21  *      this macro defines byte order of input stream.
 22  * HASH_CBLOCK
 23  *      size of a unit chunk HASH_BLOCK operates on.
 24  * HASH_LONG
 25  *      has to be at least 32 bit wide.
 26  * HASH_CTX
 27  *      context structure that at least contains following
 28  *      members:
 29  *              typedef struct {
 30  *                      ...
 31  *                      HASH_LONG       Nl,Nh;
 32  *                      either {
 33  *                      HASH_LONG       data[HASH_LBLOCK];
 34  *                      unsigned char   data[HASH_CBLOCK];
 35  *                      };
 36  *                      unsigned int    num;
 37  *                      ...
 38  *                      } HASH_CTX;
 39  *      data[] vector is expected to be zeroed upon first call to
 40  *      HASH_UPDATE.
 41  * HASH_UPDATE
 42  *      name of "Update" function, implemented here.
 43  * HASH_TRANSFORM
 44  *      name of "Transform" function, implemented here.
 45  * HASH_FINAL
 46  *      name of "Final" function, implemented here.
 47  * HASH_BLOCK_DATA_ORDER
 48  *      name of "block" function capable of treating *unaligned* input
 49  *      message in original (data) byte order, implemented externally.
 50  * HASH_MAKE_STRING
 51  *      macro converting context variables to an ASCII hash string.
 52  *
 53  * MD5 example:
 54  *
 55  *      #define DATA_ORDER_IS_LITTLE_ENDIAN
 56  *
 57  *      #define HASH_LONG               MD5_LONG
 58  *      #define HASH_CTX                MD5_CTX
 59  *      #define HASH_CBLOCK             MD5_CBLOCK
 60  *      #define HASH_UPDATE             MD5_Update
 61  *      #define HASH_TRANSFORM          MD5_Transform
 62  *      #define HASH_FINAL              MD5_Final
 63  *      #define HASH_BLOCK_DATA_ORDER   md5_block_data_order
 64  */
 65 
 66 #include <openssl/crypto.h>
 67 
 68 #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
 69 # error "DATA_ORDER must be defined!"
 70 #endif
 71 
 72 #ifndef HASH_CBLOCK
 73 # error "HASH_CBLOCK must be defined!"
 74 #endif
 75 #ifndef HASH_LONG
 76 # error "HASH_LONG must be defined!"
 77 #endif
 78 #ifndef HASH_CTX
 79 # error "HASH_CTX must be defined!"
 80 #endif
 81 
 82 #ifndef HASH_UPDATE
 83 # error "HASH_UPDATE must be defined!"
 84 #endif
 85 #ifndef HASH_TRANSFORM
 86 # error "HASH_TRANSFORM must be defined!"
 87 #endif
 88 #ifndef HASH_FINAL
 89 # error "HASH_FINAL must be defined!"
 90 #endif
 91 
 92 #ifndef HASH_BLOCK_DATA_ORDER
 93 # error "HASH_BLOCK_DATA_ORDER must be defined!"
 94 #endif
 95 
 96 #define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
 97 
 98 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
 99 
100 # define HOST_c2l(c,l)  (l =(((unsigned long)(*((c)++)))<<24),          \
101                          l|=(((unsigned long)(*((c)++)))<<16),          \
102                          l|=(((unsigned long)(*((c)++)))<< 8),          \
103                          l|=(((unsigned long)(*((c)++)))    )           )
104 # define HOST_l2c(l,c)  (*((c)++)=(unsigned char)(((l)>>24)&0xff),      \
105                          *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
106                          *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
107                          *((c)++)=(unsigned char)(((l)    )&0xff),      \
108                          l)
109 
110 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
111 
112 # define HOST_c2l(c,l)  (l =(((unsigned long)(*((c)++)))    ),          \
113                          l|=(((unsigned long)(*((c)++)))<< 8),          \
114                          l|=(((unsigned long)(*((c)++)))<<16),          \
115                          l|=(((unsigned long)(*((c)++)))<<24)           )
116 # define HOST_l2c(l,c)  (*((c)++)=(unsigned char)(((l)    )&0xff),      \
117                          *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
118                          *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
119                          *((c)++)=(unsigned char)(((l)>>24)&0xff),      \
120                          l)
121 
122 #endif
123 
124 /*
125  * Time for some action :-)
126  */
127 
128 int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
129 {
130     const unsigned char *data = data_;
131     unsigned char *p;
132     HASH_LONG l;
133     size_t n;
134 
135     if (len == 0)
136         return 1;
137 
138     l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
139     if (l < c->Nl)              /* overflow */
140         c->Nh++;
141     c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
142                                        * 16-bit */
143     c->Nl = l;
144 
145     n = c->num;
146     if (n != 0) {
147         p = (unsigned char *)c->data;
148 
149         if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
150             memcpy(p + n, data, HASH_CBLOCK - n);
151             HASH_BLOCK_DATA_ORDER(c, p, 1);
152             n = HASH_CBLOCK - n;
153             data += n;
154             len -= n;
155             c->num = 0;
156             /*
157              * We use memset rather than OPENSSL_cleanse() here deliberately.
158              * Using OPENSSL_cleanse() here could be a performance issue. It
159              * will get properly cleansed on finalisation so this isn't a
160              * security problem.
161              */
162             memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
163         } else {
164             memcpy(p + n, data, len);
165             c->num += (unsigned int)len;
166             return 1;
167         }
168     }
169 
170     n = len / HASH_CBLOCK;
171     if (n > 0) {
172         HASH_BLOCK_DATA_ORDER(c, data, n);
173         n *= HASH_CBLOCK;
174         data += n;
175         len -= n;
176     }
177 
178     if (len != 0) {
179         p = (unsigned char *)c->data;
180         c->num = (unsigned int)len;
181         memcpy(p, data, len);
182     }
183     return 1;
184 }
185 
186 void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
187 {
188     HASH_BLOCK_DATA_ORDER(c, data, 1);
189 }
190 
191 int HASH_FINAL(unsigned char *md, HASH_CTX *c)
192 {
193     unsigned char *p = (unsigned char *)c->data;
194     size_t n = c->num;
195 
196     p[n] = 0x80;                /* there is always room for one */
197     n++;
198 
199     if (n > (HASH_CBLOCK - 8)) {
200         memset(p + n, 0, HASH_CBLOCK - n);
201         n = 0;
202         HASH_BLOCK_DATA_ORDER(c, p, 1);
203     }
204     memset(p + n, 0, HASH_CBLOCK - 8 - n);
205 
206     p += HASH_CBLOCK - 8;
207 #if   defined(DATA_ORDER_IS_BIG_ENDIAN)
208     (void)HOST_l2c(c->Nh, p);
209     (void)HOST_l2c(c->Nl, p);
210 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
211     (void)HOST_l2c(c->Nl, p);
212     (void)HOST_l2c(c->Nh, p);
213 #endif
214     p -= HASH_CBLOCK;
215     HASH_BLOCK_DATA_ORDER(c, p, 1);
216     c->num = 0;
217     memset(p, 0, HASH_CBLOCK);
218 
219 #ifndef HASH_MAKE_STRING
220 # error "HASH_MAKE_STRING must be defined!"
221 #else
222     HASH_MAKE_STRING(c, md);
223 #endif
224 
225     return 1;
226 }
227 
228 #ifndef MD32_REG_T
229 # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
230 #  define MD32_REG_T long
231 /*
232  * This comment was originally written for MD5, which is why it
233  * discusses A-D. But it basically applies to all 32-bit digests,
234  * which is why it was moved to common header file.
235  *
236  * In case you wonder why A-D are declared as long and not
237  * as MD5_LONG. Doing so results in slight performance
238  * boost on LP64 architectures. The catch is we don't
239  * really care if 32 MSBs of a 64-bit register get polluted
240  * with eventual overflows as we *save* only 32 LSBs in
241  * *either* case. Now declaring 'em long excuses the compiler
242  * from keeping 32 MSBs zeroed resulting in 13% performance
243  * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
244  * Well, to be honest it should say that this *prevents*
245  * performance degradation.
246  */
247 # else
248 /*
249  * Above is not absolute and there are LP64 compilers that
250  * generate better code if MD32_REG_T is defined int. The above
251  * pre-processor condition reflects the circumstances under which
252  * the conclusion was made and is subject to further extension.
253  */
254 #  define MD32_REG_T int
255 # endif
256 #endif
md32_common.h

文件main.c

国密算法SM3 - 杂凑
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <stdint.h>
 4 
 5 #include "sm3.h"
 6 
 7 void log_hex(uint8_t *data, size_t ndata, uint8_t *description){
 8         printf("%s: ", description);
 9         size_t i = 0;
10         for(i=0; i<ndata; i++){
11                 printf("%02x", data[i]);
12         if(i && ((i+1)%4==0)){
13             printf(" ");
14         }
15         }
16         printf("\n");
17 }
18 
19 static int test_sm3(){
20     uint8_t input[] = {0x61, 0x62, 0x63};
21     uint8_t degist[SM3_DIGEST_LENGTH] = {0};
22 
23     SM3_CTX context;
24     sm3_init(&context);
25 
26     sm3_update(&context, input, 3);
27     sm3_final(degist, &context);
28 
29     printf("<GB_T 32905-2016 信息安全技术 SM3密码杂凑算法 A.1 示例1> :\n");
30     log_hex(input, 3, "输入十六进制数据");
31     log_hex(degist, SM3_DIGEST_LENGTH, "杂凑值");
32     return 0;
33 }
34 
35 int main(){
36     return test_sm3();
37 }
main.c

文件Makefile

国密算法SM3 - 杂凑
1 all:
2     gcc -c sm3.c -o sm3.o
3     gcc -c main.c -o main.o
4     gcc -o bin sm3.o main.o
Makefile

 

运行程序

国密算法SM3 - 杂凑

 

3.参考文献

1.《GB T 32905-2016 信息安全技术 SM3密码杂凑算法.pdf》

2.《密码编码学与网络安全—原理与实践 第五版》 3.1.3 Feistel密码, 11.5.1 SHA-512逻辑

3.登录

http://www.gmbz.org.cn/main/index.html

点击"标准查询入口"

国密算法SM3 - 杂凑

上一篇:国密算法库_SM2_SM3


下一篇:嵌入式设备中支持国密算法的方法(二)