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

Add support for hybrid-PQ key exchange with x25519 #169

Merged
merged 2 commits into from
Aug 26, 2024

Conversation

geedo0
Copy link

@geedo0 geedo0 commented Aug 21, 2024

This adds support for hybrid-PQ key exchanges with x25519. This allows for the implementation of mlkem768x25519-sha256 as defined by draft-kampanakis-curdle-ssh-pq-ke-02 and [email protected] as defined by upstream OpenSSH. We also take the opportunity to add hybrid implementations for all existing PQ key exchanges which supported NIST P-256. Due to the conflicting implementation for [email protected] we omit an OQS exclusive version for now and will plan for it in a future PR. Unlike in oqs-provider, we cannot provide support for x448 hybrid algorithms since the x448 algorithm is not available within OpenSSH.

The way this all works is by introducing a new source file kexoqsx25519.c which is a synthesis of kexoqsecdh.c and kexsntrup761x25519.c. These files provide example implementations of hybrid-PQ for OQS-backed algorithms and x25519 usage. In that source file, we define functions to implement OpenSSH's KEX interface for each hybrid algorithm using an oqs-template file. Within the generate.yml, we add a new boolean key to flag x25519 hybrids similar to how the rsa key works for hybrid signatures.

Related to issue #163.

Testing

In addition to the CI checks, I performed interop testing with the AWS Transfer for SFTP service's PQ support. The snippet below opens an SFTP connection to an AWS Transfer for SFTP server using the [email protected] algorithm.

➜  oqs-openssh git:(x25519) ✗ server=s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com
[email protected]
sftp \
  -S /home/gcr/git-workplace/oqs-openssh/ssh -v \
  -o KexAlgorithms=${kex} \
  ${server}
OpenSSH_9.7-2022-01_p1, Open Quantum Safe 2022-08, OpenSSL 3.0.2 15 Mar 2022
debug1: Reading configuration data /home/gcr/git-workplace/oqs-openssh/oqs-test/tmp/ssh_config
debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
debug1: Connecting to s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com [3.86.168.50] port 22.
debug1: Connection established.
...
debug1: Local version string SSH-2.0-OpenSSH_9.7-2022-01_
debug1: Remote protocol version 2.0, remote software version AWS_SFTP_1.1
debug1: compat_banner: no match: AWS_SFTP_1.1
debug1: Authenticating to s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com:22 as 'gcr'
debug1: load_hostkeys: fopen /home/gcr/.ssh/known_hosts2: No such file or directory
debug1: load_hostkeys: fopen /home/gcr/git-workplace/oqs-openssh/oqs-test/tmp/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /home/gcr/git-workplace/oqs-openssh/oqs-test/tmp/ssh_known_hosts2: No such file or directory
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: [email protected]
debug1: kex: host key algorithm: rsa-sha2-512
debug1: kex: server->client cipher: aes192-ctr MAC: [email protected] compression: none
debug1: kex: client->server cipher: aes192-ctr MAC: [email protected] compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ssh-rsa SHA256:Im6qOBKTcl2GCAlTQkEVVrDgXENNIcRavVvdQuSFtpU
..
Authenticated to s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com ([3.86.168.50]:22) using "publickey".
debug1: channel 0: new session [client-session] (inactive timeout: 0)
debug1: Entering interactive session.
debug1: pledge: filesystem
debug1: client_input_global_request: rtype [email protected] want_reply 0
debug1: client_input_hostkeys: searching /home/gcr/.ssh/known_hosts for s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com / (none)
debug1: client_input_hostkeys: searching /home/gcr/.ssh/known_hosts2 for s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com / (none)
debug1: client_input_hostkeys: hostkeys file /home/gcr/.ssh/known_hosts2 does not exist
debug1: client_input_hostkeys: no new or deprecated keys from server
debug1: Remote: SFTP: key options: agent-forwarding port-forwarding pty user-rc x11-forwarding
debug1: Remote: SFTP: key options: agent-forwarding port-forwarding pty user-rc x11-forwarding
debug1: Sending subsystem: sftp
debug1: pledge: fork
Connected to s-7505309924a2473d8.server.transfer.us-east-1.amazonaws.com.
sftp> ls
demo.txt
sftp> exit
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 4196, received 4952 bytes, in 14.3 seconds
Bytes per second: sent 292.8, received 345.6
debug1: Exit status 0

This adds support for hybrid-PQ key exchanges with x25519. This allows for the implementation of `mlkem768x25519-sha256` as defined by [draft-kampanakis-curdle-ssh-pq-ke-02](https://datatracker.ietf.org/doc/draft-kampanakis-curdle-ssh-pq-ke/) and `[email protected]` as defined by upstream OpenSSH. We also take the opportunity to add hybrid implementations for all existing PQ key exchanges which supported NIST P-256. Due to the conflicting implementation for `[email protected]` we omit an OQS exclusive version for now and will plan for it in a future PR. Unlike in `oqs-provider`, we cannot provide support for x448 hybrid algorithms since the x448 algorithm is not available within OpenSSH.

The way this all works is by introducing a new source file `kexoqsx25519.c` which is a synthesis of `kexoqsecdh.c` and `kexsntrup761x25519.c`. These files provide example implementations of hybrid-PQ for OQS-backed algorithms and x25519 usage. In that source file, we define functions to implement OpenSSH's KEX interface for each hybrid algorithm using an `oqs-template` file. Within the `generate.yml`, we add a new boolean key to flag `x25519` hybrids similar to how the `rsa` key works for hybrid signatures.

Related to issue open-quantum-safe#163.

Signed-off-by: Gerardo Ravago <[email protected]>
README.md Show resolved Hide resolved
Copy link
Member

@baentsch baentsch left a comment

Choose a reason for hiding this comment

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

Basically LGTM. Again, explanation and test process description is very clear: Thanks! Code also seems OK. The "doubly" tagging x25519 in generate.yml does not seem user-friendly, though: What about the idea to only mandate one of the two and generate the other within generate.py? That way, consistency checks (for/or user errors) can be avoided and your code-gen logic retained. Last question: Any chance the tests you mentioned can be added to the CI chain for "continuous live CI"? We do something similar in oqsprovider...

@geedo0
Copy link
Author

geedo0 commented Aug 26, 2024

Code also seems OK. The "doubly" tagging x25519 in generate.yml does not seem user-friendly, though

I totally agree with you and don't like it myself either. The choice was driven by the precedent set for RSA hybrid KEX signatures here (and all the related usage patterns). While it may look nicer to change it for the PR, it proliferates two different ways of accomplishing the same thing in this code base which is also undesirable for readability/maintainability.

. Last question: Any chance the tests you mentioned can be added to the CI chain for "continuous live CI"? We do something similar in oqsprovider...

That's a good idea, but unfortunately it does require some persistent resources to exist and be paid for somewhere. I don't have a good place for our team to own/maintain/secure it long-term right now, but it is an interesting idea for ways to host an integration test endpoint for SSH. I'll float it up with the team.

@baentsch
Copy link
Member

Code also seems OK. The "doubly" tagging x25519 in generate.yml does not seem user-friendly, though

I totally agree with you and don't like it myself either. The choice was driven by the precedent set for RSA hybrid KEX signatures here (and all the related usage patterns). While it may look nicer to change it for the PR, it proliferates two different ways of accomplishing the same thing in this code base which is also undesirable for readability/maintainability.

ACK. Then allow me to suggest creating an issue for this: Could be labelled "refactoring generator code" (with concrete suggestion what to change). May also help posterity (or anyone willing to get their feet wet in the code as a way to get started)...

. Last question: Any chance the tests you mentioned can be added to the CI chain for "continuous live CI"? We do something similar in oqsprovider...

That's a good idea, but unfortunately it does require some persistent resources to exist and be paid for somewhere. I don't have a good place for our team to own/maintain it long-term right now, but it is an interesting idea for ways to host an integration test endpoint for SSH.

Well, we already have "test.openquantumsafe.org" and running an OpenSSH test endpoint there doesn't sound outlandish. Or is that bespoke AWS software that would cause worldwide server outages or other allergic reactions on either side when run on an "IBM cloud" VM? :-)

Copy link
Member

@baentsch baentsch left a comment

Choose a reason for hiding this comment

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

OK for me -- with room for (later, outside of this PR) improvement. Thanks @geedo0 !

@geedo0
Copy link
Author

geedo0 commented Aug 26, 2024

Well, we already have "test.openquantumsafe.org" and running an OpenSSH test endpoint there doesn't sound outlandish. Or is that bespoke AWS software that would cause worldwide server outages or other allergic reactions on either side when run on an "IBM cloud" VM? :-)

Unfortunately, this is a closed-source implementation for our managed file transfer service (tl;dr - it exposes an SFTP front-end for reading/writing to AWS managed storage like S3). The only way this would work is if we had one of these managed endpoints running in an AWS account and a CNAME record in your DNS zone file pointed to it. Honestly, it's less of a technical challenge than it is a bureaucratic one.

@geedo0 geedo0 merged commit 5674ca3 into open-quantum-safe:OQS-v9 Aug 26, 2024
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants