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