Skip to content

Commit

Permalink
Incorporate latest master (d85258d) changes:
Browse files Browse the repository at this point in the history
- Fix verify_attestation.py to accept distinct versions for UI and Signer (#197)
- Version 5.2.0 release (#194)
- Removing compilation products from repository (#200)
  • Loading branch information
amendelzon committed Oct 22, 2024
1 parent 8984008 commit 25b639d
Show file tree
Hide file tree
Showing 44 changed files with 117 additions and 38 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
run: |
aws s3 sync \
middleware/coverage/ \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.1.x/middleware_coverage_report \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.2.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 @@ -49,7 +49,7 @@ jobs:
run: |
aws s3 sync \
firmware/coverage/output/ \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.1.x/firmware_coverage_report \
s3://${{ secrets.CODECOVERAGE_S3_BUCKET }}/powhsm_5.2.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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## [5.2.0] - 09/09/2024

### Features/enhancements

- Added "screen saver" mode to signer app to extend display lifetime
- Decoupled business and I/O (aka communication) layers in preparation for multiple platforms
- Improved HAL directory structure to accomodate for testing different platform implementations

### Fixes

- Fixed middleware docker image build
- Fixed verify_attestaion.py to allow distinct versions for UI and Signer
- Incidentally bumped urllib3, certifi to address dependabot findings

## [5.1.0] - 01/07/2024

### Features/enhancements
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
![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.1.x/middleware_coverage_report/badge.json)](https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.1.x/middleware_coverage_report/index.html)
[![Firmware coverage](https://img.shields.io/endpoint?url=https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.1.x/firmware_coverage_report/badge.json)](https://d16sboe9lzo4ru.cloudfront.net/powhsm_5.1.x/firmware_coverage_report/index.html)
[![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)

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

Expand Down
4 changes: 2 additions & 2 deletions docs/attestation.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Before diving into the UI attestation, it is important to recall a few relevant

To generate the attestation, the UI uses the configured attestation scheme to sign a message generated by the concatenation of:

- A predefined header (`HSM:UI:5.1`).
- A predefined header (`HSM:UI:5.2`).
- A 32 byte user-defined value. By default, the attestation generation client supplies the latest RSK block hash as this value, so it can then be used as a minimum timestamp reference for the attestation generation.
- The compressed public key corresponding to the private key obtained by deriving the generated seed with the BIP32 path `m/44'/0'/0'/0/0` (normally used as the BTC key by the Signer application).
- The hash of the currently authorized Signer version.
Expand All @@ -66,7 +66,7 @@ As a consequence of the aforementioned features, this message guarantees that th

### Signer attestation

To generate the attestation, the Signer uses the configured attestation scheme to sign a message containing a predefined header (`HSM:SIGNER:5.1`) and the `sha256sum` of the concatenation of the authorized public keys (see the [protocol](./protocol.md) for details on this) lexicographically ordered by their UTF-encoded derivation path. This message guarantees that the device is running a specific version of the Signer and that those keys are in control of the ledger device.
To generate the attestation, the Signer uses the configured attestation scheme to sign a message containing a predefined header (`HSM:SIGNER:5.2`) and the `sha256sum` of the concatenation of the authorized public keys (see the [protocol](./protocol.md) for details on this) lexicographically ordered by their UTF-encoded derivation path. This message guarantees that the device is running a specific version of the Signer and that those keys are in control of the ledger device.

## Attestation file format

Expand Down
4 changes: 2 additions & 2 deletions docs/heartbeat.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ certification -- to verify.
To generate the heartbeat, the Signer uses the configured endorsement scheme to sign a
message generated by the concatenation of:

- A predefined header (`HSM:SIGNER:HB:5.1:`).
- A predefined header (`HSM:SIGNER:HB:5.2:`).
- A 32 byte value corresponding to the currently known best block hash.
- A value corresponding to the first 8 bytes of the last successful authorized signed
operation's transaction hash.
Expand All @@ -57,7 +57,7 @@ transactions.
To generate the heartbeat, the UI uses the configured endorsement scheme to sign a message
generated by the concatenation of:

- A predefined header (`HSM:UI:HB:5.1:`).
- A predefined header (`HSM:UI:HB:5.2:`).
- A 32 byte user-defined value. This value can vary and could be, for example, used as a
timestamp reference for the end user.
- A 32 byte value corresponding to the currently authorized Signer hash.
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/ledger/ui/src/attestation.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef enum {
} err_code_att_t;

// Attestation message prefix
#define ATT_MSG_PREFIX "HSM:UI:5.1"
#define ATT_MSG_PREFIX "HSM:UI:5.2"
#define ATT_MSG_PREFIX_LENGTH (sizeof(ATT_MSG_PREFIX) - sizeof(""))

// User defined value size
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/ledger/ui/src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

// Version and patchlevel
#define VERSION_MAJOR 0x05
#define VERSION_MINOR 0x01
#define VERSION_MINOR 0x02
#define VERSION_PATCH 0x00

#endif // __DEFS_H
2 changes: 1 addition & 1 deletion firmware/src/ledger/ui/src/ui_heartbeat.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ typedef enum {
} err_code_ui_heartbeat_t;

// Heartbeat message prefix
#define UI_HEARTBEAT_MSG_PREFIX "HSM:UI:HB:5.1:"
#define UI_HEARTBEAT_MSG_PREFIX "HSM:UI:HB:5.2:"
#define UI_HEARTBEAT_MSG_PREFIX_LENGTH \
(sizeof(UI_HEARTBEAT_MSG_PREFIX) - sizeof(""))

Expand Down
8 changes: 4 additions & 4 deletions firmware/src/ledger/ui/test/attestation/test_attestation.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void test_get_attestation_ud_value() {
assert(3 == get_attestation(rx, &G_att_ctx));
// PREFIX + UD_VALUE + Compressed pubkey + Signer hash + Iteration
ASSERT_MEMCMP(
"HSM:UI:5.1"
"HSM:UI:5.2"
"\x46\x8d\xa8\x7f\x6a\x85\xe6\x40\x93\x27\xe1\x17\xe8\xc7\xd2\x11\x0c"
"\x73\x60\x22\x26\xbb\xb5\xed\xf2\x7d\x98\xc8\xa3\x1b\xcc\xf0"
"\x02\xe6\xd7\x1d\x5c\x2b\x06\x36\x03\x53\xfb\xd8\x22\x7a\xb3\xab\xfc"
Expand Down Expand Up @@ -208,7 +208,7 @@ void test_get_attestation_get_msg() {
*N_onboarded_ui = 1;
memcpy(
G_att_ctx.msg,
"HSM:UI:5.1"
"HSM:UI:5.2"
"\x46\x8d\xa8\x7f\x6a\x85\xe6\x40\x93\x27\xe1\x17\xe8\xc7\xd2\x11\x0c"
"\x73\x60\x22\x26\xbb\xb5\xed\xf2\x7d\x98\xc8\xa3\x1b\xcc\xf0"
"\x03\xe6\xd7\x1d\x5c\x2b\x06\x36\x03\x53\xfb\xd8\x22\x7a\xb3\xab\xfc"
Expand All @@ -225,7 +225,7 @@ void test_get_attestation_get_msg() {
assert((APDU_TOTAL_DATA_SIZE_OUT + 3) == get_attestation(rx, &G_att_ctx));
ASSERT_APDU(
"\x80\x50\x02\x01"
"HSM:UI:5.1"
"HSM:UI:5.2"
"\x46\x8d\xa8\x7f\x6a\x85\xe6\x40\x93\x27\xe1\x17\xe8\xc7\xd2\x11\x0c"
"\x73\x60\x22\x26\xbb\xb5\xed\xf2\x7d\x98\xc8\xa3\x1b\xcc\xf0"
"\x03\xe6\xd7\x1d\x5c\x2b\x06\x36\x03\x53\xfb\xd8\x22\x7a\xb3\xab\xfc"
Expand All @@ -249,7 +249,7 @@ void test_get_attestation_get_msg_wrong_state() {
*N_onboarded_ui = 1;
memcpy(
&G_att_ctx.msg,
"HSM:UI:5.1"
"HSM:UI:5.2"
"\x46\x8d\xa8\x7f\x6a\x85\xe6\x40\x93\x27\xe1\x17\xe8\xc7\xd2\x11\x0c"
"\x73\x60\x22\x26\xbb\xb5\xed\xf2\x7d\x98\xc8\xa3\x1b\xcc\xf0"
"\x03\xe6\xd7\x1d\x5c\x2b\x06\x36\x03\x53\xfb\xd8\x22\x7a\xb3\xab\xfc"
Expand Down
4 changes: 2 additions & 2 deletions firmware/src/ledger/ui/test/onboard/test_onboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,11 @@ void test_is_onboarded() {

G_device_onboarded = true;
assert(5 == is_onboarded());
ASSERT_APDU("\x80\x01\x05\x01\x00");
ASSERT_APDU("\x80\x01\x05\x02\x00");

G_device_onboarded = false;
assert(5 == is_onboarded());
ASSERT_APDU("\x80\x00\x05\x01\x00");
ASSERT_APDU("\x80\x00\x05\x02\x00");
}

int main() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ void test_op_ud_value() {

assert_ok("\x80\x60\x01");

const char expected_msg[] = "HSM:UI:HB:5.1:" // Prefix
const char expected_msg[] = "HSM:UI:HB:5.2:" // Prefix
"\x11" // UD
"\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22" // .
"\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22" // .
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/powhsm/src/attestation.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
// -----------------------------------------------------------------------

// Attestation message prefix
#define ATT_MSG_PREFIX "HSM:SIGNER:5.1"
#define ATT_MSG_PREFIX "HSM:SIGNER:5.2"
#define ATT_MSG_PREFIX_LENGTH (sizeof(ATT_MSG_PREFIX) - sizeof(""))

// -----------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/powhsm/src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

// Version and patchlevel
#define VERSION_MAJOR 0x05
#define VERSION_MINOR 0x01
#define VERSION_MINOR 0x02
#define VERSION_PATCH 0x00

#endif // __DEFS_H
2 changes: 1 addition & 1 deletion firmware/src/powhsm/src/heartbeat.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ typedef enum {
} err_code_heartbeat_t;

// Heartbeat message prefix
#define HEARTBEAT_MSG_PREFIX "HSM:SIGNER:HB:5.1:"
#define HEARTBEAT_MSG_PREFIX "HSM:SIGNER:HB:5.2:"
#define HEARTBEAT_MSG_PREFIX_LENGTH (sizeof(HEARTBEAT_MSG_PREFIX) - sizeof(""))

// User-defined value size
Expand Down
Binary file removed firmware/src/powhsm/test/btcscript/btcscript.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btcscript/hex_reader.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btcscript/test.out
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btcscript/test_btcscript.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btcscript/test_fwk.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btctx/hex_reader.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btctx/svarint.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/btctx/test_fwk.o
Binary file not shown.
Binary file not shown.
Binary file removed firmware/src/powhsm/test/difficulty/test_fwk.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/sha256/sha256.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/sha256/test.out
Binary file not shown.
Binary file removed firmware/src/powhsm/test/sha256/test_fwk.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/sha256/test_sha256.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/srlp/test_fwk.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/srlp/test_srlp.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/svarint/svarint.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/svarint/test.out
Binary file not shown.
Binary file removed firmware/src/powhsm/test/svarint/test_fwk.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/svarint/test_svarint.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/trie/hex_reader.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/trie/svarint.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/trie/test_fwk.o
Binary file not shown.
Binary file removed firmware/src/powhsm/test/trie/test_trie.o
Binary file not shown.
2 changes: 1 addition & 1 deletion firmware/test/cases/heartbeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@


class Heartbeat(TestCase):
EXPECTED_HEADER = "HSM:SIGNER:HB:5.1:"
EXPECTED_HEADER = "HSM:SIGNER:HB:5.2:"
EHL = len(EXPECTED_HEADER)

@classmethod
Expand Down
33 changes: 24 additions & 9 deletions middleware/admin/verify_attestation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
import json
import hashlib
import secp256k1 as ec
import re
from .misc import info, head, AdminError
from .utils import is_nonempty_hex_string
from .certificate import HSMCertificate


UI_MESSAGE_HEADER = b"HSM:UI:5.1"
SIGNER_MESSAGE_HEADER = b"HSM:SIGNER:5.1"
UI_MESSAGE_HEADER_REGEX = re.compile(b"^HSM:UI:(5.[0-9])")
SIGNER_MESSAGE_HEADER_REGEX = re.compile(b"^HSM:SIGNER:(5.[0-9])")
UI_DERIVATION_PATH = "m/44'/0'/0'/0/0"
UD_VALUE_LENGTH = 32
PUBKEY_COMPRESSED_LENGTH = 33
Expand All @@ -45,6 +46,14 @@
"dad609"


def match_ui_message_header(ui_message):
return UI_MESSAGE_HEADER_REGEX.match(ui_message)


def match_signer_message_header(signer_message):
return SIGNER_MESSAGE_HEADER_REGEX.match(signer_message)


def do_verify_attestation(options):
head("### -> Verify UI and Signer attestations", fill="#")

Expand Down Expand Up @@ -121,12 +130,14 @@ def do_verify_attestation(options):

ui_message = bytes.fromhex(ui_result[1])
ui_hash = bytes.fromhex(ui_result[2])
mh_len = len(UI_MESSAGE_HEADER)
if ui_message[:mh_len] != UI_MESSAGE_HEADER:
mh_match = match_ui_message_header(ui_message)
if mh_match is None:
raise AdminError(
f"Invalid UI attestation message header: {ui_message[:mh_len].hex()}")
f"Invalid UI attestation message header: {ui_message.hex()}")
mh_len = len(mh_match.group(0))

# Extract UD value, UI public key and signer version from message
# Extract UI version, UD value, UI public key and signer version from message
ui_version = mh_match.group(1)
ud_value = ui_message[mh_len:mh_len + UD_VALUE_LENGTH].hex()
ui_public_key = ui_message[mh_len + UD_VALUE_LENGTH:mh_len + UD_VALUE_LENGTH +
PUBKEY_COMPRESSED_LENGTH].hex()
Expand All @@ -147,6 +158,7 @@ def do_verify_attestation(options):
f"Authorized signer hash: {signer_hash}",
f"Authorized signer iteration: {signer_iteration}",
f"Installed UI hash: {ui_hash.hex()}",
f"Installed UI version: {ui_version.decode()}",
],
fill="-",
)
Expand All @@ -162,23 +174,26 @@ def do_verify_attestation(options):

signer_message = bytes.fromhex(signer_result[1])
signer_hash = bytes.fromhex(signer_result[2])
mh_len = len(SIGNER_MESSAGE_HEADER)
if signer_message[:mh_len] != SIGNER_MESSAGE_HEADER:
mh_match = match_signer_message_header(signer_message)
if mh_match is None:
raise AdminError(
f"Invalid Signer attestation message header: {signer_message[:mh_len].hex()}")
f"Invalid Signer attestation message header: {signer_message.hex()}")

mh_len = len(mh_match.group(0))
if signer_message[mh_len:] != pubkeys_hash:
reported = signer_message[mh_len:].hex()
raise AdminError(
f"Signer attestation public keys hash mismatch: expected {pubkeys_hash.hex()}"
f" but attestation reports {reported}"
)

signer_version = mh_match.group(1)
head(
["Signer verified with public keys:"] + pubkeys_output + [
"",
f"Hash: {signer_message[mh_len:].hex()}",
f"Installed Signer hash: {signer_hash.hex()}",
f"Installed Signer version: {signer_version.decode()}",
],
fill="-",
)
4 changes: 2 additions & 2 deletions middleware/ledger/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@

class HSM2ProtocolLedger(HSM2Protocol):
# Current manager supported versions for HSM UI and HSM SIGNER (<=)
UI_VERSION = HSM2FirmwareVersion(5, 1, 0)
APP_VERSION = HSM2FirmwareVersion(5, 1, 0)
UI_VERSION = HSM2FirmwareVersion(5, 2, 0)
APP_VERSION = HSM2FirmwareVersion(5, 2, 0)

# Amount of time to wait to make sure the app is opened
OPEN_APP_WAIT = 1 # second
Expand Down
Loading

0 comments on commit 25b639d

Please sign in to comment.