[PATCH] crypt: Fix strict aliasing warnings
Marek Polacek
mpolacek@redhat.com
Tue Jul 19 00:36:00 GMT 2011
This is an attempt to fix strict aliasing warnings in crypt/. I've
made use of recent Roland's elfutils patch which addresses this problem
(32899ac4f69d4ca4856d5282464c1f9cee928c8a). The md5.c part is the same,
the sha{512,256}.c parts are very similar. I've tested this patch on
x86_64 (LE) and PPC64 (BE) with crypt/{md5,sha256,sha512}c-test.c and with
crypt/{md5,sha256,sha512}test.c. It seems fine.
Alternatively, I can cook up a patch which just uses `-Wno-strict-aliasing'
or `-fno-strict-aliasing'.
Ok?
2011-07-18 Marek Polacek <mpolacek@redhat.com>
* crypt/md5.c (le64_copy): New function.
(md5_finish_ctx): Use it.
* crypt/sha256.c (be64_copy): New function.
(__sha256_finish_ctx): Use it.
(SWAP64): Remove unused macro.
* crypt/sha512.c (be64_copy): New function.
(__sha512_finish_ctx): Use it.
--- libc/crypt/md5.c.mp 2011-07-13 13:37:27.698796939 +0200
+++ libc/crypt/md5.c 2011-07-15 14:18:16.898700264 +0200
@@ -1,6 +1,6 @@
/* 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,1997,1999,2000,2001,2005
+ Copyright (C) 1995,1996,1997,1999,2000,2001,2005,2011
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -100,6 +100,16 @@ md5_read_ctx (ctx, resbuf)
return resbuf;
}
+static void
+le64_copy (char *dest, uint64_t x)
+{
+ for (size_t i = 0; i < 8; ++i)
+ {
+ dest[i] = (uint8_t) x;
+ x >>= 8;
+ }
+}
+
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
@@ -123,9 +133,10 @@ md5_finish_ctx (ctx, resbuf)
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));
+ const uint64_t bit_length = ((ctx->total[0] << 3)
+ + ((uint64_t) ((ctx->total[1] << 3) |
+ (ctx->total[0] >> 29)) << 32));
+ le64_copy (&ctx->buffer[bytes + pad], bit_length);
/* Process last bytes. */
md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
--- libc/crypt/sha256.c.mp 2011-07-14 15:21:48.560669655 +0200
+++ libc/crypt/sha256.c 2011-07-18 14:33:48.452669821 +0200
@@ -35,23 +35,12 @@
# ifdef _LIBC
# include <byteswap.h>
# define SWAP(n) bswap_32 (n)
-# define SWAP64(n) bswap_64 (n)
# else
# define SWAP(n) \
(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
-# define SWAP64(n) \
- (((n) << 56) \
- | (((n) & 0xff00) << 40) \
- | (((n) & 0xff0000) << 24) \
- | (((n) & 0xff000000) << 8) \
- | (((n) >> 8) & 0xff000000) \
- | (((n) >> 24) & 0xff0000) \
- | (((n) >> 40) & 0xff00) \
- | ((n) >> 56))
# endif
#else
# define SWAP(n) (n)
-# define SWAP64(n) (n)
#endif
@@ -199,6 +188,12 @@ __sha256_init_ctx (ctx)
ctx->buflen = 0;
}
+static void
+be64_copy (char *dest, uint64_t x)
+{
+ for (size_t i = 8; i-- > 0; x >>= 8)
+ dest[i] = (uint8_t) x;
+}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
@@ -222,13 +217,13 @@ __sha256_finish_ctx (ctx, resbuf)
/* Put the 64-bit file length in *bits* at the end of the buffer. */
#ifdef _STRING_ARCH_unaligned
- *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP64 (ctx->total64 << 3);
+ be64_copy (&ctx->buffer[bytes + pad], ctx->total64 << 3);
#else
- *(uint32_t *) &ctx->buffer[bytes + pad + 4]
- = SWAP (ctx->total[TOTAL64_low] << 3);
- *(uint32_t *) &ctx->buffer[bytes + pad]
- = SWAP ((ctx->total[TOTAL64_high] << 3) |
- (ctx->total[TOTAL64_low] >> 29));
+ const uint64_t bit_length
+ = ((ctx->total[TOTAL64_low] << 3)
+ + ((uint64_t) ((ctx->total[TOTAL64_high] << 3) |
+ (ctx->total[TOTAL64_low] >> 29)) << 32));
+ be64_copy (&ctx->buffer[bytes + pad], bit_length);
#endif
/* Process last bytes. */
--- libc/crypt/sha512.c.mp 2011-07-18 13:46:51.387794691 +0200
+++ libc/crypt/sha512.c 2011-07-18 14:55:07.041669030 +0200
@@ -225,6 +225,12 @@ __sha512_init_ctx (ctx)
ctx->buflen = 0;
}
+static void
+be64_copy (char *dest, uint64_t x)
+{
+ for (size_t i = 8; i-- > 0; x >>= 8)
+ dest[i] = (uint8_t) x;
+}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
@@ -253,11 +259,9 @@ __sha512_finish_ctx (ctx, resbuf)
memcpy (&ctx->buffer[bytes], fillbuf, pad);
/* Put the 128-bit file length in *bits* at the end of the buffer. */
- *(uint64_t *) &ctx->buffer[bytes + pad + 8]
- = SWAP (ctx->total[TOTAL128_low] << 3);
- *(uint64_t *) &ctx->buffer[bytes + pad]
- = SWAP ((ctx->total[TOTAL128_high] << 3) |
- (ctx->total[TOTAL128_low] >> 61));
+ be64_copy (&ctx->buffer[bytes + pad], (ctx->total[TOTAL128_high] << 3) |
+ (ctx->total[TOTAL128_low] >> 61));
+ be64_copy (&ctx->buffer[bytes + pad + 8], ctx->total[TOTAL128_low] << 3);
/* Process last bytes. */
sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
More information about the Libc-alpha
mailing list