Subject: [Suit] self-describing format vs fixed/binary manifest structure

From: Martin Pagel <[email-masked]>
Date: Wed, 12 Dec 2018 05:44:30 +0000

I had further discussions with some security experts about the two different manifest drafts, I thought it would be useful to summarize it for the work group:

The SUIT Architecture mentions two specific requirements:
              3.6 Operate with a small bootloader   and
              3.7 Small Parsers

A self-describing format such as CBOR obviously has the advantage that it is more extensible. This has advantages for tools as they can operate on the data without necessarily understanding all the fields. However typically a particular type of MCU does not allow for much flexibility, it usually is optimized for a particular set of crypto functions, compression, file formats etc. The MCU won't be able to handle most of the variations the format allows for. For the MCU it is far more important to meet the requirements above (small bootloader/parser). They also pointed out that CBOR not only requires extra code and data buffers but also adds complexity which might get exploited in a similar way as recently the ASN.1 parser did in OpenSSL. If you use a smaller custom parser as suggested, then you lose the flexibility but add extra custom code maintenance and potentially vulnerabilities, too. Therefore they pointed out that a fixed binary manifest structure with just the options a particular MCU supports would allow both the bootloader and the installer to be small and nimble and therefore safer.

We may want to consider using the CBOR format to submit drivers and other components to the update server which can then verify them and generate a new manifest in the specific format the particular type of MCU understands. That way only the update server needs to understand what exact formats, crypto algorithms etc the MCU (bootloader and installer) understands and what keys are available to the MCU.

Most MCUs will have the key to verify a manifest generated by the update server, but not the key for each firmware author anyways. This means the update server would need to be a trusted intermediary, but the MCU may only have to verify a single signature rather than multiple from different authors.
BR
Martin

---

From: Michael Richardson <[email-masked]>
Date: Wed, 12 Dec 2018 15:50:01 -0500

Martin Pagel <Martin.Pagel=[email-masked]> wrote:
> I had further discussions with some security experts about the two
> different manifest drafts, I thought it would be useful to summarize
> it for the work group:

I'm a security expert of 30+ years.

I've written both ASN.1 and CBOR parsers (more ASN.1 than CBOR thanks to
widely available CBOR libraries), and dozens and dozens of custom format
parsers for a large variety of 8-bit (back when that was "current"), 16-bit,
and 32/64-bit architectures.  I've written them in C, assembler, perl
(yes. bash even hardware via /dev/mem and unpack), Tcl, BASIC (PEEK/POKE),
and this includes things like bespoke mailboxes and ring structures for
things like ethernet and NPU devices. (Not just on the "OS"/Linux/BSD side,
but on the "microcontroller" side too).

ASN.1 and CBOR are in completely opposite sides of the design space: anyone
who is older than 50 desperately wishes we had CBOR back in 1984 (when ASN.1
was hatched my a committee).  The broken process that led to the design
is a probably a major reason for why the IETF does things the way we do things.

I'm also one of the maintainers of tcpdump, and I've extensive experience
with network attacks on custom C-written parsers for protocols.
(It's not pretty: even extensively reviewed code winds up with issues.
The google bounty program has had an interesting affect)

> A self-describing format such as CBOR obviously has the advantage that
> it is more extensible.

No, this is not really the advantage of CBOR.
Many structures can be defined that are easily extensible.
The IETF has dozens of TLV structures (sadly different).

The advantage is that CBOR libraries can easily be tested against a wide
variety of inputs on a machine that enforces NULL deferences, structure
overflow and underflows, and where the develop/compile/test cycle can be
measured in dozens of seconds rather than dozens of minutes.
These libraries are widely used and widely tested.

Pull parsers can be written that uses almost no storage at all (at the cost
of cycles).  Our manifest should be a simple CBOR map, and if
we put a constraint on how the keys are ordered then the pull parser could
be implemented with almost no cycles at the cost of one pointer of storage.
Such a piece of code could be in a library and be widely used/tested,
along side full CBOR parsers that map to Python/Ruby/Perl.

--
Michael Richardson <[email-masked]>, Sandelman Software Works
 -= IPv6 IoT consulting =-

---

From: Martin Pagel <[email-masked]>
Date: Thu, 13 Dec 2018 23:22:07 +0000

Thanks, Michael, 
for sharing your experience. 

In general I actually agree with your assessment. If you have many options, a well defined format like CBOR is much better than custom C structures as you can use a standard, already vetted parsing library. The standard parser library turns the CBOR data into a data structure, in IoT usually a pretty complex C structure. As the generic parser does not understand the semantics of the fields (only the syntax as defined by the CDDL), the developer still has to write code to verify a complex data structure and enforce semantics and you still have to test/verify such code. If you have lots of options, then again, that's a good approach. But, as others already pointed out, a manifest only uses a fraction of the power of CBOR and simple MCUs can only handle a fraction of the options proposed in the current Moran manifest draft. Each MCU still needs to make sure that any CBOR generated data structure is either properly processed or rejected, that is complex code which cannot be subjected to automated generic testing like the parser library can and therefore can lead to vulnerabilities. 

If you start with a binary manifest however, you skip the parsing step, you just load the data structure into memory. The data structure is much simpler as it only handles the few fields and options the MCU can actually handle. Yes, you need to do some more boundary checks on those few fields, something the CBOR parser might have done for you in the other case, but boundary checks on a simple data structure are pretty easy to implement. Far more important however is the fact that the code to enforce semantics is much smaller as it only has to deal with a few fields as your degree of freedom is far smaller.

If you want to use the manifest for secure boot via boot ROM, you want to make sure you get 100% code coverage during testing as you can't update the ROM. A generic parser often won't fit in the ROM and the number of options you would need to verify during testing becomes prohibitive. 

Therefore I believe that for constrained MCUs, in particular secure boot scenarios, a binary format has clear advantages. For larger, more flexible MCUs a CBOR based manifest may offer advantages.

Martin

-----Original Message-----
From: Suit <[email-masked]> On Behalf Of Michael Richardson
Sent: Wednesday, December 12, 2018 12:50 PM
To: [email-masked]; [email-masked]
Subject: Re: [Suit] self-describing format vs fixed/binary manifest structure

I've written both ASN.1 and CBOR parsers (more ASN.1 than CBOR thanks to widely available CBOR libraries), and dozens and dozens of custom format parsers for a large variety of 8-bit (back when that was "current"), 16-bit, and 32/64-bit architectures.  I've written them in C, assembler, perl (yes. bash even hardware via /dev/mem and unpack), Tcl, BASIC (PEEK/POKE), and this includes things like bespoke mailboxes and ring structures for things like ethernet and NPU devices. (Not just on the "OS"/Linux/BSD side, but on the "microcontroller" side too).

ASN.1 and CBOR are in completely opposite sides of the design space: anyone who is older than 50 desperately wishes we had CBOR back in 1984 (when ASN.1 was hatched my a committee).  The broken process that led to the design is a probably a major reason for why the IETF does things the way we do things.

I'm also one of the maintainers of tcpdump, and I've extensive experience with network attacks on custom C-written parsers for protocols.
(It's not pretty: even extensively reviewed code winds up with issues.
The google bounty program has had an interesting affect)

The advantage is that CBOR libraries can easily be tested against a wide variety of inputs on a machine that enforces NULL deferences, structure overflow and underflows, and where the develop/compile/test cycle can be measured in dozens of seconds rather than dozens of minutes.
These libraries are widely used and widely tested.

Pull parsers can be written that uses almost no storage at all (at the cost of cycles).  Our manifest should be a simple CBOR map, and if we put a constraint on how the keys are ordered then the pull parser could be implemented with almost no cycles at the cost of one pointer of storage.
Such a piece of code could be in a library and be widely used/tested, along side full CBOR parsers that map to Python/Ruby/Perl.

--
Michael Richardson <[email-masked]>, Sandelman Software Works  -= IPv6 IoT consulting =-

---

From: Derek Atkins <[email-masked]>
Date: Fri, 14 Dec 2018 09:10:29 -0500

Martin Pagel <Martin.Pagel=[email-masked]> writes:

> If you start with a binary manifest however, you skip the parsing
> step, you just load the data structure into memory. The data structure

Careful... This way lies dragons!!!   Indeed, this is exactly how
various overflow issues happen.  For example, if you build a manifest
for a system that has a 16-bit integer but it gets read on a system with
a 32-bit integer, you now have problems.  You also have potential
byte-order problems (is this a big-endian or little-endian system -- and
does the target match the originator?)

> is much simpler as it only handles the few fields and options the MCU
> can actually handle. Yes, you need to do some more boundary checks on
> those few fields, something the CBOR parser might have done for you in
> the other case, but boundary checks on a simple data structure are
> pretty easy to implement. Far more important however is the fact that
> the code to enforce semantics is much smaller as it only has to deal
> with a few fields as your degree of freedom is far smaller.

It's actually NOT any easier, and I would argue you STILL have to ensure
proper sizing, which means lots of testing.  At that point, you might as
well use CBOR.  The various C size-specific data types can help, to some
degree, but the cost of being wrong is greater, and in my experience
it's EASY to get it wrong.

> If you want to use the manifest for secure boot via boot ROM, you want
> to make sure you get 100% code coverage during testing as you can't
> update the ROM. A generic parser often won't fit in the ROM and the
> number of options you would need to verify during testing becomes
> prohibitive.

You don't need a generic parser; you can have a specific parser for the
items you specify and just code the system to bomb out if it finds
something unexpected.  This is SAFER (specifically in a secure boot
system!) than just reading in a C-data-structure and *hoping* all the
data bits line up correctly!

> Therefore I believe that for constrained MCUs, in particular secure
> boot scenarios, a binary format has clear advantages. For larger, more
> flexible MCUs a CBOR based manifest may offer advantages.

In $DAYJOB we build secure boot solutions for timy MCUs (8051, AVR8,
MSP430, ARM, RISC-V) and I would argue that the binary format might SEEM
to have advantages, but like I said, there be dragons!

> Martin

-derek
-- 
       Derek Atkins                 617-623-3745
       [email-masked]             www.ihtfp.com
       Computer and Internet Security Consultant

---

From: Carsten Bormann <[email-masked]>
Date: Fri, 14 Dec 2018 15:32:22 +0100

> Therefore I believe that for constrained MCUs, in particular secure boot scenarios, a binary format has clear advantages. For larger, more flexible MCUs a CBOR based manifest may offer advantages.

I’m a bit tired of this discussion, in part because I no longer quite understand what you are discussing.

CBOR is the Concise Binary Object Representation.  In what way is binary better than binary?

Grüße, Carsten

---

From: Andy Bentley <[email-masked]>
Date: Fri, 14 Dec 2018 09:59:08 -0500

In addition to all of the issues that Derek Atkins pointed out, there 
can also be data/byte alignment/offset issues if the data is packed. 
Perhaps Derek's implication was that this concern is implicit in his 
caution on "sizing".  IMO it needs to be made explicit, to watch out for it.

A common way to ensure that issues due to packing dont crop up is to 
/pad/ data structures sizes to ensure that structre/union variables line 
up on std size/offset boundaries.

reference :
https://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/

---

From: Martin Pagel <[email-masked]>
Date: Fri, 14 Dec 2018 15:35:50 +0000

Yes, Carsten, 
both formats are binary formats, the difference is that the CBOR is self-describing, meaning each field has a prefix which describes the data type and field number whereas the fixed structure are just a packed binary structure such as a C struct. The CBOR manifest as proposed allows for lots of options and requires some type of parser whereas the fixed binary manifest proposes that the data structure is as compact as possible for a particular MCU so that it can be mapped into memory and interpreted in place.
MfG
Martin

-----Original Message-----
From: Carsten Bormann <[email-masked]> 
Sent: Friday, December 14, 2018 6:32 AM
To: Martin Pagel <[email-masked]>
Cc: Michael Richardson <[email-masked]>; [email-masked]; [email-masked]
Subject: Re: [Suit] self-describing format vs fixed/binary manifest structure

Grüße, Carsten

---

From: Carsten Bormann <[email-masked]>
Date: Fri, 14 Dec 2018 16:47:18 +0100

> On Dec 14, 2018, at 16:35, Martin Pagel <[email-masked]> wrote:
> 
> Yes, Carsten, 

The bespoke binary formats you are talking about are “better” if they are specifically tailored to:

— a specific process that will make use of the information, and its requirements on what information is to be included and what is to be left out (so you don’t have “options”)
— the sequence of processing used by this process, so we know how to arrange the information in an easily digestible form
— alignment and sizing requirements of a specific MCU (that’s your “packed C struct”), combined with the sizing requirements posed by the specific process and the maximum number ranges that will be seen in that variation of the process

How many combinations of these will exist?  How many of those closely-tailored bespoke formats do we want to standardize?  Once you allow for process variation in an attempt to reduce the number of them, you’ll need a “parser” to skip the parts a specific variation doesn’t need (you need a “parser” anyway to work with items where the number of occurrences aren’t fixed).  Once you allow for MCU variation, the alignment and sizing needs to be done to the lowest common denominator of these.  I’m not saying all of this cannot be done, but there are an awful number of unspoken assumptions here.  Let’s at least drag them out into the light.

Grüße, Carsten

---

From: Martin Pagel <[email-masked]>
Date: Fri, 14 Dec 2018 16:28:04 +0000

Different MCUs support and need different image formats, crypto algorithms, keys, software components etc.  The Update Server already needs to understand the capabilities and needs of the MCU it wants to update, there is no generic way to update any type of MCU. The question is how to transfer that MCU specific data to the MCU. Two approaches have been proposed:
1. The Update Server generates a CBOR representation to pack the data and the MCU applies some type of CBOR parser to unpack it.
2. The Update Server generates a packed C struct the MCU can just load/map into memory. 

Yes, the first approach might be a bit easier for the Update Server as it doesn't have to worry about byte alignment etc, but I would rather put the burden on the server rather than the MCU in particular if the MCU needs this data to boot. As the Update Server already needs to understand the target MCU, it might as well understand how to pack the data in a way the MCU can easily digest. If I would have to develop a tight boot ROM, I would favor the second approach.

Alles Gute
Martin

-----Original Message-----
From: Suit <[email-masked]> On Behalf Of Carsten Bormann
Sent: Friday, December 14, 2018 7:47 AM
To: Martin Pagel <[email-masked]>
Cc: Michael Richardson <[email-masked]>; [email-masked]; [email-masked]
Subject: Re: [Suit] self-describing format vs fixed/binary manifest structure

— a specific process that will make use of the information, and its requirements on what information is to be included and what is to be left out (so you don’t have “options”) — the sequence of processing used by this process, so we know how to arrange the information in an easily digestible form — alignment and sizing requirements of a specific MCU (that’s your “packed C struct”), combined with the sizing requirements posed by the specific process and the maximum number ranges that will be seen in that variation of the process

Grüße, Carsten

_______________________________________________
Suit mailing list
[email-masked]
https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.ietf.org%2Fmailman%2Flistinfo%2Fsuit&amp;data=02%7C01%7Cmartin.pagel%40microsoft.com%7C3a03c54b189f40568a9108d661db77bf%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636803992568227234&amp;sdata=UZ1pn2WHiTx61xLbv9oE%2FE%2BPJU6dBFvuSjtg%2F7on14s%3D&amp;reserved=0

---

From: Michael Richardson <[email-masked]>
Date: Fri, 14 Dec 2018 12:45:44 -0500

Martin Pagel <[email-masked]> wrote:
> both formats are binary formats, the difference is that the CBOR is
> self-describing, meaning each field has a prefix which describes the data
> type and field number whereas the fixed structure are just a packed binary
> structure such as a C struct.

Unfortunately, it's only "such as", because we can not describe it as
a C-struct in a portable/standard way   :-(
Many of us have extensive experience overlaying C-structure definitions on
memory, so we can just "suck it in", but it has always resulted in issues.

This is why we like CBOR.  Please realize that the structure has to be
processed as a series of byte copies from the buffer into *ANOTHER* structure
(and/or processed and validated inline).

But, let's assume that I'm willing to go with a fixed-format structure such
as you have described.    There are some issues that I have:

1) The "Signature" block at 64-bytes is both too small and wasteful at the
   same time... :-)
   32-bytes is enough for ECDSA signatures.
   64-bytes in inadequate (as I understand it), for a hash-based signature.
   I think it's critical for any device that will be in the field past 2025
   to support hash-based signatures.  It may have to support both
   simultaenously for a period of time.

2) The SignCertThumbprint at 20 bytes seems to imply at most a sha1 hash of a
   certificate?

3) I did not understand easily the ManifestSet Header with the multiple Manifests.
   Can you split the ManifestSetHeader, Footer and Manifest sections into
   multiple sections.  Move the descriptions into a point-list after the
   description of the structure.  Don't use "Type" Unit16, but rather more
   convential IETF ascii-art diagrams.
   (You might find the tool "asciio" very useful for this)

4) I don't think that the explanation of how the format complies to the
   requirements belongs in the Security Considerations.  That's not what
   Security Considerations is for.  The protocol should explain itself,
   and then the SC should explain how those features defeat, mitigate, or
   fail to mitigate various attacks.

---

From: Martin Pagel <[email-masked]>
Date: Fri, 14 Dec 2018 19:31:28 +0000

Thanks, Michael, 
I think the greatest value of the SUIT draft is the Architecture and Information Model documents as they define the rationale for a specific set of manifest fields. How you encode these fields is secondary and I believe it is more important that these fields can get easily loaded by the MCU rather than coming up with a portable/standard format. I only specified 64-bytes as an example, yes, 32-byte are enough for ECDSA. Same applies to thumbprint. Each manufacturer (or whoever develops the boot and installation software) would need to define the details of the manifest structure format it expects including byte alignment, crypto algorithms, keys etc.

I admit that the tables are difficult to decipher in text, you might want to review the PDF version I uploaded, but I will check out the ASCIIO tool. 

I will address your notes on Security Considerations with my next revision.
Martin

-----Original Message-----
From: Suit <[email-masked]> On Behalf Of Michael Richardson
Sent: Friday, December 14, 2018 9:46 AM
To: [email-masked]; [email-masked]
Subject: Re: [Suit] self-describing format vs fixed/binary manifest structure

Martin Pagel <[email-masked]> wrote:
> self-describing, meaning each field has a prefix which describes the 
> data type and field number whereas the fixed structure are just a 
> packed binary structure such as a C struct.

Unfortunately, it's only "such as", because we can not describe it as
a C-struct in a portable/standard way   :-(
Many of us have extensive experience overlaying C-structure definitions on memory, so we can just "suck it in", but it has always resulted in issues.

This is why we like CBOR.  Please realize that the structure has to be processed as a series of byte copies from the buffer into *ANOTHER* structure (and/or processed and validated inline).

---

From: Michael Richardson <[email-masked]>
Date: Fri, 14 Dec 2018 15:02:57 -0500

Martin Pagel <[email-masked]> wrote:
> I think the greatest value of the SUIT draft is the Architecture and
> Information Model documents as they define the rationale for a specific set
> of manifest fields. How you encode these fields is secondary and I believe
> it is more important that these fields can get easily loaded by the MCU
> rather than coming up with a portable/standard format. I only specified
> 64-bytes as an example, yes, 32-byte are enough for ECDSA. Same applies to
> thumbprint. Each manufacturer (or whoever develops the boot and
> installation software) would need to define the details of the manifest
> structure format it expects including byte alignment, crypto algorithms,
> keys etc.

If each manufacturer (of a chip? board? subsystem?) defines their own format,
then we effectively have no standard.

The value of a standard is that the rest of the infrastructure required can
be amortized over many kinds of devices.  Being able to audit all of the
images+manifests in a central point is of extreme value.

> I will address your notes on Security Considerations with my next revision.

Thank you.

---

From: Kvamtrø, Frank Audun <[email-masked]>
Date: Tue, 18 Dec 2018 16:58:07 +0000

I didn't have a specific e-mail to respond to with regards to the proposal
for using packed C structs, but the discussion has gone on for quite a while
and I don't believe it is very fruitful. I hear security experts have been
mentioned in previous threads, and I want to point out that this is a logical
fallacy called "argument from authority". If some security experts want to 
comment on this, then please add them to this discussions so we can discuss
the issues first-hand. Or else the claims are difficult to argue against. 
The authors of this draft come from many different forums and I expect that the
IETF SUIT working group is packed with security experts. A base tenet of this
design process it to adhere to threat based analysis as well as using sane 
standardized methods of cryptography and security. Packed C structs raises a 
few flags for me, security wise. It is ad hoc, and I fail to see that this
approach can be certified to be secure. Especially since the content will
differ on many devices.

Please note that I don’t intend to be unnecessarily negative. I've used
18 of the 32 most known serialization formats (according to Wikipedia) myself.
I've even done the error of writing two proprietary serialization formats. 
The main reason for writing my own was either to be more efficient or to be 
more secure. I now know that I was mostly succeeding with the efficiency part.
For the most part I believe that we don't need another serialization format.

I don't think that packed C structs is a valid approach in an IETF standard. 
The formatting is not interoperable or interchangeable. I expect it to only 
work on one device with one configuration, which is asking too little from a 
firmware upgrade mechanism. I question the alleged security benefits that has 
been alluded to in previous e-mails when using packed structs. Simpler does not
mean better, especially when you have to come up with a proprietary system for
versioning to handle interchangeability, and a custom interoperability 
information format to ensure that the data isn't misrepresented or misused.

I want to note that I am not arguing against using multiple serialization 
formats in context of a complex firmware upgrade mechanisms. This may be the 
only way to support firmware upgrades for heterogenous systems that needs to be
upgraded in unison. We have discussed this in previous e-mail threads covering
payload encoding and NUMA/UMA architectures. I do take issue with an intent to 
describe manifest data using a non-serializing serialization format, without 
the exactness that I would expect when encoding and parsing data sent over any 
medium. That includes support for versioning and optional fields that can be
skipped as well as a schema to understand how the data should look to be valid.

The method of having parts of the manifest data in a binary encoding instead of 
using the full IETF SUIT manifest format may make sense in context of a 
simplified boot validation. This is the case if you are reliant on an external
security chip that only supports one format of data (e.g. ASN.1). A specialized
boot validation process can even be encoded in a simpler manifest format
than the full IETF SUIT, to keep the boot validation parser lean, and to ensure
that there aren't any ways to hijack this sensible part of the process

> From: Suit <[email-masked]> On Behalf Of Martin Pagel
> Sent: 14. desember 2018 17:28
> To: Carsten Bormann <[email-masked]>
> Different MCUs support and need different image formats, crypto algorithms,
> keys, software components etc.  The Update Server already needs to
> understand the capabilities and needs of the MCU it wants to update, there
> is no generic way to update any type of MCU. The question is how to transfer
> that MCU specific data to the MCU. Two approaches have been proposed:
> 1. The Update Server generates a CBOR representation to pack the data and
> the MCU applies some type of CBOR parser to unpack it.

First I want to understand what an update server means is in this context. I
don't see its role clearly stated in the draft documents. Maybe this is 
something that we need to be more explicit about in the architecture or in 
the information model. I feel you are mixing a concept of manifest data 
generation (with signing) and the role of hosting a firmware upgrade on a 
server. The key reason I believe this to be the case is that you state that the
CBOR/packed C struct is server-generated. I think that this is not possible if 
you want to support the multiple signer requirements as described the 
information model use-cases, as well as the broad description inside the 
architecture draft.

There is a similar concept described in the architecture draft that has some 
clearer restrictions in usage. This is the "firmware server" concept, which is 
described as a server that holds the generated firmware images and manifests 
en route to the device where they are to be applied (either through push or 
pull).

The use of the term update server to describe encoding mechanisms begs the
question on how to allow the device operator and the network operator to 
authorize a firmware upgrade in a combined signing operation. If support
for multiple signers is needed, I assume the full firmware upgrade instructions
is either a combination of multiple manifests that are individually signed or 
a manifest that has multiple signers. The key here is that the signed material 
can't be altered or else it loses the signers authorization. This makes an 
"update server" with generation capabilities difficult. Changing the content 
on an intermediate server breaks the concept of multiple authorities. 
Limiting the capabilities of the firmware server to pure device management 
tasks ensures good end-to-end security in the firmware upgrade process.

Using a well-defined serialization format is beneficial to a firmware server.
The firmware server can authenticate the content, e.g. by looking at "best 
before" combined with signature validation to ensure the addition is not
part of a denial-of-service attack. It is also possible for the firmware
server to decode information about the vendor, class and device ID to ensure
the correct device gets the update (in a push scenario). This is data that
is described in the IETF SUIT manifest format, and if this is serialized using
a standardized format it becomes much more available for any intermediary 
actor in the overall firmware upgrade process.

Using a well-defined serialization format is also beneficial to multiple
signers, as parts of the content of the full firmware upgrade can be dealt
with remotely, protecting each signers private keys. It also has clear
interoperability benefits, as you only need to follow the standard to create
your part of the combined firmware upgrade instruction.

Using a packed C struct approach removes these flexibilities. In some cases
it even demands an additional device management information outside of the 
scope of what is defined in the IETF SUIT to facilitate the firmware upgrade. 
This is a very bad thing for the standard. I don't think you can even call 
it a standard in that case...

> 
> Yes, the first approach might be a bit easier for the Update Server as it
> doesn't have to worry about byte alignment etc, but I would rather put the
> burden on the server rather than the MCU in particular if the MCU needs this
> data to boot. As the Update Server already needs to understand the target
> MCU, it might as well understand how to pack the data in a way the MCU can
> easily digest. If I would have to develop a tight boot ROM, I would favor
> the second approach.

I whole-heartedly don't favor the second approach. It has been mentioned before
that here be dragons. Let me try to exemplify some dragons:

-What kind of endianness have you compiled your data to be in this build?
-What are the actual type sizes you are compiling with? Can they change?
-What about alignment issues on the packed types? Will you know when you got 
 that wrong in a graceful manner or will you just hard-fault on unaligned 
 access?
-How large are the enum types in your compilation? Should you disallow enums 
 outright due to potential interoperability issues?
-What happens when you need to amend this format to conform to an issue you
 have discovered? 
-Is there a schema to conform to and how will you deal with optional features?

If these issues aren't addressed in the format of the data then usage
could very easily lead to undefined behavior and potential crashes. There is 
a real risk of bricking a lot of devices if you get this wrong. And it can 
come with a change of the compiler/linker or by setting one faulty define in 
your build system. I believe the minor convenience of a RAM loaded RPC 
format is quite easily overshadowed by how restrictive you need to be 
to ensure that it doesn't lead to failures without any warnings.

All compatibility and interoperability issues can be avoided by using a real
serialization format. For a list of alternatives, please look at the 
following link:
https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats

IETF SUIT has picked CBOR as the standard and I have no problem with that (TM).
Depending on the complexity of the manifest format, it is fairly easy to create
a parser generator that uses the CDDL schema as input.

If you want a fast binary encoder then you could look at https://capnproto.org/
It has all you need. Like many other binary formats, It has not gone through 
a full security review. But at least it addresses the interoperability and 
interchangeability aspects. It is eons better than a simple packed C struct. 
It even conforms to a schema, which is apt in case of having multiple versions
or differences in supported features.

The rest of the e-mail has been skipped as it has some invalid formatting 
with regards to who says what.

With regards
Frank Audun

---

From: David Brown <[email-masked]>
Date: Wed, 19 Dec 2018 10:07:22 -0700

On Thu, Dec 13, 2018 at 11:22:07PM +0000, Martin Pagel wrote:

>In general I actually agree with your assessment. If you have many
>options, a well defined format like CBOR is much better than custom C
>structures as you can use a standard, already vetted parsing library.
>The standard parser library turns the CBOR data into a data
>structure, in IoT usually a pretty complex C structure. As the
>generic parser does not understand the semantics of the fields (only
>the syntax as defined by the CDDL), the developer still has to write
>code to verify a complex data structure and enforce semantics and you
>still have to test/verify such code.

There has been some good discussion on list about pull vs push
parsing.  What you are describing is known as a push parser.  The
parser parses the CBOR and converts it into a fairly rich data
structure that describes the contents of the CBOR.  This is a common
approach, and is quite useful on "powerful" computers, such as
host-side tooling to process the data.

However, in a highly-resource-constrained device, this is not
typically how it is done.  Usually a "pull" parser is used, which will
have entry points to effectively expect a specific (and likely
limited) variant of the manifest, and simply abort if it see what is
unexpected.  The data is not converted to another structure, but
directly parsed/used in place.  For this kind of use, CBOR works very
well.  Draft 3 of the manifest document has an accompanied example
parser that works this way.

As a comparitive example, MCUboot uses a custom encoding format for
the data in its manifest.  It consists of a small amount of data in a
fixed structure (with defined byte ordering and packing), and a set of
tag-length-value items (effectively a single CBOR map, with integer
keys and all values as bstrs).  This is parsed with a similar custom
parser for the data expected.  I expect the parser for the SUIT
manifest to be somewhat larger than this, but within a similar
magnitude.  Even this simple case of a single map, there is enough
variation that a plain struct would not be appropriate to represent
this information.

David