Subject: [Suit] Parameters and Commands

From: Brendan Moran <[email-masked]>
Date: Thu, 27 Feb 2020 13:44:42 +0000

During the hackathon, I discovered that my examples and my manifest generator tool are generating incorrect sequences for testing vendor ID and class ID.

There are currently two ways to handle commands (conditions or directives):

  1.  The command consumes an argument (that is the value that follows the command's key)
  2.  The command consumes a parameter (that is a value set by the “set-parameters” or “override-parameters” commands)

This duality led to my error in setting up the Vendor and Class ID tests in the demo code.

The reasons for each mode are:

  1.  Command consumes an argument
     *   Encoding is more compact (encoding via parameters takes 2-3 more bytes, depending on the situation).
     *   Less storage needed (the argument is consumed immediately)
     *   Does not require matching parameter key
     *   More explicit association between command and argument
  2.  Command consumes a parameter
     *   More compact when the parameter is used more than once (e.g. image digest)
     *   Allows override by dependencies, when set-parameters is used

We’ve talked before about “only one way to do things” and I think I can see a path to making that the case here. Here is my proposal:

Commands consuming a parameter are absolutely necessary due to override and deduplication concerns. Conditions testing against an argument are convenient and more explicit. Therefore, harmonising around a single option probably means that we have to select parameters instead of arguments:

  1.  Eliminate arguments from most commands (see below)
  2.  Match most parameter keys with command keys to simplify the association, make “arguments” more explicit

Only these commands require arguments, since they either deal with setting parameters, setting parameter scope, or with flow control, which requires nested command sequences.

  *   Set Component Index
  *   Set Dependency Index
  *   Set Parameters
  *   Override Parameters
  *   Try-each
  *   Run Sequence
  *   For Each Component

This leaves the majority of commands with NUL arguments. This is actually quite useful for another feature.

We have also discussed the possibility of defining attestation policy within SUIT. This would mean that we need flags to indicate to the parser which measurements should be reported. For example, a Vendor ID, an image digest, or a component offset might need to be reported in the attestation report. Each of these is checked by a condition. Each of those conditions will consume a parameter under this model. Then, the argument can indicate: report a measurement, do not report a measurement, report a measurement only if comparison is successful, or perhaps other attestation-related policies. Bear in mind that attesting a failed condition may be helpful for attesting why a manifest has failed, as we discussed in the hackathon and virtual interim meeting.

If we are making the majority of commands are using parameters instead of arguments, this becomes trivial: the arguments are replaced with attestation policy arguments. This allows us to tell the attestation engine explicitly what to report from the manifest, which allows secure, dynamically updatable attestation policy.

This doesn’t introduce a substantial change to either the parser or the format. If there is some appetite for simplifying the correlation between commands and parameters, I think it might make sense to spend some effort aligning parameter keys with command keys. This could simplify the parser by allowing a generic parameter lookup to be done in one place, rather than by each handler.

Best Regards,
Brendan
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

---

From: Adrian Shaw <[email-masked]>
Date: Thu, 27 Feb 2020 14:26:13 +0000

Hi Brendan,

To me it doesn’t make much sense for the signer to define the measurement policy. The signer shouldn’t be trusted for that particular purpose.

Just as a simple example:

If a signer of a non-secure image decides to say "don’t measure me”, and the platform blindly obeys that directive, then the platform cannot accurately describe what the software state is during an attestation.

Alternatively, the manifest may decide to tell the installer to measure things that are not security relevant, whilst deliberately avoiding the parts that are security sensitive. Yes, the metadata is signed, but that only tells you who made the image. In the real world a firmware image wouldn’t tell a secure boot system what to verify and what not to verify, and is a similar case here.

There is also the possibility where, for some particular scenario, you don’t necessarily trust whoever signs the non-secure image, but you want to be able to convey to a remote party what image _is_ installed. In this case, you shouldn’t be trusting the measurement instructions from the non-secure manifest.

In essence, the thing being measured should not have any influence on the measurer, since that would not be a chain of trust. It should be the root of trust’s responsibility to decide what is reported.

Let me know if I’ve misunderstood something, as I may not have the full context.

Cheers,
Adrian

On 27 Feb 2020, at 13:44, Brendan Moran <[email-masked]<mailto:[email-masked]>> wrote:

  *   Set Component Index
  *   Set Dependency Index
  *   Set Parameters
  *   Override Parameters
  *   Try-each
  *   Run Sequence
  *   For Each Component

Best Regards,
Brendan
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
_______________________________________________
Suit mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/suit

---

From: Brendan Moran <[email-masked]>
Date: Thu, 27 Feb 2020 16:23:23 +0000

Hi Adrian,

I think I have not explained the idea behind this attestation policy concept well enough. The idea here is that the attestation policy for a given component is defined by the signer of that component. The loader/verifier of a component is the one who executes the policy. This allows the loader/verifier to apply a super-set of the policy if appropriate. For example, BL1 loads BL2. BL1 trusts the author of BL2 (which is the basis of secure boot). BL1 executes the policy laid out by BL2’s signer. BL1 could additionally mandate that certain items in BL2’s policy must always be attested, such as the digest of BL2, refusing to boot the device if the attestation policy is wrong, or overriding the manifest’s attestation policy.

I don’t believe that this introduces a privilege inversion.

There is an additional point that may not have been clear: The verifier of the attestation report requires a policy to verify against. Where does this policy come from? It could be a (Co)SWID. It could also be the manifest itself. Regardless, that must be signed by some authority. Which authority should sign the (Co)SWID? Is it the same as the Manifest signing authority? Or at least derived from the same trust anchor? If not, why not?

Finally, there is the question of how an attestation report is verified. If it is verified against the manifest, then the verifier has the opportunity to examine the policy set by the manifest. This means that the verifier can detect any “opt-out” scenarios as you describe them.

Does that make sense?

Best Regards,
Brendan

On 27 Feb 2020, at 14:26, Adrian Shaw <[email-masked]<mailto:[email-masked]>> wrote:

Hi Brendan,

Cheers,
Adrian

  *   Set Component Index
  *   Set Dependency Index
  *   Set Parameters
  *   Override Parameters
  *   Try-each
  *   Run Sequence
  *   For Each Component

Best Regards,
Brendan

---

From: Thomas Fossati <[email-masked]>
Date: Thu, 27 Feb 2020 17:18:29 +0000

Hey Brendan,

I'm having a bit of trouble parsing this bit:

On 27/02/2020, 16:23, "Brendan Moran" <[email-masked]> wrote:
> [...] For example, BL1 loads BL2. BL1 trusts the author of BL2
> (which is the basis of secure boot).  BL1 executes the policy laid out
> by BL2’s signer.

BL1 can trust BL2 only after it has measured it, therefore "executing
the policy laid out by BL2's signer" can only happen *after* a
successful verification, do you agree?  If so, there is a temporal
mismatch in the logic above.  That, or I am missing something important,
which is what usually happens :-)

cheers!

---

From: Adrian Shaw <[email-masked]>
Date: Thu, 27 Feb 2020 17:26:53 +0000

Hi Brandan,

Thanks for rephrasing. I’m ok provided that the bootloader implementation and remote verifier can decide (if they wish) to enact their own policies independently of the image signer. Which seems like what you’ve confirmed would be possible.

Best,
Adrian

On 27 Feb 2020, at 16:23, Brendan Moran <[email-masked]<mailto:[email-masked]>> wrote:

Hi Adrian,

Does that make sense?

Best Regards,
Brendan

Hi Brendan,

Cheers,
Adrian

  *   Set Component Index
  *   Set Dependency Index
  *   Set Parameters
  *   Override Parameters
  *   Try-each
  *   Run Sequence
  *   For Each Component

Best Regards,
Brendan

---

From: Michael Richardson <[email-masked]>
Date: Thu, 27 Feb 2020 17:02:41 -0500

Brendan Moran <[email-masked]> wrote:
    > We have also discussed the possibility of defining attestation policy
    > within SUIT. This would mean that we need flags to indicate to the
    > parser which measurements should be reported. For example, a Vendor ID,
    > an image digest, or a component offset might need to be reported in the
    > attestation report. Each of these is checked by a condition. Each of
    > those conditions will consume a parameter under this model. Then, the
    > argument can indicate: report a measurement, do not report a
    > measurement, report a measurement only if comparison is successful, or
    > perhaps other attestation-related policies. Bear in mind that attesting
    > a failed condition may be helpful for attesting why a manifest has
    > failed, as we discussed in the hackathon and virtual interim meeting.

Just a note that I think we are avoiding the term "attesting a X",
The RATS architecture would term all of this as providing Evidence.
It completely makes sense to provide Evidence on a failed condition.

    > If we are making the majority of commands are using parameters instead
    > of arguments, this becomes trivial: the arguments are replaced with
    > attestation policy arguments. This allows us to tell the attestation
    > engine explicitly what to report from the manifest, which allows
    > secure, dynamically updatable attestation policy.

okay.
It seems like all of this has to go into the base document.
I don't think the SUIT document needs to mention the Evidence format
directly, does it?

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

---

From: <[email-masked]>
Date: Fri, 28 Feb 2020 01:39:59 +0000

Hi Brendan,

Do we need to make a new issue here?

https://github.com/ARMmbed/suit-manifest-generator/issues

I can make an issue if it’s necessary.

Ryan

From: Suit <[email-masked]> On Behalf Of Brendan Moran
Sent: Thursday, February 27, 2020 10:45 PM
To: suit <[email-masked]>
Cc: Koen Zandberg <[email-masked]>; Emmanuel Baccelli <[email-masked]>
Subject: [Suit] Parameters and Commands

  1.  Command consumes a parameter

  *   Set Component Index
  *   Set Dependency Index
  *   Set Parameters
  *   Override Parameters
  *   Try-each
  *   Run Sequence
  *   For Each Component

Best Regards,
Brendan

---

From: Brendan Moran <[email-masked]>
Date: Fri, 28 Feb 2020 11:40:18 +0000

Hi Thomas,

I think we’re confusing the steps of validation/execution a bit here. The order is:

  1.  Verify firmware author’s authorization. (Signature validation)
  2.  Execute Manifest
     *   Each time a condition is encountered:
        *   If measurement is requested in manifest, record measurement
        *   If measurement is required by internal policy, record measurement
  3.  Seal the measurements (e.g. signature)
  4.  Execute the firmware image

You’ve said that BL2 is only trusted after BL1 verifies it. However, this is handled in a modular way in SUIT. The manifest is verified prior to execution, so BL1 can trust it. When BL2 is verified, the BL2 manifest is already verified and trusted, so it can be trusted to indicate the need for a measurement to be recorded.

I think it’s important that we strongly define the purpose of each security mechanism we have in place. Secure boot is for authority enforcement: only authorised parties can place firmware on a device. This leaves some gaps: Is the firmware authorised, but old? A device with no secure time source can’t know that. If a third party wants to interact with a device, knowing that the firmware is authorised isn’t good enough, they have to know it’s the expected firmware—version numbers can lie—so we need a strong guarantee of exact version that secure boot alone cannot provide.

Measured boot fills these gaps. The “version” of the firmware is exposed precisely via a trusted third party: the previous execution stage.

Let’s try and define exactly which threat could be opened by allowing the signer of the manifest to also set measurement policy. First an assumption: the holder of the private key for authorising firmware has become nefarious: change of heart, theft of keys, etc.

  1.  The manifest author tries to hide that a version has changed by not to reporting the firmware.
     *   The verifier notices that firmware version isn’t being reported and takes corrective action.
  2.  The manifest author tries to hide that a version has changed by making a measurement before an update, but not reporting after
     *   This attempt at subterfuge is visible in the manifest and its lifetime is limited. The next measurement will make it irrelevant.
  3.  The manifest author tries to hide that a version has changed by recording a measurement of one offset, but executing from another.
     *   This attempt at subterfuge is visible in the manifest. It can be further exposed by requiring offset measurements in multi-image devices.

Are there other threats here? I don’t think there’s much space for a bad actor in this.

I would argue that we make it required for:

  1.  A condition-image to specify either Record-on-success or Record-always.
  2.  Run Image to specify either Record-on-success or Record-always, and to require Run Image to automatically invoke a condition-image

I think that would remove any scope for bad actors to even attempt to hide, while still allowing flexible reporting and, more importantly, a sensible way to communicate verification policy to a verifier.

Best Regards,
Brendan

On 27 Feb 2020, at 17:18, Thomas Fossati <[email-masked]<mailto:[email-masked]>> wrote:

Hey Brendan,

On 27/02/2020, 16:23, "Brendan Moran" <[email-masked]<mailto:[email-masked]>> wrote:
[...] For example, BL1 loads BL2. BL1 trusts the author of BL2
(which is the basis of secure boot).  BL1 executes the policy laid out
by BL2’s signer.

cheers!

---

From: Koen Zandberg <[email-masked]>
Date: Fri, 28 Feb 2020 15:46:27 +0100

Hi Brendan,

I also support the idea ofaligningall conditionals to use parameters.
From an implementation point of view I see a small downside in that the
parameter location has to be stored to be retrieved later during the
parsing of the conditional (this matches with your argument no. 2). For
the low number of parameters used this increase is probably negligible
and I don't expect any serious concerns here. 

Concerning encoding the attestation policy within the unused arguments,
I have slightly more doubts. I assume that this would replace all nil
arguments in the commands with the attestation policy (a single cbor
uint?). If this is the case I don't have any strong concerns, but it
looks a bit like swapping one inconsistency for another, mixing
arguments and policy specifications.

I will implement the changes you've proposed here in our current ietf-v3
implementation (https://github.com/RIOT-OS/RIOT/pull/13486
<https://github.com/RIOT-OS/RIOT/pull/13486)>)
<https://github.com/RIOT-OS/RIOT/pull/13486)>to get some hard numbers on
the impact of this change, and get back to you on the list.

Cheers

On 27/02/2020 14.44, Brendan Moran wrote:
> During the hackathon, I discovered that my examples and my manifest
> generator tool are generating incorrect sequences for testing vendor
> ID and class ID.
>
>  2. The command consumes a parameter (that is a value set by the
>     “set-parameters” or “override-parameters” commands)
>
>
>      1. Encoding is more compact (encoding via parameters takes 2-3
>         more bytes, depending on the situation).
>      2. Less storage needed (the argument is consumed immediately)
>      3. Does not require matching parameter key
>      4. More explicit association between command and argument
>      1. More compact when the parameter is used more than once (e.g.
>         image digest)
>      2. Allows override by dependencies, when set-parameters is used
>
>
>
> We’ve talked before about “only one way to do things” and I think I
> can see a path to making that the case here. Here is my proposal:
>
> Commands consuming a parameter are absolutely necessary due to
> override and deduplication concerns. Conditions testing against an
> argument are convenient and more explicit. Therefore, harmonising
> around a single option probably means that we have to select
> parameters instead of arguments:
>
>  2. Match most parameter keys with command keys to simplify the
>     association, make “arguments” more explicit
>
>
> Only these commands require arguments, since they either deal with
> setting parameters, setting parameter scope, or with flow control,
> which requires nested command sequences.
>
>   * Set Component Index
>   * Set Dependency Index
>   * Set Parameters
>   * Override Parameters
>   * Try-each
>   * Run Sequence
>   * For Each Component
>
>
> This leaves the majority of commands with NUL arguments. This is
> actually quite useful for another feature.
>
> parser which measurements should be reported. For example, a Vendor
> ID, an image digest, or a component offset might need to be reported
> in the attestation report. Each of these is checked by a condition.
> Each of those conditions will consume a parameter under this model.
> Then, the argument can indicate: report a measurement, do not report a
> perhaps other attestation-related policies. Bear in mind that
> attesting a failed condition may be helpful for attesting why a
> manifest has failed, as we discussed in the hackathon and virtual
> interim meeting.
>
> This doesn’t introduce a substantial change to either the parser or
> the format. If there is some appetite for simplifying the correlation
> between commands and parameters, I think it might make sense to spend
> some effort aligning parameter keys with command keys. This could
> simplify the parser by allowing a generic parameter lookup to be done
> in one place, rather than by each handler.
>
> Best Regards,
> Brendan
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose
> the contents to any other person, use it for any purpose, or store or
> copy the information in any medium. Thank you.
>
> [email-masked]

---

From: Thomas Fossati <[email-masked]>
Date: Fri, 28 Feb 2020 17:26:05 +0000

Thanks Brendan, got it!

Cheers, t

On 28/02/2020, 11:40, "Brendan Moran" <[email-masked]> wrote:

    Hi Thomas,

    1. Verify firmware author’s authorization. (Signature validation)
    2. Execute Manifest
         1. Each time a condition is encountered:
              1. If measurement is requested in manifest, record measurement
              2. If measurement is required by internal policy, record measurement
    3. Seal the measurements (e.g. signature)
    4. Execute the firmware image

    You’ve said that BL2 is only trusted after BL1 verifies it. However, this is handled in a modular way in SUIT. The manifest is verified prior to execution, so BL1 can trust
     it. When BL2 is verified, the BL2 manifest is already verified and trusted, so it can be trusted to indicate the need for a measurement to be recorded.

    I think it’s important that we strongly define the purpose of each security mechanism we have in place. Secure boot is for authority enforcement: only authorised parties can place firmware on a device. This leaves some gaps: Is the firmware authorised,
     but old? A device with no secure time source can’t know that. If a third party wants to interact with a device, knowing that the firmware is authorised isn’t good enough, they have to know it’s the expected firmware—version numbers can lie—so we need a strong
     guarantee of exact version that secure boot alone cannot provide.

    Let’s try and define exactly which threat could be opened by allowing the signer of the manifest to also set measurement policy. First an assumption: the holder of the private key for authorising firmware has become nefarious: change of heart,
     theft of keys, etc.

    1. The manifest author tries to hide that a version has changed by not to reporting the firmware.
         1. The verifier notices that firmware version isn’t being reported and takes corrective action.
    2. The manifest author tries to hide that a version has changed by making a measurement before an update, but not reporting after
         1. This attempt at subterfuge is visible in the manifest and its lifetime is limited. The next measurement will make it irrelevant.
    3. The manifest author tries to hide that a version has changed by recording a measurement of one offset, but executing from another.
         1. This attempt at subterfuge is visible in the manifest. It can be further exposed by requiring offset measurements in multi-image devices.

    Best Regards,
    Brendan

    On 27 Feb 2020, at 17:18, Thomas Fossati <[email-masked]> wrote:

    Hey Brendan,

    cheers!