1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 Change History (most recent first):
20 Revision 1.23 2007/09/21 21:12:36 cheshire
21 DNSDigest_SignMessage does not need separate "mDNSu16 *numAdditionals" parameter
23 Revision 1.22 2007/04/22 06:02:02 cheshire
24 <rdar://problem/4615977> Query should immediately return failure when no server
26 Revision 1.21 2007/03/22 18:31:48 cheshire
27 Put dst parameter first in mDNSPlatformStrCopy/mDNSPlatformMemCopy, like conventional Posix strcpy/memcpy
29 Revision 1.20 2006/12/22 20:59:49 cheshire
30 <rdar://problem/4742742> Read *all* DNS keys from keychain,
31 not just key for the system-wide default registration domain
33 Revision 1.19 2006/12/21 00:06:07 cheshire
34 Don't need to do mDNSPlatformMemZero() -- mDNS_SetupResourceRecord() does it for us
36 Revision 1.18 2006/12/19 22:41:21 cheshire
39 Revision 1.17 2006/08/14 23:24:22 cheshire
40 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
42 Revision 1.16 2006/07/05 23:05:15 cheshire
43 <rdar://problem/4472013> Add Private DNS server functionality to dnsextd
44 Add DNSDigest_VerifyMessage() function
46 Revision 1.15 2006/06/20 04:12:30 cheshire
47 <rdar://problem/4490961> DNS Update broken
49 Revision 1.14 2006/02/25 23:12:07 cheshire
50 <rdar://problem/4427969> Fix to avoid code generation warning/error on FreeBSD 7
52 Revision 1.13 2004/12/16 20:12:59 cheshire
53 <rdar://problem/3324626> Cache memory management improvements
55 Revision 1.12 2004/12/03 07:20:50 ksekar
56 <rdar://problem/3674208> Wide-Area: Registration of large TXT record fails
58 Revision 1.11 2004/12/02 01:10:27 cheshire
59 Fix to compile cleanly on 64-bit x86
61 Revision 1.10 2004/11/01 20:36:04 ksekar
62 <rdar://problem/3802395> mDNSResponder should not receive Keychain Notifications
64 Revision 1.9 2004/10/26 09:00:12 cheshire
65 Save a few bytes by creating HMAC_MD5_AlgName as a C string instead of a 256-byte object
67 Revision 1.8 2004/09/17 01:08:48 cheshire
68 Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
69 The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
70 declared in that file are ONLY appropriate to single-address-space embedded applications.
71 For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
73 Revision 1.7 2004/08/15 18:36:38 cheshire
74 Don't use strcpy() and strlen() on "struct domainname" objects;
75 use AssignDomainName() and DomainNameLength() instead
76 (A "struct domainname" is a collection of packed pascal strings, not a C string.)
78 Revision 1.6 2004/06/02 00:17:46 ksekar
79 Referenced original OpenSSL license headers in source file description.
81 Revision 1.5 2004/05/20 18:37:37 cheshire
84 Revision 1.4 2004/04/22 20:28:20 cheshire
85 Use existing facility of PutResourceRecordTTL() to update count field for us
87 Revision 1.3 2004/04/22 03:05:28 cheshire
88 kDNSClass_ANY should be kDNSQClass_ANY
90 Revision 1.2 2004/04/15 00:51:28 bradley
91 Minor tweaks for Windows and C++ builds. Added casts for signed/unsigned integers and 64-bit pointers.
92 Prefix some functions with mDNS to avoid conflicts. Disable benign warnings on Microsoft compilers.
94 Revision 1.1 2004/04/14 23:09:28 ksekar
95 Support for TSIG signed dynamic updates.
106 #include "mDNSEmbeddedAPI.h"
107 #include "DNSCommon.h"
109 // Disable certain benign warnings with Microsoft compilers
110 #if(defined(_MSC_VER))
111 // Disable "conditional expression is constant" warning for debug macros.
112 // Otherwise, this generates warnings for the perfectly natural construct "while(1)"
113 // If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know
114 #pragma warning(disable:4127)
118 // ***************************************************************************
119 #if COMPILER_LIKES_PRAGMA_MARK
120 #pragma mark - Byte Swapping Functions
123 mDNSlocal mDNSu16
NToH16(mDNSu8
* bytes
)
125 return (mDNSu16
)((mDNSu16
)bytes
[0] << 8 | (mDNSu16
)bytes
[1]);
128 mDNSlocal mDNSu32
NToH32(mDNSu8
* bytes
)
130 return (mDNSu32
)((mDNSu32
) bytes
[0] << 24 | (mDNSu32
) bytes
[1] << 16 | (mDNSu32
) bytes
[2] << 8 | (mDNSu32
)bytes
[3]);
133 // ***************************************************************************
134 #if COMPILER_LIKES_PRAGMA_MARK
135 #pragma mark - MD5 Hash Functions
139 /* The source for the has is derived CommonCrypto files CommonDigest.h, md32_common.h, md5_locl.h, md5_locl.h, and openssl/md5.h.
140 * The following changes have been made to the original sources:
141 * replaced CC_LONG w/ mDNSu32
142 * replaced CC_MD5* with MD5*
143 * replaced CC_LONG w/ mDNSu32, removed conditional #defines from md5.h
144 * removed extern decls for MD5_Init/Update/Final from CommonDigest.h
145 * removed APPLE_COMMON_DIGEST specific #defines from md5_locl.h
147 * Note: machine archetecure specific conditionals from the original sources are turned off, but are left in the code
148 * to aid in platform-specific optimizations and debugging.
149 * Sources originally distributed under the following license headers:
150 * CommonDigest.c - APSL
153 * ====================================================================
154 * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
156 * Redistribution and use in source and binary forms, with or without
157 * modification, are permitted provided that the following conditions
160 * 1. Redistributions of source code must retain the above copyright
161 * notice, this list of conditions and the following disclaimer.
163 * 2. Redistributions in binary form must reproduce the above copyright
164 * notice, this list of conditions and the following disclaimer in
165 * the documentation and/or other materials provided with the
168 * 3. All advertising materials mentioning features or use of this
169 * software must display the following acknowledgment:
170 * "This product includes software developed by the OpenSSL Project
171 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
173 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
174 * endorse or promote products derived from this software without
175 * prior written permission. For written permission, please contact
176 * licensing@OpenSSL.org.
178 * 5. Products derived from this software may not be called "OpenSSL"
179 * nor may "OpenSSL" appear in their names without prior written
180 * permission of the OpenSSL Project.
182 * 6. Redistributions of any form whatsoever must retain the following
184 * "This product includes software developed by the OpenSSL Project
185 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
187 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
188 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
189 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
190 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
191 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
192 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
193 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
194 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
195 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
196 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
197 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
198 * OF THE POSSIBILITY OF SUCH DAMAGE.
201 * md5_dgst.c, md5_locl.h
202 * ====================================================================
204 * This product includes cryptographic software written by Eric Young
205 * (eay@cryptsoft.com). This product includes software written by Tim
206 * Hudson (tjh@cryptsoft.com).
208 * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
209 * All rights reserved.
211 * This package is an SSL implementation written
212 * by Eric Young (eay@cryptsoft.com).
213 * The implementation was written so as to conform with Netscapes SSL.
215 * This library is free for commercial and non-commercial use as long as
216 * the following conditions are aheared to. The following conditions
217 * apply to all code found in this distribution, be it the RC4, RSA,
218 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
219 * included with this distribution is covered by the same copyright terms
220 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
222 * Copyright remains Eric Young's, and as such any Copyright notices in
223 * the code are not to be removed.
224 * If this package is used in a product, Eric Young should be given attribution
225 * as the author of the parts of the library used.
226 * This can be in the form of a textual message at program startup or
227 * in documentation (online or textual) provided with the package.
229 * Redistribution and use in source and binary forms, with or without
230 * modification, are permitted provided that the following conditions
232 * 1. Redistributions of source code must retain the copyright
233 * notice, this list of conditions and the following disclaimer.
234 * 2. Redistributions in binary form must reproduce the above copyright
235 * notice, this list of conditions and the following disclaimer in the
236 * documentation and/or other materials provided with the distribution.
237 * 3. All advertising materials mentioning features or use of this software
238 * must display the following acknowledgement:
239 * "This product includes cryptographic software written by
240 * Eric Young (eay@cryptsoft.com)"
241 * The word 'cryptographic' can be left out if the rouines from the library
242 * being used are not cryptographic related :-).
243 * 4. If you include any Windows specific code (or a derivative thereof) from
244 * the apps directory (application code) you must include an acknowledgement:
245 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
247 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
248 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
249 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
250 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
251 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
252 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
253 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
254 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
255 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
259 * The licence and distribution terms for any publically available version or
260 * derivative of this code cannot be changed. i.e. this code cannot simply be
261 * copied and put under another distribution licence
262 * [including the GNU Public Licence.]
266 //from CommonDigest.h
268 #define MD5_DIGEST_LENGTH 16 /* digest length in bytes */
269 #define MD5_BLOCK_BYTES 64 /* block size in bytes */
270 #define MD5_BLOCK_LONG (MD5_BLOCK_BYTES / sizeof(mDNSu32))
272 typedef struct MD5state_st
276 mDNSu32 data
[MD5_BLOCK_LONG
];
281 // from openssl/md5.h
283 #define MD5_CBLOCK 64
284 #define MD5_LBLOCK (MD5_CBLOCK/4)
285 #define MD5_DIGEST_LENGTH 16
287 int MD5_Init(MD5_CTX
*c
);
288 int MD5_Update(MD5_CTX
*c
, const void *data
, unsigned long len
);
289 int MD5_Final(unsigned char *md
, MD5_CTX
*c
);
290 void MD5_Transform(MD5_CTX
*c
, const unsigned char *b
);
294 #ifndef MD5_LONG_LOG2
295 #define MD5_LONG_LOG2 2 /* default to 32 bits */
299 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
300 # define md5_block_host_order md5_block_asm_host_order
301 # elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
302 void md5_block_asm_data_order_aligned (MD5_CTX
*c
, const mDNSu32
*p
,int num
);
303 # define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned
307 void md5_block_host_order (MD5_CTX
*c
, const void *p
,int num
);
308 void md5_block_data_order (MD5_CTX
*c
, const void *p
,int num
);
310 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
312 * *_block_host_order is expected to handle aligned data while
313 * *_block_data_order - unaligned. As algorithm and host (x86)
314 * are in this case of the same "endianness" these two are
315 * otherwise indistinguishable. But normally you don't want to
316 * call the same function because unaligned access in places
317 * where alignment is expected is usually a "Bad Thing". Indeed,
318 * on RISCs you get punished with BUS ERROR signal or *severe*
319 * performance degradation. Intel CPUs are in turn perfectly
320 * capable of loading unaligned data without such drastic side
321 * effect. Yes, they say it's slower than aligned load, but no
322 * exception is generated and therefore performance degradation
323 * is *incomparable* with RISCs. What we should weight here is
324 * costs of unaligned access against costs of aligning data.
325 * According to my measurements allowing unaligned access results
326 * in ~9% performance improvement on Pentium II operating at
327 * 266MHz. I won't be surprised if the difference will be higher
328 * on faster systems:-)
330 * <appro@fy.chalmers.se>
332 #define md5_block_data_order md5_block_host_order
335 #define DATA_ORDER_IS_LITTLE_ENDIAN
337 #define HASH_LONG mDNSu32
338 #define HASH_LONG_LOG2 MD5_LONG_LOG2
339 #define HASH_CTX MD5_CTX
340 #define HASH_CBLOCK MD5_CBLOCK
341 #define HASH_LBLOCK MD5_LBLOCK
343 #define HASH_UPDATE MD5_Update
344 #define HASH_TRANSFORM MD5_Transform
345 #define HASH_FINAL MD5_Final
347 #define HASH_MAKE_STRING(c,s) do { \
349 ll=(c)->A; HOST_l2c(ll,(s)); \
350 ll=(c)->B; HOST_l2c(ll,(s)); \
351 ll=(c)->C; HOST_l2c(ll,(s)); \
352 ll=(c)->D; HOST_l2c(ll,(s)); \
354 #define HASH_BLOCK_HOST_ORDER md5_block_host_order
355 #if !defined(L_ENDIAN) || defined(md5_block_data_order)
356 #define HASH_BLOCK_DATA_ORDER md5_block_data_order
358 * Little-endians (Intel and Alpha) feel better without this.
359 * It looks like memcpy does better job than generic
360 * md5_block_data_order on copying-n-aligning input data.
361 * But frankly speaking I didn't expect such result on Alpha.
362 * On the other hand I've got this with egcs-1.0.2 and if
363 * program is compiled with another (better?) compiler it
364 * might turn out other way around.
366 * <appro@fy.chalmers.se>
371 // from md32_common.h
374 * This is a generic 32 bit "collector" for message digest algorithms.
375 * Whenever needed it collects input character stream into chunks of
376 * 32 bit values and invokes a block function that performs actual hash
383 * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
384 * this macro defines byte order of input stream.
386 * size of a unit chunk HASH_BLOCK operates on.
388 * has to be at lest 32 bit wide, if it's wider, then
389 * HASH_LONG_LOG2 *has to* be defined along
391 * context structure that at least contains following
396 * HASH_LONG data[HASH_LBLOCK];
401 * name of "Update" function, implemented here.
403 * name of "Transform" function, implemented here.
405 * name of "Final" function, implemented here.
406 * HASH_BLOCK_HOST_ORDER
407 * name of "block" function treating *aligned* input message
408 * in host byte order, implemented externally.
409 * HASH_BLOCK_DATA_ORDER
410 * name of "block" function treating *unaligned* input message
411 * in original (data) byte order, implemented externally (it
412 * actually is optional if data and host are of the same
415 * macro convering context variables to an ASCII hash string.
419 * B_ENDIAN or L_ENDIAN
420 * defines host byte-order.
422 * defaults to 2 if not states otherwise.
424 * assumed to be HASH_CBLOCK/4 if not stated otherwise.
425 * HASH_BLOCK_DATA_ORDER_ALIGNED
426 * alternative "block" function capable of treating
427 * aligned input message in original (data) order,
428 * implemented externally.
432 * #define DATA_ORDER_IS_LITTLE_ENDIAN
434 * #define HASH_LONG mDNSu32
435 * #define HASH_LONG_LOG2 mDNSu32_LOG2
436 * #define HASH_CTX MD5_CTX
437 * #define HASH_CBLOCK MD5_CBLOCK
438 * #define HASH_LBLOCK MD5_LBLOCK
439 * #define HASH_UPDATE MD5_Update
440 * #define HASH_TRANSFORM MD5_Transform
441 * #define HASH_FINAL MD5_Final
442 * #define HASH_BLOCK_HOST_ORDER md5_block_host_order
443 * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
445 * <appro@fy.chalmers.se>
448 #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
449 #error "DATA_ORDER must be defined!"
453 #error "HASH_CBLOCK must be defined!"
456 #error "HASH_LONG must be defined!"
459 #error "HASH_CTX must be defined!"
463 #error "HASH_UPDATE must be defined!"
465 #ifndef HASH_TRANSFORM
466 #error "HASH_TRANSFORM must be defined!"
469 #error "HASH_FINAL must be defined!"
472 #ifndef HASH_BLOCK_HOST_ORDER
473 #error "HASH_BLOCK_HOST_ORDER must be defined!"
478 * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
481 #ifndef HASH_BLOCK_DATA_ORDER
482 #error "HASH_BLOCK_DATA_ORDER must be defined!"
487 #define HASH_LBLOCK (HASH_CBLOCK/4)
490 #ifndef HASH_LONG_LOG2
491 #define HASH_LONG_LOG2 2
495 * Engage compiler specific rotate intrinsic function if available.
499 # if 0 /* defined(_MSC_VER) */
500 # define ROTATE(a,n) _lrotl(a,n)
501 # elif defined(__MWERKS__)
502 # if defined(__POWERPC__)
503 # define ROTATE(a,n) (unsigned MD32_REG_T)__rlwinm((int)a,n,0,31)
504 # elif defined(__MC68K__)
505 /* Motorola specific tweak. <appro@fy.chalmers.se> */
506 # define ROTATE(a,n) (n<24 ? __rol(a,n) : __ror(a,32-n))
508 # define ROTATE(a,n) __rol(a,n)
510 # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
512 * Some GNU C inline assembler templates. Note that these are
513 * rotates by *constant* number of bits! But that's exactly
514 * what we need here...
516 * <appro@fy.chalmers.se>
518 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
519 # define ROTATE(a,n) ({ register unsigned int ret; \
527 # elif defined(__powerpc) || defined(__ppc)
528 # define ROTATE(a,n) ({ register unsigned int ret; \
530 "rlwinm %0,%1,%2,0,31" \
539 * Engage compiler specific "fetch in reverse byte order"
540 * intrinsic function if available.
542 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
543 /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
544 # if (defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)) && !defined(I386_ONLY)
545 # define BE_FETCH32(a) ({ register unsigned int l=(a);\
548 : "=r"(l) : "0"(l)); \
551 # elif defined(__powerpc)
552 # define LE_FETCH32(a) ({ register unsigned int l; \
560 # elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
561 # define LE_FETCH32(a) ({ register unsigned int l; \
563 "lda [%1]#ASI_PRIMARY_LITTLE,%0"\
570 #endif /* PEDANTIC */
572 #if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */
573 /* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
575 /* 5 instructions with rotate instruction, else 9 */
576 #define REVERSE_FETCH32(a,l) ( \
577 l=*(const HASH_LONG *)(a), \
578 ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \
581 /* 6 instructions with rotate instruction, else 8 */
582 #define REVERSE_FETCH32(a,l) ( \
583 l=*(const HASH_LONG *)(a), \
584 l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \
588 * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
589 * It's rewritten as above for two reasons:
590 * - RISCs aren't good at long constants and have to explicitely
591 * compose 'em with several (well, usually 2) instructions in a
592 * register before performing the actual operation and (as you
593 * already realized:-) having same constant should inspire the
594 * compiler to permanently allocate the only register for it;
595 * - most modern CPUs have two ALUs, but usually only one has
596 * circuitry for shifts:-( this minor tweak inspires compiler
597 * to schedule shift instructions in a better way...
599 * <appro@fy.chalmers.se>
605 #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
609 * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
610 * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
611 * and host are of the same "endianess". It's possible to mask
612 * this with blank #define HASH_BLOCK_DATA_ORDER though...
614 * <appro@fy.chalmers.se>
616 #if defined(B_ENDIAN)
617 # if defined(DATA_ORDER_IS_BIG_ENDIAN)
618 # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
619 # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
621 # elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
622 # ifndef HOST_FETCH32
624 # define HOST_FETCH32(p,l) LE_FETCH32(p)
625 # elif defined(REVERSE_FETCH32)
626 # define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
630 #elif defined(L_ENDIAN)
631 # if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
632 # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
633 # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
635 # elif defined(DATA_ORDER_IS_BIG_ENDIAN)
636 # ifndef HOST_FETCH32
638 # define HOST_FETCH32(p,l) BE_FETCH32(p)
639 # elif defined(REVERSE_FETCH32)
640 # define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
646 #if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
647 #ifndef HASH_BLOCK_DATA_ORDER
648 #error "HASH_BLOCK_DATA_ORDER must be defined!"
652 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
654 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
655 l|=(((unsigned long)(*((c)++)))<<16), \
656 l|=(((unsigned long)(*((c)++)))<< 8), \
657 l|=(((unsigned long)(*((c)++))) ), \
659 #define HOST_p_c2l(c,l,n) { \
661 case 0: l =((unsigned long)(*((c)++)))<<24; \
662 case 1: l|=((unsigned long)(*((c)++)))<<16; \
663 case 2: l|=((unsigned long)(*((c)++)))<< 8; \
664 case 3: l|=((unsigned long)(*((c)++))); \
666 #define HOST_p_c2l_p(c,l,sc,len) { \
668 case 0: l =((unsigned long)(*((c)++)))<<24; \
669 if (--len == 0) break; \
670 case 1: l|=((unsigned long)(*((c)++)))<<16; \
671 if (--len == 0) break; \
672 case 2: l|=((unsigned long)(*((c)++)))<< 8; \
674 /* NOTE the pointer is not incremented at the end of this */
675 #define HOST_c2l_p(c,l,n) { \
678 case 3: l =((unsigned long)(*(--(c))))<< 8; \
679 case 2: l|=((unsigned long)(*(--(c))))<<16; \
680 case 1: l|=((unsigned long)(*(--(c))))<<24; \
682 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
683 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
684 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
685 *((c)++)=(unsigned char)(((l) )&0xff), \
688 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
690 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
691 l|=(((unsigned long)(*((c)++)))<< 8), \
692 l|=(((unsigned long)(*((c)++)))<<16), \
693 l|=(((unsigned long)(*((c)++)))<<24), \
695 #define HOST_p_c2l(c,l,n) { \
697 case 0: l =((unsigned long)(*((c)++))); \
698 case 1: l|=((unsigned long)(*((c)++)))<< 8; \
699 case 2: l|=((unsigned long)(*((c)++)))<<16; \
700 case 3: l|=((unsigned long)(*((c)++)))<<24; \
702 #define HOST_p_c2l_p(c,l,sc,len) { \
704 case 0: l =((unsigned long)(*((c)++))); \
705 if (--len == 0) break; \
706 case 1: l|=((unsigned long)(*((c)++)))<< 8; \
707 if (--len == 0) break; \
708 case 2: l|=((unsigned long)(*((c)++)))<<16; \
710 /* NOTE the pointer is not incremented at the end of this */
711 #define HOST_c2l_p(c,l,n) { \
714 case 3: l =((unsigned long)(*(--(c))))<<16; \
715 case 2: l|=((unsigned long)(*(--(c))))<< 8; \
716 case 1: l|=((unsigned long)(*(--(c)))); \
718 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
719 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
720 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
721 *((c)++)=(unsigned char)(((l)>>24)&0xff), \
727 * Time for some action:-)
730 int HASH_UPDATE (HASH_CTX
*c
, const void *data_
, unsigned long len
)
732 const unsigned char *data
=(const unsigned char *)data_
;
733 register HASH_LONG
* p
;
734 register unsigned long l
;
737 if (len
==0) return 1;
739 l
=(c
->Nl
+(len
<<3))&0xffffffffL
;
740 /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
741 * Wei Dai <weidai@eskimo.com> for pointing it out. */
742 if (l
< c
->Nl
) /* overflow */
753 if ((c
->num
+len
) >= HASH_CBLOCK
)
755 l
=p
[sw
]; HOST_p_c2l(data
,l
,sc
); p
[sw
++]=l
;
756 for (; sw
<HASH_LBLOCK
; sw
++)
758 HOST_c2l(data
,l
); p
[sw
]=l
;
760 HASH_BLOCK_HOST_ORDER (c
,p
,1);
761 len
-=(HASH_CBLOCK
-c
->num
);
763 /* drop through and do the rest */
768 if ((sc
+len
) < 4) /* ugly, add char's to a word */
770 l
=p
[sw
]; HOST_p_c2l_p(data
,l
,sc
,len
); p
[sw
]=l
;
778 HOST_p_c2l(data
,l
,sc
);
780 for (; sw
< ew
; sw
++)
782 HOST_c2l(data
,l
); p
[sw
]=l
;
786 HOST_c2l_p(data
,l
,ec
); p
[sw
]=l
;
793 sw
=(int)(len
/HASH_CBLOCK
);
796 #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
798 * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
799 * only if sizeof(HASH_LONG)==4.
801 if ((((unsigned long)data
)%4
) == 0)
803 /* data is properly aligned so that we can cast it: */
804 HASH_BLOCK_DATA_ORDER_ALIGNED (c
,(HASH_LONG
*)data
,sw
);
810 #if !defined(HASH_BLOCK_DATA_ORDER)
813 memcpy (p
=c
->data
,data
,HASH_CBLOCK
);
814 HASH_BLOCK_DATA_ORDER_ALIGNED(c
,p
,1);
820 #if defined(HASH_BLOCK_DATA_ORDER)
822 HASH_BLOCK_DATA_ORDER(c
,data
,sw
);
834 ew
=(int)(len
>>2); /* words to copy */
838 HOST_c2l(data
,l
); *p
=l
;
840 HOST_c2l_p(data
,l
,ec
);
847 void HASH_TRANSFORM (HASH_CTX
*c
, const unsigned char *data
)
849 #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
850 if ((((unsigned long)data
)%4
) == 0)
851 /* data is properly aligned so that we can cast it: */
852 HASH_BLOCK_DATA_ORDER_ALIGNED (c
,(HASH_LONG
*)data
,1);
854 #if !defined(HASH_BLOCK_DATA_ORDER)
856 memcpy (c
->data
,data
,HASH_CBLOCK
);
857 HASH_BLOCK_DATA_ORDER_ALIGNED (c
,c
->data
,1);
861 #if defined(HASH_BLOCK_DATA_ORDER)
862 HASH_BLOCK_DATA_ORDER (c
,data
,1);
867 int HASH_FINAL (unsigned char *md
, HASH_CTX
*c
)
869 register HASH_LONG
*p
;
870 register unsigned long l
;
872 static const unsigned char end
[4]={0x80,0x00,0x00,0x00};
873 const unsigned char *cp
=end
;
875 /* c->num should definitly have room for at least one more byte. */
881 /* purify often complains about the following line as an
882 * Uninitialized Memory Read. While this can be true, the
883 * following p_c2l macro will reset l when that case is true.
884 * This is because j&0x03 contains the number of 'valid' bytes
885 * already in p[i]. If and only if j&0x03 == 0, the UMR will
886 * occur but this is also the only time p_c2l will do
887 * l= *(cp++) instead of l|= *(cp++)
888 * Many thanks to Alex Tang <altitude@cic.net> for pickup this
891 if (j
==0) p
[i
]=0; /* Yeah, but that's not the way to fix it:-) */
895 l
= (j
==0) ? 0 : p
[i
];
897 HOST_p_c2l(cp
,l
,j
); p
[i
++]=l
; /* i is the next 'undefined word' */
899 if (i
>(HASH_LBLOCK
-2)) /* save room for Nl and Nh */
901 if (i
<HASH_LBLOCK
) p
[i
]=0;
902 HASH_BLOCK_HOST_ORDER (c
,p
,1);
905 for (; i
<(HASH_LBLOCK
-2); i
++)
908 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
909 p
[HASH_LBLOCK
-2]=c
->Nh
;
910 p
[HASH_LBLOCK
-1]=c
->Nl
;
911 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
912 p
[HASH_LBLOCK
-2]=c
->Nl
;
913 p
[HASH_LBLOCK
-1]=c
->Nh
;
915 HASH_BLOCK_HOST_ORDER (c
,p
,1);
917 #ifndef HASH_MAKE_STRING
918 #error "HASH_MAKE_STRING must be defined!"
920 HASH_MAKE_STRING(c
,md
);
924 /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
925 * but I'm not worried :-)
926 OPENSSL_cleanse((void *)c,sizeof(HASH_CTX));
932 #define MD32_REG_T long
934 * This comment was originaly written for MD5, which is why it
935 * discusses A-D. But it basically applies to all 32-bit digests,
936 * which is why it was moved to common header file.
938 * In case you wonder why A-D are declared as long and not
939 * as mDNSu32. Doing so results in slight performance
940 * boost on LP64 architectures. The catch is we don't
941 * really care if 32 MSBs of a 64-bit register get polluted
942 * with eventual overflows as we *save* only 32 LSBs in
943 * *either* case. Now declaring 'em long excuses the compiler
944 * from keeping 32 MSBs zeroed resulting in 13% performance
945 * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
946 * Well, to be honest it should say that this *prevents*
947 * performance degradation.
948 * <appro@fy.chalmers.se>
949 * Apparently there're LP64 compilers that generate better
950 * code if A-D are declared int. Most notably GCC-x86_64
951 * generates better code.
952 * <appro@fy.chalmers.se>
957 // from md5_locl.h (continued)
960 #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
961 #define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
964 /* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
965 * simplified to the code below. Wei attributes these optimizations
966 * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
968 #define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
969 #define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
970 #define H(b,c,d) ((b) ^ (c) ^ (d))
971 #define I(b,c,d) (((~(d)) | (b)) ^ (c))
973 #define R0(a,b,c,d,k,s,t) { \
974 a+=((k)+(t)+F((b),(c),(d))); \
978 #define R1(a,b,c,d,k,s,t) { \
979 a+=((k)+(t)+G((b),(c),(d))); \
983 #define R2(a,b,c,d,k,s,t) { \
984 a+=((k)+(t)+H((b),(c),(d))); \
988 #define R3(a,b,c,d,k,s,t) { \
989 a+=((k)+(t)+I((b),(c),(d))); \
996 /* Implemented from RFC1321 The MD5 Message-Digest Algorithm
999 #define INIT_DATA_A (unsigned long)0x67452301L
1000 #define INIT_DATA_B (unsigned long)0xefcdab89L
1001 #define INIT_DATA_C (unsigned long)0x98badcfeL
1002 #define INIT_DATA_D (unsigned long)0x10325476L
1004 int MD5_Init(MD5_CTX
*c
)
1016 #ifndef md5_block_host_order
1017 void md5_block_host_order (MD5_CTX
*c
, const void *data
, int num
)
1019 const mDNSu32
*X
=(const mDNSu32
*)data
;
1020 register unsigned MD32_REG_T A
,B
,C
,D
;
1027 for (;num
--;X
+=HASH_LBLOCK
)
1030 R0(A
,B
,C
,D
,X
[ 0], 7,0xd76aa478L
);
1031 R0(D
,A
,B
,C
,X
[ 1],12,0xe8c7b756L
);
1032 R0(C
,D
,A
,B
,X
[ 2],17,0x242070dbL
);
1033 R0(B
,C
,D
,A
,X
[ 3],22,0xc1bdceeeL
);
1034 R0(A
,B
,C
,D
,X
[ 4], 7,0xf57c0fafL
);
1035 R0(D
,A
,B
,C
,X
[ 5],12,0x4787c62aL
);
1036 R0(C
,D
,A
,B
,X
[ 6],17,0xa8304613L
);
1037 R0(B
,C
,D
,A
,X
[ 7],22,0xfd469501L
);
1038 R0(A
,B
,C
,D
,X
[ 8], 7,0x698098d8L
);
1039 R0(D
,A
,B
,C
,X
[ 9],12,0x8b44f7afL
);
1040 R0(C
,D
,A
,B
,X
[10],17,0xffff5bb1L
);
1041 R0(B
,C
,D
,A
,X
[11],22,0x895cd7beL
);
1042 R0(A
,B
,C
,D
,X
[12], 7,0x6b901122L
);
1043 R0(D
,A
,B
,C
,X
[13],12,0xfd987193L
);
1044 R0(C
,D
,A
,B
,X
[14],17,0xa679438eL
);
1045 R0(B
,C
,D
,A
,X
[15],22,0x49b40821L
);
1047 R1(A
,B
,C
,D
,X
[ 1], 5,0xf61e2562L
);
1048 R1(D
,A
,B
,C
,X
[ 6], 9,0xc040b340L
);
1049 R1(C
,D
,A
,B
,X
[11],14,0x265e5a51L
);
1050 R1(B
,C
,D
,A
,X
[ 0],20,0xe9b6c7aaL
);
1051 R1(A
,B
,C
,D
,X
[ 5], 5,0xd62f105dL
);
1052 R1(D
,A
,B
,C
,X
[10], 9,0x02441453L
);
1053 R1(C
,D
,A
,B
,X
[15],14,0xd8a1e681L
);
1054 R1(B
,C
,D
,A
,X
[ 4],20,0xe7d3fbc8L
);
1055 R1(A
,B
,C
,D
,X
[ 9], 5,0x21e1cde6L
);
1056 R1(D
,A
,B
,C
,X
[14], 9,0xc33707d6L
);
1057 R1(C
,D
,A
,B
,X
[ 3],14,0xf4d50d87L
);
1058 R1(B
,C
,D
,A
,X
[ 8],20,0x455a14edL
);
1059 R1(A
,B
,C
,D
,X
[13], 5,0xa9e3e905L
);
1060 R1(D
,A
,B
,C
,X
[ 2], 9,0xfcefa3f8L
);
1061 R1(C
,D
,A
,B
,X
[ 7],14,0x676f02d9L
);
1062 R1(B
,C
,D
,A
,X
[12],20,0x8d2a4c8aL
);
1064 R2(A
,B
,C
,D
,X
[ 5], 4,0xfffa3942L
);
1065 R2(D
,A
,B
,C
,X
[ 8],11,0x8771f681L
);
1066 R2(C
,D
,A
,B
,X
[11],16,0x6d9d6122L
);
1067 R2(B
,C
,D
,A
,X
[14],23,0xfde5380cL
);
1068 R2(A
,B
,C
,D
,X
[ 1], 4,0xa4beea44L
);
1069 R2(D
,A
,B
,C
,X
[ 4],11,0x4bdecfa9L
);
1070 R2(C
,D
,A
,B
,X
[ 7],16,0xf6bb4b60L
);
1071 R2(B
,C
,D
,A
,X
[10],23,0xbebfbc70L
);
1072 R2(A
,B
,C
,D
,X
[13], 4,0x289b7ec6L
);
1073 R2(D
,A
,B
,C
,X
[ 0],11,0xeaa127faL
);
1074 R2(C
,D
,A
,B
,X
[ 3],16,0xd4ef3085L
);
1075 R2(B
,C
,D
,A
,X
[ 6],23,0x04881d05L
);
1076 R2(A
,B
,C
,D
,X
[ 9], 4,0xd9d4d039L
);
1077 R2(D
,A
,B
,C
,X
[12],11,0xe6db99e5L
);
1078 R2(C
,D
,A
,B
,X
[15],16,0x1fa27cf8L
);
1079 R2(B
,C
,D
,A
,X
[ 2],23,0xc4ac5665L
);
1081 R3(A
,B
,C
,D
,X
[ 0], 6,0xf4292244L
);
1082 R3(D
,A
,B
,C
,X
[ 7],10,0x432aff97L
);
1083 R3(C
,D
,A
,B
,X
[14],15,0xab9423a7L
);
1084 R3(B
,C
,D
,A
,X
[ 5],21,0xfc93a039L
);
1085 R3(A
,B
,C
,D
,X
[12], 6,0x655b59c3L
);
1086 R3(D
,A
,B
,C
,X
[ 3],10,0x8f0ccc92L
);
1087 R3(C
,D
,A
,B
,X
[10],15,0xffeff47dL
);
1088 R3(B
,C
,D
,A
,X
[ 1],21,0x85845dd1L
);
1089 R3(A
,B
,C
,D
,X
[ 8], 6,0x6fa87e4fL
);
1090 R3(D
,A
,B
,C
,X
[15],10,0xfe2ce6e0L
);
1091 R3(C
,D
,A
,B
,X
[ 6],15,0xa3014314L
);
1092 R3(B
,C
,D
,A
,X
[13],21,0x4e0811a1L
);
1093 R3(A
,B
,C
,D
,X
[ 4], 6,0xf7537e82L
);
1094 R3(D
,A
,B
,C
,X
[11],10,0xbd3af235L
);
1095 R3(C
,D
,A
,B
,X
[ 2],15,0x2ad7d2bbL
);
1096 R3(B
,C
,D
,A
,X
[ 9],21,0xeb86d391L
);
1106 #ifndef md5_block_data_order
1110 void md5_block_data_order (MD5_CTX
*c
, const void *data_
, int num
)
1112 const unsigned char *data
=data_
;
1113 register unsigned MD32_REG_T A
,B
,C
,D
,l
;
1115 /* See comment in crypto/sha/sha_locl.h for details. */
1116 unsigned MD32_REG_T XX0
, XX1
, XX2
, XX3
, XX4
, XX5
, XX6
, XX7
,
1117 XX8
, XX9
,XX10
,XX11
,XX12
,XX13
,XX14
,XX15
;
1120 mDNSu32 XX
[MD5_LBLOCK
];
1131 HOST_c2l(data
,l
); X( 0)=l
; HOST_c2l(data
,l
); X( 1)=l
;
1133 R0(A
,B
,C
,D
,X( 0), 7,0xd76aa478L
); HOST_c2l(data
,l
); X( 2)=l
;
1134 R0(D
,A
,B
,C
,X( 1),12,0xe8c7b756L
); HOST_c2l(data
,l
); X( 3)=l
;
1135 R0(C
,D
,A
,B
,X( 2),17,0x242070dbL
); HOST_c2l(data
,l
); X( 4)=l
;
1136 R0(B
,C
,D
,A
,X( 3),22,0xc1bdceeeL
); HOST_c2l(data
,l
); X( 5)=l
;
1137 R0(A
,B
,C
,D
,X( 4), 7,0xf57c0fafL
); HOST_c2l(data
,l
); X( 6)=l
;
1138 R0(D
,A
,B
,C
,X( 5),12,0x4787c62aL
); HOST_c2l(data
,l
); X( 7)=l
;
1139 R0(C
,D
,A
,B
,X( 6),17,0xa8304613L
); HOST_c2l(data
,l
); X( 8)=l
;
1140 R0(B
,C
,D
,A
,X( 7),22,0xfd469501L
); HOST_c2l(data
,l
); X( 9)=l
;
1141 R0(A
,B
,C
,D
,X( 8), 7,0x698098d8L
); HOST_c2l(data
,l
); X(10)=l
;
1142 R0(D
,A
,B
,C
,X( 9),12,0x8b44f7afL
); HOST_c2l(data
,l
); X(11)=l
;
1143 R0(C
,D
,A
,B
,X(10),17,0xffff5bb1L
); HOST_c2l(data
,l
); X(12)=l
;
1144 R0(B
,C
,D
,A
,X(11),22,0x895cd7beL
); HOST_c2l(data
,l
); X(13)=l
;
1145 R0(A
,B
,C
,D
,X(12), 7,0x6b901122L
); HOST_c2l(data
,l
); X(14)=l
;
1146 R0(D
,A
,B
,C
,X(13),12,0xfd987193L
); HOST_c2l(data
,l
); X(15)=l
;
1147 R0(C
,D
,A
,B
,X(14),17,0xa679438eL
);
1148 R0(B
,C
,D
,A
,X(15),22,0x49b40821L
);
1150 R1(A
,B
,C
,D
,X( 1), 5,0xf61e2562L
);
1151 R1(D
,A
,B
,C
,X( 6), 9,0xc040b340L
);
1152 R1(C
,D
,A
,B
,X(11),14,0x265e5a51L
);
1153 R1(B
,C
,D
,A
,X( 0),20,0xe9b6c7aaL
);
1154 R1(A
,B
,C
,D
,X( 5), 5,0xd62f105dL
);
1155 R1(D
,A
,B
,C
,X(10), 9,0x02441453L
);
1156 R1(C
,D
,A
,B
,X(15),14,0xd8a1e681L
);
1157 R1(B
,C
,D
,A
,X( 4),20,0xe7d3fbc8L
);
1158 R1(A
,B
,C
,D
,X( 9), 5,0x21e1cde6L
);
1159 R1(D
,A
,B
,C
,X(14), 9,0xc33707d6L
);
1160 R1(C
,D
,A
,B
,X( 3),14,0xf4d50d87L
);
1161 R1(B
,C
,D
,A
,X( 8),20,0x455a14edL
);
1162 R1(A
,B
,C
,D
,X(13), 5,0xa9e3e905L
);
1163 R1(D
,A
,B
,C
,X( 2), 9,0xfcefa3f8L
);
1164 R1(C
,D
,A
,B
,X( 7),14,0x676f02d9L
);
1165 R1(B
,C
,D
,A
,X(12),20,0x8d2a4c8aL
);
1167 R2(A
,B
,C
,D
,X( 5), 4,0xfffa3942L
);
1168 R2(D
,A
,B
,C
,X( 8),11,0x8771f681L
);
1169 R2(C
,D
,A
,B
,X(11),16,0x6d9d6122L
);
1170 R2(B
,C
,D
,A
,X(14),23,0xfde5380cL
);
1171 R2(A
,B
,C
,D
,X( 1), 4,0xa4beea44L
);
1172 R2(D
,A
,B
,C
,X( 4),11,0x4bdecfa9L
);
1173 R2(C
,D
,A
,B
,X( 7),16,0xf6bb4b60L
);
1174 R2(B
,C
,D
,A
,X(10),23,0xbebfbc70L
);
1175 R2(A
,B
,C
,D
,X(13), 4,0x289b7ec6L
);
1176 R2(D
,A
,B
,C
,X( 0),11,0xeaa127faL
);
1177 R2(C
,D
,A
,B
,X( 3),16,0xd4ef3085L
);
1178 R2(B
,C
,D
,A
,X( 6),23,0x04881d05L
);
1179 R2(A
,B
,C
,D
,X( 9), 4,0xd9d4d039L
);
1180 R2(D
,A
,B
,C
,X(12),11,0xe6db99e5L
);
1181 R2(C
,D
,A
,B
,X(15),16,0x1fa27cf8L
);
1182 R2(B
,C
,D
,A
,X( 2),23,0xc4ac5665L
);
1184 R3(A
,B
,C
,D
,X( 0), 6,0xf4292244L
);
1185 R3(D
,A
,B
,C
,X( 7),10,0x432aff97L
);
1186 R3(C
,D
,A
,B
,X(14),15,0xab9423a7L
);
1187 R3(B
,C
,D
,A
,X( 5),21,0xfc93a039L
);
1188 R3(A
,B
,C
,D
,X(12), 6,0x655b59c3L
);
1189 R3(D
,A
,B
,C
,X( 3),10,0x8f0ccc92L
);
1190 R3(C
,D
,A
,B
,X(10),15,0xffeff47dL
);
1191 R3(B
,C
,D
,A
,X( 1),21,0x85845dd1L
);
1192 R3(A
,B
,C
,D
,X( 8), 6,0x6fa87e4fL
);
1193 R3(D
,A
,B
,C
,X(15),10,0xfe2ce6e0L
);
1194 R3(C
,D
,A
,B
,X( 6),15,0xa3014314L
);
1195 R3(B
,C
,D
,A
,X(13),21,0x4e0811a1L
);
1196 R3(A
,B
,C
,D
,X( 4), 6,0xf7537e82L
);
1197 R3(D
,A
,B
,C
,X(11),10,0xbd3af235L
);
1198 R3(C
,D
,A
,B
,X( 2),15,0x2ad7d2bbL
);
1199 R3(B
,C
,D
,A
,X( 9),21,0xeb86d391L
);
1210 // ***************************************************************************
1211 #if COMPILER_LIKES_PRAGMA_MARK
1212 #pragma mark - base64 -> binary conversion
1215 static const char Base64
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1216 static const char Pad64
= '=';
1219 #define mDNSisspace(x) (x == '\t' || x == '\n' || x == '\v' || x == '\f' || x == '\r' || x == ' ')
1221 mDNSlocal
const char *mDNSstrchr(const char *s
, int c
)
1225 if (c
== *s
) return s
;
1226 if (!*s
) return mDNSNULL
;
1231 // skips all whitespace anywhere.
1232 // converts characters, four at a time, starting at (or after)
1233 // src from base - 64 numbers into three 8 bit bytes in the target area.
1234 // it returns the number of data bytes stored at the target, or -1 on error.
1235 // adapted from BIND sources
1237 mDNSlocal mDNSs32
DNSDigest_Base64ToBin(const char *src
, mDNSu8
*target
, mDNSu32 targsize
)
1239 int tarindex
, state
, ch
;
1245 while ((ch
= *src
++) != '\0') {
1246 if (mDNSisspace(ch
)) /* Skip whitespace anywhere. */
1252 pos
= mDNSstrchr(Base64
, ch
);
1253 if (pos
== 0) /* A non-base64 character. */
1259 if ((mDNSu32
)tarindex
>= targsize
)
1261 target
[tarindex
] = (mDNSu8
)((pos
- Base64
) << 2);
1267 if ((mDNSu32
)tarindex
+ 1 >= targsize
)
1269 target
[tarindex
] |= (pos
- Base64
) >> 4;
1270 target
[tarindex
+1] = (mDNSu8
)(((pos
- Base64
) & 0x0f) << 4);
1277 if ((mDNSu32
)tarindex
+ 1 >= targsize
)
1279 target
[tarindex
] |= (pos
- Base64
) >> 2;
1280 target
[tarindex
+1] = (mDNSu8
)(((pos
- Base64
) & 0x03) << 6);
1287 if ((mDNSu32
)tarindex
>= targsize
)
1289 target
[tarindex
] |= (pos
- Base64
);
1300 * We are done decoding Base-64 chars. Let's see if we ended
1301 * on a byte boundary, and/or with erroneous trailing characters.
1304 if (ch
== Pad64
) { /* We got a pad char. */
1305 ch
= *src
++; /* Skip it, get next. */
1307 case 0: /* Invalid = in first position */
1308 case 1: /* Invalid = in second position */
1311 case 2: /* Valid, means one byte of info */
1312 /* Skip any number of spaces. */
1313 for ((void)mDNSNULL
; ch
!= '\0'; ch
= *src
++)
1314 if (!mDNSisspace(ch
))
1316 /* Make sure there is another trailing = sign. */
1319 ch
= *src
++; /* Skip the = */
1320 /* Fall through to "single trailing =" case. */
1323 case 3: /* Valid, means two bytes of info */
1325 * We know this char is an =. Is there anything but
1326 * whitespace after it?
1328 for ((void)mDNSNULL
; ch
!= '\0'; ch
= *src
++)
1329 if (!mDNSisspace(ch
))
1333 * Now make sure for cases 2 and 3 that the "extra"
1334 * bits that slopped past the last full byte were
1335 * zeros. If we don't check them, they become a
1336 * subliminal channel.
1338 if (target
&& target
[tarindex
] != 0)
1343 * We ended by seeing the end of the string. Make sure we
1344 * have no partial bytes lying around.
1354 // ***************************************************************************
1355 #if COMPILER_LIKES_PRAGMA_MARK
1356 #pragma mark - API exported to mDNS Core
1360 #define HMAC_IPAD 0x36
1361 #define HMAC_OPAD 0x5c
1364 #define HMAC_MD5_AlgName (*(const domainname*) "\010" "hmac-md5" "\007" "sig-alg" "\003" "reg" "\003" "int")
1366 // Adapted from Appendix, RFC 2104
1367 mDNSlocal
void DNSDigest_ConstructHMACKey(DomainAuthInfo
*info
, const mDNSu8
*key
, mDNSu32 len
)
1370 mDNSu8 buf
[MD5_LEN
];
1373 // If key is longer than HMAC_LEN reset it to MD5(key)
1377 MD5_Update(&k
, key
, len
);
1383 // store key in pads
1384 mDNSPlatformMemZero(info
->keydata_ipad
, HMAC_LEN
);
1385 mDNSPlatformMemZero(info
->keydata_opad
, HMAC_LEN
);
1386 mDNSPlatformMemCopy(info
->keydata_ipad
, key
, len
);
1387 mDNSPlatformMemCopy(info
->keydata_opad
, key
, len
);
1389 // XOR key with ipad and opad values
1390 for (i
= 0; i
< HMAC_LEN
; i
++)
1392 info
->keydata_ipad
[i
] ^= HMAC_IPAD
;
1393 info
->keydata_opad
[i
] ^= HMAC_OPAD
;
1398 mDNSexport mDNSs32
DNSDigest_ConstructHMACKeyfromBase64(DomainAuthInfo
*info
, const char *b64key
)
1400 mDNSu8 keybuf
[1024];
1401 mDNSs32 keylen
= DNSDigest_Base64ToBin(b64key
, keybuf
, sizeof(keybuf
));
1402 if (keylen
< 0) return(keylen
);
1403 DNSDigest_ConstructHMACKey(info
, keybuf
, (mDNSu32
)keylen
);
1407 mDNSexport mDNSu8
*DNSDigest_SignMessage(DNSMessage
*msg
, mDNSu8
**end
, DomainAuthInfo
*info
, mDNSu16 tcode
)
1410 mDNSu8
*rdata
, *const countPtr
= (mDNSu8
*)&msg
->h
.numAdditionals
; // Get existing numAdditionals value
1413 mDNSu8 digest
[MD5_LEN
];
1418 mDNSu16 numAdditionals
= (mDNSu16
)((mDNSu16
)countPtr
[0] << 8 | countPtr
[1]);
1420 // Init MD5 context, digest inner key pad and message
1422 MD5_Update(&c
, info
->keydata_ipad
, HMAC_LEN
);
1423 MD5_Update(&c
, (mDNSu8
*)msg
, (unsigned long)(*end
- (mDNSu8
*)msg
));
1425 // Construct TSIG RR, digesting variables as apporpriate
1426 mDNS_SetupResourceRecord(&tsig
, mDNSNULL
, 0, kDNSType_TSIG
, 0, kDNSRecordTypeKnownUnique
, mDNSNULL
, mDNSNULL
);
1429 AssignDomainName(&tsig
.namestorage
, &info
->keyname
);
1430 MD5_Update(&c
, info
->keyname
.c
, DomainNameLength(&info
->keyname
));
1433 tsig
.resrec
.rrclass
= kDNSQClass_ANY
;
1434 buf
= mDNSOpaque16fromIntVal(kDNSQClass_ANY
);
1435 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
));
1438 tsig
.resrec
.rroriginalttl
= 0;
1439 MD5_Update(&c
, (mDNSu8
*)&tsig
.resrec
.rroriginalttl
, sizeof(tsig
.resrec
.rroriginalttl
));
1442 AssignDomainName(&tsig
.resrec
.rdata
->u
.name
, &HMAC_MD5_AlgName
);
1443 len
= DomainNameLength(&HMAC_MD5_AlgName
);
1444 rdata
= tsig
.resrec
.rdata
->u
.data
+ len
;
1445 MD5_Update(&c
, HMAC_MD5_AlgName
.c
, len
);
1448 // get UTC (universal time), convert to 48-bit unsigned in network byte order
1449 utc32
= (mDNSu32
)mDNSPlatformUTC();
1450 if (utc32
== (unsigned)-1) { LogMsg("ERROR: DNSDigest_SignMessage - mDNSPlatformUTC returned bad time -1"); return mDNSNULL
; }
1453 utc48
[2] = (mDNSu8
)((utc32
>> 24) & 0xff);
1454 utc48
[3] = (mDNSu8
)((utc32
>> 16) & 0xff);
1455 utc48
[4] = (mDNSu8
)((utc32
>> 8) & 0xff);
1456 utc48
[5] = (mDNSu8
)( utc32
& 0xff);
1458 mDNSPlatformMemCopy(rdata
, utc48
, 6);
1460 MD5_Update(&c
, utc48
, 6);
1462 // 300 sec is fudge recommended in RFC 2485
1463 rdata
[0] = (mDNSu8
)((300 >> 8) & 0xff);
1464 rdata
[1] = (mDNSu8
)( 300 & 0xff);
1465 MD5_Update(&c
, rdata
, sizeof(mDNSOpaque16
));
1466 rdata
+= sizeof(mDNSOpaque16
);
1468 // digest error (tcode) and other data len (zero) - we'll add them to the rdata later
1469 buf
.b
[0] = (mDNSu8
)((tcode
>> 8) & 0xff);
1470 buf
.b
[1] = (mDNSu8
)( tcode
& 0xff);
1471 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
)); // error
1472 buf
.NotAnInteger
= 0;
1473 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
)); // other data len
1475 // finish the message & tsig var hash
1476 MD5_Final(digest
, &c
);
1478 // perform outer MD5 (outer key pad, inner digest)
1480 MD5_Update(&c
, info
->keydata_opad
, HMAC_LEN
);
1481 MD5_Update(&c
, digest
, MD5_LEN
);
1482 MD5_Final(digest
, &c
);
1484 // set remaining rdata fields
1485 rdata
[0] = (mDNSu8
)((MD5_LEN
>> 8) & 0xff);
1486 rdata
[1] = (mDNSu8
)( MD5_LEN
& 0xff);
1487 rdata
+= sizeof(mDNSOpaque16
);
1488 mDNSPlatformMemCopy(rdata
, digest
, MD5_LEN
); // MAC
1490 rdata
[0] = msg
->h
.id
.b
[0]; // original ID
1491 rdata
[1] = msg
->h
.id
.b
[1];
1492 rdata
[2] = (mDNSu8
)((tcode
>> 8) & 0xff);
1493 rdata
[3] = (mDNSu8
)( tcode
& 0xff);
1494 rdata
[4] = 0; // other data len
1498 tsig
.resrec
.rdlength
= (mDNSu16
)(rdata
- tsig
.resrec
.rdata
->u
.data
);
1499 *end
= PutResourceRecordTTLJumbo(msg
, ptr
, &numAdditionals
, &tsig
.resrec
, 0);
1500 if (!*end
) { LogMsg("ERROR: DNSDigest_SignMessage - could not put TSIG"); return mDNSNULL
; }
1502 // Write back updated numAdditionals value
1503 countPtr
[0] = (mDNSu8
)(numAdditionals
>> 8);
1504 countPtr
[1] = (mDNSu8
)(numAdditionals
& 0xFF);
1509 mDNSexport mDNSBool
DNSDigest_VerifyMessage(DNSMessage
*msg
, mDNSu8
*end
, LargeCacheRecord
* lcr
, DomainAuthInfo
*info
, mDNSu16
* rcode
, mDNSu16
* tcode
)
1511 mDNSu8
* ptr
= (mDNSu8
*) &lcr
->r
.resrec
.rdata
->u
.data
;
1514 mDNSu8 thisDigest
[MD5_LEN
];
1515 mDNSu8 thatDigest
[MD5_LEN
];
1523 mDNSBool ok
= mDNSfalse
;
1525 // We only support HMAC-MD5 for now
1527 algo
= (domainname
*) ptr
;
1529 if (!SameDomainName(algo
, &HMAC_MD5_AlgName
))
1531 LogMsg("ERROR: DNSDigest_VerifyMessage - TSIG algorithm not supported: %##s", algo
->c
);
1532 *rcode
= kDNSFlag1_RC_NotAuth
;
1533 *tcode
= TSIG_ErrBadKey
;
1538 ptr
+= DomainNameLength(algo
);
1542 now
= mDNSPlatformUTC();
1545 LogMsg("ERROR: DNSDigest_VerifyMessage - mDNSPlatformUTC returned bad time -1");
1546 *rcode
= kDNSFlag1_RC_NotAuth
;
1547 *tcode
= TSIG_ErrBadTime
;
1552 // Get the 48 bit time field, skipping over the first word
1561 then
= (mDNSs32
)NToH32(utc48
+ sizeof(mDNSu16
));
1563 fudge
= NToH16(ptr
);
1565 ptr
+= sizeof(mDNSu16
);
1567 delta
= (now
> then
) ? now
- then
: then
- now
;
1571 LogMsg("ERROR: DNSDigest_VerifyMessage - time skew > %d", fudge
);
1572 *rcode
= kDNSFlag1_RC_NotAuth
;
1573 *tcode
= TSIG_ErrBadTime
;
1580 macsize
= (mDNSu32
) NToH16(ptr
);
1582 ptr
+= sizeof(mDNSu16
);
1586 mDNSPlatformMemCopy(thatDigest
, ptr
, MD5_LEN
);
1588 // Init MD5 context, digest inner key pad and message
1591 MD5_Update(&c
, info
->keydata_ipad
, HMAC_LEN
);
1592 MD5_Update(&c
, (mDNSu8
*) msg
, (unsigned long)(end
- (mDNSu8
*) msg
));
1596 MD5_Update(&c
, lcr
->r
.resrec
.name
->c
, DomainNameLength(lcr
->r
.resrec
.name
));
1600 buf
= mDNSOpaque16fromIntVal(lcr
->r
.resrec
.rrclass
);
1601 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
));
1605 MD5_Update(&c
, (mDNSu8
*) &lcr
->r
.resrec
.rroriginalttl
, sizeof(lcr
->r
.resrec
.rroriginalttl
));
1609 MD5_Update(&c
, algo
->c
, DomainNameLength(algo
));
1613 MD5_Update(&c
, utc48
, 6);
1617 buf
= mDNSOpaque16fromIntVal(fudge
);
1618 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
));
1620 // Digest error and other data len (both zero) - we'll add them to the rdata later
1622 buf
.NotAnInteger
= 0;
1623 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
)); // error
1624 MD5_Update(&c
, buf
.b
, sizeof(mDNSOpaque16
)); // other data len
1626 // Finish the message & tsig var hash
1628 MD5_Final(thisDigest
, &c
);
1630 // perform outer MD5 (outer key pad, inner digest)
1633 MD5_Update(&c
, info
->keydata_opad
, HMAC_LEN
);
1634 MD5_Update(&c
, thisDigest
, MD5_LEN
);
1635 MD5_Final(thisDigest
, &c
);
1637 if (!mDNSPlatformMemSame(thisDigest
, thatDigest
, MD5_LEN
))
1639 LogMsg("ERROR: DNSDigest_VerifyMessage - bad signature");
1640 *rcode
= kDNSFlag1_RC_NotAuth
;
1641 *tcode
= TSIG_ErrBadSig
;
1646 // set remaining rdata fields