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:
cslashm 2018-03-26 12:38:38 +02:00
parent 641dfc991f
commit 100b7bc10d
5 changed files with 202 additions and 385 deletions

View File

@ -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 */

View File

@ -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 */
/* ======================================================================= */

View File

@ -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 */
/* ======================================================================= */

View File

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

View File

@ -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 */
/* ======================================================================= */