1*3f8e9d82SAndroid Build Coastguard Worker# DICE chain policies 2*3f8e9d82SAndroid Build Coastguard Worker 3*3f8e9d82SAndroid Build Coastguard WorkerDICE policy is the mechanism for specifying constraints on a DICE chain. A DICE chain policy 4*3f8e9d82SAndroid Build Coastguard Workerverifier takes a policy and a DICE chain, and returns whether the DICE chain meets the constraints 5*3f8e9d82SAndroid Build Coastguard Workerset out in the policy. 6*3f8e9d82SAndroid Build Coastguard Worker 7*3f8e9d82SAndroid Build Coastguard Worker## Navigating this project 8*3f8e9d82SAndroid Build Coastguard Worker 9*3f8e9d82SAndroid Build Coastguard WorkerThis directory exports Rust crates for matching Dice Chains against Dice Policies as well building 10*3f8e9d82SAndroid Build Coastguard WorkerDice Policies. 11*3f8e9d82SAndroid Build Coastguard Worker 12*3f8e9d82SAndroid Build Coastguard Worker1. [./building/](https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/dice_policy/building/src/lib.rs): 13*3f8e9d82SAndroid Build Coastguard Worker Supports constructing Dice Policies on a Dice chains, enabling various ways to specify the 14*3f8e9d82SAndroid Build Coastguard Worker constraints. 15*3f8e9d82SAndroid Build Coastguard Worker1. [./src/](https://cs.android.com/android/platform/superproject/main/+/main:system/secretkeeper/dice_policy/src/lib.rs): 16*3f8e9d82SAndroid Build Coastguard Worker Supports matching Dice Chains against Dice Policies. 17*3f8e9d82SAndroid Build Coastguard Worker 18*3f8e9d82SAndroid Build Coastguard Worker## DICE chain 19*3f8e9d82SAndroid Build Coastguard Worker 20*3f8e9d82SAndroid Build Coastguard Worker[Open Profile for DICE][open_dice_spec] is designed to be layered. The certificate generated by the 21*3f8e9d82SAndroid Build Coastguard Workernext DICE layer can chain to the certificate generated by the previous DICE layer. This chain of 22*3f8e9d82SAndroid Build Coastguard Workercertificates has been termed as DICE chain in context of this documentation. 23*3f8e9d82SAndroid Build Coastguard Worker 24*3f8e9d82SAndroid Build Coastguard WorkerNote that the libraries in this directory are implemented to work with DICE chains following tighter 25*3f8e9d82SAndroid Build Coastguard Workerconstraints of [Android Profile for DICE chains][android_dice_spec], although the concept is 26*3f8e9d82SAndroid Build Coastguard Workerapplicable to any DICE chain profiles. 27*3f8e9d82SAndroid Build Coastguard Worker 28*3f8e9d82SAndroid Build Coastguard Worker## Rollback protection and DICE 29*3f8e9d82SAndroid Build Coastguard Worker 30*3f8e9d82SAndroid Build Coastguard WorkerEach component in a DICE chain receives a secret, the “attestation CDI”, which depends on all of the 31*3f8e9d82SAndroid Build Coastguard Workerinformation in the chain up to that point; this secret is used to protect a signing keypair that the 32*3f8e9d82SAndroid Build Coastguard Workercomponent uses to sign DICE assertions. This secret isn’t useful for protecting component data, 33*3f8e9d82SAndroid Build Coastguard Workersince it changes whenever the component or any part of the boot chain is updated. Some DICE 34*3f8e9d82SAndroid Build Coastguard Workerimplementations provide a “sealing CDI” which depends only on stable information such as component 35*3f8e9d82SAndroid Build Coastguard Workernames and the public keys used to sign components. However, this provides no protection against 36*3f8e9d82SAndroid Build Coastguard Workerattacks based on version rollback because it doesn't include any version information. 37*3f8e9d82SAndroid Build Coastguard Worker 38*3f8e9d82SAndroid Build Coastguard WorkerTo resolve this, we change the sealing operation to take an additional input called a “policy”. 39*3f8e9d82SAndroid Build Coastguard WorkerUnsealing is only permitted if the DICE chain for the component requesting unsealing complies with 40*3f8e9d82SAndroid Build Coastguard Workerthe policy given when the message was sealed. A typical policy will assert things like: 41*3f8e9d82SAndroid Build Coastguard Worker 42*3f8e9d82SAndroid Build Coastguard Worker1. UDS_Public must have a specific value 43*3f8e9d82SAndroid Build Coastguard Worker1. The DICE chain must be exactly five certificates long 44*3f8e9d82SAndroid Build Coastguard Worker1. authorityHash in the third certificate must have this value 45*3f8e9d82SAndroid Build Coastguard Worker1. securityVersion in the fourth certificate must be an integer greater than 8 46*3f8e9d82SAndroid Build Coastguard Worker 47*3f8e9d82SAndroid Build Coastguard WorkerAt sealing time, the component performing the sealing must compose a policy that meets its needs: 48*3f8e9d82SAndroid Build Coastguard Workerspecific enough that its secrets are protected from attackers, but general enough that future 49*3f8e9d82SAndroid Build Coastguard Workerversions of the component can unseal them. 50*3f8e9d82SAndroid Build Coastguard Worker 51*3f8e9d82SAndroid Build Coastguard WorkerProjects such as [Secretkeeper][sk_project] use policy-based protection; they are the foundation to 52*3f8e9d82SAndroid Build Coastguard Workerproviding rollback-secure identities and secrets to VMs and Authgraph participants. 53*3f8e9d82SAndroid Build Coastguard Worker 54*3f8e9d82SAndroid Build Coastguard Worker## Example DICE policy 55*3f8e9d82SAndroid Build Coastguard Worker 56*3f8e9d82SAndroid Build Coastguard WorkerBelow is a highly simplified DICE policy on DICE chains specifying (among other things) that a 57*3f8e9d82SAndroid Build Coastguard Workerparticular DiceChainEntry need to have auth_hash value exactly equal to specified one and 58*3f8e9d82SAndroid Build Coastguard Workersecurity_version >= 5. 59*3f8e9d82SAndroid Build Coastguard Worker 60*3f8e9d82SAndroid Build Coastguard Worker``` 61*3f8e9d82SAndroid Build Coastguard Worker DicePolicy { 62*3f8e9d82SAndroid Build Coastguard Worker version: 1, 63*3f8e9d82SAndroid Build Coastguard Worker node_constraint_list: 64*3f8e9d82SAndroid Build Coastguard Worker <!-- ExplicitKeyDiceCertChain version --> 65*3f8e9d82SAndroid Build Coastguard Worker NodeConstraints [ 66*3f8e9d82SAndroid Build Coastguard Worker Constraint { 67*3f8e9d82SAndroid Build Coastguard Worker type=ExactMatch, 68*3f8e9d82SAndroid Build Coastguard Worker path=[] 69*3f8e9d82SAndroid Build Coastguard Worker value="1", 70*3f8e9d82SAndroid Build Coastguard Worker }, 71*3f8e9d82SAndroid Build Coastguard Worker ] 72*3f8e9d82SAndroid Build Coastguard Worker node_constraint_list: 73*3f8e9d82SAndroid Build Coastguard Worker <!-- Constraints on the DiceCertChainInitialPayload --> 74*3f8e9d82SAndroid Build Coastguard Worker NodeConstraints [ 75*3f8e9d82SAndroid Build Coastguard Worker Constraint { 76*3f8e9d82SAndroid Build Coastguard Worker type=ExactMatch, 77*3f8e9d82SAndroid Build Coastguard Worker path=[] 78*3f8e9d82SAndroid Build Coastguard Worker value="a50101032704810220062158203e85e5727555e51ee7f335948ebbbd741e1dca499c97397706d3c86e8bd733f9", 79*3f8e9d82SAndroid Build Coastguard Worker }, 80*3f8e9d82SAndroid Build Coastguard Worker ] 81*3f8e9d82SAndroid Build Coastguard Worker node_constraint_list: 82*3f8e9d82SAndroid Build Coastguard Worker <!-- Constraints on a DiceChainEntry --> 83*3f8e9d82SAndroid Build Coastguard Worker NodeConstraints [ 84*3f8e9d82SAndroid Build Coastguard Worker Constraint { 85*3f8e9d82SAndroid Build Coastguard Worker type=ExactMatch, 86*3f8e9d82SAndroid Build Coastguard Worker path=[authority_hash] 87*3f8e9d82SAndroid Build Coastguard Worker value="04255d605f5c450df29a6e993003b8d6e199711bf844fab531791c37684e1dc0247468f880203e44b143d29cfc129e770ade2924ff2efac710d573d4c6df629f", 88*3f8e9d82SAndroid Build Coastguard Worker }, 89*3f8e9d82SAndroid Build Coastguard Worker Constraint { 90*3f8e9d82SAndroid Build Coastguard Worker type=ExactMatch, 91*3f8e9d82SAndroid Build Coastguard Worker path=[mode] 92*3f8e9d82SAndroid Build Coastguard Worker value="01", 93*3f8e9d82SAndroid Build Coastguard Worker }, 94*3f8e9d82SAndroid Build Coastguard Worker Constraint { 95*3f8e9d82SAndroid Build Coastguard Worker type=GreaterOrEqual, 96*3f8e9d82SAndroid Build Coastguard Worker path=[config_desc,security_version] 97*3f8e9d82SAndroid Build Coastguard Worker value="5", 98*3f8e9d82SAndroid Build Coastguard Worker }, 99*3f8e9d82SAndroid Build Coastguard Worker ] 100*3f8e9d82SAndroid Build Coastguard Worker } 101*3f8e9d82SAndroid Build Coastguard Worker``` 102*3f8e9d82SAndroid Build Coastguard Worker 103*3f8e9d82SAndroid Build Coastguard Worker## CBOR representation 104*3f8e9d82SAndroid Build Coastguard Worker 105*3f8e9d82SAndroid Build Coastguard Worker### Explicit-key DiceCertChain format 106*3f8e9d82SAndroid Build Coastguard Worker 107*3f8e9d82SAndroid Build Coastguard WorkerIn the [Android Profile for DICE][android_dice_spec] `DiceCertChain` format specification, the 108*3f8e9d82SAndroid Build Coastguard Worker`subjectPublicKey` in a certificate which describes the signing key of the next party in the chain 109*3f8e9d82SAndroid Build Coastguard Workeris specified as a `.bstr cbor`: a binary string containing CBOR data. This makes it very easy to 110*3f8e9d82SAndroid Build Coastguard Workerdefine eg “the hash of the public key” or compare two keys for identity. 111*3f8e9d82SAndroid Build Coastguard Worker 112*3f8e9d82SAndroid Build Coastguard WorkerHowever, this is not true of the first public key in the chain, UDS_Public, derived from the Unique 113*3f8e9d82SAndroid Build Coastguard WorkerDevice Secret (UDS). For example, it means that the DICE chain verifiers have to resort custom look ups 114*3f8e9d82SAndroid Build Coastguard Workerlook up to converted from COSE_Key form to an algorithm-specific non-COSE format for lookup. 115*3f8e9d82SAndroid Build Coastguard Worker 116*3f8e9d82SAndroid Build Coastguard WorkerThe policy comparison code should stay as simple and predictable as possible, algorithm specific 117*3f8e9d82SAndroid Build Coastguard Workerlookups should be avoided. So instead we specify a new DICE chain format which is slightly different 118*3f8e9d82SAndroid Build Coastguard Workerto the DiceCertChain format and addresses this issue. 119*3f8e9d82SAndroid Build Coastguard Worker 120*3f8e9d82SAndroid Build Coastguard WorkerWe don’t anticipate that devices will switch to using this new chain from the moment they boot - 121*3f8e9d82SAndroid Build Coastguard Workerthat would be a disruptive change. Instead, we anticipate that components will receive their DICE 122*3f8e9d82SAndroid Build Coastguard Workerchain in DiceCertChain format, and convert it to “ExplicitKeyDiceCertChain” format before presenting 123*3f8e9d82SAndroid Build Coastguard Workerit to any other party in any context where policy comparisons are relevant. This conversion must be 124*3f8e9d82SAndroid Build Coastguard Workerdeterministic so that the UDS_Public bstr presented on the device never changes, or policy comparisons 125*3f8e9d82SAndroid Build Coastguard Workerwill fail; CBOR canonicalization can be used to this end. 126*3f8e9d82SAndroid Build Coastguard Worker 127*3f8e9d82SAndroid Build Coastguard Worker``` 128*3f8e9d82SAndroid Build Coastguard WorkerExplicitKeyDiceCertChain = [ 129*3f8e9d82SAndroid Build Coastguard Worker 1, ; version, hopefully will never change 130*3f8e9d82SAndroid Build Coastguard Worker DiceCertChainInitialPayload, 131*3f8e9d82SAndroid Build Coastguard Worker * DiceChainEntry 132*3f8e9d82SAndroid Build Coastguard Worker] 133*3f8e9d82SAndroid Build Coastguard Worker 134*3f8e9d82SAndroid Build Coastguard Worker; Encoded in accordance with Core Deterministic Encoding Requirements [RFC 8949 s4.2.1] 135*3f8e9d82SAndroid Build Coastguard WorkerDiceCertChainInitialPayload = bstr .cbor PubKeyEd25519 136*3f8e9d82SAndroid Build Coastguard Worker / bstr .cbor PubKeyECDSA256 137*3f8e9d82SAndroid Build Coastguard Worker / bstr .cbor PubKeyECDSA384 ; subjectPublicKey 138*3f8e9d82SAndroid Build Coastguard Worker``` 139*3f8e9d82SAndroid Build Coastguard Worker 140*3f8e9d82SAndroid Build Coastguard Worker## DICE policy specification 141*3f8e9d82SAndroid Build Coastguard Worker 142*3f8e9d82SAndroid Build Coastguard WorkerThe spec is extracted from [DicePolicy.cddl][dicepolicycddl] 143*3f8e9d82SAndroid Build Coastguard Worker 144*3f8e9d82SAndroid Build Coastguard Worker``` 145*3f8e9d82SAndroid Build Coastguard WorkerdicePolicy = [ 146*3f8e9d82SAndroid Build Coastguard Worker 1, ; version, hopefully will never change 147*3f8e9d82SAndroid Build Coastguard Worker + nodeConstraintList 148*3f8e9d82SAndroid Build Coastguard Worker] 149*3f8e9d82SAndroid Build Coastguard Worker 150*3f8e9d82SAndroid Build Coastguard WorkernodeConstraintList = [ 151*3f8e9d82SAndroid Build Coastguard Worker * nodeConstraint 152*3f8e9d82SAndroid Build Coastguard Worker] 153*3f8e9d82SAndroid Build Coastguard Worker 154*3f8e9d82SAndroid Build Coastguard Worker; We may add a hashConstraint item later 155*3f8e9d82SAndroid Build Coastguard WorkernodeConstraint = exactMatchConstraint / geConstraint 156*3f8e9d82SAndroid Build Coastguard Worker 157*3f8e9d82SAndroid Build Coastguard WorkerexactMatchConstraint = [1, keySpec, value] 158*3f8e9d82SAndroid Build Coastguard WorkergeConstraint = [2, keySpec, int] 159*3f8e9d82SAndroid Build Coastguard Worker 160*3f8e9d82SAndroid Build Coastguard WorkerkeySpec = [value+] 161*3f8e9d82SAndroid Build Coastguard Worker 162*3f8e9d82SAndroid Build Coastguard Workervalue = bool / int / tstr / bstr 163*3f8e9d82SAndroid Build Coastguard Worker``` 164*3f8e9d82SAndroid Build Coastguard Worker 165*3f8e9d82SAndroid Build Coastguard Worker[android_dice_spec]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl 166*3f8e9d82SAndroid Build Coastguard Worker[dicepolicycddl]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/authgraph/aidl/android/hardware/security/authgraph/DicePolicy.cddl 167*3f8e9d82SAndroid Build Coastguard Worker[open_dice_spec]: https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#Layering-Details 168*3f8e9d82SAndroid Build Coastguard Worker[sk_project]: https://android.git.corp.google.com/platform/system/secretkeeper/ 169