Add EIP 712 signing v0

This commit is contained in:
BTChip github
2020-09-26 15:49:36 +02:00
committed by TamtamHero
parent c308b55535
commit 27c34e271a
10 changed files with 356 additions and 2 deletions

View File

@@ -0,0 +1,64 @@
#include "shared_context.h"
#include "apdu_constants.h"
#include "utils.h"
#ifdef TARGET_BLUE
#include "ui_blue.h"
#endif
#ifdef HAVE_UX_FLOW
#include "ui_flow.h"
#endif
static const char const SIGN_MAGIC[] = "\x19"
"Ethereum Signed Message:\n";
void handleSignEIP712Message(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx) {
uint8_t i;
UNUSED(tx);
if ((p1 != 00) || (p2 != 00)) {
THROW(0x6B00);
}
if (appState != APP_STATE_IDLE) {
reset_app_context();
}
if (dataLength < 1) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
tmpCtx.messageSigningContext712.pathLength = workBuffer[0];
if ((tmpCtx.messageSigningContext712.pathLength < 0x01) ||
(tmpCtx.messageSigningContext712.pathLength > MAX_BIP32_PATH)) {
PRINTF("Invalid path\n");
THROW(0x6a80);
}
workBuffer++;
dataLength--;
for (i = 0; i < tmpCtx.messageSigningContext712.pathLength; i++) {
if (dataLength < 4) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
tmpCtx.messageSigningContext712.bip32Path[i] = U4BE(workBuffer, 0);
workBuffer += 4;
dataLength -= 4;
}
if (dataLength < 32 + 32) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
memmove(tmpCtx.messageSigningContext712.domainHash, workBuffer, 32);
memmove(tmpCtx.messageSigningContext712.messageHash, workBuffer + 32, 32);
#ifdef NO_CONSENT
io_seproxyhal_touch_signMessage_ok(NULL);
#else //NO_CONSENT
#if defined(TARGET_BLUE)
// TODO implement
ui_approval_message_sign_blue_init();
#else
ux_flow_init(0, ux_sign_712_v0_flow, NULL);
#endif // #if TARGET_ID
#endif // NO_CONSENT
*flags |= IO_ASYNCH_REPLY;
}

View File

@@ -0,0 +1,64 @@
#include "shared_context.h"
#include "ui_callbacks.h"
static const uint8_t const EIP_712_MAGIC[] = { 0x19, 0x01 };
unsigned int io_seproxyhal_touch_signMessage712_v0_ok(const bagl_element_t *e) {
uint8_t privateKeyData[32];
uint8_t hash[32];
uint8_t signature[100];
uint8_t signatureLength;
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));
PRINTF("EIP712 hash to sign %.*H\n", 32, hash);
io_seproxyhal_io_heartbeat();
os_perso_derive_node_bip32(
CX_CURVE_256K1, tmpCtx.messageSigningContext712.bip32Path,
tmpCtx.messageSigningContext712.pathLength, privateKeyData, NULL);
io_seproxyhal_io_heartbeat();
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
os_memset(privateKeyData, 0, sizeof(privateKeyData));
unsigned int info = 0;
io_seproxyhal_io_heartbeat();
signatureLength =
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
hash,
sizeof(hash), signature, sizeof(signature), &info);
os_memset(&privateKey, 0, sizeof(privateKey));
G_io_apdu_buffer[0] = 27;
if (info & CX_ECCINFO_PARITY_ODD) {
G_io_apdu_buffer[0]++;
}
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;
reset_app_context();
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// Display back the original UX
ui_idle();
return 0; // do not redraw the widget
}
unsigned int io_seproxyhal_touch_signMessage712_v0_cancel(const bagl_element_t *e) {
reset_app_context();
G_io_apdu_buffer[0] = 0x69;
G_io_apdu_buffer[1] = 0x85;
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
// Display back the original UX
ui_idle();
return 0; // do not redraw the widget
}

View File

@@ -0,0 +1,63 @@
#include "shared_context.h"
#include "ui_callbacks.h"
void prepare_domain_hash_v0() {
snprintf(strings.tmp.tmp, 70, "0x%.*H", 32, tmpCtx.messageSigningContext712.domainHash);
}
void prepare_message_hash_v0() {
snprintf(strings.tmp.tmp, 70, "0x%.*H", 32, tmpCtx.messageSigningContext712.messageHash);
}
UX_FLOW_DEF_NOCB(
ux_sign_712_v0_flow_1_step,
pnn,
{
&C_icon_certificate,
"Sign",
"typed message",
});
UX_STEP_NOCB_INIT(
ux_sign_712_v0_flow_2_step,
bnnn_paging,
prepare_domain_hash_v0(),
{
.title = "Domain hash",
.text = strings.tmp.tmp,
});
UX_STEP_NOCB_INIT(
ux_sign_712_v0_flow_3_step,
bnnn_paging,
prepare_message_hash_v0(),
{
.title = "Message hash",
.text = strings.tmp.tmp,
});
UX_FLOW_DEF_VALID(
ux_sign_712_v0_flow_4_step,
pbb,
io_seproxyhal_touch_signMessage712_v0_ok(NULL),
{
&C_icon_validate_14,
"Sign",
"message",
});
UX_FLOW_DEF_VALID(
ux_sign_712_v0_flow_5_step,
pbb,
io_seproxyhal_touch_signMessage712_v0_cancel(NULL),
{
&C_icon_crossmark,
"Cancel",
"signature",
});
const ux_flow_step_t * const ux_sign_712_v0_flow [] = {
&ux_sign_712_v0_flow_1_step,
&ux_sign_712_v0_flow_2_step,
&ux_sign_712_v0_flow_3_step,
&ux_sign_712_v0_flow_4_step,
&ux_sign_712_v0_flow_5_step,
FLOW_END_STEP,
};