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
159 changes: 85 additions & 74 deletions include/ncrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,77 @@ class Dsa final {
OSSL3_CONST DSA* dsa_;
};

// ============================================================================
// RSA
class BignumPointer final {
public:
BignumPointer() = default;
explicit BignumPointer(BIGNUM* bignum);
explicit BignumPointer(const unsigned char* data, size_t len);
BignumPointer(BignumPointer&& other) noexcept;
BignumPointer& operator=(BignumPointer&& other) noexcept;
NCRYPTO_DISALLOW_COPY(BignumPointer)
~BignumPointer();

int operator<=>(const BignumPointer& other) const noexcept;
int operator<=>(const BIGNUM* other) const noexcept;
inline operator bool() const { return bn_ != nullptr; }
inline BIGNUM* get() const noexcept { return bn_.get(); }
void reset(BIGNUM* bn = nullptr);
void reset(const unsigned char* data, size_t len);
BIGNUM* release();

bool isZero() const;
bool isOne() const;

bool setWord(unsigned long w); // NOLINT(runtime/int)
unsigned long getWord() const; // NOLINT(runtime/int)

size_t byteLength() const;
size_t bitLength() const;

DataPointer toHex() const;
DataPointer encode() const;
DataPointer encodePadded(size_t size) const;
size_t encodeInto(unsigned char* out) const;
size_t encodePaddedInto(unsigned char* out, size_t size) const;

using PrimeCheckCallback = std::function<bool(int, int)>;
int isPrime(int checks,
PrimeCheckCallback cb = defaultPrimeCheckCallback) const;
struct PrimeConfig {
int bits;
bool safe = false;
const BignumPointer& add;
const BignumPointer& rem;
};

static BignumPointer NewPrime(
const PrimeConfig& params,
PrimeCheckCallback cb = defaultPrimeCheckCallback);

bool generate(const PrimeConfig& params,
PrimeCheckCallback cb = defaultPrimeCheckCallback) const;

static BignumPointer New();
static BignumPointer NewSecure();
static BignumPointer NewSub(const BignumPointer& a, const BignumPointer& b);
static BignumPointer NewLShift(size_t length);

static DataPointer Encode(const BIGNUM* bn);
static DataPointer EncodePadded(const BIGNUM* bn, size_t size);
static size_t EncodePaddedInto(const BIGNUM* bn, unsigned char* out,
size_t size);
static int GetBitCount(const BIGNUM* bn);
static int GetByteCount(const BIGNUM* bn);
static unsigned long GetWord(const BIGNUM* bn); // NOLINT(runtime/int)
static const BIGNUM* One();

BignumPointer clone();

private:
DeleteFnPtr<BIGNUM, BN_clear_free> bn_;

static bool defaultPrimeCheckCallback(int, int) { return 1; }
};

class Rsa final {
public:
Expand Down Expand Up @@ -390,12 +459,24 @@ class Ec final {

const EC_GROUP* getGroup() const;
int getCurve() const;
uint32_t getDegree() const;
std::string getCurveName() const;
const EC_POINT* getPublicKey() const;
const BIGNUM* getPrivateKey() const;

inline operator bool() const { return ec_ != nullptr; }
inline operator OSSL3_CONST EC_KEY*() const { return ec_; }

inline const BignumPointer& getX() const { return x_; }
inline const BignumPointer& getY() const { return y_; }
inline const BignumPointer& getD() const { return d_; }

private:
OSSL3_CONST EC_KEY* ec_ = nullptr;
// Affine coordinates for the EC_KEY.
BignumPointer x_;
BignumPointer y_;
BignumPointer d_;
};

// A managed pointer to a buffer of data. When destroyed the underlying
Expand Down Expand Up @@ -501,78 +582,6 @@ class BIOPointer final {
mutable DeleteFnPtr<BIO, BIO_free_all> bio_;
};

class BignumPointer final {
public:
BignumPointer() = default;
explicit BignumPointer(BIGNUM* bignum);
explicit BignumPointer(const unsigned char* data, size_t len);
BignumPointer(BignumPointer&& other) noexcept;
BignumPointer& operator=(BignumPointer&& other) noexcept;
NCRYPTO_DISALLOW_COPY(BignumPointer)
~BignumPointer();

int operator<=>(const BignumPointer& other) const noexcept;
int operator<=>(const BIGNUM* other) const noexcept;
inline operator bool() const { return bn_ != nullptr; }
inline BIGNUM* get() const noexcept { return bn_.get(); }
void reset(BIGNUM* bn = nullptr);
void reset(const unsigned char* data, size_t len);
BIGNUM* release();

bool isZero() const;
bool isOne() const;

bool setWord(unsigned long w); // NOLINT(runtime/int)
unsigned long getWord() const; // NOLINT(runtime/int)

size_t byteLength() const;
size_t bitLength() const;

DataPointer toHex() const;
DataPointer encode() const;
DataPointer encodePadded(size_t size) const;
size_t encodeInto(unsigned char* out) const;
size_t encodePaddedInto(unsigned char* out, size_t size) const;

using PrimeCheckCallback = std::function<bool(int, int)>;
int isPrime(int checks,
PrimeCheckCallback cb = defaultPrimeCheckCallback) const;
struct PrimeConfig {
int bits;
bool safe = false;
const BignumPointer& add;
const BignumPointer& rem;
};

static BignumPointer NewPrime(
const PrimeConfig& params,
PrimeCheckCallback cb = defaultPrimeCheckCallback);

bool generate(const PrimeConfig& params,
PrimeCheckCallback cb = defaultPrimeCheckCallback) const;

static BignumPointer New();
static BignumPointer NewSecure();
static BignumPointer NewSub(const BignumPointer& a, const BignumPointer& b);
static BignumPointer NewLShift(size_t length);

static DataPointer Encode(const BIGNUM* bn);
static DataPointer EncodePadded(const BIGNUM* bn, size_t size);
static size_t EncodePaddedInto(const BIGNUM* bn, unsigned char* out,
size_t size);
static int GetBitCount(const BIGNUM* bn);
static int GetByteCount(const BIGNUM* bn);
static unsigned long GetWord(const BIGNUM* bn); // NOLINT(runtime/int)
static const BIGNUM* One();

BignumPointer clone();

private:
DeleteFnPtr<BIGNUM, BN_clear_free> bn_;

static bool defaultPrimeCheckCallback(int, int) { return 1; }
};

class CipherCtxPointer final {
public:
static CipherCtxPointer New();
Expand Down Expand Up @@ -800,6 +809,8 @@ class EVPKeyPointer final {
bool isSigVariant() const;
bool validateDsaParameters() const;

EVPKeyPointer clone() const;

private:
DeleteFnPtr<EVP_PKEY, EVP_PKEY_free> pkey_;
};
Expand Down
25 changes: 24 additions & 1 deletion src/ncrypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,12 @@ EVPKeyPointer::EVPKeyPointer(EVP_PKEY* pkey) : pkey_(pkey) {}
EVPKeyPointer::EVPKeyPointer(EVPKeyPointer&& other) noexcept
: pkey_(other.release()) {}

EVPKeyPointer EVPKeyPointer::clone() const {
if (!pkey_) return {};
if (!EVP_PKEY_up_ref(pkey_.get())) return {};
return EVPKeyPointer(pkey_.get());
}

EVPKeyPointer& EVPKeyPointer::operator=(EVPKeyPointer&& other) noexcept {
if (this == &other) return *this;
this->~EVPKeyPointer();
Expand Down Expand Up @@ -3546,12 +3552,29 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,

Ec::Ec() : ec_(nullptr) {}

Ec::Ec(OSSL3_CONST EC_KEY* key) : ec_(key) {}
Ec::Ec(OSSL3_CONST EC_KEY* key)
: ec_(key), x_(BignumPointer::New()), y_(BignumPointer::New()) {
if (ec_ != nullptr) {
MarkPopErrorOnReturn mark_pop_error_on_return;
EC_POINT_get_affine_coordinates(getGroup(), getPublicKey(), x_.get(),
y_.get(), nullptr);
}
}

const EC_GROUP* Ec::getGroup() const { return ECKeyPointer::GetGroup(ec_); }

int Ec::getCurve() const { return EC_GROUP_get_curve_name(getGroup()); }

uint32_t Ec::getDegree() const { return EC_GROUP_get_degree(getGroup()); }

std::string Ec::getCurveName() const {
return std::string(OBJ_nid2sn(getCurve()));
}

const EC_POINT* Ec::getPublicKey() const { return EC_KEY_get0_public_key(ec_); }

const BIGNUM* Ec::getPrivateKey() const { return EC_KEY_get0_private_key(ec_); }

// ============================================================================

EVPMDCtxPointer::EVPMDCtxPointer() : ctx_(nullptr) {}
Expand Down