1use anyhow::Result;
6use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
7use serde::{Deserialize, Serialize};
8use serde_annotate::Annotate;
9use std::convert::TryFrom;
10use std::io::{Read, Write};
11
12use super::GlobalFlags;
13use super::misc::{KeyMaterial, OwnershipKeyAlg, TlvHeader, TlvTag};
14use super::{OwnerApplicationKey, OwnerFlashConfig, OwnerFlashInfoConfig, OwnerRescueConfig};
15use crate::crypto::ecdsa::{EcdsaPrivateKey, EcdsaRawSignature};
16use crate::with_unknown;
17
18with_unknown! {
19 pub enum SramExecMode: u32 [default = Self::DisabledLocked] {
20 DisabledLocked = u32::from_le_bytes(*b"LNEX"),
21 Disabled = u32::from_le_bytes(*b"NOEX"),
22 Enabled = u32::from_le_bytes(*b"EXEC"),
23 }
24
25 pub enum MinSecurityVersion: u32 [default = Self::NoChange] {
26 NoChange = 0xFFFFFFFFu32,
27 }
28
29 pub enum OwnershipUpdateMode: u32 [default = Self::Open] {
30 Open = u32::from_le_bytes(*b"OPEN"),
31 UnlockSelf = u32::from_le_bytes(*b"SELF"),
32 SelfVersion = u32::from_le_bytes(*b"SELV"),
33 NewVersion = u32::from_le_bytes(*b"NEWV"),
34 }
35}
36
37#[derive(Debug, Serialize, Deserialize, Annotate)]
39pub struct OwnerBlock {
40 #[serde(
42 skip_serializing_if = "GlobalFlags::not_debug",
43 default = "OwnerBlock::default_header"
44 )]
45 pub header: TlvHeader,
46 #[serde(default)]
48 pub config_version: u32,
49 #[serde(default)]
51 pub sram_exec: SramExecMode,
52 pub ownership_key_alg: OwnershipKeyAlg,
54 #[serde(default)]
56 pub update_mode: OwnershipUpdateMode,
57 #[serde(default)]
59 pub min_security_version_bl0: MinSecurityVersion,
60 #[serde(default)]
62 pub lock_constraint: u32,
63 #[serde(
65 default = "OwnerBlock::default_constraint",
66 skip_serializing_if = "OwnerBlock::is_default_constraint"
67 )]
68 #[annotate(format=hex)]
69 pub device_id: [u32; 8],
70 #[serde(default, skip_serializing_if = "GlobalFlags::not_debug")]
71 #[annotate(format=hex)]
72 pub reserved: [u32; 16],
73 pub owner_key: KeyMaterial,
75 pub activate_key: KeyMaterial,
77 pub unlock_key: KeyMaterial,
79 #[serde(default)]
81 pub data: Vec<OwnerConfigItem>,
82 #[serde(default, skip_serializing_if = "EcdsaRawSignature::is_empty")]
83 #[annotate(format=hex)]
84 pub signature: EcdsaRawSignature,
86 #[serde(default, skip_serializing_if = "Vec::is_empty", with = "serde_bytes")]
88 #[annotate(format = hexstr)]
89 pub seal: Vec<u8>,
90}
91
92impl Default for OwnerBlock {
93 fn default() -> Self {
94 Self {
95 header: Self::default_header(),
96 config_version: 0,
97 sram_exec: SramExecMode::default(),
98 ownership_key_alg: OwnershipKeyAlg::default(),
99 update_mode: OwnershipUpdateMode::default(),
100 min_security_version_bl0: MinSecurityVersion::default(),
101 lock_constraint: 0,
102 device_id: Self::default_constraint(),
103 reserved: [0u32; 16],
104 owner_key: KeyMaterial::default(),
105 activate_key: KeyMaterial::default(),
106 unlock_key: KeyMaterial::default(),
107 data: Vec::new(),
108 signature: EcdsaRawSignature::default(),
109 seal: Vec::new(),
110 }
111 }
112}
113
114impl OwnerBlock {
115 pub const SIZE: usize = 2048;
116 pub const DATA_SIZE: usize = 1536;
117 pub const SIGNATURE_OFFSET: usize = 1952;
118 const NOT_PRESENT: u8 = 0x5a;
120 const NO_CONSTRAINT: u32 = 0x7e7e7e7e;
121
122 pub fn default_header() -> TlvHeader {
123 TlvHeader::new(TlvTag::Owner, 0, "0.0")
124 }
125 pub fn basic() -> Self {
126 Self {
127 data: vec![
128 OwnerConfigItem::ApplicationKey(OwnerApplicationKey::default()),
129 OwnerConfigItem::FlashConfig(OwnerFlashConfig::basic()),
130 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig::basic()),
131 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
132 ],
133 ..Default::default()
134 }
135 }
136
137 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
138 let header = TlvHeader::new(TlvTag::Owner, Self::SIZE, "0.0");
139 header.write(dest)?;
140 dest.write_u32::<LittleEndian>(self.config_version)?;
141 dest.write_u32::<LittleEndian>(u32::from(self.sram_exec))?;
142 dest.write_u32::<LittleEndian>(u32::from(self.ownership_key_alg))?;
143 dest.write_u32::<LittleEndian>(u32::from(self.update_mode))?;
144 dest.write_u32::<LittleEndian>(u32::from(self.min_security_version_bl0))?;
145 dest.write_u32::<LittleEndian>(self.lock_constraint)?;
146
147 for (i, x) in self.device_id.iter().enumerate() {
148 if self.lock_constraint & (1u32 << i) == 0 {
149 dest.write_u32::<LittleEndian>(Self::NO_CONSTRAINT)?;
150 } else {
151 dest.write_u32::<LittleEndian>(*x)?;
152 }
153 }
154 for x in &self.reserved {
155 dest.write_u32::<LittleEndian>(*x)?;
156 }
157 self.owner_key.write_length(dest, 96)?;
158 self.activate_key.write_length(dest, 96)?;
159 self.unlock_key.write_length(dest, 96)?;
160 let mut data = Vec::new();
161 for item in &self.data {
162 item.write(&mut data)?;
163 }
164 data.resize(Self::DATA_SIZE, Self::NOT_PRESENT);
165 dest.write_all(&data)?;
166 self.signature.write(dest)?;
167 if self.seal.is_empty() {
168 dest.write_all(&[0u8; 32])?;
169 } else {
170 dest.write_all(&self.seal)?;
171 }
172 Ok(())
173 }
174
175 pub fn read(src: &mut impl Read, header: TlvHeader) -> Result<Self> {
176 let config_version = src.read_u32::<LittleEndian>()?;
177 let sram_exec = SramExecMode(src.read_u32::<LittleEndian>()?);
178 let ownership_key_alg = OwnershipKeyAlg(src.read_u32::<LittleEndian>()?);
179 let update_mode = OwnershipUpdateMode(src.read_u32::<LittleEndian>()?);
180 let min_security_version_bl0 = MinSecurityVersion(src.read_u32::<LittleEndian>()?);
181 let lock_constraint = src.read_u32::<LittleEndian>()?;
182
183 let mut device_id = [0u32; 8];
184 src.read_u32_into::<LittleEndian>(&mut device_id)?;
185 let mut reserved = [0u32; 16];
186 src.read_u32_into::<LittleEndian>(&mut reserved)?;
187 let owner_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
188 let activate_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
189 let unlock_key = KeyMaterial::read_length(src, ownership_key_alg, 96)?;
190 let mut bytes = vec![0u8; Self::DATA_SIZE];
191 src.read_exact(&mut bytes)?;
192 let mut cursor = std::io::Cursor::new(&bytes);
193 let mut data = Vec::new();
194 while cursor.position() as usize != Self::DATA_SIZE {
195 match OwnerConfigItem::read(&mut cursor)? {
196 Some(item) => data.push(item),
197 None => break,
198 }
199 }
200 let signature = EcdsaRawSignature::read(src)?;
201 let mut seal = vec![0u8; 32];
202 src.read_exact(&mut seal)?;
203 Ok(Self {
204 header,
205 config_version,
206 sram_exec,
207 ownership_key_alg,
208 update_mode,
209 min_security_version_bl0,
210 lock_constraint,
211 device_id,
212 reserved,
213 owner_key,
214 activate_key,
215 unlock_key,
216 data,
217 signature,
218 seal,
219 })
220 }
221 pub fn sign(&mut self, key: &EcdsaPrivateKey) -> Result<()> {
222 let mut data = Vec::new();
223 self.write(&mut data)?;
224 self.signature = key.digest_and_sign(&data[..Self::SIGNATURE_OFFSET])?;
225 Ok(())
226 }
227
228 pub fn is_default_constraint(d: &[u32; 8]) -> bool {
229 *d == [Self::NO_CONSTRAINT; 8]
230 }
231
232 pub fn default_constraint() -> [u32; 8] {
233 [Self::NO_CONSTRAINT; 8]
234 }
235}
236
237#[derive(Debug, Serialize, Deserialize, Annotate)]
238pub enum OwnerConfigItem {
239 #[serde(alias = "application_key")]
240 ApplicationKey(OwnerApplicationKey),
241 #[serde(alias = "flash_info_config")]
242 FlashInfoConfig(OwnerFlashInfoConfig),
243 #[serde(alias = "flash_config")]
244 FlashConfig(OwnerFlashConfig),
245 #[serde(alias = "rescue_config")]
246 RescueConfig(OwnerRescueConfig),
247 #[serde(alias = "raw")]
248 Raw(
249 #[serde(with = "serde_bytes")]
250 #[annotate(format = hexdump)]
251 Vec<u8>,
252 ),
253}
254
255impl OwnerConfigItem {
256 pub fn write(&self, dest: &mut impl Write) -> Result<()> {
257 match self {
258 Self::ApplicationKey(x) => x.write(dest)?,
259 Self::FlashInfoConfig(x) => x.write(dest)?,
260 Self::FlashConfig(x) => x.write(dest)?,
261 Self::RescueConfig(x) => x.write(dest)?,
262 Self::Raw(x) => dest.write_all(x)?,
263 }
264 Ok(())
265 }
266
267 pub fn read(src: &mut impl Read) -> Result<Option<Self>> {
268 let header = TlvHeader::read(src)?;
269 let item = match header.identifier {
270 TlvTag::ApplicationKey => Self::ApplicationKey(OwnerApplicationKey::read(src, header)?),
271 TlvTag::FlashConfig => Self::FlashConfig(OwnerFlashConfig::read(src, header)?),
272 TlvTag::FlashInfoConfig => {
273 Self::FlashInfoConfig(OwnerFlashInfoConfig::read(src, header)?)
274 }
275 TlvTag::Rescue => Self::RescueConfig(OwnerRescueConfig::read(src, header)?),
276 TlvTag::NotPresent => return Ok(None),
277 _ => {
278 let mut data = Vec::new();
279 header.write(&mut data)?;
280 if header.length >= TlvHeader::SIZE && header.length < OwnerBlock::DATA_SIZE {
281 data.resize(header.length, 0);
282 let len = src.read(&mut data)?;
283 data.resize(len, 0);
284 } else {
285 src.read_to_end(&mut data)?;
286 }
287 Self::Raw(data)
288 }
289 };
290 Ok(Some(item))
291 }
292}
293
294#[cfg(test)]
295mod test {
296 use super::*;
297 use crate::crypto::ecdsa::EcdsaRawPublicKey;
298 use crate::ownership::{
299 ApplicationKeyDomain, FlashFlags, OwnerFlashInfoConfig, OwnerFlashRegion, OwnerInfoPage,
300 OwnerRescueConfig,
301 };
302 use crate::util::hexdump::{hexdump_parse, hexdump_string};
303
304 #[rustfmt::skip]
305 const OWNER_BIN: &str =
306r#"00000000: 4f 57 4e 52 00 08 00 00 00 00 00 00 4c 4e 45 58 OWNR........LNEX
30700000010: 50 32 35 36 4f 50 45 4e ff ff ff ff 00 00 00 00 P256OPEN........
30800000020: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
30900000030: 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e 7e ~~~~~~~~~~~~~~~~
31000000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
31100000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
31200000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
31300000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
31400000080: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
31500000090: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................
316000000a0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
317000000b0: 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 !!!!!!!!!!!!!!!!
318000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
319000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
320000000e0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
321000000f0: 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 3333333333333333
32200000100: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
32300000110: 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
32400000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
32500000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
32600000140: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
32700000150: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU
32800000160: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
32900000170: 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 66 ffffffffffffffff
33000000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
33100000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
332000001a0: 41 50 50 4b 70 00 00 00 50 32 35 36 70 72 6f 64 APPKp...P256prod
333000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
334000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
335000001d0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
336000001e0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ................
337000001f0: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
33800000200: bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb ................
33900000210: 46 4c 53 48 20 00 00 00 00 00 00 01 66 06 00 99 FLSH .......f...
34000000220: 66 06 00 00 00 01 00 02 77 17 11 88 77 17 11 11 f.......w...w...
34100000230: 49 4e 46 4f 20 00 00 00 00 01 00 00 66 06 00 99 INFO .......f...
34200000240: 66 06 00 00 01 05 00 00 77 17 11 88 77 17 11 11 f.......w...w...
34300000250: 52 45 53 51 50 00 00 00 58 4d 44 4d 20 00 e0 00 RESQP...XMDM ...
34400000260: 45 4d 50 54 4d 53 45 43 4e 45 58 54 55 4e 4c 4b EMPTMSECNEXTUNLK
34500000270: 41 43 54 56 51 53 45 52 42 53 45 52 4f 42 45 52 ACTVQSERBSEROBER
34600000280: 47 4f 4c 42 51 45 52 42 50 53 52 42 52 4e 57 4f GOLBQERBPSRBRNWO
34700000290: 30 47 50 4f 31 47 50 4f 44 49 54 4f 54 49 41 57 0GPO1GPODITOTIAW
348000002a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
349000002b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
350000002c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
351000002d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
352000002e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
353000002f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
35400000300: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
35500000310: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
35600000320: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
35700000330: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
35800000340: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
35900000350: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
36000000360: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
36100000370: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
36200000380: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
36300000390: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
364000003a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
365000003b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
366000003c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
367000003d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
368000003e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
369000003f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37000000400: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37100000410: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37200000420: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37300000430: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37400000440: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37500000450: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37600000460: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37700000470: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37800000480: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
37900000490: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
380000004a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
381000004b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
382000004c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
383000004d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
384000004e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
385000004f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
38600000500: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
38700000510: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
38800000520: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
38900000530: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39000000540: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39100000550: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39200000560: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39300000570: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39400000580: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
39500000590: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
396000005a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
397000005b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
398000005c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
399000005d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
400000005e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
401000005f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40200000600: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40300000610: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40400000620: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40500000630: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40600000640: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40700000650: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40800000660: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
40900000670: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41000000680: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41100000690: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
412000006a0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
413000006b0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
414000006c0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
415000006d0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
416000006e0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
417000006f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41800000700: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
41900000710: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42000000720: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42100000730: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42200000740: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42300000750: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42400000760: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42500000770: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42600000780: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
42700000790: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
428000007a0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
429000007b0: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 wwwwwwwwwwwwwwww
430000007c0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
431000007d0: 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 ................
432000007e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
433000007f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
434"#;
435
436 const OWNER_JSON: &str = r#"{
437 config_version: 0,
438 sram_exec: "DisabledLocked",
439 ownership_key_alg: "EcdsaP256",
440 update_mode: "Open",
441 min_security_version_bl0: "NoChange",
442 lock_constraint: 0,
443 owner_key: {
444 Ecdsa: {
445 x: "1111111111111111111111111111111111111111111111111111111111111111",
446 y: "2121212121212121212121212121212121212121212121212121212121212121"
447 }
448 },
449 activate_key: {
450 Ecdsa: {
451 x: "3333333333333333333333333333333333333333333333333333333333333333",
452 y: "4444444444444444444444444444444444444444444444444444444444444444"
453 }
454 },
455 unlock_key: {
456 Ecdsa: {
457 x: "5555555555555555555555555555555555555555555555555555555555555555",
458 y: "6666666666666666666666666666666666666666666666666666666666666666"
459 }
460 },
461 data: [
462 {
463 ApplicationKey: {
464 key_alg: "EcdsaP256",
465 key_domain: "Prod",
466 key_diversifier: [
467 0x0,
468 0x0,
469 0x0,
470 0x0,
471 0x0,
472 0x0,
473 0x0
474 ],
475 usage_constraint: 0x0,
476 key: {
477 Ecdsa: {
478 x: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
479 y: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
480 }
481 }
482 }
483 },
484 {
485 FlashConfig: {
486 config: [
487 {
488 start: 0,
489 size: 256,
490 read: true,
491 program: true,
492 erase: true,
493 scramble: true,
494 ecc: true,
495 high_endurance: true,
496 protect_when_active: false,
497 lock: false
498 },
499 {
500 start: 256,
501 size: 512,
502 read: true,
503 program: true,
504 erase: true,
505 scramble: true,
506 ecc: true,
507 high_endurance: true,
508 protect_when_active: false,
509 lock: false
510 }
511 ]
512 }
513 },
514 {
515 FlashInfoConfig: {
516 config: [
517 {
518 bank: 0,
519 page: 1,
520 pad: 0,
521 read: true,
522 program: true,
523 erase: true,
524 scramble: true,
525 ecc: true,
526 high_endurance: true,
527 protect_when_active: false,
528 lock: false
529 },
530 {
531 bank: 1,
532 page: 5,
533 pad: 0,
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 }
545 },
546 {
547 RescueConfig: {
548 rescue_type: "Xmodem",
549 start: 32,
550 size: 224,
551 command_allow: [
552 "Empty",
553 "MinBl0SecVerRequest",
554 "NextBl0SlotRequest",
555 "OwnershipUnlockRequest",
556 "OwnershipActivateRequest",
557 "Rescue",
558 "RescueB",
559 "Reboot",
560 "GetBootLog",
561 "BootSvcReq",
562 "BootSvcRsp",
563 "OwnerBlock",
564 "GetOwnerPage0",
565 "GetOwnerPage1",
566 "GetDeviceId",
567 "Wait"
568 ]
569 }
570 }
571 ],
572 signature: {
573 r: "7777777777777777777777777777777777777777777777777777777777777777",
574 s: "8888888888888888888888888888888888888888888888888888888888888888"
575 },
576 seal: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
577}"#;
578
579 #[test]
580 fn test_owner_write() -> Result<()> {
581 let own = OwnerBlock {
582 config_version: 0,
583 sram_exec: SramExecMode::default(),
584 ownership_key_alg: OwnershipKeyAlg::EcdsaP256,
585 owner_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
586 x: hex::decode("1111111111111111111111111111111111111111111111111111111111111111")?,
587 y: hex::decode("2121212121212121212121212121212121212121212121212121212121212121")?,
588 }),
589 activate_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
590 x: hex::decode("3333333333333333333333333333333333333333333333333333333333333333")?,
591 y: hex::decode("4444444444444444444444444444444444444444444444444444444444444444")?,
592 }),
593 unlock_key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
594 x: hex::decode("5555555555555555555555555555555555555555555555555555555555555555")?,
595 y: hex::decode("6666666666666666666666666666666666666666666666666666666666666666")?,
596 }),
597 data: vec![
598 OwnerConfigItem::ApplicationKey(OwnerApplicationKey {
599 key_alg: OwnershipKeyAlg::EcdsaP256,
600 key_domain: ApplicationKeyDomain::Prod,
601 key: KeyMaterial::Ecdsa(EcdsaRawPublicKey {
602 x: hex::decode(
603 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
604 )?,
605 y: hex::decode(
606 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
607 )?,
608 }),
609 ..Default::default()
610 }),
611 OwnerConfigItem::FlashConfig(OwnerFlashConfig {
612 config: vec![
613 OwnerFlashRegion {
614 start: 0x000,
615 size: 0x100,
616 flags: FlashFlags::basic(),
617 },
618 OwnerFlashRegion {
619 start: 0x100,
620 size: 0x200,
621 flags: FlashFlags::basic(),
622 },
623 ],
624 ..Default::default()
625 }),
626 OwnerConfigItem::FlashInfoConfig(OwnerFlashInfoConfig {
627 config: vec![
628 OwnerInfoPage::new(0, 1, FlashFlags::basic()),
629 OwnerInfoPage::new(1, 5, FlashFlags::basic()),
630 ],
631 ..Default::default()
632 }),
633 OwnerConfigItem::RescueConfig(OwnerRescueConfig::all()),
634 ],
635 signature: EcdsaRawSignature {
636 r: hex::decode("7777777777777777777777777777777777777777777777777777777777777777")?,
637 s: hex::decode("8888888888888888888888888888888888888888888888888888888888888888")?,
638 },
639 seal: hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")?,
640 ..Default::default()
641 };
642 let mut bin = Vec::new();
643 own.write(&mut bin)?;
644 eprintln!("{}", hexdump_string(&bin)?);
645 assert_eq!(hexdump_string(&bin)?, OWNER_BIN);
646 Ok(())
647 }
648
649 #[test]
650 fn test_owner_read() -> Result<()> {
651 let buf = hexdump_parse(OWNER_BIN)?;
652 let mut cur = std::io::Cursor::new(&buf);
653 let header = TlvHeader::read(&mut cur)?;
654 let own = OwnerBlock::read(&mut cur, header)?;
655 let doc = serde_annotate::serialize(&own)?.to_json5().to_string();
656 eprintln!("{}", doc);
657 assert_eq!(doc, OWNER_JSON);
658 Ok(())
659 }
660}