golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
121.44k stars 17.4k forks source link

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

Open AnomalRoil opened 6 years ago

AnomalRoil commented 6 years ago

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?

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 commented 6 years ago

/cc @agl @FiloSottile @rsc

FiloSottile commented 4 years ago

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.

ericlagergren commented 2 years ago

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)