Conversation
|
Put a hold on this to discuss within the OTC.. |
| __owur int EVP_DigestVerifyHBSInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
| const char *mdname, | ||
| OSSL_LIB_CTX *libctx, | ||
| const char *props, EVP_PKEY *pkey, | ||
| const OSSL_PARAM params[], | ||
| const unsigned char *sig, | ||
| size_t siglen); | ||
| /* Alias: since the function signature is identical */ | ||
| #define EVP_DigestVerifyHBSUpdate(a,b,c) EVP_DigestVerifyUpdate(a,b,c) | ||
|
|
||
| __owur int EVP_DigestVerifyHBSFinal(EVP_MD_CTX *ctx); |
There was a problem hiding this comment.
I like this proposal more, except for:
- It should not be called with HBS in the name as this is generic call for any possible future signature schemes and not tightly coupled to hash based signatures.
- Why do we need both pkey as input parameter and ppctx as output one? Would it be better to have only one of them. I'm unsure which one of them though.
- How does it play with this proposal https://github.com/openssl/openssl/blob/master/doc/designs/fetching-composite-algorithms.md
There was a problem hiding this comment.
- I was trying to make the Init and FInal calls match... using a matching tag.. I dont care what the tag is.
- It is the same API as the existing one with sig added to the end.
- We would either need yet another function, or pass the signature in as an OSSL_PARAM.. We dont actually use EVP_SIGNATURE_fetch() normally currently, so this seems a bit early to be adding the EVP_SIGNATURE one.
There was a problem hiding this comment.
In PKCS #11 we made the new API C_VerifySignature. Maybe EVP_SignatureVerifyInit?
We also said if you support the C_VerifySignature interface you need to support it for all the signing algorithms (basically they can just store the signature at init time and use the stored signature in Final). The form that takes the signature at init time is more general (for the signature implementers... all signatures can support this form), but less general for the application (applications that don't have the signature until the end can't use signature first without buffering).
Anyway I'm not familiar enough with normal openssl spellings, so you need to moderate my comments with openssl usage
There was a problem hiding this comment.
I was trying to make the Init and FInal calls match... using a matching tag.. I dont care what the tag is.
Definitely needs a different name.
We would either need yet another function, or pass the signature in as an OSSL_PARAM.. We dont actually use EVP_SIGNATURE_fetch() normally currently, so this seems a bit early to be adding the EVP_SIGNATURE one.
I don't see why?
There was a problem hiding this comment.
do_sigver_init() does this internally. Not much else needs the EVP_SIGNATURE_fetch()
There was a problem hiding this comment.
Actually, the 3rd option (passing EVP_SIGNATURE) will become available with the effort mentioned... and it's now underway, so it wouldn't be a bad idea to collaborate around designing the API. If we're reusing do_sigver_init() (not sure why we'd have to), it can be modified to fit.
There was a problem hiding this comment.
Err how/where can I comment on the composite algorithm design document?
There was a problem hiding this comment.
You can start a discussion or raise an issue... or wait for the draft PR I'm currently preparing.
Do note that I'm currently exploring EVP_PKEY_sign() / EVP_PKEY_verify() and associated functions rather than EVP_DigestSign and EVP_DigestVerify function groups.
There was a problem hiding this comment.
When I think of it, I think I'll start with a design document, and we can discuss that.
| In order to support the new API calls there should be 2 additional dispatch | ||
| functions.. | ||
|
|
||
| OSSL_CORE_MAKE_FUNC(int, signature_digest_verify_pbs_init, | ||
| (void *ctx, const char *mdname, void *provkey, | ||
| const OSSL_PARAM params[], | ||
| const unsigned char *sig, size_t siglen)) | ||
| OSSL_CORE_MAKE_FUNC(int, signature_digest_verify_pbs_final, | ||
| (void *ctx)) |
There was a problem hiding this comment.
Note: It should be possible to implement this init_with_signature function in terms of the existing APIs for those algorithms that do not have this new provided function. We would just cache the signature and use it in the final call. That's another reason why the EVP function should not be named with HBS in the name as this can be a fully generic call supported even with older signature algorithms on older providers.
There was a problem hiding this comment.
I would think returning not supported would be sufficient..
There was a problem hiding this comment.
It's likely the new API is the new normal. All they NIST signature algorithms are defined needing the signature first. It provides better signature guarantees. Protocol people don't like it because protocols often put the signature at the end. My guess is protocols with end up doing single shot where they use the full algorithm to sign their preselected hashes.
There was a problem hiding this comment.
Implementing the backwards compat approach seems desirable to me.
|
May I ask for a requirement that if any signing operation is implemented that it can be disabled at built time, leaving only verification operations available? LMS is something that should never been implemented in a generic software system, NIST and NSA as well recommend that LMS and XMSS signatures are implemented only in Hardware, and the reason is that duplicating state is catastrophic, and in software duplicating state is as simple as restarting a machine after a crash where updates didn't get to disk, or copying around files. We do not want to give our users a knife that has cyanide laced razor blades for a handle. |
There is no intention of implementing the sign or private key generation |
| Add a Init_ex function and leave the Final the same. | ||
|
|
||
| i.e. | ||
| EVP_DigestVerifyInit_ex3(..., const unsigned char *sig, size_t siglen); |
There was a problem hiding this comment.
@t8m mentioned _with_signature for the libcrypto<->provider interface. Could that be a good idea here as well, instead of yet another ex?
| - Support one shot operations: | ||
| Using existing EVP_DigestVerifyInit_ex + EVP_DigestVerify calls | ||
| - Dont support streaming via existing interface: | ||
| EVP_DigestVerifyInit_ex + EVP_DigestVerifyUpdate + EVP_DigestVerifyFinal. |
| sufficient for this use case. A separate LMS signature dispatch table could be | ||
| added if this is ever required. | ||
| - CMS and X509 support - this may be added at a later date. | ||
| - Implementing Extended Merkle signature scheme (XMSS) is a separate effort. |
There was a problem hiding this comment.
Yup. HSS with a single tree is basically LMS. No one uses bare LMS, so that's fine. Definitely good not so support signatures and key gen. When implementing XMSS, it's possible to use some common code, but LMS and XMSS is just different enough that it's probably best to have separate implementations (said by someone who has made the combined implementation as a testbed).
|
|
||
| Pass the signature after the init via an OSSL_PARAM. | ||
|
|
||
|
|
There was a problem hiding this comment.
We talked about both of theses type of schemes in PKCS #11: 1) adding just a new init function that takes the signature and 2) adding the signature to the mechanism parameter (the equivalent of OSSL_PARAM). Both of these generated the question of what do you return on Final if the signature is included; a) failure if it's not null, b) failure if it's not null and doesn't match, or c) undefined if the application includes the signature. In the end having a complete new set of C_VerifySignatureXXXX functions got rid of all those issues since the Final versions won't have a signature. We made the C_VerifySignatureUpdate a separate function, but your proposal to make it a #define for the normal update is actually good (so applications that need to support both don't have to keep track of which to call the correct update function.
|
Thanks for your input @rjrelyea |
| const char *props, EVP_PKEY *pkey, | ||
| const OSSL_PARAM params[], | ||
| const unsigned char *sig, | ||
| size_t siglen); |
There was a problem hiding this comment.
Using EVP_MD_CTX as the primary ctx for EVP_DigestVerify* was a design mistake IMO. The output param of an EVP_PKEY_CTX * is just horrible. We had to hack around this mistake when we moved all this stuff to providers.
This could be an opportunity to do this properly and just make this pass in an EVP_PKEY_CTX.
There was a problem hiding this comment.
That idea also ties in on this design: https://github.com/openssl/openssl/blob/master/doc/designs/fetching-composite-algorithms.md
It's actually a good idea, and aligns better with how other (non-PKEY) operations work.
| __owur int EVP_DigestVerifyHBSInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | ||
| const char *mdname, | ||
| OSSL_LIB_CTX *libctx, | ||
| const char *props, EVP_PKEY *pkey, | ||
| const OSSL_PARAM params[], | ||
| const unsigned char *sig, | ||
| size_t siglen); | ||
| /* Alias: since the function signature is identical */ | ||
| #define EVP_DigestVerifyHBSUpdate(a,b,c) EVP_DigestVerifyUpdate(a,b,c) | ||
|
|
||
| __owur int EVP_DigestVerifyHBSFinal(EVP_MD_CTX *ctx); |
There was a problem hiding this comment.
I was trying to make the Init and FInal calls match... using a matching tag.. I dont care what the tag is.
Definitely needs a different name.
We would either need yet another function, or pass the signature in as an OSSL_PARAM.. We dont actually use EVP_SIGNATURE_fetch() normally currently, so this seems a bit early to be adding the EVP_SIGNATURE one.
I don't see why?
|
|
||
| For the EVP_DigestVerifyFinal pass a NULL signature. | ||
| The signature length must be zero in this case or an error will occur. | ||
| If a signature is passed should it just ignore the value? |
There was a problem hiding this comment.
I prefer this proposal more that proposal 1. (Unless we go with my suggestion to use EVP_PKEY_CTX...in which case it really does need a new name).
| const unsigned char *sig, | ||
| size_t siglen); | ||
| /* Alias: since the function signature is identical */ | ||
| #define EVP_DigestVerifyHBSUpdate(a,b,c) EVP_DigestVerifyUpdate(a,b,c) |
There was a problem hiding this comment.
I know we've done this before - but I think this is very confusing and causes potential problems in the future if we ever want them to do different things.
| In order to support the new API calls there should be 2 additional dispatch | ||
| functions.. | ||
|
|
||
| OSSL_CORE_MAKE_FUNC(int, signature_digest_verify_pbs_init, | ||
| (void *ctx, const char *mdname, void *provkey, | ||
| const OSSL_PARAM params[], | ||
| const unsigned char *sig, size_t siglen)) | ||
| OSSL_CORE_MAKE_FUNC(int, signature_digest_verify_pbs_final, | ||
| (void *ctx)) |
There was a problem hiding this comment.
Implementing the backwards compat approach seems desirable to me.
|
|
||
| As well as using the test vectors supplied in [1] and [6], additional interop tests | ||
| should be performed by generating data using other toolkits | ||
| (such as Ciso or Bouncy Castle). |
There was a problem hiding this comment.
Do these implement the sign side?
There was a problem hiding this comment.
Since the RFC originated from Cisco they needed to write a reference implementation. BC has the sign side. The Java SDK only implements the verify.. In my opinion it is asking for trouble implementing stateful signing (which is why it is supposed to be done in hardware only)
There was a problem hiding this comment.
There is a reference implementation available: https://github.com/cisco/hash-sigs
|
I would go even further that what Simo said. I consider not only presence of signature creation a problem, but signature verification too. Safe use of any stateful hash based signature formats absolutely and unequivocally depends on the signature operation being performed in hardware. Doing it in a way that allows for disaster recovery, over 10, or 20+ years of use, is orders of magnitude harder still. That means that there will be very few originators of such signatures. Which means they will be used in very few places. In case we have widely deployed implementations that can verify such signatures, there definitely will be people that don't know better and actually implement and use signature creation in software. So, just presence of signature verification is an incentive to do the wrong thing. As such, I don't think openssl should ship with any code that can do LMS verification. It can have support for providers that support it (to support the hardware modules), but I think including verification code is a mistake. If there are specific users asking for it, it should be a separate provider module, not part of OpenSSL proper. Users should not be able to expect that LMS is supported out of the box. See also: Nuclear Non-proliferation Treaty |
There is no state associated with the signature verification, so I dont agree. There are many things in crypto that you can do wrong if you dont know what you are doing. |
|
My point is that there is a difference between "it's hard to do it correctly" and "there's literally at most double digit number of corporations in the world that will be able to do a production deployment correctly". |
|
This PR is in a state where it requires action by @openssl/otc but the last update was 61 days ago |
|
This PR is in a state where it requires action by @openssl/otc but the last update was 91 days ago |
|
This PR is in a state where it requires action by @openssl/otc but the last update was 122 days ago |
|
Considering the recent additions to the |
|
I am in the process of writing the code.. |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 30 days ago |
| Hash Function Selection | ||
| ----------------------- | ||
|
|
||
| - During the DigestVerifyInit()the passed in digest name is not required |
|
|
||
| - Support one shot operations: | ||
| Using existing EVP_DigestVerifyInit_ex + EVP_DigestVerify calls | ||
| - Dont support streaming via existing interface: |
|
|
||
| For the EVP_DigestVerifyFinal pass a NULL signature. | ||
| The signature length must be zero in this case or an error will occur. | ||
| If a signature is passed should it just ignore the value? |
|
|
||
| As well as using the test vectors supplied in [1] and [6], additional interop tests | ||
| should be performed by generating data using other toolkits | ||
| (such as Ciso or Bouncy Castle). |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 30 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 61 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 92 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 123 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 154 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 185 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 216 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 247 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 278 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 309 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 340 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 371 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 402 days ago |
|
This PR is in a state where it requires action by @openssl/committers but the last update was 433 days ago |
|
@slontis Could you please sync this with the actual implementation? |
|
Closing this as it is not likely to be reviewed if I update it. |
Checklist