Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions contrib/cryptomb/private_key_providers/source/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ envoy_cc_library(
repository = "@envoy",
visibility = ["//visibility:public"],
deps = [
":cryptomb_stats_lib",
":ipp_crypto_wrapper_lib",
"//envoy/api:api_interface",
"//envoy/event:dispatcher_interface",
Expand All @@ -83,6 +84,22 @@ envoy_cc_library(
],
)

envoy_cc_library(
name = "cryptomb_stats_lib",
srcs = [
"cryptomb_stats.cc",
],
hdrs = [
"cryptomb_stats.h",
],
deps = [
"//envoy/stats:stats_interface",
"//envoy/stats:stats_macros",
"//source/common/stats:symbol_table_lib",
"//source/common/stats:utility_lib",
],
)

envoy_cc_contrib_extension(
name = "config",
srcs = ["config.cc"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ CryptoMbContext::CryptoMbContext(Event::Dispatcher& dispatcher,
: status_(RequestStatus::Retry), dispatcher_(dispatcher), cb_(cb) {}

void CryptoMbContext::scheduleCallback(enum RequestStatus status) {
schedulable_ = dispatcher_.createSchedulableCallback([this, status]() -> void {
schedulable_ = dispatcher_.createSchedulableCallback([this, status]() {
// The status can't be set beforehand, because the callback asserts
// if someone else races to call doHandshake() and the status goes to
// HandshakeComplete.
Expand Down Expand Up @@ -330,10 +330,10 @@ ssl_private_key_result_t rsaPrivateKeyDecryptForTest(CryptoMbPrivateKeyConnectio
}

CryptoMbQueue::CryptoMbQueue(std::chrono::milliseconds poll_delay, enum KeyType type, int keysize,
IppCryptoSharedPtr ipp, Event::Dispatcher& d)
IppCryptoSharedPtr ipp, Event::Dispatcher& d, CryptoMbStats& stats)
: us_(std::chrono::duration_cast<std::chrono::microseconds>(poll_delay)), type_(type),
key_size_(keysize), ipp_(ipp),
timer_(d.createTimer([this]() -> void { processRequests(); })) {
key_size_(keysize), ipp_(ipp), timer_(d.createTimer([this]() { processRequests(); })),
stats_(stats) {
request_queue_.reserve(MULTIBUFF_BATCH);
}

Expand All @@ -359,6 +359,8 @@ void CryptoMbQueue::addAndProcessEightRequests(CryptoMbContextSharedPtr mb_ctx)

void CryptoMbQueue::processRequests() {
if (type_ == KeyType::Rsa) {
// Record queue size statistic value for histogram.
stats_.rsa_queue_sizes_.recordValue(request_queue_.size());
processRsaRequests();
}
request_queue_.clear();
Expand Down Expand Up @@ -481,12 +483,14 @@ void CryptoMbPrivateKeyMethodProvider::unregisterPrivateKeyMethod(SSL* ssl) {
delete ops;
}

// The CryptoMbPrivateKeyMethodProvider is created on config.
CryptoMbPrivateKeyMethodProvider::CryptoMbPrivateKeyMethodProvider(
const envoy::extensions::private_key_providers::cryptomb::v3alpha::
CryptoMbPrivateKeyMethodConfig& conf,
Server::Configuration::TransportSocketFactoryContext& factory_context, IppCryptoSharedPtr ipp)
: api_(factory_context.api()),
tls_(ThreadLocal::TypedSlot<ThreadLocalData>::makeUnique(factory_context.threadLocal())) {
tls_(ThreadLocal::TypedSlot<ThreadLocalData>::makeUnique(factory_context.threadLocal())),
stats_(generateCryptoMbStats("cryptomb", factory_context.scope())) {

if (!ipp->mbxIsCryptoMbApplicable(0)) {
throw EnvoyException("Multi-buffer CPU instructions not available.");
Expand Down Expand Up @@ -519,7 +523,6 @@ CryptoMbPrivateKeyMethodProvider::CryptoMbPrivateKeyMethodProvider(
method_->complete = privateKeyComplete;

RSA* rsa = EVP_PKEY_get0_RSA(pkey.get());

switch (RSA_bits(rsa)) {
case 1024:
key_size = 1024;
Expand All @@ -542,7 +545,9 @@ CryptoMbPrivateKeyMethodProvider::CryptoMbPrivateKeyMethodProvider(

BIGNUM e_check;
// const BIGNUMs, memory managed by BoringSSL in RSA key structure.
const BIGNUM *e, *n, *d;
const BIGNUM* e = nullptr;
const BIGNUM* n = nullptr;
const BIGNUM* d = nullptr;
RSA_get0_key(rsa, &n, &e, &d);
BN_init(&e_check);
BN_add_word(&e_check, 65537);
Expand Down Expand Up @@ -582,9 +587,9 @@ CryptoMbPrivateKeyMethodProvider::CryptoMbPrivateKeyMethodProvider(
enum KeyType key_type = key_type_;

// Create a single queue for every worker thread to avoid locking.
tls_->set([poll_delay, key_type, key_size, ipp](Event::Dispatcher& d) {
tls_->set([poll_delay, key_type, key_size, ipp, this](Event::Dispatcher& d) {
ENVOY_LOG(debug, "Created CryptoMb Queue for thread {}", d.name());
return std::make_shared<ThreadLocalData>(poll_delay, key_type, key_size, ipp, d);
return std::make_shared<ThreadLocalData>(poll_delay, key_type, key_size, ipp, d, stats_);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "source/common/common/c_smart_ptr.h"
#include "source/common/common/logger.h"

#include "contrib/cryptomb/private_key_providers/source/cryptomb_stats.h"
#include "contrib/cryptomb/private_key_providers/source/ipp_crypto.h"
#include "contrib/envoy/extensions/private_key_providers/cryptomb/v3alpha/cryptomb.pb.h"

Expand Down Expand Up @@ -93,7 +94,7 @@ class CryptoMbQueue : public Logger::Loggable<Logger::Id::connection> {
static constexpr uint32_t MULTIBUFF_BATCH = 8;

CryptoMbQueue(std::chrono::milliseconds poll_delay, enum KeyType type, int keysize,
IppCryptoSharedPtr ipp, Event::Dispatcher& d);
IppCryptoSharedPtr ipp, Event::Dispatcher& d, CryptoMbStats& stats);
void addAndProcessEightRequests(CryptoMbContextSharedPtr mb_ctx);

private:
Expand All @@ -120,6 +121,8 @@ class CryptoMbQueue : public Logger::Loggable<Logger::Id::connection> {

// Timer to trigger queue processing if eight requests are not received in time.
Event::TimerPtr timer_{};

CryptoMbStats& stats_;
};

// CryptoMbPrivateKeyConnection maintains the data needed by a given SSL
Expand Down Expand Up @@ -170,8 +173,8 @@ class CryptoMbPrivateKeyMethodProvider : public virtual Ssl::PrivateKeyMethodPro
// Thread local data containing a single queue per worker thread.
struct ThreadLocalData : public ThreadLocal::ThreadLocalObject {
ThreadLocalData(std::chrono::milliseconds poll_delay, enum KeyType type, int keysize,
IppCryptoSharedPtr ipp, Event::Dispatcher& d)
: queue_(poll_delay, type, keysize, ipp, d){};
IppCryptoSharedPtr ipp, Event::Dispatcher& d, CryptoMbStats& stats)
: queue_(poll_delay, type, keysize, ipp, d, stats){};
CryptoMbQueue queue_;
};

Expand All @@ -181,6 +184,8 @@ class CryptoMbPrivateKeyMethodProvider : public virtual Ssl::PrivateKeyMethodPro
enum KeyType key_type_;

ThreadLocal::TypedSlotPtr<ThreadLocalData> tls_;

CryptoMbStats stats_;
};

} // namespace CryptoMb
Expand Down
18 changes: 18 additions & 0 deletions contrib/cryptomb/private_key_providers/source/cryptomb_stats.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "contrib/cryptomb/private_key_providers/source/cryptomb_stats.h"

#include "envoy/stats/scope.h"
#include "envoy/stats/stats_macros.h"

namespace Envoy {
namespace Extensions {
namespace PrivateKeyMethodProvider {
namespace CryptoMb {

CryptoMbStats generateCryptoMbStats(const std::string& prefix, Stats::Scope& scope) {
return CryptoMbStats{ALL_CRYPTOMB_STATS(POOL_HISTOGRAM_PREFIX(scope, prefix))};
}

} // namespace CryptoMb
} // namespace PrivateKeyMethodProvider
} // namespace Extensions
} // namespace Envoy
25 changes: 25 additions & 0 deletions contrib/cryptomb/private_key_providers/source/cryptomb_stats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "envoy/stats/scope.h"
#include "envoy/stats/stats_macros.h"

namespace Envoy {
namespace Extensions {
namespace PrivateKeyMethodProvider {
namespace CryptoMb {

#define ALL_CRYPTOMB_STATS(HISTOGRAM) HISTOGRAM(rsa_queue_sizes, Unspecified)

/**
* CryptoMb stats struct definition. @see stats_macros.h
*/
struct CryptoMbStats {
ALL_CRYPTOMB_STATS(GENERATE_HISTOGRAM_STRUCT)
};

CryptoMbStats generateCryptoMbStats(const std::string& prefix, Stats::Scope& scope);

} // namespace CryptoMb
} // namespace PrivateKeyMethodProvider
} // namespace Extensions
} // namespace Envoy
10 changes: 1 addition & 9 deletions contrib/cryptomb/private_key_providers/test/fake_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ namespace CryptoMb {
FakeIppCryptoImpl::FakeIppCryptoImpl(bool supported_instruction_set)
: supported_instruction_set_(supported_instruction_set) {}

FakeIppCryptoImpl::~FakeIppCryptoImpl() {
BN_free(n_);
BN_free(e_);
BN_free(d_);
}

int FakeIppCryptoImpl::mbxIsCryptoMbApplicable(uint64_t) {
return supported_instruction_set_ ? 1 : 0;
}
Expand Down Expand Up @@ -153,10 +147,8 @@ FakeCryptoMbPrivateKeyMethodFactory::createPrivateKeyMethodProviderInstance(

bssl::UniquePtr<EVP_PKEY> pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
if (pkey != nullptr && EVP_PKEY_id(pkey.get()) == EVP_PKEY_RSA) {
const BIGNUM *e, *n, *d;
RSA* rsa = EVP_PKEY_get0_RSA(pkey.get());
RSA_get0_key(rsa, &n, &e, &d);
fakeIpp->setRsaKey(n, e, d);
fakeIpp->setRsaKey(rsa);
}

IppCryptoSharedPtr ipp = std::dynamic_pointer_cast<IppCrypto>(fakeIpp);
Expand Down
13 changes: 4 additions & 9 deletions contrib/cryptomb/private_key_providers/test/fake_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ namespace CryptoMb {
class FakeIppCryptoImpl : public virtual IppCrypto {
public:
FakeIppCryptoImpl(bool supported_instruction_set);
~FakeIppCryptoImpl() override;

int mbxIsCryptoMbApplicable(uint64_t features) override;
uint32_t mbxRsaPrivateCrtSslMb8(const uint8_t* const from_pa[8], uint8_t* const to_pa[8],
Expand All @@ -26,21 +25,17 @@ class FakeIppCryptoImpl : public virtual IppCrypto {
int expected_rsa_bitsize) override;
bool mbxGetSts(uint32_t status, unsigned req_num) override;

void setRsaKey(const BIGNUM* n, const BIGNUM* e, const BIGNUM* d) {
n_ = BN_dup(n);
e_ = BN_dup(e);
d_ = BN_dup(d);
};
void setRsaKey(RSA* rsa) { RSA_get0_key(rsa, &n_, &e_, &d_); };

void injectErrors(bool enabled) { inject_errors_ = enabled; }

private:
uint32_t mbxSetSts(uint32_t status, unsigned req_num, bool success);

bool supported_instruction_set_;
BIGNUM* n_{};
BIGNUM* e_{};
BIGNUM* d_{};
const BIGNUM* n_{};
const BIGNUM* e_{};
const BIGNUM* d_{};

bool inject_errors_{};
};
Expand Down
Loading