Running Tendermint using the Anjuna SGX Runtime

This example goes through the steps to run a one-node blockchain and protect the private keys of the node in storage and in memory.

If you followed the steps in Installing Tendermint and Installing the Anjuna SGX Runtime, you should now have Tendermint Core and the Anjuna SGX Runtime installed on your machine.

The first step is to create a configuration for running Tendermint in the Anjuna SGX Runtime.

Running

$ anjuna-sgxrun --setup

outputs manifest.template.yaml – a configuration template for the Anjuna SGX Runtime.

Typically, you would run

$ tendermint init

to initialize the node. This command creates a validator private-key, placing it in priv_validator_key.json, and the associated public-key, placed in genesis.json. It also creates a node authentication private-key and places it in node_key.json. However, we would like to protect the private-keys, such that they are never in plaintext form on the untrusted host. We let the Tendermint node generate the node authentication key, but we specify that it needs to be encrypted by Anjuna before being stored. As for the validator key, we generate it on a trusted host, and securely provision it to the untrusted host that is going to run the Tendermint node.

We specify that node_key.json needs to be encrypted, by adding an entry to the encrypted_output_files section in manifest.template.yaml, namely:

encrypted_output_files:
- /root/.tendermint/config/node_key.json

Important

The above is just an example. You need to fill in the correct path to the user’s home directory.

You also need to specify the encryption type and add the following entry to manifest.template.yaml:

output_encryption:
  type: SGX_MRSIGNER

We also specify that priv_validator_key.json is an encrypted input file, by adding its path to the encrypted_input_files section:

encrypted_input_files:
  - /root/.tendermint/config/priv_validator_key.json

Now, we generate a public key for our enclave, by running

$ anjuna-sgxrun --provision tendermint

which outputs tendermint.provision.key, the public-key for the Tendermint enclave, and tendermint.quote.bin, the attestation quote that is used to prove that the public-key was generated by the enclave. We transfer the public-key and the quote to a trusted machine (where you need to install Tendermint and the Anjuna Client Tools).

We verify the public-key against the enclave attestation by running

$ anjuna-check-attestation --quote-file tendermint.quote.bin --rsa-key-file tendermint.provision.key

If the verification passes, you have successfully established trust in the public-key and can use it to encrypt the node validator key.

Generate the validator key by running

$ tendermint gen_validator

which outputs something like this (if you pretty-print the JSON):

{
 "LastSignState" : {
    "height" : "0",
    "round" : "0",
    "step" : 0
 },
 "Key" : {
    "address" : "28D06502718DFD17AA0DB29457EF41209EE0BD39",
    "priv_key" : {
       "value" : "HniXPAnDjlw81UFz0TChOXbeYrCgiJtbZKIlhNZzOgDjNHyCOqR3Kmj63aaH6g869IN2kgw8OIDHE5VUTphNIQ==",
       "type" : "tendermint/PrivKeyEd25519"
    },
    "pub_key" : {
       "value" : "4zR8gjqkdypo+t2mh+oPOvSDdpIMPDiAxxOVVE6YTSE=",
       "type" : "tendermint/PubKeyEd25519"
    }
 }
}

Create a file named priv_validator_key.json and copy the value of the Key element to it, i.e., priv_validator_key.json should contain something similar to

{
  "address" : "28D06502718DFD17AA0DB29457EF41209EE0BD39",
  "priv_key" : {
     "value" : "HniXPAnDjlw81UFz0TChOXbeYrCgiJtbZKIlhNZzOgDjNHyCOqR3Kmj63aaH6g869IN2kgw8OIDHE5VUTphNIQ==",
     "type" : "tendermint/PrivKeyEd25519"
  },
  "pub_key" : {
     "value" : "4zR8gjqkdypo+t2mh+oPOvSDdpIMPDiAxxOVVE6YTSE=",
     "type" : "tendermint/PubKeyEd25519"
  }
}

Encrypt the file by running

$ anjuna-prov-seal --public-key tendermint.provision.key priv_validator_key.json

which generates priv_validator_key.json.sealed. Transfer priv_validator_key.json.sealed to the untrusted host where you are setting up the Tendermint node. Rename it back to priv_validator_key.json and place it in the ~/.tendermint/config directory. Create the ~/.tendermint/data directory and place there a file named priv_validator_state.json with the following content

{
  "height": "0",
  "round": "0",
  "step": 0
}

Now, initialize the node by running

$ anjuna-sgxrun tendermint init

Once initialized, the node can be started using

$ anjuna-sgxrun tendermint node --proxy_app=kvstore