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