/* md5.c - Functions to compute MD5 message digest of files or memory blocks
according to the definition of MD5 in RFC 1321 from April 1992.
- Copyright (C) 1995, 1996, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1995-2019 Free Software Foundation, Inc.
NOTE: This source is derived from an old version taken from the GNU C
Library (glibc).
{
/* Take yet unprocessed bytes into account. */
md5_uint32 bytes = ctx->buflen;
+ md5_uint32 swap_bytes;
size_t pad;
/* Now count remaining bytes. */
pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
memcpy (&ctx->buffer[bytes], fillbuf, pad);
- /* Put the 64-bit file length in *bits* at the end of the buffer. */
- *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
- *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
- (ctx->total[0] >> 29));
+ /* Put the 64-bit file length in *bits* at the end of the buffer.
+ Use memcpy to avoid aliasing problems. On most systems, this
+ will be optimized away to the same code. */
+ swap_bytes = SWAP (ctx->total[0] << 3);
+ memcpy (&ctx->buffer[bytes + pad], &swap_bytes, sizeof (swap_bytes));
+ swap_bytes = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
+ memcpy (&ctx->buffer[bytes + pad + 4], &swap_bytes, sizeof (swap_bytes));
/* Process last bytes. */
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
/* Process available complete blocks. */
if (len > 64)
{
-#if !_STRING_ARCH_unaligned
+#if !_STRING_ARCH_unaligned || defined UBSAN_BOOTSTRAP
/* To check alignment gcc has an appropriate operator. Other
compilers don't. */
# if __GNUC__ >= 2
length of the file up to 2^64 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
- if (ctx->total[0] < len)
- ++ctx->total[1];
+ ctx->total[1] += ((len >> 31) >> 1) + (ctx->total[0] < len);
/* Process all bytes in the buffer with 64 bytes in each round of
the loop. */