Skip to main content

bao1x_api/pubkeys/
mod.rs

1use crate::signatures::{FunctionCode, Pubkey};
2
3pub mod bao1;
4pub mod bao2;
5pub mod beta;
6pub mod developer;
7
8pub const BAO1_KEY_SLOT: usize = 0;
9pub const BAO2_KEY_SLOT: usize = 1;
10pub const BETA_KEY_SLOT: usize = 2;
11pub const DEVELOPER_KEY_SLOT: usize = 3;
12
13/// Nominal purposes of pub key slots:
14///   - slot 0 is Baochip secured signing key 1
15///   - slot 1 is Baochip secured signing key 2
16///   - slot 2 is a Beta signing key. It's kept in a secured token but also available in a development
17///     environment.
18///   - slot 3 is the Developer signing key. It's a well-known key that anyone can use to sign an image. If
19///     revoked, it is not a valid signing key. When not revoked, upon being presented with an image signed by
20///     this, the bootloader will automatically erase all device-local secrets.
21///
22/// The dual signing keys for Baochip allows for a laddered upgrade path in case a signing key
23/// needs to be replaced, upgraded, or cycled out for any reason.
24pub const KEYSLOT_INITIAL_TAGS: [&'static [u8; 4]; 4] = [b"bao1", b"bao2", b"beta", b"dev "];
25
26// helper function to pad arrays out, if needed. Previously used for auth_data until
27// I realized that auth_data changes with every signing.
28#[allow(dead_code)]
29const fn pad_array<const N: usize, const M: usize>(input: &[u8; N]) -> [u8; M] {
30    let mut result = [0u8; M];
31    let mut i = 0;
32    while i < N && i < M {
33        result[i] = input[i];
34        i += 1;
35    }
36    result
37}
38
39/// This is the exported record that should be copied into the header of all boot images
40pub const PUBKEY_HEADER: [Pubkey; 4] = [bao1::PUBKEY, bao2::PUBKEY, beta::PUBKEY, developer::PUBKEY];
41
42/// This structure defines a security configuration
43///
44/// `image_ptr`: a `*const u32` pointer to the base of the firmware image being configured
45/// `pubkey_ptr`: a `*const u32` pointer to the public keys used to validate the image at `image_ptr`
46/// `revocation_owc`: a `usize` number that is the one-way counter index that defines the beginning of the
47/// primary revocation counter bank. The duplicate bank is inferred based on the expected fixed offset to
48/// the duplicate bank.
49/// `function_codes`: a `&'static [u32]` that contains the allowable function codes for the image. The
50/// function codes are a domain separator that prevent an image meant for one stage of boot being used for
51/// another.
52#[derive(Copy, Clone)]
53pub struct SecurityConfiguration {
54    pub image_ptr: *const u32,
55    pub pubkey_ptr: *const u32,
56    pub revocation_owc: usize,
57    pub function_codes: &'static [u32],
58}
59
60pub const BOOT0_SELF_CHECK: SecurityConfiguration = SecurityConfiguration {
61    image_ptr: crate::BOOT0_START as *const u32,
62    pubkey_ptr: crate::BOOT0_START as *const u32,
63    revocation_owc: crate::BOOT0_REVOCATION_OFFSET,
64    function_codes: &[FunctionCode::Boot0 as u32],
65};
66
67pub const BOOT0_TO_BOOT1: SecurityConfiguration = SecurityConfiguration {
68    image_ptr: crate::BOOT1_START as *const u32,
69    pubkey_ptr: crate::BOOT0_START as *const u32,
70    revocation_owc: crate::BOOT0_REVOCATION_OFFSET,
71    function_codes: &[FunctionCode::Boot1 as u32, FunctionCode::UpdatedBoot1 as u32],
72};
73
74/// This is different from a jump directly to loader/baremetal because the
75/// function codes *must* be for Boot1 or Baremetal. Loader is not a valid option.
76pub const BOOT0_TO_ALTBOOT1: SecurityConfiguration = SecurityConfiguration {
77    image_ptr: crate::LOADER_START as *const u32,
78    pubkey_ptr: crate::BOOT0_START as *const u32,
79    revocation_owc: crate::BOOT0_REVOCATION_OFFSET,
80    function_codes: &[
81        FunctionCode::Boot1 as u32,
82        FunctionCode::UpdatedBoot1 as u32,
83        FunctionCode::Baremetal as u32,
84    ],
85};
86
87pub const BOOT1_TO_LOADER_OR_BAREMETAL: SecurityConfiguration = SecurityConfiguration {
88    image_ptr: crate::LOADER_START as *const u32,
89    pubkey_ptr: crate::BOOT1_START as *const u32,
90    revocation_owc: crate::BOOT1_REVOCATION_OFFSET,
91    function_codes: &[
92        FunctionCode::Baremetal as u32,
93        FunctionCode::UpdatedBaremetal as u32,
94        FunctionCode::Loader as u32,
95        FunctionCode::UpdatedLoader as u32,
96    ],
97};
98
99pub const LOADER_TO_KERNEL: SecurityConfiguration = SecurityConfiguration {
100    image_ptr: crate::KERNEL_START as *const u32,
101    pubkey_ptr: crate::LOADER_START as *const u32,
102    revocation_owc: crate::LOADER_REVOCATION_OFFSET,
103    function_codes: &[FunctionCode::Kernel as u32, FunctionCode::UpdatedKernel as u32],
104};
105
106pub const LOADER_TO_DETACHED_APP: SecurityConfiguration = SecurityConfiguration {
107    image_ptr: crate::offsets::dabao::APP_RRAM_START as *const u32,
108    pubkey_ptr: crate::LOADER_START as *const u32,
109    revocation_owc: crate::LOADER_REVOCATION_OFFSET,
110    function_codes: &[FunctionCode::App as u32, FunctionCode::UpdatedApp as u32],
111};
112
113pub const LOADER_TO_SWAP: SecurityConfiguration = SecurityConfiguration {
114    image_ptr: (crate::offsets::baosec::SWAP_HEADER_LEN - crate::signatures::SIGBLOCK_LEN) as *const u32,
115    pubkey_ptr: crate::LOADER_START as *const u32,
116    revocation_owc: crate::LOADER_REVOCATION_OFFSET,
117    function_codes: &[FunctionCode::Swap as u32, FunctionCode::UpdatedSwap as u32],
118};