Finalize pk.h #468
No reviewers
Labels
No labels
api-break
approved
bug
component-docs
component-platform
component-test
dependencies
deprecation
DO-NOT-MERGE
enhancement
good first issue
help wanted
needs-adoption
needs-backports
needs-ci
needs-design-approval
needs-info
needs-preceding-pr
needs-review
needs-reviewer
needs-work
priority-high
priority-low
priority-medium
priority-scheduled
priority-very-high
resolved-after-1.1
single-reviewer
size-l
size-m
size-optimisation
size-s
size-xs
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-Mbed-TLS/TF-PSA-Crypto!468
Loading…
Reference in a new issue
No description provided.
Delete branch "finalize-pk.h"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
Resolve #347 and resolve #205
Depends on: https://github.com/Mbed-TLS/mbedtls/pull/10418 for a clean CI (sigh).
PR checklist
I have reviewed for correctness (with the loss of distinction between v1.5 and v2.1 RSA keys that we discussed on Slack and that will be implemented in https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/471).
I haven't reviewed for completeness yet, I'll do another pass for that but it may have to wait until tomorrow.
The thing is, a PSA key does not in general have “the permitted algorithm”. It could be the same permitted algorithm policy (including the enrollment algorithm), or it could be the PSA key's primary algorithm (which is what it was in 3.6, and AFAIK this hasn't changed).
@ -450,0 +420,4 @@* For keys created with \c mbedtls_pk_wrap_psa(), the* primary algorithm is the same as the original PSA key.* Otherwise, it is determined as follows:* - For RSA keys:Is verification supported with ECDSA? I can't find that in the test code.
Not necessarily a key pair, it can be a public key.
@ -578,3 +548,3 @@/*** \brief Verify signature (including padding if relevant).* \brief Verify signature.*Given that this function is only useful for ECDSA, and there is only one ECDSA verification algorithm, I think this whole note is useless. For RSA, there's already a sentence above that says it's the same as
mbedtls_pk_verify.@ -606,20 +578,20 @@ int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,** \note Performs the same job as \c mbedtls_pk_verify(), but can“includes verification of the padding” is an obsolete concept from back when textbook RSA was considered a cryptographic algorithm rather than a low-level building block. Please remove this clause while you're at it.
@ -665,0 +631,4 @@* \note The signature algorithm used will be the one that would be* selected by \c mbedtls_pk_get_psa_attributes() called with a* usage of #PSA_KEY_USAGE_SIGN_HASH - see that function's* documentation for details.Given that wrapped PSA keys aren't supported (which should be mentioned in this function's description, btw), this simplifies to “this function always uses
MBEDTLS_PK_ALG_ECDSA” (plus being equivalent tombedtls_pk_signfor RSA keys as stated just above).@ -793,9 +764,8 @@ int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,* \param pwdlen Size of the password in bytes.This information is still relevant. And for RSA keys, we should state that PKCS#1v1.5 signature (
PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)orPSA_ALG_RSA_PKCS1V15_SIGN_RAW) will be used.I do think this should be mentioned explicitly, because it can be somewhat surprising: you don't necessarily end up with the same algorithm with
mbedtls_pk_wrap_psa.Also applies to
mbedtls_pk_copy_public_from_psa.@ -450,0 +420,4 @@* For keys created with \c mbedtls_pk_wrap_psa(), the* primary algorithm is the same as the original PSA key.* Otherwise, it is determined as follows:* - For RSA keys:Yes, IMO it's supported and I think it's also tested
@ -537,1 +497,3 @@* otherwise PKCS1 v1.5 is set.** \note This function only copies the key material but discards* policy information entirely. See \cI'm not sure this is consistent with what will be
mbedtls_pk_get_psa_attributesafter https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/471. For example for an RSA keymbedtls_pk_get_psa_attributeswill always return PKCS v1.5 algorithm, whereasrsa_verify_wrappicks the proper padding mode depending onpk->rsa_padding.Will this be updated after https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/471?
@ -450,0 +420,4 @@* For keys created with \c mbedtls_pk_wrap_psa(), the* primary algorithm is the same as the original PSA key.* Otherwise, it is determined as follows:* - For RSA keys:I had not checked tests and has just looked at the info structure fro which pointers are not NULL. Thank you Valerio for locating tests.
@ -793,9 +764,8 @@ int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,* \param pwdlen Size of the password in bytes.This information is now centralized in the documentation of
mbedtls_pk_get_psa_attributes(), in the "else" part of: "if the key was create withwrap_psa(), else ...." I guess I should add a pointer here?The thing is, there is not public concept of an algorithm associated with a key, as we don't say how the key will be stored. So, the only observables is what
get_psa_attributes()will return, and whatpk_sign()andpk_verify()will do, which is now defined to be the same.@ -578,3 +548,3 @@/*** \brief Verify signature (including padding if relevant).* \brief Verify signature.*Ah, right, I did the same as for sign but did not thing that there is no distinction when verifying. Thanks!
@ -606,20 +578,20 @@ int mbedtls_pk_verify(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,** \note Performs the same job as \c mbedtls_pk_verify(), but canFully agreed. I kept that out of habit but I don't like it either.
Unless I'm missing something, the value of
pk->rsa_paddingwill always be v1.5 at this point because:init()Specifically, in 471,
mbedtls_pk_set_rsa_(padding|hash)()are used only in tests, not in the library (and not in mbedtls).In fact, I think we should remove that field (and
rsa_hash) entirely. I didn't initially suggest doing that in 471 in order to keep it minimal, but that's something I'd like to do right after it. But perhaps it makes more sense to do it in 471 in order to be more confident about the fact that they're not used? (The same reason why I removedpk_context::pk_ctxhere.) Wdyt?As Gilles said previously, a guiding principle of PK for 1.0 is that it doesn't do policy - that's PSA's job. According to this principle, we shouldn't have those fields in
pk_context. (Again, it makes sense that you introduced them in the initial refactoring of how RSA keys are held, because it's better to not change existing behaviour when refactoring, but I think there should have been a 2nd step where we change the behaviour to simplify and align with the new principles.)Oh, you are perfectly right, sorry.
Well, I can open a follow-up PR so that we can both have 471 merged soon (if it's OK) and then keep other changes in the follow-up
@ -793,9 +764,8 @@ int mbedtls_pk_check_pair(const mbedtls_pk_context *pub,* \param pwdlen Size of the password in bytes.We know that, but users don't necessarily know that. An interface like pk could reasonably have a specific algorithm associated with each key, and could reasonably treat keys as pure mathematical objects with no policy. It's not obvious that we went for the latter. It's even less obvious for users who have used previous versions of Mbed TLS where a key did have partial policy information.
This is why I think this should be mentioned explicitly in the documentation of
copy_from_psa, not just by reference to the documentation of other functions. We don't necessarily have to have the specifics here, but at least we should state the general principle that this is functionally equivalent to export+import and that no policy information carries over.Duh, it says right below "key pair or public key". What was I thinking.
mbedtls_pk_[rsa|ec]()that make the CI unhappysigned-off-byMostly LGTM now, just a couple of things left.
I also had a high-level look at
pk.hto look for other things to change, and the only things that stood out were:mbedtls_pk_verify_ext().@ -0,0 +1,7 @@API changesCopyediting:
These changes overlap a lot, and I'm not sure it makes sense to list them separately. I think it would be easier to understand with a single entry that goes something like this:
I don't think “freshly initialized” is quite right, because that seems to forbid reusing a context after calling
mbedtls_pk_free()on it.@ -306,3 +279,3 @@* \param ctx The context to initialize. It must be empty (type NONE).* \param ctx The context to populate. It must be empty.* \param key The PSA key to wrap, which must hold an ECC or RSA key pair.*We no longer have anything that's called “setting up” a context. This was already a defect in the documentation in 3.x: we were using “set up” without defining it, so a reasonable understanding was that this meant calling
mbedtls_pk_setup()ormbedtls_pk_setup_xxx(). But parsing a key also counted as “set up”, even though that was neither documented as such nor obvious from the name.I think now we should completely stop using “set up”, and instead say something like “it must have been filled with key material” or “it must contain key material” or some such.
Mind you, we don't always need to call this out explicitly. In any function that consumes a PK object as a key, it's obvious that the object must, in fact, consume a key. And if the object doesn't contain a key, there is always a well-defined error for an object that doesn't contain key material (even if we don't document exactly which error code is used).
What is important to state explicitly is that for all functions that populate a PK object, the object must be initialized, and the object must not already have material in it.
Based on https://github.com/Mbed-TLS/TF-PSA-Crypto/pull/468#discussion_r2375723065 isn't this the other way round? It works with wrapped ECC keys but not wrapped RSA keys.
@ -665,0 +631,4 @@* \note The signature algorithm used will be the one that would be* selected by \c mbedtls_pk_get_psa_attributes() called with a* usage of #PSA_KEY_USAGE_SIGN_HASH - see that function's* documentation for details.This is still imprecise: if there is an enrollment algorithm, is it copied or ignored?
One more thing about
mbedtls_pk_verify_ext: with the removal ofoptions, we lost the information of what this function does about the salt length. It allows any salt length.Aw did a trial build, and even built Mbed TLS, but didn't build the programs...
Aw, copy-pasta I guess, thanks!
@ -306,3 +279,3 @@* \param ctx The context to initialize. It must be empty (type NONE).* \param ctx The context to populate. It must be empty.* \param key The PSA key to wrap, which must hold an ECC or RSA key pair.*Yeah, this was on my list at some point, then I removed it as perhaps not needed right now. Well, let's do it after all.
I'm happy with
97a417cc59but the CI isn't.Yeah, the failure in
build_no_std_functionseems to be related to makingstdlib.halways included inudp_proxy.Yes, I'm preparing an mbedtls PR to fix that. Just checking if there were other failures hidden by this one in the same component before I push.
https://github.com/Mbed-TLS/mbedtls/pull/10418