/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Function names changed to avoid namespace collisions: Rob Siemborski */
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
*/
#include <config.h>
#include "md5global.h"
#ifdef _HAVE_LIB_MD5
/*
* If libmd5 is available, we will use it.
* sasl_hmac_md5* functions are still needed.
*/
#include "md5_private.h"
#else
#include "md5.h"
#endif /* _HAVE_LIB_MD5 */
#include "hmac-md5.h"
#ifndef WIN32
#endif
/* Constants for MD5Transform routine.
*/
#ifdef _HAVE_LIB_MD5
#else
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif /* _HAVE_LIB_MD5 */
/* F, G, H and I are basic MD5 functions.
*/
#ifdef I
/* This might be defined via NANA */
#undef I
#endif
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
#ifndef _HAVE_LIB_MD5
{
/* Load magic initialization constants. */
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the context.
*/
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
/* Compute number of bytes mod 64 */
/* Update number of bits */
/* Transform as many times as possible.
*/
index = 0;
}
else
i = 0;
/* Buffer remaining input */
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
{
/* Save number of bits */
/* Pad out to 56 mod 64. */
/* Append length (before padding) */
/* Store state in digest */
/* Zeroize sensitive information. */
}
/* MD5 basic transformation. Transforms state based on block. */
unsigned char block[64];
{
/* Round 1 */
/* Round 2 */
/* Round 3 */
/* Round 4 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
unsigned char *output;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
}
/* Note: Replace "for loop" with standard memset if possible.
*/
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
}
#endif /* !_HAVE_LIB_MD5 */
const unsigned char *key,
int key_len)
{
* key XORd with ipad
*/
* key XORd with opad
*/
int i;
/* if key is longer than 64 bytes reset it to key=MD5(key) */
if (key_len > 64) {
key_len = 16;
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in pads */
/* XOR key with ipad and opad values */
for (i=0; i<64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
/* scrub the pads and key context (if used) */
/* and we're done. */
}
/* The precalc and import routines here rely on the fact that we pad
* the key out to 64 bytes and use that to initialize the md5
* contexts, and that updating an md5 context with 64 bytes of data
* leaves nothing left over; all of the interesting state is contained
* in the state field, and none of it is left over in the count and
* buffer fields. So all we have to do is save the state field; we
* can zero the others when we reload it. Which is why the decision
* was made to pad the key out to 64 bytes in the first place. */
const unsigned char *key,
int key_len)
{
unsigned lupe;
}
}
{
unsigned lupe;
}
/* Init the counts to account for our having applied
* 64 bytes of key; this works out to 0x200 (64 << 3; see
* MD5Update above...) */
}
{
}
const unsigned char* text; /* pointer to data stream */
int text_len; /* length of data stream */
const unsigned char* key; /* pointer to authentication key */
int key_len; /* length of authentication key */
unsigned char *digest; /* caller digest to be filled in */
{
* key XORd with ipad
*/
* key XORd with opad
*/
int i;
/* if key is longer than 64 bytes reset it to key=MD5(key) */
if (key_len > 64) {
key_len = 16;
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in pads */
/* XOR key with ipad and opad values */
for (i=0; i<64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
/*
* perform inner MD5
*/
* pass */
/*
* perform outer MD5
*/
* pass */
* hash */
}