Skip to content

Secure element key creation foundation #157

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e62b74e
Add public-key export method
gilles-peskine-arm Jun 25, 2019
f989dbe
SE driver lookup functions
gilles-peskine-arm Jun 26, 2019
6e59c42
Split the secure element driver method table memory layout
gilles-peskine-arm Jun 26, 2019
011e428
Look up the SE driver when creating a key
gilles-peskine-arm Jun 26, 2019
f03143a
Change driver key slot numbers to 64 bits
gilles-peskine-arm Jul 12, 2019
7a86da1
Define a driver context structure type
gilles-peskine-arm Jul 12, 2019
8597bc1
Pass the driver context to most driver methods
gilles-peskine-arm Jul 12, 2019
f2223c8
New driver method: allocate
gilles-peskine-arm Jul 12, 2019
94cc42c
Pass a writable pointer to the persistent data when needed
gilles-peskine-arm Jul 12, 2019
5243a20
Driver context manipulation functions
gilles-peskine-arm Jul 12, 2019
8abe6a2
Driver table entries are now mutable
gilles-peskine-arm Jul 12, 2019
73167e1
SE keys: store the slot number in the memory slot
gilles-peskine-arm Jul 12, 2019
cbaff46
SE keys: allocate a slot before creating the key
gilles-peskine-arm Jul 12, 2019
354f767
SE keys: support destroy
gilles-peskine-arm Jul 12, 2019
5d30967
SE keys: support import and export
gilles-peskine-arm Jul 12, 2019
5dc742c
SE keys: smoke test import, export, destroy
gilles-peskine-arm Jul 12, 2019
c8336cb
Implement a transaction record storage for resilience
gilles-peskine-arm Jul 22, 2019
fc76265
Do secure element key creation and destruction in a transaction
gilles-peskine-arm Jul 22, 2019
6032673
Fix Doxygen reference
gilles-peskine-arm Jul 22, 2019
274a263
Make whitespace consistent
gilles-peskine-arm Jul 23, 2019
bfd322f
Use a key attribute structure in the internal storage interface
gilles-peskine-arm Jul 23, 2019
0e8d495
Add the lifetime to the key storage format
gilles-peskine-arm Jul 23, 2019
1df83d4
SE keys: implement persistent storage
gilles-peskine-arm Jul 23, 2019
8b96cad
SE drivers: implement persistent storage
gilles-peskine-arm Jul 23, 2019
1d04b05
Dear check-names, where you accept struct, also accept union.
gilles-peskine-arm Jul 23, 2019
9dd125d
Fix overly complex Doxygen markup
gilles-peskine-arm Jul 23, 2019
105f67f
Move the definition of psa_key_attributes_t to crypto_types.h
gilles-peskine-arm Jul 23, 2019
831ac72
Add transaction file and driver storage; new key file format
gilles-peskine-arm Jul 23, 2019
573bbc1
Error out if a driver tries to store more than ITS can handle
gilles-peskine-arm Jul 23, 2019
28f8f30
SE keys: ensure that functions that lack support properly error out
gilles-peskine-arm Jul 24, 2019
89870eb
Cosmetic improvements in SE driver tests
gilles-peskine-arm Jul 24, 2019
f4ee662
SE keys: error out in key creation function that lack support
gilles-peskine-arm Jul 24, 2019
d1cd766
SE keys: test NOT_SUPPORTED error from generate_key
gilles-peskine-arm Jul 24, 2019
1057366
SE keys: test that no function goes crazy
gilles-peskine-arm Jul 24, 2019
d0e66b0
Turn off secure element support by default
gilles-peskine-arm Jul 24, 2019
f96aefe
Test with secure element support
gilles-peskine-arm Jul 24, 2019
75c126b
Explain some non-obvious parts of the code
gilles-peskine-arm Jul 24, 2019
4b73422
Transaction support: be more future-proof
gilles-peskine-arm Jul 24, 2019
f77a6ac
Fix indentation
gilles-peskine-arm Jul 25, 2019
6a3dd89
Improve alignment in comments
gilles-peskine-arm Jul 25, 2019
adad813
psa_key_slot_is_external exists. Use it.
gilles-peskine-arm Jul 25, 2019
725f22a
Bug fix: save the driver's persistent data in destroy_key
gilles-peskine-arm Jul 25, 2019
60450a4
Improve comments
gilles-peskine-arm Jul 25, 2019
2e0f388
Don't explicitly dereference function pointers
gilles-peskine-arm Jul 25, 2019
0c3ae1f
Improve documentation of SE driver persistent state
gilles-peskine-arm Jul 25, 2019
340b127
psa_destroy_se_key: explain why the error is NOT_PERMITTED
gilles-peskine-arm Jul 25, 2019
4aea103
Bug fix: don't start a transaction for non-SE keys
gilles-peskine-arm Jul 25, 2019
f9bb29e
Add boilerplate to recover a transaction during init
gilles-peskine-arm Jul 25, 2019
2ea06fd
Improve documentation of transaction storage
gilles-peskine-arm Jul 25, 2019
66be51c
If starting a transaction fails, wipe the transaction data
gilles-peskine-arm Jul 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions docs/architecture/mbed-crypto-storage-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,92 @@ The layout of a key file is:
* key material length (4 bytes)
* key material: output of `psa_export_key`
* Any trailing data is rejected on load.

Mbed Crypto TBD
---------------

Tags: TBD

Released in TBD 2019. <br>
Integrated in Mbed OS TBD.

### Changes introduced in TBD

* The layout of a key file now has a lifetime field before the type field.
* Key files can store references to keys in a secure element. In such key files, the key material contains the slot number.

### File namespace on a PSA platform on TBD

Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.

Assumption: the owner identifier is a nonzero value of type `int32_t`.

* Files 0 through 0xfffeffff: unused.
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.

### File namespace on ITS as a library on TBD

Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.

This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.

* File 0: unused.
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
* Files 0x100000000 through 0xffffffffffffffff: unused.

### Non-key files on TBD

File identifiers in the range 0xffff0000 through 0xffffffff are reserved for internal use in Mbed Crypto.

* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): secure element driver storage. The content of the file is the secure element driver's persistent data.
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-tbd).
* Other files are unused and reserved for future use.

### Key file format for TBD

All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.

The layout of a key file is:

* magic (8 bytes): `"PSA\0KEY\0"`.
* version (4 bytes): 0.
* lifetime (4 bytes): `psa_key_lifetime_t` value.
* type (4 bytes): `psa_key_type_t` value.
* policy usage flags (4 bytes): `psa_key_usage_t` value.
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
* key material length (4 bytes).
* key material:
* For a transparent key: output of `psa_export_key`.
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
* Any trailing data is rejected on load.

### Transaction file format for TBD

The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.

All integers are encoded in platform endianness.

All currently existing transactions concern a key in a secure element.

The layout of a transaction file is:

* type (2 bytes): the [transaction type](#transaction-types-on-tbd).
* unused (2 bytes)
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-tbd)).

#### Transaction types on TBD

* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
* The slot in the secure element designated by the slot number.
* The file containing the key metadata designated by the key identifier.
* The driver persistent data.
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
* The slot in the secure element designated by the slot number.
* The file containing the key metadata designated by the key identifier.
* The driver persistent data.
5 changes: 4 additions & 1 deletion include/mbedtls/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1715,12 +1715,15 @@
* Enable secure element support in the Platform Security Architecture
* cryptography API.
*
* \warning This feature is not yet suitable for production. It is provided
* for API evaluation and testing purposes only.
*
* Module: library/psa_crypto_se.c
*
* Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
*
*/
#define MBEDTLS_PSA_CRYPTO_SE_C
//#define MBEDTLS_PSA_CRYPTO_SE_C

/**
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
Expand Down
109 changes: 1 addition & 108 deletions include/psa/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,117 +93,10 @@ psa_status_t psa_crypto_init(void);

/**@}*/

/** \defgroup attributes Key attributes
/** \addtogroup attributes
* @{
*/

/** The type of a structure containing key attributes.
*
* This is an opaque structure that can represent the metadata of a key
* object. Metadata that can be stored in attributes includes:
* - The location of the key in storage, indicated by its key identifier
* and its lifetime.
* - The key's policy, comprising usage flags and a specification of
* the permitted algorithm(s).
* - Information about the key itself: the key type and its size.
* - Implementations may define additional attributes.
*
* The actual key material is not considered an attribute of a key.
* Key attributes do not contain information that is generally considered
* highly confidential.
*
* An attribute structure can be a simple data structure where each function
* `psa_set_key_xxx` sets a field and the corresponding function
* `psa_get_key_xxx` retrieves the value of the corresponding field.
* However, implementations may report values that are equivalent to the
* original one, but have a different encoding. For example, an
* implementation may use a more compact representation for types where
* many bit-patterns are invalid or not supported, and store all values
* that it does not support as a special marker value. In such an
* implementation, after setting an invalid value, the corresponding
* get function returns an invalid value which may not be the one that
* was originally stored.
*
* An attribute structure may contain references to auxiliary resources,
* for example pointers to allocated memory or indirect references to
* pre-calculated values. In order to free such resources, the application
* must call psa_reset_key_attributes(). As an exception, calling
* psa_reset_key_attributes() on an attribute structure is optional if
* the structure has only been modified by the following functions
* since it was initialized or last reset with psa_reset_key_attributes():
* - psa_set_key_id()
* - psa_set_key_lifetime()
* - psa_set_key_type()
* - psa_set_key_bits()
* - psa_set_key_usage_flags()
* - psa_set_key_algorithm()
*
* Before calling any function on a key attribute structure, the application
* must initialize it by any of the following means:
* - Set the structure to all-bits-zero, for example:
* \code
* psa_key_attributes_t attributes;
* memset(&attributes, 0, sizeof(attributes));
* \endcode
* - Initialize the structure to logical zero values, for example:
* \code
* psa_key_attributes_t attributes = {0};
* \endcode
* - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
* for example:
* \code
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* \endcode
* - Assign the result of the function psa_key_attributes_init()
* to the structure, for example:
* \code
* psa_key_attributes_t attributes;
* attributes = psa_key_attributes_init();
* \endcode
*
* A freshly initialized attribute structure contains the following
* values:
*
* - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
* - key identifier: unspecified.
* - type: \c 0.
* - key size: \c 0.
* - usage flags: \c 0.
* - algorithm: \c 0.
*
* A typical sequence to create a key is as follows:
* -# Create and initialize an attribute structure.
* -# If the key is persistent, call psa_set_key_id().
* Also call psa_set_key_lifetime() to place the key in a non-default
* location.
* -# Set the key policy with psa_set_key_usage_flags() and
* psa_set_key_algorithm().
* -# Set the key type with psa_set_key_type().
* Skip this step if copying an existing key with psa_copy_key().
* -# When generating a random key with psa_generate_key() or deriving a key
* with psa_key_derivation_output_key(), set the desired key size with
* psa_set_key_bits().
* -# Call a key creation function: psa_import_key(), psa_generate_key(),
* psa_key_derivation_output_key() or psa_copy_key(). This function reads
* the attribute structure, creates a key with these attributes, and
* outputs a handle to the newly created key.
* -# The attribute structure is now no longer necessary.
* You may call psa_reset_key_attributes(), although this is optional
* with the workflow presented here because the attributes currently
* defined in this specification do not require any additional resources
* beyond the structure itself.
*
* A typical sequence to query a key's attributes is as follows:
* -# Call psa_get_key_attributes().
* -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
* you are interested in.
* -# Call psa_reset_key_attributes() to free any resources that may be
* used by the attribute structure.
*
* Once a key has been created, it is impossible to change its attributes.
*/
typedef struct psa_key_attributes_s psa_key_attributes_t;

/** \def PSA_KEY_ATTRIBUTES_INIT
*
* This macro returns a suitable initializer for a key attribute structure
Expand Down
Loading