Home | History | Annotate | Download | only in lib
      1 /*
      2  * !checksrc! disable COPYRIGHT
      3  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
      4  * MD4 Message-Digest Algorithm (RFC 1320).
      5  *
      6  * Homepage:
      7  https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
      8  *
      9  * Author:
     10  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
     11  *
     12  * This software was written by Alexander Peslyak in 2001.  No copyright is
     13  * claimed, and the software is hereby placed in the public domain.  In case
     14  * this attempt to disclaim copyright and place the software in the public
     15  * domain is deemed null and void, then the software is Copyright (c) 2001
     16  * Alexander Peslyak and it is hereby released to the general public under the
     17  * following terms:
     18  *
     19  * Redistribution and use in source and binary forms, with or without
     20  * modification, are permitted.
     21  *
     22  * There's ABSOLUTELY NO WARRANTY, express or implied.
     23  *
     24  * (This is a heavily cut-down "BSD license".)
     25  *
     26  * This differs from Colin Plumb's older public domain implementation in that
     27  * no exactly 32-bit integer data type is required (any 32-bit or wider
     28  * unsigned integer data type will do), there's no compile-time endianness
     29  * configuration, and the function prototypes match OpenSSL's.  No code from
     30  * Colin Plumb's implementation has been reused; this comment merely compares
     31  * the properties of the two independent implementations.
     32  *
     33  * The primary goals of this implementation are portability and ease of use.
     34  * It is meant to be fast, but not as fast as possible.  Some known
     35  * optimizations are not included to reduce source code size and avoid
     36  * compile-time configuration.
     37  */
     38 
     39 #include "curl_setup.h"
     40 
     41 /* The NSS, OS/400 and sometimes mbed TLS crypto libraries do not provide the
     42  * MD4 hash algorithm, so we have a local implementation of it */
     43 #if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
     44     (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
     45 
     46 #include "curl_md4.h"
     47 #include "warnless.h"
     48 
     49 #ifndef HAVE_OPENSSL
     50 
     51 #include <string.h>
     52 
     53 /* Any 32-bit or wider unsigned integer data type will do */
     54 typedef unsigned int MD4_u32plus;
     55 
     56 typedef struct {
     57   MD4_u32plus lo, hi;
     58   MD4_u32plus a, b, c, d;
     59   unsigned char buffer[64];
     60   MD4_u32plus block[16];
     61 } MD4_CTX;
     62 
     63 static void MD4_Init(MD4_CTX *ctx);
     64 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
     65 static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
     66 
     67 /*
     68  * The basic MD4 functions.
     69  *
     70  * F and G are optimized compared to their RFC 1320 definitions, with the
     71  * optimization for F borrowed from Colin Plumb's MD5 implementation.
     72  */
     73 #define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
     74 #define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
     75 #define H(x, y, z)                      ((x) ^ (y) ^ (z))
     76 
     77 /*
     78  * The MD4 transformation for all three rounds.
     79  */
     80 #define STEP(f, a, b, c, d, x, s) \
     81         (a) += f((b), (c), (d)) + (x); \
     82         (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
     83 
     84 /*
     85  * SET reads 4 input bytes in little-endian byte order and stores them
     86  * in a properly aligned word in host byte order.
     87  *
     88  * The check for little-endian architectures that tolerate unaligned
     89  * memory accesses is just an optimization.  Nothing will break if it
     90  * doesn't work.
     91  */
     92 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
     93 #define SET(n) \
     94         (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
     95 #define GET(n) \
     96         SET(n)
     97 #else
     98 #define SET(n) \
     99         (ctx->block[(n)] = \
    100         (MD4_u32plus)ptr[(n) * 4] | \
    101         ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
    102         ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
    103         ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
    104 #define GET(n) \
    105         (ctx->block[(n)])
    106 #endif
    107 
    108 /*
    109  * This processes one or more 64-byte data blocks, but does NOT update
    110  * the bit counters.  There are no alignment requirements.
    111  */
    112 static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
    113 {
    114   const unsigned char *ptr;
    115   MD4_u32plus a, b, c, d;
    116   MD4_u32plus saved_a, saved_b, saved_c, saved_d;
    117 
    118   ptr = (const unsigned char *)data;
    119 
    120   a = ctx->a;
    121   b = ctx->b;
    122   c = ctx->c;
    123   d = ctx->d;
    124 
    125   do {
    126     saved_a = a;
    127     saved_b = b;
    128     saved_c = c;
    129     saved_d = d;
    130 
    131 /* Round 1 */
    132     STEP(F, a, b, c, d, SET(0), 3)
    133       STEP(F, d, a, b, c, SET(1), 7)
    134       STEP(F, c, d, a, b, SET(2), 11)
    135       STEP(F, b, c, d, a, SET(3), 19)
    136       STEP(F, a, b, c, d, SET(4), 3)
    137       STEP(F, d, a, b, c, SET(5), 7)
    138       STEP(F, c, d, a, b, SET(6), 11)
    139       STEP(F, b, c, d, a, SET(7), 19)
    140       STEP(F, a, b, c, d, SET(8), 3)
    141       STEP(F, d, a, b, c, SET(9), 7)
    142       STEP(F, c, d, a, b, SET(10), 11)
    143       STEP(F, b, c, d, a, SET(11), 19)
    144       STEP(F, a, b, c, d, SET(12), 3)
    145       STEP(F, d, a, b, c, SET(13), 7)
    146       STEP(F, c, d, a, b, SET(14), 11)
    147       STEP(F, b, c, d, a, SET(15), 19)
    148 
    149 /* Round 2 */
    150       STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
    151       STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
    152       STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
    153       STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
    154       STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
    155       STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
    156       STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
    157       STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
    158       STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
    159       STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
    160       STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
    161       STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
    162       STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
    163       STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
    164       STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
    165       STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
    166 
    167 /* Round 3 */
    168       STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
    169       STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
    170       STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
    171       STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
    172       STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
    173       STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
    174       STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
    175       STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
    176       STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
    177       STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
    178       STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
    179       STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
    180       STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
    181       STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
    182       STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
    183       STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
    184 
    185       a += saved_a;
    186     b += saved_b;
    187     c += saved_c;
    188     d += saved_d;
    189 
    190     ptr += 64;
    191   } while(size -= 64);
    192 
    193   ctx->a = a;
    194   ctx->b = b;
    195   ctx->c = c;
    196   ctx->d = d;
    197 
    198   return ptr;
    199 }
    200 
    201 static void MD4_Init(MD4_CTX *ctx)
    202 {
    203   ctx->a = 0x67452301;
    204   ctx->b = 0xefcdab89;
    205   ctx->c = 0x98badcfe;
    206   ctx->d = 0x10325476;
    207 
    208   ctx->lo = 0;
    209   ctx->hi = 0;
    210 }
    211 
    212 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
    213 {
    214   MD4_u32plus saved_lo;
    215   unsigned long used, available;
    216 
    217   saved_lo = ctx->lo;
    218   ctx->lo = (saved_lo + size) & 0x1fffffff;
    219   if(ctx->lo < saved_lo)
    220     ctx->hi++;
    221   ctx->hi += (MD4_u32plus)size >> 29;
    222 
    223   used = saved_lo & 0x3f;
    224 
    225   if(used) {
    226     available = 64 - used;
    227 
    228     if(size < available) {
    229       memcpy(&ctx->buffer[used], data, size);
    230       return;
    231     }
    232 
    233     memcpy(&ctx->buffer[used], data, available);
    234     data = (const unsigned char *)data + available;
    235     size -= available;
    236     body(ctx, ctx->buffer, 64);
    237   }
    238 
    239   if(size >= 64) {
    240     data = body(ctx, data, size & ~(unsigned long)0x3f);
    241     size &= 0x3f;
    242   }
    243 
    244   memcpy(ctx->buffer, data, size);
    245 }
    246 
    247 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
    248 {
    249   unsigned long used, available;
    250 
    251   used = ctx->lo & 0x3f;
    252 
    253   ctx->buffer[used++] = 0x80;
    254 
    255   available = 64 - used;
    256 
    257   if(available < 8) {
    258     memset(&ctx->buffer[used], 0, available);
    259     body(ctx, ctx->buffer, 64);
    260     used = 0;
    261     available = 64;
    262   }
    263 
    264   memset(&ctx->buffer[used], 0, available - 8);
    265 
    266   ctx->lo <<= 3;
    267   ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
    268   ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
    269   ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
    270   ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
    271   ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
    272   ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
    273   ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
    274   ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
    275 
    276   body(ctx, ctx->buffer, 64);
    277 
    278   result[0] = curlx_ultouc((ctx->a)&0xff);
    279   result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
    280   result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
    281   result[3] = curlx_ultouc(ctx->a >> 24);
    282   result[4] = curlx_ultouc((ctx->b)&0xff);
    283   result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
    284   result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
    285   result[7] = curlx_ultouc(ctx->b >> 24);
    286   result[8] = curlx_ultouc((ctx->c)&0xff);
    287   result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
    288   result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
    289   result[11] = curlx_ultouc(ctx->c >> 24);
    290   result[12] = curlx_ultouc((ctx->d)&0xff);
    291   result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
    292   result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
    293   result[15] = curlx_ultouc(ctx->d >> 24);
    294 
    295   memset(ctx, 0, sizeof(*ctx));
    296 }
    297 
    298 #endif
    299 
    300 void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
    301 {
    302   MD4_CTX ctx;
    303   MD4_Init(&ctx);
    304   MD4_Update(&ctx, input, curlx_uztoui(len));
    305   MD4_Final(output, &ctx);
    306 }
    307 #endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
    308     (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
    309