Preserve ARM registers, reenable ARM assembly
https://github.com/smuellerDD/leancrypto/commit/3c32c1afe3e4653fd4093ed77090c36 Resolves: RHEL-89715
This commit is contained in:
parent
8d31a65d90
commit
6e0ba93d2a
10
gnutls.spec
10
gnutls.spec
@ -176,6 +176,8 @@ Source204: nettle-3.10-hobble-to-configure.patch
|
||||
%if %{with leancrypto}
|
||||
Source300: leancrypto-1.3.0.tar.gz
|
||||
%endif
|
||||
# Not upstreamed, from a comment in smuellerDD/leancrypto#27
|
||||
Source301: leancrypto-1.3.0-preserve-arm-registers.patch
|
||||
|
||||
# Wildcard bundling exception https://fedorahosted.org/fpc/ticket/174
|
||||
Provides: bundled(gnulib) = 20130424
|
||||
@ -325,6 +327,7 @@ popd
|
||||
mkdir -p bundled_leancrypto
|
||||
pushd bundled_leancrypto
|
||||
tar --strip-components=1 -xf %{SOURCE300}
|
||||
patch -p1 < %{SOURCE301}
|
||||
popd
|
||||
%endif
|
||||
|
||||
@ -380,12 +383,6 @@ export HOGWEED_LIBS="$NETTLE_DIR/libhogweed.a $NETTLE_LIBS $GMP_LIBS"
|
||||
%if %{with leancrypto}
|
||||
pushd bundled_leancrypto
|
||||
%set_build_flags
|
||||
|
||||
# FIXME RHEL-89715 interim countermeasure
|
||||
%ifarch aarch64
|
||||
%define leancrypto_extra_setup_flags -Ddisable-asm=true
|
||||
%endif
|
||||
|
||||
meson setup -Dprefix="$PWD/install" -Dlibdir="$PWD/install/lib" \
|
||||
-Ddefault_library=static \
|
||||
-Dascon=disabled -Dascon_keccak=disabled \
|
||||
@ -404,7 +401,6 @@ meson setup -Dprefix="$PWD/install" -Dlibdir="$PWD/install/lib" \
|
||||
-Dhotp=disabled -Dtotp=disabled \
|
||||
-Daes_block=disabled -Daes_cbc=disabled -Daes_ctr=disabled \
|
||||
-Daes_kw=disabled -Dapps=disabled \
|
||||
%{?leancrypto_extra_setup_flags} \
|
||||
_build
|
||||
meson compile -v -C _build
|
||||
meson install -C _build
|
||||
|
||||
346
leancrypto-1.3.0-preserve-arm-registers.patch
Normal file
346
leancrypto-1.3.0-preserve-arm-registers.patch
Normal file
@ -0,0 +1,346 @@
|
||||
From 3c32c1afe3e4653fd4093ed77090c36223bce7a0 Mon Sep 17 00:00:00 2001
|
||||
From: Stephan Mueller <smueller@chronox.de>
|
||||
Date: Thu, 8 May 2025 12:34:21 +0200
|
||||
Subject: [PATCH] ARMv8: properly save/restore SIMD register v8 through v15
|
||||
|
||||
Those registers are used by ML-DSA and ML-KEM.
|
||||
|
||||
Signed-off-by: Stephan Mueller <smueller@chronox.de>
|
||||
---
|
||||
internal/api/armv8_helper.h | 67 ++++++++++++
|
||||
ml-dsa/src/armv8/dilithium_signature_armv8.c | 101 +++++++++++++++++--
|
||||
ml-kem/src/armv8/kyber_indcpa_armv8.c | 13 +++
|
||||
4 files changed, 173 insertions(+), 10 deletions(-)
|
||||
create mode 100644 internal/api/armv8_helper.h
|
||||
|
||||
diff --git a/internal/api/armv8_helper.h b/internal/api/armv8_helper.h
|
||||
new file mode 100644
|
||||
index 00000000..456f3239
|
||||
--- /dev/null
|
||||
+++ b/internal/api/armv8_helper.h
|
||||
@@ -0,0 +1,67 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2025, Stephan Mueller <smueller@chronox.de>
|
||||
+ *
|
||||
+ * License: see LICENSE file in root directory
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
|
||||
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
|
||||
+ * DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef ARMV8_HELPER_H
|
||||
+#define ARMV8_HELPER_H
|
||||
+
|
||||
+#include "ext_headers.h"
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * The ARMv8 Kyber implementation uses the SIMD registers v8 through v15 which
|
||||
+ * must be preserved by the callee.
|
||||
+ *
|
||||
+ * Store only the lower 64 bits of the FP registers v8 through v15 according to
|
||||
+ * https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#612simd-and-floating-point-registers
|
||||
+ */
|
||||
+static inline void store_fp_regs(uint64_t tmp[8])
|
||||
+{
|
||||
+ __asm__ volatile("mov %0, v8.d[0]" : "=r"(tmp[0]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v9.d[0]" : "=r"(tmp[1]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v10.d[0]" : "=r"(tmp[2]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v11.d[0]" : "=r"(tmp[3]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v12.d[0]" : "=r"(tmp[4]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v13.d[0]" : "=r"(tmp[5]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v14.d[0]" : "=r"(tmp[6]) : : "memory" );
|
||||
+ __asm__ volatile("mov %0, v15.d[0]" : "=r"(tmp[7]) : : "memory" );
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Reload the stored register content into the SIMD registers
|
||||
+ */
|
||||
+static inline void reload_fp_regs(uint64_t tmp[8])
|
||||
+{
|
||||
+ __asm__ volatile("mov v8.d[0], %0" : : "r"(tmp[0]) : "memory" );
|
||||
+ __asm__ volatile("mov v9.d[0], %0" : : "r"(tmp[1]) : "memory" );
|
||||
+ __asm__ volatile("mov v10.d[0], %0" : : "r"(tmp[2]) : "memory" );
|
||||
+ __asm__ volatile("mov v11.d[0], %0" : : "r"(tmp[3]) : "memory" );
|
||||
+ __asm__ volatile("mov v12.d[0], %0" : : "r"(tmp[4]) : "memory" );
|
||||
+ __asm__ volatile("mov v13.d[0], %0" : : "r"(tmp[5]) : "memory" );
|
||||
+ __asm__ volatile("mov v14.d[0], %0" : : "r"(tmp[6]) : "memory" );
|
||||
+ __asm__ volatile("mov v15.d[0], %0" : : "r"(tmp[7]) : "memory" );
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* ARMV8_HELPER_H */
|
||||
diff --git a/ml-dsa/src/armv8/dilithium_signature_armv8.c b/ml-dsa/src/armv8/dilithium_signature_armv8.c
|
||||
index a661ffe9..5bc64387 100644
|
||||
--- a/ml-dsa/src/armv8/dilithium_signature_armv8.c
|
||||
+++ b/ml-dsa/src/armv8/dilithium_signature_armv8.c
|
||||
@@ -17,6 +17,7 @@
|
||||
* DAMAGE.
|
||||
*/
|
||||
|
||||
+#include "armv8_helper.h"
|
||||
#include "dilithium_type.h"
|
||||
#include "dilithium_signature_armv8.h"
|
||||
#include "visibility.h"
|
||||
@@ -36,14 +37,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_keypair_from_seed_armv8,
|
||||
struct lc_dilithium_pk *pk, struct lc_dilithium_sk *sk,
|
||||
const uint8_t *seed, size_t seedlen)
|
||||
{
|
||||
- return lc_dilithium_keypair_from_seed_impl(pk, sk, seed, seedlen);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_keypair_from_seed_impl(pk, sk, seed, seedlen);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_keypair_armv8,
|
||||
struct lc_dilithium_pk *pk, struct lc_dilithium_sk *sk,
|
||||
struct lc_rng_ctx *rng_ctx)
|
||||
{
|
||||
- return lc_dilithium_keypair_impl(pk, sk, rng_ctx);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_keypair_impl(pk, sk, rng_ctx);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_armv8,
|
||||
@@ -51,7 +68,15 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_armv8,
|
||||
size_t mlen, const struct lc_dilithium_sk *sk,
|
||||
struct lc_rng_ctx *rng_ctx)
|
||||
{
|
||||
- return lc_dilithium_sign_impl(sig, m, mlen, sk, rng_ctx);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_sign_impl(sig, m, mlen, sk, rng_ctx);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_ctx_armv8,
|
||||
@@ -60,14 +85,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_ctx_armv8,
|
||||
size_t mlen, const struct lc_dilithium_sk *sk,
|
||||
struct lc_rng_ctx *rng_ctx)
|
||||
{
|
||||
- return lc_dilithium_sign_ctx_impl(sig, ctx, m, mlen, sk, rng_ctx);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_sign_ctx_impl(sig, ctx, m, mlen, sk, rng_ctx);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_init_armv8,
|
||||
struct lc_dilithium_ctx *ctx,
|
||||
const struct lc_dilithium_sk *sk)
|
||||
{
|
||||
- return lc_dilithium_sign_init_impl(ctx, sk);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_sign_init_impl(ctx, sk);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_update_armv8,
|
||||
@@ -83,14 +124,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_sign_final_armv8,
|
||||
const struct lc_dilithium_sk *sk,
|
||||
struct lc_rng_ctx *rng_ctx)
|
||||
{
|
||||
- return lc_dilithium_sign_final_impl(sig, ctx, sk, rng_ctx);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_sign_final_impl(sig, ctx, sk, rng_ctx);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_armv8,
|
||||
const struct lc_dilithium_sig *sig, const uint8_t *m,
|
||||
size_t mlen, const struct lc_dilithium_pk *pk)
|
||||
{
|
||||
- return lc_dilithium_verify_impl(sig, m, mlen, pk);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_verify_impl(sig, m, mlen, pk);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_ctx_armv8,
|
||||
@@ -98,14 +155,30 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_ctx_armv8,
|
||||
struct lc_dilithium_ctx *ctx, const uint8_t *m,
|
||||
size_t mlen, const struct lc_dilithium_pk *pk)
|
||||
{
|
||||
- return lc_dilithium_verify_ctx_impl(sig, ctx, m, mlen, pk);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_verify_ctx_impl(sig, ctx, m, mlen, pk);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_init_armv8,
|
||||
struct lc_dilithium_ctx *ctx,
|
||||
const struct lc_dilithium_pk *pk)
|
||||
{
|
||||
- return lc_dilithium_verify_init_impl(ctx, pk);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_verify_init_impl(ctx, pk);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_update_armv8,
|
||||
@@ -120,5 +193,13 @@ LC_INTERFACE_FUNCTION(int, lc_dilithium_verify_final_armv8,
|
||||
struct lc_dilithium_ctx *ctx,
|
||||
const struct lc_dilithium_pk *pk)
|
||||
{
|
||||
- return lc_dilithium_verify_final_impl(sig, ctx, pk);
|
||||
+ uint64_t saved_regs[8];
|
||||
+ int ret;
|
||||
+
|
||||
+ store_fp_regs(saved_regs);
|
||||
+ ret = lc_dilithium_verify_final_impl(sig, ctx, pk);
|
||||
+ reload_fp_regs(saved_regs);
|
||||
+ lc_memset_secure(saved_regs, 0, sizeof(saved_regs));
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
diff --git a/ml-kem/src/armv8/kyber_indcpa_armv8.c b/ml-kem/src/armv8/kyber_indcpa_armv8.c
|
||||
index 26b797d8..d6289d73 100644
|
||||
--- a/ml-kem/src/armv8/kyber_indcpa_armv8.c
|
||||
+++ b/ml-kem/src/armv8/kyber_indcpa_armv8.c
|
||||
@@ -23,6 +23,7 @@
|
||||
* That code is released under MIT license.
|
||||
*/
|
||||
|
||||
+#include "armv8_helper.h"
|
||||
#include "build_bug_on.h"
|
||||
#include "kyber_indcpa_armv8.h"
|
||||
#include "kyber_poly_armv8.h"
|
||||
@@ -229,6 +230,7 @@ int indcpa_keypair_armv8(uint8_t pk[LC_KYBER_INDCPA_PUBLICKEYBYTES],
|
||||
uint8_t buf[2 * LC_KYBER_SYMBYTES];
|
||||
uint8_t poly_getnoise_eta1_buf[POLY_GETNOISE_ETA1_BUFSIZE];
|
||||
polyvec a[LC_KYBER_K], e, pkpv, skpv;
|
||||
+ uint64_t saved_regs[8];
|
||||
};
|
||||
static const uint8_t kval = LC_KYBER_K;
|
||||
unsigned int i;
|
||||
@@ -239,6 +241,8 @@ int indcpa_keypair_armv8(uint8_t pk[LC_KYBER_INDCPA_PUBLICKEYBYTES],
|
||||
LC_HASH_CTX_ON_STACK(sha3_512_ctx, lc_sha3_512);
|
||||
LC_DECLARE_MEM(ws, struct workspace, 32);
|
||||
|
||||
+ store_fp_regs(ws->saved_regs);
|
||||
+
|
||||
buf = ws->buf;
|
||||
publicseed = ws->buf;
|
||||
noiseseed = ws->buf + LC_KYBER_SYMBYTES;
|
||||
@@ -282,6 +286,7 @@ int indcpa_keypair_armv8(uint8_t pk[LC_KYBER_INDCPA_PUBLICKEYBYTES],
|
||||
unpoison(pk, LC_KYBER_INDCPA_PUBLICKEYBYTES);
|
||||
|
||||
out:
|
||||
+ reload_fp_regs(ws->saved_regs);
|
||||
LC_RELEASE_MEM(ws);
|
||||
return ret;
|
||||
}
|
||||
@@ -299,12 +304,15 @@ int indcpa_enc_armv8(uint8_t c[LC_KYBER_INDCPA_BYTES],
|
||||
//uint8_t poly_getnoise_eta2_buf[POLY_GETNOISE_ETA2_BUFSIZE];
|
||||
polyvec sp, pkpv, ep, at[LC_KYBER_K], b;
|
||||
poly v, k, epp;
|
||||
+ uint64_t saved_regs[8];
|
||||
};
|
||||
unsigned int i;
|
||||
uint8_t nonce = 0, nonce2 = LC_KYBER_K;
|
||||
int ret;
|
||||
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
|
||||
|
||||
+ store_fp_regs(ws->saved_regs);
|
||||
+
|
||||
/*
|
||||
* Use the poly_getnoise_eta1_buf for this operation as seed is smaller
|
||||
* than poly_getnoise_eta1_buf and has the same alignment.
|
||||
@@ -354,6 +362,7 @@ int indcpa_enc_armv8(uint8_t c[LC_KYBER_INDCPA_BYTES],
|
||||
pack_ciphertext(c, &ws->b, &ws->v);
|
||||
|
||||
out:
|
||||
+ reload_fp_regs(ws->saved_regs);
|
||||
LC_RELEASE_MEM(ws);
|
||||
return ret;
|
||||
}
|
||||
@@ -365,9 +374,12 @@ int indcpa_dec_armv8(uint8_t m[LC_KYBER_INDCPA_MSGBYTES],
|
||||
struct workspace {
|
||||
polyvec b, skpv;
|
||||
poly v, mp;
|
||||
+ uint64_t saved_regs[8];
|
||||
};
|
||||
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
|
||||
|
||||
+ store_fp_regs(ws->saved_regs);
|
||||
+
|
||||
unpack_sk(&ws->skpv, sk);
|
||||
|
||||
/* Validate input */
|
||||
@@ -386,6 +398,7 @@ int indcpa_dec_armv8(uint8_t m[LC_KYBER_INDCPA_MSGBYTES],
|
||||
|
||||
poly_tomsg(m, &ws->mp);
|
||||
|
||||
+ reload_fp_regs(ws->saved_regs);
|
||||
LC_RELEASE_MEM(ws);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user