1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "sm4_core.h"
5
rk_left_shift(int len,unsigned char * add,unsigned char * des)6 static void rk_left_shift(int len, unsigned char* add, unsigned char*des)
7 {
8 int i;
9 for (i = 0; i < len - 1; i++)
10 {
11 des[i] = (add[i] << 1) + (add[i + 1] >= 0x80?1:0);
12 }
13 des[len - 1] = add[len - 1] << 1;
14 }
15
rk_array_xor(int len,unsigned char * a1,unsigned char * a2,unsigned char * des)16 static void rk_array_xor(int len, unsigned char*a1, unsigned char*a2, unsigned char*des)
17 {
18 int i;
19 for (i = 0; i < len; i++)
20 {
21 des[i] = a1[i] ^ a2[i];
22 }
23 }
24
rk_derive_mac_key(sm4_context * key,unsigned char * k1,unsigned char * k2)25 static void rk_derive_mac_key(sm4_context *key, unsigned char *k1, unsigned char *k2)
26 {
27 unsigned char plain[SM4_BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
28 unsigned char Rb[SM4_BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 };
29 unsigned char c0[SM4_BLOCK_SIZE];
30
31 rk_sm4_crypt_ecb(key, plain, c0);
32 if (c0[0]<0x80) //generate k1
33 {
34 rk_left_shift(SM4_BLOCK_SIZE, c0, k1);
35 }
36 else
37 {
38 rk_left_shift(SM4_BLOCK_SIZE, c0, k1);
39 rk_array_xor(SM4_BLOCK_SIZE, k1, Rb, k1);
40 }
41
42 if (k1[0] < 0x80) //generate k2
43 {
44 rk_left_shift(SM4_BLOCK_SIZE, k1, k2);
45 }
46 else
47 {
48 rk_left_shift(SM4_BLOCK_SIZE, k1, k2);
49 rk_array_xor(SM4_BLOCK_SIZE, k2, Rb, k2);
50 }
51 }
52
rk_sm4_genarate_cmac(unsigned char * key,unsigned int key_len,unsigned char * msg,unsigned int msg_len,unsigned char * macvalue)53 int rk_sm4_genarate_cmac(unsigned char *key, unsigned int key_len, unsigned char *msg, unsigned int msg_len, unsigned char *macvalue)
54 {
55 int i,block;
56 unsigned char IVtemp[SM4_BLOCK_SIZE];
57 unsigned char Blocktemp[SM4_BLOCK_SIZE];
58 unsigned char k1[SM4_BLOCK_SIZE], k2[SM4_BLOCK_SIZE];
59 sm4_context ctx;
60
61 memset(IVtemp, 0x00, sizeof(IVtemp));
62 memset(Blocktemp, 0x00, sizeof(Blocktemp));
63 memset(k1, 0x00, sizeof(k1));
64 memset(k2, 0x00, sizeof(k2));
65
66 rk_sm4_setkey_enc(&ctx, key);
67
68 rk_derive_mac_key(&ctx, k1, k2);
69 if (msg_len % SM4_BLOCK_SIZE == 0 && msg_len!=0)
70 {
71 block = msg_len / SM4_BLOCK_SIZE;
72 for (i = 0; i < block-1; i++)
73 {
74 rk_array_xor(16, &msg[i * SM4_BLOCK_SIZE], IVtemp, Blocktemp);
75 rk_sm4_crypt_ecb(&ctx, Blocktemp, IVtemp);
76 }
77 rk_array_xor(16, &msg[(block-1)*SM4_BLOCK_SIZE], IVtemp, Blocktemp);
78 rk_array_xor(16, Blocktemp, k1, Blocktemp);
79 rk_sm4_crypt_ecb(&ctx, Blocktemp, macvalue);
80 }
81 else
82 {
83 if (msg_len==0)
84 {
85 block = 1;
86 Blocktemp[0] = 0x80;//padding the first bit with 1
87 rk_array_xor(16, Blocktemp, k2, Blocktemp);
88 rk_sm4_crypt_ecb(&ctx, Blocktemp, macvalue);
89 }
90 else
91 {
92 unsigned char remain = msg_len % SM4_BLOCK_SIZE;
93 block = msg_len / SM4_BLOCK_SIZE + 1;
94 for (i = 0; i < block - 1; i++)
95 {
96 rk_array_xor(SM4_BLOCK_SIZE, &msg[i * SM4_BLOCK_SIZE], IVtemp, Blocktemp);
97 rk_sm4_crypt_ecb(&ctx, Blocktemp, IVtemp);
98 }
99 // the last block padding
100 for (i = 0; i < remain; i++)
101 {
102 Blocktemp[i] = msg[(block - 1) * SM4_BLOCK_SIZE + i];
103 }
104 Blocktemp[remain] = 0x80;
105 for (i = remain + 1; i < SM4_BLOCK_SIZE; i++)
106 {
107 Blocktemp[i] = 0;
108 }
109 // end of the last block padding
110
111 rk_array_xor(SM4_BLOCK_SIZE, Blocktemp, k2, Blocktemp);
112 rk_array_xor(SM4_BLOCK_SIZE, Blocktemp, IVtemp, Blocktemp);
113 rk_sm4_crypt_ecb(&ctx, Blocktemp, macvalue);
114 }
115
116 }
117 return 0;
118 }
119
rk_sm4_verify_cmac(unsigned char * key,unsigned int key_len,unsigned char * msg,unsigned int msg_len,unsigned char * macvalue)120 int rk_sm4_verify_cmac(unsigned char *key, unsigned int key_len, unsigned char *msg, unsigned int msg_len, unsigned char *macvalue)
121 {
122 int i, block;
123 int result=-1;
124 unsigned char IVtemp[SM4_BLOCK_SIZE];
125 unsigned char Blocktemp[SM4_BLOCK_SIZE];
126 unsigned char k1[SM4_BLOCK_SIZE], k2[SM4_BLOCK_SIZE];
127 unsigned char tmp_macvalue[SM4_BLOCK_SIZE];
128 sm4_context ctx;
129
130 memset(IVtemp, 0x00, sizeof(IVtemp));
131 memset(Blocktemp, 0x00, sizeof(Blocktemp));
132 memset(k1, 0x00, sizeof(k1));
133 memset(k2, 0x00, sizeof(k2));
134
135 rk_sm4_setkey_enc(&ctx, key);
136
137 rk_derive_mac_key(&ctx, k1, k2);
138 if (msg_len % SM4_BLOCK_SIZE == 0 && msg_len != 0)
139 {
140 block = msg_len / SM4_BLOCK_SIZE;
141 for (i = 0; i < block - 1; i++)
142 {
143 rk_array_xor(SM4_BLOCK_SIZE, &msg[i * SM4_BLOCK_SIZE], IVtemp, Blocktemp);
144 rk_sm4_crypt_ecb(&ctx, Blocktemp, IVtemp);
145 }
146 rk_array_xor(SM4_BLOCK_SIZE, &msg[(block - 1) * SM4_BLOCK_SIZE], IVtemp, Blocktemp);
147 rk_array_xor(SM4_BLOCK_SIZE, Blocktemp, k1, Blocktemp);
148 rk_sm4_crypt_ecb(&ctx, Blocktemp, tmp_macvalue);
149 }
150 else
151 {
152 if (msg_len == 0)
153 {
154 block = 1;
155 Blocktemp[0] = 0x80;//padding the first bit with 1
156 rk_array_xor(SM4_BLOCK_SIZE, Blocktemp, k2, Blocktemp);
157 rk_sm4_crypt_ecb(&ctx, Blocktemp, tmp_macvalue);
158 }
159 else
160 {
161 unsigned char remain = msg_len % SM4_BLOCK_SIZE;
162 block = msg_len / SM4_BLOCK_SIZE + 1;
163 for (i = 0; i < block - 1; i++)
164 {
165 rk_array_xor(SM4_BLOCK_SIZE, &msg[i * SM4_BLOCK_SIZE], IVtemp, Blocktemp);
166 rk_sm4_crypt_ecb(&ctx, Blocktemp, IVtemp);
167 }
168 // the last block padding
169 for (i = 0; i < remain; i++)
170 {
171 Blocktemp[i] = msg[(block - 1) * SM4_BLOCK_SIZE + i];
172 }
173 Blocktemp[remain] = 0x80;
174 for (i = remain + 1; i < SM4_BLOCK_SIZE; i++)
175 {
176 Blocktemp[i] = 0;
177 }
178 // end of the last block padding
179
180 rk_array_xor(SM4_BLOCK_SIZE, Blocktemp, k2, Blocktemp);
181 rk_array_xor(SM4_BLOCK_SIZE, Blocktemp, IVtemp, Blocktemp);
182 rk_sm4_crypt_ecb(&ctx, Blocktemp, tmp_macvalue);
183 }
184
185 }
186 result = -1;
187 for (i = 0; i < SM4_BLOCK_SIZE; i++)
188 {
189 if (tmp_macvalue[i] != macvalue[i])
190 {
191 return(result);
192 }
193 }
194 result = 0;
195 return(result);
196 }
197