• 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 <errno.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <gmssl/mem.h>
16 #include <gmssl/zuc.h>
17 #include <gmssl/hex.h>
18 
19 
20 static const char *options = "-key hex -iv hex [-in file] [-out file]";
21 
zuc_main(int argc,char ** argv)22 int zuc_main(int argc, char **argv)
23 {
24 	int ret = 1;
25 	char *prog = argv[0];
26 	char *keyhex = NULL;
27 	char *ivhex = NULL;
28 	char *infile = NULL;
29 	char *outfile = NULL;
30 	uint8_t key[16];
31 	uint8_t iv[16];
32 	size_t keylen = sizeof(key);
33 	size_t ivlen = sizeof(iv);
34 	FILE *infp = stdin;
35 	FILE *outfp = stdout;
36 	ZUC_CTX zuc_ctx;
37 	uint8_t inbuf[4096];
38 	size_t inlen;
39 	uint8_t outbuf[4196];
40 	size_t outlen;
41 
42 	argc--;
43 	argv++;
44 
45 	if (argc < 1) {
46 		fprintf(stderr, "usage: %s %s\n", prog, options);
47 		return 1;
48 	}
49 
50 	while (argc > 0) {
51 		if (!strcmp(*argv, "-help")) {
52 			printf("usage: %s %s\n", prog, options);
53 			ret = 0;
54 			goto end;
55 		} else if (!strcmp(*argv, "-key")) {
56 			if (--argc < 1) goto bad;
57 			keyhex = *(++argv);
58 			if (strlen(keyhex) != sizeof(key) * 2) {
59 				fprintf(stderr, "%s: invalid key length\n", prog);
60 				goto end;
61 			}
62 			if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) {
63 				fprintf(stderr, "%s: invalid HEX digits\n", prog);
64 				goto end;
65 			}
66 		} else if (!strcmp(*argv, "-iv")) {
67 			if (--argc < 1) goto bad;
68 			ivhex = *(++argv);
69 			if (strlen(ivhex) != sizeof(iv) * 2) {
70 				fprintf(stderr, "%s: invalid IV length\n", prog);
71 				goto end;
72 			}
73 			if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) {
74 				fprintf(stderr, "%s: invalid HEX digits\n", prog);
75 				goto end;
76 			}
77 		} else if (!strcmp(*argv, "-in")) {
78 			if (--argc < 1) goto bad;
79 			infile = *(++argv);
80 			if (!(infp = fopen(infile, "r"))) {
81 				fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
82 				goto end;
83 			}
84 		} else if (!strcmp(*argv, "-out")) {
85 			if (--argc < 1) goto bad;
86 			outfile = *(++argv);
87 			if (!(outfp = fopen(outfile, "w"))) {
88 				fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
89 				goto end;
90 			}
91 		} else {
92 			fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
93 			goto end;
94 bad:
95 			fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
96 			goto end;
97 		}
98 
99 		argc--;
100 		argv++;
101 	}
102 
103 	if (!keyhex) {
104 		fprintf(stderr, "%s: option '-key' missing\n", prog);
105 		goto end;
106 	}
107 	if (!ivhex) {
108 		fprintf(stderr, "%s: option '-iv' missing\n", prog);
109 		goto end;
110 	}
111 
112 	if (zuc_encrypt_init(&zuc_ctx, key, iv) != 1) {
113 		fprintf(stderr, "%s: inner error\n", prog);
114 		goto end;
115 	}
116 	while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) {
117 		if (zuc_encrypt_update(&zuc_ctx, inbuf, inlen, outbuf, &outlen) != 1) {
118 			fprintf(stderr, "%s: inner error\n", prog);
119 			goto end;
120 		}
121 		if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
122 			fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno));
123 			goto end;
124 		}
125 	}
126 	if (zuc_encrypt_finish(&zuc_ctx, outbuf, &outlen) != 1) {
127 		fprintf(stderr, "%s: inner error\n", prog);
128 		goto end;
129 	}
130 	if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
131 		fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno));
132 		goto end;
133 	}
134 	ret = 0;
135 end:
136 	gmssl_secure_clear(&zuc_ctx, sizeof(zuc_ctx));
137 	gmssl_secure_clear(key, sizeof(key));
138 	gmssl_secure_clear(iv, sizeof(iv));
139 	gmssl_secure_clear(inbuf, sizeof(inbuf));
140 	gmssl_secure_clear(outbuf, sizeof(outbuf));
141 	if (infile && infp) fclose(infp);
142 	if (outfile && outfp) fclose(outfp);
143 	return ret;
144 }
145