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

Experimental KEMTLS Client #20

Draft
wants to merge 4 commits into
base: dev/tls-13
Choose a base branch
from
Draft

Experimental KEMTLS Client #20

wants to merge 4 commits into from

Conversation

reneme
Copy link

@reneme reneme commented Apr 7, 2022

This introduces experimental client-side support for KEMTLS as proposed by Schwabe et.al. [1, 2].

The implementation is compatible with the reference implementation by @thomwiggers and @claucece. It is based on the yet to be merged TLS 1.3 client implementation in Botan.

The TLS key exchange is performed using Botan's Kyber implementation. Certificate signature checks are omitted for now as Dilithium is not yet implemented.

This work is funded by the German Bundesministerium für Bildung und Forschung as part of the KBLS project (see also Botan Issue #2500).

How to run this code

1. Run the rustls server

Follow the instructions in thomwiggers/kemtls-experiment, but configure the server certificate to use Kyber rather than Dilithium (i.e. set LEAF_ALG=Kyber512).

2. Configure and compile Botan

./configure.py --build-targets=static,cli --without-documentation
make

3. Run the KEMTLS client

This step assumes that the rustls server is running on port 8443.
The ./botan tls_client will perform a TLS handshake and then wait for application data on stdin. Simply enter "GET /" to communicate with the rustls server after a successful handshake.

./botan tls_client --policy=src/tests/data/tls-policy/kemtls.txt --port=8443 localhost

Note that the underlying TLS 1.3 implementation will detect the KEMTLS negotiation in the Server Hello and will behave accordingly. Hence, the ./botan tls_client invocation will happily speak with cloudflare.com as well.

At the time of this writing the Dilithium2 implementation was still under way. Once this is done, one should be able to verify the KEMTLS test server's certificate chain with:

./botan tls_client --policy=src/tests/data/tls-policy/kemtls.txt --port=8443 --skip-system-cert-store --trusted-cas=kemtls.root.pem localhost

Obtaining kemtls.root.pem

After generating the docker image, pull up a container from it:

docker run --rm -it <image identifier> /bin/sh

And extract the freshly generated root certificate:

cat kem-ca.crt

Store this PEM container as kemtls.root.pem and launch the Botan KEMTLS client as stated above.

References

[1] Schwabe, Peter, Douglas Stebila, and Thom Wiggers. "Post-quantum TLS without handshake signatures." Proceedings of the 2020 ACM SIGSAC Conference on Computer and Communications Security. 2020.

@reneme reneme marked this pull request as draft April 7, 2022 10:30
Copy link

@thomwiggers thomwiggers left a comment

Choose a reason for hiding this comment

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

Neat! I don't know C++ well enough to comment anything useful, but it looks convincing 😉

#if defined(BOTAN_HAS_KYBER)
// TODO: those OIDs are taken from thomwiggers/mk-cert for interoperability
// https://github.com/thomwiggers/mk-cert/blob/dd845f3825d8dc5fd69e0e234f6a62266ee4dd4a/algorithms.py#L84
if(alg_name == "1.3.6.1.4.1.44363.46.52")

Choose a reason for hiding this comment

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

This should work, I just want to emphasise that these OIDs aren't stable: if I add algorithms to mk-cert they tend to move around.

(Also I'm completely unsure whose OID namespace I cribbed)

Copy link
Author

Choose a reason for hiding this comment

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

FWIW: For the OIDs in the current Kyber integration in Botan we followed this IETF draft.

throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Rejecting " + key->algo_name() + " signature");
}
policy.check_peer_key_acceptable(*public_key());

Choose a reason for hiding this comment

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

Maybe you want to add a todo here?

const auto master_secret = hkdf_extract(secure_vector<uint8_t>(m_hash->output_length(), 0x00));

// Note: these labels differ from the research paper to comply with thomwiggers rustls implementation.
// https://thomwiggers.nl/publication/kemtls/kemtls.pdf

Choose a reason for hiding this comment

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

In the paper we were pretty space-constrained 😅

@reneme
Copy link
Author

reneme commented Jun 14, 2022

This now includes verification of certificates signed by Dilithium. It is not (yet) interoperable with the certificates generated by the KEMTLS reference implementation. Though, after this issue is sorted out and this experimental code is rebased accordingly, Dilithium-based certificates should be verifyable.

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.

3 participants