-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ECDSA verification succeeds when it should fail #981
Comments
Thanks @guidovranken,
What is wrong with the key? When I add a call to
Crypto++ 5.6.2, 8.0 and Master each validate the public key. |
Apologies, I was misreading my debug output. The pubkey is ok but the signature S is larger than the curve order and should be rejected as far as I can tell. |
OK, so it looks like
Tracing back in the call stack leads to
I don't see an easy way around this. @mouse07410, any thoughts? Here's the external checks that can be added to check
|
In ECDSA in general, if the hash size is greater than the P, it's truncated. Usually it's done when the signature is created - but I see no obvious reason why Verify shouldn't do that. Though I'd be less comfortable with truncation on Verify. Haven't checked the code - it should be truncation rather than modular reduction. |
Yeah, it looks like
I wonder if we can safely perform a check that verifies |
The answer to this question appears to be no. Running This is a kind of unexpected result. When I change: const size_t rLen = alg.RLen(params);
ma.m_semisignature.Assign(signature, rLen);
ma.m_s.Decode(signature+rLen, alg.SLen(params)); To: ma.m_semisignature.Assign(signature, rLen);
ma.m_s.Decode(signature+rLen, signatureLength - rLen);
std::cout << " O: " << std::hex << params.GetSubgroupOrder() << std::endl;
std::cout << " S: " << std::hex << ma.m_s << std::endl; Then the result is: O: fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141h
S: 6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31bah So |
Doh... const size_t siglen = verifier.SignatureLength();
uint8_t signature[siglen];
R.Encode(signature + 0, siglen / 2);
S.Encode(signature + (siglen / 2), siglen / 2);
std::cout << "Min size: " << S.MinEncodedSize() << std::endl;
std::cout << "s length: " << siglen / 2 << std::endl; It results in: Min size: 21
s length: 20 |
Based on testing during GH #981 we found an undersized buffer caused an out-of-bounds read.
Based on testing during GH weidai11#981 we found an undersized buffer caused an out-of-bounds read.
I think the following should not pass ECDSA verification (invalid pubkey), but it does. Tested on Linux 64 bit, latest master branch checkout.
The text was updated successfully, but these errors were encountered: