e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * MD4 (RFC-1320) message digest.
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen * Modified from MD5 code by Andrey Panin <pazke@donpac.ru>
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen * the public domain. There's absolutely no warranty.
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * This differs from Colin Plumb's older public domain implementation in
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * that no 32-bit integer data type is required, there's no compile-time
e667602217af55105d44d8d9b75f09a8a9ac2f14Timo Sirainen * endianness configuration, and the function prototypes match OpenSSL's.
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * The primary goals are portability and ease of use.
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen * This implementation is meant to be fast, but not as fast as possible.
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * Some known optimizations are not included to reduce source code size
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen * and avoid compile-time configuration.
31be5ed1551c98cddeb2295a594f010aaf4b76bcTimo Sirainen * The basic MD4 functions.
31be5ed1551c98cddeb2295a594f010aaf4b76bcTimo Sirainen#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
31be5ed1551c98cddeb2295a594f010aaf4b76bcTimo Sirainen#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#define H(x, y, z) ((x) ^ (y) ^ (z))
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen * The MD4 transformation for all four rounds.
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen (a) += f((b), (c), (d)) + (x); \
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen (a) = ((a) << (s)) | ((a) >> (32 - (s)))
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * SET reads 4 input bytes in little-endian byte order and stores them
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * in a properly aligned word in host byte order.
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * The check for little-endian architectures which tolerate unaligned
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen * memory accesses is just an optimization. Nothing will break if it
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen * doesn't work.
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen/* uint_fast32_t might be 64 bit, and thus may read 4 more bytes
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * beyond the end of the buffer. So only read precisely 32 bits
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * This processes one or more 64-byte data blocks, but does NOT update
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen * the bit counters. There're no alignment requirements.
dbb1fb1c51727e2050792f8c333b212e22a36d69Timo Sirainenstatic const void * ATTR_NOWARN_UNUSED_RESULT ATTR_UNSIGNED_WRAPS
dbb1fb1c51727e2050792f8c333b212e22a36d69Timo Sirainenbody(struct md4_context *ctx, const void *data, size_t size)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen STEP(G, b, c, d, a, GET(12) + 0x5A827999, 13);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen STEP(G, b, c, d, a, GET(13) + 0x5A827999, 13);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen STEP(G, b, c, d, a, GET(14) + 0x5A827999, 13);
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen STEP(G, b, c, d, a, GET(15) + 0x5A827999, 13);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen STEP(H, c, d, a, b, GET( 4) + 0x6ED9EBA1, 11);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen STEP(H, b, c, d, a, GET(12) + 0x6ED9EBA1, 15);
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen STEP(H, c, d, a, b, GET( 6) + 0x6ED9EBA1, 11);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen STEP(H, b, c, d, a, GET(14) + 0x6ED9EBA1, 15);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen STEP(H, c, d, a, b, GET( 5) + 0x6ED9EBA1, 11);
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen STEP(H, b, c, d, a, GET(13) + 0x6ED9EBA1, 15);
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen STEP(H, c, d, a, b, GET( 7) + 0x6ED9EBA1, 11);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen STEP(H, b, c, d, a, GET(15) + 0x6ED9EBA1, 15);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid md4_update(struct md4_context *ctx, const void *data, size_t size)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* @UNSAFE */
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
used = 0;
sizeof(struct md4_context),