Skip to content

Commit

Permalink
Merge pull request #274 from rsksmart/feature/sgx-up-to-date
Browse files Browse the repository at this point in the history
SGX powHSM
  • Loading branch information
amendelzon authored Jan 22, 2025
2 parents 635600c + eb9f881 commit 865641c
Show file tree
Hide file tree
Showing 352 changed files with 29,220 additions and 1,457 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: "Code coverage"

on:
push:
branches: [ "master" ]
branches: [ "master", "feature/sgx" ]

# Declare default permissions as read only.
permissions: read-all
Expand Down Expand Up @@ -37,7 +37,7 @@ jobs:
run: |
aws s3 sync \
middleware/coverage/ \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.2.x/middleware_coverage_report \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.3.x/middleware_coverage_report \
--sse aws:kms --sse-kms-key-id ${{ secrets.CODECOVERAGE_KMS_KEY_ID }} \
--no-progress --follow-symlinks --delete --only-show-errors
Expand All @@ -52,7 +52,7 @@ jobs:
run: |
aws s3 sync \
firmware/coverage/output/ \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.2.x/firmware_coverage_report \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.3.x/firmware_coverage_report \
--sse aws:kms --sse-kms-key-id ${{ secrets.CODECOVERAGE_KMS_KEY_ID }} \
--no-progress --follow-symlinks --delete --only-show-errors
Expand Down
76 changes: 68 additions & 8 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,32 @@ jobs:
- name: Firmware tests using TCPSigner
run: firmware/test/test-all

- name: Firmware HAL's unit tests
- name: Firmware HAL's common unit tests
run: firmware/src/hal/common/test/run-all.sh

- name: Firmware HAL's x86 unit tests
run: firmware/src/hal/x86/test/run-all.sh

- name: Firmware HAL's SGX unit tests
run: firmware/src/hal/sgx/test/run-all.sh

- name: Firmware common lib unit tests
run: firmware/src/common/test/run-all.sh

- name: Firmware PowHSM's unit tests
run: firmware/src/powhsm/test/run-all.sh

- name: Firmware SGX's unit tests
run: firmware/src/sgx/test/run-all.sh

- name: Ledger UI's unit tests
run: firmware/src/ledger/ui/test/run-all.sh

- name: Ledger Signer's unit tests
run: firmware/src/ledger/signer/test/run-all.sh

run-integration-tests:
name: Integration tests
run-integration-tests-tcpsigner:
name: Integration tests for TCPSigner
runs-on: ubuntu-20.04

steps:
Expand All @@ -56,25 +65,76 @@ jobs:
run: |
docker/mware/build
docker/packer/build
middleware/build/manager-tcp
middleware/build/manager_tcp
firmware/build/build-tcpsigner
- name: Checkout hsm-integration-test repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
repository: rootstock/hsm-integration-test
ref: 5.1.0.plus
ref: 5.3.0.plus
path: hsm-integration-test
ssh-key: ${{ secrets.HSM_INTEGRATION_TEST_SSH_KEY }}

- name: Copy required files
run: |
mkdir hsm-integration-test/docker/manager/manager-tcp
tar -xzf rsk-powhsm/middleware/bin/manager-tcp.tgz \
-C hsm-integration-test/docker/manager/manager-tcp
mkdir hsm-integration-test/docker/manager/manager_tcp
tar -xzf rsk-powhsm/middleware/bin/manager_tcp.tgz \
-C hsm-integration-test/docker/manager/manager_tcp
cp rsk-powhsm/firmware/src/tcpsigner/tcpsigner \
hsm-integration-test/docker/tcpsigner/
- name: Run HSM integration tests
working-directory: hsm-integration-test
run: sh smoke-test.sh

run-integration-tests-sgx:
name: Integration tests for SGX simulator
runs-on: ubuntu-20.04

steps:
- name: Checkout rsk-powhsm repo
uses: actions/checkout@v3
with:
path: rsk-powhsm

- name: Build required software
working-directory: rsk-powhsm
run: |
docker/mware/build
docker/packer/build
docker/sgx/build
middleware/build/manager_sgx
docker/sgx/do-notty /hsm2/firmware/src/sgx "make generate-private-key"
firmware/build/build-sgx-sim \
0xe108960a242ad7bd45c21aff9c7ed9c516789e9cffacdd895502727d8f460d2c \
0x6E regtest
- name: Checkout hsm-integration-test repo
uses: actions/checkout@v3
with:
repository: rootstock/hsm-integration-test
ref: 5.3.0.plus
path: hsm-integration-test
ssh-key: ${{ secrets.HSM_INTEGRATION_TEST_SSH_KEY }}

- name: Copy required files
run: |
mkdir hsm-integration-test/docker/manager/manager_sgx
tar -xzf rsk-powhsm/middleware/bin/manager_sgx.tgz \
-C hsm-integration-test/docker/manager/manager_sgx
cp rsk-powhsm/firmware/src/sgx/bin/hsmsgx \
hsm-integration-test/docker/sgx
cp rsk-powhsm/firmware/src/sgx/bin/hsmsgx_enclave.signed \
hsm-integration-test/docker/sgx
echo abcd1234 > hsm-integration-test/docker/manager/pin.txt
echo -n abcd1234 > hsm-integration-test/docker/sgx/kvstore-password.dat
echo -en "\x03" > hsm-integration-test/docker/sgx/kvstore-retries.dat
echo -en "\x03" > hsm-integration-test/docker/sgx/kvstore-retries.dat
dd if=/dev/urandom bs=1 count=32 \
of=hsm-integration-test/docker/sgx/kvstore-seed.dat
echo "SGX_SIM=yes" >> "$GITHUB_ENV"
- name: Run HSM integration tests
working-directory: hsm-integration-test
run: sh smoke-test.sh
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@
# Ignore fuzz artifacts
firmware/fuzz/.coverage-build
firmware/fuzz/output

# Ignore SGX data files
**/kvstore-*.dat
27 changes: 22 additions & 5 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Whether new to the project or just wanting to quickly get an environment up and
```
~/repo> docker/mware/build # Middleware image
~/repo> docker/ledger/build # Ledger image
~/repo> docker/sgx/build # SGX image
~/repo> docker/packer/build # Middleware binary packer image
```

Expand All @@ -27,26 +28,42 @@ Unless otherwise stated, only x86 platforms are supported for building this proj
~/repo> firmware/src/ledger/signer/test/run-all.sh # Ledger Signer application unit tests
~/repo> firmware/src/common/test/run-all.sh # Common code unit tests
~/repo> firmware/src/powhsm/test/run-all.sh # powHSM logic unit tests
~/repo> firmware/src/hal/test/run-all.sh # HAL unit tests
~/repo> firmware/src/hal/common/test/run-all.sh # HAL common code unit tests
~/repo> firmware/src/hal/x86/test/run-all.sh # HAL x86 implementation unit tests
```

- Build Ledger Nano S application binaries:
```
~/repo> firmware/build/build-signer <checkpoint> <difficulty> <network> # Build signer
~/repo> firmware/build/build-ui <signer_hash> <signer_iteration> <signers_file> # Build UI
~/repo> firmware/build/build-ledger-signer <checkpoint> <difficulty> <network> # Build signer
~/repo> firmware/build/build-ledger-ui <signer_hash> <signer_iteration> <signers_file> # Build UI
```

- Build SGX binaries (both host and enclave):
```
~/repo> firmware/build/build-sgx <checkpoint> <difficulty> <network>
```

- Build middleware binaries:
```
~/repo> middleware/build/all
```

- Build a complete powHSM distribution:
- Build a complete Ledger powHSM distribution:
```
~/repo> ./build-dist <destination path> <checkpoint> <minimum difficulty> <network> <ui_iteration> <ui_authorizers>
~/repo> ./build-dist-ledger <destination path> <checkpoint> <minimum difficulty> <network> <ui_iteration> <ui_authorizers>
```

- Build a complete SGX powHSM distribution:
```
~/repo> ./build-dist-sgx <destination path> <checkpoint> <minimum difficulty> <network>
```

- Build the TCPSigner:
```
~/repo> firmware/build/build-tcpsigner
```

- Build the SGX simulator:
```
~/repo> firmware/build/build-sgx-sim <checkpoint> <minimum difficulty> <network>
```
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
![Tests](https://github.com/rsksmart/rsk-powhsm/actions/workflows/run-tests.yml/badge.svg)
![Python linter](https://github.com/rsksmart/rsk-powhsm/actions/workflows/lint-python.yml/badge.svg)
![C linter](https://github.com/rsksmart/rsk-powhsm/actions/workflows/lint-c.yml/badge.svg)
[![Middleware coverage](https://img.shields.io/endpoint?url=https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.2.x/middleware_coverage_report/badge.json)](https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.2.x/middleware_coverage_report/index.html)
[![Firmware coverage](https://img.shields.io/endpoint?url=https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.2.x/firmware_coverage_report/badge.json)](https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.2.x/firmware_coverage_report/index.html)
[![Middleware coverage](https://img.shields.io/endpoint?url=https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.3.x/middleware_coverage_report/badge.json)](https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.3.x/middleware_coverage_report/index.html)
[![Firmware coverage](https://img.shields.io/endpoint?url=https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.3.x/firmware_coverage_report/badge.json)](https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.3.x/firmware_coverage_report/index.html)

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)

## About

The RSK Powpeg protects private keys stored in special purpose PowHSMs based on tamper-proof secure elements (SE). The PowHSM runs an RSK node in SPV mode, and signatures can only be commanded by chain cumulative proof of work.

This repository hosts the powHSM firmware. The stable versions are the tags published in the [releases tab](https://github.com/rsksmart/rsk-powhsm/releases).
This repository hosts the powHSM firmware and middleware. The stable versions are the tags published in the [releases tab](https://github.com/rsksmart/rsk-powhsm/releases).

## Notation

Expand All @@ -22,23 +22,30 @@ Throughout the repository READMEs, the prompt `~/repo>` is used to denote a `bas

Refer to our [quickstart guide](./QUICKSTART.md) to learn about environment setup and common tasks without further ado.

## Firmware platforms

PowHSM can run both on Ledger Nano S devices and Intel SGX servers. At any given time, a PowPeg can be composed of a mix of members running PowHSM on either platform. The decision of which platform to run on each member is ultimately up to the member itself and the Rootstock network maintainers.

## Supported platforms

Unless otherwise stated, only x86 platforms are supported for building this project and running the tools provided. It is possible, however, to build and run the [TCPSigner bundle](./utils/tcpsigner-bundle/README.md) on arm64 platforms. This is provided for development and testing purposes.

## Concepts overview

powHSM is a solution designed specifically for the [RSK network](https://www.rsk.co/) powPeg. Its main role is to safekeep and prevent the unauthorized usage of each of the powPeg's members' private keys. powHSM is currently implemented as a pair of applications for the [Ledger Nano S](https://shop.ledger.com/products/ledger-nano-s), namely a UI and a Signer, and it strongly depends on the device's security features to implement the aforementioned safekeeping.
powHSM is a solution designed specifically for the [RSK network](https://www.rsk.co/) powPeg. Its main role is to safekeep and prevent the unauthorized usage of each of the powPeg's members' private keys. powHSM has currenty got two implementations that target two different platforms.

1. The first implementation consists of a pair of applications for the [Ledger Nano S](https://shop.ledger.com/products/ledger-nano-s), namely a UI and a Signer, and it strongly depends on the device's security features to implement the aforementioned safekeeping. This implementation requires a physical Ledger Nano S device and a self-managed physical standalone server.
2. The second implementation consists of both a host and an enclave binary targetting the Intel SGX architecture. Just as the Ledger Nano S implementation, it strongly depends on the Intel SGX security features in order to keep the private keys safe. This implementation can run both on standalone SGX-enabled servers as well as on SGX-enabled cloud computing providers (e.g., Microsoft Azure).

Each powPeg member runs an individual physical device on which a transparent installation and onboarding process is carried. Amongst other things, this process safely generates the root key, that never leaves the device. There is an [attestation process](./docs/attestation.md) that serves the purpose of testifying and guaranteeing this key generation process, and ultimately the fact that the key is only ever known to the device.
Each powPeg member runs an individual physical device or SGX enclave on which a transparent installation and onboarding process is carried. Amongst other things, this process safely generates the root key, that either never leaves the device (Ledger) or can only ever be decrypted by the enclave (SGX). There is an [attestation process](./docs/attestation.md) that serves the purpose of testifying and guaranteeing this key generation process, and ultimately the fact that the key is only ever known to the physical device or SGX enclave.

After onboarding, each device is physically connected to and interacts with its corresponding powPeg node by means of a middleware layer that exposes a [high-level protocol](./docs/protocol.md) for its operation.
After onboarding, each powHSM runs either on its host (SGX) or is physically connected to it (Ledger), and interacts with its corresponding powPeg node by means of a middleware layer that exposes a [high-level protocol](./docs/protocol.md) for its operation.

The signer application running within each device enables the usage of two sets of keypairs by its owner powPeg node: an _unauthorized_ and an _authorized_ set. These keys are generated from the root key using a standard [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) derivation path (following [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)).
The signer application running within each powHSM enables the usage of two sets of keypairs by its owner powPeg node: an _unauthorized_ and an _authorized_ set. These keys are generated from the root key using a standard [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) derivation path (following [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)).

The _unauthorized_ keyset can be used to sign arbitrary hashes, and its security scheme relies solely on the knowledge of the device's pin (akin to owning a Ledger Nano S for personal usage). This keyset is used by the powPeg members for non critical operations (e.g., signing powPeg-only transactions within the RSK network).
The _unauthorized_ keyset can be used to sign arbitrary hashes, and its security scheme relies solely on the knowledge of the powHSM's pin (in the Ledger Nano S case, akin to owning a device for personal usage). This keyset is used by the powPeg members for non critical operations (e.g., signing powPeg-only transactions within the RSK network).

The _authorized_ keyset is the main security focus of the solution. It can _only_ ever be used to sign BTC transactions that correspond to pegOuts within the RSK network, i.e., the release of Bitcoin funds held within RSK's bridge mechanism. This authorization is enforced by means of events that the [Bridge contract](https://explorer.rsk.co/address/0x0000000000000000000000000000000001000006) emits whenever a pegOut request is generated, and that are included in RSK's blocks by means of transaction receipts, and ultimately mined and secured by actual Bitcoin miners. This implies that without a mined pegOut request with a minimum amount of hashing power on top, the device emits no signature. This powerful feature gives the project its name: _powHSM_ - Proof of Work Hardware Security Module.
The _authorized_ keyset is the main security focus of the solution. It can _only_ ever be used to sign BTC transactions that correspond to pegOuts within the RSK network, i.e., the release of Bitcoin funds held within RSK's bridge mechanism. This authorization is enforced by means of events that the [Bridge contract](https://explorer.rsk.co/address/0x0000000000000000000000000000000001000006) emits whenever a pegOut request is generated, and that are included in RSK's blocks by means of transaction receipts, and ultimately mined and secured by actual Bitcoin miners. This implies that, without a mined pegOut request with a minimum amount of hashing power on top, the powHSM emits no signature. This powerful feature gives the project its name: _powHSM_ - Proof of Work Hardware Security Module.

## Digging deeper

Expand Down
9 changes: 5 additions & 4 deletions build-dist → build-dist-ledger
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ fi
echo -e "\e[32mBuilding into \e[93m$DEST_DIR\e[32m with checkpoint \e[93m$CHECKPOINT\e[32m, minimum difficulty \e[93m$DIFFICULTY\e[32m, network \e[93m$NETWORK\e[32m and UI iteration \e[93m$UI_ITERATION\e[32m...\e[0m"
echo -e "\e[33mCopying files and creating directories...\e[0m"
rm -rf $DEST_DIR
cp -Rf $ROOT_DIR/dist $DEST_DIR
cp -Rf $ROOT_DIR/dist/ledger $DEST_DIR
rm $DEST_DIR/.gitignore

rm -rf $FIRMWARE_DIR
mkdir -p $FIRMWARE_DIR
Expand All @@ -48,10 +49,10 @@ rm -f $DEST_DIR/attestation.json $DEST_DIR/device_attestation.json

echo
echo -e "\e[33mBuilding middleware...\e[0m"
$ROOT_DIR/middleware/build/dist
cp $ROOT_DIR/middleware/bin/adm.tgz $BIN_DIR
$ROOT_DIR/middleware/build/dist_ledger
cp $ROOT_DIR/middleware/bin/adm_ledger.tgz $BIN_DIR
cp $ROOT_DIR/middleware/bin/lbutils.tgz $BIN_DIR
cp $ROOT_DIR/middleware/bin/manager.tgz $BIN_DIR
cp $ROOT_DIR/middleware/bin/manager_ledger.tgz $BIN_DIR
cp $ROOT_DIR/middleware/bin/signapp.tgz $BIN_DIR
echo

Expand Down
67 changes: 67 additions & 0 deletions build-dist-sgx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash

pushd $(dirname $0) > /dev/null
ROOT_DIR=$(pwd)

if [[ $# -lt 4 ]]; then
echo "Usage: $0 <destination path> <checkpoint> <minimum difficulty> <network>"
exit 1
fi

# Check docker images exist
CHECK_IMAGE=$ROOT_DIR/docker/check-image

for img in hsm:sgx hsm:mware hsm:packer; do
DOCKER_IMAGE=$img
source $CHECK_IMAGE
done

DEST_DIR=$1
CHECKPOINT=$2
DIFFICULTY=$3
NETWORK=$4
HSM_DIR=$DEST_DIR/hsm
BIN_DIR=$DEST_DIR/bin
SCRIPTS_DIR=$DEST_DIR/scripts

if [[ -e $DEST_DIR ]]; then
echo -e "\e[31mDestination directory $DEST_DIR exists"
exit 1
fi

echo -e "\e[32mBuilding into \e[93m$DEST_DIR\e[32m with checkpoint \e[93m$CHECKPOINT\e[32m, minimum difficulty \e[93m$DIFFICULTY\e[32m, network \e[93m$NETWORK\e[32m and UI iteration \e[93m$UI_ITERATION\e[32m...\e[0m"
echo -e "\e[33mCopying files and creating directories...\e[0m"
rm -rf $DEST_DIR
cp -Rf $ROOT_DIR/dist/sgx $DEST_DIR
rm $DEST_DIR/.gitignore

rm -rf $BIN_DIR
mkdir -p $BIN_DIR

echo
echo -e "\e[33mBuilding middleware...\e[0m"
$ROOT_DIR/middleware/build/dist_sgx
cp $ROOT_DIR/middleware/bin/adm_sgx.tgz $BIN_DIR
cp $ROOT_DIR/middleware/bin/manager_sgx.tgz $BIN_DIR
echo

echo -e "\e[33mBuilding SGX apps...\e[0m"
# TODO: decide what to do with the enclave signing key
#(randomizing seems like a reasonable option
# since we don't actually need it in our current scheme)
$ROOT_DIR/firmware/build/build-sgx $CHECKPOINT $DIFFICULTY $NETWORK > /dev/null
cp $ROOT_DIR/firmware/src/sgx/bin/hsmsgx $HSM_DIR/
cp $ROOT_DIR/firmware/src/sgx/bin/hsmsgx_enclave.signed $HSM_DIR/

HOST_HASH=$(sha256sum $ROOT_DIR/firmware/src/sgx/bin/hsmsgx | cut -d ' ' -f 1)
ENCLAVE_HASH=$($ROOT_DIR/firmware/build/extract-mrenclave $ROOT_DIR/firmware/src/sgx/bin/hsmsgx_enclave.signed)
echo "$HSM_DIR/hsmsgx:"
echo $HOST_HASH
echo
echo "$HSM_DIR/hsmsgx_enclave.signed"
echo "$ENCLAVE_HASH"

echo
echo -e "\e[32mBuild complete.\e[0m"

popd > /dev/null
1 change: 1 addition & 0 deletions dist/.gitignore → dist/ledger/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
bin
firmware
export
public-keys.txt
public-keys.json
pin.txt
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion dist/README-cli.md → dist/ledger/README-cli.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# powHSM Setup and onboarding
# powHSM for Ledger Nano S Setup and onboarding

## Prerequisites

Expand Down
Loading

0 comments on commit 865641c

Please sign in to comment.