Skip to content

Commit

Permalink
Merge pull request #3547 from ronald-cron-arm/psa-openless
Browse files Browse the repository at this point in the history
Openless PSA crypto APIs implementation
  • Loading branch information
gilles-peskine-arm committed Nov 20, 2020
2 parents cb0a9ee + 3a4f0e3 commit 662deb3
Show file tree
Hide file tree
Showing 56 changed files with 2,853 additions and 1,658 deletions.
17 changes: 17 additions & 0 deletions ChangeLog.d/psa-openless.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Features
* In the PSA API, it is no longer necessary to open persistent keys:
operations now accept the key identifier. The type psa_key_handle_t is now
identical to psa_key_id_t instead of being platform-defined. This bridges
the last major gap to compliance with the PSA Cryptography specification
version 1.0.0. Opening persistent keys is still supported for backward
compatibility, but will be deprecated and later removed in future
releases.

Bugfix
* psa_set_key_id() now also sets the lifetime to persistent for keys located
in a secure element.
* Attempting to create a volatile key with a non-zero key identifier now
fails. Previously the key identifier was just ignored when creating a
volatile key.
* Attempting to create or register a key with a key identifier in the vendor
range now fails.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ The design goals of the PSA cryptography API include:

* The API distinguishes caller memory from internal memory, which allows the library to be implemented in an isolated space for additional security. Library calls can be implemented as direct function calls if isolation is not desired, and as remote procedure calls if isolation is desired.
* The structure of internal data is hidden to the application, which allows substituting alternative implementations at build time or run time, for example, in order to take advantage of hardware accelerators.
* All access to the keys happens through handles, which allows support for external cryptoprocessors that is transparent to applications.
* All access to the keys happens through key identifiers, which allows support for external cryptoprocessors that is transparent to applications.
* The interface to algorithms is generic, favoring algorithm agility.
* The interface is designed to be easy to use and hard to accidentally misuse.

Expand Down
4 changes: 2 additions & 2 deletions docs/architecture/testing/invasive-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Resources include:

* Memory.
* Files in storage (PSA API only — in the Mbed TLS API, black-box unit tests are sufficient).
* Key handles (PSA API only).
* Key slots (PSA API only).
* Key slots in a secure element (PSA SE HAL).
* Communication handles (PSA crypto service only).

Expand All @@ -116,7 +116,7 @@ When code should clean up resources, how do we know that they have truly been cl

* Zeroization of confidential data after use.
* Freeing memory.
* Closing key handles.
* Freeing key slots.
* Freeing key slots in a secure element.
* Deleting files in storage (PSA API only).

Expand Down
64 changes: 32 additions & 32 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ To use the Mbed Crypto APIs, call `psa_crypto_init()` before calling any other A
### Importing a key

To use a key for cryptography operations in Mbed Crypto, you need to first
import it. Importing the key creates a handle that refers to the key for use
import it. The import operation returns the identifier of the key for use
with other function calls.

**Prerequisites to importing keys:**
Expand All @@ -76,7 +76,7 @@ void import_a_key(const uint8_t *key, size_t key_len)
{
psa_status_t status;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_handle_t handle;
psa_key_id_t key;

printf("Import an AES key...\t");
fflush(stdout);
Expand All @@ -95,7 +95,7 @@ void import_a_key(const uint8_t *key, size_t key_len)
psa_set_key_bits(&attributes, 128);

/* Import the key */
status = psa_import_key(&attributes, key, key_len, &handle);
status = psa_import_key(&attributes, key, key_len, &key);
if (status != PSA_SUCCESS) {
printf("Failed to import key\n");
return;
Expand All @@ -106,7 +106,7 @@ void import_a_key(const uint8_t *key, size_t key_len)
psa_reset_key_attributes(&attributes);

/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);

mbedtls_psa_crypto_free();
}
Expand Down Expand Up @@ -135,7 +135,7 @@ void sign_a_message_using_rsa(const uint8_t *key, size_t key_len)
0xa9, 0xe8, 0xcc, 0xac, 0xd0, 0xf6, 0x54, 0x5c};
uint8_t signature[PSA_SIGNATURE_MAX_SIZE] = {0};
size_t signature_length;
psa_key_handle_t handle;
psa_key_id_t key;
printf("Sign a message...\t");
fflush(stdout);
Expand All @@ -154,14 +154,14 @@ void sign_a_message_using_rsa(const uint8_t *key, size_t key_len)
psa_set_key_bits(&attributes, 1024);
/* Import the key */
status = psa_import_key(&attributes, key, key_len, &handle);
status = psa_import_key(&attributes, key, key_len, &key);
if (status != PSA_SUCCESS) {
printf("Failed to import key\n");
return;
}
/* Sign message using the key */
status = psa_sign_hash(handle, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
status = psa_sign_hash(key, PSA_ALG_RSA_PKCS1V15_SIGN_RAW,
hash, sizeof(hash),
signature, sizeof(signature),
&signature_length);
Expand All @@ -176,7 +176,7 @@ void sign_a_message_using_rsa(const uint8_t *key, size_t key_len)
psa_reset_key_attributes(&attributes);
/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);
mbedtls_psa_crypto_free();
}
Expand All @@ -188,7 +188,7 @@ Mbed Crypto supports encrypting and decrypting messages using various symmetric

**Prerequisites to working with the symmetric cipher API:**
* Initialize the library with a successful call to `psa_crypto_init()`.
* Have a handle to a symmetric key. This key's usage flags must include `PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption.
* Have a symmetric key. This key's usage flags must include `PSA_KEY_USAGE_ENCRYPT` to allow encryption or `PSA_KEY_USAGE_DECRYPT` to allow decryption.

**To encrypt a message with a symmetric cipher:**
1. Allocate an operation (`psa_cipher_operation_t`) structure to pass to the cipher functions.
Expand All @@ -213,7 +213,7 @@ void encrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
size_t iv_len;
uint8_t output[block_size];
size_t output_len;
psa_key_handle_t handle;
psa_key_id_t key;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;

printf("Encrypt with cipher...\t");
Expand All @@ -232,15 +232,15 @@ void encrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, key_len, &handle);
status = psa_import_key(&attributes, key, key_len, &key);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);

/* Encrypt the plaintext */
status = psa_cipher_encrypt_setup(&operation, handle, alg);
status = psa_cipher_encrypt_setup(&operation, key, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin cipher operation\n");
return;
Expand Down Expand Up @@ -268,7 +268,7 @@ void encrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
psa_cipher_abort(&operation);

/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);

mbedtls_psa_crypto_free();
}
Expand Down Expand Up @@ -298,7 +298,7 @@ void decrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
uint8_t iv[block_size] = ENCRYPTED_WITH_IV;
uint8_t output[block_size];
size_t output_len;
psa_key_handle_t handle;
psa_key_id_t key;
printf("Decrypt with cipher...\t");
fflush(stdout);
Expand All @@ -316,15 +316,15 @@ void decrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, key_len, &handle);
status = psa_import_key(&attributes, key, key_len, &key);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);
/* Decrypt the ciphertext */
status = psa_cipher_decrypt_setup(&operation, handle, alg);
status = psa_cipher_decrypt_setup(&operation, key, alg);
if (status != PSA_SUCCESS) {
printf("Failed to begin cipher operation\n");
return;
Expand Down Expand Up @@ -352,7 +352,7 @@ void decrypt_with_symmetric_ciphers(const uint8_t *key, size_t key_len)
psa_cipher_abort(&operation);
/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);
mbedtls_psa_crypto_free();
}
Expand Down Expand Up @@ -592,8 +592,8 @@ derived from the key, salt and info provided:
PSA_KEY_DERIVATION_OPERATION_INIT;
size_t derived_bits = 128;
size_t capacity = PSA_BITS_TO_BYTES(derived_bits);
psa_key_handle_t base_key;
psa_key_handle_t derived_key;
psa_key_id_t base_key;
psa_key_id_t derived_key;
printf("Derive a key (HKDF)...\t");
fflush(stdout);
Expand Down Expand Up @@ -702,7 +702,7 @@ This example shows how to authenticate and encrypt a message:
size_t output_length = 0;
size_t tag_length = 16;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_handle_t handle;
psa_key_id_t key;

printf("Authenticate encrypt...\t");
fflush(stdout);
Expand All @@ -726,11 +726,11 @@ This example shows how to authenticate and encrypt a message:
psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, sizeof(key), &handle);
status = psa_import_key(&attributes, key, sizeof(key), &key);
psa_reset_key_attributes(&attributes);

/* Authenticate and encrypt */
status = psa_aead_encrypt(handle, PSA_ALG_CCM,
status = psa_aead_encrypt(key, PSA_ALG_CCM,
nonce, sizeof(nonce),
additional_data, sizeof(additional_data),
input_data, sizeof(input_data),
Expand All @@ -747,7 +747,7 @@ This example shows how to authenticate and encrypt a message:
free(output_data);

/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);

mbedtls_psa_crypto_free();
```
Expand All @@ -756,7 +756,7 @@ This example shows how to authenticate and decrypt a message:
```C
psa_status_t status;
static const uint8_t key[] = {
static const uint8_t key_data[] = {
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF };
static const uint8_t nonce[] = {
Expand All @@ -773,7 +773,7 @@ This example shows how to authenticate and decrypt a message:
size_t output_size = 0;
size_t output_length = 0;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_handle_t handle;
psa_key_id_t key;
printf("Authenticate decrypt...\t");
fflush(stdout);
Expand All @@ -797,15 +797,15 @@ This example shows how to authenticate and decrypt a message:
psa_set_key_algorithm(&attributes, PSA_ALG_CCM);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 128);
status = psa_import_key(&attributes, key, sizeof(key), &handle);
status = psa_import_key(&attributes, key_data, sizeof(key_data), &key);
if (status != PSA_SUCCESS) {
printf("Failed to import a key\n");
return;
}
psa_reset_key_attributes(&attributes);
/* Authenticate and decrypt */
status = psa_aead_decrypt(handle, PSA_ALG_CCM,
status = psa_aead_decrypt(key, PSA_ALG_CCM,
nonce, sizeof(nonce),
additional_data, sizeof(additional_data),
input_data, sizeof(input_data),
Expand All @@ -822,7 +822,7 @@ This example shows how to authenticate and decrypt a message:
free(output_data);
/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);
mbedtls_psa_crypto_free();
```
Expand All @@ -848,7 +848,7 @@ Mbed Crypto provides a simple way to generate a key or key pair.
size_t exported_length = 0;
static uint8_t exported[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits)];
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_handle_t handle;
psa_key_id_t key;

printf("Generate a key pair...\t");
fflush(stdout);
Expand All @@ -867,14 +867,14 @@ Mbed Crypto provides a simple way to generate a key or key pair.
psa_set_key_type(&attributes,
PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&attributes, key_bits);
status = psa_generate_key(&attributes, &handle);
status = psa_generate_key(&attributes, &key);
if (status != PSA_SUCCESS) {
printf("Failed to generate key\n");
return;
}
psa_reset_key_attributes(&attributes);

status = psa_export_public_key(handle, exported, sizeof(exported),
status = psa_export_public_key(key, exported, sizeof(exported),
&exported_length);
if (status != PSA_SUCCESS) {
printf("Failed to export public key %ld\n", status);
Expand All @@ -884,7 +884,7 @@ Mbed Crypto provides a simple way to generate a key or key pair.
printf("Exported a public key\n");

/* Destroy the key */
psa_destroy_key(handle);
psa_destroy_key(key);

mbedtls_psa_crypto_free();
```
Expand Down
4 changes: 0 additions & 4 deletions docs/proposed/psa-driver-developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ A driver therefore consists of:

Mbed TLS calls driver entry points [as specified in the PSA Cryptography Driver Interface specification](psa-driver-interface.html#driver-entry-points) except as otherwise indicated in this section.

### Key handles

Mbed TLS currently implements the interface for opening and closing persistent keys from version 1.0 beta 3 of the PSA Crypto specification. As a consequence, functions that operate on an existing key take an argument of type `psa_key_handle_t` instead of `psa_key_id_t`. Functions that create a new key take an argument of type `psa_key_handle_t *` instead of `psa_key_id_t *`.

## Building and testing your driver

<!-- TODO -->
Expand Down
4 changes: 2 additions & 2 deletions docs/proposed/psa-driver-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,8 @@ psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_size(&attributes, 128);
psa_set_key_algorithm(&attributes, PSA_ALG_GCM);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_key_handle_t handle = 0;
psa_generate_key(&attributes, &handle);
psa_key_id_t key;
psa_generate_key(&attributes, &key);
```

## Using opaque drivers from an application
Expand Down
5 changes: 5 additions & 0 deletions include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,11 @@
#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
#endif

#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \
defined(MBEDTLS_USE_PSA_CRYPTO)
#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO."
#endif

#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
Expand Down
2 changes: 1 addition & 1 deletion include/mbedtls/cipher_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ typedef enum
typedef struct
{
psa_algorithm_t alg;
psa_key_handle_t slot;
psa_key_id_t slot;
mbedtls_cipher_psa_key_ownership slot_state;
} mbedtls_cipher_context_psa;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
Expand Down
2 changes: 1 addition & 1 deletion include/mbedtls/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@
* which is currently hard-coded to be int32_t.
*
* Note that this option is meant for internal use only and may be removed
* without notice.
* without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO.
*/
//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER

Expand Down

0 comments on commit 662deb3

Please sign in to comment.