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 = u32::from_le_bytes(*b"OPEN"),
37 UnlockSelf = u32::from_le_bytes(*b"SELF"),
38 SelfVersion = u32::from_le_bytes(*b"SELV"),
39 NewVersion = u32::from_le_bytes(*b"NEWV"),
40 }
41}
42
43#[derive(Debug, Deserialize, Annotate, PartialEq)]
45pub struct OwnerBlock {
46 #[serde(
48 skip_serializing_if = "GlobalFlags::not_debug",
49 default = "OwnerBlock::default_header"
50 )]
51 pub header: TlvHeader,
52 #[serde(default)]
54 pub config_version: u32,
55 #[serde(default)]
57 pub sram_exec: SramExecMode,
58 pub ownership_key_alg: OwnershipKeyAlg,
60 #[serde(default)]
62 pub update_mode: OwnershipUpdateMode,
63 #[serde(default)]
65 pub min_security_version_bl0: MinSecurityVersion,
66 #[serde(default)]
68 pub lock_constraint: u32,
69 #[serde(
71 default = "OwnerBlock::default_constraint",
72 skip_serializing_if = "OwnerBlock::is_default_constraint"
73 )]
74 #[annotate(format=hex)]
75 pub device_id: [u32; 8],
76 #[serde(default)]
77 pub boot_svc_after_wakeup: HardenedBool,
78 #[serde(default, skip_serializing_if = "GlobalFlags::not_debug")]
79 #[annotate(format=hex)]
80 pub reserved: [u32; 15],
81 pub owner_key: KeyMaterial,
83 pub activate_key: KeyMaterial,
85 pub unlock_key: KeyMaterial,
87 #[serde(default)]
89 pub data: Vec<OwnerConfigItem>,
90 #[serde(default, skip_serializing_if = "EcdsaRawSignature::is_empty")]
91 #[annotate(format=hex)]
92 pub signature: EcdsaRawSignature,
94 #[serde(default, skip_serializing_if = "Vec::is_empty", with = "serde_bytes")]
96 #[annotate(format = hexstr)]
97 pub seal: Vec<u8>,
98}
99
100impl Default for OwnerBlock {
101 fn default() -> Self {
102 Self {
103 header: Self::default_header(),
104 config_version: 0,
105 sram_exec: SramExecMode::default(),
106 ownership_key_alg: OwnershipKeyAlg::default(),
107 update_mode: OwnershipUpdateMode::default(),
108 min_security_version_bl0: MinSecurityVersion::default(),
109 lock_constraint: 0,
110 device_id: Self::default_constraint(),
111 boot_svc_after_wakeup: HardenedBool::default(),
112 reserved: [0u32; 15],
113 owner_key: KeyMaterial::default(),
114 activate_key: KeyMaterial::default(),
115 unlock_key: KeyMaterial::default(),
116 data: Vec::new(),
117 signature: EcdsaRawSignature::default(),
118 seal: Vec::new(),
119 }
120 }
121}
122
123impl OwnerBlock {
124 pub const SIZE: usize = 2048;
125 pub const DATA_SIZE: usize = 1536;
126 pub const SIGNATURE_OFFSET: usize = 1952;
127 const NOT_PRESENT: u8 = 0x5a;
129 const NO_CONSTRAINT: u32 = 0x7e7e7e7e;
130
131 pub fn default_header() -> TlvHeader {
132 TlvHeader::new(TlvTag::Owner, Self::SIZE, "0.0")
133 }
134 pub fn basic() -> Self {
135 Self {
136 data: vec![
137 OwnerConfigItem::ApplicationKey(OwnerApplicationKey::default()),
138 OwnerConfigItem::FlashConfig(OwnerFlashConfig::basic()),
139 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig::basic()),
140 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
141 ],
142 ..Default::default()
143 }
144 }
145
146 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
147 self.header.write(dest)?;
148 dest.write_u32::<LittleEndian>(self.config_version)?;
149 dest.write_u32::<LittleEndian>(u32::from(self.sram_exec))?;
150 dest.write_u32::<LittleEndian>(u32::from(self.ownership_key_alg))?;
151 dest.write_u32::<LittleEndian>(u32::from(self.update_mode))?;
152 dest.write_u32::<LittleEndian>(u32::from(self.min_security_version_bl0))?;
153 dest.write_u32::<LittleEndian>(self.lock_constraint)?;
154
155 for (i, x) in self.device_id.iter().enumerate() {
156 if self.lock_constraint & (1u32 << i) == 0 {
157 dest.write_u32::<LittleEndian>(Self::NO_CONSTRAINT)?;
158 } else {
159 dest.write_u32::<LittleEndian>(*x)?;
160 }
161 }
162 dest.write_u32::<LittleEndian>(u32::from(self.boot_svc_after_wakeup))?;
163 for x in &self.reserved {
164 dest.write_u32::<LittleEndian>(*x)?;
165 }
166 self.owner_key.write_length(dest, 96)?;
167 self.activate_key.write_length(dest, 96)?;
168 self.unlock_key.write_length(dest, 96)?;
169 let mut data = Vec::new();
170 for item in &self.data {
171 item.write(&mut data)?;
172 }
173 data.resize(Self::DATA_SIZE, Self::NOT_PRESENT);
174 dest.write_all(&data)?;
175 self.signature.write(dest)?;
176 if self.seal.is_empty() {
177 dest.write_all(&[0u8; 32])?;
178 } else {
179 dest.write_all(&self.seal)?;
180 }
181 Ok(())
182 }
183
184 pub fn read(src: &mut impl Read, header: TlvHeader) -> Result<Self> {
185 let config_version = src.read_u32::<LittleEndian>()?;
186 let sram_exec = SramExecMode(src.read_u32::<LittleEndian>()?);
187 let ownership_key_alg = OwnershipKeyAlg(src.read_u32::<LittleEndian>()?);
188 let update_mode = OwnershipUpdateMode(src.read_u32::<LittleEndian>()?);
189 let min_security_version_bl0 = MinSecurityVersion(src.read_u32::<LittleEndian>()?);
190 let lock_constraint = src.read_u32::<LittleEndian>()?;
191
192 let mut device_id = [0u32; 8];
193 src.read_u32_into::<LittleEndian>(&mut device_id)?;
194 let boot_svc_after_wakeup = HardenedBool(src.read_u32::<LittleEndian>()?);
195 let mut reserved = [0u32; 15];
196 src.read_u32_into::<LittleEndian>(&mut reserved)?;
197 let owner_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
198 let activate_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
199 let unlock_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
200 let mut bytes = vec![0u8; Self::DATA_SIZE];
201 src.read_exact(&mut bytes)?;
202 let mut cursor = std::io::Cursor::new(&bytes);
203 let mut data = Vec::new();
204 while cursor.position() as usize != Self::DATA_SIZE {
205 match OwnerConfigItem::read(&mut cursor)? {
206 Some(item) => data.push(item),
207 None => break,
208 }
209 }
210 let signature = EcdsaRawSignature::read(src)?;
211 let mut seal = vec![0u8; 32];
212 src.read_exact(&mut seal)?;
213 Ok(Self {
214 header,
215 config_version,
216 sram_exec,
217 ownership_key_alg,
218 update_mode,
219 min_security_version_bl0,
220 lock_constraint,
221 device_id,
222 boot_svc_after_wakeup,
223 reserved,
224 owner_key,
225 activate_key,
226 unlock_key,
227 data,
228 signature,
229 seal,
230 })
231 }
232 pub fn sign(&mut self, key: &EcdsaPrivateKey) -> Result<()> {
233 ensure!(
234 self.ownership_key_alg == OwnershipKeyAlg::EcdsaP256,
235 CryptoError::SignFailed(anyhow!(
236 "Algorithm {} requires a detached signature",
237 self.ownership_key_alg
238 ))
239 );
240 let mut data = Vec::new();
241 self.write(&mut data)?;
242 self.signature = key.digest_and_sign(&data[..Self::SIGNATURE_OFFSET])?;
243 Ok(())
244 }
245
246 pub fn detached_sign(
247 &mut self,
248 nonce: u64,
249 ecdsa_key: Option<&EcdsaPrivateKey>,
250 spx_key: Option<&SpxSecretKey>,
251 ) -> Result<DetachedSignature> {
252 self.signature = Default::default();
253 let mut data = Vec::new();
254 self.write(&mut data)?;
255 DetachedSignature::new(
256 &data[..Self::SIGNATURE_OFFSET],
257 TlvTag::Owner.into(),
258 self.ownership_key_alg,
259 nonce,
260 ecdsa_key,
261 spx_key,
262 )
263 }
264
265 pub fn is_default_constraint(d: &[u32; 8]) -> bool {
266 *d == [Self::NO_CONSTRAINT; 8]
267 }
268
269 pub fn default_constraint() -> [u32; 8] {
270 [Self::NO_CONSTRAINT; 8]
271 }
272}
273
274#[derive(Debug, Deserialize, Annotate, PartialEq)]
275pub enum OwnerConfigItem {
276 #[serde(alias = "application_key")]
277 ApplicationKey(OwnerApplicationKey),
278 #[serde(alias = "flash_info_config")]
279 FlashInfoConfig(OwnerFlashInfoConfig),
280 #[serde(alias = "flash_config")]
281 FlashConfig(OwnerFlashConfig),
282 #[serde(alias = "rescue_config")]
283 RescueConfig(OwnerRescueConfig),
284 #[serde(alias = "isfb_config")]
285 IsfbConfig(OwnerIsfbConfig),
286 #[serde(alias = "raw")]
287 Raw(
288 #[serde(with = "serde_bytes")]
289 #[annotate(format = hexdump)]
290 Vec<u8>,
291 ),
292}
293
294impl OwnerConfigItem {
295 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
296 match self {
297 Self::ApplicationKey(x) => x.write(dest)?,
298 Self::FlashInfoConfig(x) => x.write(dest)?,
299 Self::FlashConfig(x) => x.write(dest)?,
300 Self::RescueConfig(x) => x.write(dest)?,
301 Self::IsfbConfig(x) => x.write(dest)?,
302 Self::Raw(x) => dest.write_all(x)?,
303 }
304 Ok(())
305 }
306
307 pub fn read(src: &mut impl Read) -> Result<Option<Self>> {
308 let header = TlvHeader::read(src)?;
309 let item = match header.identifier {
310 TlvTag::ApplicationKey => Self::ApplicationKey(OwnerApplicationKey::read(src, header)?),
311 TlvTag::FlashConfig => Self::FlashConfig(OwnerFlashConfig::read(src, header)?),
312 TlvTag::FlashInfoConfig => {
313 Self::FlashInfoConfig(OwnerFlashInfoConfig::read(src, header)?)
314 }
315 TlvTag::Rescue => Self::RescueConfig(OwnerRescueConfig::read(src, header)?),
316 TlvTag::IntegratorSpecificFirmwareBinding => {
317 Self::IsfbConfig(OwnerIsfbConfig::read(src, header)?)
318 }
319 TlvTag::NotPresent => return Ok(None),
320 _ => {
321 let mut data = Vec::new();
322 header.write(&mut data)?;
323 if header.length >= TlvHeader::SIZE && header.length < OwnerBlock::DATA_SIZE {
324 data.resize(header.length, 0);
325 let len = src.read(&mut data)?;
326 data.resize(len, 0);
327 } else {
328 src.read_to_end(&mut data)?;
329 }
330 Self::Raw(data)
331 }
332 };
333 Ok(Some(item))
334 }
335}
336
337#[cfg(test)]
338mod test {
339 use super::*;
340 use crate::crypto::ecdsa::EcdsaRawPublicKey;
341 use crate::ownership::{
342 ApplicationKeyDomain, FlashFlags, OwnerFlashInfoConfig, OwnerFlashRegion, OwnerInfoPage,
343 OwnerRescueConfig,
344 };
345 use crate::util::hexdump::{hexdump_parse, hexdump_string};
346
347 #[rustfmt::skip]
348 const OWNER_BIN: &str =
349r#"00000000: 4f 57 4e 52 00 08 00 00 00 00 00 00 4c 4e 45 58 OWNR........LNEX
35000000010: 50 32 35 36 4f 50 45 4e ff ff ff ff 00 00 00 00 P256OPEN........
35100000020: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
35200000030: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
35300000040: d4 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35400000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35500000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35600000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35700000080: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
35800000090: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
359000000a0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
360000000b0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
361000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
362000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
363000000e0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
364000000f0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
36500000100: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
36600000110: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
36700000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
36800000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
36900000140: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
37000000150: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
37100000160: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
37200000170: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
37300000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
37400000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
375000001a0: 41 50 50 4b 70 00 00 00 50 32 35 36 70 72 6f 64 APPKp...P256prod
376000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
377000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
378000001d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
379000001e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
380000001f0: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
38100000200: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
38200000210: 46 4c 53 48 20 00 00 00 00 00 00 01 66 06 00 99 FLSH .......f...
38300000220: 66 06 00 00 00 01 00 02 77 17 11 88 77 17 11 11 f.......w...w...
38400000230: 49 4e 46 4f 20 00 00 00 00 01 00 00 66 06 00 99 INFO .......f...
38500000240: 66 06 00 00 01 05 00 00 77 17 11 88 77 17 11 11 f.......w...w...
38600000250: 52 45 53 51 50 00 00 00 58 00 00 40 20 00 e0 00 RESQP...X..@ ...
38700000260: 45 4d 50 54 4d 53 45 43 4e 45 58 54 55 4e 4c 4b EMPTMSECNEXTUNLK
38800000270: 41 43 54 56 51 53 45 52 42 53 45 52 4f 42 45 52 ACTVQSERBSEROBER
38900000280: 47 4f 4c 42 51 45 52 42 50 53 52 42 52 4e 57 4f GOLBQERBPSRBRNWO
39000000290: 30 47 50 4f 31 47 50 4f 44 49 54 4f 54 49 41 57 0GPO1GPODITOTIAW
391000002a0: 49 53 46 42 2c 00 00 00 01 08 00 00 66 06 00 00 ISFB,.......f...
392000002b0: 70 72 6f 64 00 00 00 00 00 00 00 00 00 00 00 00 prod............
393000002c0: 00 00 00 00 00 00 00 00 80 00 00 00 5a 5a 5a 5a ............ZZZZ
394000002d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
395000002e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
396000002f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39700000300: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39800000310: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39900000320: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40000000330: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40100000340: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40200000350: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40300000360: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40400000370: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40500000380: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40600000390: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
407000003a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
408000003b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
409000003c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
410000003d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
411000003e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
412000003f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41300000400: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41400000410: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41500000420: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41600000430: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41700000440: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41800000450: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41900000460: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42000000470: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42100000480: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42200000490: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
423000004a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
424000004b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
425000004c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
426000004d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
427000004e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
428000004f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42900000500: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43000000510: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43100000520: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43200000530: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43300000540: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43400000550: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43500000560: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43600000570: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43700000580: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43800000590: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
439000005a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
440000005b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
441000005c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
442000005d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
443000005e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
444000005f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44500000600: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44600000610: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44700000620: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44800000630: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44900000640: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45000000650: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45100000660: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45200000670: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45300000680: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45400000690: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
455000006a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
456000006b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
457000006c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
458000006d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
459000006e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
460000006f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46100000700: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46200000710: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46300000720: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46400000730: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46500000740: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46600000750: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46700000760: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46800000770: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46900000780: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
47000000790: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
471000007a0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
472000007b0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
473000007c0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
474000007d0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
475000007e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
476000007f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
477"#;
478
479 const OWNER_JSON: &str = r#"{
480 config_version: 0,
481 sram_exec: "DisabledLocked",
482 ownership_key_alg: "EcdsaP256",
483 update_mode: "Open",
484 min_security_version_bl0: "NoChange",
485 lock_constraint: 0,
486 boot_svc_after_wakeup: "False",
487 owner_key: {
488 Ecdsa: {
489 x: "1111111111111111111111111111111111111111111111111111111111111111",
490 y: "2121212121212121212121212121212121212121212121212121212121212121"
491 }
492 },
493 activate_key: {
494 Ecdsa: {
495 x: "3333333333333333333333333333333333333333333333333333333333333333",
496 y: "4444444444444444444444444444444444444444444444444444444444444444"
497 }
498 },
499 unlock_key: {
500 Ecdsa: {
501 x: "5555555555555555555555555555555555555555555555555555555555555555",
502 y: "6666666666666666666666666666666666666666666666666666666666666666"
503 }
504 },
505 data: [
506 {
507 ApplicationKey: {
508 key_alg: "EcdsaP256",
509 key_domain: "Prod",
510 key_diversifier: [
511 0x0,
512 0x0,
513 0x0,
514 0x0,
515 0x0,
516 0x0,
517 0x0
518 ],
519 usage_constraint: 0x0,
520 key: {
521 Ecdsa: {
522 x: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
523 y: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
524 }
525 }
526 }
527 },
528 {
529 FlashConfig: {
530 config: [
531 {
532 start: 0,
533 size: 256,
534 read: true,
535 program: true,
536 erase: true,
537 scramble: true,
538 ecc: true,
539 high_endurance: true,
540 protect_when_active: false,
541 lock: false
542 },
543 {
544 start: 256,
545 size: 512,
546 read: true,
547 program: true,
548 erase: true,
549 scramble: true,
550 ecc: true,
551 high_endurance: true,
552 protect_when_active: false,
553 lock: false
554 }
555 ]
556 }
557 },
558 {
559 FlashInfoConfig: {
560 config: [
561 {
562 bank: 0,
563 page: 1,
564 pad: 0,
565 read: true,
566 program: true,
567 erase: true,
568 scramble: true,
569 ecc: true,
570 high_endurance: true,
571 protect_when_active: false,
572 lock: false
573 },
574 {
575 bank: 1,
576 page: 5,
577 pad: 0,
578 read: true,
579 program: true,
580 erase: true,
581 scramble: true,
582 ecc: true,
583 high_endurance: true,
584 protect_when_active: false,
585 lock: false
586 }
587 ]
588 }
589 },
590 {
591 RescueConfig: {
592 protocol: "Xmodem",
593 trigger: "UartBreak",
594 trigger_index: 0,
595 gpio_pull_en: false,
596 gpio_value: false,
597 enter_on_watchdog: false,
598 enter_on_failure: false,
599 timeout: 0,
600 start: 32,
601 size: 224,
602 command_allow: [
603 "Empty",
604 "MinBl0SecVerRequest",
605 "NextBl0SlotRequest",
606 "OwnershipUnlockRequest",
607 "OwnershipActivateRequest",
608 "Rescue",
609 "RescueB",
610 "Reboot",
611 "GetBootLog",
612 "BootSvcReq",
613 "BootSvcRsp",
614 "OwnerBlock",
615 "GetOwnerPage0",
616 "GetOwnerPage1",
617 "GetDeviceId",
618 "Wait"
619 ]
620 }
621 },
622 {
623 IsfbConfig: {
624 bank: 1,
625 page: 8,
626 erase_conditions: 0x666,
627 key_domain: "Prod",
628 product_words: 128
629 }
630 }
631 ],
632 signature: {
633 r: "7777777777777777777777777777777777777777777777777777777777777777",
634 s: "8888888888888888888888888888888888888888888888888888888888888888"
635 },
636 seal: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
637}"#;
638
639 #[test]
640 fn test_owner_write() -> Result<()> {
641 let own = OwnerBlock {
642 config_version: 0,
643 sram_exec: SramExecMode::default(),
644 ownership_key_alg: OwnershipKeyAlg::EcdsaP256,
645 owner_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
646 x: hex::decode("1111111111111111111111111111111111111111111111111111111111111111")?,
647 y: hex::decode("2121212121212121212121212121212121212121212121212121212121212121")?,
648 }),
649 activate_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
650 x: hex::decode("3333333333333333333333333333333333333333333333333333333333333333")?,
651 y: hex::decode("4444444444444444444444444444444444444444444444444444444444444444")?,
652 }),
653 unlock_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
654 x: hex::decode("5555555555555555555555555555555555555555555555555555555555555555")?,
655 y: hex::decode("6666666666666666666666666666666666666666666666666666666666666666")?,
656 }),
657 data: vec![
658 OwnerConfigItem::ApplicationKey(OwnerApplicationKey {
659 key_alg: OwnershipKeyAlg::EcdsaP256,
660 key_domain: ApplicationKeyDomain::Prod,
661 key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
662 x: hex::decode(
663 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
664 )?,
665 y: hex::decode(
666 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
667 )?,
668 }),
669 ..Default::default()
670 }),
671 OwnerConfigItem::FlashConfig(OwnerFlashConfig {
672 config: vec![
673 OwnerFlashRegion {
674 start: 0x000,
675 size: 0x100,
676 flags: FlashFlags::basic(),
677 },
678 OwnerFlashRegion {
679 start: 0x100,
680 size: 0x200,
681 flags: FlashFlags::basic(),
682 },
683 ],
684 ..Default::default()
685 }),
686 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig {
687 config: vec![
688 OwnerInfoPage::new(0, 1, FlashFlags::basic()),
689 OwnerInfoPage::new(1, 5, FlashFlags::basic()),
690 ],
691 ..Default::default()
692 }),
693 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
694 OwnerConfigItem::IsfbConfig(OwnerIsfbConfig {
695 bank: 1,
696 page: 8,
697 pad: 0,
698 erase_conditions: 0x0000_0666,
699 key_domain: ApplicationKeyDomain::Prod,
700 product_words: 128,
701 ..Default::default()
702 }),
703 ],
704 signature: EcdsaRawSignature {
705 r: hex::decode("7777777777777777777777777777777777777777777777777777777777777777")?,
706 s: hex::decode("8888888888888888888888888888888888888888888888888888888888888888")?,
707 },
708 seal: hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")?,
709 ..Default::default()
710 };
711 let mut bin = Vec::new();
712 own.write(&mut bin)?;
713 eprintln!("{}", hexdump_string(&bin)?);
714 assert_eq!(hexdump_string(&bin)?, OWNER_BIN);
715 Ok(())
716 }
717
718 #[test]
719 fn test_owner_read() -> Result<()> {
720 let buf = hexdump_parse(OWNER_BIN)?;
721 let mut cur = std::io::Cursor::new(&buf);
722 let header = TlvHeader::read(&mut cur)?;
723 let own = OwnerBlock::read(&mut cur, header)?;
724 let doc = serde_annotate::serialize(&own)?.to_json5().to_string();
725 eprintln!("{}", doc);
726 assert_eq!(doc, OWNER_JSON);
727 Ok(())
728 }
729}