mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
Crypto library fixes for v7.4-rc2
- Disable the MIPS64 Octeon optimized SHA-1, SHA-256, and SHA-512 code on little-endian kernels, since it doesn't work correctly on them - Remove the PowerPC optimized Poly1305 code. It's already been marked as BROKEN for over a year due to not working in softirq context, but it turns out some of the Poly1305 math is incorrect too - A few robustness improvements for the ML-DSA code -----BEGIN PGP SIGNATURE----- iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCaujLJxQcZWJpZ2dlcnNA a2VybmVsLm9yZwAKCRDzXCl4vpKOKxd5AP9gCKliD6T4RAmnUtM0Jzys24ezmsl2 NZuA7BDT3rvD9wEAjSyxFeMrWCxJmAx4yKzXVNJcZC9gRc2e/0OP39Mplwg= =tcgp -----END PGP SIGNATURE----- Merge tag 'libcrypto-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux Pull crypto library fixes from Eric Biggers: - Disable the MIPS64 Octeon optimized SHA-1, SHA-256, and SHA-512 code on little-endian kernels, since it doesn't work correctly on them - Remove the PowerPC optimized Poly1305 code. It's already been marked as BROKEN for over a year due to not working in softirq context, but it turns out some of the Poly1305 math is incorrect too - A few robustness improvements for the ML-DSA code * tag 'libcrypto-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux: lib/crypto: mldsa: Add __must_check to mldsa_verify() lib/crypto: mldsa: Explicitly check that 'alg' is a valid value lib/crypto: mldsa: Check pk_len before doing pointer arithmetic lib/crypto: powerpc/poly1305: Remove BROKEN implementation lib/crypto: mips: Disable Octeon SHA code on little-endian kernels
This commit is contained in:
commit
b2e7a7bbc1
|
|
@ -48,11 +48,13 @@ enum mldsa_alg {
|
|||
* Return:
|
||||
* * 0 if the signature is valid
|
||||
* * -EBADMSG if the signature and/or public key is malformed
|
||||
* * -EINVAL if @alg is not a valid value
|
||||
* * -EKEYREJECTED if the signature is invalid but otherwise well-formed
|
||||
* * -ENOMEM if out of memory so the validity of the signature is unknown
|
||||
*/
|
||||
int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
|
||||
const u8 *msg, size_t msg_len, const u8 *pk, size_t pk_len);
|
||||
int __must_check mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
|
||||
const u8 *msg, size_t msg_len, const u8 *pk,
|
||||
size_t pk_len);
|
||||
|
||||
#if IS_ENABLED(CONFIG_CRYPTO_LIB_MLDSA_KUNIT_TEST)
|
||||
/* Internal function, exposed only for unit testing */
|
||||
|
|
|
|||
|
|
@ -197,8 +197,6 @@ config CRYPTO_LIB_POLY1305_ARCH
|
|||
default y if ARM
|
||||
default y if ARM64
|
||||
default y if MIPS
|
||||
# The PPC64 code needs to be fixed to work in softirq context.
|
||||
default y if PPC64 && CPU_LITTLE_ENDIAN && VSX && BROKEN
|
||||
default y if RISCV
|
||||
default y if X86_64
|
||||
|
||||
|
|
@ -209,9 +207,7 @@ config CRYPTO_LIB_POLY1305_ARCH
|
|||
config CRYPTO_LIB_POLY1305_GENERIC
|
||||
bool
|
||||
depends on CRYPTO_LIB_POLY1305
|
||||
# Enable if there's no arch impl or the arch impl requires the generic
|
||||
# impl as a fallback. (Or if selected explicitly.)
|
||||
default y if !CRYPTO_LIB_POLY1305_ARCH || PPC64
|
||||
default y if !CRYPTO_LIB_POLY1305_ARCH
|
||||
|
||||
config CRYPTO_LIB_POLY1305_RSIZE
|
||||
int
|
||||
|
|
@ -237,7 +233,7 @@ config CRYPTO_LIB_SHA1_ARCH
|
|||
depends on CRYPTO_LIB_SHA1 && !UML
|
||||
default y if ARM
|
||||
default y if ARM64
|
||||
default y if MIPS && CPU_CAVIUM_OCTEON
|
||||
default y if MIPS && CPU_CAVIUM_OCTEON && CPU_BIG_ENDIAN
|
||||
default y if PPC
|
||||
default y if S390
|
||||
default y if SPARC64
|
||||
|
|
@ -255,7 +251,7 @@ config CRYPTO_LIB_SHA256_ARCH
|
|||
depends on CRYPTO_LIB_SHA256 && !UML
|
||||
default y if ARM && !CPU_V7M
|
||||
default y if ARM64
|
||||
default y if MIPS && CPU_CAVIUM_OCTEON
|
||||
default y if MIPS && CPU_CAVIUM_OCTEON && CPU_BIG_ENDIAN
|
||||
default y if PPC && SPE
|
||||
default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \
|
||||
RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS
|
||||
|
|
@ -275,7 +271,7 @@ config CRYPTO_LIB_SHA512_ARCH
|
|||
depends on CRYPTO_LIB_SHA512 && !UML
|
||||
default y if ARM && !CPU_V7M
|
||||
default y if ARM64
|
||||
default y if MIPS && CPU_CAVIUM_OCTEON
|
||||
default y if MIPS && CPU_CAVIUM_OCTEON && CPU_BIG_ENDIAN
|
||||
default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \
|
||||
RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS
|
||||
default y if S390
|
||||
|
|
|
|||
|
|
@ -256,8 +256,6 @@ $(obj)/mips/poly1305-core.S: $(src)/mips/poly1305-mips.pl FORCE
|
|||
targets += mips/poly1305-core.S
|
||||
endif
|
||||
|
||||
libpoly1305-$(CONFIG_PPC) += powerpc/poly1305-p10le_64.o
|
||||
|
||||
ifeq ($(CONFIG_RISCV),y)
|
||||
libpoly1305-y += riscv/poly1305-core.o
|
||||
poly1305-perlasm-flavour-$(CONFIG_32BIT) := 32
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ static const u8 *decode_t1_elem(struct mldsa_ring_elem *out,
|
|||
* Reference: FIPS 204 Algorithm 27, sigDecode.
|
||||
*
|
||||
* This also validates that the coefficients of z are in range, corresponding
|
||||
* the infinity norm check at the end of Algorithm 8, ML-DSA.Verify_internal.
|
||||
* to the infinity norm check at the end of Algorithm 8, ML-DSA.Verify_internal.
|
||||
*
|
||||
* Finally, this also converts z to NTT form.
|
||||
*/
|
||||
|
|
@ -528,15 +528,21 @@ static size_t encode_w1(u8 out[MAX_W1_ENCODED_LEN],
|
|||
int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
|
||||
const u8 *msg, size_t msg_len, const u8 *pk, size_t pk_len)
|
||||
{
|
||||
const struct mldsa_parameter_set *params = &mldsa_parameter_sets[alg];
|
||||
const int k = params->k, l = params->l;
|
||||
const struct mldsa_parameter_set *params;
|
||||
int k, l;
|
||||
/* For now this just does pure ML-DSA with an empty context string. */
|
||||
static const u8 msg_prefix[2] = { /* dom_sep= */ 0, /* ctx_len= */ 0 };
|
||||
const u8 *ctilde; /* The signer's commitment hash */
|
||||
const u8 *t1_encoded = &pk[RHO_LEN]; /* Next encoded element of t_1 */
|
||||
const u8 *t1_encoded; /* Next encoded element of t_1 */
|
||||
u8 *h; /* The signer's hint vector, length k * N */
|
||||
size_t w1_enc_len;
|
||||
|
||||
if (alg != MLDSA44 && alg != MLDSA65 && alg != MLDSA87)
|
||||
return -EINVAL;
|
||||
params = &mldsa_parameter_sets[alg];
|
||||
k = params->k;
|
||||
l = params->l;
|
||||
|
||||
/* Validate the public key and signature lengths. */
|
||||
if (pk_len != params->pk_len || sig_len != params->sig_len)
|
||||
return -EBADMSG;
|
||||
|
|
@ -587,6 +593,7 @@ int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
|
|||
* The computation is the same for each of the k rows. Just do each row
|
||||
* before moving on to the next, resulting in only one loop over k.
|
||||
*/
|
||||
t1_encoded = &pk[RHO_LEN];
|
||||
for (int i = 0; i < k; i++) {
|
||||
/*
|
||||
* tmp = NTT(A) * NTT(z) * 2^-32
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,76 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Poly1305 authenticator algorithm, RFC7539.
|
||||
*
|
||||
* Copyright 2023- IBM Corp. All rights reserved.
|
||||
*/
|
||||
#include <asm/switch_to.h>
|
||||
#include <linux/cpufeature.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
asmlinkage void poly1305_p10le_4blocks(struct poly1305_block_state *state,
|
||||
const u8 *m, size_t mlen);
|
||||
asmlinkage void poly1305_64s(struct poly1305_block_state *state, const u8 *m,
|
||||
size_t mlen, int highbit);
|
||||
asmlinkage void poly1305_emit_64(const struct poly1305_state *state, const u32 nonce[4], u8 digest[POLY1305_DIGEST_SIZE]);
|
||||
|
||||
static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_p10);
|
||||
|
||||
static void vsx_begin(void)
|
||||
{
|
||||
preempt_disable();
|
||||
enable_kernel_vsx();
|
||||
}
|
||||
|
||||
static void vsx_end(void)
|
||||
{
|
||||
disable_kernel_vsx();
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void poly1305_block_init(struct poly1305_block_state *dctx,
|
||||
const u8 raw_key[POLY1305_BLOCK_SIZE])
|
||||
{
|
||||
if (!static_key_enabled(&have_p10))
|
||||
return poly1305_block_init_generic(dctx, raw_key);
|
||||
|
||||
dctx->h = (struct poly1305_state){};
|
||||
dctx->core_r.key.r64[0] = get_unaligned_le64(raw_key + 0);
|
||||
dctx->core_r.key.r64[1] = get_unaligned_le64(raw_key + 8);
|
||||
}
|
||||
|
||||
static void poly1305_blocks(struct poly1305_block_state *state, const u8 *src,
|
||||
size_t len, u32 padbit)
|
||||
{
|
||||
if (!static_key_enabled(&have_p10))
|
||||
return poly1305_blocks_generic(state, src, len, padbit);
|
||||
vsx_begin();
|
||||
if (len >= POLY1305_BLOCK_SIZE * 4) {
|
||||
poly1305_p10le_4blocks(state, src, len);
|
||||
src += len - (len % (POLY1305_BLOCK_SIZE * 4));
|
||||
len %= POLY1305_BLOCK_SIZE * 4;
|
||||
}
|
||||
while (len >= POLY1305_BLOCK_SIZE) {
|
||||
poly1305_64s(state, src, POLY1305_BLOCK_SIZE, padbit);
|
||||
len -= POLY1305_BLOCK_SIZE;
|
||||
src += POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
vsx_end();
|
||||
}
|
||||
|
||||
static void poly1305_emit(const struct poly1305_state *state,
|
||||
u8 digest[POLY1305_DIGEST_SIZE], const u32 nonce[4])
|
||||
{
|
||||
if (!static_key_enabled(&have_p10))
|
||||
return poly1305_emit_generic(state, digest, nonce);
|
||||
poly1305_emit_64(state, nonce, digest);
|
||||
}
|
||||
|
||||
#define poly1305_mod_init_arch poly1305_mod_init_arch
|
||||
static void poly1305_mod_init_arch(void)
|
||||
{
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
static_branch_enable(&have_p10);
|
||||
}
|
||||
|
|
@ -372,6 +372,14 @@ static void test_mldsa_use_hint(struct kunit *test)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_mldsa_invalid_alg(struct kunit *test)
|
||||
{
|
||||
KUNIT_ASSERT_EQ(test, -EINVAL,
|
||||
mldsa_verify(MLDSA44 - 1, NULL, 0, NULL, 0, NULL, 0));
|
||||
KUNIT_ASSERT_EQ(test, -EINVAL,
|
||||
mldsa_verify(MLDSA87 + 1, NULL, 0, NULL, 0, NULL, 0));
|
||||
}
|
||||
|
||||
static void benchmark_mldsa(struct kunit *test,
|
||||
const struct mldsa_testvector *tv)
|
||||
{
|
||||
|
|
@ -414,6 +422,7 @@ static struct kunit_case mldsa_kunit_cases[] = {
|
|||
KUNIT_CASE(test_mldsa65),
|
||||
KUNIT_CASE(test_mldsa87),
|
||||
KUNIT_CASE(test_mldsa_use_hint),
|
||||
KUNIT_CASE(test_mldsa_invalid_alg),
|
||||
KUNIT_CASE(benchmark_mldsa44),
|
||||
KUNIT_CASE(benchmark_mldsa65),
|
||||
KUNIT_CASE(benchmark_mldsa87),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user