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