]> git.saurik.com Git - apple/xnu.git/blob - bsd/crypto/blowfish/bf_cbc_m.c
c7a56d904722c08561179d77987c3c033f8e4a90
[apple/xnu.git] / bsd / crypto / blowfish / bf_cbc_m.c
1 /*
2 * heavily modified to accept mbuf, by Jun-ichiro itojun Itoh
3 * <itojun@itojun.org>, 1997.
4 */
5 /* crypto/bf/bf_cbc.c */
6 /* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
7 * All rights reserved.
8 *
9 * This package is an SSL implementation written
10 * by Eric Young (eay@mincom.oz.au).
11 * The implementation was written so as to conform with Netscapes SSL.
12 *
13 * This library is free for commercial and non-commercial use as long as
14 * the following conditions are aheared to. The following conditions
15 * apply to all code found in this distribution, be it the RC4, RSA,
16 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
17 * included with this distribution is covered by the same copyright terms
18 * except that the holder is Tim Hudson (tjh@mincom.oz.au).
19 *
20 * Copyright remains Eric Young's, and as such any Copyright notices in
21 * the code are not to be removed.
22 * If this package is used in a product, Eric Young should be given attribution
23 * as the author of the parts of the library used.
24 * This can be in the form of a textual message at program startup or
25 * in documentation (online or textual) provided with the package.
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * "This product includes cryptographic software written by
38 * Eric Young (eay@mincom.oz.au)"
39 * The word 'cryptographic' can be left out if the rouines from the library
40 * being used are not cryptographic related :-).
41 * 4. If you include any Windows specific code (or a derivative thereof) from
42 * the apps directory (application code) you must include an acknowledgement:
43 * "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
44 *
45 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 *
57 * The licence and distribution terms for any publically available version or
58 * derivative of this code cannot be changed. i.e. this code cannot simply be
59 * copied and put under another distribution licence
60 * [including the GNU Public Licence.]
61 */
62
63 #include <sys/param.h>
64 #include <sys/malloc.h>
65 #include <sys/mbuf.h>
66 #include <sys/systm.h>
67
68 #include <crypto/blowfish/blowfish.h>
69 #include <crypto/blowfish/bf_locl.h>
70
71 #define panic(x) {printf(x); return;}
72
73 void BF_cbc_encrypt_m(m0, skip, length, key, iv, mode)
74 struct mbuf *m0;
75 int skip;
76 int length;
77 BF_KEY *key;
78 unsigned char *iv;
79 int mode;
80 {
81 u_int8_t inbuf[8], outbuf[8];
82 struct mbuf *m;
83 size_t off;
84 register BF_LONG tin0, tin1;
85 register BF_LONG tout0, tout1;
86 BF_LONG tin[2];
87
88 /* sanity checks */
89 if (m0->m_pkthdr.len < skip) {
90 printf("mbuf length < skip\n");
91 return;
92 }
93 if (m0->m_pkthdr.len < length) {
94 printf("mbuf length < encrypt length\n");
95 return;
96 }
97 if (m0->m_pkthdr.len < skip + length) {
98 printf("mbuf length < skip + encrypt length\n");
99 return;
100 }
101 if (length % 8) {
102 printf("length is not multiple of 8\n");
103 return;
104 }
105
106 m = m0;
107 off = 0;
108
109 /* skip over the header */
110 while (skip) {
111 if (!m)
112 panic("mbuf chain?\n");
113 if (m->m_len <= skip) {
114 skip -= m->m_len;
115 m = m->m_next;
116 off = 0;
117 } else {
118 off = skip;
119 skip = 0;
120 }
121 }
122
123 /* initialize */
124 tin0 = tin1 = tout0 = tout1 = 0;
125 tin[0] = tin[1] = 0;
126
127 if (mode == BF_ENCRYPT) {
128 u_int8_t *in, *out;
129
130 n2l(iv, tout0);
131 n2l(iv, tout1);
132
133 while (0 < length) {
134 if (!m)
135 panic("mbuf chain?\n");
136
137 /*
138 * copy the source into input buffer.
139 * don't update off or m, since we need to use them * later.
140 */
141 if (off + 8 <= m->m_len)
142 bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
143 else {
144 struct mbuf *n;
145 size_t noff;
146 u_int8_t *p;
147 u_int8_t *in;
148
149 n = m;
150 noff = off;
151 p = mtod(n, u_int8_t *) + noff;
152
153 in = &inbuf[0];
154 while (in - &inbuf[0] < 8) {
155 if (!p)
156 panic("mbuf chain?\n");
157
158 *in++ = *p++;
159 noff++;
160 if (noff < n->m_len)
161 continue;
162 do {
163 n = n->m_next;
164 } while (n && ! n->m_len);
165 noff = 0;
166 if (n)
167 p = mtod(n, u_int8_t *) + noff;
168 else
169 p = NULL;
170 }
171 }
172
173 in = &inbuf[0];
174 out = &outbuf[0];
175 n2l(in, tin0);
176 n2l(in, tin1);
177
178 tin0 ^= tout0; tin[0] = tin0;
179 tin1 ^= tout1; tin[1] = tin1;
180 BF_encrypt(tin, key, BF_ENCRYPT);
181 tout0 = tin[0]; l2n(tout0, out);
182 tout1 = tin[1]; l2n(tout1, out);
183
184 /*
185 * copy the output buffer into the result.
186 * need to update off and m.
187 */
188 if (off + 8 < m->m_len) {
189 bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
190 off += 8;
191 } else if (off + 8 == m->m_len) {
192 bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
193 do {
194 m = m->m_next;
195 } while (m && ! m->m_len);
196 off = 0;
197 } else {
198 struct mbuf *n;
199 size_t noff;
200 u_int8_t *p;
201 u_int8_t *out;
202
203 n = m;
204 noff = off;
205 p = mtod(n, u_int8_t *) + noff;
206
207 out = &outbuf[0];
208 while (out - &outbuf[0] < 8) {
209 if (!p)
210 panic("mbuf chain?");
211 *p++ = *out++;
212 noff++;
213 if (noff < n->m_len)
214 continue;
215 do {
216 n = n->m_next;
217 } while (n && ! n->m_len);
218 noff = 0;
219 if (n)
220 p = mtod(n, u_int8_t *) + noff;
221 else
222 p = NULL;
223 }
224
225 m = n;
226 off = noff;
227 }
228
229 length -= 8;
230 }
231 } else if (mode == BF_DECRYPT) {
232 register BF_LONG xor0, xor1;
233 u_int8_t *in, *out;
234
235 xor0 = xor1 = 0;
236 n2l(iv, xor0);
237 n2l(iv, xor1);
238
239 while (0 < length) {
240 if (!m)
241 panic("mbuf chain?\n");
242
243 /*
244 * copy the source into input buffer.
245 * don't update off or m, since we need to use them * later.
246 */
247 if (off + 8 <= m->m_len)
248 bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
249 else {
250 struct mbuf *n;
251 size_t noff;
252 u_int8_t *p;
253 u_int8_t *in;
254
255 n = m;
256 noff = off;
257 p = mtod(n, u_int8_t *) + noff;
258
259 in = &inbuf[0];
260 while (in - &inbuf[0] < 8) {
261 if (!p)
262 panic("mbuf chain?\n");
263 *in++ = *p++;
264 noff++;
265 if (noff < n->m_len)
266 continue;
267 do {
268 n = n->m_next;
269 } while (n && ! n->m_len);
270 noff = 0;
271 if (n)
272 p = mtod(n, u_int8_t *) + noff;
273 else
274 p = NULL;
275 }
276 }
277
278 in = &inbuf[0];
279 out = &outbuf[0];
280 n2l(in, tin0); tin[0] = tin0;
281 n2l(in, tin1); tin[1] = tin1;
282 BF_encrypt(tin, key, BF_DECRYPT);
283 tout0 = tin[0] ^ xor0;
284 tout1 = tin[1] ^ xor1;
285 l2n(tout0, out);
286 l2n(tout1, out);
287 xor0 = tin0;
288 xor1 = tin1;
289
290
291 /*
292 * copy the output buffer into the result.
293 * need to update off and m.
294 */
295 if (off + 8 < m->m_len) {
296 bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
297 off += 8;
298 } else if (off + 8 == m->m_len) {
299 bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
300 do {
301 m = m->m_next;
302 } while (m && ! m->m_len);
303 off = 0;
304 } else {
305 struct mbuf *n;
306 size_t noff;
307 u_int8_t *p;
308 u_int8_t *out;
309
310 n = m;
311 noff = off;
312 p = mtod(n, u_int8_t *) + noff;
313
314 out = &outbuf[0];
315 while (out - &outbuf[0] < 8) {
316 if (!p)
317 panic("mbuf chain?\n");
318 *p++ = *out++;
319 noff++;
320 if (noff < n->m_len)
321 continue;
322 do {
323 n = n->m_next;
324 } while (n && ! n->m_len);
325 noff = 0;
326 if (n)
327 p = mtod(n, u_int8_t *) + noff;
328 else
329 p = NULL;
330 }
331
332 m = n;
333 off = noff;
334 }
335
336 length -= 8;
337 }
338 }
339 }