Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/elliptic: ECDSA parameters should be validated. #22210

Open
AnomalRoil opened this issue Oct 11, 2017 · 3 comments
Open

crypto/elliptic: ECDSA parameters should be validated. #22210

AnomalRoil opened this issue Oct 11, 2017 · 3 comments
Labels
help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@AnomalRoil
Copy link

AnomalRoil commented Oct 11, 2017

What version of Go are you using (go version)?

go1.9.1 linux/amd64

What operating system and processor architecture are you using (go env)?

GOHOSTARCH="amd64" (intel)
GOHOSTOS="linux"

What did you do?

Playground link:
https://play.golang.org/p/Ldd8fvrP5m

I've been playing around with Go's ECDSA package and have noticed a few problems, none of practical security relevance, since those problems have premises unlikely to happen in real use cases. (I actually discussed those on Go's security mailing list a long time ago.)

The problems are all about parameters validation in ECDSA.

What did you expect to see?

The Go's implementation should conform to the DSS standard, notably by performing verification that the point used are actually on the curve at hand.
But if the checks I discuss here are considered not worthy, a workaround like what has been done for DSA might be good to completely avoid any risk of infinite loops.

I would expect a method to check the validity of the provided parameters, as per FIPS 186-4 sections 3.1 and 3.3.

What did you see instead?

  • No check is performed on the curve's points used to see whether they are on the curve or not, so it is possible to use a point not even on the curve. (Whether this is dangerous for ECDSA has not been studied.)
    Note that checks that points are on the curve are performed in the TLS package (where they are important, because of the invalid curve attack) thanks to the elliptic.Unmarshal method.

  • I also see that no check is performed on the private parameter "d" to verify if it's within well defined bounds. So it is possible to sign using a 0 value, which is not among the correct boundaries which are [1, n-1] (even if the value 1 does not make much sense from a security point of view).
    There is an example on the playground linked where this causes an infinite loop when signing an null hash with a null private integer.
    The value 0 is simply invalid as a private integer and should be rejected.

  • There are no "validation" methods for keys, this could be a good way to avoid performing such checks at each signature/verification: by providing a method users are supposed to use to validate the keys.

Such checks are important in my opinion and are part of the so-called "defense in depth" we want to generally ensure in a crypto library.

What are your opinions on these topics?

@odeke-em
Copy link
Member

/cc @agl @FiloSottile @rsc

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 29, 2018
@ianlancetaylor ianlancetaylor added this to the Go1.11 milestone Mar 29, 2018
@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Go1.12 Jun 23, 2018
@andybons andybons modified the milestones: Go1.12, Go1.13 Feb 12, 2019
@andybons andybons modified the milestones: Go1.13, Go1.14 Jul 8, 2019
@FiloSottile
Copy link
Contributor

We should refuse to Sign and Verify with invalid keys, as long as the checks are not too expensive compared to the rest of the operation. I'd take a PR with some benchstat for this.

@FiloSottile FiloSottile removed their assignment Sep 30, 2019
@FiloSottile FiloSottile added help wanted NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Security labels Sep 30, 2019
@FiloSottile FiloSottile modified the milestones: Go1.14, Unplanned Sep 30, 2019
@ericlagergren
Copy link
Contributor

ericlagergren commented Jan 17, 2022

Adding a very simple check to Sign to see if D is in [1, N-1].

name         old time/op    new time/op    delta
Sign/P256-8    19.3µs ± 1%    19.3µs ± 1%    ~     (p=0.371 n=8+10)
Sign/P224-8     162µs ± 0%     161µs ± 0%  -0.64%  (p=0.000 n=9+10)
Sign/P384-8     547µs ± 1%     546µs ± 0%    ~     (p=0.962 n=10+7)
Sign/P521-8    1.63ms ± 1%    1.63ms ± 1%    ~     (p=0.052 n=10+10)

name         old alloc/op   new alloc/op   delta
Sign/P256-8    2.94kB ± 0%    2.94kB ± 0%    ~     (all equal)
Sign/P224-8    4.97kB ± 0%    4.97kB ± 0%    ~     (all equal)
Sign/P384-8    6.18kB ± 0%    6.18kB ± 0%    ~     (all equal)
Sign/P521-8    7.79kB ± 0%    7.79kB ± 0%    ~     (all equal)

name         old allocs/op  new allocs/op  delta
Sign/P256-8      43.0 ± 0%      43.0 ± 0%    ~     (all equal)
Sign/P224-8      70.0 ± 0%      70.0 ± 0%    ~     (all equal)
Sign/P384-8      71.0 ± 0%      71.0 ± 0%    ~     (all equal)
Sign/P521-8      72.0 ± 0%      72.0 ± 0%    ~     (all equal)

Checking the public key, too:

name         old time/op    new time/op    delta
Sign/P256-8    19.3µs ± 1%    20.0µs ± 1%   +3.70%  (p=0.000 n=8+10)
Sign/P224-8     162µs ± 0%     162µs ± 0%   -0.19%  (p=0.004 n=9+9)
Sign/P384-8     547µs ± 1%     546µs ± 0%     ~     (p=0.631 n=10+10)
Sign/P521-8    1.63ms ± 1%    1.64ms ± 1%     ~     (p=0.315 n=10+10)

name         old alloc/op   new alloc/op   delta
Sign/P256-8    2.94kB ± 0%    3.56kB ± 0%  +21.25%  (p=0.000 n=10+10)
Sign/P224-8    4.97kB ± 0%    5.15kB ± 0%   +3.71%  (p=0.000 n=8+10)
Sign/P384-8    6.18kB ± 0%    6.46kB ± 0%   +4.54%  (p=0.000 n=8+10)
Sign/P521-8    7.79kB ± 0%    8.20kB ± 0%   +5.24%  (p=0.000 n=8+10)

name         old allocs/op  new allocs/op  delta
Sign/P256-8      43.0 ± 0%      50.0 ± 0%  +16.28%  (p=0.000 n=10+10)
Sign/P224-8      70.0 ± 0%      75.0 ± 0%   +7.14%  (p=0.000 n=10+10)
Sign/P384-8      71.0 ± 0%      76.0 ± 0%   +7.04%  (p=0.000 n=10+10)
Sign/P521-8      72.0 ± 0%      77.0 ± 0%   +6.94%  (p=0.000 n=10+10)

Checking [d]G=Q, too:

name         old time/op    new time/op    delta
Sign/P256-8    19.3µs ± 1%    31.2µs ± 0%  +62.01%  (p=0.000 n=8+9)
Sign/P224-8     162µs ± 0%     306µs ± 0%  +88.42%  (p=0.000 n=9+8)
Sign/P384-8     547µs ± 1%    1047µs ± 1%  +91.50%  (p=0.000 n=10+9)
Sign/P521-8    1.63ms ± 1%    3.17ms ± 1%  +94.10%  (p=0.000 n=10+10)

name         old alloc/op   new alloc/op   delta
Sign/P256-8    2.94kB ± 0%    3.85kB ± 0%  +31.05%  (p=0.000 n=10+10)
Sign/P224-8    4.97kB ± 0%    5.56kB ± 0%  +11.92%  (p=0.000 n=8+10)
Sign/P384-8    6.18kB ± 0%    7.01kB ± 0%  +13.49%  (p=0.000 n=8+10)
Sign/P521-8    7.79kB ± 0%    8.97kB ± 0%  +15.17%  (p=0.000 n=8+9)

name         old allocs/op  new allocs/op  delta
Sign/P256-8      43.0 ± 0%      56.0 ± 0%  +30.23%  (p=0.000 n=10+10)
Sign/P224-8      70.0 ± 0%      85.0 ± 0%  +21.43%  (p=0.000 n=10+10)
Sign/P384-8      71.0 ± 0%      86.0 ± 0%  +21.13%  (p=0.000 n=10+10)
Sign/P521-8      72.0 ± 0%      87.0 ± 0%  +20.83%  (p=0.000 n=10+10)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants