Skip to content

Commit b0720e6

Browse files
committed
feat: push changes from deps/ncrypto back to ncrypto repo
1 parent 630ee8b commit b0720e6

File tree

2 files changed

+98
-2
lines changed

2 files changed

+98
-2
lines changed

include/ncrypto.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ class EVPKeyCtxPointer final {
837837
bool setRsaOaepLabel(DataPointer&& data);
838838

839839
bool setSignatureMd(const EVPMDCtxPointer& md);
840+
bool setSignatureMd(const Digest& md);
840841

841842
bool publicCheck() const;
842843
bool privateCheck() const;
@@ -860,6 +861,10 @@ class EVPKeyCtxPointer final {
860861
bool initForKeygen();
861862
int initForVerify();
862863
int initForSign();
864+
#if OPENSSL_VERSION_MAJOR >= 3
865+
int initForVerifyEx(const OSSL_PARAM params[]);
866+
int initForSignEx(const OSSL_PARAM params[]);
867+
#endif
863868

864869
static EVPKeyCtxPointer New(const EVPKeyPointer& key);
865870
static EVPKeyCtxPointer NewFromID(int id);

src/ncrypto.cpp

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3668,8 +3668,40 @@ bool ECKeyPointer::setPublicKey(const ECPointPointer& pub) {
36683668
bool ECKeyPointer::setPublicKeyRaw(const BignumPointer& x,
36693669
const BignumPointer& y) {
36703670
if (!key_) return false;
3671-
return EC_KEY_set_public_key_affine_coordinates(
3672-
key_.get(), x.get(), y.get()) == 1;
3671+
const EC_GROUP* group = EC_KEY_get0_group(key_.get());
3672+
if (group == nullptr) return false;
3673+
3674+
// For curves with cofactor h=1, use EC_POINT_oct2point +
3675+
// EC_KEY_set_public_key instead of
3676+
// EC_KEY_set_public_key_affine_coordinates.
3677+
// The latter internally calls EC_KEY_check_key() which performs a scalar
3678+
// multiplication (n*Q) for order validation — redundant when h=1 since every
3679+
// on-curve point already has order n. EC_POINT_oct2point validates the point
3680+
// is on the curve, which is sufficient. For curves with h!=1, fall back to
3681+
// the full check.
3682+
auto cofactor = BignumPointer::New();
3683+
if (!cofactor || !EC_GROUP_get_cofactor(group, cofactor.get(), nullptr) ||
3684+
!cofactor.isOne()) {
3685+
return EC_KEY_set_public_key_affine_coordinates(
3686+
key_.get(), x.get(), y.get()) == 1;
3687+
}
3688+
3689+
// Field element byte length: ceil(degree_bits / 8).
3690+
size_t field_len = (EC_GROUP_get_degree(group) + 7) / 8;
3691+
3692+
// Build an uncompressed point: 0x04 || x || y, each padded to field_len.
3693+
size_t uncompressed_len = 1 + 2 * field_len;
3694+
auto buf = DataPointer::Alloc(uncompressed_len);
3695+
if (!buf) return false;
3696+
unsigned char* ptr = static_cast<unsigned char*>(buf.get());
3697+
ptr[0] = POINT_CONVERSION_UNCOMPRESSED;
3698+
x.encodePaddedInto(ptr + 1, field_len);
3699+
y.encodePaddedInto(ptr + 1 + field_len, field_len);
3700+
3701+
auto point = ECPointPointer::New(group);
3702+
if (!point) return false;
3703+
if (!point.setFromBuffer({ptr, uncompressed_len}, group)) return false;
3704+
return EC_KEY_set_public_key(key_.get(), point.get()) == 1;
36733705
}
36743706

36753707
bool ECKeyPointer::setPrivateKey(const BignumPointer& priv) {
@@ -3930,6 +3962,23 @@ bool EVPKeyCtxPointer::setSignatureMd(const EVPMDCtxPointer& md) {
39303962
1;
39313963
}
39323964

3965+
bool EVPKeyCtxPointer::setSignatureMd(const Digest& md) {
3966+
if (!ctx_ || !md) return false;
3967+
return EVP_PKEY_CTX_set_signature_md(ctx_.get(), md.get()) == 1;
3968+
}
3969+
3970+
#if OPENSSL_VERSION_MAJOR >= 3
3971+
int EVPKeyCtxPointer::initForSignEx(const OSSL_PARAM params[]) {
3972+
if (!ctx_) return 0;
3973+
return EVP_PKEY_sign_init_ex(ctx_.get(), params);
3974+
}
3975+
3976+
int EVPKeyCtxPointer::initForVerifyEx(const OSSL_PARAM params[]) {
3977+
if (!ctx_) return 0;
3978+
return EVP_PKEY_verify_init_ex(ctx_.get(), params);
3979+
}
3980+
#endif
3981+
39333982
bool EVPKeyCtxPointer::initForEncrypt() {
39343983
if (!ctx_) return false;
39353984
return EVP_PKEY_encrypt_init(ctx_.get()) == 1;
@@ -4491,6 +4540,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInitWithContext(
44914540
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
44924541
EVP_PKEY_CTX* ctx = nullptr;
44934542

4543+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4544+
// Ed25519ctx requires the INSTANCE param to enable context string support.
4545+
// Ed25519 pure mode ignores context strings without this.
4546+
if (key.id() == EVP_PKEY_ED25519) {
4547+
const OSSL_PARAM params[] = {
4548+
OSSL_PARAM_construct_utf8_string(
4549+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4550+
OSSL_PARAM_construct_octet_string(
4551+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4552+
const_cast<unsigned char*>(context_string.data),
4553+
context_string.len),
4554+
OSSL_PARAM_END};
4555+
4556+
if (!EVP_DigestSignInit_ex(
4557+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4558+
return std::nullopt;
4559+
}
4560+
return ctx;
4561+
}
4562+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4563+
44944564
const OSSL_PARAM params[] = {
44954565
OSSL_PARAM_construct_octet_string(
44964566
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
@@ -4515,6 +4585,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInitWithContext(
45154585
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
45164586
EVP_PKEY_CTX* ctx = nullptr;
45174587

4588+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4589+
// Ed25519ctx requires the INSTANCE param to enable context string support.
4590+
// Ed25519 pure mode ignores context strings without this.
4591+
if (key.id() == EVP_PKEY_ED25519) {
4592+
const OSSL_PARAM params[] = {
4593+
OSSL_PARAM_construct_utf8_string(
4594+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4595+
OSSL_PARAM_construct_octet_string(
4596+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4597+
const_cast<unsigned char*>(context_string.data),
4598+
context_string.len),
4599+
OSSL_PARAM_END};
4600+
4601+
if (!EVP_DigestVerifyInit_ex(
4602+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4603+
return std::nullopt;
4604+
}
4605+
return ctx;
4606+
}
4607+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4608+
45184609
const OSSL_PARAM params[] = {
45194610
OSSL_PARAM_construct_octet_string(
45204611
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,

0 commit comments

Comments
 (0)