warning-cleanup-20010414
[openafs.git] / src / des / cbc_encrypt.c
1 /*
2  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
3  * of Technology.
4  *
5  * For copying and distribution information, please see the file
6  * <mit-cpyright.h>.
7  *
8  * These routines perform encryption and decryption using the DES
9  * private key algorithm, or else a subset of it -- fewer inner loops.
10  * (AUTH_DES_ITER defaults to 16, may be less.)
11  *
12  * Under U.S. law, this software may not be exported outside the US
13  * without license from the U.S. Commerce department.
14  *
15  * These routines form the library interface to the DES facilities.
16  *
17  * Originally written 8/85 by Steve Miller, MIT Project Athena.
18  */
19
20 #include <mit-cpyright.h>
21 #include <stdio.h>
22 #include <des.h>
23 #include <afs/param.h>
24
25 #define XPRT_CBC_ENCRYPT
26
27 extern int des_debug;
28 extern int des_debug_print();
29 extern int des_ecb_encrypt();
30
31 /*
32  * This routine performs DES cipher-block-chaining operation, either
33  * encrypting from cleartext to ciphertext, if encrypt != 0 or
34  * decrypting from ciphertext to cleartext, if encrypt == 0.
35  *
36  * The key schedule is passed as an arg, as well as the cleartext or
37  * ciphertext.  The cleartext and ciphertext should be in host order.
38  *
39  * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
40  * enough space was provided, your program will get trashed.
41  *
42  * For encryption, the cleartext string is null padded, at the end, to
43  * an integral multiple of eight bytes.
44  *
45  * For decryption, the ciphertext will be used in integral multiples
46  * of 8 bytes, but only the first "length" bytes returned into the
47  * cleartext.
48  */
49
50 afs_int32
51 des_cbc_encrypt(in,out,length,key,iv,encrypt)
52     des_cblock *in;             /* >= length bytes of input text */
53     des_cblock *out;            /* >= length bytes of output text */
54     register afs_int32 length;  /* in bytes */
55     int encrypt;                /* 0 ==> decrypt, else encrypt */
56     des_key_schedule key;               /* precomputed key schedule */
57     des_cblock *iv;             /* 8 bytes of ivec */
58 {
59     register afs_uint32 *input = (afs_uint32 *) in;
60     register afs_uint32 *output = (afs_uint32 *) out;
61     register afs_uint32 *ivec = (afs_uint32 *) iv;
62
63     afs_uint32 i,j;
64     afs_uint32 t_input[2];
65     afs_uint32 t_output[2];
66     unsigned char *t_in_p = (unsigned char *) t_input;
67     afs_uint32 xor_0, xor_1;
68
69     if (encrypt) {
70 #ifdef MUSTALIGN
71         if ((afs_int32) ivec & 3) {
72             bcopy((char *)ivec++, (char *)&t_output[0], sizeof(t_output[0]));
73             bcopy((char *)ivec, (char *)&t_output[1], sizeof(t_output[1]));
74         }
75         else
76 #endif
77         {
78             t_output[0] = *ivec++;
79             t_output[1] = *ivec;
80         }
81
82         for (i = 0; length > 0; i++, length -= 8) {
83             /* get input */
84 #ifdef MUSTALIGN
85             if ((afs_int32) input & 3) {
86                 bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
87                 bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
88             }
89             else
90 #endif
91             {
92                 t_input[0] = *input++;
93                 t_input[1] = *input++;
94             }
95
96             /* zero pad */
97             if (length < 8)
98                 for (j = length; j <= 7; j++)
99                     *(t_in_p+j)= 0;
100
101 #ifdef DEBUG
102             if (des_debug)
103                 des_debug_print("clear",length,t_input[0],t_input[1]);
104 #endif
105             /* do the xor for cbc into the temp */
106             t_input[0] ^= t_output[0];
107             t_input[1] ^= t_output[1];
108             /* encrypt */
109             (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
110             /* copy temp output and save it for cbc */
111 #ifdef MUSTALIGN
112             if ((afs_int32) output & 3) {
113                 bcopy((char *)&t_output[0],(char *)output++,
114                       sizeof(t_output[0]));
115                 bcopy((char *)&t_output[1],(char *)output++,
116                       sizeof(t_output[1]));
117             }
118             else
119 #endif
120             {
121                 *output++ = t_output[0];
122                 *output++ = t_output[1];
123             }
124
125 #ifdef DEBUG
126             if (des_debug) {
127                 des_debug_print("xor'ed",i,t_input[0],t_input[1]);
128                 des_debug_print("cipher",i,t_output[0],t_output[1]);
129             }
130 #endif
131         }
132         return 0;
133     }
134
135     else {
136         /* decrypt */
137 #ifdef MUSTALIGN
138         if ((afs_int32) ivec & 3) {
139             bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
140             bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
141         }
142         else
143 #endif
144         {
145             xor_0 = *ivec++;
146             xor_1 = *ivec;
147         }
148
149         for (i = 0; length > 0; i++, length -= 8) {
150             /* get input */
151 #ifdef MUSTALIGN
152             if ((afs_int32) input & 3) {
153                 bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
154                 bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[0]));
155             }
156             else
157 #endif
158             {
159                 t_input[0] = *input++;
160                 t_input[1] = *input++;
161             }
162
163             /* no padding for decrypt */
164 #ifdef DEBUG
165             if (des_debug)
166                 des_debug_print("cipher",i,t_input[0],t_input[1]);
167 #else
168 #ifdef lint
169             i = i;
170 #endif
171 #endif
172             /* encrypt */
173             (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
174 #ifdef DEBUG
175             if (des_debug)
176                 des_debug_print("out pre xor",i,t_output[0],t_output[1]);
177 #endif
178             /* do the xor for cbc into the output */
179             t_output[0] ^= xor_0;
180             t_output[1] ^= xor_1;
181             /* copy temp output */
182 #ifdef MUSTALIGN
183             if ((afs_int32) output & 3) {
184                 bcopy((char *)&t_output[0],(char *)output++,
185                       sizeof(t_output[0]));
186                 bcopy((char *)&t_output[1],(char *)output++,
187                       sizeof(t_output[1]));
188             }
189             else
190 #endif
191             {
192                 *output++ = t_output[0];
193                 *output++ = t_output[1];
194             }
195
196             /* save xor value for next round */
197             xor_0 = t_input[0];
198             xor_1 = t_input[1];
199 #ifdef DEBUG
200             if (des_debug)
201                 des_debug_print("clear",i,t_output[0],t_output[1]);
202 #endif
203         }
204         return 0;
205     }
206 }