Change mutex lock model to avoid dead lock and ensure locks are always released.
Additional cosmetic fixes: move 'name' as protected remove unnecessary local var Fix debug log
This commit is contained in:
parent
641dfc991f
commit
100b7bc10d
|
@ -78,8 +78,10 @@ namespace hw {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
class device {
|
||||
protected:
|
||||
std::string name;
|
||||
|
||||
public:
|
||||
|
||||
device() {}
|
||||
|
@ -92,8 +94,6 @@ namespace hw {
|
|||
static const int SIGNATURE_FAKE = 1;
|
||||
|
||||
|
||||
std::string name;
|
||||
|
||||
/* ======================================================================= */
|
||||
/* SETUP/TEARDOWN */
|
||||
/* ======================================================================= */
|
||||
|
@ -104,7 +104,15 @@ namespace hw {
|
|||
virtual bool release() = 0;
|
||||
|
||||
virtual bool connect(void) = 0;
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool disconnect(void) = 0;
|
||||
|
||||
/* ======================================================================= */
|
||||
/* LOCKER */
|
||||
/* ======================================================================= */
|
||||
virtual void lock(void) = 0;
|
||||
virtual void unlock(void) = 0;
|
||||
virtual bool try_lock(void) = 0;
|
||||
|
||||
|
||||
/* ======================================================================= */
|
||||
/* WALLET & ADDRESS */
|
||||
|
|
|
@ -81,6 +81,17 @@ namespace hw {
|
|||
dfns();
|
||||
}
|
||||
|
||||
|
||||
/* ======================================================================= */
|
||||
/* LOCKER */
|
||||
/* ======================================================================= */
|
||||
|
||||
void device_default::lock() { }
|
||||
|
||||
bool device_default::try_lock() { return true; }
|
||||
|
||||
void device_default::unlock() { }
|
||||
|
||||
/* ======================================================================= */
|
||||
/* WALLET & ADDRESS */
|
||||
/* ======================================================================= */
|
||||
|
|
|
@ -59,6 +59,13 @@ namespace hw {
|
|||
bool connect(void) override;
|
||||
bool disconnect() override;
|
||||
|
||||
/* ======================================================================= */
|
||||
/* LOCKER */
|
||||
/* ======================================================================= */
|
||||
void lock(void) override;
|
||||
void unlock(void) override;
|
||||
bool try_lock(void) override;
|
||||
|
||||
/* ======================================================================= */
|
||||
/* WALLET & ADDRESS */
|
||||
/* ======================================================================= */
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
#include "cryptonote_basic/account.h"
|
||||
#include "cryptonote_basic/subaddress_index.h"
|
||||
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
|
||||
namespace hw {
|
||||
|
||||
|
@ -204,14 +205,51 @@ namespace hw {
|
|||
MDEBUG( "Device "<<this->id <<" Destroyed");
|
||||
}
|
||||
|
||||
/* ======================================================================= */
|
||||
/* LOCKER */
|
||||
/* ======================================================================= */
|
||||
|
||||
//automatic lock one more level on device ensuring the current thread is allowed to use it
|
||||
#define AUTO_LOCK_CMD() \
|
||||
/* lock both mutexes without deadlock*/ \
|
||||
boost::lock(device_locker, command_locker); \
|
||||
/* make sure both already-locked mutexes are unlocked at the end of scope */ \
|
||||
boost::lock_guard<boost::recursive_mutex> lock1(device_locker, boost::adopt_lock); \
|
||||
boost::lock_guard<boost::mutex> lock2(command_locker, boost::adopt_lock)
|
||||
|
||||
//lock the device for a long sequence
|
||||
void device_ledger::lock(void) {
|
||||
MDEBUG( "Ask for LOCKING for device "<<this->name << " in thread ");
|
||||
device_locker.lock();
|
||||
MDEBUG( "Device "<<this->name << " LOCKed");
|
||||
}
|
||||
|
||||
//lock the device for a long sequence
|
||||
bool device_ledger::try_lock(void) {
|
||||
MDEBUG( "Ask for LOCKING(try) for device "<<this->name << " in thread ");
|
||||
bool r = device_locker.try_lock();
|
||||
if (r) {
|
||||
MDEBUG( "Device "<<this->name << " LOCKed(try)");
|
||||
} else {
|
||||
MDEBUG( "Device "<<this->name << " not LOCKed(try)");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
//lock the device for a long sequence
|
||||
void device_ledger::unlock(void) {
|
||||
try {
|
||||
MDEBUG( "Ask for UNLOCKING for device "<<this->name << " in thread ");
|
||||
} catch (...) {
|
||||
}
|
||||
device_locker.unlock();
|
||||
MDEBUG( "Device "<<this->name << " UNLOCKed");
|
||||
}
|
||||
|
||||
/* ======================================================================= */
|
||||
/* MISC */
|
||||
/* ======================================================================= */
|
||||
bool device_ledger::reset() {
|
||||
|
||||
lock_device();
|
||||
try {
|
||||
int offset;
|
||||
reset_buffer();
|
||||
|
||||
|
@ -227,11 +265,6 @@ namespace hw {
|
|||
this->buffer_send[4] = offset-5;
|
||||
this->length_send = offset;
|
||||
this->exchange();
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -261,30 +294,6 @@ namespace hw {
|
|||
memset(this->buffer_recv, 0, BUFFER_RECV_SIZE);
|
||||
}
|
||||
|
||||
void device_ledger::lock_device() {
|
||||
MDEBUG( "Ask for LOCKING for device "<<this->id);
|
||||
device_locker.lock();
|
||||
MDEBUG( "Device "<<this->id << " LOCKed");
|
||||
}
|
||||
void device_ledger::unlock_device() {
|
||||
try {
|
||||
MDEBUG( "Ask for UNLOCKING for device "<<this->id);
|
||||
} catch (...) {
|
||||
}
|
||||
device_locker.unlock();
|
||||
MDEBUG( "Device "<<this->id << " UNLOCKed");
|
||||
}
|
||||
void device_ledger::lock_tx() {
|
||||
MDEBUG( "Ask for LOCKING for TX "<<this->id);
|
||||
//tx_locker.lock();
|
||||
MDEBUG( "TX "<<this->id << " LOCKed");
|
||||
}
|
||||
void device_ledger::unlock_tx() {
|
||||
MDEBUG( "Ask for UNLOCKING for TX "<<this->id);
|
||||
//tx_locker.unlock();
|
||||
MDEBUG( "TX "<<this->id << " UNLOCKed");
|
||||
}
|
||||
|
||||
/* ======================================================================= */
|
||||
/* SETUP/TEARDOWN */
|
||||
/* ======================================================================= */
|
||||
|
@ -416,11 +425,9 @@ namespace hw {
|
|||
/* WALLET & ADDRESS */
|
||||
/* ======================================================================= */
|
||||
|
||||
/* Application API */
|
||||
bool device_ledger::get_public_address(cryptonote::account_public_address &pubkey){
|
||||
AUTO_LOCK_CMD();
|
||||
|
||||
lock_device();
|
||||
try {
|
||||
int offset;
|
||||
reset_buffer();
|
||||
|
||||
|
@ -440,21 +447,16 @@ namespace hw {
|
|||
|
||||
memmove(pubkey.m_view_public_key.data, this->buffer_recv, 32);
|
||||
memmove(pubkey.m_spend_public_key.data, this->buffer_recv+32, 32);
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) {
|
||||
AUTO_LOCK_CMD();
|
||||
memset(viewkey.data, 0x00, 32);
|
||||
memset(spendkey.data, 0xFF, 32);
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
lock_device();
|
||||
try {
|
||||
//spcialkey, normal conf handled in decrypt
|
||||
int offset;
|
||||
reset_buffer();
|
||||
|
@ -476,18 +478,13 @@ namespace hw {
|
|||
//clear key
|
||||
memmove(ledger::viewkey.data, this->buffer_recv+64, 32);
|
||||
memmove(ledger::spendkey.data, this->buffer_recv+96, 32);
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) {
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
|
@ -519,11 +516,6 @@ namespace hw {
|
|||
hw::ledger::check32("generate_chacha_key_prehashed", "key", (char*)key_x.data(), (char*)key.data());
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -532,11 +524,8 @@ namespace hw {
|
|||
/* ======================================================================= */
|
||||
|
||||
bool device_ledger::derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub){
|
||||
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::public_key pub_x = pub;
|
||||
|
@ -552,8 +541,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_DERIVE_SUBADDRESS_PUBLIC_KEY;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -561,7 +548,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//pub
|
||||
memmove(this->buffer_send+offset, pub.data, 32);
|
||||
|
@ -587,29 +574,22 @@ namespace hw {
|
|||
hw::ledger::check32("derive_subaddress_public_key", "derived_pub", derived_pub_x.data, derived_pub.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
||||
AUTO_LOCK_CMD();
|
||||
crypto::public_key D;
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
|
||||
const cryptonote::subaddress_index index_x = index;
|
||||
crypto::public_key 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_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32);
|
||||
hw::ledger::log_hexbuffer("get_subaddress_spend_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);
|
||||
D_x = this->controle_device->get_subaddress_spend_public_key(keys_x, index_x);
|
||||
hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32);
|
||||
#endif
|
||||
|
||||
|
@ -644,11 +624,6 @@ namespace hw {
|
|||
hw::ledger::check32("get_subaddress_spend_public_key", "D", D_x.data, D.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return D;
|
||||
}
|
||||
|
||||
|
@ -665,24 +640,22 @@ namespace hw {
|
|||
}
|
||||
|
||||
cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
||||
AUTO_LOCK_CMD();
|
||||
cryptonote::account_public_address address;
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
|
||||
const cryptonote::subaddress_index index_x = index;
|
||||
cryptonote::account_public_address 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_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
|
||||
hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32);
|
||||
hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
|
||||
hw::ledger::log_hexbuffer("get_subaddress: [[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);
|
||||
address_x = this->controle_device->get_subaddress(keys_x, index_x);
|
||||
hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32);
|
||||
hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32);
|
||||
#endif
|
||||
|
||||
if (index.is_zero()) {
|
||||
|
@ -717,20 +690,13 @@ namespace hw {
|
|||
hw::ledger::check32("get_subaddress", "address.m_spend_public_key.data", address_x.m_spend_public_key.data, address.m_spend_public_key.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
crypto::secret_key device_ledger::get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) {
|
||||
AUTO_LOCK_CMD();
|
||||
crypto::secret_key sub_sec;
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||
|
@ -738,7 +704,7 @@ namespace hw {
|
|||
crypto::secret_key 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);
|
||||
sub_sec_x = this->controle_device->get_subaddress_secret_key(sec_x, index_x);
|
||||
hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32);
|
||||
#endif
|
||||
|
||||
|
@ -751,7 +717,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//sec
|
||||
memmove(this->buffer_send+offset, sec.data, 32);
|
||||
|
@ -772,11 +738,6 @@ namespace hw {
|
|||
hw::ledger::check32("get_subaddress_secret_key", "sub_sec", sub_sec_x.data, sub_sec_clear.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return sub_sec;
|
||||
}
|
||||
|
||||
|
@ -785,10 +746,9 @@ namespace hw {
|
|||
/* ======================================================================= */
|
||||
|
||||
bool device_ledger::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0,sw;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset, sw;
|
||||
|
||||
reset_buffer();
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_VERIFY_KEY;
|
||||
|
@ -816,20 +776,12 @@ namespace hw {
|
|||
this->buffer_recv[2] << 8 |
|
||||
this->buffer_recv[3] << 0 ;
|
||||
|
||||
unlock_device();
|
||||
return verified == 1;
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool device_ledger::scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key P_x = P;
|
||||
|
@ -843,8 +795,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_SECRET_SCAL_MUL_KEY;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -852,7 +802,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//pub
|
||||
memmove(this->buffer_send+offset, P.bytes, 32);
|
||||
|
@ -873,19 +823,12 @@ namespace hw {
|
|||
hw::ledger::check32("scalarmultKey", "mulkey", (char*)aP_x.bytes, (char*)aP.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::scalarmultBase(rct::key &aG, const rct::key &a) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key a_x = hw::ledger::decrypt(a);
|
||||
|
@ -897,8 +840,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_SECRET_SCAL_MUL_BASE;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -906,7 +847,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//sec
|
||||
memmove(this->buffer_send+offset, a.bytes, 32);
|
||||
|
@ -923,20 +864,12 @@ namespace hw {
|
|||
hw::ledger::check32("scalarmultBase", "mulkey", (char*)aG_x.bytes, (char*)aG.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) {
|
||||
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::secret_key a_x = hw::ledger::decrypt(a);
|
||||
|
@ -947,8 +880,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_SECRET_KEY_ADD;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -956,7 +887,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//sec key
|
||||
memmove(this->buffer_send+offset, a.data, 32);
|
||||
|
@ -977,23 +908,16 @@ namespace hw {
|
|||
hw::ledger::check32("sc_secret_add", "r", r_x.data, r_clear.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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();
|
||||
if (recover) {
|
||||
throw std::runtime_error("device generate key does not support recover");
|
||||
}
|
||||
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
bool recover_x = recover;
|
||||
|
@ -1004,8 +928,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_GENERATE_KEYPAIR;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -1013,7 +935,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
|
||||
this->buffer_send[4] = offset-5;
|
||||
|
@ -1031,20 +953,13 @@ namespace hw {
|
|||
hw::ledger::check32("generate_keys", "pub", pub_x.data, pub.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return sec;
|
||||
|
||||
}
|
||||
|
||||
bool device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::public_key pub_x = pub;
|
||||
|
@ -1065,7 +980,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//pub
|
||||
memmove(this->buffer_send+offset, pub.data, 32);
|
||||
|
@ -1086,19 +1001,13 @@ namespace hw {
|
|||
hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) {
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
|
||||
|
@ -1112,8 +1021,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_DERIVATION_TO_SCALAR;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -1121,7 +1028,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//derivattion
|
||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
||||
|
@ -1145,19 +1052,12 @@ namespace hw {
|
|||
hw::ledger::check32("derivation_to_scalar", "res", res_x.data, res_clear.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) {
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
|
||||
|
@ -1173,8 +1073,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_DERIVE_SECRET_KEY;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -1182,7 +1080,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//derivation
|
||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
||||
|
@ -1209,19 +1107,12 @@ namespace hw {
|
|||
hw::ledger::check32("derive_secret_key", "derived_sec", derived_sec_x.data, derived_sec_clear.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub){
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
|
||||
|
@ -1237,8 +1128,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_DERIVE_PUBLIC_KEY;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -1246,7 +1135,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//derivation
|
||||
memmove(this->buffer_send+offset, derivation.data, 32);
|
||||
|
@ -1272,19 +1161,12 @@ namespace hw {
|
|||
hw::ledger::check32("derive_public_key", "derived_pub", derived_pub_x.data, derived_pub.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) {
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||
|
@ -1299,8 +1181,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_SECRET_KEY_TO_PUBLIC_KEY;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -1308,7 +1188,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//sec key
|
||||
memmove(this->buffer_send+offset, sec.data, 32);
|
||||
|
@ -1325,19 +1205,12 @@ namespace hw {
|
|||
hw::ledger::check32("secret_key_to_public_key", "pub", pub_x.data, pub.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image){
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::public_key pub_x = pub;
|
||||
|
@ -1351,8 +1224,6 @@ namespace hw {
|
|||
|
||||
reset_buffer();
|
||||
|
||||
options = 0;
|
||||
|
||||
this->buffer_send[0] = 0x00;
|
||||
this->buffer_send[1] = INS_GEN_KEY_IMAGE;
|
||||
this->buffer_send[2] = 0x00;
|
||||
|
@ -1360,7 +1231,7 @@ namespace hw {
|
|||
this->buffer_send[4] = 0x00;
|
||||
offset = 5;
|
||||
//options
|
||||
this->buffer_send[offset] = options;
|
||||
this->buffer_send[offset] = 0;
|
||||
offset += 1;
|
||||
//pub
|
||||
memmove(this->buffer_send+offset, pub.data, 32);
|
||||
|
@ -1380,11 +1251,6 @@ namespace hw {
|
|||
hw::ledger::check32("generate_key_image", "image", image_x.data, image.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1393,12 +1259,9 @@ namespace hw {
|
|||
/* ======================================================================= */
|
||||
|
||||
bool device_ledger::open_tx(crypto::secret_key &tx_key) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
lock_tx();
|
||||
reset_buffer();
|
||||
key_map.clear();
|
||||
|
||||
|
@ -1423,19 +1286,13 @@ namespace hw {
|
|||
this->exchange();
|
||||
|
||||
memmove(tx_key.data, &this->buffer_recv[32], 32);
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::set_signature_mode(unsigned int sig_mode) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset ;
|
||||
|
||||
reset_buffer();
|
||||
|
||||
|
@ -1455,25 +1312,19 @@ namespace hw {
|
|||
this->buffer_send[4] = offset-5;
|
||||
this->length_send = offset;
|
||||
this->exchange();
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::public_key public_key_x = public_key;
|
||||
const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key);
|
||||
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(payment_id_x, public_key_x, secret_key_x);
|
||||
#endif
|
||||
|
||||
reset_buffer();
|
||||
|
@ -1506,32 +1357,19 @@ namespace hw {
|
|||
hw::ledger::check8("stealth", "payment_id", payment_id_x.data, payment_id.data);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
lock_device();
|
||||
try {
|
||||
AUTO_LOCK_CMD();
|
||||
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();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key AKout_x = hw::ledger::decrypt(AKout);
|
||||
|
@ -1574,19 +1412,12 @@ namespace hw {
|
|||
hw::ledger::log_hexbuffer("Blind AKV input", (char*)&this->buffer_recv[64], 3*32);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::ecdhDecode(rct::ecdhTuple & masked, const rct::key & AKout) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key AKout_x = hw::ledger::decrypt(AKout);
|
||||
|
@ -1627,21 +1458,13 @@ namespace hw {
|
|||
hw::ledger::check32("ecdhDecode", "mask", (char*)masked_x.mask.bytes,(char*) masked.mask.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::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) {
|
||||
|
||||
lock_device();
|
||||
try {
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
unsigned int data_offset, C_offset, kv_offset, i;
|
||||
const char *data;
|
||||
|
||||
|
@ -1834,21 +1657,15 @@ namespace hw {
|
|||
hw::ledger::check32("mlsag_prehash", "prehash", (char*)prehash_x.bytes, (char*)prehash.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool device_ledger::mlsag_prepare(const rct::key &H, const rct::key &xx,
|
||||
rct::key &a, rct::key &aG, rct::key &aHP, rct::key &II) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key H_x = H;
|
||||
|
@ -1897,19 +1714,13 @@ namespace hw {
|
|||
hw::ledger::check32("mlsag_prepare", "II", (char*)II_x.bytes, (char*)II.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::mlsag_prepare(rct::key &a, rct::key &aG) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
rct::key a_x;
|
||||
|
@ -1941,19 +1752,13 @@ namespace hw {
|
|||
hw::ledger::check32("mlsag_prepare", "AG", (char*)aG_x.bytes, (char*)aG.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::mlsag_hash(const rct::keyV &long_message, rct::key &c) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
unsigned char options;
|
||||
size_t cnt;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
|
@ -1991,20 +1796,12 @@ namespace hw {
|
|||
hw::ledger::check32("mlsag_hash", "c", (char*)c_x.bytes, (char*)c.bytes);
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool device_ledger::mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(dsRows<=rows, "dsRows greater than rows");
|
||||
CHECK_AND_ASSERT_THROW_MES(xx.size() == rows, "xx size does not match rows");
|
||||
|
@ -2061,19 +1858,12 @@ namespace hw {
|
|||
}
|
||||
#endif
|
||||
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::close_tx() {
|
||||
lock_device();
|
||||
try {
|
||||
int offset =0;
|
||||
unsigned char options = 0;
|
||||
AUTO_LOCK_CMD();
|
||||
int offset;
|
||||
|
||||
reset_buffer();
|
||||
|
||||
|
@ -2091,12 +1881,6 @@ namespace hw {
|
|||
this->length_send = offset;
|
||||
this->exchange();
|
||||
|
||||
unlock_tx();
|
||||
unlock_device();
|
||||
}catch (...) {
|
||||
unlock_device();
|
||||
throw;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#include "device.hpp"
|
||||
#include <PCSC/winscard.h>
|
||||
#include <PCSC/wintypes.h>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
|
||||
namespace hw {
|
||||
|
||||
|
@ -80,13 +81,11 @@ namespace hw {
|
|||
|
||||
class device_ledger : public hw::device {
|
||||
private:
|
||||
mutable std::mutex device_locker;
|
||||
mutable std::mutex tx_locker;
|
||||
void lock_device() ;
|
||||
void unlock_device() ;
|
||||
void lock_tx() ;
|
||||
void unlock_tx() ;
|
||||
// Locker for concurrent access
|
||||
mutable boost::recursive_mutex device_locker;
|
||||
mutable boost::mutex command_locker;
|
||||
|
||||
//PCSC management
|
||||
std::string full_name;
|
||||
SCARDCONTEXT hContext;
|
||||
SCARDHANDLE hCard;
|
||||
|
@ -130,6 +129,14 @@ namespace hw {
|
|||
bool connect(void) override;
|
||||
bool disconnect() override;
|
||||
|
||||
|
||||
/* ======================================================================= */
|
||||
/* LOCKER */
|
||||
/* ======================================================================= */
|
||||
void lock(void) override;
|
||||
void unlock(void) override;
|
||||
bool try_lock(void) override;
|
||||
|
||||
/* ======================================================================= */
|
||||
/* WALLET & ADDRESS */
|
||||
/* ======================================================================= */
|
||||
|
|
Loading…
Reference in New Issue