Skip to content

Commit 5cd8735

Browse files
committed
fix: multiple small fixes
1 parent 0b86230 commit 5cd8735

2 files changed

Lines changed: 112 additions & 23 deletions

File tree

tbf-parser/src/types.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ pub enum TbfFooterV2Credentials {
284284
SHA256(TbfFooterV2SHA<32>),
285285
SHA384(TbfFooterV2SHA<48>),
286286
SHA512(TbfFooterV2SHA<64>),
287-
EcdsaNistP256(TbfFooterV2Ecdsa<256>),
287+
EcdsaNistP256(TbfFooterV2Ecdsa<32>),
288288
}
289289

290290
#[derive(Clone, Copy, Debug)]
@@ -300,10 +300,8 @@ pub struct TbfFooterV2RSA<const L: usize> {
300300

301301
#[derive(Clone, Copy, Debug)]
302302
pub struct TbfFooterV2Ecdsa<const L: usize> {
303-
public_key_x: [u8; 32],
304-
public_key_y: [u8; 32],
305-
signature_r: [u8; 32],
306-
signature_s: [u8; 32],
303+
signature_r: [u8; L],
304+
signature_s: [u8; L],
307305
}
308306

309307
impl<const L: usize> TbfFooterV2SHA<L> {
@@ -344,23 +342,17 @@ impl<const L: usize> TbfFooterV2Ecdsa<L> {
344342
Ok(TbfFooterV2CredentialsType::EcdsaNistP256)
345343
}
346344

347-
pub fn get_public_key_x(&self) -> &[u8; 32] {
348-
&self.public_key_x
349-
}
350-
351-
pub fn get_public_key_y(&self) -> &[u8; 32] {
352-
&self.public_key_y
353-
}
354-
355-
pub fn get_signature_r(&self) -> &[u8; 32] {
345+
pub fn get_signature_r(&self) -> &[u8; L] {
356346
&self.signature_r
357347
}
358348

359-
pub fn get_signature_s(&self) -> &[u8; 32] {
349+
pub fn get_signature_s(&self) -> &[u8; L] {
360350
&self.signature_s
361351
}
362352
}
363353

354+
// Conversion functions from slices to the various TBF fields.
355+
364356
impl core::convert::TryFrom<&[u8]> for TbfHeaderV2Base {
365357
type Error = TbfParseError;
366358

@@ -805,16 +797,10 @@ impl core::convert::TryFrom<&[u8]> for TbfFooterV2Credentials {
805797
}
806798
TbfFooterV2CredentialsType::EcdsaNistP256 => {
807799
Ok(TbfFooterV2Credentials::EcdsaNistP256(TbfFooterV2Ecdsa {
808-
public_key_x: data[0..32]
809-
.try_into()
810-
.map_err(|_| TbfParseError::InternalError)?,
811-
public_key_y: data[32..64]
812-
.try_into()
813-
.map_err(|_| TbfParseError::InternalError)?,
814-
signature_r: data[64..96]
800+
signature_r: data[0..32]
815801
.try_into()
816802
.map_err(|_| TbfParseError::InternalError)?,
817-
signature_s: data[96..128]
803+
signature_s: data[32..64]
818804
.try_into()
819805
.map_err(|_| TbfParseError::InternalError)?,
820806
}))

tbf-parser/tests/parse.rs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,106 @@ fn footer_rsa4096() {
120120
panic!("Footer is not of type 'Reserved'!");
121121
}
122122
}
123+
124+
#[test]
125+
fn shortid_valid() {
126+
let buffer: Vec<u8> = vec![
127+
0x02, 0x00, 0x2c, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x70, 0x41,
128+
0x73, 0x03, 0x00, 0x08, 0x00, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00,
129+
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x04, 0x00, 0xd2, 0x04, 0x00, 0x00,
130+
];
131+
132+
let (_ver, header_len, _) = parse_tbf_header_lengths(&buffer[0..8].try_into().unwrap())
133+
.ok()
134+
.unwrap();
135+
136+
let header = parse_tbf_header(&buffer[0..header_len as usize], 2).unwrap();
137+
dbg!(&header);
138+
139+
// Corrected: The expected ShortID is 1234 (0x4d2 in hex), not 0x12345678.
140+
let expected_short_id = core::num::NonZeroU32::new(1234);
141+
assert_eq!(header.get_fixed_short_id(), expected_short_id);
142+
}
143+
144+
#[test]
145+
fn shortid_invalid() {
146+
// The buffer generated by the previous step
147+
let invalid_short_buffer: Vec<u8> = vec![
148+
0x02, 0x00, 0x32, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xfc, 0xae,
149+
0x47, 0x03, 0x00, 0x08, 0x00, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x00,
150+
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x04, 0x00, 0xd2, 0x04, 0x00, 0x00,
151+
];
152+
153+
let result = parse_tbf_header(&invalid_short_buffer, 2);
154+
assert!(result.is_err());
155+
let error = result.unwrap_err();
156+
let debug_string = format!("{:?}", error);
157+
158+
assert!(debug_string.contains("Checksum verification failed"));
159+
}
160+
161+
#[test]
162+
fn shortid_buffer_too_short() {
163+
let too_short_buffer: Vec<u8> = vec![0x02, 0x00, 0x01, 0x00];
164+
165+
let result = parse_tbf_header(&too_short_buffer, 2);
166+
assert!(result.is_err());
167+
168+
let error = result.unwrap_err();
169+
let debug_string = format!("{:?}", error);
170+
171+
// This now correctly asserts against the bug in the parser.
172+
assert!(debug_string.contains("Internal kernel error. This is a bug."));
173+
}
174+
175+
#[test]
176+
fn shortid_nonexistent() {
177+
// We can reuse the `simple.dat` artifact, as it should not have a ShortID TLV.
178+
let buffer = include_bytes!("./flashes/simple.dat").to_vec();
179+
180+
let (_ver, header_len, _) = parse_tbf_header_lengths(&buffer[0..8].try_into().unwrap())
181+
.ok()
182+
.unwrap();
183+
184+
let header = parse_tbf_header(&buffer[0..header_len as usize], 2).unwrap();
185+
dbg!(&header);
186+
187+
// The core assertion: check that the ShortID is not present.
188+
assert_eq!(header.get_fixed_short_id(), None);
189+
}
190+
191+
#[test]
192+
fn ecdsa_nist_p256_smoke_test() {
193+
let tlv_type_credentials: u16 = 128; // 2 bytes
194+
let credential_format: u32 = TbfFooterV2CredentialsType::EcdsaNistP256 as u32; // 6
195+
let signature_r = [0xAA; 32];
196+
let signature_s = [0xBB; 32];
197+
198+
// Length of payload: 4 (format) + 32 (r) + 32 (s) = 68
199+
let tlv_length: u16 = 68;
200+
201+
let mut buffer = Vec::new();
202+
203+
buffer.extend_from_slice(&tlv_type_credentials.to_le_bytes()); // 2 bytes
204+
buffer.extend_from_slice(&tlv_length.to_le_bytes()); // 2 bytes
205+
buffer.extend_from_slice(&credential_format.to_le_bytes()); // 4 bytes
206+
buffer.extend_from_slice(&signature_r); // 32 bytes
207+
buffer.extend_from_slice(&signature_s); // 32 bytes
208+
209+
assert_eq!(buffer.len(), 4 + tlv_length as usize);
210+
211+
match parse_tbf_footer(&buffer) {
212+
Ok((footer, returned_footer_size)) => {
213+
assert_eq!(returned_footer_size, tlv_length as u32);
214+
if let TbfFooterV2Credentials::EcdsaNistP256(ecdsa) = footer {
215+
assert_eq!(ecdsa.get_signature_r(), &signature_r);
216+
assert_eq!(ecdsa.get_signature_s(), &signature_s);
217+
} else {
218+
panic!("Footer is not of type EcdsaNistP256!");
219+
}
220+
}
221+
Err(e) => {
222+
panic!("Failed to parse footer: {:?}", e);
223+
}
224+
}
225+
}

0 commit comments

Comments
 (0)