Fix deprecated warnings
This commit is contained in:
@@ -13,27 +13,35 @@ static const uint8_t BLS12_381_FIELD_MODULUS[] = {
|
||||
0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab};
|
||||
|
||||
void getEth2PublicKey(uint32_t *bip32Path, uint8_t bip32PathLength, uint8_t *out) {
|
||||
uint8_t privateKeyData[INT256_LENGTH];
|
||||
uint8_t privateKeyData[64];
|
||||
cx_ecfp_256_extended_private_key_t privateKey;
|
||||
cx_ecfp_384_public_key_t publicKey;
|
||||
uint8_t yFlag = 0;
|
||||
uint8_t tmp[96];
|
||||
int diff;
|
||||
|
||||
io_seproxyhal_io_heartbeat();
|
||||
os_perso_derive_eip2333(CX_CURVE_BLS12_381_G1, bip32Path, bip32PathLength, privateKeyData);
|
||||
CX_ASSERT(os_derive_eip2333_no_throw(CX_CURVE_BLS12_381_G1,
|
||||
bip32Path,
|
||||
bip32PathLength,
|
||||
privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
memset(tmp, 0, 48);
|
||||
memmove(tmp + 16, privateKeyData, 32);
|
||||
cx_ecfp_init_private_key(CX_CURVE_BLS12_381_G1, tmp, 48, (cx_ecfp_private_key_t *) &privateKey);
|
||||
cx_ecfp_generate_pair(CX_CURVE_BLS12_381_G1,
|
||||
(cx_ecfp_public_key_t *) &publicKey,
|
||||
(cx_ecfp_private_key_t *) &privateKey,
|
||||
1);
|
||||
CX_ASSERT(cx_ecfp_init_private_key_no_throw(CX_CURVE_BLS12_381_G1,
|
||||
tmp,
|
||||
48,
|
||||
(cx_ecfp_private_key_t *) &privateKey));
|
||||
CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_BLS12_381_G1,
|
||||
(cx_ecfp_public_key_t *) &publicKey,
|
||||
(cx_ecfp_private_key_t *) &privateKey,
|
||||
1));
|
||||
explicit_bzero(tmp, 96);
|
||||
explicit_bzero((void *) &privateKey, sizeof(cx_ecfp_256_extended_private_key_t));
|
||||
tmp[47] = 2;
|
||||
cx_math_mult(tmp, publicKey.W + 1 + 48, tmp, 48);
|
||||
if (cx_math_cmp(tmp + 48, BLS12_381_FIELD_MODULUS, 48) > 0) {
|
||||
CX_ASSERT(cx_math_mult_no_throw(tmp, publicKey.W + 1 + 48, tmp, 48));
|
||||
CX_ASSERT(cx_math_cmp_no_throw(tmp + 48, BLS12_381_FIELD_MODULUS, 48, &diff));
|
||||
if (diff > 0) {
|
||||
yFlag = 0x20;
|
||||
}
|
||||
publicKey.W[1] &= 0x1f;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "feature_getPublicKey.h"
|
||||
#include "common_ui.h"
|
||||
#include "os_io_seproxyhal.h"
|
||||
#include "lib_standard_app/crypto_helpers.h"
|
||||
|
||||
void handleGetPublicKey(uint8_t p1,
|
||||
uint8_t p2,
|
||||
@@ -11,9 +12,7 @@ void handleGetPublicKey(uint8_t p1,
|
||||
uint8_t dataLength,
|
||||
unsigned int *flags,
|
||||
unsigned int *tx) {
|
||||
uint8_t privateKeyData[INT256_LENGTH];
|
||||
bip32_path_t bip32;
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
|
||||
if (!G_called_from_swap) {
|
||||
reset_app_context();
|
||||
@@ -35,25 +34,18 @@ void handleGetPublicKey(uint8_t p1,
|
||||
}
|
||||
|
||||
tmpCtx.publicKeyContext.getChaincode = (p2 == P2_CHAINCODE);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
os_perso_derive_node_bip32(
|
||||
CX_CURVE_256K1,
|
||||
bip32.path,
|
||||
bip32.length,
|
||||
privateKeyData,
|
||||
(tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL));
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1);
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
if (!getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey,
|
||||
tmpCtx.publicKeyContext.address,
|
||||
&global_sha3,
|
||||
chainConfig->chainId)) {
|
||||
THROW(CX_INVALID_PARAMETER);
|
||||
if (bip32_derive_get_pubkey_256(
|
||||
CX_CURVE_256K1,
|
||||
bip32.path,
|
||||
bip32.length,
|
||||
tmpCtx.publicKeyContext.publicKey.W,
|
||||
(tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL),
|
||||
CX_SHA512) != CX_OK) {
|
||||
THROW(APDU_RESPONSE_UNKNOWN);
|
||||
}
|
||||
getEthAddressStringFromRawKey(tmpCtx.publicKeyContext.publicKey.W,
|
||||
tmpCtx.publicKeyContext.address,
|
||||
chainConfig->chainId);
|
||||
|
||||
uint64_t chain_id = chainConfig->chainId;
|
||||
if (dataLength >= sizeof(chain_id)) {
|
||||
|
||||
@@ -28,7 +28,7 @@ void handlePerformPrivacyOperation(uint8_t p1,
|
||||
uint8_t dataLength,
|
||||
unsigned int *flags,
|
||||
unsigned int *tx) {
|
||||
uint8_t privateKeyData[INT256_LENGTH];
|
||||
uint8_t privateKeyData[64];
|
||||
uint8_t privateKeyDataSwapped[INT256_LENGTH];
|
||||
bip32_path_t bip32;
|
||||
cx_err_t status = CX_OK;
|
||||
@@ -53,27 +53,30 @@ void handlePerformPrivacyOperation(uint8_t p1,
|
||||
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
|
||||
os_perso_derive_node_bip32(
|
||||
CX_ASSERT(os_derive_bip32_no_throw(
|
||||
CX_CURVE_256K1,
|
||||
bip32.path,
|
||||
bip32.length,
|
||||
privateKeyData,
|
||||
(tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL));
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1);
|
||||
if (!getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey,
|
||||
tmpCtx.publicKeyContext.address,
|
||||
&global_sha3,
|
||||
chainConfig->chainId)) {
|
||||
THROW(CX_INVALID_PARAMETER);
|
||||
}
|
||||
(tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL)));
|
||||
CX_ASSERT(cx_ecfp_init_private_key_no_throw(CX_CURVE_256K1, privateKeyData, 32, &privateKey));
|
||||
CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1,
|
||||
&tmpCtx.publicKeyContext.publicKey,
|
||||
&privateKey,
|
||||
1));
|
||||
getEthAddressStringFromRawKey((const uint8_t *) &tmpCtx.publicKeyContext.publicKey.W,
|
||||
tmpCtx.publicKeyContext.address,
|
||||
chainConfig->chainId);
|
||||
if (p2 == P2_PUBLIC_ENCRYPTION_KEY) {
|
||||
decodeScalar(privateKeyData, privateKeyDataSwapped);
|
||||
cx_ecfp_init_private_key(CX_CURVE_Curve25519, privateKeyDataSwapped, 32, &privateKey);
|
||||
cx_ecfp_generate_pair(CX_CURVE_Curve25519,
|
||||
&tmpCtx.publicKeyContext.publicKey,
|
||||
&privateKey,
|
||||
1);
|
||||
CX_ASSERT(cx_ecfp_init_private_key_no_throw(CX_CURVE_Curve25519,
|
||||
privateKeyDataSwapped,
|
||||
32,
|
||||
&privateKey));
|
||||
CX_ASSERT(cx_ecfp_generate_pair_no_throw(CX_CURVE_Curve25519,
|
||||
&tmpCtx.publicKeyContext.publicKey,
|
||||
&privateKey,
|
||||
1));
|
||||
explicit_bzero(privateKeyDataSwapped, sizeof(privateKeyDataSwapped));
|
||||
} else {
|
||||
memmove(tmpCtx.publicKeyContext.publicKey.W + 1, dataBuffer, 32);
|
||||
|
||||
@@ -365,36 +365,38 @@ static bool handle_address(const s_tlv_data *data,
|
||||
static bool verify_signature(const s_sig_ctx *sig_ctx) {
|
||||
uint8_t hash[INT256_LENGTH];
|
||||
cx_ecfp_public_key_t verif_key;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
cx_hash((cx_hash_t *) &sig_ctx->hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH);
|
||||
CX_CHECK(
|
||||
cx_hash_no_throw((cx_hash_t *) &sig_ctx->hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH));
|
||||
switch (sig_ctx->key_id) {
|
||||
#ifdef HAVE_DOMAIN_NAME_TEST_KEY
|
||||
case KEY_ID_TEST:
|
||||
#else
|
||||
case KEY_ID_PROD:
|
||||
#endif
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
DOMAIN_NAME_PUB_KEY,
|
||||
sizeof(DOMAIN_NAME_PUB_KEY),
|
||||
&verif_key);
|
||||
CX_CHECK(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1,
|
||||
DOMAIN_NAME_PUB_KEY,
|
||||
sizeof(DOMAIN_NAME_PUB_KEY),
|
||||
&verif_key));
|
||||
break;
|
||||
default:
|
||||
PRINTF("Error: Unknown metadata key ID %u\n", sig_ctx->key_id);
|
||||
return false;
|
||||
}
|
||||
if (!cx_ecdsa_verify(&verif_key,
|
||||
CX_LAST,
|
||||
CX_SHA256,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
sig_ctx->input_sig,
|
||||
sig_ctx->input_sig_size)) {
|
||||
if (!cx_ecdsa_verify_no_throw(&verif_key,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
sig_ctx->input_sig,
|
||||
sig_ctx->input_sig_size)) {
|
||||
PRINTF("Domain name signature verification failed!\n");
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -168,18 +168,14 @@ void handleProvideErc20TokenInformation(uint8_t p1,
|
||||
}
|
||||
if (index < NUM_TOKENS_EXTRA) {
|
||||
PRINTF("Descriptor whitelisted\n");
|
||||
} else {
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if (!cx_ecdsa_verify(&tokenKey,
|
||||
CX_LAST,
|
||||
CX_SHA256,
|
||||
hash,
|
||||
32,
|
||||
workBuffer + offset,
|
||||
dataLength)) {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey));
|
||||
if (!cx_ecdsa_verify_no_throw(&tokenKey, hash, 32, workBuffer + offset, dataLength)) {
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
PRINTF("Invalid token signature\n");
|
||||
THROW(0x6A80);
|
||||
@@ -187,26 +183,6 @@ void handleProvideErc20TokenInformation(uint8_t p1,
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if (!cx_ecdsa_verify(&tokenKey,
|
||||
CX_LAST,
|
||||
CX_SHA256,
|
||||
hash,
|
||||
32,
|
||||
workBuffer + offset,
|
||||
dataLength)) {
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
PRINTF("Invalid token signature\n");
|
||||
THROW(0x6A80);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
tmpCtx.transactionContext.tokenSet[tmpCtx.transactionContext.currentItemIndex] = 1;
|
||||
THROW(0x9000);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
PRINTF("Data too small for headers: expected at least %d, got %d\n",
|
||||
HEADER_SIZE,
|
||||
dataLength);
|
||||
THROW(0x6A80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
|
||||
uint8_t type = workBuffer[offset];
|
||||
@@ -78,7 +78,7 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unsupported type %d\n", type);
|
||||
THROW(0x6a80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
break;
|
||||
}
|
||||
offset += TYPE_SIZE;
|
||||
@@ -89,7 +89,7 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unsupported version %d\n", version);
|
||||
THROW(0x6a80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
break;
|
||||
}
|
||||
offset += VERSION_SIZE;
|
||||
@@ -104,14 +104,14 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
PRINTF("Data too small for payload: expected at least %d, got %d\n",
|
||||
payloadSize,
|
||||
dataLength);
|
||||
THROW(0x6A80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
|
||||
if (collectionNameLength > COLLECTION_NAME_MAX_LEN) {
|
||||
PRINTF("CollectionName too big: expected max %d, got %d\n",
|
||||
COLLECTION_NAME_MAX_LEN,
|
||||
collectionNameLength);
|
||||
THROW(0x6A80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
|
||||
// Safe because we've checked the size before.
|
||||
@@ -151,7 +151,7 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
break;
|
||||
default:
|
||||
PRINTF("KeyID %d not supported\n", keyId);
|
||||
THROW(0x6A80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
break;
|
||||
}
|
||||
PRINTF("RawKey: %.*H\n", rawKeyLen, rawKey);
|
||||
@@ -159,20 +159,10 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
|
||||
uint8_t algorithmId = workBuffer[offset];
|
||||
PRINTF("Algorithm: %d\n", algorithmId);
|
||||
cx_curve_t curve;
|
||||
verificationAlgo *verificationFn;
|
||||
cx_md_t hashId;
|
||||
|
||||
switch (algorithmId) {
|
||||
case ALGORITHM_ID_1:
|
||||
curve = CX_CURVE_256K1;
|
||||
verificationFn = (verificationAlgo *) cx_ecdsa_verify;
|
||||
hashId = CX_SHA256;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Incorrect algorithmId %d\n", algorithmId);
|
||||
THROW(0x6a80);
|
||||
break;
|
||||
if (algorithmId != ALGORITHM_ID_1) {
|
||||
PRINTF("Incorrect algorithmId %d\n", algorithmId);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
offset += ALGORITHM_ID_SIZE;
|
||||
PRINTF("hashing: %.*H\n", payloadSize, workBuffer);
|
||||
@@ -180,7 +170,7 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
|
||||
if (dataLength < payloadSize + SIGNATURE_LENGTH_SIZE) {
|
||||
PRINTF("Data too short to hold signature length\n");
|
||||
THROW(0x6a80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
|
||||
uint8_t signatureLen = workBuffer[offset];
|
||||
@@ -190,26 +180,24 @@ void handleProvideNFTInformation(uint8_t p1,
|
||||
MIN_DER_SIG_SIZE,
|
||||
MAX_DER_SIG_SIZE,
|
||||
signatureLen);
|
||||
THROW(0x6a80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
offset += SIGNATURE_LENGTH_SIZE;
|
||||
|
||||
if (dataLength < payloadSize + SIGNATURE_LENGTH_SIZE + signatureLen) {
|
||||
PRINTF("Signature could not fit in data\n");
|
||||
THROW(0x6a80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
}
|
||||
|
||||
cx_ecfp_init_public_key(curve, rawKey, rawKeyLen, &nftKey);
|
||||
if (!verificationFn(&nftKey,
|
||||
CX_LAST,
|
||||
hashId,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
(uint8_t *) workBuffer + offset,
|
||||
signatureLen)) {
|
||||
CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, rawKey, rawKeyLen, &nftKey));
|
||||
if (!cx_ecdsa_verify_no_throw(&nftKey,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
(uint8_t *) workBuffer + offset,
|
||||
signatureLen)) {
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
PRINTF("Invalid NFT signature\n");
|
||||
THROW(0x6A80);
|
||||
THROW(APDU_RESPONSE_INVALID_DATA);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -37,17 +37,15 @@ void handleSetExternalPlugin(uint8_t p1,
|
||||
|
||||
// check Ledger's signature over the payload
|
||||
cx_hash_sha256(workBuffer, payload_size, hash, sizeof(hash));
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey);
|
||||
if (!cx_ecdsa_verify(&tokenKey,
|
||||
CX_LAST,
|
||||
CX_SHA256,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
workBuffer + payload_size,
|
||||
dataLength - payload_size)) {
|
||||
CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&tokenKey));
|
||||
if (!cx_ecdsa_verify_no_throw(&tokenKey,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
workBuffer + payload_size,
|
||||
dataLength - payload_size)) {
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
PRINTF("Invalid plugin signature %.*H\n",
|
||||
dataLength - payload_size,
|
||||
|
||||
@@ -189,20 +189,10 @@ void handleSetPlugin(uint8_t p1,
|
||||
|
||||
uint8_t algorithmId = workBuffer[offset];
|
||||
PRINTF("Algorithm: %d\n", algorithmId);
|
||||
cx_curve_t curve;
|
||||
verificationAlgo *verificationFn;
|
||||
cx_md_t hashId;
|
||||
|
||||
switch (algorithmId) {
|
||||
case ECC_SECG_P256K1__ECDSA_SHA_256:
|
||||
curve = CX_CURVE_256K1;
|
||||
verificationFn = (verificationAlgo *) cx_ecdsa_verify;
|
||||
hashId = CX_SHA256;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Incorrect algorithmId %d\n", algorithmId);
|
||||
THROW(0x6a80);
|
||||
break;
|
||||
if (algorithmId != ECC_SECG_P256K1__ECDSA_SHA_256) {
|
||||
PRINTF("Incorrect algorithmId %d\n", algorithmId);
|
||||
THROW(0x6a80);
|
||||
}
|
||||
offset += ALGORITHM_ID_SIZE;
|
||||
PRINTF("hashing: %.*H\n", payloadSize, workBuffer);
|
||||
@@ -229,14 +219,12 @@ void handleSetPlugin(uint8_t p1,
|
||||
THROW(0x6a80);
|
||||
}
|
||||
|
||||
cx_ecfp_init_public_key(curve, rawKey, rawKeyLen, &pluginKey);
|
||||
if (!verificationFn(&pluginKey,
|
||||
CX_LAST,
|
||||
hashId,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
(unsigned char *) (workBuffer + offset),
|
||||
signatureLen)) {
|
||||
CX_ASSERT(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, rawKey, rawKeyLen, &pluginKey));
|
||||
if (!cx_ecdsa_verify_no_throw(&pluginKey,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
(unsigned char *) (workBuffer + offset),
|
||||
signatureLen)) {
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
PRINTF("Invalid NFT signature\n");
|
||||
THROW(0x6A80);
|
||||
|
||||
@@ -92,6 +92,8 @@ static void reset_ui_buffer(void) {
|
||||
* @return pointer to the start of the start of the message; \ref NULL if it failed
|
||||
*/
|
||||
static const uint8_t *first_apdu_data(const uint8_t *data, uint8_t *length) {
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
if (appState != APP_STATE_IDLE) {
|
||||
apdu_reply(APDU_RESPONSE_CONDITION_NOT_SATISFIED);
|
||||
}
|
||||
@@ -113,22 +115,29 @@ static const uint8_t *first_apdu_data(const uint8_t *data, uint8_t *length) {
|
||||
*length -= sizeof(uint32_t);
|
||||
|
||||
// Initialize message header + length
|
||||
cx_keccak_init(&global_sha3, 256);
|
||||
cx_hash((cx_hash_t *) &global_sha3, 0, (uint8_t *) SIGN_MAGIC, sizeof(SIGN_MAGIC) - 1, NULL, 0);
|
||||
CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256));
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
(uint8_t *) SIGN_MAGIC,
|
||||
sizeof(SIGN_MAGIC) - 1,
|
||||
NULL,
|
||||
0));
|
||||
snprintf(strings.tmp.tmp2,
|
||||
sizeof(strings.tmp.tmp2),
|
||||
"%u",
|
||||
tmpCtx.messageSigningContext.remainingLength);
|
||||
cx_hash((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
(uint8_t *) strings.tmp.tmp2,
|
||||
strlen(strings.tmp.tmp2),
|
||||
NULL,
|
||||
0);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
(uint8_t *) strings.tmp.tmp2,
|
||||
strlen(strings.tmp.tmp2),
|
||||
NULL,
|
||||
0));
|
||||
reset_ui_buffer();
|
||||
states.sign_state = STATE_191_HASH_DISPLAY;
|
||||
states.ui_started = false;
|
||||
return data;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,6 +148,8 @@ static const uint8_t *first_apdu_data(const uint8_t *data, uint8_t *length) {
|
||||
* @return whether it was successful or not
|
||||
*/
|
||||
static bool feed_hash(const uint8_t *const data, const uint8_t length) {
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
if (length > tmpCtx.messageSigningContext.remainingLength) {
|
||||
PRINTF("Error: Length mismatch ! (%u > %u)!\n",
|
||||
length,
|
||||
@@ -146,17 +157,19 @@ static bool feed_hash(const uint8_t *const data, const uint8_t length) {
|
||||
apdu_reply(APDU_RESPONSE_INVALID_DATA);
|
||||
return false;
|
||||
}
|
||||
cx_hash((cx_hash_t *) &global_sha3, 0, data, length, NULL, 0);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3, 0, data, length, NULL, 0));
|
||||
if ((tmpCtx.messageSigningContext.remainingLength -= length) == 0) {
|
||||
// Finalize hash
|
||||
cx_hash((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
tmpCtx.messageSigningContext.hash,
|
||||
32);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
tmpCtx.messageSigningContext.hash,
|
||||
32));
|
||||
}
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
#include "os_io_seproxyhal.h"
|
||||
#include "apdu_constants.h"
|
||||
#include "lib_standard_app/crypto_helpers.h"
|
||||
#include "common_ui.h"
|
||||
|
||||
unsigned int io_seproxyhal_touch_signMessage_ok(void) {
|
||||
uint8_t privateKeyData[INT256_LENGTH];
|
||||
uint8_t signature[100];
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
uint32_t tx = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1,
|
||||
tmpCtx.messageSigningContext.bip32.path,
|
||||
tmpCtx.messageSigningContext.bip32.length,
|
||||
privateKeyData,
|
||||
NULL);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
unsigned int info = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecdsa_sign(&privateKey,
|
||||
CX_RND_RFC6979 | CX_LAST,
|
||||
CX_SHA256,
|
||||
tmpCtx.messageSigningContext.hash,
|
||||
sizeof(tmpCtx.messageSigningContext.hash),
|
||||
signature,
|
||||
sizeof(signature),
|
||||
&info);
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
if (bip32_derive_ecdsa_sign_rs_hash_256(CX_CURVE_256K1,
|
||||
tmpCtx.messageSigningContext.bip32.path,
|
||||
tmpCtx.messageSigningContext.bip32.length,
|
||||
CX_RND_RFC6979 | CX_LAST,
|
||||
CX_SHA256,
|
||||
tmpCtx.messageSigningContext.hash,
|
||||
sizeof(tmpCtx.messageSigningContext.hash),
|
||||
G_io_apdu_buffer + 1,
|
||||
G_io_apdu_buffer + 1 + 32,
|
||||
&info) != CX_OK) {
|
||||
THROW(APDU_RESPONSE_UNKNOWN);
|
||||
}
|
||||
G_io_apdu_buffer[0] = 27;
|
||||
if (info & CX_ECCINFO_PARITY_ODD) {
|
||||
G_io_apdu_buffer[0]++;
|
||||
@@ -33,7 +25,6 @@ unsigned int io_seproxyhal_touch_signMessage_ok(void) {
|
||||
if (info & CX_ECCINFO_xGTn) {
|
||||
G_io_apdu_buffer[0] += 2;
|
||||
}
|
||||
format_signature_out(signature);
|
||||
tx = 65;
|
||||
G_io_apdu_buffer[tx++] = 0x90;
|
||||
G_io_apdu_buffer[tx++] = 0x00;
|
||||
|
||||
@@ -52,6 +52,7 @@ static const uint8_t *field_hash_prepare(const void *const field_ptr,
|
||||
const uint8_t *data,
|
||||
uint8_t *data_length) {
|
||||
e_type field_type;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
field_type = struct_field_type(field_ptr);
|
||||
fh->remaining_size = __builtin_bswap16(*(uint16_t *) &data[0]); // network byte order
|
||||
@@ -59,10 +60,12 @@ static const uint8_t *field_hash_prepare(const void *const field_ptr,
|
||||
*data_length -= sizeof(uint16_t);
|
||||
fh->state = FHS_WAITING_FOR_MORE;
|
||||
if (IS_DYN(field_type)) {
|
||||
cx_keccak_init(&global_sha3, 256); // init hash
|
||||
CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256));
|
||||
ui_712_new_field(field_ptr, data, *data_length);
|
||||
}
|
||||
return data;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,14 +123,22 @@ static const uint8_t *field_hash_finalize_static(const void *const field_ptr,
|
||||
*/
|
||||
static uint8_t *field_hash_finalize_dynamic(void) {
|
||||
uint8_t *value;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
if ((value = mem_alloc(KECCAK256_HASH_BYTESIZE)) == NULL) {
|
||||
apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
// copy hash into memory
|
||||
cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, value, KECCAK256_HASH_BYTESIZE);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
value,
|
||||
KECCAK256_HASH_BYTESIZE));
|
||||
return value;
|
||||
end:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,6 +63,7 @@ static bool verify_filtering_signature(uint8_t dname_length,
|
||||
cx_ecfp_public_key_t verifying_key;
|
||||
cx_sha256_t hash_ctx;
|
||||
uint64_t chain_id;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
cx_sha256_init(&hash_ctx);
|
||||
|
||||
@@ -105,13 +106,13 @@ static bool verify_filtering_signature(uint8_t dname_length,
|
||||
hash_nbytes((uint8_t *) dname, sizeof(char) * dname_length, (cx_hash_t *) &hash_ctx);
|
||||
|
||||
// Finalize hash
|
||||
cx_hash((cx_hash_t *) &hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &hash_ctx, CX_LAST, NULL, 0, hash, INT256_LENGTH));
|
||||
|
||||
cx_ecfp_init_public_key(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&verifying_key);
|
||||
if (!cx_ecdsa_verify(&verifying_key, CX_LAST, CX_SHA256, hash, sizeof(hash), sig, sig_length)) {
|
||||
CX_CHECK(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1,
|
||||
LEDGER_SIGNATURE_PUBLIC_KEY,
|
||||
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
|
||||
&verifying_key));
|
||||
if (!cx_ecdsa_verify_no_throw(&verifying_key, hash, sizeof(hash), sig, sig_length)) {
|
||||
#ifndef HAVE_BYPASS_SIGNATURES
|
||||
PRINTF("Invalid EIP-712 filtering signature\n");
|
||||
apdu_response_code = APDU_RESPONSE_INVALID_DATA;
|
||||
@@ -119,6 +120,8 @@ static bool verify_filtering_signature(uint8_t dname_length,
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -147,13 +147,17 @@ static cx_sha3_t *get_last_hash_ctx(void) {
|
||||
static bool finalize_hash_depth(uint8_t *hash) {
|
||||
const cx_sha3_t *hash_ctx;
|
||||
size_t hashed_bytes;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
hash_ctx = get_last_hash_ctx();
|
||||
hashed_bytes = hash_ctx->blen;
|
||||
// finalize hash
|
||||
cx_hash((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE);
|
||||
CX_CHECK(
|
||||
cx_hash_no_throw((cx_hash_t *) hash_ctx, CX_LAST, NULL, 0, hash, KECCAK256_HASH_BYTESIZE));
|
||||
mem_dealloc(sizeof(*hash_ctx)); // remove hash context
|
||||
return hashed_bytes > 0;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +170,7 @@ static void feed_last_hash_depth(const uint8_t *const hash) {
|
||||
|
||||
hash_ctx = get_last_hash_ctx();
|
||||
// continue progressive hash with the array hash
|
||||
cx_hash((cx_hash_t *) hash_ctx, 0, hash, KECCAK256_HASH_BYTESIZE, NULL, 0);
|
||||
CX_ASSERT(cx_hash_no_throw((cx_hash_t *) hash_ctx, 0, hash, KECCAK256_HASH_BYTESIZE, NULL, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,15 +181,18 @@ static void feed_last_hash_depth(const uint8_t *const hash) {
|
||||
*/
|
||||
static bool push_new_hash_depth(bool init) {
|
||||
cx_sha3_t *hash_ctx;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
// allocate new hash context
|
||||
if ((hash_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*hash_ctx)) == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (init) {
|
||||
cx_keccak_init(hash_ctx, 256); // initialize it
|
||||
CX_CHECK(cx_keccak_init_no_throw(hash_ctx, 256));
|
||||
}
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +301,6 @@ static bool path_update(void) {
|
||||
if ((field_ptr = get_field(NULL)) == NULL) {
|
||||
return false;
|
||||
}
|
||||
struct_ptr = path_struct->root_struct;
|
||||
while (struct_field_type(field_ptr) == TYPE_CUSTOM) {
|
||||
typename = get_struct_field_typename(field_ptr, &typename_len);
|
||||
if ((struct_ptr = get_structn(typename, typename_len)) == NULL) {
|
||||
@@ -432,6 +438,7 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
bool is_custom;
|
||||
uint8_t array_size;
|
||||
uint8_t array_depth_count_bak;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
if (path_struct == NULL) {
|
||||
apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED;
|
||||
@@ -479,9 +486,9 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
if (array_size > 0) {
|
||||
memcpy(hash_ctx, old_ctx, sizeof(*old_ctx));
|
||||
} else {
|
||||
cx_keccak_init(hash_ctx, 256);
|
||||
CX_CHECK(cx_keccak_init_no_throw(hash_ctx, 256));
|
||||
}
|
||||
cx_keccak_init(old_ctx, 256); // init hash
|
||||
CX_CHECK(cx_keccak_init_no_throw(old_ctx, 256));
|
||||
}
|
||||
if (array_size == 0) {
|
||||
do {
|
||||
@@ -490,6 +497,8 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) {
|
||||
}
|
||||
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ bool compute_schema_hash(void) {
|
||||
const char *name;
|
||||
uint8_t name_length;
|
||||
cx_sha224_t hash_ctx;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
cx_sha224_init(&hash_ctx);
|
||||
|
||||
@@ -61,13 +62,15 @@ bool compute_schema_hash(void) {
|
||||
hash_byte('}', (cx_hash_t *) &hash_ctx);
|
||||
|
||||
// copy hash into context struct
|
||||
cx_hash((cx_hash_t *) &hash_ctx,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
eip712_context->schema_hash,
|
||||
sizeof(eip712_context->schema_hash));
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &hash_ctx,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
eip712_context->schema_hash,
|
||||
sizeof(eip712_context->schema_hash)));
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // HAVE_EIP712_FULL_SUPPORT
|
||||
|
||||
@@ -171,8 +171,9 @@ bool type_hash(const char *const struct_name, const uint8_t struct_name_length,
|
||||
uint8_t deps_count = 0;
|
||||
const void **deps;
|
||||
void *mem_loc_bak = mem_alloc(0);
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
cx_keccak_init(&global_sha3, 256); // init hash
|
||||
CX_CHECK(cx_keccak_init_no_throw(&global_sha3, 256));
|
||||
deps = get_struct_dependencies(&deps_count, NULL, struct_ptr);
|
||||
if ((deps_count > 0) && (deps == NULL)) {
|
||||
return false;
|
||||
@@ -191,8 +192,15 @@ bool type_hash(const char *const struct_name, const uint8_t struct_name_length,
|
||||
mem_dealloc(mem_alloc(0) - mem_loc_bak);
|
||||
|
||||
// copy hash into memory
|
||||
cx_hash((cx_hash_t *) &global_sha3, CX_LAST, NULL, 0, hash_buf, KECCAK256_HASH_BYTESIZE);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
NULL,
|
||||
0,
|
||||
hash_buf,
|
||||
KECCAK256_HASH_BYTESIZE));
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // HAVE_EIP712_FULL_SUPPORT
|
||||
|
||||
@@ -58,7 +58,7 @@ static const uint8_t *field_skip_typedesc(const uint8_t *field_ptr, const uint8_
|
||||
* @return pointer to the data right after
|
||||
*/
|
||||
static const uint8_t *field_skip_typename(const uint8_t *field_ptr, const uint8_t *ptr) {
|
||||
uint8_t size;
|
||||
uint8_t size = 0;
|
||||
|
||||
if (struct_field_type(field_ptr) == TYPE_CUSTOM) {
|
||||
get_string_in_mem(ptr, &size);
|
||||
@@ -89,7 +89,7 @@ static const uint8_t *field_skip_typesize(const uint8_t *field_ptr, const uint8_
|
||||
* @return pointer to the data right after
|
||||
*/
|
||||
static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr, const uint8_t *ptr) {
|
||||
uint8_t size;
|
||||
uint8_t size = 0;
|
||||
|
||||
if (struct_field_is_array(field_ptr)) {
|
||||
ptr = get_array_in_mem(ptr, &size);
|
||||
@@ -108,11 +108,12 @@ static const uint8_t *field_skip_array_levels(const uint8_t *field_ptr, const ui
|
||||
* @return pointer to the data right after
|
||||
*/
|
||||
static const uint8_t *field_skip_keyname(const uint8_t *field_ptr, const uint8_t *ptr) {
|
||||
uint8_t size;
|
||||
uint8_t size = 0;
|
||||
uint8_t *new_ptr;
|
||||
|
||||
(void) field_ptr;
|
||||
ptr = get_array_in_mem(ptr, &size);
|
||||
return ptr + size;
|
||||
new_ptr = (uint8_t *) get_array_in_mem(ptr, &size);
|
||||
return (const uint8_t *) (new_ptr + size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -416,7 +417,7 @@ const uint8_t *get_structs_array(uint8_t *const length) {
|
||||
* @return pointer to struct
|
||||
*/
|
||||
const uint8_t *get_structn(const char *const name, const uint8_t length) {
|
||||
uint8_t structs_count;
|
||||
uint8_t structs_count = 0;
|
||||
const uint8_t *struct_ptr;
|
||||
const char *struct_name;
|
||||
uint8_t name_length;
|
||||
|
||||
@@ -247,7 +247,6 @@ static bool ui_712_format_addr(const uint8_t *const data, uint8_t length) {
|
||||
if (!getEthDisplayableAddress((uint8_t *) data,
|
||||
strings.tmp.tmp,
|
||||
sizeof(strings.tmp.tmp),
|
||||
&global_sha3,
|
||||
chainConfig->chainId)) {
|
||||
THROW(APDU_RESPONSE_ERROR_NO_INFO);
|
||||
}
|
||||
@@ -292,7 +291,7 @@ static void ui_712_format_bytes(const uint8_t *const data, uint8_t length) {
|
||||
// x2 for each byte value is represented by 2 ASCII characters
|
||||
if ((2 + (length * 2)) > (sizeof(strings.tmp.tmp) - 1)) {
|
||||
strings.tmp.tmp[sizeof(strings.tmp.tmp) - 1 - 3] = '\0';
|
||||
strcat(strings.tmp.tmp, "...");
|
||||
strlcat(strings.tmp.tmp, "...", sizeof(strings.tmp.tmp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "shared_context.h"
|
||||
#include "apdu_constants.h"
|
||||
#include "os_io_seproxyhal.h"
|
||||
#include "lib_standard_app/crypto_helpers.h"
|
||||
#include "ui_callbacks.h"
|
||||
#include "common_712.h"
|
||||
#include "ui_callbacks.h"
|
||||
@@ -8,54 +10,45 @@
|
||||
static const uint8_t EIP_712_MAGIC[] = {0x19, 0x01};
|
||||
|
||||
unsigned int ui_712_approve_cb(void) {
|
||||
uint8_t privateKeyData[INT256_LENGTH];
|
||||
uint8_t hash[INT256_LENGTH];
|
||||
uint8_t signature[100];
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
uint32_t tx = 0;
|
||||
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_keccak_init(&global_sha3, 256);
|
||||
cx_hash((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
(uint8_t *) EIP_712_MAGIC,
|
||||
sizeof(EIP_712_MAGIC),
|
||||
NULL,
|
||||
0);
|
||||
cx_hash((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
tmpCtx.messageSigningContext712.domainHash,
|
||||
sizeof(tmpCtx.messageSigningContext712.domainHash),
|
||||
NULL,
|
||||
0);
|
||||
cx_hash((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
tmpCtx.messageSigningContext712.messageHash,
|
||||
sizeof(tmpCtx.messageSigningContext712.messageHash),
|
||||
hash,
|
||||
sizeof(hash));
|
||||
CX_ASSERT(cx_keccak_init_no_throw(&global_sha3, 256));
|
||||
CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
(uint8_t *) EIP_712_MAGIC,
|
||||
sizeof(EIP_712_MAGIC),
|
||||
NULL,
|
||||
0));
|
||||
CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
0,
|
||||
tmpCtx.messageSigningContext712.domainHash,
|
||||
sizeof(tmpCtx.messageSigningContext712.domainHash),
|
||||
NULL,
|
||||
0));
|
||||
CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
tmpCtx.messageSigningContext712.messageHash,
|
||||
sizeof(tmpCtx.messageSigningContext712.messageHash),
|
||||
hash,
|
||||
sizeof(hash)));
|
||||
PRINTF("EIP712 Domain hash 0x%.*h\n", 32, tmpCtx.messageSigningContext712.domainHash);
|
||||
PRINTF("EIP712 Message hash 0x%.*h\n", 32, tmpCtx.messageSigningContext712.messageHash);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1,
|
||||
tmpCtx.messageSigningContext712.bip32.path,
|
||||
tmpCtx.messageSigningContext712.bip32.length,
|
||||
privateKeyData,
|
||||
NULL);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
|
||||
unsigned int info = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecdsa_sign(&privateKey,
|
||||
CX_RND_RFC6979 | CX_LAST,
|
||||
CX_SHA256,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
signature,
|
||||
sizeof(signature),
|
||||
&info);
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
if (bip32_derive_ecdsa_sign_rs_hash_256(CX_CURVE_256K1,
|
||||
tmpCtx.messageSigningContext712.bip32.path,
|
||||
tmpCtx.messageSigningContext712.bip32.length,
|
||||
CX_RND_RFC6979 | CX_LAST,
|
||||
CX_SHA256,
|
||||
hash,
|
||||
sizeof(hash),
|
||||
G_io_apdu_buffer + 1,
|
||||
G_io_apdu_buffer + 1 + 32,
|
||||
&info) != CX_OK) {
|
||||
THROW(APDU_RESPONSE_UNKNOWN);
|
||||
}
|
||||
G_io_apdu_buffer[0] = 27;
|
||||
if (info & CX_ECCINFO_PARITY_ODD) {
|
||||
G_io_apdu_buffer[0]++;
|
||||
@@ -63,7 +56,6 @@ unsigned int ui_712_approve_cb(void) {
|
||||
if (info & CX_ECCINFO_xGTn) {
|
||||
G_io_apdu_buffer[0] += 2;
|
||||
}
|
||||
format_signature_out(signature);
|
||||
tx = 65;
|
||||
G_io_apdu_buffer[tx++] = 0x90;
|
||||
G_io_apdu_buffer[tx++] = 0x00;
|
||||
|
||||
@@ -43,7 +43,7 @@ void handleSign(uint8_t p1,
|
||||
if (txType >= MIN_TX_TYPE && txType <= MAX_TX_TYPE) {
|
||||
// Enumerate through all supported txTypes here...
|
||||
if (txType == EIP2930 || txType == EIP1559) {
|
||||
cx_hash((cx_hash_t *) &global_sha3, 0, workBuffer, 1, NULL, 0);
|
||||
CX_ASSERT(cx_hash_no_throw((cx_hash_t *) &global_sha3, 0, workBuffer, 1, NULL, 0));
|
||||
txContext.txType = txType;
|
||||
workBuffer++;
|
||||
dataLength--;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "common_ui.h"
|
||||
#include "ui_callbacks.h"
|
||||
#include "apdu_constants.h"
|
||||
#include "lib_standard_app/crypto_helpers.h"
|
||||
|
||||
#define ERR_SILENT_MODE_CHECK_FAILED 0x6001
|
||||
|
||||
@@ -184,10 +185,9 @@ static void address_to_string(uint8_t *in,
|
||||
size_t in_len,
|
||||
char *out,
|
||||
size_t out_len,
|
||||
cx_sha3_t *sha3,
|
||||
uint64_t chainId) {
|
||||
if (in_len != 0) {
|
||||
if (!getEthDisplayableAddress(in, out, out_len, sha3, chainId)) {
|
||||
if (!getEthDisplayableAddress(in, out, out_len, chainId)) {
|
||||
THROW(APDU_RESPONSE_ERROR_NO_INFO);
|
||||
}
|
||||
} else {
|
||||
@@ -279,26 +279,21 @@ static void get_network_as_string(char *out, size_t out_size) {
|
||||
}
|
||||
|
||||
static void get_public_key(uint8_t *out, uint8_t outLength) {
|
||||
uint8_t privateKeyData[INT256_LENGTH] = {0};
|
||||
cx_ecfp_private_key_t privateKey = {0};
|
||||
cx_ecfp_public_key_t publicKey = {0};
|
||||
uint8_t raw_pubkey[65];
|
||||
|
||||
if (outLength < ADDRESS_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1,
|
||||
tmpCtx.transactionContext.bip32.path,
|
||||
tmpCtx.transactionContext.bip32.length,
|
||||
privateKeyData,
|
||||
NULL);
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1, &publicKey, &privateKey, 1);
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
if (!getEthAddressFromKey(&publicKey, out, &global_sha3)) {
|
||||
THROW(CX_INVALID_PARAMETER);
|
||||
if (bip32_derive_get_pubkey_256(CX_CURVE_256K1,
|
||||
tmpCtx.transactionContext.bip32.path,
|
||||
tmpCtx.transactionContext.bip32.length,
|
||||
raw_pubkey,
|
||||
NULL,
|
||||
CX_SHA512) != CX_OK) {
|
||||
THROW(APDU_RESPONSE_UNKNOWN);
|
||||
}
|
||||
|
||||
getEthAddressFromRawKey(raw_pubkey, out);
|
||||
}
|
||||
|
||||
/* Local implmentation of strncasecmp, workaround of the segfaulting base implem
|
||||
@@ -322,6 +317,7 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool
|
||||
uint64_t chain_id = get_tx_chain_id();
|
||||
const char *ticker = get_displayable_ticker(&chain_id, chainConfig);
|
||||
ethPluginFinalize_t pluginFinalize;
|
||||
cx_err_t error = CX_INTERNAL_ERROR;
|
||||
|
||||
// Verify the chain
|
||||
if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) {
|
||||
@@ -337,12 +333,12 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool
|
||||
}
|
||||
}
|
||||
// Store the hash
|
||||
cx_hash((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
tmpCtx.transactionContext.hash,
|
||||
0,
|
||||
tmpCtx.transactionContext.hash,
|
||||
32);
|
||||
CX_CHECK(cx_hash_no_throw((cx_hash_t *) &global_sha3,
|
||||
CX_LAST,
|
||||
tmpCtx.transactionContext.hash,
|
||||
0,
|
||||
tmpCtx.transactionContext.hash,
|
||||
32));
|
||||
|
||||
// Finalize the plugin handling
|
||||
if (dataContext.tokenContext.pluginStatus >= ETH_PLUGIN_RESULT_SUCCESSFUL) {
|
||||
@@ -460,7 +456,6 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool
|
||||
tmpContent.txContent.destinationLength,
|
||||
displayBuffer,
|
||||
sizeof(displayBuffer),
|
||||
&global_sha3,
|
||||
chainConfig->chainId);
|
||||
if (G_called_from_swap) {
|
||||
// Ensure the values are the same that the ones that have been previously validated
|
||||
@@ -529,6 +524,8 @@ __attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool
|
||||
get_network_as_string(strings.common.network_name, sizeof(strings.common.network_name));
|
||||
PRINTF("Network: %s\n", strings.common.network_name);
|
||||
return true;
|
||||
end:
|
||||
return false;
|
||||
}
|
||||
|
||||
void finalizeParsing(bool direct) {
|
||||
|
||||
Reference in New Issue
Block a user