md5.c revision 22bed621ef87bc8b6c1fea599b02c4b38dd6bf48
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley/*
7d98a1783f222964bcde7d56dab77b822706204dBob Halley * Copyright (C) 2000, 2001, 2004, 2005, 2007, 2009, 2014-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * This Source Code Form is subject to the terms of the Mozilla Public
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * License, v. 2.0. If a copy of the MPL was not distributed with this
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * file, You can obtain one at http://mozilla.org/MPL/2.0/.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence */
15a44745412679c30a6d022733925af70a38b715David Lawrence
15a44745412679c30a6d022733925af70a38b715David Lawrence/* $Id: md5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */
15a44745412679c30a6d022733925af70a38b715David Lawrence
15a44745412679c30a6d022733925af70a38b715David Lawrence/*! \file
15a44745412679c30a6d022733925af70a38b715David Lawrence * This code implements the MD5 message-digest algorithm.
15a44745412679c30a6d022733925af70a38b715David Lawrence * The algorithm is due to Ron Rivest. This code was
15a44745412679c30a6d022733925af70a38b715David Lawrence * written by Colin Plumb in 1993, no copyright is claimed.
15a44745412679c30a6d022733925af70a38b715David Lawrence * This code is in the public domain; do with it what you wish.
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley *
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * Equivalent code is available from RSA Data Security, Inc.
8f7cae3d7b0c122c3b17e8409bbb80005433acd2Brian Wellington * This code has been tested against that, and is equivalent,
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * except that you don't need to include two pages of legalese
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * with every copy.
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley *
8f7cae3d7b0c122c3b17e8409bbb80005433acd2Brian Wellington * To compute the message digest of a chunk of bytes, declare an
8f7cae3d7b0c122c3b17e8409bbb80005433acd2Brian Wellington * MD5Context structure, pass it to MD5Init, call MD5Update as
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * needed on buffers full of bytes, and then call MD5Final, which
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * will fill a supplied 16-byte array with the digest.
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley */
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include "config.h"
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <pk11/site.h>
5fe5a0c02634eaadfcbc3528bf2c184557110a3bAndreas Gustafsson
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#ifndef PK11_MD5_DISABLE
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson#include <isc/assertions.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <isc/md5.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <isc/platform.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <isc/string.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <isc/types.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#if PKCS11CRYPTO
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <pk11/internal.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <pk11/pk11.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#endif
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#include <isc/util.h>
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#ifdef ISC_PLATFORM_OPENSSLHASH
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson#define EVP_MD_CTX_new() &(ctx->_ctx)
8327c62a49a2487d29a37acbed6b602e629fc0eeAndreas Gustafsson#define EVP_MD_CTX_free(ptr) EVP_MD_CTX_cleanup(ptr)
608f870f4821972313eadc5388a42fa55b6279d1Mark Andrews#endif
878d3073b13833ee1a50dfeabf8e400b6fdfc754Brian Wellington
878d3073b13833ee1a50dfeabf8e400b6fdfc754Brian Wellingtonvoid
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halleyisc_md5_init(isc_md5_t *ctx) {
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley ctx->ctx = EVP_MD_CTX_new();
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley RUNTIME_CHECK(ctx->ctx != NULL);
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley RUNTIME_CHECK(EVP_DigestInit(ctx->ctx, EVP_md5()) == 1);
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson}
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrencevoid
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halleyisc_md5_invalidate(isc_md5_t *ctx) {
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley EVP_MD_CTX_free(ctx->ctx);
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley ctx->ctx = NULL;
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley}
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halley
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halleyvoid
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halleyisc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence if (len == 0U)
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley return;
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley RUNTIME_CHECK(EVP_DigestUpdate(ctx->ctx,
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence (const void *) buf,
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrence (size_t) len) == 1);
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley}
c90f5e8d1edbd5c277f2ee320167a12a30ba7c7bMichael Graff
edcd1247ad7e81bb8b430e610d9718f64c70f05dDavid Lawrencevoid
c90f5e8d1edbd5c277f2ee320167a12a30ba7c7bMichael Graffisc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halley RUNTIME_CHECK(EVP_DigestFinal(ctx->ctx, digest, NULL) == 1);
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson EVP_MD_CTX_free(ctx->ctx);
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->ctx = NULL;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson}
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson#elif PKCS11CRYPTO
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafssonvoid
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafssonisc_md5_init(isc_md5_t *ctx) {
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson CK_RV rv;
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson ISC_FALSE, NULL, 0) == ISC_R_SUCCESS);
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson}
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafssonvoid
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafssonisc_md5_invalidate(isc_md5_t *ctx) {
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson CK_BYTE garbage[ISC_MD5_DIGESTLENGTH];
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson CK_ULONG len = ISC_MD5_DIGESTLENGTH;
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson if (ctx->handle == NULL)
e02c696ea586f8dcc7c6145cc0f143f887960cd4Andreas Gustafsson return;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence (void) pkcs_C_DigestFinal(ctx->session, garbage, &len);
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halley memset(garbage, 0, sizeof(garbage));
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson pk11_return_session(ctx);
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson}
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halleyvoid
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafssonisc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson CK_RV rv;
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson CK_BYTE_PTR pPart;
44fee668021c7ceef4ee1c848031d883a508b359James Brister
44fee668021c7ceef4ee1c848031d883a508b359James Brister DE_CONST(buf, pPart);
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson PK11_FATALCHECK(pkcs_C_DigestUpdate,
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson (ctx->session, pPart, (CK_ULONG) len));
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson}
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafssonvoid
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafssonisc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson CK_RV rv;
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson CK_ULONG len = ISC_MD5_DIGESTLENGTH;
44fee668021c7ceef4ee1c848031d883a508b359James Brister
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson PK11_FATALCHECK(pkcs_C_DigestFinal,
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson (ctx->session, (CK_BYTE_PTR) digest, &len));
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson pk11_return_session(ctx);
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson}
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson#else
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafssonstatic void
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas GustafssonbyteSwap(isc_uint32_t *buf, unsigned words)
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson{
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson unsigned char *p = (unsigned char *)buf;
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson do {
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson *buf++ = (isc_uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 |
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ((unsigned)p[1] << 8 | p[0]);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence p += 4;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson } while (--words);
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson}
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson/*!
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson * initialization constants.
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson */
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafssonvoid
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafssonisc_md5_init(isc_md5_t *ctx) {
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->buf[0] = 0x67452301;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->buf[1] = 0xefcdab89;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->buf[2] = 0x98badcfe;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->buf[3] = 0x10325476;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->bytes[0] = 0;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson ctx->bytes[1] = 0;
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson}
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafssonvoid
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafssonisc_md5_invalidate(isc_md5_t *ctx) {
7193a1762e428cfba06907e51fa9e4bce3b5569aAndreas Gustafsson memset(ctx, 0, sizeof(isc_md5_t));
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson}
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson/*@{*/
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson/*! The four core functions - F1 is optimized somewhat */
5542df09597c479be604da0ece8271cbc6fd9c4aDavid Lawrence
5542df09597c479be604da0ece8271cbc6fd9c4aDavid Lawrence/* #define F1(x, y, z) (x & y | ~x & z) */
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#define F1(x, y, z) (z ^ (x & (y ^ z)))
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley#define F2(x, y, z) F1(z, x, y)
11d435aa4cf77e035445978f7e3776a3589715fdAndreas Gustafsson#define F3(x, y, z) (x ^ y ^ z)
5542df09597c479be604da0ece8271cbc6fd9c4aDavid Lawrence#define F4(x, y, z) (y ^ (x | ~z))
5542df09597c479be604da0ece8271cbc6fd9c4aDavid Lawrence/*@}*/
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley/*! This is the central step in the MD5 algorithm. */
8582a1e113c13886ccbd1b534d6c240315767be6Bob Halley#define MD5STEP(f,w,x,y,z,in,s) \
a0f6cda5fd9f2fcc4154bb63628f849b639a40caAndreas Gustafsson (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley/*!
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * The core of the MD5 algorithm, this alters an existing MD5 hash to
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * reflect the addition of 16 longwords of new data. MD5Update blocks
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley * the data and converts bytes into longwords for this routine.
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley */
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halleystatic void
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halleytransform(isc_uint32_t buf[4], isc_uint32_t const in[16]) {
1687985cdfc3a4c330c5bdb02c131835f8756e3cBob Halley register isc_uint32_t a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
/*!
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
isc_uint32_t t;
/* Update byte count */
t = ctx->bytes[0];
if ((ctx->bytes[0] = t + len) < t)
ctx->bytes[1]++; /* Carry from low to high */
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
if (t > len) {
memmove((unsigned char *)ctx->in + 64 - t, buf, len);
return;
}
/* First chunk is an odd size */
memmove((unsigned char *)ctx->in + 64 - t, buf, t);
byteSwap(ctx->in, 16);
transform(ctx->buf, ctx->in);
buf += t;
len -= t;
/* Process data in 64-byte chunks */
while (len >= 64) {
memmove(ctx->in, buf, 64);
byteSwap(ctx->in, 16);
transform(ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memmove(ctx->in, buf, len);
}
/*!
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
unsigned char *p = (unsigned char *)ctx->in + count;
/* Set the first char of padding to 0x80. There is always room. */
*p++ = 0x80;
/* Bytes of padding needed to make 56 bytes (-8..55) */
count = 56 - 1 - count;
if (count < 0) { /* Padding forces an extra block */
memset(p, 0, count + 8);
byteSwap(ctx->in, 16);
transform(ctx->buf, ctx->in);
p = (unsigned char *)ctx->in;
count = 56;
}
memset(p, 0, count);
byteSwap(ctx->in, 14);
/* Append length in bits and transform */
ctx->in[14] = ctx->bytes[0] << 3;
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
transform(ctx->buf, ctx->in);
byteSwap(ctx->buf, 4);
memmove(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */
}
#endif
#else /* !PK11_MD5_DISABLE */
#ifdef WIN32
/* Make the Visual Studio linker happy */
#include <isc/util.h>
void isc_md5_final() { INSIST(0); }
void isc_md5_init() { INSIST(0); }
void isc_md5_invalidate() { INSIST(0); }
void isc_md5_update() { INSIST(0); }
#endif
#endif /* PK11_MD5_DISABLE */