-
Notifications
You must be signed in to change notification settings - Fork 7
Composite device description using domain membership triples
Groups are intended to simplify explaining the shape of Attesters and the composition of corresponding Evidence to Verifiers. A Verifier must be able to understand what Target Environments an Attesting Environment is intended to generate Evidence about. A Group bundles all Target Environments that a Verifier should expect an Attesting Environment to generate Evidence about. Inversely, Evidence about Target Environments not included in a Group that is associated with an Attesting Environment must be ignored. The following solution proposal for Groups is based on domain membership triples.
We model a composite device with a lead attester and two sub-attesters.
Each sub-attester produces signed evidence about itself that the lead attester collects, wraps and counter-signs.
We model a firmware life-cycle management scenario for one of the sub-attesters, comprising firmware update and a security incident.
The arrangement in terms of composition and target environments is as follows:
flowchart TD
Domain1["PSA sub-attester"]
subgraph Attester1[" "]
TEx["BL"]
TEy["TF-M"]
end
Domain2["GPU sub-attester"]
subgraph Attester2[" "]
TE2["GPU FW"]
end
Domain1 --> Attester1
Domain2 --> Attester2
Domain0["Lead Attester"]
subgraph DomainComp[" "]
Domain1
Domain2
end
Domain0 --> DomainComp
In order to model recursive composition, the domain-membership-triple-record
is extended to allow the domain name to be expressed as an environment.
domain-membership-triple-record = [
$domain-type-choice / environment-map
[ + environment-map ]
]
Semantically, a domain describes the target environments that constitute a given attester. The domain has a name which is either an environment or a plain identifier. The environment form should be used unless the domain (attester) is never expected to be found in CoMID triples.
To model revocation of previously provisioned reference values, the x-reference-triple-record
is introduced with the following syntax:
x-reference-triple-record = [
environment-map
measurement-map
$refval-x-reason
]
$refval-x-reason /= obsolete
$refval-x-reason /= insecure
; other reasons
obsolete = 0
insecure = 1
The PSA sub-attester has two firmware components: boot-loader and secure partition manager. The GPU sub-attester has one firmware component. Each component is assigned a unique identifier that is guaranteed to remain stable for the lifetime of the component -- i.e., it will not change across firmware updates, security related events, etc. As long as the target environments in the domain description don't change, when target measurements are updated the overarching domain remains fixed.
The PSA sub-attester is modelled using a domain membership triple.
The name of the domain is given as an environment with class-id
set to the PSA Implementation ID of the sub-attester.
Naming the domain using the environment syntax allows recursive composition.
The domain elements are the target environments associated with the FW components (i.e., BL
and TF-M
).
graph TD
PSA["class-id=acme-implementation-id-000000001\nmodel=PSA RoT X"]
BL["class-id=57057D65-...\nmodel=BL"]
TF-M["class-id=993A383A-...\nmodel=TF-M"]
subgraph PSA-name["PSA sub-attester"]
PSA
end
subgraph PSA-targets["Target Environments"]
BL
TF-M
end
PSA-name --> PSA-targets
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : / tagged-impl-id-type / 600(
h'61636d652d696d706c656d656e746174696f6e2d69642d303030303030303031'
),
/ comid.vendor / 1 : "ACME Ltd.",
/ comid.model / 2 : "PSA RoT X"
}
},
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'57057d658db1403b9e387f9f0fa604cf'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "BL"
}
},
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'993a383a41134c999c333a13414a546d'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "TF-M"
}
}
]
]
The initial set of reference values is configured with the following reference-value triples:
- boot-loader (
BL
), version 1.0.0:
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'57057d658db1403b9e387f9f0fa604cf'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "BL"
}
},
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.version / 0 : {
/ version / 0: "1.0.0"
},
/ comid.digests / 2 : [
[
/ hash-alg-id / 1, / sha256 /
/ hash-value / h'44aa336af4cb14a879432e53dd6571c7fa9bccafb75f488259262d6ea3a4d91b'
]
]
}
},
],
- secure partition manager (
TF-M
), version 1.0.0:
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'993a383a41134c999c333a13414a546d'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "TF-M"
}
},
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.version / 0 : {
/version / 0: "1.0.0"
},
/ comid.digests / 2 : [
[
/ hash-alg-id / 1, / sha256 /
/ hash-value / h'9c49c3f7b15f62db77deb9a5fa5a21e516edb15bb7b2214654695a59ac492d9e'
]
]
}
}
]
Visually:
graph TD
PSA["class-id=acme-implementation-id-000000001\nmodel=PSA RoT X"]
BL["class-id=57057D65-...\nmodel=BL"]
TF-M["class-id=993A383A-...\nmodel=TF-M"]
subgraph PSA-name["PSA sub-attester"]
PSA
end
subgraph PSA-targets["Target Environments"]
BL
TF-M
end
BL_M1["version=1.0.0\ndigest=44aa336a..."]
TF-M_M1["version=1.0.0\ndigest=9c49c3f7..."]
PSA-name --- PSA-targets
BL --> BL_M1
TF-M --> TF-M_M1
Each raw public key (RPK) associated to a PSA device is individually provisioned in the verifier.
For each RPK, we use an attestation key triple.
The subject is an environment with its own instance-id
, and class-id
equal to the PSA domain's class-id
.
Note that the linkage between the PSA domain and each PSA instance is implicit in the environment's hierarchical naming scheme.
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : / tagged-impl-id-type / 600(
h'61636d652d696d706c656d656e746174696f6e2d69642d303030303030303031'
),
/ comid.vendor / 1 : "ACME Ltd.",
/ comid.model / 2 : "PSA RoT X"
},
/ comid.instance / 1 : / tagged-ueid-type / 550(
h'014ca3e4f50bf248c39787020d68ffd05c88767751bf2645ca923f57a98becd296'
)
},
[
/ tagged-pkix-base64-key-type /
#6.554("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETl4iCZ47zrRbRG0TVf0dw7VFlHtv18HInYhnmMNybo+A1wuECyVqrDSmLt4QQzZPBECV8ANHS5HgGCCSr7E/Lg==")
]
],
[
/ ... another RPK /
]
Visually:
graph TD
PSA["class-id=acme-implementation-id-000000001\nmodel=PSA RoT X"]
subgraph PSA-name["PSA sub-attester"]
PSA
end
PSA-inst["class-id=acme-implementation-id-000000001\ninstance-id=EUID(014ca3e4...)"]
PSA-inst_K1["pkey=MFkwEwYHKoZI..."]
PSA-name -.- PSA-inst
PSA-inst --> PSA-inst_K1
Putting all the pieces together, this is what we have:
graph TD
PSA["class-id=acme-implementation-id-000000001\nmodel=PSA RoT X"]
BL["class-id=57057D65-...\nmodel=BL"]
TF-M["class-id=993A383A-...\nmodel=TF-M"]
subgraph PSA-name["PSA sub-attester"]
PSA
end
subgraph PSA-targets[" "]
BL
TF-M
end
BL_M1["version=1.0.0\ndigest=44aa336a..."]
TF-M_M1["version=1.0.0\ndigest=9c49c3f7..."]
PSA-name --- PSA-targets
BL --> BL_M1
TF-M --> TF-M_M1
PSA-inst["class-id=acme-implementation-id-000000001\ninstance-id=EUID(014ca3e4...)"]
PSA-inst_K1["pkey=MFkwEwYHKoZI..."]
PSA-name -.- PSA-inst
PSA-inst --> PSA-inst_K1
The GPU sub-attester has one firmware component (GPU-FW
).
Its reference values are initially configured with the following reference-value triple:
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : / 37(h'0b27f2c351a04b338368d25f9021c1c2'),
/ comid.vendor / 1 : "GPU Manufacturer X",
/ comid.model / 2 : "GPU-FW"
}
},
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.version / 0 : {
/ version / 0: "1.0.0"
},
/ comid.digests / 2 : [
[
/ hash-alg-id / 1, / sha256 /
/ hash-value / h'34b03909f183581749721835ea2473e9377647da3cf7c7169b9b78e77ec260a2'
]
]
}
},
]
Similar to the PSA sub-attester, the GPU sub-attester is modelled using a domain membership triple.
The name of the domain is given as an environment with class-id
set to the unique identifier for the GPU model.
The domain element is the target environment associated with the FW component (i.e., GPU-FW
).
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'c77b8c870b4a44058b024e5388ffd8e6'),
/ comid.vendor / 1 : "GPUs Inc.",
/ comid.model / 2 : "Fancy 2.0"
}
},
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : / 37(h'0b27f2c351a04b338368d25f9021c1c2'),
/ comid.vendor / 1 : "GPU Manufacturer X",
/ comid.model / 2 : "GPU-FW"
}
}
]
]
Each GPU has its own key-pair certified by the GPU vendor's CA. The CA certificate chain is provided in an attestation key triple. The subject is the GPU domain name environment.
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'c77b8c870b4a44058b024e5388ffd8e6'),
/ comid.vendor / 1 : "GPUs Inc.",
/ comid.model / 2 : "Fancy 2.0"
}
},
/ root & intermediate CAs certs / [
#6.555("MIICYzCCAcygAwIBAgIBADANBgkq..."),
#6.555("MIIF2zCCBMOgAwIBAgIQMj8Hjgwe..."),
]
]
The lead attester aggregates the two sub-attesters (PSA and GPU) via their domain "names" (i.e., environments).
For simplicity, there are no reference values associated with the lead attester.
The domain membership triple for the lead attester is as under
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'4304ada1ea71408dbafb27b4310f1181'),
/ comid.vendor / 1 : "Capi Attestatori SpA",
/ comid.model / 2 : "Lead Attester 1.0"
}
},
[
/ PSA / {
/ comid.class / 0 : {
/ comid.class-id / 0 : / tagged-impl-id-type / 600(
h'61636d652d696d706c656d656e746174696f6e2d69642d303030303030303031'
),
/ comid.vendor / 1 : "ACME Ltd.",
/ comid.model / 2 : "PSA RoT X"
}
},
/ GPU / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'c77b8c870b4a44058b024e5388ffd8e6'),
/ comid.vendor / 1 : "GPUs Inc.",
/ comid.model / 2 : "Fancy 2.0"
}
}
]
]
Similar to the GPU arrangement, the lead attester has its own key-pair certified by the lead attester vendor's CA. The CA certificate chain is provided in an attestation key triple. The subject is the lead attester domain name environment.
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'4304ada1ea71408dbafb27b4310f1181'),
/ comid.vendor / 1 : "Capi Attestatori SpA",
/ comid.model / 2 : "Lead Attester 1.0"
}
},
/ root & intermediate CAs certs / [
#6.555("MIIKcQIBAzCCCi0GCSqGSIb3DQEH..."),
#6.555("MIIB0TCCATqgAwIBAgIQUq+2SdEk...")
]
]
The example below models the lifecycle of the boot-loader firmware component of the PSA RoT.
The ideas below are applicable to reference values updates of any other component.
At time t1, BL
gets updated to a new version "1.0.1" using the following reference value triple:
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'57057d658db1403b9e387f9f0fa604cf'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "BL"
}
},
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.version / 0 : {
/ version / 0: "1.0.1"
},
/ comid.digests / 2 : [
[
/ hash-alg-id / 1, / sha256 /
/ hash-value / h'a62506de002fc1765adff7efa79402504ae68bdd78c840bcac6fdbbfdef0cb82'
]
]
}
},
]
(Note that the above makes the measurement map the grouping boundary bundling version and digest together inextricably.)
At time t2, a security vulnerability is discovered in BL
version "1.0.1". The vulnerability does not affect version "1.0.0".
BL
is patched to a new version "1.0.2" using the following reference value triple:
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'57057d658db1403b9e387f9f0fa604cf'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "BL"
}
},
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.version / 0 : {
/ version / 0: "1.0.2"
},
/ comid.digests / 2 : [
[
/ hash-alg-id / 1, / sha256 /
/ hash-value / h'4d311aace8a34760011d2a7625c9c02f48707a06403f62f27cdf891651e3d79d'
]
]
}
},
]
Simultaneously, an x-reference-triple-record
is issued to mark version "1.0.1" as unsuitable with reason code "insecure":
[
/ environment-map / {
/ comid.class / 0 : {
/ comid.class-id / 0 : 37(h'57057d658db1403b9e387f9f0fa604cf'),
/ comid.vendor / 1 : "FW Manufacturer X",
/ comid.model / 2 : "BL"
}
},
/ measurement-map / {
/ comid.mval / 1 : {
/ comid.version / 0 : {
/ version / 0: "1.0.1"
},
/ comid.digests / 2 : [
[
/ hash-alg-id / 1, / sha256 /
/ hash-value / h'a62506de002fc1765adff7efa79402504ae68bdd78c840bcac6fdbbfdef0cb82'
]
]
}
},
1 / insecure /
]
At this point the verifier accepts both BL
"1.0.0" and "1.0.2", but not "1.0.1".
The complete update story is illustrated below:
flowchart TD
BL["BL"]
subgraph TimeT2["t2"]
AE4["1.0.0"]
AE5["1.0.1"]
style AE5 fill:#bbf,stroke:#f77,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
AE6["1.0.2"]
end
subgraph TimeT1["t1"]
AE2["1.0.0"]
AE3["1.0.1"]
end
subgraph TimeT0["t0"]
AE1["1.0.0"]
end
BL --> TimeT0
BL --> TimeT1
BL --> TimeT2
It is not possible to limit the acceptable combinations: all possible cross-products are acceptable.
Suppose TF-M
goes through a similar update cycle as BL
.
Using the semantics above it is not possible to express things like: BL
"1.0.0" is acceptable only with TF-M
"1.0.0" and not with TF-M
"1.0.1".