Bug#382465: Fix for hppa FTBFS
Hi,
I think I could fix the alignment errors. I had to change various
things, as the code was totally unaware of alignment problems, and I
really doubt that this ever worked on archs where correct alignment is
mandatory.
Please, look at it, as it changes the SHA1 code (and downgrades
performance, I know, I tried to keep it as simple as possible). There
were three problems WRT alignment: the buffer passed by the user is a
char array, later interpreted as ints; the context buffer and the
returned hash suffer the same problem.
--
Martín Ferrari
--- src/hackerlab/hash/sha1.c-orig 2006-08-21 19:28:34.585850524 -0300
+++ src/hackerlab/hash/sha1.c 2006-08-21 19:31:42.667183132 -0300
@@ -39,11 +39,11 @@
t_uint32 total[2];
t_uint32 buflen;
- t_uchar buffer[128];
+ t_uchar buffer[128] __attribute__((aligned(4)));
};
static void
-sha1_process_blocks (const void *buffer, size_t len, sha1_context_t ctx);
+sha1_process_blocks (const t_uchar *buffer, size_t len, sha1_context_t ctx);
#if MACHINE_IS_BIGENDIAN
# define NOTSWAP(n) (n)
@@ -124,7 +124,7 @@
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
- if (ctx->buflen != 0)
+ while (len > 0)
{
size_t left_over = ctx->buflen;
size_t add = 128 - left_over > len ? len : 128 - left_over;
@@ -147,14 +147,17 @@
}
/* Process available complete blocks. */
+ /*
if (len >= 64)
{
sha1_process_blocks (buffer, len & ~63, ctx);
buffer = (const t_uchar *) buffer + (len & ~63);
len &= 63;
}
+ */
/* Move remaining bytes in internal buffer. */
+ /*
if (len > 0)
{
size_t left_over = ctx->buflen;
@@ -169,6 +172,7 @@
}
ctx->buflen = left_over;
}
+ */
}
@@ -191,6 +195,8 @@
/* Take yet unprocessed bytes into account. */
t_uint32 bytes = ctx->buflen;
size_t pad;
+ /* Temporary array for solving alignment issues */
+ t_uint32 tmp[5];
/* Now count remaining bytes. */
ctx->total[0] += bytes;
@@ -208,11 +214,12 @@
/* Process last bytes. */
sha1_process_blocks (ctx->buffer, bytes + pad + 8, ctx);
- ((t_uint32 *) result)[0] = NOTSWAP (ctx->current_sha1.A);
- ((t_uint32 *) result)[1] = NOTSWAP (ctx->current_sha1.B);
- ((t_uint32 *) result)[2] = NOTSWAP (ctx->current_sha1.C);
- ((t_uint32 *) result)[3] = NOTSWAP (ctx->current_sha1.D);
- ((t_uint32 *) result)[4] = NOTSWAP (ctx->current_sha1.E);
+ tmp[0] = NOTSWAP (ctx->current_sha1.A);
+ tmp[1] = NOTSWAP (ctx->current_sha1.B);
+ tmp[2] = NOTSWAP (ctx->current_sha1.C);
+ tmp[3] = NOTSWAP (ctx->current_sha1.D);
+ tmp[4] = NOTSWAP (ctx->current_sha1.E);
+ mem_cpy (result, tmp, 20);
sha1_context_reset (ctx);
}
@@ -329,7 +336,7 @@
It is assumed that LEN % 64 == 0.
Most of this code comes from GnuPG's cipher/sha1.c. */
static void
-sha1_process_blocks (const void *buffer, size_t len, sha1_context_t ctx)
+sha1_process_blocks (const t_uchar *buffer, size_t len, sha1_context_t ctx)
{
const t_uint32 *words = buffer;
size_t nwords = len / sizeof (t_uint32);
Reply to: