Skip to content
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

Secure element key registration #183

Conversation

gilles-peskine-arm
Copy link
Collaborator

@gilles-peskine-arm gilles-peskine-arm commented Jul 19, 2019

Add an API method that allows applications to register a key in a secure element.

Successor of #202. The first new commit is "psa_start_key_creation: take the method as a parameter".

This PR has undergone significant rework. See #183 (comment) . Previous iterations are available as 1, 2, 3, 4.

@gilles-peskine-arm gilles-peskine-arm added enhancement New feature or request needs: design review DO NOT MERGE The PR is not intended to be merged (yet). Usually used for a review of worked in progress. api-spec Issue or PR about the PSA specifications labels Jul 19, 2019
@AndrzejKurek AndrzejKurek self-requested a review July 22, 2019 08:15
@@ -154,6 +154,60 @@ typedef struct mbedtls_psa_stats_s
*/
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats );
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo in commit c3d4baa - "pplications"

*
* \retval #PSA_SUCCESS
* The key was successfully registered.
* Note that depending on the driver's
Copy link
Contributor

Choose a reason for hiding this comment

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

Unfinished sentence.

* The key was successfully registered.
* Note that depending on the driver's
* \retval #PSA_ERROR_ALREADY_EXISTS
* There is already a key with thw identifier specified in
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo - thw -> the

* \p attributes.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p attributes specifies a lifetime which is not located
* in a secure eleement.
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo - eleement -> element

* \param[in] key_slot Slot where the key is to be stored.
*
* \retval #PSA_SUCCESS
* The given slot number is valid.for a key with the given
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo - . ->

&slot->data.se.slot_number );
if( status != PSA_SUCCESS )
return( status );
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a call to p_check_slot could be made here if the method is PSA_KEY_CREATION_REGISTER? Just to check that what the application is trying to register is sane.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, but not as is: p_check_slot might say “no, you can't create a key here because it's occupied”. I lean towards adding a psa_key_creation_method_t to p_allocate and p_check_slot, which would allow the driver to enforce constraints like “this slot is locked against import and can only contain internally-generated, non-exportable keys”.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in the newest rebase. On a related note, I renamed p_check_slot to p_validate_slot_number in #202.

Copy link
Contributor

@AndrzejKurek AndrzejKurek left a comment

Choose a reason for hiding this comment

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

This design looks promising. What part of the PSA depends on the key type being PSA_KEY_TYPE_RAW_DATA to work properly with secure elements, if any? I'm asking because I'm considering a case where you pass the exact key type that can/will be handled in a given slot during registration.

@gilles-peskine-arm
Copy link
Collaborator Author

What part of the PSA depends on the key type being PSA_KEY_TYPE_RAW_DATA to work properly with secure elements, if any?

I'm not sure I understand the question. A secure element doesn't have to support PSA_KEY_TYPE_RAW_DATA. I expect that most do: it's of very limited usefulness since the SE can't use that data, but it helps deployment to use a secure element slot to store a certificate for a private key that's in the secure element, and that slot would have the type PSA_KEY_TYPE_RAW_DATA.

Copy link
Contributor

@athoelke athoelke left a comment

Choose a reason for hiding this comment

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

Not sure about the "unspecified/undefined" API behaviour if the key attributes has no valid key slot number? (see comments for further thoughts)

attributes->has_slot_number = 1;
}

/** Retrieve the enrollment algorithm policy from key attributes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Cut and paste bug - description copied from psa_get_key_policy

* \return The slot containing the specified key.
* If the key is not in a secure element,
* or if the caller is not permitted to observe slot numbers,
* the value is unspecified.
Copy link
Contributor

Choose a reason for hiding this comment

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

Slightly 'euww!'

Can we define a symbolic name for PSA_KEY_SLOT_NUMBER_INVALID (or similar), and have the implementation define it as a constant value of type psa_key_slot_number_t? - this API will return that value if the key slot number is not set (or doesn't exist in this implementation).

That way we get implementation efficiency, precision in the spec, and still permit implementations to define the type of psa_key_slot_number_t and use 0 as a valid slot number.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right now, all 2^64 potential values for a slot number are considered valid. I'm not sure this is the best design. I'm sure every driver can afford one invalid value. For consistency with the rest of PSA crypto, 0 should be invalid. Making 0 invalid would also avoid the annoying extra has_slot_number bit. But typical secure elements number their slots from 0 to N-1, so it would require most drivers to do some shifting. So declare all-bits-one invalid (with a symbolic constant of course) and mandate implementations to return it when not applicable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've changed psa_get_key_slot_number to return an error if there is no recorded slot number. See #201.

static inline psa_key_slot_number_t psa_get_key_slot_number(
const psa_key_attributes_t *attributes)
{
return( attributes->slot_number );
Copy link
Contributor

Choose a reason for hiding this comment

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

Will compiler-error if MBEDTLS_PSA_CRYPTO_SE_C is not defined. Yes I know you say "undefined" but this is a painful way to inform developers that they misunderstand the API and how to fix their mistake.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll fix such errors in a batch when I add a build with MBEDTLS_PSA_CRYPTO_SE_C not defined.

* \retval #PSA_ERROR_INVALID_ARGUMENT
* \p attributes specifies a lifetime which is not located
* in a secure eleement.
* \retval #PSA_ERROR_INVALID_ARGUMENT
Copy link
Contributor

Choose a reason for hiding this comment

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

Duplicate error code - this might be confusing in the API documentation? (or is this pattern used elsewhere)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This pattern is used elsewhere: each \retval is an error reason, and some error reasons can map to the same error code. The alternative is something like

 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         \p attributes specifies a lifetime which is not located
 *         in a secure eleement.
 *
 *         Alternatively, …

I have no strong feelings either way, but I'd only change this if we change it elsewhere.

@@ -114,10 +114,14 @@ typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context,
void *persistent_data,
psa_key_lifetime_t lifetime);

#ifdef __DOXYGEN_ONLY__
/* Mbed Crypto defines this type in crypto_extra.h because it is also
* available to applications through implementation-specific extensions. */
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth a comment to indicate that this type is also defined in crypto_types.h - and the definitions need to be identical?

Copy link
Collaborator Author

@gilles-peskine-arm gilles-peskine-arm Jul 22, 2019

Choose a reason for hiding this comment

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

I'd prefer to create a new header file. I made this hack to avoid having to mess with build scripts (including the API build scripts).

Copy link
Collaborator Author

@gilles-peskine-arm gilles-peskine-arm Aug 5, 2019

Choose a reason for hiding this comment

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

For the time being, I'm not adding a header file. I think I'll just wait until the header files are no longer used to generate the documentation so this becomes moot. But I did improve the comment.

#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_get_se_driver( slot->lifetime, &drv, NULL ) )
{
attributes->slot_number = slot->data.se.slot_number;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this also set has_slot_number?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. Fixed.

@gilles-peskine-arm
Copy link
Collaborator Author

Thanks for the reviews. I'll fix the documentation mistakes in a batch later, probably rebased against a new version of #157.

@gilles-peskine-arm gilles-peskine-arm force-pushed the psa-se_driver-register_key branch from 06ca0b2 to 1dfa905 Compare July 24, 2019 19:38
@gilles-peskine-arm gilles-peskine-arm changed the base branch from dev/gilles-peskine/psa-se_driver-create_key to psa-api-1.0-beta July 24, 2019 19:43
@gilles-peskine-arm gilles-peskine-arm changed the base branch from psa-api-1.0-beta to dev/gilles-peskine-arm/psa-se_driver-create_key July 24, 2019 19:45
@gilles-peskine-arm
Copy link
Collaborator Author

I've rebased this work on top of the latest version of #157 . I also made significant changes to the history, to address review comments, to avoid breaking tests, and also to make some design changes.

@athoelke @AndrzejKurek As per our habit I marked the review comments that I've handled with 🚀. I'm still planning to make an improvement pass, but perhaps only after yet another rebase on top of #157 once I've addressed the review comments there.

@gilles-peskine-arm gilles-peskine-arm added the needs: work The pull request needs rework before it can be merged. label Jul 24, 2019
@gilles-peskine-arm gilles-peskine-arm force-pushed the psa-se_driver-register_key branch from 1dfa905 to 6ce6e65 Compare July 26, 2019 13:58
@gilles-peskine-arm gilles-peskine-arm changed the base branch from dev/gilles-peskine-arm/psa-se_driver-create_key to psa-api-1.0-beta July 26, 2019 13:59
@gilles-peskine-arm
Copy link
Collaborator Author

gilles-peskine-arm commented Jul 26, 2019

Now that #157 is merged, I've rebased on top of that and switched the target branch to psa-api-1.0-beta. I'm not planning any more rebases, but I am planning further changes to address review feedback.

@gilles-peskine-arm
Copy link
Collaborator Author

gilles-peskine-arm commented Jul 29, 2019

On second thoughts, I am planning to rebase and even split this PR. It does three four five things which would be better done separately and in the right sequence:

  1. Store the bit size of a key in a secure element, and make sure that psa_get_key_attributes works for an SE key after a restart. → Secure element keys: save the key size #191
  2. Clean up the code a bit. Much more in Tidy up attribute management inside psa_crypto #197
  3. Report the slot number in key attributes. → Add slot number attribute #201
  4. Allow applications to choose a slot number. → Let applications create a key in a specific secure element slot #202
  5. Key registration. → this PR

@gilles-peskine-arm gilles-peskine-arm force-pushed the psa-se_driver-register_key branch from 6ce6e65 to 828963c Compare August 5, 2019 15:18
@gilles-peskine-arm gilles-peskine-arm removed DO NOT MERGE The PR is not intended to be merged (yet). Usually used for a review of worked in progress. needs: design review needs: work The pull request needs rework before it can be merged. labels Aug 5, 2019
@gilles-peskine-arm gilles-peskine-arm added needs: preceding PR Requires another PR to be merged first needs: review The pull request is ready for review. This generally means that it has no known issues. labels Aug 5, 2019
@gilles-peskine-arm gilles-peskine-arm force-pushed the psa-se_driver-register_key branch from 828963c to afb289c Compare August 5, 2019 16:17
Copy link
Contributor

@k-stachowiak k-stachowiak left a comment

Choose a reason for hiding this comment

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

I went through the changes and ran the test suites, and didn't find issues. I've only found two suspicious documentation changes, noted below.

library/psa_crypto.c Outdated Show resolved Hide resolved
include/psa/crypto_se_driver.h Show resolved Hide resolved
PSA_KEY_CREATION_COPY, /**< During psa_copy_key() */

#ifndef __DOXYGEN_ONLY__
/** A key is being registered with mbedtls_psa_register_se_key().
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this in the doxygen ifndef block?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because it's an Mbed Crypto extension, so it shouldn't be included in the PSA specification. We normally resolve this by using different files, but this is an enum so it can't be defined partly in one file and partly in another. __DOXYGEN_ONLY__ is not defined when generating the Mbed Crypto documentation.

AndrzejKurek
AndrzejKurek previously approved these changes Aug 8, 2019
k-stachowiak
k-stachowiak previously approved these changes Aug 8, 2019
@gilles-peskine-arm gilles-peskine-arm removed the needs: review The pull request is ready for review. This generally means that it has no known issues. label Aug 9, 2019
Let psa_start_key_creation know what type of key creation this is. This
will be used at least for key registration in a secure element, which
is a peculiar kind of creation since it uses existing key material.
Pass the key creation method (import/generate/derive/copy) to the
driver methods to allocate or validate a slot number. This allows
drivers to enforce policies such as "this key slot can only be used
for keys generated inside the secure element".
Register an existing key in a secure element.

Minimal implementation that doesn't call any driver method and just
lets the application declare whatever it wants.
When registering a key in a secure element, if the driver has a
p_validate_slot_number method, call it.
@gilles-peskine-arm
Copy link
Collaborator Author

I rebased again to get rid of the commits from preceding PRs, to resolve a trivial conflict in crypto_se_driver.h due to the late changes of the documentation of psa_drv_se_allocate_key_t in #202, and also to reorder commits (I moved "Pass the key creation method to drivers" before "New function mbedtls_psa_register_se_key") to avoid having an unbuildable commit in the middle.

@gilles-peskine-arm gilles-peskine-arm added needs: review The pull request is ready for review. This generally means that it has no known issues. and removed needs: preceding PR Requires another PR to be merged first labels Aug 9, 2019
@gilles-peskine-arm gilles-peskine-arm removed the needs: review The pull request is ready for review. This generally means that it has no known issues. label Aug 9, 2019
@gilles-peskine-arm gilles-peskine-arm merged commit 5a2d152 into ARMmbed:psa-api-1.0-beta Aug 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-spec Issue or PR about the PSA specifications enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants