Commit graph

500 commits

Author SHA1 Message Date
Gilles Peskine c8000c005a Add slot_number attribute
Add a slot_number field to psa_key_attributes_t and getter/setter
functions. Since slot numbers can have the value 0, indicate the
presence of the field via a separate flag.

In psa_get_key_attributes(), report the slot number if the key is in a
secure element.

When creating a key, for now, applications cannot choose a slot
number. A subsequent commit will add this capability in the secure
element HAL.
2019-08-08 10:58:09 +02:00
Gilles Peskine 91e8c33f48 Add infrastructure for key attribute flags
Add infrastructure for internal, external and dual-use flags, with a
compile-time check (if static_assert is available) to ensure that the
same numerical value doesn't get declared for two different purposes
in crypto_struct.h (external or dual-use) and
psa_crypto_core.h (internal).
2019-08-08 10:58:09 +02:00
Gilles Peskine 0c77b0e2f9
Merge pull request #198 from gilles-peskine-arm/psa-api-1.0-beta-merge_development_20190801
Merge mbed-crypto/development into psa-api-1.0-beta
2019-08-08 10:24:53 +02:00
Gilles Peskine f181eca350 Fix psa_generate_random for >1024 bytes
mbedtls_ctr_drbg_random can only return up to
MBEDTLS_CTR_DRBG_MAX_REQUEST (normally 1024) bytes at a time. So if
more than that is requested, call mbedtls_ctr_drbg_random in a loop.
2019-08-07 13:49:00 +02:00
Gilles Peskine a6b2f60b4c Fix double free in psa_generate_key when psa_generate_random fails
When psa_generate_random fails, psa_generate_key_internal frees the
key buffer but a the pointer to the now-freed buffer in the slot. Then
psa_generate_key calls psa_fail_key_creation which sees the pointer
and calls free() again.

This bug was introduced by ff5f0e7221
"Implement atomic-creation psa_{generate,generator_import}_key" which
changed how psa_generate_key() cleans up on errors. I went through the
code and could not find a similar bug in cleanup on an error during
key creation.

Fix #207
2019-08-07 13:43:09 +02:00
Gilles Peskine 1b9505c451 Correct some comments 2019-08-07 10:59:45 +02:00
Gilles Peskine 8908c5e81c Make psa_calculate_key_bits return psa_key_bits_t
This is cleaner and solves a complaint from MSVC about truncation from
size_t to psa_key_bits_t.
2019-07-31 18:55:00 +02:00
Gilles Peskine 72c8c5b352 Merge remote-tracking branch 'upstream-crypto/development' into psa-api-1.0-beta-merge_development_20190801
Conflict resolution:
* `scripts/config.pl`:
  Take the exclusion of `MBEDTLS_PSA_CRYPTO_SE_C` from the API branch.
  Take the removal of `MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C` (obsolete) from
  the development branch.
* `tests/scripts/all.sh`:
  Multiple instances of factoring a sequence of `config.pl` calls into
  a mere `config.pl baremetal` in the development branch, and a change in
  the composition of `baremetal` in the API branch. In each case, take the
  version from development.
* `tests/suites/test_suite_psa_crypto_slot_management.function`:
  A function became non-static in development and disappeared in the API
  branch. Keep the version from the API branch. Functions need to be
  non-static if they're defined but unused in some configurations,
  which is not the case for any function in this file at the moment.
* `tests/suites/test_suite_psa_crypto.function`:
  Consecutive changes in the two branches, reconciled.
2019-07-31 17:47:49 +02:00
Gilles Peskine 1b8594a218 More refactoring: consolidate attribute validation
Consolidate attribute validation at the beginning of key creation into
a single function. Improve comments.
2019-07-31 17:21:46 +02:00
Gilles Peskine 3825e14e65 Fix policy validity check on key creation.
Add a non-regression test.
2019-07-31 16:54:38 +02:00
Gilles Peskine 41e50d26ea Remove "allocated" flag from key slots
The flag to mark key slots as allocated was introduced to mark slots
that are claimed and in use, but do not have key material yet, at a
time when creating a key used several API functions: allocate a slot,
then progressively set its metadata, and finally create the key
material. Now that all of these steps are combined into a single
API function call, the notion of allocated-but-not-filled slot is no
longer relevant. So remove the corresponding flag.

A slot is occupied iff there is a key in it. (For a key in a secure
element, the key material is not present, but the slot contains the
key metadata.) This key must have a type which is nonzero, so use this
as an indicator that a slot is in use.
2019-07-31 16:54:38 +02:00
Gilles Peskine 76aa09c9a9 Take advantage of psa_core_key_attributes_t internally #2
Key creation and psa_get_key_attributes
2019-07-31 16:54:37 +02:00
Gilles Peskine b46bef2f76 Store the key size in the slot in memory
There is now a field for the key size in the key slot in memory. Use
it.

This makes psa_get_key_attributes() marginally faster at the expense
of memory that is available anyway in the current memory layout (16
bits for the size, 16 bits for flags). That's not the goal, though:
the goal is to simplify the code, in particular to make it more
uniform between transparent keys (whose size can be recomputed) and
keys in secure elements (whose size cannot be recomputed).

For keys in a secure element, the bit size is now saved by serializing
the type psa_key_bits_t (which is an alias for uint16_t) rather than
size_t.
2019-07-31 14:16:50 +02:00
Gilles Peskine 4ed0e6f11a Switch storage functions over to psa_core_key_attributes_t 2019-07-31 14:15:27 +02:00
Gilles Peskine 8e3387029d Use psa_core_key_attributes_t in key slots in memory
Change the type of key slots in memory to use
psa_core_key_attributes_t rather than separate fields. The goal is to
simplify some parts of the code. This commit only does the mechanical
replacement, not the substitution.

The bit-field `allocate` is now a flag `PSA_KEY_SLOT_FLAG_ALLOCATED`
in the `flags` field.

Write accessor functions for flags.

Key slots now contain a bit size field which is currently unused.
Subsequent commits will make use of it.
2019-07-31 14:15:27 +02:00
Gilles Peskine 68cc433b5b Store key sizes in 16 bits in attributes
This is larger than the maximum key size introduced in the previous
commit, by design.

Make some room for flags (not used yet).
2019-07-30 21:08:38 +02:00
Gilles Peskine c744d99386 Limit keys to 65528 bits
65528 bits is more than any reasonable key until we start supporting
post-quantum cryptography.

This limit is chosen to allow bit-sizes to be stored in 16 bits, with
65535 left to indicate an invalid value. It's a whole number of bytes,
which facilitates some calculations, in particular allowing a key of
exactly PSA_CRYPTO_MAX_STORAGE_SIZE to be created but not one bit
more.

As a resource usage limit, this is arguably too large, but that's out
of scope of the current commit.

Test that key import, generation and derivation reject overly large
sizes.
2019-07-30 20:58:33 +02:00
Gilles Peskine 7e0cff90b9 Move attribute fields to a substructure
Move the "core attributes" to a substructure of psa_key_attribute_t.
The motivation is to be able to use the new structure
psa_core_key_attributes_t internally.
2019-07-30 20:58:27 +02:00
Gilles Peskine e60d1d08a4 SE keys: save the bit size in storage
For a key in a secure element, save the bit size alongside the slot
number.

This is a quick-and-dirty implementation where the storage format
depends on sizeof(size_t), which is fragile. This should be replaced
by a more robust implementation before going into production.
2019-07-29 18:11:09 +02:00
Gilles Peskine 1801740a7c SE driver: report the bit size on key import
Add a parameter to the key import method of a secure element driver to
make it report the key size in bits. This is necessary (otherwise the
core has no idea what the bit-size is), and making import report it is
easier than adding a separate method (for other key creation methods,
this information is an input, not an output).
2019-07-29 18:07:09 +02:00
Gilles Peskine dc5bfe9784 SE keys: implement and test psa_get_key_attributes 2019-07-29 18:07:03 +02:00
Gilles Peskine 424f89453b SE keys: store the bit size internally (partial implementation)
This commit blindingly copies the size from the attributes. This is
not correct for copy and import.
2019-07-29 17:06:06 +02:00
Gilles Peskine adb1c52149
Merge pull request #157 from gilles-peskine-arm/psa-se_driver-create_key
Secure element key creation foundation
2019-07-26 14:39:55 +02:00
Gilles Peskine 66be51c35d If starting a transaction fails, wipe the transaction data
Nothing has been saved to disk yet, but there is stale data in
psa_crypto_transaction. This stale data should not be reused, but do
wipe it to reduce the risk of it mattering somehow in the future.
2019-07-26 13:23:51 +02:00
Gilles Peskine f9bb29ec26 Add boilerplate to recover a transaction during init 2019-07-25 17:52:59 +02:00
Gilles Peskine 4aea1036c6 Bug fix: don't start a transaction for non-SE keys 2019-07-25 17:38:34 +02:00
Gilles Peskine 2e0f388d2a Don't explicitly dereference function pointers
Be stylistically consistent.
2019-07-25 11:42:19 +02:00
Gilles Peskine 60450a4812 Improve comments 2019-07-25 11:32:45 +02:00
Gilles Peskine 725f22a545 Bug fix: save the driver's persistent data in destroy_key 2019-07-25 11:32:27 +02:00
Gilles Peskine adad813d7b psa_key_slot_is_external exists. Use it. 2019-07-25 11:32:27 +02:00
Gilles Peskine f77a6acf83 Fix indentation 2019-07-25 10:51:03 +02:00
Gilles Peskine 4b73422318 Transaction support: be more future-proof
If there's ever a non-SE-related transaction, make sure it gets
handled during init.
2019-07-24 15:56:31 +02:00
Gilles Peskine f4ee662868 SE keys: error out in key creation function that lack support 2019-07-24 13:44:30 +02:00
Gilles Peskine 28f8f3068f SE keys: ensure that functions that lack support properly error out
Introduce a new function psa_get_transparent_key which returns
NOT_SUPPORTED if the key is in a secure element. Use this function in
functions that don't support keys in a secure element.

After this commit, all functions that access a key slot directly via
psa_get_key_slot or psa_get_key_from_slot rather than via
psa_get_transparent_key have at least enough support for secure
elements not to crash or otherwise cause undefined behavior. Lesser
bad behavior such as wrong results or resource leakage is still
possible in error cases.
2019-07-24 13:30:31 +02:00
Gilles Peskine 1df83d4f5b SE keys: implement persistent storage
For a key in a secure element, persist the key slot.

This is implemented in the nominal case. Failures may not be handled
properly.
2019-07-23 16:13:14 +02:00
Gilles Peskine bfd322ff34 Use a key attribute structure in the internal storage interface
Pass information via a key attribute structure rather than as separate
parameters to psa_crypto_storage functions. This makes it easier to
maintain the code when the metadata of a key evolves.

This has negligible impact on code size (+4B with "gcc -Os" on x86_64).
2019-07-23 13:31:54 +02:00
Gilles Peskine fc76265385 Do secure element key creation and destruction in a transaction
Key creation and key destruction for a key in a secure element both
require updating three pieces of data: the key data in the secure
element, the key metadata in internal storage, and the SE driver's
persistent data. Perform these actions in a transaction so that
recovery is possible if the action is interrupted midway.
2019-07-22 19:46:22 +02:00
Gilles Peskine c11c4dcf95 Favor stdint.h types in internal types
Use uint8_t for PSA buffers. Keep unsigned char for generic libc
buffers and for mbedtls buffers.
2019-07-15 11:17:53 +02:00
Gilles Peskine 7228da25f9 Favor stdint.h types in implementation-specific API 2019-07-15 11:16:18 +02:00
Andrew Thoelke 163639b830 Apply same changes to implementation source code 2019-07-15 11:14:56 +02:00
Gilles Peskine 5d309672af SE keys: support import and export 2019-07-12 23:47:28 +02:00
Gilles Peskine 354f7671f4 SE keys: support destroy
When destroying a key in a secure element, call the driver's destroy
method and update the driver's persistent data in storage.
2019-07-12 23:46:38 +02:00
Gilles Peskine cbaff467ef SE keys: allocate a slot before creating the key 2019-07-12 23:46:04 +02:00
Gilles Peskine 73167e128f SE keys: store the slot number in the memory slot 2019-07-12 23:44:37 +02:00
Gilles Peskine 8abe6a2d5c Driver table entries are now mutable
Since driver table entries contain the driver context, which is
mutable, they can't be const anymore.
2019-07-12 23:42:20 +02:00
Gilles Peskine 011e4284a1 Look up the SE driver when creating a key
When creating a key with a lifetime that places it in a secure
element, retrieve the appropriate driver table entry.

This commit doesn't yet achieve behavior: so far the code only
retrieves the driver, it doesn't call the driver.
2019-07-12 11:47:50 +02:00
Adrian L. Shaw 2282cfa660 Remove GMAC algorithm (for now)
It can't be implemented with the current version of the API
2019-07-11 15:51:45 +01:00
Jaeden Amero c19dcebbdd
Merge pull request #154 from yanesca/iotcrypt-789-update-tls-prf-to-multipart
Update TLS 1.2 PRF to multipart API
2019-07-04 11:53:04 +01:00
Janos Follath d6dce9f4f3 Fix zero-length seed or label in TLS 1.2 PRF
The psa_tls12_prf_set_seed() and psa_tls12_prf_set_label() functions did
not work on platforms where malloc(0) returns NULL.

It does not affect the TLS use case but these PRFs are used in other
protocols as well and might not be used the same way. For example EAP
uses the TLS PRF with an empty secret. (This would not trigger the bug,
but is a strong indication that it is not safe to assume that certain
inputs to this function are not zero length.)

The conditional block includes the memcpy() call as well to avoid
passing a NULL pointer as a parameter resulting in undefined behaviour.

The current tests are already using zero length label and seed, there is
no need to add new test for this bug.
2019-07-04 09:11:38 +01:00
Janos Follath 0c1ed84258 Improve style 2019-06-28 15:10:06 +01:00