Skip to content

Commit

Permalink
Decouple business and hardware layers (#183)
Browse files Browse the repository at this point in the history
* Decoupling business layer from hardware layer in Signer component (#177)

- Added HAL headers
- Added HAL implementation for Ledger
- Refactored necessary common sources
- Refactored necessary Signer sources
- Updated Signer Makefile to include HAL code
- Removed HSM_SIMULATOR define in favor of HSM_PLATFORM_* defines
- Included X86 (partial) implemenations of some HAL modules (exceptions, logging, hashing)
- Renamed UI communication module to avoid name clashing with HAL
- Changed platform define in Makefile

* Decoupling business layer from hardware layer in TCPSigner (#179)

- Implementing HAL for x86 based on the existing TCPSigner implementation
- Additional x86-only functions for HAL implementation
- Updating TCPSigner implementation to use HAL
- Added TCPSigner-specific UI dependencies to implement functions needed by UI only code
- Factoring HAL constants into a constants file
- New BIP32 parser for TCPSigner seed file
- Ensuring Firmware tests pass both on Ledger Nano S and TCPSigner
- Linting

* Updating directory structure to accomodate for multiple platforms (#180)

- Moved 'ledger' directory to 'firmware'
- Unified Makefile, source and tests directory structure
- Updated Makefiles to account for new (unified) directory structure
- Updated paths within scripts
- Updated github workflows
- Updated script names to account for underlying platform
- Updated documentation references
- New 'run all' script for tcpsigner unit tests
- Incidentally fixing cross-module responsibility includes
- Incidentally fixing version number in Ledger app deployment scripts

* Firmware unit test fixing (#181)

- Fixing existing unit tests
- New unit tests for the TCPSigner BIP32 library
- Moving TCPSigner unit tests to HAL (TCPSigner is now basically a shell)
- Moving Signer unit tests to PowHSM
- Fixing code coverage generation to:
  - Forcibly terminate the TCPSigner after tests run
  - Ignore unit test sources
- Unifying firmware .gitignore files
- Organising common unit test Makefile rules into common.mk files
- Removed unnecessary testing comments
- Incidentally fixing some include style (angle bracket x quotes)

* Updating documentation to reflect the possibility of multiple platform implementations (#182)
  • Loading branch information
amendelzon authored Jun 18, 2024
1 parent 726be1d commit 6b191e5
Show file tree
Hide file tree
Showing 617 changed files with 3,398 additions and 2,749 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ jobs:
- name: Run firmware coverage script
run: |
ledger/coverage/gen-coverage
COVPCT=$(cat ledger/coverage/output/total)
firmware/coverage/gen-coverage
COVPCT=$(cat firmware/coverage/output/total)
COVCOL=$(utils/coverage-color.sh $COVPCT)
echo "{ \"schemaVersion\": 1, \"label\": \"Firmware coverage\", \"message\": \"$COVPCT%\", \"color\": \"$COVCOL\" }" > ledger/coverage/output/badge.json
echo "{ \"schemaVersion\": 1, \"label\": \"Firmware coverage\", \"message\": \"$COVPCT%\", \"color\": \"$COVCOL\" }" > firmware/coverage/output/badge.json
- name: "Upload firmware coverage report"
run: |
aws s3 sync \
ledger/coverage/output/ \
firmware/coverage/output/ \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.0.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
32 changes: 12 additions & 20 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,20 @@ jobs:
- name: Middleware tests
run: middleware/test-all

- name: Ledger tests for TCPSigner
run: ledger/test/test-all
- name: Firmware tests using TCPSigner
run: firmware/test/test-all

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

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

- name: Ledger common lib tests
working-directory: ledger/src/common/test/
run: |
for d in memutil ints; do
(cd "$d" && make clean test)
done
- name: Firmware PowHSM's unit tests
run: firmware/src/powhsm/test/run-all.sh

- name: Ledger TCPSigner's tests
working-directory: ledger/src/tcpsigner/test/
run: |
for d in hmac_sha256; do
(cd "$d" && make clean test)
done
- name: Ledger UI's unit tests
run: firmware/src/ledger/ui/test/run-all.sh

run-integration-tests:
name: Integration tests
Expand All @@ -59,7 +51,7 @@ jobs:
docker/mware/build
docker/packer/build
middleware/build/manager-tcp
ledger/build/build-tcpsigner
firmware/build/build-tcpsigner
- name: Checkout hsm-integration-test repo
uses: actions/checkout@v3
Expand All @@ -74,7 +66,7 @@ jobs:
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/ledger/src/tcpsigner/tcpsigner \
cp rsk-powhsm/firmware/src/tcpsigner/tcpsigner \
hsm-integration-test/docker/tcpsigner/
- name: Run HSM integration tests
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ jobs:
id: static-analysis
continue-on-error: true
run: |
ledger/static-analysis/gen-static-analysis
firmware/static-analysis/gen-static-analysis
- name: Upload static analysis reports
uses: actions/upload-artifact@v3
with:
name: static-analysis-reports
path: ledger/static-analysis/output
path: firmware/static-analysis/output

- name: Report static analysis findings
if: steps.static-analysis.outcome != 'success'
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
.vscode/

# Ignore fuzz artifacts
ledger/fuzz/.coverage-build
ledger/fuzz/output
firmware/fuzz/.coverage-build
firmware/fuzz/output
20 changes: 13 additions & 7 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@ Whether new to the project or just wanting to quickly get an environment up and

Unless otherwise stated, only x86 platforms are supported for building this project and running the tools provided. The only exception is the [TCPSigner bundle](./utils/tcpsigner-bundle/README.md), which can be built and ran in x86 and arm64 platforms.


## Common tasks

- Run tests:
```
~/repo> middleware/test-all # Middleware unit tests
~/repo> ledger/test/test-all # Ledger signer application tests
~/repo/ledger/src/signer/test/*> make test # Run ledger signer application unit tests
~/repo/ledger/src/common/test/*> make test # Run ledger common libraries unit tests
~/repo> firmware/test/test-all # Firmware tests
~/repo> firmware/src/ledger/ui/test/run-all.sh # Ledger UI 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
```

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

- Build middleware binaries:
Expand All @@ -43,3 +44,8 @@ Unless otherwise stated, only x86 platforms are supported for building this proj
```
~/repo> ./build-dist <destination path> <checkpoint> <minimum difficulty> <network> <ui_iteration> <ui_authorizers>
```

- Build the TCPSigner:
```
~/repo> firmware/build/build-tcpsigner
```
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Unless otherwise stated, only x86 platforms are supported for building this proj

## 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 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 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.

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.

Expand All @@ -48,7 +48,7 @@ Refer to the following documents for details on specifics:
- [Blockchain bookkeeping documentation](./docs/blockchain-bookkeeping.md)
- [Attestation documentation](./docs/attestation.md)
- [Heartbeat documentation](./docs/heartbeat.md)
- [Ledger apps](./ledger/README.md)
- [Firmware](./firmware/README.md)
- [Middleware](./middleware/README.md)
- [Distribution](./dist/README.md)

Expand Down
24 changes: 12 additions & 12 deletions build-dist
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,32 @@ computeHash() {
}

echo -e "\e[33mBuilding signer...\e[0m"
$ROOT_DIR/ledger/build/build-signer $CHECKPOINT $DIFFICULTY $NETWORK > /dev/null
cp $ROOT_DIR/ledger/src/signer/bin/app.hex $FIRMWARE_DIR/signer.hex
cp $ROOT_DIR/ledger/src/signer/icon.hex $FIRMWARE_DIR/signer.icon.hex
$ROOT_DIR/firmware/build/build-ledger-signer $CHECKPOINT $DIFFICULTY $NETWORK > /dev/null
cp $ROOT_DIR/firmware/src/ledger/signer/bin/app.hex $FIRMWARE_DIR/signer.hex
cp $ROOT_DIR/firmware/src/ledger/signer/icon.hex $FIRMWARE_DIR/signer.icon.hex
HEX_NAME="Signer"
HEX_PATH="ledger/src/signer/bin/app.hex"
HEX_PATH="firmware/src/ledger/signer/bin/app.hex"
computeHash
SIGNER_HASH=$APP_HASH

echo -e "\e[33mBuilding UI...\e[0m"
$ROOT_DIR/ledger/build/build-ui $SIGNER_HASH $UI_ITERATION $UI_AUTHORIZERS > /dev/null
cp $ROOT_DIR/ledger/src/ui/bin/token.hex $FIRMWARE_DIR/ui.hex
cp $ROOT_DIR/ledger/src/ui/icon.hex $FIRMWARE_DIR/ui.icon.hex
$ROOT_DIR/firmware/build/build-ledger-ui $SIGNER_HASH $UI_ITERATION $UI_AUTHORIZERS > /dev/null
cp $ROOT_DIR/firmware/src/ledger/ui/bin/token.hex $FIRMWARE_DIR/ui.hex
cp $ROOT_DIR/firmware/src/ledger/ui/icon.hex $FIRMWARE_DIR/ui.icon.hex
HEX_NAME="UI"
HEX_PATH="ledger/src/ui/bin/token.hex"
HEX_PATH="firmware/src/ledger/ui/bin/token.hex"
CA_FILE="rsk-ca.txt"
computeHash

echo -e "\e[33mSigning apps...\e[0m"
$ROOT_DIR/docker/mware/do-notty-nousb /hsm2 "python middleware/signonetime.py -a ledger/src/ui/bin/token.hex,ledger/src/signer/bin/app.hex -p $CA_FILE" > /dev/null
mv -f $ROOT_DIR/ledger/src/ui/bin/token.hex.sig $FIRMWARE_DIR/ui.hex.sig
mv -f $ROOT_DIR/ledger/src/signer/bin/app.hex.sig $FIRMWARE_DIR/signer.hex.sig
$ROOT_DIR/docker/mware/do-notty-nousb /hsm2 "python middleware/signonetime.py -a firmware/src/ledger/ui/bin/token.hex,firmware/src/ledger/signer/bin/app.hex -p $CA_FILE" > /dev/null
mv -f $ROOT_DIR/firmware/src/ledger/ui/bin/token.hex.sig $FIRMWARE_DIR/ui.hex.sig
mv -f $ROOT_DIR/firmware/src/ledger/signer/bin/app.hex.sig $FIRMWARE_DIR/signer.hex.sig
mv -f $ROOT_DIR/$CA_FILE $SCRIPTS_DIR/$CA_FILE

SIGNER_AUTH_FILE="signer_auth.json"
echo -e "\e[33mCreating empty signer authorization for upgrades...\e[0m"
$ROOT_DIR/docker/mware/do-notty-nousb /hsm2 "python middleware/signapp.py message -a ledger/src/signer/bin/app.hex -i $UI_ITERATION -o $SIGNER_AUTH_FILE" > /dev/null
$ROOT_DIR/docker/mware/do-notty-nousb /hsm2 "python middleware/signapp.py message -a firmware/src/ledger/signer/bin/app.hex -i $UI_ITERATION -o $SIGNER_AUTH_FILE" > /dev/null
mv -f $ROOT_DIR/$SIGNER_AUTH_FILE $FIRMWARE_DIR/$SIGNER_AUTH_FILE

echo
Expand Down
4 changes: 2 additions & 2 deletions dist/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# powHSM distribution

This document describes the artifacts provided to build a distributable version of the powHSM software. This distributable version includes both ledger apps and middleware binaries, as well as scripts for both setting up and onboarding a brand new Ledger Nano S; and also for upgrading an existing Ledger Nano S with powHSM to a newer Signer version.
This document describes the artifacts provided to build a distributable version of the powHSM software for Ledger Nano S. This distributable version includes both Ledger apps and middleware binaries, as well as scripts for both setting up and onboarding a brand new Ledger Nano S; and also for upgrading an existing Ledger Nano S with powHSM to a newer Signer version.

## Prerequisites

Expand All @@ -14,7 +14,7 @@ To generate a full distribution into a fresh directory, issue:
~/repo> ./build-dist <destination path> <checkpoint> <minimum difficulty> <network> <ui_iteration> <ui_authorizers>
```

where `<destination path>` is the target directory (which must not exist); `<checkpoint>`, `<minimum difficulty>` and `<network>` are the build parameters for the signer app; `<ui_iteration>` is the signer version iteration with which the UI must be built; and `<ui_authorizers>` is the basename of the authorizers header file. The script will build the ledger apps (signer and UI) as well as the required middleware. Then it will output all of the necessary distribution artifacts, including the aforementioned builds, to the destination path given.
where `<destination path>` is the target directory (which must not exist); `<checkpoint>`, `<minimum difficulty>` and `<network>` are the build parameters for the signer app; `<ui_iteration>` is the signer version iteration with which the UI must be built; and `<ui_authorizers>` is the basename of the authorizers header file. The script will build the Ledger apps (signer and UI) as well as the required middleware. Then it will output all of the necessary distribution artifacts, including the aforementioned builds, to the destination path given.

For example, to build a distribution with checkpoint `0x00f06dcff26ec8b4d373fbd53ee770e9348d9bd6a247ad4c86e82ceb3c2130ac`, minimum cumulative difficulty of `0x7c50933098`, `testnet` network, signer iteration `43` and authorizers header file `testing`, issue:

Expand Down
2 changes: 1 addition & 1 deletion docs/blockchain-bookkeeping.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ In order to update the `blockchain_state` of an *initialized* powHSM device, we

#### Context and preliminaries

The following constants are assumed to be predefined (and hardcoded into the physical device's firmware):
The following constants are assumed to be predefined (and hardcoded into the device's firmware):

- `MINIMUM_CUMULATIVE_DIFFICULTY`: The minimum cumulative block difficulty to consider a block sufficiently confirmed.
- `MAXIMUM_BLOCK_DIFFICULTY`: The maximum allowed difficulty for any given block.
Expand Down
10 changes: 5 additions & 5 deletions docs/heartbeat.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ acknowledge the state of a running powHSM installation.

## Heartbeat and attestation

Just like the attestation process, the heartbeat feature makes use of the Ledger Nano S
endorsement mechanism to prove to the end user a given state of the device and its running
applications. Nevertheless, and as opposed to the attestation process, the heartbeat
feature itself does not include the chain of certification all the way up to the
manufacturer (Ledger itself), but rather leverages the previously generated attestation
Just like the attestation process, the heartbeat feature makes use of the Hardware
Abstraction Layer's endorsement mechanism to prove to the end user a given state of the
device and its running applications. Nevertheless, and as opposed to the attestation
process, the heartbeat feature itself does not include the chain of certification all the
way up to the manufacturer, but rather leverages the previously generated attestation
process artifacts for this purpose. For more details about this and the attestation
process, see [the attestation documentation](./attestation.md).

Expand Down
22 changes: 11 additions & 11 deletions docs/signer-authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

## Abstract

This document describes the mechanisms by which the UI component authorizes versions of
the Signer component to run on a device. It is an improvement to the authorization scheme
present up to version 2.3 in that it introduces an "N of M" signatures requirement for the
authorization of any given Signer version, enhancing security and decentralization of the
powHSM solution as a whole. It is also an improvement over the "downgrade prevention"
mechanism (also present up to version 2.3), in that it removes the limit present in the
feature up to then.
This document describes the mechanisms by which the Ledger Nano S UI application
authorizes versions of the Signer application to run on an onboarded device. It is an
improvement to the authorization scheme present up to version 2.3 in that it introduces an
"N of M" signatures requirement for the authorization of any given Signer version,
enhancing security and decentralization of the powHSM solution as a whole. It is also an
improvement over the "downgrade prevention" mechanism (also present up to version 2.3), in
that it removes the limit present in the feature up to then.

## Motivation

Up to version 2.3 of the UI, each new version of the Signer component is authorized using
the Ledger Nano S's custom certificate authority (CCA for short), represented by a unique
ECDSA pair. If lost or stolen, there would be a need to generate a new pair, reset the
existing devices and update the RSK federation in order to issue new Signer versions.
existing devices and update the RSK PowPeg in order to issue new Signer versions.
Moreover, the downgrade prevention mechanism, which is based on a finite blacklist of
previous signer versions, rolls over after 100 versions, which also implies the need to
reset existing devices, the CCA and update the RSK federation in order to clear said list
reset existing devices, the CCA and update the RSK PowPeg in order to clear said list
and move past the 100 signer version mark. Even though at the time of writing the 100
signer version mark is very far away, it would eventually become an issue.

Expand All @@ -36,7 +36,7 @@ has no real use beyond the device setup, a scenario where the user tampers with
process and uses a CCA of his choosing would have no real impact on the device's security.
The UI and Signer are still protected from counterfeiting by the [attestation
process](./attestation.md), which is the ultimate source of truth when it comes to
determining RSK's federation members.
determining RSK's PowPeg members.

## Implementation

Expand Down Expand Up @@ -92,7 +92,7 @@ of:

### Considerations

It is important to mention that, when distributing UI and Signer for a new federation
It is important to mention that, when distributing UI and Signer for a new PowPeg
member, the UI should be built with the `authorized_signer_iteration` corresponding to the
current Signer version, preventing the installation of older Signers using old
authorization witnesses.
Expand Down
Loading

0 comments on commit 6b191e5

Please sign in to comment.