md4c.c revision 6684
1/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm 2 * $FreeBSD: head/lib/libmd/md4c.c 6684 1995-02-24 08:51:34Z phk $ 3 */ 4 5/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved. 6 7 License to copy and use this software is granted provided that it 8 is identified as the "RSA Data Security, Inc. MD4 Message-Digest 9 Algorithm" in all material mentioning or referencing this software 10 or this function. 11 12 License is also granted to make and use derivative works provided 13 that such works are identified as "derived from the RSA Data 14 Security, Inc. MD4 Message-Digest Algorithm" in all material 15 mentioning or referencing the derived work. 16 17 RSA Data Security, Inc. makes no representations concerning either 18 the merchantability of this software or the suitability of this 19 software for any particular purpose. It is provided "as is" 20 without express or implied warranty of any kind. 21 22 These notices must be retained in any copies of any part of this 23 documentation and/or software. 24 */ 25 26#include "md4.h" 27#include <string.h> 28 29typedef unsigned char *POINTER; 30typedef unsigned short int UINT2; 31typedef unsigned long int UINT4; 32 33#define PROTO_LIST(list) list 34 35/* Constants for MD4Transform routine. 36 */ 37#define S11 3 38#define S12 7 39#define S13 11 40#define S14 19 41#define S21 3 42#define S22 5 43#define S23 9 44#define S24 13 45#define S31 3 46#define S32 9 47#define S33 11 48#define S34 15 49 50static void MD4Transform PROTO_LIST ((UINT4 [4], const unsigned char [64])); 51static void Encode PROTO_LIST 52 ((unsigned char *, UINT4 *, unsigned int)); 53static void Decode PROTO_LIST 54 ((UINT4 *, const unsigned char *, unsigned int)); 55 56static unsigned char PADDING[64] = { 57 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 60}; 61 62/* F, G and H are basic MD4 functions. 63 */ 64#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 65#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 66#define H(x, y, z) ((x) ^ (y) ^ (z)) 67 68/* ROTATE_LEFT rotates x left n bits. 69 */ 70#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 71 72/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ 73/* Rotation is separate from addition to prevent recomputation */ 74#define FF(a, b, c, d, x, s) { \ 75 (a) += F ((b), (c), (d)) + (x); \ 76 (a) = ROTATE_LEFT ((a), (s)); \ 77 } 78#define GG(a, b, c, d, x, s) { \ 79 (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \ 80 (a) = ROTATE_LEFT ((a), (s)); \ 81 } 82#define HH(a, b, c, d, x, s) { \ 83 (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \ 84 (a) = ROTATE_LEFT ((a), (s)); \ 85 } 86 87/* MD4 initialization. Begins an MD4 operation, writing a new context. 88 */ 89void MD4Init (context) 90MD4_CTX *context; /* context */ 91{ 92 context->count[0] = context->count[1] = 0; 93 94 /* Load magic initialization constants. 95 */ 96 context->state[0] = 0x67452301; 97 context->state[1] = 0xefcdab89; 98 context->state[2] = 0x98badcfe; 99 context->state[3] = 0x10325476; 100} 101 102/* MD4 block update operation. Continues an MD4 message-digest 103 operation, processing another message block, and updating the 104 context. 105 */ 106void MD4Update (context, input, inputLen) 107MD4_CTX *context; /* context */ 108const unsigned char *input; /* input block */ 109unsigned int inputLen; /* length of input block */ 110{ 111 unsigned int i, index, partLen; 112 113 /* Compute number of bytes mod 64 */ 114 index = (unsigned int)((context->count[0] >> 3) & 0x3F); 115 /* Update number of bits */ 116 if ((context->count[0] += ((UINT4)inputLen << 3)) 117 < ((UINT4)inputLen << 3)) 118 context->count[1]++; 119 context->count[1] += ((UINT4)inputLen >> 29); 120 121 partLen = 64 - index; 122 /* Transform as many times as possible. 123 */ 124 if (inputLen >= partLen) { 125 memcpy 126 ((POINTER)&context->buffer[index], (POINTER)input, partLen); 127 MD4Transform (context->state, context->buffer); 128 129 for (i = partLen; i + 63 < inputLen; i += 64) 130 MD4Transform (context->state, &input[i]); 131 132 index = 0; 133 } 134 else 135 i = 0; 136 137 /* Buffer remaining input */ 138 memcpy 139 ((POINTER)&context->buffer[index], (POINTER)&input[i], 140 inputLen-i); 141} 142 143/* MD4 finalization. Ends an MD4 message-digest operation, writing the 144 the message digest and zeroizing the context. 145 */ 146void MD4Final (digest, context) 147unsigned char digest[16]; /* message digest */ 148MD4_CTX *context; /* context */ 149{ 150 unsigned char bits[8]; 151 unsigned int index, padLen; 152 153 /* Save number of bits */ 154 Encode (bits, context->count, 8); 155 156 /* Pad out to 56 mod 64. 157 */ 158 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 159 padLen = (index < 56) ? (56 - index) : (120 - index); 160 MD4Update (context, PADDING, padLen); 161 162 /* Append length (before padding) */ 163 MD4Update (context, bits, 8); 164 /* Store state in digest */ 165 Encode (digest, context->state, 16); 166 167 /* Zeroize sensitive information. 168 */ 169 memset ((POINTER)context, 0, sizeof (*context)); 170} 171 172/* MD4 basic transformation. Transforms state based on block. 173 */ 174static void MD4Transform (state, block) 175UINT4 state[4]; 176const unsigned char block[64]; 177{ 178 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 179 180 Decode (x, block, 64); 181 182 /* Round 1 */ 183 FF (a, b, c, d, x[ 0], S11); /* 1 */ 184 FF (d, a, b, c, x[ 1], S12); /* 2 */ 185 FF (c, d, a, b, x[ 2], S13); /* 3 */ 186 FF (b, c, d, a, x[ 3], S14); /* 4 */ 187 FF (a, b, c, d, x[ 4], S11); /* 5 */ 188 FF (d, a, b, c, x[ 5], S12); /* 6 */ 189 FF (c, d, a, b, x[ 6], S13); /* 7 */ 190 FF (b, c, d, a, x[ 7], S14); /* 8 */ 191 FF (a, b, c, d, x[ 8], S11); /* 9 */ 192 FF (d, a, b, c, x[ 9], S12); /* 10 */ 193 FF (c, d, a, b, x[10], S13); /* 11 */ 194 FF (b, c, d, a, x[11], S14); /* 12 */ 195 FF (a, b, c, d, x[12], S11); /* 13 */ 196 FF (d, a, b, c, x[13], S12); /* 14 */ 197 FF (c, d, a, b, x[14], S13); /* 15 */ 198 FF (b, c, d, a, x[15], S14); /* 16 */ 199 200 /* Round 2 */ 201 GG (a, b, c, d, x[ 0], S21); /* 17 */ 202 GG (d, a, b, c, x[ 4], S22); /* 18 */ 203 GG (c, d, a, b, x[ 8], S23); /* 19 */ 204 GG (b, c, d, a, x[12], S24); /* 20 */ 205 GG (a, b, c, d, x[ 1], S21); /* 21 */ 206 GG (d, a, b, c, x[ 5], S22); /* 22 */ 207 GG (c, d, a, b, x[ 9], S23); /* 23 */ 208 GG (b, c, d, a, x[13], S24); /* 24 */ 209 GG (a, b, c, d, x[ 2], S21); /* 25 */ 210 GG (d, a, b, c, x[ 6], S22); /* 26 */ 211 GG (c, d, a, b, x[10], S23); /* 27 */ 212 GG (b, c, d, a, x[14], S24); /* 28 */ 213 GG (a, b, c, d, x[ 3], S21); /* 29 */ 214 GG (d, a, b, c, x[ 7], S22); /* 30 */ 215 GG (c, d, a, b, x[11], S23); /* 31 */ 216 GG (b, c, d, a, x[15], S24); /* 32 */ 217 218 /* Round 3 */ 219 HH (a, b, c, d, x[ 0], S31); /* 33 */ 220 HH (d, a, b, c, x[ 8], S32); /* 34 */ 221 HH (c, d, a, b, x[ 4], S33); /* 35 */ 222 HH (b, c, d, a, x[12], S34); /* 36 */ 223 HH (a, b, c, d, x[ 2], S31); /* 37 */ 224 HH (d, a, b, c, x[10], S32); /* 38 */ 225 HH (c, d, a, b, x[ 6], S33); /* 39 */ 226 HH (b, c, d, a, x[14], S34); /* 40 */ 227 HH (a, b, c, d, x[ 1], S31); /* 41 */ 228 HH (d, a, b, c, x[ 9], S32); /* 42 */ 229 HH (c, d, a, b, x[ 5], S33); /* 43 */ 230 HH (b, c, d, a, x[13], S34); /* 44 */ 231 HH (a, b, c, d, x[ 3], S31); /* 45 */ 232 HH (d, a, b, c, x[11], S32); /* 46 */ 233 HH (c, d, a, b, x[ 7], S33); /* 47 */ 234 HH (b, c, d, a, x[15], S34); /* 48 */ 235 236 state[0] += a; 237 state[1] += b; 238 state[2] += c; 239 state[3] += d; 240 241 /* Zeroize sensitive information. 242 */ 243 memset ((POINTER)x, 0, sizeof (x)); 244} 245 246/* Encodes input (UINT4) into output (unsigned char). Assumes len is 247 a multiple of 4. 248 */ 249static void Encode (output, input, len) 250unsigned char *output; 251UINT4 *input; 252unsigned int len; 253{ 254 unsigned int i, j; 255 256 for (i = 0, j = 0; j < len; i++, j += 4) { 257 output[j] = (unsigned char)(input[i] & 0xff); 258 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 259 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 260 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 261 } 262} 263 264/* Decodes input (unsigned char) into output (UINT4). Assumes len is 265 a multiple of 4. 266 */ 267static void Decode (output, input, len) 268 269UINT4 *output; 270const unsigned char *input; 271unsigned int len; 272{ 273 unsigned int i, j; 274 275 for (i = 0, j = 0; j < len; i++, j += 4) 276 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 277 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); 278} 279