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