(root)/
libxcrypt-4.4.36/
lib/
alg-md4.c
       1  /*
       2   * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
       3   * MD4 Message-Digest Algorithm (RFC 1320).
       4   *
       5   * Homepage:
       6   * http://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  #include "crypt-port.h"
      39  
      40  #if INCLUDE_nt
      41  
      42  #include "alg-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 0 /* defined(__i386__) || defined(__x86_64__) || defined(__vax__) */
      77  #define SET(n) \
      78  	(*(const 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, unsigned long 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  	unsigned long 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 & ~(unsigned long)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(uint8_t result[16], MD4_CTX *ctx)
     238  {
     239  	unsigned long 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  	explicit_bzero(ctx, sizeof(*ctx));
     268  }
     269  
     270  #endif