Skip to content

Commit 799d6fc

Browse files
authored
Merge branch 'main' into feat/update-fibs-policy
2 parents 2c44a0d + 7d2102f commit 799d6fc

File tree

14 files changed

+313
-34
lines changed

14 files changed

+313
-34
lines changed

api/s2n.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,7 @@ typedef enum {
26502650
S2N_TLS_SIGNATURE_ANONYMOUS = 0,
26512651
S2N_TLS_SIGNATURE_RSA = 1,
26522652
S2N_TLS_SIGNATURE_ECDSA = 3,
2653+
S2N_TLS_SIGNATURE_MLDSA = 9,
26532654

26542655
/* Use Private Range for RSA PSS since it's not defined there */
26552656
S2N_TLS_SIGNATURE_RSA_PSS_RSAE = 224,
@@ -3482,6 +3483,9 @@ S2N_API extern int s2n_async_pkey_op_get_input_size(struct s2n_async_pkey_op *op
34823483
*
34833484
* When signing, the input is the digest to sign.
34843485
* When decrypting, the input is the data to decrypt.
3486+
*
3487+
* When signing with ML-DSA, the input is the "external mu" pre-hash value described in
3488+
* https://www.ietf.org/archive/id/draft-ietf-lamps-dilithium-certificates-09.html#appendix-D
34853489
*
34863490
* # Safety
34873491
* * `data` must be sufficiently large to contain the input.

bin/echo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const char *sig_alg_strs[] = {
4040
[S2N_TLS_SIGNATURE_ECDSA] = "ECDSA",
4141
[S2N_TLS_SIGNATURE_RSA_PSS_RSAE] = "RSA-PSS-RSAE",
4242
[S2N_TLS_SIGNATURE_RSA_PSS_PSS] = "RSA-PSS-PSS",
43+
[S2N_TLS_SIGNATURE_MLDSA] = "MLDSA",
4344
};
4445

4546
const char *sig_hash_strs[] = {

bindings/rust/extended/s2n-tls/src/enums.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ pub enum SignatureAlgorithm {
189189
RSA_PSS_RSAE,
190190
RSA_PSS_PSS,
191191
ECDSA,
192+
MLDSA,
192193
}
193194

194195
impl TryFrom<s2n_tls_signature_algorithm::Type> for SignatureAlgorithm {
@@ -200,6 +201,7 @@ impl TryFrom<s2n_tls_signature_algorithm::Type> for SignatureAlgorithm {
200201
s2n_tls_signature_algorithm::RSA_PSS_RSAE => Self::RSA_PSS_RSAE,
201202
s2n_tls_signature_algorithm::RSA_PSS_PSS => Self::RSA_PSS_PSS,
202203
s2n_tls_signature_algorithm::ECDSA => Self::ECDSA,
204+
s2n_tls_signature_algorithm::MLDSA => Self::MLDSA,
203205
_ => return Err(Error::INVALID_INPUT),
204206
};
205207
Ok(version)

bindings/rust/standard/integration/Cargo.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ no-network-tests = []
1616

1717
# Not all libcryptos support PQ capabilities. Tests relying on PQ functionality
1818
# can be disabled by turning off this feature.
19-
pq = []
19+
pq = [ "s2n-tls/pq" ]
2020

2121
[dependencies]
2222
s2n-tls = { path = "../../extended/s2n-tls", features = ["unstable-testing"]}
@@ -25,7 +25,9 @@ s2n-tls-tokio = { path = "../../extended/s2n-tls-tokio" }
2525
s2n-tls-sys = { path = "../../extended/s2n-tls-sys" }
2626

2727
[dev-dependencies]
28+
openssl = { version = "0.10", features = ["vendored"] }
2829
tokio = { version = "1", features = ["macros", "test-util"] }
30+
tokio-openssl = { version = "0.6.5" }
2931

3032
tracing = "0.1"
3133
tracing-subscriber = "0.3"
@@ -36,3 +38,10 @@ http-body-util = "0.1"
3638
bytes = "1.8"
3739
hyper = "1.5"
3840
hyper-util = "0.1"
41+
42+
[build-dependencies]
43+
# The ML-DSA tests require the ML-DSA support added in Openssl-3.5
44+
# Since this overrides the dependency from the openssl-src crate,
45+
# the features are copied from the openssl-src crate's Cargo.toml:
46+
# https://github.com/sfackler/rust-openssl/blob/eb88fb0533c3593cc2fff6d03cf2befea8ecbe27/openssl-sys/Cargo.toml#L31
47+
openssl-src = { version = "300.5", optional = true, features = ["legacy"] }
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use openssl::ssl::{Ssl, SslContextBuilder, SslFiletype, SslMethod};
5+
use s2n_tls::{config::Config, enums::SignatureAlgorithm, security::DEFAULT_PQ};
6+
use s2n_tls_tokio::{TlsAcceptor, TlsConnector};
7+
use std::{fs, path::Path, pin::Pin};
8+
use tokio::net::{TcpListener, TcpStream};
9+
use tokio_openssl::SslStream;
10+
11+
const TEST_PEMS_PATH: &'static str =
12+
concat!(env!("CARGO_MANIFEST_DIR"), "/../../../../tests/pems/");
13+
14+
pub async fn get_streams() -> Result<(TcpStream, TcpStream), tokio::io::Error> {
15+
let localhost = "127.0.0.1".to_owned();
16+
let listener = TcpListener::bind(format!("{}:0", localhost)).await?;
17+
let addr = listener.local_addr()?;
18+
let client_stream = TcpStream::connect(&addr).await?;
19+
let (server_stream, _) = listener.accept().await?;
20+
Ok((server_stream, client_stream))
21+
}
22+
23+
#[test_log::test(tokio::test)]
24+
async fn s2n_client() -> Result<(), Box<dyn std::error::Error>> {
25+
let cert_path = format!("{TEST_PEMS_PATH}mldsa/ML-DSA-87.crt");
26+
let key_path = format!("{TEST_PEMS_PATH}mldsa/ML-DSA-87-seed.priv");
27+
28+
let (server_stream, client_stream) = get_streams().await?;
29+
30+
// Setup Openssl server with ML-DSA certs
31+
let mut server = {
32+
let mut builder = SslContextBuilder::new(SslMethod::tls())?;
33+
builder.set_private_key_file(key_path, SslFiletype::PEM)?;
34+
builder.set_certificate_chain_file(cert_path.clone())?;
35+
let context = builder.build();
36+
let ssl = Ssl::new(&context)?;
37+
SslStream::new(ssl, server_stream)?
38+
};
39+
40+
// Setup s2n-tls client with default_pq
41+
let client = {
42+
let mut config = Config::builder();
43+
config.set_security_policy(&DEFAULT_PQ)?;
44+
config.trust_location(Some(Path::new(&cert_path)), None)?;
45+
TlsConnector::new(config.build()?)
46+
};
47+
48+
let server_pin = Pin::new(&mut server);
49+
let (_, client_result) = tokio::join!(
50+
server_pin.accept(),
51+
// The test certs are copied from the original RFC,
52+
// so s2n-tls expects "LAMPS-WG" as the server name. See:
53+
// https://github.com/lamps-wg/dilithium-certificates/blob/5b23428b08a53aacdb89d93422b81228433e34d8/examples/ML-DSA-87.crt.txt#L40-L42
54+
client.connect("LAMPS WG", client_stream),
55+
);
56+
57+
let client = client_result?;
58+
let conn = client.as_ref();
59+
assert_eq!(
60+
conn.selected_signature_algorithm()?,
61+
SignatureAlgorithm::MLDSA
62+
);
63+
Ok(())
64+
}
65+
66+
#[test_log::test(tokio::test)]
67+
async fn s2n_server() -> Result<(), Box<dyn std::error::Error>> {
68+
let cert_path = format!("{TEST_PEMS_PATH}mldsa/ML-DSA-87.crt");
69+
let key_path = format!("{TEST_PEMS_PATH}mldsa/ML-DSA-87-seed.priv");
70+
71+
let (server_stream, client_stream) = get_streams().await?;
72+
73+
// Setup Openssl client
74+
let mut client = {
75+
let mut builder = SslContextBuilder::new(SslMethod::tls())?;
76+
builder.set_ca_file(Path::new(&cert_path))?;
77+
let context = builder.build();
78+
let ssl = Ssl::new(&context)?;
79+
SslStream::new(ssl, client_stream)?
80+
};
81+
82+
// Setup s2n-tls server with ML-DSA certs
83+
let server = {
84+
let mut config = Config::builder();
85+
config.set_security_policy(&DEFAULT_PQ)?;
86+
let cert = fs::read(cert_path)?;
87+
let key = fs::read(key_path)?;
88+
config.load_pem(&cert, &key)?;
89+
TlsAcceptor::new(config.build()?)
90+
};
91+
92+
let client_pin = Pin::new(&mut client);
93+
let (server_result, _) = tokio::join!(server.accept(server_stream), client_pin.connect(),);
94+
95+
let server = server_result?;
96+
let conn = server.as_ref();
97+
assert_eq!(
98+
conn.selected_signature_algorithm()?,
99+
SignatureAlgorithm::MLDSA
100+
);
101+
Ok(())
102+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#[cfg(feature = "pq")]
5+
mod mldsa;

bindings/rust/standard/integration/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
#[cfg(test)]
5+
mod features;
46
#[cfg(all(not(feature = "no-network-tests"), test))]
57
mod network;
68

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
# Post Quantum (PQ) Support
22

3-
s2n-tls supports post-quantum key exchange for TLS1.3. Currently, only [Kyber](https://pq-crystals.org/kyber/) is supported. See the draft IETF standard: https://datatracker.ietf.org/doc/html/draft-ietf-tls-hybrid-design
3+
s2n-tls supports both post-quantum key exchange and post-quantum authentication for TLS1.3.
44

5-
Specifically, s2n-tls supports hybrid key exchange. PQ hybrid key exchange involves performing both classic ECDH key exchange and post-quantum Kyber key exchange, then combining the two resultant secrets. This strategy combines the high assurance of the classical key exchange algorithms with the quantum-resistance of the new post-quantum key exchange algorithms. If one of the two algorithms is compromised, either because advances in quantum computing make the classic algorithms insecure or because cryptographers find a flaw in the relatively new post-quantum algorithms, the secret is still secure. Hybrid post-quantum key exchange is more secure than standard key exchange, but is slower and requires more processing and more network bandwidth.
5+
## Key Exchange: ML-KEM / Kyber
6+
7+
Currently, only [ML-KEM](https://csrc.nist.gov/pubs/fips/203) / [Kyber](https://pq-crystals.org/kyber/) are supported for post-quantum key exchange. "ML-KEM" is the name given to the NIST standardized version of Kyber.
8+
9+
Specifically, s2n-tls supports hybrid key exchange. PQ hybrid key exchange involves performing both classic ECDH key exchange and post-quantum key exchange, then combining the two resultant secrets. This strategy combines the high assurance of the classical key exchange algorithms with the quantum-resistance of the new post-quantum key exchange algorithms. If one of the two algorithms is compromised, either because advances in quantum computing make the classic algorithms insecure or because cryptographers find a flaw in the relatively new post-quantum algorithms, the secret is still secure. Hybrid post-quantum key exchange is more secure than standard key exchange, but is slower and requires more processing and more network bandwidth.
610

711
Careful: An s2n-tls server that enables post-quantum cryptography will mandate post-quantum key exchange with any client advertising post-quantum algorithms. This can result in a retry and an extra round trip if the client does not initially send a post-quantum key share. The rational behind this behavior is that post-quantum users prioritize security over the potential cost of an extra round trip.
812

13+
## Authentication: ML-DSA
14+
15+
Currently, only [ML-DSA](https://csrc.nist.gov/pubs/fips/204) is supported for post-quantum authentication.
16+
17+
In order to use ML-DSA, you must configure s2n-tls to use an ML-DSA certificate, just as you would configure an RSA or ECDSA certificate. See [certificates](./ch09-certificates.md).
18+
919
## Requirements
1020

1121
### AWS-LC
1222

13-
s2n-tls must be built with aws-lc to use post-quantum key exchange. See the [s2n-tls build documentation](https://github.com/aws/s2n-tls/blob/main/docs/BUILD.md#building-with-a-specific-libcrypto) for how to build with aws-lc.
23+
s2n-tls must be built with aws-lc to use post-quantum algorithms. See the [s2n-tls build documentation](https://github.com/aws/s2n-tls/blob/main/docs/BUILD.md#building-with-a-specific-libcrypto) for how to build with aws-lc. For ML-DSA, you will need to use a version of AWS-LC >= v1.50.0 (API version 33).
1424

1525
If you're unsure what cryptography library s2n-tls is built against, trying running s2nd or s2nc:
1626
```
@@ -21,17 +31,18 @@ Listening on localhost:8000
2131

2232
### Security Policy
2333

24-
Post-quantum key exchange is enabled by configuring a security policy (see [Security Policies](./ch06-security-policies.md)) that supports post-quantum key exchange algorithms.
34+
Post-quantum algorithms are enabled by configuring a security policy (see [Security Policies](./ch06-security-policies.md)) that supports post-quantum algorithms.
2535

26-
"default_pq" is the equivalent of "default_tls13", but with PQ support. Like the other default policies, "default_pq" may change as a result of library updates. The fixed, numbered equivalent of "default_pq" is currently "20240730". For previous defaults, see the "Default Policy History" section below.
36+
"default_pq" is the equivalent of "default_tls13", but with PQ support. Like the other default policies, "default_pq" may change as a result of library updates. The fixed, numbered equivalent of "default_pq" is currently "20250512". For previous defaults, see the "Default Policy History" section below.
2737

2838
Other available PQ policies are compared in the tables below.
2939

3040
### Chart: Security Policy Version To PQ Hybrid Key Exchange Methods
3141

3242
| Version | secp256r1+kyber768 | x25519+kyber768 | secp384r1+kyber768 | secp521r1+kyber1024 | secp256r1+kyber512 | x25519+kyber512 |
3343
|-----------------------|--------------------|-----------------|--------------------|---------------------|--------------------|-----------------|
34-
| default_pq / 20240730 | X | X | X | X | X | X |
44+
| default_pq / 20250512 | X | X | X | X | X | X |
45+
| 20240730 | X | X | X | X | X | X |
3546
| PQ-TLS-1-2-2023-12-15 | X | | X | X | X | |
3647
| PQ-TLS-1-2-2023-12-14 | X | | X | X | X | |
3748
| PQ-TLS-1-2-2023-12-13 | X | | X | X | X | |
@@ -41,13 +52,29 @@ Other available PQ policies are compared in the tables below.
4152
| PQ-TLS-1-2-2023-10-07 | X | X | X | X | X | X |
4253
| PQ-TLS-1-3-2023-06-01 | X | X | X | X | X | X |
4354

55+
### Chart: Security Policy Version To Signature Schemes
56+
57+
| Version | ML-DSA | ECDSA | RSA | RSA-PSS | Legacy SHA1 |
58+
|-----------------------|--------|-------|-----|---------|-------------|
59+
| default_pq / 20250512 | X | X | X | X | |
60+
| 20240730 | | X | X | X | |
61+
| PQ-TLS-1-2-2023-12-15 | | X | X | X | |
62+
| PQ-TLS-1-2-2023-12-14 | | X | X | X | |
63+
| PQ-TLS-1-2-2023-12-13 | | X | X | X | |
64+
| PQ-TLS-1-2-2023-10-10 | | X | X | X | X |
65+
| PQ-TLS-1-2-2023-10-09 | | X | X | X | X |
66+
| PQ-TLS-1-2-2023-10-08 | | X | X | X | X |
67+
| PQ-TLS-1-2-2023-10-07 | | X | X | X | X |
68+
| PQ-TLS-1-3-2023-06-01 | | X | X | X | X |
69+
4470
### Chart: Security Policy Version To Classic Key Exchange
4571

4672
If the peer doesn't support a PQ hybrid key exchange method, s2n-tls will fall back to a classical option.
4773

4874
| Version | secp256r1 | x25519 | secp384r1 | secp521r1 | DHE | RSA |
4975
|-----------------------|-----------|--------|-----------|-----------|-----|-----|
50-
| default_pq / 20240730 | X | X | X | X | | |
76+
| default_pq / 20250512 | X | X | X | X | | |
77+
| 20240730 | X | X | X | X | | |
5178
| PQ-TLS-1-2-2023-12-15 | X | | X | X | X | |
5279
| PQ-TLS-1-2-2023-12-14 | X | | X | X | | |
5380
| PQ-TLS-1-2-2023-12-13 | X | | X | X | | X |
@@ -61,7 +88,8 @@ If the peer doesn't support a PQ hybrid key exchange method, s2n-tls will fall b
6188

6289
| Version | AES-CBC | AES-GCM | CHACHAPOLY | 3DES |
6390
|-----------------------|---------|---------|------------|------|
64-
| default_pq / 20240730 | X | X | X | |
91+
| default_pq / 20250512 | X | X | X | |
92+
| 20240730 | X | X | X | |
6593
| PQ-TLS-1-2-2023-12-15 | X | X | | |
6694
| PQ-TLS-1-2-2023-12-14 | X | X | | |
6795
| PQ-TLS-1-2-2023-12-13 | X | X | | |
@@ -72,25 +100,12 @@ If the peer doesn't support a PQ hybrid key exchange method, s2n-tls will fall b
72100
| PQ-TLS-1-3-2023-06-01 | X | X | X* | X |
73101
\* only for TLS1.3
74102

75-
### Chart: Security Policy Version To Signature Schemes
76-
77-
| Version | ECDSA | RSA | RSA-PSS | Legacy SHA1 |
78-
|-----------------------|---------|-----|---------|-------------|
79-
| default_pq / 20240730 | X | X | X | |
80-
| PQ-TLS-1-2-2023-12-15 | X | X | X | |
81-
| PQ-TLS-1-2-2023-12-14 | X | X | X | |
82-
| PQ-TLS-1-2-2023-12-13 | X | X | X | |
83-
| PQ-TLS-1-2-2023-10-10 | X | X | X | X |
84-
| PQ-TLS-1-2-2023-10-09 | X | X | X | X |
85-
| PQ-TLS-1-2-2023-10-08 | X | X | X | X |
86-
| PQ-TLS-1-2-2023-10-07 | X | X | X | X |
87-
| PQ-TLS-1-3-2023-06-01 | X | X | X | X |
88-
89103
### Chart: Security Policy Version To TLS Protocol Version
90104

91105
| Version | 1.2 | 1.3 |
92106
|-----------------------|-----|-----|
93-
| default_pq / 20240730 | X | X |
107+
| default_pq / 20250512 | X | X |
108+
| 20240730 | X | X |
94109
| PQ-TLS-1-2-2023-12-15 | X | X |
95110
| PQ-TLS-1-2-2023-12-14 | X | X |
96111
| PQ-TLS-1-2-2023-12-13 | X | X |
@@ -103,7 +118,8 @@ If the peer doesn't support a PQ hybrid key exchange method, s2n-tls will fall b
103118
#### Default Policy History
104119
| Version | "default_pq" |
105120
|------------|--------------|
106-
| v1.5.0 | 20240730 |
121+
| v1.5.19 | 20250512 |
122+
| v1.5.0 | 20240730 |
107123

108124
## Visibility
109125
Call `s2n_connection_get_kem_group_name` to determine if a TLS handshake negotiated PQ key exchange.

tests/unit/s2n_connection_test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ int main(int argc, char **argv)
302302
[S2N_SIGNATURE_ECDSA] = S2N_TLS_SIGNATURE_ECDSA,
303303
[S2N_SIGNATURE_RSA_PSS_RSAE] = S2N_TLS_SIGNATURE_RSA_PSS_RSAE,
304304
[S2N_SIGNATURE_RSA_PSS_PSS] = S2N_TLS_SIGNATURE_RSA_PSS_PSS,
305+
[S2N_SIGNATURE_MLDSA] = S2N_TLS_SIGNATURE_MLDSA,
305306
};
306307

307308
for (size_t i = 0; i <= UINT16_MAX; i++) {

0 commit comments

Comments
 (0)