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 Post-Quantum Cryptography (PQC) Algorithms for TLS 1.3 Key Exchange #1560

Closed
wants to merge 8 commits into from

Conversation

yuhh0328
Copy link
Contributor

Description:
Hi, I've made some changes to the key exchange mechanism in TLS 1.3 by incorporating Post-Quantum Cryptography (PQC) algorithms.

Changes:

  • Add kyber algorithms to the NamedGroup.
  • Add TlsAgreement for PQC algorithms. (BcTlsKyber, JceTlsKyber)
  • Add TlsPQCKemMode to distinguish Client / Server, and move receivePeerValue() forward than generateEphemeral().
  • We do not add PQC namedGroups to CANDIDATES_DEFAULT. So in order to use PQC namedGroups, you must set the "jdk.tls.namedGroups".
    (java -Djdk.tls.namedGroups=kyber1024,x25519,x448 ClientExample)

Questions:

  • NamedGroupInfo.hanAnyECDSA() was temporarily modified to use PQC namedGroups with ECDSA certificate. Where is a better location than here?
  • We've added TlsPQCKemMode to distinguish Client / Server, is there any good way to distinguish without this?

I'd be happy to address any feedback or questions you may have.
Thank you for your time and consideration!
Best regards,
hunhee

@yuhh0328
Copy link
Contributor Author

Hello, Is the review still in progress?
code for ec-kyber-hybrid, edec-kyber-hybrid are also prepared.

@roy-basmacier
Copy link

@yuhh0328

  • NamedGroupInfo.hanAnyECDSA() was temporarily modified to use PQC namedGroups with ECDSA certificate. Where is a better location than here?

Modifiying the NamedGroupInfo changes are wrong and presumably unnecessary. Proir to TLS 1.3, signature schemes based on ECDSA could function without specifying a particular curve. The "hasAnyECDSA" determined whether a NamedGroup supported such schemes. I might be mistakened, is it applicable to the PQC Groups?

  • We've added TlsPQCKemMode to distinguish Client / Server, is there any good way to distinguish without this?

TlsPQCKemMode isn't needed. The TlsCryptoParameters interface would be a better way of distinguishing between Client/Server. It would be better to pass a TlsCryptoParameters implementation inside of TlsPQCDomain.createPQC()

Can you clean up these two things? Then we can take over the rest.

Another note that things shouldn't be named for their "PQC"-ness, but instead for the type of algorithm/functionality, presumably "KEM" in many cases here.

@yuhh0328
Copy link
Contributor Author

@roy-basmacier @lee-changhoon

  1. It has been changed to use "TlsCryptoParameters" to distinguish client/server. (TlsPQCKemMode has been deleted)
  2. "PQC" has been changed to "KEM".
  3. "hasAnyECDSA" is back to its original code.
    ※ To use the KEM namedGroups with ECDSA certificate, the EC namedGroup must be included in the "jdk.tls.namedGroups".
    (jdk.tls.namedGroups=kyber512,kyber768,kyber1024,secp384r1)

@@ -102,6 +102,10 @@ public class NamedGroup
public static final int arbitrary_explicit_prime_curves = 0xFF01;
public static final int arbitrary_explicit_char2_curves = 0xFF02;

public static final int kyber512 = 0x023A;
Copy link

@hwupathum hwupathum Mar 26, 2024

Choose a reason for hiding this comment

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

As mentioned in #1578, the NIST round 3 implementation of Kyber is used in liboqs and FIPS implementation is used in BouncyCastle for the oids mentioned in this PR.

| kyber512 | 0x023A | Yes | OQS_CODEPOINT_KYBER512 |

In liboqs, the FIPS implementation uses a separate OID and a separate name

| mlkem512 | 0x0247 | Yes | OQS_CODEPOINT_MLKEM512 |

Therefore to keep interoperability between BC and liboqs, we need to support both NIST3 and FIPS implementations for BC. Specially since both Cloudflare and Google chrome supports X25519Kyber768 which used NIST round 3 implementation of Kyber. It is important to support the older KEMs as well.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@hwupathum Note that that issue is stale. In 0.10.0, liboqs now includes draft ML-KEM in addition to round 3 Kyber.

Copy link

@hwupathum hwupathum Mar 26, 2024

Choose a reason for hiding this comment

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

Yes, but as I mentioned the algorithm IDs are different between liboqs and BC. Therefore if I try to do a TLS handshake between a BC and liboqs with kyber768, it fails due to algorithm id mismatch. Also if I try to use mlkem768 in liboqs, the handshake fails due to shared secret mismatch.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@hwupathum Yes, I would expect the first to fail, because Round 3 Kyber and draft ML-DSA are different.

The latter I would've expected to succeed. I'd suggest we should fix the compatibility for this case.

I don't think support for Round 3 Kyber will remain once NIST publishes drafts. I'd imagine both Cloudflare and Google will update fairly quickly to the standardized (non-draft) ML-KEM implementation.

@hwupathum
Copy link

Currently, BC only look at the priority of NamedGroups in Djdk.tls.namedGroups if X25519 or secp256r1 is not in the list as mentioned in https://github.com/bcgit/bc-java/blob/main/tls/src/main/java/org/bouncycastle/tls/AbstractTlsClient.java#L409.

If I create a BC client with the list of Namedgroups [kyber768,X25519], it will only send X25519 shared keys only while a client with liboqs provider will send the both pairs of keys. IMO it is preferred if we can support sending a standard NameGroup alongside the PQC ones as a fallback option, since most of the other clients and the servers still does not support PQC NamedGroups.

@cipherboy cipherboy self-assigned this Apr 1, 2024
Copy link
Collaborator

@cipherboy cipherboy left a comment

Choose a reason for hiding this comment

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

Looks fairly good! I think Roy will merge the patch set, but mostly I'm nitpicking around naming things as ML-KEM going forward. :-)

Thank you!

ffdhe8192(NamedGroup.ffdhe8192, "DiffieHellman");
ffdhe8192(NamedGroup.ffdhe8192, "DiffieHellman"),

kyber512(NamedGroup.kyber512, "KEM"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

These are incorrect. We only support ML-KEM (FIPS draft), not round 3 Kyber.

import org.bouncycastle.tls.crypto.TlsSecret;
import org.bouncycastle.util.Arrays;

public class BcTlsKyber implements TlsAgreement
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd rename this as well to BcTlsMlKem perhaps :-)

(Comments apply below as well)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Might be good to drop a reference to https://datatracker.ietf.org/doc/draft-connolly-tls-mlkem-key-agreement/ as well.

return crypto.adoptLocalSecret(secret);
}

public SecretWithEncapsulation enCap(KyberPublicKeyParameters peerPublicKey)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd make this all lowercase personally. "encapsulate" is all one word :-)

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.

4 participants