1/* $Id: pc_md5.c 14574 2005-10-29 16:27:43Z bonefish $ 2 * 3 * PDFlib MD5 message digest routines 4 * 5 */ 6 7/* This is a slightly modified version of the RSA reference 8 * implementation for MD5, which originally contained 9 * the following copyright notice: 10 */ 11 12/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 13 rights reserved. 14 15 License to copy and use this software is granted provided that it 16 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 17 Algorithm" in all material mentioning or referencing this software 18 or this function. 19 20 License is also granted to make and use derivative works provided 21 that such works are identified as "derived from the RSA Data 22 Security, Inc. MD5 Message-Digest Algorithm" in all material 23 mentioning or referencing the derived work. 24 25 RSA Data Security, Inc. makes no representations concerning either 26 the merchantability of this software or the suitability of this 27 software for any particular purpose. It is provided "as is" 28 without express or implied warranty of any kind. 29 30 These notices must be retained in any copies of any part of this 31 documentation and/or software. 32*/ 33 34#include <string.h> 35 36#include "pc_util.h" 37#include "pc_md5.h" 38 39/* Constants for MD5_Transform routine. 40 */ 41#define S11 7 42#define S12 12 43#define S13 17 44#define S14 22 45#define S21 5 46#define S22 9 47#define S23 14 48#define S24 20 49#define S31 4 50#define S32 11 51#define S33 16 52#define S34 23 53#define S41 6 54#define S42 10 55#define S43 15 56#define S44 21 57 58static unsigned char PADDING[64] = { 59 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 62}; 63 64/* F, G, H and I are basic MD5 functions. 65 */ 66#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 67#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 68#define H(x, y, z) ((x) ^ (y) ^ (z)) 69#define I(x, y, z) ((y) ^ ((x) | (~z))) 70 71/* ROTATE_LEFT rotates x left n bits. 72 */ 73#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 74 75/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 76 * Rotation is separate from addition to prevent recomputation. 77 */ 78#define FF(a, b, c, d, x, s, ac) { \ 79 (a) += F ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ 80 (a) = ROTATE_LEFT ((a), (s)); \ 81 (a) += (b); \ 82} 83#define GG(a, b, c, d, x, s, ac) { \ 84 (a) += G ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ 85 (a) = ROTATE_LEFT ((a), (s)); \ 86 (a) += (b); \ 87} 88#define HH(a, b, c, d, x, s, ac) { \ 89 (a) += H ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ 90 (a) = ROTATE_LEFT ((a), (s)); \ 91 (a) += (b); \ 92} 93#define II(a, b, c, d, x, s, ac) { \ 94 (a) += I ((b), (c), (d)) + (x) + (MD5_UINT4)(ac); \ 95 (a) = ROTATE_LEFT ((a), (s)); \ 96 (a) += (b); \ 97} 98 99 100/* Encodes input (MD5_UINT4) into output (unsigned char). Assumes len is 101 * a multiple of 4. 102 */ 103static void Encode(unsigned char *output, MD5_UINT4 *input, unsigned int len) 104{ 105 unsigned int i, j; 106 107 for (i = 0, j = 0; j < len; i++, j += 4) { 108 output[j] = (unsigned char) (input[i] & 0xff); 109 output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff); 110 output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff); 111 output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff); 112 } 113} 114 115/* Decodes input (unsigned char) into output (MD5_UINT4). Assumes len is 116 * a multiple of 4. 117 */ 118static void Decode( 119 MD5_UINT4 *output, 120 const unsigned char *input, 121 unsigned int len) 122{ 123 unsigned int i, j; 124 125 for (i = 0, j = 0; j < len; i++, j += 4) 126 output[i] = ((MD5_UINT4) input[j]) | 127 (((MD5_UINT4) input[j+1]) << 8) | 128 (((MD5_UINT4) input[j+2]) << 16) | 129 (((MD5_UINT4) input[j+3]) << 24); 130} 131 132/* MD5 basic transformation. Transforms state based on block. 133 */ 134static void MD5_Transform(MD5_UINT4 state[4], const unsigned char block[64]) 135{ 136 MD5_UINT4 a = state[0]; 137 MD5_UINT4 b = state[1]; 138 MD5_UINT4 c = state[2]; 139 MD5_UINT4 d = state[3]; 140 MD5_UINT4 x[16]; 141 142 Decode(x, block, 64); 143 144 /* Round 1 */ 145 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 146 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 147 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 148 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 149 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 150 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 151 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 152 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 153 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 154 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 155 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 156 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 157 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 158 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 159 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 160 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 161 162 /* Round 2 */ 163 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 164 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 165 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 166 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 167 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 168 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 169 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 170 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 171 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 172 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 173 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 174 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 175 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 176 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 177 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 178 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 179 180 /* Round 3 */ 181 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 182 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 183 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 184 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 185 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 186 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 187 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 188 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 189 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 190 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 191 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 192 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ 193 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 194 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 195 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 196 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 197 198 /* Round 4 */ 199 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 200 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 201 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 202 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 203 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 204 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 205 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 206 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 207 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 208 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 209 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 210 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 211 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 212 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 213 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 214 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 215 216 state[0] += a; 217 state[1] += b; 218 state[2] += c; 219 state[3] += d; 220 221 /* Zeroize sensitive information. 222 */ 223 memset (x, 0, sizeof (x)); 224} 225 226/* MD5 initialization. Begins an MD5 operation, writing a new context. 227 */ 228void MD5_Init(MD5_CTX *context) 229{ 230 context->count[0] = context->count[1] = 0; 231 232 /* Load magic initialization constants. 233 */ 234 context->state[0] = 0x67452301; 235 context->state[1] = 0xefcdab89; 236 context->state[2] = 0x98badcfe; 237 context->state[3] = 0x10325476; 238} 239 240/* MD5 block update operation. Continues an MD5 message-digest 241 * operation, processing another message block, and updating the 242 * context. 243 */ 244void MD5_Update( 245 MD5_CTX *context, 246 const unsigned char *input, 247 unsigned int inputLen) 248{ 249 unsigned int i, idx, partLen; 250 251 /* Compute number of bytes mod 64 */ 252 idx = (unsigned int) ((context->count[0] >> 3) & 0x3F); 253 254 /* Update number of bits */ 255 if ((context->count[0] += ((MD5_UINT4) inputLen << 3)) 256 < ((MD5_UINT4) inputLen << 3)) 257 context->count[1]++; 258 259 context->count[1] += ((MD5_UINT4) inputLen >> 29); 260 261 partLen = 64 - idx; 262 263 /* Transform as many times as possible. 264 */ 265 if (inputLen >= partLen) { 266 memcpy(&context->buffer[idx], input, partLen); 267 MD5_Transform(context->state, context->buffer); 268 269 for (i = partLen; i + 63 < inputLen; i += 64) 270 MD5_Transform (context->state, &input[i]); 271 272 idx = 0; 273 } 274 else 275 i = 0; 276 277 /* Buffer remaining input */ 278 memcpy(&context->buffer[idx], &input[i], inputLen - i); 279} 280 281/* MD5 finalization. Ends an MD5 message-digest operation, writing the 282 * the message digest and zeroizing the context. 283 */ 284void MD5_Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *context) 285{ 286 unsigned char bits[8]; 287 unsigned int idx, padLen; 288 289 /* Save number of bits */ 290 Encode(bits, context->count, 8); 291 292 /* Pad out to 56 mod 64. 293 */ 294 idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); 295 padLen = (idx < 56) ? (56 - idx) : (120 - idx); 296 MD5_Update(context, PADDING, padLen); 297 298 /* Append length (before padding) */ 299 MD5_Update(context, bits, 8); 300 301 /* Store state in digest */ 302 Encode(digest, context->state, 16); 303 304 /* Zeroize sensitive information. 305 */ 306 memset(context, 0, sizeof (*context)); 307} 308