md5: fix md5_uint32 4 byte alignment, code copy from glibc

This commit is contained in:
Jacek Jendrzej
2021-10-23 17:40:31 +02:00
parent 4a23e0cdf2
commit 676423f72b
2 changed files with 47 additions and 18 deletions

View File

@@ -216,13 +216,14 @@ md5_process_bytes (buffer, len, ctx)
memmove (&ctx->buffer[left_over], buffer, add); memmove (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add; ctx->buflen += add;
if (left_over + add > 64) if (ctx->buflen > 64)
{ {
md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
ctx->buflen &= 63;
/* The regions in the following copy operation cannot overlap. */ /* The regions in the following copy operation cannot overlap. */
memmove (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], memmove (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
(left_over + add) & 63); ctx->buflen);
ctx->buflen = (left_over + add) & 63;
} }
buffer = (const char *) buffer + add; buffer = (const char *) buffer + add;
@@ -230,18 +231,46 @@ md5_process_bytes (buffer, len, ctx)
} }
/* Process available complete blocks. */ /* Process available complete blocks. */
if (len > 64) if (len >= 64)
{ {
md5_process_block (buffer, len & ~63, ctx); #if !_STRING_ARCH_unaligned
buffer = (const char *) buffer + (len & ~63); /* To check alignment gcc has an appropriate operator. Other
len &= 63; compilers don't. */
# if __GNUC__ >= 2
# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0)
# else
# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0)
# endif
if (UNALIGNED_P (buffer))
while (len > 64)
{
md5_process_block (memmove (ctx->buffer, buffer, 64), 64, ctx);
buffer = (const char *) buffer + 64;
len -= 64;
}
else
#endif
{
md5_process_block (buffer, len & ~63, ctx);
buffer = (const char *) buffer + (len & ~63);
len &= 63;
}
} }
/* Move remaining bytes in internal buffer. */ /* Move remaining bytes in internal buffer. */
if (len > 0) if (len > 0)
{ {
memmove (ctx->buffer, buffer, len); size_t left_over = ctx->buflen;
ctx->buflen = len;
memmove (&ctx->buffer[left_over], buffer, len);
left_over += len;
if (left_over >= 64)
{
md5_process_block (ctx->buffer, 64, ctx);
left_over -= 64;
memmove (ctx->buffer, &ctx->buffer[64], left_over);
}
ctx->buflen = left_over;
} }
} }

View File

@@ -35,14 +35,11 @@
is usually not possible. */ is usually not possible. */
#ifdef _LIBC #ifdef _LIBC
# include <sys/types.h> # include <stdint.h>
typedef u_int32_t md5_uint32; typedef uint32_t md5_uint32;
typedef uintptr_t md5_uintptr;
#else #else
# if defined __STDC__ && __STDC__ # define UINT_MAX_32_BITS 4294967295U
# define UINT_MAX_32_BITS 4294967295U
# else
# define UINT_MAX_32_BITS 0xFFFFFFFF
# endif
/* If UINT_MAX isn't defined, assume it's a 32-bit type. /* If UINT_MAX isn't defined, assume it's a 32-bit type.
This should be valid for all systems GNU cares about because This should be valid for all systems GNU cares about because
@@ -63,11 +60,14 @@ typedef u_int32_t md5_uint32;
typedef unsigned long md5_uint32; typedef unsigned long md5_uint32;
# else # else
/* The following line is intended to evoke an error. /* The following line is intended to evoke an error.
Using #error is not portable enough. */ Using #error is not portable enough. */
"Cannot determine unsigned 32-bit data type." "Cannot determine unsigned 32-bit data type."
# endif # endif
# endif # endif
# endif # endif
/* We have to make a guess about the integer type equivalent in size
to pointers which should always be correct. */
typedef unsigned long int md5_uintptr;
#endif #endif
#undef __P #undef __P