Fixed UB(arithmetics on uninit values) in cmovs
This commit is contained in:
parent
3a6fd7f636
commit
a39c2b09de
|
@ -14,7 +14,7 @@
|
|||
|
||||
/* This is like `ECMULT_TABLE_GET_GE` but is constant time */
|
||||
#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \
|
||||
int m; \
|
||||
int m = 0; \
|
||||
/* Extract the sign-bit for a constant time absolute-value. */ \
|
||||
int mask = (n) >> (sizeof(n) * CHAR_BIT - 1); \
|
||||
int abs_n = ((n) + mask) ^ mask; \
|
||||
|
@ -25,7 +25,11 @@
|
|||
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \
|
||||
VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \
|
||||
VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \
|
||||
for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \
|
||||
/* Unconditionally set r->x = (pre)[m].x. r->y = (pre)[m].y. because it's either the correct one \
|
||||
* or will get replaced in the later iterations, this is needed to make sure `r` is initialized. */ \
|
||||
(r)->x = (pre)[m].x; \
|
||||
(r)->y = (pre)[m].y; \
|
||||
for (m = 1; m < ECMULT_TABLE_SIZE(w); m++) { \
|
||||
/* This loop is used to avoid secret data in array indices. See
|
||||
* the comment in ecmult_gen_impl.h for rationale. */ \
|
||||
secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \
|
||||
|
|
|
@ -125,10 +125,10 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe
|
|||
/** Convert a field element back from the storage type. */
|
||||
static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a);
|
||||
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
|
||||
static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag);
|
||||
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
|
||||
static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
|
||||
|
||||
#endif /* SECP256K1_FIELD_H */
|
||||
|
|
|
@ -132,7 +132,7 @@ static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge
|
|||
/** Convert a group element back from the storage type. */
|
||||
static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a);
|
||||
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
|
||||
static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag);
|
||||
|
||||
/** Rescale a jacobian point by b which must be non-zero. Constant-time. */
|
||||
|
|
|
@ -111,7 +111,7 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar
|
|||
/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */
|
||||
static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift);
|
||||
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
|
||||
static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag);
|
||||
|
||||
#endif /* SECP256K1_SCALAR_H */
|
||||
|
|
|
@ -468,7 +468,8 @@ const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function
|
|||
const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979;
|
||||
|
||||
int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) {
|
||||
secp256k1_scalar r, s;
|
||||
/* Default initialization here is important so we won't pass uninit values to the cmov in the end */
|
||||
secp256k1_scalar r = secp256k1_scalar_zero, s = secp256k1_scalar_zero;
|
||||
secp256k1_scalar sec, non, msg;
|
||||
int ret = 0;
|
||||
int is_sec_valid;
|
||||
|
|
Loading…
Reference in New Issue