"Fossies" - the Fresh Open Source Software Archive

Member "zsync-0.6.2/librcksum/md4.c" (16 Sep 2010, 7321 Bytes) of package /linux/privat/old/zsync-0.6.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "md4.c" see the Fossies "Dox" file reference documentation.

    1 /*  $OpenBSD: md4.c,v 1.6 2004/05/28 15:10:27 millert Exp $ */
    2 
    3 /*
    4  * This code implements the MD4 message-digest algorithm.
    5  * The algorithm is due to Ron Rivest.  This code was
    6  * written by Colin Plumb in 1993, no copyright is claimed.
    7  * This code is in the public domain; do with it what you wish.
    8  * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
    9  *
   10  * Equivalent code is available from RSA Data Security, Inc.
   11  * This code has been tested against that, and is equivalent,
   12  * except that you don't need to include two pages of legalese
   13  * with every copy.
   14  *
   15  * To compute the message digest of a chunk of bytes, declare an
   16  * MD4Context structure, pass it to MD4Init, call MD4Update as
   17  * needed on buffers full of bytes, and then call MD4Final, which
   18  * will fill a supplied 16-byte array with the digest.
   19  */
   20 
   21 #if defined(LIBC_SCCS) && !defined(lint)
   22 static const char rcsid[] = "$OpenBSD: md4.c,v 1.6 2004/05/28 15:10:27 millert Exp $";
   23 #endif /* LIBC_SCCS and not lint */
   24 
   25 #include <sys/types.h>
   26 #include <string.h>
   27 #include "md4.h"
   28 
   29 /* Map Solaris endian stuff to something useful */
   30 #if defined(_BIG_ENDIAN) && !defined(_BYTE_ORDER)
   31 #define LITTLE_ENDIAN 0
   32 #define BIG_ENDIAN 1
   33 #define BYTE_ORDER 1
   34 #endif
   35 
   36 #define PUT_64BIT_LE(cp, value) do {                    \
   37     (cp)[7] = (value) >> 56;                    \
   38     (cp)[6] = (value) >> 48;                    \
   39     (cp)[5] = (value) >> 40;                    \
   40     (cp)[4] = (value) >> 32;                    \
   41     (cp)[3] = (value) >> 24;                    \
   42     (cp)[2] = (value) >> 16;                    \
   43     (cp)[1] = (value) >> 8;                     \
   44     (cp)[0] = (value); } while (0)
   45 
   46 #define PUT_32BIT_LE(cp, value) do {                    \
   47     (cp)[3] = (value) >> 24;                    \
   48     (cp)[2] = (value) >> 16;                    \
   49     (cp)[1] = (value) >> 8;                     \
   50     (cp)[0] = (value); } while (0)
   51 
   52 static uint8_t PADDING[MD4_BLOCK_LENGTH] = {
   53     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   54     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   55     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   56 };
   57 
   58 /*
   59  * Start MD4 accumulation.
   60  * Set bit count to 0 and buffer to mysterious initialization constants.
   61  */
   62 void
   63 MD4Init(MD4_CTX *ctx)
   64 {
   65     ctx->count = 0;
   66     ctx->state[0] = 0x67452301;
   67     ctx->state[1] = 0xefcdab89;
   68     ctx->state[2] = 0x98badcfe;
   69     ctx->state[3] = 0x10325476;
   70 }
   71 
   72 /*
   73  * Update context to reflect the concatenation of another buffer full
   74  * of bytes.
   75  */
   76 void
   77 MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
   78 {
   79     size_t have, need;
   80 
   81     /* Check how many bytes we already have and how many more we need. */
   82     have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
   83     need = MD4_BLOCK_LENGTH - have;
   84 
   85     /* Update bitcount */
   86     ctx->count += (uint64_t)len << 3;
   87 
   88     if (len >= need) {
   89         if (have != 0) {
   90             memcpy(ctx->buffer + have, input, need);
   91             MD4Transform(ctx->state, ctx->buffer);
   92             input += need;
   93             len -= need;
   94             have = 0;
   95         }
   96 
   97         /* Process data in MD4_BLOCK_LENGTH-byte chunks. */
   98         while (len >= MD4_BLOCK_LENGTH) {
   99             MD4Transform(ctx->state, input);
  100             input += MD4_BLOCK_LENGTH;
  101             len -= MD4_BLOCK_LENGTH;
  102         }
  103     }
  104 
  105     /* Handle any remaining bytes of data. */
  106     if (len != 0)
  107         memcpy(ctx->buffer + have, input, len);
  108 }
  109 
  110 /*
  111  * Pad pad to 64-byte boundary with the bit pattern
  112  * 1 0* (64-bit count of bits processed, MSB-first)
  113  */
  114 void
  115 MD4Pad(MD4_CTX *ctx)
  116 {
  117     uint8_t count[8];
  118     size_t padlen;
  119 
  120     /* Convert count to 8 bytes in little endian order. */
  121     PUT_64BIT_LE(count, ctx->count);
  122 
  123     /* Pad out to 56 mod 64. */
  124     padlen = MD4_BLOCK_LENGTH -
  125         ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
  126     if (padlen < 1 + 8)
  127         padlen += MD4_BLOCK_LENGTH;
  128     MD4Update(ctx, PADDING, padlen - 8);        /* padlen - 8 <= 64 */
  129     MD4Update(ctx, count, 8);
  130 }
  131 
  132 /*
  133  * Final wrapup--call MD4Pad, fill in digest and zero out ctx.
  134  */
  135 void
  136 MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
  137 {
  138     int i;
  139 
  140     MD4Pad(ctx);
  141     if (digest != NULL) {
  142         for (i = 0; i < 4; i++)
  143             PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
  144         memset(ctx, 0, sizeof(*ctx));
  145     }
  146 }
  147 
  148 
  149 /* The three core functions - F1 is optimized somewhat */
  150 
  151 /* #define F1(x, y, z) (x & y | ~x & z) */
  152 #define F1(x, y, z) (z ^ (x & (y ^ z)))
  153 #define F2(x, y, z) ((x & y) | (x & z) | (y & z))
  154 #define F3(x, y, z) (x ^ y ^ z)
  155 
  156 /* This is the central step in the MD4 algorithm. */
  157 #define MD4STEP(f, w, x, y, z, data, s) \
  158     ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
  159 
  160 /*
  161  * The core of the MD4 algorithm, this alters an existing MD4 hash to
  162  * reflect the addition of 16 longwords of new data.  MD4Update blocks
  163  * the data and converts bytes into longwords for this routine.
  164  */
  165 void
  166 MD4Transform(uint32_t state[4], const uint8_t block[MD4_BLOCK_LENGTH])
  167 {
  168     uint32_t a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
  169 
  170 #if BYTE_ORDER == LITTLE_ENDIAN
  171     memcpy(in, block, sizeof(in));
  172 #else
  173     for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
  174         in[a] = (uint32_t)(
  175             (uint32_t)(block[a * 4 + 0]) |
  176             (uint32_t)(block[a * 4 + 1]) <<  8 |
  177             (uint32_t)(block[a * 4 + 2]) << 16 |
  178             (uint32_t)(block[a * 4 + 3]) << 24);
  179     }
  180 #endif
  181 
  182     a = state[0];
  183     b = state[1];
  184     c = state[2];
  185     d = state[3];
  186 
  187     MD4STEP(F1, a, b, c, d, in[ 0],  3);
  188     MD4STEP(F1, d, a, b, c, in[ 1],  7);
  189     MD4STEP(F1, c, d, a, b, in[ 2], 11);
  190     MD4STEP(F1, b, c, d, a, in[ 3], 19);
  191     MD4STEP(F1, a, b, c, d, in[ 4],  3);
  192     MD4STEP(F1, d, a, b, c, in[ 5],  7);
  193     MD4STEP(F1, c, d, a, b, in[ 6], 11);
  194     MD4STEP(F1, b, c, d, a, in[ 7], 19);
  195     MD4STEP(F1, a, b, c, d, in[ 8],  3);
  196     MD4STEP(F1, d, a, b, c, in[ 9],  7);
  197     MD4STEP(F1, c, d, a, b, in[10], 11);
  198     MD4STEP(F1, b, c, d, a, in[11], 19);
  199     MD4STEP(F1, a, b, c, d, in[12],  3);
  200     MD4STEP(F1, d, a, b, c, in[13],  7);
  201     MD4STEP(F1, c, d, a, b, in[14], 11);
  202     MD4STEP(F1, b, c, d, a, in[15], 19);
  203 
  204     MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999,  3);
  205     MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999,  5);
  206     MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999,  9);
  207     MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
  208     MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999,  3);
  209     MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999,  5);
  210     MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999,  9);
  211     MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
  212     MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999,  3);
  213     MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999,  5);
  214     MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999,  9);
  215     MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
  216     MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999,  3);
  217     MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999,  5);
  218     MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999,  9);
  219     MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
  220 
  221     MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1,  3);
  222     MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1,  9);
  223     MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
  224     MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
  225     MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1,  3);
  226     MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1,  9);
  227     MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
  228     MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
  229     MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1,  3);
  230     MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1,  9);
  231     MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
  232     MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
  233     MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1,  3);
  234     MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1,  9);
  235     MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
  236     MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
  237 
  238     state[0] += a;
  239     state[1] += b;
  240     state[2] += c;
  241     state[3] += d;
  242 }