summaryrefslogtreecommitdiff
path: root/mpi
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2021-04-03 19:59:47 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2021-04-09 17:22:27 +0300
commit1266f5bb02b7f76f2e4697ecfb85ef19c2ae04a9 (patch)
treecdd1262c99d0a7bc637f22b8eb014e52d389a5d2 /mpi
parent840713de1a685920b6b1e1379902d545eccc74cf (diff)
downloadlibgcrypt-1266f5bb02b7f76f2e4697ecfb85ef19c2ae04a9.tar.gz
mpi: harden swap_cond functions against EM leakage
* mpi/mpih-const-time.c (vzero, vone): New. (_gcry_mpih_swap_cond): Use two masks for selecting output. * mpi/mpiutil.c (vzero, vone): New. (_gcry_mpi_swap_cond): Use to masks for selecting output. -- GnuPG-bug-id: T5330 Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'mpi')
-rw-r--r--mpi/mpih-const-time.c17
-rw-r--r--mpi/mpiutil.c34
2 files changed, 35 insertions, 16 deletions
diff --git a/mpi/mpih-const-time.c b/mpi/mpih-const-time.c
index 96899505..8b78aabc 100644
--- a/mpi/mpih-const-time.c
+++ b/mpi/mpih-const-time.c
@@ -25,6 +25,12 @@
#define A_LIMB_1 ((mpi_limb_t)1)
+/* These variables are used to generate masks from conditional operation
+ * flag parameters. Use of volatile prevents compiler optimizations from
+ * converting AND-masking to conditional branches. */
+static volatile mpi_limb_t vzero = 0;
+static volatile mpi_limb_t vone = 1;
+
/*
* W = U when OP_ENABLED=1
* otherwise, W keeps old value
@@ -112,14 +118,15 @@ _gcry_mpih_swap_cond (mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t usize,
unsigned long op_enable)
{
mpi_size_t i;
- mpi_limb_t mask = ((mpi_limb_t)0) - op_enable;
+ mpi_limb_t mask1 = vzero - op_enable;
+ mpi_limb_t mask2 = op_enable - vone;
for (i = 0; i < usize; i++)
{
- mpi_limb_t x = mask & (up[i] ^ vp[i]);
-
- up[i] = up[i] ^ x;
- vp[i] = vp[i] ^ x;
+ mpi_limb_t u = up[i];
+ mpi_limb_t v = vp[i];
+ up[i] = (u & mask2) | (v & mask1);
+ vp[i] = (u & mask1) | (v & mask2);
}
}
diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c
index 86b8361e..a1ac1c43 100644
--- a/mpi/mpiutil.c
+++ b/mpi/mpiutil.c
@@ -46,6 +46,11 @@
/* Constants allocated right away at startup. */
static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
+/* These variables are used to generate masks from conditional operation
+ * flag parameters. Use of volatile prevents compiler optimizations from
+ * converting AND-masking to conditional branches. */
+static volatile mpi_limb_t vzero = 0;
+static volatile mpi_limb_t vone = 1;
const char *
@@ -608,8 +613,12 @@ _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
{
mpi_size_t i;
mpi_size_t nlimbs;
- mpi_limb_t mask = ((mpi_limb_t)0) - swap;
- mpi_limb_t x;
+ mpi_limb_t mask1 = vzero - swap;
+ mpi_limb_t mask2 = swap - vone;
+ mpi_limb_t *ua = a->d;
+ mpi_limb_t *ub = b->d;
+ mpi_limb_t xa;
+ mpi_limb_t xb;
if (a->alloced > b->alloced)
nlimbs = b->alloced;
@@ -620,18 +629,21 @@ _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
for (i = 0; i < nlimbs; i++)
{
- x = mask & (a->d[i] ^ b->d[i]);
- a->d[i] = a->d[i] ^ x;
- b->d[i] = b->d[i] ^ x;
+ xa = ua[i];
+ xb = ub[i];
+ ua[i] = (xa & mask2) | (xb & mask1);
+ ub[i] = (xa & mask1) | (xb & mask2);
}
- x = mask & (a->nlimbs ^ b->nlimbs);
- a->nlimbs = a->nlimbs ^ x;
- b->nlimbs = b->nlimbs ^ x;
+ xa = a->nlimbs;
+ xb = b->nlimbs;
+ a->nlimbs = (xa & mask2) | (xb & mask1);
+ b->nlimbs = (xa & mask1) | (xb & mask2);
- x = mask & (a->sign ^ b->sign);
- a->sign = a->sign ^ x;
- b->sign = b->sign ^ x;
+ xa = a->sign;
+ xb = b->sign;
+ a->sign = (xa & mask2) | (xb & mask1);
+ b->sign = (xa & mask1) | (xb & mask2);
}