-
Notifications
You must be signed in to change notification settings - Fork 606
Signature padding improvements #3315
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
Conversation
Previously if RFC 6979 was enabled, we would test only that file. And if it was disabled, we would test only the CAVS file. Now test signature *generation* using whichever method is enabled, but also test verification of the signatures from the other method.
Remove support for message prefixes from the PK_Ops base classes, since it was only used for ECKCDSA.
Only RSA still supports this now that Rabin-Williams and NR have been removed; it's easier to move that logic to the RSA specific impl.
This effectively sidelines the EMSA1/EMSA_Raw code for (EC)DSA, GOST, and company.
At least keeping parity with what is done on master currently.
5a42882
to
9eb96f3
Compare
Codecov ReportBase: 87.99% // Head: 88.02% // Increases project coverage by
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## master #3315 +/- ##
==========================================
+ Coverage 87.99% 88.02% +0.03%
==========================================
Files 608 608
Lines 68680 68758 +78
Branches 6845 6850 +5
==========================================
+ Hits 60436 60526 +90
+ Misses 5395 5368 -27
- Partials 2849 2864 +15
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I skimmed over the changes and didn't find any obvious blunder. But frankly I'm lacking a good enough overview of the EMSA implementations to give a decent review.
Anything we can do to help with Dilithium, though?
src/lib/tls/tls_signature_scheme.cpp
Outdated
switch(m_code) | ||
{ | ||
case RSA_PKCS1_SHA1: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA3(SHA-1)"), AlgorithmIdentifier::USE_NULL_PARAM); | ||
case RSA_PKCS1_SHA256: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA3(SHA-256)"), AlgorithmIdentifier::USE_NULL_PARAM); | ||
case RSA_PKCS1_SHA384: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA3(SHA-384)"), AlgorithmIdentifier::USE_NULL_PARAM); | ||
case RSA_PKCS1_SHA512: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA3(SHA-512)"), AlgorithmIdentifier::USE_NULL_PARAM); | ||
|
||
case ECDSA_SHA1: | ||
return AlgorithmIdentifier(OID::from_string("ECDSA/EMSA1(SHA-1)"), AlgorithmIdentifier::USE_EMPTY_PARAM); | ||
case ECDSA_SHA256: | ||
return AlgorithmIdentifier(OID::from_string("ECDSA/EMSA1(SHA-256)"), AlgorithmIdentifier::USE_EMPTY_PARAM); | ||
case ECDSA_SHA384: | ||
return AlgorithmIdentifier(OID::from_string("ECDSA/EMSA1(SHA-384)"), AlgorithmIdentifier::USE_EMPTY_PARAM); | ||
case ECDSA_SHA512: | ||
return AlgorithmIdentifier(OID::from_string("ECDSA/EMSA1(SHA-512)"), AlgorithmIdentifier::USE_EMPTY_PARAM); | ||
|
||
case RSA_PSS_SHA256: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA4"), | ||
hex_decode("3039A00F300D06096086480165030402010500A11C301A06092A864886F70D010108300D06096086480165030402010500A203020120A303020101")); | ||
case RSA_PSS_SHA384: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA4"), | ||
hex_decode("3039A00F300D06096086480165030402020500A11C301A06092A864886F70D010108300D06096086480165030402020500A203020130A303020101")); | ||
case RSA_PSS_SHA512: | ||
return AlgorithmIdentifier(OID::from_string("RSA/EMSA4"), | ||
hex_decode("3039A00F300D06096086480165030402030500A11C301A06092A864886F70D010108300D06096086480165030402030500A203020140A303020101")); | ||
|
||
default: | ||
// Note that Ed25519 and Ed448 end up here | ||
return AlgorithmIdentifier(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as last year: Sad that we need to scatter those mappings around the code. But then again: it feels like every protocol has their own particularities that make it hard to abstract this.
Anyway: Maybe at least add a comment to the hex_decode
-ed EMSA4 parameters explaining what's inside the magic strings?
In the linked comment, I regenerated those for every invocation. Less efficient but easier to understand:
auto pss_params = [](const std::string hash_name)
{
const AlgorithmIdentifier hash_id(hash_name, AlgorithmIdentifier::USE_NULL_PARAM);
const AlgorithmIdentifier mgf_id("MGF1", hash_id.BER_encode());
std::vector<uint8_t> parameters;
DER_Encoder(parameters)
.start_sequence()
.start_context_specific(0).encode(hash_id).end_cons()
.start_context_specific(1).encode(mgf_id).end_cons()
.start_context_specific(2).encode(HashFunction::create(hash_name)->output_length()).end_cons()
.start_context_specific(3).encode(size_t(1)).end_cons() // trailer field
.end_cons();
return parameters;
};
Still wondering whether DER_Encoder
could do this as a constexpr
generation. Purely academic question though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this instance though, the specific values we're encoding don't even matter. That is, TLS 1.3 could have just as easily mandated that the parameters be empty, or be the raw binary ASCII "I_PINKY_SWEAR_THIS_IS_PSS". In the context of TLS 1.3, no additional information is conveyed; there is a 1:1 mapping between the signature_algorithm
enumeration, and the DER-encoded PssParams
.
This could probably be cleaned up a bit by adding an explicit type for PssParams
.
@reneme A lot of code in this area is more complicated than it needed to be, as a result of some historical blunders
This PR (and followup work in #3319) will hopefully address a lot of these |
if(m_output_length > 0 && m_bits.size() != m_output_length) | ||
{ | ||
m_bits.resize(0); | ||
throw Invalid_Argument("EMSA_Raw was configured to use a " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is a copy and paste error and EMSA_Raw
should probably be RawHashFunction
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thank you, yes
Fixes #2841 and #3313
@reneme review is optional but I figure you would be interested. It is probably easier to review commit-by-commit. Also important note: Dilithium X.509 is still broken. The old tests used
Botan::get_sig_paddings
to get the padding parameters, but this returned an empty list for Dilithium. If I enable the tests for Dilithium, things fail.#3319 captures some followup items.