Skip to content

EVP: make EVP_PKEY_{bits,security_bits,size} work with provider only keys#10778

Closed
levitte wants to merge 11 commits intoopenssl:masterfrom
levitte:get-evp_pkey-params
Closed

EVP: make EVP_PKEY_{bits,security_bits,size} work with provider only keys#10778
levitte wants to merge 11 commits intoopenssl:masterfrom
levitte:get-evp_pkey-params

Conversation

@levitte
Copy link
Member

@levitte levitte commented Jan 8, 2020

These functions relied entirely on the presence of 'pkey->pmeth',
which is NULL on provider only keys. This adds an interface to get
domparam and key data from a provider, given corresponding provider
data (the actual domparam or key).

The retrieved data is cached in the EVP_PKEY structure (lending the
idea from provided EVP_CIPHER).

Checklist
  • documentation is added or updated
  • tests are added or updated

@levitte levitte added branch: master Applies to master branch approval: review pending This pull request needs review by a committer labels Jan 8, 2020
@levitte
Copy link
Member Author

levitte commented Jan 8, 2020

Note that #10289 is now pending on this as well

Copy link
Member

@romen romen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine at a first look, I will test more later on.

But I notice a doc update is missing in this PR and maybe it could also be the right PR to add simple tests for the involved EVP_PKEY_* functions.

Bonus points if you want to revise the doc for EVP_PKEY_bits vs security_bits because last time I checked I had trouble understanding the exact definition of the returned values!

@levitte
Copy link
Member Author

levitte commented Jan 8, 2020

I have tweaked a test for this already. Docs to be added today

@levitte
Copy link
Member Author

levitte commented Jan 8, 2020

Documentation added. @romen, are you happy with the result?

@levitte levitte force-pushed the get-evp_pkey-params branch from f854036 to 4a32483 Compare January 8, 2020 14:41
@levitte
Copy link
Member Author

levitte commented Jan 8, 2020

Finally got all the docs bits right. Final review, please?

Copy link
Member

@slontis slontis Jan 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're thinking of PSS, aren't you? Otherwise, rsa doesn't come with domain parameters as far as I know.

Either way, I'm finally about to put together PSS support across the diverse implementations where it's missing.

@levitte
Copy link
Member Author

levitte commented Jan 9, 2020

Let's move the discussion away from specific diff spots, shall we?

[for those not quite following, the discussion is about EVP_PKEY_size() not being quite suitable for what it does, how to implement it for provided keys, and whether it should be divided into operation specific size functions]

@romen said:

For the EC operations for example it is completely left to the whims of the provider developer what to return in this case: he could return the estimated output either of a signature operation or of a kexchange operation.

With legacy keys, this is implemented in the EVP_PKEY_ASN1_METHOD, which is as close to the keymgmt interface as you can get.

Something to be noted is that EVP_PKEY_size returns a number large enough for any operation, i.e. in the case you mention, it would return MAX(sigsize, kexsize).

I'm quite doubtful that having EVP_PKEY_size() make an exhaustive search for the exact size is useful when the max size is good enough for its intended use. Something to think of is the extra churn that generates.

@levitte
Copy link
Member Author

levitte commented Jan 9, 2020

I've wrapped my brain around the idea of operation specific size functions and could give that a go in a separate PR.

@romen
Copy link
Member

romen commented Jan 9, 2020

@levitte

What if we reduce the size of this PR by excluding the bits (pun intended) about EVP_PKEY_size() and its counterpart into the provider API?

That way we can proceed with the rest of this PR that seems pretty much ready, and debate to our hearts content about what to do for the naming and the ambiguity of EVP_PKEY_size().

Does it sound a plausible approach?

(also I am out of cycles for reviews for today, so it is unlikely I can look at big changes before tomorrow)

@romen
Copy link
Member

romen commented Jan 9, 2020

Something to be noted is that EVP_PKEY_size returns a number large enough for any operation, i.e. in the case you mention, it would return MAX(sigsize, kexsize).

@levitte I think that this could become a good interim definition of what EVP_PKEY_size() and OSSL_PKEY_PARAM_SIZE should return. At least it removes the ambiguity for provider implementers and it also marginally improves the situation for developers linking against libcrypto that at least now would have a description of what EVP_PKEY_size() returns that matches more closely with the current and legacy behavior.

@levitte
Copy link
Member Author

levitte commented Jan 9, 2020

@romen said:

What if we reduce the size of this PR by excluding the bits (pun intended) about EVP_PKEY_size() and its counterpart into the provider API?

The problem is that this is used everywhere to allocate a suitable buffer. Without this change, anything that uses provider-only keys (such as those created with EVP_PKEY_fromdata(), or those generated in #10289) will not be able to do any signing, because EVP_PKEY_size() returns zero for such keys.

This is actually a very serious stumbling block (of many) that has kinda halted #10289 for quite some time.

@levitte levitte force-pushed the get-evp_pkey-params branch from 489246f to 922f7c6 Compare January 9, 2020 14:06
@levitte
Copy link
Member Author

levitte commented Jan 9, 2020

@romen, there's one thing I don't quite understand, and it's why a KEYMGMT shouldn't be able to return a known max buffer size for all operations that will use the particular key. I mean this technically rather than on principle.

However, I realise that you might not be entirely aware of one little fact: the KEYMGMT used with any operation must belong to the same provider as the operation that uses the keys. This means that as far as provider authors' "whims" are concerned, it should not be a concern, because that provider will have to be self-consistent to work properly, i.e. what the KEYMGMT part returns must be correct for all the operations that the same provider implements.

In other words, an exhaustive search for a maximum size should not be necessary, technically speaking. It can be provided once, by the provider author.

@levitte levitte force-pushed the get-evp_pkey-params branch from da3b4da to 70072ca Compare January 9, 2020 20:43
@levitte
Copy link
Member Author

levitte commented Jan 9, 2020

I've added some more changes that eliminate quite a lot of our internal use of EVP_PKEY_size() (including a number that went against our documentation!).

I haven't touched libssl at all. The code in ssl/statem/ scares me. @mattcaswell, would you be willing to have a look? Most specifically, these calls go against documented recommendations (*):

siglen = EVP_PKEY_size(pkey);

siglen = EVP_PKEY_size(pkey);

(*) doc/man3/EVP_DigestSignInit.pod explicitly says:

The use of EVP_PKEY_size() with these functions is discouraged because some
signature operations may have a signature length which depends on the
parameters set. As a result EVP_PKEY_size() would have to return a value
which indicates the maximum possible signature for any set of parameters.

@romen
Copy link
Member

romen commented Jan 9, 2020

@levitte Re: #10778 (comment)

With the definition of "is the maximum size of any supported operation on
this key" I don't see a technical problem.

I was against it when the definition seemed to be "it must return the first
meaningful size to conform with the legacy behavior of EVP_PKEY_size: i.e.
return signature size if supported, alternatively encryption size,
alternatively key exchange size, etc."

The first definition is self contained, the second is pushing hacks to
support the ambiguity of EVP_PKEY_size from core to providers!

That being said, I still feel that it is not particularly elegant to
hardcode in keymgmt.c a number that depends on operations defined in a
different source files (say signature.c and exchange.c).
It means that as a provider implementer I have to remember to recheck
the maximum size of every possible operation even if I am modifying
only say exchange.c to introduce a new kdf ctrl flag.

It is bad enough that I have to consider every possible combination of
parameters for a single operation, having to recheck it also for the other
files might be problematic and error prone (in addition to being easily
forgotten!).

Anyway, while my first objection felt like something worth holding this PR,
elegance seems secondary and I would be fine with approving this PR even
against my second objection (if we opened an issue to keep track of the
fact that we wish to improve it as soon as possible)

@levitte
Copy link
Member Author

levitte commented Jan 10, 2020

I was against it when the definition seemed to be "it must return the first
meaningful size to conform with the legacy behavior of EVP_PKEY_size: i.e.
return signature size if supported, alternatively encryption size,
alternatively key exchange size, etc."

That's not the legacy behaviour either. The number returned for one legacy key is constant for that key and is large enough to accommodate a signature done using that key, as well as a secret key encrypted with key, as well as a derived key (DH). It returns a maximum meaningful size for all. That explains why it returns ECDSA_size() for our EC keys, that's simply because it's a larger number than ECDH_size() returns, i.e. whoever authored that code already knew the result of MAX(ECDSA_size(), ECDH_size()).

Actually, this also strengthens my believe that the description of EVP_PKEY_size() that makes you think that it's only about signatures is incorrect. This has never matched the actual behaviour, or how we use it in our own code.

@levitte
Copy link
Member Author

levitte commented Jan 10, 2020

I've added some more changes that eliminate quite a lot of our internal use of EVP_PKEY_size() (including a number that went against our documentation!).

That was a fun experiment, but I'm going to move it to another branch / PR. For the intents and purposes of this PR, that was a bit over the top.

@levitte levitte force-pushed the get-evp_pkey-params branch from ca035c9 to f9fbfd0 Compare January 15, 2020 12:23
@mspncp
Copy link
Contributor

mspncp commented Jan 15, 2020

Let's move the discussion away from specific diff spots, shall we?

[for those not quite following, the discussion is about EVP_PKEY_size() not being quite suitable for what it does, how to implement it for provided keys, and whether it should be divided into operation specific size functions]

Indeed, I'm a bit lost and unsure where the discussion about EVP_PKEY_size() ended up. GitHub's web interface makes it very hard to reconstruct the discussion thread behind all those hidden resolved comments.

@romen have all your concerns about EVP_PKEY_size() now been resolved? If you still think that the function is misnamed and has problems, it would be good if you could take the time to open a separate issue which summarizes your concerns and the current status-quo.

@romen
Copy link
Member

romen commented Jan 15, 2020

Yes all my concerns about EVP_PKEY_size() have been addressed so far, we are just trying to please the CIs

@levitte
Copy link
Member Author

levitte commented Jan 15, 2020

Current travis failure is not relevant, it's just a worker that's slow (it seems to be one and the same, I've seen that job fail with early timeouts for a while now)

Copy link
Member

@romen romen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few very minor nits/side notes.

My approval stands even in case the resolution of these minor things is won't fix, as I don't really have a strong opinion on them and are just very minor things that popped out during my last review!

P. S. I agree that the Travis failure seems unrelated.

@levitte
Copy link
Member Author

levitte commented Jan 16, 2020

The extra commits that came just now solve the nits @romen had for me. From where I stand, the approval still stands.

@levitte levitte added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Jan 16, 2020
@romen
Copy link
Member

romen commented Jan 16, 2020

Yes, I confirm that my approval was implicitly granted!

@levitte
Copy link
Member Author

levitte commented Jan 16, 2020

I actually found it rather explicit 😉

@levitte levitte added approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: done This pull request has the required number of approvals labels Jan 17, 2020
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
…keys

These functions relied entirely on the presence of 'pkey->pmeth',
which is NULL on provider only keys.  This adds an interface to get
domparam and key data from a provider, given corresponding provider
data (the actual domparam or key).

The retrieved data is cached in the EVP_PKEY structure (lending the
idea from provided EVP_CIPHER).

Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from #10778)
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
They now all respond to requests for key size, bits and security bits.

Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from #10778)
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
This is for the case where we build keys from user data

Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from #10778)
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
…ity_bits()

We change the description to be about the key rather than the
signature.  How the key size is related to the signature is explained
in the description of EVP_SignFinal() anyway.

Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from #10778)
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
openssl-machine pushed a commit that referenced this pull request Jan 17, 2020
... to make them accessible from the FIPS provider module.

Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from #10778)
@levitte
Copy link
Member Author

levitte commented Jan 17, 2020

Merged.

6508e85 EVP: make EVP_PKEY_{bits,security_bits,size} work with provider only keys
9e5aaf7 PROV: Adapt the RSA, DSA and DH KEYMGMT implementations
81a624f TEST: Adapt test/evp_pkey_provided_test.c to check the key size
6942a0d DOC: New file for EVP_PKEY_size(), EVP_PKEY_bits() and EVP_PKEY_security_bits()
03d65ca DOC: Make EVP_SignInit.pod conform with man-pages(7)
f17268d Add CHANGES entry regarding the documentation of EVP_PKEY_size() et al
806253f DSA: Move DSA_security_bits() and DSA_bits()

@levitte levitte closed this Jan 17, 2020
mspncp pushed a commit to mspncp/openssl that referenced this pull request Mar 3, 2020
…ity_bits()

We change the description to be about the key rather than the
signature.  How the key size is related to the signature is explained
in the description of EVP_SignFinal() anyway.

Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from openssl#10778)

(cherry picked from commit 6942a0d)
mspncp pushed a commit to mspncp/openssl that referenced this pull request Mar 3, 2020
Reviewed-by: Nicola Tuveri <[email protected]>
(Merged from openssl#10778)

(cherry picked from commit 03d65ca)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Applies to master branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants