summaryrefslogtreecommitdiffstats
path: root/crypto/bn
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2022-06-09 16:20:05 +0200
committerTomas Mraz <tomas@openssl.org>2022-06-16 15:22:35 +0200
commit6d702cebfce3ffd9d8c0cb2af80a987d3288e7a3 (patch)
treeed3f3a084d21568c6b3853828e39ddaed21a60be /crypto/bn
parent0ae365e1f80648f4c52aa3ac9bbc279b6192b23e (diff)
Add an extra reduction step to RSAZ mod_exp implementations
Inspired by BoringSSL fix by David Benjamin. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18510)
Diffstat (limited to 'crypto/bn')
-rw-r--r--crypto/bn/rsaz_exp.c8
-rw-r--r--crypto/bn/rsaz_exp.h23
-rw-r--r--crypto/bn/rsaz_exp_x2.c3
3 files changed, 34 insertions, 0 deletions
diff --git a/crypto/bn/rsaz_exp.c b/crypto/bn/rsaz_exp.c
index 2dbcb88ac3..e44eae43be 100644
--- a/crypto/bn/rsaz_exp.c
+++ b/crypto/bn/rsaz_exp.c
@@ -66,6 +66,7 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
unsigned char *R2 = table_s; /* borrow */
int index;
int wvalue;
+ BN_ULONG tmp[16];
if ((((size_t)p_str & 4095) + 320) >> 12) {
result = p_str;
@@ -237,7 +238,10 @@ void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
rsaz_1024_red2norm_avx2(result_norm, result);
+ bn_reduce_once_in_place(result_norm, /*carry=*/0, m_norm, tmp, 16);
+
OPENSSL_cleanse(storage, sizeof(storage));
+ OPENSSL_cleanse(tmp, sizeof(tmp));
}
/*
@@ -266,6 +270,7 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
unsigned char *p_str = (unsigned char *)exponent;
int index;
unsigned int wvalue;
+ BN_ULONG tmp[8];
/* table[0] = 1_inv */
temp[0] = 0 - m[0];
@@ -309,7 +314,10 @@ void RSAZ_512_mod_exp(BN_ULONG result[8],
/* from Montgomery */
rsaz_512_mul_by_one(result, temp, m, k0);
+ bn_reduce_once_in_place(result, /*carry=*/0, m, tmp, 8);
+
OPENSSL_cleanse(storage, sizeof(storage));
+ OPENSSL_cleanse(tmp, sizeof(tmp));
}
#endif
diff --git a/crypto/bn/rsaz_exp.h b/crypto/bn/rsaz_exp.h
index b4fd3cbbba..45dc9cc197 100644
--- a/crypto/bn/rsaz_exp.h
+++ b/crypto/bn/rsaz_exp.h
@@ -22,6 +22,8 @@
# define RSAZ_ENABLED
# include <openssl/bn.h>
+# include "internal/constant_time.h"
+# include "bn_local.h"
void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16],
const BN_ULONG base_norm[16],
@@ -52,6 +54,27 @@ int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1,
BN_ULONG k0_2,
int factor_size);
+static ossl_inline void bn_select_words(BN_ULONG *r, BN_ULONG mask,
+ const BN_ULONG *a,
+ const BN_ULONG *b, size_t num)
+{
+ size_t i;
+
+ for (i = 0; i < num; i++) {
+ r[i] = constant_time_select_64(mask, a[i], b[i]);
+ }
+}
+
+static ossl_inline BN_ULONG bn_reduce_once_in_place(BN_ULONG *r,
+ BN_ULONG carry,
+ const BN_ULONG *m,
+ BN_ULONG *tmp, size_t num)
+{
+ carry -= bn_sub_words(tmp, r, m, num);
+ bn_select_words(r, carry, r /* tmp < 0 */, tmp /* tmp >= 0 */, num);
+ return carry;
+}
+
# endif
#endif
diff --git a/crypto/bn/rsaz_exp_x2.c b/crypto/bn/rsaz_exp_x2.c
index 9969d45e40..6b04486e3f 100644
--- a/crypto/bn/rsaz_exp_x2.c
+++ b/crypto/bn/rsaz_exp_x2.c
@@ -257,6 +257,9 @@ int ossl_rsaz_mod_exp_avx512_x2(BN_ULONG *res1,
from_words52(res1, factor_size, rr1_red);
from_words52(res2, factor_size, rr2_red);
+ bn_reduce_once_in_place(res1, /*carry=*/0, m1, storage, factor_size);
+ bn_reduce_once_in_place(res2, /*carry=*/0, m2, storage, factor_size);
+
err:
if (storage != NULL) {
OPENSSL_cleanse(storage, storage_len_bytes);