Subject: Re: [Suit] Parameters and Commands

From: Brendan Moran <[email-masked]>
Date: Mon, 2 Mar 2020 15:40:25 +0000

Hi Koen,

I haven’t heard any complaints about harmonising condition handling to parameter-only, so I will take that as a consensus.

You’re absolutely right about my plan for measurement encoding. I anticipate that there are only 3 possible values for the measurement policy:

  1.  Do not record measurement (Leave as null)
  2.  Record measurement on success (typical)
  3.  Always record measurement (Full trace)

I’m open to suggestions for encoding of 2 and 3. I would ideally like to use simple values, rather than integers here, however that leaves only:

  *   False
  *   True
  *   Undefined

This doesn’t really seem to map into reporting policy well. The only semi-logical approach with simple values I can see is:
Should_report = report_arg || condition_result

This maps “record measurement on success” to “False" and "always record” to “True”

This seems quite opaque, so I think using integers would be a better choice. This has the advantage that we could cover more policies that we haven’t thought of yet without change to the encoding.

I see what you mean about trading one inconsistency for another. I’m not sure if it’s a blocker for this approach or not. If we decide to separate reporting policy from SUIT, then there are a few approaches we could use to prune the NULLs, but then I’m not sure how to tie RATS and SUIT together.

Effectively my idea is to enable reporting of any measurements that are done (conditions). That’s almost enough, however there’s one point that is missing from this: Run should be measurable since an argument could be passed to Run—c.f. Linux kernel command line, or argc/argv to main(). I’ve already floated the idea of making Run imply an image condition. This would justify the reporting of a measurement for Run. I could see an argument for making the same requirement for Fetch and Copy, since they should probably be followed immediately by an image condition anyway. All parameters are either invariant or set based on conditions, so with a copy of the manifest, you can determine what they were.

What would you think of:

  1.  All conditions take a measurement policy argument.
  2.  Run implies an image pre-condition before the activation
  3.  Fetch implies an image post-condition
  4.  Copy implies an image post-condition
  5.  Run, Fetch, Copy take a measurement policy argument.

That seems fairly consistent.

Brendan

On 28 Feb 2020, at 14:46, Koen Zandberg <[email-masked]<mailto:[email-masked]>> wrote:

Hi Brendan,

I also support the idea of aligning all 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.

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.

_______________________________________________
Suit mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/suit

_______________________________________________
Suit mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/suit

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: Brendan Moran <[email-masked]>
Date: Fri, 6 Mar 2020 13:32:40 +0000

To clarify, I don’t think that this approach is ready to be included in the manifest just yet. I think it needs a little more work to define it properly. I’m not planning to add this for v04, which I plan to publish on Monday.

Best Regards,
Brendan

On 2 Mar 2020, at 15:40, Brendan Moran <[email-masked]<mailto:[email-masked]>> wrote:

Hi Koen,

  *   False
  *   True
  *   Undefined

What would you think of:

Brendan

Hi Brendan,

Cheers

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

Best Regards,
Brendan

---

From: Koen Zandberg <[email-masked]>
Date: Wed, 11 Mar 2020 13:58:28 +0100

Hi Brendan,

On 02/03/2020 16.40, Brendan Moran wrote:
> Hi Koen,
>
> I haven’t heard any complaints about harmonising condition handling to
> parameter-only, so I will take that as a consensus.
No complaints from my side. V4 has this from what I've read in the
changelog.
> <snip>
> This seems quite opaque, so I think using integers would be a better
> choice. This has the advantage that we could cover more policies that
> we haven’t thought of yet without change to the encoding.
I agree with you on this. Using integers here should come for free and
it gives users the option to use (also here) negative numbers for their
custom policies, whatever they might be.
>
> I see what you mean about trading one inconsistency for another. I’m
> not sure if it’s a blocker for this approach or not. If we decide to
> separate reporting policy from SUIT, then there are a few approaches
> we could use to prune the NULLs, but then I’m not sure how to tie RATS
> and SUIT together.

I don't have a better solution at the moment than what you propose here.
Is the full per command granularity required from the RATS side? It is
not sufficient to set a global policy per manifest? And I guess it is
too much overhead to set the policy as a SUIT parameter every time the
policy requires modification during a manifest sequence.

As I mentioned before, I don't consider this a strong concern from my
side and definitely something that can be solved with sufficient
clarification in the spec. From an implementation point of view,
ignoring the nill vs ignoring the integer is trivial.

>
> Effectively my idea is to enable reporting of any measurements that
> are done (conditions). That’s almost enough, however there’s one point
> that is missing from this: Run should be measurable since an argument
> could be passed to Run—c.f. Linux kernel command line, or argc/argv to
> main(). I’ve already floated the idea of making Run imply an image
> condition. This would justify the reporting of a measurement for Run.
> I could see an argument for making the same requirement for Fetch and
> Copy, since they should probably be followed immediately by an image
> condition anyway. All parameters are either invariant or set based on
> conditions, so with a copy of the manifest, you can determine what
> they were.
Looking at the current spec (ietf-v4), I think it is also possible to
move the argument for the fetch and the run directive to a separate
parameter. This way the measurement policy can be included as the
'argument' to the directive. Does this make sense assuming this is the
way measurement settings are included via arguments.
>  5. Run, Fetch, Copy take a measurement policy argument.
Is it the case that we're describing the same idea here? Is this image
pre-condition and post-condition a solution to include a 'measurement'
in these directives?

Cheers,

Koen