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::crypto::Error as CryptoError;
20use crate::crypto::ecdsa::{EcdsaPrivateKey, EcdsaRawSignature};
21use crate::with_unknown;
22
23with_unknown! {
24 pub enum SramExecMode: u32 [default = Self::DisabledLocked] {
25 DisabledLocked = u32::from_le_bytes(*b"LNEX"),
26 Disabled = u32::from_le_bytes(*b"NOEX"),
27 Enabled = u32::from_le_bytes(*b"EXEC"),
28 }
29
30 pub enum MinSecurityVersion: u32 [default = Self::NoChange] {
31 NoChange = 0xFFFFFFFFu32,
32 }
33
34 pub enum OwnershipUpdateMode: u32 [default = Self::Open] {
35 Open = u32::from_le_bytes(*b"OPEN"),
36 UnlockSelf = u32::from_le_bytes(*b"SELF"),
37 SelfVersion = u32::from_le_bytes(*b"SELV"),
38 NewVersion = u32::from_le_bytes(*b"NEWV"),
39 }
40}
41
42#[derive(Debug, Deserialize, Annotate)]
44pub struct OwnerBlock {
45 #[serde(
47 skip_serializing_if = "GlobalFlags::not_debug",
48 default = "OwnerBlock::default_header"
49 )]
50 pub header: TlvHeader,
51 #[serde(default)]
53 pub config_version: u32,
54 #[serde(default)]
56 pub sram_exec: SramExecMode,
57 pub ownership_key_alg: OwnershipKeyAlg,
59 #[serde(default)]
61 pub update_mode: OwnershipUpdateMode,
62 #[serde(default)]
64 pub min_security_version_bl0: MinSecurityVersion,
65 #[serde(default)]
67 pub lock_constraint: u32,
68 #[serde(
70 default = "OwnerBlock::default_constraint",
71 skip_serializing_if = "OwnerBlock::is_default_constraint"
72 )]
73 #[annotate(format=hex)]
74 pub device_id: [u32; 8],
75 #[serde(default, skip_serializing_if = "GlobalFlags::not_debug")]
76 #[annotate(format=hex)]
77 pub reserved: [u32; 16],
78 pub owner_key: KeyMaterial,
80 pub activate_key: KeyMaterial,
82 pub unlock_key: KeyMaterial,
84 #[serde(default)]
86 pub data: Vec<OwnerConfigItem>,
87 #[serde(default, skip_serializing_if = "EcdsaRawSignature::is_empty")]
88 #[annotate(format=hex)]
89 pub signature: EcdsaRawSignature,
91 #[serde(default, skip_serializing_if = "Vec::is_empty", with = "serde_bytes")]
93 #[annotate(format = hexstr)]
94 pub seal: Vec<u8>,
95}
96
97impl Default for OwnerBlock {
98 fn default() -> Self {
99 Self {
100 header: Self::default_header(),
101 config_version: 0,
102 sram_exec: SramExecMode::default(),
103 ownership_key_alg: OwnershipKeyAlg::default(),
104 update_mode: OwnershipUpdateMode::default(),
105 min_security_version_bl0: MinSecurityVersion::default(),
106 lock_constraint: 0,
107 device_id: Self::default_constraint(),
108 reserved: [0u32; 16],
109 owner_key: KeyMaterial::default(),
110 activate_key: KeyMaterial::default(),
111 unlock_key: KeyMaterial::default(),
112 data: Vec::new(),
113 signature: EcdsaRawSignature::default(),
114 seal: Vec::new(),
115 }
116 }
117}
118
119impl OwnerBlock {
120 pub const SIZE: usize = 2048;
121 pub const DATA_SIZE: usize = 1536;
122 pub const SIGNATURE_OFFSET: usize = 1952;
123 const NOT_PRESENT: u8 = 0x5a;
125 const NO_CONSTRAINT: u32 = 0x7e7e7e7e;
126
127 pub fn default_header() -> TlvHeader {
128 TlvHeader::new(TlvTag::Owner, 0, "0.0")
129 }
130 pub fn basic() -> Self {
131 Self {
132 data: vec![
133 OwnerConfigItem::ApplicationKey(OwnerApplicationKey::default()),
134 OwnerConfigItem::FlashConfig(OwnerFlashConfig::basic()),
135 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig::basic()),
136 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
137 ],
138 ..Default::default()
139 }
140 }
141
142 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
143 let header = TlvHeader::new(TlvTag::Owner, Self::SIZE, "0.0");
144 header.write(dest)?;
145 dest.write_u32::<LittleEndian>(self.config_version)?;
146 dest.write_u32::<LittleEndian>(u32::from(self.sram_exec))?;
147 dest.write_u32::<LittleEndian>(u32::from(self.ownership_key_alg))?;
148 dest.write_u32::<LittleEndian>(u32::from(self.update_mode))?;
149 dest.write_u32::<LittleEndian>(u32::from(self.min_security_version_bl0))?;
150 dest.write_u32::<LittleEndian>(self.lock_constraint)?;
151
152 for (i, x) in self.device_id.iter().enumerate() {
153 if self.lock_constraint & (1u32 << i) == 0 {
154 dest.write_u32::<LittleEndian>(Self::NO_CONSTRAINT)?;
155 } else {
156 dest.write_u32::<LittleEndian>(*x)?;
157 }
158 }
159 for x in &self.reserved {
160 dest.write_u32::<LittleEndian>(*x)?;
161 }
162 self.owner_key.write_length(dest, 96)?;
163 self.activate_key.write_length(dest, 96)?;
164 self.unlock_key.write_length(dest, 96)?;
165 let mut data = Vec::new();
166 for item in &self.data {
167 item.write(&mut data)?;
168 }
169 data.resize(Self::DATA_SIZE, Self::NOT_PRESENT);
170 dest.write_all(&data)?;
171 self.signature.write(dest)?;
172 if self.seal.is_empty() {
173 dest.write_all(&[0u8; 32])?;
174 } else {
175 dest.write_all(&self.seal)?;
176 }
177 Ok(())
178 }
179
180 pub fn read(src: &mut impl Read, header: TlvHeader) -> Result<Self> {
181 let config_version = src.read_u32::<LittleEndian>()?;
182 let sram_exec = SramExecMode(src.read_u32::<LittleEndian>()?);
183 let ownership_key_alg = OwnershipKeyAlg(src.read_u32::<LittleEndian>()?);
184 let update_mode = OwnershipUpdateMode(src.read_u32::<LittleEndian>()?);
185 let min_security_version_bl0 = MinSecurityVersion(src.read_u32::<LittleEndian>()?);
186 let lock_constraint = src.read_u32::<LittleEndian>()?;
187
188 let mut device_id = [0u32; 8];
189 src.read_u32_into::<LittleEndian>(&mut device_id)?;
190 let mut reserved = [0u32; 16];
191 src.read_u32_into::<LittleEndian>(&mut reserved)?;
192 let owner_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
193 let activate_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
194 let unlock_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
195 let mut bytes = vec![0u8; Self::DATA_SIZE];
196 src.read_exact(&mut bytes)?;
197 let mut cursor = std::io::Cursor::new(&bytes);
198 let mut data = Vec::new();
199 while cursor.position() as usize != Self::DATA_SIZE {
200 match OwnerConfigItem::read(&mut cursor)? {
201 Some(item) => data.push(item),
202 None => break,
203 }
204 }
205 let signature = EcdsaRawSignature::read(src)?;
206 let mut seal = vec![0u8; 32];
207 src.read_exact(&mut seal)?;
208 Ok(Self {
209 header,
210 config_version,
211 sram_exec,
212 ownership_key_alg,
213 update_mode,
214 min_security_version_bl0,
215 lock_constraint,
216 device_id,
217 reserved,
218 owner_key,
219 activate_key,
220 unlock_key,
221 data,
222 signature,
223 seal,
224 })
225 }
226 pub fn sign(&mut self, key: &EcdsaPrivateKey) -> Result<()> {
227 ensure!(
228 self.ownership_key_alg == OwnershipKeyAlg::EcdsaP256,
229 CryptoError::SignFailed(anyhow!(
230 "Algorithm {} requires a detached signature",
231 self.ownership_key_alg
232 ))
233 );
234 let mut data = Vec::new();
235 self.write(&mut data)?;
236 self.signature = key.digest_and_sign(&data[..Self::SIGNATURE_OFFSET])?;
237 Ok(())
238 }
239
240 pub fn detached_sign(
241 &mut self,
242 nonce: u64,
243 ecdsa_key: Option<&EcdsaPrivateKey>,
244 spx_key: Option<&SpxSecretKey>,
245 ) -> Result<DetachedSignature> {
246 self.signature = Default::default();
247 let mut data = Vec::new();
248 self.write(&mut data)?;
249 DetachedSignature::new(
250 &data[..Self::SIGNATURE_OFFSET],
251 TlvTag::Owner.into(),
252 self.ownership_key_alg,
253 nonce,
254 ecdsa_key,
255 spx_key,
256 )
257 }
258
259 pub fn is_default_constraint(d: &[u32; 8]) -> bool {
260 *d == [Self::NO_CONSTRAINT; 8]
261 }
262
263 pub fn default_constraint() -> [u32; 8] {
264 [Self::NO_CONSTRAINT; 8]
265 }
266}
267
268#[derive(Debug, Deserialize, Annotate)]
269pub enum OwnerConfigItem {
270 #[serde(alias = "application_key")]
271 ApplicationKey(OwnerApplicationKey),
272 #[serde(alias = "flash_info_config")]
273 FlashInfoConfig(OwnerFlashInfoConfig),
274 #[serde(alias = "flash_config")]
275 FlashConfig(OwnerFlashConfig),
276 #[serde(alias = "rescue_config")]
277 RescueConfig(OwnerRescueConfig),
278 #[serde(alias = "isfb_config")]
279 IsfbConfig(OwnerIsfbConfig),
280 #[serde(alias = "raw")]
281 Raw(
282 #[serde(with = "serde_bytes")]
283 #[annotate(format = hexdump)]
284 Vec<u8>,
285 ),
286}
287
288impl OwnerConfigItem {
289 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
290 match self {
291 Self::ApplicationKey(x) => x.write(dest)?,
292 Self::FlashInfoConfig(x) => x.write(dest)?,
293 Self::FlashConfig(x) => x.write(dest)?,
294 Self::RescueConfig(x) => x.write(dest)?,
295 Self::IsfbConfig(x) => x.write(dest)?,
296 Self::Raw(x) => dest.write_all(x)?,
297 }
298 Ok(())
299 }
300
301 pub fn read(src: &mut impl Read) -> Result<Option<Self>> {
302 let header = TlvHeader::read(src)?;
303 let item = match header.identifier {
304 TlvTag::ApplicationKey => Self::ApplicationKey(OwnerApplicationKey::read(src, header)?),
305 TlvTag::FlashConfig => Self::FlashConfig(OwnerFlashConfig::read(src, header)?),
306 TlvTag::FlashInfoConfig => {
307 Self::FlashInfoConfig(OwnerFlashInfoConfig::read(src, header)?)
308 }
309 TlvTag::Rescue => Self::RescueConfig(OwnerRescueConfig::read(src, header)?),
310 TlvTag::IntegratorSpecificFirmwareBinding => {
311 Self::IsfbConfig(OwnerIsfbConfig::read(src, header)?)
312 }
313 TlvTag::NotPresent => return Ok(None),
314 _ => {
315 let mut data = Vec::new();
316 header.write(&mut data)?;
317 if header.length >= TlvHeader::SIZE && header.length < OwnerBlock::DATA_SIZE {
318 data.resize(header.length, 0);
319 let len = src.read(&mut data)?;
320 data.resize(len, 0);
321 } else {
322 src.read_to_end(&mut data)?;
323 }
324 Self::Raw(data)
325 }
326 };
327 Ok(Some(item))
328 }
329}
330
331#[cfg(test)]
332mod test {
333 use super::*;
334 use crate::crypto::ecdsa::EcdsaRawPublicKey;
335 use crate::ownership::{
336 ApplicationKeyDomain, FlashFlags, OwnerFlashInfoConfig, OwnerFlashRegion, OwnerInfoPage,
337 OwnerRescueConfig,
338 };
339 use crate::util::hexdump::{hexdump_parse, hexdump_string};
340
341 #[rustfmt::skip]
342 const OWNER_BIN: &str =
343r#"00000000: 4f 57 4e 52 00 08 00 00 00 00 00 00 4c 4e 45 58 OWNR........LNEX
34400000010: 50 32 35 36 4f 50 45 4e ff ff ff ff 00 00 00 00 P256OPEN........
34500000020: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
34600000030: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
34700000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
34800000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
34900000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35000000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
35100000080: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
35200000090: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
353000000a0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
354000000b0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
355000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
356000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
357000000e0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
358000000f0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
35900000100: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
36000000110: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
36100000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
36200000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
36300000140: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
36400000150: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
36500000160: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
36600000170: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
36700000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
36800000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
369000001a0: 41 50 50 4b 70 00 00 00 50 32 35 36 70 72 6f 64 APPKp...P256prod
370000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
371000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
372000001d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
373000001e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
374000001f0: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
37500000200: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
37600000210: 46 4c 53 48 20 00 00 00 00 00 00 01 66 06 00 99 FLSH .......f...
37700000220: 66 06 00 00 00 01 00 02 77 17 11 88 77 17 11 11 f.......w...w...
37800000230: 49 4e 46 4f 20 00 00 00 00 01 00 00 66 06 00 99 INFO .......f...
37900000240: 66 06 00 00 01 05 00 00 77 17 11 88 77 17 11 11 f.......w...w...
38000000250: 52 45 53 51 50 00 00 00 58 00 00 40 20 00 e0 00 RESQP...X..@ ...
38100000260: 45 4d 50 54 4d 53 45 43 4e 45 58 54 55 4e 4c 4b EMPTMSECNEXTUNLK
38200000270: 41 43 54 56 51 53 45 52 42 53 45 52 4f 42 45 52 ACTVQSERBSEROBER
38300000280: 47 4f 4c 42 51 45 52 42 50 53 52 42 52 4e 57 4f GOLBQERBPSRBRNWO
38400000290: 30 47 50 4f 31 47 50 4f 44 49 54 4f 54 49 41 57 0GPO1GPODITOTIAW
385000002a0: 49 53 46 42 2c 00 00 00 01 08 00 00 66 06 00 00 ISFB,.......f...
386000002b0: 70 72 6f 64 00 00 00 00 00 00 00 00 00 00 00 00 prod............
387000002c0: 00 00 00 00 00 00 00 00 80 00 00 00 5a 5a 5a 5a ............ZZZZ
388000002d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
389000002e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
390000002f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39100000300: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39200000310: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39300000320: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39400000330: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39500000340: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39600000350: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39700000360: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39800000370: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39900000380: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40000000390: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
401000003a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
402000003b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
403000003c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
404000003d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
405000003e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
406000003f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40700000400: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40800000410: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40900000420: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41000000430: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41100000440: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41200000450: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41300000460: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41400000470: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41500000480: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41600000490: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
417000004a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
418000004b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
419000004c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
420000004d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
421000004e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
422000004f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42300000500: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42400000510: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42500000520: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42600000530: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42700000540: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42800000550: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42900000560: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43000000570: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43100000580: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43200000590: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
433000005a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
434000005b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
435000005c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
436000005d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
437000005e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
438000005f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
43900000600: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44000000610: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44100000620: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44200000630: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44300000640: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44400000650: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44500000660: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44600000670: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44700000680: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
44800000690: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
449000006a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
450000006b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
451000006c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
452000006d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
453000006e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
454000006f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45500000700: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45600000710: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45700000720: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45800000730: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
45900000740: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46000000750: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46100000760: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46200000770: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46300000780: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
46400000790: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
465000007a0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
466000007b0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
467000007c0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
468000007d0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
469000007e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
470000007f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
471"#;
472
473 const OWNER_JSON: &str = r#"{
474 config_version: 0,
475 sram_exec: "DisabledLocked",
476 ownership_key_alg: "EcdsaP256",
477 update_mode: "Open",
478 min_security_version_bl0: "NoChange",
479 lock_constraint: 0,
480 owner_key: {
481 Ecdsa: {
482 x: "1111111111111111111111111111111111111111111111111111111111111111",
483 y: "2121212121212121212121212121212121212121212121212121212121212121"
484 }
485 },
486 activate_key: {
487 Ecdsa: {
488 x: "3333333333333333333333333333333333333333333333333333333333333333",
489 y: "4444444444444444444444444444444444444444444444444444444444444444"
490 }
491 },
492 unlock_key: {
493 Ecdsa: {
494 x: "5555555555555555555555555555555555555555555555555555555555555555",
495 y: "6666666666666666666666666666666666666666666666666666666666666666"
496 }
497 },
498 data: [
499 {
500 ApplicationKey: {
501 key_alg: "EcdsaP256",
502 key_domain: "Prod",
503 key_diversifier: [
504 0x0,
505 0x0,
506 0x0,
507 0x0,
508 0x0,
509 0x0,
510 0x0
511 ],
512 usage_constraint: 0x0,
513 key: {
514 Ecdsa: {
515 x: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
516 y: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
517 }
518 }
519 }
520 },
521 {
522 FlashConfig: {
523 config: [
524 {
525 start: 0,
526 size: 256,
527 read: true,
528 program: true,
529 erase: true,
530 scramble: true,
531 ecc: true,
532 high_endurance: true,
533 protect_when_active: false,
534 lock: false
535 },
536 {
537 start: 256,
538 size: 512,
539 read: true,
540 program: true,
541 erase: true,
542 scramble: true,
543 ecc: true,
544 high_endurance: true,
545 protect_when_active: false,
546 lock: false
547 }
548 ]
549 }
550 },
551 {
552 FlashInfoConfig: {
553 config: [
554 {
555 bank: 0,
556 page: 1,
557 pad: 0,
558 read: true,
559 program: true,
560 erase: true,
561 scramble: true,
562 ecc: true,
563 high_endurance: true,
564 protect_when_active: false,
565 lock: false
566 },
567 {
568 bank: 1,
569 page: 5,
570 pad: 0,
571 read: true,
572 program: true,
573 erase: true,
574 scramble: true,
575 ecc: true,
576 high_endurance: true,
577 protect_when_active: false,
578 lock: false
579 }
580 ]
581 }
582 },
583 {
584 RescueConfig: {
585 protocol: "Xmodem",
586 trigger: "UartBreak",
587 trigger_index: 0,
588 gpio_pull_en: false,
589 gpio_value: false,
590 start: 32,
591 size: 224,
592 command_allow: [
593 "Empty",
594 "MinBl0SecVerRequest",
595 "NextBl0SlotRequest",
596 "OwnershipUnlockRequest",
597 "OwnershipActivateRequest",
598 "Rescue",
599 "RescueB",
600 "Reboot",
601 "GetBootLog",
602 "BootSvcReq",
603 "BootSvcRsp",
604 "OwnerBlock",
605 "GetOwnerPage0",
606 "GetOwnerPage1",
607 "GetDeviceId",
608 "Wait"
609 ]
610 }
611 },
612 {
613 IsfbConfig: {
614 bank: 1,
615 page: 8,
616 erase_conditions: 0x666,
617 key_domain: "Prod",
618 product_words: 128
619 }
620 }
621 ],
622 signature: {
623 r: "7777777777777777777777777777777777777777777777777777777777777777",
624 s: "8888888888888888888888888888888888888888888888888888888888888888"
625 },
626 seal: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
627}"#;
628
629 #[test]
630 fn test_owner_write() -> Result<()> {
631 let own = OwnerBlock {
632 config_version: 0,
633 sram_exec: SramExecMode::default(),
634 ownership_key_alg: OwnershipKeyAlg::EcdsaP256,
635 owner_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
636 x: hex::decode("1111111111111111111111111111111111111111111111111111111111111111")?,
637 y: hex::decode("2121212121212121212121212121212121212121212121212121212121212121")?,
638 }),
639 activate_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
640 x: hex::decode("3333333333333333333333333333333333333333333333333333333333333333")?,
641 y: hex::decode("4444444444444444444444444444444444444444444444444444444444444444")?,
642 }),
643 unlock_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
644 x: hex::decode("5555555555555555555555555555555555555555555555555555555555555555")?,
645 y: hex::decode("6666666666666666666666666666666666666666666666666666666666666666")?,
646 }),
647 data: vec![
648 OwnerConfigItem::ApplicationKey(OwnerApplicationKey {
649 key_alg: OwnershipKeyAlg::EcdsaP256,
650 key_domain: ApplicationKeyDomain::Prod,
651 key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
652 x: hex::decode(
653 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
654 )?,
655 y: hex::decode(
656 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
657 )?,
658 }),
659 ..Default::default()
660 }),
661 OwnerConfigItem::FlashConfig(OwnerFlashConfig {
662 config: vec![
663 OwnerFlashRegion {
664 start: 0x000,
665 size: 0x100,
666 flags: FlashFlags::basic(),
667 },
668 OwnerFlashRegion {
669 start: 0x100,
670 size: 0x200,
671 flags: FlashFlags::basic(),
672 },
673 ],
674 ..Default::default()
675 }),
676 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig {
677 config: vec![
678 OwnerInfoPage::new(0, 1, FlashFlags::basic()),
679 OwnerInfoPage::new(1, 5, FlashFlags::basic()),
680 ],
681 ..Default::default()
682 }),
683 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
684 OwnerConfigItem::IsfbConfig(OwnerIsfbConfig {
685 bank: 1,
686 page: 8,
687 pad: 0,
688 erase_conditions: 0x0000_0666,
689 key_domain: ApplicationKeyDomain::Prod,
690 product_words: 128,
691 ..Default::default()
692 }),
693 ],
694 signature: EcdsaRawSignature {
695 r: hex::decode("7777777777777777777777777777777777777777777777777777777777777777")?,
696 s: hex::decode("8888888888888888888888888888888888888888888888888888888888888888")?,
697 },
698 seal: hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")?,
699 ..Default::default()
700 };
701 let mut bin = Vec::new();
702 own.write(&mut bin)?;
703 eprintln!("{}", hexdump_string(&bin)?);
704 assert_eq!(hexdump_string(&bin)?, OWNER_BIN);
705 Ok(())
706 }
707
708 #[test]
709 fn test_owner_read() -> Result<()> {
710 let buf = hexdump_parse(OWNER_BIN)?;
711 let mut cur = std::io::Cursor::new(&buf);
712 let header = TlvHeader::read(&mut cur)?;
713 let own = OwnerBlock::read(&mut cur, header)?;
714 let doc = serde_annotate::serialize(&own)?.to_json5().to_string();
715 eprintln!("{}", doc);
716 assert_eq!(doc, OWNER_JSON);
717 Ok(())
718 }
719}