-
Notifications
You must be signed in to change notification settings - Fork 62
PK: add mbedtls_pk_write_pubkey_psa()
#577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a9520f0 to
d0aa1bd
Compare
mpg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good to me, thanks for the nice documentation, but I want more tests :)
include/mbedtls/pk.h
Outdated
| * | ||
| * \param ctx PK context from which the public key is extracted. It must | ||
| * have been populated. | ||
| * \param buf Output buffer where the pubblic key is written. It must not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: pubBlic
include/mbedtls/pk.h
Outdated
| * operation is successful. In case of failure the value is 0. | ||
| * | ||
| * \return 0 if successful. | ||
| * \return MBEDTLS_ERR_PK_BAD_INPUT_DATA if \p ctx, \p buf or \p buf_len |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to check for that or promise that we do in the documentation. Generally speaking when passed NULL pointers that shouldn't be NULL, we're OK with getting whatever behaviour we get from the platform (like segfault on Linux etc).
Some of the old code in PK has more checks than our current policy, but I don't think we should copy that in new code.
(Though thanks for documenting every error condition here!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While addressing comments I realized that the implementation I provided completely misses the support for opaque keys! This is not a regression compared to what there before since opaque contexts (EC and RSA) do not have the debug support. So the question: is this something we foresee that might be useful in the future? Or are we OK with the current implementation?
I think that extending the test coverage as you suggested will tell if at least we're fine with non-opaque keys, I guess
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second thought I have a proposal/question as follow-up. How bad is it for opaque keys in PK to have their public part in the PK context (like non-opaque EC/RSA)? I cannot think of any drawback to this, but you know for sure better than me.
Rationale.
I found that mbedtls_pk_ecc_set_pubkey_from_prv and mbedtls_pk_rsa_set_pubkey_from_prv are basically the same, so instead of duplicating the code I can move them in pk.c with their prototype being in pk_internal.h. Then in mbedtls_pk_write_pubkey_psa I can check if pk->pub_raw_len != 0 and memcpy from that; however in case it's empty BUT pk->priv_id is not empty, I can try to export the public key from the private one (using the merge of mbedtls_pk_ecc_set_pubkey_from_prv & mbedtls_pk_rsa_set_pubkey_from_prv ) as last resort.
To me this makes mbedtls_pk_write_pubkey_psa able to work in all scenarios without end user intervention and being able to support opaque keys as well!
Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How bad is it for opaque keys in PK to have their public part in the PK context (like non-opaque EC/RSA)?
It's just a memory-vs-performance compromise. Given that the current trend in pk is to reduce the number of cases when manipulating key representations, I think it would make sense to always store the public key in the context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Gilles said, and as I was trying to say on the bitlen PR, I think we want to avoid as much as possible having fields in the pk_context that are sometimes set, sometimes not, and as maintainers we have to remember about them and what condition to check to know if the field is set or not, and that adds a lot of cognitive load when working with the code.
So, yes, every time we can reduce the number of cases we have to consider and move to a situation where the same information is always present in the same way not matter how the key was populated, I'll be in favour of doing so!
| USE_PSA_INIT(); | ||
| TEST_EQUAL(mbedtls_pk_parse_public_keyfile(&pk, key_file), 0); | ||
|
|
||
| /* TODO: Replace this with mbedtls_pk_get_type() once it will be available */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has now been merged, so this can be updated :)
| TEST_EQUAL(mbedtls_pk_write_pubkey_psa(&pk, buf, sizeof(buf), &buf_len), | ||
| MBEDTLS_ERR_PK_BAD_INPUT_DATA); | ||
|
|
||
| USE_PSA_INIT(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Post 1.0, we can (and should) just call PSA_INIT(). (Same with PSA_DONE().)
| MBEDTLS_ERR_PK_BAD_INPUT_DATA); | ||
|
|
||
| USE_PSA_INIT(); | ||
| TEST_EQUAL(mbedtls_pk_parse_public_keyfile(&pk, key_file), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's one was to populate a context. As discussed elsewhere, we need to test other ways of populating the context. Also as discussed, that might either be done with more test functions, or my handling multiple methods in a single function.
Off the top of my head, I'd say:
- one function for parse public (this one)
- for parse keypair: possibly the same function, with an extra param for public/private, as I think the only thing that's going to change is the parse function being called
- possibly a single function from all 3 of
wrap_psa(),copy_from_psa()andcopy_public_from_psa(), as they all start with a PSA key?
Add function implementation, prototype and documentation. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Signed-off-by: Valerio Setti <vsetti@baylibre.com>
a9f7d9e to
06cd968
Compare
|
Sorry I had to rebase on |
…_psa() It is OK to segfault (or any crash, depending on the platform) if a NULL pointer is passed when the documentation clearly states that this must not be done. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Since "mbedtls_pk_ecc_set_pubkey_from_prv" and "mbedtls_pk_rsa_set_pubkey_from_prv" are exactly the same they can be merged together. The new function is named "mbedtls_pk_set_pubkey_from_prv" and it's placed in "pk.c" because it's common to all key types. The prototype was already in "pk_internal.h" so this was already fine. Until now these functions has been used for non-opaque context, but given the recent changes to PK, this new function can also be used to handle opaque context in the same way (i.e. exporting its public key and keping it in the PK context). Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Allow the function to be able to return the public key in all the scenarios supported by PK: - If the public key is already available in the PK context, then simply memcpy() it. - If only the private key is available, then export the public key from the private one and then memcpy() it. Advantages are: - The user doesn't need to worry about filling the public part before calling this function. - It allows the function to work also with opaque keys. This functionality wasn't supported before, so it's an improvement that comes for free. The only side effect of this change is that the first parameter of mbedtls_pk_write_pubkey_psa (i.e. mbedtls_pk_context) cannot be const because otherwise it wouldn't be possible to pass it to "mbedtls_pk_set_pubkey_from_prv" without some dirty casting. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
- replace USE_PSA_INIT/USE_PSA_DONE, with PSA_INIT/PSA_DONE - use mbedtls_pk_get_key_type() to get the type of key being tested instead of the temporary solution that was added before when this function was not yet available. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
…e key For the EC keys this is already happening in "pk_parse_key_sec1_der()" even though the procedure is a bit different in that case. For SEC1 the key might or might not be present on the parsed buffer, so it might or might not be derived form the private counterpart. For RSA keys there is no such possibility: the public key should always be exported from the private key. The point here is that at the end of the "mbedtls_pk_parse_key()" we want private and public fields of the PK context to be filled for all the supported key types. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
In this way both private and public key files are parsed and tested with the same test function. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Since we're going to add new test scenarios for "mbedtls_pk_write_pubkey_psa()" where the PK context is generated in a different way than parsing a key file, we rename "pk_write_pubkey_psa" to "pk_write_pubkey_psa_from_file" to differentiate it from the new test functions that will be added in following commits. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
…write_pubkey_psa_from_file() This will become handy in follow up commits where the same core test function will be used elsewhere. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
64a93fb to
9533816
Compare
PK returns "int" not "psa_status_t" so the return code should have been "0" and not "PSA_SUCCESS". Signed-off-by: Valerio Setti <vsetti@baylibre.com>
After the PK context has been initialized it must be tested (obviously), the same as in "pk_write_pubkey_psa_from_file", but this part was missing. This commit fixes this. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Add a previously missing check that caused some tests to erroneously fail when "pk->pub_raw_len = 0" and also the current output buffer len was set to 0. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
…_psa Partially reverts commit 63660b7 for what concerns with the following: - keep "const" on the PK parameter being passed in input to the function; - do not try to complete the PK context if the public key is missing. The rationale here is that this is just a debug function meant to get some data from the PK context. It's the caller responsibility to properly fill the PK context before calling it. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
Add a call to "mbedtls_pk_set_pubkey_from_prv" from "mbedtls_pk_wrap_psa" in order to set the public key in PK context when the PSA key pair is wrapped. This aligns "mbedtls_pk_wrap_psa" to all other current ways of generating a PK context from a key pair: "mbedtls_pk_copy_from_psa" and "mbedtls_pk_parse_keyfile". Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This helps reading the ".data" file so that it's immediately clear if a certain file being parsed is supposed to contain a private or public key. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This completes the testing of mbedtls_pk_write_pubkey_psa() for all possible scenarios. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This is not needed at all by this PR, but it required to make the CI happy. It's just updating the reference of framework to the current HEAD of main branch. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
62e8557 to
3cdd524
Compare
|
@mpg @bjwtaylor I had to rebase to resolve a conflict on the |
mpg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Description
Resolves #529
PR checklist