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

@@ -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;