Skip to content

Commit 660231a

Browse files
Nicolas Pitregitster
authored andcommitted
block-sha1: support for architectures with memory alignment restrictions
This is needed on architectures with poor or non-existent unaligned memory support and/or no fast byte swap instruction (such as ARM) by using byte accesses to memory and shifting the result together. This also makes the code portable, therefore the byte access methods are the defaults. Any architecture that properly supports unaligned word accesses in hardware simply has to enable the alternative methods. Signed-off-by: Nicolas Pitre <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent dc52fd2 commit 660231a

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

block-sha1/sha1.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,42 @@
6060
#define setW(x, val) (W(x) = (val))
6161
#endif
6262

63+
/*
64+
* Performance might be improved if the CPU architecture is OK with
65+
* unaligned 32-bit loads and a fast ntohl() is available.
66+
* Otherwise fall back to byte loads and shifts which is portable,
67+
* and is faster on architectures with memory alignment issues.
68+
*/
69+
70+
#if defined(__i386__) || defined(__x86_64__)
71+
72+
#define get_be32(p) ntohl(*(unsigned int *)(p))
73+
#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0)
74+
75+
#else
76+
77+
#define get_be32(p) ( \
78+
(*((unsigned char *)(p) + 0) << 24) | \
79+
(*((unsigned char *)(p) + 1) << 16) | \
80+
(*((unsigned char *)(p) + 2) << 8) | \
81+
(*((unsigned char *)(p) + 3) << 0) )
82+
#define put_be32(p, v) do { \
83+
unsigned int __v = (v); \
84+
*((unsigned char *)(p) + 0) = __v >> 24; \
85+
*((unsigned char *)(p) + 1) = __v >> 16; \
86+
*((unsigned char *)(p) + 2) = __v >> 8; \
87+
*((unsigned char *)(p) + 3) = __v >> 0; } while (0)
88+
89+
#endif
90+
6391
/* This "rolls" over the 512-bit array */
6492
#define W(x) (array[(x)&15])
6593

6694
/*
6795
* Where do we get the source from? The first 16 iterations get it from
6896
* the input data, the next mix it from the 512-bit array.
6997
*/
70-
#define SHA_SRC(t) htonl(data[t])
98+
#define SHA_SRC(t) get_be32(data + t)
7199
#define SHA_MIX(t) SHA_ROL(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1)
72100

73101
#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \
@@ -245,5 +273,5 @@ void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx)
245273

246274
/* Output hash */
247275
for (i = 0; i < 5; i++)
248-
((unsigned int *)hashout)[i] = htonl(ctx->H[i]);
276+
put_be32(hashout + i*4, ctx->H[i]);
249277
}

0 commit comments

Comments
 (0)