[winpr,crypto] use inline functions for md4

This commit is contained in:
akallabeth 2024-10-22 09:32:53 +02:00
parent 6929ade1c4
commit b9aa91bfcb
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5

View File

@ -45,9 +45,18 @@
* F and G are optimized compared to their RFC 1320 definitions, with the
* optimization for F borrowed from Colin Plumb's MD5 implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
static inline winpr_MD4_u32plus F(winpr_MD4_u32plus x, winpr_MD4_u32plus y, winpr_MD4_u32plus z)
{
return ((z) ^ ((x) & ((y) ^ (z))));
}
static inline winpr_MD4_u32plus G(winpr_MD4_u32plus x, winpr_MD4_u32plus y, winpr_MD4_u32plus z)
{
return (((x) & ((y) | (z))) | ((y) & (z)));
}
static inline winpr_MD4_u32plus H(winpr_MD4_u32plus x, winpr_MD4_u32plus y, winpr_MD4_u32plus z)
{
return ((x) ^ (y) ^ (z));
}
/*
* The MD4 transformation for all three rounds.
@ -72,13 +81,14 @@
* their own translation unit avoids the problem.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) (*(const winpr_MD4_u32plus*)&ptr[(n)*4])
#define SET(n) (*(const winpr_MD4_u32plus*)&ptr[4ULL * (n)])
#define GET(n) SET(n)
#else
#define SET(n) \
(ctx->block[(n)] = (winpr_MD4_u32plus)ptr[(n)*4] | ((winpr_MD4_u32plus)ptr[(n)*4 + 1] << 8) | \
((winpr_MD4_u32plus)ptr[(n)*4 + 2] << 16) | \
((winpr_MD4_u32plus)ptr[(n)*4 + 3] << 24))
#define SET(n) \
(ctx->block[(n)] = (winpr_MD4_u32plus)ptr[4ULL * (n)] | \
((winpr_MD4_u32plus)ptr[4ULL * (n) + 1] << 8) | \
((winpr_MD4_u32plus)ptr[4ULL * (n) + 2] << 16) | \
((winpr_MD4_u32plus)ptr[4ULL * (n) + 3] << 24))
#define GET(n) (ctx->block[(n)])
#endif
@ -88,31 +98,22 @@
*/
static const void* body(WINPR_MD4_CTX* ctx, const void* data, unsigned long size)
{
const unsigned char* ptr = NULL;
winpr_MD4_u32plus a = 0;
winpr_MD4_u32plus b = 0;
winpr_MD4_u32plus c = 0;
winpr_MD4_u32plus d = 0;
winpr_MD4_u32plus saved_a = 0;
winpr_MD4_u32plus saved_b = 0;
winpr_MD4_u32plus saved_c = 0;
winpr_MD4_u32plus saved_d = 0;
const winpr_MD4_u32plus ac1 = 0x5a827999;
const winpr_MD4_u32plus ac2 = 0x6ed9eba1;
ptr = (const unsigned char*)data;
const unsigned char* ptr = (const unsigned char*)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
winpr_MD4_u32plus a = ctx->a;
winpr_MD4_u32plus b = ctx->b;
winpr_MD4_u32plus c = ctx->c;
winpr_MD4_u32plus d = ctx->d;
do
{
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
winpr_MD4_u32plus saved_a = a;
winpr_MD4_u32plus saved_b = b;
winpr_MD4_u32plus saved_c = c;
winpr_MD4_u32plus saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 3)
@ -197,20 +198,16 @@ void winpr_MD4_Init(WINPR_MD4_CTX* ctx)
void winpr_MD4_Update(WINPR_MD4_CTX* ctx, const void* data, unsigned long size)
{
winpr_MD4_u32plus saved_lo = 0;
unsigned long used = 0;
unsigned long available = 0;
saved_lo = ctx->lo;
winpr_MD4_u32plus saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
unsigned long used = saved_lo & 0x3f;
if (used)
{
available = 64 - used;
unsigned long available = 64 - used;
if (size < available)
{
@ -233,22 +230,21 @@ void winpr_MD4_Update(WINPR_MD4_CTX* ctx, const void* data, unsigned long size)
memcpy(ctx->buffer, data, size);
}
#define OUT(dst, src) \
(dst)[0] = (unsigned char)(src); \
(dst)[1] = (unsigned char)((src) >> 8); \
(dst)[2] = (unsigned char)((src) >> 16); \
static inline void OUT(unsigned char* dst, winpr_MD4_u32plus src)
{
(dst)[0] = (unsigned char)(src);
(dst)[1] = (unsigned char)((src) >> 8);
(dst)[2] = (unsigned char)((src) >> 16);
(dst)[3] = (unsigned char)((src) >> 24);
}
void winpr_MD4_Final(unsigned char* result, WINPR_MD4_CTX* ctx)
{
unsigned long used = 0;
unsigned long available = 0;
used = ctx->lo & 0x3f;
unsigned long used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
unsigned long available = 64 - used;
if (available < 8)
{
@ -261,15 +257,15 @@ void winpr_MD4_Final(unsigned char* result, WINPR_MD4_CTX* ctx)
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
OUT(&ctx->buffer[56], ctx->lo)
OUT(&ctx->buffer[60], ctx->hi)
OUT(&ctx->buffer[56], ctx->lo);
OUT(&ctx->buffer[60], ctx->hi);
body(ctx, ctx->buffer, 64);
OUT(&result[0], ctx->a)
OUT(&result[4], ctx->b)
OUT(&result[8], ctx->c)
OUT(&result[12], ctx->d)
OUT(&result[0], ctx->a);
OUT(&result[4], ctx->b);
OUT(&result[8], ctx->c);
OUT(&result[12], ctx->d);
memset(ctx, 0, sizeof(*ctx));
}