Merge pull request #5958
d25acd7
Add hmac over encrypted value during transaction (clashm)34f28a7
Add display address (clashm)235b94e
Revert PR #5835 (export view key) (clashm)32febd2
Fix debug feature (clashm)
This commit is contained in:
commit
07c6789148
|
@ -612,7 +612,7 @@ namespace cryptonote
|
||||||
{
|
{
|
||||||
hw::device &hwdev = sender_account_keys.get_device();
|
hw::device &hwdev = sender_account_keys.get_device();
|
||||||
hwdev.open_tx(tx_key);
|
hwdev.open_tx(tx_key);
|
||||||
|
try {
|
||||||
// figure out if we need to make additional tx pubkeys
|
// figure out if we need to make additional tx pubkeys
|
||||||
size_t num_stdaddresses = 0;
|
size_t num_stdaddresses = 0;
|
||||||
size_t num_subaddresses = 0;
|
size_t num_subaddresses = 0;
|
||||||
|
@ -629,6 +629,10 @@ namespace cryptonote
|
||||||
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout);
|
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout);
|
||||||
hwdev.close_tx();
|
hwdev.close_tx();
|
||||||
return r;
|
return r;
|
||||||
|
} catch(...) {
|
||||||
|
hwdev.close_tx();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time)
|
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry>& sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time)
|
||||||
|
|
|
@ -64,6 +64,41 @@ namespace hw {
|
||||||
crypto::secret_key dbg_spendkey;
|
crypto::secret_key dbg_spendkey;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* === hmacmap ==== */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
SecHMAC::SecHMAC(const uint8_t s[32], const uint8_t h[32]) {
|
||||||
|
memcpy(this->sec, s, 32);
|
||||||
|
memcpy(this->hmac, h, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HMACmap::find_mac(const uint8_t sec[32], uint8_t hmac[32]) {
|
||||||
|
size_t sz = hmacs.size();
|
||||||
|
log_hexbuffer("find_mac: lookup for ", (char*)sec,32);
|
||||||
|
for (size_t i=0; i<sz; i++) {
|
||||||
|
log_hexbuffer("find_mac: - try ",(char*)hmacs[i].sec,32);
|
||||||
|
if (memcmp(sec, hmacs[i].sec, 32) == 0) {
|
||||||
|
memcpy(hmac, hmacs[i].hmac, 32);
|
||||||
|
log_hexbuffer("find_mac: - found ",(char*)hmacs[i].hmac,32);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Protocol error: try to send untrusted secret");
|
||||||
|
}
|
||||||
|
|
||||||
|
void HMACmap::add_mac(const uint8_t sec[32], const uint8_t hmac[32]) {
|
||||||
|
log_hexbuffer("add_mac: sec ", (char*)sec,32);
|
||||||
|
log_hexbuffer("add_mac: hmac ", (char*)hmac,32);
|
||||||
|
hmacs.push_back(SecHMAC(sec,hmac));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HMACmap::clear() {
|
||||||
|
hmacs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/* ===================================================================== */
|
/* ===================================================================== */
|
||||||
/* === Keymap ==== */
|
/* === Keymap ==== */
|
||||||
/* ===================================================================== */
|
/* ===================================================================== */
|
||||||
|
@ -162,9 +197,11 @@ namespace hw {
|
||||||
#define INS_RESET 0x02
|
#define INS_RESET 0x02
|
||||||
|
|
||||||
#define INS_GET_KEY 0x20
|
#define INS_GET_KEY 0x20
|
||||||
|
#define INS_DISPLAY_ADDRESS 0x21
|
||||||
#define INS_PUT_KEY 0x22
|
#define INS_PUT_KEY 0x22
|
||||||
#define INS_GET_CHACHA8_PREKEY 0x24
|
#define INS_GET_CHACHA8_PREKEY 0x24
|
||||||
#define INS_VERIFY_KEY 0x26
|
#define INS_VERIFY_KEY 0x26
|
||||||
|
#define INS_MANAGE_SEEDWORDS 0x28
|
||||||
|
|
||||||
#define INS_SECRET_KEY_TO_PUBLIC_KEY 0x30
|
#define INS_SECRET_KEY_TO_PUBLIC_KEY 0x30
|
||||||
#define INS_GEN_KEY_DERIVATION 0x32
|
#define INS_GEN_KEY_DERIVATION 0x32
|
||||||
|
@ -205,6 +242,7 @@ namespace hw {
|
||||||
this->reset_buffer();
|
this->reset_buffer();
|
||||||
this->mode = NONE;
|
this->mode = NONE;
|
||||||
this->has_view_key = false;
|
this->has_view_key = false;
|
||||||
|
this->tx_in_progress = false;
|
||||||
MDEBUG( "Device "<<this->id <<" Created");
|
MDEBUG( "Device "<<this->id <<" Created");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +355,26 @@ namespace hw {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void device_ledger::send_secret(const unsigned char sec[32], int &offset) {
|
||||||
|
MDEBUG("send_secret: " << this->tx_in_progress);
|
||||||
|
memmove(this->buffer_send+offset, sec, 32);
|
||||||
|
offset +=32;
|
||||||
|
if (this->tx_in_progress) {
|
||||||
|
this->hmac_map.find_mac((uint8_t*)sec, this->buffer_send+offset);
|
||||||
|
offset += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void device_ledger::receive_secret(unsigned char sec[32], int &offset) {
|
||||||
|
MDEBUG("receive_secret: " << this->tx_in_progress);
|
||||||
|
memmove(sec, this->buffer_recv+offset, 32);
|
||||||
|
offset += 32;
|
||||||
|
if (this->tx_in_progress) {
|
||||||
|
this->hmac_map.add_mac((uint8_t*)sec, this->buffer_recv+offset);
|
||||||
|
offset += 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool device_ledger::reset() {
|
bool device_ledger::reset() {
|
||||||
reset_buffer();
|
reset_buffer();
|
||||||
int offset = set_command_header_noopt(INS_RESET);
|
int offset = set_command_header_noopt(INS_RESET);
|
||||||
|
@ -418,10 +476,10 @@ namespace hw {
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
cryptonote::account_public_address pubkey;
|
cryptonote::account_public_address pubkey;
|
||||||
this->get_public_address(pubkey);
|
this->get_public_address(pubkey);
|
||||||
|
#endif
|
||||||
crypto::secret_key vkey;
|
crypto::secret_key vkey;
|
||||||
crypto::secret_key skey;
|
crypto::secret_key skey;
|
||||||
this->get_secret_keys(vkey,skey);
|
this->get_secret_keys(vkey,skey);
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -509,6 +567,7 @@ namespace hw {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
send_simple(INS_GET_KEY, 0x04);
|
||||||
memmove(dbg_viewkey.data, this->buffer_recv+0, 32);
|
memmove(dbg_viewkey.data, this->buffer_recv+0, 32);
|
||||||
memmove(dbg_spendkey.data, this->buffer_recv+32, 32);
|
memmove(dbg_spendkey.data, this->buffer_recv+32, 32);
|
||||||
#endif
|
#endif
|
||||||
|
@ -538,6 +597,27 @@ namespace hw {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void device_ledger::display_address(const cryptonote::subaddress_index& index, const boost::optional<crypto::hash8> &payment_id) {
|
||||||
|
AUTO_LOCK_CMD();
|
||||||
|
|
||||||
|
int offset = set_command_header_noopt(INS_DISPLAY_ADDRESS, payment_id?1:0);
|
||||||
|
//index
|
||||||
|
memmove(this->buffer_send+offset, &index, sizeof(cryptonote::subaddress_index));
|
||||||
|
offset +=8 ;
|
||||||
|
|
||||||
|
//payment ID
|
||||||
|
if (payment_id) {
|
||||||
|
memmove(this->buffer_send+offset, (*payment_id).data, 8);
|
||||||
|
} else {
|
||||||
|
memset(this->buffer_send+offset, 0, 8);
|
||||||
|
}
|
||||||
|
offset +=8;
|
||||||
|
|
||||||
|
this->buffer_send[4] = offset-5;
|
||||||
|
this->length_send = offset;
|
||||||
|
CHECK_AND_ASSERT_THROW_MES(this->exchange_wait_on_input() == 0, "Timeout/Error on display address.");
|
||||||
|
}
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* SUB ADDRESS */
|
/* SUB ADDRESS */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
@ -573,8 +653,7 @@ namespace hw {
|
||||||
memmove(this->buffer_send+offset, pub.data, 32);
|
memmove(this->buffer_send+offset, pub.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//derivation
|
//derivation
|
||||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
this->send_secret((unsigned char*)derivation.data, offset);
|
||||||
offset += 32;
|
|
||||||
//index
|
//index
|
||||||
this->buffer_send[offset+0] = output_index>>24;
|
this->buffer_send[offset+0] = output_index>>24;
|
||||||
this->buffer_send[offset+1] = output_index>>16;
|
this->buffer_send[offset+1] = output_index>>16;
|
||||||
|
@ -706,8 +785,7 @@ namespace hw {
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
|
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, sec.data, 32);
|
this->send_secret((unsigned char*)sec.data, offset);
|
||||||
offset += 32;
|
|
||||||
//index
|
//index
|
||||||
static_assert(sizeof(cryptonote::subaddress_index) == 8, "cryptonote::subaddress_index shall be 8 bytes length");
|
static_assert(sizeof(cryptonote::subaddress_index) == 8, "cryptonote::subaddress_index shall be 8 bytes length");
|
||||||
memmove(this->buffer_send+offset, &index, sizeof(cryptonote::subaddress_index));
|
memmove(this->buffer_send+offset, &index, sizeof(cryptonote::subaddress_index));
|
||||||
|
@ -717,7 +795,8 @@ namespace hw {
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
memmove(sub_sec.data, &this->buffer_recv[0], 32);
|
offset = 0;
|
||||||
|
this->receive_secret((unsigned char*)sub_sec.data, offset);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::secret_key sub_sec_clear = hw::ledger::decrypt(sub_sec);
|
crypto::secret_key sub_sec_clear = hw::ledger::decrypt(sub_sec);
|
||||||
|
@ -737,8 +816,7 @@ namespace hw {
|
||||||
|
|
||||||
offset = set_command_header_noopt(INS_VERIFY_KEY);
|
offset = set_command_header_noopt(INS_VERIFY_KEY);
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, secret_key.data, 32);
|
this->send_secret((unsigned char*)secret_key.data, offset);
|
||||||
offset += 32;
|
|
||||||
//pub
|
//pub
|
||||||
memmove(this->buffer_send+offset, public_key.data, 32);
|
memmove(this->buffer_send+offset, public_key.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -774,9 +852,7 @@ namespace hw {
|
||||||
memmove(this->buffer_send+offset, P.bytes, 32);
|
memmove(this->buffer_send+offset, P.bytes, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, a.bytes, 32);
|
this->send_secret(a.bytes, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -805,8 +881,7 @@ namespace hw {
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE);
|
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE);
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, a.bytes, 32);
|
this->send_secret(a.bytes, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -824,6 +899,7 @@ namespace hw {
|
||||||
|
|
||||||
bool device_ledger::sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) {
|
bool device_ledger::sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
int offset;
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const crypto::secret_key a_x = hw::ledger::decrypt(a);
|
const crypto::secret_key a_x = hw::ledger::decrypt(a);
|
||||||
|
@ -836,20 +912,19 @@ namespace hw {
|
||||||
log_hexbuffer("sc_secret_add: [[OUT]] aG", (char*)r_x.data, 32);
|
log_hexbuffer("sc_secret_add: [[OUT]] aG", (char*)r_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
|
offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
|
||||||
//sec key
|
//sec key
|
||||||
memmove(this->buffer_send+offset, a.data, 32);
|
this->send_secret((unsigned char*)a.data, offset);
|
||||||
offset += 32;
|
|
||||||
//sec key
|
//sec key
|
||||||
memmove(this->buffer_send+offset, b.data, 32);
|
this->send_secret((unsigned char*)b.data, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
//pub key
|
//sec key
|
||||||
memmove(r.data, &this->buffer_recv[0], 32);
|
offset = 0;
|
||||||
|
this->receive_secret((unsigned char*)r.data, offset);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::secret_key r_clear = hw::ledger::decrypt(r);
|
crypto::secret_key r_clear = hw::ledger::decrypt(r);
|
||||||
|
@ -861,6 +936,8 @@ namespace hw {
|
||||||
|
|
||||||
crypto::secret_key device_ledger::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) {
|
crypto::secret_key device_ledger::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
int offset;
|
||||||
|
|
||||||
if (recover) {
|
if (recover) {
|
||||||
throw std::runtime_error("device generate key does not support recover");
|
throw std::runtime_error("device generate key does not support recover");
|
||||||
}
|
}
|
||||||
|
@ -877,9 +954,11 @@ namespace hw {
|
||||||
|
|
||||||
send_simple(INS_GENERATE_KEYPAIR);
|
send_simple(INS_GENERATE_KEYPAIR);
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
//pub key
|
//pub key
|
||||||
memmove(pub.data, &this->buffer_recv[0], 32);
|
memmove(pub.data, &this->buffer_recv[0], 32);
|
||||||
memmove(sec.data, &this->buffer_recv[32], 32);
|
offset += 32;
|
||||||
|
this->receive_secret((unsigned char*)sec.data, offset);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::secret_key sec_clear = hw::ledger::decrypt(sec);
|
crypto::secret_key sec_clear = hw::ledger::decrypt(sec);
|
||||||
|
@ -922,15 +1001,16 @@ namespace hw {
|
||||||
memmove(this->buffer_send+offset, pub.data, 32);
|
memmove(this->buffer_send+offset, pub.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, sec.data, 32);
|
this->send_secret((unsigned char*)sec.data, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
//derivattion data
|
//derivattion data
|
||||||
memmove(derivation.data, &this->buffer_recv[0], 32);
|
this->receive_secret((unsigned char*)derivation.data, offset);
|
||||||
|
|
||||||
r = true;
|
r = true;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
@ -978,9 +1058,9 @@ namespace hw {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
|
int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
|
||||||
//derivattion
|
//derivation
|
||||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
this->send_secret((unsigned char*)derivation.data, offset);
|
||||||
offset += 32;
|
|
||||||
//index
|
//index
|
||||||
this->buffer_send[offset+0] = output_index>>24;
|
this->buffer_send[offset+0] = output_index>>24;
|
||||||
this->buffer_send[offset+1] = output_index>>16;
|
this->buffer_send[offset+1] = output_index>>16;
|
||||||
|
@ -992,8 +1072,9 @@ namespace hw {
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
//derivattion data
|
//derivation data
|
||||||
memmove(res.data, &this->buffer_recv[0], 32);
|
offset = 0;
|
||||||
|
this->receive_secret((unsigned char*)res.data, offset);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::ec_scalar res_clear = hw::ledger::decrypt(res);
|
crypto::ec_scalar res_clear = hw::ledger::decrypt(res);
|
||||||
|
@ -1020,8 +1101,7 @@ namespace hw {
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
|
int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
|
||||||
//derivation
|
//derivation
|
||||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
this->send_secret((unsigned char*)derivation.data, offset);
|
||||||
offset += 32;
|
|
||||||
//index
|
//index
|
||||||
this->buffer_send[offset+0] = output_index>>24;
|
this->buffer_send[offset+0] = output_index>>24;
|
||||||
this->buffer_send[offset+1] = output_index>>16;
|
this->buffer_send[offset+1] = output_index>>16;
|
||||||
|
@ -1029,15 +1109,15 @@ namespace hw {
|
||||||
this->buffer_send[offset+3] = output_index>>0;
|
this->buffer_send[offset+3] = output_index>>0;
|
||||||
offset += 4;
|
offset += 4;
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, sec.data, 32);
|
this->send_secret((unsigned char*)sec.data, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
//pub key
|
offset = 0;
|
||||||
memmove(derived_sec.data, &this->buffer_recv[0], 32);
|
//sec key
|
||||||
|
this->receive_secret((unsigned char*)derived_sec.data, offset);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::secret_key derived_sec_clear = hw::ledger::decrypt(derived_sec);
|
crypto::secret_key derived_sec_clear = hw::ledger::decrypt(derived_sec);
|
||||||
|
@ -1064,8 +1144,7 @@ namespace hw {
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
|
int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
|
||||||
//derivation
|
//derivation
|
||||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
this->send_secret((unsigned char*)derivation.data, offset);
|
||||||
offset += 32;
|
|
||||||
//index
|
//index
|
||||||
this->buffer_send[offset+0] = output_index>>24;
|
this->buffer_send[offset+0] = output_index>>24;
|
||||||
this->buffer_send[offset+1] = output_index>>16;
|
this->buffer_send[offset+1] = output_index>>16;
|
||||||
|
@ -1106,8 +1185,7 @@ namespace hw {
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_SECRET_KEY_TO_PUBLIC_KEY);
|
int offset = set_command_header_noopt(INS_SECRET_KEY_TO_PUBLIC_KEY);
|
||||||
//sec key
|
//sec key
|
||||||
memmove(this->buffer_send+offset, sec.data, 32);
|
this->send_secret((unsigned char*)sec.data, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -1141,8 +1219,7 @@ namespace hw {
|
||||||
memmove(this->buffer_send+offset, pub.data, 32);
|
memmove(this->buffer_send+offset, pub.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//sec
|
//sec
|
||||||
memmove(this->buffer_send+offset, sec.data, 32);
|
this->send_secret((unsigned char*)sec.data, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -1211,8 +1288,7 @@ namespace hw {
|
||||||
memmove(&this->buffer_send[offset], D.data, 32);
|
memmove(&this->buffer_send[offset], D.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
// r
|
// r
|
||||||
memmove(&this->buffer_send[offset], r.data, 32);
|
this->send_secret((unsigned char*)r.data, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -1225,6 +1301,7 @@ namespace hw {
|
||||||
log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r.data, sizeof( sig.r.data));
|
log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r.data, sizeof( sig.r.data));
|
||||||
|
|
||||||
this->controle_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x);
|
this->controle_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x);
|
||||||
|
MDEBUG("FAIL is normal if random is not fixed in proof");
|
||||||
hw::ledger::check32("generate_tx_proof", "c", sig_x.c.data, sig.c.data);
|
hw::ledger::check32("generate_tx_proof", "c", sig_x.c.data, sig.c.data);
|
||||||
hw::ledger::check32("generate_tx_proof", "r", sig_x.r.data, sig.r.data);
|
hw::ledger::check32("generate_tx_proof", "r", sig_x.r.data, sig.r.data);
|
||||||
|
|
||||||
|
@ -1233,8 +1310,10 @@ namespace hw {
|
||||||
|
|
||||||
bool device_ledger::open_tx(crypto::secret_key &tx_key) {
|
bool device_ledger::open_tx(crypto::secret_key &tx_key) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
this->lock();
|
||||||
key_map.clear();
|
key_map.clear();
|
||||||
|
hmac_map.clear();
|
||||||
|
this->tx_in_progress = true;
|
||||||
int offset = set_command_header_noopt(INS_OPEN_TX, 0x01);
|
int offset = set_command_header_noopt(INS_OPEN_TX, 0x01);
|
||||||
|
|
||||||
//account
|
//account
|
||||||
|
@ -1248,7 +1327,13 @@ namespace hw {
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
memmove(tx_key.data, &this->buffer_recv[32], 32);
|
//skip R, receive: r, r_hmac, fake_a, a_hmac, fake_b, hmac_b
|
||||||
|
unsigned char tmp[32];
|
||||||
|
offset = 32;
|
||||||
|
this->receive_secret((unsigned char*)tx_key.data, offset);
|
||||||
|
this->receive_secret(tmp, offset);
|
||||||
|
this->receive_secret(tmp, offset);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const crypto::secret_key r_x = hw::ledger::decrypt(tx_key);
|
const crypto::secret_key r_x = hw::ledger::decrypt(tx_key);
|
||||||
log_hexbuffer("open_tx: [[OUT]] R ", (char*)&this->buffer_recv[0], 32);
|
log_hexbuffer("open_tx: [[OUT]] R ", (char*)&this->buffer_recv[0], 32);
|
||||||
|
@ -1276,8 +1361,7 @@ namespace hw {
|
||||||
memmove(&this->buffer_send[offset], public_key.data, 32);
|
memmove(&this->buffer_send[offset], public_key.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//sec
|
//sec
|
||||||
memmove(&this->buffer_send[offset], secret_key.data, 32);
|
this->send_secret((unsigned char*)secret_key.data, offset);
|
||||||
offset += 32;
|
|
||||||
//id
|
//id
|
||||||
memmove(&this->buffer_send[offset], payment_id.data, 8);
|
memmove(&this->buffer_send[offset], payment_id.data, 8);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
@ -1365,8 +1449,7 @@ namespace hw {
|
||||||
this->buffer_send[offset+3] = tx_version>>0;
|
this->buffer_send[offset+3] = tx_version>>0;
|
||||||
offset += 4;
|
offset += 4;
|
||||||
//tx_key
|
//tx_key
|
||||||
memmove(&this->buffer_send[offset], tx_key.data, 32);
|
this->send_secret((unsigned char*)tx_key.data, offset);
|
||||||
offset += 32;
|
|
||||||
//txkey_pub
|
//txkey_pub
|
||||||
memmove(&this->buffer_send[offset], txkey_pub.data, 32);
|
memmove(&this->buffer_send[offset], txkey_pub.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -1394,11 +1477,11 @@ namespace hw {
|
||||||
offset++;
|
offset++;
|
||||||
//additional_tx_key
|
//additional_tx_key
|
||||||
if (need_additional_txkeys) {
|
if (need_additional_txkeys) {
|
||||||
memmove(&this->buffer_send[offset], additional_txkey.sec.data, 32);
|
this->send_secret((unsigned char*)additional_txkey.sec.data, offset);
|
||||||
} else {
|
} else {
|
||||||
memset(&this->buffer_send[offset], 0, 32);
|
memset(&this->buffer_send[offset], 0, 32);
|
||||||
}
|
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
}
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -1411,9 +1494,8 @@ namespace hw {
|
||||||
{
|
{
|
||||||
ASSERT_X(recv_len>=32, "Not enought data from device");
|
ASSERT_X(recv_len>=32, "Not enought data from device");
|
||||||
crypto::secret_key scalar1;
|
crypto::secret_key scalar1;
|
||||||
memmove(scalar1.data, &this->buffer_recv[offset],32);
|
this->receive_secret((unsigned char*)scalar1.data, offset);
|
||||||
amount_keys.push_back(rct::sk2rct(scalar1));
|
amount_keys.push_back(rct::sk2rct(scalar1));
|
||||||
offset += 32;
|
|
||||||
recv_len -= 32;
|
recv_len -= 32;
|
||||||
}
|
}
|
||||||
ASSERT_X(recv_len>=32, "Not enought data from device");
|
ASSERT_X(recv_len>=32, "Not enought data from device");
|
||||||
|
@ -1464,8 +1546,7 @@ namespace hw {
|
||||||
rct::key mask;
|
rct::key mask;
|
||||||
int offset = set_command_header_noopt(INS_GEN_COMMITMENT_MASK);
|
int offset = set_command_header_noopt(INS_GEN_COMMITMENT_MASK);
|
||||||
// AKout
|
// AKout
|
||||||
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
this->send_secret(AKout.bytes, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -1494,8 +1575,7 @@ namespace hw {
|
||||||
this->buffer_send[offset] = short_amount?0x02:0x00;
|
this->buffer_send[offset] = short_amount?0x02:0x00;
|
||||||
offset += 1;
|
offset += 1;
|
||||||
// AKout
|
// AKout
|
||||||
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
this->send_secret(AKout.bytes, offset);
|
||||||
offset += 32;
|
|
||||||
//mask k
|
//mask k
|
||||||
memmove(this->buffer_send+offset, unmasked.mask.bytes, 32);
|
memmove(this->buffer_send+offset, unmasked.mask.bytes, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -1535,8 +1615,7 @@ namespace hw {
|
||||||
this->buffer_send[offset] = short_amount?0x02:0x00;
|
this->buffer_send[offset] = short_amount?0x02:0x00;
|
||||||
offset += 1;
|
offset += 1;
|
||||||
// AKout
|
// AKout
|
||||||
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
this->send_secret(AKout.bytes, offset);
|
||||||
offset += 32;
|
|
||||||
//mask k
|
//mask k
|
||||||
memmove(this->buffer_send+offset, masked.mask.bytes, 32);
|
memmove(this->buffer_send+offset, masked.mask.bytes, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -1649,7 +1728,6 @@ namespace hw {
|
||||||
this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
|
this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
|
||||||
this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2)?0x02:0x00;
|
this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2)?0x02:0x00;
|
||||||
offset += 1;
|
offset += 1;
|
||||||
if (found) {
|
|
||||||
//is_subaddress
|
//is_subaddress
|
||||||
this->buffer_send[offset] = outKeys.is_subaddress;
|
this->buffer_send[offset] = outKeys.is_subaddress;
|
||||||
offset++;
|
offset++;
|
||||||
|
@ -1663,12 +1741,8 @@ namespace hw {
|
||||||
memmove(this->buffer_send+offset, outKeys.Bout.bytes, 32);
|
memmove(this->buffer_send+offset, outKeys.Bout.bytes, 32);
|
||||||
offset+=32;
|
offset+=32;
|
||||||
//AKout
|
//AKout
|
||||||
memmove(this->buffer_send+offset, outKeys.AKout.bytes, 32);
|
this->send_secret(outKeys.AKout.bytes, offset);
|
||||||
offset+=32;
|
|
||||||
} else {
|
|
||||||
// dummy: is_subaddress Aout Bout AKout
|
|
||||||
offset += 2+32*3;
|
|
||||||
}
|
|
||||||
//C
|
//C
|
||||||
memmove(this->buffer_send+offset, data+C_offset,32);
|
memmove(this->buffer_send+offset, data+C_offset,32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -1760,17 +1834,19 @@ namespace hw {
|
||||||
memmove(this->buffer_send+offset, H.bytes, 32);
|
memmove(this->buffer_send+offset, H.bytes, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//mask xin
|
//mask xin
|
||||||
memmove(this->buffer_send+offset, xx.bytes, 32);
|
this->send_secret(xx.bytes, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
memmove(a.bytes, &this->buffer_recv[32*0], 32);
|
offset = 0;
|
||||||
memmove(aG.bytes, &this->buffer_recv[32*1], 32);
|
this->receive_secret(a.bytes, offset);
|
||||||
memmove(aHP.bytes, &this->buffer_recv[32*2], 32);
|
memmove(aG.bytes, &this->buffer_recv[offset], 32);
|
||||||
memmove(II.bytes, &this->buffer_recv[32*3], 32);
|
offset +=32;
|
||||||
|
memmove(aHP.bytes, &this->buffer_recv[offset], 32);
|
||||||
|
offset +=32;
|
||||||
|
memmove(II.bytes, &this->buffer_recv[offset], 32);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
a_x = hw::ledger::decrypt(a);
|
a_x = hw::ledger::decrypt(a);
|
||||||
|
@ -1788,6 +1864,7 @@ namespace hw {
|
||||||
|
|
||||||
bool device_ledger::mlsag_prepare(rct::key &a, rct::key &aG) {
|
bool device_ledger::mlsag_prepare(rct::key &a, rct::key &aG) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
int offset;
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
rct::key a_x;
|
rct::key a_x;
|
||||||
|
@ -1796,8 +1873,9 @@ namespace hw {
|
||||||
|
|
||||||
send_simple(INS_MLSAG, 0x01);
|
send_simple(INS_MLSAG, 0x01);
|
||||||
|
|
||||||
memmove(a.bytes, &this->buffer_recv[32*0], 32);
|
offset = 0;
|
||||||
memmove(aG.bytes, &this->buffer_recv[32*1], 32);
|
this->receive_secret(a.bytes, offset);
|
||||||
|
memmove(aG.bytes, &this->buffer_recv[offset], 32);
|
||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
a_x = hw::ledger::decrypt(a);
|
a_x = hw::ledger::decrypt(a);
|
||||||
|
@ -1870,11 +1948,9 @@ namespace hw {
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
//xx
|
//xx
|
||||||
memmove(this->buffer_send+offset, xx[j].bytes, 32);
|
this->send_secret(xx[j].bytes, offset);
|
||||||
offset += 32;
|
|
||||||
//alpa
|
//alpa
|
||||||
memmove(this->buffer_send+offset, alpha[j].bytes, 32);
|
this->send_secret(alpha[j].bytes, offset);
|
||||||
offset += 32;
|
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
|
@ -1900,6 +1976,10 @@ namespace hw {
|
||||||
bool device_ledger::close_tx() {
|
bool device_ledger::close_tx() {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
send_simple(INS_CLOSE_TX);
|
send_simple(INS_CLOSE_TX);
|
||||||
|
key_map.clear();
|
||||||
|
hmac_map.clear();
|
||||||
|
this->tx_in_progress = false;
|
||||||
|
this->unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,25 @@ namespace hw {
|
||||||
void log();
|
void log();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SecHMAC {
|
||||||
|
public:
|
||||||
|
uint32_t sec[32];
|
||||||
|
uint32_t hmac[32];
|
||||||
|
|
||||||
|
SecHMAC(const uint8_t s[32], const uint8_t m[32]);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class HMACmap {
|
||||||
|
public:
|
||||||
|
std::vector<SecHMAC> hmacs;
|
||||||
|
|
||||||
|
void find_mac(const uint8_t sec[32], uint8_t hmac[32]) ;
|
||||||
|
void add_mac(const uint8_t sec[32], const uint8_t hmac[32]) ;
|
||||||
|
void clear() ;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define BUFFER_SEND_SIZE 262
|
#define BUFFER_SEND_SIZE 262
|
||||||
#define BUFFER_RECV_SIZE 262
|
#define BUFFER_RECV_SIZE 262
|
||||||
|
|
||||||
|
@ -115,15 +134,21 @@ namespace hw {
|
||||||
int set_command_header(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00);
|
int set_command_header(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00);
|
||||||
int set_command_header_noopt(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00);
|
int set_command_header_noopt(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00);
|
||||||
void send_simple(unsigned char ins, unsigned char p1 = 0x00);
|
void send_simple(unsigned char ins, unsigned char p1 = 0x00);
|
||||||
|
void send_secret(const unsigned char sec[32], int &offset);
|
||||||
|
void receive_secret(unsigned char sec[32], int &offset);
|
||||||
|
|
||||||
// hw running mode
|
// hw running mode
|
||||||
device_mode mode;
|
device_mode mode;
|
||||||
|
bool tx_in_progress;
|
||||||
|
|
||||||
// map public destination key to ephemeral destination key
|
// map public destination key to ephemeral destination key
|
||||||
Keymap key_map;
|
Keymap key_map;
|
||||||
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change,
|
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change,
|
||||||
const bool need_additional, const size_t real_output_index,
|
const bool need_additional, const size_t real_output_index,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key);
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key);
|
||||||
|
//hmac for some encrypted value
|
||||||
|
HMACmap hmac_map;
|
||||||
|
|
||||||
// To speed up blockchain parsing the view key maybe handle here.
|
// To speed up blockchain parsing the view key maybe handle here.
|
||||||
crypto::secret_key viewkey;
|
crypto::secret_key viewkey;
|
||||||
bool has_view_key;
|
bool has_view_key;
|
||||||
|
@ -174,7 +199,7 @@ namespace hw {
|
||||||
bool get_public_address(cryptonote::account_public_address &pubkey) override;
|
bool get_public_address(cryptonote::account_public_address &pubkey) override;
|
||||||
bool get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) override;
|
bool get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) override;
|
||||||
bool generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key, uint64_t kdf_rounds) override;
|
bool generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key, uint64_t kdf_rounds) override;
|
||||||
|
void display_address(const cryptonote::subaddress_index& index, const boost::optional<crypto::hash8> &payment_id) override;
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* SUB ADDRESS */
|
/* SUB ADDRESS */
|
||||||
|
|
Loading…
Reference in New Issue