OTC VOTE: EVP_PKEY private/public key components
Nicola Tuveri
nic.tuv at gmail.com
Wed Nov 11 22:34:53 UTC 2020
Usually the labs provide assurances on the key generation and the
other cryptographic operations, including validation, but have special
provisions to avoid providing assurances on key serialization and
deserialization.
This seems particularly true in the context of the FIPS validation for
OpenSSL, where the encoders/decoders are outside the scope of the FIPS
module and of validation.
The issue that triggered this discussion is particularly an issue of
encoding/decoding: the user application uses a custom format, and that
is the reason why the `EVP_PKEY` object is built from an `EC_KEY`
object built from scratch.
The application has only these ways to validate if the created
`EVP_PKEY` object is valid from a programmer's perspective AND as a
cryptographic object:
- EVP_PKEY_check (check an EVP_PKEY keypair)
- EVP_PKEY_public_check (check an EVP_PKEY pubkey, or just the public
component of an EVP_PKEY keypair)
- EVP_PKEY_param_check (check an EVP_PKEY params object, or just the
params component of an EVP_PKEY keypair or pubkey)
By design the consistency checks and validation checks are omitted
unless these functions are called, and there is no
EVP_PKEY_private_check.
To me this proves that what was described as a "breaking change" in
3.0 with strict EC keymgmt, is instead a programmer error in the
application that abused the API with an incomplete initialization,
which would have been detected if the dedicated validation functions
were called appropriately.
Even if the security policies that apply to the users of that
application wouldn't require to validate the cryptographic properties
of the key every time they are loaded because of external processes
and assurances, the developers of the application would have
discovered they were abusing the API if they tried validating the
half-initialized objects even just in development builds, which in my
opinion debunks the "lack of enforcement" argument that partially
supported the discussion that led to this vote.
In light of this I would dare say that:
a) the current "strict" state of EC keymgmt in 3.0 does not represent
a "breaking change" w.r.t 1.1.1, as it only catches existing API
abuses that were catched in 1.1.1, if only the half-initialized
objects were validated
b) relaxing the "keypair assumption" for EVP_PKEY objects is entirely
a new feature
Neither of these points makes the vote "invalid", but they could
change some of the casted votes, and they would strengthen my -1 in a
-2 if it were an option.
--
Nicola
P.S. For the record, given that I expressed this mostly in the virtual
meetings rather than in the discussion thread in the mailing list,
while from these emails it might seem like I hate with fiery rage the
idea of relaxing the keypair assumption, this is not really the case.
My main concern is changing this deeply rooted and pervasive
assumption in the timeframe of the 3.0 release, and with (IMO)
insufficient test coverage to make sure that we can transition to a
more relaxed model without introducing defects that could translate
into security risks.
On Wed, Nov 11, 2020 at 11:58 PM SHANE LONTIS <shane.lontis at oracle.com> wrote:
>
> Key assurance really depends on what you are doing, so I don't think this is quite true.
> For example if you generate a key using a valid algorithm (that is validated by a lab), then there is already an assurance that the key is valid without needing to run EVP_PKEY_check().
>
> There are many operations that don't need EVP_PKEY_check, but they may need a sub check such as
> EVP_PKEY_public_check, EVP_PKEY_param_check, EVP_PKEY_private_check or EVP_PKEY_pairwise_check (or some combination of those).
> Keys (and certs) that are received from another entity should be validated unless there is some other mechanism for establishing that the key is trusted.
>
>
> On 12 Nov 2020, at 12:14 am, Nicola Tuveri <nic.tuv at gmail.com> wrote:
>
> In light of recently working more closely to `EVP_PKEY_check()` I
> would add to the discussion on this vote that it is not entirely true
> that we were not enforcing the keypair assumption and that the current
> strict behavior of the EC keymgmt in 3.0 is a breaking change w.r.t.
> some uses that work in 1.1.1.
>
> In particular in 1.1.1, the key created as depicted in #12612 that
> triggered this discussion (Matt posted a useful reproducer among the
> first comments), is indeed capable of signing in the used pattern, but
> the pattern is conveniently omitting the validation pass that should
> be required in any serious use of the API.
>
> `EVP_PKEY_check()`
> (https://urldefense.com/v3/__https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_check.html__;!!GqivPVa7Brio!PdWuiQz52CFt9zZk9s6He6IimqtSPbLrvJ1ck_RKJIydCE80FY4lRl-WD8v1m4r6Zg$ ) is
> one of the many places in 1.1.1 where both the documentation and the
> behavior assume that an `EVP_PKEY` object is a keypair.
> Even in the version used by the user that posted the issue, running
> `EVP_PKEY_check()` on the created key would have revealed that the
> user was abusing the API.
>
> The "lack of enforcement" argument, that was partially at the base of
> formulating the vote text as it is, and conditioned our votes, seems
> to me an intentional design choice, as part of preferring the usage
> pattern "validate once, and reuse many times": for performance reasons
> we are not running `EVP_PKEY_check()` on every single key loaded from
> a PEM file or created by the user, but there is an assumption that the
> user did validate at least once the key material using
> `EVP_PKEY_check()` or `openssl pkey -check`.
> So enforcement was never lacking, but it was relegated together with
> more expensive checks, into functions that the user should execute at
> least once, possibly according to well documented security policies
> concerning the management of key material in transit and at rest.
>
> 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.
>
>
> --
>
> Nicola
>
>
>
> On Tue, Nov 3, 2020 at 2:11 PM Matt Caswell <matt at openssl.org> wrote:
>
>
> Background to the vote:
>
> The OTC meeting today discussed the problems raised by issue #12612. In
> summary the problem is that there has been a long standing, widespread
> and documented assumption that an EVP_PKEY with a private key will
> always also have the public key component.
>
> In spite of this it turns out that in the EC implementation in 1.1.1 it
> was perfectly possible to create an EVP_PKEY with only a private key and
> no public key - and it was also possible to use such an EVP_PKEY in a
> signing operation.
>
> The current 3.0 code in master introduced an explicit check (in line
> with the long held assumption) that the public key was present and
> rejected keys where this was not the case. This caused a backwards
> compatibility break for some users (as discussed at length in #12612).
>
> The OTC discussed a proposal that we should relax our conceptual model
> in this regards and conceptually allow EVP_PKEYs to exist that only have
> the private component without the public component - although individual
> algorithm implementations may still require both.
>
> It is possible to automatically generate the public component from the
> private for many algorithms, although this may come at a performance and
> (potentially) a security cost.
>
> The proposal discussed was that while relaxing the conceptual model,
> most of the existing implementations would still require both. The EC
> implementation would be relaxed however. This essentially gives largely
> compatible behaviour between 1.1.1 and 3.0.
>
> The vote text is as follows:
>
> topic: For 3.0 EVP_PKEY keys, the OTC accepts the following resolution:
> * relax the conceptual model to allow private keys to exist without public
> components;
> * all implementations apart from EC require the public component to be
> present;
> * relax implementation for EC key management to allow private keys that
> do not
> contain public keys and
> * our decoders unconditionally generate the public key (where possible).
>
> Proposed by Matt Caswell
> Public: yes
> opened: 2020-11-03
> closed: 2020-mm-dd
> accepted: yes/no (for: X, against: Y, abstained: Z, not voted: T)
>
> Matt [+1]
> Mark [ ]
> Pauli [+1]
> Viktor [ ]
> Tim [ ]
> Richard [+1]
> Shane [+1]
> Tomas [+1]
> Kurt [ ]
> Matthias [ ]
> Nicola [-1]
>
>
More information about the openssl-project
mailing list