Skip to content

Commit 9e558af

Browse files
committed
Add pqc_config.json and fix responder-emu PQC cert chain loading
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
1 parent 6e086e1 commit 9e558af

3 files changed

Lines changed: 86 additions & 57 deletions

File tree

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,9 @@ SPDM 1.4 introduces Post-Quantum Cryptography (PQC) support. spdm-rs supports ML
244244
git submodule update --init --recursive external/aws-lc-rs
245245
```
246246

247-
2. Build with the `spdm-aws-lc` feature:
247+
2. Build with the `spdm-aws-lc` feature and `pqc_config.json` (PQC signatures and key exchanges require larger buffer sizes than the default configuration):
248248
```
249+
export SPDM_CONFIG="etc/pqc_config.json"
249250
cargo build -p spdm-requester-emu -p spdm-responder-emu --no-default-features --features "spdm-ring,hashed-transcript-data,async-executor,spdm-aws-lc"
250251
```
251252

@@ -254,18 +255,19 @@ cargo build -p spdm-requester-emu -p spdm-responder-emu --no-default-features --
254255
Currently PQC is supported in raw public key mode (RFC 7250). Set the following environment variables to enable PQC:
255256

256257
```
258+
export SPDM_CONFIG="etc/pqc_config.json"
257259
export SPDMRS_USE_PQC=true
258260
export SPDMRS_USE_RAW_PUB_KEY=true
259261
```
260262

261263
Open one command window and run the responder:
262264
```
263-
SPDMRS_USE_PQC=true SPDMRS_USE_RAW_PUB_KEY=true cargo run -p spdm-responder-emu --no-default-features --features "spdm-ring,hashed-transcript-data,async-executor,spdm-aws-lc"
265+
SPDM_CONFIG="etc/pqc_config.json" SPDMRS_USE_PQC=true SPDMRS_USE_RAW_PUB_KEY=true cargo run -p spdm-responder-emu --no-default-features --features "spdm-ring,hashed-transcript-data,async-executor,spdm-aws-lc"
264266
```
265267

266268
Open another command window and run the requester:
267269
```
268-
SPDMRS_USE_PQC=true SPDMRS_USE_RAW_PUB_KEY=true cargo run -p spdm-requester-emu --no-default-features --features "spdm-ring,hashed-transcript-data,async-executor,spdm-aws-lc"
270+
SPDM_CONFIG="etc/pqc_config.json" SPDMRS_USE_PQC=true SPDMRS_USE_RAW_PUB_KEY=true cargo run -p spdm-requester-emu --no-default-features --features "spdm-ring,hashed-transcript-data,async-executor,spdm-aws-lc"
269271
```
270272

271273
This exercises the full SPDM handshake with ML-DSA-87 for signature and ML-KEM-1024 for key exchange, including: GET_VERSION, GET_CAPABILITIES, NEGOTIATE_ALGORITHMS, CHALLENGE, GET_MEASUREMENTS, KEY_EXCHANGE, FINISH, HEARTBEAT, KEY_UPDATE, GET_MEASUREMENTS (in-session), END_SESSION, PSK_EXCHANGE, PSK_FINISH, and END_SESSION.
@@ -274,6 +276,7 @@ This exercises the full SPDM handshake with ML-DSA-87 for signature and ML-KEM-1
274276

275277
| Variable | Description |
276278
|---|---|
279+
| `SPDM_CONFIG` | Set to `"etc/pqc_config.json"` for PQC builds (larger buffers for ML-DSA signatures and cert chains) |
277280
| `SPDMRS_USE_PQC` | Set to `true` to enable PQC-only mode (ML-DSA-87 + ML-KEM-1024) |
278281
| `SPDMRS_USE_RAW_PUB_KEY` | Set to `true` to use raw public key (RFC 7250) instead of certificate chain |
279282

spdmlib/etc/pqc_config.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"__usage": "config for PQC (ML-DSA + ML-KEM) support with larger buffers for PQC signatures and cert chains",
3+
"cert_config": {
4+
"max_cert_chain_data_size": 24576
5+
},
6+
"measurement_config": {
7+
"max_measurement_record_size": 4000,
8+
"max_measurement_val_len": 1024
9+
},
10+
"psk_config": {
11+
"max_psk_context_size": 64,
12+
"max_psk_hint_size": 32
13+
},
14+
"max_opaque_list_elements_count": 3,
15+
"max_session_count": 4,
16+
"transport_config": {
17+
"sender_buffer_size": 8256,
18+
"receiver_buffer_size": 8256
19+
},
20+
"max_spdm_msg_size": 8192,
21+
"heartbeat_period_value": 240,
22+
"max_root_cert_support": 10
23+
}

test/spdm-responder-emu/src/main.rs

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -372,61 +372,64 @@ async fn handle_message(
372372
..Default::default()
373373
};
374374

375-
// Check for environment variable or use default cert chain path
376-
let cert_chain_path = std::env::var("SPDMRS_RSP_EMU_CERT_CHAIN_PATH").ok();
377-
378-
if let Some(chain_path) = cert_chain_path {
379-
// Load pre-assembled cert chain from single DER file
380-
println!("Loading certificate chain from: {}", chain_path);
381-
let cert_chain = std::fs::read(&chain_path)
382-
.unwrap_or_else(|e| panic!("Unable to read cert chain from {}: {}", chain_path, e));
383-
let chain_len = cert_chain.len();
384-
println!("Loaded certificate chain size: {:?}", chain_len);
385-
my_cert_chain_data.data_size = chain_len as u32;
386-
my_cert_chain_data.data[0..chain_len].copy_from_slice(&cert_chain);
387-
} else {
388-
// Use default individual cert files
389-
let ca_file_path = if use_pqc {
390-
"test_key/mldsa87/ca.cert.der"
391-
} else if use_ecdsa() {
392-
"test_key/ecp384/ca.cert.der"
393-
} else {
394-
"test_key/rsa3072/ca.cert.der"
395-
};
396-
let ca_cert = std::fs::read(ca_file_path).expect("unable to read ca cert!");
397-
let inter_file_path = if use_pqc {
398-
"test_key/mldsa87/inter.cert.der"
399-
} else if use_ecdsa() {
400-
"test_key/ecp384/inter.cert.der"
375+
if !use_raw_pub_key {
376+
// Check for environment variable or use default cert chain path
377+
let cert_chain_path = std::env::var("SPDMRS_RSP_EMU_CERT_CHAIN_PATH").ok();
378+
379+
if let Some(chain_path) = cert_chain_path {
380+
// Load pre-assembled cert chain from single DER file
381+
println!("Loading certificate chain from: {}", chain_path);
382+
let cert_chain = std::fs::read(&chain_path)
383+
.unwrap_or_else(|e| panic!("Unable to read cert chain from {}: {}", chain_path, e));
384+
let chain_len = cert_chain.len();
385+
println!("Loaded certificate chain size: {:?}", chain_len);
386+
my_cert_chain_data.data_size = chain_len as u32;
387+
my_cert_chain_data.data[0..chain_len].copy_from_slice(&cert_chain);
401388
} else {
402-
"test_key/rsa3072/inter.cert.der"
403-
};
404-
let inter_cert = std::fs::read(inter_file_path).expect("unable to read inter cert!");
405-
let leaf_file_path = if use_pqc {
406-
"test_key/mldsa87/end_responder.cert.der"
407-
} else if use_ecdsa() {
408-
"test_key/ecp384/end_responder.cert.der"
409-
} else {
410-
"test_key/rsa3072/end_responder.cert.der"
411-
};
412-
let leaf_cert = std::fs::read(leaf_file_path).expect("unable to read leaf cert!");
413-
414-
let ca_len = ca_cert.len();
415-
let inter_len = inter_cert.len();
416-
let leaf_len = leaf_cert.len();
417-
println!(
418-
"total cert size - {:?} = {:?} + {:?} + {:?}",
419-
ca_len + inter_len + leaf_len,
420-
ca_len,
421-
inter_len,
422-
leaf_len
423-
);
424-
my_cert_chain_data.data_size = (ca_len + inter_len + leaf_len) as u32;
425-
my_cert_chain_data.data[0..ca_len].copy_from_slice(ca_cert.as_ref());
426-
my_cert_chain_data.data[ca_len..(ca_len + inter_len)].copy_from_slice(inter_cert.as_ref());
427-
my_cert_chain_data.data[(ca_len + inter_len)..(ca_len + inter_len + leaf_len)]
428-
.copy_from_slice(leaf_cert.as_ref());
429-
}
389+
// Use default individual cert files
390+
let ca_file_path = if use_pqc {
391+
"test_key/mldsa87/ca.cert.der"
392+
} else if use_ecdsa() {
393+
"test_key/ecp384/ca.cert.der"
394+
} else {
395+
"test_key/rsa3072/ca.cert.der"
396+
};
397+
let ca_cert = std::fs::read(ca_file_path).expect("unable to read ca cert!");
398+
let inter_file_path = if use_pqc {
399+
"test_key/mldsa87/inter.cert.der"
400+
} else if use_ecdsa() {
401+
"test_key/ecp384/inter.cert.der"
402+
} else {
403+
"test_key/rsa3072/inter.cert.der"
404+
};
405+
let inter_cert = std::fs::read(inter_file_path).expect("unable to read inter cert!");
406+
let leaf_file_path = if use_pqc {
407+
"test_key/mldsa87/end_responder.cert.der"
408+
} else if use_ecdsa() {
409+
"test_key/ecp384/end_responder.cert.der"
410+
} else {
411+
"test_key/rsa3072/end_responder.cert.der"
412+
};
413+
let leaf_cert = std::fs::read(leaf_file_path).expect("unable to read leaf cert!");
414+
415+
let ca_len = ca_cert.len();
416+
let inter_len = inter_cert.len();
417+
let leaf_len = leaf_cert.len();
418+
println!(
419+
"total cert size - {:?} = {:?} + {:?} + {:?}",
420+
ca_len + inter_len + leaf_len,
421+
ca_len,
422+
inter_len,
423+
leaf_len
424+
);
425+
my_cert_chain_data.data_size = (ca_len + inter_len + leaf_len) as u32;
426+
my_cert_chain_data.data[0..ca_len].copy_from_slice(ca_cert.as_ref());
427+
my_cert_chain_data.data[ca_len..(ca_len + inter_len)]
428+
.copy_from_slice(inter_cert.as_ref());
429+
my_cert_chain_data.data[(ca_len + inter_len)..(ca_len + inter_len + leaf_len)]
430+
.copy_from_slice(leaf_cert.as_ref());
431+
}
432+
} // !use_raw_pub_key
430433

431434
let provision_info = if use_raw_pub_key {
432435
let pub_key_file_path = if use_pqc {

0 commit comments

Comments
 (0)