md5.c (5832B)
1 /********************************************************************* 2 * Filename: md5.c 3 * Author: Brad Conte (brad AT bradconte.com) 4 * Copyright: 5 * Disclaimer: This code is presented "as is" without any guarantees. 6 * Details: Implementation of the MD5 hashing algorithm. 7 Algorithm specification can be found here: 8 * http://tools.ietf.org/html/rfc1321 9 This implementation uses little endian byte order. 10 *********************************************************************/ 11 12 /*************************** HEADER FILES ***************************/ 13 #include <stdlib.h> 14 #include <memory.h> 15 #include "md5.h" 16 17 /****************************** MACROS ******************************/ 18 #define ROTLEFT(a,b) ((a << b) | (a >> (32-b))) 19 20 #define F(x,y,z) ((x & y) | (~x & z)) 21 #define G(x,y,z) ((x & z) | (y & ~z)) 22 #define H(x,y,z) (x ^ y ^ z) 23 #define I(x,y,z) (y ^ (x | ~z)) 24 25 #define FF(a,b,c,d,m,s,t) { a += F(b,c,d) + m + t; \ 26 a = b + ROTLEFT(a,s); } 27 #define GG(a,b,c,d,m,s,t) { a += G(b,c,d) + m + t; \ 28 a = b + ROTLEFT(a,s); } 29 #define HH(a,b,c,d,m,s,t) { a += H(b,c,d) + m + t; \ 30 a = b + ROTLEFT(a,s); } 31 #define II(a,b,c,d,m,s,t) { a += I(b,c,d) + m + t; \ 32 a = b + ROTLEFT(a,s); } 33 34 /*********************** FUNCTION DEFINITIONS ***********************/ 35 void md5_transform(MD5_CTX *ctx, const BYTE data[]) 36 { 37 WORD a, b, c, d, m[16], i, j; 38 39 // MD5 specifies big endian byte order, but this implementation assumes a little 40 // endian byte order CPU. Reverse all the bytes upon input, and re-reverse them 41 // on output (in md5_final()). 42 for (i = 0, j = 0; i < 16; ++i, j += 4) 43 m[i] = (data[j]) + (data[j + 1] << 8) + (data[j + 2] << 16) + (data[j + 3] << 24); 44 45 a = ctx->state[0]; 46 b = ctx->state[1]; 47 c = ctx->state[2]; 48 d = ctx->state[3]; 49 50 FF(a,b,c,d,m[0], 7,0xd76aa478); 51 FF(d,a,b,c,m[1], 12,0xe8c7b756); 52 FF(c,d,a,b,m[2], 17,0x242070db); 53 FF(b,c,d,a,m[3], 22,0xc1bdceee); 54 FF(a,b,c,d,m[4], 7,0xf57c0faf); 55 FF(d,a,b,c,m[5], 12,0x4787c62a); 56 FF(c,d,a,b,m[6], 17,0xa8304613); 57 FF(b,c,d,a,m[7], 22,0xfd469501); 58 FF(a,b,c,d,m[8], 7,0x698098d8); 59 FF(d,a,b,c,m[9], 12,0x8b44f7af); 60 FF(c,d,a,b,m[10],17,0xffff5bb1); 61 FF(b,c,d,a,m[11],22,0x895cd7be); 62 FF(a,b,c,d,m[12], 7,0x6b901122); 63 FF(d,a,b,c,m[13],12,0xfd987193); 64 FF(c,d,a,b,m[14],17,0xa679438e); 65 FF(b,c,d,a,m[15],22,0x49b40821); 66 67 GG(a,b,c,d,m[1], 5,0xf61e2562); 68 GG(d,a,b,c,m[6], 9,0xc040b340); 69 GG(c,d,a,b,m[11],14,0x265e5a51); 70 GG(b,c,d,a,m[0], 20,0xe9b6c7aa); 71 GG(a,b,c,d,m[5], 5,0xd62f105d); 72 GG(d,a,b,c,m[10], 9,0x02441453); 73 GG(c,d,a,b,m[15],14,0xd8a1e681); 74 GG(b,c,d,a,m[4], 20,0xe7d3fbc8); 75 GG(a,b,c,d,m[9], 5,0x21e1cde6); 76 GG(d,a,b,c,m[14], 9,0xc33707d6); 77 GG(c,d,a,b,m[3], 14,0xf4d50d87); 78 GG(b,c,d,a,m[8], 20,0x455a14ed); 79 GG(a,b,c,d,m[13], 5,0xa9e3e905); 80 GG(d,a,b,c,m[2], 9,0xfcefa3f8); 81 GG(c,d,a,b,m[7], 14,0x676f02d9); 82 GG(b,c,d,a,m[12],20,0x8d2a4c8a); 83 84 HH(a,b,c,d,m[5], 4,0xfffa3942); 85 HH(d,a,b,c,m[8], 11,0x8771f681); 86 HH(c,d,a,b,m[11],16,0x6d9d6122); 87 HH(b,c,d,a,m[14],23,0xfde5380c); 88 HH(a,b,c,d,m[1], 4,0xa4beea44); 89 HH(d,a,b,c,m[4], 11,0x4bdecfa9); 90 HH(c,d,a,b,m[7], 16,0xf6bb4b60); 91 HH(b,c,d,a,m[10],23,0xbebfbc70); 92 HH(a,b,c,d,m[13], 4,0x289b7ec6); 93 HH(d,a,b,c,m[0], 11,0xeaa127fa); 94 HH(c,d,a,b,m[3], 16,0xd4ef3085); 95 HH(b,c,d,a,m[6], 23,0x04881d05); 96 HH(a,b,c,d,m[9], 4,0xd9d4d039); 97 HH(d,a,b,c,m[12],11,0xe6db99e5); 98 HH(c,d,a,b,m[15],16,0x1fa27cf8); 99 HH(b,c,d,a,m[2], 23,0xc4ac5665); 100 101 II(a,b,c,d,m[0], 6,0xf4292244); 102 II(d,a,b,c,m[7], 10,0x432aff97); 103 II(c,d,a,b,m[14],15,0xab9423a7); 104 II(b,c,d,a,m[5], 21,0xfc93a039); 105 II(a,b,c,d,m[12], 6,0x655b59c3); 106 II(d,a,b,c,m[3], 10,0x8f0ccc92); 107 II(c,d,a,b,m[10],15,0xffeff47d); 108 II(b,c,d,a,m[1], 21,0x85845dd1); 109 II(a,b,c,d,m[8], 6,0x6fa87e4f); 110 II(d,a,b,c,m[15],10,0xfe2ce6e0); 111 II(c,d,a,b,m[6], 15,0xa3014314); 112 II(b,c,d,a,m[13],21,0x4e0811a1); 113 II(a,b,c,d,m[4], 6,0xf7537e82); 114 II(d,a,b,c,m[11],10,0xbd3af235); 115 II(c,d,a,b,m[2], 15,0x2ad7d2bb); 116 II(b,c,d,a,m[9], 21,0xeb86d391); 117 118 ctx->state[0] += a; 119 ctx->state[1] += b; 120 ctx->state[2] += c; 121 ctx->state[3] += d; 122 } 123 124 void md5_init(MD5_CTX *ctx) 125 { 126 ctx->datalen = 0; 127 ctx->bitlen = 0; 128 ctx->state[0] = 0x67452301; 129 ctx->state[1] = 0xEFCDAB89; 130 ctx->state[2] = 0x98BADCFE; 131 ctx->state[3] = 0x10325476; 132 } 133 134 void md5_update(MD5_CTX *ctx, const BYTE data[], size_t len) 135 { 136 size_t i; 137 138 for (i = 0; i < len; ++i) { 139 ctx->data[ctx->datalen] = data[i]; 140 ctx->datalen++; 141 if (ctx->datalen == 64) { 142 md5_transform(ctx, ctx->data); 143 ctx->bitlen += 512; 144 ctx->datalen = 0; 145 } 146 } 147 } 148 149 void md5_final(MD5_CTX *ctx, BYTE hash[]) 150 { 151 size_t i; 152 153 i = ctx->datalen; 154 155 // Pad whatever data is left in the buffer. 156 if (ctx->datalen < 56) { 157 ctx->data[i++] = 0x80; 158 while (i < 56) 159 ctx->data[i++] = 0x00; 160 } 161 else if (ctx->datalen >= 56) { 162 ctx->data[i++] = 0x80; 163 while (i < 64) 164 ctx->data[i++] = 0x00; 165 md5_transform(ctx, ctx->data); 166 memset(ctx->data, 0, 56); 167 } 168 169 // Append to the padding the total message's length in bits and transform. 170 ctx->bitlen += ctx->datalen * 8; 171 ctx->data[56] = ctx->bitlen; 172 ctx->data[57] = ctx->bitlen >> 8; 173 ctx->data[58] = ctx->bitlen >> 16; 174 ctx->data[59] = ctx->bitlen >> 24; 175 ctx->data[60] = ctx->bitlen >> 32; 176 ctx->data[61] = ctx->bitlen >> 40; 177 ctx->data[62] = ctx->bitlen >> 48; 178 ctx->data[63] = ctx->bitlen >> 56; 179 md5_transform(ctx, ctx->data); 180 181 // Since this implementation uses little endian byte ordering and MD uses big endian, 182 // reverse all the bytes when copying the final state to the output hash. 183 for (i = 0; i < 4; ++i) { 184 hash[i] = (ctx->state[0] >> (i * 8)) & 0x000000ff; 185 hash[i + 4] = (ctx->state[1] >> (i * 8)) & 0x000000ff; 186 hash[i + 8] = (ctx->state[2] >> (i * 8)) & 0x000000ff; 187 hash[i + 12] = (ctx->state[3] >> (i * 8)) & 0x000000ff; 188 } 189 }