Ethereum EIP-155 replay protection

Added chain_id field in sign transaction.
If chain_id is set use hashing as specified in EIP-155.
This commit is contained in:
Jochen Hoenicke 2017-01-22 17:53:48 +01:00 committed by Pavol Rusnak
parent 5b40f6d90b
commit 32fb7e96cc
1 changed files with 32 additions and 1 deletions

View File

@ -35,6 +35,7 @@ static bool ethereum_signing = false;
static uint32_t data_total, data_left;
static EthereumTxRequest resp;
static uint8_t privkey[32];
static uint8_t chain_id;
struct SHA3_CTX keccak_ctx;
static inline void hash_data(const uint8_t *buf, size_t size)
@ -150,6 +151,15 @@ static void send_signature(void)
uint8_t hash[32], sig[64];
uint8_t v;
layoutProgress("Signing", 1000);
/* eip-155 replay protection */
if (chain_id != 0) {
/* hash v=chain_id, r=0, s=0 */
hash_rlp_field(&chain_id, 1);
hash_rlp_length(0, 0);
hash_rlp_length(0, 0);
}
keccak_Final(&keccak_ctx, hash);
if (ecdsa_sign_digest(&secp256k1, privkey, hash, sig, &v, ethereum_is_canonic) != 0) {
fsm_sendFailure(FailureType_Failure_Other, "Signing failed");
@ -163,7 +173,11 @@ static void send_signature(void)
resp.has_data_length = false;
resp.has_signature_v = true;
resp.signature_v = v + 27;
if (chain_id) {
resp.signature_v = v + 2*chain_id + 35;
} else {
resp.signature_v = v + 27;
}
resp.has_signature_r = true;
resp.signature_r.size = 32;
@ -421,6 +435,18 @@ void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node)
if (!msg->has_nonce)
msg->nonce.size = 0;
/* eip-155 chain id */
if (msg->has_chain_id) {
if (msg->chain_id < 1 || msg->chain_id > 109) {
fsm_sendFailure(FailureType_Failure_Other, "Chain Id out of bounds");
ethereum_signing_abort();
return;
}
chain_id = (uint8_t) msg->chain_id;
} else {
chain_id = 0;
}
if (msg->has_data_length && msg->data_length > 0) {
if (!msg->has_data_initial_chunk || msg->data_initial_chunk.size == 0) {
fsm_sendFailure(FailureType_Failure_Other, "Data length provided, but no initial chunk");
@ -488,6 +514,11 @@ void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node)
rlp_length += rlp_calculate_length(msg->to.size, msg->to.bytes[0]);
rlp_length += rlp_calculate_length(msg->value.size, msg->value.bytes[0]);
rlp_length += rlp_calculate_length(data_total, msg->data_initial_chunk.bytes[0]);
if (chain_id) {
rlp_length += rlp_calculate_length(1, chain_id);
rlp_length += rlp_calculate_length(0, 0);
rlp_length += rlp_calculate_length(0, 0);
}
/* Stage 2: Store header fields */
hash_rlp_list_length(rlp_length);