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

Introduce CCA Realm provisioning plugin #222

Closed
wants to merge 7 commits into from

Conversation

yogeshbdeshpande
Copy link
Collaborator

@yogeshbdeshpande yogeshbdeshpande commented May 1, 2024

This change introduces Realm Provisioning Plugin

Signed-off-by: Yogesh Deshpande <[email protected]>
@yogeshbdeshpande yogeshbdeshpande marked this pull request as ready for review May 1, 2024 16:48
"scheme": "CCA_REALM",
"type": "REFERENCE_VALUE",
"attributes": {
"CCA_REALM.vendor": "Worload Client Ltd",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/worload/workload/

"scheme": "CCA_REALM",
"type": "REFERENCE_VALUE",
"attributes": {
"CCA_REALM.vendor": "Worload Client Ltd",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/worload/workload/

scheme/cca-realm-provisioning/corim_test_vectors.go Outdated Show resolved Hide resolved
@@ -0,0 +1,34 @@
// Copyright 2022-2024 Contributors to the Veraison project.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/2022-//

var attrs = map[string]interface{}{
"CCA_REALM.vendor": cAttr.Vendor,
"CCA_REALM-class-id": cAttr.UUID,
"CCA_REALM-instance-id": rAttr.Rim,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be "CCA_REALM-realm-initial-measurement"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it can be expressed this way and perhaps better, hence renamed it now!


var attrs = map[string]interface{}{
"CCA_REALM.vendor": cAttr.Vendor,
"CCA_REALM-class-id": cAttr.UUID,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the right choice? Would "model" be a better identifier for what is essentially a software product?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the intent here was to identify a Workload provider Identity which is launching N number of Realms, each with a Unique RIM Value.

@@ -8,6 +8,7 @@ SUBDIR += psa-iot
SUBDIR += tpm-enacttrust
SUBDIR += parsec-tpm
SUBDIR += parsec-cca
SUBDIR += cca-realm-provisioning
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this currently only implements the provisioning part, shouldn't the scheme be just cca-realm (and any future verification implementation would go under here as well)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@setrofim : As discussed only the provisioning will be a separate scheme, as it is coming from a different supply chain, the Verification will be taken care inside a combined CCA plugin, which verifies both Realm and Platform part together. Hence I chosen the name cca-realm-provisioning.

If I keep it just cca-realm then it will assume both Provisioning and Verifications are handled inside!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm ok, that would mean that the StoreHandler implementation would essentially be split/duplicated across two schemes, as the key formats need to be aligned across both schemes (which breaks the conceptual integrity of a scheme -- schems ought to be independent of each other).

Are we sure this is the right way forward? Would it not be better to implement as single cca scheme that handles everything in a single set of plugins, and then use configuration and/or policy to control whether the platform or realm parts, or both, are handled by a particular deployment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I thought about StoreHandler part, while implementing the provisioning scheme and came to conclusion that the internal logic will be implemented in the common set of functions and both the schemes will invoke the same internal implementation thus essentially avoiding duplication! This is the best way of approaching as the CCA Scheme StoreHandler needs to fetch in sequence the RefValues for Platform and Realm in sequence, however this scheme will only do that latter!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conceptually, a "scheme" is supposed to encompass the entire attestation "lifecycle", i.e. provisioning and attestion. It doesn't make sense to have a scheme with only provisioning, after all, the sole purpose of provisioning endorsements is so that they would later be used in verification.

the Verification will be taken care inside a combined CCA plugin, which verifies both Realm and Platform part together.

If that is the case, then this should be part of that combined plugin as well (going back to my intial suggestion of renaming this). When implementing the verification part of it, we can then re-use the commmon functionality between this and the cca-ssd-platform scheme.

On the other hand, if the goal is to modify cca-ssd-platfom scheme to optinally handle the realm part as well, then (it should probably be renamed, and) this should be part of that too.

Basically, it doesn't make sense for provisioning to exist in a scheme of its own, as the only purpose of provisioning is to enable verification. So if realm verification on its own is not a thing, and we can only have plaform and platform+realm, then we should have two schemes: cca-ssd-platform and cca (or cca-combined).

Copy link
Contributor

@thomas-fossati thomas-fossati May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the same media type for both is incorrect, isn't it?

It's not incorrect, as long as the same CoRIM profile takes care of both platform and realm.

Instead, if we want to have separate profiles, we will need two media types.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they should be separate media types/profiles.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, CCA Platform and CCA Realm are two separate profiles and hence we will need two media types!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not incorrect, as long as the same CoRIM profile takes care of both platform and realm.

They technically could be handled with a single profile. However, I belive the arguement is that they should be handled by separate profiles, as they're expected to be privided by different entitied within the supply chain, and that would simplify the profile that each entity needs to understand.

Copy link
Contributor

@thomas-fossati thomas-fossati May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are clear practical advantages to separating the two. I was just noting that it's not "incorrect" per se.

I think we are all in agreement about "two media types for one scheme"

if classID == nil {
log.Debug("no classID in the environment")
}
if classID != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be an else clause for the if statement above, rather than a separate if statement.

log.Debug("no classID in the environment")
}
if classID != nil {
uuID, err := classID.GetUUID()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: rename to uuid, the whole thing, "UUID" is an initialism, and it doesn't make sense to only keep the "ID" part capitalized; so either UUID or uuid.


type CorimExtractor struct{}

func (o CorimExtractor) RefValExtractor(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to ExtractRefVal. In general, methods should be verbs (unless constructors, factories, properties, etc). The name as-is suggests that this should return an extractor, rather than a slice of ref vals.

(note: I realise that this is meant to be implementing common.IExtractor, however there is no need for that interface -- this is only used within this code, and is never passed via the interface.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IExtractor is the interface which is been implemented by CorimExtractor. To your comment: however there is no need for that interface -- this is only used within this code

is not true, IExtractor interfaces are invoked from: UnsignedCorimDecoder.go
hence this is not a local function!


}

func RefValLookupKey(schemeName, tenantID, instID string) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be changed to a local function (i. e. refValLookupKey)?

Copy link
Contributor

@thomas-fossati thomas-fossati left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a couple of questions:

  • is it possible to provide an incomplete integrity register (e.g., if I don't care about REMs and only care about RIM)?
  • why is PV left out from the realm reference values?

for k, val := range r.M {
a, d, err := o.extractRealmDigest(val)
if err != nil {
return errors.New("unable to extract digest for ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incomplete sentence

scheme/cca-realm-provisioning/realmattributes.go Outdated Show resolved Hide resolved
return "", nil, fmt.Errorf("invalid digest: %v", err)
}
if len(digests) != 1 {
return "", nil, fmt.Errorf("invalid number %d for digest", len(digests))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return "", nil, fmt.Errorf("invalid number %d for digest", len(digests))
return "", nil, fmt.Errorf("expecting 1 digest, got %d", len(digests))

}

func (o *RealmAttributes) extractRealmDigest(digests comid.Digests) (algID string, hash []byte, err error) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spurious NL

Suggested change

@thomas-fossati
Copy link
Contributor

Follow up on this:

  • is it possible to provide an incomplete integrity register (e.g., if I don't care about REMs and only care about RIM)?

I think there should be a RealmAttributes::Valid() method that makes it clear what are the exact requirements in terms of what we are willing to ingest.

@yogeshbdeshpande
Copy link
Collaborator Author

RealmAttributes

@thomas-fossati: I will look into this further! Basically my initial thought was REM slots will always be 4 in token, so we provide 4 to Supply Chain. They can use whatever they want to use 1,2,3, or all. The rest will be filled with nil values same as received in the token. When comparing, we compare the whole blob and should work, isn't it?

@thomas-fossati
Copy link
Contributor

RealmAttributes

@thomas-fossati: I will look into this further! Basically my initial thought was REM slots will always be 4 in token, so we provide 4 to Supply Chain. They can use whatever they want to use 1,2,3, or all. The rest will be filled with nil values same as received in the token. When comparing, we compare the whole blob and should work, isn't it?

Not really. Suppose at run-time the workload app extends the REMs but the verifier is only in the "pure" TCB (i.e., platform + RIM).

If both RIM and REMs must be specified there is no way to tell the verifier to "ignore REMs".

Signed-off-by: Yogesh Deshpande <[email protected]>
Signed-off-by: Yogesh Deshpande <[email protected]>
Signed-off-by: Yogesh Deshpande <[email protected]>
Signed-off-by: Yogesh Deshpande <[email protected]>
Signed-off-by: Yogesh Deshpande <[email protected]>
@yogeshbdeshpande
Copy link
Collaborator Author

Closing this PR as the changes intended for this Pull Request will be addressed using the PR #233

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

Successfully merging this pull request may close these issues.

3 participants