Subject: [Suit] Suit manifest with variable recipients

From: Brendan Moran <[email-masked]>
Date: Mon, 12 Jul 2021 20:30:48 +0000

At the virtual interim, we discussed the possibility of altering the recipients (e.g. pruning some during distribution) of a COSE_Encrypt structure in a manifest. In the current structure, a signed digest is calculated over the COSE_Encrypt, which will means any change to the recipient list will cause a change in digest, meaning that the signature of the manifest will not match.

The result is that COSE_Recipients MUST be held outside of the manifest’s chain of trust. This complicates matters somewhat. It would be better if most of the COSE_Encrypt was held under the trust umbrella while the COSE_Recipients were held outside the umbrella. However, COSE does not support detached Recipient lists. This may be a failing of COSE, and perhaps it should be discussed there. In the interim, however, SUIT needs to move forward with some solution to deploying variable recipient lists.

I can see several options:

Option 1: Place the COSE_Encrypt outside the manifest, reference it by URI (remote) or Integer (envelope)
Modify suit-parameter-encryption-info to take a tstr (URI) or integer (Envelope Reference)

This means that all devices supporting the encryption-info parameter MUST support both integrated, detached local, and detached remote modes. I don’t think this is really in the spirit of SUIT.

Option 2: Place the COSE_Encrypt outside the manifest, reference it by Integer (envelope)
Add a new suit-parameter-encryption-info-detached that takes the integer (Envelope Reference)

This has the benefit of being unambiguous. However, it creates a new problem: what happens if both the suit-parameter-encryption-info-detached and the suit-parameter-encryption-info are set? Does there need to be a rule that one explicitly unsets the other? How does that work with permissions?

Option 3: Abuse COSE slightly: Place a COSE_Encrypt0 in the manifest. Place a list of recipients outside the manifest.

This has the benefit of being what we actually want, but it probably won’t play nice with COSE libraries.

On balance, I think we should probably go with option 2. I recommend that we add the following CDDL

SUIT_Parameters //= (
  suit-parameter-encryption-info-detached => suit-encryption-info-detached-key
)

$$SUIT_Envelope_Extensions //=  (
  suit-encryption-info-detached-key => bstr .cbor COSE_Encrypt
)

suit-encryption-info-detached-key = nint / uint .ge 24

This provides an explicit parameter to use when placing the COSE_Encrypt in the envelope. It’s unambiguous and should be reasonably easy to implement. This could be added to either draft-ietf-suit-manifest or draft-ietf-suit-firmware-encryption.

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: Michael Richardson <[email-masked]>
Date: Mon, 12 Jul 2021 21:09:58 -0400

Brendan Moran <[email-masked]> wrote:
    > The result is that COSE_Recipients MUST be held outside of the
    > manifest’s chain of trust. This complicates matters somewhat. It would
    > be better if most of the COSE_Encrypt was held under the trust umbrella
    > while the COSE_Recipients were held outside the umbrella. However, COSE
    > does not support detached Recipient lists. This may be a failing of
    > COSE, and perhaps it should be discussed there. In the interim,
    > however, SUIT needs to move forward with some solution to deploying
    > variable recipient lists.

I think it is reasonable that SUIT give COSE a clear set of requirements.
(Let's not do CBOR packed goof again)

    > Option 1: Place the COSE_Encrypt outside the manifest, reference it by
    > URI (remote) or Integer (envelope) Modify
    > suit-parameter-encryption-info to take a tstr (URI) or integer
    > (Envelope Reference)

    > This means that all devices supporting the encryption-info parameter
    > MUST support both integrated, detached local, and detached remote
    > modes. I don’t think this is really in the spirit of SUIT.

I see your point.

    > Option 2: Place the COSE_Encrypt outside the manifest, reference it by
    > Integer (envelope) Add a new suit-parameter-encryption-info-detached
    > that takes the integer (Envelope Reference)

    > This has the benefit of being unambiguous. However, it creates a new
    > problem: what happens if both the
    > suit-parameter-encryption-info-detached and the
    > suit-parameter-encryption-info are set? Does there need to be a rule
    > that one explicitly unsets the other? How does that work with
    > permissions?

It sounds to me that either it's invalid (manifest rejected outright), or one
simply has a higher priority than the other.

    > Option 3: Abuse COSE slightly: Place a COSE_Encrypt0 in the
    > manifest. Place a list of recipients outside the manifest.

    > won’t play nice with COSE libraries.

I think that few devices will have totally generic COSE libraries anyway.
Encoders can cope.

--
Michael Richardson <[email-masked]>   . o O ( IPv6 IøT consulting )
           Sandelman Software Works Inc, Ottawa and Worldwide

---

From: Brendan Moran <[email-masked]>
Date: Tue, 20 Jul 2021 09:58:47 +0000

There is another possibility that I don’t think we’ve discussed. It has some pros and a really big con. For the sake of completeness, here it is: We keep the COSE_Encrypt exactly as it is and allow standard manifest overrides via dependencies. This is good because it means that only authorised parties can edit the recipients list. This is bad because it means that the unused recipients structures cannot be severed.

I do have a big concern about the existing proposals: It is not possible to detect tampering with the recipients list. An on-path attacker could remove one or many devices from the recipients list. This would not be flagged as corruption because all signatures and digests are still correct. This would appear exactly as though the target device was not authorised to receive the update. This gives an on-path attacker an elevation of privilege because they can now control the recipients list without the explicit rights to do so. This is different from a normal denial of service attack; it is far less detectable.

For example, suppose a Firmware Author provides firmware to many Device Operators. Under normal DoS conditions, the location of an on-path attacker dictates how much control they have: if they are between the Firmware Author and the Device Operator, then either all the Device Operator’s devices are upgraded, or none of them are. If they are between the Device Operator and the Recipient (Device), then they can control whether that specific device is upgraded. This attack is detectable and not scalable.

However in our situation, an on-path attacker upstream of the Device Operator gains fine-grained control of which of the Device Operator’s devices are upgraded. This is scalable and difficult to detect. A Device Operator would need to communicate with the Firmware Author to determine why certain devices were not upgraded before the attack was discovered, giving attackers a window of opportunity. Depending on implementation details, competency, level of automation, and any other coincident attacks launched by the threat actor, this window could be longer or shorter.

I don’t believe that this is inline with our goals, however this specific threat is not listed in the threat model within draft-ietf-suit-information-model—evidence that threat models are living documents, I suppose! Perhaps this threat should be discussed in draft-ietf-suit-firmware-encryption?

I think the solution, though less than ideal, is to place some metadata in the manifest about the COSE_Encrypt within the manifest. In short, if COSE_Encrypt is external to the manifest, it must be authenticated by the manifest. If it is altered by an authorised party, that must be explicit and authenticated as well.

I can see two possible implementations for this:
1) manifest override. A digest of the COSE_Encrypt is placed in the manifest. This digest can be replaced by an authorised party by creating a dependent manifest that overrides it. This approach suggests that we should add the facility to digest integrated payloads/images as Øyvind requested..

2) COSE_Sign: If the COSE_Encrypt (actually a COSE_Encrypt_Tagged in this case) is overridden, then it must be replaced with a COSE_Sign_tagged containing the altered COSE_Encrypt. This initially seems less complex, but 1) reuses existing code paths, whereas 2) requires the creation of new ones.

I think we should consider requiring a digest of the COSE_Encrypt to be verified in advance of using the COSE_Encrypt in order to detect tampering. However if the COSE_Encrypt has been tampered with, but the resulting key is still usable, there’s no reason to halt installation. This presents an unusual problem: the verification of COSE_Encrypt is more important at the distribution level than at the Recipient level. At the Recipient level, it’s most important for reporting purposes.

The “correct” answer for this issue is not immediately clear to me.

Best Regards,
Brendan

> On 13 Jul 2021, at 02:09, Michael Richardson <[email-masked]> wrote:
>
>

---

From: Russ Housley <[email-masked]>
Date: Tue, 20 Jul 2021 10:35:00 -0400

Brendan:

This is a DoS issue.  We wanted distribution to be able to add recipients and remove recipients.  This means that an attacker can also add recipients and remove recipients.  A second signature to bind the recipient information to the author-signed firmware would be a way to prevent attackers from doing this manimulation, but it comes at the cost of a second signature and the management of the trust anchor to validate it.

Russ

> On Jul 20, 2021, at 5:58 AM, Brendan Moran <[email-masked]> wrote:
> 
> _______________________________________________
> Suit mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/suit

---

From: "Dick Brooks" <[email-masked]>
Date: Tue, 20 Jul 2021 11:01:29 -0400

This also appears to be a provenance/chain of custody issue, if Brendan's scenario is feasible. 

Thanks,

Dick Brooks

Never trust software, always verify and report! ™
http://www.reliableenergyanalytics.com
Email: [email-masked]
Tel: +1 978-696-1788

-----Original Message-----
From: Suit <[email-masked]> On Behalf Of Russ Housley
Sent: Tuesday, July 20, 2021 10:35 AM
To: Brendan Moran <[email-masked]>
Cc: Michael Richardson <[email-masked]>; suit <[email-masked]>
Subject: Re: [Suit] Suit manifest with variable recipients

Brendan:

Russ

>>> manifest’s chain of trust. This complicates matters somewhat. It 
>>> would be better if most of the COSE_Encrypt was held under the trust 
>>> umbrella while the COSE_Recipients were held outside the umbrella. 
>>> However, COSE does not support detached Recipient lists. This may be 
>>> a failing of COSE, and perhaps it should be discussed there. In the 
>>> interim, however, SUIT needs to move forward with some solution to 
>>> deploying variable recipient lists.
>> 
>>> Option 1: Place the COSE_Encrypt outside the manifest, reference it 
>>> by URI (remote) or Integer (envelope) Modify 
>>> Option 2: Place the COSE_Encrypt outside the manifest, reference it 
>>> by Integer (envelope) Add a new 
>>> suit-parameter-encryption-info-detached
>> It sounds to me that either it's invalid (manifest rejected 
>> outright), or one simply has a higher priority than the other.
>>

---

From: Brendan Moran <[email-masked]>
Date: Tue, 20 Jul 2021 15:30:11 +0000

While I agree that this is a DoS issue, it’s possible to surgically DoS individual devices without access to those devices or their networks. As I laid out in my previous mail, this is a scalable DoS that is difficult to detect: how does a Device Operator know why a particular device does not have a COSE_Recipients? This is the situation I want to avoid.

I don’t think that it makes sense for Recipients to validate the COSE_Encrypt. However, it might make sense for it to be authenticated between elements of the distribution infrastructure/chain of custody.

Maybe another way to do this would be to add one or more detached COSE_Sign elements to the envelope, which authenticate the COSE_Encrypt(s) that are presented in the envelope. This would allow the distributors to remove those COSE_Sign elements to reduce distribution bandwidth, or replace them when modifying the audience of the manifest.

Best Regards,
Brendan

> On 20 Jul 2021, at 16:01, Dick Brooks <[email-masked]> wrote:
>

---

From: Michael Richardson <[email-masked]>
Date: Wed, 21 Jul 2021 16:22:52 -0400

Not sure why I'm explicitely in the CC, reply-all I guess.

Brendan Moran <[email-masked]> wrote:
    > There is another possibility that I don’t think we’ve discussed. It has
    > some pros and a really big con. For the sake of completeness, here it
    > is: We keep the COSE_Encrypt exactly as it is and allow standard
    > manifest overrides via dependencies. This is good because it means that
    > only authorised parties can edit the recipients list. This is bad
    > because it means that the unused recipients structures cannot be
    > severed.

It's a tussle.

    > However in our situation, an on-path attacker upstream of the Device
    > Operator gains fine-grained control of which of the Device Operator’s
    > devices are upgraded. This is scalable and difficult to detect. A
    > Device Operator would need to communicate with the Firmware Author to
    > determine why certain devices were not upgraded before the attack was
    > discovered, giving attackers a window of opportunity. Depending on
    > implementation details, competency, level of automation, and any other
    > coincident attacks launched by the threat actor, this window could be
    > longer or shorter.

    > I don’t believe that this is inline with our goals, however this
    > specific threat is not listed in the threat model within
    > draft-ietf-suit-information-model—evidence that threat models are
    > living documents, I suppose! Perhaps this threat should be discussed in
    > draft-ietf-suit-firmware-encryption?

I think that such an on-path attacker can also drop the entire update, right?
Or such an on-path attacker could selectively suppress the manifest getting
to specific devices anyway.  The summary is that this is not something new
that is enabled by fine-grained control of the encryption.

    > I think the solution, though less than ideal, is to place some metadata
    > in the manifest about the COSE_Encrypt within the manifest. In short,
    > if COSE_Encrypt is external to the manifest, it must be authenticated
    > by the manifest. If it is altered by an authorised party, that must be
    > explicit and authenticated as well.

I think that this barks up the wrong tree.
Let's go back to the architecture (now RFC9019: woohoo!)
Isn't the Status Tracker supposed to keep track of what version each device
is running, and let it know that there is something new?

AFAIK, standardization of the status tracker was not a goal in this round of
SUIT.  I'm unclear if we this was an ordering/chartering decision, or if it
was because we really didn't think we could accomplish this without boiling
oceans.  RFC9019 mentions that LwM2M already has this functionality, and so
maybe we will never ever have a single standard, but maybe it's time to
identify what other places we can place the Status Tracker functionality.

We have also been discussing SBOM pointers via MUD and/or Remote Attestation.

At this time, I think that the manifest has became a bit of a hammer, and
we'e actually run out of nail-shaped things.

---

From: Michael Richardson <[email-masked]>
Date: Wed, 21 Jul 2021 16:24:36 -0400

Russ Housley <[email-masked]> wrote:
    > This is a DoS issue.  We wanted distribution to be able to add
    > recipients and remove recipients.  This means that an attacker can also
    > add recipients and remove recipients.  A second signature to bind the
    > recipient information to the author-signed firmware would be a way to
    > prevent attackers from doing this manimulation, but it comes at the
    > cost of a second signature and the management of the trust anchor to
    > validate it.

I think that management of the first trust anchor is going to be complex
enough.

Before we contemplated a second signature, I think that we'd have to have
more specific (application-specific) use cases that explained how it all went together.

---

From: Michael Richardson <[email-masked]>
Date: Wed, 21 Jul 2021 16:27:22 -0400

Brendan Moran <[email-masked]> wrote:
    > While I agree that this is a DoS issue, it’s possible to surgically DoS
    > individual devices without access to those devices or their
    > networks. As I laid out in my previous mail, this is a scalable DoS
    > that is difficult to detect: how does a Device Operator know why a
    > particular device does not have a COSE_Recipients? This is the
    > situation I want to avoid.

And, if it's visible to the Device Operator, then it's probably visible to
everyone.  So now you have a privacy issue.

If you leave out the device identities (the device has to try each cipher key
block until it finds one that decrypts for it: sorry I forget if have a
specific name for that), then there is more privacy, but no audit log.

---

From: Brendan Moran <[email-masked]>
Date: Thu, 22 Jul 2021 15:25:42 +0000

> On 21 Jul 2021, at 21:22, Michael Richardson <[email-masked]> wrote:
>
>

Yup.

> that is enabled by fine-grained control of the encryption.

It depends where the on-path attacker is. If they are resident between the firmware author and the status tracker, then it was all or nothing: suppress the manifest in its entirety or don’t. This fine-grained control of encryption allows them fine-grained suppression control with repudiation: a single recipient can be suppressed by an attacker upstream of the status tracker without any evidence they have done so. It is impossible to tell whether an attacker suppressed the recipient or the manifest author suppressed the recipient.

>> explicit and authenticated as well.

So, this is wrong. It’s not that the COSE_Encrypt MUST be authenticated by the manifest; it’s that the COSE_Encrypt MUST be authenticated! More below.

> Let's go back to the architecture (now RFC9019: woohoo!)

Hurray!

> is running, and let it know that there is something new?

There are two threats that we need to concern ourselves with:

1: The threat described above: An on-path attacker upstream of the status tracker suppresses a device. This is different from existing SUIT DoS threats because of the targeting of single devices from outside a network. To be clear, this is not simply a DoS; it is an Elevation of Privilege (unprivileged actor decides which devices are updated) AND a Repudiation threat (Not possible to know who chose which devices received updates). The status tracker CAN inform the device of the new update, but the device appears not to have been authorised by the owner of the firmware (via the Content Encryption Key)

2: An on-path attacker (upstream or downstream of the status tracker) tampers with the COSE_Encrypt, causing a device to spend extra energy on receiving data, cryptographic operations, flash writes, etc.

These two threats are detected in different parts of the infrastructure and so may require different solutions.

For threat 1, the status tracker needs to validate that there has been no tampering with the list of recipient devices. This requires a signature that covers the recipient list. This signature does NOT need to be verified by a Manifest Processor. Therefore, this signature does not need to be integrated into the manifest dependency hierarchy and it does not need to be integrated as metadata in the manifest; it can exist purely in the envelope. Furthermore, the signature MAY be severed prior to delivery to a Recipient Device.

For threat 2, we want to prevent a device from performing unnecessary payload fetches, public key cryptographic operations, and flash writes. For the sake of argument, the energy cost to receive a byte over LoRa is approximately 15x the energy cost to write it to flash [1]. There’s not much we can do to make sure the cipher text of the payload is correct before fetching it. The manifest already provides a mechanism for verifying before decrypting, but that is not always applicable nor desirable from an energy perspective.

The COSE_Recipients structure is more interesting. We cannot verify the whole structure without public key operations unless there is already a trusted PSK with the distributor, but this simply recreates the key distribution problem.

In the Hybrid Public-Key Encryption (HPKE, non-interactive ephemeral-static Diffie-Hellman exchange) case, COSE_Encrypt contains the ephemeral public key and COSE_Recipients structure contains the cipher text of the Content Encryption Key (CEK) and a key id. The ephemeral public key is the same for all recipients. Similarly, the CEK is the same for all recipients. The CEK ciphertext and the key id are different for each recipient. While the ephemeral public key could be different for multiple “batches” of recipient devices, the CEK MUST be the same for the same payload.

In this case, it would make sense to authenticate the CEK. The digest of the CEK could be added to the manifest trivially in the parameter that references the COSE_Encrypt in the envelope. This would resolve Threat 2. We could potentially authenticate the ephemeral public key. I’m not certain that this improves over CEK authentication in a meaningful way since we can’t reasonably authenticate the CEK ciphertext without additional public key operations

1 public key operation to validate the manifest
1 public key operation to compute the shared secret
1 digest of CEK

A separately-signed COSE_Encrypt list makes this worse:

1 public key operation to validate the manifest
1 public key operation to validate the COSE_Encrypt & COSE_Recipients (including a digest of the whole COSE_Encrypt, not just a CEK)
1 public key operation to compute the shared secret

Including a digest of the CEK adds no public key operations and allows us to avoid fetching, decrypting, and storing a payload if the CEK is invalid. It takes less space to encode and less energy to verify. It costs 1 SUIT_Digest to encode this in the manifest. Given that this is a scenario where there is a COSE_Encrypt containing a public key, and a COSE_Recipient containing a key id, and a ciphertext key, a single SUIT_Digest is not a substantial increase in size.

To summarise, I think that the best course of action is to add a detached COSE_Sign for each COSE_Encrypt OR wrap the whole SUIT_Envelope in a COSE_Sign—though this becomes much more complex with dependencies that have encrypted payloads. The COSE_Sign allows the author and status tracker to exchange manifests without tampering by on-path attackers between. This COSE_Sign MAY be pruned prior to distribution to Recipients.

> identify what other places we can place the Status Tracker functionality.

This isn’t about the status tracker. This is about document format support for ensuring that the recipient list isn’t tampered with between Author and Status Tracker, between Status Trackers, or between Status Tracker and Recipient.

> We have also been discussing SBOM pointers via MUD and/or Remote Attestation.

I wrote a draft that’s very related to this for iotops! https://datatracker.ietf.org/doc/draft-moran-iot-nets/

> we'e actually run out of nail-shaped things.

Overall, I think I agree. However, we have a few use cases left to cover, or cover more explicitly, I think.

Cheers,
Brendan

[1] The background for receive vs write estimates is as follows; but it may vary substantially with data rates, models of transceiver & MCU, etc.
SX1262 LoRa transceiver quotes up to 62.5kb/s, 8.2mA @ 1.8V in RX mode => 0.236 pJ/b or 1.89pJ/B
STM32F401RE quotes 12mA erase current (3.3V & 32-bit mode) and 16us word programming time => 0.119pJ/B

---

From: Michael Richardson <[email-masked]>
Date: Thu, 22 Jul 2021 16:36:04 -0400

Brendan Moran <[email-masked]> wrote:
    > 1: The threat described above: An on-path attacker upstream of the
    > status tracker suppresses a device. This is different from existing
    > SUIT DoS threats because of the targeting of single devices from
    > outside a network. To be clear, this is not simply a DoS; it is an
    > Elevation of Privilege (unprivileged actor decides which devices are
    > updated) AND a Repudiation threat (Not possible to know who chose which
    > devices received updates). The status tracker CAN inform the device of
    > the new update, but the device appears not to have been authorised by
    > the owner of the firmware (via the Content Encryption Key)

Let's say that it's not malicious.
Let's say that upstream provider noticed that you didn't renew support on
that device, so they removed the access.

Shouldn't the Status-Tracker still notice that the device hasn't got the
right firmware?

Again, I think you are trying to solve an operational problem in the
manifest, and I think that it just can't work.  I think you are trying to do
this, because we don't have any specifications on real status-trackers.

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

---

From: Brendan Moran <[email-masked]>
Date: Fri, 23 Jul 2021 06:48:43 +0000

> On 22 Jul 2021, at 21:36, Michael Richardson <[email-masked]> wrote:

Yes, that’s explicitly called out; it's a recognised use case that I detailed previously. The point is that it would be indistinguishable from an attacker modifying—at rest or in transit—the list of recipients. This is the Repudiation threat. This is not acceptable. There needs to be at-rest protection for the recipient list.

> Shouldn't the Status-Tracker still notice that the device hasn't got the

Yes, but it can’t tell the difference between a modification by an up-stream provider and by an attacker. This is an open Repudiation threat.

I don’t see why it’s controversial to sign the recipient list—especially if that signature is NOT delivered to constrained nodes.

Brendan