diff --git a/scheme/parsec-tpm/README.md b/scheme/parsec-tpm/README.md index 935127a5..368c1717 100644 --- a/scheme/parsec-tpm/README.md +++ b/scheme/parsec-tpm/README.md @@ -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) + +### 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==" + }] + } + ] +} +``` diff --git a/scheme/parsec-tpm/corim_extractor.go b/scheme/parsec-tpm/corim_extractor.go index 10fb8b76..9a2b236f 100644 --- a/scheme/parsec-tpm/corim_extractor.go +++ b/scheme/parsec-tpm/corim_extractor.go @@ -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) } } @@ -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) } @@ -95,7 +95,7 @@ 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, @@ -103,6 +103,18 @@ func makeRefValAttrs(class string, pcr uint64, digest swid.HashEntry) (json.RawM "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) @@ -110,7 +122,7 @@ func makeRefValAttrs(class string, pcr uint64, digest swid.HashEntry) (json.RawM 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") } @@ -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) diff --git a/scheme/parsec-tpm/evidence_handler.go b/scheme/parsec-tpm/evidence_handler.go index c7f04f58..e542df73 100644 --- a/scheme/parsec-tpm/evidence_handler.go +++ b/scheme/parsec-tpm/evidence_handler.go @@ -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 { @@ -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 + Vendor *string `json:"parsec-tpm.vendor,omitempty"` + // Optional model information for the TPM + Model *string `json:"parsec-tpm.model,omitempty"` } type TaEndorsements struct {