opentitanlib/chip/
helper.rs1use crate::chip::boot_svc::{OwnershipActivateRequest, OwnershipUnlockRequest, UnlockMode};
6use crate::crypto::ecdsa::{EcdsaPrivateKey, EcdsaPublicKey, EcdsaRawPublicKey, EcdsaRawSignature};
7use crate::util::parse_int::ParseInt;
8use anyhow::Result;
9use clap::Args;
10use std::fs::File;
11use std::io::Read;
12use std::path::PathBuf;
13
14#[derive(Debug, Default, Args)]
15pub struct OwnershipUnlockParams {
16 #[arg(long, value_enum, help = "Requested unlock mode")]
17 pub mode: Option<UnlockMode>,
18 #[arg(long, value_parser = u64::from_str, help="Current ROM_EXT nonce")]
19 pub nonce: Option<u64>,
20 #[arg(long, value_parser = u64::from_str, help="Device Identification Number of the chip")]
21 pub din: Option<u64>,
22 #[arg(long, help = "A path to the next owner key (for endorsed mode)")]
23 pub next_owner: Option<PathBuf>,
24 #[arg(long, help = "A path to a detached signature for the unlock request")]
25 pub signature: Option<PathBuf>,
26 #[arg(long, help = "A path to a private key to sign the request")]
27 pub sign: Option<PathBuf>,
28}
29
30impl OwnershipUnlockParams {
31 pub fn apply(&self, unlock: &mut OwnershipUnlockRequest) -> Result<()> {
33 if let Some(mode) = &self.mode {
34 unlock.unlock_mode = *mode;
35 }
36 if let Some(nonce) = &self.nonce {
37 unlock.nonce = *nonce;
38 }
39 if let Some(din) = &self.din {
40 unlock.din = *din;
41 }
42 if let Some(next_owner) = &self.next_owner {
43 let key = EcdsaPublicKey::load(next_owner)?;
44 unlock.next_owner_key = EcdsaRawPublicKey::try_from(&key)?;
45 }
46 if let Some(signature) = &self.signature {
47 let mut f = File::open(signature)?;
48 unlock.signature = EcdsaRawSignature::read(&mut f)?;
49 }
50 if let Some(sign) = &self.sign {
51 let key = EcdsaPrivateKey::load(sign)?;
52 unlock.sign(&key)?;
53 }
54 Ok(())
55 }
56
57 pub fn apply_to(&self, reader: Option<&mut impl Read>) -> Result<OwnershipUnlockRequest> {
59 let mut unlock = if let Some(r) = reader {
60 let mut data = Vec::new();
61 r.read_to_end(&mut data)?;
62 OwnershipUnlockRequest::try_from(data.as_slice())?
63 } else {
64 OwnershipUnlockRequest::default()
65 };
66 self.apply(&mut unlock)?;
67 Ok(unlock)
68 }
69}
70
71#[derive(Debug, Default, Args)]
72pub struct OwnershipActivateParams {
73 #[arg(long, value_parser = u64::from_str, help="Current ROM_EXT nonce")]
74 pub nonce: Option<u64>,
75 #[arg(long, value_parser = u64::from_str, help="Device Identification Number of the chip")]
76 pub din: Option<u64>,
77 #[arg(long, help = "A path to a detached signature for the activate request")]
78 pub signature: Option<PathBuf>,
79 #[arg(long, help = "A path to a private key to sign the request")]
80 pub sign: Option<PathBuf>,
81}
82
83impl OwnershipActivateParams {
84 pub fn apply(&self, activate: &mut OwnershipActivateRequest) -> Result<()> {
86 if let Some(nonce) = &self.nonce {
87 activate.nonce = *nonce;
88 }
89 if let Some(din) = &self.din {
90 activate.din = *din;
91 }
92 if let Some(signature) = &self.signature {
93 let mut f = File::open(signature)?;
94 activate.signature = EcdsaRawSignature::read(&mut f)?;
95 }
96 if let Some(sign) = &self.sign {
97 let key = EcdsaPrivateKey::load(sign)?;
98 activate.sign(&key)?;
99 }
100 Ok(())
101 }
102
103 pub fn apply_to(&self, reader: Option<&mut impl Read>) -> Result<OwnershipActivateRequest> {
105 let mut activate = if let Some(r) = reader {
106 let mut data = Vec::new();
107 r.read_to_end(&mut data)?;
108 OwnershipActivateRequest::try_from(data.as_slice())?
109 } else {
110 OwnershipActivateRequest::default()
111 };
112 self.apply(&mut activate)?;
113 Ok(activate)
114 }
115}