1a8e1175bSopenharmony_ci# Mbed TLS driver interface test strategy 2a8e1175bSopenharmony_ci 3a8e1175bSopenharmony_ciThis document describes the test strategy for the driver interfaces in Mbed TLS. Mbed TLS has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed TLS itself; testing drivers is out of scope. 4a8e1175bSopenharmony_ci 5a8e1175bSopenharmony_ciThe driver interfaces are standardized through PSA Cryptography functional specifications. 6a8e1175bSopenharmony_ci 7a8e1175bSopenharmony_ci## Secure element driver interface testing 8a8e1175bSopenharmony_ci 9a8e1175bSopenharmony_ci### Secure element driver interfaces 10a8e1175bSopenharmony_ci 11a8e1175bSopenharmony_ci#### Opaque driver interface 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ciThe [unified driver interface](../../proposed/psa-driver-interface.md) supports both transparent drivers (for accelerators) and opaque drivers (for secure elements). 14a8e1175bSopenharmony_ci 15a8e1175bSopenharmony_ciDrivers exposing this interface need to be registered at compile time by declaring their JSON description file. 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci#### Dynamic secure element driver interface 18a8e1175bSopenharmony_ci 19a8e1175bSopenharmony_ciThe dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../include/psa/crypto_se_driver.h). This is an interface between Mbed TLS and one or more third-party drivers. 20a8e1175bSopenharmony_ci 21a8e1175bSopenharmony_ciThe SE interface consists of one function provided by Mbed TLS (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed TLS, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function. 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci### SE driver interface unit tests 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ciThis section describes unit tests that must be implemented to validate the secure element driver interface. Note that a test case may cover multiple requirements; for example a “good case” test can validate that the proper function is called, that it receives the expected inputs and that it produces the expected outputs. 26a8e1175bSopenharmony_ci 27a8e1175bSopenharmony_ciMany SE driver interface unit tests could be covered by running the existing API tests with a key in a secure element. 28a8e1175bSopenharmony_ci 29a8e1175bSopenharmony_ci#### SE driver registration 30a8e1175bSopenharmony_ci 31a8e1175bSopenharmony_ciThis applies to dynamic drivers only. 32a8e1175bSopenharmony_ci 33a8e1175bSopenharmony_ci* Test `psa_register_se_driver` with valid and with invalid arguments. 34a8e1175bSopenharmony_ci* Make at least one failing call to `psa_register_se_driver` followed by a successful call. 35a8e1175bSopenharmony_ci* Make at least one test that successfully registers the maximum number of drivers and fails to register one more. 36a8e1175bSopenharmony_ci 37a8e1175bSopenharmony_ci#### Dispatch to SE driver 38a8e1175bSopenharmony_ci 39a8e1175bSopenharmony_ciFor each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent): 40a8e1175bSopenharmony_ci 41a8e1175bSopenharmony_ci* Make at least one test with a key in a secure element that checks that the driver method is called. A few API functions involve multiple driver methods; these should validate that all the expected driver methods are called. 42a8e1175bSopenharmony_ci* Make at least one test with a key that is not in a secure element that checks that the driver method is not called. 43a8e1175bSopenharmony_ci* Make at least one test with a key in a secure element with a driver that does not have the requisite method (i.e. the method pointer is `NULL`) but has the substructure containing that method, and check that the return value is `PSA_ERROR_NOT_SUPPORTED`. 44a8e1175bSopenharmony_ci* Make at least one test with a key in a secure element with a driver that does not have the substructure containing that method (i.e. the pointer to the substructure is `NULL`), and check that the return value is `PSA_ERROR_NOT_SUPPORTED`. 45a8e1175bSopenharmony_ci* At least one test should register multiple drivers with a key in each driver and check that the expected driver is called. This does not need to be done for all operations (use a white-box approach to determine if operations may use different code paths to choose the driver). 46a8e1175bSopenharmony_ci* At least one test should register the same driver structure with multiple lifetime values and check that the driver receives the expected lifetime value. 47a8e1175bSopenharmony_ci 48a8e1175bSopenharmony_ciSome methods only make sense as a group (for example a driver that provides the MAC methods must provide all or none). In those cases, test with all of them null and none of them null. 49a8e1175bSopenharmony_ci 50a8e1175bSopenharmony_ci#### SE driver inputs 51a8e1175bSopenharmony_ci 52a8e1175bSopenharmony_ciFor each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent): 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ci* Wherever the specification guarantees parameters that satisfy certain preconditions, check these preconditions whenever practical. 55a8e1175bSopenharmony_ci* If the API function can take parameters that are invalid and must not reach the driver, call the API function with such parameters and verify that the driver method is not called. 56a8e1175bSopenharmony_ci* Check that the expected inputs reach the driver. This may be implicit in a test that checks the outputs if the only realistic way to obtain the correct outputs is to start from the expected inputs (as is often the case for cryptographic material, but not for metadata). 57a8e1175bSopenharmony_ci 58a8e1175bSopenharmony_ci#### SE driver outputs 59a8e1175bSopenharmony_ci 60a8e1175bSopenharmony_ciFor each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed TLS handles the outputs. 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci* Correct outputs. 63a8e1175bSopenharmony_ci* Incorrect outputs such as an invalid output length. 64a8e1175bSopenharmony_ci* Expected errors (e.g. `PSA_ERROR_INVALID_SIGNATURE` from a signature verification method). 65a8e1175bSopenharmony_ci* Unexpected errors. At least test that if the driver returns `PSA_ERROR_GENERIC_ERROR`, this is propagated correctly. 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ciKey creation functions invoke multiple methods and need more complex error handling: 68a8e1175bSopenharmony_ci 69a8e1175bSopenharmony_ci* Check the consequence of errors detected at each stage (slot number allocation or validation, key creation method, storage accesses). 70a8e1175bSopenharmony_ci* Check that the storage ends up in the expected state. At least make sure that no intermediate file remains after a failure. 71a8e1175bSopenharmony_ci 72a8e1175bSopenharmony_ci#### Persistence of SE keys 73a8e1175bSopenharmony_ci 74a8e1175bSopenharmony_ciThe following tests must be performed at least one for each key creation method (import, generate, ...). 75a8e1175bSopenharmony_ci 76a8e1175bSopenharmony_ci* Test that keys in a secure element survive `psa_close_key(); psa_open_key()`. 77a8e1175bSopenharmony_ci* Test that keys in a secure element survive `mbedtls_psa_crypto_free(); psa_crypto_init()`. 78a8e1175bSopenharmony_ci* Test that the driver's persistent data survives `mbedtls_psa_crypto_free(); psa_crypto_init()`. 79a8e1175bSopenharmony_ci* Test that `psa_destroy_key()` does not leave any trace of the key. 80a8e1175bSopenharmony_ci 81a8e1175bSopenharmony_ci#### Resilience for SE drivers 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_ciCreating or removing a key in a secure element involves multiple storage modifications (M<sub>1</sub>, ..., M<sub>n</sub>). If the operation is interrupted by a reset at any point, it must be either rolled back or completed. 84a8e1175bSopenharmony_ci 85a8e1175bSopenharmony_ci* For each potential interruption point (before M<sub>1</sub>, between M<sub>1</sub> and M<sub>2</sub>, ..., after M<sub>n</sub>), call `mbedtls_psa_crypto_free(); psa_crypto_init()` at that point and check that this either rolls back or completes the operation that was started. 86a8e1175bSopenharmony_ci* This must be done for each key creation method and for key destruction. 87a8e1175bSopenharmony_ci* This must be done for each possible flow, including error cases (e.g. a key creation that fails midway due to `OUT_OF_MEMORY`). 88a8e1175bSopenharmony_ci* The recovery during `psa_crypto_init` can itself be interrupted. Test those interruptions too. 89a8e1175bSopenharmony_ci* Two things need to be tested: the key that is being created or destroyed, and the driver's persistent storage. 90a8e1175bSopenharmony_ci* Check both that the storage has the expected content (this can be done by e.g. using a key that is supposed to be present) and does not have any unexpected content (for keys, this can be done by checking that `psa_open_key` fails with `PSA_ERROR_DOES_NOT_EXIST`). 91a8e1175bSopenharmony_ci 92a8e1175bSopenharmony_ciThis requires instrumenting the storage implementation, either to force it to fail at each point or to record successive storage states and replay each of them. Each `psa_its_xxx` function call is assumed to be atomic. 93a8e1175bSopenharmony_ci 94a8e1175bSopenharmony_ci### SE driver system tests 95a8e1175bSopenharmony_ci 96a8e1175bSopenharmony_ci#### Real-world use case 97a8e1175bSopenharmony_ci 98a8e1175bSopenharmony_ciWe must have at least one driver that is close to real-world conditions: 99a8e1175bSopenharmony_ci 100a8e1175bSopenharmony_ci* With its own source tree. 101a8e1175bSopenharmony_ci* Running on actual hardware. 102a8e1175bSopenharmony_ci* Run the full driver validation test suite (which does not yet exist). 103a8e1175bSopenharmony_ci* Run at least one test application (e.g. the Mbed OS TLS example). 104a8e1175bSopenharmony_ci 105a8e1175bSopenharmony_ciThis requirement shall be fulfilled by the [Microchip ATECC508A driver](https://github.com/ARMmbed/mbed-os-atecc608a/). 106a8e1175bSopenharmony_ci 107a8e1175bSopenharmony_ci#### Complete driver 108a8e1175bSopenharmony_ci 109a8e1175bSopenharmony_ciWe should have at least one driver that covers the whole interface: 110a8e1175bSopenharmony_ci 111a8e1175bSopenharmony_ci* With its own source tree. 112a8e1175bSopenharmony_ci* Implementing all the methods. 113a8e1175bSopenharmony_ci* Run the full driver validation test suite (which does not yet exist). 114a8e1175bSopenharmony_ci 115a8e1175bSopenharmony_ciA PKCS#11 driver would be a good candidate. It would be useful as part of our product offering. 116a8e1175bSopenharmony_ci 117a8e1175bSopenharmony_ci## Transparent driver interface testing 118a8e1175bSopenharmony_ci 119a8e1175bSopenharmony_ciThe [unified driver interface](../../proposed/psa-driver-interface.md) defines interfaces for accelerators. 120a8e1175bSopenharmony_ci 121a8e1175bSopenharmony_ci### Test requirements 122a8e1175bSopenharmony_ci 123a8e1175bSopenharmony_ci#### Requirements for transparent driver testing 124a8e1175bSopenharmony_ci 125a8e1175bSopenharmony_ciEvery cryptographic mechanism for which a transparent driver interface exists (key creation, cryptographic operations, …) must be exercised in at least one build. The test must verify that the driver code is called. 126a8e1175bSopenharmony_ci 127a8e1175bSopenharmony_ci#### Requirements for fallback 128a8e1175bSopenharmony_ci 129a8e1175bSopenharmony_ciThe driver interface includes a fallback mechanism so that a driver can reject a request at runtime and let another driver handle the request. For each entry point, there must be at least three test runs with two or more drivers available with driver A configured to fall back to driver B, with one run where A returns `PSA_SUCCESS`, one where A returns `PSA_ERROR_NOT_SUPPORTED` and B is invoked, and one where A returns a different error and B is not invoked. 130a8e1175bSopenharmony_ci 131a8e1175bSopenharmony_ci## Entropy and randomness interface testing 132a8e1175bSopenharmony_ci 133a8e1175bSopenharmony_ciTODO 134