|
77 | 77 | from .numbertheory import square_root_mod_prime, SquareRootError |
78 | 78 | from .ecdsa import RSZeroError |
79 | 79 | 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 |
81 | 81 | from .util import ( |
82 | 82 | oid_ecPublicKey, |
83 | 83 | encoded_oid_ecPublicKey, |
@@ -694,14 +694,28 @@ def verify_digest( |
694 | 694 | # signature doesn't have to be a bytes-like-object so don't normalise |
695 | 695 | # it, the decoders will do that |
696 | 696 | 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: |
700 | 698 | raise BadDigestError( |
701 | 699 | "this curve (%s) is too short " |
702 | 700 | "for your digest (%d)" % (self.curve.name, 8 * len(digest)) |
703 | 701 | ) |
704 | 702 | 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 | + |
705 | 719 | try: |
706 | 720 | r, s = sigdecode(signature, self.pubkey.order) |
707 | 721 | except (der.UnexpectedDER, MalformedSignature) as e: |
|
0 commit comments