Merge pull request #3353

73dd883d Ledger HW Bug fixes (Cédric)
This commit is contained in:
Riccardo Spagni 2018-03-14 13:36:14 +02:00
commit 2dfb4f098e
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
11 changed files with 210 additions and 138 deletions

View File

@ -140,9 +140,7 @@ DISABLE_VS_WARNINGS(4244 4345)
hwdev.init(); hwdev.init();
hwdev.connect(); hwdev.connect();
hwdev.get_public_address(m_keys.m_account_address); hwdev.get_public_address(m_keys.m_account_address);
#ifdef DEBUG_HWDEVICE
hwdev.get_secret_keys(m_keys.m_view_secret_key, m_keys.m_spend_secret_key); hwdev.get_secret_keys(m_keys.m_view_secret_key, m_keys.m_spend_secret_key);
#endif
struct tm timestamp = {0}; struct tm timestamp = {0};
timestamp.tm_year = 2014 - 1900; // year 2014 timestamp.tm_year = 2014 - 1900; // year 2014
timestamp.tm_mon = 4 - 1; // month april timestamp.tm_mon = 4 - 1; // month april

View File

@ -409,7 +409,7 @@ namespace cryptonote
r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key, hwdev); r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key, hwdev);
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")"); CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, output_index, amount_keys.back(), out_eph_public_key); hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, output_index, amount_keys.back(), out_eph_public_key);
tx_out out; tx_out out;
out.amount = dst_entr.amount; out.amount = dst_entr.amount;

View File

@ -28,6 +28,20 @@
// //
/* Note about debug:
* To debug Device you can def the following :
* #define DEBUG_HWDEVICE
* Activate debug mechanism:
* - Add more trace
* - All computation done by device are checked by default device.
* Required IODUMMYCRYPT_HWDEVICE or IONOCRYPT_HWDEVICE for fully working
* #define IODUMMYCRYPT_HWDEVICE 1
* - It assumes sensitive data encryption is is off on device side. a XOR with 0x55. This allow Ledger Class to make check on clear value
* #define IONOCRYPT_HWDEVICE 1
* - It assumes sensitive data encryption is off on device side.
*/
#pragma once #pragma once
#include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_basic.h"
@ -128,8 +142,8 @@ namespace hw {
virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) = 0; virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) = 0;
virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) = 0; virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) = 0;
virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0; const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0;
virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0; virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0;

View File

@ -29,11 +29,6 @@
#pragma once #pragma once
//#define DEBUG_HWDEVICE
//#define IODUMMYCRYPT 1
//#define IONOCRYPT 1
namespace hw { namespace hw {
class device; class device;

View File

@ -185,7 +185,7 @@ namespace hw {
} }
bool device_default::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, bool device_default::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, 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) {
return true; return true;
} }

View File

@ -105,8 +105,8 @@ namespace hw {
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override;
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override; bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override;
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override; bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;

View File

@ -55,30 +55,29 @@ namespace hw {
#define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ; #define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ;
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
#define DEVICE_CONTROLE :controle_device(hw::get_device("default"))
crypto::secret_key viewkey; crypto::secret_key viewkey;
crypto::secret_key spendkey; crypto::secret_key spendkey;
#else
#define DEVICE_CONTROLE
#endif #endif
/* ===================================================================== */ /* ===================================================================== */
/* === Keymap ==== */ /* === Keymap ==== */
/* ===================================================================== */ /* ===================================================================== */
ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, size_t real_output_index, const rct::key& P, const rct::key& AK) { ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const size_t real_output_index, const rct::key& P, const rct::key& AK) {
Aout = A; Aout = A;
Bout = B; Bout = B;
is_subaddress = is_subaddr;
index = real_output_index; index = real_output_index;
Pout = P; Pout = P;
AKout = AK; AKout = AK;
} }
ABPkeys::ABPkeys(const ABPkeys& keys) { ABPkeys::ABPkeys(const ABPkeys& keys) {
Aout = keys.Aout; Aout = keys.Aout;
Bout = keys.Bout; Bout = keys.Bout;
is_subaddress = keys.is_subaddress;
index = keys.index; index = keys.index;
Pout = keys.Pout; Pout = keys.Pout;
AKout = keys.AKout; AKout = keys.AKout;
} }
@ -109,6 +108,7 @@ namespace hw {
log_message(" keymap", std::to_string(i)); log_message(" keymap", std::to_string(i));
log_hexbuffer(" Aout", (char*)ABP[i].Aout.bytes, 32); log_hexbuffer(" Aout", (char*)ABP[i].Aout.bytes, 32);
log_hexbuffer(" Bout", (char*)ABP[i].Bout.bytes, 32); log_hexbuffer(" Bout", (char*)ABP[i].Bout.bytes, 32);
log_message (" is_sub", std::to_string(ABP[i].is_subaddress));
log_message (" index", std::to_string(ABP[i].index)); log_message (" index", std::to_string(ABP[i].index));
log_hexbuffer(" Pout", (char*)ABP[i].Pout.bytes, 32); log_hexbuffer(" Pout", (char*)ABP[i].Pout.bytes, 32);
} }
@ -189,7 +189,7 @@ namespace hw {
} }
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
device_ledger::device_ledger() DEVICE_CONTROLE { device_ledger::device_ledger() {
this->id = device_id++; this->id = device_id++;
this->hCard = 0; this->hCard = 0;
this->hContext = 0; this->hContext = 0;
@ -300,6 +300,9 @@ namespace hw {
} }
bool device_ledger::init(void) { bool device_ledger::init(void) {
#ifdef DEBUG_HWDEVICE
this->controle_device = &hw::get_device("default");
#endif
LONG rv; LONG rv;
this->release(); this->release();
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM,0,0, &this->hContext); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM,0,0, &this->hContext);
@ -411,12 +414,6 @@ namespace hw {
/* WALLET & ADDRESS */ /* WALLET & ADDRESS */
/* ======================================================================= */ /* ======================================================================= */
bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) {
memset(viewkey.data, 0x00, 32);
memset(spendkey.data, 0xFF, 32);
return true;
}
/* Application API */ /* Application API */
bool device_ledger::get_public_address(cryptonote::account_public_address &pubkey){ bool device_ledger::get_public_address(cryptonote::account_public_address &pubkey){
@ -449,8 +446,11 @@ namespace hw {
return true; return true;
} }
#ifdef DEBUG_HWDEVICE
bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) { bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) {
memset(viewkey.data, 0x00, 32);
memset(spendkey.data, 0xFF, 32);
#ifdef DEBUG_HWDEVICE
lock_device(); lock_device();
try { try {
//spcialkey, normal conf handled in decrypt //spcialkey, normal conf handled in decrypt
@ -479,9 +479,9 @@ namespace hw {
unlock_device(); unlock_device();
throw; throw;
} }
#endif
return true; return true;
} }
#endif
bool device_ledger::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) { bool device_ledger::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) {
lock_device(); lock_device();
@ -489,9 +489,9 @@ namespace hw {
int offset; int offset;
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const cryptonote::account_keys keys_x = decrypt(keys);
crypto::chacha_key key_x; crypto::chacha_key key_x;
this->controle_device.generate_chacha_key(keys_x, key_x); cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
this->controle_device->generate_chacha_key(keys_x, key_x);
#endif #endif
reset_buffer(); reset_buffer();
@ -541,7 +541,11 @@ namespace hw {
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
const std::size_t output_index_x = output_index; const std::size_t output_index_x = output_index;
crypto::public_key derived_pub_x; crypto::public_key derived_pub_x;
this->controle_device.derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x); hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32);
hw::ledger::log_message ("derive_subaddress_public_key: [[IN]] index ", std::to_string((int)output_index_x));
this->controle_device->derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -599,7 +603,11 @@ namespace hw {
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
const cryptonote::subaddress_index index_x = index; const cryptonote::subaddress_index index_x = index;
crypto::public_key D_x; crypto::public_key D_x;
this->controle_device.get_subaddress_spend_public_key(keys_x, index_x, D_x); hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32);
hw::ledger::log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor));
this->controle_device->get_subaddress_spend_public_key(keys_x, index_x, D_x);
hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32);
#endif #endif
if (index.is_zero()) { if (index.is_zero()) {
@ -662,7 +670,14 @@ namespace hw {
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
const cryptonote::subaddress_index index_x = index; const cryptonote::subaddress_index index_x = index;
cryptonote::account_public_address address_x; cryptonote::account_public_address address_x;
this->controle_device.get_subaddress(keys_x, index_x, address_x); hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32);
hw::ledger::log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor));
this->controle_device->get_subaddress(keys_x, index_x, address_x);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32);
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32);
#endif #endif
if (index.is_zero()) { if (index.is_zero()) {
@ -715,7 +730,10 @@ namespace hw {
const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
const cryptonote::subaddress_index index_x = index; const cryptonote::subaddress_index index_x = index;
crypto::secret_key sub_sec_x; crypto::secret_key sub_sec_x;
this->controle_device.get_subaddress_secret_key(sec_x, index_x, sub_sec_x); hw::ledger::log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32);
this->controle_device->get_subaddress_secret_key(sec_x, index_x, sub_sec_x);
hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -808,10 +826,13 @@ namespace hw {
unsigned char options = 0; unsigned char options = 0;
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const rct::key pub_x = pub; const rct::key P_x = P;
const rct::key sec_x = hw::ledger::decrypt(sec); const rct::key a_x = hw::ledger::decrypt(a);
rct::key mulkey_x; rct::key aP_x;
this->controle_device.scalarmultKey(pub_x, sec_x, mulkey_x); hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] P ", (char*)P_x.bytes, 32);
hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32);
this->controle_device->scalarmultKey(aP_x, P_x, a_x);
hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aP", (char*)aP_x.bytes, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -843,7 +864,7 @@ namespace hw {
memmove(aP.bytes, &this->buffer_recv[0], 32); memmove(aP.bytes, &this->buffer_recv[0], 32);
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
hw::ledger::check32("scalarmultKey", "mulkey", (char*)mulkey_x.bytes, (char*)mulkey.bytes); hw::ledger::check32("scalarmultKey", "mulkey", (char*)aP_x.bytes, (char*)aP.bytes);
#endif #endif
unlock_device(); unlock_device();
@ -861,9 +882,11 @@ namespace hw {
unsigned char options = 0; unsigned char options = 0;
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const rct::key sec_x = hw::ledger::decrypt(sec); const rct::key a_x = hw::ledger::decrypt(a);
rct::key mulkey_x; rct::key aG_x;
this->controle_device.scalarmultBase(sec_x, mulkey_x); hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32);
this->controle_device->scalarmultBase(aG_x, a_x);
hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aG", (char*)aG_x.bytes, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -891,7 +914,7 @@ namespace hw {
memmove(aG.bytes, &this->buffer_recv[0], 32); memmove(aG.bytes, &this->buffer_recv[0], 32);
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
hw::ledger::check32("scalarmultBase", "mulkey", (char*)mulkey_x.bytes, (char*)mulkey.bytes); hw::ledger::check32("scalarmultBase", "mulkey", (char*)aG_x.bytes, (char*)aG.bytes);
#endif #endif
unlock_device(); unlock_device();
@ -913,7 +936,7 @@ namespace hw {
const crypto::secret_key a_x = hw::ledger::decrypt(a); const crypto::secret_key a_x = hw::ledger::decrypt(a);
const crypto::secret_key b_x = hw::ledger::decrypt(b); const crypto::secret_key b_x = hw::ledger::decrypt(b);
crypto::secret_key r_x; crypto::secret_key r_x;
this->controle_device.sc_secret_add(r_x, a_x, b_x); this->controle_device->sc_secret_add(r_x, a_x, b_x);
#endif #endif
reset_buffer(); reset_buffer();
@ -1021,10 +1044,10 @@ namespace hw {
const crypto::public_key pub_x = pub; const crypto::public_key pub_x = pub;
const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
crypto::key_derivation derivation_x; crypto::key_derivation derivation_x;
this->controle_device.generate_key_derivation(pub_x, sec_x, derivation_x); hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
hw::ledger::log_hexbuffer("generate_key_derivation: sec_x.data", sec_x.data, 32); hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
hw::ledger::log_hexbuffer("generate_key_derivation: pub_x.data", pub_x.data, 32); this->controle_device->generate_key_derivation(pub_x, sec_x, derivation_x);
hw::ledger::log_hexbuffer("generate_key_derivation: derivation_x.data", derivation_x.data, 32); hw::ledger::log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -1075,7 +1098,10 @@ namespace hw {
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
const size_t output_index_x = output_index; const size_t output_index_x = output_index;
crypto::ec_scalar res_x; crypto::ec_scalar res_x;
this->controle_device.derivation_to_scalar(derivation_x, output_index_x, res_x); hw::ledger::log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32);
hw::ledger::log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index_x));
this->controle_device->derivation_to_scalar(derivation_x, output_index_x, res_x);
hw::ledger::log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -1132,7 +1158,11 @@ namespace hw {
const std::size_t output_index_x = output_index; const std::size_t output_index_x = output_index;
const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
crypto::secret_key derived_sec_x; crypto::secret_key derived_sec_x;
this->controle_device.derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x); hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32);
hw::ledger::log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index_x));
hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32);
this->controle_device->derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x);
hw::ledger::log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -1192,7 +1222,11 @@ namespace hw {
const std::size_t output_index_x = output_index; const std::size_t output_index_x = output_index;
const crypto::public_key pub_x = pub; const crypto::public_key pub_x = pub;
crypto::public_key derived_pub_x; crypto::public_key derived_pub_x;
this->controle_device.derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x); hw::ledger::log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32);
hw::ledger::log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index_x));
hw::ledger::log_hexbuffer("derive_public_key: [[IN]] pub ", pub_x.data, 32);
this->controle_device->derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x);
hw::ledger::log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -1249,7 +1283,12 @@ namespace hw {
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
crypto::public_key pub_x; crypto::public_key pub_x;
this->controle_device.secret_key_to_public_key(sec_x, pub_x); hw::ledger::log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32);
bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x);
hw::ledger::log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32);
if (!rc){
hw::ledger::log_message("secret_key_to_public_key", "secret_key rejected");
}
#endif #endif
reset_buffer(); reset_buffer();
@ -1298,7 +1337,10 @@ namespace hw {
const crypto::public_key pub_x = pub; const crypto::public_key pub_x = pub;
const crypto::secret_key sec_x = hw::ledger::decrypt(sec); const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
crypto::key_image image_x; crypto::key_image image_x;
this->controle_device.generate_key_image(pub_x, sec_x, image_x); hw::ledger::log_hexbuffer("generate_key_image: [[IN]] pub ", pub_x.data, 32);
hw::ledger::log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32);
this->controle_device->generate_key_image(pub_x, sec_x, image_x);
hw::ledger::log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32);
#endif #endif
reset_buffer(); reset_buffer();
@ -1425,7 +1467,7 @@ namespace hw {
const crypto::public_key public_key_x = public_key; const crypto::public_key public_key_x = public_key;
const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key); const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key);
crypto::hash8 payment_id_x = payment_id; crypto::hash8 payment_id_x = payment_id;
this->controle_device.encrypt_payment_id(public_key_x, secret_key_x, payment_id_x); this->controle_device->encrypt_payment_id(public_key_x, secret_key_x, payment_id_x);
#endif #endif
reset_buffer(); reset_buffer();
@ -1466,11 +1508,11 @@ namespace hw {
return true; return true;
} }
bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, 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) {
lock_device(); lock_device();
try { try {
key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), real_output_index, rct::pk2rct(out_eph_public_key), amount_key)); key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, real_output_index, rct::pk2rct(out_eph_public_key), amount_key));
unlock_device(); unlock_device();
}catch (...) { }catch (...) {
unlock_device(); unlock_device();
@ -1488,7 +1530,7 @@ namespace hw {
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const rct::key AKout_x = hw::ledger::decrypt(AKout); const rct::key AKout_x = hw::ledger::decrypt(AKout);
rct::ecdhTuple unmasked_x = unmasked; rct::ecdhTuple unmasked_x = unmasked;
this->controle_device.ecdhEncode(AKout_x, unmasked_x); this->controle_device->ecdhEncode(unmasked_x, AKout_x);
#endif #endif
reset_buffer(); reset_buffer();
@ -1543,7 +1585,7 @@ namespace hw {
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const rct::key AKout_x = hw::ledger::decrypt(AKout); const rct::key AKout_x = hw::ledger::decrypt(AKout);
rct::ecdhTuple masked_x = masked; rct::ecdhTuple masked_x = masked;
this->controle_device.ecdhDecode(AKout_x, masked_x); this->controle_device->ecdhDecode(masked_x, AKout_x);
#endif #endif
reset_buffer(); reset_buffer();
@ -1604,7 +1646,7 @@ namespace hw {
const rct::keyV hashes_x = hashes; const rct::keyV hashes_x = hashes;
const rct::ctkeyV outPk_x = outPk; const rct::ctkeyV outPk_x = outPk;
rct::key prehash_x; rct::key prehash_x;
this->controle_device.mlsag_prehash(blob_x, inputs_size_x, outputs_size_x, hashes_x, outPk_x, prehash_x); this->controle_device->mlsag_prehash(blob_x, inputs_size_x, outputs_size_x, hashes_x, outPk_x, prehash_x);
if (inputs_size) { if (inputs_size) {
log_message("mlsag_prehash", (std::string("inputs_size not null: ") + std::to_string(inputs_size)).c_str()); log_message("mlsag_prehash", (std::string("inputs_size not null: ") + std::to_string(inputs_size)).c_str());
} }
@ -1629,6 +1671,7 @@ namespace hw {
offset += 1; offset += 1;
//type //type
uint8_t type = data[0];
this->buffer_send[offset] = data[0]; this->buffer_send[offset] = data[0];
offset += 1; offset += 1;
@ -1648,25 +1691,27 @@ namespace hw {
this->exchange(); this->exchange();
//pseudoOuts //pseudoOuts
for ( i = 0; i < inputs_size; i++) { if ((type == rct::RCTTypeSimple) || (type == rct::RCTTypeSimpleBulletproof)) {
reset_buffer(); for ( i = 0; i < inputs_size; i++) {
this->buffer_send[0] = 0x00; reset_buffer();
this->buffer_send[1] = INS_VALIDATE; this->buffer_send[0] = 0x00;
this->buffer_send[2] = 0x01; this->buffer_send[1] = INS_VALIDATE;
this->buffer_send[3] = i+2; this->buffer_send[2] = 0x01;
this->buffer_send[4] = 0x00; this->buffer_send[3] = i+2;
offset = 5; this->buffer_send[4] = 0x00;
//options offset = 5;
this->buffer_send[offset] = (i==inputs_size-1)? 0x00:0x80; //options
offset += 1; this->buffer_send[offset] = (i==inputs_size-1)? 0x00:0x80;
//pseudoOut offset += 1;
memmove(this->buffer_send+offset, data+data_offset,32); //pseudoOut
offset += 32; memmove(this->buffer_send+offset, data+data_offset,32);
data_offset += 32; offset += 32;
data_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();
}
} }
// ====== Aout, Bout, AKout, C, v, k ====== // ====== Aout, Bout, AKout, C, v, k ======
@ -1693,6 +1738,9 @@ namespace hw {
this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ; this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
offset += 1; offset += 1;
if (found) { if (found) {
//is_subaddress
this->buffer_send[offset] = outKeys.is_subaddress;
offset++;
//Aout //Aout
memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32); memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32);
offset+=32; offset+=32;
@ -1703,8 +1751,8 @@ namespace hw {
memmove(this->buffer_send+offset, outKeys.AKout.bytes, 32); memmove(this->buffer_send+offset, outKeys.AKout.bytes, 32);
offset+=32; offset+=32;
} else { } else {
// dummy: Aout Bout AKout // dummy: is_subaddress Aout Bout AKout
offset += 32*3; offset += 1+32*3;
} }
//C //C
memmove(this->buffer_send+offset, data+C_offset,32); memmove(this->buffer_send+offset, data+C_offset,32);
@ -1905,7 +1953,7 @@ namespace hw {
#ifdef DEBUG_HWDEVICE #ifdef DEBUG_HWDEVICE
const rct::keyV long_message_x = long_message; const rct::keyV long_message_x = long_message;
rct::key c_x; rct::key c_x;
this->controle_device.mlsag_hash(long_message_x, c_x); this->controle_device->mlsag_hash(long_message_x, c_x);
#endif #endif
cnt = long_message.size(); cnt = long_message.size();
@ -1964,7 +2012,7 @@ namespace hw {
const int rows_x = rows; const int rows_x = rows;
const int dsRows_x = dsRows; const int dsRows_x = dsRows;
rct::keyV ss_x(ss.size()); rct::keyV ss_x(ss.size());
this->controle_device.mlsag_sign(c_x, xx_x, alpha_x, rows_x, dsRows_x, ss_x); this->controle_device->mlsag_sign(c_x, xx_x, alpha_x, rows_x, dsRows_x, ss_x);
#endif #endif
for (size_t j = 0; j < dsRows; j++) { for (size_t j = 0; j < dsRows; j++) {

View File

@ -56,12 +56,13 @@ namespace hw {
public: public:
rct::key Aout; rct::key Aout;
rct::key Bout; rct::key Bout;
bool is_subaddress;
size_t index; size_t index;
rct::key Pout; rct::key Pout;
rct::key AKout; rct::key AKout;
ABPkeys(const rct::key& A, const rct::key& B, size_t index, const rct::key& P,const rct::key& AK); ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, size_t index, const rct::key& P,const rct::key& AK);
ABPkeys(const ABPkeys& keys) ; ABPkeys(const ABPkeys& keys) ;
ABPkeys() {index=0;} ABPkeys() {index=0;is_subaddress=false;}
}; };
class Keymap { class Keymap {
@ -103,8 +104,8 @@ namespace hw {
unsigned int exchange(unsigned int ok=0x9000, unsigned int mask=0xFFFF); unsigned int exchange(unsigned int ok=0x9000, unsigned int mask=0xFFFF);
void reset_buffer(void); void reset_buffer(void);
#ifdef DEBUGLEDGER #ifdef DEBUG_HWDEVICE
Device &controle_device; device *controle_device;
#endif #endif
public: public:
@ -174,8 +175,8 @@ namespace hw {
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override;
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override; bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec) override;
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, size_t real_output_index, bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override; const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override; bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
@ -190,7 +191,7 @@ namespace hw {
#ifdef DEBUGLEDGER #ifdef DEBUG_HWDEVICE
extern crypto::secret_key viewkey; extern crypto::secret_key viewkey;
extern crypto::secret_key spendkey; extern crypto::secret_key spendkey;
#endif #endif

View File

@ -55,14 +55,14 @@ namespace hw {
MDEBUG(msg << ": " << info); MDEBUG(msg << ": " << info);
} }
#ifdef DEBUGLEDGER #ifdef DEBUG_HWDEVICE
extern crypto::secret_key viewkey; extern crypto::secret_key viewkey;
extern crypto::secret_key spendkey; extern crypto::secret_key spendkey;
void decrypt(char* buf, size_t len) { void decrypt(char* buf, size_t len) {
#ifdef IODUMMYCRYPT #ifdef IODUMMYCRYPT_HWDEVICE
int i; size_t i;
if (len == 32) { if (len == 32) {
//view key? //view key?
for (i = 0; i<32; i++) { for (i = 0; i<32; i++) {
@ -144,7 +144,7 @@ namespace hw {
log_hexbuffer(" device", dd, len); log_hexbuffer(" device", dd, len);
} else { } else {
buffer_to_str(logstr, dd, len); buffer_to_str(logstr, 128, dd, len);
log_message("ASSERT EQ OK", msg + ": "+ info + ": "+ std::string(logstr) ); log_message("ASSERT EQ OK", msg + ": "+ info + ": "+ std::string(logstr) );
} }
} }

View File

@ -6712,6 +6712,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
cryptonote::transaction tx; cryptonote::transaction tx;
pending_tx ptx; pending_tx ptx;
size_t bytes; size_t bytes;
std::vector<std::vector<tools::wallet2::get_outs_entry>> outs;
void add(const account_public_address &addr, bool is_subaddress, uint64_t amount, unsigned int original_output_index, bool merge_destinations) { void add(const account_public_address &addr, bool is_subaddress, uint64_t amount, unsigned int original_output_index, bool merge_destinations) {
if (merge_destinations) if (merge_destinations)
@ -7101,40 +7102,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Made a final " << get_size_string(txBlob) << " tx, with " << print_money(test_ptx.fee) << LOG_PRINT_L2("Made a final " << get_size_string(txBlob) << " tx, with " << print_money(test_ptx.fee) <<
" fee and " << print_money(test_ptx.change_dts.amount) << " change"); " fee and " << print_money(test_ptx.change_dts.amount) << " change");
if ((!dsts.empty()) ||
(dsts.empty() && !(adding_fee || !preferred_inputs.empty() || should_pick_a_second_output(use_rct, txes.back().selected_transfers.size(), *unused_transfers_indices, *unused_dust_indices)) )
) {
hwdev.set_signature_mode(hw::device::SIGNATURE_REAL);
if (use_rct) {
transfer_selected_rct(tx.dsts, /* NOMOD std::vector<cryptonote::tx_destination_entry> dsts,*/
tx.selected_transfers, /* const std::list<size_t> selected_transfers */
fake_outs_count, /* CONST size_t fake_outputs_count, */
outs, /* MOD std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, */
unlock_time, /* CONST uint64_t unlock_time, */
needed_fee, /* CONST uint64_t fee, */
extra, /* const std::vector<uint8_t>& extra, */
test_tx, /* OUT cryptonote::transaction& tx, */
test_ptx, /* OUT cryptonote::transaction& tx, */
bulletproof);
} else {
transfer_selected(tx.dsts,
tx.selected_transfers,
fake_outs_count,
outs,
unlock_time,
needed_fee,
extra,
detail::digit_split_strategy,
tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD),
test_tx,
test_ptx);
}
hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE);
}
tx.tx = test_tx; tx.tx = test_tx;
tx.ptx = test_ptx; tx.ptx = test_ptx;
tx.bytes = txBlob.size(); tx.bytes = txBlob.size();
tx.outs = outs;
accumulated_fee += test_ptx.fee; accumulated_fee += test_ptx.fee;
accumulated_change += test_ptx.change_dts.amount; accumulated_change += test_ptx.change_dts.amount;
adding_fee = false; adding_fee = false;
@ -7174,6 +7145,42 @@ skip_tx:
LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) << LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) <<
" total fee, " << print_money(accumulated_change) << " total change"); " total fee, " << print_money(accumulated_change) << " total change");
hwdev.set_signature_mode(hw::device::SIGNATURE_REAL);
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
{
TX &tx = *i;
cryptonote::transaction test_tx;
pending_tx test_ptx;
if (use_rct) {
transfer_selected_rct(tx.dsts, /* NOMOD std::vector<cryptonote::tx_destination_entry> dsts,*/
tx.selected_transfers, /* const std::list<size_t> selected_transfers */
fake_outs_count, /* CONST size_t fake_outputs_count, */
tx.outs, /* MOD std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, */
unlock_time, /* CONST uint64_t unlock_time, */
needed_fee, /* CONST uint64_t fee, */
extra, /* const std::vector<uint8_t>& extra, */
test_tx, /* OUT cryptonote::transaction& tx, */
test_ptx, /* OUT cryptonote::transaction& tx, */
bulletproof);
} else {
transfer_selected(tx.dsts,
tx.selected_transfers,
fake_outs_count,
tx.outs,
unlock_time,
needed_fee,
extra,
detail::digit_split_strategy,
tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD),
test_tx,
test_ptx);
}
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
tx.tx = test_tx;
tx.ptx = test_ptx;
tx.bytes = txBlob.size();
}
std::vector<wallet2::pending_tx> ptx_vector; std::vector<wallet2::pending_tx> ptx_vector;
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
{ {
@ -7276,6 +7283,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
cryptonote::transaction tx; cryptonote::transaction tx;
pending_tx ptx; pending_tx ptx;
size_t bytes; size_t bytes;
std::vector<std::vector<get_outs_entry>> outs;
}; };
std::vector<TX> txes; std::vector<TX> txes;
uint64_t needed_fee, available_for_fee = 0; uint64_t needed_fee, available_for_fee = 0;
@ -7367,24 +7375,13 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
" fee and " << print_money(test_ptx.change_dts.amount) << " change"); " fee and " << print_money(test_ptx.change_dts.amount) << " change");
} while (needed_fee > test_ptx.fee); } while (needed_fee > test_ptx.fee);
if (!unused_transfers_indices.empty() || !unused_dust_indices.empty()) {
hwdev.set_signature_mode(hw::device::SIGNATURE_REAL);
if (use_rct) {
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
test_tx, test_ptx, bulletproof);
} else {
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, outs, unlock_time, needed_fee, extra,
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
}
hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE);
}
LOG_PRINT_L2("Made a final " << get_size_string(txBlob) << " tx, with " << print_money(test_ptx.fee) << LOG_PRINT_L2("Made a final " << get_size_string(txBlob) << " tx, with " << print_money(test_ptx.fee) <<
" fee and " << print_money(test_ptx.change_dts.amount) << " change"); " fee and " << print_money(test_ptx.change_dts.amount) << " change");
tx.tx = test_tx; tx.tx = test_tx;
tx.ptx = test_ptx; tx.ptx = test_ptx;
tx.bytes = txBlob.size(); tx.bytes = txBlob.size();
tx.outs = outs;
accumulated_fee += test_ptx.fee; accumulated_fee += test_ptx.fee;
accumulated_change += test_ptx.change_dts.amount; accumulated_change += test_ptx.change_dts.amount;
if (!unused_transfers_indices.empty() || !unused_dust_indices.empty()) if (!unused_transfers_indices.empty() || !unused_dust_indices.empty())
@ -7398,6 +7395,25 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) << LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) <<
" total fee, " << print_money(accumulated_change) << " total change"); " total fee, " << print_money(accumulated_change) << " total change");
hwdev.set_signature_mode(hw::device::SIGNATURE_REAL);
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
{
TX &tx = *i;
cryptonote::transaction test_tx;
pending_tx test_ptx;
if (use_rct) {
transfer_selected_rct(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, needed_fee, extra,
test_tx, test_ptx, bulletproof);
} else {
transfer_selected(tx.dsts, tx.selected_transfers, fake_outs_count, tx.outs, unlock_time, needed_fee, extra,
detail::digit_split_strategy, tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD), test_tx, test_ptx);
}
auto txBlob = t_serializable_object_to_blob(test_ptx.tx);
tx.tx = test_tx;
tx.ptx = test_ptx;
tx.bytes = txBlob.size();
}
std::vector<wallet2::pending_tx> ptx_vector; std::vector<wallet2::pending_tx> ptx_vector;
for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i)
{ {