Skip to content

Commit ccff823

Browse files
committed
fix truncation of hash input with order bit size not multiple of 8
all curves we have defined, with exception of NIST P-521, have bit length of order that's multiple of 8, and there are no hashes that are longer than 512 bits, so NIST P-521 is not affected either, but do fix this issue in case user provides raw input longer than 512 bits or uses custom curves
1 parent 73f3d3e commit ccff823

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/ecdsa/keys.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
from .numbertheory import square_root_mod_prime, SquareRootError
7878
from .ecdsa import RSZeroError
7979
from .util import string_to_number, number_to_string, randrange
80-
from .util import sigencode_string, sigdecode_string
80+
from .util import sigencode_string, sigdecode_string, bit_length
8181
from .util import (
8282
oid_ecPublicKey,
8383
encoded_oid_ecPublicKey,
@@ -694,14 +694,28 @@ def verify_digest(
694694
# signature doesn't have to be a bytes-like-object so don't normalise
695695
# it, the decoders will do that
696696
digest = normalise_bytes(digest)
697-
if allow_truncate:
698-
digest = digest[: self.curve.baselen]
699-
if len(digest) > self.curve.baselen:
697+
if not allow_truncate and len(digest) > self.curve.baselen:
700698
raise BadDigestError(
701699
"this curve (%s) is too short "
702700
"for your digest (%d)" % (self.curve.name, 8 * len(digest))
703701
)
704702
number = string_to_number(digest)
703+
if allow_truncate:
704+
max_length = bit_length(self.curve.order)
705+
# we don't use bit_length(number) as that truncates leading zeros
706+
length = len(digest) * 8
707+
708+
# See NIST FIPS 186-4:
709+
#
710+
# When the length of the output of the hash function is greater
711+
# than N (i.e., the bit length of q), then the leftmost N bits of
712+
# the hash function output block shall be used in any calculation
713+
# using the hash function output during the generation or
714+
# verification of a digital signature.
715+
#
716+
# as such, we need to shift-out the low-order bits:
717+
number >>= max(0, length - max_length)
718+
705719
try:
706720
r, s = sigdecode(signature, self.pubkey.order)
707721
except (der.UnexpectedDER, MalformedSignature) as e:

0 commit comments

Comments
 (0)