1#![deny(warnings)]
11#![deny(unused)]
12#![deny(unsafe_code)]
13
14use crate::with_unknown;
15use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
16
17pub const CHIP_MANIFEST_SIZE: u32 = 1024;
30
31pub const CHIP_MANIFEST_VERSION_MAJOR2: u16 = 0x0002;
34pub const CHIP_MANIFEST_VERSION_MINOR1: u16 = 0x6c47;
35pub const CHIP_MANIFEST_VERSION_MAJOR1: u16 = 0x71c3;
36pub const CHIP_MANIFEST_EXT_TABLE_COUNT: usize = 15;
37pub const MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL: u32 = 0xa5a5a5a5;
38pub const MANIFEST_EXT_ID_SPX_KEY: u32 = 0x94ac01ec;
39pub const MANIFEST_EXT_ID_SPX_SIGNATURE: u32 = 0xad77f84a;
40pub const MANIFEST_EXT_ID_IMAGE_TYPE: u32 = 0x494d4754;
41pub const MANIFEST_EXT_NAME_SPX_KEY: u32 = 0x30545845;
42pub const MANIFEST_EXT_NAME_SPX_SIGNATURE: u32 = 0x31545845;
43pub const MANIFEST_EXT_NAME_IMAGE_TYPE: u32 = 0x494d4754;
44pub const CHIP_ROM_EXT_IDENTIFIER: u32 = 0x4552544f;
45pub const CHIP_BL0_IDENTIFIER: u32 = 0x3042544f;
46pub const CHIP_ROM_EXT_SIZE_MIN: u32 = 8788;
47pub const CHIP_ROM_EXT_SIZE_MAX: u32 = 0x10000;
48pub const CHIP_BL0_SIZE_MIN: u32 = 8788;
49pub const CHIP_BL0_SIZE_MAX: u32 = 0x70000;
50
51with_unknown! {
52 pub enum ManifestKind: u32 {
53 RomExt = CHIP_ROM_EXT_IDENTIFIER,
54 Application = CHIP_BL0_IDENTIFIER,
55 }
56}
57
58#[repr(C)]
60#[derive(KnownLayout, Immutable, IntoBytes, FromBytes, Debug, Default)]
61pub struct Manifest {
62 pub signature: SigverifyBuffer,
63 pub usage_constraints: ManifestUsageConstraints,
64 pub pub_key: SigverifyBuffer,
65 pub address_translation: u32,
66 pub identifier: u32,
67 pub manifest_version: ManifestVersion,
68 pub signed_region_end: u32,
69 pub length: u32,
70 pub version_major: u32,
71 pub version_minor: u32,
72 pub security_version: u32,
73 pub timestamp: Timestamp,
74 pub binding_value: KeymgrBindingValue,
75 pub max_key_version: u32,
76 pub code_start: u32,
77 pub code_end: u32,
78 pub entry_point: u32,
79 pub extensions: ManifestExtTable,
80}
81
82#[repr(C)]
84#[derive(Immutable, IntoBytes, FromBytes, Debug, Default, Copy, Clone)]
85pub struct ManifestVersion {
86 pub minor: u16,
87 pub major: u16,
88}
89
90#[repr(C)]
92#[derive(Immutable, IntoBytes, FromBytes, Debug, Copy, Clone)]
93pub struct SigverifySpxSignature {
94 pub data: [u32; 1964usize],
95}
96
97impl Default for SigverifySpxSignature {
98 fn default() -> Self {
99 Self {
100 data: [0; 1964usize],
101 }
102 }
103}
104
105#[repr(C)]
107#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
108pub struct ManifestExtHeader {
109 pub identifier: u32,
110 pub name: u32,
111}
112
113#[repr(C)]
115#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
116pub struct ManifestExtSpxSignature {
117 pub header: ManifestExtHeader,
118 pub signature: SigverifySpxSignature,
119}
120
121#[repr(C)]
123#[derive(Immutable, IntoBytes, FromBytes, Debug, Default, Copy, Clone)]
124pub struct SigverifySpxKey {
125 pub data: [u32; 8usize],
126}
127
128#[repr(C)]
130#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
131pub struct ManifestExtSpxKey {
132 pub header: ManifestExtHeader,
133 pub key: SigverifySpxKey,
134}
135
136#[repr(C)]
138#[derive(Immutable, IntoBytes, FromBytes, Debug)]
139pub struct SigverifyBuffer {
140 pub data: [u32; 96usize],
141}
142
143impl Default for SigverifyBuffer {
144 fn default() -> Self {
145 Self { data: [0; 96usize] }
146 }
147}
148
149#[repr(C)]
150#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
151pub struct ManifestExtImageType {
152 pub header: ManifestExtHeader,
153 pub image_type: u32,
154}
155
156#[repr(C)]
158#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
159pub struct LifecycleDeviceId {
160 pub device_id: [u32; 8usize],
161}
162
163#[repr(C)]
165#[derive(Immutable, IntoBytes, FromBytes, Debug)]
166pub struct ManifestUsageConstraints {
167 pub selector_bits: u32,
168 pub device_id: LifecycleDeviceId,
169 pub manuf_state_creator: u32,
170 pub manuf_state_owner: u32,
171 pub life_cycle_state: u32,
172}
173
174impl Default for ManifestUsageConstraints {
175 fn default() -> Self {
176 Self {
177 selector_bits: 0,
178 device_id: LifecycleDeviceId {
179 device_id: [MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL; 8usize],
180 },
181 manuf_state_creator: MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL,
182 manuf_state_owner: MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL,
183 life_cycle_state: MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD_VAL,
184 }
185 }
186}
187
188#[repr(C)]
190#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
191pub struct Timestamp {
192 pub timestamp_low: u32,
193 pub timestamp_high: u32,
194}
195
196#[repr(C)]
197#[derive(Immutable, IntoBytes, FromBytes, Debug, Default)]
198pub struct KeymgrBindingValue {
199 pub data: [u32; 8usize],
200}
201
202#[repr(C)]
203#[derive(KnownLayout, Immutable, IntoBytes, FromBytes, Debug, Default, Copy, Clone)]
204pub struct ManifestExtTableEntry {
205 pub identifier: u32,
206 pub offset: u32,
207}
208
209#[repr(C)]
210#[derive(KnownLayout, Immutable, IntoBytes, FromBytes, Debug, Default, Copy, Clone)]
211pub struct ManifestExtTable {
212 pub entries: [ManifestExtTableEntry; CHIP_MANIFEST_EXT_TABLE_COUNT],
213}
214
215#[cfg(test)]
216mod tests {
217 use super::*;
218 use std::mem::{offset_of, size_of};
219
220 #[test]
225 pub fn test_manifest_layout() {
226 assert_eq!(offset_of!(Manifest, signature), 0);
227 assert_eq!(offset_of!(Manifest, usage_constraints), 384);
228 assert_eq!(offset_of!(Manifest, pub_key), 432);
229 assert_eq!(offset_of!(Manifest, address_translation), 816);
230 assert_eq!(offset_of!(Manifest, identifier), 820);
231 assert_eq!(offset_of!(Manifest, manifest_version), 824);
232 assert_eq!(offset_of!(Manifest, signed_region_end), 828);
233 assert_eq!(offset_of!(Manifest, length), 832);
234 assert_eq!(offset_of!(Manifest, version_major), 836);
235 assert_eq!(offset_of!(Manifest, version_minor), 840);
236 assert_eq!(offset_of!(Manifest, security_version), 844);
237 assert_eq!(offset_of!(Manifest, timestamp), 848);
238 assert_eq!(offset_of!(Manifest, binding_value), 856);
239 assert_eq!(offset_of!(Manifest, max_key_version), 888);
240 assert_eq!(offset_of!(Manifest, code_start), 892);
241 assert_eq!(offset_of!(Manifest, code_end), 896);
242 assert_eq!(offset_of!(Manifest, entry_point), 900);
243 assert_eq!(offset_of!(Manifest, extensions), 904);
244 assert_eq!(size_of::<Manifest>(), CHIP_MANIFEST_SIZE as usize);
245 }
246}