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