summaryrefslogtreecommitdiff
path: root/src/fundamental
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-06-01 02:31:10 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-06-02 14:14:22 +0900
commitc7a5eabeba1bc12adab79d2dc2cb20a78fe33227 (patch)
tree72f638bd8c972b80c40008d87132ff562df7346f /src/fundamental
parentb278cf2efdff18f970c2827e2f28ee948b18dd6e (diff)
downloadsystemd-c7a5eabeba1bc12adab79d2dc2cb20a78fe33227.tar.gz
sha256: use memcpy() when result buffer is unaligned
Fixes #23578.
Diffstat (limited to 'src/fundamental')
-rw-r--r--src/fundamental/sha256.c39
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;