Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #64

Merged
merged 21 commits into from
Sep 17, 2024
Merged

Dev #64

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
[submodule "deps/ledger-zxlib"]
path = deps/ledger-zxlib
url = https://github.com/Zondax/ledger-zxlib.git
[submodule "deps/nanox-secure-sdk"]
path = deps/nanox-secure-sdk
url = https://github.com/LedgerHQ/ledger-secure-sdk
[submodule "deps/nanosplus-secure-sdk"]
path = deps/nanosplus-secure-sdk
url = https://github.com/LedgerHQ/ledger-secure-sdk
[submodule "deps/ledger-secure-sdk"]
path = deps/ledger-secure-sdk
url = https://github.com/LedgerHQ/ledger-secure-sdk
[submodule "deps/blake2"]
path = deps/blake2
url = https://github.com/Zondax/BLAKE2.git
[submodule "deps/nanos-secure-sdk"]
path = deps/nanos-secure-sdk
url = https://github.com/LedgerHQ/ledger-secure-sdk
url = https://github.com/Zondax/BLAKE2.git
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ifeq ($(BOLOS_SDK),)
# In this case, there is not predefined SDK and we run dockerized
# When not using the SDK, we override and build the XL complete app
ZXLIB_COMPILE_STAX ?= 1
PRODUCTION_BUILD ?= 0
PRODUCTION_BUILD ?= 1
include $(CURDIR)/deps/ledger-zxlib/dockerized_build.mk

else
Expand Down
2 changes: 1 addition & 1 deletion app/Makefile.version
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ APPVERSION_M=0
# This is the `spec_version` field of `Runtime`
APPVERSION_N=0
# This is the patch version of this release
APPVERSION_P=27
APPVERSION_P=28
24 changes: 19 additions & 5 deletions app/src/apdu_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ __Z_INLINE void handleSignTransaction(volatile uint32_t *flags, volatile uint32_
CHECK_APP_CANARY()

if (error_msg != NULL) {
transaction_reset();
const int error_msg_length = strnlen(error_msg, sizeof(G_io_apdu_buffer));
memcpy(G_io_apdu_buffer, error_msg, error_msg_length);
*tx += (error_msg_length);
Expand Down Expand Up @@ -145,8 +146,8 @@ __Z_INLINE void handleGetAddr(volatile uint32_t *flags, volatile uint32_t *tx, u
THROW(APDU_CODE_OK);
}
#if defined(COMPILE_MASP)
__Z_INLINE void handleSignMasp(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
ZEMU_LOGF(50, "handleSignMasp\n")
__Z_INLINE void handleSignMaspSpends(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
ZEMU_LOGF(50, "handleSignMaspSpends\n")
if (!process_chunk(tx, rx)) {
THROW(APDU_CODE_OK);
}
Expand All @@ -156,14 +157,15 @@ __Z_INLINE void handleSignMasp(volatile uint32_t *flags, volatile uint32_t *tx,
CHECK_APP_CANARY()

if (error_msg != NULL) {
transaction_reset();
const int error_msg_length = strnlen(error_msg, sizeof(G_io_apdu_buffer));
memcpy(G_io_apdu_buffer, error_msg, error_msg_length);
*tx += (error_msg_length);
THROW(APDU_CODE_DATA_INVALID);
}

CHECK_APP_CANARY()
view_review_init(tx_getItem, tx_getNumItems, app_sign_masp);
view_review_init(tx_getItem, tx_getNumItems, app_sign_masp_spends);
view_review_show(REVIEW_TXN);
*flags |= IO_ASYNCH_REPLY;
}
Expand Down Expand Up @@ -202,6 +204,7 @@ __Z_INLINE void handleComputeMaspRand(__Z_UNUSED volatile uint32_t *flags, volat
*tx = 0;
zxerr_t zxerr = app_fill_randomness(type);
if (zxerr != zxerr_ok) {
transaction_reset();
*tx = 0;
THROW(APDU_CODE_DATA_INVALID);
}
Expand All @@ -221,6 +224,12 @@ __Z_INLINE void handleExtractSpendSign(__Z_UNUSED volatile uint32_t *flags, vola
THROW(APDU_CODE_OK);
}

__Z_INLINE void handleCleanRandomnessBuffers(__Z_UNUSED volatile uint32_t *flags, volatile uint32_t *tx, __Z_UNUSED uint32_t rx) {
*tx = 0;
transaction_reset();
THROW(APDU_CODE_OK);
}

#endif

__Z_INLINE void handle_getversion(__Z_UNUSED volatile uint32_t *flags, volatile uint32_t *tx)
Expand Down Expand Up @@ -315,9 +324,9 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
break;
}

case INS_SIGN_MASP: {
case INS_SIGN_MASP_SPENDS: {
CHECK_PIN_VALIDATED()
handleSignMasp(flags, tx, rx);
handleSignMaspSpends(flags, tx, rx);
break;
}

Expand All @@ -326,6 +335,11 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
handleExtractSpendSign(flags, tx, rx);
break;
}
case INS_CLEAN_BUFFERS: {
CHECK_PIN_VALIDATED()
handleCleanRandomnessBuffers(flags, tx, rx);
break;
}
#endif
#if defined(APP_TESTING)
case INS_TEST: {
Expand Down
3 changes: 2 additions & 1 deletion app/src/coin.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ typedef enum {
#define INS_GET_SPEND_RAND 0x04
#define INS_GET_OUTPUT_RAND 0x05
#define INS_GET_CONVERT_RAND 0x06
#define INS_SIGN_MASP 0x07
#define INS_SIGN_MASP_SPENDS 0x07
#define INS_EXTRACT_SPEND_SIGN 0x08
#define INS_CLEAN_BUFFERS 0x09

#define APDU_CODE_CHECK_SIGN_TR_FAIL 0x6999
#ifdef __cplusplus
Expand Down
8 changes: 5 additions & 3 deletions app/src/common/actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,21 @@ __Z_INLINE void app_sign() {
const zxerr_t err = crypto_sign(txObj, G_io_apdu_buffer, sizeof(G_io_apdu_buffer) - 2);

if (err != zxerr_ok) {
transaction_reset();
MEMZERO(G_io_apdu_buffer, sizeof(G_io_apdu_buffer));
set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
} else {
transaction_reset();
const uint16_t responseLen = PK_LEN_25519_PLUS_TAG + 2 * SALT_LEN + 2 * SIG_LEN_25519_PLUS_TAG + 2 + 10;
set_code(G_io_apdu_buffer, responseLen, APDU_CODE_OK);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, responseLen + 2);
}
}

__Z_INLINE void app_sign_masp() {
const parser_tx_t *txObj = tx_get_txObject();
const zxerr_t err = crypto_sign_masp(txObj, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3);
__Z_INLINE void app_sign_masp_spends() {
parser_tx_t *txObj = tx_get_txObject();
const zxerr_t err = crypto_sign_masp_spends(txObj, G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3);

if (err != zxerr_ok) {
transaction_reset();
Expand Down
1 change: 1 addition & 0 deletions app/src/common/parser_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ typedef enum {
parser_invalid_number_of_converts,
parser_invalid_rk,
parser_invalid_cv,
parser_invalid_target_hash,
} parser_error_t;

typedef struct {
Expand Down
68 changes: 33 additions & 35 deletions app/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

#define CHECK_PARSER_OK(CALL) \
do { \
cx_err_t __cx_err = CALL; \
parser_error_t __cx_err = CALL; \
if (__cx_err != parser_ok) { \
return zxerr_unknown; \
} \
Expand Down Expand Up @@ -310,6 +310,16 @@ static zxerr_t crypto_addTxnHashes(const parser_tx_t *txObj, concatenated_hashes
return zxerr_ok;
}

zxerr_t crypto_hashMaspSection(const uint8_t *input, uint64_t inputLen, uint8_t* output) {
if (input == NULL || output == NULL) {
return zxerr_invalid_crypto_settings;
}
cx_sha256_t sha256 = {0};
cx_sha256_init(&sha256);
CHECK_CX_OK(cx_sha256_update(&sha256, input, (size_t)inputLen));
CHECK_CX_OK(cx_sha256_final(&sha256, output));
return zxerr_ok;
}

zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLen) {
const uint16_t minimumBufferSize = PK_LEN_25519_PLUS_TAG + 2 * SALT_LEN + 2 * SIG_LEN_25519_PLUS_TAG + 2 + 10;
Expand All @@ -321,7 +331,7 @@ zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLe
CHECK_ZXERR(crypto_extractPublicKey_ed25519(output + 1, PK_LEN_25519))
const bytes_t pubkey = {.ptr = output, .len = PK_LEN_25519_PLUS_TAG};

// Hashes: code, data, (initAcc | initVali | updateVP = 1 / initProp = 2), raw_signature, header ---> MaxHashes = 6
// Hashes: code, data, (initAcc | initVali | updateVP = 1 / initProp = 2), raw_signature, header, masp ---> MaxHashes = 6
uint8_t hashes_buffer[MAX_SIGNATURE_HASHES * HASH_LEN] = {0};
uint8_t indices_buffer[MAX_SIGNATURE_HASHES] = {0};
concatenated_hashes_t section_hashes = {
Expand Down Expand Up @@ -400,6 +410,17 @@ zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLe
section_hashes.hashesLen += 2;
signature_section.hashes.hashesLen += 2;

// Include Masp hash in the signature if it's there
if (txObj->transaction.isMasp) {
const uint8_t *maspSection = txObj->transaction.sections.maspTx.masptx_ptr;
uint64_t maspSectionLen = txObj->transaction.sections.maspTx.masptx_len;
uint8_t *maspHash = section_hashes.hashes.ptr + (section_hashes.hashesLen * HASH_LEN);
CHECK_ZXERR(crypto_hashMaspSection(maspSection, maspSectionLen, maspHash))
section_hashes.indices.ptr[section_hashes.hashesLen] = txObj->transaction.maspTx_idx;
section_hashes.hashesLen++;
signature_section.hashes.hashesLen++;
}

// Include the memo section hash in the signature if it's there
if (txObj->transaction.header.memoSection != NULL) {
const section_t *memo = txObj->transaction.header.memoSection;
Expand Down Expand Up @@ -520,13 +541,14 @@ __Z_INLINE zxerr_t copyKeys(keys_t *saplingKeys, key_kind_e requestedKeys, uint8
break;

case ViewKeys:
if (outputLen < 4 * KEY_LENGTH) {
if (outputLen < 5 * KEY_LENGTH) {
return zxerr_buffer_too_small;
}
memcpy(output, saplingKeys->ak, KEY_LENGTH);
memcpy(output + KEY_LENGTH, saplingKeys->nk, KEY_LENGTH);
memcpy(output + 2 * KEY_LENGTH, saplingKeys->ovk, KEY_LENGTH);
memcpy(output + 3 * KEY_LENGTH, saplingKeys->ivk, KEY_LENGTH);
memcpy(output + 4 * KEY_LENGTH, saplingKeys->dk, KEY_LENGTH);
break;

case ProofGenerationKey:
Expand Down Expand Up @@ -612,7 +634,7 @@ zxerr_t crypto_fillMASP(uint8_t *buffer, uint16_t bufferLen, uint16_t *cmdRespon
break;

case ViewKeys:
*cmdResponseLen = 4 * KEY_LENGTH;
*cmdResponseLen = 5 * KEY_LENGTH;
break;

case ProofGenerationKey:
Expand All @@ -626,32 +648,8 @@ zxerr_t crypto_fillMASP(uint8_t *buffer, uint16_t bufferLen, uint16_t *cmdRespon
return zxerr_ok;
}

static parser_error_t h_star(uint8_t *a, uint16_t a_len, uint8_t *b, uint16_t b_len, uint8_t *output) {
if (a == NULL || b == NULL || output == NULL) {
return parser_no_data;
}

uint8_t hash[BLAKE2B_OUTPUT_LEN] = {0};
#if defined(LEDGER_SPECIFIC)
cx_blake2b_t ctx = {0};
ASSERT_CX_OK(cx_blake2b_init2_no_throw(&ctx, BLAKE2B_OUTPUT_LEN, NULL, 0, (uint8_t *)SIGNING_REDJUBJUB,
sizeof(SIGNING_REDJUBJUB)));
ASSERT_CX_OK(cx_blake2b_update(&ctx, a, a_len));
ASSERT_CX_OK(cx_blake2b_update(&ctx, b, b_len));
cx_blake2b_final(&ctx, hash);
#else
blake2b_state state = {0};
blake2b_init_with_personalization(&state, BLAKE2B_OUTPUT_LEN, (const uint8_t *)SIGNING_REDJUBJUB,
sizeof(SIGNING_REDJUBJUB));
blake2b_update(&state, a, a_len);
blake2b_update(&state, b, b_len);
blake2b_final(&state, hash, BLAKE2B_OUTPUT_LEN);
#endif

from_bytes_wide(hash, output);

return parser_ok;
}
// https://github.com/anoma/masp/blob/8d83b172698098fba393006016072bc201ed9ab7/masp_primitives/src/sapling.rs#L170
// https://github.com/anoma/masp/blob/main/masp_primitives/src/sapling/redjubjub.rs#L136
static zxerr_t sign_sapling_spend(keys_t *keys, uint8_t alpha[static KEY_LENGTH], uint8_t sign_hash[static KEY_LENGTH], uint8_t *signature) {
if (alpha == NULL || sign_hash == NULL || signature == NULL) {
return zxerr_no_data;
Expand All @@ -662,10 +660,10 @@ static zxerr_t sign_sapling_spend(keys_t *keys, uint8_t alpha[static KEY_LENGTH]
uint8_t rk[KEY_LENGTH] = {0};

// get randomized secret
randomized_secret_from_seed(keys->ask, alpha, rsk);
CHECK_PARSER_OK(parser_randomized_secret_from_seed(keys->ask, alpha, rsk));

//rsk to rk
scalar_multiplication(rsk, SpendingKeyGenerator, rk);
CHECK_PARSER_OK(parser_scalar_multiplication(rsk, SpendingKeyGenerator, rk));

// sign
MEMCPY(data_to_be_signed, rk, KEY_LENGTH);
Expand All @@ -679,13 +677,13 @@ static zxerr_t sign_sapling_spend(keys_t *keys, uint8_t alpha[static KEY_LENGTH]
uint8_t r[32] = {0};
uint8_t rbar[32] = {0};
CHECK_PARSER_OK(h_star(rng, sizeof(rng), data_to_be_signed, sizeof(data_to_be_signed), r));
CHECK_PARSER_OK(scalar_multiplication(r, SpendingKeyGenerator, rbar));
CHECK_PARSER_OK(parser_scalar_multiplication(r, SpendingKeyGenerator, rbar));

//compute s and sbar
uint8_t s[32] = {0};
uint8_t sbar[32] = {0};
CHECK_PARSER_OK(h_star(rbar, sizeof(rbar), data_to_be_signed, sizeof(data_to_be_signed), s));
CHECK_PARSER_OK(compute_sbar(s, r, rsk, sbar));
CHECK_PARSER_OK(parser_compute_sbar(s, r, rsk, sbar));

MEMCPY(signature, rbar, HASH_LEN);
MEMCPY(signature + HASH_LEN, sbar, HASH_LEN);
Expand Down Expand Up @@ -905,7 +903,7 @@ zxerr_t crypto_hash_messagebuffer(uint8_t *buffer, uint16_t bufferLen,
return zxerr_ok;
}

zxerr_t crypto_sign_masp(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLen) {
zxerr_t crypto_sign_masp_spends(parser_tx_t *txObj, uint8_t *output, uint16_t outputLen) {
if (txObj == NULL || output == NULL || outputLen < ED25519_SIGNATURE_SIZE) {
return zxerr_unknown;
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern uint32_t hdPath[HDPATH_LEN_DEFAULT];
zxerr_t crypto_fillAddress(signing_key_type_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *cmdResponseLen);
zxerr_t crypto_sign(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLen);
zxerr_t crypto_fillMASP(uint8_t *buffer, uint16_t bufferLen, uint16_t *cmdResponseLen, key_kind_e requestedKey);
zxerr_t crypto_sign_masp(const parser_tx_t *txObj, uint8_t *output, uint16_t outputLen);
zxerr_t crypto_sign_masp_spends(parser_tx_t *txObj, uint8_t *output, uint16_t outputLen);
zxerr_t crypto_extract_spend_signature(uint8_t *buffer, uint16_t bufferLen, uint16_t *cmdResponseLen);
zxerr_t crypto_computeRandomness(masp_type_e type, uint8_t *out, uint16_t outLen, uint16_t *replyLen);
#ifdef __cplusplus
Expand Down
Loading
Loading