1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-19 22:50:17 +03:00

Merge pull request #23579 from yuwata/sha256-unaligned

sha256: use memcpy() to accept unaligned result buffer
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2022-06-02 16:38:19 +02:00 committed by GitHub
commit 7e5c7522e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 64 deletions

View File

@ -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;

View File

@ -670,6 +670,8 @@ tests += [
[], [], [], 'ENABLE_NSCD', 'manual'],
[files('test-hmac.c')],
[files('test-sha256.c')],
]
############################################################

View File

@ -10,59 +10,59 @@ static void hmac_sha256_by_string(const char *key, const char *value, uint8_t re
}
TEST(hmac) {
uint8_t result[SHA256_DIGEST_SIZE];
char *hex_result = NULL;
uint8_t result[SHA256_DIGEST_SIZE];
char *hex_result = NULL;
/* Results compared with output of 'echo -n "<input>" | openssl dgst -sha256 -hmac "<key>"' */
/* Results compared with output of 'echo -n "<input>" | openssl dgst -sha256 -hmac "<key>"' */
hmac_sha256_by_string("waldo",
"",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "cadd5e42114351181f3abff477641d88efb57d2b5641a1e5c6d623363a6d3bad"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "cadd5e42114351181f3abff477641d88efb57d2b5641a1e5c6d623363a6d3bad"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"baldohaldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "c47ad5031ba21605e52c6ca68090d66a2dd5ccf84efa4bace15361a8cba63cda"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"baldohaldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "c47ad5031ba21605e52c6ca68090d66a2dd5ccf84efa4bace15361a8cba63cda"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"baldo haldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"baldo haldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"baldo 4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69 haldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "039f3df430b19753ffb493e5b90708f75c5210b63c6bcbef3374eb3f0a3f97f7"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("waldo",
"baldo 4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69 haldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "039f3df430b19753ffb493e5b90708f75c5210b63c6bcbef3374eb3f0a3f97f7"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69",
"baldo haldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "c4cfaf48077cbb0bbd177a09e59ec4c248f4ca771503410f5b54b98d88d2f47b"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69",
"baldo haldo",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "c4cfaf48077cbb0bbd177a09e59ec4c248f4ca771503410f5b54b98d88d2f47b"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69",
"supercalifragilisticexpialidocious",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "2c059e7a63c4c3b23f47966a65fd2f8a2f5d7161e2e90d78ff68866b5c375cb7"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69",
"supercalifragilisticexpialidocious",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "2c059e7a63c4c3b23f47966a65fd2f8a2f5d7161e2e90d78ff68866b5c375cb7"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69c47ad5031ba21605e52c6ca68090d66a2dd5ccf84efa4bace15361a8cba63cda",
"supercalifragilisticexpialidocious",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "1dd1d1d45b9d9f9673dc9983c968c46ff3168e03cfeb4156a219eba1af4cff5f"));
hex_result = mfree(hex_result);
hmac_sha256_by_string("4e8974ad6c08b98cc2519cd1e27aa7195769fcf86db1dd7ceaab4d44c490ad69c47ad5031ba21605e52c6ca68090d66a2dd5ccf84efa4bace15361a8cba63cda",
"supercalifragilisticexpialidocious",
result);
hex_result = hexmem(result, sizeof(result));
assert_se(streq_ptr(hex_result, "1dd1d1d45b9d9f9673dc9983c968c46ff3168e03cfeb4156a219eba1af4cff5f"));
hex_result = mfree(hex_result);
}
DEFINE_TEST_MAIN(LOG_INFO);

50
src/test/test-sha256.c Normal file
View File

@ -0,0 +1,50 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "hexdecoct.h"
#include "sha256.h"
#include "string-util.h"
#include "tests.h"
static void sha256_process_string(const char *key, struct sha256_ctx *ctx) {
sha256_process_bytes(key, strlen(key), ctx);
}
static void test_sha256_one(const char *key, const char *expect) {
uint8_t result[SHA256_DIGEST_SIZE + 3];
_cleanup_free_ char *str = NULL;
struct sha256_ctx ctx;
log_debug("\"%s\" → %s", key, expect);
assert_se(str = new(char, strlen(key) + 4));
/* This tests unaligned buffers. */
for (size_t i = 0; i < 4; i++) {
strcpy(str + i, key);
for (size_t j = 0; j < 4; j++) {
_cleanup_free_ char *hex_result = NULL;
sha256_init_ctx(&ctx);
sha256_process_string(str + i, &ctx);
sha256_finish_ctx(&ctx, result + j);
hex_result = hexmem(result + j, SHA256_DIGEST_SIZE);
assert_se(streq_ptr(hex_result, expect));
}
}
}
TEST(sha256) {
/* Results compared with output of 'echo -n "<input>" | sha256sum -' */
test_sha256_one("abcdefghijklmnopqrstuvwxyz",
"71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73");
test_sha256_one("ほげほげあっちょんぶりけ",
"ce7225683653be3b74861c5a4323b6baf3c3ceb361413ca99e3a5b52c04411bd");
test_sha256_one("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
"9cfe7faff7054298ca87557e15a10262de8d3eee77827417fbdfea1c41b9ec23");
}
DEFINE_TEST_MAIN(LOG_INFO);