1*7c2fbfb3SApril Chin /*********************************************************************** 2*7c2fbfb3SApril Chin * * 3*7c2fbfb3SApril Chin * This software is part of the ast package * 4*7c2fbfb3SApril Chin * Copyright (c) 1996-2008 AT&T Intellectual Property * 5*7c2fbfb3SApril Chin * and is licensed under the * 6*7c2fbfb3SApril Chin * Common Public License, Version 1.0 * 7*7c2fbfb3SApril Chin * by AT&T Intellectual Property * 8*7c2fbfb3SApril Chin * * 9*7c2fbfb3SApril Chin * A copy of the License is available at * 10*7c2fbfb3SApril Chin * http://www.opensource.org/licenses/cpl1.0.txt * 11*7c2fbfb3SApril Chin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*7c2fbfb3SApril Chin * * 13*7c2fbfb3SApril Chin * Information and Software Systems Research * 14*7c2fbfb3SApril Chin * AT&T Research * 15*7c2fbfb3SApril Chin * Florham Park NJ * 16*7c2fbfb3SApril Chin * * 17*7c2fbfb3SApril Chin * Glenn Fowler <gsf@research.att.com> * 18*7c2fbfb3SApril Chin * * 19*7c2fbfb3SApril Chin ***********************************************************************/ 20*7c2fbfb3SApril Chin #pragma prototyped 21*7c2fbfb3SApril Chin 22*7c2fbfb3SApril Chin /* 23*7c2fbfb3SApril Chin * md5 24*7c2fbfb3SApril Chin */ 25*7c2fbfb3SApril Chin 26*7c2fbfb3SApril Chin /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 27*7c2fbfb3SApril Chin rights reserved. 28*7c2fbfb3SApril Chin 29*7c2fbfb3SApril Chin License to copy and use this software is granted provided that it 30*7c2fbfb3SApril Chin is identified as the "RSA Data Security, Inc. MD5 Message-Digest 31*7c2fbfb3SApril Chin Method" in all material mentioning or referencing this software 32*7c2fbfb3SApril Chin or this function. 33*7c2fbfb3SApril Chin 34*7c2fbfb3SApril Chin License is also granted to make and use derivative works provided 35*7c2fbfb3SApril Chin that such works are identified as "derived from the RSA Data 36*7c2fbfb3SApril Chin Security, Inc. MD5 Message-Digest Method" in all material 37*7c2fbfb3SApril Chin mentioning or referencing the derived work. 38*7c2fbfb3SApril Chin 39*7c2fbfb3SApril Chin RSA Data Security, Inc. makes no representations concerning either 40*7c2fbfb3SApril Chin the merchantability of this software or the suitability of this 41*7c2fbfb3SApril Chin software for any particular purpose. It is provided "as is" 42*7c2fbfb3SApril Chin without express or implied warranty of any kind. 43*7c2fbfb3SApril Chin 44*7c2fbfb3SApril Chin These notices must be retained in any copies of any part of this 45*7c2fbfb3SApril Chin documentation and/or software. 46*7c2fbfb3SApril Chin */ 47*7c2fbfb3SApril Chin 48*7c2fbfb3SApril Chin #define md5_description \ 49*7c2fbfb3SApril Chin "The RSA Data Security, Inc. MD5 Message-Digest Method, 1991-2, \ 50*7c2fbfb3SApril Chin used with permission. The block count is not printed." 51*7c2fbfb3SApril Chin #define md5_options "[+(version)?md5 (RSA Data Security, Inc. MD5 Message-Digest, 1991-2) 1996-02-29]" 52*7c2fbfb3SApril Chin #define md5_match "md5|MD5" 53*7c2fbfb3SApril Chin #define md5_scale 0 54*7c2fbfb3SApril Chin 55*7c2fbfb3SApril Chin typedef uint32_t UINT4; 56*7c2fbfb3SApril Chin 57*7c2fbfb3SApril Chin typedef struct Md5_s 58*7c2fbfb3SApril Chin { 59*7c2fbfb3SApril Chin _SUM_PUBLIC_ 60*7c2fbfb3SApril Chin _SUM_PRIVATE_ 61*7c2fbfb3SApril Chin UINT4 state[4]; /* state (ABCD) */ 62*7c2fbfb3SApril Chin UINT4 count[2]; /* # bits handled mod 2^64 (lsb)*/ 63*7c2fbfb3SApril Chin unsigned char buffer[64]; /* input buffer */ 64*7c2fbfb3SApril Chin unsigned char digest[16]; /* final digest */ 65*7c2fbfb3SApril Chin unsigned char digest_sum[16]; /* sum of all digests */ 66*7c2fbfb3SApril Chin } Md5_t; 67*7c2fbfb3SApril Chin 68*7c2fbfb3SApril Chin static const unsigned char md5_pad[] = 69*7c2fbfb3SApril Chin { 70*7c2fbfb3SApril Chin 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77*7c2fbfb3SApril Chin 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 78*7c2fbfb3SApril Chin }; 79*7c2fbfb3SApril Chin 80*7c2fbfb3SApril Chin /* 81*7c2fbfb3SApril Chin * encode input into output 82*7c2fbfb3SApril Chin * len must be a multiple of 4 83*7c2fbfb3SApril Chin */ 84*7c2fbfb3SApril Chin 85*7c2fbfb3SApril Chin static void 86*7c2fbfb3SApril Chin md5_encode(register unsigned char* output, register UINT4* input, unsigned int len) 87*7c2fbfb3SApril Chin { 88*7c2fbfb3SApril Chin register unsigned int i; 89*7c2fbfb3SApril Chin register unsigned int j; 90*7c2fbfb3SApril Chin 91*7c2fbfb3SApril Chin for (i = j = 0; j < len; i++, j += 4) 92*7c2fbfb3SApril Chin { 93*7c2fbfb3SApril Chin output[j] = (unsigned char)(input[i] & 0xff); 94*7c2fbfb3SApril Chin output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 95*7c2fbfb3SApril Chin output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 96*7c2fbfb3SApril Chin output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 97*7c2fbfb3SApril Chin } 98*7c2fbfb3SApril Chin } 99*7c2fbfb3SApril Chin 100*7c2fbfb3SApril Chin /* 101*7c2fbfb3SApril Chin * decode input into output 102*7c2fbfb3SApril Chin * len must be a multiple of 4 103*7c2fbfb3SApril Chin */ 104*7c2fbfb3SApril Chin 105*7c2fbfb3SApril Chin static void 106*7c2fbfb3SApril Chin md5_decode(register UINT4* output, register unsigned char* input, unsigned int len) 107*7c2fbfb3SApril Chin { 108*7c2fbfb3SApril Chin unsigned int i; 109*7c2fbfb3SApril Chin unsigned int j; 110*7c2fbfb3SApril Chin 111*7c2fbfb3SApril Chin for (i = j = 0; j < len; i++, j += 4) 112*7c2fbfb3SApril Chin output[i] = ((UINT4)input[j]) | 113*7c2fbfb3SApril Chin (((UINT4)input[j+1]) << 8) | 114*7c2fbfb3SApril Chin (((UINT4)input[j+2]) << 16) | 115*7c2fbfb3SApril Chin (((UINT4)input[j+3]) << 24); 116*7c2fbfb3SApril Chin } 117*7c2fbfb3SApril Chin 118*7c2fbfb3SApril Chin static int 119*7c2fbfb3SApril Chin md5_init(Sum_t* p) 120*7c2fbfb3SApril Chin { 121*7c2fbfb3SApril Chin register Md5_t* context = (Md5_t*)p; 122*7c2fbfb3SApril Chin 123*7c2fbfb3SApril Chin context->count[0] = context->count[1] = 0; 124*7c2fbfb3SApril Chin context->state[0] = 0x67452301; 125*7c2fbfb3SApril Chin context->state[1] = 0xefcdab89; 126*7c2fbfb3SApril Chin context->state[2] = 0x98badcfe; 127*7c2fbfb3SApril Chin context->state[3] = 0x10325476; 128*7c2fbfb3SApril Chin return 0; 129*7c2fbfb3SApril Chin } 130*7c2fbfb3SApril Chin 131*7c2fbfb3SApril Chin static Sum_t* 132*7c2fbfb3SApril Chin md5_open(const Method_t* method, const char* name) 133*7c2fbfb3SApril Chin { 134*7c2fbfb3SApril Chin Md5_t* p; 135*7c2fbfb3SApril Chin 136*7c2fbfb3SApril Chin if (p = newof(0, Md5_t, 1, 0)) 137*7c2fbfb3SApril Chin { 138*7c2fbfb3SApril Chin p->method = (Method_t*)method; 139*7c2fbfb3SApril Chin p->name = name; 140*7c2fbfb3SApril Chin md5_init((Sum_t*)p); 141*7c2fbfb3SApril Chin } 142*7c2fbfb3SApril Chin return (Sum_t*)p; 143*7c2fbfb3SApril Chin } 144*7c2fbfb3SApril Chin 145*7c2fbfb3SApril Chin /* 146*7c2fbfb3SApril Chin * basic MD5 step -- transforms buf based on in 147*7c2fbfb3SApril Chin */ 148*7c2fbfb3SApril Chin 149*7c2fbfb3SApril Chin #define S11 7 150*7c2fbfb3SApril Chin #define S12 12 151*7c2fbfb3SApril Chin #define S13 17 152*7c2fbfb3SApril Chin #define S14 22 153*7c2fbfb3SApril Chin #define S21 5 154*7c2fbfb3SApril Chin #define S22 9 155*7c2fbfb3SApril Chin #define S23 14 156*7c2fbfb3SApril Chin #define S24 20 157*7c2fbfb3SApril Chin #define S31 4 158*7c2fbfb3SApril Chin #define S32 11 159*7c2fbfb3SApril Chin #define S33 16 160*7c2fbfb3SApril Chin #define S34 23 161*7c2fbfb3SApril Chin #define S41 6 162*7c2fbfb3SApril Chin #define S42 10 163*7c2fbfb3SApril Chin #define S43 15 164*7c2fbfb3SApril Chin #define S44 21 165*7c2fbfb3SApril Chin 166*7c2fbfb3SApril Chin /* F, G, H and I are basic MD5 functions */ 167*7c2fbfb3SApril Chin #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 168*7c2fbfb3SApril Chin #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 169*7c2fbfb3SApril Chin #define H(x, y, z) ((x) ^ (y) ^ (z)) 170*7c2fbfb3SApril Chin #define I(x, y, z) ((y) ^ ((x) | (~z))) 171*7c2fbfb3SApril Chin 172*7c2fbfb3SApril Chin /* ROTATE_LEFT rotates x left n bits */ 173*7c2fbfb3SApril Chin #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 174*7c2fbfb3SApril Chin 175*7c2fbfb3SApril Chin /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ 176*7c2fbfb3SApril Chin /* Rotation is separate from addition to prevent recomputation */ 177*7c2fbfb3SApril Chin #define FF(a, b, c, d, x, s, ac) { \ 178*7c2fbfb3SApril Chin (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 179*7c2fbfb3SApril Chin (a) = ROTATE_LEFT ((a), (s)); \ 180*7c2fbfb3SApril Chin (a) += (b); \ 181*7c2fbfb3SApril Chin } 182*7c2fbfb3SApril Chin #define GG(a, b, c, d, x, s, ac) { \ 183*7c2fbfb3SApril Chin (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 184*7c2fbfb3SApril Chin (a) = ROTATE_LEFT ((a), (s)); \ 185*7c2fbfb3SApril Chin (a) += (b); \ 186*7c2fbfb3SApril Chin } 187*7c2fbfb3SApril Chin #define HH(a, b, c, d, x, s, ac) { \ 188*7c2fbfb3SApril Chin (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 189*7c2fbfb3SApril Chin (a) = ROTATE_LEFT ((a), (s)); \ 190*7c2fbfb3SApril Chin (a) += (b); \ 191*7c2fbfb3SApril Chin } 192*7c2fbfb3SApril Chin #define II(a, b, c, d, x, s, ac) { \ 193*7c2fbfb3SApril Chin (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 194*7c2fbfb3SApril Chin (a) = ROTATE_LEFT ((a), (s)); \ 195*7c2fbfb3SApril Chin (a) += (b); \ 196*7c2fbfb3SApril Chin } 197*7c2fbfb3SApril Chin 198*7c2fbfb3SApril Chin static void 199*7c2fbfb3SApril Chin md5_transform(UINT4 state[4], unsigned char block[64]) 200*7c2fbfb3SApril Chin { 201*7c2fbfb3SApril Chin UINT4 a = state[0]; 202*7c2fbfb3SApril Chin UINT4 b = state[1]; 203*7c2fbfb3SApril Chin UINT4 c = state[2]; 204*7c2fbfb3SApril Chin UINT4 d = state[3]; 205*7c2fbfb3SApril Chin UINT4 x[16]; 206*7c2fbfb3SApril Chin 207*7c2fbfb3SApril Chin md5_decode(x, block, 64); 208*7c2fbfb3SApril Chin 209*7c2fbfb3SApril Chin /* round 1 */ 210*7c2fbfb3SApril Chin FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 211*7c2fbfb3SApril Chin FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 212*7c2fbfb3SApril Chin FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 213*7c2fbfb3SApril Chin FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 214*7c2fbfb3SApril Chin FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 215*7c2fbfb3SApril Chin FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 216*7c2fbfb3SApril Chin FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 217*7c2fbfb3SApril Chin FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 218*7c2fbfb3SApril Chin FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 219*7c2fbfb3SApril Chin FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 220*7c2fbfb3SApril Chin FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 221*7c2fbfb3SApril Chin FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 222*7c2fbfb3SApril Chin FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 223*7c2fbfb3SApril Chin FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 224*7c2fbfb3SApril Chin FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 225*7c2fbfb3SApril Chin FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 226*7c2fbfb3SApril Chin 227*7c2fbfb3SApril Chin /* round 2 */ 228*7c2fbfb3SApril Chin GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 229*7c2fbfb3SApril Chin GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 230*7c2fbfb3SApril Chin GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 231*7c2fbfb3SApril Chin GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 232*7c2fbfb3SApril Chin GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 233*7c2fbfb3SApril Chin GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */ 234*7c2fbfb3SApril Chin GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 235*7c2fbfb3SApril Chin GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 236*7c2fbfb3SApril Chin GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 237*7c2fbfb3SApril Chin GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 238*7c2fbfb3SApril Chin GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 239*7c2fbfb3SApril Chin GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 240*7c2fbfb3SApril Chin GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 241*7c2fbfb3SApril Chin GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 242*7c2fbfb3SApril Chin GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 243*7c2fbfb3SApril Chin GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 244*7c2fbfb3SApril Chin 245*7c2fbfb3SApril Chin /* round 3 */ 246*7c2fbfb3SApril Chin HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 247*7c2fbfb3SApril Chin HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 248*7c2fbfb3SApril Chin HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 249*7c2fbfb3SApril Chin HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 250*7c2fbfb3SApril Chin HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 251*7c2fbfb3SApril Chin HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 252*7c2fbfb3SApril Chin HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 253*7c2fbfb3SApril Chin HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 254*7c2fbfb3SApril Chin HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 255*7c2fbfb3SApril Chin HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 256*7c2fbfb3SApril Chin HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 257*7c2fbfb3SApril Chin HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */ 258*7c2fbfb3SApril Chin HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 259*7c2fbfb3SApril Chin HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 260*7c2fbfb3SApril Chin HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 261*7c2fbfb3SApril Chin HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 262*7c2fbfb3SApril Chin 263*7c2fbfb3SApril Chin /* round 4 */ 264*7c2fbfb3SApril Chin II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 265*7c2fbfb3SApril Chin II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 266*7c2fbfb3SApril Chin II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 267*7c2fbfb3SApril Chin II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 268*7c2fbfb3SApril Chin II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 269*7c2fbfb3SApril Chin II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 270*7c2fbfb3SApril Chin II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 271*7c2fbfb3SApril Chin II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 272*7c2fbfb3SApril Chin II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 273*7c2fbfb3SApril Chin II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 274*7c2fbfb3SApril Chin II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 275*7c2fbfb3SApril Chin II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 276*7c2fbfb3SApril Chin II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 277*7c2fbfb3SApril Chin II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 278*7c2fbfb3SApril Chin II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 279*7c2fbfb3SApril Chin II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 280*7c2fbfb3SApril Chin 281*7c2fbfb3SApril Chin state[0] += a; 282*7c2fbfb3SApril Chin state[1] += b; 283*7c2fbfb3SApril Chin state[2] += c; 284*7c2fbfb3SApril Chin state[3] += d; 285*7c2fbfb3SApril Chin } 286*7c2fbfb3SApril Chin 287*7c2fbfb3SApril Chin static int 288*7c2fbfb3SApril Chin md5_block(Sum_t* p, const void* s, size_t inputLen) 289*7c2fbfb3SApril Chin { 290*7c2fbfb3SApril Chin register Md5_t* context = (Md5_t*)p; 291*7c2fbfb3SApril Chin unsigned char* input = (unsigned char*)s; 292*7c2fbfb3SApril Chin unsigned int i; 293*7c2fbfb3SApril Chin unsigned int index; 294*7c2fbfb3SApril Chin unsigned int partLen; 295*7c2fbfb3SApril Chin 296*7c2fbfb3SApril Chin /* compute number of bytes mod 64 */ 297*7c2fbfb3SApril Chin index = (unsigned int)((context->count[0] >> 3) & 0x3f); 298*7c2fbfb3SApril Chin 299*7c2fbfb3SApril Chin /* update number of bits */ 300*7c2fbfb3SApril Chin if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) 301*7c2fbfb3SApril Chin context->count[1]++; 302*7c2fbfb3SApril Chin context->count[1] += ((UINT4)inputLen >> 29); 303*7c2fbfb3SApril Chin partLen = 64 - index; 304*7c2fbfb3SApril Chin 305*7c2fbfb3SApril Chin /* transform as many times as possible */ 306*7c2fbfb3SApril Chin if (inputLen >= partLen) 307*7c2fbfb3SApril Chin { 308*7c2fbfb3SApril Chin memcpy(&context->buffer[index], input, partLen); 309*7c2fbfb3SApril Chin md5_transform(context->state, context->buffer); 310*7c2fbfb3SApril Chin for (i = partLen; i + 63 < inputLen; i += 64) 311*7c2fbfb3SApril Chin md5_transform(context->state, &input[i]); 312*7c2fbfb3SApril Chin index = 0; 313*7c2fbfb3SApril Chin } 314*7c2fbfb3SApril Chin else 315*7c2fbfb3SApril Chin i = 0; 316*7c2fbfb3SApril Chin 317*7c2fbfb3SApril Chin /* buffer remaining input */ 318*7c2fbfb3SApril Chin memcpy(&context->buffer[index], &input[i], inputLen - i); 319*7c2fbfb3SApril Chin 320*7c2fbfb3SApril Chin return 0; 321*7c2fbfb3SApril Chin } 322*7c2fbfb3SApril Chin 323*7c2fbfb3SApril Chin static int 324*7c2fbfb3SApril Chin md5_done(Sum_t* p) 325*7c2fbfb3SApril Chin { 326*7c2fbfb3SApril Chin register Md5_t* context = (Md5_t*)p; 327*7c2fbfb3SApril Chin unsigned char bits[8]; 328*7c2fbfb3SApril Chin unsigned int index; 329*7c2fbfb3SApril Chin unsigned int padLen; 330*7c2fbfb3SApril Chin 331*7c2fbfb3SApril Chin /* save number of bits */ 332*7c2fbfb3SApril Chin md5_encode(bits, context->count, sizeof(bits)); 333*7c2fbfb3SApril Chin 334*7c2fbfb3SApril Chin /* pad out to 56 mod 64 */ 335*7c2fbfb3SApril Chin index = (unsigned int)((context->count[0] >> 3) & 0x3f); 336*7c2fbfb3SApril Chin padLen = (index < 56) ? (56 - index) : (120 - index); 337*7c2fbfb3SApril Chin md5_block(p, md5_pad, padLen); 338*7c2fbfb3SApril Chin 339*7c2fbfb3SApril Chin /* append length (before padding) */ 340*7c2fbfb3SApril Chin md5_block(p, bits, sizeof(bits)); 341*7c2fbfb3SApril Chin 342*7c2fbfb3SApril Chin /* store state in digest */ 343*7c2fbfb3SApril Chin md5_encode(context->digest, context->state, sizeof(context->digest)); 344*7c2fbfb3SApril Chin 345*7c2fbfb3SApril Chin /* accumulate the digests */ 346*7c2fbfb3SApril Chin for (index = 0; index < elementsof(context->digest); index++) 347*7c2fbfb3SApril Chin context->digest_sum[index] ^= context->digest[index]; 348*7c2fbfb3SApril Chin 349*7c2fbfb3SApril Chin return 0; 350*7c2fbfb3SApril Chin } 351*7c2fbfb3SApril Chin 352*7c2fbfb3SApril Chin static int 353*7c2fbfb3SApril Chin md5_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale) 354*7c2fbfb3SApril Chin { 355*7c2fbfb3SApril Chin register Md5_t* x = (Md5_t*)p; 356*7c2fbfb3SApril Chin register unsigned char* d; 357*7c2fbfb3SApril Chin register int n; 358*7c2fbfb3SApril Chin 359*7c2fbfb3SApril Chin d = (flags & SUM_TOTAL) ? x->digest_sum : x->digest; 360*7c2fbfb3SApril Chin for (n = 0; n < elementsof(x->digest); n++) 361*7c2fbfb3SApril Chin sfprintf(sp, "%02x", d[n]); 362*7c2fbfb3SApril Chin return 0; 363*7c2fbfb3SApril Chin } 364*7c2fbfb3SApril Chin 365*7c2fbfb3SApril Chin static int 366*7c2fbfb3SApril Chin md5_data(Sum_t* p, Sumdata_t* data) 367*7c2fbfb3SApril Chin { 368*7c2fbfb3SApril Chin register Md5_t* x = (Md5_t*)p; 369*7c2fbfb3SApril Chin 370*7c2fbfb3SApril Chin data->size = elementsof(x->digest); 371*7c2fbfb3SApril Chin data->num = 0; 372*7c2fbfb3SApril Chin data->buf = x->digest; 373*7c2fbfb3SApril Chin return 0; 374*7c2fbfb3SApril Chin } 375