Unleashing Enclave from being tied to a CPU -  using KDS in Conclave

Conclave Dec 07 2021 By: Sneha Damle
Comments

0 Comments

Views

698 Views

Unleashing Enclave from being tied to a CPU -  using KDS in Conclave
Sneha Damle
Sneha Damle Blockchain Development (Corda Open Source)
Share this post:
Copied

In my previous blog, I spoke about why we need KDS – Key Derivation Service. Now in this blog lets us dive into the technical details of KDS. I will divide my blog into three parts:

  1. Let us talk from a high level about the need for KDS.
  2. We will talk a bit about the KDS service itself.
  3. We will see how can we retrieve a key from KDS in our Conclave Application. 

Part 1: Need for KDS

There will be scenarios where you want to move to another physical machine(the cloud provider can select a different physical system when redeploying the VM). There can be a situation where the CPU breaks down, and I want to move my enclave data onto a different physical system. To start the computation from where you left on this new system, you must access the previous enclave data/state. 

Hence the need for enclave data persistence arises. Persisting enclave data to external storage allows us to migrate this data to different physical storage and start the enclave processing from where we last left off. By default, Conclave uses the sealing key(bound to a specific CPU) for persisting enclave data. Persistent data must be encrypted and stored so that the enclave data is not attached to one particular physical system. That’s where we use KDS, which is a Key Derivation Service. The application enclave can request a stable key from this service and can use this key to encrypt the enclave data before persisting to external storage.

Part 2: How does the KDS work?

KDS uses Key specifications given by enclave to derive a key from the master key
KDS uses Key specifications given by enclave to derive a key from the master key

KDS derives the key from a master key. This master key can be a key stored in an HSM, Azure KMS, or it can be a hardcoded debug key. For the 1.2 release, there is only one master key that KDS provides, and this is hardcoded in KDS and is called the DEBUG key.

Conclave KDS is itself deployed as an enclave, making it easy for both your application and Conclave KDS to remote attest to each other before talking to each other. 

The key derivation logic of KDS depends on the parameters provided by your application enclave. As an enclave developer, you are in complete control of which all enclaves can access this key. You can enforce constraints and make only a specific enclave(having a particular code hash) access this key or allow all the enclaves signed by a particular entity/organisation access to this key. These parameters are the key specification that you can see in the above diagram. Your Enclave can also specify the type of master key you wish the key to be derived from. As mentioned, for this release, we only have the option of using a hardcoded DEBUG key.

How do I enforce constraints to allow specific enclaves access to the key?

To ensure that only an enclave with a specific hash value can access this key, use the below key specification. For this scenario, upgrading the Enclave will change the enclave code hash, and hence the new Enclave will not be able to use the old persisted data.


PolicyConstraint keyConstraint = new PolicyConstraint().useOwnCodeHash();

To allow any enclave signed by a particular entity to access this key, use the below key specification. Upgrading the Enclave is also possible, and the new version of Enclave can still access the old persisted data.


PolicyConstraint keyConstraint = new PolicyConstraint().useOwnCodeSignerAndProductID()

PolicyConstraint is a wrapper around our usual EnclaveConstraint class. You can even enforce a security level, i.e. you can say that any enclave which wants to access this key must have the specified security (SECURE/INSECURE/STALE). Read more here.


PolicyConstraint keyConstraint = new PolicyConstraint().getEnclaveConstraint().setMinSecurityLevel(EnclaveSecurityInfo.Summary.SECURE)

There are a few more specifications that you can enforce; you can read about them here.

You have to define this key specification inside your application enclave code itself. When you build your Enclave, you get an enclave code hash. Changing the key specification will change this Enclave’s code hash. Each time an enclave requests access to a key from KDS, as long as the parameters are the same, the same stable key will be returned by the KDS.

Steps to retrieve key from KDS
Steps to retrieve key from KDS

The above diagram shows a typical flow when an application enclave requests a key for use from the KDS. The application enclave sends its remote attestation object (containing code hash, codesigner key hash, tells if the Enclave is patched with the latest security updates, etc.), with the key specification to the KDS. KDS verifies the remote attestation object and the key specification. If the key specification matches with the enclave details(give key access to any enclave having specific code hash/or check if the Enclave is signed by a particular signer as mentioned in the key specification), a key is derived by KDS and is released to the Enclave. This key is encrypted using the public key received from Enclave’s remote attestation object. Hence only the Enclave can access this key. The Enclave first verifies the remote attestation object of the KDS. KDS constraint can also be added to the key specification at the time of building the Enclave. Usually, the code hash of KDS is added as the KDS constraint, as we know at the time of building our application what is the code hash of the deployed KDS service onto the Enclave. This can be added using the kdsEnclaveConstraint parameter as shown below (part 3).

Once the Enclave verifies KDS’s remote attestation object, it can decrypt the key and use it to persist any of its computations.

Part 3: Configuring KDS for the Conclave application

Use the below steps to write and start a conclave application using KDS.

Let us add the key specification and KDS enclave constraint to our application enclave. You can do this by overriding kdsConfig method in the Enclave class.


conclave {
...
     kds {
         kdsEnclaveConstraint = "S:4924CA3A9C8241A3C0AA1A24A407AA86401D2B79FA9FF84932DA798A942166D4 PROD:1 SEC:STALE"
         keySpec {
             masterKeyType = "debug"
             policyConstraint {
                 constraint = ""
                 useOwnCodeHash = (true|false)                 // Optional
                 useOwnCodeSignerAndProductID = (true|false)   // Optional
             }
         }
     }
...
 }

If you are using the web host then you can specify the KDS connection parameters on the command line when starting your service.


--kds.url=https://kds.dev.conclave.cloud
--kds.connection.timeout.seconds=60

Otherwise, if you are developing your own host application you use KDSConfiguration to specify these parameters then pass the configuration to EnclaveHost.start


import com.r3.conclave.host.kds.KDSConfiguration;

...

KDSConfiguration kdsConfiguration = new KDSConfiguration("https://kds.dev.conclave.cloud");
EnclaveHost enclaveHost = EnclaveHost.load("com.example.MyEnclave");
enclaveHost.start(null, null, null, kdsConfiguration) {}

We will enable persistence by adding the below parameter to the enclave’s build.gradle


conclave {
   productID = 1
   revocationLevel = 0
   persistentFileSystemSize = "64m"
   ....
}

Let’s now start our host(conclave-web-host) and connect to KDS. We will start the host in simulation mode.


./gradlew clean host:shadowJar -PenclaveMode=simulation

If you are on a mac, set up a Linux environment to run the conclave application. If you are on Linux, you can skip this step.


./gradlew enclave:setupLinuxExecEnvironment

Start the docker container.


docker run -it --rm -p 8080:8080 -v ${PWD}:/project -w /project conclave-build /bin/bash

Run the host application by passing in the URL and the timeout to the KDS service.


java -jar host/build/libs/host-simulation.jar --filesystem.file=host/scratch.txt --kds.url=https://kds.dev.conclave.cloud --kds.connection.timeout.secconds=60

KDS service is deployed at the URL mentioned above. Note: This URL is for a public preview of the KDS service, and this URL might change later.


Thanks to Roy and the Conclave team.

Sneha Damle
Sneha Damle Sneha Damle is a Developer Evangelist at R3, an enterprise blockchain software firm working with a global ecosystem of more than 350 participants across multiple industries from both the private and public sectors to develop on Corda, its open-source blockchain platform, Corda Enterprise, a commercial version of Corda for enterprise usage, and Conclave, a confidential computing platform.

Leave a Reply

Subscribe to our newsletter to stay up to date on the latest developer news, tools, and articles.