xref: /netbsd/sys/crypto/des/des_cbc.c (revision 6550d01e)
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57 
58 #include <sys/cdefs.h>
59 __KERNEL_RCSID(0, "$NetBSD: des_cbc.c,v 1.8 2005/12/11 12:20:52 christos Exp $");
60 
61 #include <sys/types.h>
62 
63 #include <crypto/des/des_locl.h>
64 
65 void des_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length,
66 	     des_key_schedule schedule, des_cblock *ivec, int enc)
67 {
68 	register DES_LONG tin0,tin1;
69 	register DES_LONG tout0,tout1,xor0,xor1;
70 	register long l=length;
71 	DES_LONG tin[2];
72 	unsigned char *iv;
73 
74 	iv = &(*ivec)[0];
75 
76 	if (enc)
77 		{
78 		c2l(iv,tout0);
79 		c2l(iv,tout1);
80 		for (l-=8; l>=0; l-=8)
81 			{
82 			c2l(in,tin0);
83 			c2l(in,tin1);
84 			tin0^=tout0; tin[0]=tin0;
85 			tin1^=tout1; tin[1]=tin1;
86 			des_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
87 			tout0=tin[0]; l2c(tout0,out);
88 			tout1=tin[1]; l2c(tout1,out);
89 			}
90 		if (l != -8)
91 			{
92 			c2ln(in,tin0,tin1,l+8);
93 			tin0^=tout0; tin[0]=tin0;
94 			tin1^=tout1; tin[1]=tin1;
95 			des_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT);
96 			tout0=tin[0]; l2c(tout0,out);
97 			tout1=tin[1]; l2c(tout1,out);
98 			}
99 		iv = &(*ivec)[0];
100 		l2c(tout0,iv);
101 		l2c(tout1,iv);
102 		}
103 	else
104 		{
105 		c2l(iv,xor0);
106 		c2l(iv,xor1);
107 		for (l-=8; l>=0; l-=8)
108 			{
109 			c2l(in,tin0); tin[0]=tin0;
110 			c2l(in,tin1); tin[1]=tin1;
111 			des_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT);
112 			tout0=tin[0]^xor0;
113 			tout1=tin[1]^xor1;
114 			l2c(tout0,out);
115 			l2c(tout1,out);
116 			xor0=tin0;
117 			xor1=tin1;
118 			}
119 		if (l != -8)
120 			{
121 			c2l(in,tin0); tin[0]=tin0;
122 			c2l(in,tin1); tin[1]=tin1;
123 			des_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT);
124 			tout0=tin[0]^xor0;
125 			tout1=tin[1]^xor1;
126 			l2cn(tout0,tout1,out,l+8);
127 			xor0=tin0;
128 			xor1=tin1;
129 			}
130 		iv = &(*ivec)[0];
131 		l2c(xor0,iv);
132 		l2c(xor1,iv);
133 		}
134 	tin0=tin1=tout0=tout1=xor0=xor1=0;
135 	tin[0]=tin[1]=0;
136 }
137 
138 void des_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
139 	     long length, des_key_schedule ks1, des_key_schedule ks2,
140 	     des_key_schedule ks3, des_cblock *ivec, int enc)
141 {
142 	register DES_LONG tin0,tin1;
143 	register DES_LONG tout0,tout1,xor0,xor1;
144 	register const unsigned char *in;
145 	unsigned char *out;
146 	register long l=length;
147 	DES_LONG tin[2];
148 	unsigned char *iv;
149 
150 	in=input;
151 	out=output;
152 	iv = &(*ivec)[0];
153 
154 	if (enc)
155 		{
156 		c2l(iv,tout0);
157 		c2l(iv,tout1);
158 		for (l-=8; l>=0; l-=8)
159 			{
160 			c2l(in,tin0);
161 			c2l(in,tin1);
162 			tin0^=tout0;
163 			tin1^=tout1;
164 
165 			tin[0]=tin0;
166 			tin[1]=tin1;
167 			des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
168 			tout0=tin[0];
169 			tout1=tin[1];
170 
171 			l2c(tout0,out);
172 			l2c(tout1,out);
173 			}
174 		if (l != -8)
175 			{
176 			c2ln(in,tin0,tin1,l+8);
177 			tin0^=tout0;
178 			tin1^=tout1;
179 
180 			tin[0]=tin0;
181 			tin[1]=tin1;
182 			des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
183 			tout0=tin[0];
184 			tout1=tin[1];
185 
186 			l2c(tout0,out);
187 			l2c(tout1,out);
188 			}
189 		iv = &(*ivec)[0];
190 		l2c(tout0,iv);
191 		l2c(tout1,iv);
192 		}
193 	else
194 		{
195 		register DES_LONG t0,t1;
196 
197 		c2l(iv,xor0);
198 		c2l(iv,xor1);
199 		for (l-=8; l>=0; l-=8)
200 			{
201 			c2l(in,tin0);
202 			c2l(in,tin1);
203 
204 			t0=tin0;
205 			t1=tin1;
206 
207 			tin[0]=tin0;
208 			tin[1]=tin1;
209 			des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
210 			tout0=tin[0];
211 			tout1=tin[1];
212 
213 			tout0^=xor0;
214 			tout1^=xor1;
215 			l2c(tout0,out);
216 			l2c(tout1,out);
217 			xor0=t0;
218 			xor1=t1;
219 			}
220 		if (l != -8)
221 			{
222 			c2l(in,tin0);
223 			c2l(in,tin1);
224 
225 			t0=tin0;
226 			t1=tin1;
227 
228 			tin[0]=tin0;
229 			tin[1]=tin1;
230 			des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
231 			tout0=tin[0];
232 			tout1=tin[1];
233 
234 			tout0^=xor0;
235 			tout1^=xor1;
236 			l2cn(tout0,tout1,out,l+8);
237 			xor0=t0;
238 			xor1=t1;
239 			}
240 
241 		iv = &(*ivec)[0];
242 		l2c(xor0,iv);
243 		l2c(xor1,iv);
244 		}
245 	tin0=tin1=tout0=tout1=xor0=xor1=0;
246 	tin[0]=tin[1]=0;
247 }
248