00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "curl_setup.h"
00039
00040
00041
00042 #if defined(USE_NSS) || defined(USE_OS400CRYPTO)
00043
00044 #include "curl_md4.h"
00045 #include "warnless.h"
00046
00047 #ifndef HAVE_OPENSSL
00048
00049 #include <string.h>
00050
00051
00052 typedef unsigned int MD4_u32plus;
00053
00054 typedef struct {
00055 MD4_u32plus lo, hi;
00056 MD4_u32plus a, b, c, d;
00057 unsigned char buffer[64];
00058 MD4_u32plus block[16];
00059 } MD4_CTX;
00060
00061 static void MD4_Init(MD4_CTX *ctx);
00062 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
00063 static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
00064
00065
00066
00067
00068
00069
00070
00071 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
00072 #define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
00073 #define H(x, y, z) ((x) ^ (y) ^ (z))
00074
00075
00076
00077
00078 #define STEP(f, a, b, c, d, x, s) \
00079 (a) += f((b), (c), (d)) + (x); \
00080 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
00091 #define SET(n) \
00092 (*(MD4_u32plus *)&ptr[(n) * 4])
00093 #define GET(n) \
00094 SET(n)
00095 #else
00096 #define SET(n) \
00097 (ctx->block[(n)] = \
00098 (MD4_u32plus)ptr[(n) * 4] | \
00099 ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
00100 ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
00101 ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
00102 #define GET(n) \
00103 (ctx->block[(n)])
00104 #endif
00105
00106
00107
00108
00109
00110 static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
00111 {
00112 const unsigned char *ptr;
00113 MD4_u32plus a, b, c, d;
00114 MD4_u32plus saved_a, saved_b, saved_c, saved_d;
00115
00116 ptr = (const unsigned char *)data;
00117
00118 a = ctx->a;
00119 b = ctx->b;
00120 c = ctx->c;
00121 d = ctx->d;
00122
00123 do {
00124 saved_a = a;
00125 saved_b = b;
00126 saved_c = c;
00127 saved_d = d;
00128
00129
00130 STEP(F, a, b, c, d, SET(0), 3)
00131 STEP(F, d, a, b, c, SET(1), 7)
00132 STEP(F, c, d, a, b, SET(2), 11)
00133 STEP(F, b, c, d, a, SET(3), 19)
00134 STEP(F, a, b, c, d, SET(4), 3)
00135 STEP(F, d, a, b, c, SET(5), 7)
00136 STEP(F, c, d, a, b, SET(6), 11)
00137 STEP(F, b, c, d, a, SET(7), 19)
00138 STEP(F, a, b, c, d, SET(8), 3)
00139 STEP(F, d, a, b, c, SET(9), 7)
00140 STEP(F, c, d, a, b, SET(10), 11)
00141 STEP(F, b, c, d, a, SET(11), 19)
00142 STEP(F, a, b, c, d, SET(12), 3)
00143 STEP(F, d, a, b, c, SET(13), 7)
00144 STEP(F, c, d, a, b, SET(14), 11)
00145 STEP(F, b, c, d, a, SET(15), 19)
00146
00147
00148 STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
00149 STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
00150 STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
00151 STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
00152 STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
00153 STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
00154 STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
00155 STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
00156 STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
00157 STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
00158 STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
00159 STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
00160 STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
00161 STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
00162 STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
00163 STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
00164
00165
00166 STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
00167 STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
00168 STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
00169 STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
00170 STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
00171 STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
00172 STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
00173 STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
00174 STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
00175 STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
00176 STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
00177 STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
00178 STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
00179 STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
00180 STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
00181 STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
00182
00183 a += saved_a;
00184 b += saved_b;
00185 c += saved_c;
00186 d += saved_d;
00187
00188 ptr += 64;
00189 } while(size -= 64);
00190
00191 ctx->a = a;
00192 ctx->b = b;
00193 ctx->c = c;
00194 ctx->d = d;
00195
00196 return ptr;
00197 }
00198
00199 static void MD4_Init(MD4_CTX *ctx)
00200 {
00201 ctx->a = 0x67452301;
00202 ctx->b = 0xefcdab89;
00203 ctx->c = 0x98badcfe;
00204 ctx->d = 0x10325476;
00205
00206 ctx->lo = 0;
00207 ctx->hi = 0;
00208 }
00209
00210 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
00211 {
00212 MD4_u32plus saved_lo;
00213 unsigned long used, available;
00214
00215 saved_lo = ctx->lo;
00216 ctx->lo = (saved_lo + size) & 0x1fffffff;
00217 if(ctx->lo < saved_lo)
00218 ctx->hi++;
00219 ctx->hi += (MD4_u32plus)size >> 29;
00220
00221 used = saved_lo & 0x3f;
00222
00223 if(used) {
00224 available = 64 - used;
00225
00226 if(size < available) {
00227 memcpy(&ctx->buffer[used], data, size);
00228 return;
00229 }
00230
00231 memcpy(&ctx->buffer[used], data, available);
00232 data = (const unsigned char *)data + available;
00233 size -= available;
00234 body(ctx, ctx->buffer, 64);
00235 }
00236
00237 if(size >= 64) {
00238 data = body(ctx, data, size & ~(unsigned long)0x3f);
00239 size &= 0x3f;
00240 }
00241
00242 memcpy(ctx->buffer, data, size);
00243 }
00244
00245 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
00246 {
00247 unsigned long used, available;
00248
00249 used = ctx->lo & 0x3f;
00250
00251 ctx->buffer[used++] = 0x80;
00252
00253 available = 64 - used;
00254
00255 if(available < 8) {
00256 memset(&ctx->buffer[used], 0, available);
00257 body(ctx, ctx->buffer, 64);
00258 used = 0;
00259 available = 64;
00260 }
00261
00262 memset(&ctx->buffer[used], 0, available - 8);
00263
00264 ctx->lo <<= 3;
00265 ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
00266 ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
00267 ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
00268 ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
00269 ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
00270 ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
00271 ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
00272 ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
00273
00274 body(ctx, ctx->buffer, 64);
00275
00276 result[0] = curlx_ultouc((ctx->a)&0xff);
00277 result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
00278 result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
00279 result[3] = curlx_ultouc(ctx->a >> 24);
00280 result[4] = curlx_ultouc((ctx->b)&0xff);
00281 result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
00282 result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
00283 result[7] = curlx_ultouc(ctx->b >> 24);
00284 result[8] = curlx_ultouc((ctx->c)&0xff);
00285 result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
00286 result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
00287 result[11] = curlx_ultouc(ctx->c >> 24);
00288 result[12] = curlx_ultouc((ctx->d)&0xff);
00289 result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
00290 result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
00291 result[15] = curlx_ultouc(ctx->d >> 24);
00292
00293 memset(ctx, 0, sizeof(*ctx));
00294 }
00295
00296 #endif
00297
00298 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
00299 {
00300 MD4_CTX ctx;
00301 MD4_Init(&ctx);
00302 MD4_Update(&ctx, input, curlx_uztoui(len));
00303 MD4_Final(output, &ctx);
00304 }
00305 #endif