/[cvs]/ccvs/lib/md5.c
ViewVC logotype

Diff of /ccvs/lib/md5.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by dprice, Thu Oct 20 21:06:01 2005 UTC revision 1.13 by mdb, Mon Nov 28 02:35:49 2005 UTC
# Line 108  md5_finish_ctx (struct md5_ctx *ctx, voi Line 108  md5_finish_ctx (struct md5_ctx *ctx, voi
108  {  {
109    /* Take yet unprocessed bytes into account.  */    /* Take yet unprocessed bytes into account.  */
110    uint32_t bytes = ctx->buflen;    uint32_t bytes = ctx->buflen;
111    size_t pad;    size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
112    
113    /* Now count remaining bytes.  */    /* Now count remaining bytes.  */
114    ctx->total[0] += bytes;    ctx->total[0] += bytes;
115    if (ctx->total[0] < bytes)    if (ctx->total[0] < bytes)
116      ++ctx->total[1];      ++ctx->total[1];
117    
   pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;  
   memcpy (&ctx->buffer[bytes], fillbuf, pad);  
   
118    /* Put the 64-bit file length in *bits* at the end of the buffer.  */    /* Put the 64-bit file length in *bits* at the end of the buffer.  */
119    *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);    ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3);
120    *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |    ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
121                                                          (ctx->total[0] >> 29));  
122      memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
123    
124    /* Process last bytes.  */    /* Process last bytes.  */
125    md5_process_block (ctx->buffer, bytes + pad + 8, ctx);    md5_process_block (ctx->buffer, size * 4, ctx);
126    
127    return md5_read_ctx (ctx, resbuf);    return md5_read_ctx (ctx, resbuf);
128  }  }
# Line 146  md5_stream (FILE *stream, void *resblock Line 144  md5_stream (FILE *stream, void *resblock
144    while (1)    while (1)
145      {      {
146        /* We read the file in blocks of BLOCKSIZE bytes.  One call of the        /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
147           computation function processes the whole buffer so that with the           computation function processes the whole buffer so that with the
148           next round of the loop another block can be read.  */           next round of the loop another block can be read.  */
149        size_t n;        size_t n;
150        sum = 0;        sum = 0;
151    
# Line 164  md5_stream (FILE *stream, void *resblock Line 162  md5_stream (FILE *stream, void *resblock
162            if (n == 0)            if (n == 0)
163              {              {
164                /* Check for the error flag IFF N == 0, so that we don't                /* Check for the error flag IFF N == 0, so that we don't
165                   exit the loop after a partial read due to e.g., EAGAIN                   exit the loop after a partial read due to e.g., EAGAIN
166                   or EWOULDBLOCK.  */                   or EWOULDBLOCK.  */
167                if (ferror (stream))                if (ferror (stream))
168                  return 1;                  return 1;
169                goto process_partial_block;                goto process_partial_block;
# Line 179  md5_stream (FILE *stream, void *resblock Line 177  md5_stream (FILE *stream, void *resblock
177          }          }
178    
179        /* Process buffer with BLOCKSIZE bytes.  Note that        /* Process buffer with BLOCKSIZE bytes.  Note that
180                          BLOCKSIZE % 64 == 0           BLOCKSIZE % 64 == 0
181         */         */
182        md5_process_block (buffer, BLOCKSIZE, &ctx);        md5_process_block (buffer, BLOCKSIZE, &ctx);
183      }      }
184    
185   process_partial_block:;  process_partial_block:
186    
187    /* Process any remaining bytes.  */    /* Process any remaining bytes.  */
188    if (sum > 0)    if (sum > 0)
# Line 225  md5_process_bytes (const void *buffer, s Line 223  md5_process_bytes (const void *buffer, s
223        size_t left_over = ctx->buflen;        size_t left_over = ctx->buflen;
224        size_t add = 128 - left_over > len ? len : 128 - left_over;        size_t add = 128 - left_over > len ? len : 128 - left_over;
225    
226        memcpy (&ctx->buffer[left_over], buffer, add);        memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
227        ctx->buflen += add;        ctx->buflen += add;
228    
229        if (ctx->buflen > 64)        if (ctx->buflen > 64)
# Line 234  md5_process_bytes (const void *buffer, s Line 232  md5_process_bytes (const void *buffer, s
232    
233            ctx->buflen &= 63;            ctx->buflen &= 63;
234            /* The regions in the following copy operation cannot overlap.  */            /* The regions in the following copy operation cannot overlap.  */
235            memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],            memcpy (ctx->buffer,
236                      &((char *) ctx->buffer)[(left_over + add) & ~63],
237                    ctx->buflen);                    ctx->buflen);
238          }          }
239    
# Line 275  md5_process_bytes (const void *buffer, s Line 274  md5_process_bytes (const void *buffer, s
274      {      {
275        size_t left_over = ctx->buflen;        size_t left_over = ctx->buflen;
276    
277        memcpy (&ctx->buffer[left_over], buffer, len);        memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
278        left_over += len;        left_over += len;
279        if (left_over >= 64)        if (left_over >= 64)
280          {          {
281            md5_process_block (ctx->buffer, 64, ctx);            md5_process_block (ctx->buffer, 64, ctx);
282            left_over -= 64;            left_over -= 64;
283            memcpy (ctx->buffer, &ctx->buffer[64], left_over);            memcpy (ctx->buffer, &ctx->buffer[16], left_over);
284          }          }
285        ctx->buflen = left_over;        ctx->buflen = left_over;
286      }      }
# Line 330  md5_process_block (const void *buffer, s Line 329  md5_process_block (const void *buffer, s
329        uint32_t D_save = D;        uint32_t D_save = D;
330    
331        /* First round: using the given function, the context and a constant        /* First round: using the given function, the context and a constant
332           the next context is computed.  Because the algorithms processing           the next context is computed.  Because the algorithms processing
333           unit is a 32-bit word and it is determined to work on words in           unit is a 32-bit word and it is determined to work on words in
334           little endian byte order we perhaps have to change the byte order           little endian byte order we perhaps have to change the byte order
335           before the computation.  To reduce the work for the next steps           before the computation.  To reduce the work for the next steps
336           we store the swapped words in the array CORRECT_WORDS.  */           we store the swapped words in the array CORRECT_WORDS.  */
337    
338  #define OP(a, b, c, d, s, T)                                            \  #define OP(a, b, c, d, s, T)                                            \
339        do                                                                \        do                                                                \
# Line 347  md5_process_block (const void *buffer, s Line 346  md5_process_block (const void *buffer, s
346        while (0)        while (0)
347    
348        /* It is unfortunate that C does not provide an operator for        /* It is unfortunate that C does not provide an operator for
349           cyclic rotation.  Hope the C compiler is smart enough.  */           cyclic rotation.  Hope the C compiler is smart enough.  */
350  #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))  #define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
351    
352        /* Before we start, one word to the strange constants.        /* Before we start, one word to the strange constants.
353           They are defined in RFC 1321 as           They are defined in RFC 1321 as
354    
355           T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64           T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
356    
357           Here is an equivalent invocation using Perl:           Here is an equivalent invocation using Perl:
358    
359           perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'           perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
360         */         */
361    
362        /* Round 1.  */        /* Round 1.  */
363        OP (A, B, C, D,  7, 0xd76aa478);        OP (A, B, C, D, 7, 0xd76aa478);
364        OP (D, A, B, C, 12, 0xe8c7b756);        OP (D, A, B, C, 12, 0xe8c7b756);
365        OP (C, D, A, B, 17, 0x242070db);        OP (C, D, A, B, 17, 0x242070db);
366        OP (B, C, D, A, 22, 0xc1bdceee);        OP (B, C, D, A, 22, 0xc1bdceee);
367        OP (A, B, C, D,  7, 0xf57c0faf);        OP (A, B, C, D, 7, 0xf57c0faf);
368        OP (D, A, B, C, 12, 0x4787c62a);        OP (D, A, B, C, 12, 0x4787c62a);
369        OP (C, D, A, B, 17, 0xa8304613);        OP (C, D, A, B, 17, 0xa8304613);
370        OP (B, C, D, A, 22, 0xfd469501);        OP (B, C, D, A, 22, 0xfd469501);
371        OP (A, B, C, D,  7, 0x698098d8);        OP (A, B, C, D, 7, 0x698098d8);
372        OP (D, A, B, C, 12, 0x8b44f7af);        OP (D, A, B, C, 12, 0x8b44f7af);
373        OP (C, D, A, B, 17, 0xffff5bb1);        OP (C, D, A, B, 17, 0xffff5bb1);
374        OP (B, C, D, A, 22, 0x895cd7be);        OP (B, C, D, A, 22, 0x895cd7be);
375        OP (A, B, C, D,  7, 0x6b901122);        OP (A, B, C, D, 7, 0x6b901122);
376        OP (D, A, B, C, 12, 0xfd987193);        OP (D, A, B, C, 12, 0xfd987193);
377        OP (C, D, A, B, 17, 0xa679438e);        OP (C, D, A, B, 17, 0xa679438e);
378        OP (B, C, D, A, 22, 0x49b40821);        OP (B, C, D, A, 22, 0x49b40821);
379    
380        /* For the second to fourth round we have the possibly swapped words        /* For the second to fourth round we have the possibly swapped words
381           in CORRECT_WORDS.  Redefine the macro to take an additional first           in CORRECT_WORDS.  Redefine the macro to take an additional first
382           argument specifying the function to use.  */           argument specifying the function to use.  */
383  #undef OP  #undef OP
384  #define OP(f, a, b, c, d, k, s, T)                                      \  #define OP(f, a, b, c, d, k, s, T)                                      \
385        do                                                                \        do                                                                \
# Line 392  md5_process_block (const void *buffer, s Line 391  md5_process_block (const void *buffer, s
391        while (0)        while (0)
392    
393        /* Round 2.  */        /* Round 2.  */
394        OP (FG, A, B, C, D,  1,  5, 0xf61e2562);        OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
395        OP (FG, D, A, B, C,  6,  9, 0xc040b340);        OP (FG, D, A, B, C, 6, 9, 0xc040b340);
396        OP (FG, C, D, A, B, 11, 14, 0x265e5a51);        OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
397        OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);        OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
398        OP (FG, A, B, C, D,  5,  5, 0xd62f105d);        OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
399        OP (FG, D, A, B, C, 10,  9, 0x02441453);        OP (FG, D, A, B, C, 10, 9, 0x02441453);
400        OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);        OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
401        OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);        OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
402        OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);        OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
403        OP (FG, D, A, B, C, 14,  9, 0xc33707d6);        OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
404        OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);        OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
405        OP (FG, B, C, D, A,  8, 20, 0x455a14ed);        OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
406        OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);        OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
407        OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);        OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
408        OP (FG, C, D, A, B,  7, 14, 0x676f02d9);        OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
409        OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);        OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
410    
411        /* Round 3.  */        /* Round 3.  */
412        OP (FH, A, B, C, D,  5,  4, 0xfffa3942);        OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
413        OP (FH, D, A, B, C,  8, 11, 0x8771f681);        OP (FH, D, A, B, C, 8, 11, 0x8771f681);
414        OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);        OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
415        OP (FH, B, C, D, A, 14, 23, 0xfde5380c);        OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
416        OP (FH, A, B, C, D,  1,  4, 0xa4beea44);        OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
417        OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);        OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
418        OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);        OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
419        OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);        OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
420        OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);        OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
421        OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);        OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
422        OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);        OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
423        OP (FH, B, C, D, A,  6, 23, 0x04881d05);        OP (FH, B, C, D, A, 6, 23, 0x04881d05);
424        OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);        OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
425        OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);        OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
426        OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);        OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
427        OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);        OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
428    
429        /* Round 4.  */        /* Round 4.  */
430        OP (FI, A, B, C, D,  0,  6, 0xf4292244);        OP (FI, A, B, C, D, 0, 6, 0xf4292244);
431        OP (FI, D, A, B, C,  7, 10, 0x432aff97);        OP (FI, D, A, B, C, 7, 10, 0x432aff97);
432        OP (FI, C, D, A, B, 14, 15, 0xab9423a7);        OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
433        OP (FI, B, C, D, A,  5, 21, 0xfc93a039);        OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
434        OP (FI, A, B, C, D, 12,  6, 0x655b59c3);        OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
435        OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);        OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
436        OP (FI, C, D, A, B, 10, 15, 0xffeff47d);        OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
437        OP (FI, B, C, D, A,  1, 21, 0x85845dd1);        OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
438        OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);        OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
439        OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);        OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
440        OP (FI, C, D, A, B,  6, 15, 0xa3014314);        OP (FI, C, D, A, B, 6, 15, 0xa3014314);
441        OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);        OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
442        OP (FI, A, B, C, D,  4,  6, 0xf7537e82);        OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
443        OP (FI, D, A, B, C, 11, 10, 0xbd3af235);        OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
444        OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);        OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
445        OP (FI, B, C, D, A,  9, 21, 0xeb86d391);        OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
446    
447        /* Add the starting values of the context.  */        /* Add the starting values of the context.  */
448        A += A_save;        A += A_save;

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26