mbn/
metadata.rs

1use std::mem::size_of;
2
3use crate::{
4    byte_read::{ByteRead, ByteReader},
5    error::ParseError,
6};
7
8/// The [`flags`](MetadataLen120::flags) field of [`MetadataLen120`].
9///
10/// See [`QtiFlagsV6Builder`] for build a [`QtiFlagsV6`].
11#[repr(transparent)]
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
13pub struct QtiFlagsV6(pub u32);
14
15/// Builder for [`QtiFlagsV6`].
16#[repr(transparent)]
17#[derive(Clone, Copy, Debug, Default)]
18pub struct QtiFlagsV6Builder(u32);
19
20/// The [`flags`](MetadataLen224::flags) field of [`MetadataLen224`].
21///
22/// This version of QTI flags use `0b01` as `false` and `0b10` as `true`,
23/// so illegal values may appear in each field.
24///
25/// See [`QtiFlagsV7Builder`] for build a [`QtiFlagsV7`].
26#[repr(transparent)]
27#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28pub struct QtiFlagsV7(pub u32);
29
30/// Builder for [`QtiFlagsV7`].
31#[repr(transparent)]
32#[derive(Clone, Copy, Debug, Default)]
33pub struct QtiFlagsV7Builder(u32);
34
35/// The common metadata representation.
36///
37/// Only [`HashTableSegment`](crate::HashTableSegment)
38/// containing [`MbnHeaderV7`](crate::MbnHeaderV7) has common metadata.
39#[repr(packed)]
40#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
41pub struct CommonMetadata {
42    /// Metadata major version.
43    pub major_version: u32,
44    /// Metadata minor version.
45    pub minor_version: u32,
46    /// A 32-bit software type value of the image which specifies the signed image.
47    pub software_id: u32,
48    /// Required for a TZ application.
49    pub app_id: u32,
50    /// Hash algorithm used for hash table.
51    ///
52    /// * 2: SHA256
53    /// * 3: SHA384
54    pub hash_table_algorithm: u32,
55    /// Measurement Register Target.
56    ///
57    /// * 0: None
58    /// * 1: Hardware Measurement Register #1
59    /// * 2: Hardware Measurement Register #2
60    /// * 3: Firmware Measurement Register #1
61    /// * 4: Firmware Measurement Register #2
62    /// * 5: Firmware Measurement Register #3
63    /// * 6: Firmware Measurement Register #4
64    pub measurement_register: u32,
65}
66
67/// The 120 bytes QTI metadata and OEM metadata representation.
68///
69/// Only [`HashTableSegment`](crate::HashTableSegment)
70/// containing [`MbnHeaderV6`](crate::MbnHeaderV6) has 120 bytes metadata.
71#[repr(packed)]
72#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
73pub struct MetadataLen120 {
74    /// Metadata major version.
75    pub major_version: u32,
76    /// Metadata minor version.
77    pub minor_version: u32,
78    /// A 32-bit software type value of the image which specifies the signed image.
79    pub software_id: u32,
80    /// The hardware ID is composed of JTAG ID.
81    pub hardware_id: u32,
82    /// A 32-bit value served as CASS account ID for the OEM.
83    pub oem_id: u32,
84    /// Model ID prevents misuse of images across various models.
85    pub model_id: u32,
86    /// Required for a TZ application.
87    pub app_id: u32,
88    /// See [`QtiFlagsV6`].
89    pub flags: QtiFlagsV6,
90    /// Contains up to 12 unique SoC hardware version values.
91    pub soc_version: [u32; 12],
92    /// Contains up to 8 serial numbers.
93    pub multi_serial_numbers: [u32; 8],
94    /// The active root certificate index in MRC (Multiple Root Certificate).
95    pub root_cert_index: u32,
96    /// Anti-rollback version specifies the minimum supported version.
97    pub anti_rollback_version: u32,
98}
99
100/// The 224 bytes QTI metadata and OEM metadata representation.
101///
102/// Only [`HashTableSegment`](crate::HashTableSegment)
103/// containing [`MbnHeaderV7`](crate::MbnHeaderV7) has 224 bytes metadata.
104#[repr(packed)]
105#[derive(Clone, Copy, Debug, PartialEq, Eq)]
106pub struct MetadataLen224 {
107    /// Metadata major version.
108    pub major_version: u32,
109    /// Metadata minor version.
110    pub minor_version: u32,
111    /// Anti-rollback version specifies the minimum supported version.
112    pub anti_rollback_version: u32,
113    /// The active root certificate index in MRC (Multiple Root Certificate).
114    pub root_cert_index: u32,
115    /// Contains up to 12 unique SoC hardware version values.
116    pub soc_version: [u32; 12],
117    /// SoC feature ID.
118    pub feature_id: u32,
119    /// The hardware ID is composed of JTAG ID.
120    pub hardware_id: u32,
121    /// Contains up to 8 serial numbers.
122    pub multi_serial_numbers: [u64; 8],
123    /// A 32-bit value served as CASS account ID for the OEM.
124    pub oem_id: u32,
125    /// Model ID prevents misuse of images across various models.
126    pub model_id: u32,
127    /// OEM lifecycle state.
128    ///
129    /// * `0x200000000`: Development
130    /// * `0xD00000000`: Production
131    pub oem_lifecycle_state: u64,
132    /// Hash algorithm used for OEM root certificate.
133    ///
134    /// * 0: N/A
135    /// * 2: SHA256
136    /// * 3: SHA384
137    pub oem_root_cert_hash_algorithm: u32,
138    /// OEM root certificate hash value.
139    ///
140    /// Use the last 32 bytes when [`oem_root_cert_hash_algorithm`](MetadataLen224::oem_root_cert_hash_algorithm)
141    /// is 2 (SHA256) or the last 48 bytes when it is 3 (SHA384).
142    pub oem_root_cert_hash: [u8; 64],
143    /// See [`QtiFlagsV7`].
144    pub flags: QtiFlagsV7,
145}
146
147/// The QTI metadata and OEM metadata representation.
148///
149/// Only [`HashTableSegment`](crate::HashTableSegment)
150/// containing MBN header with version greater than 6 has this metadata.
151#[derive(Clone, Copy, Debug, PartialEq, Eq)]
152pub enum Metadata {
153    Len120(MetadataLen120),
154    Len224(MetadataLen224),
155}
156
157impl QtiFlagsV6 {
158    /// RoT (Root of Trust) enablement.
159    pub fn rot_en(&self) -> bool {
160        self.0 & 1 != 0
161    }
162
163    /// Using [`MetadataLen120::soc_version`] in image signing.
164    pub fn use_soc_hw_version(&self) -> bool {
165        self.0 & (1 << 1) != 0
166    }
167
168    /// Using serial number in image signing.
169    pub fn use_serial_number(&self) -> bool {
170        self.0 & (1 << 2) != 0
171    }
172
173    /// Using [`MetadataLen120::oem_id`] in image signing if **`false`**.
174    pub fn oem_id_independent(&self) -> bool {
175        self.0 & (1 << 3) != 0
176    }
177
178    /// Enables revocation and activation in MRC (Multiple Root Certificate).
179    ///
180    /// * 0: Disable
181    /// * 1: Enable
182    /// * 2: Enable with serial number binding provided in the [`MetadataLen120::multi_serial_numbers`] field.
183    pub fn root_revoke_activate_enable(&self) -> u8 {
184        ((self.0 >> 4) & 0b11) as u8
185    }
186
187    /// Enables UIE (Unified Image Encryption) key switch.
188    ///
189    /// * 0: Disable
190    /// * 1: Enable
191    /// * 2: Enable with serial number binding provided in the [`MetadataLen120::multi_serial_numbers`] field.
192    pub fn uie_key_switch_enable(&self) -> u8 {
193        ((self.0 >> 6) & 0b11) as u8
194    }
195
196    /// JTAG debug.
197    ///
198    /// * 0: Nothing is written to the one-time debug override registers.
199    /// * 1: `0` is to be written to the one-time debug override registers.
200    /// * 2: `1` is to be written to the one-time debug override registers.
201    pub fn debug(&self) -> u8 {
202        ((self.0 >> 8) & 0b11) as u8
203    }
204
205    /// Using [`MetadataLen120::hardware_id`] in image signing.
206    ///
207    /// Valid only when [`MetadataLen120::major_version`] is greater than 0.
208    pub fn use_hw_id(&self) -> bool {
209        self.0 & (1 << 10) != 0
210    }
211
212    /// Using [`MetadataLen120::model_id`] in image signing if **`false`**.
213    ///
214    /// Valid only when [`MetadataLen120::major_version`] is greater than 0.
215    pub fn model_id_independent(&self) -> bool {
216        self.0 & (1 << 11) != 0
217    }
218}
219
220impl QtiFlagsV6Builder {
221    fn set_bit(&mut self, bit: u8) {
222        self.0 |= 1 << bit;
223    }
224
225    fn clear_bit(&mut self, bit: u8) {
226        self.0 &= !(1 << bit);
227    }
228
229    fn set_value(&mut self, start: u8, end: u8, value: u8) {
230        (start..end).for_each(|x| self.clear_bit(x));
231        let mask = (1 << (end - start)) - 1;
232        self.0 |= (value as u32 & mask) << start;
233    }
234
235    /// Create a new builder.
236    pub fn new() -> Self {
237        Default::default()
238    }
239
240    /// Create a new builder based on [`QtiFlagsV6`].
241    pub fn with(flags: QtiFlagsV6) -> Self {
242        Self(flags.0)
243    }
244
245    /// Build [`QtiFlagsV6`].
246    pub fn build(self) -> QtiFlagsV6 {
247        QtiFlagsV6(self.0)
248    }
249
250    /// Set [`rot_en`](QtiFlagsV6::rot_en()) bit.
251    pub fn rot_en(&mut self) {
252        self.set_bit(0);
253    }
254
255    /// Set [`use_soc_hw_version`](QtiFlagsV6::use_soc_hw_version()) bit.
256    pub fn use_soc_hw_version(&mut self) {
257        self.set_bit(1);
258    }
259
260    /// Set [`use_serial_number`](QtiFlagsV6::use_serial_number) bit.
261    pub fn use_use_serial_number(&mut self) {
262        self.set_bit(2);
263    }
264
265    /// Set [`oem_id_independent`](QtiFlagsV6::oem_id_independent()) bit.
266    pub fn oem_id_independent(&mut self) {
267        self.set_bit(3);
268    }
269
270    /// Set [`root_revoke_activate_enable`](QtiFlagsV6::root_revoke_activate_enable()) value.
271    pub fn root_revoke_activate_enable(&mut self, value: u8) {
272        self.set_value(4, 6, value);
273    }
274
275    /// Set [`uie_key_switch_enable`](QtiFlagsV6::uie_key_switch_enable()) value.
276    pub fn uie_key_switch_enable(&mut self, value: u8) {
277        self.set_value(6, 8, value);
278    }
279
280    /// Set [`debug`](QtiFlagsV6::debug()) value.
281    pub fn debug(&mut self, value: u8) {
282        self.set_value(8, 10, value);
283    }
284
285    /// Set [`use_hw_id`](QtiFlagsV6::use_hw_id()) bit.
286    pub fn use_hw_id(&mut self) {
287        self.set_bit(10);
288    }
289
290    /// Set [`model_id_independent`](QtiFlagsV6::model_id_independent()) bit.
291    pub fn model_id_independent(&mut self) {
292        self.set_bit(11);
293    }
294}
295
296impl QtiFlagsV7 {
297    /// Using [`MetadataLen224::soc_version`] in image signing.
298    pub fn use_soc_hw_version(&self) -> Result<bool, u8> {
299        match self.0 & 0b11 {
300            0b01 => Ok(false),
301            0b10 => Ok(true),
302            unknown => Err(unknown as u8),
303        }
304    }
305
306    /// Using [`MetadataLen224::feature_id`] in image signing.
307    pub fn use_feature_id(&self) -> Result<bool, u8> {
308        match (self.0 >> 2) & 0b11 {
309            0b01 => Ok(false),
310            0b10 => Ok(true),
311            unknown => Err(unknown as u8),
312        }
313    }
314
315    /// Using [`MetadataLen224::hardware_id`] in image signing.
316    pub fn use_hw_id(&self) -> Result<bool, u8> {
317        match (self.0 >> 4) & 0b11 {
318            0b01 => Ok(false),
319            0b10 => Ok(true),
320            unknown => Err(unknown as u8),
321        }
322    }
323
324    /// Using serial number in image signing.
325    pub fn use_serial_number(&self) -> Result<bool, u8> {
326        match (self.0 >> 6) & 0b11 {
327            0b01 => Ok(false),
328            0b10 => Ok(true),
329            unknown => Err(unknown as u8),
330        }
331    }
332
333    /// Using [`MetadataLen224::oem_id`] in image signing.
334    pub fn use_oem_id(&self) -> Result<bool, u8> {
335        match (self.0 >> 8) & 0b11 {
336            0b01 => Ok(false),
337            0b10 => Ok(true),
338            unknown => Err(unknown as u8),
339        }
340    }
341
342    /// Using [`MetadataLen224::model_id`] in image signing.
343    pub fn use_model_id(&self) -> Result<bool, u8> {
344        match (self.0 >> 10) & 0b11 {
345            0b01 => Ok(false),
346            0b10 => Ok(true),
347            unknown => Err(unknown as u8),
348        }
349    }
350
351    /// Using SoC lifecycle state in image signing.
352    pub fn use_soc_lifecycle_state(&self) -> Result<bool, u8> {
353        match (self.0 >> 12) & 0b11 {
354            0b01 => Ok(false),
355            0b10 => Ok(true),
356            unknown => Err(unknown as u8),
357        }
358    }
359
360    /// Using [`MetadataLen224::oem_lifecycle_state`] in image signing.
361    pub fn use_oem_lifecycle_state(&self) -> Result<bool, u8> {
362        match (self.0 >> 14) & 0b11 {
363            0b01 => Ok(false),
364            0b10 => Ok(true),
365            unknown => Err(unknown as u8),
366        }
367    }
368
369    /// Using [`MetadataLen224::oem_root_cert_hash`] in image signing.
370    pub fn use_oem_root_cert_hash(&self) -> Result<bool, u8> {
371        match (self.0 >> 16) & 0b11 {
372            0b01 => Ok(false),
373            0b10 => Ok(true),
374            unknown => Err(unknown as u8),
375        }
376    }
377
378    /// JTAG debug.
379    ///
380    /// * `false`: Nothing is written to the one-time debug override registers.
381    /// * `true`: `0` is to be written to the one-time debug override registers.
382    ///
383    /// *It seems that `1` is no longer supported? Not clear.*
384    pub fn debug(&self) -> Result<bool, u8> {
385        match (self.0 >> 18) & 0b11 {
386            0b01 => Ok(false),
387            0b10 => Ok(true),
388            unknown => Err(unknown as u8),
389        }
390    }
391
392    /// RoT (Root of Trust) enablement.
393    pub fn rot_en(&self) -> Result<bool, u8> {
394        match (self.0 >> 20) & 0b11 {
395            0b01 => Ok(false),
396            0b10 => Ok(true),
397            unknown => Err(unknown as u8),
398        }
399    }
400}
401
402impl QtiFlagsV7Builder {
403    fn clear_bit(&mut self, bit: u8) {
404        self.0 &= !(1 << bit);
405    }
406
407    fn set_true(&mut self, start: u8) {
408        (start..start + 2).for_each(|x| self.clear_bit(x));
409        self.0 |= 0b10 << start;
410    }
411
412    /// Create a new builder.
413    pub fn new() -> Self {
414        Self(0b0101010101010101010101)
415    }
416
417    /// Create a new builder based on [`QtiFlagsV7`].
418    pub fn with(flags: QtiFlagsV7) -> Self {
419        Self(flags.0)
420    }
421
422    /// Build [`QtiFlagsV7`].
423    pub fn build(self) -> QtiFlagsV7 {
424        QtiFlagsV7(self.0)
425    }
426
427    /// Set [`use_soc_hw_version`](QtiFlagsV7::use_soc_hw_version()) to `true`.
428    pub fn use_soc_hw_version(&mut self) {
429        self.set_true(0);
430    }
431
432    /// Set [`use_feature_id`](QtiFlagsV7::use_feature_id()) to `true`.
433    pub fn use_feature_id(&mut self) {
434        self.set_true(2);
435    }
436
437    /// Set [`use_hw_id`](QtiFlagsV7::use_hw_id()) to `true`.
438    pub fn use_hw_id(&mut self) {
439        self.set_true(4);
440    }
441
442    /// Set [`use_serial_number`](QtiFlagsV7::use_serial_number()) to `true`.
443    pub fn use_serial_number(&mut self) {
444        self.set_true(6);
445    }
446
447    /// Set [`use_oem_id`](QtiFlagsV7::use_oem_id()) to `true`.
448    pub fn use_oem_id(&mut self) {
449        self.set_true(8);
450    }
451
452    /// Set [`use_model_id`](QtiFlagsV7::use_model_id()) to `true`.
453    pub fn use_model_id(&mut self) {
454        self.set_true(10);
455    }
456
457    /// Set [`use_soc_lifecycle_state`](QtiFlagsV7::use_soc_lifecycle_state()) to `true`.
458    pub fn use_soc_lifecycle_state(&mut self) {
459        self.set_true(12);
460    }
461
462    /// Set [`use_oem_lifecycle_state`](QtiFlagsV7::use_oem_lifecycle_state()) to `true`.
463    pub fn use_oem_lifecycle_state(&mut self) {
464        self.set_true(14);
465    }
466
467    /// Set [`use_oem_root_cert_hash`](QtiFlagsV7::use_oem_root_cert_hash()) to `true`.
468    pub fn use_oem_root_cert_hash(&mut self) {
469        self.set_true(16);
470    }
471
472    /// Set [`debug`](QtiFlagsV7::debug()) to `true`.
473    pub fn debug(&mut self) {
474        self.set_true(18);
475    }
476
477    /// Set [`rot_en`](QtiFlagsV7::rot_en()) to `true`.
478    pub fn rot_en(&mut self) {
479        self.set_true(20);
480    }
481}
482
483impl CommonMetadata {
484    /// Convert itself to a 24 bytes slice without copy.
485    pub fn as_bytes(&self) -> &[u8; size_of::<Self>()] {
486        unsafe { &*(self as *const _ as *const _) }
487    }
488}
489
490impl MetadataLen120 {
491    /// Convert itself to a 120 bytes slice without copy.
492    pub fn as_bytes(&self) -> &[u8; size_of::<Self>()] {
493        unsafe { &*(self as *const _ as *const _) }
494    }
495}
496
497impl MetadataLen224 {
498    /// Convert itself to a 224 bytes slice without copy.
499    pub fn as_bytes(&self) -> &[u8; size_of::<Self>()] {
500        unsafe { &*(self as *const _ as *const _) }
501    }
502}
503
504impl Metadata {
505    /// Convert itself to a slice without copy.
506    pub fn as_bytes(&self) -> &[u8] {
507        match self {
508            Metadata::Len120(metadata) => metadata.as_bytes(),
509            Metadata::Len224(metadata) => metadata.as_bytes(),
510        }
511    }
512}
513
514impl Default for MetadataLen224 {
515    fn default() -> Self {
516        unsafe { std::mem::zeroed() }
517    }
518}
519
520impl Default for QtiFlagsV7 {
521    fn default() -> Self {
522        Self(0b0101010101010101010101)
523    }
524}
525
526impl std::fmt::Display for CommonMetadata {
527    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
528        writeln!(f, "Major Version: {}", { self.major_version })?;
529        writeln!(f, "Minor Version: {}", { self.minor_version })?;
530        writeln!(f, "Software ID: {:#010x}", { self.software_id })?;
531        writeln!(f, "Application ID: {:#010x}", { self.app_id })?;
532        writeln!(
533            f,
534            "Hash Table Algorithm: {} ({:#x})",
535            match self.hash_table_algorithm {
536                2 => "SHA256",
537                3 => "SHA384",
538                _ => "/* Unknown */",
539            },
540            { self.hash_table_algorithm }
541        )?;
542        write!(
543            f,
544            "Measurement Register: {} ({:#x})",
545            match self.measurement_register {
546                0 => "None",
547                1 => "Hardware Measurement Register #1",
548                2 => "Hardware Measurement Register #2",
549                3 => "Firmware Measurement Register #1",
550                4 => "Firmware Measurement Register #2",
551                5 => "Firmware Measurement Register #3",
552                6 => "Firmware Measurement Register #4",
553                _ => "/* Unknown */",
554            },
555            { self.measurement_register }
556        )
557    }
558}
559
560impl std::fmt::Display for MetadataLen120 {
561    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
562        writeln!(f, "Major Version: {}", { self.major_version })?;
563        writeln!(f, "Minor Version: {}", { self.minor_version })?;
564        writeln!(f, "Software ID: {:#010x}", { self.software_id })?;
565        writeln!(f, "JTAG ID: {:#010x}", { self.hardware_id })?;
566        writeln!(f, "OEM ID: {:#010x}", { self.oem_id })?;
567        writeln!(f, "Product ID: {:#010x}", { self.model_id })?;
568        writeln!(f, "Application ID: {:#010x}", { self.app_id })?;
569        writeln!(f, "Flags: {:#034b}", { self.flags.0 })?;
570        writeln!(f, "    RoT (Root of Trust): {}", ({ self.flags }).rot_en())?;
571        writeln!(
572            f,
573            "    Use SoC Hardware Versions: {}",
574            ({ self.flags }).use_soc_hw_version()
575        )?;
576        writeln!(
577            f,
578            "    Use Serial Numbers: {}",
579            ({ self.flags }).use_serial_number()
580        )?;
581        writeln!(
582            f,
583            "    Use OEM ID: {}",
584            !({ self.flags }).oem_id_independent()
585        )?;
586        writeln!(
587            f,
588            "    Revocation and Activation in MRC (Multiple Root Certificate): {} ({:#x})",
589            ({ self.flags }).root_revoke_activate_enable() > 0,
590            ({ self.flags }).root_revoke_activate_enable()
591        )?;
592        writeln!(
593            f,
594            "    UIE (Unified Image Encryption) Key Switch: {} ({:#x})",
595            ({ self.flags }).uie_key_switch_enable() > 0,
596            ({ self.flags }).uie_key_switch_enable()
597        )?;
598        writeln!(
599            f,
600            "    JTAG Debug: {} ({:#x})",
601            match ({ self.flags }).debug() {
602                0 => "Nop",
603                1 => "Disabled",
604                2 => "Enabled",
605                _ => "/* Unknown */",
606            },
607            ({ self.flags }).debug()
608        )?;
609        writeln!(f, "    Use JTAG ID: {}", ({ self.flags }).use_hw_id())?;
610        if self.major_version > 0 {
611            writeln!(
612                f,
613                "    Use Product ID: {}",
614                !({ self.flags }).model_id_independent()
615            )?;
616        }
617        writeln!(
618            f,
619            "SoC Hardware Versions: [\n{}",
620            self.soc_version
621                .into_iter()
622                .filter(|v| *v != 0)
623                .map(|v| format!("        {:#010x},", v))
624                .chain(std::iter::once("    ]".to_string()))
625                .collect::<Vec<String>>()
626                .join("\n")
627        )?;
628        writeln!(
629            f,
630            "Serial Numbers: [\n{}",
631            self.multi_serial_numbers
632                .into_iter()
633                .filter(|v| *v != 0)
634                .map(|v| format!("        {:#010x},", v))
635                .chain(std::iter::once("    ]".to_string()))
636                .collect::<Vec<String>>()
637                .join("\n")
638        )?;
639        writeln!(
640            f,
641            "Root Certificate Index in MRC (Multiple Root Certificate): {}",
642            { self.root_cert_index }
643        )?;
644        write!(f, "Anti-Rollback Version: {:#x}", {
645            self.anti_rollback_version
646        })
647    }
648}
649
650impl std::fmt::Display for MetadataLen224 {
651    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
652        writeln!(f, "Major Version: {}", { self.major_version })?;
653        writeln!(f, "Minor Version: {}", { self.minor_version })?;
654        writeln!(f, "Anti-Rollback Version: {:#x}", {
655            self.anti_rollback_version
656        })?;
657        writeln!(
658            f,
659            "Root Certificate Index in MRC (Multiple Root Certificate): {}",
660            { self.root_cert_index }
661        )?;
662        writeln!(
663            f,
664            "SoC Hardware Versions: [\n{}",
665            self.soc_version
666                .into_iter()
667                .filter(|v| *v != 0)
668                .map(|v| format!("        {:#010x},", v))
669                .chain(std::iter::once("    ]".to_string()))
670                .collect::<Vec<String>>()
671                .join("\n")
672        )?;
673        writeln!(f, "SoC Feature ID: {:#010x}", { self.feature_id })?;
674        writeln!(f, "JTAG ID: {:#010x}", { self.hardware_id })?;
675        writeln!(
676            f,
677            "Serial Numbers: [\n{}",
678            self.multi_serial_numbers
679                .into_iter()
680                .filter(|v| *v != 0)
681                .map(|v| format!("        {:#018x},", v))
682                .chain(std::iter::once("    ]".to_string()))
683                .collect::<Vec<String>>()
684                .join("\n")
685        )?;
686        writeln!(f, "OEM ID: {:#010x}", { self.oem_id })?;
687        writeln!(f, "Product ID: {:#010x}", { self.model_id })?;
688        writeln!(
689            f,
690            "OEM Lifecycle State: {} ({:#018x})",
691            match self.oem_lifecycle_state {
692                0x200000000 => "Development",
693                0xD00000000 => "Production",
694                _ => "/* Unknown */",
695            },
696            { self.oem_lifecycle_state }
697        )?;
698        writeln!(
699            f,
700            "OEM Root Certificate Hash Algorithm: {} ({:#x})",
701            match self.oem_root_cert_hash_algorithm {
702                0 => "N/A",
703                2 => "SHA256",
704                3 => "SHA384",
705                _ => "/* Unknown */",
706            },
707            { self.oem_root_cert_hash_algorithm }
708        )?;
709        if self.oem_root_cert_hash_algorithm != 0 {
710            writeln!(
711                f,
712                "OEM Root Certificate Hash: {}",
713                match self.oem_root_cert_hash_algorithm {
714                    2 => &self.oem_root_cert_hash[32..],
715                    3 => &self.oem_root_cert_hash[24..],
716                    _ => &self.oem_root_cert_hash,
717                }
718                .iter()
719                .fold(String::from("0x"), |s, byte| s + &format!("{:02x}", byte)),
720            )?;
721        }
722        writeln!(f, "Flags: {:#034b}", { self.flags.0 })?;
723        writeln!(
724            f,
725            "    Use SoC Hardware Versions: {}",
726            match ({ self.flags }).use_soc_hw_version() {
727                Ok(v) => format!("{}", v),
728                Err(v) => format!("/* Unknown */ ({:#04b})", v),
729            }
730        )?;
731        writeln!(
732            f,
733            "    Use Feature ID: {}",
734            match ({ self.flags }).use_feature_id() {
735                Ok(v) => format!("{}", v),
736                Err(v) => format!("/* Unknown */ ({:#04b})", v),
737            }
738        )?;
739        writeln!(
740            f,
741            "    Use JTAG ID: {}",
742            match ({ self.flags }).use_hw_id() {
743                Ok(v) => format!("{}", v),
744                Err(v) => format!("/* Unknown */ ({:#04b})", v),
745            }
746        )?;
747        writeln!(
748            f,
749            "    Use Serial Numbers: {}",
750            match ({ self.flags }).use_serial_number() {
751                Ok(v) => format!("{}", v),
752                Err(v) => format!("/* Unknown */ ({:#04b})", v),
753            }
754        )?;
755        writeln!(
756            f,
757            "    Use OEM ID: {}",
758            match ({ self.flags }).use_oem_id() {
759                Ok(v) => format!("{}", v),
760                Err(v) => format!("/* Unknown */ ({:#04b})", v),
761            }
762        )?;
763        writeln!(
764            f,
765            "    Use Product ID: {}",
766            match ({ self.flags }).use_model_id() {
767                Ok(v) => format!("{}", v),
768                Err(v) => format!("/* Unknown */ ({:#04b})", v),
769            }
770        )?;
771        writeln!(
772            f,
773            "    Use SoC Lifecycle State: {}",
774            match ({ self.flags }).use_soc_lifecycle_state() {
775                Ok(v) => format!("{}", v),
776                Err(v) => format!("/* Unknown */ ({:#04b})", v),
777            }
778        )?;
779        writeln!(
780            f,
781            "    Use OEM Lifecycle State: {}",
782            match ({ self.flags }).use_oem_lifecycle_state() {
783                Ok(v) => format!("{}", v),
784                Err(v) => format!("/* Unknown */ ({:#04b})", v),
785            }
786        )?;
787        writeln!(
788            f,
789            "    Use OEM Root Certificate Hash: {}",
790            match ({ self.flags }).use_oem_root_cert_hash() {
791                Ok(v) => format!("{}", v),
792                Err(v) => format!("/* Unknown */ ({:#04b})", v),
793            }
794        )?;
795        writeln!(
796            f,
797            "    JTAG Debug: {}",
798            match ({ self.flags }).debug() {
799                Ok(false) => "Nop (0b01)".to_string(),
800                Ok(true) => "Disabled (0b10)".to_string(),
801                Err(v) => format!("/* Unknown */ ({:#04b})", v),
802            }
803        )?;
804        write!(
805            f,
806            "    RoT (Root of Trust): {}",
807            match ({ self.flags }).rot_en() {
808                Ok(v) => format!("{}", v),
809                Err(v) => format!("/* Unknown */ ({:#04b})", v),
810            }
811        )
812    }
813}
814
815impl std::fmt::Display for Metadata {
816    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
817        match self {
818            Metadata::Len120(metadata) => metadata.fmt(f),
819            Metadata::Len224(metadata) => metadata.fmt(f),
820        }
821    }
822}
823
824impl From<u32> for QtiFlagsV6 {
825    fn from(value: u32) -> Self {
826        Self(value)
827    }
828}
829
830impl From<QtiFlagsV6> for u32 {
831    fn from(value: QtiFlagsV6) -> Self {
832        value.0
833    }
834}
835
836impl From<u32> for QtiFlagsV7 {
837    fn from(value: u32) -> Self {
838        Self(value)
839    }
840}
841
842impl From<QtiFlagsV7> for u32 {
843    fn from(value: QtiFlagsV7) -> Self {
844        value.0
845    }
846}
847
848impl From<[u8; size_of::<Self>()]> for CommonMetadata {
849    fn from(value: [u8; size_of::<Self>()]) -> Self {
850        unsafe { std::mem::transmute(value) }
851    }
852}
853
854impl From<CommonMetadata> for [u8; 24] {
855    fn from(value: CommonMetadata) -> Self {
856        unsafe { std::mem::transmute(value) }
857    }
858}
859
860impl ByteRead for CommonMetadata {
861    fn read(buffer: &ByteReader<'_>) -> crate::Result<(Self, usize)> {
862        Ok((
863            From::<[u8; std::mem::size_of::<Self>()]>::from(
864                buffer
865                    .current()
866                    .get(0..std::mem::size_of::<Self>())
867                    .ok_or(ParseError::InputUnexpectedTermination)?
868                    .try_into()
869                    .unwrap(),
870            ),
871            std::mem::size_of::<Self>(),
872        ))
873    }
874}
875
876impl From<[u8; size_of::<Self>()]> for MetadataLen120 {
877    fn from(value: [u8; size_of::<Self>()]) -> Self {
878        unsafe { std::mem::transmute(value) }
879    }
880}
881
882impl From<MetadataLen120> for [u8; 120] {
883    fn from(value: MetadataLen120) -> Self {
884        unsafe { std::mem::transmute(value) }
885    }
886}
887
888impl ByteRead for MetadataLen120 {
889    fn read(buffer: &ByteReader<'_>) -> crate::Result<(Self, usize)> {
890        Ok((
891            From::<[u8; std::mem::size_of::<Self>()]>::from(
892                buffer
893                    .current()
894                    .get(0..std::mem::size_of::<Self>())
895                    .ok_or(ParseError::InputUnexpectedTermination)?
896                    .try_into()
897                    .unwrap(),
898            ),
899            std::mem::size_of::<Self>(),
900        ))
901    }
902}
903
904impl From<[u8; size_of::<Self>()]> for MetadataLen224 {
905    fn from(value: [u8; size_of::<Self>()]) -> Self {
906        unsafe { std::mem::transmute(value) }
907    }
908}
909
910impl From<MetadataLen224> for [u8; 224] {
911    fn from(value: MetadataLen224) -> Self {
912        unsafe { std::mem::transmute(value) }
913    }
914}
915
916impl ByteRead for MetadataLen224 {
917    fn read(buffer: &ByteReader<'_>) -> crate::Result<(Self, usize)> {
918        Ok((
919            From::<[u8; std::mem::size_of::<Self>()]>::from(
920                buffer
921                    .current()
922                    .get(0..std::mem::size_of::<Self>())
923                    .ok_or(ParseError::InputUnexpectedTermination)?
924                    .try_into()
925                    .unwrap(),
926            ),
927            std::mem::size_of::<Self>(),
928        ))
929    }
930}