Blame rfc1321.txt

Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Network Working Group                                          R. Rivest
Packit f354a3
Request for Comments: 1321           MIT Laboratory for Computer Science
Packit f354a3
                                             and RSA Data Security, Inc.
Packit f354a3
                                                              April 1992
Packit f354a3
Packit f354a3
Packit f354a3
                     The MD5 Message-Digest Algorithm
Packit f354a3
Packit f354a3
Status of this Memo
Packit f354a3
Packit f354a3
   This memo provides information for the Internet community.  It does
Packit f354a3
   not specify an Internet standard.  Distribution of this memo is
Packit f354a3
   unlimited.
Packit f354a3
Packit f354a3
Acknowlegements
Packit f354a3
Packit f354a3
   We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
Packit f354a3
   David Chaum, and Noam Nisan for numerous helpful comments and
Packit f354a3
   suggestions.
Packit f354a3
Packit f354a3
Table of Contents
Packit f354a3
Packit f354a3
   1. Executive Summary                                                1
Packit f354a3
   2. Terminology and Notation                                         2
Packit f354a3
   3. MD5 Algorithm Description                                        3
Packit f354a3
   4. Summary                                                          6
Packit f354a3
   5. Differences Between MD4 and MD5                                  6
Packit f354a3
   References                                                          7
Packit f354a3
   APPENDIX A - Reference Implementation                               7
Packit f354a3
   Security Considerations                                            21
Packit f354a3
   Author's Address                                                   21
Packit f354a3
Packit f354a3
1. Executive Summary
Packit f354a3
Packit f354a3
   This document describes the MD5 message-digest algorithm. The
Packit f354a3
   algorithm takes as input a message of arbitrary length and produces
Packit f354a3
   as output a 128-bit "fingerprint" or "message digest" of the input.
Packit f354a3
   It is conjectured that it is computationally infeasible to produce
Packit f354a3
   two messages having the same message digest, or to produce any
Packit f354a3
   message having a given prespecified target message digest. The MD5
Packit f354a3
   algorithm is intended for digital signature applications, where a
Packit f354a3
   large file must be "compressed" in a secure manner before being
Packit f354a3
   encrypted with a private (secret) key under a public-key cryptosystem
Packit f354a3
   such as RSA.
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 1]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
   The MD5 algorithm is designed to be quite fast on 32-bit machines. In
Packit f354a3
   addition, the MD5 algorithm does not require any large substitution
Packit f354a3
   tables; the algorithm can be coded quite compactly.
Packit f354a3
Packit f354a3
   The MD5 algorithm is an extension of the MD4 message-digest algorithm
Packit f354a3
   1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
Packit f354a3
   design. MD5 was designed because it was felt that MD4 was perhaps
Packit f354a3
   being adopted for use more quickly than justified by the existing
Packit f354a3
   critical review; because MD4 was designed to be exceptionally fast,
Packit f354a3
   it is "at the edge" in terms of risking successful cryptanalytic
Packit f354a3
   attack. MD5 backs off a bit, giving up a little in speed for a much
Packit f354a3
   greater likelihood of ultimate security. It incorporates some
Packit f354a3
   suggestions made by various reviewers, and contains additional
Packit f354a3
   optimizations. The MD5 algorithm is being placed in the public domain
Packit f354a3
   for review and possible adoption as a standard.
Packit f354a3
Packit f354a3
   For OSI-based applications, MD5's object identifier is
Packit f354a3
Packit f354a3
   md5 OBJECT IDENTIFIER ::=
Packit f354a3
     iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
Packit f354a3
Packit f354a3
   In the X.509 type AlgorithmIdentifier [3], the parameters for MD5
Packit f354a3
   should have type NULL.
Packit f354a3
Packit f354a3
2. Terminology and Notation
Packit f354a3
Packit f354a3
   In this document a "word" is a 32-bit quantity and a "byte" is an
Packit f354a3
   eight-bit quantity. A sequence of bits can be interpreted in a
Packit f354a3
   natural manner as a sequence of bytes, where each consecutive group
Packit f354a3
   of eight bits is interpreted as a byte with the high-order (most
Packit f354a3
   significant) bit of each byte listed first. Similarly, a sequence of
Packit f354a3
   bytes can be interpreted as a sequence of 32-bit words, where each
Packit f354a3
   consecutive group of four bytes is interpreted as a word with the
Packit f354a3
   low-order (least significant) byte given first.
Packit f354a3
Packit f354a3
   Let x_i denote "x sub i". If the subscript is an expression, we
Packit f354a3
   surround it in braces, as in x_{i+1}. Similarly, we use ^ for
Packit f354a3
   superscripts (exponentiation), so that x^i denotes x to the i-th
Packit f354a3
   power.
Packit f354a3
Packit f354a3
   Let the symbol "+" denote addition of words (i.e., modulo-2^32
Packit f354a3
   addition). Let X <<< s denote the 32-bit value obtained by circularly
Packit f354a3
   shifting (rotating) X left by s bit positions. Let not(X) denote the
Packit f354a3
   bit-wise complement of X, and let X v Y denote the bit-wise OR of X
Packit f354a3
   and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
Packit f354a3
   denote the bit-wise AND of X and Y.
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 2]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
3. MD5 Algorithm Description
Packit f354a3
Packit f354a3
   We begin by supposing that we have a b-bit message as input, and that
Packit f354a3
   we wish to find its message digest. Here b is an arbitrary
Packit f354a3
   nonnegative integer; b may be zero, it need not be a multiple of
Packit f354a3
   eight, and it may be arbitrarily large. We imagine the bits of the
Packit f354a3
   message written down as follows:
Packit f354a3
Packit f354a3
          m_0 m_1 ... m_{b-1}
Packit f354a3
Packit f354a3
   The following five steps are performed to compute the message digest
Packit f354a3
   of the message.
Packit f354a3
Packit f354a3
3.1 Step 1. Append Padding Bits
Packit f354a3
Packit f354a3
   The message is "padded" (extended) so that its length (in bits) is
Packit f354a3
   congruent to 448, modulo 512. That is, the message is extended so
Packit f354a3
   that it is just 64 bits shy of being a multiple of 512 bits long.
Packit f354a3
   Padding is always performed, even if the length of the message is
Packit f354a3
   already congruent to 448, modulo 512.
Packit f354a3
Packit f354a3
   Padding is performed as follows: a single "1" bit is appended to the
Packit f354a3
   message, and then "0" bits are appended so that the length in bits of
Packit f354a3
   the padded message becomes congruent to 448, modulo 512. In all, at
Packit f354a3
   least one bit and at most 512 bits are appended.
Packit f354a3
Packit f354a3
3.2 Step 2. Append Length
Packit f354a3
Packit f354a3
   A 64-bit representation of b (the length of the message before the
Packit f354a3
   padding bits were added) is appended to the result of the previous
Packit f354a3
   step. In the unlikely event that b is greater than 2^64, then only
Packit f354a3
   the low-order 64 bits of b are used. (These bits are appended as two
Packit f354a3
   32-bit words and appended low-order word first in accordance with the
Packit f354a3
   previous conventions.)
Packit f354a3
Packit f354a3
   At this point the resulting message (after padding with bits and with
Packit f354a3
   b) has a length that is an exact multiple of 512 bits. Equivalently,
Packit f354a3
   this message has a length that is an exact multiple of 16 (32-bit)
Packit f354a3
   words. Let M[0 ... N-1] denote the words of the resulting message,
Packit f354a3
   where N is a multiple of 16.
Packit f354a3
Packit f354a3
3.3 Step 3. Initialize MD Buffer
Packit f354a3
Packit f354a3
   A four-word buffer (A,B,C,D) is used to compute the message digest.
Packit f354a3
   Here each of A, B, C, D is a 32-bit register. These registers are
Packit f354a3
   initialized to the following values in hexadecimal, low-order bytes
Packit f354a3
   first):
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 3]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
          word A: 01 23 45 67
Packit f354a3
          word B: 89 ab cd ef
Packit f354a3
          word C: fe dc ba 98
Packit f354a3
          word D: 76 54 32 10
Packit f354a3
Packit f354a3
3.4 Step 4. Process Message in 16-Word Blocks
Packit f354a3
Packit f354a3
   We first define four auxiliary functions that each take as input
Packit f354a3
   three 32-bit words and produce as output one 32-bit word.
Packit f354a3
Packit f354a3
          F(X,Y,Z) = XY v not(X) Z
Packit f354a3
          G(X,Y,Z) = XZ v Y not(Z)
Packit f354a3
          H(X,Y,Z) = X xor Y xor Z
Packit f354a3
          I(X,Y,Z) = Y xor (X v not(Z))
Packit f354a3
Packit f354a3
   In each bit position F acts as a conditional: if X then Y else Z.
Packit f354a3
   The function F could have been defined using + instead of v since XY
Packit f354a3
   and not(X)Z will never have 1's in the same bit position.) It is
Packit f354a3
   interesting to note that if the bits of X, Y, and Z are independent
Packit f354a3
   and unbiased, the each bit of F(X,Y,Z) will be independent and
Packit f354a3
   unbiased.
Packit f354a3
Packit f354a3
   The functions G, H, and I are similar to the function F, in that they
Packit f354a3
   act in "bitwise parallel" to produce their output from the bits of X,
Packit f354a3
   Y, and Z, in such a manner that if the corresponding bits of X, Y,
Packit f354a3
   and Z are independent and unbiased, then each bit of G(X,Y,Z),
Packit f354a3
   H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
Packit f354a3
   the function H is the bit-wise "xor" or "parity" function of its
Packit f354a3
   inputs.
Packit f354a3
Packit f354a3
   This step uses a 64-element table T[1 ... 64] constructed from the
Packit f354a3
   sine function. Let T[i] denote the i-th element of the table, which
Packit f354a3
   is equal to the integer part of 4294967296 times abs(sin(i)), where i
Packit f354a3
   is in radians. The elements of the table are given in the appendix.
Packit f354a3
Packit f354a3
   Do the following:
Packit f354a3
Packit f354a3
   /* Process each 16-word block. */
Packit f354a3
   For i = 0 to N/16-1 do
Packit f354a3
Packit f354a3
     /* Copy block i into X. */
Packit f354a3
     For j = 0 to 15 do
Packit f354a3
       Set X[j] to M[i*16+j].
Packit f354a3
     end /* of loop on j */
Packit f354a3
Packit f354a3
     /* Save A as AA, B as BB, C as CC, and D as DD. */
Packit f354a3
     AA = A
Packit f354a3
     BB = B
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 4]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
     CC = C
Packit f354a3
     DD = D
Packit f354a3
Packit f354a3
     /* Round 1. */
Packit f354a3
     /* Let [abcd k s i] denote the operation
Packit f354a3
          a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
Packit f354a3
     /* Do the following 16 operations. */
Packit f354a3
     [ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
Packit f354a3
     [ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8]
Packit f354a3
     [ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12]
Packit f354a3
     [ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16]
Packit f354a3
Packit f354a3
     /* Round 2. */
Packit f354a3
     /* Let [abcd k s i] denote the operation
Packit f354a3
          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
Packit f354a3
     /* Do the following 16 operations. */
Packit f354a3
     [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
Packit f354a3
     [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]
Packit f354a3
     [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]
Packit f354a3
     [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]
Packit f354a3
Packit f354a3
     /* Round 3. */
Packit f354a3
     /* Let [abcd k s t] denote the operation
Packit f354a3
          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
Packit f354a3
     /* Do the following 16 operations. */
Packit f354a3
     [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
Packit f354a3
     [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]
Packit f354a3
     [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]
Packit f354a3
     [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]
Packit f354a3
Packit f354a3
     /* Round 4. */
Packit f354a3
     /* Let [abcd k s t] denote the operation
Packit f354a3
          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
Packit f354a3
     /* Do the following 16 operations. */
Packit f354a3
     [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
Packit f354a3
     [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]
Packit f354a3
     [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]
Packit f354a3
     [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]
Packit f354a3
Packit f354a3
     /* Then perform the following additions. (That is increment each
Packit f354a3
        of the four registers by the value it had before this block
Packit f354a3
        was started.) */
Packit f354a3
     A = A + AA
Packit f354a3
     B = B + BB
Packit f354a3
     C = C + CC
Packit f354a3
     D = D + DD
Packit f354a3
Packit f354a3
   end /* of loop on i */
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 5]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
3.5 Step 5. Output
Packit f354a3
Packit f354a3
   The message digest produced as output is A, B, C, D. That is, we
Packit f354a3
   begin with the low-order byte of A, and end with the high-order byte
Packit f354a3
   of D.
Packit f354a3
Packit f354a3
   This completes the description of MD5. A reference implementation in
Packit f354a3
   C is given in the appendix.
Packit f354a3
Packit f354a3
4. Summary
Packit f354a3
Packit f354a3
   The MD5 message-digest algorithm is simple to implement, and provides
Packit f354a3
   a "fingerprint" or message digest of a message of arbitrary length.
Packit f354a3
   It is conjectured that the difficulty of coming up with two messages
Packit f354a3
   having the same message digest is on the order of 2^64 operations,
Packit f354a3
   and that the difficulty of coming up with any message having a given
Packit f354a3
   message digest is on the order of 2^128 operations. The MD5 algorithm
Packit f354a3
   has been carefully scrutinized for weaknesses. It is, however, a
Packit f354a3
   relatively new algorithm and further security analysis is of course
Packit f354a3
   justified, as is the case with any new proposal of this sort.
Packit f354a3
Packit f354a3
5. Differences Between MD4 and MD5
Packit f354a3
Packit f354a3
     The following are the differences between MD4 and MD5:
Packit f354a3
Packit f354a3
       1.   A fourth round has been added.
Packit f354a3
Packit f354a3
       2.   Each step now has a unique additive constant.
Packit f354a3
Packit f354a3
       3.   The function g in round 2 was changed from (XY v XZ v YZ) to
Packit f354a3
       (XZ v Y not(Z)) to make g less symmetric.
Packit f354a3
Packit f354a3
       4.   Each step now adds in the result of the previous step.  This
Packit f354a3
       promotes a faster "avalanche effect".
Packit f354a3
Packit f354a3
       5.   The order in which input words are accessed in rounds 2 and
Packit f354a3
       3 is changed, to make these patterns less like each other.
Packit f354a3
Packit f354a3
       6.   The shift amounts in each round have been approximately
Packit f354a3
       optimized, to yield a faster "avalanche effect." The shifts in
Packit f354a3
       different rounds are distinct.
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 6]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
References
Packit f354a3
Packit f354a3
   [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and
Packit f354a3
       RSA Data Security, Inc., April 1992.
Packit f354a3
Packit f354a3
   [2] Rivest, R., "The MD4 message digest algorithm", in A.J.  Menezes
Packit f354a3
       and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90
Packit f354a3
       Proceedings, pages 303-311, Springer-Verlag, 1991.
Packit f354a3
Packit f354a3
   [3] CCITT Recommendation X.509 (1988), "The Directory -
Packit f354a3
       Authentication Framework."
Packit f354a3
Packit f354a3
APPENDIX A - Reference Implementation
Packit f354a3
Packit f354a3
   This appendix contains the following files taken from RSAREF: A
Packit f354a3
   Cryptographic Toolkit for Privacy-Enhanced Mail:
Packit f354a3
Packit f354a3
     global.h -- global header file
Packit f354a3
Packit f354a3
     md5.h -- header file for MD5
Packit f354a3
Packit f354a3
     md5c.c -- source code for MD5
Packit f354a3
Packit f354a3
   For more information on RSAREF, send email to <rsaref@rsa.com>.
Packit f354a3
Packit f354a3
   The appendix also includes the following file:
Packit f354a3
Packit f354a3
     mddriver.c -- test driver for MD2, MD4 and MD5
Packit f354a3
Packit f354a3
   The driver compiles for MD5 by default but can compile for MD2 or MD4
Packit f354a3
   if the symbol MD is defined on the C compiler command line as 2 or 4.
Packit f354a3
Packit f354a3
   The implementation is portable and should work on many different
Packit f354a3
   plaforms. However, it is not difficult to optimize the implementation
Packit f354a3
   on particular platforms, an exercise left to the reader. For example,
Packit f354a3
   on "little-endian" platforms where the lowest-addressed byte in a 32-
Packit f354a3
   bit word is the least significant and there are no alignment
Packit f354a3
   restrictions, the call to Decode in MD5Transform can be replaced with
Packit f354a3
   a typecast.
Packit f354a3
Packit f354a3
A.1 global.h
Packit f354a3
Packit f354a3
/* GLOBAL.H - RSAREF types and constants
Packit f354a3
 */
Packit f354a3
Packit f354a3
/* PROTOTYPES should be set to one if and only if the compiler supports
Packit f354a3
  function argument prototyping.
Packit f354a3
The following makes PROTOTYPES default to 0 if it has not already
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 7]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
  been defined with C compiler flags.
Packit f354a3
 */
Packit f354a3
#ifndef PROTOTYPES
Packit f354a3
#define PROTOTYPES 0
Packit f354a3
#endif
Packit f354a3
Packit f354a3
/* POINTER defines a generic pointer type */
Packit f354a3
typedef unsigned char *POINTER;
Packit f354a3
Packit f354a3
/* UINT2 defines a two byte word */
Packit f354a3
typedef unsigned short int UINT2;
Packit f354a3
Packit f354a3
/* UINT4 defines a four byte word */
Packit f354a3
typedef unsigned long int UINT4;
Packit f354a3
Packit f354a3
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
Packit f354a3
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
Packit f354a3
  returns an empty list.
Packit f354a3
 */
Packit f354a3
#if PROTOTYPES
Packit f354a3
#define PROTO_LIST(list) list
Packit f354a3
#else
Packit f354a3
#define PROTO_LIST(list) ()
Packit f354a3
#endif
Packit f354a3
Packit f354a3
A.2 md5.h
Packit f354a3
Packit f354a3
/* MD5.H - header file for MD5C.C
Packit f354a3
 */
Packit f354a3
Packit f354a3
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
Packit f354a3
rights reserved.
Packit f354a3
Packit f354a3
License to copy and use this software is granted provided that it
Packit f354a3
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Packit f354a3
Algorithm" in all material mentioning or referencing this software
Packit f354a3
or this function.
Packit f354a3
Packit f354a3
License is also granted to make and use derivative works provided
Packit f354a3
that such works are identified as "derived from the RSA Data
Packit f354a3
Security, Inc. MD5 Message-Digest Algorithm" in all material
Packit f354a3
mentioning or referencing the derived work.
Packit f354a3
Packit f354a3
RSA Data Security, Inc. makes no representations concerning either
Packit f354a3
the merchantability of this software or the suitability of this
Packit f354a3
software for any particular purpose. It is provided "as is"
Packit f354a3
without express or implied warranty of any kind.
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 8]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
These notices must be retained in any copies of any part of this
Packit f354a3
documentation and/or software.
Packit f354a3
 */
Packit f354a3
Packit f354a3
/* MD5 context. */
Packit f354a3
typedef struct {
Packit f354a3
  UINT4 state[4];                                   /* state (ABCD) */
Packit f354a3
  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
Packit f354a3
  unsigned char buffer[64];                         /* input buffer */
Packit f354a3
} MD5_CTX;
Packit f354a3
Packit f354a3
void MD5Init PROTO_LIST ((MD5_CTX *));
Packit f354a3
void MD5Update PROTO_LIST
Packit f354a3
  ((MD5_CTX *, unsigned char *, unsigned int));
Packit f354a3
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
Packit f354a3
Packit f354a3
A.3 md5c.c
Packit f354a3
Packit f354a3
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
Packit f354a3
 */
Packit f354a3
Packit f354a3
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
Packit f354a3
rights reserved.
Packit f354a3
Packit f354a3
License to copy and use this software is granted provided that it
Packit f354a3
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Packit f354a3
Algorithm" in all material mentioning or referencing this software
Packit f354a3
or this function.
Packit f354a3
Packit f354a3
License is also granted to make and use derivative works provided
Packit f354a3
that such works are identified as "derived from the RSA Data
Packit f354a3
Security, Inc. MD5 Message-Digest Algorithm" in all material
Packit f354a3
mentioning or referencing the derived work.
Packit f354a3
Packit f354a3
RSA Data Security, Inc. makes no representations concerning either
Packit f354a3
the merchantability of this software or the suitability of this
Packit f354a3
software for any particular purpose. It is provided "as is"
Packit f354a3
without express or implied warranty of any kind.
Packit f354a3
Packit f354a3
These notices must be retained in any copies of any part of this
Packit f354a3
documentation and/or software.
Packit f354a3
 */
Packit f354a3
Packit f354a3
#include "global.h"
Packit f354a3
#include "md5.h"
Packit f354a3
Packit f354a3
/* Constants for MD5Transform routine.
Packit f354a3
 */
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                          [Page 9]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
#define S11 7
Packit f354a3
#define S12 12
Packit f354a3
#define S13 17
Packit f354a3
#define S14 22
Packit f354a3
#define S21 5
Packit f354a3
#define S22 9
Packit f354a3
#define S23 14
Packit f354a3
#define S24 20
Packit f354a3
#define S31 4
Packit f354a3
#define S32 11
Packit f354a3
#define S33 16
Packit f354a3
#define S34 23
Packit f354a3
#define S41 6
Packit f354a3
#define S42 10
Packit f354a3
#define S43 15
Packit f354a3
#define S44 21
Packit f354a3
Packit f354a3
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
Packit f354a3
static void Encode PROTO_LIST
Packit f354a3
  ((unsigned char *, UINT4 *, unsigned int));
Packit f354a3
static void Decode PROTO_LIST
Packit f354a3
  ((UINT4 *, unsigned char *, unsigned int));
Packit f354a3
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
Packit f354a3
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
Packit f354a3
Packit f354a3
static unsigned char PADDING[64] = {
Packit f354a3
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Packit f354a3
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Packit f354a3
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Packit f354a3
};
Packit f354a3
Packit f354a3
/* F, G, H and I are basic MD5 functions.
Packit f354a3
 */
Packit f354a3
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
Packit f354a3
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
Packit f354a3
#define H(x, y, z) ((x) ^ (y) ^ (z))
Packit f354a3
#define I(x, y, z) ((y) ^ ((x) | (~z)))
Packit f354a3
Packit f354a3
/* ROTATE_LEFT rotates x left n bits.
Packit f354a3
 */
Packit f354a3
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
Packit f354a3
Packit f354a3
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Packit f354a3
Rotation is separate from addition to prevent recomputation.
Packit f354a3
 */
Packit f354a3
#define FF(a, b, c, d, x, s, ac) { \
Packit f354a3
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit f354a3
 (a) = ROTATE_LEFT ((a), (s)); \
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 10]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
 (a) += (b); \
Packit f354a3
  }
Packit f354a3
#define GG(a, b, c, d, x, s, ac) { \
Packit f354a3
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit f354a3
 (a) = ROTATE_LEFT ((a), (s)); \
Packit f354a3
 (a) += (b); \
Packit f354a3
  }
Packit f354a3
#define HH(a, b, c, d, x, s, ac) { \
Packit f354a3
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit f354a3
 (a) = ROTATE_LEFT ((a), (s)); \
Packit f354a3
 (a) += (b); \
Packit f354a3
  }
Packit f354a3
#define II(a, b, c, d, x, s, ac) { \
Packit f354a3
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
Packit f354a3
 (a) = ROTATE_LEFT ((a), (s)); \
Packit f354a3
 (a) += (b); \
Packit f354a3
  }
Packit f354a3
Packit f354a3
/* MD5 initialization. Begins an MD5 operation, writing a new context.
Packit f354a3
 */
Packit f354a3
void MD5Init (context)
Packit f354a3
MD5_CTX *context;                                        /* context */
Packit f354a3
{
Packit f354a3
  context->count[0] = context->count[1] = 0;
Packit f354a3
  /* Load magic initialization constants.
Packit f354a3
*/
Packit f354a3
  context->state[0] = 0x67452301;
Packit f354a3
  context->state[1] = 0xefcdab89;
Packit f354a3
  context->state[2] = 0x98badcfe;
Packit f354a3
  context->state[3] = 0x10325476;
Packit f354a3
}
Packit f354a3
Packit f354a3
/* MD5 block update operation. Continues an MD5 message-digest
Packit f354a3
  operation, processing another message block, and updating the
Packit f354a3
  context.
Packit f354a3
 */
Packit f354a3
void MD5Update (context, input, inputLen)
Packit f354a3
MD5_CTX *context;                                        /* context */
Packit f354a3
unsigned char *input;                                /* input block */
Packit f354a3
unsigned int inputLen;                     /* length of input block */
Packit f354a3
{
Packit f354a3
  unsigned int i, index, partLen;
Packit f354a3
Packit f354a3
  /* Compute number of bytes mod 64 */
Packit f354a3
  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
Packit f354a3
Packit f354a3
  /* Update number of bits */
Packit f354a3
  if ((context->count[0] += ((UINT4)inputLen << 3))
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 11]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
   < ((UINT4)inputLen << 3))
Packit f354a3
 context->count[1]++;
Packit f354a3
  context->count[1] += ((UINT4)inputLen >> 29);
Packit f354a3
Packit f354a3
  partLen = 64 - index;
Packit f354a3
Packit f354a3
  /* Transform as many times as possible.
Packit f354a3
*/
Packit f354a3
  if (inputLen >= partLen) {
Packit f354a3
 MD5_memcpy
Packit f354a3
   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
Packit f354a3
 MD5Transform (context->state, context->buffer);
Packit f354a3
Packit f354a3
 for (i = partLen; i + 63 < inputLen; i += 64)
Packit f354a3
   MD5Transform (context->state, &input[i]);
Packit f354a3
Packit f354a3
 index = 0;
Packit f354a3
  }
Packit f354a3
  else
Packit f354a3
 i = 0;
Packit f354a3
Packit f354a3
  /* Buffer remaining input */
Packit f354a3
  MD5_memcpy
Packit f354a3
 ((POINTER)&context->buffer[index], (POINTER)&input[i],
Packit f354a3
  inputLen-i);
Packit f354a3
}
Packit f354a3
Packit f354a3
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
Packit f354a3
  the message digest and zeroizing the context.
Packit f354a3
 */
Packit f354a3
void MD5Final (digest, context)
Packit f354a3
unsigned char digest[16];                         /* message digest */
Packit f354a3
MD5_CTX *context;                                       /* context */
Packit f354a3
{
Packit f354a3
  unsigned char bits[8];
Packit f354a3
  unsigned int index, padLen;
Packit f354a3
Packit f354a3
  /* Save number of bits */
Packit f354a3
  Encode (bits, context->count, 8);
Packit f354a3
Packit f354a3
  /* Pad out to 56 mod 64.
Packit f354a3
*/
Packit f354a3
  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
Packit f354a3
  padLen = (index < 56) ? (56 - index) : (120 - index);
Packit f354a3
  MD5Update (context, PADDING, padLen);
Packit f354a3
Packit f354a3
  /* Append length (before padding) */
Packit f354a3
  MD5Update (context, bits, 8);
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 12]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
  /* Store state in digest */
Packit f354a3
  Encode (digest, context->state, 16);
Packit f354a3
Packit f354a3
  /* Zeroize sensitive information.
Packit f354a3
*/
Packit f354a3
  MD5_memset ((POINTER)context, 0, sizeof (*context));
Packit f354a3
}
Packit f354a3
Packit f354a3
/* MD5 basic transformation. Transforms state based on block.
Packit f354a3
 */
Packit f354a3
static void MD5Transform (state, block)
Packit f354a3
UINT4 state[4];
Packit f354a3
unsigned char block[64];
Packit f354a3
{
Packit f354a3
  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Packit f354a3
Packit f354a3
  Decode (x, block, 64);
Packit f354a3
Packit f354a3
  /* Round 1 */
Packit f354a3
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
Packit f354a3
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
Packit f354a3
  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
Packit f354a3
  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
Packit f354a3
  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
Packit f354a3
  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
Packit f354a3
  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
Packit f354a3
  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
Packit f354a3
  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
Packit f354a3
  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
Packit f354a3
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
Packit f354a3
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
Packit f354a3
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
Packit f354a3
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
Packit f354a3
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
Packit f354a3
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
Packit f354a3
Packit f354a3
 /* Round 2 */
Packit f354a3
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
Packit f354a3
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
Packit f354a3
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
Packit f354a3
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
Packit f354a3
  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
Packit f354a3
  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
Packit f354a3
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
Packit f354a3
  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
Packit f354a3
  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
Packit f354a3
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
Packit f354a3
  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 13]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
Packit f354a3
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
Packit f354a3
  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
Packit f354a3
  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
Packit f354a3
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
Packit f354a3
Packit f354a3
  /* Round 3 */
Packit f354a3
  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
Packit f354a3
  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
Packit f354a3
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
Packit f354a3
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
Packit f354a3
  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
Packit f354a3
  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
Packit f354a3
  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
Packit f354a3
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
Packit f354a3
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
Packit f354a3
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
Packit f354a3
  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
Packit f354a3
  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
Packit f354a3
  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
Packit f354a3
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
Packit f354a3
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
Packit f354a3
  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
Packit f354a3
Packit f354a3
  /* Round 4 */
Packit f354a3
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
Packit f354a3
  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
Packit f354a3
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
Packit f354a3
  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
Packit f354a3
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
Packit f354a3
  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
Packit f354a3
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
Packit f354a3
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
Packit f354a3
  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
Packit f354a3
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
Packit f354a3
  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
Packit f354a3
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
Packit f354a3
  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
Packit f354a3
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
Packit f354a3
  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
Packit f354a3
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
Packit f354a3
Packit f354a3
  state[0] += a;
Packit f354a3
  state[1] += b;
Packit f354a3
  state[2] += c;
Packit f354a3
  state[3] += d;
Packit f354a3
Packit f354a3
  /* Zeroize sensitive information.
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 14]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
*/
Packit f354a3
  MD5_memset ((POINTER)x, 0, sizeof (x));
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
Packit f354a3
  a multiple of 4.
Packit f354a3
 */
Packit f354a3
static void Encode (output, input, len)
Packit f354a3
unsigned char *output;
Packit f354a3
UINT4 *input;
Packit f354a3
unsigned int len;
Packit f354a3
{
Packit f354a3
  unsigned int i, j;
Packit f354a3
Packit f354a3
  for (i = 0, j = 0; j < len; i++, j += 4) {
Packit f354a3
 output[j] = (unsigned char)(input[i] & 0xff);
Packit f354a3
 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
Packit f354a3
 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
Packit f354a3
 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
Packit f354a3
  }
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
Packit f354a3
  a multiple of 4.
Packit f354a3
 */
Packit f354a3
static void Decode (output, input, len)
Packit f354a3
UINT4 *output;
Packit f354a3
unsigned char *input;
Packit f354a3
unsigned int len;
Packit f354a3
{
Packit f354a3
  unsigned int i, j;
Packit f354a3
Packit f354a3
  for (i = 0, j = 0; j < len; i++, j += 4)
Packit f354a3
 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
Packit f354a3
   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Note: Replace "for loop" with standard memcpy if possible.
Packit f354a3
 */
Packit f354a3
Packit f354a3
static void MD5_memcpy (output, input, len)
Packit f354a3
POINTER output;
Packit f354a3
POINTER input;
Packit f354a3
unsigned int len;
Packit f354a3
{
Packit f354a3
  unsigned int i;
Packit f354a3
Packit f354a3
  for (i = 0; i < len; i++)
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 15]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
 output[i] = input[i];
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Note: Replace "for loop" with standard memset if possible.
Packit f354a3
 */
Packit f354a3
static void MD5_memset (output, value, len)
Packit f354a3
POINTER output;
Packit f354a3
int value;
Packit f354a3
unsigned int len;
Packit f354a3
{
Packit f354a3
  unsigned int i;
Packit f354a3
Packit f354a3
  for (i = 0; i < len; i++)
Packit f354a3
 ((char *)output)[i] = (char)value;
Packit f354a3
}
Packit f354a3
Packit f354a3
A.4 mddriver.c
Packit f354a3
Packit f354a3
/* MDDRIVER.C - test driver for MD2, MD4 and MD5
Packit f354a3
 */
Packit f354a3
Packit f354a3
/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
Packit f354a3
rights reserved.
Packit f354a3
Packit f354a3
RSA Data Security, Inc. makes no representations concerning either
Packit f354a3
the merchantability of this software or the suitability of this
Packit f354a3
software for any particular purpose. It is provided "as is"
Packit f354a3
without express or implied warranty of any kind.
Packit f354a3
Packit f354a3
These notices must be retained in any copies of any part of this
Packit f354a3
documentation and/or software.
Packit f354a3
 */
Packit f354a3
Packit f354a3
/* The following makes MD default to MD5 if it has not already been
Packit f354a3
  defined with C compiler flags.
Packit f354a3
 */
Packit f354a3
#ifndef MD
Packit f354a3
#define MD MD5
Packit f354a3
#endif
Packit f354a3
Packit f354a3
#include <stdio.h>
Packit f354a3
#include <time.h>
Packit f354a3
#include <string.h>
Packit f354a3
#include "global.h"
Packit f354a3
#if MD == 2
Packit f354a3
#include "md2.h"
Packit f354a3
#endif
Packit f354a3
#if MD == 4
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 16]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
#include "md4.h"
Packit f354a3
#endif
Packit f354a3
#if MD == 5
Packit f354a3
#include "md5.h"
Packit f354a3
#endif
Packit f354a3
Packit f354a3
/* Length of test block, number of test blocks.
Packit f354a3
 */
Packit f354a3
#define TEST_BLOCK_LEN 1000
Packit f354a3
#define TEST_BLOCK_COUNT 1000
Packit f354a3
Packit f354a3
static void MDString PROTO_LIST ((char *));
Packit f354a3
static void MDTimeTrial PROTO_LIST ((void));
Packit f354a3
static void MDTestSuite PROTO_LIST ((void));
Packit f354a3
static void MDFile PROTO_LIST ((char *));
Packit f354a3
static void MDFilter PROTO_LIST ((void));
Packit f354a3
static void MDPrint PROTO_LIST ((unsigned char [16]));
Packit f354a3
Packit f354a3
#if MD == 2
Packit f354a3
#define MD_CTX MD2_CTX
Packit f354a3
#define MDInit MD2Init
Packit f354a3
#define MDUpdate MD2Update
Packit f354a3
#define MDFinal MD2Final
Packit f354a3
#endif
Packit f354a3
#if MD == 4
Packit f354a3
#define MD_CTX MD4_CTX
Packit f354a3
#define MDInit MD4Init
Packit f354a3
#define MDUpdate MD4Update
Packit f354a3
#define MDFinal MD4Final
Packit f354a3
#endif
Packit f354a3
#if MD == 5
Packit f354a3
#define MD_CTX MD5_CTX
Packit f354a3
#define MDInit MD5Init
Packit f354a3
#define MDUpdate MD5Update
Packit f354a3
#define MDFinal MD5Final
Packit f354a3
#endif
Packit f354a3
Packit f354a3
/* Main driver.
Packit f354a3
Packit f354a3
Arguments (may be any combination):
Packit f354a3
  -sstring - digests string
Packit f354a3
  -t       - runs time trial
Packit f354a3
  -x       - runs test script
Packit f354a3
  filename - digests file
Packit f354a3
  (none)   - digests standard input
Packit f354a3
 */
Packit f354a3
int main (argc, argv)
Packit f354a3
int argc;
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 17]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
char *argv[];
Packit f354a3
{
Packit f354a3
  int i;
Packit f354a3
Packit f354a3
  if (argc > 1)
Packit f354a3
 for (i = 1; i < argc; i++)
Packit f354a3
   if (argv[i][0] == '-' && argv[i][1] == 's')
Packit f354a3
     MDString (argv[i] + 2);
Packit f354a3
   else if (strcmp (argv[i], "-t") == 0)
Packit f354a3
     MDTimeTrial ();
Packit f354a3
   else if (strcmp (argv[i], "-x") == 0)
Packit f354a3
     MDTestSuite ();
Packit f354a3
   else
Packit f354a3
     MDFile (argv[i]);
Packit f354a3
  else
Packit f354a3
 MDFilter ();
Packit f354a3
Packit f354a3
  return (0);
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Digests a string and prints the result.
Packit f354a3
 */
Packit f354a3
static void MDString (string)
Packit f354a3
char *string;
Packit f354a3
{
Packit f354a3
  MD_CTX context;
Packit f354a3
  unsigned char digest[16];
Packit f354a3
  unsigned int len = strlen (string);
Packit f354a3
Packit f354a3
  MDInit (&context);
Packit f354a3
  MDUpdate (&context, string, len);
Packit f354a3
  MDFinal (digest, &context);
Packit f354a3
Packit f354a3
  printf ("MD%d (\"%s\") = ", MD, string);
Packit f354a3
  MDPrint (digest);
Packit f354a3
  printf ("\n");
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
Packit f354a3
  blocks.
Packit f354a3
 */
Packit f354a3
static void MDTimeTrial ()
Packit f354a3
{
Packit f354a3
  MD_CTX context;
Packit f354a3
  time_t endTime, startTime;
Packit f354a3
  unsigned char block[TEST_BLOCK_LEN], digest[16];
Packit f354a3
  unsigned int i;
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 18]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
  printf
Packit f354a3
 ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
Packit f354a3
  TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
Packit f354a3
Packit f354a3
  /* Initialize block */
Packit f354a3
  for (i = 0; i < TEST_BLOCK_LEN; i++)
Packit f354a3
 block[i] = (unsigned char)(i & 0xff);
Packit f354a3
Packit f354a3
  /* Start timer */
Packit f354a3
  time (&startTime);
Packit f354a3
Packit f354a3
  /* Digest blocks */
Packit f354a3
  MDInit (&context);
Packit f354a3
  for (i = 0; i < TEST_BLOCK_COUNT; i++)
Packit f354a3
 MDUpdate (&context, block, TEST_BLOCK_LEN);
Packit f354a3
  MDFinal (digest, &context);
Packit f354a3
Packit f354a3
  /* Stop timer */
Packit f354a3
  time (&endTime);
Packit f354a3
Packit f354a3
  printf (" done\n");
Packit f354a3
  printf ("Digest = ");
Packit f354a3
  MDPrint (digest);
Packit f354a3
  printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));
Packit f354a3
  printf
Packit f354a3
 ("Speed = %ld bytes/second\n",
Packit f354a3
  (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Digests a reference suite of strings and prints the results.
Packit f354a3
 */
Packit f354a3
static void MDTestSuite ()
Packit f354a3
{
Packit f354a3
  printf ("MD%d test suite:\n", MD);
Packit f354a3
Packit f354a3
  MDString ("");
Packit f354a3
  MDString ("a");
Packit f354a3
  MDString ("abc");
Packit f354a3
  MDString ("message digest");
Packit f354a3
  MDString ("abcdefghijklmnopqrstuvwxyz");
Packit f354a3
  MDString
Packit f354a3
 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
Packit f354a3
  MDString
Packit f354a3
 ("1234567890123456789012345678901234567890\
Packit f354a3
1234567890123456789012345678901234567890");
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Digests a file and prints the result.
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 19]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
 */
Packit f354a3
static void MDFile (filename)
Packit f354a3
char *filename;
Packit f354a3
{
Packit f354a3
  FILE *file;
Packit f354a3
  MD_CTX context;
Packit f354a3
  int len;
Packit f354a3
  unsigned char buffer[1024], digest[16];
Packit f354a3
Packit f354a3
  if ((file = fopen (filename, "rb")) == NULL)
Packit f354a3
 printf ("%s can't be opened\n", filename);
Packit f354a3
Packit f354a3
  else {
Packit f354a3
 MDInit (&context);
Packit f354a3
 while (len = fread (buffer, 1, 1024, file))
Packit f354a3
   MDUpdate (&context, buffer, len);
Packit f354a3
 MDFinal (digest, &context);
Packit f354a3
Packit f354a3
 fclose (file);
Packit f354a3
Packit f354a3
 printf ("MD%d (%s) = ", MD, filename);
Packit f354a3
 MDPrint (digest);
Packit f354a3
 printf ("\n");
Packit f354a3
  }
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Digests the standard input and prints the result.
Packit f354a3
 */
Packit f354a3
static void MDFilter ()
Packit f354a3
{
Packit f354a3
  MD_CTX context;
Packit f354a3
  int len;
Packit f354a3
  unsigned char buffer[16], digest[16];
Packit f354a3
Packit f354a3
  MDInit (&context);
Packit f354a3
  while (len = fread (buffer, 1, 16, stdin))
Packit f354a3
 MDUpdate (&context, buffer, len);
Packit f354a3
  MDFinal (digest, &context);
Packit f354a3
Packit f354a3
  MDPrint (digest);
Packit f354a3
  printf ("\n");
Packit f354a3
}
Packit f354a3
Packit f354a3
/* Prints a message digest in hexadecimal.
Packit f354a3
 */
Packit f354a3
static void MDPrint (digest)
Packit f354a3
unsigned char digest[16];
Packit f354a3
{
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 20]
Packit f354a3

Packit f354a3
RFC 1321              MD5 Message-Digest Algorithm            April 1992
Packit f354a3
Packit f354a3
Packit f354a3
  unsigned int i;
Packit f354a3
Packit f354a3
  for (i = 0; i < 16; i++)
Packit f354a3
 printf ("%02x", digest[i]);
Packit f354a3
}
Packit f354a3
Packit f354a3
A.5 Test suite
Packit f354a3
Packit f354a3
   The MD5 test suite (driver option "-x") should print the following
Packit f354a3
   results:
Packit f354a3
Packit f354a3
MD5 test suite:
Packit f354a3
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
Packit f354a3
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
Packit f354a3
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
Packit f354a3
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
Packit f354a3
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
Packit f354a3
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
Packit f354a3
d174ab98d277d9f5a5611c2c9f419d9f
Packit f354a3
MD5 ("123456789012345678901234567890123456789012345678901234567890123456
Packit f354a3
78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
Packit f354a3
Packit f354a3
Security Considerations
Packit f354a3
Packit f354a3
   The level of security discussed in this memo is considered to be
Packit f354a3
   sufficient for implementing very high security hybrid digital-
Packit f354a3
   signature schemes based on MD5 and a public-key cryptosystem.
Packit f354a3
Packit f354a3
Author's Address
Packit f354a3
Packit f354a3
   Ronald L. Rivest
Packit f354a3
   Massachusetts Institute of Technology
Packit f354a3
   Laboratory for Computer Science
Packit f354a3
   NE43-324
Packit f354a3
   545 Technology Square
Packit f354a3
   Cambridge, MA  02139-1986
Packit f354a3
Packit f354a3
   Phone: (617) 253-5880
Packit f354a3
   EMail: rivest@theory.lcs.mit.edu
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Packit f354a3
Rivest                                                         [Page 21]
Packit f354a3