<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 12 Nov 2020 at 10:33, Nicola Tuveri <<a href="mailto:nic.tuv@gmail.com" target="_blank">nic.tuv@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
>8<br><br>
> The private key is a random or pseudo-random 256-bit integer.<br>
> How do you propose to "validate" that?<br>
<br>
For ECDSA it's not a a random or pseudo-random 256-bit integer: it's a<br>
random or pseudo-random integer `k`, with `1 <= k < n`, not all<br>
256-bit integers fit into this definition for a 256-bit prime `n`<br>
(where `n` is the order of the generator point for the curve.<br>
Validating the private key guarantees that the input private scalar is<br>
within the correct range.<br></blockquote><div><br></div><div>The key generator is responsible for that, not the signer.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Sidenote: I don't know how the software in question does keygen, if it<br>
is happening outside of OpenSSL or not, but validating the key<br>
generation step is also crucial, because the random integer generation<br>
should have a uniform distribution over the whole range without any<br>
biases.<br></blockquote><div><br></div><div>If you do not know how the keys are generated, it is obvious that you have not read #12612<br></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
><br>
>  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.<br>
><br>

<br>
I agree that performing an ECDSA signature generation does not require<br>
the public key, and that would be reason in favor of relaxing the<br>
assumption.<br></blockquote><div><br></div><div>So why do you persist in arguing against it?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I am not saying it is wrong to want to generate signatures only with<br>
the private key, I am saying that it does not fit well with the<br>
OpenSSL API design (and with most other cryptographic libraries, not<br>
just OpenSSL forks, that also have similar "keypair assumptions").<br></blockquote><div><br></div><div>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. <br></div><div></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
A counter argument to yours is that ECDSA signature verification<br>
requires only the public component, and it is a mathematical fact of<br>
life that knowledge of the private component in this case implies<br>
knowledge of the public component.<br></blockquote><div><br></div><div>So what?</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A user of a cryptographic library can therefore expect that an<br>
abstract key object embedding knowledge of the private key is capable<br>
of being used in operations requiring knowledge of the public<br>
component, including ECDSA signature verification.<br></blockquote><div><br></div><div>If I know the private key, I have no need at all to verify a signature using the public key.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Computing the public component on demand only when such operation is<br>
requested is a sub-optimal design choice from both performance and<br>
security points of views, and robust cryptographic libraries have to<br>
deal with it.<br></blockquote><div><br></div><div>Agree</div><div><br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
We can reach different compromises, relaxing the documented assumption<br>
as this vote proposes, and then offering API functions for the most<br>
generic use cases and specialized API functions for specific use cases<br>
like yours. I'm not arguing against doing that moving forward, I am<br>
arguing about categorizing the current strict behavior of EC keymgmt<br>
in 3.0 as a "breaking change" and considering the current use pattern<br>
of the reproducer in #12612 against 1.1.1 as "supported" in the<br>
current LTS release.<br></blockquote><div><br></div><div>#12612 reports a change which breaks code that runs on every version from 1.0.1 to 3.0.0-alpha5.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
>><br>
>> Omitting the `EVP_PKEY_check()` in the reproducer and the user<br>
>> application, would for example allow me to write a DoS attack: the<br>
>> secret scalar could easily be hand-picked to trigger an endless loop<br>
>> in the sign operation.<br></blockquote><div><br></div><div>There exists no private key value which will cause the EVP_sign operation to enter an endless loop.</div><div>The operation will always return a result, which may not be useful if it is impossible to generate the corresponding public key.</div><div><br></div><div></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
~~~sh<br>
; which openssl; openssl version<br>
/usr/bin/openssl<br>
OpenSSL 1.1.1f  31 Mar 2020<br>
; cat > /tmp/p256_invalid.pem<br>
-----BEGIN PRIVATE KEY-----<br>
MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCD/////AAAAAP//////<br>
////vOb6racXnoTzucrC/GMlUQ==<br>
-----END PRIVATE KEY-----<br>
; openssl pkey -check -text -noout -in /tmp/p256_invalid.pem<br>
Key is invalid<br>
Detailed error: point at infinity<br>
Private-Key: (256 bit)<br>
priv:<br>
    ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:<br>
    ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:63:<br>
    25:51<br>
pub:<br>
    00<br>
ASN1 OID: prime256v1<br>
NIST CURVE: P-256<br>
; dd if=/dev/zero of=/tmp/foo.hash bs=1 count=32<br>
; openssl pkeyutl -sign -inkey /tmp/p256_invalid.pem -in /tmp/foo.hash<br>
-out /tmp/sig.der<br>
# here is the infinite loop<br>
~~~<br>
<br></blockquote><div><br></div><div>ROFL!<br></div><div><br></div><div><br></div><div></div><div><br></div><div>--RWF</div><div><br></div></div></div>