From 56c4ea978af3991a404c72d4358d40483922cd09 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 24 Sep 2018 21:25:13 +0200 Subject: hchacha20: keep in native endian in words --- src/crypto/zinc/chacha20/chacha20-arm-glue.h | 8 +++--- src/crypto/zinc/chacha20/chacha20-arm.S | 4 +-- src/crypto/zinc/chacha20/chacha20-mips-glue.h | 7 ++++-- src/crypto/zinc/chacha20/chacha20-x86_64-glue.h | 8 +++--- src/crypto/zinc/chacha20/chacha20.c | 33 +++++++++++-------------- src/crypto/zinc/chacha20poly1305.c | 10 +++++--- src/crypto/zinc/selftest/chacha20.h | 8 +++--- 7 files changed, 41 insertions(+), 37 deletions(-) (limited to 'src/crypto/zinc') diff --git a/src/crypto/zinc/chacha20/chacha20-arm-glue.h b/src/crypto/zinc/chacha20/chacha20-arm-glue.h index 1f1add0..86cce85 100644 --- a/src/crypto/zinc/chacha20/chacha20-arm-glue.h +++ b/src/crypto/zinc/chacha20/chacha20-arm-glue.h @@ -57,8 +57,10 @@ static inline bool chacha20_arch(struct chacha20_ctx *state, u8 *dst, return true; } -static inline bool hchacha20_arch(u8 *derived_key, const u8 *nonce, - const u8 *key, simd_context_t *simd_context) +static inline bool hchacha20_arch(u32 derived_key[CHACHA20_KEY_WORDS], + const u8 nonce[HCHACHA20_NONCE_SIZE], + const u8 key[HCHACHA20_KEY_SIZE], + simd_context_t *simd_context) { #if defined(CONFIG_ARM) u32 x[] = { CHACHA20_CONSTANT_EXPA, @@ -78,7 +80,7 @@ static inline bool hchacha20_arch(u8 *derived_key, const u8 *nonce, get_unaligned_le32(nonce + 8), get_unaligned_le32(nonce + 12) }; - hchacha20_arm(x, (u32 *)derived_key); + hchacha20_arm(x, derived_key); return true; #else return false; diff --git a/src/crypto/zinc/chacha20/chacha20-arm.S b/src/crypto/zinc/chacha20/chacha20-arm.S index 7fbb631..5abedaf 100644 --- a/src/crypto/zinc/chacha20/chacha20-arm.S +++ b/src/crypto/zinc/chacha20/chacha20-arm.S @@ -457,9 +457,7 @@ ENTRY(hchacha20_arm) ror X14, X14, #drot ror X15, X15, #drot - // Store (x0-x3,x12-x15) to 'out' after byte swapping - _le32_bswap_4x X0, X1, X2, X3, X4, X5, X6 - _le32_bswap_4x X12, X13, X14, X15, X4, X5, X6 + // Store (x0-x3,x12-x15) to 'out' stm r4, {X0,X1,X2,X3,X12,X13,X14,X15} pop {r4-r11,pc} diff --git a/src/crypto/zinc/chacha20/chacha20-mips-glue.h b/src/crypto/zinc/chacha20/chacha20-mips-glue.h index 929ca12..6e70dd6 100644 --- a/src/crypto/zinc/chacha20/chacha20-mips-glue.h +++ b/src/crypto/zinc/chacha20/chacha20-mips-glue.h @@ -17,8 +17,11 @@ static inline bool chacha20_arch(struct chacha20_ctx *state, u8 *dst, return true; } -static inline bool hchacha20_arch(u8 *derived_key, const u8 *nonce, - const u8 *key, simd_context_t *simd_context) + +static inline bool hchacha20_arch(u32 derived_key[CHACHA20_KEY_WORDS], + const u8 nonce[HCHACHA20_NONCE_SIZE], + const u8 key[HCHACHA20_KEY_SIZE], + simd_context_t *simd_context) { return false; } diff --git a/src/crypto/zinc/chacha20/chacha20-x86_64-glue.h b/src/crypto/zinc/chacha20/chacha20-x86_64-glue.h index 77dacf6..1b7fc05 100644 --- a/src/crypto/zinc/chacha20/chacha20-x86_64-glue.h +++ b/src/crypto/zinc/chacha20/chacha20-x86_64-glue.h @@ -9,7 +9,7 @@ #include #ifdef CONFIG_AS_SSSE3 -asmlinkage void hchacha20_ssse3(u8 *derived_key, const u8 *nonce, +asmlinkage void hchacha20_ssse3(u32 *derived_key, const u8 *nonce, const u8 *key); asmlinkage void chacha20_ssse3(u8 *out, const u8 *in, const size_t len, const u32 key[8], const u32 counter[4]); @@ -92,8 +92,10 @@ success: return true; } -static inline bool hchacha20_arch(u8 *derived_key, const u8 *nonce, - const u8 *key, simd_context_t *simd_context) +static inline bool hchacha20_arch(u32 derived_key[CHACHA20_KEY_WORDS], + const u8 nonce[HCHACHA20_NONCE_SIZE], + const u8 key[HCHACHA20_KEY_SIZE], + simd_context_t *simd_context) { #if defined(CONFIG_AS_SSSE3) if (chacha20_use_ssse3 && simd_use(simd_context)) { diff --git a/src/crypto/zinc/chacha20/chacha20.c b/src/crypto/zinc/chacha20/chacha20.c index ca50d0e..dc9770b 100644 --- a/src/crypto/zinc/chacha20/chacha20.c +++ b/src/crypto/zinc/chacha20/chacha20.c @@ -30,8 +30,10 @@ static inline bool chacha20_arch(struct chacha20_ctx *state, u8 *out, { return false; } -static inline bool hchacha20_arch(u8 *derived_key, const u8 *nonce, - const u8 *key, simd_context_t *simd_context) +static inline bool hchacha20_arch(u32 derived_key[CHACHA20_KEY_WORDS], + const u8 nonce[HCHACHA20_NONCE_SIZE], + const u8 key[HCHACHA20_KEY_SIZE], + simd_context_t *simd_context) { return false; } @@ -118,43 +120,36 @@ void chacha20(struct chacha20_ctx *state, u8 *dst, const u8 *src, u32 len, } EXPORT_SYMBOL(chacha20); -static void hchacha20_generic(u8 derived_key[CHACHA20_KEY_SIZE], +static void hchacha20_generic(u32 derived_key[CHACHA20_KEY_WORDS], const u8 nonce[HCHACHA20_NONCE_SIZE], const u8 key[HCHACHA20_KEY_SIZE]) { - __le32 *out = (__force __le32 *)derived_key; u32 x[] = { CHACHA20_CONSTANT_EXPA, CHACHA20_CONSTANT_ND_3, CHACHA20_CONSTANT_2_BY, CHACHA20_CONSTANT_TE_K, - get_unaligned_le32(key + 0), - get_unaligned_le32(key + 4), - get_unaligned_le32(key + 8), + get_unaligned_le32(key + 0), + get_unaligned_le32(key + 4), + get_unaligned_le32(key + 8), get_unaligned_le32(key + 12), get_unaligned_le32(key + 16), get_unaligned_le32(key + 20), get_unaligned_le32(key + 24), get_unaligned_le32(key + 28), - get_unaligned_le32(nonce + 0), - get_unaligned_le32(nonce + 4), - get_unaligned_le32(nonce + 8), + get_unaligned_le32(nonce + 0), + get_unaligned_le32(nonce + 4), + get_unaligned_le32(nonce + 8), get_unaligned_le32(nonce + 12) }; TWENTY_ROUNDS(x); - out[0] = cpu_to_le32(x[0]); - out[1] = cpu_to_le32(x[1]); - out[2] = cpu_to_le32(x[2]); - out[3] = cpu_to_le32(x[3]); - out[4] = cpu_to_le32(x[12]); - out[5] = cpu_to_le32(x[13]); - out[6] = cpu_to_le32(x[14]); - out[7] = cpu_to_le32(x[15]); + memcpy(derived_key + 0, x + 0, sizeof(u32) * 4); + memcpy(derived_key + 4, x + 12, sizeof(u32) * 4); } /* Derived key should be 32-bit aligned */ -void hchacha20(u8 derived_key[CHACHA20_KEY_SIZE], +void hchacha20(u32 derived_key[CHACHA20_KEY_WORDS], const u8 nonce[HCHACHA20_NONCE_SIZE], const u8 key[HCHACHA20_KEY_SIZE], simd_context_t *simd_context) { diff --git a/src/crypto/zinc/chacha20poly1305.c b/src/crypto/zinc/chacha20poly1305.c index 2003cb1..f2d82a1 100644 --- a/src/crypto/zinc/chacha20poly1305.c +++ b/src/crypto/zinc/chacha20poly1305.c @@ -305,13 +305,14 @@ void xchacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, const u8 key[CHACHA20POLY1305_KEYLEN]) { simd_context_t simd_context; - u8 derived_key[CHACHA20POLY1305_KEYLEN] __aligned(16); + u32 derived_key[CHACHA20_KEY_WORDS] __aligned(16); simd_get(&simd_context); hchacha20(derived_key, nonce, key, &simd_context); + cpu_to_le32_array(derived_key, ARRAY_SIZE(derived_key)); __chacha20poly1305_encrypt(dst, src, src_len, ad, ad_len, get_unaligned_le64(nonce + 16), - derived_key, &simd_context); + (u8 *)derived_key, &simd_context); memzero_explicit(derived_key, CHACHA20POLY1305_KEYLEN); simd_put(&simd_context); } @@ -324,13 +325,14 @@ bool xchacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len, { bool ret; simd_context_t simd_context; - u8 derived_key[CHACHA20POLY1305_KEYLEN] __aligned(16); + u32 derived_key[CHACHA20_KEY_WORDS] __aligned(16); simd_get(&simd_context); hchacha20(derived_key, nonce, key, &simd_context); + cpu_to_le32_array(derived_key, ARRAY_SIZE(derived_key)); ret = __chacha20poly1305_decrypt(dst, src, src_len, ad, ad_len, get_unaligned_le64(nonce + 16), - derived_key, &simd_context); + (u8 *)derived_key, &simd_context); memzero_explicit(derived_key, CHACHA20POLY1305_KEYLEN); simd_put(&simd_context); return ret; diff --git a/src/crypto/zinc/selftest/chacha20.h b/src/crypto/zinc/selftest/chacha20.h index b20fd31..fefcb75 100644 --- a/src/crypto/zinc/selftest/chacha20.h +++ b/src/crypto/zinc/selftest/chacha20.h @@ -2518,6 +2518,7 @@ static bool __init chacha20_selftest(void) { enum { MAXIMUM_TEST_BUFFER_LEN = 1UL << 10 }; size_t i, j; + u32 derived_key[CHACHA20_KEY_WORDS]; u8 *offset_input = NULL, *computed_output = NULL; u8 offset_key[CHACHA20_KEY_SIZE + 1] __aligned(__alignof__(unsigned long)); @@ -2609,10 +2610,11 @@ next_test: } } for (i = 0; i < ARRAY_SIZE(hchacha20_testvecs); ++i) { - memset(computed_output, 0, MAXIMUM_TEST_BUFFER_LEN + 1); - hchacha20(computed_output, hchacha20_testvecs[i].nonce, + memset(&derived_key, 0, sizeof(derived_key)); + hchacha20(derived_key, hchacha20_testvecs[i].nonce, hchacha20_testvecs[i].key, &simd_context); - if (memcmp(computed_output, hchacha20_testvecs[i].output, + cpu_to_le32_array(derived_key, ARRAY_SIZE(derived_key)); + if (memcmp(derived_key, hchacha20_testvecs[i].output, CHACHA20_KEY_SIZE)) { pr_info("hchacha20 self-test %zu: FAIL\n", i + 1); success = false; -- cgit v1.2.3-59-g8ed1b