Update copyright notice
[krb5.git] / src / lib / des425 / verify.c
1 /*
2  * $Source$
3  * $Author$
4  *
5  * Copyright 1988,1990 by the Massachusetts Institute of Technology.
6  * All Rights Reserved.
7  *
8  * Export of this software from the United States of America is assumed
9  *   to require a specific license from the United States Government.
10  *   It is the responsibility of any person or organization contemplating
11  *   export to obtain such a license before exporting.
12  * 
13  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
14  * distribute this software and its documentation for any purpose and
15  * without fee is hereby granted, provided that the above copyright
16  * notice appear in all copies and that both that copyright notice and
17  * this permission notice appear in supporting documentation, and that
18  * the name of M.I.T. not be used in advertising or publicity pertaining
19  * to distribution of the software without specific, written prior
20  * permission.  M.I.T. makes no representations about the suitability of
21  * this software for any purpose.  It is provided "as is" without express
22  * or implied warranty.
23  * 
24  *
25  * Program to test the correctness of the DES library
26  * implementation.
27  *
28  * exit returns  0 ==> success
29  *              -1 ==> error
30  */
31
32 #ifndef lint
33 static char rcsid_verify_c[] =
34 "$Id$";
35 #endif  lint
36
37 #include <stdio.h>
38 #include <errno.h>
39 #include "./des.h"
40
41 extern char *errmsg();
42 extern int errno;
43 extern int des_string_to_key();
44 extern int des_key_sched();
45 extern int des_ecb_encrypt();
46 extern int des_cbc_encrypt();
47 extern exit();
48 char *progname;
49 int nflag = 2;
50 int vflag;
51 int mflag;
52 int zflag;
53 int pid;
54 int des_debug;
55 des_key_schedule KS;
56 unsigned char cipher_text[64];
57 unsigned char clear_text[64] = "Now is the time for all " ;
58 unsigned char clear_text2[64] = "7654321 Now is the time for ";
59 unsigned char clear_text3[64] = {2,0,0,0, 1,0,0,0};
60 unsigned char output[64];
61 unsigned char zero_text[8] = {0x0,0,0,0,0,0,0,0};
62 unsigned char msb_text[8] = {0x0,0,0,0, 0,0,0,0x40}; /* to ANSI MSB */
63 unsigned char *input;
64
65 /* 0x0123456789abcdef */
66 unsigned char default_key[8] = {
67     0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
68 };
69 unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f };
70 unsigned char key3[8] = { 0x80,1,1,1,1,1,1,1 };
71 des_cblock s_key;
72 unsigned char default_ivec[8] = {
73     0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef
74 };
75 unsigned char *ivec;
76 unsigned char zero_key[8] = {1,1,1,1,1,1,1,1}; /* just parity bits */
77 int i,j;
78
79 /*
80  * Can also add :
81  * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?)
82  */
83
84 main(argc,argv)
85     int argc;
86     char *argv[];
87 {
88     /* Local Declarations */
89     long in_length;
90
91     progname=argv[0];           /* salt away invoking program */
92
93     /* Assume a long is four bytes */
94     if (sizeof(long) != 4) {
95         printf("\nERROR,  size of long is %d",sizeof(long));
96         exit(-1);
97     }
98
99     while (--argc > 0 && (*++argv)[0] == '-')
100         for (i=1; argv[0][i] != '\0'; i++) {
101             switch (argv[0][i]) {
102
103                 /* debug flag */
104             case 'd':
105                 des_debug=3;
106                 continue;
107
108             case 'z':
109                 zflag = 1;
110                 continue;
111
112             case 'm':
113                 mflag = 1;
114                 continue;
115
116             default:
117                 printf("%s: illegal flag \"%c\" ",
118                        progname,argv[0][i]);
119                 exit(1);
120             }
121         };
122
123     if (argc) {
124         fprintf(stderr, "Usage: %s [-dmz]\n", progname);
125         exit(1);
126     }
127
128     /* use known input and key */
129
130     /* ECB zero text zero key */
131     if (zflag) {
132         input = zero_text;
133         des_key_sched(zero_key,KS);
134         printf("plaintext = key = 0, cipher = 0x8ca64de9c1b123a7\n");
135         do_encrypt(input,cipher_text);
136         printf("\tcipher  = (low to high bytes)\n\t\t");
137         for (j = 0; j<=7; j++)
138             printf("%02x ",cipher_text[j]);
139         printf("\n");
140         do_decrypt(output,cipher_text);
141         return(0);
142     }
143
144     if (mflag) {
145         input = msb_text;
146         des_key_sched(key3,KS);
147         printf("plaintext = 0x00 00 00 00 00 00 00 40, ");
148         printf("key = 0, cipher = 0x??\n");
149         do_encrypt(input,cipher_text);
150         printf("\tcipher  = (low to high bytes)\n\t\t");
151         for (j = 0; j<=7; j++) {
152             printf("%02x ",cipher_text[j]);
153         }
154         printf("\n");
155         do_decrypt(output,cipher_text);
156         return(0);
157     }
158
159     /* ECB mode Davies and Price */
160     {
161         input = zero_text;
162         des_key_sched(key2,KS);
163         printf("Examples per FIPS publication 81, keys ivs and cipher\n");
164         printf("in hex.  These are the correct answers, see below for\n");
165         printf("the actual answers.\n\n");
166         printf("Examples per Davies and Price.\n\n");
167         printf("EXAMPLE ECB\tkey = 08192a3b4c5d6e7f\n");
168         printf("\tclear = 0\n");
169         printf("\tcipher = 25 dd ac 3e 96 17 64 67\n");
170         printf("ACTUAL ECB\n");
171         printf("\tclear \"%s\"\n", input);
172         do_encrypt(input,cipher_text);
173         printf("\tcipher  = (low to high bytes)\n\t\t");
174         for (j = 0; j<=7; j++)
175             printf("%02x ",cipher_text[j]);
176         printf("\n\n");
177         do_decrypt(output,cipher_text);
178     }
179
180     /* ECB mode */
181     {
182         des_key_sched(default_key,KS);
183         input = clear_text;
184         ivec = default_ivec;
185         printf("EXAMPLE ECB\tkey = 0123456789abcdef\n");
186         printf("\tclear = \"Now is the time for all \"\n");
187         printf("\tcipher = 3f a4 0e 8a 98 4d 48 15 ...\n");
188         printf("ACTUAL ECB\n\tclear \"%s\"",input);
189         do_encrypt(input,cipher_text);
190         printf("\n\tcipher      = (low to high bytes)\n\t\t");
191         for (j = 0; j<=7; j++) {
192             printf("%02x ",cipher_text[j]);
193         }
194         printf("\n\n");
195         do_decrypt(output,cipher_text);
196     }
197
198     /* CBC mode */
199     printf("EXAMPLE CBC\tkey = 0123456789abcdef");
200     printf("\tiv = 1234567890abcdef\n");
201     printf("\tclear = \"Now is the time for all \"\n");
202     printf("\tcipher =\te5 c7 cd de 87 2b f2 7c\n");
203     printf("\t\t\t43 e9 34 00 8c 38 9c 0f\n");
204     printf("\t\t\t68 37 88 49 9a 7c 05 f6\n");
205
206     printf("ACTUAL CBC\n\tclear \"%s\"\n",input);
207     in_length = strlen(input);
208     des_cbc_encrypt(input,cipher_text,(long) in_length,KS,ivec,1);
209     printf("\tciphertext = (low to high bytes)\n");
210     for (i = 0; i <= 7; i++) {
211         printf("\t\t");
212         for (j = 0; j <= 7; j++) {
213             printf("%02x ",cipher_text[i*8+j]);
214         }
215         printf("\n");
216     }
217     des_cbc_encrypt(cipher_text,clear_text,(long) in_length,KS,ivec,0);
218     printf("\tdecrypted clear_text = \"%s\"\n",clear_text);
219
220     printf("EXAMPLE CBC checksum");
221     printf("\tkey =  0123456789abcdef\tiv =  1234567890abcdef\n");
222     printf("\tclear =\t\t\"7654321 Now is the time for \"\n");
223     printf("\tchecksum\t58 d2 e7 7e 86 06 27 33, ");
224     printf("or some part thereof\n");
225     input = clear_text2;
226     des_cbc_cksum(input,cipher_text,(long) strlen(input),KS,ivec,1);
227     printf("ACTUAL CBC checksum\n");
228     printf("\t\tencrypted cksum = (low to high bytes)\n\t\t");
229     for (j = 0; j<=7; j++)
230         printf("%02x ",cipher_text[j]);
231     printf("\n\n");
232     exit(0);
233 }
234
235 flip(array)
236     char *array;
237 {
238     register old,new,i,j;
239     /* flips the bit order within each byte from 0 lsb to 0 msb */
240     for (i = 0; i<=7; i++) {
241         old = *array;
242         new = 0;
243         for (j = 0; j<=7; j++) {
244             if (old & 01)
245                 new = new | 01;
246             if (j < 7) {
247                 old = old >> 1;
248                 new = new << 1;
249             }
250         }
251         *array = new;
252         array++;
253     }
254 }
255
256 do_encrypt(in,out)
257     char *in;
258     char *out;
259 {
260     for (i =1; i<=nflag; i++) {
261         des_ecb_encrypt(in,out,KS,1);
262         if (des_debug) {
263             printf("\nclear %s\n",in);
264             for (j = 0; j<=7; j++)
265                 printf("%02 X ",in[j] & 0xff);
266             printf("\tcipher ");
267             for (j = 0; j<=7; j++)
268                 printf("%02X ",out[j] & 0xff);
269         }
270     }
271 }
272
273 do_decrypt(in,out)
274     char *out;
275     char *in;
276     /* try to invert it */
277 {
278     for (i =1; i<=nflag; i++) {
279         des_ecb_encrypt(out,in,KS,0);
280         if (des_debug) {
281             printf("clear %s\n",in);
282             for (j = 0; j<=7; j++)
283                 printf("%02X ",in[j] & 0xff);
284             printf("\tcipher ");
285             for (j = 0; j<=7; j++)
286                 printf("%02X ",out[j] & 0xff);
287         }
288     }
289 }