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