]> git.saurik.com Git - apple/xnu.git/blob - bsd/crypto/des/des_3cbc.c
xnu-123.5.tar.gz
[apple/xnu.git] / bsd / crypto / des / des_3cbc.c
1 /*
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29 /*
30 * based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
31 */
32 #include <crypto/des/des_locl.h>
33
34
35 void des_3cbc_process(m0, skip, length, schedule, ivec, mode)
36 struct mbuf *m0;
37 size_t skip;
38 size_t length;
39 des_key_schedule *schedule;
40 des_cblock (*ivec);
41 int mode;
42 {
43 u_int8_t inbuf[8], outbuf[8];
44 struct mbuf *m;
45 size_t off;
46 DES_LONG tin0, tin1;
47 DES_LONG tout0, tout1;
48 DES_LONG tin[2];
49 DES_LONG xor0 = 0, xor1 = 0;
50 u_int8_t *iv;
51 u_int8_t *in, *out;
52
53 /* sanity check */
54 if (m0->m_pkthdr.len < skip) {
55 printf("des_3cbc_process: mbuf length < skip\n");
56 return;
57 }
58 if (m0->m_pkthdr.len < length) {
59 printf("des_3cbc_process: mbuf length < encrypt length\n");
60 return;
61 }
62 if (m0->m_pkthdr.len < skip + length) {
63 printf("des_3cbc_process: mbuf length < "
64 "skip + encrypt length\n");
65 return;
66 }
67 if (length % 8) {
68 printf("des_3cbc_process: length(%lu) is not multiple of 8\n",
69 (u_long)length);
70 return;
71 }
72
73 m = m0;
74 off = 0;
75
76 /* skip over the header */
77 while (skip) {
78 if (!m)
79 panic("des_3cbc_process: mbuf chain?\n");
80 if (m->m_len <= skip) {
81 skip -= m->m_len;
82 m = m->m_next;
83 off = 0;
84 } else {
85 off = skip;
86 skip = 0;
87 }
88 }
89
90 /* initialize */
91 tin0 = tin1 = tout0 = tout1 = 0;
92 tin[0] = tin[1] = 0;
93
94 switch (mode) {
95 case DES_ENCRYPT:
96 iv = (u_int8_t *)ivec;
97 c2l(iv, tout0);
98 c2l(iv, tout1);
99 break;
100 case DES_DECRYPT:
101 xor0 = xor1 = 0;
102 iv = (u_int8_t *)ivec;
103 c2l(iv, xor0);
104 c2l(iv, xor1);
105 break;
106 }
107
108 /*
109 * encrypt/decrypt packet
110 */
111 while (length > 0) {
112 if (!m)
113 panic("des_3cbc_process: mbuf chain?\n");
114
115 /*
116 * copy the source into input buffer.
117 * don't update off or m, since we need to use them
118 * later.
119 */
120 if (off + 8 <= m->m_len)
121 bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
122 else {
123 struct mbuf *n;
124 size_t noff;
125 u_int8_t *p;
126 u_int8_t *in;
127
128 n = m;
129 noff = off;
130 p = mtod(n, u_int8_t *) + noff;
131
132 in = &inbuf[0];
133 while (in - &inbuf[0] < 8) {
134 if (!p) {
135 panic("des_3cbc_process: "
136 "mbuf chain?\n");
137 }
138 *in++ = *p++;
139 noff++;
140 if (noff < n->m_len)
141 continue;
142 do {
143 n = n->m_next;
144 } while (n && !n->m_len);
145 noff = 0;
146 if (n)
147 p = mtod(n, u_int8_t *) + noff;
148 else
149 p = NULL;
150 }
151 }
152
153 /* encrypt/decrypt */
154 switch (mode) {
155 case DES_ENCRYPT:
156 in = &inbuf[0];
157 out = &outbuf[0];
158 c2l(in, tin0);
159 c2l(in, tin1);
160
161 /* XOR */
162 tin0 ^= tout0; tin[0] = tin0;
163 tin1 ^= tout1; tin[1] = tin1;
164
165 des_encrypt((DES_LONG *)tin, schedule[0], DES_ENCRYPT);
166 des_encrypt((DES_LONG *)tin, schedule[1], DES_DECRYPT);
167 des_encrypt((DES_LONG *)tin, schedule[2], DES_ENCRYPT);
168
169 tout0 = tin[0]; l2c(tout0, out);
170 tout1 = tin[1]; l2c(tout1, out);
171 break;
172 case DES_DECRYPT:
173 in = &inbuf[0];
174 out = &outbuf[0];
175 c2l(in, tin0); tin[0] = tin0;
176 c2l(in, tin1); tin[1] = tin1;
177
178 des_encrypt((DES_LONG *)tin, schedule[2], DES_DECRYPT);
179 des_encrypt((DES_LONG *)tin, schedule[1], DES_ENCRYPT);
180 des_encrypt((DES_LONG *)tin, schedule[0], DES_DECRYPT);
181
182 /* XOR */
183 tout0 = tin[0] ^ xor0;
184 tout1 = tin[1] ^ xor1;
185 l2c(tout0, out);
186 l2c(tout1, out);
187
188 /* for next iv */
189 xor0 = tin0;
190 xor1 = tin1;
191 break;
192 }
193
194 /*
195 * copy the output buffer int the result.
196 * need to update off and m.
197 */
198 if (off + 8 < m->m_len) {
199 bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
200 off += 8;
201 } else if (off + 8 == m->m_len) {
202 bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
203 do {
204 m = m->m_next;
205 } while (m && !m->m_len);
206 off = 0;
207 } else {
208 struct mbuf *n;
209 size_t noff;
210 u_int8_t *p;
211 u_int8_t *out;
212
213 n = m;
214 noff = off;
215 p = mtod(n, u_int8_t *) + noff;
216
217 out = &outbuf[0];
218 while (out - &outbuf[0] < 8) {
219 if (!p) {
220 panic("des_3cbc_process: "
221 "mbuf chain?\n");
222 }
223 *p++ = *out++;
224 noff++;
225 if (noff < n->m_len)
226 continue;
227 do {
228 n = n->m_next;
229 } while (n && !n->m_len);
230 noff = 0;
231 if (n)
232 p = mtod(n, u_int8_t *) + noff;
233 else
234 p = NULL;
235 }
236
237 m = n;
238 off = noff;
239 }
240
241 length -= 8;
242 }
243 }
244