Skip to content

Added helper to initialize EC key using affine coordinates#30597

Closed
igus68 wants to merge 3 commits into
openssl:masterfrom
igus68:fix-16270-alt
Closed

Added helper to initialize EC key using affine coordinates#30597
igus68 wants to merge 3 commits into
openssl:masterfrom
igus68:fix-16270-alt

Conversation

@igus68
Copy link
Copy Markdown
Contributor

@igus68 igus68 commented Mar 27, 2026

This PR implements an alternative approach to providing initialisation of an EC public key from its affine coordinates:
it adds the function which converts the affine coordinates of an EC point to an octet string conforming to Sec. 2.3.4 of the SECG SEC 1 ("Elliptic Curve Cryptography") standard. This octet string can further be passed to the OSSL_PARAM_BLD_push_octet_string() function.

Fixes #16270

Additionally, it fixes the null pointer dereference in the EVP_EC_gen macro and adds explicit handling of the situation when NULL is passed to EVP_PKEY_Q_keygen() instead of the curve name.

Checklist
  • documentation is added or updated
  • tests are added or updated

@igus68 igus68 added branch: master Applies to master branch triaged: feature The issue/pr requests/adds a feature backlog fix The issue was closed as part of the backlog reduction initiative. labels Mar 27, 2026
@openssl-machine openssl-machine added the approval: review pending This pull request needs review by a committer label Mar 27, 2026
@github-actions github-actions Bot added severity: fips change The pull request changes FIPS provider sources severity: ABI change This pull request contains ABI changes labels Mar 27, 2026
Comment thread include/openssl/ec.h Outdated
Comment on lines +1553 to +1555
int EVP_EC_affine2octet_string(const BIGNUM *X, const BIGNUM *Y,
int field_len, unsigned char **pbuf, size_t *pbsize);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to evp.h

And I would move the EVP_EC_gen() there as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread crypto/evp/evp_lib.c Outdated
return ret;
}

int EVP_EC_affine2octet_string(const BIGNUM *X, const BIGNUM *Y,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please use lowercase for x and y.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread doc/man3/EC_KEY_new.pod Outdated
Comment on lines +25 to +26
int EVP_EC_affine2octet_string(const BIGNUM *X, const BIGNUM *Y, int field_len,
unsigned char **pbuf, size_t *pbsize);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this and EVP_EC_gen() to a separate manual page.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@t8m t8m added the tests: present The PR has suitable tests present label Mar 27, 2026
@igus68 igus68 force-pushed the fix-16270-alt branch 2 times, most recently from 33a8823 to 7b6f669 Compare March 30, 2026 09:55
Comment thread include/openssl/evp.h
Comment thread test/evp_pkey_provided_test.c Outdated
Comment thread crypto/ec/ec_oct.c Outdated
return len;
}

int EVP_EC_affine2oct(const BIGNUM *x, const BIGNUM *y, int field_len,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to move this into another file (a new one?) in crypto/evp

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crypto/evp/ec_support.c looks to be a proper one. Moved.

Comment thread crypto/ec/ec_oct.c Outdated
@t8m t8m requested review from slontis and t8m April 9, 2026 07:33
@slontis
Copy link
Copy Markdown
Member

slontis commented Apr 9, 2026

@aisle-analyzer

@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot Bot commented Apr 9, 2026

🔒 Aisle Security Analysis

We found 2 potential security issue(s) in this PR:

# Severity Title
1 🟠 High Integer overflow and potential buffer overflow in EVP_EC_affine2oct() via unchecked field_len
2 🔵 Low NULL pointer dereference in public EVP_EC_gen() macro via strstr(curve, "")

Each finding is detailed in a separate comment below.


Analyzed PR: #30597 at commit 685c1cc

Last updated on: 2026-04-09T22:21:46Z

Comment thread crypto/evp/ec_support.c
Comment thread include/openssl/evp.h Outdated
Comment on lines +1945 to +1946
#define EVP_EC_gen(curve) \
EVP_PKEY_Q_keygen(NULL, NULL, "EC", (char *)(strstr(curve, "")))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2. 🔵 NULL pointer dereference in public EVP_EC_gen() macro via strstr(curve, "")

Property Value
Severity Low
CWE CWE-476

Description

The public macro EVP_EC_gen(curve) expands to a call that unconditionally evaluates strstr(curve, ""):

  • If a caller passes curve == NULL (e.g., from language bindings or application code that propagates optional/unchecked inputs), strstr(NULL, "") dereferences a NULL pointer and will crash the process.
  • This is reachable before OpenSSL can raise an error, because the crash happens during macro argument evaluation.
  • The macro also casts away const ((char *)), which can encourage UB if EVP_PKEY_Q_keygen or downstream code ever attempted to modify the string.

Vulnerable code:

#define EVP_EC_gen(curve) \
    EVP_PKEY_Q_keygen(NULL, NULL, "EC", (char *)(strstr(curve, "")))

While passing NULL may be considered API misuse, OpenSSL APIs commonly handle NULL parameters by returning errors. Here it results in an immediate application-level denial of service.

Recommendation

Replace the macro with a real function (or an inline function) that validates inputs before calling the variadic API.

Example (header):

static ossl_inline EVP_PKEY *EVP_EC_gen(const char *curve)
{
    if (curve == NULL) {
        ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }
    return EVP_PKEY_Q_keygen(NULL, NULL, "EC", (char *)curve);
}

If you must keep the macro for ABI/API reasons, avoid evaluating curve inside strstr() and avoid discarding const; at minimum guard against NULL:

#define EVP_EC_gen(curve) \
    EVP_PKEY_Q_keygen(NULL, NULL, "EC", (char *)((curve) != NULL ? (curve) : ""))

(Prefer the function form so NULL can produce a proper OpenSSL error rather than silently using an empty string.)

Last updated on: 2026-04-09T22:21:48Z

Comment thread crypto/evp/ec_support.c
Comment thread doc/man3/EVP_EC_gen.pod

=head1 COPYRIGHT

Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just 2026 maybe?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description of EVP_EC_gen() is not new, it was moved from EC_KEY_new.pod
I'm not sure what the copyright dates should be in this case.

@igus68
Copy link
Copy Markdown
Contributor Author

igus68 commented Apr 13, 2026

In practice, overflow is impossible here because field_len is a signed int and the result is converted to size_t, so the result will always be correct. But I agree that from the perspective of the formal specification it is undefined behaviour. So I added an explicit cast of field_len to size_t.

@igus68
Copy link
Copy Markdown
Contributor Author

igus68 commented Apr 13, 2026

I spent a considerable amount of time finding out why this strange construction "(char *)(strstr(curve, ""))" is necessary in the EVP_EC_gen macro, so I described it in a comment for future generations. And I fixed this NULL dereference

@igus68 igus68 requested a review from slontis April 13, 2026 14:38
Comment thread crypto/evp/ec_support.c Outdated
return NID_undef;
}

int EVP_EC_affine2oct(const BIGNUM *x, const BIGNUM *y, int field_len,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should field_len really be a size_t? I'm not sure why we should be accepting a signed type here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use int for lengths in other functions:
int BN_num_bytes(const BIGNUM *a);
int EC_GROUP_get_degree(const EC_GROUP *group);
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
etc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we do. I think those were a bad idea too. No need to make the hole bigger since this is a completely new API.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are starting a new life, what type is best here? Although field_len is technically used to determine the size of allocated memory, logically it's a mathematical group parameter that has nothing to do with memory or addressing. Therefore, I'd rather use an unsigned int.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I still think a size_t is most appropriate for lengths and sizes of things. It is ultimately used to determine the amount of memory to allocate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As agreed, changed to size_t.

Comment thread test/evp_pkey_provided_test.c Outdated
* 0 = uncompressed format
* 1 = compressed format
* 2 = affine coordinates format via OSSL_PARAM_BLD_push_EC_affine_point()
* 3 = affine coordinates format via OSSL_PARAM_BLD_push_EC_affine_point_ex()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are OSSL_PARAM_BLD_push_EC_affine_point are OSSL_PARAM_BLD_push_EC_affine_point_ex? From an earlier iteration of this PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. Fixed.

Comment thread CHANGES.md Outdated

*Tomáš Mráz*

* Added `EVP_EC_affine2oct()` converts affine coordinates of an EC point
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Added `EVP_EC_affine2oct()` converts affine coordinates of an EC point
* Added `EVP_EC_affine2oct()` that converts the affine coordinates of an EC point

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@t8m
Copy link
Copy Markdown
Member

t8m commented Apr 28, 2026

@igus68 this needs a rebase

when NULL is passed instead of the curve name.
igus68 added 2 commits April 30, 2026 10:49
coordinates of an EC point to an octet string conforming to Sec. 2.3.4
of the SECG SEC 1 ("Elliptic Curve Cryptography") standard.
@igus68
Copy link
Copy Markdown
Contributor Author

igus68 commented Apr 30, 2026

@igus68 this needs a rebase
Done

@igus68 igus68 requested review from mattcaswell and slontis April 30, 2026 09:46
@t8m
Copy link
Copy Markdown
Member

t8m commented May 4, 2026

ping @slontis @mattcaswell for second review

@t8m t8m requested a review from a team May 5, 2026 12:34
Copy link
Copy Markdown
Member

@mattcaswell mattcaswell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. One minor suggested improvement below.

Comment thread doc/man7/EVP_PKEY-EC.pod

"qx" (B<OSSL_PKEY_PARAM_EC_PUB_X>) and "qy" (B<OSSL_PKEY_PARAM_EC_PUB_Y>)
can be used for getting the EC public key affine coordinates. To set
them call EVP_EC_affine2oct() to convert affine coordinates to
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
them call EVP_EC_affine2oct() to convert affine coordinates to
them call L<EVP_EC_affine2oct(3)> to convert affine coordinates to

@openssl-machine openssl-machine added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels May 5, 2026
@openssl-machine openssl-machine added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels May 6, 2026
@openssl-machine
Copy link
Copy Markdown
Collaborator

This pull request is ready to merge

@t8m
Copy link
Copy Markdown
Member

t8m commented May 6, 2026

Merged to the master branch with tweaked commit messages.

Thank you.

@t8m t8m closed this May 6, 2026
openssl-machine pushed a commit that referenced this pull request May 6, 2026
It errors out with ERR_R_PASSED_NULL_PARAMETER in such case.

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed May  6 16:47:55 2026
(Merged from #30597)
openssl-machine pushed a commit that referenced this pull request May 6, 2026
This function converts affine coordinates of an EC point
to an octet string conforming to Sec. 2.3.4
of the SECG SEC 1 ("Elliptic Curve Cryptography") standard.

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed May  6 16:47:57 2026
(Merged from #30597)
openssl-machine pushed a commit that referenced this pull request May 6, 2026
Also fixed the potential NULL pointer dereference in this macro.

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed May  6 16:47:58 2026
(Merged from #30597)
jericson pushed a commit to jericson/openssl that referenced this pull request May 9, 2026
It errors out with ERR_R_PASSED_NULL_PARAMETER in such case.

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed May  6 16:47:55 2026
(Merged from openssl#30597)
jericson pushed a commit to jericson/openssl that referenced this pull request May 9, 2026
This function converts affine coordinates of an EC point
to an octet string conforming to Sec. 2.3.4
of the SECG SEC 1 ("Elliptic Curve Cryptography") standard.

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed May  6 16:47:57 2026
(Merged from openssl#30597)
jericson pushed a commit to jericson/openssl that referenced this pull request May 9, 2026
Also fixed the potential NULL pointer dereference in this macro.

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed May  6 16:47:58 2026
(Merged from openssl#30597)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge backlog fix The issue was closed as part of the backlog reduction initiative. branch: master Applies to master branch severity: ABI change This pull request contains ABI changes severity: fips change The pull request changes FIPS provider sources tests: present The PR has suitable tests present triaged: feature The issue/pr requests/adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Initialize EC key using EC_PUB_X and EC_PUB_Y

6 participants