diff --git a/bftengine/include/bftengine/CryptoManager.hpp b/bftengine/include/bftengine/CryptoManager.hpp index 15089a7b30..3c8c10c5f1 100644 --- a/bftengine/include/bftengine/CryptoManager.hpp +++ b/bftengine/include/bftengine/CryptoManager.hpp @@ -18,7 +18,7 @@ #include "ReplicaConfig.hpp" #include "IKeyExchanger.hpp" #include "Logger.hpp" -#include "crypto/crypto.h" +#include "crypto/crypto.hpp" namespace bftEngine { typedef std::int64_t SeqNum; // TODO [TK] redefinition diff --git a/bftengine/include/bftengine/IKeyExchanger.hpp b/bftengine/include/bftengine/IKeyExchanger.hpp index eaa2f954df..7046988c64 100644 --- a/bftengine/include/bftengine/IKeyExchanger.hpp +++ b/bftengine/include/bftengine/IKeyExchanger.hpp @@ -10,11 +10,10 @@ // file. #pragma once -#include "crypto.hpp" #include #include #include -#include +#include "crypto/crypto.hpp" // Interface for objects that need to be notified on key rotation class IKeyExchanger { diff --git a/bftengine/include/bftengine/KeyExchangeManager.hpp b/bftengine/include/bftengine/KeyExchangeManager.hpp index 4e38eebd5a..819bbf3dc8 100644 --- a/bftengine/include/bftengine/KeyExchangeManager.hpp +++ b/bftengine/include/bftengine/KeyExchangeManager.hpp @@ -18,7 +18,7 @@ #include "Metrics.hpp" #include "secrets_manager_impl.h" #include "SysConsts.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include namespace bftEngine::impl { diff --git a/bftengine/src/bcstatetransfer/AsyncStateTransferCRE.cpp b/bftengine/src/bcstatetransfer/AsyncStateTransferCRE.cpp index e00dd59ada..cef7c573a1 100644 --- a/bftengine/src/bcstatetransfer/AsyncStateTransferCRE.cpp +++ b/bftengine/src/bcstatetransfer/AsyncStateTransferCRE.cpp @@ -73,13 +73,11 @@ class Communication : public ICommunication { class InternalSigner : public concord::crypto::ISigner { public: - std::string sign(const std::string& data) override { - std::string out; - out.resize(bftEngine::impl::SigManager::instance()->getMySigLength()); - bftEngine::impl::SigManager::instance()->sign(data.data(), data.size(), out.data()); - return out; + size_t signBuffer(const concord::Byte* dataIn, size_t dataLen, concord::Byte* sigOutBuffer) override { + return bftEngine::impl::SigManager::instance()->sign(dataIn, dataLen, sigOutBuffer); } - uint32_t signatureLength() const override { return bftEngine::impl::SigManager::instance()->getMySigLength(); } + + size_t signatureLength() const override { return bftEngine::impl::SigManager::instance()->getMySigLength(); } std::string getPrivKey() const override { return ""; } }; diff --git a/bftengine/src/bftengine/KeyExchangeManager.cpp b/bftengine/src/bftengine/KeyExchangeManager.cpp index 9b65ee84cf..326ec80b92 100644 --- a/bftengine/src/bftengine/KeyExchangeManager.cpp +++ b/bftengine/src/bftengine/KeyExchangeManager.cpp @@ -22,8 +22,9 @@ #include "communication/StateControl.hpp" #include "ReplicaImp.hpp" #include "crypto/factory.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "openssl/utils.hpp" +#include "crypto/cryptopp/keygen.hpp" namespace bftEngine::impl { diff --git a/bftengine/src/bftengine/ReplicaImp.cpp b/bftengine/src/bftengine/ReplicaImp.cpp index 3b8031ba04..df7ae099eb 100644 --- a/bftengine/src/bftengine/ReplicaImp.cpp +++ b/bftengine/src/bftengine/ReplicaImp.cpp @@ -5312,9 +5312,8 @@ void ReplicaImp::onExecutionFinish() { // Mark this request as an internal one std::vector data_vec; concord::messages::serialize(data_vec, req); - std::string sig(SigManager::instance()->getMySigLength(), '\0'); - SigManager::instance()->sign(reinterpret_cast(data_vec.data()), data_vec.size(), sig.data()); - req.signature = std::vector(sig.begin(), sig.end()); + req.signature.resize(SigManager::instance()->getMySigLength()); + SigManager::instance()->sign(data_vec.data(), data_vec.size(), req.signature.data()); data_vec.clear(); concord::messages::serialize(data_vec, req); std::string strMsg(data_vec.begin(), data_vec.end()); diff --git a/bftengine/src/bftengine/SigManager.cpp b/bftengine/src/bftengine/SigManager.cpp index ae7b2509b3..7772f6261d 100644 --- a/bftengine/src/bftengine/SigManager.cpp +++ b/bftengine/src/bftengine/SigManager.cpp @@ -26,6 +26,7 @@ namespace impl { using concord::crypto::IVerifier; using concord::crypto::Factory; +using concord::crypto::KeyFormat; concord::messages::keys_and_signatures::ClientsPublicKeys clientsPublicKeys_; @@ -203,14 +204,12 @@ uint16_t SigManager::getSigLength(PrincipalId pid) const { } bool SigManager::verifySig( - PrincipalId pid, const char* data, size_t dataLength, const char* sig, uint16_t sigLength) const { + PrincipalId pid, const concord::Byte* data, size_t dataLength, const concord::Byte* sig, uint16_t sigLength) const { bool result = false; { - std::string str_data(data, dataLength); - std::string str_sig(sig, sigLength); std::shared_lock lock(mutex_); if (auto pos = verifiers_.find(pid); pos != verifiers_.end()) { - result = pos->second->verify(str_data, str_sig); + result = pos->second->verifyBuffer(data, dataLength, sig, sigLength); } else { LOG_ERROR(GL, "Unrecognized pid " << pid); metrics_.sigVerificationFailedOnUnrecognizedParticipantId_++; @@ -245,10 +244,12 @@ bool SigManager::verifySig( return result; } -void SigManager::sign(const char* data, size_t dataLength, char* outSig) const { - std::string str_data(data, dataLength); - std::string sig = mySigner_->sign(str_data); - std::memcpy(outSig, sig.c_str(), sig.size()); +size_t SigManager::sign(const concord::Byte* data, size_t dataLength, concord::Byte* outSig) const { + return mySigner_->signBuffer(data, dataLength, outSig); +} + +size_t SigManager::sign(const char* data, size_t dataLength, char* outSig) const { + return sign(reinterpret_cast(data), dataLength, reinterpret_cast(outSig)); } uint16_t SigManager::getMySigLength() const { return (uint16_t)mySigner_->signatureLength(); } @@ -273,6 +274,10 @@ void SigManager::setClientPublicKey(const std::string& key, PrincipalId id, KeyF bool SigManager::hasVerifier(PrincipalId pid) { return verifiers_.find(pid) != verifiers_.end(); } concord::crypto::SignatureAlgorithm SigManager::getMainKeyAlgorithm() const { return concord::crypto::EdDSA; } +concord::crypto::ISigner& SigManager::getSigner() { return *mySigner_; } +const concord::crypto::IVerifier& SigManager::getVerifier(PrincipalId otherPrincipal) const { + return *verifiers_.at(otherPrincipal); +} } // namespace impl } // namespace bftEngine diff --git a/bftengine/src/bftengine/SigManager.hpp b/bftengine/src/bftengine/SigManager.hpp index 4156c5a1ff..e7f6052a23 100644 --- a/bftengine/src/bftengine/SigManager.hpp +++ b/bftengine/src/bftengine/SigManager.hpp @@ -13,7 +13,7 @@ #include "PrimitiveTypes.hpp" #include "assertUtils.hpp" #include "Metrics.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "crypto/signer.hpp" #include "crypto/verifier.hpp" @@ -29,7 +29,6 @@ using concordMetrics::AtomicCounterHandle; namespace bftEngine { namespace impl { - class ReplicasInfo; class SigManager { @@ -53,22 +52,41 @@ class SigManager { static SigManager* init(ReplicaId myId, const Key& mySigPrivateKey, const std::set>& publicKeysOfReplicas, - concord::util::crypto::KeyFormat replicasKeysFormat, + concord::crypto::KeyFormat replicasKeysFormat, const std::set>>* publicKeysOfClients, - concord::util::crypto::KeyFormat clientsKeysFormat, + concord::crypto::KeyFormat clientsKeysFormat, ReplicasInfo& replicasInfo); // returns 0 if pid is invalid - caller might consider throwing an exception uint16_t getSigLength(PrincipalId pid) const; // returns false if actual verification failed, or if pid is invalid - bool verifySig(PrincipalId pid, const char* data, size_t dataLength, const char* sig, uint16_t sigLength) const; - void sign(const char* data, size_t dataLength, char* outSig) const; + bool verifySig(PrincipalId pid, + const concord::Byte* data, + size_t dataLength, + const concord::Byte* sig, + uint16_t sigLength) const; + + template + bool verifySig(PrincipalId pid, const DataContainer& data, const SignatureContainer& sig) const { + static_assert(sizeof(typename DataContainer::value_type) == sizeof(concord::Byte), + "data elements are not byte-sized"); + static_assert(sizeof(typename SignatureContainer::value_type) == sizeof(concord::Byte), + "signature elements are not byte-sized"); + return verifySig(pid, + reinterpret_cast(data.data()), + data.size(), + reinterpret_cast(sig.data()), + static_cast(sig.size())); + } + + size_t sign(const concord::Byte* data, size_t dataLength, concord::Byte* outSig) const; + size_t sign(const char* data, size_t dataLength, char* outSig) const; uint16_t getMySigLength() const; bool isClientTransactionSigningEnabled() { return clientTransactionSigningEnabled_; } void SetAggregator(std::shared_ptr aggregator) { metrics_component_.SetAggregator(aggregator); } - void setClientPublicKey(const std::string& key, PrincipalId, concord::util::crypto::KeyFormat); + void setClientPublicKey(const std::string& key, PrincipalId, concord::crypto::KeyFormat); bool hasVerifier(PrincipalId pid); SigManager(const SigManager&) = delete; SigManager& operator=(const SigManager&) = delete; @@ -76,6 +94,8 @@ class SigManager { SigManager& operator=(SigManager&&) = delete; concord::crypto::SignatureAlgorithm getMainKeyAlgorithm() const; + concord::crypto::ISigner& getSigner(); + const concord::crypto::IVerifier& getVerifier(PrincipalId otherPrincipal) const; std::string getClientsPublicKeys(); std::string getPublicKeyOfVerifier(uint32_t id) const { @@ -89,8 +109,8 @@ class SigManager { SigManager(PrincipalId myId, uint16_t numReplicas, - const std::pair& mySigPrivateKey, - const std::vector>& publickeys, + const std::pair& mySigPrivateKey, + const std::vector>& publickeys, const std::map& publicKeysMapping, bool clientTransactionSigningEnabled, ReplicasInfo& replicasInfo); @@ -98,9 +118,9 @@ class SigManager { static SigManager* initImpl(ReplicaId myId, const Key& mySigPrivateKey, const std::set>& publicKeysOfReplicas, - concord::util::crypto::KeyFormat replicasKeysFormat, + concord::crypto::KeyFormat replicasKeysFormat, const std::set>>* publicKeysOfClients, - concord::util::crypto::KeyFormat clientsKeysFormat, + concord::crypto::KeyFormat clientsKeysFormat, ReplicasInfo& replicasInfo); const PrincipalId myId_; @@ -131,9 +151,9 @@ class SigManager { ReplicaId myId, const Key& mySigPrivateKey, const std::set>& publicKeysOfReplicas, - concord::util::crypto::KeyFormat replicasKeysFormat, + concord::crypto::KeyFormat replicasKeysFormat, const std::set>>* publicKeysOfClients, - concord::util::crypto::KeyFormat clientsKeysFormat, + concord::crypto::KeyFormat clientsKeysFormat, ReplicasInfo& replicasInfo) { return initImpl(myId, mySigPrivateKey, diff --git a/bftengine/src/bftengine/messages/CheckpointMsg.cpp b/bftengine/src/bftengine/messages/CheckpointMsg.cpp index e951f53eec..3e3ca346bc 100644 --- a/bftengine/src/bftengine/messages/CheckpointMsg.cpp +++ b/bftengine/src/bftengine/messages/CheckpointMsg.cpp @@ -64,8 +64,9 @@ void CheckpointMsg::validate(const ReplicasInfo& repInfo) const { throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": size")); } - if (!sigManager->verifySig( - idOfGeneratedReplica(), body(), sizeof(Header), body() + sizeof(Header) + spanContextSize(), sigLen)) + if (!sigManager->verifySig(idOfGeneratedReplica(), + std::string_view{body(), sizeof(Header)}, + std::string_view{body() + sizeof(Header) + spanContextSize(), sigLen})) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": verifySig")); // TODO(GG): consider to protect against messages that are larger than needed (here and in other messages) } diff --git a/bftengine/src/bftengine/messages/ClientRequestMsg.cpp b/bftengine/src/bftengine/messages/ClientRequestMsg.cpp index b2dac2debd..e12026135c 100644 --- a/bftengine/src/bftengine/messages/ClientRequestMsg.cpp +++ b/bftengine/src/bftengine/messages/ClientRequestMsg.cpp @@ -195,8 +195,9 @@ void ClientRequestMsg::validateImp(const ReplicasInfo& repInfo) const { throw std::runtime_error(msg.str()); } if (doSigVerify) { - if (!sigManager->verifySig( - clientId, requestBuf(), header->requestLength, requestSignature(), header->reqSignatureLength)) { + if (!sigManager->verifySig(clientId, + std::string_view{requestBuf(), header->requestLength}, + std::string_view{requestSignature(), header->reqSignatureLength})) { std::stringstream msg; LOG_WARN(CNSUS, "Signature verification failed for" << KVLOG(header->reqSeqNum, this->senderId(), clientId)); msg << "Signature verification failed for: " diff --git a/bftengine/src/bftengine/messages/ReplicaAsksToLeaveViewMsg.cpp b/bftengine/src/bftengine/messages/ReplicaAsksToLeaveViewMsg.cpp index 34ceafd97a..6136049e59 100644 --- a/bftengine/src/bftengine/messages/ReplicaAsksToLeaveViewMsg.cpp +++ b/bftengine/src/bftengine/messages/ReplicaAsksToLeaveViewMsg.cpp @@ -61,7 +61,9 @@ void ReplicaAsksToLeaveViewMsg::validate(const ReplicasInfo& repInfo) const { uint16_t sigLen = sigManager->getSigLength(idOfGeneratedReplica()); if (size() < totalSize + sigLen) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": size")); - if (!sigManager->verifySig(idOfGeneratedReplica(), body(), sizeof(Header), body() + totalSize, sigLen)) + if (!sigManager->verifySig(idOfGeneratedReplica(), + std::string_view{body(), sizeof(Header)}, + std::string_view{body() + totalSize, sigLen})) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": verifySig")); } diff --git a/bftengine/src/bftengine/messages/ReplicaRestartReadyMsg.cpp b/bftengine/src/bftengine/messages/ReplicaRestartReadyMsg.cpp index 5c235312fc..e59fc215a1 100644 --- a/bftengine/src/bftengine/messages/ReplicaRestartReadyMsg.cpp +++ b/bftengine/src/bftengine/messages/ReplicaRestartReadyMsg.cpp @@ -52,7 +52,7 @@ ReplicaRestartReadyMsg* ReplicaRestartReadyMsg::create(ReplicaId senderId, ReplicaRestartReadyMsg* m = new ReplicaRestartReadyMsg(senderId, s, sigLen, r, extraData, spanContext); auto dataSize = sizeof(Header) + m->getExtraDataLength() + spanContext.data().size(); auto position = m->body() + dataSize; - sigManager->sign(m->body(), dataSize, position); + sigManager->sign(reinterpret_cast(m->body()), dataSize, reinterpret_cast(position)); //+-----------+-----------+----------+ //| Header | extraData | Signature| //+-----------+-----------+----------+ @@ -75,7 +75,8 @@ void ReplicaRestartReadyMsg::validate(const ReplicasInfo& repInfo) const { uint16_t sigLen = sigManager->getSigLength(idOfSenderReplica); if (size() < dataSize + sigLen) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": size")); - if (!sigManager->verifySig(idOfSenderReplica, body(), dataSize, body() + dataSize, sigLen)) + if (!sigManager->verifySig( + idOfSenderReplica, std::string_view{body(), dataSize}, std::string_view{body() + dataSize, sigLen})) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": verifySig")); } diff --git a/bftengine/src/bftengine/messages/ReplicasRestartReadyProofMsg.cpp b/bftengine/src/bftengine/messages/ReplicasRestartReadyProofMsg.cpp index 80221897d7..b9edcd13f9 100644 --- a/bftengine/src/bftengine/messages/ReplicasRestartReadyProofMsg.cpp +++ b/bftengine/src/bftengine/messages/ReplicasRestartReadyProofMsg.cpp @@ -106,7 +106,9 @@ bool ReplicasRestartReadyProofMsg::checkElements(const ReplicasInfo& repInfo, ui return false; if (repInfo.myId() != hdr->genReplicaId) { auto dataSize = sizeof(ReplicaRestartReadyMsg::Header) + hdr->extraDataLen; - if (!sigManager->verifySig(hdr->genReplicaId, currLoc, dataSize, currLoc + dataSize, hdr->sigLength)) { + if (!sigManager->verifySig(hdr->genReplicaId, + std::string_view{currLoc, dataSize}, + std::string_view{currLoc + dataSize, hdr->sigLength})) { return false; } } diff --git a/bftengine/src/bftengine/messages/ViewChangeMsg.cpp b/bftengine/src/bftengine/messages/ViewChangeMsg.cpp index 900183c652..48876d5774 100644 --- a/bftengine/src/bftengine/messages/ViewChangeMsg.cpp +++ b/bftengine/src/bftengine/messages/ViewChangeMsg.cpp @@ -179,7 +179,8 @@ void ViewChangeMsg::validate(const ReplicasInfo& repInfo) const { uint16_t sigLen = sigManager->getSigLength(idOfGeneratedReplica()); if (size() < (dataLength + sigLen)) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": size")); - if (!sigManager->verifySig(idOfGeneratedReplica(), body(), dataLength, body() + dataLength, sigLen)) + if (!sigManager->verifySig( + idOfGeneratedReplica(), std::string_view{body(), dataLength}, std::string_view{body() + dataLength, sigLen})) throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": verifySig")); if (!checkElements(sigLen)) // check elements in message throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(": check elements in message")); diff --git a/bftengine/src/preprocessor/RequestProcessingState.cpp b/bftengine/src/preprocessor/RequestProcessingState.cpp index 1b5ccb4af1..0aa6977888 100644 --- a/bftengine/src/preprocessor/RequestProcessingState.cpp +++ b/bftengine/src/preprocessor/RequestProcessingState.cpp @@ -106,10 +106,8 @@ void RequestProcessingState::handlePrimaryPreProcessed(const char *preProcessRes // information. if (preProcessResult != OperationResult::SUCCESS) setupPreProcessResultData(preProcessResult); auto sm = SigManager::instance(); - std::vector sig(sm->getMySigLength()); - sm->sign(reinterpret_cast(primaryPreProcessResultHash_.data()), - primaryPreProcessResultHash_.size(), - sig.data()); + std::vector sig(sm->getMySigLength()); + sm->sign(primaryPreProcessResultHash_.data(), primaryPreProcessResultHash_.size(), sig.data()); if (!preProcessingResultHashes_[primaryPreProcessResultHash_] .emplace(std::move(sig), myReplicaId_, preProcessResult) .second) { @@ -231,10 +229,8 @@ void RequestProcessingState::modifyPrimaryResult( memcpy(const_cast(primaryPreProcessResultData_), result.first.c_str(), primaryPreProcessResultLen_); primaryPreProcessResultHash_ = result.second; auto sm = SigManager::instance(); - std::vector sig(sm->getMySigLength()); - sm->sign(reinterpret_cast(primaryPreProcessResultHash_.data()), - primaryPreProcessResultHash_.size(), - sig.data()); + std::vector sig(sm->getMySigLength()); + sm->sign(primaryPreProcessResultHash_.data(), primaryPreProcessResultHash_.size(), sig.data()); if (!preProcessingResultHashes_[primaryPreProcessResultHash_] .emplace(std::move(sig), myReplicaId_, primaryPreProcessResult_) .second) { diff --git a/bftengine/src/preprocessor/messages/PreProcessReplyMsg.cpp b/bftengine/src/preprocessor/messages/PreProcessReplyMsg.cpp index 69f140687d..7c3a2b1fde 100644 --- a/bftengine/src/preprocessor/messages/PreProcessReplyMsg.cpp +++ b/bftengine/src/preprocessor/messages/PreProcessReplyMsg.cpp @@ -83,21 +83,21 @@ void PreProcessReplyMsg::validate(const ReplicasInfo& repInfo) const { } concord::diagnostics::TimeRecorder scoped_timer(*preProcessorHistograms_->verifyPreProcessReplySig); if (!sigManager->verifySig(msgHeader.senderId, - (char*)msgBody()->resultsHash, + msgBody()->resultsHash, SHA3_256::SIZE_IN_BYTES, - (char*)msgBody() + headerSize, + reinterpret_cast(msgBody()) + headerSize, sigLen)) throw runtime_error(__PRETTY_FUNCTION__ + string(": verifySig failed")); } } // namespace preprocessor -std::vector PreProcessReplyMsg::getResultHashSignature() const { +std::vector PreProcessReplyMsg::getResultHashSignature() const { const uint64_t headerSize = sizeof(Header); const auto& msgHeader = *msgBody(); auto sigManager = SigManager::instance(); uint16_t sigLen = sigManager->getSigLength(msgHeader.senderId); - return std::vector((char*)msgBody() + headerSize, (char*)msgBody() + headerSize + sigLen); + return std::vector((uint8_t*)msgBody() + headerSize, (uint8_t*)msgBody() + headerSize + sigLen); } void PreProcessReplyMsg::setParams(NodeIdType senderId, @@ -154,7 +154,7 @@ void PreProcessReplyMsg::setupMsgBody(const char* preProcessResultBuf, memcpy(msgBody()->resultsHash, hash.data(), SHA3_256::SIZE_IN_BYTES); { concord::diagnostics::TimeRecorder scoped_timer(*preProcessorHistograms_->signPreProcessReplyHash); - sigManager->sign((char*)hash.data(), SHA3_256::SIZE_IN_BYTES, body() + sizeof(Header)); + sigManager->sign(hash.data(), SHA3_256::SIZE_IN_BYTES, reinterpret_cast(body() + sizeof(Header))); } setLeftMsgParams(reqCid, sigSize); } diff --git a/bftengine/src/preprocessor/messages/PreProcessReplyMsg.hpp b/bftengine/src/preprocessor/messages/PreProcessReplyMsg.hpp index 7451cf51cd..298514b897 100644 --- a/bftengine/src/preprocessor/messages/PreProcessReplyMsg.hpp +++ b/bftengine/src/preprocessor/messages/PreProcessReplyMsg.hpp @@ -58,7 +58,7 @@ class PreProcessReplyMsg : public MessageBase { const ReplyStatus status() const { return msgBody()->status; } const bftEngine::OperationResult preProcessResult() const { return msgBody()->preProcessResult; } const ViewNum viewNum() const { return msgBody()->viewNum; } - std::vector getResultHashSignature() const; + std::vector getResultHashSignature() const; std::string getCid() const; static void setPreProcessorHistograms(preprocessor::PreProcessorRecorder* histograms) { diff --git a/bftengine/src/preprocessor/messages/PreProcessRequestMsg.cpp b/bftengine/src/preprocessor/messages/PreProcessRequestMsg.cpp index 47a491eff9..f03b716d6d 100644 --- a/bftengine/src/preprocessor/messages/PreProcessRequestMsg.cpp +++ b/bftengine/src/preprocessor/messages/PreProcessRequestMsg.cpp @@ -100,8 +100,9 @@ void PreProcessRequestMsg::validate(const ReplicasInfo& repInfo) const { if (requestSignature) { ConcordAssert(sigManager->isClientTransactionSigningEnabled()); - if (!sigManager->verifySig( - header->clientId, requestBuf(), header->requestLength, requestSignature, header->reqSignatureLength)) { + if (!sigManager->verifySig(header->clientId, + std::string_view{requestBuf(), header->requestLength}, + std::string_view{requestSignature, header->reqSignatureLength})) { std::stringstream msg; LOG_WARN(logger(), "Signature verification failed for " << KVLOG(header->reqSeqNum, header->clientId, this->senderId())); diff --git a/bftengine/src/preprocessor/messages/PreProcessResultMsg.cpp b/bftengine/src/preprocessor/messages/PreProcessResultMsg.cpp index 48d513168f..3a67d806a2 100644 --- a/bftengine/src/preprocessor/messages/PreProcessResultMsg.cpp +++ b/bftengine/src/preprocessor/messages/PreProcessResultMsg.cpp @@ -79,12 +79,12 @@ std::optional PreProcessResultMsg::validatePreProcessResultSignatur for (const auto& sig : sigs) { bool verificationResult = false; if (myReplicaId == sig.sender_replica) { - std::vector mySignature(sigManager_->getMySigLength(), '\0'); - sigManager_->sign(reinterpret_cast(hash.data()), hash.size(), mySignature.data()); + std::vector mySignature(sigManager_->getMySigLength(), '\0'); + sigManager_->sign(hash.data(), hash.size(), mySignature.data()); verificationResult = mySignature == sig.signature; } else { verificationResult = sigManager_->verifySig( - sig.sender_replica, (const char*)hash.data(), hash.size(), sig.signature.data(), sig.signature.size()); + sig.sender_replica, hash.data(), hash.size(), sig.signature.data(), sig.signature.size()); } if (!verificationResult) { @@ -145,7 +145,7 @@ std::set PreProcessResultSignature::deserializeResult throw std::runtime_error("Deserialization error - remaining buffer length is less than a signature size"); } - ret.emplace(std::vector(buf + pos, buf + pos + signature_size), sender_id, pre_process_result); + ret.emplace(std::vector(buf + pos, buf + pos + signature_size), sender_id, pre_process_result); pos += signature_size; if (len - pos == 0) { diff --git a/bftengine/src/preprocessor/messages/PreProcessResultMsg.hpp b/bftengine/src/preprocessor/messages/PreProcessResultMsg.hpp index ec434c3817..d5039a7204 100644 --- a/bftengine/src/preprocessor/messages/PreProcessResultMsg.hpp +++ b/bftengine/src/preprocessor/messages/PreProcessResultMsg.hpp @@ -11,6 +11,7 @@ #pragma once +#include "types.hpp" #include "messages/ClientRequestMsg.hpp" #include "SharedTypes.hpp" #include @@ -59,13 +60,13 @@ class PreProcessResultMsg : public ClientRequestMsg { }; struct PreProcessResultSignature { - std::vector signature; + std::vector signature; NodeIdType sender_replica; bftEngine::OperationResult pre_process_result; PreProcessResultSignature() = default; - PreProcessResultSignature(std::vector&& sig, NodeIdType sender, bftEngine::OperationResult result) + PreProcessResultSignature(std::vector&& sig, NodeIdType sender, bftEngine::OperationResult result) : signature{std::move(sig)}, sender_replica{sender}, pre_process_result{result} {} bool operator==(const PreProcessResultSignature& rhs) const { diff --git a/bftengine/src/preprocessor/tests/messages/PreProcessReplyMsg_test.cpp b/bftengine/src/preprocessor/tests/messages/PreProcessReplyMsg_test.cpp index 9dd4bbda73..e8ae00d7d4 100644 --- a/bftengine/src/preprocessor/tests/messages/PreProcessReplyMsg_test.cpp +++ b/bftengine/src/preprocessor/tests/messages/PreProcessReplyMsg_test.cpp @@ -109,8 +109,8 @@ TEST_F(PreProcessReplyMsgTestFixture, getResultHashSignature) { viewNum); const auto hash = PreProcessResultHashCreator::create(preProcessResultBuf, preProcessResultBufLen, opResult, clientId, reqSeqNum); - auto expected_signature = std::vector(sigManager->getMySigLength(), 0); - sigManager->sign((char*)hash.data(), sizeof(hash), expected_signature.data()); + auto expected_signature = std::vector(sigManager->getMySigLength()); + sigManager->sign(hash.data(), sizeof(hash), expected_signature.data()); EXPECT_THAT(expected_signature, testing::ContainerEq(preProcessReplyMsg.getResultHashSignature())); clearDiagnosticsHandlers(); } diff --git a/bftengine/src/preprocessor/tests/messages/PreProcessResultMsg_test.cpp b/bftengine/src/preprocessor/tests/messages/PreProcessResultMsg_test.cpp index e63ebd2e57..e925120b61 100644 --- a/bftengine/src/preprocessor/tests/messages/PreProcessResultMsg_test.cpp +++ b/bftengine/src/preprocessor/tests/messages/PreProcessResultMsg_test.cpp @@ -64,6 +64,10 @@ struct MsgParams { const std::string spanContext{rawSpanContext}; }; +std::vector copyAsBytes(const std::vector vec) { + return *reinterpret_cast*>(&vec); +} + std::pair> getProcessResultSigBuff(const std::unique_ptr& sigManager, const MsgParams& p, const int sigCount) { @@ -76,7 +80,7 @@ std::pair> getProcessResultSigBuff(const std::uni // for simplicity, copy the same signatures std::set resultSigs; for (int i = 0; i < sigCount; i++) { - resultSigs.emplace(std::vector(msgSig), i, OperationResult::SUCCESS); + resultSigs.emplace(copyAsBytes(msgSig), i, OperationResult::SUCCESS); } return std::make_pair(PreProcessResultSignature::serializeResultSignatures(resultSigs, sigCount), msgSig); } @@ -132,7 +136,7 @@ class PreProcessResultMsgTestFixture : public testing::Test { // For simplicity, copy the same signatures std::list resultSigs; for (int i = 0; i < sigCount; i++) { - resultSigs.emplace_back(std::vector(msgSig), i, OperationResult::SUCCESS); + resultSigs.emplace_back(copyAsBytes(msgSig), i, OperationResult::SUCCESS); } return std::make_unique(p.senderId, @@ -204,7 +208,7 @@ TEST_F(PreProcessResultMsgTestFixture, SignatureDeserialization) { std::set resultSigs; for (int i = 0; i < replicaInfo.getNumberOfReplicas(); i++) { - resultSigs.emplace(std::vector(msgSig), i, OperationResult::SUCCESS); + resultSigs.emplace(copyAsBytes(msgSig), i, OperationResult::SUCCESS); } auto resultSigsBuf = PreProcessResultSignature::serializeResultSignatures(resultSigs, replicaInfo.getNumberOfReplicas()); @@ -220,7 +224,7 @@ TEST_F(PreProcessResultMsgTestFixture, ShrinkSignaturesToSize) { auto numReplies = 7; auto numRepliesNeeded = 4; for (int i = 0; i < numReplies; i++) { - resultSigs.emplace(std::vector(msgSig), i, OperationResult::SUCCESS); + resultSigs.emplace(copyAsBytes(msgSig), i, OperationResult::SUCCESS); } auto resultSigsBuf = PreProcessResultSignature::serializeResultSignatures(resultSigs, numRepliesNeeded); @@ -260,7 +264,7 @@ TEST_F(PreProcessResultMsgTestFixture, MsgDeserialisation) { auto i = 0; for (const auto& s : sigs) { ASSERT_EQ(s.sender_replica, i++); - EXPECT_THAT(msgSig, s.signature); + EXPECT_THAT(copyAsBytes(msgSig), s.signature); } } @@ -294,7 +298,7 @@ TEST_F(PreProcessResultMsgTestFixture, MsgDeserialisationFromBase) { auto i = 0; for (const auto& s : sigs) { ASSERT_EQ(s.sender_replica, i++); - EXPECT_THAT(msgSig, s.signature); + EXPECT_THAT(copyAsBytes(msgSig), s.signature); } } diff --git a/bftengine/tests/SigManager/SigManager_test.cpp b/bftengine/tests/SigManager/SigManager_test.cpp index 96e1d6bb78..4955aa275b 100644 --- a/bftengine/tests/SigManager/SigManager_test.cpp +++ b/bftengine/tests/SigManager/SigManager_test.cpp @@ -20,7 +20,7 @@ #include #include "gtest/gtest.h" #include "crypto/factory.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" using namespace std; using concord::crypto::KeyFormat; @@ -78,12 +78,14 @@ void generateRandomData(char* data, size_t len) { } } -void corrupt(char* data, size_t len) { +void corrupt(concord::Byte* data, size_t len) { for (size_t i{0}; i < len; ++i) { ++data[i]; } } +void corrupt(char* data, size_t len) { corrupt(reinterpret_cast(data), len); } + TEST(SignerAndVerifierTest, LoadSignVerifyFromHexKeyPair) { char data[RANDOM_DATA_SIZE]{0}; @@ -94,13 +96,11 @@ TEST(SignerAndVerifierTest, LoadSignVerifyFromHexKeyPair) { const auto verifier_ = Factory::getVerifier(keyPair.second, ReplicaConfig::instance().replicaMsgSigningAlgo); // sign with replica signer. - std::string sig; size_t expectedSignerSigLen = signer_->signatureLength(); - sig.reserve(expectedSignerSigLen); + std::vector sig(expectedSignerSigLen); size_t lenRetData; std::string str_data(data, RANDOM_DATA_SIZE); - sig = signer_->sign(str_data); - lenRetData = sig.size(); + lenRetData = signer_->sign(str_data, sig.data()); ASSERT_EQ(lenRetData, expectedSignerSigLen); // validate with replica verifier. @@ -123,7 +123,7 @@ TEST(SignerAndVerifierTest, LoadSignVerifyFromPemfiles) { string publicKeyFullPath({string(KEYS_BASE_PATH) + string("/1/") + PUB_KEY_NAME}); string privateKeyFullPath({string(KEYS_BASE_PATH) + string("/1/") + PRIV_KEY_NAME}); - string privKey, pubkey, sig; + string privKey, pubkey; char data[RANDOM_DATA_SIZE]{0}; generateKeyPairs(1); @@ -139,12 +139,10 @@ TEST(SignerAndVerifierTest, LoadSignVerifyFromPemfiles) { // sign with replica signer. size_t expectedSignerSigLen = signer_->signatureLength(); - sig.reserve(expectedSignerSigLen); - size_t lenRetData; + std::vector sig(expectedSignerSigLen); std::string str_data(data, RANDOM_DATA_SIZE); - sig = signer_->sign(str_data); - lenRetData = sig.size(); - ASSERT_EQ(lenRetData, expectedSignerSigLen); + uint32_t lenRetData = signer_->sign(str_data, sig.data()); + ASSERT_EQ(lenRetData, signer_->signatureLength()); // validate with replica verifier. ASSERT_TRUE(verifier_->verify(str_data, sig)); @@ -194,7 +192,7 @@ TEST(SigManagerTest, ReplicasOnlyCheckVerify) { for (size_t i{0}; i < numReplicas; ++i) { const auto& signer = signers[i]; - string sig; + char data[RANDOM_DATA_SIZE]{0}; size_t lenRetData; size_t expectedSignerSigLen; @@ -203,26 +201,26 @@ TEST(SigManagerTest, ReplicasOnlyCheckVerify) { // sign with replica signer (other replicas, mock) expectedSignerSigLen = signer->signatureLength(); - sig.reserve(expectedSignerSigLen); + std::vector sig(expectedSignerSigLen); + generateRandomData(data, RANDOM_DATA_SIZE); std::string str_data(data, RANDOM_DATA_SIZE); - sig = signer->sign(str_data); - lenRetData = sig.size(); + lenRetData = signer->sign(str_data, sig.data()); ASSERT_EQ(lenRetData, expectedSignerSigLen); // Validate with SigManager (my replica) - size_t expectedVerifierSigLen = sigManager->getSigLength(i); - ASSERT_TRUE(sigManager->verifySig(i, data, RANDOM_DATA_SIZE, sig.data(), expectedVerifierSigLen)); + ASSERT_EQ(sig.size(), sigManager->getSigLength(i)); + ASSERT_TRUE(sigManager->verifySig(i, std::string_view{data, RANDOM_DATA_SIZE}, sig)); // change data randomally, expect failure char data1[RANDOM_DATA_SIZE]; std::copy(std::begin(data), std::end(data), std::begin(data1)); corrupt(data1 + 10, 1); - ASSERT_FALSE(sigManager->verifySig(i, data1, RANDOM_DATA_SIZE, sig.data(), expectedVerifierSigLen)); + ASSERT_FALSE(sigManager->verifySig(i, std::string_view{data1, RANDOM_DATA_SIZE}, sig)); // change signature randomally, expect failure corrupt(sig.data(), 1); - ASSERT_FALSE(sigManager->verifySig(i, data, RANDOM_DATA_SIZE, sig.data(), expectedVerifierSigLen)); + ASSERT_FALSE(sigManager->verifySig(i, std::string_view{data, RANDOM_DATA_SIZE}, sig)); } } @@ -364,7 +362,6 @@ TEST(SigManagerTest, ReplicasAndClientsCheckVerify) { PrincipalId minPidInclusive = 1, maxPidInclusive = currPrincipalId - 1; std::uniform_int_distribution distribution(minPidInclusive, maxPidInclusive); for (size_t i{0}; i < 3E4; ++i) { - string sig; char data[RANDOM_DATA_SIZE]{0}; size_t lenRetData, expectedVerifierSigLen, expectedSignerSigLen, signerIndex; bool expectFailure = false; @@ -380,18 +377,16 @@ TEST(SigManagerTest, ReplicasAndClientsCheckVerify) { // sign expectedSignerSigLen = signers[signerIndex]->signatureLength(); - sig.reserve(expectedSignerSigLen); + std::vector sig(expectedSignerSigLen); generateRandomData(data, RANDOM_DATA_SIZE); std::string str_data(data, RANDOM_DATA_SIZE); - sig = signers[signerIndex]->sign(str_data); - lenRetData = sig.size(); + lenRetData = signers[signerIndex]->sign(str_data, sig.data()); ASSERT_EQ(lenRetData, expectedSignerSigLen); // Validate with SigManager (my replica) expectedVerifierSigLen = sigManager->getSigLength(signerPrincipalId); ASSERT_TRUE((expectFailure && expectedVerifierSigLen == 0) || (!expectFailure && expectedVerifierSigLen > 0)); - bool signatureValid = - sigManager->verifySig(signerPrincipalId, data, RANDOM_DATA_SIZE, sig.data(), expectedVerifierSigLen); + bool signatureValid = sigManager->verifySig(signerPrincipalId, std::string_view{data, RANDOM_DATA_SIZE}, sig); ASSERT_TRUE((expectFailure && !signatureValid) || (!expectFailure && signatureValid)); } } diff --git a/bftengine/tests/clientsManager/ClientsManager_test.cpp b/bftengine/tests/clientsManager/ClientsManager_test.cpp index 25cb8f3428..a9608e6ccd 100644 --- a/bftengine/tests/clientsManager/ClientsManager_test.cpp +++ b/bftengine/tests/clientsManager/ClientsManager_test.cpp @@ -17,7 +17,8 @@ #include "messages/ClientReplyMsg.hpp" #include "ReservedPagesMock.hpp" #include "crypto/factory.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" +#include "crypto/cryptopp/keygen.hpp" using concord::crypto::Factory; using bftEngine::impl::ClientsManager; @@ -153,7 +154,7 @@ static void setMockReservedPages(shared_ptr>& static void resetSigManager() { SigManager::Key kReplicaPrivateKeyForTesting; if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - kReplicaPrivateKeyForTesting = generateRsaKeyPair(RSA_SIGNATURE_LENGTH).first; + kReplicaPrivateKeyForTesting = generateRsaKeyPair().first; } else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { kReplicaPrivateKeyForTesting = generateEdDSAKeyPair().first; } @@ -239,12 +240,9 @@ static bool verifyClientPublicKeyLoadedToKEM(NodeIdType client_id, const pairsign(kArbitraryMessageForTestingKeyAgreement); - return SigManager::instance()->verifySig(client_id, - kArbitraryMessageForTestingKeyAgreement.data(), - kArbitraryMessageForTestingKeyAgreement.length(), - signature.data(), - signature.length()); + std::vector signature(signer->signatureLength()); + EXPECT_EQ(signer->sign(kArbitraryMessageForTestingKeyAgreement, signature.data()), signer->signatureLength()); + return SigManager::instance()->verifySig(client_id, kArbitraryMessageForTestingKeyAgreement, signature); } static bool verifyNoClientPublicKeyLoadedToKEM(NodeIdType client_id) { // Note KeyExchangeManager passes keys a ClientsManager loads to it through to SigManager. @@ -326,7 +324,7 @@ TEST(ClientsManager, loadInfoFromReservedPagesLoadsCorrectInfo) { map> client_keys; if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - client_keys[2] = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + client_keys[2] = generateRsaKeyPair(); } else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { client_keys[2] = generateEdDSAKeyPair(); } @@ -449,7 +447,7 @@ TEST(ClientsManager, loadInfoFromReservedPagesHandlesNoInfoAvailable) { TEST(ClientsManager, loadInfoFromReservedPagesHandlesSingleClientClientsManager) { pair client_key_pair; if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - client_key_pair = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + client_key_pair = generateRsaKeyPair(); } else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { client_key_pair = generateEdDSAKeyPair(); } @@ -1333,8 +1331,8 @@ TEST(ClientsManager, setClientPublicKey) { pair client_2_key; pair client_7_key; if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - client_2_key = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); - client_7_key = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + client_2_key = generateRsaKeyPair(); + client_7_key = generateRsaKeyPair(); } else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { client_2_key = generateEdDSAKeyPair(); client_7_key = generateEdDSAKeyPair(); diff --git a/client/bftclient/src/bft_client.cpp b/client/bftclient/src/bft_client.cpp index cc54d60ada..6d10fbc791 100644 --- a/client/bftclient/src/bft_client.cpp +++ b/client/bftclient/src/bft_client.cpp @@ -130,12 +130,8 @@ Msg Client::createClientMsg(const RequestConfig& config, Msg&& request, bool rea size_t actualSigSize = 0; position += config.correlation_id.size(); { - std::string sig; - std::string data(request.begin(), request.end()); TimeRecorder scoped_timer(*histograms_->sign_duration); - sig = transaction_signer_->sign(data); - actualSigSize = sig.size(); - std::memcpy(position, sig.data(), sig.size()); + actualSigSize = transaction_signer_->sign(request, position); ConcordAssert(expected_sig_len == actualSigSize); header->reqSignatureLength = actualSigSize; histograms_->transaction_size->record(request.size()); @@ -382,7 +378,8 @@ std::string Client::signMessage(std::vector& data) { if (transaction_signer_) { auto expected_sig_len = transaction_signer_->signatureLength(); signature.resize(expected_sig_len); - signature = transaction_signer_->sign(std::string(data.begin(), data.end())); + auto actual_sig_len = transaction_signer_->sign(data, reinterpret_cast(signature.data())); + ConcordAssertEQ(actual_sig_len, expected_sig_len); } return signature; } diff --git a/client/reconfiguration/src/default_handlers.cpp b/client/reconfiguration/src/default_handlers.cpp index 3c8ebcdeac..7b8604183d 100644 --- a/client/reconfiguration/src/default_handlers.cpp +++ b/client/reconfiguration/src/default_handlers.cpp @@ -12,9 +12,10 @@ #include "client/reconfiguration/default_handlers.hpp" #include "bftclient/StateControl.hpp" #include "concord.cmf.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "ReplicaConfig.hpp" #include "openssl/utils.hpp" +#include "crypto/cryptopp/keygen.hpp" #include #include @@ -165,7 +166,7 @@ bool ClientMasterKeyExchangeHandler::execute(const State& state, WriteState& out std::pair hex_keys; std::pair pem_keys; if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - hex_keys = generateRsaKeyPair(concord::crypto::cryptopp::RSA_SIGNATURE_LENGTH); + hex_keys = generateRsaKeyPair(); pem_keys = RsaHexToPem(hex_keys); } if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { diff --git a/communication/src/AsyncTlsConnection.cpp b/communication/src/AsyncTlsConnection.cpp index 01b62df0b4..60b0041dc3 100644 --- a/communication/src/AsyncTlsConnection.cpp +++ b/communication/src/AsyncTlsConnection.cpp @@ -19,7 +19,8 @@ #include #include -#include "crypto.hpp" +#include "crypto/crypto.hpp" +#include "crypto/cryptopp/keygen.hpp" #include "AsyncTlsConnection.h" #include "TlsDiagnostics.h" #include "TlsWriteQueue.h" diff --git a/kvbc/src/pruning_handler.cpp b/kvbc/src/pruning_handler.cpp index 3f14c04b09..2da8eba697 100644 --- a/kvbc/src/pruning_handler.cpp +++ b/kvbc/src/pruning_handler.cpp @@ -20,7 +20,6 @@ namespace concord::kvbc::pruning { -using concord::crypto::Factory; using bftEngine::ReplicaConfig; void PruningSigner::sign(concord::messages::LatestPrunableBlock& block) { @@ -28,18 +27,21 @@ void PruningSigner::sign(concord::messages::LatestPrunableBlock& block) { std::string ser; oss << block.replica << block.block_id; ser = oss.str(); - std::string signature = signer_->sign(ser); - block.signature = std::vector(signature.begin(), signature.end()); + std::vector signature(signer_->signatureLength()); + auto actualSignatureLength = signer_->sign(ser, signature.data()); + ConcordAssertEQ(actualSignatureLength, signer_->signatureLength()); + block.signature = std::move(signature); } PruningSigner::PruningSigner(const std::string& key) { - signer_ = Factory::getSigner(key, ReplicaConfig::instance().replicaMsgSigningAlgo); + signer_ = concord::crypto::Factory::getSigner(key, ReplicaConfig::instance().replicaMsgSigningAlgo); } PruningVerifier::PruningVerifier(const std::set>& replicasPublicKeys) { auto i = 0u; for (auto& [idx, pkey] : replicasPublicKeys) { - replicas_.push_back(Replica{idx, Factory::getVerifier(pkey, ReplicaConfig::instance().replicaMsgSigningAlgo)}); + replicas_.push_back( + Replica{idx, concord::crypto::Factory::getVerifier(pkey, ReplicaConfig::instance().replicaMsgSigningAlgo)}); const auto ins_res = replica_ids_.insert(replicas_.back().principal_id); if (!ins_res.second) { throw std::runtime_error{"PruningVerifier found duplicate replica principal_id: " + diff --git a/kvbc/src/reconfiguration_kvbc_handler.cpp b/kvbc/src/reconfiguration_kvbc_handler.cpp index d0b98945c6..7905796f15 100644 --- a/kvbc/src/reconfiguration_kvbc_handler.cpp +++ b/kvbc/src/reconfiguration_kvbc_handler.cpp @@ -28,7 +28,8 @@ #include "categorized_kvbc_msgs.cmf.hpp" #include "metadata_block_id.h" #include "ReplicaResources.h" -#include "crypto.hpp" +#include "crypto/crypto.hpp" +#include "crypto/cryptopp/keygen.hpp" #include #include @@ -1001,8 +1002,7 @@ bool ReconfigurationHandler::handle(const messages::UnwedgeCommand& cmd, std::string sig_data = std::to_string(id) + std::to_string(unwedge_stat.curr_epoch); auto& sig = unwedge_stat.signature; std::string signature(sig.begin(), sig.end()); - bool valid = bftEngine::impl::SigManager::instance()->verifySig( - id, sig_data.c_str(), sig_data.size(), signature.data(), signature.size()); + bool valid = bftEngine::impl::SigManager::instance()->verifySig(id, sig_data, signature); if (valid) valid_sigs++; } LOG_INFO(getLogger(), "verified " << valid_sigs << " unwedge signatures, required quorum is " << quorum_size); @@ -1140,8 +1140,7 @@ bool InternalKvReconfigurationHandler::verifySignature(uint32_t sender_id, const std::string& data, const std::string& signature) const { if (sender_id >= ReplicaConfig::instance().numReplicas) return false; - return bftEngine::impl::SigManager::instance()->verifySig( - sender_id, data.data(), data.size(), signature.data(), signature.size()); + return bftEngine::impl::SigManager::instance()->verifySig(sender_id, data, signature); } bool InternalKvReconfigurationHandler::handle(const concord::messages::ReplicaMainKeyUpdate& command, diff --git a/kvbc/test/pruning_test.cpp b/kvbc/test/pruning_test.cpp index 93aee5163f..a3371c0930 100644 --- a/kvbc/test/pruning_test.cpp +++ b/kvbc/test/pruning_test.cpp @@ -20,6 +20,7 @@ #include "pruning_handler.hpp" #include "storage/test/storage_test_common.h" +#include "crypto/cryptopp/keygen.hpp" #include #include @@ -56,7 +57,7 @@ std::map private_keys_of_replicas; void setUpKeysConfiguration_4() { for (auto i = 0; i < noOfReplicas; ++i) { if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - keyPair[i] = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + keyPair[i] = generateRsaKeyPair(); } else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { keyPair[i] = generateEdDSAKeyPair(); } diff --git a/kvbc/tools/db_editor/include/kv_blockchain_db_editor.hpp b/kvbc/tools/db_editor/include/kv_blockchain_db_editor.hpp index a6ab6059bd..570874e761 100644 --- a/kvbc/tools/db_editor/include/kv_blockchain_db_editor.hpp +++ b/kvbc/tools/db_editor/include/kv_blockchain_db_editor.hpp @@ -1122,9 +1122,7 @@ struct VerifyDbCheckpoint { if (verifier) { auto signature_len = verifier->signatureLength(); if (signature_len == sig_len) { - std::string _data(data, data_len); - std::string _sig(sig, sig_len); - return verifier->verify(_data, _sig); + return verifier->verify(std::string_view{data, data_len}, std::string_view{sig, sig_len}); } } return false; diff --git a/reconfiguration/include/reconfiguration/reconfiguration_handler.hpp b/reconfiguration/include/reconfiguration/reconfiguration_handler.hpp index 01dcd84c6d..abbd1677dc 100644 --- a/reconfiguration/include/reconfiguration/reconfiguration_handler.hpp +++ b/reconfiguration/include/reconfiguration/reconfiguration_handler.hpp @@ -106,8 +106,7 @@ class ClientReconfigurationHandler : public concord::reconfiguration::IReconfigu bool verifySignature(uint32_t sender_id, const std::string &data, const std::string &signature) const override { if (!bftEngine::impl::SigManager::instance()->hasVerifier(sender_id)) return false; - return bftEngine::impl::SigManager::instance()->verifySig( - sender_id, data.data(), data.size(), signature.data(), signature.size()); + return bftEngine::impl::SigManager::instance()->verifySig(sender_id, data, signature); } }; diff --git a/threshsign/include/threshsign/eddsa/EdDSAMultisigVerifier.h b/threshsign/include/threshsign/eddsa/EdDSAMultisigVerifier.h index 21af0a6bc2..3aacf11de8 100644 --- a/threshsign/include/threshsign/eddsa/EdDSAMultisigVerifier.h +++ b/threshsign/include/threshsign/eddsa/EdDSAMultisigVerifier.h @@ -59,7 +59,7 @@ class EdDSAMultisigVerifier : public IThresholdVerifier { const IPublicKey &getPublicKey() const override; const IShareVerificationKey &getShareVerificationKey(ShareID signer) const override; - bool verifySingleSignature(const uint8_t *msg, size_t msgLen, const SingleEdDSASignature &signature) const; + bool verifySingleSignature(const concord::Byte *msg, size_t msgLen, const SingleEdDSASignature &signature) const; ~EdDSAMultisigVerifier() override = default; private: diff --git a/threshsign/include/threshsign/eddsa/EdDSAThreshsignKeys.h b/threshsign/include/threshsign/eddsa/EdDSAThreshsignKeys.h index 7c01b1867c..284affe2d9 100644 --- a/threshsign/include/threshsign/eddsa/EdDSAThreshsignKeys.h +++ b/threshsign/include/threshsign/eddsa/EdDSAThreshsignKeys.h @@ -14,16 +14,16 @@ #include "threshsign/ISecretKey.h" #include "crypto/openssl/EdDSA.hpp" -class EdDSAThreshsignPrivateKey : public IShareSecretKey, public concord::util::crypto::openssl::EdDSAPrivateKey { +class EdDSAThreshsignPrivateKey : public IShareSecretKey, public concord::crypto::openssl::EdDSAPrivateKey { public: EdDSAThreshsignPrivateKey(const EdDSAThreshsignPrivateKey::ByteArray& arr) - : concord::util::crypto::openssl::EdDSAPrivateKey(arr) {} + : concord::crypto::openssl::EdDSAPrivateKey(arr) {} std::string toString() const override { return toHexString(); } }; -class EdDSAThreshsignPublicKey : public IShareVerificationKey, public concord::util::crypto::openssl::EdDSAPublicKey { +class EdDSAThreshsignPublicKey : public IShareVerificationKey, public concord::crypto::openssl::EdDSAPublicKey { public: EdDSAThreshsignPublicKey(const EdDSAThreshsignPublicKey::ByteArray& arr) - : concord::util::crypto::openssl::EdDSAPublicKey(arr) {} + : concord::crypto::openssl::EdDSAPublicKey(arr) {} std::string toString() const override { return toHexString(); } }; \ No newline at end of file diff --git a/threshsign/include/threshsign/eddsa/SingleEdDSASignature.h b/threshsign/include/threshsign/eddsa/SingleEdDSASignature.h index 9cba6ee185..36f8fe93cd 100644 --- a/threshsign/include/threshsign/eddsa/SingleEdDSASignature.h +++ b/threshsign/include/threshsign/eddsa/SingleEdDSASignature.h @@ -12,11 +12,13 @@ #pragma once #include #include +#include "types.hpp" +#include "crypto/openssl/EdDSA.hpp" /** * Used as an interface between signers and verifiers */ struct SingleEdDSASignature { uint64_t id; - std::array signatureBytes; + std::array signatureBytes; }; \ No newline at end of file diff --git a/threshsign/src/ThresholdSignaturesTypes.cpp b/threshsign/src/ThresholdSignaturesTypes.cpp index 14923c61e3..0e21e3bcc9 100644 --- a/threshsign/src/ThresholdSignaturesTypes.cpp +++ b/threshsign/src/ThresholdSignaturesTypes.cpp @@ -18,7 +18,7 @@ #include "yaml_utils.hpp" #include "Logger.hpp" #include "string.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" using concord::crypto::isValidKey; @@ -236,7 +236,7 @@ void Cryptosystem::validatePublicKey(const std::string& key) const { void Cryptosystem::validateVerificationKey(const std::string& key) const { #ifdef USE_EDDSA_OPENSSL - constexpr const size_t expectedKeyLength = concord::util::crypto::openssl::EdDSAPublicKeyByteSize * 2; + constexpr const size_t expectedKeyLength = concord::crypto::openssl::EdDSAPublicKeyByteSize * 2; #else constexpr const size_t expectedKeyLength = 130u; #endif @@ -246,7 +246,7 @@ void Cryptosystem::validateVerificationKey(const std::string& key) const { void Cryptosystem::validatePrivateKey(const std::string& key) const { #ifdef USE_EDDSA_OPENSSL - constexpr const size_t expectedKeyLength = concord::util::crypto::openssl::EdDSAPrivateKeyByteSize * 2; + constexpr const size_t expectedKeyLength = concord::crypto::openssl::EdDSAPrivateKeyByteSize * 2; #else // We currently do not validate the length of the private key's string // representation because the length of its serialization varies slightly. diff --git a/threshsign/src/eddsa/EdDSAMultisigSigner.cpp b/threshsign/src/eddsa/EdDSAMultisigSigner.cpp index a97c974e74..45f36a8989 100644 --- a/threshsign/src/eddsa/EdDSAMultisigSigner.cpp +++ b/threshsign/src/eddsa/EdDSAMultisigSigner.cpp @@ -25,10 +25,7 @@ void EdDSAMultisigSigner::signData(const char *hash, int hashLen, char *outSig, LOG_DEBUG(EDDSA_MULTISIG_LOG, KVLOG(id_)); SingleEdDSASignature result; auto outSigBytesLen = result.signatureBytes.size(); - sign(reinterpret_cast(hash), - static_cast(hashLen), - result.signatureBytes.data(), - outSigBytesLen); + signBuffer(reinterpret_cast(hash), static_cast(hashLen), result.signatureBytes.data()); ConcordAssertEQ(outSigBytesLen, result.signatureBytes.size()); result.id = id_; std::memcpy(outSig, &result, sizeof(SingleEdDSASignature)); diff --git a/threshsign/src/eddsa/EdDSAMultisigVerifier.cpp b/threshsign/src/eddsa/EdDSAMultisigVerifier.cpp index 2451ab93fd..e72129e059 100644 --- a/threshsign/src/eddsa/EdDSAMultisigVerifier.cpp +++ b/threshsign/src/eddsa/EdDSAMultisigVerifier.cpp @@ -79,13 +79,14 @@ IThresholdAccumulator *EdDSAMultisigVerifier::newAccumulator(bool withShareVerif return new EdDSASignatureAccumulator(withShareVerification, *this); } -bool EdDSAMultisigVerifier::verifySingleSignature(const uint8_t *msg, +bool EdDSAMultisigVerifier::verifySingleSignature(const concord::Byte *msg, size_t msgLen, const SingleEdDSASignature &signature) const { if (signature.id == 0) { return false; } - return verifiers_[signature.id].verify(msg, msgLen, signature.signatureBytes.data(), signature.signatureBytes.size()); + return verifiers_[signature.id].verifyBuffer( + msg, msgLen, signature.signatureBytes.data(), signature.signatureBytes.size()); } bool EdDSAMultisigVerifier::verify(const char *msg, int msgLen, const char *sig, int sigLen) const { diff --git a/tools/GenerateConcordKeys.cpp b/tools/GenerateConcordKeys.cpp index b72c23aea8..8403c49a6c 100644 --- a/tools/GenerateConcordKeys.cpp +++ b/tools/GenerateConcordKeys.cpp @@ -23,7 +23,8 @@ #include "threshsign/ThresholdSignaturesTypes.h" #include "KeyfileIOUtils.hpp" #include "util/filesystem.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" +#include "crypto/cryptopp/keygen.hpp" using bftEngine::ReplicaConfig; using concord::crypto::SIGN_VERIFY_ALGO; @@ -192,7 +193,7 @@ int main(int argc, char** argv) { for (uint16_t i = 0; i < n + ro; ++i) { if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) { - replicaKeyPairs.push_back(generateRsaKeyPair(RSA_SIGNATURE_LENGTH)); + replicaKeyPairs.push_back(generateRsaKeyPair()); } else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) { replicaKeyPairs.push_back(generateEdDSAKeyPair()); } diff --git a/tools/KeyfileIOUtils.cpp b/tools/KeyfileIOUtils.cpp index b70cfb4b63..2d1e11f1d8 100644 --- a/tools/KeyfileIOUtils.cpp +++ b/tools/KeyfileIOUtils.cpp @@ -21,13 +21,13 @@ #include "KeyfileIOUtils.hpp" #include "yaml_utils.hpp" #include "crypto/openssl/EdDSA.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" using concord::crypto::isValidKey; using bftEngine::ReplicaConfig; using concord::crypto::SIGN_VERIFY_ALGO; -using concord::util::crypto::openssl::EdDSAPrivateKeyByteSize; -using concord::util::crypto::openssl::EdDSAPublicKeyByteSize; +using concord::crypto::openssl::EdDSAPrivateKeyByteSize; +using concord::crypto::openssl::EdDSAPublicKeyByteSize; void outputReplicaKeyfile(uint16_t numReplicas, uint16_t numRoReplicas, diff --git a/tools/TestGeneratedKeys.cpp b/tools/TestGeneratedKeys.cpp index 907ae9f333..c97e4ead2e 100644 --- a/tools/TestGeneratedKeys.cpp +++ b/tools/TestGeneratedKeys.cpp @@ -154,14 +154,19 @@ static bool testReplicaKeyPair(const std::string& privateKey, const std::string& return false; } + auto expectedSignatureLength = signer->signatureLength(); + ConcordAssertGT(expectedSignatureLength, 0); + for (auto iter = std::begin(kHashesToTest); iter != std::end(kHashesToTest); ++iter) { const std::string& hash = *iter; - std::string sig; + std::string sig(expectedSignatureLength + 1, '\x00'); try { - sig = signer->sign(hash); - if (sig.empty()) { + auto sigLength = signer->sign(hash, reinterpret_cast(sig.data())); + if (sigLength != expectedSignatureLength) { std::cout << "FAILURE: Failed to sign data with replica " << replicaID << "'s private key.\n"; + std::cout << "Expected signature length: " << expectedSignatureLength << ", actual length: " << sigLength + << ".\n"; return false; } } catch (std::exception& e) { diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index b24c4968ea..d6df046cb0 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -15,6 +15,7 @@ set(util_source_files src/openssl/utils.cpp src/crypto/cryptopp/signers.cpp src/crypto/cryptopp/verifiers.cpp + src/crypto/cryptopp/keygen.cpp src/RawMemoryPool.cpp src/config_file_parser.cpp src/cryptopp/digest_creator.cpp diff --git a/util/bench/benchmarkSignVerify.cpp b/util/bench/benchmarkSignVerify.cpp index 5498766f85..5e603cf79e 100644 --- a/util/bench/benchmarkSignVerify.cpp +++ b/util/bench/benchmarkSignVerify.cpp @@ -23,12 +23,13 @@ #include "thread_pool.hpp" #include "picobench.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "crypto/openssl/EdDSASigner.hpp" #include "crypto/openssl/EdDSAVerifier.hpp" #include "util/filesystem.hpp" #include "crypto/cryptopp/signers.hpp" #include "crypto/cryptopp/verifiers.hpp" +#include "crypto/cryptopp/keygen.hpp" namespace concord::benchmark { using std::string; @@ -39,12 +40,13 @@ using concord::crypto::cryptopp::RSAVerifier; using concord::crypto::cryptopp::RSA_SIGNATURE_LENGTH; using concord::crypto::generateEdDSAKeyPair; using concord::crypto::generateRsaKeyPair; -using concord::util::crypto::openssl::EdDSAPrivateKey; -using concord::util::crypto::openssl::EdDSAPublicKey; -using concord::util::crypto::openssl::deserializeKey; +using concord::crypto::openssl::EdDSAPrivateKey; +using concord::crypto::openssl::EdDSAPublicKey; +using concord::crypto::openssl::deserializeKey; using TestSigner = concord::crypto::openssl::EdDSASigner; using TestVerifier = concord::crypto::openssl::EdDSAVerifier; +using SignatureBytes = std::vector; std::default_random_engine generator; @@ -52,7 +54,7 @@ constexpr size_t RANDOM_DATA_SIZE = 1000U; constexpr uint8_t RANDOM_DATA_ARRAY_SIZE = 100U; static string randomData[RANDOM_DATA_ARRAY_SIZE]; -const auto rsaKeysPair = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); +const auto rsaKeysPair = generateRsaKeyPair(); const auto eddsaKeysPair = generateEdDSAKeyPair(); /** @@ -78,13 +80,12 @@ void generateRandomData(size_t len) { * @param s */ void edDSASignerBenchmark(picobench::state& s) { - string sig; const auto signingKey = deserializeKey(eddsaKeysPair.first); - auto signer_ = unique_ptr(new TestSigner(signingKey.getBytes())); + auto signer_ = unique_ptr(new TestSigner(signingKey.getBytes())); + size_t expectedSignerSigLen = signer_->signatureLength(); + SignatureBytes sig(expectedSignerSigLen); // Sign with EdDSASigner. - size_t expectedSignerSigLen = signer_->signatureLength(); - sig.reserve(expectedSignerSigLen); size_t lenRetData; uint64_t signaturesPerformed = 0; @@ -92,8 +93,7 @@ void edDSASignerBenchmark(picobench::state& s) { picobench::scope scope(s); for (int msgIdx = 0; msgIdx < s.iterations(); msgIdx++) { - sig = signer_->sign(randomData[msgIdx % RANDOM_DATA_ARRAY_SIZE]); - lenRetData = sig.size(); + lenRetData = signer_->sign(randomData[msgIdx % RANDOM_DATA_ARRAY_SIZE], sig.data()); ++signaturesPerformed; ConcordAssertEQ(lenRetData, expectedSignerSigLen); } @@ -107,23 +107,20 @@ void edDSASignerBenchmark(picobench::state& s) { * @param s */ void edDSAVerifierBenchmark(picobench::state& s) { - string sig; const auto signingKey = deserializeKey(eddsaKeysPair.first); + auto signer_ = unique_ptr(new TestSigner(signingKey.getBytes())); + size_t expectedSignerSigLen = signer_->signatureLength(); + SignatureBytes sig(expectedSignerSigLen); const auto verificationKey = deserializeKey(eddsaKeysPair.second); - - auto signer_ = unique_ptr(new TestSigner(signingKey.getBytes())); auto verifier_ = unique_ptr(new TestVerifier(verificationKey.getBytes())); // Sign with EdDSASigner. - size_t expectedSignerSigLen = signer_->signatureLength(); - sig.reserve(expectedSignerSigLen); - size_t lenRetData; - const auto offset = (uint8_t)rand() % RANDOM_DATA_ARRAY_SIZE; - sig = signer_->sign(randomData[offset]); - lenRetData = sig.size(); + size_t lenRetData = signer_->sign(randomData[offset], sig.data()); ConcordAssertEQ(lenRetData, expectedSignerSigLen); + std::string sigAsString("\x00", sig.size() + 1); + std::memcpy(sigAsString.data(), sig.data(), sig.size()); uint64_t signaturesVerified = 0; { picobench::scope scope(s); @@ -132,7 +129,7 @@ void edDSAVerifierBenchmark(picobench::state& s) { ++signaturesVerified; // validate with EdDSAVerifier. - ConcordAssert(verifier_->verify(randomData[offset], sig)); + ConcordAssert(verifier_->verify(randomData[offset], sigAsString)); } } s.set_result(signaturesVerified); @@ -144,11 +141,12 @@ void edDSAVerifierBenchmark(picobench::state& s) { * @param s */ void rsaSignerBenchmark(picobench::state& s) { - string sig; - auto signer_ = unique_ptr(new RSASigner(rsaKeysPair.first, KeyFormat::HexaDecimalStrippedFormat)); - - // Sign with RSA_Signer. + auto signer_ = + unique_ptr(new RSASigner(rsaKeysPair.first, KeyFormat::HexaDecimalStrippedFormat)); size_t expectedSignerSigLen = signer_->signatureLength(); + SignatureBytes sig; + // Sign with RSA_Signer. + sig.reserve(expectedSignerSigLen); size_t lenRetData; @@ -157,8 +155,7 @@ void rsaSignerBenchmark(picobench::state& s) { picobench::scope scope(s); for (int msgIdx = 0; msgIdx < s.iterations(); msgIdx++) { - sig = signer_->sign(randomData[msgIdx % RANDOM_DATA_ARRAY_SIZE]); - lenRetData = sig.size(); + lenRetData = signer_->sign(randomData[msgIdx % RANDOM_DATA_ARRAY_SIZE], sig.data()); ++signaturesPerformed; ConcordAssertEQ(lenRetData, expectedSignerSigLen); } @@ -172,20 +169,20 @@ void rsaSignerBenchmark(picobench::state& s) { * @param s */ void rsaVerifierBenchmark(picobench::state& s) { - string sig; - auto signer_ = unique_ptr(new RSASigner(rsaKeysPair.first, KeyFormat::HexaDecimalStrippedFormat)); + auto signer_ = + unique_ptr(new RSASigner(rsaKeysPair.first, KeyFormat::HexaDecimalStrippedFormat)); + size_t expectedSignerSigLen = signer_->signatureLength(); + SignatureBytes sig(expectedSignerSigLen); auto verifier_ = unique_ptr(new RSAVerifier(rsaKeysPair.second, KeyFormat::HexaDecimalStrippedFormat)); // Sign with RSASigner. - size_t expectedSignerSigLen = signer_->signatureLength(); - sig.reserve(expectedSignerSigLen); - size_t lenRetData; const auto offset = (uint8_t)rand() % RANDOM_DATA_ARRAY_SIZE; - sig = signer_->sign(randomData[offset]); - lenRetData = sig.size(); + size_t lenRetData = signer_->sign(randomData[offset], sig.data()); ConcordAssertEQ(lenRetData, expectedSignerSigLen); + std::string sigAsString("\x00", sig.size() + 1); + std::memcpy(sigAsString.data(), sig.data(), sig.size()); uint64_t signaturesVerified = 0; { picobench::scope scope(s); @@ -194,7 +191,7 @@ void rsaVerifierBenchmark(picobench::state& s) { ++signaturesVerified; // validate with RSAVerifier. - ConcordAssert(verifier_->verify(randomData[offset], sig)); + ConcordAssert(verifier_->verify(randomData[offset], sigAsString)); } } s.set_result(signaturesVerified); diff --git a/util/include/crypto.hpp b/util/include/crypto/crypto.hpp similarity index 59% rename from util/include/crypto.hpp rename to util/include/crypto/crypto.hpp index 9dc71abbf9..79e0c39409 100644 --- a/util/include/crypto.hpp +++ b/util/include/crypto/crypto.hpp @@ -13,11 +13,14 @@ #pragma once -#include +#include #include +#include namespace concord::crypto { +enum SignatureAlgorithm : uint32_t { Uninitialized = 0, BLS = 1, EdDSA = 2, RSA = 3 }; + enum class KeyFormat : uint16_t { HexaDecimalStrippedFormat, PemFormat }; enum class CurveType : uint16_t { secp256k1, secp384r1 }; @@ -37,40 +40,6 @@ std::pair generateEdDSAKeyPair(const KeyFormat fmt = K */ std::pair EdDSAHexToPem(const std::pair& hex_key_pair); -/** - * @brief Generates an RSA asymmetric key pair (private-public key pair). - * - * @param fmt Output key format. - * @return pair Private-Public key pair. - */ -std::pair generateRsaKeyPair(const uint32_t sig_length, - const KeyFormat fmt = KeyFormat::HexaDecimalStrippedFormat); - -/** - * @brief Generates an ECDSA asymmetric key pair (private-public key pair). - * - * @param fmt Output key format. - * @return pair Private-Public key pair. - */ -std::pair generateECDSAKeyPair( - const KeyFormat fmt, concord::crypto::CurveType curve_type = concord::crypto::CurveType::secp256k1); - -/** - * @brief Generates an RSA PEM file from hexadecimal key pair (private-public key pair). - * - * @param key_pair Key pair in hexa-decimal format. - * @return pair - */ -std::pair RsaHexToPem(const std::pair& key_pair); - -/** - * @brief Generates an ECDSA PEM file from hexadecimal key pair (private-public key pair). - * - * @param key_pair Key pair in hexa-decimal format. - * @return pair - */ -std::pair ECDSAHexToPem(const std::pair& key_pair); - /** * @brief If the key string contains 'BEGIN' token, then it is PEM format, else HEX format. * diff --git a/util/include/crypto/cryptopp/keygen.hpp b/util/include/crypto/cryptopp/keygen.hpp new file mode 100644 index 0000000000..9d25459077 --- /dev/null +++ b/util/include/crypto/cryptopp/keygen.hpp @@ -0,0 +1,53 @@ +// Concord +// +// Copyright (c) 2022 VMware, Inc. All Rights Reserved. +// +// This product is licensed to you under the Apache 2.0 license (the "License"). +// You may not use this product except in compliance with the Apache 2.0 +// License. +// +// This product may include a number of subcomponents with separate copyright +// notices and license terms. Your use of these subcomponents is subject to the +// terms and conditions of the sub-component's license, as noted in the LICENSE +// file. + +#pragma once +#include "crypto/crypto.hpp" +#include + +namespace concord::crypto { +/** + * @brief Generates an RSA PEM file from hexadecimal key pair (private-public key pair). + * + * @param key_pair Key pair in hexa-decimal format. + * @return pair + */ +std::pair RsaHexToPem(const std::pair& key_pair); + +/** + * @brief Generates an ECDSA PEM file from hexadecimal key pair (private-public key pair). + * + * @param key_pair Key pair in hexa-decimal format. + * @return pair + */ +std::pair ECDSAHexToPem(const std::pair& key_pair); + +/** + * @brief Generates an RSA asymmetric key pair (private-public key pair). + * + * @param fmt Output key format. + * @return pair Private-Public key pair. + */ +std::pair generateRsaKeyPair(const KeyFormat fmt = KeyFormat::HexaDecimalStrippedFormat); + +/** + * @brief Generates an ECDSA asymmetric key pair (private-public key + * pair). + * + * @param fmt Output key format. + * @return pair Private-Public key pair. + */ +std::pair generateECDSAKeyPair( + const KeyFormat fmt, concord::crypto::CurveType curve_type = concord::crypto::CurveType::secp256k1); + +} // namespace concord::crypto \ No newline at end of file diff --git a/util/include/crypto/cryptopp/signers.hpp b/util/include/crypto/cryptopp/signers.hpp index 5b4e6b4031..506aeee78e 100644 --- a/util/include/crypto/cryptopp/signers.hpp +++ b/util/include/crypto/cryptopp/signers.hpp @@ -15,7 +15,7 @@ #include -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "crypto/signer.hpp" namespace concord::crypto::cryptopp { @@ -26,8 +26,9 @@ class ECDSASigner : public ISigner { public: ECDSASigner(const std::string& str_priv_key, concord::crypto::KeyFormat fmt = concord::crypto::KeyFormat::HexaDecimalStrippedFormat); - std::string sign(const std::string& data) override; - uint32_t signatureLength() const override; + std::string sign(const std::string& data); + size_t signBuffer(const Byte* const dataIn, size_t dataLen, Byte* sigOutBuffer) override; + size_t signatureLength() const override; std::string getPrivKey() const override { return key_str_; } ~ECDSASigner(); @@ -41,8 +42,8 @@ class RSASigner : public ISigner { public: RSASigner(const std::string& str_priv_key, concord::crypto::KeyFormat fmt = concord::crypto::KeyFormat::HexaDecimalStrippedFormat); - std::string sign(const std::string& data) override; - uint32_t signatureLength() const override; + size_t signBuffer(const Byte* const dataIn, size_t dataLen, Byte* sigOutBuffer) override; + size_t signatureLength() const override; std::string getPrivKey() const override { return key_str_; } ~RSASigner(); diff --git a/util/include/crypto/cryptopp/verifiers.hpp b/util/include/crypto/cryptopp/verifiers.hpp index 8b57476c6b..8b175a85dd 100644 --- a/util/include/crypto/cryptopp/verifiers.hpp +++ b/util/include/crypto/cryptopp/verifiers.hpp @@ -14,17 +14,17 @@ #pragma once #include - -#include "crypto.hpp" +#include "types.hpp" +#include "crypto/crypto.hpp" #include "crypto/verifier.hpp" namespace concord::crypto::cryptopp { class ECDSAVerifier : public IVerifier { public: - ECDSAVerifier(const std::string& str_pub_key, + ECDSAVerifier(const std::string &str_pub_key, concord::crypto::KeyFormat fmt = concord::crypto::KeyFormat::HexaDecimalStrippedFormat); - bool verify(const std::string& data, const std::string& sig) const override; + bool verifyBuffer(const concord::Byte *msg, size_t msgLen, const concord::Byte *sig, size_t sigLen) const override; uint32_t signatureLength() const override; std::string getPubKey() const override { return key_str_; } ~ECDSAVerifier(); @@ -37,9 +37,9 @@ class ECDSAVerifier : public IVerifier { class RSAVerifier : public IVerifier { public: - RSAVerifier(const std::string& str_pub_key, + RSAVerifier(const std::string &str_pub_key, concord::crypto::KeyFormat fmt = concord::crypto::KeyFormat::HexaDecimalStrippedFormat); - bool verify(const std::string& data, const std::string& sig) const override; + bool verifyBuffer(const concord::Byte *msg, size_t msgLen, const concord::Byte *sig, size_t sigLen) const override; uint32_t signatureLength() const override; std::string getPubKey() const override { return key_str_; } ~RSAVerifier(); diff --git a/util/include/crypto/eddsa/EdDSA.h b/util/include/crypto/eddsa/EdDSA.h deleted file mode 100644 index 974af3b96b..0000000000 --- a/util/include/crypto/eddsa/EdDSA.h +++ /dev/null @@ -1,28 +0,0 @@ -// Concord -// -// Copyright (c) 2018-2022 VMware, Inc. All Rights Reserved. -// -// This product is licensed to you under the Apache 2.0 license (the "License"). -// You may not use this product except in compliance with the Apache 2.0 License. -// -// This product may include a number of subcomponents with separate copyright -// notices and license terms. Your use of these subcomponents is subject to the -// terms and conditions of the subcomponent's license, as noted in the -// LICENSE file. -// -#pragma once -#include "SerializableByteArray.hpp" - -static constexpr const size_t EdDSAPrivateKeyByteSize = 32; -static constexpr const size_t EdDSAPublicKeyByteSize = 32; -static constexpr const size_t EdDSASignatureByteSize = 64; - -class EdDSAPrivateKey : public SerializableByteArray { - public: - EdDSAPrivateKey(const EdDSAPrivateKey::ByteArray& arr) : SerializableByteArray(arr) {} -}; - -class EdDSAPublicKey : public SerializableByteArray { - public: - EdDSAPublicKey(const EdDSAPublicKey::ByteArray& arr) : SerializableByteArray(arr) {} -}; \ No newline at end of file diff --git a/util/include/crypto/eddsa/EdDSASigner.hpp b/util/include/crypto/eddsa/EdDSASigner.hpp deleted file mode 100644 index d9c5cc9402..0000000000 --- a/util/include/crypto/eddsa/EdDSASigner.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Concord -// -// Copyright (c) 2018-2022 VMware, Inc. All Rights Reserved. -// -// This product is licensed to you under the Apache 2.0 license (the "License"). -// You may not use this product except in compliance with the Apache 2.0 License. -// -// This product may include a number of subcomponents with separate copyright -// notices and license terms. Your use of these subcomponents is subject to the -// terms and conditions of the subcomponent's license, as noted in the -// LICENSE file. -// -#pragma once -#include "EdDSA.h" -#include "openssl_crypto.hpp" - -/** - * - * @tparam PrivateKeyType The type of the private key, expected to be a SerializableByteArray - * - */ -template -class EdDSASigner { - public: - using SignerKeyType = PrivateKeyType; - EdDSASigner(const PrivateKeyType &privateKey) : privateKey_(privateKey) {} - - std::string sign(const uint8_t *msg, size_t len) const { - std::string signature(EdDSASignatureByteSize, 0); - size_t sigLen_ = EdDSASignatureByteSize; - sign(msg, len, reinterpret_cast(signature.data()), sigLen_); - ConcordAssertEQ(sigLen_, EdDSASignatureByteSize); - return signature; - } - - void sign(const uint8_t *msg, size_t len, uint8_t *signature, size_t &signatureLength) const { - concord::util::openssl_utils::UniquePKEY pkey{EVP_PKEY_new_raw_private_key( - NID_ED25519, nullptr, privateKey_.getBytes().data(), privateKey_.getBytes().size())}; - concord::util::openssl_utils::UniqueOpenSSLContext ctx{EVP_MD_CTX_new()}; - ConcordAssertEQ(EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get()), - concord::util::openssl_utils::OPENSSL_SUCCESS); - ConcordAssertEQ(EVP_DigestSign(ctx.get(), signature, &signatureLength, msg, len), - concord::util::openssl_utils::OPENSSL_SUCCESS); - } - - std::string sign(const std::string &message) const { - return sign(reinterpret_cast(message.data()), message.size()); - } - - const PrivateKeyType &getPrivKey() const { return privateKey_; } - virtual ~EdDSASigner() = default; - - private: - PrivateKeyType privateKey_; -}; diff --git a/util/include/crypto/eddsa/EdDSAVerifier.hpp b/util/include/crypto/eddsa/EdDSAVerifier.hpp deleted file mode 100644 index 57e0a7cd41..0000000000 --- a/util/include/crypto/eddsa/EdDSAVerifier.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Concord -// -// Copyright (c) 2018-2022 VMware, Inc. All Rights Reserved. -// -// This product is licensed to you under the Apache 2.0 license (the "License"). -// You may not use this product except in compliance with the Apache 2.0 License. -// -// This product may include a number of subcomponents with separate copyright -// notices and license terms. Your use of these subcomponents is subject to the -// terms and conditions of the subcomponent's license, as noted in the -// LICENSE file. -// -#pragma once -#include "EdDSA.h" -#include "openssl_crypto.hpp" - -/** - * @tparam PublicKeyType The type of the public key - expected to be a SerializableByteArray - * - */ -template -class EdDSAVerifier { - public: - using VerifierKeyType = PublicKeyType; - EdDSAVerifier(const PublicKeyType &publicKey) : publicKey_(publicKey) {} - - bool verify(const std::string &message, const std::string &signature) const { - return verify(message.data(), message.size(), signature.data(), signature.size()); - } - - bool verify(const char *msg, int msgLen, const char *sig, int sigLen) const { - return verify(reinterpret_cast(msg), - static_cast(msgLen), - reinterpret_cast(sig), - static_cast(sigLen)); - } - - bool verify(const uint8_t *msg, size_t msgLen, const uint8_t *sig, size_t sigLen) const { - ConcordAssertEQ(sigLen, EdDSASignatureByteSize); - concord::util::openssl_utils::UniquePKEY pkey{ - EVP_PKEY_new_raw_public_key(NID_ED25519, nullptr, publicKey_.getBytes().data(), publicKey_.getBytes().size())}; - concord::util::openssl_utils::UniqueOpenSSLContext ctx{EVP_MD_CTX_new()}; - ConcordAssertEQ(EVP_DigestVerifyInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get()), - concord::util::openssl_utils::OPENSSL_SUCCESS); - return concord::util::openssl_utils::OPENSSL_SUCCESS == EVP_DigestVerify(ctx.get(), sig, sigLen, msg, msgLen); - } - const PublicKeyType &getPubKey() const { return publicKey_; } - virtual ~EdDSAVerifier() = default; - - private: - PublicKeyType publicKey_; -}; \ No newline at end of file diff --git a/util/include/crypto/factory.hpp b/util/include/crypto/factory.hpp index 864984b2ec..bbc98c96c5 100644 --- a/util/include/crypto/factory.hpp +++ b/util/include/crypto/factory.hpp @@ -36,11 +36,9 @@ class Factory { return std::unique_ptr(new concord::crypto::cryptopp::RSASigner(signingKey, fmt)); } case SIGN_VERIFY_ALGO::EDDSA: { - using MainReplicaSigner = - concord::crypto::openssl::EdDSASigner; + using MainReplicaSigner = concord::crypto::openssl::EdDSASigner; const auto signingKeyObject = - concord::util::crypto::openssl::deserializeKey(signingKey, - fmt); + concord::crypto::openssl::deserializeKey(signingKey, fmt); return std::unique_ptr(new MainReplicaSigner(signingKeyObject.getBytes())); } default: @@ -63,11 +61,9 @@ class Factory { new concord::crypto::cryptopp::RSAVerifier(verificationKey, fmt)); } case SIGN_VERIFY_ALGO::EDDSA: { - using MainReplicaVerifier = - concord::crypto::openssl::EdDSAVerifier; + using MainReplicaVerifier = concord::crypto::openssl::EdDSAVerifier; const auto verifyingKeyObject = - concord::util::crypto::openssl::deserializeKey( - verificationKey, fmt); + concord::crypto::openssl::deserializeKey(verificationKey, fmt); return std::unique_ptr(new MainReplicaVerifier(verifyingKeyObject.getBytes())); } default: diff --git a/util/include/crypto/openssl/EdDSA.hpp b/util/include/crypto/openssl/EdDSA.hpp index 6514501ce1..1ee2b248f2 100644 --- a/util/include/crypto/openssl/EdDSA.hpp +++ b/util/include/crypto/openssl/EdDSA.hpp @@ -12,11 +12,11 @@ // #pragma once -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "SerializableByteArray.hpp" #include "openssl_crypto.hpp" -namespace concord::util::crypto::openssl { +namespace concord::crypto::openssl { static constexpr const size_t EdDSAPrivateKeyByteSize = 32UL; static constexpr const size_t EdDSAPublicKeyByteSize = 32UL; @@ -86,4 +86,4 @@ static ByteArrayKeyClass deserializeKey( } return fromHexString(key); } -} // namespace concord::util::crypto::openssl +} // namespace concord::crypto::openssl diff --git a/util/include/crypto/openssl/EdDSASigner.hpp b/util/include/crypto/openssl/EdDSASigner.hpp index cfcd7dc60d..ab33487c58 100644 --- a/util/include/crypto/openssl/EdDSASigner.hpp +++ b/util/include/crypto/openssl/EdDSASigner.hpp @@ -15,7 +15,7 @@ #include "EdDSA.hpp" #include "openssl_crypto.hpp" #include "crypto/signer.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" namespace concord::crypto::openssl { @@ -33,40 +33,33 @@ class EdDSASigner : public ISigner { * * @param privateKey */ - explicit EdDSASigner(const PrivateKeyType &privateKey) : privateKey_(privateKey) { - pkey_.reset(EVP_PKEY_new_raw_private_key( - NID_ED25519, nullptr, privateKey_.getBytes().data(), privateKey_.getBytes().size())); - ConcordAssertNE(pkey_, nullptr); - } + explicit EdDSASigner(const PrivateKeyType &privateKey) : privateKey_(privateKey) {} - std::string sign(const uint8_t *msg, size_t len) const { - std::string signature(concord::util::crypto::openssl::EdDSASignatureByteSize, 0); - size_t sigLen_ = concord::util::crypto::openssl::EdDSASignatureByteSize; - sign(msg, len, reinterpret_cast(signature.data()), sigLen_); - ConcordAssertEQ(sigLen_, concord::util::crypto::openssl::EdDSASignatureByteSize); - return signature; - } + size_t signBuffer(const concord::Byte *msg, size_t len, concord::Byte *signature) override { + using concord::util::openssl_utils::UniquePKEY; + UniquePKEY pkey(EVP_PKEY_new_raw_private_key( + NID_ED25519, nullptr, privateKey_.getBytes().data(), privateKey_.getBytes().size())); + ConcordAssertNE(pkey, nullptr); - void sign(const uint8_t *msg, size_t len, uint8_t *signature, size_t &signatureLength) const { + size_t signatureLength = concord::crypto::openssl::EdDSASignatureByteSize; using concord::util::openssl_utils::OPENSSL_SUCCESS; concord::util::openssl_utils::UniqueOpenSSLContext ctx{EVP_MD_CTX_new()}; - ConcordAssertEQ(EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, pkey_.get()), OPENSSL_SUCCESS); - ConcordAssertEQ(EVP_DigestSign(ctx.get(), signature, &signatureLength, msg, len), OPENSSL_SUCCESS); + ConcordAssertEQ(EVP_DigestSignInit(ctx.get(), nullptr, nullptr, nullptr, pkey.get()), OPENSSL_SUCCESS); + ConcordAssertEQ(EVP_DigestSign(ctx.get(), + reinterpret_cast(signature), + &signatureLength, + reinterpret_cast(msg), + len), + OPENSSL_SUCCESS); + return signatureLength; } - std::string sign(const std::string &message) override { - return sign(reinterpret_cast(message.data()), message.size()); - } - - uint32_t signatureLength() const override { return concord::util::crypto::openssl::EdDSASignatureByteSize; } + size_t signatureLength() const override { return concord::crypto::openssl::EdDSASignatureByteSize; } std::string getPrivKey() const override { return privateKey_.toString(); } virtual ~EdDSASigner() = default; - private: - concord::util::openssl_utils::UniquePKEY pkey_; - protected: const PrivateKeyType privateKey_; }; diff --git a/util/include/crypto/openssl/EdDSAVerifier.hpp b/util/include/crypto/openssl/EdDSAVerifier.hpp index 113c71d533..4f6fa99919 100644 --- a/util/include/crypto/openssl/EdDSAVerifier.hpp +++ b/util/include/crypto/openssl/EdDSAVerifier.hpp @@ -36,18 +36,10 @@ class EdDSAVerifier : public IVerifier { */ explicit EdDSAVerifier(const PublicKeyType &publicKey) : publicKey_(publicKey) {} - bool verify(const std::string &message, const std::string &signature) const override { - return verify(message.data(), message.size(), signature.data(), signature.size()); - } - - bool verify(const char *msg, std::size_t msgLen, const char *sig, std::size_t sigLen) const { - return verify(reinterpret_cast(msg), msgLen, reinterpret_cast(sig), sigLen); - } - - bool verify(const uint8_t *msg, size_t msgLen, const uint8_t *sig, size_t sigLen) const { + bool verifyBuffer(const Byte *msg, size_t msgLen, const Byte *sig, size_t sigLen) const override { using concord::util::openssl_utils::UniquePKEY; using concord::util::openssl_utils::OPENSSL_SUCCESS; - ConcordAssertEQ(sigLen, concord::util::crypto::openssl::EdDSASignatureByteSize); + ConcordAssertEQ(sigLen, concord::crypto::openssl::EdDSASignatureByteSize); UniquePKEY pkey{ EVP_PKEY_new_raw_public_key(NID_ED25519, nullptr, publicKey_.getBytes().data(), publicKey_.getBytes().size())}; concord::util::openssl_utils::UniqueOpenSSLContext ctx{EVP_MD_CTX_new()}; @@ -55,7 +47,7 @@ class EdDSAVerifier : public IVerifier { return (OPENSSL_SUCCESS == EVP_DigestVerify(ctx.get(), sig, sigLen, msg, msgLen)); } - uint32_t signatureLength() const override { return concord::util::crypto::openssl::EdDSASignatureByteSize; } + uint32_t signatureLength() const override { return concord::crypto::openssl::EdDSASignatureByteSize; } std::string getPubKey() const override { return publicKey_.toString(); } diff --git a/util/include/crypto/signer.hpp b/util/include/crypto/signer.hpp index 49646408c8..98a93949f8 100644 --- a/util/include/crypto/signer.hpp +++ b/util/include/crypto/signer.hpp @@ -12,15 +12,27 @@ // file. #pragma once +#include "crypto.hpp" +#include "types.hpp" #include namespace concord::crypto { // Interface for signer. +// Signers expect the memory for the signature to be allocated by the caller +// to prevent redundant memory allocations class ISigner { public: - virtual std::string sign(const std::string& data) = 0; - virtual uint32_t signatureLength() const = 0; + // This function's name need to be different from ISigner::sign, otherwise inheriting + // classes will hide ISigner::sign + virtual size_t signBuffer(const Byte* dataIn, size_t dataLen, Byte* sigOutBuffer) = 0; + template + size_t sign(const Container& dataIn, Byte* sigOutBuffer) { + static_assert(sizeof(typename Container::value_type) == sizeof(Byte), + "Attempting to sign a container whose elements are not byte-sized"); + return signBuffer(reinterpret_cast(dataIn.data()), dataIn.size(), sigOutBuffer); + } + virtual size_t signatureLength() const = 0; virtual ~ISigner() = default; virtual std::string getPrivKey() const = 0; }; diff --git a/util/include/crypto/verifier.hpp b/util/include/crypto/verifier.hpp index c4d9589d69..525130e97f 100644 --- a/util/include/crypto/verifier.hpp +++ b/util/include/crypto/verifier.hpp @@ -19,7 +19,20 @@ namespace concord::crypto { // Interface for verifier. class IVerifier { public: - virtual bool verify(const std::string& data, const std::string& sig) const = 0; + virtual bool verifyBuffer(const Byte* data, + size_t dataByteSize, + const Byte* signature, + size_t signatureByteSize) const = 0; + template + bool verify(const DataContainer& data, const SignatureContainer& signature) const { + static_assert(sizeof(typename DataContainer::value_type) == sizeof(Byte), "data elements are not byte-sized"); + static_assert(sizeof(typename SignatureContainer::value_type) == sizeof(Byte), + "signature elements are not byte-sized"); + return verifyBuffer(reinterpret_cast(data.data()), + data.size(), + reinterpret_cast(signature.data()), + signature.size()); + } virtual uint32_t signatureLength() const = 0; virtual ~IVerifier() = default; virtual std::string getPubKey() const = 0; diff --git a/util/include/cryptopp/digest_creator.hpp b/util/include/cryptopp/digest_creator.hpp index f90b80c5cc..b9106b9143 100644 --- a/util/include/cryptopp/digest_creator.hpp +++ b/util/include/cryptopp/digest_creator.hpp @@ -23,7 +23,7 @@ #define DigestType CryptoPP::SHA512 #endif -namespace concord::util::crypto::cryptopp { +namespace concord::crypto::cryptopp { // Implements digest creator using Crypto++ library. class CryptoppDigestCreator : public concord::util::digest::DigestCreator { @@ -46,4 +46,4 @@ class CryptoppDigestCreator : public concord::util::digest::DigestCreator { private: void* internalState_; }; -} // namespace concord::util::crypto::cryptopp +} // namespace concord::crypto::cryptopp diff --git a/util/include/digest.hpp b/util/include/digest.hpp index a3db5e73a2..4089d33ee0 100644 --- a/util/include/digest.hpp +++ b/util/include/digest.hpp @@ -23,11 +23,11 @@ namespace concord::util::digest { #if defined USE_CRYPTOPP_SHA_256 -using Digest = DigestHolder; -using DigestGenerator = concord::util::crypto::cryptopp::CryptoppDigestCreator; +using Digest = DigestHolder; +using DigestGenerator = concord::crypto::cryptopp::CryptoppDigestCreator; #elif defined USE_OPENSSL_SHA_256 -using Digest = DigestHolder >; -using DigestGenerator = concord::util::crypto::openssl::OpenSSLDigestCreator; +using Digest = DigestHolder >; +using DigestGenerator = concord::crypto::openssl::OpenSSLDigestCreator; #endif static_assert(DIGEST_SIZE >= sizeof(uint64_t), "Digest size should be >= sizeof(uint64_t)"); diff --git a/util/include/openssl/digest_creator.hpp b/util/include/openssl/digest_creator.hpp index 0f1b98a6ac..3ac65b3f4d 100644 --- a/util/include/openssl/digest_creator.hpp +++ b/util/include/openssl/digest_creator.hpp @@ -14,7 +14,7 @@ #include "sha_hash.hpp" #include "digestCreator.hpp" -namespace concord::util::crypto::openssl { +namespace concord::crypto::openssl { template || @@ -68,4 +68,4 @@ class OpenSSLDigestCreator : public concord::util::digest::DigestCreator { bool initialized_{false}; SHACTX hash_ctx_; }; -} // namespace concord::util::crypto::openssl +} // namespace concord::crypto::openssl diff --git a/util/include/crypto/crypto.h b/util/include/types.hpp similarity index 59% rename from util/include/crypto/crypto.h rename to util/include/types.hpp index 5cbf9d4f6f..e8e49a38be 100644 --- a/util/include/crypto/crypto.h +++ b/util/include/types.hpp @@ -1,17 +1,18 @@ // Concord // -// Copyright (c) 2018-2022 VMware, Inc. All Rights Reserved. +// Copyright (c) 2022 VMware, Inc. All Rights Reserved. // // This product is licensed to you under the Apache 2.0 license (the "License"). // You may not use this product except in compliance with the Apache 2.0 License. // // This product may include a number of subcomponents with separate copyright // notices and license terms. Your use of these subcomponents is subject to the -// terms and conditions of the subcomponent's license, as noted in the +// terms and conditions of the sub-component's license, as noted in the // LICENSE file. -// #pragma once -namespace concord::crypto { -enum SignatureAlgorithm : uint32_t { Uninitialized = 0, BLS = 1, EdDSA = 2, RSA = 3 }; -} +#include + +namespace concord { +using Byte = uint8_t; +} \ No newline at end of file diff --git a/util/src/crypto.cpp b/util/src/crypto.cpp index cc9884e4d0..b71c7d16de 100644 --- a/util/src/crypto.cpp +++ b/util/src/crypto.cpp @@ -11,60 +11,54 @@ // terms and conditions of the sub-component's license, as noted in the LICENSE // file. -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "Logger.hpp" #include "assertUtils.hpp" #include "hex_tools.h" #include "string.hpp" +#include "types.hpp" #include "crypto/openssl/EdDSA.hpp" #include "util/filesystem.hpp" - -#include #include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -#include -#include -#include -#include -#include -#pragma GCC diagnostic pop - namespace concord::crypto { using std::array; using std::pair; using std::string; +using concord::Byte; using concord::crypto::KeyFormat; using concord::crypto::CurveType; using concord::util::openssl_utils::UniquePKEY; using concord::util::openssl_utils::UniqueOpenSSLPKEYContext; using concord::util::openssl_utils::UniqueOpenSSLBIO; using concord::util::openssl_utils::OPENSSL_SUCCESS; -using concord::util::crypto::openssl::EdDSASignatureByteSize; -using namespace CryptoPP; +using concord::crypto::openssl::EdDSASignatureByteSize; +using concord::crypto::openssl::EdDSAPrivateKeyByteSize; +using concord::crypto::openssl::EdDSAPublicKeyByteSize; pair generateEdDSAKeyPair(const KeyFormat fmt) { UniquePKEY edPkey; UniqueOpenSSLPKEYContext edPkeyCtx(EVP_PKEY_CTX_new_id(NID_ED25519, nullptr)); ConcordAssertNE(edPkeyCtx, nullptr); - ConcordAssertEQ(OPENSSL_SUCCESS, EVP_PKEY_keygen_init(edPkeyCtx.get())); - ConcordAssertEQ( - OPENSSL_SUCCESS, - EVP_PKEY_keygen(edPkeyCtx.get(), reinterpret_cast(&edPkey))); // Generate EdDSA key 'edPkey'. + EVP_PKEY* keygenRet = nullptr; + ConcordAssertEQ(OPENSSL_SUCCESS, EVP_PKEY_keygen(edPkeyCtx.get(), &keygenRet)); + edPkey.reset(keygenRet); - array privKey; - array pubKey; - size_t privlen{EdDSASignatureByteSize}; - size_t publen{EdDSASignatureByteSize}; + array privKey; + array pubKey; + size_t keyLen{EdDSAPrivateKeyByteSize}; - ConcordAssertEQ(OPENSSL_SUCCESS, EVP_PKEY_get_raw_private_key(edPkey.get(), privKey.data(), &privlen)); - ConcordAssertEQ(OPENSSL_SUCCESS, EVP_PKEY_get_raw_public_key(edPkey.get(), pubKey.data(), &publen)); + ConcordAssertEQ(OPENSSL_SUCCESS, EVP_PKEY_get_raw_private_key(edPkey.get(), privKey.data(), &keyLen)); + ConcordAssertEQ(keyLen, EdDSAPrivateKeyByteSize); + keyLen = EdDSAPublicKeyByteSize; + ConcordAssertEQ(OPENSSL_SUCCESS, EVP_PKEY_get_raw_public_key(edPkey.get(), pubKey.data(), &keyLen)); + ConcordAssertEQ(keyLen, EdDSAPublicKeyByteSize); - pair keyPair(boost::algorithm::hex(string(reinterpret_cast(privKey.data()), privlen)), - boost::algorithm::hex(string(reinterpret_cast(pubKey.data()), publen))); + pair keyPair( + boost::algorithm::hex(string(reinterpret_cast(privKey.data()), EdDSAPrivateKeyByteSize)), + boost::algorithm::hex(string(reinterpret_cast(pubKey.data()), EdDSAPublicKeyByteSize))); if (KeyFormat::PemFormat == fmt) { keyPair = EdDSAHexToPem(keyPair); @@ -115,84 +109,6 @@ pair EdDSAHexToPem(const std::pair& he return make_pair(privPemString, pubPemString); } -pair RsaHexToPem(const pair& key_pair) { - pair out; - if (!key_pair.first.empty()) { - StringSource priv_str(key_pair.first, true, new HexDecoder()); - CryptoPP::RSA::PrivateKey priv; - priv.Load(priv_str); - StringSink priv_string_sink(out.first); - PEM_Save(priv_string_sink, priv); - priv_string_sink.MessageEnd(); - } - - if (!key_pair.second.empty()) { - StringSource pub_str(key_pair.second, true, new HexDecoder()); - CryptoPP::RSA::PublicKey pub; - pub.Load(pub_str); - StringSink pub_string_sink(out.second); - PEM_Save(pub_string_sink, pub); - pub_string_sink.MessageEnd(); - } - return out; -} - -pair ECDSAHexToPem(const pair& key_pair) { - pair out; - if (!key_pair.first.empty()) { - StringSource priv_str(key_pair.first, true, new HexDecoder()); - ECDSA::PrivateKey priv; - priv.Load(priv_str); - StringSink priv_string_sink(out.first); - PEM_Save(priv_string_sink, priv); - } - if (!key_pair.second.empty()) { - StringSource pub_str(key_pair.second, true, new HexDecoder()); - ECDSA::PublicKey pub; - pub.Load(pub_str); - StringSink pub_string_sink(out.second); - PEM_Save(pub_string_sink, pub); - } - return out; -} - -pair generateRsaKeyPair(const uint32_t sig_length, const KeyFormat fmt) { - AutoSeededRandomPool rng; - pair keyPair; - - RSAES>::Decryptor priv(rng, sig_length); - RSAES>::Encryptor pub(priv); - HexEncoder privEncoder(new StringSink(keyPair.first)); - priv.AccessMaterial().Save(privEncoder); - privEncoder.MessageEnd(); - - HexEncoder pubEncoder(new StringSink(keyPair.second)); - pub.AccessMaterial().Save(pubEncoder); - pubEncoder.MessageEnd(); - if (fmt == KeyFormat::PemFormat) { - keyPair = RsaHexToPem(keyPair); - } - return keyPair; -} - -pair generateECDSAKeyPair(const KeyFormat fmt, CurveType curve_types) { - AutoSeededRandomPool prng; - ECDSA::PrivateKey privateKey; - ECDSA::PublicKey publicKey; - - privateKey.Initialize(prng, curve_types == CurveType::secp256k1 ? ASN1::secp256k1() : ASN1::secp384r1()); - privateKey.MakePublicKey(publicKey); - pair keyPair; - HexEncoder privEncoder(new StringSink(keyPair.first)); - privateKey.Save(privEncoder); - HexEncoder pubEncoder(new StringSink(keyPair.second)); - publicKey.Save(pubEncoder); - if (fmt == KeyFormat::PemFormat) { - keyPair = ECDSAHexToPem(keyPair); - } - return keyPair; -} - KeyFormat getFormat(const std::string& key) { return (key.find("BEGIN") != std::string::npos) ? KeyFormat::PemFormat : KeyFormat::HexaDecimalStrippedFormat; } diff --git a/util/src/crypto/cryptopp/keygen.cpp b/util/src/crypto/cryptopp/keygen.cpp new file mode 100644 index 0000000000..4209eb7576 --- /dev/null +++ b/util/src/crypto/cryptopp/keygen.cpp @@ -0,0 +1,118 @@ +// Concord +// +// Copyright (c) 2022 VMware, Inc. All Rights Reserved. +// +// This product is licensed to you under the Apache 2.0 license (the "License"). +// You may not use this product except in compliance with the Apache 2.0 +// License. +// +// This product may include a number of subcomponents with separate copyright +// notices and license terms. Your use of these subcomponents is subject to the +// terms and conditions of the sub-component's license, as noted in the LICENSE +// file. +#include "crypto/cryptopp/keygen.hpp" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#include +#include +#include +#include +#include +#pragma GCC diagnostic pop + +namespace concord::crypto { +using CryptoPP::StringSource; +using CryptoPP::StringSink; +using CryptoPP::HexDecoder; +using CryptoPP::AutoSeededRandomPool; +using CryptoPP::HexEncoder; +using CryptoPP::ECP; +using CryptoPP::ECDSA; +using CryptoPP::SHA256; +using CryptoPP::OAEP; +using CryptoPP::RSAES; +using std::pair; +using std::string; + +pair RsaHexToPem(const pair& key_pair) { + pair out; + if (!key_pair.first.empty()) { + StringSource priv_str(key_pair.first, true, new HexDecoder()); + CryptoPP::RSA::PrivateKey priv; + priv.Load(priv_str); + StringSink priv_string_sink(out.first); + PEM_Save(priv_string_sink, priv); + priv_string_sink.MessageEnd(); + } + + if (!key_pair.second.empty()) { + StringSource pub_str(key_pair.second, true, new HexDecoder()); + CryptoPP::RSA::PublicKey pub; + pub.Load(pub_str); + StringSink pub_string_sink(out.second); + PEM_Save(pub_string_sink, pub); + pub_string_sink.MessageEnd(); + } + return out; +} + +pair ECDSAHexToPem(const pair& key_pair) { + pair out; + if (!key_pair.first.empty()) { + StringSource priv_str(key_pair.first, true, new HexDecoder()); + ECDSA::PrivateKey priv; + priv.Load(priv_str); + StringSink priv_string_sink(out.first); + PEM_Save(priv_string_sink, priv); + } + if (!key_pair.second.empty()) { + StringSource pub_str(key_pair.second, true, new HexDecoder()); + ECDSA::PublicKey pub; + pub.Load(pub_str); + StringSink pub_string_sink(out.second); + PEM_Save(pub_string_sink, pub); + } + return out; +} + +pair generateRsaKeyPair(const KeyFormat fmt) { + AutoSeededRandomPool rng; + pair keyPair; + + constexpr const size_t privateKeyLength = 2048; + RSAES>::Decryptor priv(rng, privateKeyLength); + RSAES>::Encryptor pub(priv); + HexEncoder privEncoder(new StringSink(keyPair.first)); + priv.AccessMaterial().Save(privEncoder); + privEncoder.MessageEnd(); + + HexEncoder pubEncoder(new StringSink(keyPair.second)); + pub.AccessMaterial().Save(pubEncoder); + pubEncoder.MessageEnd(); + if (fmt == KeyFormat::PemFormat) { + keyPair = RsaHexToPem(keyPair); + } + return keyPair; +} + +pair generateECDSAKeyPair(const KeyFormat fmt, CurveType curve_types) { + AutoSeededRandomPool prng; + ECDSA::PrivateKey privateKey; + ECDSA::PublicKey publicKey; + + privateKey.Initialize( + prng, curve_types == CurveType::secp256k1 ? CryptoPP::ASN1::secp256k1() : CryptoPP::ASN1::secp384r1()); + privateKey.MakePublicKey(publicKey); + pair keyPair; + HexEncoder privEncoder(new StringSink(keyPair.first)); + privateKey.Save(privEncoder); + HexEncoder pubEncoder(new StringSink(keyPair.second)); + publicKey.Save(pubEncoder); + if (fmt == KeyFormat::PemFormat) { + keyPair = ECDSAHexToPem(keyPair); + } + return keyPair; +} + +} // namespace concord::crypto diff --git a/util/src/crypto/cryptopp/signers.cpp b/util/src/crypto/cryptopp/signers.cpp index 9a444003c1..32d0e55733 100644 --- a/util/src/crypto/cryptopp/signers.cpp +++ b/util/src/crypto/cryptopp/signers.cpp @@ -26,6 +26,7 @@ namespace concord::crypto::cryptopp { using namespace CryptoPP; using concord::crypto::KeyFormat; +using concord::Byte; class ECDSASigner::Impl { std::unique_ptr::Signer> signer_; @@ -36,18 +37,21 @@ class ECDSASigner::Impl { signer_ = std::make_unique::Signer>(std::move(privateKey)); } - std::string sign(const std::string& data_to_sign) { - size_t siglen = signer_->MaxSignatureLength(); - std::string signature(siglen, 0x00); - siglen = signer_->SignMessage( - prng_, (const CryptoPP::byte*)&data_to_sign[0], data_to_sign.size(), (CryptoPP::byte*)&signature[0]); - signature.resize(siglen); - return signature; + size_t sign(const Byte* dataIn, size_t dataLen, Byte* sigOutBuffer) { + return signer_->SignMessage(prng_, reinterpret_cast(dataIn), dataLen, (CryptoPP::byte*)sigOutBuffer); } - uint32_t signatureLength() const { return signer_->SignatureLength(); } + + size_t signatureLength() const { return signer_->SignatureLength(); } }; -std::string ECDSASigner::sign(const std::string& data) { return impl_->sign(data); } +std::string ECDSASigner::sign(const std::string& data) { + size_t siglen = impl_->signatureLength(); + std::string signature(siglen, 0x00); + siglen = signBuffer( + reinterpret_cast(data.data()), data.size(), reinterpret_cast(signature.data())); + signature.resize(siglen); + return signature; +} ECDSASigner::ECDSASigner(const std::string& str_priv_key, KeyFormat fmt) : key_str_{str_priv_key} { ECDSA::PrivateKey privateKey; @@ -61,7 +65,10 @@ ECDSASigner::ECDSASigner(const std::string& str_priv_key, KeyFormat fmt) : key_s impl_.reset(new Impl(privateKey)); } -uint32_t ECDSASigner::signatureLength() const { return impl_->signatureLength(); } +size_t ECDSASigner::signatureLength() const { return impl_->signatureLength(); } +size_t ECDSASigner::signBuffer(const Byte* dataIn, size_t dataLen, Byte* sigOutBuffer) { + return impl_->sign(dataIn, dataLen, sigOutBuffer); +} ECDSASigner::~ECDSASigner() = default; @@ -70,14 +77,11 @@ class RSASigner::Impl { Impl(CryptoPP::RSA::PrivateKey& private_key) { signer_ = std::make_unique::Signer>(std::move(private_key)); } - std::string sign(const std::string& data_to_sign) { - size_t siglen = signer_->MaxSignatureLength(); - std::string signature(siglen, 0x00); - siglen = signer_->SignMessage( - prng_, (const CryptoPP::byte*)&data_to_sign[0], data_to_sign.size(), (CryptoPP::byte*)&signature[0]); - signature.resize(siglen); - return signature; + + uint32_t sign(const Byte* const dataIn, uint32_t dataLen, Byte* sigOutBuffer) { + return signer_->SignMessage(prng_, (const CryptoPP::byte*)dataIn, dataLen, (CryptoPP::byte*)sigOutBuffer); } + uint32_t signatureLength() const { return signer_->SignatureLength(); } private: @@ -97,9 +101,11 @@ RSASigner::RSASigner(const std::string& str_priv_key, KeyFormat fmt) : key_str_{ impl_.reset(new RSASigner::Impl(private_key)); } -std::string RSASigner::sign(const std::string& data) { return impl_->sign(data); } +size_t RSASigner::signBuffer(const Byte* const dataIn, size_t dataLen, Byte* sigOutBuffer) { + return impl_->sign(dataIn, dataLen, sigOutBuffer); +} -uint32_t RSASigner::signatureLength() const { return impl_->signatureLength(); } +size_t RSASigner::signatureLength() const { return impl_->signatureLength(); } RSASigner::~RSASigner() = default; diff --git a/util/src/crypto/cryptopp/verifiers.cpp b/util/src/crypto/cryptopp/verifiers.cpp index 069d14fce8..3716c54d07 100644 --- a/util/src/crypto/cryptopp/verifiers.cpp +++ b/util/src/crypto/cryptopp/verifiers.cpp @@ -12,6 +12,7 @@ // file. #include "crypto/cryptopp/verifiers.hpp" +#include "types.hpp" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" @@ -26,28 +27,28 @@ namespace concord::crypto::cryptopp { using namespace CryptoPP; using concord::crypto::KeyFormat; +using concord::Byte; class ECDSAVerifier::Impl { std::unique_ptr::Verifier> verifier_; public: - Impl(ECDSA::PublicKey& publicKey) { + Impl(ECDSA::PublicKey &publicKey) { verifier_ = std::make_unique::Verifier>(std::move(publicKey)); } - bool verify(const std::string& data_to_verify, const std::string& signature) const { - return verifier_->VerifyMessage((const CryptoPP::byte*)&data_to_verify[0], - data_to_verify.size(), - (const CryptoPP::byte*)&signature[0], - signature.size()); + bool verify(const Byte *msg, size_t msgLen, const Byte *sig, size_t sigLen) const { + return verifier_->VerifyMessage((const CryptoPP::byte *)&msg[0], msgLen, (const CryptoPP::byte *)sig, sigLen); } uint32_t signatureLength() const { return verifier_->SignatureLength(); } }; -bool ECDSAVerifier::verify(const std::string& data, const std::string& sig) const { return impl_->verify(data, sig); } +bool ECDSAVerifier::verifyBuffer(const Byte *msg, size_t msgLen, const Byte *sig, size_t sigLen) const { + return impl_->verify(msg, msgLen, sig, sigLen); +} -ECDSAVerifier::ECDSAVerifier(const std::string& str_pub_key, KeyFormat fmt) : key_str_{str_pub_key} { +ECDSAVerifier::ECDSAVerifier(const std::string &str_pub_key, KeyFormat fmt) : key_str_{str_pub_key} { ECDSA::PublicKey publicKey; if (fmt == KeyFormat::PemFormat) { StringSource s(str_pub_key, true); @@ -65,14 +66,11 @@ ECDSAVerifier::~ECDSAVerifier() = default; class RSAVerifier::Impl { public: - Impl(CryptoPP::RSA::PublicKey& public_key) { + Impl(CryptoPP::RSA::PublicKey &public_key) { verifier_ = std::make_unique::Verifier>(std::move(public_key)); } - bool verify(const std::string& data_to_verify, const std::string& signature) const { - return verifier_->VerifyMessage((const CryptoPP::byte*)&data_to_verify[0], - data_to_verify.size(), - (const CryptoPP::byte*)&signature[0], - signature.size()); + bool verify(const Byte *msg, size_t msgLen, const Byte *sig, size_t sigLen) const { + return verifier_->VerifyMessage((const CryptoPP::byte *)msg, msgLen, (const CryptoPP::byte *)sig, sigLen); } uint32_t signatureLength() const { return verifier_->SignatureLength(); } @@ -81,7 +79,7 @@ class RSAVerifier::Impl { std::unique_ptr::Verifier> verifier_; }; -RSAVerifier::RSAVerifier(const std::string& str_pub_key, KeyFormat fmt) : key_str_{str_pub_key} { +RSAVerifier::RSAVerifier(const std::string &str_pub_key, KeyFormat fmt) : key_str_{str_pub_key} { CryptoPP::RSA::PublicKey public_key; if (fmt == KeyFormat::PemFormat) { StringSource s(str_pub_key, true); @@ -93,7 +91,9 @@ RSAVerifier::RSAVerifier(const std::string& str_pub_key, KeyFormat fmt) : key_st impl_.reset(new RSAVerifier::Impl(public_key)); } -bool RSAVerifier::verify(const std::string& data, const std::string& sig) const { return impl_->verify(data, sig); } +bool RSAVerifier::verifyBuffer(const Byte *msg, size_t msgLen, const Byte *sig, size_t sigLen) const { + return impl_->verify(msg, msgLen, sig, sigLen); +} uint32_t RSAVerifier::signatureLength() const { return impl_->signatureLength(); } diff --git a/util/src/cryptopp/digest_creator.cpp b/util/src/cryptopp/digest_creator.cpp index c1d27efa55..4855fb1809 100644 --- a/util/src/cryptopp/digest_creator.cpp +++ b/util/src/cryptopp/digest_creator.cpp @@ -24,7 +24,7 @@ #include "cryptopp/digest_creator.hpp" #include "digest.hpp" -namespace concord::util::crypto::cryptopp { +namespace concord::crypto::cryptopp { using CryptoPP::SecByteBlock; using concord::util::digest::DigestGenerator; @@ -88,4 +88,4 @@ CryptoppDigestCreator::~CryptoppDigestCreator() { internalState_ = nullptr; } } -} // namespace concord::util::crypto::cryptopp +} // namespace concord::crypto::cryptopp diff --git a/util/test/crypto_utils_test.cpp b/util/test/crypto_utils_test.cpp index bcd088af67..2c3f6120a4 100644 --- a/util/test/crypto_utils_test.cpp +++ b/util/test/crypto_utils_test.cpp @@ -13,7 +13,7 @@ // #include "gtest/gtest.h" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "Logger.hpp" namespace { @@ -24,14 +24,14 @@ using concord::crypto::generateECDSAKeyPair; using concord::crypto::ECDSAHexToPem; TEST(crypto_utils, generate_rsa_keys_hex_format) { - ASSERT_NO_THROW(generateRsaKeyPair(RSA_SIGNATURE_LENGTH)); - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + ASSERT_NO_THROW(generateRsaKeyPair()); + auto keys = generateRsaKeyPair(); LOG_INFO(GL, keys.first << " | " << keys.second); } TEST(crypto_utils, generate_rsa_keys_pem_format) { - ASSERT_NO_THROW(generateRsaKeyPair(RSA_SIGNATURE_LENGTH, KeyFormat::PemFormat)); - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH, KeyFormat::PemFormat); + ASSERT_NO_THROW(generateRsaKeyPair(KeyFormat::PemFormat)); + auto keys = generateRsaKeyPair(KeyFormat::PemFormat); LOG_INFO(GL, keys.first << " | " << keys.second); } @@ -48,7 +48,7 @@ TEST(crypto_utils, generate_ECDSA_keys_hex_format) { } TEST(crypto_utils, test_rsa_keys_hex) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + auto keys = generateRsaKeyPair(); RSASigner signer(keys.first, KeyFormat::HexaDecimalStrippedFormat); RSAVerifier verifier(keys.second, KeyFormat::HexaDecimalStrippedFormat); std::string data = "Hello world"; @@ -57,7 +57,7 @@ TEST(crypto_utils, test_rsa_keys_hex) { } TEST(crypto_utils, test_rsa_keys_pem) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH, KeyFormat::PemFormat); + auto keys = generateRsaKeyPair(KeyFormat::PemFormat); RSASigner signer(keys.first, KeyFormat::PemFormat); RSAVerifier verifier(keys.second, KeyFormat::PemFormat); std::string data = "Hello world"; @@ -66,7 +66,7 @@ TEST(crypto_utils, test_rsa_keys_pem) { } TEST(crypto_utils, test_rsa_keys_combined_a) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + auto keys = generateRsaKeyPair(); auto pemKeys = RsaHexToPem(keys); RSASigner signer(keys.first, KeyFormat::HexaDecimalStrippedFormat); RSAVerifier verifier(pemKeys.second, KeyFormat::PemFormat); @@ -76,7 +76,7 @@ TEST(crypto_utils, test_rsa_keys_combined_a) { } TEST(crypto_utils, test_rsa_keys_combined_b) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + auto keys = generateRsaKeyPair(); auto pemKeys = RsaHexToPem(keys); RSASigner signer(pemKeys.first, KeyFormat::PemFormat); RSAVerifier verifier(keys.second, KeyFormat::HexaDecimalStrippedFormat); diff --git a/util/test/cryptopp_digest_creator_test.cpp b/util/test/cryptopp_digest_creator_test.cpp index 4589ca83a2..c2b1b1567d 100644 --- a/util/test/cryptopp_digest_creator_test.cpp +++ b/util/test/cryptopp_digest_creator_test.cpp @@ -16,7 +16,7 @@ #include "hex_tools.h" #include "cryptopp/digest_creator.hpp" -using concord::util::crypto::cryptopp::CryptoppDigestCreator; +using concord::crypto::cryptopp::CryptoppDigestCreator; using DigestGeneratorTest = CryptoppDigestCreator; diff --git a/util/test/cryptopp_digest_holder_test.cpp b/util/test/cryptopp_digest_holder_test.cpp index 78dfaf2d5c..31f6a4c21f 100644 --- a/util/test/cryptopp_digest_holder_test.cpp +++ b/util/test/cryptopp_digest_holder_test.cpp @@ -18,7 +18,7 @@ #include "cryptopp/digest_creator.hpp" using concord::util::digest::DigestHolder; -using concord::util::crypto::cryptopp::CryptoppDigestCreator; +using concord::crypto::cryptopp::CryptoppDigestCreator; using Digest = DigestHolder; diff --git a/util/test/cryptopp_utils_test.cpp b/util/test/cryptopp_utils_test.cpp index 9548e08072..ba4fc07440 100644 --- a/util/test/cryptopp_utils_test.cpp +++ b/util/test/cryptopp_utils_test.cpp @@ -13,9 +13,10 @@ // #include "gtest/gtest.h" -#include "crypto.hpp" +#include "crypto/crypto.hpp" #include "crypto/cryptopp/signers.hpp" #include "crypto/cryptopp/verifiers.hpp" +#include "crypto/cryptopp/keygen.hpp" #include "Logger.hpp" namespace { @@ -27,15 +28,21 @@ using concord::crypto::RsaHexToPem; using concord::crypto::generateECDSAKeyPair; using concord::crypto::ECDSAHexToPem; +std::string getSig(const std::string& data, concord::crypto::ISigner& signer) { + std::string buf(signer.signatureLength() + 1, '\x00'); + signer.sign(data, reinterpret_cast(buf.data())); + return buf; +} + TEST(cryptopp_utils, generate_rsa_keys_hex_format) { - ASSERT_NO_THROW(generateRsaKeyPair(RSA_SIGNATURE_LENGTH)); - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + ASSERT_NO_THROW(generateRsaKeyPair()); + auto keys = generateRsaKeyPair(); LOG_INFO(GL, keys.first << " | " << keys.second); } TEST(cryptopp_utils, generate_rsa_keys_pem_format) { - ASSERT_NO_THROW(generateRsaKeyPair(RSA_SIGNATURE_LENGTH, KeyFormat::PemFormat)); - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH, KeyFormat::PemFormat); + ASSERT_NO_THROW(generateRsaKeyPair(KeyFormat::PemFormat)); + auto keys = generateRsaKeyPair(KeyFormat::PemFormat); LOG_INFO(GL, keys.first << " | " << keys.second); } @@ -52,40 +59,40 @@ TEST(cryptopp_utils, generate_ECDSA_keys_hex_format) { } TEST(cryptopp_utils, test_rsa_keys_hex) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + auto keys = generateRsaKeyPair(); RSASigner signer(keys.first, KeyFormat::HexaDecimalStrippedFormat); RSAVerifier verifier(keys.second, KeyFormat::HexaDecimalStrippedFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } TEST(cryptopp_utils, test_rsa_keys_pem) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH, KeyFormat::PemFormat); + auto keys = generateRsaKeyPair(KeyFormat::PemFormat); RSASigner signer(keys.first, KeyFormat::PemFormat); RSAVerifier verifier(keys.second, KeyFormat::PemFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } TEST(cryptopp_utils, test_rsa_keys_combined_a) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + auto keys = generateRsaKeyPair(); auto pemKeys = RsaHexToPem(keys); RSASigner signer(keys.first, KeyFormat::HexaDecimalStrippedFormat); RSAVerifier verifier(pemKeys.second, KeyFormat::PemFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } TEST(cryptopp_utils, test_rsa_keys_combined_b) { - auto keys = generateRsaKeyPair(RSA_SIGNATURE_LENGTH); + auto keys = generateRsaKeyPair(); auto pemKeys = RsaHexToPem(keys); RSASigner signer(pemKeys.first, KeyFormat::PemFormat); RSAVerifier verifier(keys.second, KeyFormat::HexaDecimalStrippedFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } @@ -94,7 +101,7 @@ TEST(cryptopp_utils, test_ecdsa_keys_hex) { ECDSASigner signer(keys.first, KeyFormat::HexaDecimalStrippedFormat); ECDSAVerifier verifier(keys.second, KeyFormat::HexaDecimalStrippedFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } @@ -103,7 +110,7 @@ TEST(cryptopp_utils, test_ecdsa_keys_pem) { ECDSASigner signer(keys.first, KeyFormat::PemFormat); ECDSAVerifier verifier(keys.second, KeyFormat::PemFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } @@ -113,7 +120,7 @@ TEST(cryptopp_utils, test_ecdsa_keys_pem_combined_a) { ECDSASigner signer(keys.first, KeyFormat::HexaDecimalStrippedFormat); ECDSAVerifier verifier(pemKeys.second, KeyFormat::PemFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } @@ -123,7 +130,7 @@ TEST(cryptopp_utils, test_ecdsa_keys_pem_combined_b) { ECDSASigner signer(pemKeys.first, KeyFormat::PemFormat); ECDSAVerifier verifier(keys.second, KeyFormat::HexaDecimalStrippedFormat); std::string data = "Hello world"; - auto sig = signer.sign(data); + auto sig = getSig(data, signer); ASSERT_TRUE(verifier.verify(data, sig)); } } // namespace diff --git a/util/test/openssl_digest_creator_test.cpp b/util/test/openssl_digest_creator_test.cpp index 459fa58de7..a9a945b5e9 100644 --- a/util/test/openssl_digest_creator_test.cpp +++ b/util/test/openssl_digest_creator_test.cpp @@ -18,7 +18,7 @@ using concord::util::SHA2_256; using concord::util::SHA3_256; -using concord::util::crypto::openssl::OpenSSLDigestCreator; +using concord::crypto::openssl::OpenSSLDigestCreator; using DigestGeneratorTest_SHA2_256 = OpenSSLDigestCreator; using DigestGeneratorTest_SHA3_256 = OpenSSLDigestCreator; diff --git a/util/test/openssl_digest_holder_test.cpp b/util/test/openssl_digest_holder_test.cpp index 1efe4acdb2..f297764c04 100644 --- a/util/test/openssl_digest_holder_test.cpp +++ b/util/test/openssl_digest_holder_test.cpp @@ -20,7 +20,7 @@ using concord::util::SHA2_256; using concord::util::SHA3_256; using concord::util::digest::DigestHolder; -using concord::util::crypto::openssl::OpenSSLDigestCreator; +using concord::crypto::openssl::OpenSSLDigestCreator; using Digest256 = DigestHolder>; using Digest3_256 = DigestHolder>; diff --git a/util/test/openssl_utils_test.cpp b/util/test/openssl_utils_test.cpp index b760bd932a..2e96f2eaea 100644 --- a/util/test/openssl_utils_test.cpp +++ b/util/test/openssl_utils_test.cpp @@ -18,173 +18,71 @@ #include "crypto/openssl/EdDSA.hpp" #include "crypto/openssl/EdDSASigner.hpp" #include "crypto/openssl/EdDSAVerifier.hpp" -#include "crypto.hpp" +#include "crypto/crypto.hpp" namespace { using concord::crypto::KeyFormat; using concord::crypto::generateEdDSAKeyPair; using concord::crypto::EdDSAHexToPem; -using concord::util::crypto::openssl::EdDSAPrivateKey; -using concord::util::crypto::openssl::EdDSAPublicKey; -using concord::util::crypto::openssl::EdDSAPrivateKeyByteSize; -using concord::util::crypto::openssl::deserializeKey; - -using TestTxnSigner = concord::crypto::openssl::EdDSASigner; -using TestTxnVerifier = concord::crypto::openssl::EdDSAVerifier; - -TEST(openssl_utils, check_eddsa_keys_hex_format_length) { - const auto hexKeys = generateEdDSAKeyPair(KeyFormat::HexaDecimalStrippedFormat); - ASSERT_EQ(hexKeys.first.size(), EdDSAPrivateKeyByteSize * 2); - ASSERT_EQ(hexKeys.second.size(), EdDSAPrivateKeyByteSize * 2); +using concord::crypto::openssl::EdDSAPrivateKey; +using concord::crypto::openssl::EdDSAPublicKey; +using concord::crypto::openssl::EdDSAPrivateKeyByteSize; +using concord::crypto::openssl::EdDSAPublicKeyByteSize; +using concord::crypto::openssl::deserializeKey; + +class EdDSATests : public ::testing::Test { + public: + using Signer = concord::crypto::openssl::EdDSASigner; + using Verifier = concord::crypto::openssl::EdDSAVerifier; + + void SetUp() override { initSignerVerifier(KeyFormat::HexaDecimalStrippedFormat); } + + void initSignerVerifier(KeyFormat format) { + auto keys = generateEdDSAKeyPair(format); + + const auto signingKey = deserializeKey(keys.first, format); + const auto verificationKey = deserializeKey(keys.second, format); + + signer_ = std::make_unique(signingKey.getBytes()); + verifier_ = std::make_unique(verificationKey.getBytes()); + } + + std::vector sign(const std::string& data) { + const auto expectedSigLength = signer_->signatureLength(); + std::vector signature(signer_->signatureLength()); + auto sigLength = signer_->sign(data, signature.data()); + EXPECT_EQ(sigLength, expectedSigLength); + return signature; + } + + bool verify(const std::string& data, const std::vector& signature) { + return verifier_->verify(data, signature); + } + + void signVerify(const std::string& data) { ASSERT_TRUE(verify(data, sign(data))); } + + std::unique_ptr signer_; + std::unique_ptr verifier_; + static constexpr const char* Message = "Hello VMworld"; +}; + +TEST_F(EdDSATests, TestHexFormatKeyLengths) { + const auto keyPair = generateEdDSAKeyPair(KeyFormat::HexaDecimalStrippedFormat); + ASSERT_TRUE(concord::crypto::isValidKey("", keyPair.first, EdDSAPrivateKeyByteSize * 2)); + ASSERT_TRUE(concord::crypto::isValidKey("", keyPair.second, EdDSAPublicKeyByteSize * 2)); } -TEST(openssl_utils, generate_eddsa_keys_hex_format) { - ASSERT_NO_THROW(generateEdDSAKeyPair()); - const auto hexKeys1 = generateEdDSAKeyPair(); - LOG_INFO(GL, hexKeys1.first << " | " << hexKeys1.second); - - ASSERT_NO_THROW(generateEdDSAKeyPair(KeyFormat::HexaDecimalStrippedFormat)); - const auto hexKeys2 = generateEdDSAKeyPair(KeyFormat::HexaDecimalStrippedFormat); - LOG_INFO(GL, hexKeys2.first << " | " << hexKeys2.second); -} - -TEST(openssl_utils, generate_eddsa_keys_pem_format) { - ASSERT_NO_THROW(generateEdDSAKeyPair()); - ASSERT_NO_THROW(generateEdDSAKeyPair(KeyFormat::PemFormat)); - const auto pemKeys = generateEdDSAKeyPair(KeyFormat::PemFormat); - LOG_INFO(GL, pemKeys.first << " | " << pemKeys.second); -} - -TEST(openssl_utils, test_eddsa_keys_hex_ok) { - auto hexKeys = generateEdDSAKeyPair(); - - const auto signingKey = deserializeKey(hexKeys.first); - const auto verificationKey = deserializeKey(hexKeys.second); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - ASSERT_TRUE(verifier.verify(data, sig)); -} - -TEST(openssl_utils, test_eddsa_keys_hex_nok) { - const auto hexKeys = generateEdDSAKeyPair(); - - const auto signingKey = deserializeKey(hexKeys.first); - const auto verificationKey = deserializeKey(hexKeys.second); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - - // Corrupt data. - ++sig[0]; - - ASSERT_FALSE(verifier.verify(data, sig)); -} - -TEST(openssl_utils, test_eddsa_keys_pem_ok) { - const auto pemKeys = generateEdDSAKeyPair(KeyFormat::PemFormat); - - const auto signingKey = deserializeKey(pemKeys.first, KeyFormat::PemFormat); - const auto verificationKey = deserializeKey(pemKeys.second, KeyFormat::PemFormat); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - ASSERT_TRUE(verifier.verify(data, sig)); -} - -TEST(openssl_utils, test_eddsa_keys_pem_nok) { - const auto pemKeys = generateEdDSAKeyPair(KeyFormat::PemFormat); - - const auto signingKey = deserializeKey(pemKeys.first, KeyFormat::PemFormat); - const auto verificationKey = deserializeKey(pemKeys.second, KeyFormat::PemFormat); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - - // Corrupt data. - ++sig[0]; - - ASSERT_FALSE(verifier.verify(data, sig)); -} - -TEST(openssl_utils, test_eddsa_keys_combined_a_ok) { - const auto hexKeys = generateEdDSAKeyPair(); - const auto pemKeys = EdDSAHexToPem(hexKeys); - - const auto signingKey = deserializeKey(hexKeys.first); - const auto verificationKey = deserializeKey(pemKeys.second, KeyFormat::PemFormat); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - ASSERT_TRUE(verifier.verify(data, sig)); -} - -TEST(openssl_utils, test_eddsa_keys_combined_a_nok) { - const auto hexKeys = generateEdDSAKeyPair(); - const auto pemKeys = EdDSAHexToPem(hexKeys); - - const auto signingKey = deserializeKey(hexKeys.first); - const auto verificationKey = deserializeKey(pemKeys.second, KeyFormat::PemFormat); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - - // Corrupt data. - ++sig[0]; - - ASSERT_FALSE(verifier.verify(data, sig)); -} - -TEST(openssl_utils, test_eddsa_keys_combined_b_ok) { - const auto hexKeys = generateEdDSAKeyPair(); - const auto pemKeys = EdDSAHexToPem(hexKeys); - - const auto signingKey = deserializeKey(pemKeys.first, KeyFormat::PemFormat); - const auto verificationKey = deserializeKey(hexKeys.second); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - const std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - ASSERT_TRUE(verifier.verify(data, sig)); +TEST_F(EdDSATests, TestPEMFormatValidity) { + initSignerVerifier(KeyFormat::PemFormat); + signVerify(Message); } -TEST(openssl_utils, test_eddsa_keys_combined_b_nok) { - const auto hexKeys = generateEdDSAKeyPair(); - const auto pemKeys = EdDSAHexToPem(hexKeys); - - const auto signingKey = deserializeKey(pemKeys.first, KeyFormat::PemFormat); - const auto verificationKey = deserializeKey(hexKeys.second); - - TestTxnSigner signer(signingKey.getBytes()); - TestTxnVerifier verifier(verificationKey.getBytes()); - - std::string data = "Hello VMworld"; - auto sig = signer.sign(data); - - // Corrupt data. - ++sig[0]; +TEST_F(EdDSATests, TestValidSignature) { signVerify(Message); } - ASSERT_FALSE(verifier.verify(data, sig)); +TEST_F(EdDSATests, TestInvalidSignature) { + auto signature = sign(Message); + signature[0] = ~signature[0]; + ASSERT_FALSE(verify(Message, signature)); } } // namespace