|
OLD | NEW |
---|---|
(Empty) | |
1 /*- | |
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. | |
3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. | |
4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. | |
5 * | |
6 * Redistribution and use in source and binary forms, with or without | |
7 * modification, are permitted provided that the following conditions are met: | |
8 * | |
9 * a) Redistributions of source code must retain the above copyright notice, | |
10 * this list of conditions and the following disclaimer. | |
11 * | |
12 * b) Redistributions in binary form must reproduce the above copyright | |
13 * notice, this list of conditions and the following disclaimer in | |
14 * the documentation and/or other materials provided with the distribution. | |
15 * | |
16 * c) Neither the name of Cisco Systems, Inc. nor the names of its | |
17 * contributors may be used to endorse or promote products derived | |
18 * from this software without specific prior written permission. | |
19 * | |
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOS E | |
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
30 * THE POSSIBILITY OF SUCH DAMAGE. | |
31 */ | |
32 | |
33 #ifdef __FreeBSD__ | |
34 #include <sys/cdefs.h> | |
35 __FBSDID("$FreeBSD$"); | |
36 #endif | |
37 | |
38 #include <netinet/sctp_sha1.h> | |
39 #if !defined(__Userspace_os_Windows) | |
40 #include <sys/param.h> | |
41 #if !defined(__Windows__) | |
42 #include <arpa/inet.h> | |
43 #endif | |
44 #else | |
45 #include <winsock2.h> | |
46 #endif | |
47 #if !defined(__Userspace__) | |
48 #include <sys/systm.h> | |
49 #endif | |
50 #include <string.h> | |
51 void | |
52 SCTP_SHA1_Init(struct sha1_context *ctx) | |
Ryan Sleevi
2013/06/05 00:00:31
ctx = PK11_CreateDigestContext(SEC_OID_SHA1);
PK11
Mallinath (Gone from Chromium)
2013/06/06 14:55:51
Done.
| |
53 { | |
54 /* Init the SHA-1 context structure */ | |
55 ctx->A = 0; | |
56 ctx->B = 0; | |
57 ctx->C = 0; | |
58 ctx->D = 0; | |
59 ctx->E = 0; | |
60 ctx->H0 = H0INIT; | |
61 ctx->H1 = H1INIT; | |
62 ctx->H2 = H2INIT; | |
63 ctx->H3 = H3INIT; | |
64 ctx->H4 = H4INIT; | |
65 ctx->TEMP = 0; | |
66 memset(ctx->words, 0, sizeof(ctx->words)); | |
67 ctx->how_many_in_block = 0; | |
68 ctx->running_total = 0; | |
69 } | |
70 | |
71 static void | |
72 sha1_process_a_block(struct sha1_context *ctx, unsigned int *block) | |
73 { | |
74 int i; | |
75 | |
76 /* init the W0-W15 to the block of words being hashed. */ | |
77 /* step a) */ | |
78 for (i = 0; i < 16; i++) { | |
79 ctx->words[i] = ntohl(block[i]); | |
80 } | |
81 /* now init the rest based on the SHA-1 formula, step b) */ | |
82 for (i = 16; i < 80; i++) { | |
83 ctx->words[i] = CSHIFT(1, ((ctx->words[(i - 3)]) ^ | |
84 (ctx->words[(i - 8)]) ^ | |
85 (ctx->words[(i - 14)]) ^ | |
86 (ctx->words[(i - 16)]))); | |
87 } | |
88 /* step c) */ | |
89 ctx->A = ctx->H0; | |
90 ctx->B = ctx->H1; | |
91 ctx->C = ctx->H2; | |
92 ctx->D = ctx->H3; | |
93 ctx->E = ctx->H4; | |
94 | |
95 /* step d) */ | |
96 for (i = 0; i < 80; i++) { | |
97 if (i < 20) { | |
98 ctx->TEMP = ((CSHIFT(5, ctx->A)) + | |
99 (F1(ctx->B, ctx->C, ctx->D)) + | |
100 (ctx->E) + | |
101 ctx->words[i] + | |
102 K1); | |
103 } else if (i < 40) { | |
104 ctx->TEMP = ((CSHIFT(5, ctx->A)) + | |
105 (F2(ctx->B, ctx->C, ctx->D)) + | |
106 (ctx->E) + | |
107 (ctx->words[i]) + | |
108 K2); | |
109 } else if (i < 60) { | |
110 ctx->TEMP = ((CSHIFT(5, ctx->A)) + | |
111 (F3(ctx->B, ctx->C, ctx->D)) + | |
112 (ctx->E) + | |
113 (ctx->words[i]) + | |
114 K3); | |
115 } else { | |
116 ctx->TEMP = ((CSHIFT(5, ctx->A)) + | |
117 (F4(ctx->B, ctx->C, ctx->D)) + | |
118 (ctx->E) + | |
119 (ctx->words[i]) + | |
120 K4); | |
121 } | |
122 ctx->E = ctx->D; | |
123 ctx->D = ctx->C; | |
124 ctx->C = CSHIFT(30, ctx->B); | |
125 ctx->B = ctx->A; | |
126 ctx->A = ctx->TEMP; | |
127 } | |
128 /* step e) */ | |
129 ctx->H0 = (ctx->H0) + (ctx->A); | |
130 ctx->H1 = (ctx->H1) + (ctx->B); | |
131 ctx->H2 = (ctx->H2) + (ctx->C); | |
132 ctx->H3 = (ctx->H3) + (ctx->D); | |
133 ctx->H4 = (ctx->H4) + (ctx->E); | |
134 } | |
135 | |
136 | |
137 void | |
138 SCTP_SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz) | |
Ryan Sleevi
2013/06/05 00:00:31
PK11_DigestOp(ctx, data, data_len)
Mallinath (Gone from Chromium)
2013/06/06 14:55:51
Done.
| |
139 { | |
140 int number_left, left_to_fill; | |
141 | |
142 number_left = siz; | |
143 while (number_left > 0) { | |
144 left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block; | |
145 if (left_to_fill > number_left) { | |
146 /* can only partially fill up this one */ | |
147 memcpy(&ctx->sha_block[ctx->how_many_in_block], | |
148 ptr, number_left); | |
149 ctx->how_many_in_block += number_left; | |
150 ctx->running_total += number_left; | |
151 number_left = 0; | |
152 break; | |
153 } else { | |
154 /* block is now full, process it */ | |
155 memcpy(&ctx->sha_block[ctx->how_many_in_block], | |
156 ptr, left_to_fill); | |
157 sha1_process_a_block(ctx, | |
158 (unsigned int *)ctx->sha_block); | |
159 number_left -= left_to_fill; | |
160 ctx->running_total += left_to_fill; | |
161 ctx->how_many_in_block = 0; | |
162 ptr = (const unsigned char *)(ptr + left_to_fill); | |
163 } | |
164 } | |
165 } | |
166 | |
167 void | |
168 SCTP_SHA1_Final(unsigned char *digest, struct sha1_context *ctx) | |
Ryan Sleevi
2013/06/05 00:00:31
PK11_DigestFinal(ctx, digest, &output_len, digest_
Mallinath (Gone from Chromium)
2013/06/06 14:55:51
Done.
| |
169 { | |
170 /* | |
171 * if any left in block fill with padding and process. Then transfer | |
172 * the digest to the pointer. At the last block some special rules | |
173 * need to apply. We must add a 1 bit following the message, then we | |
174 * pad with 0's. The total size is encoded as a 64 bit number at the | |
175 * end. Now if the last buffer has more than 55 octets in it we | |
176 * cannot fit the 64 bit number + 10000000 pad on the end and must | |
177 * add the 10000000 pad, pad the rest of the message with 0's and | |
178 * then create an all 0 message with just the 64 bit size at the end | |
179 * and run this block through by itself. Also the 64 bit int must | |
180 * be in network byte order. | |
181 */ | |
182 int left_to_fill; | |
183 unsigned int i, *ptr; | |
184 | |
185 if (ctx->how_many_in_block > 55) { | |
186 /* | |
187 * special case, we need to process two blocks here. One for | |
188 * the current stuff plus possibly the pad. The other for | |
189 * the size. | |
190 */ | |
191 left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block; | |
192 if (left_to_fill == 0) { | |
193 /* Should not really happen but I am paranoid */ | |
194 sha1_process_a_block(ctx, | |
195 (unsigned int *)ctx->sha_block); | |
196 /* init last block, a bit different than the rest */ | |
197 ctx->sha_block[0] = '\x80'; | |
198 for (i = 1; i < sizeof(ctx->sha_block); i++) { | |
199 ctx->sha_block[i] = 0x0; | |
200 } | |
201 } else if (left_to_fill == 1) { | |
202 ctx->sha_block[ctx->how_many_in_block] = '\x80'; | |
203 sha1_process_a_block(ctx, | |
204 (unsigned int *)ctx->sha_block); | |
205 /* init last block */ | |
206 memset(ctx->sha_block, 0, sizeof(ctx->sha_block)); | |
207 } else { | |
208 ctx->sha_block[ctx->how_many_in_block] = '\x80'; | |
209 for (i = (ctx->how_many_in_block + 1); | |
210 i < sizeof(ctx->sha_block); | |
211 i++) { | |
212 ctx->sha_block[i] = 0x0; | |
213 } | |
214 sha1_process_a_block(ctx, | |
215 (unsigned int *)ctx->sha_block); | |
216 /* init last block */ | |
217 memset(ctx->sha_block, 0, sizeof(ctx->sha_block)); | |
218 } | |
219 /* This is in bits so multiply by 8 */ | |
220 ctx->running_total *= 8; | |
221 ptr = (unsigned int *)&ctx->sha_block[60]; | |
222 *ptr = htonl(ctx->running_total); | |
223 sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block); | |
224 } else { | |
225 /* | |
226 * easy case, we just pad this message to size - end with 0 | |
227 * add the magic 0x80 to the next word and then put the | |
228 * network byte order size in the last spot and process the | |
229 * block. | |
230 */ | |
231 ctx->sha_block[ctx->how_many_in_block] = '\x80'; | |
232 for (i = (ctx->how_many_in_block + 1); | |
233 i < sizeof(ctx->sha_block); | |
234 i++) { | |
235 ctx->sha_block[i] = 0x0; | |
236 } | |
237 /* get last int spot */ | |
238 ctx->running_total *= 8; | |
239 ptr = (unsigned int *)&ctx->sha_block[60]; | |
240 *ptr = htonl(ctx->running_total); | |
241 sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block); | |
242 } | |
243 /* transfer the digest back to the user */ | |
244 digest[3] = (ctx->H0 & 0xff); | |
245 digest[2] = ((ctx->H0 >> 8) & 0xff); | |
246 digest[1] = ((ctx->H0 >> 16) & 0xff); | |
247 digest[0] = ((ctx->H0 >> 24) & 0xff); | |
248 | |
249 digest[7] = (ctx->H1 & 0xff); | |
250 digest[6] = ((ctx->H1 >> 8) & 0xff); | |
251 digest[5] = ((ctx->H1 >> 16) & 0xff); | |
252 digest[4] = ((ctx->H1 >> 24) & 0xff); | |
253 | |
254 digest[11] = (ctx->H2 & 0xff); | |
255 digest[10] = ((ctx->H2 >> 8) & 0xff); | |
256 digest[9] = ((ctx->H2 >> 16) & 0xff); | |
257 digest[8] = ((ctx->H2 >> 24) & 0xff); | |
258 | |
259 digest[15] = (ctx->H3 & 0xff); | |
260 digest[14] = ((ctx->H3 >> 8) & 0xff); | |
261 digest[13] = ((ctx->H3 >> 16) & 0xff); | |
262 digest[12] = ((ctx->H3 >> 24) & 0xff); | |
263 | |
264 digest[19] = (ctx->H4 & 0xff); | |
265 digest[18] = ((ctx->H4 >> 8) & 0xff); | |
266 digest[17] = ((ctx->H4 >> 16) & 0xff); | |
267 digest[16] = ((ctx->H4 >> 24) & 0xff); | |
268 } | |
OLD | NEW |