mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-12 18:49:07 +00:00
enable Trezor to perform SSH public key authentication
support both NIST256P1 and SECP256K1 ECDSA curves.
This commit is contained in:
parent
b4728e6cf9
commit
0ac032917b
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,9 +1,9 @@
|
||||
[submodule "trezor-crypto"]
|
||||
path = trezor-crypto
|
||||
url = https://github.com/trezor/trezor-crypto.git
|
||||
url = https://github.com/romanz/trezor-crypto.git
|
||||
[submodule "trezor-common"]
|
||||
path = trezor-common
|
||||
url = https://github.com/trezor/trezor-common.git
|
||||
url = https://github.com/romanz/trezor-common.git
|
||||
[submodule "trezor-qrenc"]
|
||||
path = trezor-qrenc
|
||||
url = https://github.com/trezor/trezor-qrenc.git
|
||||
|
@ -1,10 +1,10 @@
|
||||
#!/bin/bash
|
||||
IMAGETAG=trezor-mcu-build
|
||||
FIRMWARETAG=${1:-master}
|
||||
FIRMWARETAG="ssh-agent"
|
||||
|
||||
docker build -t $IMAGETAG .
|
||||
docker run -t -v $(pwd)/output:/output $IMAGETAG /bin/sh -c "\
|
||||
git clone https://github.com/trezor/trezor-mcu && \
|
||||
git clone https://github.com/romanz/trezor-mcu && \
|
||||
cd trezor-mcu && \
|
||||
git checkout $FIRMWARETAG && \
|
||||
git submodule update --init && \
|
||||
|
@ -22,6 +22,7 @@ OBJS += debug.o
|
||||
OBJS += ../trezor-crypto/bignum.o
|
||||
OBJS += ../trezor-crypto/ecdsa.o
|
||||
OBJS += ../trezor-crypto/secp256k1.o
|
||||
OBJS += ../trezor-crypto/nist256p1.o
|
||||
OBJS += ../trezor-crypto/hmac.o
|
||||
OBJS += ../trezor-crypto/bip32.o
|
||||
OBJS += ../trezor-crypto/bip39.o
|
||||
|
@ -20,12 +20,13 @@
|
||||
#include <string.h>
|
||||
#include "crypto.h"
|
||||
#include "sha2.h"
|
||||
#include "ecdsa.h"
|
||||
#include "pbkdf2.h"
|
||||
#include "aes.h"
|
||||
#include "hmac.h"
|
||||
#include "bip32.h"
|
||||
#include "layout.h"
|
||||
#include "secp256k1.h"
|
||||
#include "nist256p1.h"
|
||||
|
||||
uint32_t ser_length(uint32_t len, uint8_t *out)
|
||||
{
|
||||
@ -83,6 +84,12 @@ uint32_t deser_length(const uint8_t *in, uint32_t *out)
|
||||
return 1 + 8;
|
||||
}
|
||||
|
||||
int sshMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature)
|
||||
{
|
||||
signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes
|
||||
return ecdsa_sign(&nist256p1, privkey, message, message_len, signature + 1, NULL);
|
||||
}
|
||||
|
||||
int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
@ -96,7 +103,7 @@ int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t
|
||||
sha256_Final(hash, &ctx);
|
||||
sha256_Raw(hash, 32, hash);
|
||||
uint8_t pby;
|
||||
ecdsa_sign_digest(privkey, hash, signature + 1, &pby);
|
||||
ecdsa_sign_digest(&secp256k1, privkey, hash, signature + 1, &pby);
|
||||
signature[0] = 27 + pby + 4;
|
||||
return 0;
|
||||
}
|
||||
@ -124,7 +131,7 @@ int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_
|
||||
// x = r
|
||||
memcpy(&cp.x, &r, sizeof(bignum256));
|
||||
// compute y from x
|
||||
uncompress_coords(recid % 2, &cp.x, &cp.y);
|
||||
uncompress_coords(&secp256k1, recid % 2, &cp.x, &cp.y);
|
||||
// calculate hash
|
||||
sha256_Init(&ctx);
|
||||
sha256_Update(&ctx, (const uint8_t *)"\x18" "Bitcoin Signed Message:" "\n", 25);
|
||||
@ -136,13 +143,13 @@ int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_
|
||||
sha256_Raw(hash, 32, hash);
|
||||
// e = -hash
|
||||
bn_read_be(hash, &e);
|
||||
bn_subtract(&order256k1, &e, &e);
|
||||
bn_subtract(&secp256k1.order, &e, &e);
|
||||
// r = r^-1
|
||||
bn_inverse(&r, &order256k1);
|
||||
point_multiply(&s, &cp, &cp);
|
||||
scalar_multiply(&e, &cp2);
|
||||
point_add(&cp2, &cp);
|
||||
point_multiply(&r, &cp, &cp);
|
||||
bn_inverse(&r, &secp256k1.order);
|
||||
point_multiply(&secp256k1, &s, &cp, &cp);
|
||||
scalar_multiply(&secp256k1, &e, &cp2);
|
||||
point_add(&secp256k1, &cp2, &cp);
|
||||
point_multiply(&secp256k1, &r, &cp, &cp);
|
||||
pubkey[0] = 0x04;
|
||||
bn_write_be(&cp.x, pubkey + 1);
|
||||
bn_write_be(&cp.y, pubkey + 33);
|
||||
@ -155,7 +162,7 @@ int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_
|
||||
return 2;
|
||||
}
|
||||
// check if signature verifies the digest
|
||||
if (ecdsa_verify_digest(pubkey, signature + 1, hash) != 0) {
|
||||
if (ecdsa_verify_digest(&secp256k1, pubkey, signature + 1, hash) != 0) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
@ -181,16 +188,16 @@ int cryptoMessageEncrypt(curve_point *pubkey, const uint8_t *msg, size_t msg_siz
|
||||
// generate random nonce
|
||||
curve_point R;
|
||||
bignum256 k;
|
||||
if (generate_k_random(&k) != 0) {
|
||||
if (generate_k_random(&secp256k1, &k) != 0) {
|
||||
return 2;
|
||||
}
|
||||
// compute k*G
|
||||
scalar_multiply(&k, &R);
|
||||
scalar_multiply(&secp256k1, &k, &R);
|
||||
nonce[0] = 0x02 | (R.y.val[0] & 0x01);
|
||||
bn_write_be(&R.x, nonce + 1);
|
||||
*nonce_len = 33;
|
||||
// compute shared secret
|
||||
point_multiply(&k, pubkey, &R);
|
||||
point_multiply(&secp256k1, &k, pubkey, &R);
|
||||
uint8_t shared_secret[33];
|
||||
shared_secret[0] = 0x02 | (R.y.val[0] & 0x01);
|
||||
bn_write_be(&R.x, shared_secret + 1);
|
||||
@ -222,7 +229,7 @@ int cryptoMessageDecrypt(curve_point *nonce, uint8_t *payload, size_t payload_le
|
||||
curve_point R;
|
||||
bignum256 k;
|
||||
bn_read_be(privkey, &k);
|
||||
point_multiply(&k, nonce, &R);
|
||||
point_multiply(&secp256k1, &k, nonce, &R);
|
||||
uint8_t shared_secret[33];
|
||||
shared_secret[0] = 0x02 | (R.y.val[0] & 0x01);
|
||||
bn_write_be(&R.x, shared_secret + 1);
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <secp256k1.h>
|
||||
#include <ecdsa.h>
|
||||
#include <sha2.h>
|
||||
#include <pb.h>
|
||||
#include "types.pb.h"
|
||||
@ -32,6 +32,8 @@ uint32_t ser_length(uint32_t len, uint8_t *out);
|
||||
|
||||
uint32_t ser_length_hash(SHA256_CTX *ctx, uint32_t len);
|
||||
|
||||
int sshMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature);
|
||||
|
||||
int cryptoMessageSign(const uint8_t *message, size_t message_len, const uint8_t *privkey, uint8_t *signature);
|
||||
|
||||
int cryptoMessageVerify(const uint8_t *message, size_t message_len, const uint8_t *address_raw, const uint8_t *signature);
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "base58.h"
|
||||
#include "bip39.h"
|
||||
#include "ripemd160.h"
|
||||
#include "secp256k1.h"
|
||||
#include "nist256p1.h"
|
||||
|
||||
// message methods
|
||||
|
||||
@ -285,6 +287,17 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
|
||||
const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count);
|
||||
if (!node) return;
|
||||
|
||||
uint8_t public_key[33]; // copy public key to temporary buffer
|
||||
memcpy(public_key, node->public_key, sizeof(public_key));
|
||||
|
||||
if (msg->has_ecdsa_curve_name) {
|
||||
const ecdsa_curve *curve = get_curve_by_name(msg->ecdsa_curve_name);
|
||||
if (curve) {
|
||||
// correct public key (since fsm_getDerivedNode uses secp256k1 curve)
|
||||
ecdsa_get_public_key33(curve, node->private_key, public_key);
|
||||
}
|
||||
}
|
||||
|
||||
resp->node.depth = node->depth;
|
||||
resp->node.fingerprint = node->fingerprint;
|
||||
resp->node.child_num = node->child_num;
|
||||
@ -293,7 +306,7 @@ void fsm_msgGetPublicKey(GetPublicKey *msg)
|
||||
resp->node.has_private_key = false;
|
||||
resp->node.has_public_key = true;
|
||||
resp->node.public_key.size = 33;
|
||||
memcpy(resp->node.public_key.bytes, node->public_key, 33);
|
||||
memcpy(resp->node.public_key.bytes, public_key, 33);
|
||||
resp->has_xpub = true;
|
||||
hdnode_serialize_public(node, resp->xpub, sizeof(resp->xpub));
|
||||
msg_write(MessageType_MessageType_PublicKey, resp);
|
||||
@ -662,6 +675,7 @@ void fsm_msgSignIdentity(SignIdentity *msg)
|
||||
layoutHome();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t address_n[5];
|
||||
address_n[0] = 0x80000000 | 13;
|
||||
address_n[1] = 0x80000000 | hash[ 0] | (hash[ 1] << 8) | (hash[ 2] << 16) | (hash[ 3] << 24);
|
||||
@ -672,20 +686,51 @@ void fsm_msgSignIdentity(SignIdentity *msg)
|
||||
const HDNode *node = fsm_getDerivedNode(address_n, 5);
|
||||
if (!node) return;
|
||||
|
||||
uint8_t message[256 + 256];
|
||||
memcpy(message, msg->challenge_hidden.bytes, msg->challenge_hidden.size);
|
||||
const int len = strlen(msg->challenge_visual);
|
||||
memcpy(message + msg->challenge_hidden.size, msg->challenge_visual, len);
|
||||
uint8_t public_key[33]; // copy public key to temporary buffer
|
||||
memcpy(public_key, node->public_key, sizeof(public_key));
|
||||
|
||||
layoutProgressSwipe("Signing", 0);
|
||||
if (cryptoMessageSign(message, msg->challenge_hidden.size + len, node->private_key, resp->signature.bytes) == 0) {
|
||||
resp->has_address = true;
|
||||
uint8_t addr_raw[21];
|
||||
ecdsa_get_address_raw(node->public_key, 0x00, addr_raw); // hardcoded Bitcoin address type
|
||||
base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
|
||||
if (msg->has_ecdsa_curve_name) {
|
||||
const ecdsa_curve *curve = get_curve_by_name(msg->ecdsa_curve_name);
|
||||
if (curve) {
|
||||
// correct public key (since fsm_getDerivedNode uses secp256k1 curve)
|
||||
ecdsa_get_public_key33(curve, node->private_key, public_key);
|
||||
}
|
||||
}
|
||||
|
||||
bool sign_ssh = false;
|
||||
if (msg->identity.has_proto) {
|
||||
sign_ssh = (strcmp(msg->identity.proto, "ssh") == 0);
|
||||
}
|
||||
|
||||
uint8_t message_bytes[256 + 256];
|
||||
memcpy(message_bytes, msg->challenge_hidden.bytes, msg->challenge_hidden.size);
|
||||
int message_size = msg->challenge_hidden.size;
|
||||
|
||||
int result = 0;
|
||||
if (sign_ssh) {
|
||||
// SSH doesn't sign visual challenge.
|
||||
layoutProgressSwipe("Signing SSH", 0);
|
||||
result = sshMessageSign(message_bytes, message_size, node->private_key, resp->signature.bytes);
|
||||
} else {
|
||||
const int len = strlen(msg->challenge_visual);
|
||||
memcpy(message_bytes + message_size, msg->challenge_visual, len);
|
||||
message_size = message_size + len;
|
||||
layoutProgressSwipe("Signing", 0);
|
||||
result = cryptoMessageSign(message_bytes, message_size, node->private_key, resp->signature.bytes);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
if (sign_ssh) {
|
||||
resp->has_address = false;
|
||||
} else {
|
||||
resp->has_address = true;
|
||||
uint8_t addr_raw[21];
|
||||
ecdsa_get_address_raw(node->public_key, 0x00, addr_raw); // hardcoded Bitcoin address type
|
||||
base58_encode_check(addr_raw, 21, resp->address, sizeof(resp->address));
|
||||
}
|
||||
resp->has_public_key = true;
|
||||
resp->public_key.size = 33;
|
||||
memcpy(resp->public_key.bytes, node->public_key, 33);
|
||||
memcpy(resp->public_key.bytes, public_key, 33);
|
||||
resp->has_signature = true;
|
||||
resp->signature.size = 65;
|
||||
msg_write(MessageType_MessageType_SignedIdentity, resp);
|
||||
@ -706,7 +751,7 @@ void fsm_msgEncryptMessage(EncryptMessage *msg)
|
||||
return;
|
||||
}
|
||||
curve_point pubkey;
|
||||
if (msg->pubkey.size != 33 || ecdsa_read_pubkey(msg->pubkey.bytes, &pubkey) == 0) {
|
||||
if (msg->pubkey.size != 33 || ecdsa_read_pubkey(&secp256k1, msg->pubkey.bytes, &pubkey) == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_SyntaxError, "Invalid public key provided");
|
||||
return;
|
||||
}
|
||||
@ -729,7 +774,7 @@ void fsm_msgEncryptMessage(EncryptMessage *msg)
|
||||
node = fsm_getDerivedNode(msg->address_n, msg->address_n_count);
|
||||
if (!node) return;
|
||||
uint8_t public_key[33];
|
||||
ecdsa_get_public_key33(node->private_key, public_key);
|
||||
ecdsa_get_public_key33(&secp256k1, node->private_key, public_key);
|
||||
ecdsa_get_address_raw(public_key, coin->address_type, address_raw);
|
||||
}
|
||||
layoutEncryptMessage(msg->message.bytes, msg->message.size, signing);
|
||||
@ -766,7 +811,7 @@ void fsm_msgDecryptMessage(DecryptMessage *msg)
|
||||
return;
|
||||
}
|
||||
curve_point nonce_pubkey;
|
||||
if (msg->nonce.size != 33 || ecdsa_read_pubkey(msg->nonce.bytes, &nonce_pubkey) == 0) {
|
||||
if (msg->nonce.size != 33 || ecdsa_read_pubkey(&secp256k1, msg->nonce.bytes, &nonce_pubkey) == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_SyntaxError, "Invalid nonce provided");
|
||||
return;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ PassphraseAck.passphrase max_size:51
|
||||
Entropy.entropy max_size:1024
|
||||
|
||||
GetPublicKey.address_n max_count:8
|
||||
GetPublicKey.ecdsa_curve_name max_size:32
|
||||
|
||||
PublicKey.xpub max_size:113
|
||||
|
||||
@ -88,6 +89,7 @@ SignTx.coin_name max_size:17
|
||||
|
||||
SignIdentity.challenge_hidden max_size:256
|
||||
SignIdentity.challenge_visual max_size:256
|
||||
SignIdentity.ecdsa_curve_name max_size:32
|
||||
|
||||
SignedIdentity.address max_size:36
|
||||
SignedIdentity.public_key max_size:33
|
||||
|
@ -123,8 +123,9 @@ const pb_field_t Entropy_fields[2] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t GetPublicKey_fields[2] = {
|
||||
const pb_field_t GetPublicKey_fields[3] = {
|
||||
PB_FIELD2( 1, UINT32 , REPEATED, STATIC , FIRST, GetPublicKey, address_n, address_n, 0),
|
||||
PB_FIELD2( 2, STRING , OPTIONAL, STATIC , OTHER, GetPublicKey, ecdsa_curve_name, address_n, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
@ -304,10 +305,11 @@ const pb_field_t TxAck_fields[2] = {
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
const pb_field_t SignIdentity_fields[4] = {
|
||||
const pb_field_t SignIdentity_fields[5] = {
|
||||
PB_FIELD2( 1, MESSAGE , OPTIONAL, STATIC , FIRST, SignIdentity, identity, identity, &IdentityType_fields),
|
||||
PB_FIELD2( 2, BYTES , OPTIONAL, STATIC , OTHER, SignIdentity, challenge_hidden, identity, 0),
|
||||
PB_FIELD2( 3, STRING , OPTIONAL, STATIC , OTHER, SignIdentity, challenge_visual, challenge_hidden, 0),
|
||||
PB_FIELD2( 4, STRING , OPTIONAL, STATIC , OTHER, SignIdentity, ecdsa_curve_name, challenge_visual, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
@ -417,6 +417,8 @@ typedef struct _GetEntropy {
|
||||
typedef struct _GetPublicKey {
|
||||
size_t address_n_count;
|
||||
uint32_t address_n[8];
|
||||
bool has_ecdsa_curve_name;
|
||||
char ecdsa_curve_name[32];
|
||||
} GetPublicKey;
|
||||
|
||||
typedef struct _LoadDevice {
|
||||
@ -520,6 +522,8 @@ typedef struct _SignIdentity {
|
||||
SignIdentity_challenge_hidden_t challenge_hidden;
|
||||
bool has_challenge_visual;
|
||||
char challenge_visual[256];
|
||||
bool has_ecdsa_curve_name;
|
||||
char ecdsa_curve_name[32];
|
||||
} SignIdentity;
|
||||
|
||||
typedef struct {
|
||||
@ -650,7 +654,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define PassphraseAck_init_default {""}
|
||||
#define GetEntropy_init_default {0}
|
||||
#define Entropy_init_default {{0, {0}}}
|
||||
#define GetPublicKey_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define GetPublicKey_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, ""}
|
||||
#define PublicKey_init_default {HDNodeType_init_default, false, ""}
|
||||
#define GetAddress_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "Bitcoin", false, 0, false, MultisigRedeemScriptType_init_default}
|
||||
#define Address_init_default {""}
|
||||
@ -677,7 +681,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define SimpleSignTx_init_default {0, {}, 0, {}, 0, {}, false, "Bitcoin"}
|
||||
#define TxRequest_init_default {false, (RequestType)0, false, TxRequestDetailsType_init_default, false, TxRequestSerializedType_init_default}
|
||||
#define TxAck_init_default {false, TransactionType_init_default}
|
||||
#define SignIdentity_init_default {false, IdentityType_init_default, false, {0, {0}}, false, ""}
|
||||
#define SignIdentity_init_default {false, IdentityType_init_default, false, {0, {0}}, false, "", false, ""}
|
||||
#define SignedIdentity_init_default {false, "", false, {0, {0}}, false, {0, {0}}}
|
||||
#define FirmwareErase_init_default {0}
|
||||
#define FirmwareUpload_init_default {{0, {0}}}
|
||||
@ -704,7 +708,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define PassphraseAck_init_zero {""}
|
||||
#define GetEntropy_init_zero {0}
|
||||
#define Entropy_init_zero {{0, {0}}}
|
||||
#define GetPublicKey_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define GetPublicKey_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, ""}
|
||||
#define PublicKey_init_zero {HDNodeType_init_zero, false, ""}
|
||||
#define GetAddress_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, false, "", false, 0, false, MultisigRedeemScriptType_init_zero}
|
||||
#define Address_init_zero {""}
|
||||
@ -731,7 +735,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define SimpleSignTx_init_zero {0, {}, 0, {}, 0, {}, false, ""}
|
||||
#define TxRequest_init_zero {false, (RequestType)0, false, TxRequestDetailsType_init_zero, false, TxRequestSerializedType_init_zero}
|
||||
#define TxAck_init_zero {false, TransactionType_init_zero}
|
||||
#define SignIdentity_init_zero {false, IdentityType_init_zero, false, {0, {0}}, false, ""}
|
||||
#define SignIdentity_init_zero {false, IdentityType_init_zero, false, {0, {0}}, false, "", false, ""}
|
||||
#define SignedIdentity_init_zero {false, "", false, {0, {0}}, false, {0, {0}}}
|
||||
#define FirmwareErase_init_zero {0}
|
||||
#define FirmwareUpload_init_zero {{0, {0}}}
|
||||
@ -816,6 +820,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define GetAddress_multisig_tag 4
|
||||
#define GetEntropy_size_tag 1
|
||||
#define GetPublicKey_address_n_tag 1
|
||||
#define GetPublicKey_ecdsa_curve_name_tag 2
|
||||
#define LoadDevice_mnemonic_tag 1
|
||||
#define LoadDevice_node_tag 2
|
||||
#define LoadDevice_pin_tag 3
|
||||
@ -849,6 +854,7 @@ extern const char SimpleSignTx_coin_name_default[17];
|
||||
#define SignIdentity_identity_tag 1
|
||||
#define SignIdentity_challenge_hidden_tag 2
|
||||
#define SignIdentity_challenge_visual_tag 3
|
||||
#define SignIdentity_ecdsa_curve_name_tag 4
|
||||
#define SignMessage_address_n_tag 1
|
||||
#define SignMessage_message_tag 2
|
||||
#define SignMessage_coin_name_tag 3
|
||||
@ -892,7 +898,7 @@ extern const pb_field_t PassphraseRequest_fields[1];
|
||||
extern const pb_field_t PassphraseAck_fields[2];
|
||||
extern const pb_field_t GetEntropy_fields[2];
|
||||
extern const pb_field_t Entropy_fields[2];
|
||||
extern const pb_field_t GetPublicKey_fields[2];
|
||||
extern const pb_field_t GetPublicKey_fields[3];
|
||||
extern const pb_field_t PublicKey_fields[3];
|
||||
extern const pb_field_t GetAddress_fields[5];
|
||||
extern const pb_field_t Address_fields[2];
|
||||
@ -919,7 +925,7 @@ extern const pb_field_t SignTx_fields[4];
|
||||
extern const pb_field_t SimpleSignTx_fields[5];
|
||||
extern const pb_field_t TxRequest_fields[4];
|
||||
extern const pb_field_t TxAck_fields[2];
|
||||
extern const pb_field_t SignIdentity_fields[4];
|
||||
extern const pb_field_t SignIdentity_fields[5];
|
||||
extern const pb_field_t SignedIdentity_fields[4];
|
||||
extern const pb_field_t FirmwareErase_fields[1];
|
||||
extern const pb_field_t FirmwareUpload_fields[2];
|
||||
@ -948,7 +954,7 @@ extern const pb_field_t DebugLinkLog_fields[4];
|
||||
#define PassphraseAck_size 53
|
||||
#define GetEntropy_size 6
|
||||
#define Entropy_size 1027
|
||||
#define GetPublicKey_size 48
|
||||
#define GetPublicKey_size 82
|
||||
#define PublicKey_size (121 + HDNodeType_size)
|
||||
#define GetAddress_size (75 + MultisigRedeemScriptType_size)
|
||||
#define Address_size 38
|
||||
@ -975,7 +981,7 @@ extern const pb_field_t DebugLinkLog_fields[4];
|
||||
#define SimpleSignTx_size (19 + 0*TxInputType_size + 0*TxOutputType_size + 0*TransactionType_size)
|
||||
#define TxRequest_size (18 + TxRequestDetailsType_size + TxRequestSerializedType_size)
|
||||
#define TxAck_size (6 + TransactionType_size)
|
||||
#define SignIdentity_size (524 + IdentityType_size)
|
||||
#define SignIdentity_size (558 + IdentityType_size)
|
||||
#define SignedIdentity_size 140
|
||||
#define FirmwareErase_size 0
|
||||
#define FirmwareUpload_size 2
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ecdsa.h"
|
||||
#include "protect.h"
|
||||
#include "crypto.h"
|
||||
#include "secp256k1.h"
|
||||
|
||||
static uint32_t inputs_count;
|
||||
static uint32_t outputs_count;
|
||||
@ -536,7 +537,7 @@ void signing_txack(TransactionType *tx)
|
||||
resp.serialized.signature_index = idx1;
|
||||
resp.serialized.has_signature = true;
|
||||
resp.serialized.has_serialized_tx = true;
|
||||
ecdsa_sign_digest(privkey, hash, sig, 0);
|
||||
ecdsa_sign_digest(&secp256k1, privkey, hash, sig, 0);
|
||||
resp.serialized.signature.size = ecdsa_sig_to_der(sig, resp.serialized.signature.bytes);
|
||||
if (input.script_type == InputScriptType_SPENDMULTISIG) {
|
||||
if (!input.has_multisig) {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e96ec085d55c20eccecb47e0a55b33295164de6d
|
||||
Subproject commit 12288143f563cc51e4ae1d990de08db3add87380
|
@ -1 +1 @@
|
||||
Subproject commit a757693fe3904f60d80d36fe0bfe437dea55e02e
|
||||
Subproject commit 7c58fc11a46361476e3a7862816adb0671de6a74
|
Loading…
Reference in New Issue
Block a user