Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion scheme/parsec-tpm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,53 @@
"attributes": {
"parsec-tpm.ak-pub": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETKRFE_RwSXooI8DdatPOYg_uiKm2XrtT_uEMEvqQZrwJHHcfw0c3WVzGoqL3Y_Q6xkHFfdUVqS2WWkPdKO03uw==",
"parsec-tpm.class-id": "cd1f0e55-26f9-460d-b9d8-f7fde171787c",
"parsec-tpm.instance-id": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"parsec-tpm.instance-id": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"parsec-tpm.vendor": "ACME Corp",
"parsec-tpm.model": "TPM-2000"
}
}
```

### Vendor and Model Information

The TPM Trust Anchor can include optional vendor and model information to provide additional context about the TPM manufacturer and specific model. These fields are:

- `parsec-tpm.vendor`: The manufacturer or vendor of the TPM (optional)
- `parsec-tpm.model`: The specific model identifier of the TPM (optional)

Both fields support:
- Unicode characters (e.g., for international vendor names)
- Special characters (allowed in both fields)
- Variable length strings (no artificial length restrictions)
Comment on lines +41 to +44
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Both fields support:
- Unicode characters (e.g., for international vendor names)
- Special characters (allowed in both fields)
- Variable length strings (no artificial length restrictions)
Both fields support:
- Unicode characters (e.g., for international vendor names)
- Special characters (allowed in both fields)
- Variable length strings (no artificial length restrictions)


### CoRIM Example

To include vendor and model information in your CoRIM manifest, add them to the `environment.class` section (following standard CoRIM specification):

```json
{
"comid.verification-keys": [
{
"environment": {
"class": {
"id": {
"class-id": "cd1f0e55-26f9-460d-b9d8-f7fde171787c"
},
"vendor": "ACME Corp",
"model": "TPM-2000"
},
"instance": {
"instance-id": {
"type": "ueid",
"value": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
}
}
},
"key": [{
"type": "pkix-base64-key",
"value": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETKRFE_RwSXooI8DdatPOYg_uiKm2XrtT_uEMEvqQZrwJHHcfw0c3WVzGoqL3Y_Q6xkHFfdUVqS2WWkPdKO03uw=="
}]
}
]
}
```
53 changes: 38 additions & 15 deletions scheme/parsec-tpm/corim_extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@ func (o CorimExtractor) RefValExtractor(
return nil, fmt.Errorf("measurement[%d]: %w", i, err)
}

for j, digest := range digests {
attrs, err := makeRefValAttrs(id.class, pcr, digest)
if err != nil {
return nil, fmt.Errorf("measurement[%d].digest[%d]: %w", i, j, err)
}

refval = &handler.Endorsement{
Scheme: SchemeName,
Type: handler.EndorsementType_REFERENCE_VALUE,
Attributes: attrs,
}
for j, digest := range digests {
attrs, err := makeRefValAttrs(id.class, pcr, digest, rv.Environment)
if err != nil {
return nil, fmt.Errorf("measurement[%d].digest[%d]: %w", i, j, err)
}

refval = &handler.Endorsement{
Scheme: SchemeName,
Type: handler.EndorsementType_REFERENCE_VALUE,
Attributes: attrs,
}
refVals = append(refVals, refval)
}
refVals = append(refVals, refval)
}
}

Expand Down Expand Up @@ -81,7 +81,7 @@ func (o CorimExtractor) TaExtractor(
return nil, fmt.Errorf("ak-pub does not appear to be a PEM key (%T)", akPub.Value)
}

taAttrs, err := makeTaAttrs(id, akPub)
taAttrs, err := makeTaAttrs(id, akPub, avk.Environment)
if err != nil {
return nil, fmt.Errorf("failed to create trust anchor raw public key: %w", err)
}
Expand All @@ -95,22 +95,34 @@ func (o CorimExtractor) TaExtractor(
return ta, nil
}

func makeRefValAttrs(class string, pcr uint64, digest swid.HashEntry) (json.RawMessage, error) {
func makeRefValAttrs(class string, pcr uint64, digest swid.HashEntry, env comid.Environment) (json.RawMessage, error) {

var attrs = map[string]interface{}{
"parsec-tpm.class-id": class,
"parsec-tpm.pcr": pcr,
"parsec-tpm.digest": digest.HashValue,
"parsec-tpm.alg-id": digest.HashAlgID,
}

// Extract optional vendor and model from environment.class
// Following CoRIM specification - vendor/model are stored in environment, not key parameters
if env.Class != nil {
if env.Class.Vendor != nil {
attrs["parsec-tpm.vendor"] = string(*env.Class.Vendor)
}
if env.Class.Model != nil {
attrs["parsec-tpm.model"] = string(*env.Class.Model)
}
}

data, err := json.Marshal(attrs)
if err != nil {
return nil, fmt.Errorf("unable to marshal reference value attributes: %w", err)
}
return data, nil
}

func makeTaAttrs(id ID, key *comid.CryptoKey) (json.RawMessage, error) {
func makeTaAttrs(id ID, key *comid.CryptoKey, env comid.Environment) (json.RawMessage, error) {
if id.instance == nil {
return nil, errors.New("instance not found in ID")
}
Expand All @@ -121,6 +133,17 @@ func makeTaAttrs(id ID, key *comid.CryptoKey) (json.RawMessage, error) {
"parsec-tpm.ak-pub": key.String(),
}

// Extract optional vendor and model from environment.class
// Following CoRIM specification - vendor/model are stored in environment, not key parameters
if env.Class != nil {
if env.Class.Vendor != nil {
attrs["parsec-tpm.vendor"] = string(*env.Class.Vendor)
}
if env.Class.Model != nil {
attrs["parsec-tpm.model"] = string(*env.Class.Model)
}
}

data, err := json.Marshal(attrs)
if err != nil {
return nil, fmt.Errorf("unable to marshal trust anchor attributes: %w", err)
Expand Down
8 changes: 8 additions & 0 deletions scheme/parsec-tpm/evidence_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ type SwAttr struct {
ClassID *string `json:"parsec-tpm.class-id"`
Digest *[]byte `json:"parsec-tpm.digest"`
PCR *uint `json:"parsec-tpm.pcr"`
// Optional vendor information for the TPM
Vendor *string `json:"parsec-tpm.vendor,omitempty"`
// Optional model information for the TPM
Model *string `json:"parsec-tpm.model,omitempty"`
}

type Endorsements struct {
Expand All @@ -38,6 +42,10 @@ type TaAttr struct {
VerifKey *string `json:"parsec-tpm.ak-pub"`
ClassID *string `json:"parsec-tpm.class-id"`
InstID *string `json:"parsec-tpm.instance-id"`
// Optional vendor information for the TPM
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is not just the Trust Anchor but the supply chain for SwAttr (line 24) which also has class, needs the Optional Vendor and Model information

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Vendor *string `json:"parsec-tpm.vendor,omitempty"`
// Optional model information for the TPM
Model *string `json:"parsec-tpm.model,omitempty"`
}

type TaEndorsements struct {
Expand Down