22//
33// SPDX-License-Identifier: BSD-2-Clause-Patent
44
5+ use anyhow:: { anyhow, Context } ;
56use clap:: Parser ;
67use log:: debug;
78use 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 } ;
1112use std:: {
1213 fs:: { self , File } ,
13- path:: PathBuf ,
14+ path:: { Path , PathBuf } ,
1415 process:: exit,
1516} ;
1617
1718const SERVTD_HASH_KEY : & str = "servtdHash" ;
1819const 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 ) ]
2179struct 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
54115fn 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