1 /*
2  * This DES validation program shipped with FreeSec is derived from that
3  * shipped with UFC-crypt which is apparently derived from one distributed
4  * with Phil Karns PD DES package.
5  *
6  * $FreeBSD: src/secure/lib/libcipher/test/cert.c,v 1.5 1999/08/28 01:30:22 peter Exp $
7  * $DragonFly: src/secure/lib/libcipher/test/cert.c,v 1.2 2003/06/17 04:27:48 dillon Exp $
8  */
9 
10 #include <stdio.h>
11 
12 int totfails = 0;
13 
14 char *crypt();
15 #ifdef HAVE_CRYPT16
16 char *crypt16();
17 #endif /* HAVE_CRYPT16 */
18 
19 
20 static struct crypt_test {
21 	char	*key, *setting, *answer;
22 } crypt_tests[] = {
23 	"foob",			"ar",		"arlEKn0OzVJn.",
24 	"holyhooplasbatman!",	"_X.......",	"_X.......N89y2Z.e4WU",
25 	"holyhooplasbatman!",	"_X...X...",	"_X...X...rSUDQ5Na/QM",
26 	"holyhooplasbatman!",	"_XX..X...",	"_XX..X...P8vb9xU4JAk",
27 	"holyhooplasbatman!",	"_XX..XX..",	"_XX..XX..JDs5IlGLqT2",
28 	"holyhooplasbatman!",	"_XX..XXa.",	"_XX..XXa.bFVsOnCNh8Y",
29 	"holyhooplasbatman!",	"_XXa.X...",	"_XXa.X...Ghsb3QKNaps",
30 #ifdef TAKES_TOO_LONG_ON_SOME_CRYPTS
31 	"holyhooplasbatman!",	"_arararar",	"_ararararNGMzvpNjeCc",
32 #endif
33 	NULL, NULL, NULL,
34 };
35 
36 
37 static struct crypt_test crypt16_tests[] = {
38 	"foob",			"ar",		"arxo23jZDD5AYbHbqoy9Dalg",
39 	"holyhooplasbatman!",	"ar",		"arU5FRLJ3kxIoedlmyrOelEw",
40 	NULL, NULL, NULL
41 };
42 
43 
good_bye()44 void good_bye()
45 {
46   if(totfails == 0) {
47     printf(" Passed validation\n");
48     exit(0);
49   } else {
50     printf(" %d failures during validation!!!\n", totfails);
51     exit(1);
52   }
53 }
54 
55 
put8(cp)56 void put8(cp)
57 char *cp;
58 {
59 	int i,j,t;
60 
61 	for(i = 0; i < 8; i++){
62 		t = 0;
63 		for(j = 0; j < 8; j++)
64 			t = t << 1 | *cp++;
65 		printf("%02x", t);
66 	}
67 }
68 
69 
print_bits(bits)70 void print_bits(bits)
71 unsigned char *bits;
72 {
73 	int	i;
74 
75 	for (i = 0; i < 8; i++) {
76 		printf("%02x", bits[i]);
77 	}
78 }
79 
80 
parse_line(buff,salt,key,plain,answer)81 int parse_line(buff, salt, key, plain, answer)
82 char *buff;
83 long *salt;
84 char *key, *plain, *answer;
85 {
86 	char *ptr1, *ptr2;
87 	int val;
88 	int i,j,t;
89 
90 	/*
91 	 * Extract salt
92 	 */
93 	if (sscanf(buff, "%lu", salt) != 1)
94 		return(-1);
95 	for (ptr2 = buff; *ptr2 && !isspace(*ptr2); ptr2++)
96 		;
97 
98 	/*
99 	 * Extract key
100 	 */
101 	for (ptr1 = ptr2; *ptr1 && isspace(*ptr1); ptr1++)
102 		;
103 	for (ptr2 = ptr1; *ptr2 && !isspace(*ptr2); ptr2++)
104 		;
105 	if (ptr2 - ptr1 != 16)
106 		return(-1);
107 	for (i = 0; i < 8; i++){
108 		if (sscanf(ptr1 + 2*i, "%2x", &t) != 1)
109 			return(-2);
110 		for (j = 0; j < 8; j++)
111 			*key++ = (t & 1 << (7 - j)) != 0;
112 	}
113 
114 	/*
115 	 * Extract plain
116 	 */
117 	for (ptr1 = ptr2; *ptr1 && isspace(*ptr1); ptr1++)
118 		;
119 	for (ptr2 = ptr1; *ptr2 && !isspace(*ptr2); ptr2++)
120 		;
121 	if (ptr2 - ptr1 != 16)
122 		return(-1);
123 	for (i = 0; i < 8; i++){
124 		if (sscanf(ptr1 + 2*i, "%2x", &t) != 1)
125 			return(-2);
126 		for (j = 0; j < 8; j++)
127 			*plain++ = (t & 1 << (7 - j)) != 0;
128 	}
129 
130 	/*
131 	 * Extract answer
132 	 */
133 	for (ptr1 = ptr2; *ptr1 && isspace(*ptr1); ptr1++)
134 		;
135 	for (ptr2 = ptr1; *ptr2 && !isspace(*ptr2); ptr2++)
136 		;
137 	if (ptr2 - ptr1 != 16)
138 		return(-1);
139 	for (i = 0; i < 8; i++){
140 		if (sscanf(ptr1 + 2*i, "%2x", &t) != 1)
141 			return(-2);
142 		for (j = 0; j < 8; j++)
143 			*answer++ = (t & 1 << (7 - j)) != 0;
144 	}
145 	return(0);
146 }
147 
148 /*
149  * Test the setkey and encrypt functions
150  */
test_encrypt()151 void test_encrypt()
152 {
153 	char key[64],plain[64],cipher[64],answer[64];
154 	char buff[BUFSIZ];
155 	unsigned long salt;
156 	int i;
157 	int test;
158 	int fail;
159 
160 	printf("Testing setkey/encrypt\n");
161 
162 	for(test=0;fgets(buff, BUFSIZ, stdin);test++){
163 
164 		/*
165 		 * Allow comments.
166 		 */
167 		if (*buff == '#')
168 			continue;
169 
170 		if ((fail = parse_line(buff, &salt, key, plain, answer)) < 0){
171 			printf("test %d garbled (%d)\n", test, fail);
172 			continue;
173 		}
174 
175 		if (salt)
176 			continue;	/* encrypt has no salt support */
177 
178 		printf(" K: "); put8(key);
179 		printf(" P: "); put8(plain);
180 		printf(" C: "); put8(answer);
181 
182 		setkey(key);
183 		for(i = 0; i < 64; i++)
184 			cipher[i] = plain[i];
185 		encrypt(cipher, 0);
186 
187 		for(i=0;i<64;i++)
188 			if(cipher[i] != answer[i])
189 				break;
190 		fail = 0;
191 		if(i != 64){
192 			printf(" Enc FAIL ");
193 			put8(cipher);
194 			fail++; totfails++;
195 		}
196 
197 		encrypt(cipher, 1);
198 
199 		for(i=0;i<64;i++)
200 			if(cipher[i] != plain[i])
201 				break;
202 		if(i != 64){
203 			printf(" Dec FAIL");
204 			fail++; totfails++;
205 		}
206 
207 		if(fail == 0)
208 			printf(" OK");
209 		printf("\n");
210 	}
211 }
212 
213 
bytes_to_bits(bytes,bits)214 void bytes_to_bits(bytes, bits)
215 char *bytes;
216 unsigned char *bits;
217 {
218 	int	i, j;
219 
220 	for (i = 0; i < 8; i++) {
221 		bits[i] = 0;
222 		for (j = 0; j < 8; j++) {
223 			bits[i] |= (bytes[i*8+j] & 1) << (7 - j);
224 		}
225 	}
226 }
227 
228 
229 /*
230  * Test the des_setkey and des_cipher functions
231  */
test_des()232 void test_des()
233 {
234 	char ckey[64], cplain[64], canswer[64];
235 	unsigned char key[8], plain[8], cipher[8], answer[8];
236 	char buff[BUFSIZ];
237 	unsigned long salt;
238 	int i;
239 	int test;
240 	int fail;
241 
242 	printf("Testing des_setkey/des_cipher\n");
243 
244 	for(test=0;fgets(buff, BUFSIZ, stdin);test++){
245 
246 		/*
247 		 * Allow comments.
248 		 */
249 		if (*buff == '#')
250 			continue;
251 
252 		if ((fail = parse_line(buff, &salt, ckey, cplain, canswer)) <0){
253 			printf("test %d garbled (%d)\n", test, fail);
254 			continue;
255 		}
256 
257 		printf(" S: %06x", salt);
258 		printf(" K: "); put8(ckey);
259 		printf(" P: "); put8(cplain);
260 		printf(" C: "); put8(canswer);
261 
262 		bytes_to_bits(ckey, key);
263 		bytes_to_bits(cplain, plain);
264 		bytes_to_bits(canswer, answer);
265 		des_setkey(key);
266 		des_cipher(plain, cipher, salt, 1);
267 
268 		for(i = 0; i < 8; i++)
269 			if(cipher[i] != answer[i])
270 				break;
271 		fail = 0;
272 		if(i != 8){
273 			printf(" Enc FAIL ");
274 			print_bits(cipher);
275 			fail++; totfails++;
276 		}
277 
278 		des_cipher(cipher, cipher, salt, -1);
279 
280 		for(i = 0; i < 8; i++)
281 			if(cipher[i] != plain[i])
282 				break;
283 		if(i != 8){
284 			printf(" Dec FAIL");
285 			fail++; totfails++;
286 		}
287 
288 		if(fail == 0)
289 			printf(" OK");
290 		printf("\n");
291 	}
292 }
293 
294 
295 /*
296  *	Test the old-style crypt(), the new-style crypt(), and crypt16().
297  */
test_crypt()298 void test_crypt()
299 {
300 	char	*result;
301 	struct crypt_test	*p;
302 
303 	printf("Testing crypt() family\n");
304 
305 	for (p = crypt_tests; p->key; p++) {
306 		printf(" crypt(\"%s\", \"%s\"), \"%s\" expected",
307 			p->key, p->setting, p->answer);
308 		fflush(stdout);
309 		result = crypt(p->key, p->setting);
310 		if(!strcmp(result, p->answer)) {
311 			printf(", OK\n");
312 		} else {
313 			printf("\n  failed (\"%s\")\n", result);
314 			totfails++;
315 		}
316 	}
317 
318 #ifdef HAVE_CRYPT16
319 	for (p = crypt16_tests; p->key; p++) {
320 		printf(" crypt16(\"%s\", \"%s\"), \"%s\" expected",
321 			p->key, p->setting, p->answer);
322 		fflush(stdout);
323 		result = crypt16(p->key, p->setting);
324 		if(!strcmp(result, p->answer)) {
325 			printf(", OK\n");
326 		} else {
327 			printf("\n  failed (\"%s\")\n", result);
328 			totfails++;
329 		}
330 	}
331 #endif /* HAVE_CRYPT16 */
332 }
333 
main(argc,argv)334 main(argc, argv)
335 int argc;
336 char *argv[];
337 {
338 	if(argc < 1 || !strcmp(argv[1], "-e"))
339 		test_encrypt();
340 	else if(!strcmp(argv[1], "-d"))
341 		test_des();
342 	else if(!strcmp(argv[1], "-c"))
343 		test_crypt();
344 	good_bye();
345 }
346