00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto.h"
00019
00020 #define MD4_BLOCK_LENGTH 64
00021 #define MD4_DIGEST_LENGTH 16
00022
00023 typedef struct MD4Context {
00024 u32 state[4];
00025 u64 count;
00026 u8 buffer[MD4_BLOCK_LENGTH];
00027 } MD4_CTX;
00028
00029
00030 static void MD4Init(MD4_CTX *ctx);
00031 static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len);
00032 static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx);
00033
00034
00035 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00036 {
00037 MD4_CTX ctx;
00038 size_t i;
00039
00040 MD4Init(&ctx);
00041 for (i = 0; i < num_elem; i++)
00042 MD4Update(&ctx, addr[i], len[i]);
00043 MD4Final(mac, &ctx);
00044 return 0;
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #define MD4_DIGEST_STRING_LENGTH (MD4_DIGEST_LENGTH * 2 + 1)
00070
00071
00072 static void
00073 MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]);
00074
00075 #define PUT_64BIT_LE(cp, value) do { \
00076 (cp)[7] = (value) >> 56; \
00077 (cp)[6] = (value) >> 48; \
00078 (cp)[5] = (value) >> 40; \
00079 (cp)[4] = (value) >> 32; \
00080 (cp)[3] = (value) >> 24; \
00081 (cp)[2] = (value) >> 16; \
00082 (cp)[1] = (value) >> 8; \
00083 (cp)[0] = (value); } while (0)
00084
00085 #define PUT_32BIT_LE(cp, value) do { \
00086 (cp)[3] = (value) >> 24; \
00087 (cp)[2] = (value) >> 16; \
00088 (cp)[1] = (value) >> 8; \
00089 (cp)[0] = (value); } while (0)
00090
00091 static u8 PADDING[MD4_BLOCK_LENGTH] = {
00092 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00093 0, 0, 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
00095 };
00096
00097
00098
00099
00100
00101 static void MD4Init(MD4_CTX *ctx)
00102 {
00103 ctx->count = 0;
00104 ctx->state[0] = 0x67452301;
00105 ctx->state[1] = 0xefcdab89;
00106 ctx->state[2] = 0x98badcfe;
00107 ctx->state[3] = 0x10325476;
00108 }
00109
00110
00111
00112
00113
00114 static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
00115 {
00116 size_t have, need;
00117
00118
00119 have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
00120 need = MD4_BLOCK_LENGTH - have;
00121
00122
00123 ctx->count += (u64)len << 3;
00124
00125 if (len >= need) {
00126 if (have != 0) {
00127 os_memcpy(ctx->buffer + have, input, need);
00128 MD4Transform(ctx->state, ctx->buffer);
00129 input += need;
00130 len -= need;
00131 have = 0;
00132 }
00133
00134
00135 while (len >= MD4_BLOCK_LENGTH) {
00136 MD4Transform(ctx->state, input);
00137 input += MD4_BLOCK_LENGTH;
00138 len -= MD4_BLOCK_LENGTH;
00139 }
00140 }
00141
00142
00143 if (len != 0)
00144 os_memcpy(ctx->buffer + have, input, len);
00145 }
00146
00147
00148
00149
00150
00151 static void MD4Pad(MD4_CTX *ctx)
00152 {
00153 u8 count[8];
00154 size_t padlen;
00155
00156
00157 PUT_64BIT_LE(count, ctx->count);
00158
00159
00160 padlen = MD4_BLOCK_LENGTH -
00161 ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
00162 if (padlen < 1 + 8)
00163 padlen += MD4_BLOCK_LENGTH;
00164 MD4Update(ctx, PADDING, padlen - 8);
00165 MD4Update(ctx, count, 8);
00166 }
00167
00168
00169
00170
00171 static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
00172 {
00173 int i;
00174
00175 MD4Pad(ctx);
00176 if (digest != NULL) {
00177 for (i = 0; i < 4; i++)
00178 PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
00179 os_memset(ctx, 0, sizeof(*ctx));
00180 }
00181 }
00182
00183
00184
00185
00186
00187 #define F1(x, y, z) (z ^ (x & (y ^ z)))
00188 #define F2(x, y, z) ((x & y) | (x & z) | (y & z))
00189 #define F3(x, y, z) (x ^ y ^ z)
00190
00191
00192 #define MD4STEP(f, w, x, y, z, data, s) \
00193 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s) )
00194
00195
00196
00197
00198
00199
00200 static void
00201 MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH])
00202 {
00203 u32 a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
00204
00205 #if BYTE_ORDER == LITTLE_ENDIAN
00206 os_memcpy(in, block, sizeof(in));
00207 #else
00208 for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
00209 in[a] = (u32)(
00210 (u32)(block[a * 4 + 0]) |
00211 (u32)(block[a * 4 + 1]) << 8 |
00212 (u32)(block[a * 4 + 2]) << 16 |
00213 (u32)(block[a * 4 + 3]) << 24);
00214 }
00215 #endif
00216
00217 a = state[0];
00218 b = state[1];
00219 c = state[2];
00220 d = state[3];
00221
00222 MD4STEP(F1, a, b, c, d, in[ 0], 3);
00223 MD4STEP(F1, d, a, b, c, in[ 1], 7);
00224 MD4STEP(F1, c, d, a, b, in[ 2], 11);
00225 MD4STEP(F1, b, c, d, a, in[ 3], 19);
00226 MD4STEP(F1, a, b, c, d, in[ 4], 3);
00227 MD4STEP(F1, d, a, b, c, in[ 5], 7);
00228 MD4STEP(F1, c, d, a, b, in[ 6], 11);
00229 MD4STEP(F1, b, c, d, a, in[ 7], 19);
00230 MD4STEP(F1, a, b, c, d, in[ 8], 3);
00231 MD4STEP(F1, d, a, b, c, in[ 9], 7);
00232 MD4STEP(F1, c, d, a, b, in[10], 11);
00233 MD4STEP(F1, b, c, d, a, in[11], 19);
00234 MD4STEP(F1, a, b, c, d, in[12], 3);
00235 MD4STEP(F1, d, a, b, c, in[13], 7);
00236 MD4STEP(F1, c, d, a, b, in[14], 11);
00237 MD4STEP(F1, b, c, d, a, in[15], 19);
00238
00239 MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999, 3);
00240 MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999, 5);
00241 MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999, 9);
00242 MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
00243 MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999, 3);
00244 MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999, 5);
00245 MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999, 9);
00246 MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
00247 MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999, 3);
00248 MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999, 5);
00249 MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999, 9);
00250 MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
00251 MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999, 3);
00252 MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999, 5);
00253 MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999, 9);
00254 MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
00255
00256 MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1, 3);
00257 MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1, 9);
00258 MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
00259 MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
00260 MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1, 3);
00261 MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1, 9);
00262 MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
00263 MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
00264 MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1, 3);
00265 MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1, 9);
00266 MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
00267 MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
00268 MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1, 3);
00269 MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1, 9);
00270 MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
00271 MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
00272
00273 state[0] += a;
00274 state[1] += b;
00275 state[2] += c;
00276 state[3] += d;
00277 }
00278