Add Ledger signature checking for external plugins

This commit is contained in:
TamtamHero
2021-05-04 23:33:33 +02:00
committed by pscott
parent 46ebe6320a
commit 0bd5fa717e
4 changed files with 62 additions and 21 deletions

View File

@@ -245,12 +245,18 @@ None
#### Description
This commands provides the name of a plugin that should be called to interpret contract data in the following transaction signing command.
This commands provides the name of a trusted binding of a plugin with a contract address and a supported method selector. This plugin will be called to interpret contract data in the following transaction signing command.
It shall be run immediately before performing a transaction involving a contract supported by this plugin to display the proper information to the user if necessary.
The function returns an error sw (0x6984) if the plugin requested is not installed on the device, 0x9000 otherwise.
The signature is computed on
len(pluginName) || pluginName || contractAddress || methodSelector
signed by the following secp256k1 public key 0482bbf2f34f367b2e5bc21847b6566f21f0976b22d3388a9a5e446ac62d25cf725b62a2555b2dd464a4da0ab2f4d506820543af1d242470b1b1a969a27578f353
#### Coding
'Command'
@@ -266,7 +272,11 @@ The function returns an error sw (0x6984) if the plugin requested is not install
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Plugin name | variable
| Length of plugin name | 1
| plugin name | variable
| contract address | 20
| method selector | 4
| signature | variable
|==============================================================================================================================
'Output data'

View File

@@ -39,7 +39,30 @@ extern tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA];
#endif
#ifdef HAVE_TOKENS_LIST
#ifndef HAVE_TOKENS_LIST
#ifndef LEDGER_TEST_PUBLIC_KEY
static const uint8_t const LEDGER_SIGNATURE_PUBLIC_KEY[] = {
// production key 2019-01-11 03:07PM (erc20signer)
0x04,
0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c, 0x0b, 0x68, 0xcd,
0xb1, 0x59, 0x76, 0xdc, 0x24, 0xf2, 0x4c, 0x31, 0x6e, 0x7b, 0x30, 0xfe, 0x4e, 0x8c, 0xc7, 0x6b,
0x14, 0x89, 0x15, 0x0c, 0x21, 0x51, 0x4e, 0xbf, 0x44, 0x0f, 0xf5, 0xde, 0xa5, 0x39, 0x3d, 0x83,
0xde, 0x53, 0x58, 0xcd, 0x09, 0x8f, 0xce, 0x8f, 0xd0, 0xf8, 0x1d, 0xaa, 0x94, 0x97, 0x91, 0x83
};
#else
static const uint8_t const LEDGER_SIGNATURE_PUBLIC_KEY[] = {
// test key 2019-01-11 03:07PM (erc20signer)
0x04,
0x20, 0xda, 0x62, 0x00, 0x3c, 0x0c, 0xe0, 0x97, 0xe3, 0x36, 0x44, 0xa1, 0x0f, 0xe4, 0xc3, 0x04,
0x54, 0x06, 0x9a, 0x44, 0x54, 0xf0, 0xfa, 0x9d, 0x4e, 0x84, 0xf4, 0x50, 0x91, 0x42, 0x9b, 0x52,
0x20, 0xaf, 0x9e, 0x35, 0xc0, 0xb2, 0xd9, 0x28, 0x93, 0x80, 0x13, 0x73, 0x07, 0xde, 0x4d, 0xd1,
0xd4, 0x18, 0x42, 0x8c, 0xf2, 0x1a, 0x93, 0xb3, 0x35, 0x61, 0xbb, 0x09, 0xd8, 0x8f, 0xe5, 0x79,
};
#endif
#else
#define NUM_TOKENS_AKROMA 0
#define NUM_TOKENS_ELLAISM 1

View File

@@ -1,16 +1,7 @@
#include "shared_context.h"
#include "apdu_constants.h"
#include "ui_flow.h"
static const uint8_t const TOKEN_SIGNATURE_PUBLIC_KEY[] = {
// production key 2019-01-11 03:07PM (erc20signer)
0x04,
0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c, 0x0b, 0x68, 0xcd,
0xb1, 0x59, 0x76, 0xdc, 0x24, 0xf2, 0x4c, 0x31, 0x6e, 0x7b, 0x30, 0xfe, 0x4e, 0x8c, 0xc7, 0x6b,
0x14, 0x89, 0x15, 0x0c, 0x21, 0x51, 0x4e, 0xbf, 0x44, 0x0f, 0xf5, 0xde, 0xa5, 0x39, 0x3d, 0x83,
0xde, 0x53, 0x58, 0xcd, 0x09, 0x8f, 0xce, 0x8f, 0xd0, 0xf8, 0x1d, 0xaa, 0x94, 0x97, 0x91, 0x83};
#include "tokens.h"
#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
@@ -87,8 +78,8 @@ void handleProvideErc20TokenInformation(uint8_t p1,
offset += 4;
dataLength -= 4;
cx_ecfp_init_public_key(CX_CURVE_256K1,
TOKEN_SIGNATURE_PUBLIC_KEY,
sizeof(TOKEN_SIGNATURE_PUBLIC_KEY),
LEDGER_SIGNATURE_PUBLIC_KEY,
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
&tokenKey);
if (!cx_ecdsa_verify(&tokenKey,
CX_LAST,
@@ -174,8 +165,8 @@ void handleProvideErc20TokenInformation(uint8_t p1,
PRINTF("Descriptor whitelisted\n");
} else {
cx_ecfp_init_public_key(CX_CURVE_256K1,
TOKEN_SIGNATURE_PUBLIC_KEY,
sizeof(TOKEN_SIGNATURE_PUBLIC_KEY),
LEDGER_SIGNATURE_PUBLIC_KEY,
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
&tokenKey);
if (!cx_ecdsa_verify(&tokenKey,
CX_LAST,
@@ -192,8 +183,8 @@ void handleProvideErc20TokenInformation(uint8_t p1,
#else
cx_ecfp_init_public_key(CX_CURVE_256K1,
TOKEN_SIGNATURE_PUBLIC_KEY,
sizeof(TOKEN_SIGNATURE_PUBLIC_KEY),
LEDGER_SIGNATURE_PUBLIC_KEY,
sizeof(LEDGER_SIGNATURE_PUBLIC_KEY),
&tokenKey);
if (!cx_ecdsa_verify(&tokenKey,
CX_LAST,

View File

@@ -1,6 +1,7 @@
#include "shared_context.h"
#include "apdu_constants.h"
#include "ui_flow.h"
#include "tokens.h"
#define CONTRACT_ADDR_SIZE 20
#define SELECTOR_SIZE 4
@@ -14,9 +15,12 @@ void handleSetExternalPlugin(uint8_t p1,
UNUSED(p1);
UNUSED(p2);
UNUSED(flags);
uint8_t pluginNameLength = *workBuffer++;
uint8_t hash[32];
cx_ecfp_public_key_t tokenKey;
uint8_t pluginNameLength = *workBuffer;
const size_t payload_size = 1 + pluginNameLength + CONTRACT_ADDR_SIZE + SELECTOR_SIZE;
if (dataLength < 1 || dataLength != 1 + pluginNameLength + CONTRACT_ADDR_SIZE + SELECTOR_SIZE) {
if (dataLength <= payload_size) {
THROW(0x6A80);
}
@@ -24,6 +28,19 @@ void handleSetExternalPlugin(uint8_t p1,
THROW(0x6A80);
}
// 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)){
PRINTF("Invalid external plugin signature %.*H\n", payload_size, workBuffer);
THROW(0x6A80);
}
// move on to the rest of the payload parsing
workBuffer++;
memmove(dataContext.tokenContext.pluginName, workBuffer, pluginNameLength);
dataContext.tokenContext.pluginName[pluginNameLength] = '\0';
workBuffer += pluginNameLength;