QOF
0.8.0
|
00001 /* md5.c - Functions to compute MD5 message digest of files or memory blocks 00002 according to the definition of MD5 in RFC 1321 from April 1992. 00003 Copyright (C) 1995, 1996 Free Software Foundation, Inc. 00004 NOTE: The canonical source of this file is maintained with the GNU C 00005 Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. 00006 00007 This program is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 2, or (at your option) any 00010 later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 00020 00021 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ 00022 00025 #ifdef HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include <sys/types.h> 00030 00031 #if STDC_HEADERS || defined _LIBC 00032 # include <stdlib.h> 00033 # include <string.h> 00034 #else 00035 # ifndef HAVE_MEMCPY 00036 #include <string.h> 00037 # define memcpy(d, s, n) bcopy ((s), (d), (n)) 00038 # endif 00039 #endif 00040 00041 #include "md5.h" 00042 00043 #ifdef _LIBC 00044 # include <endian.h> 00045 # if __BYTE_ORDER == __BIG_ENDIAN 00046 # define WORDS_BIGENDIAN 1 00047 # endif 00048 #endif 00049 00050 #ifdef WORDS_BIGENDIAN 00051 # define SWAP(n) \ 00052 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) 00053 #else 00054 # define SWAP(n) (n) 00055 #endif 00056 00057 00058 /* This array contains the bytes used to pad the buffer to the next 00059 64-byte boundary. (RFC 1321, 3.1: Step 1) */ 00060 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; 00061 00062 00063 /* Initialize structure containing state of computation. 00064 (RFC 1321, 3.3: Step 3) */ 00065 void 00066 md5_init_ctx (ctx) 00067 struct md5_ctx *ctx; 00068 { 00069 ctx->A = 0x67452301; 00070 ctx->B = 0xefcdab89; 00071 ctx->C = 0x98badcfe; 00072 ctx->D = 0x10325476; 00073 00074 ctx->total[0] = ctx->total[1] = 0; 00075 ctx->buflen = 0; 00076 } 00077 00078 /* Put result from CTX in first 16 bytes following RESBUF. The result 00079 must be in little endian byte order. 00080 00081 IMPORTANT: On some systems it is required that RESBUF is correctly 00082 aligned for a 32 bits value. */ 00083 void * 00084 md5_read_ctx (ctx, resbuf) 00085 const struct md5_ctx *ctx; 00086 void *resbuf; 00087 { 00088 ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); 00089 ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); 00090 ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); 00091 ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); 00092 00093 return resbuf; 00094 } 00095 00096 /* Process the remaining bytes in the internal buffer and the usual 00097 prolog according to the standard and write the result to RESBUF. 00098 00099 IMPORTANT: On some systems it is required that RESBUF is correctly 00100 aligned for a 32 bits value. */ 00101 void * 00102 md5_finish_ctx (ctx, resbuf) 00103 struct md5_ctx *ctx; 00104 void *resbuf; 00105 { 00106 /* Take yet unprocessed bytes into account. */ 00107 md5_uint32 bytes = ctx->buflen; 00108 size_t pad; 00109 00110 /* Now count remaining bytes. */ 00111 ctx->total[0] += bytes; 00112 if (ctx->total[0] < bytes) 00113 ++ctx->total[1]; 00114 00115 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; 00116 memcpy (&ctx->buffer[bytes], fillbuf, pad); 00117 00118 /* Put the 64-bit file length in *bits* at the end of the buffer. */ 00119 *(md5_uint32 *) & ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); 00120 *(md5_uint32 *) & ctx->buffer[bytes + pad + 4] = 00121 SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); 00122 00123 /* Process last bytes. */ 00124 md5_process_block (ctx->buffer, bytes + pad + 8, ctx); 00125 00126 return md5_read_ctx (ctx, resbuf); 00127 } 00128 00129 /* Compute MD5 message digest for bytes read from STREAM. The 00130 resulting message digest number will be written into the 16 bytes 00131 beginning at RESBLOCK. */ 00132 int 00133 md5_stream (stream, resblock) 00134 FILE *stream; 00135 void *resblock; 00136 { 00137 /* Important: BLOCKSIZE must be a multiple of 64. */ 00138 #define BLOCKSIZE 4096 00139 struct md5_ctx ctx; 00140 char buffer[BLOCKSIZE + 72]; 00141 size_t sum; 00142 00143 /* Initialize the computation context. */ 00144 md5_init_ctx (&ctx); 00145 00146 /* Iterate over full file contents. */ 00147 while (1) 00148 { 00149 /* We read the file in blocks of BLOCKSIZE bytes. One call of the 00150 computation function processes the whole buffer so that with the 00151 next round of the loop another block can be read. */ 00152 size_t n; 00153 sum = 0; 00154 00155 /* Read block. Take care for partial reads. */ 00156 do 00157 { 00158 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); 00159 00160 sum += n; 00161 } 00162 while (sum < BLOCKSIZE && n != 0); 00163 if (n == 0 && ferror (stream)) 00164 return 1; 00165 00166 /* If end of file is reached, end the loop. */ 00167 if (n == 0) 00168 break; 00169 00170 /* Process buffer with BLOCKSIZE bytes. Note that 00171 BLOCKSIZE % 64 == 0 00172 */ 00173 md5_process_block (buffer, BLOCKSIZE, &ctx); 00174 } 00175 00176 /* Add the last bytes if necessary. */ 00177 if (sum > 0) 00178 md5_process_bytes (buffer, sum, &ctx); 00179 00180 /* Construct result in desired memory. */ 00181 md5_finish_ctx (&ctx, resblock); 00182 return 0; 00183 } 00184 00185 /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The 00186 result is always in little endian byte order, so that a byte-wise 00187 output yields to the wanted ASCII representation of the message 00188 digest. */ 00189 void * 00190 md5_buffer (buffer, len, resblock) 00191 const char *buffer; 00192 size_t len; 00193 void *resblock; 00194 { 00195 struct md5_ctx ctx; 00196 00197 /* Initialize the computation context. */ 00198 md5_init_ctx (&ctx); 00199 00200 /* Process whole buffer but last len % 64 bytes. */ 00201 md5_process_bytes (buffer, len, &ctx); 00202 00203 /* Put result in desired memory area. */ 00204 return md5_finish_ctx (&ctx, resblock); 00205 } 00206 00207 00208 void 00209 md5_process_bytes (buffer, len, ctx) 00210 const void *buffer; 00211 size_t len; 00212 struct md5_ctx *ctx; 00213 { 00214 #define NUM_MD5_WORDS 1024 00215 size_t add = 0; 00216 00217 /* When we already have some bits in our internal buffer concatenate 00218 both inputs first. */ 00219 if (ctx->buflen != 0) 00220 { 00221 size_t left_over = ctx->buflen; 00222 00223 add = 128 - left_over > len ? len : 128 - left_over; 00224 00225 memcpy (&ctx->buffer[left_over], buffer, add); 00226 ctx->buflen += add; 00227 00228 if (left_over + add > 64) 00229 { 00230 md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); 00231 /* The regions in the following copy operation cannot overlap. */ 00232 memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], 00233 (left_over + add) & 63); 00234 ctx->buflen = (left_over + add) & 63; 00235 } 00236 00237 buffer = (const char *) buffer + add; 00238 len -= add; 00239 } 00240 00241 /* Process available complete blocks. */ 00242 if (len > 64) 00243 { 00244 if ((add & 3) == 0) /* buffer is still 32-bit aligned */ 00245 { 00246 md5_process_block (buffer, len & ~63, ctx); 00247 buffer = (const char *) buffer + (len & ~63); 00248 } 00249 else /* buffer is not 32-bit aligned */ 00250 { 00251 md5_uint32 md5_buffer[NUM_MD5_WORDS]; 00252 size_t num_bytes; 00253 size_t buf_bytes; 00254 00255 num_bytes = len & ~63; 00256 while (num_bytes > 0) 00257 { 00258 buf_bytes = (num_bytes < sizeof (md5_buffer)) ? 00259 num_bytes : sizeof (md5_buffer); 00260 memcpy (md5_buffer, buffer, buf_bytes); 00261 md5_process_block (md5_buffer, buf_bytes, ctx); 00262 num_bytes -= buf_bytes; 00263 buffer = (const char *) buffer + buf_bytes; 00264 } 00265 } 00266 00267 len &= 63; 00268 } 00269 00270 /* Move remaining bytes in internal buffer. */ 00271 if (len > 0) 00272 { 00273 memcpy (ctx->buffer, buffer, len); 00274 ctx->buflen = len; 00275 } 00276 } 00277 00278 00279 /* These are the four functions used in the four steps of the MD5 algorithm 00280 and defined in the RFC 1321. The first function is a little bit optimized 00281 (as found in Colin Plumbs public domain implementation). */ 00282 /* #define FF(b, c, d) ((b & c) | (~b & d)) */ 00283 #define FF(b, c, d) (d ^ (b & (c ^ d))) 00284 #define FG(b, c, d) FF (d, b, c) 00285 #define FH(b, c, d) (b ^ c ^ d) 00286 #define FI(b, c, d) (c ^ (b | ~d)) 00287 00288 /* Process LEN bytes of BUFFER, accumulating context into CTX. 00289 It is assumed that LEN % 64 == 0. */ 00290 00291 void 00292 md5_process_block (buffer, len, ctx) 00293 const void *buffer; 00294 size_t len; 00295 struct md5_ctx *ctx; 00296 { 00297 md5_uint32 correct_words[16]; 00298 const md5_uint32 *words = buffer; 00299 size_t nwords = len / sizeof (md5_uint32); 00300 const md5_uint32 *endp = words + nwords; 00301 md5_uint32 A = ctx->A; 00302 md5_uint32 B = ctx->B; 00303 md5_uint32 C = ctx->C; 00304 md5_uint32 D = ctx->D; 00305 00306 /* First increment the byte count. RFC 1321 specifies the possible 00307 length of the file up to 2^64 bits. Here we only compute the 00308 number of bytes. Do a double word increment. */ 00309 ctx->total[0] += len; 00310 if (ctx->total[0] < len) 00311 ++ctx->total[1]; 00312 00313 /* Process all bytes in the buffer with 64 bytes in each round of 00314 the loop. */ 00315 while (words < endp) 00316 { 00317 md5_uint32 *cwp = correct_words; 00318 md5_uint32 A_save = A; 00319 md5_uint32 B_save = B; 00320 md5_uint32 C_save = C; 00321 md5_uint32 D_save = D; 00322 00323 /* First round: using the given function, the context and a constant 00324 the next context is computed. Because the algorithms processing 00325 unit is a 32-bit word and it is determined to work on words in 00326 little endian byte order we perhaps have to change the byte order 00327 before the computation. To reduce the work for the next steps 00328 we store the swapped words in the array CORRECT_WORDS. */ 00329 00330 #define OP(a, b, c, d, s, T) \ 00331 do \ 00332 { \ 00333 a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ 00334 ++words; \ 00335 CYCLIC (a, s); \ 00336 a += b; \ 00337 } \ 00338 while (0) 00339 00340 /* It is unfortunate that C does not provide an operator for 00341 cyclic rotation. Hope the C compiler is smart enough. */ 00342 #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) 00343 00344 /* Before we start, one word to the strange constants. 00345 They are defined in RFC 1321 as 00346 00347 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 00348 */ 00349 00350 /* Round 1. */ 00351 OP (A, B, C, D, 7, 0xd76aa478); 00352 OP (D, A, B, C, 12, 0xe8c7b756); 00353 OP (C, D, A, B, 17, 0x242070db); 00354 OP (B, C, D, A, 22, 0xc1bdceee); 00355 OP (A, B, C, D, 7, 0xf57c0faf); 00356 OP (D, A, B, C, 12, 0x4787c62a); 00357 OP (C, D, A, B, 17, 0xa8304613); 00358 OP (B, C, D, A, 22, 0xfd469501); 00359 OP (A, B, C, D, 7, 0x698098d8); 00360 OP (D, A, B, C, 12, 0x8b44f7af); 00361 OP (C, D, A, B, 17, 0xffff5bb1); 00362 OP (B, C, D, A, 22, 0x895cd7be); 00363 OP (A, B, C, D, 7, 0x6b901122); 00364 OP (D, A, B, C, 12, 0xfd987193); 00365 OP (C, D, A, B, 17, 0xa679438e); 00366 OP (B, C, D, A, 22, 0x49b40821); 00367 00368 /* For the second to fourth round we have the possibly swapped words 00369 in CORRECT_WORDS. Redefine the macro to take an additional first 00370 argument specifying the function to use. */ 00371 #undef OP 00372 #define OP(f, a, b, c, d, k, s, T) \ 00373 do \ 00374 { \ 00375 a += f (b, c, d) + correct_words[k] + T; \ 00376 CYCLIC (a, s); \ 00377 a += b; \ 00378 } \ 00379 while (0) 00380 00381 /* Round 2. */ 00382 OP (FG, A, B, C, D, 1, 5, 0xf61e2562); 00383 OP (FG, D, A, B, C, 6, 9, 0xc040b340); 00384 OP (FG, C, D, A, B, 11, 14, 0x265e5a51); 00385 OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); 00386 OP (FG, A, B, C, D, 5, 5, 0xd62f105d); 00387 OP (FG, D, A, B, C, 10, 9, 0x02441453); 00388 OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); 00389 OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); 00390 OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); 00391 OP (FG, D, A, B, C, 14, 9, 0xc33707d6); 00392 OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); 00393 OP (FG, B, C, D, A, 8, 20, 0x455a14ed); 00394 OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); 00395 OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); 00396 OP (FG, C, D, A, B, 7, 14, 0x676f02d9); 00397 OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); 00398 00399 /* Round 3. */ 00400 OP (FH, A, B, C, D, 5, 4, 0xfffa3942); 00401 OP (FH, D, A, B, C, 8, 11, 0x8771f681); 00402 OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); 00403 OP (FH, B, C, D, A, 14, 23, 0xfde5380c); 00404 OP (FH, A, B, C, D, 1, 4, 0xa4beea44); 00405 OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); 00406 OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); 00407 OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); 00408 OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); 00409 OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); 00410 OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); 00411 OP (FH, B, C, D, A, 6, 23, 0x04881d05); 00412 OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); 00413 OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); 00414 OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); 00415 OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); 00416 00417 /* Round 4. */ 00418 OP (FI, A, B, C, D, 0, 6, 0xf4292244); 00419 OP (FI, D, A, B, C, 7, 10, 0x432aff97); 00420 OP (FI, C, D, A, B, 14, 15, 0xab9423a7); 00421 OP (FI, B, C, D, A, 5, 21, 0xfc93a039); 00422 OP (FI, A, B, C, D, 12, 6, 0x655b59c3); 00423 OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); 00424 OP (FI, C, D, A, B, 10, 15, 0xffeff47d); 00425 OP (FI, B, C, D, A, 1, 21, 0x85845dd1); 00426 OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); 00427 OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); 00428 OP (FI, C, D, A, B, 6, 15, 0xa3014314); 00429 OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); 00430 OP (FI, A, B, C, D, 4, 6, 0xf7537e82); 00431 OP (FI, D, A, B, C, 11, 10, 0xbd3af235); 00432 OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); 00433 OP (FI, B, C, D, A, 9, 21, 0xeb86d391); 00434 00435 /* Add the starting values of the context. */ 00436 A += A_save; 00437 B += B_save; 00438 C += C_save; 00439 D += D_save; 00440 } 00441 00442 /* Put checksum in context given as argument. */ 00443 ctx->A = A; 00444 ctx->B = B; 00445 ctx->C = C; 00446 ctx->D = D; 00447 }