Skip to content

Commit

Permalink
feature: message signing (CIP-8)
Browse files Browse the repository at this point in the history
  • Loading branch information
janmazak committed Feb 26, 2024
1 parent 8b0896f commit 92add78
Show file tree
Hide file tree
Showing 31 changed files with 1,008 additions and 33 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [7.1.0](TBD) - [TBD]

Message signing (CIP-8)

### Added

- support for basic message signing (CIP-8, CIP-30)

### Changed

- usage of chunks of maximum allowed size is now enforced (datums and reference scripts in outputs)
- TODO updated list of native tokens recognized by the app with correct decimal places


## [7.0.2](TBD) - [TBD]

Conway era
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
APPNAME = "Cardano ADA"

APPVERSION_M = 7
APPVERSION_N = 0
APPVERSION_P = 2
APPVERSION_N = 1
APPVERSION_P = 0
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"

ifeq ($(BOLOS_SDK),)
Expand Down
9 changes: 6 additions & 3 deletions fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ set(CARDANO_SOURCE
${CARDANO_PATH}/src/securityPolicy.c
${CARDANO_PATH}/src/signCVote.c
${CARDANO_PATH}/src/signCVote_ui.c
${CARDANO_PATH}/src/signMsg.c
${CARDANO_PATH}/src/signMsg_ui.c
${CARDANO_PATH}/src/signOpCert.c
${CARDANO_PATH}/src/signTx.c
${CARDANO_PATH}/src/signTxCVoteRegistration.c
Expand Down Expand Up @@ -153,7 +155,7 @@ add_compile_definitions(
APP_FEATURE_TOKEN_MINTING
)

set(SOURCE
set(SOURCE
${UX_SOURCE}
${CARDANO_SOURCE}
./src/os_mocks.c
Expand All @@ -169,13 +171,14 @@ set(harnesses
deriveNativeScriptHash_harness
getPublicKeys_harness
signCVote_harness
signMsg_harness
signOpCert_harness
signTx_harness
)

foreach(harness IN LISTS harnesses)
add_executable(${harness}
add_executable(${harness}
./src/${harness}.c
)
)
target_link_libraries(${harness} PUBLIC cardano)
endforeach()
1 change: 1 addition & 0 deletions fuzzing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ deriveAddress_harness
deriveNativeScriptHash_harness
getPublicKeys_harness
signCVote_harness
signMsg_harness
signOpCert_harness
signTx_harness
```
Expand Down
52 changes: 52 additions & 0 deletions fuzzing/src/signMsg_harness.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <cx.h>
#include <os_io.h>
#include <signMsg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

uint8_t G_io_apdu_buffer[IO_APDU_BUFFER_SIZE];

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {

UX_INIT();

uint8_t *input = NULL;
bool is_first = true;

while (size > 5) {
io_state = IO_EXPECT_NONE;
uint8_t ins = data[0];
uint8_t p1 = data[1];
uint8_t p2 = data[2];
uint8_t lc = data[3];

data += sizeof(uint8_t) * 4;
size -= sizeof(uint8_t) * 4;

if (size < lc) {
return 0;
}

uint8_t *input = malloc(lc);
if (input == NULL) {
return 0;
}

memcpy(input, data, lc);

data += lc;
size -= lc;

BEGIN_TRY {
TRY { signMsg_handleAPDU(p1, p2, input, lc, is_first); }
CATCH_ALL {}
FINALLY {}
}
END_TRY;

is_first = false;
free(input);
}
return 0;
}
13 changes: 13 additions & 0 deletions src/bufView.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,18 @@ static inline int64_t parse_int64be(read_view_t* view)
return (int64_t) parse_u8be(view);
};

static inline bool parse_bool(read_view_t* view)
{
uint8_t value = parse_u1be(view);

switch (value) {
case 0:
return false;
case 1:
return true;
default:
THROW(ERR_INVALID_DATA);
}
}

#endif // H_CARDANO_APP_BUF_VIEW
9 changes: 9 additions & 0 deletions src/cardano.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

STATIC_ASSERT(LOVELACE_MAX_SUPPLY < LOVELACE_INVALID, "bad LOVELACE_INVALID");

#define ED25519_SIGNATURE_LENGTH 64

#define ADDRESS_KEY_HASH_LENGTH 28
#define POOL_KEY_HASH_LENGTH 28
#define VRF_KEY_HASH_LENGTH 32
Expand Down Expand Up @@ -180,4 +182,11 @@ typedef enum {

#endif // APP_FEATURE_NATIVE_SCRIPT_HASH

// ============================== CIP8 MESSAGE SIGNING ==============================

typedef enum {
CIP8_ADDRESS_FIELD_ADDRESS = 1,
CIP8_ADDRESS_FIELD_KEYHASH = 2,
} cip8_address_field_type_t;

#endif // H_CARDANO_APP_CARDANO
2 changes: 2 additions & 0 deletions src/handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "deriveAddress.h"
#include "deriveNativeScriptHash.h"
#include "signTx.h"
#include "signMsg.h"
#include "signOpCert.h"
#include "signCVote.h"

Expand Down Expand Up @@ -39,6 +40,7 @@ handler_fn_t* lookupHandler(uint8_t ins)
CASE(0x22, signOpCert_handleAPDU);
#endif // APP_FEATURE_OPCERT
CASE(0x23, signCVote_handleAPDU);
CASE(0x24, signMsg_handleAPDU);

#ifdef DEVEL
// 0xF* - debug_mode related
Expand Down
11 changes: 7 additions & 4 deletions src/messageSigning.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#include "securityPolicy.h"
#include "crypto.h"

static void signRawMessageWithPath(bip44_path_t* pathSpec,
const uint8_t* messageBuffer, size_t messageSize,
uint8_t* outBuffer, size_t outSize)
void signRawMessageWithPath(bip44_path_t* pathSpec,
const uint8_t* messageBuffer, size_t messageSize,
uint8_t* outBuffer, size_t outSize)
{
size_t sigLen = outSize;

Expand All @@ -23,6 +23,10 @@ static void signRawMessageWithPath(bip44_path_t* pathSpec,

#ifndef FUZZING
{
TRACE("signing with path:");
BIP44_PRINTF(pathSpec);
PRINTF("\n");

cx_err_t error = crypto_eddsa_sign(pathSpec->path,
pathSpec->length,
messageBuffer,
Expand All @@ -37,7 +41,6 @@ static void signRawMessageWithPath(bip44_path_t* pathSpec,
#endif

ASSERT(sigLen == ED25519_SIGNATURE_LENGTH);

}

// sign the given hash by the private key derived according to the given path
Expand Down
4 changes: 4 additions & 0 deletions src/messageSigning.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

#include "bip44.h"

void signRawMessageWithPath(bip44_path_t* pathSpec,
const uint8_t* messageBuffer, size_t messageSize,
uint8_t* outBuffer, size_t outSize);

void getWitness(bip44_path_t* pathSpec,
const uint8_t* txHashBuffer, size_t txHashSize,
uint8_t* outBuffer, size_t outSize);
Expand Down
8 changes: 4 additions & 4 deletions src/runTests.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#ifdef DEVEL

#ifndef H_CARDANO_APP_RUN_TESTS
#define H_CARDANO_APP_RUN_TESTS

#ifdef DEVEL

#include "handlers.h"

handler_fn_t handleRunTests;

#endif // H_CARDANO_APP_RUN_TESTS

#endif // DEVEL

#endif // H_CARDANO_APP_RUN_TESTS
43 changes: 43 additions & 0 deletions src/securityPolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2183,3 +2183,46 @@ security_policy_t policyForSignCVoteWitness(bip44_path_t* path)
break;
}
}

security_policy_t policyForSignMsg(
const bip44_path_t* witnessPath,
cip8_address_field_type_t addressFieldType,
const addressParams_t* addressParams
)
{
switch (bip44_classifyPath(witnessPath)) {
case PATH_ORDINARY_SPENDING_KEY:
case PATH_ORDINARY_STAKING_KEY:
case PATH_MULTISIG_SPENDING_KEY:
case PATH_MULTISIG_STAKING_KEY:
case PATH_MINT_KEY:
case PATH_DREP_KEY:
case PATH_COMMITTEE_COLD_KEY:
case PATH_COMMITTEE_HOT_KEY:
case PATH_POOL_COLD_KEY:
// OK
break;
default:
DENY();
break;
}

if (addressFieldType == CIP8_ADDRESS_FIELD_ADDRESS) {
DENY_UNLESS(isValidAddressParams(addressParams));

switch (addressParams->type) {
case BASE_PAYMENT_KEY_STAKE_KEY:
case BASE_PAYMENT_KEY_STAKE_SCRIPT:
case REWARD_KEY:
case ENTERPRISE_KEY:
// OK
break;

default:
DENY();
break;
}
}

PROMPT();
}
6 changes: 6 additions & 0 deletions src/securityPolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,10 @@ security_policy_t policyForSignCVoteInit();
security_policy_t policyForSignCVoteConfirm();
security_policy_t policyForSignCVoteWitness(bip44_path_t* path);

security_policy_t policyForSignMsg(
const bip44_path_t* witnessPath,
cip8_address_field_type_t addressFieldType,
const addressParams_t* addressParams
);

#endif // H_CARDANO_APP_SECURITY_POLICY
4 changes: 2 additions & 2 deletions src/signCVote.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void signCVote_handleInitAPDU(
default:
THROW(ERR_NOT_IMPLEMENTED);
}
handleInit_ui_runStep();
signCVote_handleInit_ui_runStep();
}

// ============================== VOTECAST CHUNK ==============================
Expand Down Expand Up @@ -190,7 +190,7 @@ void signCVote_handleConfirmAPDU(
}
}

handleConfirm_ui_runStep();
signCVote_handleConfirm_ui_runStep();
}

// ============================== WITNESS ==============================
Expand Down
8 changes: 4 additions & 4 deletions src/signCVote_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ static ins_sign_cvote_context_t* ctx = &(instructionState.signCVoteContext);

// ============================== INIT ==============================

void handleInit_ui_runStep()
void signCVote_handleInit_ui_runStep()
{
ui_callback_fn_t* this_fn = handleInit_ui_runStep;
ui_callback_fn_t* this_fn = signCVote_handleInit_ui_runStep;

UI_STEP_BEGIN(ctx->ui_step, this_fn);

Expand Down Expand Up @@ -92,11 +92,11 @@ void handleInit_ui_runStep()

// ============================== CONFIRM ==============================

void handleConfirm_ui_runStep()
void signCVote_handleConfirm_ui_runStep()
{
TRACE("UI step %d", ctx->ui_step);
TRACE_STACK_USAGE();
ui_callback_fn_t* this_fn = handleConfirm_ui_runStep;
ui_callback_fn_t* this_fn = signCVote_handleConfirm_ui_runStep;

UI_STEP_BEGIN(ctx->ui_step, this_fn);

Expand Down
5 changes: 3 additions & 2 deletions src/signCVote_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define H_CARDANO_APP_SIGN_CVOTE_UI

#include "uiHelpers.h"

// ============================== INIT ==============================

enum {
Expand All @@ -13,7 +14,7 @@ enum {
HANDLE_INIT_INVALID,
};

void handleInit_ui_runStep();
void signCVote_handleInit_ui_runStep();

// ============================== CONFIRM ==============================

Expand All @@ -23,7 +24,7 @@ enum {
HANDLE_CONFIRM_STEP_INVALID,
};

void handleConfirm_ui_runStep();
void signCVote_handleConfirm_ui_runStep();

// ============================== WITNESS ==============================

Expand Down
Loading

0 comments on commit 92add78

Please sign in to comment.