Skip to content

Commit 1639022

Browse files
committed
Add tools to support key & policy auto generation and auto update td info into tcb_mapping.json
Signed-off-by: Wei Liu <[email protected]>
1 parent be197ed commit 1639022

File tree

4 files changed

+196
-7
lines changed

4 files changed

+196
-7
lines changed

sh_script/build_policy_v2.sh

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
config_temp_dir="./config/templates"
5+
key_dir="./key"
6+
7+
environment="${1:-pre-production}"
8+
case "$environment" in
9+
pre-production|preprod)
10+
collateral_file="collateral_pre_production_fmspc.json"
11+
;;
12+
production|prod)
13+
collateral_file="collateral_production_fmspc.json"
14+
;;
15+
*)
16+
echo "Usage: $0 <pre-production|production>"
17+
exit 1
18+
;;
19+
esac
20+
21+
echo "Selected collateral environment '$environment' using $collateral_file"
22+
23+
# Build migtd-collateral-generator and generate collateral_pre_production_fmspc.json
24+
# cargo build -p migtd-collateral-generator
25+
# ./target/debug/migtd-collateral-generator \
26+
# -o $config_temp_dir/collateral_pre_production_fmspc.json \
27+
# --pre-production
28+
29+
# Build json-signer and sign td_identity.json
30+
cargo build -p json-signer
31+
./target/debug/json-signer --sign \
32+
--name tdIdentity \
33+
--private-key $key_dir/issuer_pkcs8.key \
34+
--input $config_temp_dir/td_identity.json \
35+
--output $config_temp_dir/td_identity_signed.json
36+
37+
# Sign tcb_mapping.json
38+
./target/debug/json-signer --sign \
39+
--name tdTcbMapping \
40+
--private-key $key_dir/issuer_pkcs8.key \
41+
--input $config_temp_dir/tcb_mapping.json \
42+
--output $config_temp_dir/tcb_mapping_signed.json
43+
44+
# Build servtd-collateral-generator and generate servtd_collateral.json
45+
cargo build -p servtd-collateral-generator
46+
./target/debug/servtd-collateral-generator \
47+
--identity $config_temp_dir/td_identity_signed.json \
48+
--identity-chain $key_dir/migtd_issuer_chain.pem \
49+
--mapping $config_temp_dir/tcb_mapping_signed.json \
50+
--mapping-chain $key_dir/migtd_issuer_chain.pem \
51+
-o $config_temp_dir/servtd_collateral.json
52+
53+
# Build migtd-policy-generator and generate policy_v2.json
54+
cargo build -p migtd-policy-generator
55+
./target/debug/migtd-policy-generator v2 \
56+
--policy-data $config_temp_dir/policy_v2.json \
57+
--collaterals $config_temp_dir/../$collateral_file \
58+
--servtd-collateral $config_temp_dir/servtd_collateral.json \
59+
-o $config_temp_dir/policy_v2.json
60+
61+
# Sign policy_v2.json
62+
./target/debug/json-signer --sign \
63+
--name policyData \
64+
--private-key $key_dir/issuer_pkcs8.key \
65+
--input $config_temp_dir/policy_v2.json \
66+
--output $config_temp_dir/policy_v2_signed.json

sh_script/key_gen.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Set output directory
5+
OUTPUT_DIR="key"
6+
mkdir -p "$OUTPUT_DIR"
7+
8+
# 1. Create the Root CA Key and Certificate
9+
openssl ecparam -name secp384r1 -genkey -noout -out "$OUTPUT_DIR/ca.key"
10+
if [ ! -s "$OUTPUT_DIR/ca.key" ]; then
11+
echo "Error: Root CA key ($OUTPUT_DIR/ca.key) was not generated successfully." >&2
12+
exit 1
13+
fi
14+
openssl req -x509 -new -nodes -key "$OUTPUT_DIR/ca.key" -sha384 -days 3650 -out "$OUTPUT_DIR/root_ca.crt" -subj "/C=US/ST=CA/L=Santa Clara/O=MigTD Issuer/CN=MigTD Root CA"
15+
16+
# 2. Create the Intermediate CA Key and Certificate
17+
openssl ecparam -name secp384r1 -genkey -noout -out "$OUTPUT_DIR/intermediate_ca.key"
18+
if [ ! -s "$OUTPUT_DIR/intermediate_ca.key" ]; then
19+
echo "Error: Intermediate CA key ($OUTPUT_DIR/intermediate_ca.key) was not generated successfully." >&2
20+
exit 1
21+
fi
22+
openssl req -new -nodes -key "$OUTPUT_DIR/intermediate_ca.key" -sha384 -out "$OUTPUT_DIR/intermediate_ca.csr" -subj "/C=US/ST=CA/L=Santa Clara/O=MigTD Intermediate Issuer/CN=MigTD Intermediate CA"
23+
openssl x509 -req -in "$OUTPUT_DIR/intermediate_ca.csr" -CA "$OUTPUT_DIR/root_ca.crt" -CAkey "$OUTPUT_DIR/ca.key" -CAcreateserial -sha384 -days 1825 -out "$OUTPUT_DIR/intermediate_ca.crt"
24+
25+
# 3. Create the End-Entity (Server/Client) Key and Certificate
26+
openssl ecparam -name secp384r1 -genkey -noout -out "$OUTPUT_DIR/issuer.key"
27+
if [ ! -s "$OUTPUT_DIR/issuer.key" ]; then
28+
echo "Error: End-Entity key ($OUTPUT_DIR/issuer.key) was not generated successfully." >&2
29+
exit 1
30+
fi
31+
openssl req -new -nodes -key "$OUTPUT_DIR/issuer.key" -sha384 -out "$OUTPUT_DIR/issuer.csr" -subj "/C=US/ST=CA/L=Santa Clara/O=MigTD Issuer/CN=MigTD Info Issuer"
32+
openssl x509 -req -in "$OUTPUT_DIR/issuer.csr" -CA "$OUTPUT_DIR/intermediate_ca.crt" -CAkey "$OUTPUT_DIR/intermediate_ca.key" -CAcreateserial -sha384 -days 365 -out "$OUTPUT_DIR/issuer.crt"
33+
34+
# 4. Concat them into cert chain
35+
cat "$OUTPUT_DIR/issuer.crt" "$OUTPUT_DIR/intermediate_ca.crt" "$OUTPUT_DIR/root_ca.crt" > "$OUTPUT_DIR/migtd_issuer_chain.pem"
36+
37+
# 5. Convert issuer key to PKCS8
38+
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in "$OUTPUT_DIR/issuer.key" -out "$OUTPUT_DIR/issuer_pkcs8.key"
39+
40+
if [ ! -s "$OUTPUT_DIR/issuer_pkcs8.key" ]; then
41+
echo "Error: PKCS8 key ($OUTPUT_DIR/issuer_pkcs8.key) was not generated successfully." >&2
42+
exit 1
43+
fi
44+
echo "Certificate chain and keys generated successfully in $OUTPUT_DIR."

tools/migtd-hash/readme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ popd
3232
./target/debug/migtd-hash --manifest config/servtd_info.json --image <migtd.bin> --verbose
3333
```
3434

35+
- Calculate migtd SERVTD_INFO_HASH and update tcb_mapping.json (For policy v2)
36+
```
37+
./target/debug/migtd-hash --manifest config/servtd_info.json --image <migtd.bin> --update-tcb-mapping <tcb_mapping.json> --policy-v2 --verbose
38+
```
39+
3540
- Generate migtd SERVTD_HASH with debug infomation:
3641
```
3742
./target/debug/migtd-hash --manifest config/servtd_info.json --image <migtd.bin> --servtd-attr 0 --calc-servtd-hash --verbose

tools/migtd-hash/src/main.rs

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,79 @@
22
//
33
// SPDX-License-Identifier: BSD-2-Clause-Patent
44

5+
use anyhow::{anyhow, Context};
56
use clap::Parser;
67
use log::debug;
78
use migtd_hash::{
89
build_td_info, calculate_servtd_hash, calculate_servtd_info_hash, SERVTD_TYPE_MIGTD,
910
};
10-
use serde_json::json;
11+
use serde_json::{json, Value};
1112
use std::{
1213
fs::{self, File},
13-
path::PathBuf,
14+
path::{Path, PathBuf},
1415
process::exit,
1516
};
1617

1718
const SERVTD_HASH_KEY: &str = "servtdHash";
1819
const SERVTD_INFO_HASH_KEY: &str = "servtdInfoHash";
1920

21+
fn bytes_to_hex(bytes: &[u8]) -> String {
22+
bytes.iter().map(|byte| format!("{:02x}", byte)).collect()
23+
}
24+
25+
fn update_tcb_mapping_file(
26+
path: &Path,
27+
mrtd: &[u8],
28+
rtmr0: &[u8],
29+
rtmr1: &[u8],
30+
) -> anyhow::Result<()> {
31+
let manifest =
32+
fs::read_to_string(path).with_context(|| format!("Failed to read {}", path.display()))?;
33+
let mut tcb_mapping: Value = serde_json::from_str(&manifest)
34+
.with_context(|| format!("Failed to parse {}", path.display()))?;
35+
36+
let svn_mappings = tcb_mapping
37+
.get_mut("svnMappings")
38+
.and_then(Value::as_array_mut)
39+
.ok_or_else(|| {
40+
anyhow!(
41+
"'svnMappings' missing or not an array in {}",
42+
path.display()
43+
)
44+
})?;
45+
let td_measurements = svn_mappings
46+
.get_mut(0)
47+
.ok_or_else(|| anyhow!("'svnMappings' array is empty in {}", path.display()))?
48+
.get_mut("tdMeasurements")
49+
.and_then(Value::as_object_mut)
50+
.ok_or_else(|| {
51+
anyhow!(
52+
"'tdMeasurements' missing or not an object in {}",
53+
path.display()
54+
)
55+
})?;
56+
57+
for (key, value) in [("mrtd", mrtd), ("rtmr0", rtmr0), ("rtmr1", rtmr1)] {
58+
if !td_measurements.contains_key(key) {
59+
eprintln!("Warning: '{}' not found in tdMeasurements, adding it.", key);
60+
}
61+
td_measurements.insert(
62+
key.to_string(),
63+
Value::String(bytes_to_hex(value).to_uppercase()),
64+
);
65+
}
66+
67+
let serialized = serde_json::to_string(&tcb_mapping).with_context(|| {
68+
format!(
69+
"Failed to serialize updated tcb mapping for {}",
70+
path.display()
71+
)
72+
})?;
73+
fs::write(path, serialized)
74+
.with_context(|| format!("Failed to write updated tcb mapping to {}", path.display()))?;
75+
println!("Updated {} successfully.", path.display());
76+
Ok(())
77+
}
2078
#[derive(Clone, Parser)]
2179
struct Config {
2280
/// A json format manifest that contains values of TD info fields
@@ -49,6 +107,9 @@ struct Config {
49107
/// Enable verbose logging
50108
#[clap(short, long)]
51109
pub verbose: bool,
110+
/// Update the provided tcb_mapping JSON with the generated TD measurements
111+
#[clap(long)]
112+
pub update_tcb_mapping: Option<PathBuf>,
52113
}
53114

54115
fn main() {
@@ -157,11 +218,11 @@ fn main() {
157218
if let Some(output_td_info) = config.output_td_info {
158219
debug!("Writing TD Info to: {:?}", output_td_info);
159220
let td_info_json = json!({
160-
"mrtd": td_info.mrtd.iter().map(|b| format!("{:02x}", b)).collect::<String>(),
161-
"rtmr0": td_info.rtmr0.iter().map(|b| format!("{:02x}", b)).collect::<String>(),
162-
"rtmr1": td_info.rtmr1.iter().map(|b| format!("{:02x}", b)).collect::<String>(),
163-
"rtmr2": td_info.rtmr2.iter().map(|b| format!("{:02x}", b)).collect::<String>(),
164-
"rtmr3": td_info.rtmr3.iter().map(|b| format!("{:02x}", b)).collect::<String>(),
221+
"mrtd": bytes_to_hex(&td_info.mrtd),
222+
"rtmr0": bytes_to_hex(&td_info.rtmr0),
223+
"rtmr1": bytes_to_hex(&td_info.rtmr1),
224+
"rtmr2": bytes_to_hex(&td_info.rtmr2),
225+
"rtmr3": bytes_to_hex(&td_info.rtmr3),
165226
});
166227

167228
fs::write(
@@ -174,6 +235,19 @@ fn main() {
174235
})
175236
}
176237

238+
debug!("Updating tcb_mapping file...");
239+
if let Some(tcb_mapping_path) = &config.update_tcb_mapping {
240+
if let Err(e) = update_tcb_mapping_file(
241+
tcb_mapping_path,
242+
&td_info.mrtd,
243+
&td_info.rtmr0,
244+
&td_info.rtmr1,
245+
) {
246+
eprintln!("Failed to update tcb_mapping file: {}", e);
247+
exit(1);
248+
}
249+
}
250+
177251
debug!("Calculating servtd_info_hash...");
178252
let servtd_info_hash = calculate_servtd_info_hash(td_info).unwrap_or_else(|e| {
179253
eprintln!("Failed to calculate hash: {:?}", e);

0 commit comments

Comments
 (0)