On Thu, 12 Nov 2020 at 10:33, Nicola Tuveri <[email protected]> wrote:
> > >8 > > > The private key is a random or pseudo-random 256-bit integer. > > How do you propose to "validate" that? > > For ECDSA it's not a a random or pseudo-random 256-bit integer: it's a > random or pseudo-random integer `k`, with `1 <= k < n`, not all > 256-bit integers fit into this definition for a 256-bit prime `n` > (where `n` is the order of the generator point for the curve. > Validating the private key guarantees that the input private scalar is > within the correct range. > The key generator is responsible for that, not the signer. > > Sidenote: I don't know how the software in question does keygen, if it > is happening outside of OpenSSL or not, but validating the key > generation step is also crucial, because the random integer generation > should have a uniform distribution over the whole range without any > biases. > If you do not know how the keys are generated, it is obvious that you have not read #12612 > > > > I was not "abusing the API" as you put it, merely pointing out that the > public key is not a required item for performing ECDSA signature > generation. This is a mathematical fact of life that you are going to have > to learn to live with. > > > > I agree that performing an ECDSA signature generation does not require > the public key, and that would be reason in favor of relaxing the > assumption. > So why do you persist in arguing against it? > I am not saying it is wrong to want to generate signatures only with > the private key, I am saying that it does not fit well with the > OpenSSL API design (and with most other cryptographic libraries, not > just OpenSSL forks, that also have similar "keypair assumptions"). > If OpenSSL API design conflicts with the well-understood requirements of EC cryptography, then OpenSSL will need to change, because the mathematics certainly is not going to change. > > A counter argument to yours is that ECDSA signature verification > requires only the public component, and it is a mathematical fact of > life that knowledge of the private component in this case implies > knowledge of the public component. > So what? > A user of a cryptographic library can therefore expect that an > abstract key object embedding knowledge of the private key is capable > of being used in operations requiring knowledge of the public > component, including ECDSA signature verification. > If I know the private key, I have no need at all to verify a signature using the public key. > Computing the public component on demand only when such operation is > requested is a sub-optimal design choice from both performance and > security points of views, and robust cryptographic libraries have to > deal with it. > Agree > We can reach different compromises, relaxing the documented assumption > as this vote proposes, and then offering API functions for the most > generic use cases and specialized API functions for specific use cases > like yours. I'm not arguing against doing that moving forward, I am > arguing about categorizing the current strict behavior of EC keymgmt > in 3.0 as a "breaking change" and considering the current use pattern > of the reproducer in #12612 against 1.1.1 as "supported" in the > current LTS release. > #12612 reports a change which breaks code that runs on every version from 1.0.1 to 3.0.0-alpha5. > > >> > >> Omitting the `EVP_PKEY_check()` in the reproducer and the user > >> application, would for example allow me to write a DoS attack: the > >> secret scalar could easily be hand-picked to trigger an endless loop > >> in the sign operation. > There exists no private key value which will cause the EVP_sign operation to enter an endless loop. The operation will always return a result, which may not be useful if it is impossible to generate the corresponding public key. > ~~~sh > ; which openssl; openssl version > /usr/bin/openssl > OpenSSL 1.1.1f 31 Mar 2020 > ; cat > /tmp/p256_invalid.pem > -----BEGIN PRIVATE KEY----- > MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCD/////AAAAAP////// > ////vOb6racXnoTzucrC/GMlUQ== > -----END PRIVATE KEY----- > ; openssl pkey -check -text -noout -in /tmp/p256_invalid.pem > Key is invalid > Detailed error: point at infinity > Private-Key: (256 bit) > priv: > ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:ff: > ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:63: > 25:51 > pub: > 00 > ASN1 OID: prime256v1 > NIST CURVE: P-256 > ; dd if=/dev/zero of=/tmp/foo.hash bs=1 count=32 > ; openssl pkeyutl -sign -inkey /tmp/p256_invalid.pem -in /tmp/foo.hash > -out /tmp/sig.der > # here is the infinite loop > ~~~ > > ROFL! --RWF
