Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

authority baselines and authority delegation (was authorized-by appears to be a security flaw) #244

Open
deeglaze opened this issue Jun 19, 2024 · 7 comments

Comments

@deeglaze
Copy link
Collaborator

I don't think it's appropriate at all for X to sign a document that Y is the one that actually authorized the claims. There is no signature by Y. This is a clear spoofing problem. Even if the Verifier is supposedly forwarding an authorization that it had previously seen by including it in the CoRIM, I don't think that Y has delegated that authority to the Verifier. The Verifier would need to use a "hearsay" claim that it had already shown that Y authorized the claim.

@deeglaze
Copy link
Collaborator Author

I think one way to address unsoundness is to remove authorized-by from measurement-map and add an optional ‘authorities’ entry to ‘stateful-environment-record’.

@nedmsmith
Copy link
Collaborator

X to sign a document that Y is the one that actually authorized the claims

This isn't the intended semantics of authorized-by. The motivating use case is entity A wants to specify whether entity B is authorized to say X (where X is a set of claims aka an ECT). The logic is "A says B says X". Note, it is still necessary for B to say X. authorized-by is therefore a matching condition (as opposed to an addition).

We think AEs are not likely to need this, so it is excluded from Evidence.

But it is reasonable that X could be applied to RVs or Endorsements.

The suggested change:
"remove authorized-by from measurement-map and add an optional ‘authorities’ entry to stateful-environment-record"

would have the same semantics as authorized-by only it restricts its use to Endorsements as stateful-environment-record is only used by Endorsements. To make a symmetric change to the CDDL reference-triple-record should be updated too.

reference-triple-record = [
  environment-map
  measurement-map
 ? authority: [ + $crypto-key-type-choice ]
]

In both structures, the authority is used as a matching condition that determines if B did in fact assert X. In the case above, authority and environment-map are the matching condition, and environment-map and measurement-map are the addition (which is added under the authority of the RIM signer - A).

An internal representation is supposed to keep track of the dynamic that A says B says X.

I don't think the current internal representation using ECTs is sufficient to represent this dynamic. We could modify ECT so that there is an outer authority. I'll use policy to explain what I mean:
Given:

policy = [
    condition: [ + ECT ]
    addition: [ + ECT ]
]

By defining a nested ECT:

nested-ECT = [
  ECT
  ? a: [ + $crypto-key-type-choice ]
  ? cm: cm-type
]

Policy can be changed to:

policy = [
    condition: [ + ECT ]
    addition: [ + ECT / nested-ECT ]
]

This would allow expressions such as:

/cbor diag example/
[
  [
    e: 'x0',
    c: 'x1',
    a: B,
    cm: 0 /ref-val/
  ]
  a: A,
  cm: 5 /policy/
]

It would be interpreted as: A says [ B says (x0, x1) ]

As a policy, it is applied after all the inputs are processed, including an input that includes: B says (x0, x1)

If an RP has policy that says A is trusted, but is silent about B. Then the statement asserted by A (that B says (x0, x1)) would evaluate to true and be eligible as a matching condition for attestation results.

Something to consider is whether it makes sense to restrict transitive trust statements like A says B says X to policy statements or if these should still be supported by Endorsements and RV statements.

More complex transitive trust statements such as: A says B says C says X seems unnecessary at this point since the primary motivation for this type of delegation is a dominant supplier wants to maintain some control over downstream suppliers' clobbering upstream reference values. It's implied that the authority to delegate is not delegated.

If downstream suppliers beyond the first supplier need to be authorized, the originator (A) can do something like:
(A says B says X,
A says C says X)

If we see value in restricting transitive trust statements to policies, then we might consider a new triple:
policy-triple-record = policy
and we can remove authorized-by from measurement-values-map.

This approach might have some beneficial flexibility such as allowing statements like "A says B says -any-" by:

/cbor diag example/
[
  [
    a: B,
    cm: 0 /ref-val/
  ]
  a: A,
  cm: 5 /policy/
]

where the absence of e and c is interpreted as -any-.

We wouldn't want to complicate RV and Endorsement with such semantics IMO.

@deeglaze
Copy link
Collaborator Author

deeglaze commented Jun 22, 2024

I'm not so much asking for a hearsay triple as I am confused by the intended semantics.

I can propose some words to make the role of authorized-by clearer since its meaning is different whether it's in the ACS ("was authorized by all...") or in the CoRIM ("must also be authorized by one of...").

This makes me wonder if we accept cycles or if we reject them.

Kid to parents: Can I go to the concert with Foo?
Bar: I'm okay with it if your Baz's okay with it.
Baz: I'm okay with it if your Bar's okay with it.
Kid: My parents said I could go!

or

Kid: My parents are deadlocked, so I can't go.

Both seem like valid interpretations, but a simple fixed point calculation would not collapse the co-dependence, and thus rejection is easier to implement. I can also see resolving bounded length cycles by having primary endorsement keys and hedged-n-levels endorsement keys to stratify the trust relationship. I'd thus err on the side of rejection for simplicity.

Regarding

An internal representation is supposed to keep track of the dynamic that A says B says X.

This doesn't match the words in the document, which is simply that the ACS ends up saying "both A and B say X", unless you have some order dependence in the authorized-by codepoint processing, which I don't see any evidence of. Sure, you might only say "A says X only if B says X" in your CoRIM, but that relationship is lost and irrelevant unless we add hearsay triples (which I don't want).

@deeglaze deeglaze changed the title authorized-by is a security flaw authorized-by appears to be a security flaw Jun 22, 2024
@nedmsmith
Copy link
Collaborator

In a sidebar with Thomas, he suggested defining a new triple for doing authority delegation as a way to compare and contrast current use of authorized-by. I'll tweak naming so as to borrow semantic context from existing CDDL, but slightly different names help prevent bringing over baggage.

Authority is delegated using a triple.
The signer of the RIM identifies principal making the delegation assertion/statement.
The triples-map is extended to include an authority delegation triple:

triples-map = non-empty<{
...
? &(authority-delegation-triples: 11) =>
    [ + authority-delegation-record ]
...
}>

authority-delegation-record = [
    acs-conditions: [ + eect ]
    delegations: [ + delegation-record ]
]

Since ECT is a common building block (used in above example) but is intended as an internal representation. I'll define External ECT (EECT) as follows:

eect = [
 ? a: [ + $crypto-key-type-choice ]
 ? e: environment-map
 ? m: measurement-map
]

a is a matching condition that is used to conditionally apply the delegation when certain principals have asserted claims. For example, only when principal A asserted someting or when principal B asserted something.
e are target environment claims that have been asserted / appraised.
m are measurement claims that have been asserted / appraised.

If the acs-conditions are met, the delegation record is applied.

I don't think it makes sense to put delegations in the ACS since they are policy statements rather than actual Attester state. Note that this CDDL is an external representation. An internal representation of delegations may require a different structure than an ECT. Possibly, a nested ECT as defined above nested-ECT.

A delegation record describes what is delegated:

delegation-record = [
  ? delegate: $crypto-key-type-choice
  ? ct: cm-type2
  ? env: environment-map2
  ? mea: measurement-values-map2
]

delegate identifies the principal that is the target of delegation.
ct means a delegate may be constrained to a subset of possible message types such as reference values only.
env means the delegate may be constrained to specific target environments.
mea means the delegate may be constrained to a specific set of measurement values.
Note: a variation of environment-map and measurement-map is used that allows a wildcard for -any- set of measurements or environments. I didn't write the CDDL for this yet. It means that a delegate may supply any measurement values, but may be restricted to a subset of possible measurement types such as digests only - no svn measurements...

/cbor diag example/
/ Authority-delegation-record / [
  / acs condition /  [
    principal_A, / authority /
    h'0xDEADBEEF', / uuid environment /
    '1', / svn measurement /
    0 / cm-type : ref-vals /
  ],
  / delegation / [
    principal_B, / delegate /
    0 / ref-vals /
    "cm.class-id.uuid" h'0xFEEDABBE', / constrained to the FEEDABBE environment /
    "mm.mvm.version" "-any-" / constrained to version claims of any value /
  ]
]

@deeglaze deeglaze changed the title authorized-by appears to be a security flaw authority baselines and authority delegation (was authorized-by appears to be a security flaw) Jul 3, 2024
@thomas-fossati
Copy link
Collaborator

thomas-fossati commented Jul 4, 2024

Thanks @nedmsmith for putting forward a proposal.

The statement we need to model is, I think, the following:

A "delegates" B "to make" ConceptualMessages "statements about" ClaimsNames "claims of" Env "environment"

Where:

  • A and B are $crypto-key-type-choice
  • ConceptualMessages is one of reference-values, endorsements, or "any"
  • ClaimsNames is a list of measurement-map code-points or "any"
  • Env is an environment-map or "any"

This allows us to say things like:

  1. A delegates B to make any statements about any claims of any environment
  2. A delegates B to make ref-value and endorsements statements about any claims of any environment
  3. A delegates B to make endorsements statements about SVN and version claims of any environment
  4. A delegates B to make endorsements statements about SVN and version claims of environment with class-id=1825

etc.

In CDDL, this could be expressed as:

delegation-statement = {
  authority: $crypto-key-type-choice
  delegate: $crypto-key-type-choice
  ? cm: uint .bits cm-type-restricted
  ? claim-names: [ + int / text ]
  ? environment: environment-map
}

$crypto-key-type-choice = bytes .size 4
environment-map = "an environment"

cm-type-restricted = &(
  reference-values: 0
  endorsements: 1
)

Morphing it into a triple shape is a matter of rearranging and grouping things, but I believe the highlighted types are the core ones. In particular, it looks like we need cm-type-restricted and a sensible definition for claim-names (which may include a profile indicator alongside the raw numbers & strings).

@deeglaze
Copy link
Collaborator Author

deeglaze commented Jul 5, 2024

Stepping back from just how the wildcarding is supposed to be expressed, I want to make sure I understand the concept. What’s the theory of operation?
It seems that there’s

  • the delegation definer, i.e., the issuer of the corim that contains this triple,
  • the issuer’s trusted delegator, A, or “authority”
  • the permitted delegate(s) to sign corims with some substructure that is defined by
  • a corim filter, i.e., a means of accepting or rejecting the contents of the delegate’s signed corim. It will take careful language design to express a good enough filter for most, but there absolutely should be a way to introduce new filter logic with cbor tags.

is that about right?
In the theory of operation, we then have ECTs with first party signing authorities as a field, and new ECTs with delegated authorities.

If some CoRIM measurement-map/authority (say, B) is compared against, it’s that CoRIM’s issuer (C) that wants the ECT to be signed by B. But integrator (I) signed a delegation that B can delegate to D for anything. Let’s say D signs the corim that would otherwise match that C wants. If we have a list of all ects in the ACS that match without considering authority, we then need to check delegations.

D is allowed to sign for B if you trust I to provide delegations. So now the C-signed corim triple gets added to the ACS with authorities C(if you trust I), B(if you trust I), and D.

The delegated authority becomes infectious for anything that depends on the authority to match, until you get first-hand knowledge that oh, B actually signed the data first hand, and now we need to backtrack to all the provisional assignments to make them direct authorities?

Probably the verifier would want to ensure that I is certainly trusted to assign delegations as a matter of a priori policy to remove this complicated provisional authority tracking.

Does this pass our litmus tests?

  1. Vertical integration: each layer of a measured boot can be seen as a system integrator up to their point of boot, but with specific delegated authorities for who can sign the previous layers.

  2. Right to repair: can integrator further in the chain allow for delegations above them that the prior layers did not delegate to themselves?

Vertical integration I would say specialized versions of a linux distribution can delegate pcrs 0-10,12-15 to the main distribution while they sign their own measurements for higher pcrs. That’s not expressible with the proposed syntax since it’s too coarse to limit to specific integrity registers. Say it were.

S: special version authority
D: distro authority
H: shim authority
G: grub authority.
F: firmware authority
S signs high pcrs reference values and a delegation of pcrs 0-10,12-15 to D. But whose authority is delegated? Let’s say S.
D signs pcr 9,10,12-15 reference values (oops this is merged with shim measurements. Drat) and a delegation of D’s authority to G for pcrs 0-8.
G signs pcr 8 (oops this is merged with shim. Drat) and a delegation of G’s authority to H for pcrs 0-7.
H does its thing that breaks this example and delegates H to F for pcrs 0-7.
F signs reference values for pcrs 0-7 (oops ESP from D gets mixed in here).

So pcrs are messy. Lets say we have signed CELRs instead and some policy for safely rearranging them for the verifier to then add an ECT that measured boot passes a TPM integration policy. However it’s do e, it’s not the most important thing.
When the Verifier gets a request and has all these corims, then it doesn’t look like the filter syntax would allow redelegation like the distro to grub or shim to firmware. If you did, then it would need to be a narrowing of what was permitted to the delegate. You can’t limit an app to only have read access for it to then call another app that needs write access. It’s the capabilities model.

Say we allow delegating delegations but only within the scope of what has been delegated. Does S authorize the firmware measurement? S let D authorize it as if it were S. D let G authorize as if it were D (which is also as S), G let H authorize it as if it were G (which is also as D and then S), etc with cascading authority additions. So S authorizes the firmware.

That test failed with the current proposal. What about test 2? I’ll edit this later when I’m not getting pulled away.

@deeglaze
Copy link
Collaborator Author

I tried working out test 2 and it's not worth sharing. I confused myself with the authority field. I don't see how authority in delegation-statement would be anything other than the CoRIM issuer. I think that's why Ned's delegation-record does not include it. I suppose that's why Thomas, you said something about morphing it into a triple shape?

It does appear that test 2 would pass if you allow every delegated authority to sign any pcr index value, but that's generally not what I'd want to express.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants