Skip to content
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

Fully Pluggable TLSv1.3 KEM #13018

Closed
wants to merge 13 commits into from

Conversation

romen
Copy link
Member

@romen romen commented Sep 28, 2020

Fully Pluggable TLSv1.3 KEM

This PR is extending the work done in changes recently merged for OpenSSL 3.0:

This PR would extend #11914 to:

  • add an extra capability to allow providers to optionally signal that a "plugged-in" group behaves as a KEM (key encapsulation method),
  • include minimal changes in libssl to act on this optional capability:
    • handling of the Key Share extension on the client and the server checks the new capability so that, if set to true, the API introduced in Add RSASVE from SP800-56Br2 #12750 is called, as an alternative to the traditional "DH-like scheme", that remains unchanged.

The combination of these 2 items would allow OpenSSL Providers to model the "plugged-in" groups either under the key exchange scheme (both sides do a Diffie-Hellman_-like_ exchange) or the key encapsulation method scheme (client sends KEM pubkey in Key Share, server encapsulates under given pubkey and send back the ciphertext as its Key Share, client decapsulates the received ciphertext using the paired privkey).
Given that a key exchange scheme can trivially be described as a KEM scheme, this also allows the authors of OpenSSL Providers to optionally describe DH-like primitives in terms of KEM, which also simplifies the design and deployment of hybrid schemes composing traditional-computing-resistant and quantum-computing-resistant primitives.


Edit: I edited the original description in favor of one that is hopefully slightly more useful for readers that have not been closely following the latest developments in 3.0; the original description is still available, collapsed immediately after this line.

Original description

Fully Pluggable TLSv1.3 KEM

This PR builds upon #11914 and the recent KEM support introduced with #12750, to further expand the "capabilities" approach to support KEM.

The libssl TLSv1.3 handling of the key share extensions is slightly tweaked, to support running KEM instead of DH-like KEX, if a provider signals so for a group using the new OSSL_CAPABILITY_TLS_GROUP_IS_KEM boolean parameter.

This would open the way to have providers implementing schemes that are fully compatible with the current TLSv1.3 spec yet using the KEM paradigm rather than KEX.
This would be very useful to implement post-quantum KEM primitives, and test their pure or hybrid deployment in TLS 1.3 with OpenSSL completely self-contained in a provider.

This also serves the purpose of testing the usability of the new EVP KEM API.


Merge window

I believe it would be possible to merge this already in 3.0, and that it is highly desirable:

  • as the NIST PQC selection process enters its final stages, real world deployments are more and more significant;
  • outside of the NIST effort, equivalent standardization bodies, like the German BSI, are already adopting some PQC KEM schemes in their recommendations;
  • IETF Internet drafts to design hybrid TLSv1.3 schemes to join classical-computing-resistant and quantum-computing-resistant algorithms are currently under development, and past experiments by Google and Cloudflare show such schemes can succesfully be deployed via the existing Key Share extension, without further changes as the current definition of the groups is opaque.

That being said, it is very late in the 3.0 development cycle, and although the required change to the public API is small, this configures as a new feature, and as such would require to be accepted before beta1.
I am submitting this now, but I am aware that it won't hold back the release of beta1 if it is not approved in time.

Here is a link for the comment further down in the discussion with my argument in favor of inclusion in 3.0.

Checklist

  • documentation is added or updated
  • tests are added or updated

@romen romen added the branch: master Merge to master branch label Sep 28, 2020
@romen romen self-assigned this Sep 28, 2020
@romen
Copy link
Member Author

romen commented Sep 28, 2020

@bbbrumley if you have the extra cycles, you might want to chime in here!

@slontis
Copy link
Member

slontis commented Sep 28, 2020

@romen although I applaud your enthusiasm, we need to start locking stuff down for beta. This is feature creep :)
The only thing that I will glean from this - is if the existing kem interface meets your needs for expansion after 3.0.
If it doesn't then submit a PR for that part.

@romen
Copy link
Member Author

romen commented Sep 28, 2020

@romen although I applaud your enthusiasm, we need to start locking stuff down for beta. This is feature creep :)

@slontis Yes, I opened this mostly as a follow-up to the discussion in the last weekly meeting, to have an actual user of the KEM API.

I still really really wish we could manage to get this in before beta1, but I know it is tough and I don't expect it.

The only thing that I will glean from this - is if the existing kem interface meets your needs for expansion after 3.0.
If it doesn't then submit a PR for that part.

It seems like the current API is flexible enough to implement this, so I don't think there is a need for a separate PR to change something in the KEM API.

@slontis
Copy link
Member

slontis commented Sep 28, 2020

It seems like the current API is flexible enough to implement this, so I don't think there is a need for a separate PR to change something in the KEM API.

I am hoping there is a discussion about what beta is - and how we get there soon..

@romen
Copy link
Member Author

romen commented Sep 28, 2020

It seems like the current API is flexible enough to implement this, so I don't think there is a need for a separate PR to change something in the KEM API.

I am hoping there is a discussion about what beta is - and how we get there soon..

Maybe I phrased my answer ambiguously: I meant that, considering this PR just as a test of the usability of the existing KEM API, I believe the work done in #12750 does not require further changes that I can foresee.

Regarding the second part, i.e. my wish to have this merged in 3.0, I have no high expectations, and I understand and appreciate the "no feature creep" angle.
The only reason I am still proposing this is that I believe this PR would have been part of #11914 if the requirement for RSASVE that led to #12750 did not surface quite late and well into the "no feature creep" window, and that it is indeed valuable from a strategic point of view.

Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An awesome piece of work!!!

However, I'm placing an OTC hold on it because its unclear whether this should go in before beta 1 or not.

@mattcaswell mattcaswell added the hold: need otc decision The OTC needs to make a decision label Sep 28, 2020
@romen
Copy link
Member Author

romen commented Sep 28, 2020

Thanks @mattcaswell for the feedback, 51b8d41dc12ae808ea96ed0b844238c10fd969fd should address all the issues.

Regarding the hold, I plan to talk about this on the committer or OTC meeting, as the schedule allows it, so we can collectively clarify if we want to include this feature or not in 3.0.

@kaduk
Copy link
Contributor

kaduk commented Sep 28, 2020

FWIW, this is the sort of thing I had in mind when I suggested that "potentially destabilizing changes" should not go into master until after 3.0 branches.

@romen
Copy link
Member Author

romen commented Sep 29, 2020

We share concerns about merging this PR before 3.0-beta1, because it is coming very late in the development cycle and because we all want to avoid "feature creep".

In favor of inclusion

My argument in favor of inclusion is that from a technical risk profile #13018 is not adding any significant amount of risk to the current 3.0 state and is, on the other hand, fulfilling long-standing requests from our users.

More in detail:

@romen
Copy link
Member Author

romen commented Sep 29, 2020

Call for comments

To build support for my argument for inclusion, I'd like to seek endorsement by members of the community, especially among the expert practitioners that are using OpenSSL —or forks of OpenSSL— as a toolkit as part of their ongoing efforts in the NIST PQC process.

I encourage you to share your view on the capability added by this PR, suggest improvements if it is lacking in some fundamental regard, and weight in with your expertise in favor or against the inclusion of this change in the 3.0 timeframe, and its impact on the evolution of the KEM software ecosystem.

I'd jumpstart this by pinging, in no particular order, @thomwiggers, @henrydcase, @cryptojedi, @christianpaquin, @baentsch, @xvzcf, @dstebila, @bbbrumley.
There is more people that I'd like to ping, but I don't know their Github handles.
For some of them I am also extending the invite via side-channels (:wink:) outside Github, please feel free to do the same to reach users that you know might want to participate in this discussion.

@richsalz
Copy link
Contributor

I do not see this as a mainstream feature. Folks can always fork it themselves and experiment. Or it can go into the 3.1 release. I do not see any pressure to have every downstream user be able to plug in their own key exchange. It's neat, but not worth it to most.

@romen
Copy link
Member Author

romen commented Sep 29, 2020

I updated the description adding a summary written targeting users that have not been following the latest developments in 3.0, and adding a link to my argument for inclusion.
The original description is still included for ease of reference.

@kriskwiatkowski
Copy link
Contributor

kriskwiatkowski commented Sep 29, 2020

I fully support the idea of KEM API. I don't see any reason to wait for it until NIST PQC to be finished, as whatever will be chosen it will be a KEM. "Fully pluggable" will help the community to experiment with PQ crypto and will help companies to prepare for migrations.
One important aspect, in my opinion, is to keep in mind that industry is mostly interested in hybrid-KEM/KEX.
Not sure if it should be in 3.0 or 3.1. Would be great to have it rather soon.

@romen
Copy link
Member Author

romen commented Sep 29, 2020

Thanks @richsalz for the feedback, I appreciate it!

I don't expect to change your opinion on the matter, which is perfectly fine and agreeable for many, but I want to counterargument it to stimulate debate.


Folks can always fork it themselves and experiment. Or it can go into the 3.1 release.

True, and people have been doing so, but I believe this is also preventing the users that have to maintain their fork to be able to conduct their experiments directly in OpenSSL and devote more energies in improving OpenSSL directly.

Regarding delay to 3.1, what I argue is that now is the time to include this to avoid alienating a valuable part of our community, because now is when the focus of the NIST PQC is shifting more and more on experiments on real-world deployments, now national standardization bodies outside NIST are updating their recommendations to include a selection of PQC KEM.


I do not see any pressure to have every downstream user be able to plug in their own key exchange. It's neat, but not worth it to most.

That is not under discussion, that feature is already in, and I would say required by many users outside of US that have a recommendation or requirement to use different groups than P-256 or X25519, or the FFDHE without having to replace the OpenSSL version provided by the maintainers of their distribution: if someone had a requirement to use FourQ or NationalGroup42 they could do so with a provider, without patching OpenSSL.

On this matter, this PR only adds an extra flag to signal that the group is modeled according to KEM rather than DH-KEX.

I agree that at the moment the latter feature is useful almost exclusively to people experimenting about real-world deployments. The likelihood that some organization today wants/needs to deploy PQC KEM for TLSv1.3 is also quite low, but my expectation is that even this likelihood is bound to increase before we will be ready for a 3.1 release.

And I would still argue that this might not be motivation enough if this was a major new feature potentially causing further delays for 3.0 or with a moderate/high risk of biting us in the foreseeable future, but this is not the case for this PR.

  • The code change in libssl is small, maximizing reuse of existing code.
  • The change to the public API consists in a single extra OSSL_PARAM, within an already merged query mechanism that is already used by libssl and by our providers.
  • The risk profile seems minimal.

Under these conditions I would argue that the pressure of unnecessarily alienating some of our users is the pressure I am seeing to get this in.
And it is the reason why I posted the above Call for Comments, to make the pressure more visible rather than just my personal gut feeling (that can easily be mistaken).

@richsalz
Copy link
Contributor

Sorry, I used the wrong term and that led you to go onto a larger rebuttal than necessary. I made most of my point and will not otherwise get into a debate to that others can contribute.

@romen
Copy link
Member Author

romen commented Sep 29, 2020

Thanks @henrydcase for your feedback!

I fully support the idea of KEM API. I don't see any reason to wait for it until NIST PQC to be finished, as whatever will be chosen it will be a KEM.

The KEM API is already in (thanks to #12750 work), so that already allows authors of OpenSSL Providers to inject such functionality in libcrypto.

"Fully pluggable" will help the community to experiment with PQ crypto and will help companies to prepare for migrations.
One important aspect, in my opinion, is to keep in mind that industry is mostly interested in hybrid-KEM/KEX.
Not sure if it should be in 3.0 or 3.1. Would be great to have it rather soon.

This PR further improves the mechanism that lets libssl interact with providers, allowing the provider to plug in a group as a KEM-group rather than a KEX-group: this wouldn't prevent hybrid-KEM/KEX scenarios, as KEX can be modeled under a KEM scheme and easily be combined with another KEM scheme, e.g. under this Internet-Draft by @dstebila.

It would be up to the OpenSSL Provider to plug a group PQCfooKEM and a separate group X25519+PQCfooKEM.
In the first case PQCfooKEM would encapsulate/decapsulate according to the reference implementation of the PQCfooKEM primitive, the second would encapsulate/decapsulate combining the X25519 operation and the PQCfooKEM

@mspncp
Copy link
Contributor

mspncp commented Sep 29, 2020

Excellent write-up, @romen!

@kriskwiatkowski
Copy link
Contributor

kriskwiatkowski commented Sep 29, 2020

yep, that sounds very useful, would be great to have it. makes integration of PQ into TLS much simpler. After looking at a code a bit closer, it seems like that's a relatively small change, comparing to #12750).

@romen
Copy link
Member Author

romen commented Sep 29, 2020

I realize only now that answering point by point to feedback as I did above, might come across as off-putting.
It was not my intention to do so, especially after soliciting feedback. It's just my (poor) choice of style in trying to organize my answers to compensate my writing skills in English, that can be sometime lacking.

I can do better and I'll try to, in the meantime I think it is important to extend my apologies if anyone felt annoyed by it, and to remark that I truly do welcome all feedback, not just the answers that are more or less clearly in favor of my argument for inclusion in 3.0!
I will strive to be more considerate!

@bbbrumley
Copy link
Contributor

I support this PR and the reasons are exactly those mentioned by Kris. Having personally hacked libssl so (1) it supports some kind of KEM paradigm; and (2) it knows about OIDs being injected from engines, I can confidently say that is not fun and nobody wants to maintain a fork.

Since others being tagged might feel a bit blindsided, I can summarize quickly -- at least for one project. @dstebila and @christianpaquin for OQS this would mean your OpenSSL fork goes away entirely -- cryptosystems load dynamically in libcrypto by registering through the Provider API (an upcoming OpenSSL 3.0 concept which, among other things, supersedes the Engine concept), and for KEMs it's this PR that bubbles that functionality up to libssl.

@dstebila
Copy link

I support this PR and the reasons are exactly those mentioned by Kris. Having personally hacked libssl so (1) it supports some kind of KEM paradigm; and (2) it knows about OIDs being injected from engines, I can confidently say that is not fun and nobody wants to maintain a fork.

Since others being tagged might feel a bit blindsided, I can summarize quickly -- at least for one project. @dstebila and @christianpaquin for OQS this would mean your OpenSSL fork goes away entirely -- cryptosystems load dynamically in libcrypto by registering through the Provider API (an upcoming OpenSSL 3.0 concept which, among other things, supersedes the Engine concept), and for KEMs it's this PR that bubbles that functionality up to libssl.

Having a more direct method to add key exchange methods in libssl would be welcome. The goal of our fork is to be able to experiment with and demonstrate post-quantum algorithms prior to widespread adoption. We're able to do so by modifying the libcrypto and libssl code in many places, but would be happy to have a simpler route.

Our fork will probably go away eventually after the end of the NIST standardization and OpenSSL's eventual incorporation of those algorithms, and we're okay with that -- although it will take more than just pluggable KEMs in libssl, as we also do PQ and hybrid signatures in libssl, S/MIME & CMS signing, and a few more things.

Currently all our work has been on 1.1.1, and we haven't touched 3.0 yet, but are looking forward to experimenting with it when the time is right.

@christianpaquin
Copy link

I didn't review the details of this PR or the KEM integration strategy, but to echo @dstebila's comments, I also fully agree with the addition of KEM support in OpenSSL. NIST will standardize a post-quantum KEM; doesn't matter which one, OpenSSL can proactively add support for the mechanism. In fact, OpenSSL's integration feedback would be helpful to the NIST competition, and the project would benefit if its preferred (from an integration's perspective) finalist is selected, rather than being forced later to integrate a scheme that's not as well suited for TLS or OpenSSL.

Early integration would also encourage people to experiment with real-world deployments. Hybrid (classical+PQ) is critical, and a good strategy should be implemented (see this paper for example). There is this chicken and egg problem of people wanting the feature but also wanting to use official OpenSSL code to conduct quantum-safe pilots. I, as many of my OQS colleagues I'm sure, would be happy to work with the OpenSSL team to make this happen.

OQS's goal is to provide post-quantum features on top of OpenSSL; if none exist, then we declare victory as the library would be quantum safe!

@romen romen force-pushed the features/3.0.0-dev/pluggable-kem branch from 51b8d41 to 74ac213 Compare October 13, 2020 14:20
@romen
Copy link
Member Author

romen commented Oct 13, 2020

Just rebased.

  • 316e1e5 fixup! [test][tls-provider] Group xor_group properties in a struct
  • 47d809f fixup! [test][tls-provider] Add 2nd pluggable tls group for KEM
  • 74ac213 fixup! [test][tls-provider] Implement KEM algorithm

Are the ones addressing latest feedback from @mattcaswell (last listed is latest)

The commits from 1574d6f up to 55a6890 (both included) are just the result of an automatic rebase with not conflicts.

Copy link
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mattcaswell mattcaswell added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Oct 13, 2020
@openssl-machine openssl-machine removed the approval: done This pull request has the required number of approvals label Oct 14, 2020
@openssl-machine
Copy link
Collaborator

This pull request is ready to merge

@openssl-machine openssl-machine added the approval: ready to merge The 24 hour grace period has passed, ready to merge label Oct 14, 2020
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
Note that with this commit the optional parameter is introduced, but
libssl still ignores it.

Reviewed-by: Matt Caswell <[email protected]>
(Merged from #13018)
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
openssl-machine pushed a commit that referenced this pull request Oct 14, 2020
@romen
Copy link
Member Author

romen commented Oct 14, 2020

Merged on master with

  • 32fea07 [test][tls-provider] Group xor_group properties in a struct
  • c8e3a4c [test][sslapitest] Add test for pluggable KEM group
  • ecff43e [test][tls-provider] Add 2nd pluggable tls group for KEM
  • c1a74f5 Define OSSL_CAPABILITY_TLS_GROUP_IS_KEM
  • a011b58 [ssl] Support ssl_decapsulate on client side
  • 8b17fba [ssl] Support ssl_encapsulate on server side
  • 5b70206 [test][tls-provider] Implement KEM algorithm

Thanks everyone for the feedback and the review.

@romen romen closed this Oct 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Merge to master branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.