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