Skip to content

Commit

Permalink
Merge pull request #530 from tlsfuzzer/ml-kem
Browse files Browse the repository at this point in the history
support for ML-KEM hybrid key exchange groups
  • Loading branch information
tomato42 authored Oct 18, 2024
2 parents ba52c6b + bfae6e1 commit 6342bda
Show file tree
Hide file tree
Showing 8 changed files with 460 additions and 39 deletions.
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

0 comments on commit 6342bda

Please sign in to comment.