Nitriding supports horizontal scaling, i.e., it allows for the synchronization of key material among identical enclaves. Key material consists of both nitriding and application keys:
- Nitriding's key material is the self-signed HTTPS certificate (both public and private key) that provides the confidential channel between clients and the enclave.
- The application's key material is application-specific. Nitriding is agnostic to the structure of this key material and treats it as arbitrary bytes.
All of the above must be synced among enclaves.
For enclave key synchronization to work, there must be a single leader enclave and one or more worker enclaves. The leader's sole job is to create key material and make itself available for synchronizing this key material with worker enclaves. Worker enclaves do the actual work, i.e., process user requests. Before doing any work though, workers must register themselves with the leader, which triggers key synchronization.
To set up key synchronization, several steps are necessary:
- Use the
-fqdn-leader
command line flag on both the leader and the worker. Note that the leader and worker images must be identical. The leader is only willing to synchronize key material with identical enclaves. - Practically speaking, the leader is meant to run in a separate k8s deployment from the workers.
- The leader creates a 20-byte nonce
$\textrm{nonce}_l$ and sends it to the worker as part of aGET
request. - Upon receiving
$\textrm{nonce}_l$ , the worker creates its own 20-byte nonce$\textrm{nonce}_w$ and an ephemeral asymmetric key pair$K_e = (sk, pk)$ , which we generate with Go'scrypto/nacl/box
package. The worker now asks its hypervisor to create an attestation document$A_w$ containing$\textrm{nonce}_l$ ,$\textrm{nonce}_w$ , and$pk$ . The worker responds to the leader'sGET
request with$A_w$ . - Having received
$A_w$ , the leader now verifies that...- ...the attestation document is signed by the AWS Nitro Enclave hypervisor. This stops attackers from sending spoofed attestation documents.
- ...the attestation document contains
$\textrm{nonce}_l$ . This stops attackers from replaying old attestation documents. Note that attestation documents always contain the enclave's image ID. - ...the attestation document's platform configuration registers are identical to the leader's registers. This stops attackers from using modified enclaves to extract the sensitive key material.
- The leader is now convinced that it's dealing with an authentic worker
enclave. In the next and final interaction, the leader encrypts its sensitive
enclave keys
$K_s$ using the worker's ephemeral public key$pk$ , resulting in$E = \textrm{Enc}(K_s, pk)$ . The leader then asks its hypervisor to create an attestation document$A_l$ containing$\textrm{nonce}_w$ and SHA-256($E$ ). The leader sends$A_l$ and$E$ to the worker in a separatePOST
request. - Upon receiving
$A_l$ , the worker first verifies the attestation document (same as above), and decrypts$E$ using$sk$ , revealing in$K_s$ , the sensitive enclave keys. At this point, key synchronization is complete. - After key synchronization, workers send a periodic heartbeat to the leader in
a
POST
request. The request's body contains a Base64-encoded SHA-256 hash over$K_s$ . This allows the leader to verify if the worker's keys are still up-to-date. If not, the leader initiates key-synchronization using the protocol as above.
The sensitive key material
-
Communication between leader and worker enclaves happens over AWS's Virtual Private Cloud (VPC). We therefore expose the endpoints for key synchronization over a separate Web server that's not reachable over the Internet.
-
Leader and worker enclaves use HTTPS as an underlying secure channel. Note that the authenticity of our HTTPS certificates is rooted in the hypervisor-signed attestation documents; not in a certificate authority.
-
Worker enclaves create an ephemeral key pair that's used to encrypt key material using Go's
crypto/nacl/box
API. Even if an attacker can snoop on the VPC network and compromise the confidentiality of our HTTPS connection, enclave keys are still protected by this ephemeral key pair.
The leader only synchronizes with workers that run identical code. The leader therefore has assurance that workers are not going to game the system.
sequenceDiagram
box rgba(100, 100, 100, .1) Leader enclave
participant leaderApp as Enclave application
participant leader as Leader enclave
end
box rgba(100, 100, 100, .1) Worker enclave
participant worker as Worker enclave
participant workerApp as Enclave application
end
leader->>leader: Generate HTTPS certificate
leaderApp->>leaderApp: Generate key material
Note over leader,worker: Enclaves designate the leader
worker->>+leader: GET /enclave/leader (nonce_w)
leader-->>-worker: OK
worker->>worker: Did not call itself: worker
leader->>leader: GET /enclave/leader (nonce_l)
leader->>leader: Did call itself: leader
Note over leaderApp,leader: Application sets its key material
leaderApp->>+leader: PUT /enclave/state (key material)
leader->>leader: Save key material
leader-->>-leaderApp: OK
Note over leader,worker: Worker announces itself to leader
worker->>+leader: POST /enclave/heartbeat
leader->>leader: Register new worker
leader-->>-worker: OK
Note over leader,worker: Leader initiates key synchronization
leader->>leader: Create nonce
leader->>+worker: GET /enclave/sync (nonce_l)
worker->>worker: Create attestation, nonce, and ephemeral keys
worker-->>-leader: OK (Attestation(nonce_l, nonce_w, pk))
leader->>leader: Verify & create attestation
leader->>+worker: POST /enclave/sync (Attestation(nonce_w, SHA-256(E(keys, pk))), E(keys, pk))
worker->>worker: Verify attestation & install keys
worker-->>-leader: OK
worker->>worker: Install HTTPS certificate
Note over worker,workerApp: Application retrieves key material
workerApp->>+worker: GET /enclave/state
worker->>worker: Retrieve key material
worker-->>-workerApp: OK (key material)
workerApp->>workerApp: Install key material
Note over leader, worker: Worker starts heartbeat loop
loop Heartbeat
worker->>+leader: POST /enclave/heartbeat (Hash(key material))
leader-->>-worker: OK
end
Note over leaderApp: Application updates its key material
leaderApp->>+leader: PUT /enclave/state (key material)
leader->>leader: Save key material
leader-->>-leaderApp: OK
note over leader,worker: Leader initiates key re-synchronization as above