147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* -*- Mode: C; tab-width: 4 -*-
247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License");
647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * you may not use this file except in compliance with the License.
747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * You may obtain a copy of the License at
847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *     http://www.apache.org/licenses/LICENSE-2.0
1047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
1147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Unless required by applicable law or agreed to in writing, software
1247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS,
1347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * See the License for the specific language governing permissions and
1547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * limitations under the License.
1647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
1747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
1847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
1947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef __cplusplus
2047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltextern "C" {
2147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
2247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
2347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "mDNSEmbeddedAPI.h"
2447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "DNSCommon.h"
2547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
2647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Disable certain benign warnings with Microsoft compilers
2747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if(defined(_MSC_VER))
2847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Disable "conditional expression is constant" warning for debug macros.
2947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Otherwise, this generates warnings for the perfectly natural construct "while(1)"
3047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know
3147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	#pragma warning(disable:4127)
3247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
3347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
3447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
3547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // ***************************************************************************
3647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if COMPILER_LIKES_PRAGMA_MARK
3747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#pragma mark - Byte Swapping Functions
3847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
3947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSu16 NToH16(mDNSu8 * bytes)
4147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
4247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return (mDNSu16)((mDNSu16)bytes[0] << 8 | (mDNSu16)bytes[1]);
4347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
4447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSu32 NToH32(mDNSu8 * bytes)
4647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
4747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return (mDNSu32)((mDNSu32) bytes[0] << 24 | (mDNSu32) bytes[1] << 16 | (mDNSu32) bytes[2] << 8 | (mDNSu32)bytes[3]);
4847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
4947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
5047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // ***************************************************************************
5147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if COMPILER_LIKES_PRAGMA_MARK
5247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#pragma mark - MD5 Hash Functions
5347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
5447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
5547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
5647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* The source for the has is derived CommonCrypto files CommonDigest.h, md32_common.h, md5_locl.h, md5_locl.h, and openssl/md5.h.
5747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * The following changes have been made to the original sources:
5847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    replaced CC_LONG w/ mDNSu32
5947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    replaced CC_MD5* with MD5*
6047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    replaced CC_LONG w/ mDNSu32, removed conditional #defines from md5.h
6147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    removed extern decls for MD5_Init/Update/Final from CommonDigest.h
6247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    removed APPLE_COMMON_DIGEST specific #defines from md5_locl.h
6347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
6447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Note: machine archetecure specific conditionals from the original sources are turned off, but are left in the code
6547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * to aid in platform-specific optimizations and debugging.
6647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Sources originally distributed under the following license headers:
6747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * CommonDigest.h - APSL
6847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
6947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * md32_Common.h
7047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * ====================================================================
7147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
7247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
7347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Redistribution and use in source and binary forms, with or without
7447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * modification, are permitted provided that the following conditions
7547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * are met:
7647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
7747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 1. Redistributions of source code must retain the above copyright
7847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    notice, this list of conditions and the following disclaimer.
7947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
8047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 2. Redistributions in binary form must reproduce the above copyright
8147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    notice, this list of conditions and the following disclaimer in
8247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    the documentation and/or other materials provided with the
8347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    distribution.
8447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
8547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 3. All advertising materials mentioning features or use of this
8647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    software must display the following acknowledgment:
8747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    "This product includes software developed by the OpenSSL Project
8847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
8947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
9047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    endorse or promote products derived from this software without
9247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    prior written permission. For written permission, please contact
9347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    licensing@OpenSSL.org.
9447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
9547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 5. Products derived from this software may not be called "OpenSSL"
9647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    nor may "OpenSSL" appear in their names without prior written
9747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    permission of the OpenSSL Project.
9847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
9947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 6. Redistributions of any form whatsoever must retain the following
10047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    acknowledgment:
10147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    "This product includes software developed by the OpenSSL Project
10247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
10347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
10447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
10547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
10847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
11047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
11247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
11347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
11447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
11547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * OF THE POSSIBILITY OF SUCH DAMAGE.
11647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
11747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
11847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * md5_dgst.c, md5_locl.h
11947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * ====================================================================
12047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
12147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This product includes cryptographic software written by Eric Young
12247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * (eay@cryptsoft.com).  This product includes software written by Tim
12347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Hudson (tjh@cryptsoft.com).
12447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
12547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
12647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * All rights reserved.
12747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
12847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This package is an SSL implementation written
12947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * by Eric Young (eay@cryptsoft.com).
13047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * The implementation was written so as to conform with Netscapes SSL.
13147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
13247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This library is free for commercial and non-commercial use as long as
13347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * the following conditions are aheared to.  The following conditions
13447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * apply to all code found in this distribution, be it the RC4, RSA,
13547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * included with this distribution is covered by the same copyright terms
13747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * except that the holder is Tim Hudson (tjh@cryptsoft.com).
13847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
13947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright remains Eric Young's, and as such any Copyright notices in
14047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * the code are not to be removed.
14147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * If this package is used in a product, Eric Young should be given attribution
14247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * as the author of the parts of the library used.
14347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This can be in the form of a textual message at program startup or
14447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * in documentation (online or textual) provided with the package.
14547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
14647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Redistribution and use in source and binary forms, with or without
14747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * modification, are permitted provided that the following conditions
14847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * are met:
14947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 1. Redistributions of source code must retain the copyright
15047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    notice, this list of conditions and the following disclaimer.
15147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 2. Redistributions in binary form must reproduce the above copyright
15247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    notice, this list of conditions and the following disclaimer in the
15347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    documentation and/or other materials provided with the distribution.
15447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 3. All advertising materials mentioning features or use of this software
15547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    must display the following acknowledgement:
15647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    "This product includes cryptographic software written by
15747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *     Eric Young (eay@cryptsoft.com)"
15847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    The word 'cryptographic' can be left out if the rouines from the library
15947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    being used are not cryptographic related :-).
16047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 4. If you include any Windows specific code (or a derivative thereof) from
16147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    the apps directory (application code) you must include an acknowledgement:
16247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
16347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
16447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
17247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * SUCH DAMAGE.
17547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
17647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * The licence and distribution terms for any publically available version or
17747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * derivative of this code cannot be changed.  i.e. this code cannot simply be
17847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * copied and put under another distribution licence
17947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * [including the GNU Public Licence.]
18047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
18147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
18247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//from CommonDigest.h
18447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_DIGEST_LENGTH	16			/* digest length in bytes */
18647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_BLOCK_BYTES		64			/* block size in bytes */
18747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_BLOCK_LONG       (MD5_BLOCK_BYTES / sizeof(mDNSu32))
18847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct MD5state_st
19047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
19147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 A,B,C,D;
19247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 Nl,Nh;
19347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 data[MD5_BLOCK_LONG];
19447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	int num;
19547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} MD5_CTX;
19647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
1970b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon#ifndef HAVE_MD5
19847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
19947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// from openssl/md5.h
20047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
20147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_CBLOCK	64
20247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_LBLOCK	(MD5_CBLOCK/4)
20347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_DIGEST_LENGTH 16
20447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
20547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint MD5_Init(MD5_CTX *c);
20647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
20747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint MD5_Final(unsigned char *md, MD5_CTX *c);
20847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid MD5_Transform(MD5_CTX *c, const unsigned char *b);
20947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
21047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// From md5_locl.h
21147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
21247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef MD5_LONG_LOG2
21347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_LONG_LOG2 2 /* default to 32 bits */
21447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
21547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
21647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef MD5_ASM
21747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
21847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  define md5_block_host_order md5_block_asm_host_order
21947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
22047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   void md5_block_asm_data_order_aligned (MD5_CTX *c, const mDNSu32 *p,int num);
22147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned
22247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# endif
22347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
22447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
22547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid md5_block_host_order (MD5_CTX *c, const void *p,int num);
22647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid md5_block_data_order (MD5_CTX *c, const void *p,int num);
22747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
22847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
22947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
23047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * *_block_host_order is expected to handle aligned data while
23147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * *_block_data_order - unaligned. As algorithm and host (x86)
23247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * are in this case of the same "endianness" these two are
23347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * otherwise indistinguishable. But normally you don't want to
23447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * call the same function because unaligned access in places
23547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * where alignment is expected is usually a "Bad Thing". Indeed,
23647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * on RISCs you get punished with BUS ERROR signal or *severe*
23747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * performance degradation. Intel CPUs are in turn perfectly
23847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * capable of loading unaligned data without such drastic side
23947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * effect. Yes, they say it's slower than aligned load, but no
24047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * exception is generated and therefore performance degradation
24147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * is *incomparable* with RISCs. What we should weight here is
24247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * costs of unaligned access against costs of aligning data.
24347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * According to my measurements allowing unaligned access results
24447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * in ~9% performance improvement on Pentium II operating at
24547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 266MHz. I won't be surprised if the difference will be higher
24647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * on faster systems:-)
24747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
24847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *				<appro@fy.chalmers.se>
24947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
25047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define md5_block_data_order md5_block_host_order
25147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
25247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
25347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define DATA_ORDER_IS_LITTLE_ENDIAN
25447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
25547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_LONG		mDNSu32
25647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_LONG_LOG2	MD5_LONG_LOG2
25747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_CTX		MD5_CTX
25847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_CBLOCK		MD5_CBLOCK
25947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_LBLOCK		MD5_LBLOCK
26047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
26147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_UPDATE		MD5_Update
26247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_TRANSFORM	MD5_Transform
26347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_FINAL		MD5_Final
26447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
26547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	HASH_MAKE_STRING(c,s)	do {	\
26647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	unsigned long ll;		\
26747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ll=(c)->A; HOST_l2c(ll,(s));	\
26847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ll=(c)->B; HOST_l2c(ll,(s));	\
26947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ll=(c)->C; HOST_l2c(ll,(s));	\
27047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ll=(c)->D; HOST_l2c(ll,(s));	\
27147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	} while (0)
27247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_BLOCK_HOST_ORDER	md5_block_host_order
27347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !defined(L_ENDIAN) || defined(md5_block_data_order)
27447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	HASH_BLOCK_DATA_ORDER	md5_block_data_order
27547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
27647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Little-endians (Intel and Alpha) feel better without this.
27747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * It looks like memcpy does better job than generic
27847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * md5_block_data_order on copying-n-aligning input data.
27947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * But frankly speaking I didn't expect such result on Alpha.
28047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * On the other hand I've got this with egcs-1.0.2 and if
28147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * program is compiled with another (better?) compiler it
28247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * might turn out other way around.
28347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
28447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *				<appro@fy.chalmers.se>
28547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
28647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
28747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
28847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
28947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// from md32_common.h
29047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
29147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
29247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This is a generic 32 bit "collector" for message digest algorithms.
29347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Whenever needed it collects input character stream into chunks of
29447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 32 bit values and invokes a block function that performs actual hash
29547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * calculations.
29647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
29747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Porting guide.
29847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
29947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Obligatory macros:
30047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
30147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
30247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	this macro defines byte order of input stream.
30347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_CBLOCK
30447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	size of a unit chunk HASH_BLOCK operates on.
30547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_LONG
30647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	has to be at lest 32 bit wide, if it's wider, then
30747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	HASH_LONG_LOG2 *has to* be defined along
30847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_CTX
30947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	context structure that at least contains following
31047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	members:
31147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *		typedef struct {
31247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *			...
31347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *			HASH_LONG	Nl,Nh;
31447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *			HASH_LONG	data[HASH_LBLOCK];
31547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *			int		num;
31647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *			...
31747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *			} HASH_CTX;
31847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_UPDATE
31947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	name of "Update" function, implemented here.
32047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_TRANSFORM
32147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	name of "Transform" function, implemented here.
32247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_FINAL
32347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	name of "Final" function, implemented here.
32447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_BLOCK_HOST_ORDER
32547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	name of "block" function treating *aligned* input message
32647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	in host byte order, implemented externally.
32747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_BLOCK_DATA_ORDER
32847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	name of "block" function treating *unaligned* input message
32947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	in original (data) byte order, implemented externally (it
33047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	actually is optional if data and host are of the same
33147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	"endianess").
33247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_MAKE_STRING
33347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	macro convering context variables to an ASCII hash string.
33447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
33547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Optional macros:
33647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
33747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * B_ENDIAN or L_ENDIAN
33847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	defines host byte-order.
33947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_LONG_LOG2
34047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	defaults to 2 if not states otherwise.
34147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_LBLOCK
34247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	assumed to be HASH_CBLOCK/4 if not stated otherwise.
34347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * HASH_BLOCK_DATA_ORDER_ALIGNED
34447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	alternative "block" function capable of treating
34547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	aligned input message in original (data) order,
34647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	implemented externally.
34747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
34847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * MD5 example:
34947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
35047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define DATA_ORDER_IS_LITTLE_ENDIAN
35147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
35247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_LONG		mDNSu32
35347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_LONG_LOG2	mDNSu32_LOG2
35447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_CTX		MD5_CTX
35547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_CBLOCK		MD5_CBLOCK
35647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_LBLOCK		MD5_LBLOCK
35747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_UPDATE		MD5_Update
35847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_TRANSFORM		MD5_Transform
35947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_FINAL		MD5_Final
36047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_BLOCK_HOST_ORDER	md5_block_host_order
36147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order
36247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
36347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *					<appro@fy.chalmers.se>
36447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
36547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
36647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
36747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "DATA_ORDER must be defined!"
36847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
36947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
37047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_CBLOCK
37147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_CBLOCK must be defined!"
37247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
37347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_LONG
37447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_LONG must be defined!"
37547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
37647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_CTX
37747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_CTX must be defined!"
37847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
37947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
38047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_UPDATE
38147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_UPDATE must be defined!"
38247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
38347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_TRANSFORM
38447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_TRANSFORM must be defined!"
38547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
38647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_FINAL
38747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_FINAL must be defined!"
38847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
38947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
39047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_BLOCK_HOST_ORDER
39147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_BLOCK_HOST_ORDER must be defined!"
39247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
39347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
39447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if 0
39547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
39647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
39747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * isn't defined.
39847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
39947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_BLOCK_DATA_ORDER
40047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_BLOCK_DATA_ORDER must be defined!"
40147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
40247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
40347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
40447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_LBLOCK
40547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_LBLOCK	(HASH_CBLOCK/4)
40647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
40747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
40847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_LONG_LOG2
40947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HASH_LONG_LOG2	2
41047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
41147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
41247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
41347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Engage compiler specific rotate intrinsic function if available.
41447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
41547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#undef ROTATE
41647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef PEDANTIC
41747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# if 0 /* defined(_MSC_VER) */
41847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  define ROTATE(a,n)	_lrotl(a,n)
41947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# elif defined(__MWERKS__)
42047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  if defined(__POWERPC__)
42147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define ROTATE(a,n)	(unsigned MD32_REG_T)__rlwinm((int)a,n,0,31)
42247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  elif defined(__MC68K__)
42347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    /* Motorola specific tweak. <appro@fy.chalmers.se> */
42447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define ROTATE(a,n)	(n<24 ? __rol(a,n) : __ror(a,32-n))
42547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  else
42647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define ROTATE(a,n)	__rol(a,n)
42747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  endif
42847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
42947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt  /*
43047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * Some GNU C inline assembler templates. Note that these are
43147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * rotates by *constant* number of bits! But that's exactly
43247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * what we need here...
43347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   *
43447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * 					<appro@fy.chalmers.se>
43547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   */
43647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt  /*
43747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * LLVM is more strict about compatibility of types between input & output constraints,
43847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * but we want these to be rotations of 32 bits, not 64, so we explicitly drop the
43947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   * most significant bytes by casting to an unsigned int.
44047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   */
44147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
44247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define ROTATE(a,n)	({ register unsigned int ret;	\
44347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				asm (			\
44447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				"roll %1,%0"		\
44547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "=r"(ret)		\
44647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "I"(n), "0"((unsigned int)a)	\
44747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "cc");		\
44847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			   ret;				\
44947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			})
45047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  elif defined(__powerpc) || defined(__ppc)
45147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define ROTATE(a,n)	({ register unsigned int ret;	\
45247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				asm (			\
45347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				"rlwinm %0,%1,%2,0,31"	\
45447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "=r"(ret)		\
45547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "r"(a), "I"(n));	\
45647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			   ret;				\
45747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			})
45847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  endif
45947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# endif
46047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
46147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
46247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Engage compiler specific "fetch in reverse byte order"
46347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * intrinsic function if available.
46447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
46547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
46647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt  /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
46747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  if (defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)) && !defined(I386_ONLY)
46847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define BE_FETCH32(a)	({ register unsigned int l=(a);\
46947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				asm (			\
47047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				"bswapl %0"		\
47147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "=r"(l) : "0"(l));	\
47247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			  l;				\
47347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			})
47447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  elif defined(__powerpc)
47547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#   define LE_FETCH32(a)	({ register unsigned int l;	\
47647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				asm (			\
47747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				"lwbrx %0,0,%1"		\
47847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "=r"(l)		\
47947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "r"(a));		\
48047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			   l;				\
48147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			})
48247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
48347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
48447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  define LE_FETCH32(a)	({ register unsigned int l;		\
48547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				asm (				\
48647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				"lda [%1]#ASI_PRIMARY_LITTLE,%0"\
48747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "=r"(l)			\
48847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				: "r"(a));			\
48947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			   l;					\
49047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			})
49147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  endif
49247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# endif
49347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif /* PEDANTIC */
49447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
49547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if HASH_LONG_LOG2==2	/* Engage only if sizeof(HASH_LONG)== 4 */
49647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
49747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef ROTATE
49847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 5 instructions with rotate instruction, else 9 */
49947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define REVERSE_FETCH32(a,l)	(					\
50047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		l=*(const HASH_LONG *)(a),				\
50147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24)))	\
50247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				)
50347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else
50447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 6 instructions with rotate instruction, else 8 */
50547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define REVERSE_FETCH32(a,l)	(				\
50647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		l=*(const HASH_LONG *)(a),			\
50747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)),	\
50847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ROTATE(l,16)					\
50947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				)
51047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
51147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
51247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * It's rewritten as above for two reasons:
51347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	- RISCs aren't good at long constants and have to explicitely
51447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	  compose 'em with several (well, usually 2) instructions in a
51547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	  register before performing the actual operation and (as you
51647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	  already realized:-) having same constant should inspire the
51747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	  compiler to permanently allocate the only register for it;
51847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	- most modern CPUs have two ALUs, but usually only one has
51947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	  circuitry for shifts:-( this minor tweak inspires compiler
52047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *	  to schedule shift instructions in a better way...
52147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
52247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *				<appro@fy.chalmers.se>
52347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
52447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
52547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
52647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
52747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef ROTATE
52847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
52947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
53047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
53147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
53247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
53347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
53447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * and host are of the same "endianess". It's possible to mask
53547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * this with blank #define HASH_BLOCK_DATA_ORDER though...
53647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
53747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *				<appro@fy.chalmers.se>
53847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
53947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(B_ENDIAN)
54047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  if defined(DATA_ORDER_IS_BIG_ENDIAN)
54147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
54247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      define HASH_BLOCK_DATA_ORDER_ALIGNED	HASH_BLOCK_HOST_ORDER
54347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    endif
54447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
54547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    ifndef HOST_FETCH32
54647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      ifdef LE_FETCH32
54747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#        define HOST_FETCH32(p,l)	LE_FETCH32(p)
54847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      elif defined(REVERSE_FETCH32)
54947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#        define HOST_FETCH32(p,l)	REVERSE_FETCH32(p,l)
55047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      endif
55147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    endif
55247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  endif
55347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#elif defined(L_ENDIAN)
55447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
55547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
55647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      define HASH_BLOCK_DATA_ORDER_ALIGNED	HASH_BLOCK_HOST_ORDER
55747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    endif
55847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  elif defined(DATA_ORDER_IS_BIG_ENDIAN)
55947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    ifndef HOST_FETCH32
56047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      ifdef BE_FETCH32
56147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#        define HOST_FETCH32(p,l)	BE_FETCH32(p)
56247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      elif defined(REVERSE_FETCH32)
56347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#        define HOST_FETCH32(p,l)	REVERSE_FETCH32(p,l)
56447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#      endif
56547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#    endif
56647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#  endif
56747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
56847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
56947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
57047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_BLOCK_DATA_ORDER
57147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_BLOCK_DATA_ORDER must be defined!"
57247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
57347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
57447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
57547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(DATA_ORDER_IS_BIG_ENDIAN)
57647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
57747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
57847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l|=(((unsigned long)(*((c)++)))<<16),		\
57947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l|=(((unsigned long)(*((c)++)))<< 8),		\
58047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l|=(((unsigned long)(*((c)++)))    ),		\
58147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l)
58247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_p_c2l(c,l,n)	{					\
58347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			switch (n) {					\
58447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 0: l =((unsigned long)(*((c)++)))<<24;	\
58547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 1: l|=((unsigned long)(*((c)++)))<<16;	\
58647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 2: l|=((unsigned long)(*((c)++)))<< 8;	\
58747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 3: l|=((unsigned long)(*((c)++)));		\
58847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				} }
58947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_p_c2l_p(c,l,sc,len) {					\
59047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			switch (sc) {					\
59147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 0: l =((unsigned long)(*((c)++)))<<24;	\
59247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (--len == 0) break;			\
59347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 1: l|=((unsigned long)(*((c)++)))<<16;	\
59447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (--len == 0) break;			\
59547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 2: l|=((unsigned long)(*((c)++)))<< 8;	\
59647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				} }
59747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* NOTE the pointer is not incremented at the end of this */
59847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_c2l_p(c,l,n)	{					\
59947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			l=0; (c)+=n;					\
60047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			switch (n) {					\
60147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 3: l =((unsigned long)(*(--(c))))<< 8;	\
60247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 2: l|=((unsigned long)(*(--(c))))<<16;	\
60347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 1: l|=((unsigned long)(*(--(c))))<<24;	\
60447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				} }
60547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
60647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
60747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
60847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
60947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l)
61047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
61147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
61247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
61347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
61447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l|=(((unsigned long)(*((c)++)))<< 8),		\
61547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l|=(((unsigned long)(*((c)++)))<<16),		\
61647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l|=(((unsigned long)(*((c)++)))<<24),		\
61747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l)
61847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_p_c2l(c,l,n)	{					\
61947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			switch (n) {					\
62047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 0: l =((unsigned long)(*((c)++)));		\
62147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 1: l|=((unsigned long)(*((c)++)))<< 8;	\
62247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 2: l|=((unsigned long)(*((c)++)))<<16;	\
62347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 3: l|=((unsigned long)(*((c)++)))<<24;	\
62447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				} }
62547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_p_c2l_p(c,l,sc,len) {					\
62647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			switch (sc) {					\
62747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 0: l =((unsigned long)(*((c)++)));		\
62847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (--len == 0) break;			\
62947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 1: l|=((unsigned long)(*((c)++)))<< 8;	\
63047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (--len == 0) break;			\
63147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 2: l|=((unsigned long)(*((c)++)))<<16;	\
63247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				} }
63347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* NOTE the pointer is not incremented at the end of this */
63447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_c2l_p(c,l,n)	{					\
63547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			l=0; (c)+=n;					\
63647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			switch (n) {					\
63747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 3: l =((unsigned long)(*(--(c))))<<16;	\
63847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 2: l|=((unsigned long)(*(--(c))))<< 8;	\
63947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			case 1: l|=((unsigned long)(*(--(c))));		\
64047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				} }
64147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
64247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
64347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
64447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
64547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 l)
64647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
64747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
64847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
64947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
65047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Time for some action:-)
65147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
65247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
65347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
65447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
65547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const unsigned char *data=(const unsigned char *)data_;
65647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register HASH_LONG * p;
65747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register unsigned long l;
65847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	int sw,sc,ew,ec;
65947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
66047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (len==0) return 1;
66147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
66247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	l=(c->Nl+(len<<3))&0xffffffffL;
66347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
66447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * Wei Dai <weidai@eskimo.com> for pointing it out. */
66547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (l < c->Nl) /* overflow */
66647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		c->Nh++;
66747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->Nh+=(len>>29);
66847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->Nl=l;
66947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
67047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (c->num != 0)
67147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
67247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		p=c->data;
67347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		sw=c->num>>2;
67447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		sc=c->num&0x03;
67547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
67647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if ((c->num+len) >= HASH_CBLOCK)
67747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
67847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
67947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			for (; sw<HASH_LBLOCK; sw++)
68047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				{
68147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				HOST_c2l(data,l); p[sw]=l;
68247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				}
68347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			HASH_BLOCK_HOST_ORDER (c,p,1);
68447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			len-=(HASH_CBLOCK-c->num);
68547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			c->num=0;
68647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/* drop through and do the rest */
68747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
68847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		else
68947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
69047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			c->num+=len;
69147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if ((sc+len) < 4) /* ugly, add char's to a word */
69247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				{
69347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
69447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				}
69547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			else
69647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				{
69747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				ew=(c->num>>2);
69847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				ec=(c->num&0x03);
69947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (sc)
70047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					l=p[sw];
70147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				HOST_p_c2l(data,l,sc);
70247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				p[sw++]=l;
70347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				for (; sw < ew; sw++)
70447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					{
70547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					HOST_c2l(data,l); p[sw]=l;
70647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					}
70747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (ec)
70847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					{
70947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					HOST_c2l_p(data,l,ec); p[sw]=l;
71047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					}
71147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				}
71247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			return 1;
71347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
71447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
71547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
71647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	sw=(int)(len/HASH_CBLOCK);
71747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (sw > 0)
71847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
71947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
72047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		/*
72147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		 * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
72247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		 * only if sizeof(HASH_LONG)==4.
72347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		 */
72447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if ((((unsigned long)data)%4) == 0)
72547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
72647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/* data is properly aligned so that we can cast it: */
72747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
72847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			sw*=HASH_CBLOCK;
72947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			data+=sw;
73047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			len-=sw;
73147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
73247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		else
73347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !defined(HASH_BLOCK_DATA_ORDER)
73447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			while (sw--)
73547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				{
73647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				mDNSPlatformMemCopy(p=c->data,data,HASH_CBLOCK);
73747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
73847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				data+=HASH_CBLOCK;
73947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				len-=HASH_CBLOCK;
74047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				}
74147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
74247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
74347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(HASH_BLOCK_DATA_ORDER)
74447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
74547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			HASH_BLOCK_DATA_ORDER(c,data,sw);
74647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			sw*=HASH_CBLOCK;
74747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			data+=sw;
74847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			len-=sw;
74947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
75047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
75147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
75247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
75347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (len!=0)
75447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
75547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		p = c->data;
75647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		c->num = (int)len;
75747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ew=(int)(len>>2);	/* words to copy */
75847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ec=(int)(len&0x03);
75947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		for (; ew; ew--,p++)
76047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			{
76147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			HOST_c2l(data,l); *p=l;
76247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
76347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		HOST_c2l_p(data,l,ec);
76447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*p=l;
76547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
76647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return 1;
76747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
76847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
76947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
77047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
77147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
77247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
77347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if ((((unsigned long)data)%4) == 0)
77447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		/* data is properly aligned so that we can cast it: */
77547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
77647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	else
77747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if !defined(HASH_BLOCK_DATA_ORDER)
77847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
77947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		mDNSPlatformMemCopy(c->data,data,HASH_CBLOCK);
78047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
78147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
78247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
78347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
78447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if defined(HASH_BLOCK_DATA_ORDER)
78547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	HASH_BLOCK_DATA_ORDER (c,data,1);
78647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
78747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
78847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
78947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
79047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint HASH_FINAL (unsigned char *md, HASH_CTX *c)
79147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
79247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register HASH_LONG *p;
79347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register unsigned long l;
79447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register int i,j;
79547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	static const unsigned char end[4]={0x80,0x00,0x00,0x00};
79647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const unsigned char *cp=end;
79747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
79847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* c->num should definitly have room for at least one more byte. */
79947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	p=c->data;
80047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	i=c->num>>2;
80147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	j=c->num&0x03;
80247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
80347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if 0
80447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* purify often complains about the following line as an
80547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * Uninitialized Memory Read.  While this can be true, the
80647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * following p_c2l macro will reset l when that case is true.
80747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * This is because j&0x03 contains the number of 'valid' bytes
80847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * already in p[i].  If and only if j&0x03 == 0, the UMR will
80947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * occur but this is also the only time p_c2l will do
81047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * l= *(cp++) instead of l|= *(cp++)
81147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * Many thanks to Alex Tang <altitude@cic.net> for pickup this
81247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * 'potential bug' */
81347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef PURIFY
81447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
81547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
81647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	l=p[i];
81747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else
81847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	l = (j==0) ? 0 : p[i];
81947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
82047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
82147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
82247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
82347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
82447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (i<HASH_LBLOCK) p[i]=0;
82547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		HASH_BLOCK_HOST_ORDER (c,p,1);
82647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		i=0;
82747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
82847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	for (; i<(HASH_LBLOCK-2); i++)
82947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		p[i]=0;
83047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
83147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
83247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	p[HASH_LBLOCK-2]=c->Nh;
83347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	p[HASH_LBLOCK-1]=c->Nl;
83447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
83547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	p[HASH_LBLOCK-2]=c->Nl;
83647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	p[HASH_LBLOCK-1]=c->Nh;
83747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
83847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	HASH_BLOCK_HOST_ORDER (c,p,1);
83947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
84047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef HASH_MAKE_STRING
84147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#error "HASH_MAKE_STRING must be defined!"
84247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else
84347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	HASH_MAKE_STRING(c,md);
84447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
84547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
84647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->num=0;
84747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
84847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * but I'm not worried :-)
84947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	OPENSSL_cleanse((void *)c,sizeof(HASH_CTX));
85047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 */
85147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return 1;
85247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
85347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
85447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef MD32_REG_T
85547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD32_REG_T long
85647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
85747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * This comment was originaly written for MD5, which is why it
85847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * discusses A-D. But it basically applies to all 32-bit digests,
85947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * which is why it was moved to common header file.
86047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
86147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * In case you wonder why A-D are declared as long and not
86247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * as mDNSu32. Doing so results in slight performance
86347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * boost on LP64 architectures. The catch is we don't
86447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * really care if 32 MSBs of a 64-bit register get polluted
86547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * with eventual overflows as we *save* only 32 LSBs in
86647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * *either* case. Now declaring 'em long excuses the compiler
86747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * from keeping 32 MSBs zeroed resulting in 13% performance
86847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
86947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Well, to be honest it should say that this *prevents*
87047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * performance degradation.
87147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *				<appro@fy.chalmers.se>
87247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Apparently there're LP64 compilers that generate better
87347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * code if A-D are declared int. Most notably GCC-x86_64
87447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * generates better code.
87547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *				<appro@fy.chalmers.se>
87647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
87747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
87847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
87947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
88047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// from md5_locl.h (continued)
88147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
88247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
88347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	F(x,y,z)	(((x) & (y))  |  ((~(x)) & (z)))
88447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	G(x,y,z)	(((x) & (z))  |  ((y) & (~(z))))
88547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt*/
88647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
88747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
88847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * simplified to the code below.  Wei attributes these optimizations
88947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
89047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
89147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	F(b,c,d)	((((c) ^ (d)) & (b)) ^ (d))
89247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	G(b,c,d)	((((b) ^ (c)) & (d)) ^ (c))
89347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	H(b,c,d)	((b) ^ (c) ^ (d))
89447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define	I(b,c,d)	(((~(d)) | (b)) ^ (c))
89547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
89647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define R0(a,b,c,d,k,s,t) { \
89747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=((k)+(t)+F((b),(c),(d))); \
89847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a=ROTATE(a,s); \
89947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=b; };\
90047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
90147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define R1(a,b,c,d,k,s,t) { \
90247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=((k)+(t)+G((b),(c),(d))); \
90347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a=ROTATE(a,s); \
90447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=b; };
90547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
90647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define R2(a,b,c,d,k,s,t) { \
90747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=((k)+(t)+H((b),(c),(d))); \
90847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a=ROTATE(a,s); \
90947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=b; };
91047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
91147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define R3(a,b,c,d,k,s,t) { \
91247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=((k)+(t)+I((b),(c),(d))); \
91347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a=ROTATE(a,s); \
91447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	a+=b; };
91547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
91647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// from md5_dgst.c
91747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
91847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
91947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
92047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
92147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
92247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define INIT_DATA_A (unsigned long)0x67452301L
92347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define INIT_DATA_B (unsigned long)0xefcdab89L
92447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define INIT_DATA_C (unsigned long)0x98badcfeL
92547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define INIT_DATA_D (unsigned long)0x10325476L
92647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
92747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint MD5_Init(MD5_CTX *c)
92847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
92947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->A=INIT_DATA_A;
93047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->B=INIT_DATA_B;
93147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->C=INIT_DATA_C;
93247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->D=INIT_DATA_D;
93347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->Nl=0;
93447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->Nh=0;
93547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	c->num=0;
93647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return 1;
93747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
93847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
93947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef md5_block_host_order
94047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid md5_block_host_order (MD5_CTX *c, const void *data, int num)
94147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
94247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const mDNSu32 *X=(const mDNSu32 *)data;
94347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register unsigned MD32_REG_T A,B,C,D;
94447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
94547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	A=c->A;
94647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	B=c->B;
94747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	C=c->C;
94847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	D=c->D;
94947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
95047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	for (;num--;X+=HASH_LBLOCK)
95147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
95247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 0 */
95347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
95447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
95547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X[ 2],17,0x242070dbL);
95647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
95747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
95847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X[ 5],12,0x4787c62aL);
95947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X[ 6],17,0xa8304613L);
96047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X[ 7],22,0xfd469501L);
96147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X[ 8], 7,0x698098d8L);
96247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
96347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X[10],17,0xffff5bb1L);
96447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X[11],22,0x895cd7beL);
96547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X[12], 7,0x6b901122L);
96647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X[13],12,0xfd987193L);
96747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X[14],17,0xa679438eL);
96847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X[15],22,0x49b40821L);
96947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 1 */
97047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
97147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X[ 6], 9,0xc040b340L);
97247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X[11],14,0x265e5a51L);
97347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
97447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
97547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X[10], 9,0x02441453L);
97647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X[15],14,0xd8a1e681L);
97747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
97847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
97947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X[14], 9,0xc33707d6L);
98047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
98147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X[ 8],20,0x455a14edL);
98247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X[13], 5,0xa9e3e905L);
98347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
98447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X[ 7],14,0x676f02d9L);
98547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
98647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 2 */
98747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
98847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X[ 8],11,0x8771f681L);
98947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X[11],16,0x6d9d6122L);
99047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X[14],23,0xfde5380cL);
99147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
99247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
99347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
99447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X[10],23,0xbebfbc70L);
99547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X[13], 4,0x289b7ec6L);
99647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X[ 0],11,0xeaa127faL);
99747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
99847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X[ 6],23,0x04881d05L);
99947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
100047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X[12],11,0xe6db99e5L);
100147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X[15],16,0x1fa27cf8L);
100247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
100347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 3 */
100447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X[ 0], 6,0xf4292244L);
100547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X[ 7],10,0x432aff97L);
100647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X[14],15,0xab9423a7L);
100747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X[ 5],21,0xfc93a039L);
100847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X[12], 6,0x655b59c3L);
100947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
101047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X[10],15,0xffeff47dL);
101147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X[ 1],21,0x85845dd1L);
101247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
101347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
101447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X[ 6],15,0xa3014314L);
101547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X[13],21,0x4e0811a1L);
101647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
101747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X[11],10,0xbd3af235L);
101847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
101947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X[ 9],21,0xeb86d391L);
102047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
102147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	A = c->A += A;
102247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	B = c->B += B;
102347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	C = c->C += C;
102447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	D = c->D += D;
102547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
102647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
102747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
102847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
102947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef md5_block_data_order
103047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef X
103147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#undef X
103247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
103347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid md5_block_data_order (MD5_CTX *c, const void *data_, int num)
103447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
103547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const unsigned char *data=data_;
103647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	register unsigned MD32_REG_T A,B,C,D,l;
103747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifndef MD32_XARRAY
103847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* See comment in crypto/sha/sha_locl.h for details. */
103947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
104047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
104147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# define X(i)	XX##i
104247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else
104347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 XX[MD5_LBLOCK];
104447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt# define X(i)	XX[i]
104547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
104647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
104747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	A=c->A;
104847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	B=c->B;
104947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	C=c->C;
105047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	D=c->D;
105147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
105247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	for (;num--;)
105347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
105447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
105547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 0 */
105647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X( 0), 7,0xd76aa478L);	HOST_c2l(data,l); X( 2)=l;
105747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X( 1),12,0xe8c7b756L);	HOST_c2l(data,l); X( 3)=l;
105847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X( 2),17,0x242070dbL);	HOST_c2l(data,l); X( 4)=l;
105947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X( 3),22,0xc1bdceeeL);	HOST_c2l(data,l); X( 5)=l;
106047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X( 4), 7,0xf57c0fafL);	HOST_c2l(data,l); X( 6)=l;
106147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X( 5),12,0x4787c62aL);	HOST_c2l(data,l); X( 7)=l;
106247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X( 6),17,0xa8304613L);	HOST_c2l(data,l); X( 8)=l;
106347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X( 7),22,0xfd469501L);	HOST_c2l(data,l); X( 9)=l;
106447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X( 8), 7,0x698098d8L);	HOST_c2l(data,l); X(10)=l;
106547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X( 9),12,0x8b44f7afL);	HOST_c2l(data,l); X(11)=l;
106647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X(10),17,0xffff5bb1L);	HOST_c2l(data,l); X(12)=l;
106747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X(11),22,0x895cd7beL);	HOST_c2l(data,l); X(13)=l;
106847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(A,B,C,D,X(12), 7,0x6b901122L);	HOST_c2l(data,l); X(14)=l;
106947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(D,A,B,C,X(13),12,0xfd987193L);	HOST_c2l(data,l); X(15)=l;
107047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(C,D,A,B,X(14),17,0xa679438eL);
107147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R0(B,C,D,A,X(15),22,0x49b40821L);
107247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 1 */
107347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X( 1), 5,0xf61e2562L);
107447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X( 6), 9,0xc040b340L);
107547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X(11),14,0x265e5a51L);
107647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
107747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X( 5), 5,0xd62f105dL);
107847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X(10), 9,0x02441453L);
107947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X(15),14,0xd8a1e681L);
108047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
108147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
108247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X(14), 9,0xc33707d6L);
108347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X( 3),14,0xf4d50d87L);
108447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X( 8),20,0x455a14edL);
108547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(A,B,C,D,X(13), 5,0xa9e3e905L);
108647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
108747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(C,D,A,B,X( 7),14,0x676f02d9L);
108847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
108947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 2 */
109047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X( 5), 4,0xfffa3942L);
109147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X( 8),11,0x8771f681L);
109247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X(11),16,0x6d9d6122L);
109347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X(14),23,0xfde5380cL);
109447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X( 1), 4,0xa4beea44L);
109547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
109647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
109747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X(10),23,0xbebfbc70L);
109847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X(13), 4,0x289b7ec6L);
109947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X( 0),11,0xeaa127faL);
110047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X( 3),16,0xd4ef3085L);
110147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X( 6),23,0x04881d05L);
110247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
110347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(D,A,B,C,X(12),11,0xe6db99e5L);
110447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(C,D,A,B,X(15),16,0x1fa27cf8L);
110547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R2(B,C,D,A,X( 2),23,0xc4ac5665L);
110647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/* Round 3 */
110747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X( 0), 6,0xf4292244L);
110847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X( 7),10,0x432aff97L);
110947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X(14),15,0xab9423a7L);
111047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X( 5),21,0xfc93a039L);
111147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X(12), 6,0x655b59c3L);
111247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
111347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X(10),15,0xffeff47dL);
111447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X( 1),21,0x85845dd1L);
111547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
111647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
111747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X( 6),15,0xa3014314L);
111847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X(13),21,0x4e0811a1L);
111947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(A,B,C,D,X( 4), 6,0xf7537e82L);
112047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(D,A,B,C,X(11),10,0xbd3af235L);
112147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
112247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	R3(B,C,D,A,X( 9),21,0xeb86d391L);
112347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
112447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	A = c->A += A;
112547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	B = c->B += B;
112647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	C = c->C += C;
112747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	D = c->D += D;
112847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
112947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
113047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
113147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
11320b6b4e32c36ce143bfd095119b4939e4cf826021Joshua Melcon#endif  // !HAVE_MD5
113347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
113447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // ***************************************************************************
113547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if COMPILER_LIKES_PRAGMA_MARK
113647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#pragma mark - base64 -> binary conversion
113747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
113847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
113947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
114047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char Pad64 = '=';
114147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
114247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
114347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define mDNSisspace(x) (x == '\t' || x == '\n' || x == '\v' || x == '\f' || x == '\r' || x == ' ')
114447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
114547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal const char *mDNSstrchr(const char *s, int c)
114647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
114747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	while (1)
114847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
114947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (c == *s) return s;
115047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (!*s) return mDNSNULL;
115147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		s++;
115247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
115347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
115447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
115547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// skips all whitespace anywhere.
115647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// converts characters, four at a time, starting at (or after)
115747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// src from base - 64 numbers into three 8 bit bytes in the target area.
115847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// it returns the number of data bytes stored at the target, or -1 on error.
115947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// adapted from BIND sources
116047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
116147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSs32 DNSDigest_Base64ToBin(const char *src, mDNSu8 *target, mDNSu32 targsize)
116247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
116347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	int tarindex, state, ch;
116447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	const char *pos;
116547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
116647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	state = 0;
116747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	tarindex = 0;
116847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
116947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	while ((ch = *src++) != '\0') {
117047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (mDNSisspace(ch))	/* Skip whitespace anywhere. */
117147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			continue;
117247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
117347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (ch == Pad64)
117447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			break;
117547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
117647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		pos = mDNSstrchr(Base64, ch);
117747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (pos == 0) 		/* A non-base64 character. */
117847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			return (-1);
117947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
118047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		switch (state) {
118147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 0:
118247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if (target) {
118347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if ((mDNSu32)tarindex >= targsize)
118447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					return (-1);
118547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				target[tarindex] = (mDNSu8)((pos - Base64) << 2);
118647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
118747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			state = 1;
118847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			break;
118947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 1:
119047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if (target) {
119147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if ((mDNSu32)tarindex + 1 >= targsize)
119247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					return (-1);
119347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				target[tarindex]   |=  (pos - Base64) >> 4;
119447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				target[tarindex+1]  = (mDNSu8)(((pos - Base64) & 0x0f) << 4);
119547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
119647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			tarindex++;
119747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			state = 2;
119847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			break;
119947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 2:
120047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if (target) {
120147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if ((mDNSu32)tarindex + 1 >= targsize)
120247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					return (-1);
120347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				target[tarindex]   |=  (pos - Base64) >> 2;
120447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				target[tarindex+1]  = (mDNSu8)(((pos - Base64) & 0x03) << 6);
120547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
120647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			tarindex++;
120747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			state = 3;
120847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			break;
120947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 3:
121047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if (target) {
121147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if ((mDNSu32)tarindex >= targsize)
121247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					return (-1);
121347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				target[tarindex] |= (pos - Base64);
121447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			}
121547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			tarindex++;
121647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			state = 0;
121747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			break;
121847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		default:
121947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			return -1;
122047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
122147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
122247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
122347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	/*
122447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * We are done decoding Base-64 chars.  Let's see if we ended
122547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 * on a byte boundary, and/or with erroneous trailing characters.
122647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 */
122747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
122847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (ch == Pad64) {		/* We got a pad char. */
122947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ch = *src++;		/* Skip it, get next. */
123047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		switch (state) {
123147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 0:		/* Invalid = in first position */
123247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 1:		/* Invalid = in second position */
123347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			return (-1);
123447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
123547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 2:		/* Valid, means one byte of info */
123647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/* Skip any number of spaces. */
123747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			for ((void)mDNSNULL; ch != '\0'; ch = *src++)
123847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (!mDNSisspace(ch))
123947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					break;
124047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/* Make sure there is another trailing = sign. */
124147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if (ch != Pad64)
124247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				return (-1);
124347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			ch = *src++;		/* Skip the = */
124447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/* Fall through to "single trailing =" case. */
124547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/* FALLTHROUGH */
124647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
124747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		case 3:		/* Valid, means two bytes of info */
124847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/*
124947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 * We know this char is an =.  Is there anything but
125047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 * whitespace after it?
125147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 */
125247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			for ((void)mDNSNULL; ch != '\0'; ch = *src++)
125347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				if (!mDNSisspace(ch))
125447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt					return (-1);
125547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
125647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			/*
125747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 * Now make sure for cases 2 and 3 that the "extra"
125847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 * bits that slopped past the last full byte were
125947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 * zeros.  If we don't check them, they become a
126047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 * subliminal channel.
126147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			 */
126247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			if (target && target[tarindex] != 0)
126347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt				return (-1);
126447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
126547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	} else {
126647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		/*
126747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		 * We ended by seeing the end of the string.  Make sure we
126847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		 * have no partial bytes lying around.
126947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		 */
127047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		if (state != 0)
127147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt			return (-1);
127247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
127347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
127447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return (tarindex);
127547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
127647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
127747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
127847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // ***************************************************************************
127947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if COMPILER_LIKES_PRAGMA_MARK
128047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#pragma mark - API exported to mDNS Core
128147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
128247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
128347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Constants
128447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HMAC_IPAD   0x36
128547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HMAC_OPAD   0x5c
128647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define MD5_LEN     16
128747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
128847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define HMAC_MD5_AlgName (*(const domainname*) "\010" "hmac-md5" "\007" "sig-alg" "\003" "reg" "\003" "int")
128947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
129047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Adapted from Appendix, RFC 2104
129147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal void DNSDigest_ConstructHMACKey(DomainAuthInfo *info, const mDNSu8 *key, mDNSu32 len)
129247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
129347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_CTX k;
129447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8 buf[MD5_LEN];
129547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	int i;
129647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
129747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// If key is longer than HMAC_LEN reset it to MD5(key)
129847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (len > HMAC_LEN)
129947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
130047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		MD5_Init(&k);
130147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		MD5_Update(&k, key, len);
130247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		MD5_Final(buf, &k);
130347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		key = buf;
130447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		len = MD5_LEN;
130547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
130647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
130747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// store key in pads
130847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemZero(info->keydata_ipad, HMAC_LEN);
130947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemZero(info->keydata_opad, HMAC_LEN);
131047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemCopy(info->keydata_ipad, key, len);
131147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemCopy(info->keydata_opad, key, len);
131247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
131347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// XOR key with ipad and opad values
131447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	for (i = 0; i < HMAC_LEN; i++)
131547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
131647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		info->keydata_ipad[i] ^= HMAC_IPAD;
131747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		info->keydata_opad[i] ^= HMAC_OPAD;
131847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
131947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
132047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
132147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
132247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport mDNSs32 DNSDigest_ConstructHMACKeyfromBase64(DomainAuthInfo *info, const char *b64key)
132347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
132447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8 keybuf[1024];
132547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSs32 keylen = DNSDigest_Base64ToBin(b64key, keybuf, sizeof(keybuf));
132647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (keylen < 0) return(keylen);
132747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	DNSDigest_ConstructHMACKey(info, keybuf, (mDNSu32)keylen);
132847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return(keylen);
132947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
133047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
133147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport void DNSDigest_SignMessage(DNSMessage *msg, mDNSu8 **end, DomainAuthInfo *info, mDNSu16 tcode)
133247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
133347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	AuthRecord tsig;
133447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8  *rdata, *const countPtr = (mDNSu8 *)&msg->h.numAdditionals;	// Get existing numAdditionals value
133547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 utc32;
133647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8 utc48[6];
133747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8 digest[MD5_LEN];
133847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8 *ptr = *end;
133947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32 len;
134047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSOpaque16 buf;
134147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_CTX c;
134247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu16 numAdditionals = (mDNSu16)((mDNSu16)countPtr[0] << 8 | countPtr[1]);
134347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
134447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Init MD5 context, digest inner key pad and message
134547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    MD5_Init(&c);
134647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    MD5_Update(&c, info->keydata_ipad, HMAC_LEN);
134747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, (mDNSu8 *)msg, (unsigned long)(*end - (mDNSu8 *)msg));
134847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
134947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Construct TSIG RR, digesting variables as apporpriate
135047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNS_SetupResourceRecord(&tsig, mDNSNULL, 0, kDNSType_TSIG, 0, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
135147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
135247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// key name
135347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	AssignDomainName(&tsig.namestorage, &info->keyname);
135447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, info->keyname.c, DomainNameLength(&info->keyname));
135547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
135647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// class
135747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	tsig.resrec.rrclass = kDNSQClass_ANY;
135847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf = mDNSOpaque16fromIntVal(kDNSQClass_ANY);
135947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));
136047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
136147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// ttl
136247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	tsig.resrec.rroriginalttl = 0;
136347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, (mDNSu8 *)&tsig.resrec.rroriginalttl, sizeof(tsig.resrec.rroriginalttl));
136447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
136547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// alg name
136647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	AssignDomainName(&tsig.resrec.rdata->u.name, &HMAC_MD5_AlgName);
136747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	len = DomainNameLength(&HMAC_MD5_AlgName);
136847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata = tsig.resrec.rdata->u.data + len;
136947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, HMAC_MD5_AlgName.c, len);
137047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
137147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// time
137247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// get UTC (universal time), convert to 48-bit unsigned in network byte order
137347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc32 = (mDNSu32)mDNSPlatformUTC();
137447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (utc32 == (unsigned)-1) { LogMsg("ERROR: DNSDigest_SignMessage - mDNSPlatformUTC returned bad time -1"); *end = mDNSNULL; }
137547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[0] = 0;
137647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[1] = 0;
137747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[2] = (mDNSu8)((utc32 >> 24) & 0xff);
137847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[3] = (mDNSu8)((utc32 >> 16) & 0xff);
137947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[4] = (mDNSu8)((utc32 >>  8) & 0xff);
138047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[5] = (mDNSu8)( utc32        & 0xff);
138147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
138247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemCopy(rdata, utc48, 6);
138347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata += 6;
138447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, utc48, 6);
138547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
138647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// 300 sec is fudge recommended in RFC 2485
138747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[0] = (mDNSu8)((300 >> 8)  & 0xff);
138847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[1] = (mDNSu8)( 300        & 0xff);
138947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, rdata, sizeof(mDNSOpaque16));
139047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata += sizeof(mDNSOpaque16);
139147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
139247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// digest error (tcode) and other data len (zero) - we'll add them to the rdata later
139347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf.b[0] = (mDNSu8)((tcode >> 8) & 0xff);
139447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf.b[1] = (mDNSu8)( tcode       & 0xff);
139547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));  // error
139647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf.NotAnInteger = 0;
139747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));  // other data len
139847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
139947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// finish the message & tsig var hash
140047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    MD5_Final(digest, &c);
140147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
140247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// perform outer MD5 (outer key pad, inner digest)
140347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Init(&c);
140447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, info->keydata_opad, HMAC_LEN);
140547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, digest, MD5_LEN);
140647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Final(digest, &c);
140747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
140847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// set remaining rdata fields
140947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[0] = (mDNSu8)((MD5_LEN >> 8)  & 0xff);
141047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[1] = (mDNSu8)( MD5_LEN        & 0xff);
141147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata += sizeof(mDNSOpaque16);
141247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemCopy(rdata, digest, MD5_LEN);                          // MAC
141347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata += MD5_LEN;
141447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[0] = msg->h.id.b[0];                                            // original ID
141547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[1] = msg->h.id.b[1];
141647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[2] = (mDNSu8)((tcode >> 8) & 0xff);
141747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[3] = (mDNSu8)( tcode       & 0xff);
141847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[4] = 0;                                                         // other data len
141947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata[5] = 0;
142047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	rdata += 6;
142147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
142247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	tsig.resrec.rdlength = (mDNSu16)(rdata - tsig.resrec.rdata->u.data);
142347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	*end = PutResourceRecordTTLJumbo(msg, ptr, &numAdditionals, &tsig.resrec, 0);
142447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!*end) { LogMsg("ERROR: DNSDigest_SignMessage - could not put TSIG"); *end = mDNSNULL; return; }
142547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
142647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Write back updated numAdditionals value
142747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	countPtr[0] = (mDNSu8)(numAdditionals >> 8);
142847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	countPtr[1] = (mDNSu8)(numAdditionals &  0xFF);
142947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
143047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
143147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport mDNSBool DNSDigest_VerifyMessage(DNSMessage *msg, mDNSu8 *end, LargeCacheRecord * lcr, DomainAuthInfo *info, mDNSu16 * rcode, mDNSu16 * tcode)
143247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	{
143347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8			*	ptr = (mDNSu8*) &lcr->r.resrec.rdata->u.data;
143447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSs32				now;
143547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSs32				then;
143647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8				thisDigest[MD5_LEN];
143747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8				thatDigest[MD5_LEN];
143847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu32				macsize;
143947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSOpaque16 		buf;
144047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu8				utc48[6];
144147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSs32				delta;
144247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSu16				fudge;
144347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	domainname		*	algo;
144447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_CTX				c;
144547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSBool			ok = mDNSfalse;
144647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
144747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// We only support HMAC-MD5 for now
144847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
144947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	algo = (domainname*) ptr;
145047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
145147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!SameDomainName(algo, &HMAC_MD5_AlgName))
145247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
145347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		LogMsg("ERROR: DNSDigest_VerifyMessage - TSIG algorithm not supported: %##s", algo->c);
145447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*rcode = kDNSFlag1_RC_NotAuth;
145547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*tcode = TSIG_ErrBadKey;
145647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ok = mDNSfalse;
145747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		goto exit;
145847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
145947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
146047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ptr += DomainNameLength(algo);
146147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
146247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Check the times
146347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
146447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	now = mDNSPlatformUTC();
146547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (now == -1)
146647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
146747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		LogMsg("ERROR: DNSDigest_VerifyMessage - mDNSPlatformUTC returned bad time -1");
146847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*rcode = kDNSFlag1_RC_NotAuth;
146947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*tcode = TSIG_ErrBadTime;
147047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ok = mDNSfalse;
147147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		goto exit;
147247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
147347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
147447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Get the 48 bit time field, skipping over the first word
147547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
147647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[0] = *ptr++;
147747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[1] = *ptr++;
147847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[2] = *ptr++;
147947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[3] = *ptr++;
148047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[4] = *ptr++;
148147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	utc48[5] = *ptr++;
148247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
148347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	then  = (mDNSs32)NToH32(utc48 + sizeof(mDNSu16));
148447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
148547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	fudge = NToH16(ptr);
148647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
148747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ptr += sizeof(mDNSu16);
148847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
148947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	delta = (now > then) ? now - then : then - now;
149047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
149147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (delta > fudge)
149247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
149347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		LogMsg("ERROR: DNSDigest_VerifyMessage - time skew > %d", fudge);
149447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*rcode = kDNSFlag1_RC_NotAuth;
149547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*tcode = TSIG_ErrBadTime;
149647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ok = mDNSfalse;
149747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		goto exit;
149847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
149947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
150047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// MAC size
150147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
150247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	macsize = (mDNSu32) NToH16(ptr);
150347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
150447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ptr += sizeof(mDNSu16);
150547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
150647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// MAC
150747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
150847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	mDNSPlatformMemCopy(thatDigest, ptr, MD5_LEN);
150947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
151047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Init MD5 context, digest inner key pad and message
151147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
151247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Init(&c);
151347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, info->keydata_ipad, HMAC_LEN);
151447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, (mDNSu8*) msg, (unsigned long)(end - (mDNSu8*) msg));
151547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
151647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Key name
151747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
151847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, lcr->r.resrec.name->c, DomainNameLength(lcr->r.resrec.name));
151947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
152047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Class name
152147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
152247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf = mDNSOpaque16fromIntVal(lcr->r.resrec.rrclass);
152347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));
152447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
152547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// TTL
152647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
152747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, (mDNSu8*) &lcr->r.resrec.rroriginalttl, sizeof(lcr->r.resrec.rroriginalttl));
152847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
152947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Algorithm
153047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
153147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, algo->c, DomainNameLength(algo));
153247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
153347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Time
153447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
153547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, utc48, 6);
153647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
153747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Fudge
153847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
153947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf = mDNSOpaque16fromIntVal(fudge);
154047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));
154147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
154247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Digest error and other data len (both zero) - we'll add them to the rdata later
154347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
154447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	buf.NotAnInteger = 0;
154547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));  // error
154647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));  // other data len
154747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
154847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// Finish the message & tsig var hash
154947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
155047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt    MD5_Final(thisDigest, &c);
155147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
155247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// perform outer MD5 (outer key pad, inner digest)
155347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
155447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Init(&c);
155547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, info->keydata_opad, HMAC_LEN);
155647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Update(&c, thisDigest, MD5_LEN);
155747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	MD5_Final(thisDigest, &c);
155847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
155947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	if (!mDNSPlatformMemSame(thisDigest, thatDigest, MD5_LEN))
156047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		{
156147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		LogMsg("ERROR: DNSDigest_VerifyMessage - bad signature");
156247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*rcode = kDNSFlag1_RC_NotAuth;
156347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		*tcode = TSIG_ErrBadSig;
156447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		ok = mDNSfalse;
156547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		goto exit;
156647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt		}
156747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
156847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	// set remaining rdata fields
156947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	ok = mDNStrue;
157047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
157147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltexit:
157247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
157347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	return ok;
157447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	}
157547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
157647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
157747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef __cplusplus
157847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
157947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
1580