* 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.kivili...@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 _______________________________________________ Gcrypt-devel mailing list Gcrypt-devel@gnupg.org https://lists.gnupg.org/mailman/listinfo/gcrypt-devel