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