mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Merge pull request #7020 from SparkiDev/ecc_gen_k_by_reject
ECC: generate values in range of order by rejection
This commit is contained in:
@ -92,6 +92,12 @@ Possible ECC enable options:
|
||||
* Enables implementations that protect data that is in
|
||||
* encrypted memory.
|
||||
* default: off
|
||||
* WOLFSSL_ECC_GEN_REJECT_SAMPLING
|
||||
* Enables generation of scalar (private key and ECDSA
|
||||
* nonce) to be performed using reject sampling algorithm.
|
||||
* Use this when CPU state can be closely observed by
|
||||
* attacker.
|
||||
* default: off
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -5135,6 +5141,7 @@ int wc_ecc_point_is_at_infinity(ecc_point* p)
|
||||
int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
|
||||
{
|
||||
#ifndef WC_NO_RNG
|
||||
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
|
||||
int err;
|
||||
byte buf[ECC_MAXSIZE_GEN];
|
||||
|
||||
@ -5176,6 +5183,54 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
|
||||
#endif
|
||||
|
||||
return err;
|
||||
#else
|
||||
int err;
|
||||
byte buf[ECC_MAXSIZE_GEN];
|
||||
int bits;
|
||||
|
||||
if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
|
||||
(k == NULL) || (order == NULL)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Get actual bit count of order. */
|
||||
bits = mp_count_bits(order);
|
||||
size = (bits + 7) >> 3;
|
||||
|
||||
/* generate number in range of order through rejection sampling. */
|
||||
/* see section A.2.2 and A.4.2 in FIPS 186-5 */
|
||||
do {
|
||||
/* A.2.2 step 3: make up random string */
|
||||
err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
|
||||
#endif
|
||||
/* Generated multiple of 8 bits but now make it size of order. */
|
||||
if ((bits & 0x7) > 0) {
|
||||
buf[0] &= (1 << (bits & 0x7)) - 1;
|
||||
}
|
||||
|
||||
/* A.2.2 step 4: convert to integer. */
|
||||
/* A.4.2 step 3: Convert the bit string to integer x. */
|
||||
if (err == 0) {
|
||||
err = mp_read_unsigned_bin(k, buf, (word32)size);
|
||||
}
|
||||
|
||||
/* A.4.2 step 4, 5: x must be in range [1, n-1] */
|
||||
if ((err == MP_OKAY) && !mp_iszero(k) &&
|
||||
(mp_cmp_ct(k, order, order->used) == MP_LT)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (err == MP_OKAY);
|
||||
|
||||
ForceZero(buf, ECC_MAXSIZE_GEN);
|
||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||
wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
#endif
|
||||
#else
|
||||
(void)rng;
|
||||
(void)size;
|
||||
|
@ -4780,7 +4780,7 @@ static void _sp_mont_setup(const sp_int* m, sp_int_digit* rho);
|
||||
|
||||
/* Determine when mp_add_d is required. */
|
||||
#if !defined(NO_PWDBASED) || defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || \
|
||||
!defined(NO_DSA) || (defined(HAVE_ECC) && defined(HAVE_COMP_KEY)) || \
|
||||
!defined(NO_DSA) || defined(HAVE_ECC) || \
|
||||
(!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
|
||||
defined(OPENSSL_EXTRA)
|
||||
#define WOLFSSL_SP_ADD_D
|
||||
@ -5327,8 +5327,8 @@ int sp_abs(const sp_int* a, sp_int* r)
|
||||
(!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY))
|
||||
/* Compare absolute value of two multi-precision numbers.
|
||||
*
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
*
|
||||
* @return MP_GT when a is greater than b.
|
||||
* @return MP_LT when a is less than b.
|
||||
@ -5373,8 +5373,8 @@ static int _sp_cmp_abs(const sp_int* a, const sp_int* b)
|
||||
*
|
||||
* Pointers are compared such that NULL is less than not NULL.
|
||||
*
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
*
|
||||
* @return MP_GT when a is greater than b.
|
||||
* @return MP_LT when a is less than b.
|
||||
@ -5413,8 +5413,8 @@ int sp_cmp_mag(const sp_int* a, const sp_int* b)
|
||||
*
|
||||
* Assumes a and b are not NULL.
|
||||
*
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
*
|
||||
* @return MP_GT when a is greater than b.
|
||||
* @return MP_LT when a is less than b.
|
||||
@ -5457,8 +5457,8 @@ static int _sp_cmp(const sp_int* a, const sp_int* b)
|
||||
*
|
||||
* Pointers are compared such that NULL is less than not NULL.
|
||||
*
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
*
|
||||
* @return MP_GT when a is greater than b.
|
||||
* @return MP_LT when a is less than b.
|
||||
@ -5490,6 +5490,80 @@ int sp_cmp(const sp_int* a, const sp_int* b)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ECC) && !defined(WC_NO_RNG) && \
|
||||
defined(WOLFSSL_ECC_GEN_REJECT_SAMPLING)
|
||||
/* Compare two multi-precision numbers in constant time.
|
||||
*
|
||||
* Assumes a and b are not NULL.
|
||||
* Assumes a and b are positive.
|
||||
*
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
* @param [in] n Number of digits to compare.
|
||||
*
|
||||
* @return MP_GT when a is greater than b.
|
||||
* @return MP_LT when a is less than b.
|
||||
* @return MP_EQ when a is equals b.
|
||||
*/
|
||||
static int _sp_cmp_ct(const sp_int* a, const sp_int* b, unsigned int n)
|
||||
{
|
||||
int ret = MP_EQ;
|
||||
int i;
|
||||
int mask = -1;
|
||||
|
||||
for (i = n - 1; i >= 0; i--) {
|
||||
sp_int_digit ad = a->dp[i] & ((sp_int_digit)0 - (i < (int)a->used));
|
||||
sp_int_digit bd = b->dp[i] & ((sp_int_digit)0 - (i < (int)b->used));
|
||||
|
||||
ret |= mask & ((0 - (ad < bd)) & MP_LT);
|
||||
mask &= 0 - (ret == MP_EQ);
|
||||
ret |= mask & ((0 - (ad > bd)) & MP_GT);
|
||||
mask &= 0 - (ret == MP_EQ);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Compare two multi-precision numbers in constant time.
|
||||
*
|
||||
* Pointers are compared such that NULL is less than not NULL.
|
||||
* Assumes a and b are positive.
|
||||
* Assumes a and b have n digits set at sometime.
|
||||
*
|
||||
* @param [in] a SP integer.
|
||||
* @param [in] b SP integer.
|
||||
* @param [in] n Number of digits to compare.
|
||||
*
|
||||
* @return MP_GT when a is greater than b.
|
||||
* @return MP_LT when a is less than b.
|
||||
* @return MP_EQ when a is equals b.
|
||||
*/
|
||||
int sp_cmp_ct(const sp_int* a, const sp_int* b, unsigned int n)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Check pointers first. Both NULL returns equal. */
|
||||
if (a == b) {
|
||||
ret = MP_EQ;
|
||||
}
|
||||
/* Nothing is smaller than something. */
|
||||
else if (a == NULL) {
|
||||
ret = MP_LT;
|
||||
}
|
||||
/* Something is larger than nothing. */
|
||||
else if (b == NULL) {
|
||||
ret = MP_GT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Compare values - a and b are not NULL. */
|
||||
ret = _sp_cmp_ct(a, b, n);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_ECC && !WC_NO_RNG && WOLFSSL_ECC_GEN_REJECT_SAMPLING */
|
||||
|
||||
/*************************
|
||||
* Bit check/set functions
|
||||
*************************/
|
||||
@ -7673,10 +7747,6 @@ int sp_submod(const sp_int* a, const sp_int* b, const sp_int* m, sp_int* r)
|
||||
}
|
||||
#endif /* WOLFSSL_SP_MATH_ALL */
|
||||
|
||||
#if (defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)) || \
|
||||
(defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) || \
|
||||
defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE) || \
|
||||
defined(OPENSSL_ALL))
|
||||
/* Constant time clamping/
|
||||
*
|
||||
* @param [in, out] a SP integer to clamp.
|
||||
@ -7693,7 +7763,6 @@ static void sp_clamp_ct(sp_int* a)
|
||||
}
|
||||
a->used = used;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
|
||||
/* Add two value and reduce: r = (a + b) % m
|
||||
@ -14362,7 +14431,8 @@ int sp_div_2d(const sp_int* a, int e, sp_int* r, sp_int* rem)
|
||||
}
|
||||
#endif /* WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY */
|
||||
|
||||
#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
|
||||
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
|
||||
defined(HAVE_ECC)
|
||||
/* The bottom e bits: r = a & ((1 << e) - 1)
|
||||
*
|
||||
* @param [in] a SP integer to reduce.
|
||||
@ -14432,7 +14502,7 @@ int sp_mod_2d(const sp_int* a, int e, sp_int* r)
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY */
|
||||
#endif /* (WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY)) || HAVE_ECC */
|
||||
|
||||
#if (defined(WOLFSSL_SP_MATH_ALL) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \
|
||||
!defined(NO_DH))) || defined(OPENSSL_ALL)
|
||||
@ -17780,7 +17850,7 @@ int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz)
|
||||
#endif /* LITTLE_ENDIAN_ORDER */
|
||||
}
|
||||
#endif
|
||||
sp_clamp(a);
|
||||
sp_clamp_ct(a);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -4863,6 +4863,12 @@ int mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d)
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
int mp_mod_2d(fp_int* a, int b, fp_int* c)
|
||||
{
|
||||
fp_mod_2d(a, b, c);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/* copy (src = a) to (dst = b) */
|
||||
void fp_copy(const fp_int *a, fp_int *b)
|
||||
{
|
||||
|
@ -46174,6 +46174,67 @@ static wc_test_ret_t mp_test_cmp(mp_int* a, mp_int* b)
|
||||
return WC_TEST_RET_ENC_NC;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ECC) && !defined(WC_NO_RNG) && \
|
||||
defined(WOLFSSL_ECC_GEN_REJECT_SAMPLING)
|
||||
mp_zero(a);
|
||||
mp_zero(b);
|
||||
ret = mp_cmp_ct(a, b, 1);
|
||||
if (ret != MP_EQ)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(a, a, a->used);
|
||||
if (ret != MP_EQ)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
#ifdef WOLFSSL_SP_MATH_ALL
|
||||
ret = mp_cmp_ct(a, NULL, a->used);
|
||||
if (ret != MP_GT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(NULL, a, a->used);
|
||||
if (ret != MP_LT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
#endif
|
||||
|
||||
mp_read_radix(a, "1", MP_RADIX_HEX);
|
||||
ret = mp_cmp_ct(a, b, 1);
|
||||
if (ret != MP_GT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(b, a, 1);
|
||||
if (ret != MP_LT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
mp_read_radix(a, "0123456789abcdef0123456789abcdef", MP_RADIX_HEX);
|
||||
ret = mp_cmp_ct(a, b, a->used);
|
||||
if (ret != MP_GT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(b, a, a->used);
|
||||
if (ret != MP_LT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
mp_read_radix(b, "1123456789abcdef0123456789abcdef", MP_RADIX_HEX);
|
||||
ret = mp_cmp_ct(b, a, a->used);
|
||||
if (ret != MP_GT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(a, b, a->used);
|
||||
if (ret != MP_LT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
mp_read_radix(b, "0123456789abcdef0123456789abcdf0", MP_RADIX_HEX);
|
||||
ret = mp_cmp_ct(b, a, a->used);
|
||||
if (ret != MP_GT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(a, b, a->used);
|
||||
if (ret != MP_LT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
mp_read_radix(b, "0123456789abcdf0", MP_RADIX_HEX);
|
||||
ret = mp_cmp_ct(a, b, a->used);
|
||||
if (ret != MP_GT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = mp_cmp_ct(b, a, a->used);
|
||||
if (ret != MP_LT)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -344,6 +344,7 @@ int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c);
|
||||
MP_API int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
|
||||
MP_API int mp_cmp_mag (mp_int * a, mp_int * b);
|
||||
MP_API int mp_cmp (mp_int * a, mp_int * b);
|
||||
#define mp_cmp_ct(a, b, n) mp_cmp(a, b)
|
||||
MP_API int mp_cmp_d(mp_int * a, mp_digit b);
|
||||
MP_API int mp_set (mp_int * a, mp_digit b);
|
||||
MP_API int mp_is_bit_set (mp_int * a, mp_digit b);
|
||||
|
@ -945,6 +945,7 @@ MP_API int sp_abs(const sp_int* a, sp_int* r);
|
||||
MP_API int sp_cmp_mag(const sp_int* a, const sp_int* b);
|
||||
#endif
|
||||
MP_API int sp_cmp(const sp_int* a, const sp_int* b);
|
||||
MP_API int sp_cmp_ct(const sp_int* a, const sp_int* b, unsigned int n);
|
||||
|
||||
MP_API int sp_is_bit_set(const sp_int* a, unsigned int b);
|
||||
MP_API int sp_count_bits(const sp_int* a);
|
||||
@ -1030,9 +1031,11 @@ MP_API int sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m,
|
||||
|
||||
#if defined(WOLFSSL_SP_MATH_ALL) || defined(OPENSSL_ALL)
|
||||
MP_API int sp_div_2d(const sp_int* a, int e, sp_int* r, sp_int* rem);
|
||||
MP_API int sp_mod_2d(const sp_int* a, int e, sp_int* r);
|
||||
MP_API int sp_mul_2d(const sp_int* a, int e, sp_int* r);
|
||||
#endif
|
||||
#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) || defined(OPENSSL_ALL)
|
||||
MP_API int sp_mod_2d(const sp_int* a, int e, sp_int* r);
|
||||
#endif
|
||||
|
||||
MP_API int sp_sqr(const sp_int* a, sp_int* r);
|
||||
MP_API int sp_sqrmod(const sp_int* a, const sp_int* m, sp_int* r);
|
||||
@ -1119,6 +1122,7 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp);
|
||||
#define mp_cond_swap_ct_ex sp_cond_swap_ct_ex
|
||||
#define mp_cmp_mag sp_cmp_mag
|
||||
#define mp_cmp sp_cmp
|
||||
#define mp_cmp_ct sp_cmp_ct
|
||||
#define mp_count_bits sp_count_bits
|
||||
#define mp_cnt_lsb sp_cnt_lsb
|
||||
#define mp_leading_bit sp_leading_bit
|
||||
|
@ -838,6 +838,7 @@ MP_API int mp_2expt(mp_int* a, int b);
|
||||
MP_API int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
|
||||
|
||||
MP_API int mp_cmp(mp_int *a, mp_int *b);
|
||||
#define mp_cmp_ct(a, b, n) mp_cmp(a, b)
|
||||
MP_API int mp_cmp_d(mp_int *a, mp_digit b);
|
||||
|
||||
MP_API int mp_unsigned_bin_size(const mp_int * a);
|
||||
@ -908,6 +909,7 @@ MP_API int mp_cond_swap_ct(mp_int* a, mp_int* b, int c, int m);
|
||||
|
||||
MP_API int mp_cnt_lsb(fp_int *a);
|
||||
MP_API int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);
|
||||
MP_API int mp_mod_2d(fp_int *a, int b, fp_int *c);
|
||||
MP_API int mp_mod_d(fp_int* a, fp_digit b, fp_digit* c);
|
||||
MP_API int mp_lshd (mp_int * a, int b);
|
||||
MP_API int mp_abs(mp_int* a, mp_int* b);
|
||||
|
Reference in New Issue
Block a user