opentitanlib/chip/
helper.rs

1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5use 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    /// Applies the parameters to the unlock request.
32    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    /// Reads an unlock request (or creates a default request) and applies the aprameters.
58    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    /// Applies the parameters to the activate request.
85    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    /// Reads an activate request (or creates a default request) and applies the parameters.
104    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}