1use bytemuck::{Pod, Zeroable};
2
3use crate::*;
4
5pub const SIGBLOCK_LEN: usize = 768;
7pub const UNSIGNED_LEN: usize = SignatureInFlash::sealed_data_offset();
9
10pub const SIGNATURE_LENGTH: usize = 64; pub const PUBLIC_KEY_LENGTH: usize = 32; pub const AAD_LENGTH: usize = 60; #[repr(u32)]
17#[derive(num_enum::TryFromPrimitive, PartialEq, Eq, Clone, Copy)]
18pub enum FunctionCode {
19 Invalid = 0,
21 Boot0 = 1,
23 Boot1 = 2,
25 UpdatedBoot1 = 3,
29 Loader = 4,
31 UpdatedLoader = 5,
32 Baremetal = 6,
34 UpdatedBaremetal = 7,
35 Kernel = 0x1_00,
37 UpdatedKernel = 0x1_01,
38 Swap = 0x80_00,
40 UpdatedSwap = 0x80_01,
41 App = 0x10_0000,
43 UpdatedApp = 0x10_0001,
44}
45
46impl FunctionCode {
47 pub fn to_anti_rollback_counter(&self) -> Option<usize> {
48 match self {
49 Self::Boot0 => Some(BOOT0_ANTI_ROLLBACK),
50 Self::Boot1 | Self::UpdatedBoot1 => Some(BOOT1_ANTI_ROLLBACK),
51 Self::Loader | Self::UpdatedLoader => Some(LOADER_ANTI_ROLLBACK),
52 Self::Kernel | Self::UpdatedKernel => Some(KERNEL_ANTI_ROLLBACK),
53 Self::Swap | Self::UpdatedSwap => Some(SWAP_ANTI_ROLLBACK),
54 Self::App | Self::UpdatedApp => Some(APP_ANTI_ROLLBACK),
55 Self::Baremetal | Self::UpdatedBaremetal => Some(BAREMETAL_ANTI_ROLLBACK),
56 _ => None,
57 }
58 }
59}
60
61pub const BAOCHIP_SIG_VERSION: u32 = 0x1_00;
62pub const PADDING_LEN: usize = SIGBLOCK_LEN - size_of::<SignatureInFlash>();
63pub const MAGIC_NUMBER: [u32; 2] = [u32::from_be_bytes(*b"yumy"), u32::from_be_bytes(*b"Bao3")];
64#[repr(C)]
66#[derive(Copy, Clone)]
67pub struct SignatureInFlash {
68 pub _jal_instruction: u32,
71 pub signature: [u8; SIGNATURE_LENGTH],
73 pub aad_len: u32,
81 pub aad: [u8; AAD_LENGTH],
82 pub sealed_data: SealedFields,
84}
85unsafe impl Zeroable for SignatureInFlash {}
86unsafe impl Pod for SignatureInFlash {}
87impl AsRef<[u8]> for SignatureInFlash {
88 fn as_ref(&self) -> &[u8] { bytemuck::bytes_of(self) }
89}
90impl AsMut<[u8]> for SignatureInFlash {
91 fn as_mut(&mut self) -> &mut [u8] { bytemuck::bytes_of_mut(self) }
92}
93impl Default for SignatureInFlash {
94 fn default() -> Self {
95 Self {
96 _jal_instruction: 0,
97 signature: [0u8; SIGNATURE_LENGTH],
98 aad_len: 0,
99 aad: [0u8; AAD_LENGTH],
100 sealed_data: SealedFields::default(),
101 }
102 }
103}
104impl SignatureInFlash {
105 pub const fn sealed_data_offset() -> usize {
107 size_of::<u32>() + SIGNATURE_LENGTH + size_of::<u32>() + AAD_LENGTH
108 }
109}
110
111#[repr(C)]
112#[derive(Copy, Clone)]
113pub struct Pubkey {
114 pub pk: [u8; PUBLIC_KEY_LENGTH],
115 pub tag: [u8; 4],
116}
117unsafe impl Zeroable for Pubkey {}
118unsafe impl Pod for Pubkey {}
119impl Default for Pubkey {
120 fn default() -> Self { Self { pk: [0u8; PUBLIC_KEY_LENGTH], tag: [0u8; 4] } }
121}
122impl Pubkey {
123 pub fn populate_from(&mut self, record: &Pubkey) {
124 self.pk.copy_from_slice(&record.pk);
125 self.tag.copy_from_slice(&record.tag);
126 }
127}
128
129#[repr(C)]
130#[derive(Copy, Clone, Pod, Zeroable)]
131pub struct SealedFields {
132 pub version: u32,
134 pub magic: [u32; 2],
136 pub signed_len: u32,
138 pub function_code: u32,
141 pub anti_rollback: u32,
144 pub min_semver: [u8; 16],
147 pub semver: [u8; 16],
149 pub pubkeys: [Pubkey; 4],
165}
166
167impl AsRef<[u8]> for SealedFields {
168 fn as_ref(&self) -> &[u8] { bytemuck::bytes_of(self) }
169}
170impl Default for SealedFields {
171 fn default() -> Self {
172 Self {
173 version: BAOCHIP_SIG_VERSION,
174 magic: MAGIC_NUMBER,
175 signed_len: 0,
176 function_code: 0,
177 anti_rollback: 0,
178 min_semver: [0u8; 16],
179 semver: [0u8; 16],
180 pubkeys: [Pubkey::default(); 4],
181 }
182 }
183}
184
185#[derive(Debug, Clone, Copy, Pod, Zeroable)]
186#[repr(C)]
187pub struct SwapSourceHeader {
188 pub version: u32,
189 pub partial_nonce: [u8; 8],
190 pub mac_offset: u32,
191 pub aad_len: u32,
192 pub aad: [u8; 64],
194}
195impl AsRef<[u8]> for SwapSourceHeader {
196 fn as_ref(&self) -> &[u8] { bytemuck::bytes_of(self) }
197}
198impl Default for SwapSourceHeader {
199 fn default() -> Self {
200 Self { version: 0, partial_nonce: [0; 8], mac_offset: 0, aad_len: 0, aad: [0; 64] }
201 }
202}
203
204#[repr(C)]
205#[derive(Debug, Clone, Copy, Pod, Zeroable, Default)]
206pub struct SwapDescriptor {
207 pub ram_offset: u32,
208 pub ram_size: u32,
209 pub name: u32,
210 pub key: [u8; 32],
211 pub flash_offset: u32,
212}
213impl AsRef<[u8]> for SwapDescriptor {
214 fn as_ref(&self) -> &[u8] { bytemuck::bytes_of(self) }
215}