xref: /OK3568_Linux_fs/external/security/librkcrypto/test/c_mode/sm4_cmac.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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