Fix Minerva timing side-channel signal for P-384 curve on PPC

1. bn_ppc.c: Used bn_mul_mont_int() instead of bn_mul_mont_300_fixed_n6()
   for Montgomery multiplication.
2. ecp_nistp384-ppc64.pl:
   - Re-wrote p384_felem_mul and p384_felem_square for easier maintenance with
     minumum perl wrapper.
   - Implemented p384_felem_reduce, p384_felem_mul_reduce and p384_felem_square_reduce.
   - Implemented p384_felem_diff64, felem_diff_128_64 and felem_diff128 in assembly.
3. ecp_nistp384.c:
   - Added wrapper function for p384_felem_mul_reduce and p384_felem_square_reduce.

Signed-off-by: Danny Tsen <dtsen@us.ibm.com>

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26709)
This commit is contained in:
Danny Tsen 2025-02-11 13:48:01 -05:00 committed by Tomas Mraz
parent ff030ad5bd
commit 85cabd9495
3 changed files with 1520 additions and 267 deletions

View File

@ -41,12 +41,15 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
*/
#if defined(_ARCH_PPC64) && !defined(__ILP32__)
/* Minerva side-channel fix danny */
# if defined(USE_FIXED_N6)
if (num == 6) {
if (OPENSSL_ppccap_P & PPC_MADD300)
return bn_mul_mont_300_fixed_n6(rp, ap, bp, np, n0, num);
else
return bn_mul_mont_fixed_n6(rp, ap, bp, np, n0, num);
}
# endif
#endif
return bn_mul_mont_int(rp, ap, bp, np, n0, num);

File diff suppressed because it is too large Load Diff

View File

@ -252,6 +252,16 @@ static void felem_neg(felem out, const felem in)
out[6] = two60m4 - in[6];
}
#if defined(ECP_NISTP384_ASM)
void p384_felem_diff64(felem out, const felem in);
void p384_felem_diff128(widefelem out, const widefelem in);
void p384_felem_diff_128_64(widefelem out, const felem in);
# define felem_diff64 p384_felem_diff64
# define felem_diff128 p384_felem_diff128
# define felem_diff_128_64 p384_felem_diff_128_64
#else
/*-
* felem_diff64 subtracts |in| from |out|
* On entry:
@ -369,6 +379,7 @@ static void felem_diff128(widefelem out, const widefelem in)
for (i = 0; i < 2*NLIMBS-1; i++)
out[i] -= in[i];
}
#endif /* ECP_NISTP384_ASM */
static void felem_square_ref(widefelem out, const felem in)
{
@ -503,7 +514,7 @@ static void felem_mul_ref(widefelem out, const felem in1, const felem in2)
* [3]: Y = 2^48 (acc[6] >> 48)
* (Where a | b | c | d = (2^56)^3 a + (2^56)^2 b + (2^56) c + d)
*/
static void felem_reduce(felem out, const widefelem in)
static void felem_reduce_ref(felem out, const widefelem in)
{
/*
* In order to prevent underflow, we add a multiple of p before subtracting.
@ -682,8 +693,11 @@ static void (*felem_square_p)(widefelem out, const felem in) =
static void (*felem_mul_p)(widefelem out, const felem in1, const felem in2) =
felem_mul_wrapper;
static void (*felem_reduce_p)(felem out, const widefelem in) = felem_reduce_ref;
void p384_felem_square(widefelem out, const felem in);
void p384_felem_mul(widefelem out, const felem in1, const felem in2);
void p384_felem_reduce(felem out, const widefelem in);
# if defined(_ARCH_PPC64)
# include "crypto/ppc_arch.h"
@ -695,6 +709,7 @@ static void felem_select(void)
if ((OPENSSL_ppccap_P & PPC_MADD300) && (OPENSSL_ppccap_P & PPC_ALTIVEC)) {
felem_square_p = p384_felem_square;
felem_mul_p = p384_felem_mul;
felem_reduce_p = p384_felem_reduce;
return;
}
@ -703,6 +718,7 @@ static void felem_select(void)
/* Default */
felem_square_p = felem_square_ref;
felem_mul_p = felem_mul_ref;
felem_reduce_p = p384_felem_reduce;
}
static void felem_square_wrapper(widefelem out, const felem in)
@ -719,10 +735,17 @@ static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2)
# define felem_square felem_square_p
# define felem_mul felem_mul_p
# define felem_reduce felem_reduce_p
void p384_felem_square_reduce(felem out, const felem in);
void p384_felem_mul_reduce(felem out, const felem in1, const felem in2);
# define felem_square_reduce p384_felem_square_reduce
# define felem_mul_reduce p384_felem_mul_reduce
#else
# define felem_square felem_square_ref
# define felem_mul felem_mul_ref
#endif
# define felem_reduce felem_reduce_ref
static ossl_inline void felem_square_reduce(felem out, const felem in)
{
@ -739,6 +762,7 @@ static ossl_inline void felem_mul_reduce(felem out, const felem in1, const felem
felem_mul(tmp, in1, in2);
felem_reduce(out, tmp);
}
#endif
/*-
* felem_inv calculates |out| = |in|^{-1}