• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <gmssl/hex.h>
15 #include <gmssl/sm4.h>
16 #include <gmssl/error.h>
17 #include <gmssl/rand.h>
18 
19 
test_sm4(void)20 static int test_sm4(void)
21 {
22 	const uint8_t user_key[16] = {
23 		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
24 		0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
25 	};
26 	const uint32_t rk[32] = {
27 		0xf12186f9, 0x41662b61, 0x5a6ab19a, 0x7ba92077,
28 		0x367360f4, 0x776a0c61, 0xb6bb89b3, 0x24763151,
29 		0xa520307c, 0xb7584dbd, 0xc30753ed, 0x7ee55b57,
30 		0x6988608c, 0x30d895b7, 0x44ba14af, 0x104495a1,
31 		0xd120b428, 0x73b55fa3, 0xcc874966, 0x92244439,
32 		0xe89e641f, 0x98ca015a, 0xc7159060, 0x99e1fd2e,
33 		0xb79bd80c, 0x1d2115b0, 0x0e228aeb, 0xf1780c81,
34 		0x428d3654, 0x62293496, 0x01cf72e5, 0x9124a012,
35 	};
36 	const uint8_t plaintext[16] = {
37 		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
38 		0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
39 	};
40 	const uint8_t ciphertext[16] = {
41 		0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e,
42 		0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46,
43 	};
44 	const uint8_t ciphertext1m[16] = {
45 		0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f,
46 		0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, 0x3f, 0x66,
47 	};
48 
49 	SM4_KEY key;
50 	unsigned char buf[16];
51 	int i;
52 
53 	/* test key scheduling */
54 	sm4_set_encrypt_key(&key, user_key);
55 
56 	if (memcmp(key.rk, rk, sizeof(rk)) != 0) {
57 		fprintf(stderr, "sm4 key scheduling not passed!\n");
58 		return -1;
59 	}
60 
61 	/* test encrypt once */
62 	sm4_encrypt(&key, plaintext, buf);
63 	if (memcmp(buf, ciphertext, sizeof(ciphertext)) != 0) {
64 		fprintf(stderr, "sm4 encrypt not pass!\n");
65 		return -1;
66 	}
67 
68 	/* test encrypt 1000000 times */
69 	memcpy(buf, plaintext, sizeof(plaintext));
70 	for (i = 0; i < 1000000; i++) {
71 		sm4_encrypt(&key, buf, buf);
72 	}
73 	if (memcmp(buf, ciphertext1m, sizeof(ciphertext1m)) != 0) {
74 		fprintf(stderr, "sm4 encrypt 1000000 times not pass!\n");
75 		return -1;
76 	}
77 
78 	/* test decrypt */
79 	memset(&key, 0, sizeof(key));
80 	memset(buf, 0, sizeof(buf));
81 	sm4_set_decrypt_key(&key, user_key);
82 	sm4_decrypt(&key, ciphertext, buf);
83 	if (memcmp(buf, plaintext, sizeof(plaintext)) != 0) {
84 		fprintf(stderr, "sm4 decrypt not pass!\n");
85 		return -1;
86 	}
87 
88 	printf("%s() ok\n", __FUNCTION__);
89 	return 1;
90 }
91 
test_sm4_cbc(void)92 static int test_sm4_cbc(void)
93 {
94 	SM4_KEY sm4_key;
95 	uint8_t key[16] = {0};
96 	uint8_t iv[16] = {0};
97 	uint8_t buf1[32] = {0};
98 	uint8_t buf2[32] = {0};
99 	uint8_t buf3[32] = {0};
100 
101 	sm4_set_encrypt_key(&sm4_key, key);
102 	sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2);
103 	sm4_set_decrypt_key(&sm4_key, key);
104 	sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3);
105 
106 	if (memcmp(buf1, buf3, sizeof(buf3)) != 0) {
107 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
108 		return -1;
109 	}
110 
111 	printf("%s() ok\n", __FUNCTION__);
112 	return 1;
113 }
114 
test_sm4_cbc_padding(void)115 static int test_sm4_cbc_padding(void)
116 {
117 	SM4_KEY enc_key;
118 	SM4_KEY dec_key;
119 	uint8_t key[16] = {0};
120 	uint8_t iv[16] = {0};
121 	uint8_t buf1[64];
122 	uint8_t buf2[128];
123 	uint8_t buf3[128];
124 	size_t len1, len2, len3;
125 
126 	sm4_set_encrypt_key(&enc_key, key);
127 	sm4_set_decrypt_key(&dec_key, key);
128 
129 	len1 = 0;
130 	sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
131 	sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
132 	if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
133 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
134 		return -1;
135 	}
136 
137 	len1 = 7;
138 	sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
139 	sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
140 	if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
141 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
142 		return -1;
143 	}
144 
145 	len1 = 16;
146 	sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
147 	sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
148 	if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
149 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
150 		return -1;
151 	}
152 
153 	len1 = 33;
154 	sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
155 	sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
156 	if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
157 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
158 		return -1;
159 	}
160 
161 	len1 = sizeof(buf1);
162 	sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
163 	sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
164 	if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
165 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
166 		return -1;
167 	}
168 
169 	printf("%s() ok\n", __FUNCTION__);
170 	return 1;
171 }
172 
test_sm4_ctr(void)173 static int test_sm4_ctr(void)
174 {
175 	SM4_KEY sm4_key;
176 	uint8_t key[16] = {0};
177 	uint8_t ctr[16];
178 	uint8_t buf1[30] = {0};
179 	uint8_t buf2[30] = {0};
180 	uint8_t buf3[30] = {0};
181 
182 	sm4_set_encrypt_key(&sm4_key, key);
183 	memset(ctr, 0, sizeof(ctr));
184 	sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2);
185 
186 	memset(ctr, 0, sizeof(ctr));
187 	sm4_ctr_decrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3);
188 
189 	if (memcmp(buf1, buf3, sizeof(buf3)) != 0) {
190 		fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
191 		return -1;
192 	}
193 
194 	printf("%s() ok\n", __FUNCTION__);
195 	return 1;
196 }
197 
test_sm4_ctr_with_carray(void)198 static int test_sm4_ctr_with_carray(void)
199 {
200 	const char *hex_key =	"0123456789ABCDEFFEDCBA9876543210";
201 	const char *hex_ctr =	"0000000000000000000000000000FFFF";
202 	const char *hex_in =	"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"
203 							"CCCCCCCCCCCCCCCCDDDDDDDDDDDD";
204 	const char *hex_out =	"7EA678F9F0CBE2000917C63D4E77B4C8"
205 							"6E4E8532B0046E4AC1E97DA8B831";
206 
207 	SM4_KEY sm4_key;
208 	uint8_t key[16] = {0};
209 	uint8_t ctr[16];
210 	uint8_t buf1[30] = {0};
211 	uint8_t buf2[30] = {0};
212 	uint8_t buf3[30] = {0};
213 
214 	size_t keylen, ctrlen, inlen, outlen;
215 
216 	hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
217 	hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
218 	hex_to_bytes(hex_in, strlen(hex_in), buf1, &inlen);
219 	hex_to_bytes(hex_out, strlen(hex_out), buf3, &outlen);
220 
221 	sm4_set_encrypt_key(&sm4_key, key);
222 
223 	sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2);
224 
225 	if (memcmp(buf2, buf3, sizeof(buf3)) != 0) {
226 			error_print();
227 			return -1;
228 		}
229 
230 	hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
231 	sm4_ctr_decrypt(&sm4_key, ctr, buf3, sizeof(buf3), buf2);
232 
233 	if (memcmp(buf2, buf1, sizeof(buf1)) != 0) {
234 		error_print();
235 		return -1;
236 	}
237 
238 	printf("%s() ok\n", __FUNCTION__);
239 	return 1;
240 }
241 
test_sm4_gcm(void)242 static int test_sm4_gcm(void)
243 {
244 	// gcm test vectors from rfc 8998 A.1
245 	const char *hex_key =	"0123456789ABCDEFFEDCBA9876543210";
246 	const char *hex_iv =	"00001234567800000000ABCD";
247 	const char *hex_aad =	"FEEDFACEDEADBEEFFEEDFACEDEADBEEF"
248 				"ABADDAD2";
249 	const char *hex_in =	"AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"
250 				"CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD"
251 				"EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF"
252 				"EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA";
253 	const char *hex_out =	"17F399F08C67D5EE19D0DC9969C4BB7D"
254 				"5FD46FD3756489069157B282BB200735"
255 				"D82710CA5C22F0CCFA7CBF93D496AC15"
256 				"A56834CBCF98C397B4024A2691233B8D";
257 	const char *hex_tag =	"83DE3541E4C2B58177E065A9BF7B62EC";
258 
259 	SM4_KEY sm4_key;
260 	uint8_t key[16];
261 	uint8_t iv[12];
262 	uint8_t aad[20];
263 	uint8_t in[64];
264 	uint8_t out[64];
265 	uint8_t tag[16];
266 	size_t keylen, ivlen, aadlen, inlen, outlen, taglen;
267 
268 	uint8_t buf[64];
269 	uint8_t mac[16];
270 
271 	hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
272 	hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen);
273 	hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen);
274 	hex_to_bytes(hex_in, strlen(hex_in), in, &inlen);
275 	hex_to_bytes(hex_out, strlen(hex_out), out, &outlen);
276 	hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen);
277 
278 	memset(buf, 0, sizeof(buf));
279 	memset(mac, 0, sizeof(mac));
280 
281 	sm4_set_encrypt_key(&sm4_key, key);
282 
283 	// test gcm encrypt
284 	sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac);
285 	if (memcmp(buf, out, outlen) != 0) {
286 		error_print();
287 		return -1;
288 	}
289 	if (memcmp(mac, tag, taglen) != 0) {
290 		error_print();
291 		return -1;
292 	}
293 
294 	// test gcm decrypt
295 	memset(buf, 0, sizeof(buf));
296 	sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf);
297 	if (memcmp(buf, in, inlen) != 0) {
298 		error_print();
299 		return -1;
300 	}
301 
302 	printf("%s() ok\n", __FUNCTION__);
303 	return 1;
304 }
305 
test_sm4_cbc_update(void)306 static int test_sm4_cbc_update(void)
307 {
308 	SM4_KEY sm4_key;
309 	SM4_CBC_CTX enc_ctx;
310 	SM4_CBC_CTX dec_ctx;
311 
312 	uint8_t key[16];
313 	uint8_t iv[16];
314 	uint8_t mbuf[16 * 10];
315 	uint8_t cbuf[16 * 11];
316 	uint8_t pbuf[16 * 11];
317 	size_t mlen = 0;
318 	size_t clen = 0;
319 	size_t plen = 0;
320 
321 	uint8_t *in;
322 	uint8_t *out;
323 	size_t len;
324 	size_t lens[] = { 1,5,17,80 };
325 	int i;
326 
327 	rand_bytes(key, sizeof(key));
328 	rand_bytes(iv, sizeof(iv));
329 
330 
331 
332 	// first test
333 
334 	mlen = 16;
335 	rand_bytes(mbuf, mlen);
336 
337 	if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1
338 		|| sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1
339 		|| sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) {
340 		error_print();
341 		return -1;
342 	}
343 	clen += len;
344 
345 	// check ciphertext
346 	sm4_set_encrypt_key(&sm4_key, key);
347 	sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen);
348 	if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) {
349 		error_print();
350 		return -1;
351 	}
352 
353 	// check decrypt
354 	if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1
355 		|| sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
356 		|| sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
357 		error_print();
358 		return -1;
359 	}
360 	plen += len;
361 	if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
362 		error_print();
363 		return -1;
364 	}
365 
366 
367 	// second test
368 
369 	rand_bytes(mbuf, sizeof(mbuf));
370 
371 	if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) {
372 		error_print();
373 		return -1;
374 	}
375 	in = mbuf;
376 	out = cbuf;
377 	mlen = 0;
378 	clen = 0;
379 	for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
380 		if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) {
381 			error_print();
382 			return -1;
383 		}
384 		in += lens[i];
385 		mlen += lens[i];
386 		out += len;
387 		clen += len;
388 
389 	}
390 	if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) {
391 		error_print();
392 		return -1;
393 	}
394 	clen += len;
395 
396 	// check ciphertest
397 	sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen);
398 	if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) {
399 		error_print();
400 		return -1;
401 	}
402 
403 	// check decrypt
404 	if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) {
405 		error_print();
406 		return -1;
407 	}
408 	plen = 0;
409 	in = cbuf;
410 	out = pbuf;
411 	for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
412 		if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) {
413 			error_print();
414 			return -1;
415 		}
416 		in += lens[i];
417 		clen -= lens[i];
418 		out += len;
419 		plen += len;
420 	}
421 	if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) {
422 		error_print();
423 		return -1;
424 	}
425 	out += len;
426 	plen += len;
427 	if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) {
428 		error_print();
429 		return -1;
430 	}
431 	plen += len;
432 
433 	if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
434 		error_print();
435 		return -1;
436 	}
437 
438 	printf("%s() ok\n", __FUNCTION__);
439 	return 1;
440 }
441 
test_sm4_ctr_update(void)442 static int test_sm4_ctr_update(void)
443 {
444 	SM4_KEY sm4_key;
445 	SM4_CTR_CTX enc_ctx;
446 	SM4_CTR_CTX dec_ctx;
447 
448 	uint8_t key[16];
449 	uint8_t iv[16];
450 	uint8_t ctr[16];
451 	uint8_t mbuf[16 * 10];
452 	uint8_t cbuf[16 * 11];
453 	uint8_t pbuf[16 * 11];
454 	size_t mlen = 0;
455 	size_t clen = 0;
456 	size_t plen = 0;
457 
458 	uint8_t *in;
459 	uint8_t *out;
460 	size_t len;
461 	size_t lens[] = { 1,5,17,80 };
462 	int i;
463 
464 	rand_bytes(key, sizeof(key));
465 	rand_bytes(iv, sizeof(iv));
466 
467 	// first test
468 
469 	mlen = 16;
470 	rand_bytes(mbuf, mlen);
471 	memcpy(ctr, iv, sizeof(iv));
472 	if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1
473 		|| sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1
474 		|| sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) {
475 		error_print();
476 		return -1;
477 	}
478 	clen += len;
479 
480 	// check ciphertext
481 	sm4_set_encrypt_key(&sm4_key, key);
482 	sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // 注意:sm4_ctr_encrypt() 会修改ctr的值
483 	memcpy(ctr, iv, sizeof(iv));
484 	if (memcmp(cbuf, pbuf, clen) != 0) {
485 		error_print();
486 		return -1;
487 	}
488 
489 	// check decrypt
490 	if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1
491 		|| sm4_ctr_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
492 		|| sm4_ctr_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
493 		error_print();
494 		return -1;
495 	}
496 	plen += len;
497 
498 	if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
499 		error_print();
500 		return -1;
501 	}
502 
503 
504 	// second test
505 
506 	rand_bytes(mbuf, sizeof(mbuf));
507 
508 	if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1) {
509 		error_print();
510 		return -1;
511 	}
512 	in = mbuf;
513 	out = cbuf;
514 	mlen = 0;
515 	clen = 0;
516 	for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
517 		if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) {
518 			error_print();
519 			return -1;
520 		}
521 		in += lens[i];
522 		mlen += lens[i];
523 		out += len;
524 		clen += len;
525 
526 	}
527 	if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) {
528 		error_print();
529 		return -1;
530 	}
531 	clen += len;
532 
533 	// check ciphertest
534 	sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf);
535 	memcpy(ctr, iv, sizeof(iv));
536 	if (memcmp(pbuf, cbuf, mlen) != 0) {
537 		error_print();
538 		return -1;
539 	}
540 
541 	// check decrypt
542 	if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1) {
543 		error_print();
544 		return -1;
545 	}
546 	plen = 0;
547 	in = cbuf;
548 	out = pbuf;
549 	for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
550 		if (sm4_ctr_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) {
551 			error_print();
552 			return -1;
553 		}
554 		in += lens[i];
555 		clen -= lens[i];
556 		out += len;
557 		plen += len;
558 	}
559 	if (sm4_ctr_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) {
560 		error_print();
561 		return -1;
562 	}
563 	out += len;
564 	plen += len;
565 	if (sm4_ctr_decrypt_finish(&dec_ctx, out, &len) != 1) {
566 		error_print();
567 		return -1;
568 	}
569 	plen += len;
570 
571 	if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
572 		error_print();
573 		return -1;
574 	}
575 
576 	printf("%s() ok\n", __FUNCTION__);
577 	return 1;
578 }
579 
main(void)580 int main(void)
581 {
582 	if (test_sm4() != 1) goto err;
583 	if (test_sm4_cbc() != 1) goto err;
584 	if (test_sm4_cbc_padding() != 1) goto err;
585 	if (test_sm4_ctr() != 1) goto err;
586 	if (test_sm4_gcm() != 1) goto err;
587 	if (test_sm4_cbc_update() != 1) goto err;
588 	if (test_sm4_ctr_update() != 1) goto err;
589 	printf("%s all tests passed\n", __FILE__);
590 	return 0;
591 err:
592 	error_print();
593 	return 1;
594 }
595