• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #if !defined(CURL_DISABLE_CRYPTO_AUTH)
26 
27 #include "curl_md4.h"
28 #include "warnless.h"
29 
30 #ifdef USE_OPENSSL
31 #include <openssl/opensslconf.h>
32 #endif
33 #ifdef USE_MBEDTLS
34 #include <mbedtls/config.h>
35 #endif
36 
37 #if defined(USE_GNUTLS_NETTLE)
38 
39 #include <nettle/md4.h>
40 
41 #include "curl_memory.h"
42 
43 /* The last #include file should be: */
44 #include "memdebug.h"
45 
46 typedef struct md4_ctx MD4_CTX;
47 
MD4_Init(MD4_CTX * ctx)48 static void MD4_Init(MD4_CTX *ctx)
49 {
50   md4_init(ctx);
51 }
52 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)53 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
54 {
55   md4_update(ctx, size, data);
56 }
57 
MD4_Final(unsigned char * result,MD4_CTX * ctx)58 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
59 {
60   md4_digest(ctx, MD4_DIGEST_SIZE, result);
61 }
62 
63 #elif defined(USE_GNUTLS)
64 
65 #include <gcrypt.h>
66 
67 #include "curl_memory.h"
68 /* The last #include file should be: */
69 #include "memdebug.h"
70 
71 typedef struct gcry_md_hd_t MD4_CTX;
72 
MD4_Init(MD4_CTX * ctx)73 static void MD4_Init(MD4_CTX *ctx)
74 {
75   gcry_md_open(ctx, GCRY_MD_MD4, 0);
76 }
77 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)78 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
79 {
80   gcry_md_write(*ctx, data, size);
81 }
82 
MD4_Final(unsigned char * result,MD4_CTX * ctx)83 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
84 {
85   memcpy(result, gcry_md_read(ctx, 0), MD4_DIGEST_LENGTH);
86   gcry_md_close(ctx);
87 }
88 
89 #elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
90 /* When OpenSSL is available we use the MD4-functions from OpenSSL */
91 #include <openssl/md4.h>
92 
93 #elif defined(USE_SECTRANSP)
94 
95 #include <CommonCrypto/CommonDigest.h>
96 
97 #include "curl_memory.h"
98 /* The last #include file should be: */
99 #include "memdebug.h"
100 
101 typedef struct {
102   void *data;
103   unsigned long size;
104 } MD4_CTX;
105 
MD4_Init(MD4_CTX * ctx)106 static void MD4_Init(MD4_CTX *ctx)
107 {
108   ctx->data = NULL;
109   ctx->size = 0;
110 }
111 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)112 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
113 {
114   if(ctx->data == NULL) {
115     ctx->data = malloc(size);
116     if(ctx->data != NULL) {
117       memcpy(ctx->data, data, size);
118       ctx->size = size;
119     }
120   }
121 }
122 
MD4_Final(unsigned char * result,MD4_CTX * ctx)123 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
124 {
125   if(ctx->data != NULL) {
126     (void)CC_MD4(ctx->data, (CC_LONG) ctx->size, result);
127 
128     Curl_safefree(ctx->data);
129     ctx->size = 0;
130   }
131 }
132 
133 #elif defined(USE_WIN32_CRYPTO)
134 
135 #include <wincrypt.h>
136 
137 #include "curl_memory.h"
138  /* The last #include file should be: */
139 #include "memdebug.h"
140 
141 typedef struct {
142   HCRYPTPROV hCryptProv;
143   HCRYPTHASH hHash;
144 } MD4_CTX;
145 
MD4_Init(MD4_CTX * ctx)146 static void MD4_Init(MD4_CTX *ctx)
147 {
148   ctx->hCryptProv = 0;
149   ctx->hHash = 0;
150 
151   if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
152                          CRYPT_VERIFYCONTEXT)) {
153     CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
154   }
155 }
156 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)157 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
158 {
159   CryptHashData(ctx->hHash, data, (unsigned int) size, 0);
160 }
161 
MD4_Final(unsigned char * result,MD4_CTX * ctx)162 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
163 {
164   unsigned long length = 0;
165 
166   CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
167   if(length == MD4_DIGEST_LENGTH)
168     CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
169 
170   if(ctx->hHash)
171     CryptDestroyHash(ctx->hHash);
172 
173   if(ctx->hCryptProv)
174     CryptReleaseContext(ctx->hCryptProv, 0);
175 }
176 
177 #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
178 
179 #include <mbedtls/md4.h>
180 
181 #include "curl_memory.h"
182 /* The last #include file should be: */
183 #include "memdebug.h"
184 
185 typedef struct {
186   void *data;
187   unsigned long size;
188 } MD4_CTX;
189 
MD4_Init(MD4_CTX * ctx)190 static void MD4_Init(MD4_CTX *ctx)
191 {
192   ctx->data = NULL;
193   ctx->size = 0;
194 }
195 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)196 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
197 {
198   if(ctx->data == NULL) {
199     ctx->data = malloc(size);
200     if(ctx->data != NULL) {
201       memcpy(ctx->data, data, size);
202       ctx->size = size;
203     }
204   }
205 }
206 
MD4_Final(unsigned char * result,MD4_CTX * ctx)207 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
208 {
209   if(ctx->data != NULL) {
210     mbedtls_md4(ctx->data, ctx->size, result);
211 
212     Curl_safefree(ctx->data);
213     ctx->size = 0;
214   }
215 }
216 
217 #else
218 /* When no other crypto library is available, or the crypto library doesn't
219  * support MD4, we use this code segment this implementation of it
220  *
221  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
222  * MD4 Message-Digest Algorithm (RFC 1320).
223  *
224  * Homepage:
225  https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
226  *
227  * Author:
228  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
229  *
230  * This software was written by Alexander Peslyak in 2001.  No copyright is
231  * claimed, and the software is hereby placed in the public domain.  In case
232  * this attempt to disclaim copyright and place the software in the public
233  * domain is deemed null and void, then the software is Copyright (c) 2001
234  * Alexander Peslyak and it is hereby released to the general public under the
235  * following terms:
236  *
237  * Redistribution and use in source and binary forms, with or without
238  * modification, are permitted.
239  *
240  * There's ABSOLUTELY NO WARRANTY, express or implied.
241  *
242  * (This is a heavily cut-down "BSD license".)
243  *
244  * This differs from Colin Plumb's older public domain implementation in that
245  * no exactly 32-bit integer data type is required (any 32-bit or wider
246  * unsigned integer data type will do), there's no compile-time endianness
247  * configuration, and the function prototypes match OpenSSL's.  No code from
248  * Colin Plumb's implementation has been reused; this comment merely compares
249  * the properties of the two independent implementations.
250  *
251  * The primary goals of this implementation are portability and ease of use.
252  * It is meant to be fast, but not as fast as possible.  Some known
253  * optimizations are not included to reduce source code size and avoid
254  * compile-time configuration.
255  */
256 
257 
258 #include <string.h>
259 
260 /* Any 32-bit or wider unsigned integer data type will do */
261 typedef unsigned int MD4_u32plus;
262 
263 typedef struct {
264   MD4_u32plus lo, hi;
265   MD4_u32plus a, b, c, d;
266   unsigned char buffer[64];
267   MD4_u32plus block[16];
268 } MD4_CTX;
269 
270 static void MD4_Init(MD4_CTX *ctx);
271 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
272 static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
273 
274 /*
275  * The basic MD4 functions.
276  *
277  * F and G are optimized compared to their RFC 1320 definitions, with the
278  * optimization for F borrowed from Colin Plumb's MD5 implementation.
279  */
280 #define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
281 #define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
282 #define H(x, y, z)                      ((x) ^ (y) ^ (z))
283 
284 /*
285  * The MD4 transformation for all three rounds.
286  */
287 #define STEP(f, a, b, c, d, x, s) \
288         (a) += f((b), (c), (d)) + (x); \
289         (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
290 
291 /*
292  * SET reads 4 input bytes in little-endian byte order and stores them
293  * in a properly aligned word in host byte order.
294  *
295  * The check for little-endian architectures that tolerate unaligned
296  * memory accesses is just an optimization.  Nothing will break if it
297  * doesn't work.
298  */
299 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
300 #define SET(n) \
301         (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
302 #define GET(n) \
303         SET(n)
304 #else
305 #define SET(n) \
306         (ctx->block[(n)] = \
307         (MD4_u32plus)ptr[(n) * 4] | \
308         ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
309         ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
310         ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
311 #define GET(n) \
312         (ctx->block[(n)])
313 #endif
314 
315 /*
316  * This processes one or more 64-byte data blocks, but does NOT update
317  * the bit counters.  There are no alignment requirements.
318  */
body(MD4_CTX * ctx,const void * data,unsigned long size)319 static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
320 {
321   const unsigned char *ptr;
322   MD4_u32plus a, b, c, d;
323 
324   ptr = (const unsigned char *)data;
325 
326   a = ctx->a;
327   b = ctx->b;
328   c = ctx->c;
329   d = ctx->d;
330 
331   do {
332     MD4_u32plus saved_a, saved_b, saved_c, saved_d;
333 
334     saved_a = a;
335     saved_b = b;
336     saved_c = c;
337     saved_d = d;
338 
339 /* Round 1 */
340     STEP(F, a, b, c, d, SET(0), 3)
341     STEP(F, d, a, b, c, SET(1), 7)
342     STEP(F, c, d, a, b, SET(2), 11)
343     STEP(F, b, c, d, a, SET(3), 19)
344     STEP(F, a, b, c, d, SET(4), 3)
345     STEP(F, d, a, b, c, SET(5), 7)
346     STEP(F, c, d, a, b, SET(6), 11)
347     STEP(F, b, c, d, a, SET(7), 19)
348     STEP(F, a, b, c, d, SET(8), 3)
349     STEP(F, d, a, b, c, SET(9), 7)
350     STEP(F, c, d, a, b, SET(10), 11)
351     STEP(F, b, c, d, a, SET(11), 19)
352     STEP(F, a, b, c, d, SET(12), 3)
353     STEP(F, d, a, b, c, SET(13), 7)
354     STEP(F, c, d, a, b, SET(14), 11)
355     STEP(F, b, c, d, a, SET(15), 19)
356 
357 /* Round 2 */
358     STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
359     STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
360     STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
361     STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
362     STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
363     STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
364     STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
365     STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
366     STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
367     STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
368     STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
369     STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
370     STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
371     STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
372     STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
373     STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
374 
375 /* Round 3 */
376     STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
377     STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
378     STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
379     STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
380     STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
381     STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
382     STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
383     STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
384     STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
385     STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
386     STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
387     STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
388     STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
389     STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
390     STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
391     STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
392 
393     a += saved_a;
394     b += saved_b;
395     c += saved_c;
396     d += saved_d;
397 
398     ptr += 64;
399   } while(size -= 64);
400 
401   ctx->a = a;
402   ctx->b = b;
403   ctx->c = c;
404   ctx->d = d;
405 
406   return ptr;
407 }
408 
MD4_Init(MD4_CTX * ctx)409 static void MD4_Init(MD4_CTX *ctx)
410 {
411   ctx->a = 0x67452301;
412   ctx->b = 0xefcdab89;
413   ctx->c = 0x98badcfe;
414   ctx->d = 0x10325476;
415 
416   ctx->lo = 0;
417   ctx->hi = 0;
418 }
419 
MD4_Update(MD4_CTX * ctx,const void * data,unsigned long size)420 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
421 {
422   MD4_u32plus saved_lo;
423   unsigned long used;
424 
425   saved_lo = ctx->lo;
426   ctx->lo = (saved_lo + size) & 0x1fffffff;
427   if(ctx->lo < saved_lo)
428     ctx->hi++;
429   ctx->hi += (MD4_u32plus)size >> 29;
430 
431   used = saved_lo & 0x3f;
432 
433   if(used) {
434     unsigned long available = 64 - used;
435 
436     if(size < available) {
437       memcpy(&ctx->buffer[used], data, size);
438       return;
439     }
440 
441     memcpy(&ctx->buffer[used], data, available);
442     data = (const unsigned char *)data + available;
443     size -= available;
444     body(ctx, ctx->buffer, 64);
445   }
446 
447   if(size >= 64) {
448     data = body(ctx, data, size & ~(unsigned long)0x3f);
449     size &= 0x3f;
450   }
451 
452   memcpy(ctx->buffer, data, size);
453 }
454 
MD4_Final(unsigned char * result,MD4_CTX * ctx)455 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
456 {
457   unsigned long used, available;
458 
459   used = ctx->lo & 0x3f;
460 
461   ctx->buffer[used++] = 0x80;
462 
463   available = 64 - used;
464 
465   if(available < 8) {
466     memset(&ctx->buffer[used], 0, available);
467     body(ctx, ctx->buffer, 64);
468     used = 0;
469     available = 64;
470   }
471 
472   memset(&ctx->buffer[used], 0, available - 8);
473 
474   ctx->lo <<= 3;
475   ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
476   ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
477   ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
478   ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
479   ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
480   ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
481   ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
482   ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
483 
484   body(ctx, ctx->buffer, 64);
485 
486   result[0] = curlx_ultouc((ctx->a)&0xff);
487   result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
488   result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
489   result[3] = curlx_ultouc(ctx->a >> 24);
490   result[4] = curlx_ultouc((ctx->b)&0xff);
491   result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
492   result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
493   result[7] = curlx_ultouc(ctx->b >> 24);
494   result[8] = curlx_ultouc((ctx->c)&0xff);
495   result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
496   result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
497   result[11] = curlx_ultouc(ctx->c >> 24);
498   result[12] = curlx_ultouc((ctx->d)&0xff);
499   result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
500   result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
501   result[15] = curlx_ultouc(ctx->d >> 24);
502 
503   memset(ctx, 0, sizeof(*ctx));
504 }
505 
506 #endif /* CRYPTO LIBS */
507 
Curl_md4it(unsigned char * output,const unsigned char * input,size_t len)508 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
509 {
510   MD4_CTX ctx;
511   MD4_Init(&ctx);
512   MD4_Update(&ctx, input, curlx_uztoui(len));
513   MD4_Final(output, &ctx);
514 }
515 
516 #endif /* CURL_DISABLE_CRYPTO_AUTH */
517