crypt-take-voids-20041005
[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 <afsconfig.h>
22 #include <afs/param.h>
23
24 #ifndef KERNEL
25 #include <stdio.h>
26 #endif
27
28 #include <des.h>
29 #include "des_prototypes.h"
30
31 RCSID
32     ("$Header$");
33
34
35 #define XPRT_CBC_ENCRYPT
36
37 /*
38  * This routine performs DES cipher-block-chaining operation, either
39  * encrypting from cleartext to ciphertext, if encrypt != 0 or
40  * decrypting from ciphertext to cleartext, if encrypt == 0.
41  *
42  * The key schedule is passed as an arg, as well as the cleartext or
43  * ciphertext.  The cleartext and ciphertext should be in host order.
44  *
45  * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
46  * enough space was provided, your program will get trashed.
47  *
48  * For encryption, the cleartext string is null padded, at the end, to
49  * an integral multiple of eight bytes.
50  *
51  * For decryption, the ciphertext will be used in integral multiples
52  * of 8 bytes, but only the first "length" bytes returned into the
53  * cleartext.
54  */
55 /*
56     des_cblock *in;             * >= length bytes of input text *
57     des_cblock *out;            * >= length bytes of output text *
58     register afs_int32 length;  * in bytes *
59     int encrypt;                * 0 ==> decrypt, else encrypt *
60     des_key_schedule key;               * precomputed key schedule *
61     des_cblock *iv;             * 8 bytes of ivec *
62 */
63 afs_int32
64 des_cbc_encrypt(void * in, void * out, register afs_int32 length,
65                 des_key_schedule key, des_cblock * iv, int encrypt)
66 {
67     register afs_uint32 *input = (afs_uint32 *) in;
68     register afs_uint32 *output = (afs_uint32 *) out;
69     register afs_uint32 *ivec = (afs_uint32 *) iv;
70
71     afs_uint32 i, j;
72     afs_uint32 t_input[2];
73     afs_uint32 t_output[2];
74     unsigned char *t_in_p = (unsigned char *)t_input;
75     afs_uint32 xor_0, xor_1;
76
77     if (encrypt) {
78 #ifdef MUSTALIGN
79         if ((afs_int32) ivec & 3) {
80             memcpy((char *)&t_output[0], (char *)ivec++, sizeof(t_output[0]));
81             memcpy((char *)&t_output[1], (char *)ivec, sizeof(t_output[1]));
82         } else
83 #endif
84         {
85             t_output[0] = *ivec++;
86             t_output[1] = *ivec;
87         }
88
89         for (i = 0; length > 0; i++, length -= 8) {
90             /* get input */
91 #ifdef MUSTALIGN
92             if ((afs_int32) input & 3) {
93                 memcpy((char *)&t_input[0], (char *)input++,
94                        sizeof(t_input[0]));
95                 memcpy((char *)&t_input[1], (char *)input++,
96                        sizeof(t_input[1]));
97             } else
98 #endif
99             {
100                 t_input[0] = *input++;
101                 t_input[1] = *input++;
102             }
103
104             /* zero pad */
105             if (length < 8)
106                 for (j = length; j <= 7; j++)
107                     *(t_in_p + j) = 0;
108
109 #ifdef DEBUG
110             if (des_debug)
111                 des_debug_print("clear", length, t_input[0], t_input[1]);
112 #endif
113             /* do the xor for cbc into the temp */
114             t_input[0] ^= t_output[0];
115             t_input[1] ^= t_output[1];
116             /* encrypt */
117             (void)des_ecb_encrypt(t_input, t_output, key, encrypt);
118             /* copy temp output and save it for cbc */
119 #ifdef MUSTALIGN
120             if ((afs_int32) output & 3) {
121                 memcpy((char *)output++, (char *)&t_output[0],
122                        sizeof(t_output[0]));
123                 memcpy((char *)output++, (char *)&t_output[1],
124                        sizeof(t_output[1]));
125             } else
126 #endif
127             {
128                 *output++ = t_output[0];
129                 *output++ = t_output[1];
130             }
131
132 #ifdef DEBUG
133             if (des_debug) {
134                 des_debug_print("xor'ed", i, t_input[0], t_input[1]);
135                 des_debug_print("cipher", i, t_output[0], t_output[1]);
136             }
137 #endif
138         }
139         return 0;
140     }
141
142     else {
143         /* decrypt */
144 #ifdef MUSTALIGN
145         if ((afs_int32) ivec & 3) {
146             memcpy((char *)&xor_0, (char *)ivec++, sizeof(xor_0));
147             memcpy((char *)&xor_1, (char *)ivec, sizeof(xor_1));
148         } else
149 #endif
150         {
151             xor_0 = *ivec++;
152             xor_1 = *ivec;
153         }
154
155         for (i = 0; length > 0; i++, length -= 8) {
156             /* get input */
157 #ifdef MUSTALIGN
158             if ((afs_int32) input & 3) {
159                 memcpy((char *)&t_input[0], (char *)input++,
160                        sizeof(t_input[0]));
161                 memcpy((char *)&t_input[1], (char *)input++,
162                        sizeof(t_input[0]));
163             } else
164 #endif
165             {
166                 t_input[0] = *input++;
167                 t_input[1] = *input++;
168             }
169
170             /* no padding for decrypt */
171 #ifdef DEBUG
172             if (des_debug)
173                 des_debug_print("cipher", i, t_input[0], t_input[1]);
174 #else
175 #ifdef lint
176             i = i;
177 #endif
178 #endif
179             /* encrypt */
180             (void)des_ecb_encrypt(t_input, t_output, key, encrypt);
181 #ifdef DEBUG
182             if (des_debug)
183                 des_debug_print("out pre xor", i, t_output[0], t_output[1]);
184 #endif
185             /* do the xor for cbc into the output */
186             t_output[0] ^= xor_0;
187             t_output[1] ^= xor_1;
188             /* copy temp output */
189 #ifdef MUSTALIGN
190             if ((afs_int32) output & 3) {
191                 memcpy((char *)output++, (char *)&t_output[0],
192                        sizeof(t_output[0]));
193                 memcpy((char *)output++, (char *)&t_output[1],
194                        sizeof(t_output[1]));
195             } else
196 #endif
197             {
198                 *output++ = t_output[0];
199                 *output++ = t_output[1];
200             }
201
202             /* save xor value for next round */
203             xor_0 = t_input[0];
204             xor_1 = t_input[1];
205 #ifdef DEBUG
206             if (des_debug)
207                 des_debug_print("clear", i, t_output[0], t_output[1]);
208 #endif
209         }
210         return 0;
211     }
212 }