"Fossies" - the Fresh Open Source Software Archive

Member "passwdqc-2.0.3/md4.c" (23 Jun 2023, 7542 Bytes) of package /linux/privat/passwdqc-2.0.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "md4.c" see the Fossies "Dox" file reference documentation.

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