Skip to content

Commit 9b4caca

Browse files
committed
push changes from deps/ncrypto back to ncrypto repo
1 parent 630ee8b commit 9b4caca

2 files changed

Lines changed: 114 additions & 2 deletions

File tree

include/ncrypto.h

Lines changed: 9 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,14 @@ 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
868+
#ifdef OSSL_SIGNATURE_PARAM_MU
869+
int initForSignMessage(const OSSL_PARAM params[]);
870+
int initForVerifyMessage(const OSSL_PARAM params[]);
871+
#endif
863872

864873
static EVPKeyCtxPointer New(const EVPKeyPointer& key);
865874
static EVPKeyCtxPointer NewFromID(int id);

src/ncrypto.cpp

Lines changed: 105 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,35 @@ 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+
3982+
#ifdef OSSL_SIGNATURE_PARAM_MU
3983+
int EVPKeyCtxPointer::initForSignMessage(const OSSL_PARAM params[]) {
3984+
if (!ctx_) return 0;
3985+
return EVP_PKEY_sign_message_init(ctx_.get(), nullptr, params);
3986+
}
3987+
3988+
int EVPKeyCtxPointer::initForVerifyMessage(const OSSL_PARAM params[]) {
3989+
if (!ctx_) return 0;
3990+
return EVP_PKEY_verify_message_init(ctx_.get(), nullptr, params);
3991+
}
3992+
#endif
3993+
39333994
bool EVPKeyCtxPointer::initForEncrypt() {
39343995
if (!ctx_) return false;
39353996
return EVP_PKEY_encrypt_init(ctx_.get()) == 1;
@@ -4491,6 +4552,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInitWithContext(
44914552
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
44924553
EVP_PKEY_CTX* ctx = nullptr;
44934554

4555+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4556+
// Ed25519ctx requires the INSTANCE param to enable context string support.
4557+
// Ed25519 pure mode ignores context strings without this.
4558+
if (key.id() == EVP_PKEY_ED25519) {
4559+
const OSSL_PARAM params[] = {
4560+
OSSL_PARAM_construct_utf8_string(
4561+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4562+
OSSL_PARAM_construct_octet_string(
4563+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4564+
const_cast<unsigned char*>(context_string.data),
4565+
context_string.len),
4566+
OSSL_PARAM_END};
4567+
4568+
if (!EVP_DigestSignInit_ex(
4569+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4570+
return std::nullopt;
4571+
}
4572+
return ctx;
4573+
}
4574+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4575+
44944576
const OSSL_PARAM params[] = {
44954577
OSSL_PARAM_construct_octet_string(
44964578
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
@@ -4515,6 +4597,27 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInitWithContext(
45154597
#ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
45164598
EVP_PKEY_CTX* ctx = nullptr;
45174599

4600+
#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
4601+
// Ed25519ctx requires the INSTANCE param to enable context string support.
4602+
// Ed25519 pure mode ignores context strings without this.
4603+
if (key.id() == EVP_PKEY_ED25519) {
4604+
const OSSL_PARAM params[] = {
4605+
OSSL_PARAM_construct_utf8_string(
4606+
OSSL_SIGNATURE_PARAM_INSTANCE, const_cast<char*>("Ed25519ctx"), 0),
4607+
OSSL_PARAM_construct_octet_string(
4608+
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
4609+
const_cast<unsigned char*>(context_string.data),
4610+
context_string.len),
4611+
OSSL_PARAM_END};
4612+
4613+
if (!EVP_DigestVerifyInit_ex(
4614+
ctx_.get(), &ctx, nullptr, nullptr, nullptr, key.get(), params)) {
4615+
return std::nullopt;
4616+
}
4617+
return ctx;
4618+
}
4619+
#endif // OSSL_SIGNATURE_PARAM_INSTANCE
4620+
45184621
const OSSL_PARAM params[] = {
45194622
OSSL_PARAM_construct_octet_string(
45204623
OSSL_SIGNATURE_PARAM_CONTEXT_STRING,

0 commit comments

Comments
 (0)