1use anyhow::{Result, anyhow, ensure};
6use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
7use serde::Deserialize;
8use serde_annotate::Annotate;
9use sphincsplus::SpxSecretKey;
10use std::convert::TryFrom;
11use std::io::{Read, Write};
12
13use super::GlobalFlags;
14use super::misc::{KeyMaterial, OwnershipKeyAlg, TlvHeader, TlvTag};
15use super::{
16 DetachedSignature, OwnerApplicationKey, OwnerFlashConfig, OwnerFlashInfoConfig,
17 OwnerIsfbConfig, OwnerRescueConfig,
18};
19use crate::chip::boolean::HardenedBool;
20use crate::crypto::Error as CryptoError;
21use crate::crypto::ecdsa::{EcdsaPrivateKey, EcdsaRawSignature};
22use crate::with_unknown;
23
24with_unknown! {
25 pub enum SramExecMode: u32 [default = Self::DisabledLocked] {
26 DisabledLocked = u32::from_le_bytes(*b"LNEX"),
27 Disabled = u32::from_le_bytes(*b"NOEX"),
28 Enabled = u32::from_le_bytes(*b"EXEC"),
29 }
30
31 pub enum MinSecurityVersion: u32 [default = Self::NoChange] {
32 NoChange = 0xFFFFFFFFu32,
33 }
34
35 pub enum OwnershipUpdateMode: u32 [default = Self::Open] {
36 Open = bindgen::ownership_datatypes::ownership_update_mode::kOwnershipUpdateModeOpen as u32,
37 UnlockSelf = bindgen::ownership_datatypes::ownership_update_mode::kOwnershipUpdateModeSelf as u32,
38 SelfVersion = bindgen::ownership_datatypes::ownership_update_mode::kOwnershipUpdateModeSelfVersion as u32,
39 NewVersion = bindgen::ownership_datatypes::ownership_update_mode::kOwnershipUpdateModeNewVersion as u32,
40 AnyVersion = bindgen::ownership_datatypes::ownership_update_mode::kOwnershipUpdateModeAnyVersion as u32,
41 }
42}
43
44#[derive(Debug, Deserialize, Annotate, PartialEq)]
46pub struct OwnerBlock {
47 #[serde(
49 skip_serializing_if = "GlobalFlags::not_debug",
50 default = "OwnerBlock::default_header"
51 )]
52 pub header: TlvHeader,
53 #[serde(default)]
55 pub config_version: u32,
56 #[serde(default)]
58 pub sram_exec: SramExecMode,
59 pub ownership_key_alg: OwnershipKeyAlg,
61 #[serde(default)]
63 pub update_mode: OwnershipUpdateMode,
64 #[serde(default)]
66 pub min_security_version_bl0: MinSecurityVersion,
67 #[serde(default)]
69 pub lock_constraint: u32,
70 #[serde(
72 default = "OwnerBlock::default_constraint",
73 skip_serializing_if = "OwnerBlock::is_default_constraint"
74 )]
75 #[annotate(format=hex)]
76 pub device_id: [u32; 8],
77 #[serde(default)]
78 pub boot_svc_after_wakeup: HardenedBool,
79 #[serde(default, skip_serializing_if = "GlobalFlags::not_debug")]
80 #[annotate(format=hex)]
81 pub reserved: [u32; 15],
82 pub owner_key: KeyMaterial,
84 pub activate_key: KeyMaterial,
86 pub unlock_key: KeyMaterial,
88 #[serde(default)]
90 pub data: Vec<OwnerConfigItem>,
91 #[serde(default, skip_serializing_if = "EcdsaRawSignature::is_empty")]
92 #[annotate(format=hex)]
93 pub signature: EcdsaRawSignature,
95 #[serde(default, skip_serializing_if = "Vec::is_empty", with = "serde_bytes")]
97 #[annotate(format = hexstr)]
98 pub seal: Vec<u8>,
99}
100
101impl Default for OwnerBlock {
102 fn default() -> Self {
103 Self {
104 header: Self::default_header(),
105 config_version: 0,
106 sram_exec: SramExecMode::default(),
107 ownership_key_alg: OwnershipKeyAlg::default(),
108 update_mode: OwnershipUpdateMode::default(),
109 min_security_version_bl0: MinSecurityVersion::default(),
110 lock_constraint: 0,
111 device_id: Self::default_constraint(),
112 boot_svc_after_wakeup: HardenedBool::default(),
113 reserved: [0u32; 15],
114 owner_key: KeyMaterial::default(),
115 activate_key: KeyMaterial::default(),
116 unlock_key: KeyMaterial::default(),
117 data: Vec::new(),
118 signature: EcdsaRawSignature::default(),
119 seal: Vec::new(),
120 }
121 }
122}
123
124impl OwnerBlock {
125 pub const SIZE: usize = 2048;
126 pub const DATA_SIZE: usize = 1536;
127 pub const SIGNATURE_OFFSET: usize = 1952;
128 const NOT_PRESENT: u8 = 0x5a;
130 const NO_CONSTRAINT: u32 = 0x7e7e7e7e;
131
132 pub fn default_header() -> TlvHeader {
133 TlvHeader::new(TlvTag::Owner, Self::SIZE, "0.0")
134 }
135 pub fn basic() -> Self {
136 Self {
137 data: vec![
138 OwnerConfigItem::ApplicationKey(OwnerApplicationKey::default()),
139 OwnerConfigItem::FlashConfig(OwnerFlashConfig::basic()),
140 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig::basic()),
141 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
142 ],
143 ..Default::default()
144 }
145 }
146
147 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
148 self.header.write(dest)?;
149 dest.write_u32::<LittleEndian>(self.config_version)?;
150 dest.write_u32::<LittleEndian>(u32::from(self.sram_exec))?;
151 dest.write_u32::<LittleEndian>(u32::from(self.ownership_key_alg))?;
152 dest.write_u32::<LittleEndian>(u32::from(self.update_mode))?;
153 dest.write_u32::<LittleEndian>(u32::from(self.min_security_version_bl0))?;
154 dest.write_u32::<LittleEndian>(self.lock_constraint)?;
155
156 for (i, x) in self.device_id.iter().enumerate() {
157 if self.lock_constraint & (1u32 << i) == 0 {
158 dest.write_u32::<LittleEndian>(Self::NO_CONSTRAINT)?;
159 } else {
160 dest.write_u32::<LittleEndian>(*x)?;
161 }
162 }
163 dest.write_u32::<LittleEndian>(u32::from(self.boot_svc_after_wakeup))?;
164 for x in &self.reserved {
165 dest.write_u32::<LittleEndian>(*x)?;
166 }
167 self.owner_key.write_length(dest, 96)?;
168 self.activate_key.write_length(dest, 96)?;
169 self.unlock_key.write_length(dest, 96)?;
170 let mut data = Vec::new();
171 for item in &self.data {
172 item.write(&mut data)?;
173 }
174 data.resize(Self::DATA_SIZE, Self::NOT_PRESENT);
175 dest.write_all(&data)?;
176 self.signature.write(dest)?;
177 if self.seal.is_empty() {
178 dest.write_all(&[0u8; 32])?;
179 } else {
180 dest.write_all(&self.seal)?;
181 }
182 Ok(())
183 }
184
185 pub fn read(src: &mut impl Read, header: TlvHeader) -> Result<Self> {
186 let config_version = src.read_u32::<LittleEndian>()?;
187 let sram_exec = SramExecMode(src.read_u32::<LittleEndian>()?);
188 let ownership_key_alg = OwnershipKeyAlg(src.read_u32::<LittleEndian>()?);
189 let update_mode = OwnershipUpdateMode(src.read_u32::<LittleEndian>()?);
190 let min_security_version_bl0 = MinSecurityVersion(src.read_u32::<LittleEndian>()?);
191 let lock_constraint = src.read_u32::<LittleEndian>()?;
192
193 let mut device_id = [0u32; 8];
194 src.read_u32_into::<LittleEndian>(&mut device_id)?;
195 let boot_svc_after_wakeup = HardenedBool(src.read_u32::<LittleEndian>()?);
196 let mut reserved = [0u32; 15];
197 src.read_u32_into::<LittleEndian>(&mut reserved)?;
198 let owner_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
199 let activate_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
200 let unlock_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
201 let mut bytes = vec![0u8; Self::DATA_SIZE];
202 src.read_exact(&mut bytes)?;
203 let mut cursor = std::io::Cursor::new(&bytes);
204 let mut data = Vec::new();
205 while cursor.position() as usize != Self::DATA_SIZE {
206 match OwnerConfigItem::read(&mut cursor)? {
207 Some(item) => data.push(item),
208 None => break,
209 }
210 }
211 let signature = EcdsaRawSignature::read(src)?;
212 let mut seal = vec![0u8; 32];
213 src.read_exact(&mut seal)?;
214 Ok(Self {
215 header,
216 config_version,
217 sram_exec,
218 ownership_key_alg,
219 update_mode,
220 min_security_version_bl0,
221 lock_constraint,
222 device_id,
223 boot_svc_after_wakeup,
224 reserved,
225 owner_key,
226 activate_key,
227 unlock_key,
228 data,
229 signature,
230 seal,
231 })
232 }
233 pub fn sign(&mut self, key: &EcdsaPrivateKey) -> Result<()> {
234 ensure!(
235 self.ownership_key_alg == OwnershipKeyAlg::EcdsaP256,
236 CryptoError::SignFailed(anyhow!(
237 "Algorithm {} requires a detached signature",
238 self.ownership_key_alg
239 ))
240 );
241 let mut data = Vec::new();
242 self.write(&mut data)?;
243 self.signature = key.digest_and_sign(&data[..Self::SIGNATURE_OFFSET])?;
244 Ok(())
245 }
246
247 pub fn detached_sign(
248 &mut self,
249 nonce: u64,
250 ecdsa_key: Option<&EcdsaPrivateKey>,
251 spx_key: Option<&SpxSecretKey>,
252 ) -> Result<DetachedSignature> {
253 self.signature = Default::default();
254 let mut data = Vec::new();
255 self.write(&mut data)?;
256 DetachedSignature::new(
257 &data[..Self::SIGNATURE_OFFSET],
258 TlvTag::Owner.into(),
259 self.ownership_key_alg,
260 nonce,
261 ecdsa_key,
262 spx_key,
263 )
264 }
265
266 pub fn is_default_constraint(d: &[u32; 8]) -> bool {
267 *d == [Self::NO_CONSTRAINT; 8]
268 }
269
270 pub fn default_constraint() -> [u32; 8] {
271 [Self::NO_CONSTRAINT; 8]
272 }
273}
274
275#[derive(Debug, Deserialize, Annotate, PartialEq)]
276pub enum OwnerConfigItem {
277 #[serde(alias = "application_key")]
278 ApplicationKey(OwnerApplicationKey),
279 #[serde(alias = "flash_info_config")]
280 FlashInfoConfig(OwnerFlashInfoConfig),
281 #[serde(alias = "flash_config")]
282 FlashConfig(OwnerFlashConfig),
283 #[serde(alias = "rescue_config")]
284 RescueConfig(OwnerRescueConfig),
285 #[serde(alias = "isfb_config")]
286 IsfbConfig(OwnerIsfbConfig),
287 #[serde(alias = "raw")]
288 Raw(
289 #[serde(with = "serde_bytes")]
290 #[annotate(format = hexdump)]
291 Vec<u8>,
292 ),
293}
294
295impl OwnerConfigItem {
296 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
297 match self {
298 Self::ApplicationKey(x) => x.write(dest)?,
299 Self::FlashInfoConfig(x) => x.write(dest)?,
300 Self::FlashConfig(x) => x.write(dest)?,
301 Self::RescueConfig(x) => x.write(dest)?,
302 Self::IsfbConfig(x) => x.write(dest)?,
303 Self::Raw(x) => dest.write_all(x)?,
304 }
305 Ok(())
306 }
307
308 pub fn read(src: &mut impl Read) -> Result<Option<Self>> {
309 let header = TlvHeader::read(src)?;
310 let item = match header.identifier {
311 TlvTag::ApplicationKey => Self::ApplicationKey(OwnerApplicationKey::read(src, header)?),
312 TlvTag::FlashConfig => Self::FlashConfig(OwnerFlashConfig::read(src, header)?),
313 TlvTag::FlashInfoConfig => {
314 Self::FlashInfoConfig(OwnerFlashInfoConfig::read(src, header)?)
315 }
316 TlvTag::Rescue => Self::RescueConfig(OwnerRescueConfig::read(src, header)?),
317 TlvTag::IntegratorSpecificFirmwareBinding => {
318 Self::IsfbConfig(OwnerIsfbConfig::read(src, header)?)
319 }
320 TlvTag::NotPresent => return Ok(None),
321 _ => {
322 let mut data = Vec::new();
323 header.write(&mut data)?;
324 if header.length >= TlvHeader::SIZE && header.length < OwnerBlock::DATA_SIZE {
325 data.resize(header.length, 0);
326 let len = src.read(&mut data)?;
327 data.resize(len, 0);
328 } else {
329 src.read_to_end(&mut data)?;
330 }
331 Self::Raw(data)
332 }
333 };
334 Ok(Some(item))
335 }
336}
337
338#[cfg(test)]
339mod test {
340 use super::*;
341 use crate::crypto::ecdsa::EcdsaRawPublicKey;
342 use crate::ownership::{
343 ApplicationKeyDomain, FlashFlags, OwnerFlashInfoConfig, OwnerFlashRegion, OwnerInfoPage,
344 OwnerRescueConfig,
345 };
346 use crate::util::hexdump::{hexdump_parse, hexdump_string};
347
348 #[rustfmt::skip]
349 const OWNER_BIN: &str =
350r#"00000000: 4f 57 4e 52 00 08 00 00 00 00 00 00 4c 4e 45 58 OWNR........LNEX
35100000010: 50 32 35 36 4f 50 45 4e ff ff ff ff 00 00 00 00 P256OPEN........
35200000020: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
35300000030: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
35400000040: d4 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35500000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35600000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35700000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35800000080: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
35900000090: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
360000000a0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
361000000b0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
362000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
363000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
364000000e0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
365000000f0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
36600000100: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
36700000110: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
36800000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
36900000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
37000000140: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
37100000150: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
37200000160: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
37300000170: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
37400000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
37500000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
376000001a0: 41 50 50 4b 70 00 00 00 50 32 35 36 70 72 6f 64 APPKp...P256prod
377000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
378000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
379000001d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
380000001e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
381000001f0: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
38200000200: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
38300000210: 46 4c 53 48 20 00 00 00 00 00 00 01 66 06 00 99 FLSH .......f...
38400000220: 66 06 00 00 00 01 00 02 77 17 11 88 77 17 11 11 f.......w...w...
38500000230: 49 4e 46 4f 20 00 00 00 00 01 00 00 66 06 00 99 INFO .......f...
38600000240: 66 06 00 00 01 05 00 00 77 17 11 88 77 17 11 11 f.......w...w...
38700000250: 52 45 53 51 50 00 00 00 58 00 00 40 20 00 e0 00 RESQP...X..@ ...
38800000260: 45 4d 50 54 4d 53 45 43 4e 45 58 54 55 4e 4c 4b EMPTMSECNEXTUNLK
38900000270: 41 43 54 56 51 53 45 52 42 53 45 52 4f 42 45 52 ACTVQSERBSEROBER
39000000280: 47 4f 4c 42 51 45 52 42 50 53 52 42 52 4e 57 4f GOLBQERBPSRBRNWO
39100000290: 30 47 50 4f 31 47 50 4f 44 49 54 4f 54 49 41 57 0GPO1GPODITOTIAW
392000002a0: 49 53 46 42 2c 00 00 00 01 08 00 00 66 06 00 00 ISFB,.......f...
393000002b0: 70 72 6f 64 00 00 00 00 00 00 00 00 00 00 00 00 prod............
394000002c0: 00 00 00 00 00 00 00 00 80 00 00 00 5a 5a 5a 5a ............ZZZZ
395000002d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
396000002e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
397000002f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39800000300: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39900000310: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40000000320: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40100000330: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40200000340: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40300000350: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40400000360: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40500000370: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40600000380: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40700000390: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
408000003a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
409000003b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
410000003c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
411000003d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
412000003e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
413000003f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41400000400: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41500000410: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41600000420: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41700000430: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41800000440: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41900000450: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42000000460: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42100000470: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42200000480: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42300000490: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
424000004a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
425000004b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
426000004c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
427000004d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
428000004e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
429000004f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43000000500: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43100000510: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43200000520: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43300000530: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43400000540: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43500000550: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43600000560: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43700000570: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43800000580: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43900000590: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
440000005a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
441000005b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
442000005c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
443000005d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
444000005e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
445000005f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44600000600: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44700000610: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44800000620: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44900000630: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45000000640: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45100000650: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45200000660: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45300000670: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45400000680: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45500000690: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
456000006a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
457000006b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
458000006c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
459000006d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
460000006e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
461000006f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46200000700: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46300000710: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46400000720: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46500000730: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46600000740: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46700000750: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46800000760: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46900000770: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
47000000780: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
47100000790: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
472000007a0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
473000007b0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
474000007c0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
475000007d0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
476000007e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
477000007f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
478"#;
479
480 const OWNER_JSON: &str = r#"{
481 config_version: 0,
482 sram_exec: "DisabledLocked",
483 ownership_key_alg: "EcdsaP256",
484 update_mode: "Open",
485 min_security_version_bl0: "NoChange",
486 lock_constraint: 0,
487 boot_svc_after_wakeup: "False",
488 owner_key: {
489 Ecdsa: {
490 x: "1111111111111111111111111111111111111111111111111111111111111111",
491 y: "2121212121212121212121212121212121212121212121212121212121212121"
492 }
493 },
494 activate_key: {
495 Ecdsa: {
496 x: "3333333333333333333333333333333333333333333333333333333333333333",
497 y: "4444444444444444444444444444444444444444444444444444444444444444"
498 }
499 },
500 unlock_key: {
501 Ecdsa: {
502 x: "5555555555555555555555555555555555555555555555555555555555555555",
503 y: "6666666666666666666666666666666666666666666666666666666666666666"
504 }
505 },
506 data: [
507 {
508 ApplicationKey: {
509 key_alg: "EcdsaP256",
510 key_domain: "Prod",
511 key_diversifier: [
512 0x0,
513 0x0,
514 0x0,
515 0x0,
516 0x0,
517 0x0,
518 0x0
519 ],
520 usage_constraint: 0x0,
521 key: {
522 Ecdsa: {
523 x: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
524 y: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
525 }
526 }
527 }
528 },
529 {
530 FlashConfig: {
531 config: [
532 {
533 start: 0,
534 size: 256,
535 read: true,
536 program: true,
537 erase: true,
538 scramble: true,
539 ecc: true,
540 high_endurance: true,
541 protect_when_active: false,
542 lock: false
543 },
544 {
545 start: 256,
546 size: 512,
547 read: true,
548 program: true,
549 erase: true,
550 scramble: true,
551 ecc: true,
552 high_endurance: true,
553 protect_when_active: false,
554 lock: false
555 }
556 ]
557 }
558 },
559 {
560 FlashInfoConfig: {
561 config: [
562 {
563 bank: 0,
564 page: 1,
565 pad: 0,
566 read: true,
567 program: true,
568 erase: true,
569 scramble: true,
570 ecc: true,
571 high_endurance: true,
572 protect_when_active: false,
573 lock: false
574 },
575 {
576 bank: 1,
577 page: 5,
578 pad: 0,
579 read: true,
580 program: true,
581 erase: true,
582 scramble: true,
583 ecc: true,
584 high_endurance: true,
585 protect_when_active: false,
586 lock: false
587 }
588 ]
589 }
590 },
591 {
592 RescueConfig: {
593 protocol: "Xmodem",
594 trigger: "UartBreak",
595 trigger_index: 0,
596 gpio_pull_en: false,
597 gpio_value: false,
598 enter_on_watchdog: false,
599 enter_on_failure: false,
600 timeout: 0,
601 start: 32,
602 size: 224,
603 command_allow: [
604 "Empty",
605 "MinBl0SecVerRequest",
606 "NextBl0SlotRequest",
607 "OwnershipUnlockRequest",
608 "OwnershipActivateRequest",
609 "Rescue",
610 "RescueB",
611 "Reboot",
612 "GetBootLog",
613 "BootSvcReq",
614 "BootSvcRsp",
615 "OwnerBlock",
616 "GetOwnerPage0",
617 "GetOwnerPage1",
618 "GetDeviceId",
619 "Wait"
620 ]
621 }
622 },
623 {
624 IsfbConfig: {
625 bank: 1,
626 page: 8,
627 erase_conditions: 0x666,
628 key_domain: "Prod",
629 product_words: 128
630 }
631 }
632 ],
633 signature: {
634 r: "7777777777777777777777777777777777777777777777777777777777777777",
635 s: "8888888888888888888888888888888888888888888888888888888888888888"
636 },
637 seal: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
638}"#;
639
640 #[test]
641 fn test_owner_write() -> Result<()> {
642 let own = OwnerBlock {
643 config_version: 0,
644 sram_exec: SramExecMode::default(),
645 ownership_key_alg: OwnershipKeyAlg::EcdsaP256,
646 owner_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
647 x: hex::decode("1111111111111111111111111111111111111111111111111111111111111111")?,
648 y: hex::decode("2121212121212121212121212121212121212121212121212121212121212121")?,
649 }),
650 activate_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
651 x: hex::decode("3333333333333333333333333333333333333333333333333333333333333333")?,
652 y: hex::decode("4444444444444444444444444444444444444444444444444444444444444444")?,
653 }),
654 unlock_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
655 x: hex::decode("5555555555555555555555555555555555555555555555555555555555555555")?,
656 y: hex::decode("6666666666666666666666666666666666666666666666666666666666666666")?,
657 }),
658 data: vec![
659 OwnerConfigItem::ApplicationKey(OwnerApplicationKey {
660 key_alg: OwnershipKeyAlg::EcdsaP256,
661 key_domain: ApplicationKeyDomain::Prod,
662 key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
663 x: hex::decode(
664 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
665 )?,
666 y: hex::decode(
667 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
668 )?,
669 }),
670 ..Default::default()
671 }),
672 OwnerConfigItem::FlashConfig(OwnerFlashConfig {
673 config: vec![
674 OwnerFlashRegion {
675 start: 0x000,
676 size: 0x100,
677 flags: FlashFlags::basic(),
678 },
679 OwnerFlashRegion {
680 start: 0x100,
681 size: 0x200,
682 flags: FlashFlags::basic(),
683 },
684 ],
685 ..Default::default()
686 }),
687 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig {
688 config: vec![
689 OwnerInfoPage::new(0, 1, FlashFlags::basic()),
690 OwnerInfoPage::new(1, 5, FlashFlags::basic()),
691 ],
692 ..Default::default()
693 }),
694 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
695 OwnerConfigItem::IsfbConfig(OwnerIsfbConfig {
696 bank: 1,
697 page: 8,
698 pad: 0,
699 erase_conditions: 0x0000_0666,
700 key_domain: ApplicationKeyDomain::Prod,
701 product_words: 128,
702 ..Default::default()
703 }),
704 ],
705 signature: EcdsaRawSignature {
706 r: hex::decode("7777777777777777777777777777777777777777777777777777777777777777")?,
707 s: hex::decode("8888888888888888888888888888888888888888888888888888888888888888")?,
708 },
709 seal: hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")?,
710 ..Default::default()
711 };
712 let mut bin = Vec::new();
713 own.write(&mut bin)?;
714 eprintln!("{}", hexdump_string(&bin)?);
715 assert_eq!(hexdump_string(&bin)?, OWNER_BIN);
716 Ok(())
717 }
718
719 #[test]
720 fn test_owner_read() -> Result<()> {
721 let buf = hexdump_parse(OWNER_BIN)?;
722 let mut cur = std::io::Cursor::new(&buf);
723 let header = TlvHeader::read(&mut cur)?;
724 let own = OwnerBlock::read(&mut cur, header)?;
725 let doc = serde_annotate::serialize(&own)?.to_json5().to_string();
726 eprintln!("{}", doc);
727 assert_eq!(doc, OWNER_JSON);
728 Ok(())
729 }
730}