@@ -106,7 +106,7 @@ impl fmt::Debug for TbfParseError {
106106 TbfParseError :: TooManyEntries ( tipe) => {
107107 write ! (
108108 f,
109- "There are too many variable entries of {tipe} for Tock to parse"
109+ "There are too many variable entries of {tipe} for Tock to parse" ,
110110 )
111111 }
112112 TbfParseError :: PackageNameTooLong => write ! ( f, "The package name is too long." ) ,
@@ -137,6 +137,7 @@ pub enum TbfHeaderTypes {
137137 TbfHeaderStoragePermissions = 7 ,
138138 TbfHeaderKernelVersion = 8 ,
139139 TbfHeaderProgram = 9 ,
140+ TbfHeaderShortId = 10 ,
140141 TbfFooterCredentials = 128 ,
141142
142143 /// Some field in the header that we do not understand. Since the TLV format
@@ -254,6 +255,14 @@ pub struct TbfHeaderV2KernelVersion {
254255 minor : u16 ,
255256}
256257
258+ /// The v2 ShortId for apps.
259+ ///
260+ /// Header to specify a fixed ShortID for an app.
261+ #[ derive( Clone , Copy , Debug ) ]
262+ pub struct TbfHeaderV2ShortId {
263+ short_id : Option < core:: num:: NonZeroU32 > ,
264+ }
265+
257266#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
258267pub enum TbfFooterV2CredentialsType {
259268 Reserved = 0 ,
@@ -262,6 +271,7 @@ pub enum TbfFooterV2CredentialsType {
262271 SHA256 = 3 ,
263272 SHA384 = 4 ,
264273 SHA512 = 5 ,
274+ EcdsaNistP256 = 6 ,
265275}
266276
267277/// Reference: https://github.com/tock/tock/blob/master/doc/reference/trd-appid.md#52-credentials-footer
@@ -274,6 +284,7 @@ pub enum TbfFooterV2Credentials {
274284 SHA256 ( TbfFooterV2SHA < 32 > ) ,
275285 SHA384 ( TbfFooterV2SHA < 48 > ) ,
276286 SHA512 ( TbfFooterV2SHA < 64 > ) ,
287+ EcdsaNistP256 ( TbfFooterV2Ecdsa < 32 > ) ,
277288}
278289
279290#[ derive( Clone , Copy , Debug ) ]
@@ -287,6 +298,12 @@ pub struct TbfFooterV2RSA<const L: usize> {
287298 signature : [ u8 ; L ] ,
288299}
289300
301+ #[ derive( Clone , Copy , Debug ) ]
302+ pub struct TbfFooterV2Ecdsa < const L : usize > {
303+ signature_r : [ u8 ; L ] ,
304+ signature_s : [ u8 ; L ] ,
305+ }
306+
290307impl < const L : usize > TbfFooterV2SHA < L > {
291308 pub fn get_format ( & self ) -> Result < TbfFooterV2CredentialsType , TbfParseError > {
292309 match L {
@@ -320,6 +337,20 @@ impl<const L: usize> TbfFooterV2RSA<L> {
320337 }
321338}
322339
340+ impl < const L : usize > TbfFooterV2Ecdsa < L > {
341+ pub fn get_format ( & self ) -> Result < TbfFooterV2CredentialsType , TbfParseError > {
342+ Ok ( TbfFooterV2CredentialsType :: EcdsaNistP256 )
343+ }
344+
345+ pub fn get_signature_r ( & self ) -> & [ u8 ; L ] {
346+ & self . signature_r
347+ }
348+
349+ pub fn get_signature_s ( & self ) -> & [ u8 ; L ] {
350+ & self . signature_s
351+ }
352+ }
353+
323354// Conversion functions from slices to the various TBF fields.
324355
325356impl core:: convert:: TryFrom < & [ u8 ] > for TbfHeaderV2Base {
@@ -372,6 +403,7 @@ impl core::convert::TryFrom<u16> for TbfHeaderTypes {
372403 7 => Ok ( TbfHeaderTypes :: TbfHeaderStoragePermissions ) ,
373404 8 => Ok ( TbfHeaderTypes :: TbfHeaderKernelVersion ) ,
374405 9 => Ok ( TbfHeaderTypes :: TbfHeaderProgram ) ,
406+ 10 => Ok ( TbfHeaderTypes :: TbfHeaderShortId ) ,
375407 128 => Ok ( TbfHeaderTypes :: TbfFooterCredentials ) ,
376408 _ => Ok ( TbfHeaderTypes :: Unknown ) ,
377409 }
@@ -675,6 +707,20 @@ impl core::convert::TryFrom<&[u8]> for TbfHeaderV2KernelVersion {
675707 }
676708}
677709
710+ impl core:: convert:: TryFrom < & [ u8 ] > for TbfHeaderV2ShortId {
711+ type Error = TbfParseError ;
712+
713+ fn try_from ( b : & [ u8 ] ) -> Result < TbfHeaderV2ShortId , Self :: Error > {
714+ Ok ( TbfHeaderV2ShortId {
715+ short_id : core:: num:: NonZeroU32 :: new ( u32:: from_le_bytes (
716+ b. get ( 0 ..4 )
717+ . ok_or ( TbfParseError :: InternalError ) ?
718+ . try_into ( ) ?,
719+ ) ) ,
720+ } )
721+ }
722+ }
723+
678724impl core:: convert:: TryFrom < & [ u8 ] > for TbfFooterV2Credentials {
679725 type Error = TbfParseError ;
680726
@@ -691,6 +737,7 @@ impl core::convert::TryFrom<&[u8]> for TbfFooterV2Credentials {
691737 3 => TbfFooterV2CredentialsType :: SHA256 ,
692738 4 => TbfFooterV2CredentialsType :: SHA384 ,
693739 5 => TbfFooterV2CredentialsType :: SHA512 ,
740+ 6 => TbfFooterV2CredentialsType :: EcdsaNistP256 ,
694741 _ => {
695742 return Err ( TbfParseError :: InternalError ) ;
696743 }
@@ -702,6 +749,7 @@ impl core::convert::TryFrom<&[u8]> for TbfFooterV2Credentials {
702749 TbfFooterV2CredentialsType :: SHA256 => 32 ,
703750 TbfFooterV2CredentialsType :: SHA384 => 48 ,
704751 TbfFooterV2CredentialsType :: SHA512 => 64 ,
752+ TbfFooterV2CredentialsType :: EcdsaNistP256 => 64 ,
705753 } ;
706754
707755 let data = b
@@ -747,6 +795,16 @@ impl core::convert::TryFrom<&[u8]> for TbfFooterV2Credentials {
747795 . map_err ( |_| TbfParseError :: InternalError ) ?,
748796 } ) )
749797 }
798+ TbfFooterV2CredentialsType :: EcdsaNistP256 => {
799+ Ok ( TbfFooterV2Credentials :: EcdsaNistP256 ( TbfFooterV2Ecdsa {
800+ signature_r : data[ 0 ..32 ]
801+ . try_into ( )
802+ . map_err ( |_| TbfParseError :: InternalError ) ?,
803+ signature_s : data[ 32 ..64 ]
804+ . try_into ( )
805+ . map_err ( |_| TbfParseError :: InternalError ) ?,
806+ } ) )
807+ }
750808 }
751809 }
752810}
@@ -760,6 +818,7 @@ impl TbfFooterV2Credentials {
760818 TbfFooterV2Credentials :: SHA256 ( _) => "SHA256" ,
761819 TbfFooterV2Credentials :: SHA384 ( _) => "SHA384" ,
762820 TbfFooterV2Credentials :: SHA512 ( _) => "SHA512" ,
821+ TbfFooterV2Credentials :: EcdsaNistP256 ( _) => "EcdsaNistP256" ,
763822 }
764823 }
765824}
@@ -794,6 +853,7 @@ pub struct TbfHeaderV2 {
794853 pub ( crate ) permissions : Option < TbfHeaderV2Permissions < 8 > > ,
795854 pub ( crate ) storage_permissions : Option < TbfHeaderV2StoragePermissions < NUM_STORAGE_PERMISSIONS > > ,
796855 pub ( crate ) kernel_version : Option < TbfHeaderV2KernelVersion > ,
856+ pub ( crate ) short_id : Option < TbfHeaderV2ShortId > ,
797857}
798858
799859/// Type that represents the fields of the Tock Binary Format header.
@@ -967,13 +1027,13 @@ impl TbfHeader {
9671027 }
9681028
9691029 /// Get the offset and size of a given flash region.
970- pub fn get_writeable_flash_region ( & self , index : usize ) -> ( u32 , u32 ) {
1030+ pub fn get_writeable_flash_region ( & self , index : usize ) -> ( usize , usize ) {
9711031 match * self {
9721032 TbfHeader :: TbfHeaderV2 ( hd) => hd. writeable_regions . map_or ( ( 0 , 0 ) , |wrs| {
9731033 wrs. get ( index) . unwrap_or ( & None ) . map_or ( ( 0 , 0 ) , |wr| {
9741034 (
975- wr. writeable_flash_region_offset ,
976- wr. writeable_flash_region_size ,
1035+ wr. writeable_flash_region_offset as usize ,
1036+ wr. writeable_flash_region_size as usize ,
9771037 )
9781038 } )
9791039 } ) ,
@@ -1114,4 +1174,13 @@ impl TbfHeader {
11141174 _ => 0 ,
11151175 }
11161176 }
1177+
1178+ /// Return the fixed ShortId of the application if it was specified in the
1179+ /// TBF header.
1180+ pub fn get_fixed_short_id ( & self ) -> Option < core:: num:: NonZeroU32 > {
1181+ match self {
1182+ TbfHeader :: TbfHeaderV2 ( hd) => hd. short_id . and_then ( |si| si. short_id ) ,
1183+ _ => None ,
1184+ }
1185+ }
11171186}
0 commit comments