md4-internal.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "crypto.h"
00020 
00021 #define MD4_BLOCK_LENGTH                64
00022 #define MD4_DIGEST_LENGTH               16
00023 
00024 typedef struct MD4Context {
00025         u32 state[4];                   /* state */
00026         u64 count;                      /* number of bits, mod 2^64 */
00027         u8 buffer[MD4_BLOCK_LENGTH];    /* input buffer */
00028 } MD4_CTX;
00029 
00030 
00031 static void MD4Init(MD4_CTX *ctx);
00032 static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len);
00033 static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx);
00034 
00035 
00036 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00037 {
00038         MD4_CTX ctx;
00039         size_t i;
00040 
00041         MD4Init(&ctx);
00042         for (i = 0; i < num_elem; i++)
00043                 MD4Update(&ctx, addr[i], len[i]);
00044         MD4Final(mac, &ctx);
00045         return 0;
00046 }
00047 
00048 
00049 /* ===== start - public domain MD4 implementation ===== */
00050 /*      $OpenBSD: md4.c,v 1.7 2005/08/08 08:05:35 espie Exp $   */
00051 
00052 /*
00053  * This code implements the MD4 message-digest algorithm.
00054  * The algorithm is due to Ron Rivest.  This code was
00055  * written by Colin Plumb in 1993, no copyright is claimed.
00056  * This code is in the public domain; do with it what you wish.
00057  * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
00058  *
00059  * Equivalent code is available from RSA Data Security, Inc.
00060  * This code has been tested against that, and is equivalent,
00061  * except that you don't need to include two pages of legalese
00062  * with every copy.
00063  *
00064  * To compute the message digest of a chunk of bytes, declare an
00065  * MD4Context structure, pass it to MD4Init, call MD4Update as
00066  * needed on buffers full of bytes, and then call MD4Final, which
00067  * will fill a supplied 16-byte array with the digest.
00068  */
00069 
00070 #define MD4_DIGEST_STRING_LENGTH        (MD4_DIGEST_LENGTH * 2 + 1)
00071 
00072 
00073 static void
00074 MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]);
00075 
00076 #define PUT_64BIT_LE(cp, value) do {                                    \
00077         (cp)[7] = (value) >> 56;                                        \
00078         (cp)[6] = (value) >> 48;                                        \
00079         (cp)[5] = (value) >> 40;                                        \
00080         (cp)[4] = (value) >> 32;                                        \
00081         (cp)[3] = (value) >> 24;                                        \
00082         (cp)[2] = (value) >> 16;                                        \
00083         (cp)[1] = (value) >> 8;                                         \
00084         (cp)[0] = (value); } while (0)
00085 
00086 #define PUT_32BIT_LE(cp, value) do {                                    \
00087         (cp)[3] = (value) >> 24;                                        \
00088         (cp)[2] = (value) >> 16;                                        \
00089         (cp)[1] = (value) >> 8;                                         \
00090         (cp)[0] = (value); } while (0)
00091 
00092 static u8 PADDING[MD4_BLOCK_LENGTH] = {
00093         0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00094         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00095         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00096 };
00097 
00098 /*
00099  * Start MD4 accumulation.
00100  * Set bit count to 0 and buffer to mysterious initialization constants.
00101  */
00102 static void MD4Init(MD4_CTX *ctx)
00103 {
00104         ctx->count = 0;
00105         ctx->state[0] = 0x67452301;
00106         ctx->state[1] = 0xefcdab89;
00107         ctx->state[2] = 0x98badcfe;
00108         ctx->state[3] = 0x10325476;
00109 }
00110 
00111 /*
00112  * Update context to reflect the concatenation of another buffer full
00113  * of bytes.
00114  */
00115 static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
00116 {
00117         size_t have, need;
00118 
00119         /* Check how many bytes we already have and how many more we need. */
00120         have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
00121         need = MD4_BLOCK_LENGTH - have;
00122 
00123         /* Update bitcount */
00124         ctx->count += (u64)len << 3;
00125 
00126         if (len >= need) {
00127                 if (have != 0) {
00128                         os_memcpy(ctx->buffer + have, input, need);
00129                         MD4Transform(ctx->state, ctx->buffer);
00130                         input += need;
00131                         len -= need;
00132                         have = 0;
00133                 }
00134 
00135                 /* Process data in MD4_BLOCK_LENGTH-byte chunks. */
00136                 while (len >= MD4_BLOCK_LENGTH) {
00137                         MD4Transform(ctx->state, input);
00138                         input += MD4_BLOCK_LENGTH;
00139                         len -= MD4_BLOCK_LENGTH;
00140                 }
00141         }
00142 
00143         /* Handle any remaining bytes of data. */
00144         if (len != 0)
00145                 os_memcpy(ctx->buffer + have, input, len);
00146 }
00147 
00148 /*
00149  * Pad pad to 64-byte boundary with the bit pattern
00150  * 1 0* (64-bit count of bits processed, MSB-first)
00151  */
00152 static void MD4Pad(MD4_CTX *ctx)
00153 {
00154         u8 count[8];
00155         size_t padlen;
00156 
00157         /* Convert count to 8 bytes in little endian order. */
00158         PUT_64BIT_LE(count, ctx->count);
00159 
00160         /* Pad out to 56 mod 64. */
00161         padlen = MD4_BLOCK_LENGTH -
00162             ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
00163         if (padlen < 1 + 8)
00164                 padlen += MD4_BLOCK_LENGTH;
00165         MD4Update(ctx, PADDING, padlen - 8);            /* padlen - 8 <= 64 */
00166         MD4Update(ctx, count, 8);
00167 }
00168 
00169 /*
00170  * Final wrapup--call MD4Pad, fill in digest and zero out ctx.
00171  */
00172 static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
00173 {
00174         int i;
00175 
00176         MD4Pad(ctx);
00177         if (digest != NULL) {
00178                 for (i = 0; i < 4; i++)
00179                         PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
00180                 os_memset(ctx, 0, sizeof(*ctx));
00181         }
00182 }
00183 
00184 
00185 /* The three core functions - F1 is optimized somewhat */
00186 
00187 /* #define F1(x, y, z) (x & y | ~x & z) */
00188 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00189 #define F2(x, y, z) ((x & y) | (x & z) | (y & z))
00190 #define F3(x, y, z) (x ^ y ^ z)
00191 
00192 /* This is the central step in the MD4 algorithm. */
00193 #define MD4STEP(f, w, x, y, z, data, s) \
00194         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
00195 
00196 /*
00197  * The core of the MD4 algorithm, this alters an existing MD4 hash to
00198  * reflect the addition of 16 longwords of new data.  MD4Update blocks
00199  * the data and converts bytes into longwords for this routine.
00200  */
00201 static void
00202 MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH])
00203 {
00204         u32 a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
00205 
00206 #if BYTE_ORDER == LITTLE_ENDIAN
00207         os_memcpy(in, block, sizeof(in));
00208 #else
00209         for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
00210                 in[a] = (u32)(
00211                     (u32)(block[a * 4 + 0]) |
00212                     (u32)(block[a * 4 + 1]) <<  8 |
00213                     (u32)(block[a * 4 + 2]) << 16 |
00214                     (u32)(block[a * 4 + 3]) << 24);
00215         }
00216 #endif
00217 
00218         a = state[0];
00219         b = state[1];
00220         c = state[2];
00221         d = state[3];
00222 
00223         MD4STEP(F1, a, b, c, d, in[ 0],  3);
00224         MD4STEP(F1, d, a, b, c, in[ 1],  7);
00225         MD4STEP(F1, c, d, a, b, in[ 2], 11);
00226         MD4STEP(F1, b, c, d, a, in[ 3], 19);
00227         MD4STEP(F1, a, b, c, d, in[ 4],  3);
00228         MD4STEP(F1, d, a, b, c, in[ 5],  7);
00229         MD4STEP(F1, c, d, a, b, in[ 6], 11);
00230         MD4STEP(F1, b, c, d, a, in[ 7], 19);
00231         MD4STEP(F1, a, b, c, d, in[ 8],  3);
00232         MD4STEP(F1, d, a, b, c, in[ 9],  7);
00233         MD4STEP(F1, c, d, a, b, in[10], 11);
00234         MD4STEP(F1, b, c, d, a, in[11], 19);
00235         MD4STEP(F1, a, b, c, d, in[12],  3);
00236         MD4STEP(F1, d, a, b, c, in[13],  7);
00237         MD4STEP(F1, c, d, a, b, in[14], 11);
00238         MD4STEP(F1, b, c, d, a, in[15], 19);
00239 
00240         MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999,  3);
00241         MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999,  5);
00242         MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999,  9);
00243         MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
00244         MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999,  3);
00245         MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999,  5);
00246         MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999,  9);
00247         MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
00248         MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999,  3);
00249         MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999,  5);
00250         MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999,  9);
00251         MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
00252         MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999,  3);
00253         MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999,  5);
00254         MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999,  9);
00255         MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
00256 
00257         MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1,  3);
00258         MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1,  9);
00259         MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
00260         MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
00261         MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1,  3);
00262         MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1,  9);
00263         MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
00264         MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
00265         MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1,  3);
00266         MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1,  9);
00267         MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
00268         MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
00269         MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1,  3);
00270         MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1,  9);
00271         MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
00272         MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
00273 
00274         state[0] += a;
00275         state[1] += b;
00276         state[2] += c;
00277         state[3] += d;
00278 }
00279 /* ===== end - public domain MD4 implementation ===== */
00280 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:50 2009 for hostapd by  doxygen 1.6.1