1 //! A tool for handling data related to the hardware root-of-trust.
2
3 use anyhow::Result;
4 use clap::{Parser, Subcommand, ValueEnum};
5 use hwtrust::dice;
6 use hwtrust::session::{Options, Session};
7 use std::fs;
8
9 #[derive(Parser)]
10 /// A tool for handling data related to the hardware root-of-trust
11 #[clap(name = "hwtrust")]
12 struct Args {
13 #[clap(subcommand)]
14 action: Action,
15 }
16
17 #[derive(Subcommand)]
18 enum Action {
19 VerifyDiceChain(VerifyDiceChainArgs),
20 }
21
22 #[derive(Parser)]
23 /// Verify that a DICE chain is well-formed
24 ///
25 /// DICE chains are expected to follow the specification of the RKP HAL [1] which is based on the
26 /// Open Profile for DICE [2].
27 ///
28 /// [1] -- https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
29 /// [2] -- https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md
30 struct VerifyDiceChainArgs {
31 /// Dump the DICE chain on the standard output
32 #[clap(long)]
33 dump: bool,
34
35 /// Path to a file containing a DICE chain
36 chain: String,
37
38 /// The VSR version to validate against. If omitted, the set of rules that are used have no
39 /// compromises or workarounds and new implementations should validate against them as it will
40 /// be the basis for future VSR versions.
41 #[clap(long, value_enum)]
42 vsr: Option<VsrVersion>,
43 }
44
45 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
46 enum VsrVersion {
47 /// VSR 13 / Android T / 2022
48 Vsr13,
49 /// VSR 14 / Android U / 2023
50 Vsr14,
51 }
52
main() -> Result<()>53 fn main() -> Result<()> {
54 let args = Args::parse();
55 let Action::VerifyDiceChain(sub_args) = args.action;
56 let session = Session {
57 options: match sub_args.vsr {
58 Some(VsrVersion::Vsr13) => Options::vsr13(),
59 Some(VsrVersion::Vsr14) => Options::vsr14(),
60 None => Options::default(),
61 },
62 };
63 let chain = dice::Chain::from_cbor(&session, &fs::read(sub_args.chain)?)?;
64 println!("Success!");
65 if sub_args.dump {
66 print!("{}", chain);
67 }
68 Ok(())
69 }
70
71 #[cfg(test)]
72 mod tests {
73 use super::*;
74 use clap::CommandFactory;
75
76 #[test]
verify_command()77 fn verify_command() {
78 Args::command().debug_assert();
79 }
80 }
81