1/* md5.c - MD5 Message-Digest Algorithm 2 * Copyright (C) 1995, 1996, 1998, 1999, 3 * 2000, 2001 Free Software Foundation, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2, or (at your option) any 8 * later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software Foundation, 17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * 19 * According to the definition of MD5 in RFC 1321 from April 1992. 20 * NOTE: This is *not* the same file as the one from glibc. 21 */ 22/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ 23/* Heavily modified for GnuPG by <wk@gnupg.org> */ 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <assert.h> 29 30#include "types.h" 31 32#ifdef WORDS_BIGENDIAN 33#define BIG_ENDIAN_HOST 34#endif 35 36//#define DIM(v) (sizeof(v)/sizeof((v)[0])) 37#define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0) 38#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) 39#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) 40 41typedef struct { 42 u32 A,B,C,D; /* chaining variables */ 43 u32 nblocks; 44 byte buf[64]; 45 int count; 46} MD5_CONTEXT; 47 48 49void 50md5_init( MD5_CONTEXT *ctx ) 51{ 52 ctx->A = 0x67452301; 53 ctx->B = 0xefcdab89; 54 ctx->C = 0x98badcfe; 55 ctx->D = 0x10325476; 56 57 ctx->nblocks = 0; 58 ctx->count = 0; 59} 60 61 62 63 64/* These are the four functions used in the four steps of the MD5 algorithm 65 and defined in the RFC 1321. The first function is a little bit optimized 66 (as found in Colin Plumbs public domain implementation). */ 67/* #define FF(b, c, d) ((b & c) | (~b & d)) */ 68#define FF(b, c, d) (d ^ (b & (c ^ d))) 69#define FG(b, c, d) FF (d, b, c) 70#define FH(b, c, d) (b ^ c ^ d) 71#define FI(b, c, d) (c ^ (b | ~d)) 72 73static void 74burn_stack (int bytes) 75{ 76 char buf[128]; 77 78 wipememory(buf,sizeof buf); 79 bytes -= sizeof buf; 80 if (bytes > 0) 81 burn_stack (bytes); 82} 83 84 85 86/**************** 87 * transform n*64 bytes 88 */ 89static void 90/*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/ 91transform( MD5_CONTEXT *ctx, byte *data ) 92{ 93 u32 correct_words[16]; 94 u32 A = ctx->A; 95 u32 B = ctx->B; 96 u32 C = ctx->C; 97 u32 D = ctx->D; 98 u32 *cwp = correct_words; 99 100#ifdef BIG_ENDIAN_HOST 101 { int i; 102 byte *p2, *p1; 103 for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) { 104 p2[3] = *p1++; 105 p2[2] = *p1++; 106 p2[1] = *p1++; 107 p2[0] = *p1++; 108 } 109 } 110#else 111 memcpy( correct_words, data, 64 ); 112#endif 113 114 115#define OP(a, b, c, d, s, T) \ 116 do \ 117 { \ 118 a += FF (b, c, d) + (*cwp++) + T; \ 119 a = rol(a, s); \ 120 a += b; \ 121 } \ 122 while (0) 123 124 /* Before we start, one word about the strange constants. 125 They are defined in RFC 1321 as 126 127 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 128 */ 129 130 /* Round 1. */ 131 OP (A, B, C, D, 7, 0xd76aa478); 132 OP (D, A, B, C, 12, 0xe8c7b756); 133 OP (C, D, A, B, 17, 0x242070db); 134 OP (B, C, D, A, 22, 0xc1bdceee); 135 OP (A, B, C, D, 7, 0xf57c0faf); 136 OP (D, A, B, C, 12, 0x4787c62a); 137 OP (C, D, A, B, 17, 0xa8304613); 138 OP (B, C, D, A, 22, 0xfd469501); 139 OP (A, B, C, D, 7, 0x698098d8); 140 OP (D, A, B, C, 12, 0x8b44f7af); 141 OP (C, D, A, B, 17, 0xffff5bb1); 142 OP (B, C, D, A, 22, 0x895cd7be); 143 OP (A, B, C, D, 7, 0x6b901122); 144 OP (D, A, B, C, 12, 0xfd987193); 145 OP (C, D, A, B, 17, 0xa679438e); 146 OP (B, C, D, A, 22, 0x49b40821); 147 148#undef OP 149#define OP(f, a, b, c, d, k, s, T) \ 150 do \ 151 { \ 152a += f (b, c, d) + correct_words[k] + T; \ 153a = rol(a, s); \ 154a += b; \ 155 } \ 156 while (0) 157 158 /* Round 2. */ 159 OP (FG, A, B, C, D, 1, 5, 0xf61e2562); 160 OP (FG, D, A, B, C, 6, 9, 0xc040b340); 161 OP (FG, C, D, A, B, 11, 14, 0x265e5a51); 162 OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); 163 OP (FG, A, B, C, D, 5, 5, 0xd62f105d); 164 OP (FG, D, A, B, C, 10, 9, 0x02441453); 165 OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); 166 OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); 167 OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); 168 OP (FG, D, A, B, C, 14, 9, 0xc33707d6); 169 OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); 170 OP (FG, B, C, D, A, 8, 20, 0x455a14ed); 171 OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); 172 OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); 173 OP (FG, C, D, A, B, 7, 14, 0x676f02d9); 174 OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); 175 176 /* Round 3. */ 177 OP (FH, A, B, C, D, 5, 4, 0xfffa3942); 178 OP (FH, D, A, B, C, 8, 11, 0x8771f681); 179 OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); 180 OP (FH, B, C, D, A, 14, 23, 0xfde5380c); 181 OP (FH, A, B, C, D, 1, 4, 0xa4beea44); 182 OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); 183 OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); 184 OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); 185 OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); 186 OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); 187 OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); 188 OP (FH, B, C, D, A, 6, 23, 0x04881d05); 189 OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); 190 OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); 191 OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); 192 OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); 193 194 /* Round 4. */ 195 OP (FI, A, B, C, D, 0, 6, 0xf4292244); 196 OP (FI, D, A, B, C, 7, 10, 0x432aff97); 197 OP (FI, C, D, A, B, 14, 15, 0xab9423a7); 198 OP (FI, B, C, D, A, 5, 21, 0xfc93a039); 199 OP (FI, A, B, C, D, 12, 6, 0x655b59c3); 200 OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); 201 OP (FI, C, D, A, B, 10, 15, 0xffeff47d); 202 OP (FI, B, C, D, A, 1, 21, 0x85845dd1); 203 OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); 204 OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); 205 OP (FI, C, D, A, B, 6, 15, 0xa3014314); 206 OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); 207 OP (FI, A, B, C, D, 4, 6, 0xf7537e82); 208 OP (FI, D, A, B, C, 11, 10, 0xbd3af235); 209 OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); 210 OP (FI, B, C, D, A, 9, 21, 0xeb86d391); 211 212 /* Put checksum in context given as argument. */ 213 ctx->A += A; 214 ctx->B += B; 215 ctx->C += C; 216 ctx->D += D; 217} 218 219 220 221/* The routine updates the message-digest context to 222 * account for the presence of each of the characters inBuf[0..inLen-1] 223 * in the message whose digest is being computed. 224 */ 225void 226md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen) 227{ 228 if( hd->count == 64 ) { /* flush the buffer */ 229 transform( hd, hd->buf ); 230 burn_stack (80+6*sizeof(void*)); 231 hd->count = 0; 232 hd->nblocks++; 233 } 234 if( !inbuf ) 235 return; 236 if( hd->count ) { 237 for( ; inlen && hd->count < 64; inlen-- ) 238 hd->buf[hd->count++] = *inbuf++; 239 md5_write( hd, NULL, 0 ); 240 if( !inlen ) 241 return; 242 } 243 244 while( inlen >= 64 ) { 245 transform( hd, inbuf ); 246 hd->count = 0; 247 hd->nblocks++; 248 inlen -= 64; 249 inbuf += 64; 250 } 251 burn_stack (80+6*sizeof(void*)); 252 for( ; inlen && hd->count < 64; inlen-- ) 253 hd->buf[hd->count++] = *inbuf++; 254} 255/* The routine final terminates the message-digest computation and 256 * ends with the desired message digest in mdContext->digest[0...15]. 257 * The handle is prepared for a new MD5 cycle. 258 * Returns 16 bytes representing the digest. 259 */ 260 261void 262md5_final( MD5_CONTEXT *hd ) 263{ 264 u32 t, msb, lsb; 265 byte *p; 266 267 md5_write(hd, NULL, 0); /* flush */; 268 269 t = hd->nblocks; 270 /* multiply by 64 to make a byte count */ 271 lsb = t << 6; 272 msb = t >> 26; 273 /* add the count */ 274 t = lsb; 275 if( (lsb += hd->count) < t ) 276 msb++; 277 /* multiply by 8 to make a bit count */ 278 t = lsb; 279 lsb <<= 3; 280 msb <<= 3; 281 msb |= t >> 29; 282 283 if( hd->count < 56 ) { /* enough room */ 284 hd->buf[hd->count++] = 0x80; /* pad */ 285 while( hd->count < 56 ) 286 hd->buf[hd->count++] = 0; /* pad */ 287 } 288 else { /* need one extra block */ 289 hd->buf[hd->count++] = 0x80; /* pad character */ 290 while( hd->count < 64 ) 291 hd->buf[hd->count++] = 0; 292 md5_write(hd, NULL, 0); /* flush */; 293 memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ 294 } 295 /* append the 64 bit count */ 296 hd->buf[56] = lsb ; 297 hd->buf[57] = lsb >> 8; 298 hd->buf[58] = lsb >> 16; 299 hd->buf[59] = lsb >> 24; 300 hd->buf[60] = msb ; 301 hd->buf[61] = msb >> 8; 302 hd->buf[62] = msb >> 16; 303 hd->buf[63] = msb >> 24; 304 transform( hd, hd->buf ); 305 burn_stack (80+6*sizeof(void*)); 306 307 p = hd->buf; 308#ifdef BIG_ENDIAN_HOST 309#define X(a) do { *p++ = hd-> a ; *p++ = hd-> a >> 8; \ 310 *p++ = hd-> a >> 16; *p++ = hd-> a >> 24; } while(0) 311#else /* little endian */ 312#define X(a) do { *(u32*)p = hd-> a ; p += 4; } while(0) 313#endif 314 X(A); 315 X(B); 316 X(C); 317 X(D); 318#undef X 319 320} 321