]> git.saurik.com Git - apple/xnu.git/blame - bsd/crypto/cast128/cast128_cbc.c
xnu-201.42.3.tar.gz
[apple/xnu.git] / bsd / crypto / cast128 / cast128_cbc.c
CommitLineData
1c79356b
A
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
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/mbuf.h>
36#include <crypto/cast128/cast128.h>
37
38
39void
40cast128_cbc_process(m0, skip, length, subkey, iv, keylen, mode)
41 struct mbuf *m0;
42 size_t skip;
43 size_t length;
44 u_int32_t *subkey;
45 u_int8_t *iv;
46 size_t keylen;
47 int mode;
48{
49 struct mbuf *m;
50 u_int8_t inbuf[8], outbuf[8];
51 size_t off;
52
53 /* sanity check */
54 if (m0->m_pkthdr.len < skip) {
55 printf("cast128_cbc_process: mbuf length < skip\n");
56 return;
57 }
58 if (m0->m_pkthdr.len < length) {
59 printf("cast128_cbc_process: mbuf length < encrypt length\n");
60 return;
61 }
62 if (m0->m_pkthdr.len < skip + length) {
63 printf("cast128_cbc_process: "
64 "mbuf length < skip + encrypt length\n");
65 return;
66 }
67 if (length % 8) {
68 printf("cast128_cbc_process: length is not multiple of 8\n");
69 return;
70 }
71
72 m = m0;
73 off = 0;
74
75 /* skip over the header */
76 while (skip) {
77 if (!m)
78 panic("cast128_cbc_process: mbuf chain?\n");
79 if (m->m_len <= skip) {
80 skip -= m->m_len;
81 m = m->m_next;
82 off = 0;
83 } else {
84 off = skip;
85 skip = 0;
86 }
87 }
88
89 /* copy iv into outbuf for XOR (encrypt) */
90 bcopy(iv, outbuf, 8);
91
92 /*
93 * encrypt/decrypt packet
94 */
95 while (length > 0) {
96 int i;
97
98 if (!m)
99 panic("cast128_cbc_process: mbuf chain?\n");
100
101 /*
102 * copy the source into input buffer.
103 * don't update off or m, since we need to use them
104 * later.
105 */
106 if (off + 8 <= m->m_len)
107 bcopy(mtod(m, u_int8_t *)+off, inbuf, 8);
108 else {
109 struct mbuf *n;
110 size_t noff;
111 u_int8_t *p, *in;
112
113 n = m;
114 noff = off;
115 p = mtod(n, u_int8_t *) + noff;
116
117 in = inbuf;
118 while (in - inbuf < 8) {
119 if (!p) {
120 panic("cast128_cbc_process: "
121 "mbuf chain?\n");
122 }
123 *in++ = *p++;
124 noff++;
125 if (noff < n->m_len)
126 continue;
127 do {
128 n = n->m_next;
129 } while (n && !n->m_len);
130 noff = 0;
131 if (n)
132 p = mtod(n, u_int8_t *);
133 else
134 p = NULL;
135 }
136 }
137
138 /* encrypt/decrypt */
139 switch (mode) {
140 case CAST128_ENCRYPT:
141 /* XOR */
142 for (i = 0; i < 8; i++)
143 inbuf[i] ^= outbuf[i];
144
145 /* encrypt */
146 if (keylen <= 80/8)
147 cast128_encrypt_round12(outbuf, inbuf, subkey);
148 else
149 cast128_encrypt_round16(outbuf, inbuf, subkey);
150 break;
151
152 case CAST128_DECRYPT:
153 /* decrypt */
154 if (keylen <= 80/8)
155 cast128_decrypt_round12(outbuf, inbuf, subkey);
156 else
157 cast128_decrypt_round16(outbuf, inbuf, subkey);
158
159 /* XOR */
160 for (i = 0; i < 8; i++)
161 outbuf[i] ^= iv[i];
162
163 /* copy inbuf into iv for next XOR */
164 bcopy(inbuf, iv, 8);
165 break;
166 }
167
168 /*
169 * copy the output buffer into the result.
170 * need to update off and m.
171 */
172 if (off + 8 < m->m_len) {
173 bcopy(outbuf, mtod(m, u_int8_t *) + off, 8);
174 off += 8;
175 } else if (off + 8 == m->m_len) {
176 bcopy(outbuf, mtod(m, u_int8_t *) + off, 8);
177 do {
178 m = m->m_next;
179 } while (m && !m->m_len);
180 off = 0;
181 } else {
182 struct mbuf *n;
183 size_t noff;
184 u_int8_t *p, *out;
185
186 n = m;
187 noff = off;
188 p = mtod(n, u_int8_t *) + noff;
189
190 out = outbuf;
191 while (out - outbuf < 8) {
192 if (!p) {
193 panic("cast128_cbc_process: "
194 "mbuf chain?\n");
195 }
196 *p++ = *out++;
197 noff++;
198 if (noff < n->m_len)
199 continue;
200 do {
201 n = n->m_next;
202 } while (n && !n->m_len);
203 noff = 0;
204 if (n)
205 p = mtod(n, u_int8_t *);
206 else
207 p = NULL;
208 }
209
210 m = n;
211 off = noff;
212 }
213
214 length -= 8;
215 }
216}
217