HAMMER 60I/Many: Mirroring
[dragonfly.git] / sys / netinet / sctp_hashdriver.c
blob703218640e18198f2b541fd2302523fc10e56284
1 /* $KAME: sctp_hashdriver.c,v 1.5 2004/01/19 09:48:26 itojun Exp $ */
2 /* $DragonFly: src/sys/netinet/sctp_hashdriver.c,v 1.2 2006/01/14 11:33:50 swildner Exp $ */
4 /*
5 * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Cisco Systems, Inc.
19 * 4. Neither the name of the project nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
38 #include <sys/mbuf.h>
39 #include <sys/domain.h>
40 #include <sys/protosw.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/proc.h>
44 #include <sys/kernel.h>
45 #include <sys/sysctl.h>
46 #include <sys/types.h>
47 #include <netinet/sctp_constants.h>
48 #ifdef USE_MD5
49 #include <crypto/md5.h>
50 #else
51 #include <netinet/sctp_sha1.h>
52 #endif /* USE_MD5 */
53 #include <netinet/sctp_hashdriver.h>
56 * Main driver for SCTP's hashing.
57 * passing a two pointers and two lengths, returning a digest pointer
58 * filled. The md5 code was taken directly from the RFC (2104) so to
59 * understand it you may want to go look at the RFC referenced in the
60 * SCTP spec. We did modify this code to either user OURs implementation
61 * of SLA1 or the MD5 that comes from its RFC. SLA1 may have IPR issues
62 * so you need to check in to this if you wish to use it... Or at least
63 * that is what the FIP-180.1 web page says.
66 void
67 sctp_hash_digest(char *key, int key_len, char *text, int text_len,
68 unsigned char *digest)
70 #ifdef USE_MD5
71 md5_ctxt context;
72 #else
73 struct sha1_context context;
74 #endif /* USE_MD5 */
75 /* inner padding - key XORd with ipad */
76 unsigned char k_ipad[65];
77 /* outer padding - key XORd with opad */
78 unsigned char k_opad[65];
79 unsigned char tk[20];
80 int i;
82 if (key_len > 64) {
83 #ifdef USE_MD5
84 md5_ctxt tctx;
85 MD5Init(&tctx);
86 MD5Update(&tctx, key, key_len);
87 MD5Final(tk, &tctx);
88 key = tk;
89 key_len = 16;
90 #else
91 struct sha1_context tctx;
92 SHA1_Init(&tctx);
93 SHA1_Process(&tctx, key, key_len);
94 SHA1_Final(&tctx, tk);
95 key = tk;
96 key_len = 20;
97 #endif /* USE_MD5 */
101 * the HMAC_MD5 transform looks like:
103 * MD5(K XOR opad, MD5(K XOR ipad, text))
105 * where K is an n byte key
106 * ipad is the byte 0x36 repeated 64 times
107 * opad is the byte 0x5c repeated 64 times
108 * and text is the data being protected
111 /* start out by storing key in pads */
112 bzero(k_ipad, sizeof k_ipad);
113 bzero(k_opad, sizeof k_opad);
114 bcopy(key, k_ipad, key_len);
115 bcopy(key, k_opad, key_len);
117 /* XOR key with ipad and opad values */
118 for (i = 0; i < 64; i++) {
119 k_ipad[i] ^= 0x36;
120 k_opad[i] ^= 0x5c;
123 * perform inner MD5
125 #ifdef USE_MD5
126 MD5Init(&context); /* init context for 1st pass */
127 MD5Update(&context, k_ipad, 64); /* start with inner pad */
128 MD5Update(&context, text, text_len); /* then text of datagram */
129 MD5Final(digest, &context); /* finish up 1st pass */
130 #else
131 SHA1_Init(&context); /* init context for 1st pass */
132 SHA1_Process(&context, k_ipad, 64); /* start with inner pad */
133 SHA1_Process(&context, text, text_len); /* then text of datagram */
134 SHA1_Final(&context, digest); /* finish up 1st pass */
135 #endif /* USE_MD5 */
138 * perform outer MD5
140 #ifdef USE_MD5
141 MD5Init(&context); /* init context for 2nd pass */
142 MD5Update(&context, k_opad, 64); /* start with outer pad */
143 MD5Update(&context, digest, 16); /* then results of 1st hash */
144 MD5Final(digest, &context); /* finish up 2nd pass */
145 #else
146 SHA1_Init(&context); /* init context for 2nd pass */
147 SHA1_Process(&context, k_opad, 64); /* start with outer pad */
148 SHA1_Process(&context, digest, 20); /* then results of 1st hash */
149 SHA1_Final(&context, digest); /* finish up 2nd pass */
150 #endif /* USE_MD5 */
153 void
154 sctp_hash_digest_m(char *key, int key_len, struct mbuf *m, int offset,
155 unsigned char *digest)
157 struct mbuf *m_at;
158 #ifdef USE_MD5
159 md5_ctxt context;
160 #else
161 struct sha1_context context;
162 #endif /* USE_MD5 */
163 /* inner padding - key XORd with ipad */
164 unsigned char k_ipad[65];
165 /* outer padding - key XORd with opad */
166 unsigned char k_opad[65];
167 unsigned char tk[20];
168 int i;
170 if (key_len > 64) {
171 #ifdef USE_MD5
172 md5_ctxt tctx;
173 MD5Init(&tctx);
174 MD5Update(&tctx, key, key_len);
175 MD5Final(tk, &tctx);
176 key = tk;
177 key_len = 16;
178 #else
179 struct sha1_context tctx;
180 SHA1_Init(&tctx);
181 SHA1_Process(&tctx, key, key_len);
182 SHA1_Final(&tctx, tk);
183 key = tk;
184 key_len = 20;
185 #endif /* USE_MD5 */
189 * the HMAC_MD5 transform looks like:
191 * MD5(K XOR opad, MD5(K XOR ipad, text))
193 * where K is an n byte key
194 * ipad is the byte 0x36 repeated 64 times
195 * opad is the byte 0x5c repeated 64 times
196 * and text is the data being protected
199 /* start out by storing key in pads */
200 bzero(k_ipad, sizeof k_ipad);
201 bzero(k_opad, sizeof k_opad);
202 bcopy(key, k_ipad, key_len);
203 bcopy(key, k_opad, key_len);
205 /* XOR key with ipad and opad values */
206 for (i = 0; i < 64; i++) {
207 k_ipad[i] ^= 0x36;
208 k_opad[i] ^= 0x5c;
211 /* find the correct mbuf and offset into mbuf */
212 m_at = m;
213 while ((m_at != NULL) && (offset > m_at->m_len)) {
214 offset -= m_at->m_len; /* update remaining offset left */
215 m_at = m_at->m_next;
218 * perform inner MD5
220 #ifdef USE_MD5
221 MD5Init(&context); /* init context for 1st pass */
222 MD5Update(&context, k_ipad, 64); /* start with inner pad */
223 /******/
224 while (m_at != NULL) {
225 /* then text of datagram... */
226 MD5Update(&context, mtod(m_at, char *)+offset,
227 m_at->m_len-offset);
228 /* only offset on the first mbuf */
229 offset = 0;
230 m_at = m_at->m_next;
232 /******/
233 MD5Final(digest, &context); /* finish up 1st pass */
234 #else
235 SHA1_Init(&context); /* init context for 1st pass */
236 SHA1_Process(&context, k_ipad, 64); /* start with inner pad */
237 /******/
238 while (m_at != NULL) {
239 /* then text of datagram */
240 SHA1_Process(&context, mtod(m_at, char *)+offset,
241 m_at->m_len-offset);
242 /* only offset on the first mbuf */
243 offset = 0;
244 m_at = m_at->m_next;
246 /******/
247 SHA1_Final(&context, digest); /* finish up 1st pass */
248 #endif /* USE_MD5 */
251 * perform outer MD5
253 #ifdef USE_MD5
254 MD5Init(&context); /* init context for 2nd pass */
255 MD5Update(&context, k_opad, 64); /* start with outer pad */
256 MD5Update(&context, digest, 16); /* then results of 1st hash */
257 MD5Final(digest, &context); /* finish up 2nd pass */
258 #else
259 SHA1_Init(&context); /* init context for 2nd pass */
260 SHA1_Process(&context, k_opad, 64); /* start with outer pad */
261 SHA1_Process(&context, digest, 20); /* then results of 1st hash */
262 SHA1_Final(&context, digest); /* finish up 2nd pass */
263 #endif /* USE_MD5 */