diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index d28212e4..1be1df43 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -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 @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e33d9f..d680f359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 6708e24b..b4f7c6b6 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/docs/attestation.md b/docs/attestation.md index 9edfac85..9d30255c 100644 --- a/docs/attestation.md +++ b/docs/attestation.md @@ -52,7 +52,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. @@ -62,7 +62,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 diff --git a/docs/heartbeat.md b/docs/heartbeat.md index 9233b6d2..1d521ad6 100644 --- a/docs/heartbeat.md +++ b/docs/heartbeat.md @@ -37,7 +37,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. @@ -53,7 +53,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. diff --git a/firmware/src/ledger/ui/src/attestation.h b/firmware/src/ledger/ui/src/attestation.h index 8eeb5413..bb9230e3 100644 --- a/firmware/src/ledger/ui/src/attestation.h +++ b/firmware/src/ledger/ui/src/attestation.h @@ -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 diff --git a/firmware/src/ledger/ui/src/defs.h b/firmware/src/ledger/ui/src/defs.h index d9f2e9ff..afb7635b 100644 --- a/firmware/src/ledger/ui/src/defs.h +++ b/firmware/src/ledger/ui/src/defs.h @@ -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 diff --git a/firmware/src/ledger/ui/src/ui_heartbeat.h b/firmware/src/ledger/ui/src/ui_heartbeat.h index d5f873da..e42db887 100644 --- a/firmware/src/ledger/ui/src/ui_heartbeat.h +++ b/firmware/src/ledger/ui/src/ui_heartbeat.h @@ -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("")) diff --git a/firmware/src/ledger/ui/test/attestation/test_attestation.c b/firmware/src/ledger/ui/test/attestation/test_attestation.c index eae3b102..31333927 100644 --- a/firmware/src/ledger/ui/test/attestation/test_attestation.c +++ b/firmware/src/ledger/ui/test/attestation/test_attestation.c @@ -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" @@ -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" @@ -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" @@ -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" diff --git a/firmware/src/ledger/ui/test/onboard/test_onboard.c b/firmware/src/ledger/ui/test/onboard/test_onboard.c index fe686a05..1e9ccebc 100644 --- a/firmware/src/ledger/ui/test/onboard/test_onboard.c +++ b/firmware/src/ledger/ui/test/onboard/test_onboard.c @@ -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() { diff --git a/firmware/src/ledger/ui/test/ui_heartbeat/test_ui_heartbeat.c b/firmware/src/ledger/ui/test/ui_heartbeat/test_ui_heartbeat.c index 810b6a0b..36fe5518 100644 --- a/firmware/src/ledger/ui/test/ui_heartbeat/test_ui_heartbeat.c +++ b/firmware/src/ledger/ui/test/ui_heartbeat/test_ui_heartbeat.c @@ -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" // . diff --git a/firmware/src/powhsm/src/attestation.h b/firmware/src/powhsm/src/attestation.h index 6d405300..23d1171b 100644 --- a/firmware/src/powhsm/src/attestation.h +++ b/firmware/src/powhsm/src/attestation.h @@ -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("")) // ----------------------------------------------------------------------- diff --git a/firmware/src/powhsm/src/defs.h b/firmware/src/powhsm/src/defs.h index a78e7ca0..7413c6ee 100644 --- a/firmware/src/powhsm/src/defs.h +++ b/firmware/src/powhsm/src/defs.h @@ -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 diff --git a/firmware/src/powhsm/src/heartbeat.h b/firmware/src/powhsm/src/heartbeat.h index c9a52133..1026f2b1 100644 --- a/firmware/src/powhsm/src/heartbeat.h +++ b/firmware/src/powhsm/src/heartbeat.h @@ -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 diff --git a/firmware/test/cases/heartbeat.py b/firmware/test/cases/heartbeat.py index 3b838106..09bad8d2 100644 --- a/firmware/test/cases/heartbeat.py +++ b/firmware/test/cases/heartbeat.py @@ -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 diff --git a/middleware/ledger/protocol.py b/middleware/ledger/protocol.py index 738cbab5..53d6dcad 100644 --- a/middleware/ledger/protocol.py +++ b/middleware/ledger/protocol.py @@ -37,8 +37,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 diff --git a/middleware/tests/admin/test_verify_attestation.py b/middleware/tests/admin/test_verify_attestation.py index b3b0286f..3b1968ab 100644 --- a/middleware/tests/admin/test_verify_attestation.py +++ b/middleware/tests/admin/test_verify_attestation.py @@ -37,8 +37,8 @@ logging.disable(logging.CRITICAL) EXPECTED_UI_DERIVATION_PATH = "m/44'/0'/0'/0/0" -SIGNER_HEADER = b"HSM:SIGNER:5.1" -UI_HEADER = b"HSM:UI:5.1" +SIGNER_HEADER = b"HSM:SIGNER:5.2" +UI_HEADER = b"HSM:UI:5.2" @patch("sys.stdout.write") @@ -114,7 +114,7 @@ def test_verify_attestation(self, f"Authorized signer hash: {'cc'*32}", "Authorized signer iteration: 291", f"Installed UI hash: {'ee'*32}", - "Installed UI version: 5.1", + "Installed UI version: 5.2", ], fill="-", ) @@ -125,7 +125,7 @@ def test_verify_attestation(self, "", f"Hash: {self.pubkeys_hash.hex()}", f"Installed Signer hash: {'ff'*32}", - "Installed Signer version: 5.1", + "Installed Signer version: 5.2", ], fill="-", ) diff --git a/middleware/tests/ledger/test_protocol.py b/middleware/tests/ledger/test_protocol.py index 3efb7ea6..13de3f4f 100644 --- a/middleware/tests/ledger/test_protocol.py +++ b/middleware/tests/ledger/test_protocol.py @@ -49,7 +49,7 @@ def setUp(self): self.dongle.disconnect = Mock() self.dongle.is_onboarded = Mock(return_value=True) self.dongle.get_current_mode = Mock(return_value=HSM2Dongle.MODE.SIGNER) - self.dongle.get_version = Mock(return_value=HSM2FirmwareVersion(5, 1, 0)) + self.dongle.get_version = Mock(return_value=HSM2FirmwareVersion(5, 2, 0)) self.dongle.get_signer_parameters = Mock(return_value=Mock( min_required_difficulty=123)) self.protocol = HSM2ProtocolLedger(self.pin, self.dongle) diff --git a/middleware/tests/ledger/test_protocol_v1.py b/middleware/tests/ledger/test_protocol_v1.py index be1d0cab..9a98ee65 100644 --- a/middleware/tests/ledger/test_protocol_v1.py +++ b/middleware/tests/ledger/test_protocol_v1.py @@ -47,7 +47,7 @@ def setUp(self): self.dongle.disconnect = Mock() self.dongle.is_onboarded = Mock(return_value=True) self.dongle.get_current_mode = Mock(return_value=HSM2Dongle.MODE.SIGNER) - self.dongle.get_version = Mock(return_value=HSM2FirmwareVersion(5, 1, 0)) + self.dongle.get_version = Mock(return_value=HSM2FirmwareVersion(5, 2, 0)) self.dongle.get_signer_parameters = Mock(return_value=Mock( min_required_difficulty=123)) self.protocol = HSM1ProtocolLedger(self.pin, self.dongle)