[PATCH 1/2] const-time: add functions for generating masks from 0/1 input

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu Nov 2 20:27:49 CET 2023


* mpi/ec-nist.c (ct_limb_gen_mask, ct_limb_gen_inv_mask): New.
(_gcry_mpi_ec_nist192_mod, _gcry_mpi_ec_nist224_mod)
(_gcry_mpi_ec_nist256_mod, _gcry_mpi_ec_nist384_mod): Use mask generating
functions.
* mpi/mpih-const-time.c (ct_limb_gen_mask, ct_limb_gen_inv_mask): New.
(_gcry_mpih_set_cond, _gcry_mpih_add_n_cond, _gcry_mpih_sub_n_cond)
(_gcry_mpih_sub_n_cond, _gcry_mpih_swap_cond): Use mask generating
functions.
* mpi/mpiutil.c (ct_limb_gen_mask, ct_limb_gen_inv_mask): New.
(_gcry_mpi_set_cond, _gcry_mpi_swap_cond): Use mask generating functions.
* src/const-time.h (DEFINE_CT_TYPE_GEN_MASK, ct_uintptr_gen_mask)
(ct_ulong_gen_mask, DEFINE_CT_TYPE_GEN_INV_MASK, ct_uintptr_gen_inv_mask)
(ct_ulong_gen_inv_mask): New.
(DEFINE_CT_TYPE_SELECT_FUNC): Use mask generating functions.
* src/const-time.c (_gcry_ct_memmov_cond): Use mask generating functions.
--

Provide functions for generating mask for constant time operations.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 mpi/ec-nist.c         | 22 ++++++++++--------
 mpi/mpih-const-time.c | 24 +++++++++++---------
 mpi/mpiutil.c         | 12 ++++++----
 src/const-time.c      |  4 ++--
 src/const-time.h      | 52 +++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 87 insertions(+), 27 deletions(-)

diff --git a/mpi/ec-nist.c b/mpi/ec-nist.c
index 6dfaa1da..f3b3cd66 100644
--- a/mpi/ec-nist.c
+++ b/mpi/ec-nist.c
@@ -35,6 +35,10 @@
 #include "const-time.h"
 
 
+DEFINE_CT_TYPE_GEN_MASK(limb, mpi_limb_t)
+DEFINE_CT_TYPE_GEN_INV_MASK(limb, mpi_limb_t)
+
+
 static inline
 void prefetch(const void *tab, size_t len)
 {
@@ -141,8 +145,8 @@ _gcry_mpi_ec_nist192_mod (gcry_mpi_t w, mpi_ec_t ctx)
 
   s_is_negative = LO32_LIMB64(s[3]) >> 31;
 
-  mask2 = _gcry_ct_vzero - s_is_negative;
-  mask1 = s_is_negative - _gcry_ct_vone;
+  mask2 = ct_limb_gen_mask(s_is_negative);
+  mask1 = ct_limb_gen_inv_mask(s_is_negative);
 
   STORE64_COND(wp, 0, mask2, o[0], mask1, s[0]);
   STORE64_COND(wp, 1, mask2, o[1], mask1, s[1]);
@@ -264,8 +268,8 @@ _gcry_mpi_ec_nist224_mod (gcry_mpi_t w, mpi_ec_t ctx)
 
   s_is_negative = (HI32_LIMB64(s[3]) >> 31);
 
-  mask2 = _gcry_ct_vzero - s_is_negative;
-  mask1 = s_is_negative - _gcry_ct_vone;
+  mask2 = ct_limb_gen_mask(s_is_negative);
+  mask1 = ct_limb_gen_inv_mask(s_is_negative);
 
   STORE64_COND(wp, 0, mask2, d[0], mask1, s[0]);
   STORE64_COND(wp, 1, mask2, d[1], mask1, s[1]);
@@ -493,9 +497,9 @@ _gcry_mpi_ec_nist256_mod (gcry_mpi_t w, mpi_ec_t ctx)
 
   s_is_negative = LO32_LIMB64(s[4]) >> 31;
   d_is_negative = LO32_LIMB64(d[4]) >> 31;
-  mask3 = _gcry_ct_vzero - d_is_negative;
-  mask2 = (_gcry_ct_vzero - s_is_negative) & ~mask3;
-  mask1 = (s_is_negative - _gcry_ct_vone) & ~mask3;
+  mask3 = ct_limb_gen_mask(d_is_negative);
+  mask2 = ct_limb_gen_mask(s_is_negative) & ~mask3;
+  mask1 = ct_limb_gen_inv_mask(s_is_negative) & ~mask3;
 
   s[0] = LIMB_OR64(MASK_AND64(mask2, d[0]), MASK_AND64(mask1, s[0]));
   s[1] = LIMB_OR64(MASK_AND64(mask2, d[1]), MASK_AND64(mask1, s[1]));
@@ -764,8 +768,8 @@ _gcry_mpi_ec_nist384_mod (gcry_mpi_t w, mpi_ec_t ctx)
 	       p_mult[0 + 3][1], p_mult[0 + 3][0]);
 
   s_is_negative = LO32_LIMB64(s[6]) >> 31;
-  mask2 = _gcry_ct_vzero - s_is_negative;
-  mask1 = s_is_negative - _gcry_ct_vone;
+  mask2 = ct_limb_gen_mask(s_is_negative);
+  mask1 = ct_limb_gen_inv_mask(s_is_negative);
 
   STORE64_COND(wp, 0, mask2, d[0], mask1, s[0]);
   STORE64_COND(wp, 1, mask2, d[1], mask1, s[1]);
diff --git a/mpi/mpih-const-time.c b/mpi/mpih-const-time.c
index 3d854e8c..4ebd072d 100644
--- a/mpi/mpih-const-time.c
+++ b/mpi/mpih-const-time.c
@@ -27,6 +27,10 @@
 #define A_LIMB_1 ((mpi_limb_t)1)
 
 
+DEFINE_CT_TYPE_GEN_MASK(limb, mpi_limb_t)
+DEFINE_CT_TYPE_GEN_INV_MASK(limb, mpi_limb_t)
+
+
 /*
  *  W = U when OP_ENABLED=1
  *  otherwise, W keeps old value
@@ -36,8 +40,8 @@ _gcry_mpih_set_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
                      unsigned long op_enable)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - op_enable;
-  mpi_limb_t mask2 = op_enable - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(op_enable);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(op_enable);
   mpi_size_t i;
 
   for (i = 0; i < usize; i++)
@@ -56,8 +60,8 @@ _gcry_mpih_add_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
                        mpi_size_t usize, unsigned long op_enable)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - op_enable;
-  mpi_limb_t mask2 = op_enable - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(op_enable);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(op_enable);
   mpi_size_t i;
   mpi_limb_t cy;
 
@@ -88,8 +92,8 @@ _gcry_mpih_sub_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
                        mpi_size_t usize, unsigned long op_enable)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - op_enable;
-  mpi_limb_t mask2 = op_enable - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(op_enable);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(op_enable);
   mpi_size_t i;
   mpi_limb_t cy;
 
@@ -120,8 +124,8 @@ _gcry_mpih_swap_cond (mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t usize,
                       unsigned long op_enable)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - op_enable;
-  mpi_limb_t mask2 = op_enable - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(op_enable);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(op_enable);
   mpi_size_t i;
 
   for (i = 0; i < usize; i++)
@@ -143,8 +147,8 @@ _gcry_mpih_abs_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
                      unsigned long op_enable)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - op_enable;
-  mpi_limb_t mask2 = op_enable - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(op_enable);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(op_enable);
   mpi_limb_t cy = op_enable;
   mpi_size_t i;
 
diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c
index f7506718..954bb1ea 100644
--- a/mpi/mpiutil.c
+++ b/mpi/mpiutil.c
@@ -30,6 +30,10 @@
 #include "const-time.h"
 
 
+DEFINE_CT_TYPE_GEN_MASK(limb, mpi_limb_t)
+DEFINE_CT_TYPE_GEN_INV_MASK(limb, mpi_limb_t)
+
+
 #if SIZEOF_UNSIGNED_INT == 2
 # define MY_UINT_MAX 0xffff
 /* (visual check:      0123 ) */
@@ -509,8 +513,8 @@ gcry_mpi_t
 _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - set;
-  mpi_limb_t mask2 = set - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(set);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(set);
   mpi_size_t i;
   mpi_size_t nlimbs = u->alloced;
   mpi_limb_t xu;
@@ -611,8 +615,8 @@ void
 _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  mpi_limb_t mask1 = _gcry_ct_vzero - swap;
-  mpi_limb_t mask2 = swap - _gcry_ct_vone;
+  mpi_limb_t mask1 = ct_limb_gen_mask(swap);
+  mpi_limb_t mask2 = ct_limb_gen_inv_mask(swap);
   mpi_size_t i;
   mpi_size_t nlimbs;
   mpi_limb_t *ua = a->d;
diff --git a/src/const-time.c b/src/const-time.c
index 73bf8b40..55edd979 100644
--- a/src/const-time.c
+++ b/src/const-time.c
@@ -75,8 +75,8 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len,
 		      unsigned long op_enable)
 {
   /* Note: dual mask with AND/OR used for EM leakage mitigation */
-  unsigned char mask1 = _gcry_ct_vzero - op_enable;
-  unsigned char mask2 = op_enable - _gcry_ct_vone;
+  unsigned char mask1 = ct_ulong_gen_mask(op_enable);
+  unsigned char mask2 = ct_ulong_gen_inv_mask(op_enable);
   unsigned char *b_dst = dst;
   const unsigned char *b_src = src;
   size_t i;
diff --git a/src/const-time.h b/src/const-time.h
index e324dcb7..cfb59f9a 100644
--- a/src/const-time.h
+++ b/src/const-time.h
@@ -80,6 +80,54 @@ unsigned int _gcry_ct_not_memequal (const void *b1, const void *b2, size_t len);
    any structure.  */
 unsigned int _gcry_ct_memequal (const void *b1, const void *b2, size_t len);
 
+/*
+ * Return all bits set if A is 1 and return 0 otherwise.
+ */
+#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY
+#  define DEFINE_CT_TYPE_GEN_MASK(name, type) \
+     static inline type \
+     ct_##name##_gen_mask (unsigned long op_enable) \
+     { \
+       type mask = -(type)op_enable; \
+       asm volatile ("\n" :: "r" (mask) : "memory"); \
+       return mask; \
+     }
+#else
+#  define DEFINE_CT_TYPE_GEN_MASK(name, type) \
+     static inline type \
+     ct_##name##_gen_mask (unsigned long op_enable) \
+     { \
+       type mask = (type)_gcry_ct_vzero - (type)op_enable; \
+       return mask; \
+     }
+#endif
+DEFINE_CT_TYPE_GEN_MASK(uintptr, uintptr_t)
+DEFINE_CT_TYPE_GEN_MASK(ulong, unsigned long)
+
+/*
+ * Return all bits set if A is 0 and return 1 otherwise.
+ */
+#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY
+#  define DEFINE_CT_TYPE_GEN_INV_MASK(name, type) \
+     static inline type \
+     ct_##name##_gen_inv_mask (unsigned long op_enable) \
+     { \
+       type mask = (type)op_enable - (type)1; \
+       asm volatile ("\n" :: "r" (mask) : "memory"); \
+       return mask; \
+     }
+#else
+#  define DEFINE_CT_TYPE_GEN_INV_MASK(name, type) \
+     static inline type \
+     ct_##name##_gen_inv_mask (unsigned long op_enable) \
+     { \
+       type mask = (type)op_enable - (type)_gcry_ct_vone; \
+       return mask; \
+     }
+#endif
+DEFINE_CT_TYPE_GEN_INV_MASK(uintptr, uintptr_t)
+DEFINE_CT_TYPE_GEN_INV_MASK(ulong, unsigned long)
+
 /*
  *  Return A when OP_ENABLED=1
  *  otherwise, return B
@@ -88,8 +136,8 @@ unsigned int _gcry_ct_memequal (const void *b1, const void *b2, size_t len);
   static inline type \
   ct_##name##_select (type a, type b, unsigned long op_enable) \
   { \
-    type mask_b = (type)op_enable - (type)_gcry_ct_vone; \
-    type mask_a = (type)_gcry_ct_vzero - (type)op_enable; \
+    type mask_b = ct_##name##_gen_inv_mask(op_enable); \
+    type mask_a = ct_##name##_gen_mask(op_enable); \
     return (mask_a & a) | (mask_b & b); \
   }
 DEFINE_CT_TYPE_SELECT_FUNC(uintptr, uintptr_t)
-- 
2.40.1




More information about the Gcrypt-devel mailing list