diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-05-31 19:31:10 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-06-02 07:14:22 +0200 |
commit | c7a5eabeba1bc12adab79d2dc2cb20a78fe33227 (patch) | |
tree | 72f638bd8c972b80c40008d87132ff562df7346f /src/fundamental/sha256.c | |
parent | src: The return value of server_vacuum () is not used and could be modified t... (diff) | |
download | systemd-c7a5eabeba1bc12adab79d2dc2cb20a78fe33227.tar.xz systemd-c7a5eabeba1bc12adab79d2dc2cb20a78fe33227.zip |
sha256: use memcpy() when result buffer is unaligned
Fixes #23578.
Diffstat (limited to '')
-rw-r--r-- | src/fundamental/sha256.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/src/fundamental/sha256.c b/src/fundamental/sha256.c index 6fcb37a7d9..67d83b5f1c 100644 --- a/src/fundamental/sha256.c +++ b/src/fundamental/sha256.c @@ -49,6 +49,20 @@ # define SWAP64(n) (n) #endif +/* The condition below is from glibc's string/string-inline.c. + * See definition of _STRING_INLINE_unaligned. */ +#if !defined(__mc68020__) && !defined(__s390__) && !defined(__i386__) + +/* To check alignment gcc has an appropriate operator. Other compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((size_t) p) % __alignof__(uint32_t) != 0) +# else +# define UNALIGNED_P(p) (((size_t) p) % sizeof(uint32_t) != 0) +# endif +#else +# define UNALIGNED_P(p) false +#endif + /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (FIPS 180-2:5.1.1) */ static const uint8_t fillbuf[64] = { @@ -96,10 +110,7 @@ void sha256_init_ctx(struct sha256_ctx *ctx) { } /* Process the remaining bytes in the internal buffer and the usual - prolog according to the standard and write the result to RESBUF. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ + prolog according to the standard and write the result to RESBUF. */ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { /* Take yet unprocessed bytes into account. */ uint32_t bytes = ctx->buflen; @@ -124,7 +135,10 @@ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { /* Put result from CTX in first 32 bytes following RESBUF. */ for (size_t i = 0; i < 8; ++i) - ((uint32_t *) resbuf)[i] = SWAP(ctx->H[i]); + if (UNALIGNED_P(resbuf)) + memcpy((uint8_t*) resbuf + i * sizeof(uint32_t), (uint32_t[]) { SWAP(ctx->H[i]) }, sizeof(uint32_t)); + else + ((uint32_t *) resbuf)[i] = SWAP(ctx->H[i]); return resbuf; } @@ -158,17 +172,6 @@ void sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx /* Process available complete blocks. */ if (len >= 64) { - -/* The condition below is from glibc's string/string-inline.c. - * See definition of _STRING_INLINE_unaligned. */ -#if !defined(__mc68020__) && !defined(__s390__) && !defined(__i386__) - -/* To check alignment gcc has an appropriate operator. Other compilers don't. */ -# if __GNUC__ >= 2 -# define UNALIGNED_P(p) (((size_t) p) % __alignof__(uint32_t) != 0) -# else -# define UNALIGNED_P(p) (((size_t) p) % sizeof(uint32_t) != 0) -# endif if (UNALIGNED_P(buffer)) while (len > 64) { memcpy(ctx->buffer, buffer, 64); @@ -176,9 +179,7 @@ void sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx buffer = (const char *) buffer + 64; len -= 64; } - else -#endif - { + else { sha256_process_block(buffer, len & ~63, ctx); buffer = (const char *) buffer + (len & ~63); len &= 63; |