1 /* -*- Mode: C; tab-width: 4 -*- 2 * 3 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #include "mDNSEmbeddedAPI.h" 24 #include "DNSCommon.h" 25 26 // Disable certain benign warnings with Microsoft compilers 27 #if(defined(_MSC_VER)) 28 // Disable "conditional expression is constant" warning for debug macros. 29 // Otherwise, this generates warnings for the perfectly natural construct "while(1)" 30 // If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know 31 #pragma warning(disable:4127) 32 #endif 33 34 35 // *************************************************************************** 36 #if COMPILER_LIKES_PRAGMA_MARK 37 #pragma mark - Byte Swapping Functions 38 #endif 39 40 mDNSlocal mDNSu16 NToH16(mDNSu8 * bytes) 41 { 42 return (mDNSu16)((mDNSu16)bytes[0] << 8 | (mDNSu16)bytes[1]); 43 } 44 45 mDNSlocal mDNSu32 NToH32(mDNSu8 * bytes) 46 { 47 return (mDNSu32)((mDNSu32) bytes[0] << 24 | (mDNSu32) bytes[1] << 16 | (mDNSu32) bytes[2] << 8 | (mDNSu32)bytes[3]); 48 } 49 50 // *************************************************************************** 51 #if COMPILER_LIKES_PRAGMA_MARK 52 #pragma mark - MD5 Hash Functions 53 #endif 54 55 56 /* The source for the has is derived CommonCrypto files CommonDigest.h, md32_common.h, md5_locl.h, md5_locl.h, and openssl/md5.h. 57 * The following changes have been made to the original sources: 58 * replaced CC_LONG w/ mDNSu32 59 * replaced CC_MD5* with MD5* 60 * replaced CC_LONG w/ mDNSu32, removed conditional #defines from md5.h 61 * removed extern decls for MD5_Init/Update/Final from CommonDigest.h 62 * removed APPLE_COMMON_DIGEST specific #defines from md5_locl.h 63 * 64 * Note: machine archetecure specific conditionals from the original sources are turned off, but are left in the code 65 * to aid in platform-specific optimizations and debugging. 66 * Sources originally distributed under the following license headers: 67 * CommonDigest.h - APSL 68 * 69 * md32_Common.h 70 * ==================================================================== 71 * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. 72 * 73 * Redistribution and use in source and binary forms, with or without 74 * modification, are permitted provided that the following conditions 75 * are met: 76 * 77 * 1. Redistributions of source code must retain the above copyright 78 * notice, this list of conditions and the following disclaimer. 79 * 80 * 2. Redistributions in binary form must reproduce the above copyright 81 * notice, this list of conditions and the following disclaimer in 82 * the documentation and/or other materials provided with the 83 * distribution. 84 * 85 * 3. All advertising materials mentioning features or use of this 86 * software must display the following acknowledgment: 87 * "This product includes software developed by the OpenSSL Project 88 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 89 * 90 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 91 * endorse or promote products derived from this software without 92 * prior written permission. For written permission, please contact 93 * licensing (at) OpenSSL.org. 94 * 95 * 5. Products derived from this software may not be called "OpenSSL" 96 * nor may "OpenSSL" appear in their names without prior written 97 * permission of the OpenSSL Project. 98 * 99 * 6. Redistributions of any form whatsoever must retain the following 100 * acknowledgment: 101 * "This product includes software developed by the OpenSSL Project 102 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 103 * 104 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 105 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 106 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 107 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 108 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 109 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 110 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 111 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 112 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 113 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 114 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 115 * OF THE POSSIBILITY OF SUCH DAMAGE. 116 * 117 * 118 * md5_dgst.c, md5_locl.h 119 * ==================================================================== 120 * 121 * This product includes cryptographic software written by Eric Young 122 * (eay (at) cryptsoft.com). This product includes software written by Tim 123 * Hudson (tjh (at) cryptsoft.com). 124 * 125 * Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 126 * All rights reserved. 127 * 128 * This package is an SSL implementation written 129 * by Eric Young (eay (at) cryptsoft.com). 130 * The implementation was written so as to conform with Netscapes SSL. 131 * 132 * This library is free for commercial and non-commercial use as long as 133 * the following conditions are aheared to. The following conditions 134 * apply to all code found in this distribution, be it the RC4, RSA, 135 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 136 * included with this distribution is covered by the same copyright terms 137 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 138 * 139 * Copyright remains Eric Young's, and as such any Copyright notices in 140 * the code are not to be removed. 141 * If this package is used in a product, Eric Young should be given attribution 142 * as the author of the parts of the library used. 143 * This can be in the form of a textual message at program startup or 144 * in documentation (online or textual) provided with the package. 145 * 146 * Redistribution and use in source and binary forms, with or without 147 * modification, are permitted provided that the following conditions 148 * are met: 149 * 1. Redistributions of source code must retain the copyright 150 * notice, this list of conditions and the following disclaimer. 151 * 2. Redistributions in binary form must reproduce the above copyright 152 * notice, this list of conditions and the following disclaimer in the 153 * documentation and/or other materials provided with the distribution. 154 * 3. All advertising materials mentioning features or use of this software 155 * must display the following acknowledgement: 156 * "This product includes cryptographic software written by 157 * Eric Young (eay (at) cryptsoft.com)" 158 * The word 'cryptographic' can be left out if the rouines from the library 159 * being used are not cryptographic related :-). 160 * 4. If you include any Windows specific code (or a derivative thereof) from 161 * the apps directory (application code) you must include an acknowledgement: 162 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 163 * 164 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 165 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 167 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 168 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 169 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 170 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 171 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 172 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 173 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 174 * SUCH DAMAGE. 175 * 176 * The licence and distribution terms for any publically available version or 177 * derivative of this code cannot be changed. i.e. this code cannot simply be 178 * copied and put under another distribution licence 179 * [including the GNU Public Licence.] 180 * 181 */ 182 183 //from CommonDigest.h 184 185 #define MD5_DIGEST_LENGTH 16 /* digest length in bytes */ 186 #define MD5_BLOCK_BYTES 64 /* block size in bytes */ 187 #define MD5_BLOCK_LONG (MD5_BLOCK_BYTES / sizeof(mDNSu32)) 188 189 typedef struct MD5state_st 190 { 191 mDNSu32 A,B,C,D; 192 mDNSu32 Nl,Nh; 193 mDNSu32 data[MD5_BLOCK_LONG]; 194 int num; 195 } MD5_CTX; 196 197 #ifndef HAVE_MD5 198 199 // from openssl/md5.h 200 201 #define MD5_CBLOCK 64 202 #define MD5_LBLOCK (MD5_CBLOCK/4) 203 #define MD5_DIGEST_LENGTH 16 204 205 int MD5_Init(MD5_CTX *c); 206 int MD5_Update(MD5_CTX *c, const void *data, unsigned long len); 207 int MD5_Final(unsigned char *md, MD5_CTX *c); 208 void MD5_Transform(MD5_CTX *c, const unsigned char *b); 209 210 // From md5_locl.h 211 212 #ifndef MD5_LONG_LOG2 213 #define MD5_LONG_LOG2 2 /* default to 32 bits */ 214 #endif 215 216 #ifdef MD5_ASM 217 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) 218 # define md5_block_host_order md5_block_asm_host_order 219 # elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC) 220 void md5_block_asm_data_order_aligned (MD5_CTX *c, const mDNSu32 *p,int num); 221 # define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned 222 # endif 223 #endif 224 225 void md5_block_host_order (MD5_CTX *c, const void *p,int num); 226 void md5_block_data_order (MD5_CTX *c, const void *p,int num); 227 228 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) 229 /* 230 * *_block_host_order is expected to handle aligned data while 231 * *_block_data_order - unaligned. As algorithm and host (x86) 232 * are in this case of the same "endianness" these two are 233 * otherwise indistinguishable. But normally you don't want to 234 * call the same function because unaligned access in places 235 * where alignment is expected is usually a "Bad Thing". Indeed, 236 * on RISCs you get punished with BUS ERROR signal or *severe* 237 * performance degradation. Intel CPUs are in turn perfectly 238 * capable of loading unaligned data without such drastic side 239 * effect. Yes, they say it's slower than aligned load, but no 240 * exception is generated and therefore performance degradation 241 * is *incomparable* with RISCs. What we should weight here is 242 * costs of unaligned access against costs of aligning data. 243 * According to my measurements allowing unaligned access results 244 * in ~9% performance improvement on Pentium II operating at 245 * 266MHz. I won't be surprised if the difference will be higher 246 * on faster systems:-) 247 * 248 * <appro (at) fy.chalmers.se> 249 */ 250 #define md5_block_data_order md5_block_host_order 251 #endif 252 253 #define DATA_ORDER_IS_LITTLE_ENDIAN 254 255 #define HASH_LONG mDNSu32 256 #define HASH_LONG_LOG2 MD5_LONG_LOG2 257 #define HASH_CTX MD5_CTX 258 #define HASH_CBLOCK MD5_CBLOCK 259 #define HASH_LBLOCK MD5_LBLOCK 260 261 #define HASH_UPDATE MD5_Update 262 #define HASH_TRANSFORM MD5_Transform 263 #define HASH_FINAL MD5_Final 264 265 #define HASH_MAKE_STRING(c,s) do { \ 266 unsigned long ll; \ 267 ll=(c)->A; HOST_l2c(ll,(s)); \ 268 ll=(c)->B; HOST_l2c(ll,(s)); \ 269 ll=(c)->C; HOST_l2c(ll,(s)); \ 270 ll=(c)->D; HOST_l2c(ll,(s)); \ 271 } while (0) 272 #define HASH_BLOCK_HOST_ORDER md5_block_host_order 273 #if !defined(L_ENDIAN) || defined(md5_block_data_order) 274 #define HASH_BLOCK_DATA_ORDER md5_block_data_order 275 /* 276 * Little-endians (Intel and Alpha) feel better without this. 277 * It looks like memcpy does better job than generic 278 * md5_block_data_order on copying-n-aligning input data. 279 * But frankly speaking I didn't expect such result on Alpha. 280 * On the other hand I've got this with egcs-1.0.2 and if 281 * program is compiled with another (better?) compiler it 282 * might turn out other way around. 283 * 284 * <appro (at) fy.chalmers.se> 285 */ 286 #endif 287 288 289 // from md32_common.h 290 291 /* 292 * This is a generic 32 bit "collector" for message digest algorithms. 293 * Whenever needed it collects input character stream into chunks of 294 * 32 bit values and invokes a block function that performs actual hash 295 * calculations. 296 * 297 * Porting guide. 298 * 299 * Obligatory macros: 300 * 301 * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN 302 * this macro defines byte order of input stream. 303 * HASH_CBLOCK 304 * size of a unit chunk HASH_BLOCK operates on. 305 * HASH_LONG 306 * has to be at lest 32 bit wide, if it's wider, then 307 * HASH_LONG_LOG2 *has to* be defined along 308 * HASH_CTX 309 * context structure that at least contains following 310 * members: 311 * typedef struct { 312 * ... 313 * HASH_LONG Nl,Nh; 314 * HASH_LONG data[HASH_LBLOCK]; 315 * int num; 316 * ... 317 * } HASH_CTX; 318 * HASH_UPDATE 319 * name of "Update" function, implemented here. 320 * HASH_TRANSFORM 321 * name of "Transform" function, implemented here. 322 * HASH_FINAL 323 * name of "Final" function, implemented here. 324 * HASH_BLOCK_HOST_ORDER 325 * name of "block" function treating *aligned* input message 326 * in host byte order, implemented externally. 327 * HASH_BLOCK_DATA_ORDER 328 * name of "block" function treating *unaligned* input message 329 * in original (data) byte order, implemented externally (it 330 * actually is optional if data and host are of the same 331 * "endianess"). 332 * HASH_MAKE_STRING 333 * macro convering context variables to an ASCII hash string. 334 * 335 * Optional macros: 336 * 337 * B_ENDIAN or L_ENDIAN 338 * defines host byte-order. 339 * HASH_LONG_LOG2 340 * defaults to 2 if not states otherwise. 341 * HASH_LBLOCK 342 * assumed to be HASH_CBLOCK/4 if not stated otherwise. 343 * HASH_BLOCK_DATA_ORDER_ALIGNED 344 * alternative "block" function capable of treating 345 * aligned input message in original (data) order, 346 * implemented externally. 347 * 348 * MD5 example: 349 * 350 * #define DATA_ORDER_IS_LITTLE_ENDIAN 351 * 352 * #define HASH_LONG mDNSu32 353 * #define HASH_LONG_LOG2 mDNSu32_LOG2 354 * #define HASH_CTX MD5_CTX 355 * #define HASH_CBLOCK MD5_CBLOCK 356 * #define HASH_LBLOCK MD5_LBLOCK 357 * #define HASH_UPDATE MD5_Update 358 * #define HASH_TRANSFORM MD5_Transform 359 * #define HASH_FINAL MD5_Final 360 * #define HASH_BLOCK_HOST_ORDER md5_block_host_order 361 * #define HASH_BLOCK_DATA_ORDER md5_block_data_order 362 * 363 * <appro (at) fy.chalmers.se> 364 */ 365 366 #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) 367 #error "DATA_ORDER must be defined!" 368 #endif 369 370 #ifndef HASH_CBLOCK 371 #error "HASH_CBLOCK must be defined!" 372 #endif 373 #ifndef HASH_LONG 374 #error "HASH_LONG must be defined!" 375 #endif 376 #ifndef HASH_CTX 377 #error "HASH_CTX must be defined!" 378 #endif 379 380 #ifndef HASH_UPDATE 381 #error "HASH_UPDATE must be defined!" 382 #endif 383 #ifndef HASH_TRANSFORM 384 #error "HASH_TRANSFORM must be defined!" 385 #endif 386 #ifndef HASH_FINAL 387 #error "HASH_FINAL must be defined!" 388 #endif 389 390 #ifndef HASH_BLOCK_HOST_ORDER 391 #error "HASH_BLOCK_HOST_ORDER must be defined!" 392 #endif 393 394 #if 0 395 /* 396 * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED 397 * isn't defined. 398 */ 399 #ifndef HASH_BLOCK_DATA_ORDER 400 #error "HASH_BLOCK_DATA_ORDER must be defined!" 401 #endif 402 #endif 403 404 #ifndef HASH_LBLOCK 405 #define HASH_LBLOCK (HASH_CBLOCK/4) 406 #endif 407 408 #ifndef HASH_LONG_LOG2 409 #define HASH_LONG_LOG2 2 410 #endif 411 412 /* 413 * Engage compiler specific rotate intrinsic function if available. 414 */ 415 #undef ROTATE 416 #ifndef PEDANTIC 417 # if 0 /* defined(_MSC_VER) */ 418 # define ROTATE(a,n) _lrotl(a,n) 419 # elif defined(__MWERKS__) 420 # if defined(__POWERPC__) 421 # define ROTATE(a,n) (unsigned MD32_REG_T)__rlwinm((int)a,n,0,31) 422 # elif defined(__MC68K__) 423 /* Motorola specific tweak. <appro (at) fy.chalmers.se> */ 424 # define ROTATE(a,n) (n<24 ? __rol(a,n) : __ror(a,32-n)) 425 # else 426 # define ROTATE(a,n) __rol(a,n) 427 # endif 428 # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 429 /* 430 * Some GNU C inline assembler templates. Note that these are 431 * rotates by *constant* number of bits! But that's exactly 432 * what we need here... 433 * 434 * <appro (at) fy.chalmers.se> 435 */ 436 /* 437 * LLVM is more strict about compatibility of types between input & output constraints, 438 * but we want these to be rotations of 32 bits, not 64, so we explicitly drop the 439 * most significant bytes by casting to an unsigned int. 440 */ 441 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) 442 # define ROTATE(a,n) ({ register unsigned int ret; \ 443 asm ( \ 444 "roll %1,%0" \ 445 : "=r"(ret) \ 446 : "I"(n), "0"((unsigned int)a) \ 447 : "cc"); \ 448 ret; \ 449 }) 450 # elif defined(__powerpc) || defined(__ppc) 451 # define ROTATE(a,n) ({ register unsigned int ret; \ 452 asm ( \ 453 "rlwinm %0,%1,%2,0,31" \ 454 : "=r"(ret) \ 455 : "r"(a), "I"(n)); \ 456 ret; \ 457 }) 458 # endif 459 # endif 460 461 /* 462 * Engage compiler specific "fetch in reverse byte order" 463 * intrinsic function if available. 464 */ 465 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 466 /* some GNU C inline assembler templates by <appro (at) fy.chalmers.se> */ 467 # if (defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)) && !defined(I386_ONLY) 468 # define BE_FETCH32(a) ({ register unsigned int l=(a);\ 469 asm ( \ 470 "bswapl %0" \ 471 : "=r"(l) : "0"(l)); \ 472 l; \ 473 }) 474 # elif defined(__powerpc) 475 # define LE_FETCH32(a) ({ register unsigned int l; \ 476 asm ( \ 477 "lwbrx %0,0,%1" \ 478 : "=r"(l) \ 479 : "r"(a)); \ 480 l; \ 481 }) 482 483 # elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC) 484 # define LE_FETCH32(a) ({ register unsigned int l; \ 485 asm ( \ 486 "lda [%1]#ASI_PRIMARY_LITTLE,%0"\ 487 : "=r"(l) \ 488 : "r"(a)); \ 489 l; \ 490 }) 491 # endif 492 # endif 493 #endif /* PEDANTIC */ 494 495 #if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ 496 /* A nice byte order reversal from Wei Dai <weidai (at) eskimo.com> */ 497 #ifdef ROTATE 498 /* 5 instructions with rotate instruction, else 9 */ 499 #define REVERSE_FETCH32(a,l) ( \ 500 l=*(const HASH_LONG *)(a), \ 501 ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ 502 ) 503 #else 504 /* 6 instructions with rotate instruction, else 8 */ 505 #define REVERSE_FETCH32(a,l) ( \ 506 l=*(const HASH_LONG *)(a), \ 507 l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ 508 ROTATE(l,16) \ 509 ) 510 /* 511 * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... 512 * It's rewritten as above for two reasons: 513 * - RISCs aren't good at long constants and have to explicitely 514 * compose 'em with several (well, usually 2) instructions in a 515 * register before performing the actual operation and (as you 516 * already realized:-) having same constant should inspire the 517 * compiler to permanently allocate the only register for it; 518 * - most modern CPUs have two ALUs, but usually only one has 519 * circuitry for shifts:-( this minor tweak inspires compiler 520 * to schedule shift instructions in a better way... 521 * 522 * <appro (at) fy.chalmers.se> 523 */ 524 #endif 525 #endif 526 527 #ifndef ROTATE 528 #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) 529 #endif 530 531 /* 532 * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED 533 * and HASH_BLOCK_HOST_ORDER ought to be the same if input data 534 * and host are of the same "endianess". It's possible to mask 535 * this with blank #define HASH_BLOCK_DATA_ORDER though... 536 * 537 * <appro (at) fy.chalmers.se> 538 */ 539 #if defined(B_ENDIAN) 540 # if defined(DATA_ORDER_IS_BIG_ENDIAN) 541 # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 542 # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER 543 # endif 544 # elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 545 # ifndef HOST_FETCH32 546 # ifdef LE_FETCH32 547 # define HOST_FETCH32(p,l) LE_FETCH32(p) 548 # elif defined(REVERSE_FETCH32) 549 # define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) 550 # endif 551 # endif 552 # endif 553 #elif defined(L_ENDIAN) 554 # if defined(DATA_ORDER_IS_LITTLE_ENDIAN) 555 # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 556 # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER 557 # endif 558 # elif defined(DATA_ORDER_IS_BIG_ENDIAN) 559 # ifndef HOST_FETCH32 560 # ifdef BE_FETCH32 561 # define HOST_FETCH32(p,l) BE_FETCH32(p) 562 # elif defined(REVERSE_FETCH32) 563 # define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) 564 # endif 565 # endif 566 # endif 567 #endif 568 569 #if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) 570 #ifndef HASH_BLOCK_DATA_ORDER 571 #error "HASH_BLOCK_DATA_ORDER must be defined!" 572 #endif 573 #endif 574 575 #if defined(DATA_ORDER_IS_BIG_ENDIAN) 576 577 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ 578 l|=(((unsigned long)(*((c)++)))<<16), \ 579 l|=(((unsigned long)(*((c)++)))<< 8), \ 580 l|=(((unsigned long)(*((c)++))) ), \ 581 l) 582 #define HOST_p_c2l(c,l,n) { \ 583 switch (n) { \ 584 case 0: l =((unsigned long)(*((c)++)))<<24; \ 585 case 1: l|=((unsigned long)(*((c)++)))<<16; \ 586 case 2: l|=((unsigned long)(*((c)++)))<< 8; \ 587 case 3: l|=((unsigned long)(*((c)++))); \ 588 } } 589 #define HOST_p_c2l_p(c,l,sc,len) { \ 590 switch (sc) { \ 591 case 0: l =((unsigned long)(*((c)++)))<<24; \ 592 if (--len == 0) break; \ 593 case 1: l|=((unsigned long)(*((c)++)))<<16; \ 594 if (--len == 0) break; \ 595 case 2: l|=((unsigned long)(*((c)++)))<< 8; \ 596 } } 597 /* NOTE the pointer is not incremented at the end of this */ 598 #define HOST_c2l_p(c,l,n) { \ 599 l=0; (c)+=n; \ 600 switch (n) { \ 601 case 3: l =((unsigned long)(*(--(c))))<< 8; \ 602 case 2: l|=((unsigned long)(*(--(c))))<<16; \ 603 case 1: l|=((unsigned long)(*(--(c))))<<24; \ 604 } } 605 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ 606 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 607 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 608 *((c)++)=(unsigned char)(((l) )&0xff), \ 609 l) 610 611 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 612 613 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ 614 l|=(((unsigned long)(*((c)++)))<< 8), \ 615 l|=(((unsigned long)(*((c)++)))<<16), \ 616 l|=(((unsigned long)(*((c)++)))<<24), \ 617 l) 618 #define HOST_p_c2l(c,l,n) { \ 619 switch (n) { \ 620 case 0: l =((unsigned long)(*((c)++))); \ 621 case 1: l|=((unsigned long)(*((c)++)))<< 8; \ 622 case 2: l|=((unsigned long)(*((c)++)))<<16; \ 623 case 3: l|=((unsigned long)(*((c)++)))<<24; \ 624 } } 625 #define HOST_p_c2l_p(c,l,sc,len) { \ 626 switch (sc) { \ 627 case 0: l =((unsigned long)(*((c)++))); \ 628 if (--len == 0) break; \ 629 case 1: l|=((unsigned long)(*((c)++)))<< 8; \ 630 if (--len == 0) break; \ 631 case 2: l|=((unsigned long)(*((c)++)))<<16; \ 632 } } 633 /* NOTE the pointer is not incremented at the end of this */ 634 #define HOST_c2l_p(c,l,n) { \ 635 l=0; (c)+=n; \ 636 switch (n) { \ 637 case 3: l =((unsigned long)(*(--(c))))<<16; \ 638 case 2: l|=((unsigned long)(*(--(c))))<< 8; \ 639 case 1: l|=((unsigned long)(*(--(c)))); \ 640 } } 641 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 642 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 643 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 644 *((c)++)=(unsigned char)(((l)>>24)&0xff), \ 645 l) 646 647 #endif 648 649 /* 650 * Time for some action:-) 651 */ 652 653 int HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len) 654 { 655 const unsigned char *data=(const unsigned char *)data_; 656 register HASH_LONG * p; 657 register unsigned long l; 658 int sw,sc,ew,ec; 659 660 if (len==0) return 1; 661 662 l=(c->Nl+(len<<3))&0xffffffffL; 663 /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to 664 * Wei Dai <weidai (at) eskimo.com> for pointing it out. */ 665 if (l < c->Nl) /* overflow */ 666 c->Nh++; 667 c->Nh+=(len>>29); 668 c->Nl=l; 669 670 if (c->num != 0) 671 { 672 p=c->data; 673 sw=c->num>>2; 674 sc=c->num&0x03; 675 676 if ((c->num+len) >= HASH_CBLOCK) 677 { 678 l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; 679 for (; sw<HASH_LBLOCK; sw++) 680 { 681 HOST_c2l(data,l); p[sw]=l; 682 } 683 HASH_BLOCK_HOST_ORDER (c,p,1); 684 len-=(HASH_CBLOCK-c->num); 685 c->num=0; 686 /* drop through and do the rest */ 687 } 688 else 689 { 690 c->num+=len; 691 if ((sc+len) < 4) /* ugly, add char's to a word */ 692 { 693 l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l; 694 } 695 else 696 { 697 ew=(c->num>>2); 698 ec=(c->num&0x03); 699 if (sc) 700 l=p[sw]; 701 HOST_p_c2l(data,l,sc); 702 p[sw++]=l; 703 for (; sw < ew; sw++) 704 { 705 HOST_c2l(data,l); p[sw]=l; 706 } 707 if (ec) 708 { 709 HOST_c2l_p(data,l,ec); p[sw]=l; 710 } 711 } 712 return 1; 713 } 714 } 715 716 sw=(int)(len/HASH_CBLOCK); 717 if (sw > 0) 718 { 719 #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) 720 /* 721 * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined 722 * only if sizeof(HASH_LONG)==4. 723 */ 724 if ((((unsigned long)data)%4) == 0) 725 { 726 /* data is properly aligned so that we can cast it: */ 727 HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw); 728 sw*=HASH_CBLOCK; 729 data+=sw; 730 len-=sw; 731 } 732 else 733 #if !defined(HASH_BLOCK_DATA_ORDER) 734 while (sw--) 735 { 736 mDNSPlatformMemCopy(p=c->data,data,HASH_CBLOCK); 737 HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1); 738 data+=HASH_CBLOCK; 739 len-=HASH_CBLOCK; 740 } 741 #endif 742 #endif 743 #if defined(HASH_BLOCK_DATA_ORDER) 744 { 745 HASH_BLOCK_DATA_ORDER(c,data,sw); 746 sw*=HASH_CBLOCK; 747 data+=sw; 748 len-=sw; 749 } 750 #endif 751 } 752 753 if (len!=0) 754 { 755 p = c->data; 756 c->num = (int)len; 757 ew=(int)(len>>2); /* words to copy */ 758 ec=(int)(len&0x03); 759 for (; ew; ew--,p++) 760 { 761 HOST_c2l(data,l); *p=l; 762 } 763 HOST_c2l_p(data,l,ec); 764 *p=l; 765 } 766 return 1; 767 } 768 769 770 void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) 771 { 772 #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) 773 if ((((unsigned long)data)%4) == 0) 774 /* data is properly aligned so that we can cast it: */ 775 HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1); 776 else 777 #if !defined(HASH_BLOCK_DATA_ORDER) 778 { 779 mDNSPlatformMemCopy(c->data,data,HASH_CBLOCK); 780 HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1); 781 } 782 #endif 783 #endif 784 #if defined(HASH_BLOCK_DATA_ORDER) 785 HASH_BLOCK_DATA_ORDER (c,data,1); 786 #endif 787 } 788 789 790 int HASH_FINAL (unsigned char *md, HASH_CTX *c) 791 { 792 register HASH_LONG *p; 793 register unsigned long l; 794 register int i,j; 795 static const unsigned char end[4]={0x80,0x00,0x00,0x00}; 796 const unsigned char *cp=end; 797 798 /* c->num should definitly have room for at least one more byte. */ 799 p=c->data; 800 i=c->num>>2; 801 j=c->num&0x03; 802 803 #if 0 804 /* purify often complains about the following line as an 805 * Uninitialized Memory Read. While this can be true, the 806 * following p_c2l macro will reset l when that case is true. 807 * This is because j&0x03 contains the number of 'valid' bytes 808 * already in p[i]. If and only if j&0x03 == 0, the UMR will 809 * occur but this is also the only time p_c2l will do 810 * l= *(cp++) instead of l|= *(cp++) 811 * Many thanks to Alex Tang <altitude (at) cic.net> for pickup this 812 * 'potential bug' */ 813 #ifdef PURIFY 814 if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */ 815 #endif 816 l=p[i]; 817 #else 818 l = (j==0) ? 0 : p[i]; 819 #endif 820 HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */ 821 822 if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */ 823 { 824 if (i<HASH_LBLOCK) p[i]=0; 825 HASH_BLOCK_HOST_ORDER (c,p,1); 826 i=0; 827 } 828 for (; i<(HASH_LBLOCK-2); i++) 829 p[i]=0; 830 831 #if defined(DATA_ORDER_IS_BIG_ENDIAN) 832 p[HASH_LBLOCK-2]=c->Nh; 833 p[HASH_LBLOCK-1]=c->Nl; 834 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 835 p[HASH_LBLOCK-2]=c->Nl; 836 p[HASH_LBLOCK-1]=c->Nh; 837 #endif 838 HASH_BLOCK_HOST_ORDER (c,p,1); 839 840 #ifndef HASH_MAKE_STRING 841 #error "HASH_MAKE_STRING must be defined!" 842 #else 843 HASH_MAKE_STRING(c,md); 844 #endif 845 846 c->num=0; 847 /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack 848 * but I'm not worried :-) 849 OPENSSL_cleanse((void *)c,sizeof(HASH_CTX)); 850 */ 851 return 1; 852 } 853 854 #ifndef MD32_REG_T 855 #define MD32_REG_T long 856 /* 857 * This comment was originaly written for MD5, which is why it 858 * discusses A-D. But it basically applies to all 32-bit digests, 859 * which is why it was moved to common header file. 860 * 861 * In case you wonder why A-D are declared as long and not 862 * as mDNSu32. Doing so results in slight performance 863 * boost on LP64 architectures. The catch is we don't 864 * really care if 32 MSBs of a 64-bit register get polluted 865 * with eventual overflows as we *save* only 32 LSBs in 866 * *either* case. Now declaring 'em long excuses the compiler 867 * from keeping 32 MSBs zeroed resulting in 13% performance 868 * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. 869 * Well, to be honest it should say that this *prevents* 870 * performance degradation. 871 * <appro (at) fy.chalmers.se> 872 * Apparently there're LP64 compilers that generate better 873 * code if A-D are declared int. Most notably GCC-x86_64 874 * generates better code. 875 * <appro (at) fy.chalmers.se> 876 */ 877 #endif 878 879 880 // from md5_locl.h (continued) 881 882 /* 883 #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) 884 #define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) 885 */ 886 887 /* As pointed out by Wei Dai <weidai (at) eskimo.com>, the above can be 888 * simplified to the code below. Wei attributes these optimizations 889 * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. 890 */ 891 #define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) 892 #define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) 893 #define H(b,c,d) ((b) ^ (c) ^ (d)) 894 #define I(b,c,d) (((~(d)) | (b)) ^ (c)) 895 896 #define R0(a,b,c,d,k,s,t) { \ 897 a+=((k)+(t)+F((b),(c),(d))); \ 898 a=ROTATE(a,s); \ 899 a+=b; };\ 900 901 #define R1(a,b,c,d,k,s,t) { \ 902 a+=((k)+(t)+G((b),(c),(d))); \ 903 a=ROTATE(a,s); \ 904 a+=b; }; 905 906 #define R2(a,b,c,d,k,s,t) { \ 907 a+=((k)+(t)+H((b),(c),(d))); \ 908 a=ROTATE(a,s); \ 909 a+=b; }; 910 911 #define R3(a,b,c,d,k,s,t) { \ 912 a+=((k)+(t)+I((b),(c),(d))); \ 913 a=ROTATE(a,s); \ 914 a+=b; }; 915 916 // from md5_dgst.c 917 918 919 /* Implemented from RFC1321 The MD5 Message-Digest Algorithm 920 */ 921 922 #define INIT_DATA_A (unsigned long)0x67452301L 923 #define INIT_DATA_B (unsigned long)0xefcdab89L 924 #define INIT_DATA_C (unsigned long)0x98badcfeL 925 #define INIT_DATA_D (unsigned long)0x10325476L 926 927 int MD5_Init(MD5_CTX *c) 928 { 929 c->A=INIT_DATA_A; 930 c->B=INIT_DATA_B; 931 c->C=INIT_DATA_C; 932 c->D=INIT_DATA_D; 933 c->Nl=0; 934 c->Nh=0; 935 c->num=0; 936 return 1; 937 } 938 939 #ifndef md5_block_host_order 940 void md5_block_host_order (MD5_CTX *c, const void *data, int num) 941 { 942 const mDNSu32 *X=(const mDNSu32 *)data; 943 register unsigned MD32_REG_T A,B,C,D; 944 945 A=c->A; 946 B=c->B; 947 C=c->C; 948 D=c->D; 949 950 for (;num--;X+=HASH_LBLOCK) 951 { 952 /* Round 0 */ 953 R0(A,B,C,D,X[ 0], 7,0xd76aa478L); 954 R0(D,A,B,C,X[ 1],12,0xe8c7b756L); 955 R0(C,D,A,B,X[ 2],17,0x242070dbL); 956 R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); 957 R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); 958 R0(D,A,B,C,X[ 5],12,0x4787c62aL); 959 R0(C,D,A,B,X[ 6],17,0xa8304613L); 960 R0(B,C,D,A,X[ 7],22,0xfd469501L); 961 R0(A,B,C,D,X[ 8], 7,0x698098d8L); 962 R0(D,A,B,C,X[ 9],12,0x8b44f7afL); 963 R0(C,D,A,B,X[10],17,0xffff5bb1L); 964 R0(B,C,D,A,X[11],22,0x895cd7beL); 965 R0(A,B,C,D,X[12], 7,0x6b901122L); 966 R0(D,A,B,C,X[13],12,0xfd987193L); 967 R0(C,D,A,B,X[14],17,0xa679438eL); 968 R0(B,C,D,A,X[15],22,0x49b40821L); 969 /* Round 1 */ 970 R1(A,B,C,D,X[ 1], 5,0xf61e2562L); 971 R1(D,A,B,C,X[ 6], 9,0xc040b340L); 972 R1(C,D,A,B,X[11],14,0x265e5a51L); 973 R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL); 974 R1(A,B,C,D,X[ 5], 5,0xd62f105dL); 975 R1(D,A,B,C,X[10], 9,0x02441453L); 976 R1(C,D,A,B,X[15],14,0xd8a1e681L); 977 R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L); 978 R1(A,B,C,D,X[ 9], 5,0x21e1cde6L); 979 R1(D,A,B,C,X[14], 9,0xc33707d6L); 980 R1(C,D,A,B,X[ 3],14,0xf4d50d87L); 981 R1(B,C,D,A,X[ 8],20,0x455a14edL); 982 R1(A,B,C,D,X[13], 5,0xa9e3e905L); 983 R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L); 984 R1(C,D,A,B,X[ 7],14,0x676f02d9L); 985 R1(B,C,D,A,X[12],20,0x8d2a4c8aL); 986 /* Round 2 */ 987 R2(A,B,C,D,X[ 5], 4,0xfffa3942L); 988 R2(D,A,B,C,X[ 8],11,0x8771f681L); 989 R2(C,D,A,B,X[11],16,0x6d9d6122L); 990 R2(B,C,D,A,X[14],23,0xfde5380cL); 991 R2(A,B,C,D,X[ 1], 4,0xa4beea44L); 992 R2(D,A,B,C,X[ 4],11,0x4bdecfa9L); 993 R2(C,D,A,B,X[ 7],16,0xf6bb4b60L); 994 R2(B,C,D,A,X[10],23,0xbebfbc70L); 995 R2(A,B,C,D,X[13], 4,0x289b7ec6L); 996 R2(D,A,B,C,X[ 0],11,0xeaa127faL); 997 R2(C,D,A,B,X[ 3],16,0xd4ef3085L); 998 R2(B,C,D,A,X[ 6],23,0x04881d05L); 999 R2(A,B,C,D,X[ 9], 4,0xd9d4d039L); 1000 R2(D,A,B,C,X[12],11,0xe6db99e5L); 1001 R2(C,D,A,B,X[15],16,0x1fa27cf8L); 1002 R2(B,C,D,A,X[ 2],23,0xc4ac5665L); 1003 /* Round 3 */ 1004 R3(A,B,C,D,X[ 0], 6,0xf4292244L); 1005 R3(D,A,B,C,X[ 7],10,0x432aff97L); 1006 R3(C,D,A,B,X[14],15,0xab9423a7L); 1007 R3(B,C,D,A,X[ 5],21,0xfc93a039L); 1008 R3(A,B,C,D,X[12], 6,0x655b59c3L); 1009 R3(D,A,B,C,X[ 3],10,0x8f0ccc92L); 1010 R3(C,D,A,B,X[10],15,0xffeff47dL); 1011 R3(B,C,D,A,X[ 1],21,0x85845dd1L); 1012 R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL); 1013 R3(D,A,B,C,X[15],10,0xfe2ce6e0L); 1014 R3(C,D,A,B,X[ 6],15,0xa3014314L); 1015 R3(B,C,D,A,X[13],21,0x4e0811a1L); 1016 R3(A,B,C,D,X[ 4], 6,0xf7537e82L); 1017 R3(D,A,B,C,X[11],10,0xbd3af235L); 1018 R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); 1019 R3(B,C,D,A,X[ 9],21,0xeb86d391L); 1020 1021 A = c->A += A; 1022 B = c->B += B; 1023 C = c->C += C; 1024 D = c->D += D; 1025 } 1026 } 1027 #endif 1028 1029 #ifndef md5_block_data_order 1030 #ifdef X 1031 #undef X 1032 #endif 1033 void md5_block_data_order (MD5_CTX *c, const void *data_, int num) 1034 { 1035 const unsigned char *data=data_; 1036 register unsigned MD32_REG_T A,B,C,D,l; 1037 #ifndef MD32_XARRAY 1038 /* See comment in crypto/sha/sha_locl.h for details. */ 1039 unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, 1040 XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; 1041 # define X(i) XX##i 1042 #else 1043 mDNSu32 XX[MD5_LBLOCK]; 1044 # define X(i) XX[i] 1045 #endif 1046 1047 A=c->A; 1048 B=c->B; 1049 C=c->C; 1050 D=c->D; 1051 1052 for (;num--;) 1053 { 1054 HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l; 1055 /* Round 0 */ 1056 R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l; 1057 R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l; 1058 R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l; 1059 R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l; 1060 R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l; 1061 R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l; 1062 R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l; 1063 R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l; 1064 R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l; 1065 R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l; 1066 R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l; 1067 R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l; 1068 R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l; 1069 R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l; 1070 R0(C,D,A,B,X(14),17,0xa679438eL); 1071 R0(B,C,D,A,X(15),22,0x49b40821L); 1072 /* Round 1 */ 1073 R1(A,B,C,D,X( 1), 5,0xf61e2562L); 1074 R1(D,A,B,C,X( 6), 9,0xc040b340L); 1075 R1(C,D,A,B,X(11),14,0x265e5a51L); 1076 R1(B,C,D,A,X( 0),20,0xe9b6c7aaL); 1077 R1(A,B,C,D,X( 5), 5,0xd62f105dL); 1078 R1(D,A,B,C,X(10), 9,0x02441453L); 1079 R1(C,D,A,B,X(15),14,0xd8a1e681L); 1080 R1(B,C,D,A,X( 4),20,0xe7d3fbc8L); 1081 R1(A,B,C,D,X( 9), 5,0x21e1cde6L); 1082 R1(D,A,B,C,X(14), 9,0xc33707d6L); 1083 R1(C,D,A,B,X( 3),14,0xf4d50d87L); 1084 R1(B,C,D,A,X( 8),20,0x455a14edL); 1085 R1(A,B,C,D,X(13), 5,0xa9e3e905L); 1086 R1(D,A,B,C,X( 2), 9,0xfcefa3f8L); 1087 R1(C,D,A,B,X( 7),14,0x676f02d9L); 1088 R1(B,C,D,A,X(12),20,0x8d2a4c8aL); 1089 /* Round 2 */ 1090 R2(A,B,C,D,X( 5), 4,0xfffa3942L); 1091 R2(D,A,B,C,X( 8),11,0x8771f681L); 1092 R2(C,D,A,B,X(11),16,0x6d9d6122L); 1093 R2(B,C,D,A,X(14),23,0xfde5380cL); 1094 R2(A,B,C,D,X( 1), 4,0xa4beea44L); 1095 R2(D,A,B,C,X( 4),11,0x4bdecfa9L); 1096 R2(C,D,A,B,X( 7),16,0xf6bb4b60L); 1097 R2(B,C,D,A,X(10),23,0xbebfbc70L); 1098 R2(A,B,C,D,X(13), 4,0x289b7ec6L); 1099 R2(D,A,B,C,X( 0),11,0xeaa127faL); 1100 R2(C,D,A,B,X( 3),16,0xd4ef3085L); 1101 R2(B,C,D,A,X( 6),23,0x04881d05L); 1102 R2(A,B,C,D,X( 9), 4,0xd9d4d039L); 1103 R2(D,A,B,C,X(12),11,0xe6db99e5L); 1104 R2(C,D,A,B,X(15),16,0x1fa27cf8L); 1105 R2(B,C,D,A,X( 2),23,0xc4ac5665L); 1106 /* Round 3 */ 1107 R3(A,B,C,D,X( 0), 6,0xf4292244L); 1108 R3(D,A,B,C,X( 7),10,0x432aff97L); 1109 R3(C,D,A,B,X(14),15,0xab9423a7L); 1110 R3(B,C,D,A,X( 5),21,0xfc93a039L); 1111 R3(A,B,C,D,X(12), 6,0x655b59c3L); 1112 R3(D,A,B,C,X( 3),10,0x8f0ccc92L); 1113 R3(C,D,A,B,X(10),15,0xffeff47dL); 1114 R3(B,C,D,A,X( 1),21,0x85845dd1L); 1115 R3(A,B,C,D,X( 8), 6,0x6fa87e4fL); 1116 R3(D,A,B,C,X(15),10,0xfe2ce6e0L); 1117 R3(C,D,A,B,X( 6),15,0xa3014314L); 1118 R3(B,C,D,A,X(13),21,0x4e0811a1L); 1119 R3(A,B,C,D,X( 4), 6,0xf7537e82L); 1120 R3(D,A,B,C,X(11),10,0xbd3af235L); 1121 R3(C,D,A,B,X( 2),15,0x2ad7d2bbL); 1122 R3(B,C,D,A,X( 9),21,0xeb86d391L); 1123 1124 A = c->A += A; 1125 B = c->B += B; 1126 C = c->C += C; 1127 D = c->D += D; 1128 } 1129 } 1130 #endif 1131 1132 #endif // !HAVE_MD5 1133 1134 // *************************************************************************** 1135 #if COMPILER_LIKES_PRAGMA_MARK 1136 #pragma mark - base64 -> binary conversion 1137 #endif 1138 1139 static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 1140 static const char Pad64 = '='; 1141 1142 1143 #define mDNSisspace(x) (x == '\t' || x == '\n' || x == '\v' || x == '\f' || x == '\r' || x == ' ') 1144 1145 mDNSlocal const char *mDNSstrchr(const char *s, int c) 1146 { 1147 while (1) 1148 { 1149 if (c == *s) return s; 1150 if (!*s) return mDNSNULL; 1151 s++; 1152 } 1153 } 1154 1155 // skips all whitespace anywhere. 1156 // converts characters, four at a time, starting at (or after) 1157 // src from base - 64 numbers into three 8 bit bytes in the target area. 1158 // it returns the number of data bytes stored at the target, or -1 on error. 1159 // adapted from BIND sources 1160 1161 mDNSlocal mDNSs32 DNSDigest_Base64ToBin(const char *src, mDNSu8 *target, mDNSu32 targsize) 1162 { 1163 int tarindex, state, ch; 1164 const char *pos; 1165 1166 state = 0; 1167 tarindex = 0; 1168 1169 while ((ch = *src++) != '\0') { 1170 if (mDNSisspace(ch)) /* Skip whitespace anywhere. */ 1171 continue; 1172 1173 if (ch == Pad64) 1174 break; 1175 1176 pos = mDNSstrchr(Base64, ch); 1177 if (pos == 0) /* A non-base64 character. */ 1178 return (-1); 1179 1180 switch (state) { 1181 case 0: 1182 if (target) { 1183 if ((mDNSu32)tarindex >= targsize) 1184 return (-1); 1185 target[tarindex] = (mDNSu8)((pos - Base64) << 2); 1186 } 1187 state = 1; 1188 break; 1189 case 1: 1190 if (target) { 1191 if ((mDNSu32)tarindex + 1 >= targsize) 1192 return (-1); 1193 target[tarindex] |= (pos - Base64) >> 4; 1194 target[tarindex+1] = (mDNSu8)(((pos - Base64) & 0x0f) << 4); 1195 } 1196 tarindex++; 1197 state = 2; 1198 break; 1199 case 2: 1200 if (target) { 1201 if ((mDNSu32)tarindex + 1 >= targsize) 1202 return (-1); 1203 target[tarindex] |= (pos - Base64) >> 2; 1204 target[tarindex+1] = (mDNSu8)(((pos - Base64) & 0x03) << 6); 1205 } 1206 tarindex++; 1207 state = 3; 1208 break; 1209 case 3: 1210 if (target) { 1211 if ((mDNSu32)tarindex >= targsize) 1212 return (-1); 1213 target[tarindex] |= (pos - Base64); 1214 } 1215 tarindex++; 1216 state = 0; 1217 break; 1218 default: 1219 return -1; 1220 } 1221 } 1222 1223 /* 1224 * We are done decoding Base-64 chars. Let's see if we ended 1225 * on a byte boundary, and/or with erroneous trailing characters. 1226 */ 1227 1228 if (ch == Pad64) { /* We got a pad char. */ 1229 ch = *src++; /* Skip it, get next. */ 1230 switch (state) { 1231 case 0: /* Invalid = in first position */ 1232 case 1: /* Invalid = in second position */ 1233 return (-1); 1234 1235 case 2: /* Valid, means one byte of info */ 1236 /* Skip any number of spaces. */ 1237 for ((void)mDNSNULL; ch != '\0'; ch = *src++) 1238 if (!mDNSisspace(ch)) 1239 break; 1240 /* Make sure there is another trailing = sign. */ 1241 if (ch != Pad64) 1242 return (-1); 1243 ch = *src++; /* Skip the = */ 1244 /* Fall through to "single trailing =" case. */ 1245 /* FALLTHROUGH */ 1246 1247 case 3: /* Valid, means two bytes of info */ 1248 /* 1249 * We know this char is an =. Is there anything but 1250 * whitespace after it? 1251 */ 1252 for ((void)mDNSNULL; ch != '\0'; ch = *src++) 1253 if (!mDNSisspace(ch)) 1254 return (-1); 1255 1256 /* 1257 * Now make sure for cases 2 and 3 that the "extra" 1258 * bits that slopped past the last full byte were 1259 * zeros. If we don't check them, they become a 1260 * subliminal channel. 1261 */ 1262 if (target && target[tarindex] != 0) 1263 return (-1); 1264 } 1265 } else { 1266 /* 1267 * We ended by seeing the end of the string. Make sure we 1268 * have no partial bytes lying around. 1269 */ 1270 if (state != 0) 1271 return (-1); 1272 } 1273 1274 return (tarindex); 1275 } 1276 1277 1278 // *************************************************************************** 1279 #if COMPILER_LIKES_PRAGMA_MARK 1280 #pragma mark - API exported to mDNS Core 1281 #endif 1282 1283 // Constants 1284 #define HMAC_IPAD 0x36 1285 #define HMAC_OPAD 0x5c 1286 #define MD5_LEN 16 1287 1288 #define HMAC_MD5_AlgName (*(const domainname*) "\010" "hmac-md5" "\007" "sig-alg" "\003" "reg" "\003" "int") 1289 1290 // Adapted from Appendix, RFC 2104 1291 mDNSlocal void DNSDigest_ConstructHMACKey(DomainAuthInfo *info, const mDNSu8 *key, mDNSu32 len) 1292 { 1293 MD5_CTX k; 1294 mDNSu8 buf[MD5_LEN]; 1295 int i; 1296 1297 // If key is longer than HMAC_LEN reset it to MD5(key) 1298 if (len > HMAC_LEN) 1299 { 1300 MD5_Init(&k); 1301 MD5_Update(&k, key, len); 1302 MD5_Final(buf, &k); 1303 key = buf; 1304 len = MD5_LEN; 1305 } 1306 1307 // store key in pads 1308 mDNSPlatformMemZero(info->keydata_ipad, HMAC_LEN); 1309 mDNSPlatformMemZero(info->keydata_opad, HMAC_LEN); 1310 mDNSPlatformMemCopy(info->keydata_ipad, key, len); 1311 mDNSPlatformMemCopy(info->keydata_opad, key, len); 1312 1313 // XOR key with ipad and opad values 1314 for (i = 0; i < HMAC_LEN; i++) 1315 { 1316 info->keydata_ipad[i] ^= HMAC_IPAD; 1317 info->keydata_opad[i] ^= HMAC_OPAD; 1318 } 1319 1320 } 1321 1322 mDNSexport mDNSs32 DNSDigest_ConstructHMACKeyfromBase64(DomainAuthInfo *info, const char *b64key) 1323 { 1324 mDNSu8 keybuf[1024]; 1325 mDNSs32 keylen = DNSDigest_Base64ToBin(b64key, keybuf, sizeof(keybuf)); 1326 if (keylen < 0) return(keylen); 1327 DNSDigest_ConstructHMACKey(info, keybuf, (mDNSu32)keylen); 1328 return(keylen); 1329 } 1330 1331 mDNSexport void DNSDigest_SignMessage(DNSMessage *msg, mDNSu8 **end, DomainAuthInfo *info, mDNSu16 tcode) 1332 { 1333 AuthRecord tsig; 1334 mDNSu8 *rdata, *const countPtr = (mDNSu8 *)&msg->h.numAdditionals; // Get existing numAdditionals value 1335 mDNSu32 utc32; 1336 mDNSu8 utc48[6]; 1337 mDNSu8 digest[MD5_LEN]; 1338 mDNSu8 *ptr = *end; 1339 mDNSu32 len; 1340 mDNSOpaque16 buf; 1341 MD5_CTX c; 1342 mDNSu16 numAdditionals = (mDNSu16)((mDNSu16)countPtr[0] << 8 | countPtr[1]); 1343 1344 // Init MD5 context, digest inner key pad and message 1345 MD5_Init(&c); 1346 MD5_Update(&c, info->keydata_ipad, HMAC_LEN); 1347 MD5_Update(&c, (mDNSu8 *)msg, (unsigned long)(*end - (mDNSu8 *)msg)); 1348 1349 // Construct TSIG RR, digesting variables as apporpriate 1350 mDNS_SetupResourceRecord(&tsig, mDNSNULL, 0, kDNSType_TSIG, 0, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL); 1351 1352 // key name 1353 AssignDomainName(&tsig.namestorage, &info->keyname); 1354 MD5_Update(&c, info->keyname.c, DomainNameLength(&info->keyname)); 1355 1356 // class 1357 tsig.resrec.rrclass = kDNSQClass_ANY; 1358 buf = mDNSOpaque16fromIntVal(kDNSQClass_ANY); 1359 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); 1360 1361 // ttl 1362 tsig.resrec.rroriginalttl = 0; 1363 MD5_Update(&c, (mDNSu8 *)&tsig.resrec.rroriginalttl, sizeof(tsig.resrec.rroriginalttl)); 1364 1365 // alg name 1366 AssignDomainName(&tsig.resrec.rdata->u.name, &HMAC_MD5_AlgName); 1367 len = DomainNameLength(&HMAC_MD5_AlgName); 1368 rdata = tsig.resrec.rdata->u.data + len; 1369 MD5_Update(&c, HMAC_MD5_AlgName.c, len); 1370 1371 // time 1372 // get UTC (universal time), convert to 48-bit unsigned in network byte order 1373 utc32 = (mDNSu32)mDNSPlatformUTC(); 1374 if (utc32 == (unsigned)-1) { LogMsg("ERROR: DNSDigest_SignMessage - mDNSPlatformUTC returned bad time -1"); *end = mDNSNULL; } 1375 utc48[0] = 0; 1376 utc48[1] = 0; 1377 utc48[2] = (mDNSu8)((utc32 >> 24) & 0xff); 1378 utc48[3] = (mDNSu8)((utc32 >> 16) & 0xff); 1379 utc48[4] = (mDNSu8)((utc32 >> 8) & 0xff); 1380 utc48[5] = (mDNSu8)( utc32 & 0xff); 1381 1382 mDNSPlatformMemCopy(rdata, utc48, 6); 1383 rdata += 6; 1384 MD5_Update(&c, utc48, 6); 1385 1386 // 300 sec is fudge recommended in RFC 2485 1387 rdata[0] = (mDNSu8)((300 >> 8) & 0xff); 1388 rdata[1] = (mDNSu8)( 300 & 0xff); 1389 MD5_Update(&c, rdata, sizeof(mDNSOpaque16)); 1390 rdata += sizeof(mDNSOpaque16); 1391 1392 // digest error (tcode) and other data len (zero) - we'll add them to the rdata later 1393 buf.b[0] = (mDNSu8)((tcode >> 8) & 0xff); 1394 buf.b[1] = (mDNSu8)( tcode & 0xff); 1395 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); // error 1396 buf.NotAnInteger = 0; 1397 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); // other data len 1398 1399 // finish the message & tsig var hash 1400 MD5_Final(digest, &c); 1401 1402 // perform outer MD5 (outer key pad, inner digest) 1403 MD5_Init(&c); 1404 MD5_Update(&c, info->keydata_opad, HMAC_LEN); 1405 MD5_Update(&c, digest, MD5_LEN); 1406 MD5_Final(digest, &c); 1407 1408 // set remaining rdata fields 1409 rdata[0] = (mDNSu8)((MD5_LEN >> 8) & 0xff); 1410 rdata[1] = (mDNSu8)( MD5_LEN & 0xff); 1411 rdata += sizeof(mDNSOpaque16); 1412 mDNSPlatformMemCopy(rdata, digest, MD5_LEN); // MAC 1413 rdata += MD5_LEN; 1414 rdata[0] = msg->h.id.b[0]; // original ID 1415 rdata[1] = msg->h.id.b[1]; 1416 rdata[2] = (mDNSu8)((tcode >> 8) & 0xff); 1417 rdata[3] = (mDNSu8)( tcode & 0xff); 1418 rdata[4] = 0; // other data len 1419 rdata[5] = 0; 1420 rdata += 6; 1421 1422 tsig.resrec.rdlength = (mDNSu16)(rdata - tsig.resrec.rdata->u.data); 1423 *end = PutResourceRecordTTLJumbo(msg, ptr, &numAdditionals, &tsig.resrec, 0); 1424 if (!*end) { LogMsg("ERROR: DNSDigest_SignMessage - could not put TSIG"); *end = mDNSNULL; return; } 1425 1426 // Write back updated numAdditionals value 1427 countPtr[0] = (mDNSu8)(numAdditionals >> 8); 1428 countPtr[1] = (mDNSu8)(numAdditionals & 0xFF); 1429 } 1430 1431 mDNSexport mDNSBool DNSDigest_VerifyMessage(DNSMessage *msg, mDNSu8 *end, LargeCacheRecord * lcr, DomainAuthInfo *info, mDNSu16 * rcode, mDNSu16 * tcode) 1432 { 1433 mDNSu8 * ptr = (mDNSu8*) &lcr->r.resrec.rdata->u.data; 1434 mDNSs32 now; 1435 mDNSs32 then; 1436 mDNSu8 thisDigest[MD5_LEN]; 1437 mDNSu8 thatDigest[MD5_LEN]; 1438 mDNSu32 macsize; 1439 mDNSOpaque16 buf; 1440 mDNSu8 utc48[6]; 1441 mDNSs32 delta; 1442 mDNSu16 fudge; 1443 domainname * algo; 1444 MD5_CTX c; 1445 mDNSBool ok = mDNSfalse; 1446 1447 // We only support HMAC-MD5 for now 1448 1449 algo = (domainname*) ptr; 1450 1451 if (!SameDomainName(algo, &HMAC_MD5_AlgName)) 1452 { 1453 LogMsg("ERROR: DNSDigest_VerifyMessage - TSIG algorithm not supported: %##s", algo->c); 1454 *rcode = kDNSFlag1_RC_NotAuth; 1455 *tcode = TSIG_ErrBadKey; 1456 ok = mDNSfalse; 1457 goto exit; 1458 } 1459 1460 ptr += DomainNameLength(algo); 1461 1462 // Check the times 1463 1464 now = mDNSPlatformUTC(); 1465 if (now == -1) 1466 { 1467 LogMsg("ERROR: DNSDigest_VerifyMessage - mDNSPlatformUTC returned bad time -1"); 1468 *rcode = kDNSFlag1_RC_NotAuth; 1469 *tcode = TSIG_ErrBadTime; 1470 ok = mDNSfalse; 1471 goto exit; 1472 } 1473 1474 // Get the 48 bit time field, skipping over the first word 1475 1476 utc48[0] = *ptr++; 1477 utc48[1] = *ptr++; 1478 utc48[2] = *ptr++; 1479 utc48[3] = *ptr++; 1480 utc48[4] = *ptr++; 1481 utc48[5] = *ptr++; 1482 1483 then = (mDNSs32)NToH32(utc48 + sizeof(mDNSu16)); 1484 1485 fudge = NToH16(ptr); 1486 1487 ptr += sizeof(mDNSu16); 1488 1489 delta = (now > then) ? now - then : then - now; 1490 1491 if (delta > fudge) 1492 { 1493 LogMsg("ERROR: DNSDigest_VerifyMessage - time skew > %d", fudge); 1494 *rcode = kDNSFlag1_RC_NotAuth; 1495 *tcode = TSIG_ErrBadTime; 1496 ok = mDNSfalse; 1497 goto exit; 1498 } 1499 1500 // MAC size 1501 1502 macsize = (mDNSu32) NToH16(ptr); 1503 1504 ptr += sizeof(mDNSu16); 1505 1506 // MAC 1507 1508 mDNSPlatformMemCopy(thatDigest, ptr, MD5_LEN); 1509 1510 // Init MD5 context, digest inner key pad and message 1511 1512 MD5_Init(&c); 1513 MD5_Update(&c, info->keydata_ipad, HMAC_LEN); 1514 MD5_Update(&c, (mDNSu8*) msg, (unsigned long)(end - (mDNSu8*) msg)); 1515 1516 // Key name 1517 1518 MD5_Update(&c, lcr->r.resrec.name->c, DomainNameLength(lcr->r.resrec.name)); 1519 1520 // Class name 1521 1522 buf = mDNSOpaque16fromIntVal(lcr->r.resrec.rrclass); 1523 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); 1524 1525 // TTL 1526 1527 MD5_Update(&c, (mDNSu8*) &lcr->r.resrec.rroriginalttl, sizeof(lcr->r.resrec.rroriginalttl)); 1528 1529 // Algorithm 1530 1531 MD5_Update(&c, algo->c, DomainNameLength(algo)); 1532 1533 // Time 1534 1535 MD5_Update(&c, utc48, 6); 1536 1537 // Fudge 1538 1539 buf = mDNSOpaque16fromIntVal(fudge); 1540 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); 1541 1542 // Digest error and other data len (both zero) - we'll add them to the rdata later 1543 1544 buf.NotAnInteger = 0; 1545 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); // error 1546 MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); // other data len 1547 1548 // Finish the message & tsig var hash 1549 1550 MD5_Final(thisDigest, &c); 1551 1552 // perform outer MD5 (outer key pad, inner digest) 1553 1554 MD5_Init(&c); 1555 MD5_Update(&c, info->keydata_opad, HMAC_LEN); 1556 MD5_Update(&c, thisDigest, MD5_LEN); 1557 MD5_Final(thisDigest, &c); 1558 1559 if (!mDNSPlatformMemSame(thisDigest, thatDigest, MD5_LEN)) 1560 { 1561 LogMsg("ERROR: DNSDigest_VerifyMessage - bad signature"); 1562 *rcode = kDNSFlag1_RC_NotAuth; 1563 *tcode = TSIG_ErrBadSig; 1564 ok = mDNSfalse; 1565 goto exit; 1566 } 1567 1568 // set remaining rdata fields 1569 ok = mDNStrue; 1570 1571 exit: 1572 1573 return ok; 1574 } 1575 1576 1577 #ifdef __cplusplus 1578 } 1579 #endif 1580