Use bn_rshift_words for the ECDSA bit-shift.
May as well use it. Also avoid an overflow with digest_len if someone asks to sign a truly enormous digest. Change-Id: Ia0a53007a496f9c7cadd44b1020ec2774b310936 Reviewed-on: https://boringssl-review.googlesource.com/26966 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
0645c05f5e
commit
2257e8f3bf
@ -370,6 +370,11 @@ int bn_odd_number_is_obviously_composite(const BIGNUM *bn);
|
|||||||
// bn_rshift1_words sets |r| to |a| >> 1, where both arrays are |num| bits wide.
|
// bn_rshift1_words sets |r| to |a| >> 1, where both arrays are |num| bits wide.
|
||||||
void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num);
|
void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num);
|
||||||
|
|
||||||
|
// bn_rshift_words sets |r| to |a| >> |shift|, where both arrays are |num| bits
|
||||||
|
// wide.
|
||||||
|
void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift,
|
||||||
|
size_t num);
|
||||||
|
|
||||||
// bn_rshift_secret_shift behaves like |BN_rshift| but runs in time independent
|
// bn_rshift_secret_shift behaves like |BN_rshift| but runs in time independent
|
||||||
// of both |a| and |n|.
|
// of both |a| and |n|.
|
||||||
OPENSSL_EXPORT int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a,
|
OPENSSL_EXPORT int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a,
|
||||||
|
@ -133,8 +133,8 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift,
|
void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift,
|
||||||
size_t num) {
|
size_t num) {
|
||||||
unsigned shift_bits = shift % BN_BITS2;
|
unsigned shift_bits = shift % BN_BITS2;
|
||||||
size_t shift_words = shift / BN_BITS2;
|
size_t shift_words = shift / BN_BITS2;
|
||||||
if (shift_words >= num) {
|
if (shift_words >= num) {
|
||||||
|
@ -116,22 +116,18 @@ static void digest_to_scalar(const EC_GROUP *group, EC_LOOSE_SCALAR *out,
|
|||||||
const BIGNUM *order = &group->order;
|
const BIGNUM *order = &group->order;
|
||||||
size_t num_bits = BN_num_bits(order);
|
size_t num_bits = BN_num_bits(order);
|
||||||
// Need to truncate digest if it is too long: first truncate whole bytes.
|
// Need to truncate digest if it is too long: first truncate whole bytes.
|
||||||
if (8 * digest_len > num_bits) {
|
size_t num_bytes = (num_bits + 7) / 8;
|
||||||
digest_len = (num_bits + 7) / 8;
|
if (digest_len > num_bytes) {
|
||||||
|
digest_len = num_bytes;
|
||||||
}
|
}
|
||||||
OPENSSL_memset(out, 0, sizeof(EC_SCALAR));
|
OPENSSL_memset(out, 0, sizeof(EC_SCALAR));
|
||||||
for (size_t i = 0; i < digest_len; i++) {
|
for (size_t i = 0; i < digest_len; i++) {
|
||||||
out->bytes[i] = digest[digest_len - 1 - i];
|
out->bytes[i] = digest[digest_len - 1 - i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If still too long truncate remaining bits with a shift
|
// If it is still too long, truncate remaining bits with a shift.
|
||||||
if (8 * digest_len > num_bits) {
|
if (8 * digest_len > num_bits) {
|
||||||
size_t shift = 8 - (num_bits & 0x7);
|
bn_rshift_words(out->words, out->words, 8 - (num_bits & 0x7), order->width);
|
||||||
for (int i = 0; i < order->width - 1; i++) {
|
|
||||||
out->words[i] =
|
|
||||||
(out->words[i] >> shift) | (out->words[i + 1] << (BN_BITS2 - shift));
|
|
||||||
}
|
|
||||||
out->words[order->width - 1] >>= shift;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user