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