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

support for ML-KEM hybrid key exchange groups #530

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,26 @@ jobs:
os: ubuntu-latest
python-version: '3.11'
opt-deps: ['brotli', 'zstd']
- name: py3.12with brotli and zstandard
- name: py3.12 with brotli and zstandard
os: ubuntu-latest
python-version: '3.12'
opt-deps: ['brotli', 'zstd']
- name: py3.9 with kyber-py
os: ubuntu-latest
python-version: "3.9"
opt-deps: ["kyber_py"]
- name: py3.10 with kyber-py
os: ubuntu-latest
python-version: "3.10"
opt-deps: ["kyber_py"]
- name: py3.11 with kyber-py
os: ubuntu-latest
python-version: "3.11"
opt-deps: ["kyber_py"]
- name: py3.12 with kyber-py
os: ubuntu-latest
python-version: "3.12"
opt-deps: ["kyber_py"]
# finally test with multiple dependencies installed at the same time
- name: py2.7 with m2crypto, pycrypto, gmpy, gmpy2, and brotli
os: ubuntu-20.04
Expand All @@ -204,22 +220,22 @@ jobs:
- name: py3.9 with m2crypto, gmpy, gmpy2, brotli, and zstandard
os: ubuntu-latest
python-version: 3.9
opt-deps: ['m2crypto', 'gmpy', 'gmpy2', 'brotli', 'zstd']
opt-deps: ['m2crypto', 'gmpy', 'gmpy2', 'brotli', 'zstd', 'kyber_py']
- name: py3.10 with m2crypto, gmpy, gmpy2, brotli, and zstandard
os: ubuntu-latest
python-version: '3.10'
opt-deps: ['m2crypto', 'gmpy', 'gmpy2', 'brotli', 'zstd']
opt-deps: ['m2crypto', 'gmpy', 'gmpy2', 'brotli', 'zstd', 'kyber_py']
- name: py3.11 with m2crypto, gmpy, gmpy2, brotli, and zstandard
os: ubuntu-latest
python-version: '3.11'
# gmpy doesn't build with 3.11
opt-deps: ['m2crypto', 'gmpy2', 'brotli', 'zstd']
opt-deps: ['m2crypto', 'gmpy2', 'brotli', 'zstd', 'kyber_py']
- name: py3.12 with m2crypto, gmpy, gmpy2, brotli, and zstandard
os: ubuntu-latest
python-version: '3.12'
# gmpy doesn't build with 3.12
# coverage to codeclimate can be submitted just once
opt-deps: ['m2crypto', 'gmpy2', 'codeclimate', 'brotli', 'zstd']
opt-deps: ['m2crypto', 'gmpy2', 'codeclimate', 'brotli', 'zstd', 'kyber_py']
steps:
- uses: actions/checkout@v2
if: ${{ !matrix.container }}
Expand Down Expand Up @@ -346,6 +362,9 @@ jobs:
- name: Install zstandard for py3.8 and after
if: ${{ contains(matrix.opt-deps, 'zstd') }}
run: pip install zstandard
- name: Install kyber_py
if: ${{ contains(matrix.opt-deps, 'kyber_py') }}
run: pip install "https://github.com/GiacomoPope/kyber-py/archive/b187189a514b3327578928c1d4c901d34592678e.zip"
- name: Install build dependencies (2.6)
if: ${{ matrix.python-version == '2.6' }}
run: |
Expand Down
7 changes: 6 additions & 1 deletion scripts/tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
GroupName, SignatureScheme
from tlslite.handshakesettings import Keypair, VirtualHost
from tlslite import __version__
from tlslite.utils.compat import b2a_hex, a2b_hex, time_stamp
from tlslite.utils.compat import b2a_hex, a2b_hex, time_stamp, \
ML_KEM_AVAILABLE
from tlslite.utils.dns_utils import is_valid_hostname
from tlslite.utils.cryptomath import getRandomBytes
from tlslite.constants import KeyUpdateMessageType
Expand Down Expand Up @@ -76,6 +77,10 @@ def printUsage(s=None):
print(" GMPY2 : Loaded")
else:
print(" GMPY2 : Not Loaded")
if ML_KEM_AVAILABLE:
print(" Kyber-py : Loaded")
else:
print(" Kyber-py : Not Loaded")

print("")
print("Certificate compression algorithms:")
Expand Down
8 changes: 7 additions & 1 deletion tlslite/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,13 @@ class GroupName(TLSEnum):
brainpoolP512r1tls13 = 33
allEC.extend(list(range(31, 34)))

all = allEC + allFF
# draft-kwiatkowski-tls-ecdhe-mlkem
secp256r1mlkem768 = 0x11EB
x25519mlkem768 = 0x11EC
secp384r1mlkem1024 = 0x11ED
allKEM = [0x11EB, 0x11EC, 0x11ED]

all = allEC + allFF + allKEM

@classmethod
def toRepr(cls, value, blacklist=None):
Expand Down
19 changes: 14 additions & 5 deletions tlslite/handshakesettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .constants import CertificateType
from .utils import cryptomath
from .utils import cipherfactory
from .utils.compat import ecdsaAllCurves, int_types
from .utils.compat import ecdsaAllCurves, int_types, ML_KEM_AVAILABLE
from .utils.compression import compression_algo_impls

CIPHER_NAMES = ["chacha20-poly1305",
Expand All @@ -34,10 +34,14 @@
ALL_RSA_SIGNATURE_HASHES = RSA_SIGNATURE_HASHES + ["md5"]
SIGNATURE_SCHEMES = ["Ed25519", "Ed448"]
RSA_SCHEMES = ["pss", "pkcs1"]
CURVE_NAMES = []
if ML_KEM_AVAILABLE:
CURVE_NAMES += ["secp256r1mlkem768", "x25519mlkem768",
"secp384r1mlkem1024"]
# while secp521r1 is the most secure, it's also much slower than the others
# so place it as the last one
CURVE_NAMES = ["x25519", "x448", "secp384r1", "secp256r1",
"secp521r1"]
CURVE_NAMES += ["x25519", "x448", "secp384r1", "secp256r1",
"secp521r1"]
ALL_CURVE_NAMES = CURVE_NAMES + ["secp256k1", "brainpoolP512r1",
"brainpoolP384r1", "brainpoolP256r1"]
if ecdsaAllCurves:
Expand All @@ -57,7 +61,8 @@
TLS13_PERMITTED_GROUPS = ["secp256r1", "secp384r1", "secp521r1",
"x25519", "x448", "ffdhe2048",
"ffdhe3072", "ffdhe4096", "ffdhe6144",
"ffdhe8192"]
"ffdhe8192", "secp256r1mlkem768", "x25519mlkem768",
"secp384r1mlkem1024"]
KNOWN_VERSIONS = ((3, 0), (3, 1), (3, 2), (3, 3), (3, 4))
TICKET_CIPHERS = ["chacha20-poly1305", "aes256gcm", "aes128gcm", "aes128ccm",
"aes128ccm_8", "aes256ccm", "aes256ccm_8"]
Expand Down Expand Up @@ -395,7 +400,11 @@ def _init_key_settings(self):
self.dhParams = None
self.dhGroups = list(ALL_DH_GROUP_NAMES)
self.defaultCurve = "secp256r1"
self.keyShares = ["secp256r1", "x25519"]
if ML_KEM_AVAILABLE:
self.keyShares = ["x25519mlkem768"]
else:
self.keyShares = []
self.keyShares += ["secp256r1", "x25519"]
self.padding_cb = None
self.use_heartbeat_extension = True
self.heartbeat_response_callback = None
Expand Down
Loading
Loading