1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/sctp/src/netinet/sctp_sha1.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,328 @@ 1.4 +/*- 1.5 + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 1.6 + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 1.7 + * Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved. 1.8 + * Copyright (c) 2013, by Lally Singh. All rights reserved. 1.9 + * 1.10 + * Redistribution and use in source and binary forms, with or without 1.11 + * modification, are permitted provided that the following conditions are met: 1.12 + * 1.13 + * a) Redistributions of source code must retain the above copyright notice, 1.14 + * this list of conditions and the following disclaimer. 1.15 + * 1.16 + * b) Redistributions in binary form must reproduce the above copyright 1.17 + * notice, this list of conditions and the following disclaimer in 1.18 + * the documentation and/or other materials provided with the distribution. 1.19 + * 1.20 + * c) Neither the name of Cisco Systems, Inc. nor the names of its 1.21 + * contributors may be used to endorse or promote products derived 1.22 + * from this software without specific prior written permission. 1.23 + * 1.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.25 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1.26 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.27 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.28 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.29 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.30 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.31 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.32 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.33 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1.34 + * THE POSSIBILITY OF SUCH DAMAGE. 1.35 + */ 1.36 + 1.37 +#include <netinet/sctp_sha1.h> 1.38 + 1.39 +#if defined(SCTP_USE_NSS_SHA1) 1.40 +/* A SHA-1 Digest is 160 bits, or 20 bytes */ 1.41 +#define SHA_DIGEST_LENGTH (20) 1.42 + 1.43 +void 1.44 +sctp_sha1_init(struct sctp_sha1_context *ctx) 1.45 +{ 1.46 + ctx->pk11_ctx = PK11_CreateDigestContext(SEC_OID_SHA1); 1.47 + PK11_DigestBegin(ctx->pk11_ctx); 1.48 +} 1.49 + 1.50 +void 1.51 +sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz) 1.52 +{ 1.53 + PK11_DigestOp(ctx->pk11_ctx, ptr, siz); 1.54 +} 1.55 + 1.56 +void 1.57 +sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx) 1.58 +{ 1.59 + unsigned int output_len = 0; 1.60 + 1.61 + PK11_DigestFinal(ctx->pk11_ctx, digest, &output_len, SHA_DIGEST_LENGTH); 1.62 + PK11_DestroyContext(ctx->pk11_ctx, PR_TRUE); 1.63 +} 1.64 + 1.65 +#elif defined(SCTP_USE_OPENSSL_SHA1) 1.66 + 1.67 +void 1.68 +sctp_sha1_init(struct sctp_sha1_context *ctx) 1.69 +{ 1.70 + SHA1_Init(&ctx->sha_ctx); 1.71 +} 1.72 + 1.73 +void 1.74 +sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz) 1.75 +{ 1.76 + SHA1_Update(&ctx->sha_ctx, ptr, (unsigned long)siz); 1.77 +} 1.78 + 1.79 +void 1.80 +sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx) 1.81 +{ 1.82 + SHA1_Final(digest, &ctx->sha_ctx); 1.83 +} 1.84 + 1.85 +#else 1.86 + 1.87 +#include <string.h> 1.88 +#if defined(__Userspace_os_Windows) 1.89 +#include <winsock2.h> 1.90 +#elif !defined(__Windows__) 1.91 +#include <arpa/inet.h> 1.92 +#endif 1.93 + 1.94 +#define F1(B,C,D) (((B & C) | ((~B) & D))) /* 0 <= t <= 19 */ 1.95 +#define F2(B,C,D) (B ^ C ^ D) /* 20 <= t <= 39 */ 1.96 +#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */ 1.97 +#define F4(B,C,D) (B ^ C ^ D) /* 600 <= t <= 79 */ 1.98 + 1.99 +/* circular shift */ 1.100 +#define CSHIFT(A,B) ((B << A) | (B >> (32-A))) 1.101 + 1.102 +#define K1 0x5a827999 /* 0 <= t <= 19 */ 1.103 +#define K2 0x6ed9eba1 /* 20 <= t <= 39 */ 1.104 +#define K3 0x8f1bbcdc /* 40 <= t <= 59 */ 1.105 +#define K4 0xca62c1d6 /* 60 <= t <= 79 */ 1.106 + 1.107 +#define H0INIT 0x67452301 1.108 +#define H1INIT 0xefcdab89 1.109 +#define H2INIT 0x98badcfe 1.110 +#define H3INIT 0x10325476 1.111 +#define H4INIT 0xc3d2e1f0 1.112 + 1.113 +void 1.114 +sctp_sha1_init(struct sctp_sha1_context *ctx) 1.115 +{ 1.116 + /* Init the SHA-1 context structure */ 1.117 + ctx->A = 0; 1.118 + ctx->B = 0; 1.119 + ctx->C = 0; 1.120 + ctx->D = 0; 1.121 + ctx->E = 0; 1.122 + ctx->H0 = H0INIT; 1.123 + ctx->H1 = H1INIT; 1.124 + ctx->H2 = H2INIT; 1.125 + ctx->H3 = H3INIT; 1.126 + ctx->H4 = H4INIT; 1.127 + ctx->TEMP = 0; 1.128 + memset(ctx->words, 0, sizeof(ctx->words)); 1.129 + ctx->how_many_in_block = 0; 1.130 + ctx->running_total = 0; 1.131 +} 1.132 + 1.133 +static void 1.134 +sctp_sha1_process_a_block(struct sctp_sha1_context *ctx, unsigned int *block) 1.135 +{ 1.136 + int i; 1.137 + 1.138 + /* init the W0-W15 to the block of words being hashed. */ 1.139 + /* step a) */ 1.140 + for (i = 0; i < 16; i++) { 1.141 + ctx->words[i] = ntohl(block[i]); 1.142 + } 1.143 + /* now init the rest based on the SHA-1 formula, step b) */ 1.144 + for (i = 16; i < 80; i++) { 1.145 + ctx->words[i] = CSHIFT(1, ((ctx->words[(i - 3)]) ^ 1.146 + (ctx->words[(i - 8)]) ^ 1.147 + (ctx->words[(i - 14)]) ^ 1.148 + (ctx->words[(i - 16)]))); 1.149 + } 1.150 + /* step c) */ 1.151 + ctx->A = ctx->H0; 1.152 + ctx->B = ctx->H1; 1.153 + ctx->C = ctx->H2; 1.154 + ctx->D = ctx->H3; 1.155 + ctx->E = ctx->H4; 1.156 + 1.157 + /* step d) */ 1.158 + for (i = 0; i < 80; i++) { 1.159 + if (i < 20) { 1.160 + ctx->TEMP = ((CSHIFT(5, ctx->A)) + 1.161 + (F1(ctx->B, ctx->C, ctx->D)) + 1.162 + (ctx->E) + 1.163 + ctx->words[i] + 1.164 + K1); 1.165 + } else if (i < 40) { 1.166 + ctx->TEMP = ((CSHIFT(5, ctx->A)) + 1.167 + (F2(ctx->B, ctx->C, ctx->D)) + 1.168 + (ctx->E) + 1.169 + (ctx->words[i]) + 1.170 + K2); 1.171 + } else if (i < 60) { 1.172 + ctx->TEMP = ((CSHIFT(5, ctx->A)) + 1.173 + (F3(ctx->B, ctx->C, ctx->D)) + 1.174 + (ctx->E) + 1.175 + (ctx->words[i]) + 1.176 + K3); 1.177 + } else { 1.178 + ctx->TEMP = ((CSHIFT(5, ctx->A)) + 1.179 + (F4(ctx->B, ctx->C, ctx->D)) + 1.180 + (ctx->E) + 1.181 + (ctx->words[i]) + 1.182 + K4); 1.183 + } 1.184 + ctx->E = ctx->D; 1.185 + ctx->D = ctx->C; 1.186 + ctx->C = CSHIFT(30, ctx->B); 1.187 + ctx->B = ctx->A; 1.188 + ctx->A = ctx->TEMP; 1.189 + } 1.190 + /* step e) */ 1.191 + ctx->H0 = (ctx->H0) + (ctx->A); 1.192 + ctx->H1 = (ctx->H1) + (ctx->B); 1.193 + ctx->H2 = (ctx->H2) + (ctx->C); 1.194 + ctx->H3 = (ctx->H3) + (ctx->D); 1.195 + ctx->H4 = (ctx->H4) + (ctx->E); 1.196 +} 1.197 + 1.198 +void 1.199 +sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz) 1.200 +{ 1.201 + unsigned int number_left, left_to_fill; 1.202 + 1.203 + number_left = siz; 1.204 + while (number_left > 0) { 1.205 + left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block; 1.206 + if (left_to_fill > number_left) { 1.207 + /* can only partially fill up this one */ 1.208 + memcpy(&ctx->sha_block[ctx->how_many_in_block], 1.209 + ptr, number_left); 1.210 + ctx->how_many_in_block += number_left; 1.211 + ctx->running_total += number_left; 1.212 + number_left = 0; 1.213 + break; 1.214 + } else { 1.215 + /* block is now full, process it */ 1.216 + memcpy(&ctx->sha_block[ctx->how_many_in_block], 1.217 + ptr, left_to_fill); 1.218 + sctp_sha1_process_a_block(ctx, 1.219 + (unsigned int *)ctx->sha_block); 1.220 + number_left -= left_to_fill; 1.221 + ctx->running_total += left_to_fill; 1.222 + ctx->how_many_in_block = 0; 1.223 + ptr = (const unsigned char *)(ptr + left_to_fill); 1.224 + } 1.225 + } 1.226 +} 1.227 + 1.228 +void 1.229 +sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx) 1.230 +{ 1.231 + /* 1.232 + * if any left in block fill with padding and process. Then transfer 1.233 + * the digest to the pointer. At the last block some special rules 1.234 + * need to apply. We must add a 1 bit following the message, then we 1.235 + * pad with 0's. The total size is encoded as a 64 bit number at the 1.236 + * end. Now if the last buffer has more than 55 octets in it we 1.237 + * cannot fit the 64 bit number + 10000000 pad on the end and must 1.238 + * add the 10000000 pad, pad the rest of the message with 0's and 1.239 + * then create an all 0 message with just the 64 bit size at the end 1.240 + * and run this block through by itself. Also the 64 bit int must 1.241 + * be in network byte order. 1.242 + */ 1.243 + int left_to_fill; 1.244 + unsigned int i, *ptr; 1.245 + 1.246 + if (ctx->how_many_in_block > 55) { 1.247 + /* 1.248 + * special case, we need to process two blocks here. One for 1.249 + * the current stuff plus possibly the pad. The other for 1.250 + * the size. 1.251 + */ 1.252 + left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block; 1.253 + if (left_to_fill == 0) { 1.254 + /* Should not really happen but I am paranoid */ 1.255 + sctp_sha1_process_a_block(ctx, 1.256 + (unsigned int *)ctx->sha_block); 1.257 + /* init last block, a bit different than the rest */ 1.258 + ctx->sha_block[0] = '\x80'; 1.259 + for (i = 1; i < sizeof(ctx->sha_block); i++) { 1.260 + ctx->sha_block[i] = 0x0; 1.261 + } 1.262 + } else if (left_to_fill == 1) { 1.263 + ctx->sha_block[ctx->how_many_in_block] = '\x80'; 1.264 + sctp_sha1_process_a_block(ctx, 1.265 + (unsigned int *)ctx->sha_block); 1.266 + /* init last block */ 1.267 + memset(ctx->sha_block, 0, sizeof(ctx->sha_block)); 1.268 + } else { 1.269 + ctx->sha_block[ctx->how_many_in_block] = '\x80'; 1.270 + for (i = (ctx->how_many_in_block + 1); 1.271 + i < sizeof(ctx->sha_block); 1.272 + i++) { 1.273 + ctx->sha_block[i] = 0x0; 1.274 + } 1.275 + sctp_sha1_process_a_block(ctx, 1.276 + (unsigned int *)ctx->sha_block); 1.277 + /* init last block */ 1.278 + memset(ctx->sha_block, 0, sizeof(ctx->sha_block)); 1.279 + } 1.280 + /* This is in bits so multiply by 8 */ 1.281 + ctx->running_total *= 8; 1.282 + ptr = (unsigned int *)&ctx->sha_block[60]; 1.283 + *ptr = htonl(ctx->running_total); 1.284 + sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block); 1.285 + } else { 1.286 + /* 1.287 + * easy case, we just pad this message to size - end with 0 1.288 + * add the magic 0x80 to the next word and then put the 1.289 + * network byte order size in the last spot and process the 1.290 + * block. 1.291 + */ 1.292 + ctx->sha_block[ctx->how_many_in_block] = '\x80'; 1.293 + for (i = (ctx->how_many_in_block + 1); 1.294 + i < sizeof(ctx->sha_block); 1.295 + i++) { 1.296 + ctx->sha_block[i] = 0x0; 1.297 + } 1.298 + /* get last int spot */ 1.299 + ctx->running_total *= 8; 1.300 + ptr = (unsigned int *)&ctx->sha_block[60]; 1.301 + *ptr = htonl(ctx->running_total); 1.302 + sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block); 1.303 + } 1.304 + /* transfer the digest back to the user */ 1.305 + digest[3] = (ctx->H0 & 0xff); 1.306 + digest[2] = ((ctx->H0 >> 8) & 0xff); 1.307 + digest[1] = ((ctx->H0 >> 16) & 0xff); 1.308 + digest[0] = ((ctx->H0 >> 24) & 0xff); 1.309 + 1.310 + digest[7] = (ctx->H1 & 0xff); 1.311 + digest[6] = ((ctx->H1 >> 8) & 0xff); 1.312 + digest[5] = ((ctx->H1 >> 16) & 0xff); 1.313 + digest[4] = ((ctx->H1 >> 24) & 0xff); 1.314 + 1.315 + digest[11] = (ctx->H2 & 0xff); 1.316 + digest[10] = ((ctx->H2 >> 8) & 0xff); 1.317 + digest[9] = ((ctx->H2 >> 16) & 0xff); 1.318 + digest[8] = ((ctx->H2 >> 24) & 0xff); 1.319 + 1.320 + digest[15] = (ctx->H3 & 0xff); 1.321 + digest[14] = ((ctx->H3 >> 8) & 0xff); 1.322 + digest[13] = ((ctx->H3 >> 16) & 0xff); 1.323 + digest[12] = ((ctx->H3 >> 24) & 0xff); 1.324 + 1.325 + digest[19] = (ctx->H4 & 0xff); 1.326 + digest[18] = ((ctx->H4 >> 8) & 0xff); 1.327 + digest[17] = ((ctx->H4 >> 16) & 0xff); 1.328 + digest[16] = ((ctx->H4 >> 24) & 0xff); 1.329 +} 1.330 + 1.331 +#endif