xref: /aosp_15_r20/external/mbedtls/docs/architecture/testing/driver-interface-test-strategy.md (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi# Mbed TLS driver interface test strategy
2*62c56f98SSadaf Ebrahimi
3*62c56f98SSadaf EbrahimiThis 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.
4*62c56f98SSadaf Ebrahimi
5*62c56f98SSadaf EbrahimiThe driver interfaces are standardized through PSA Cryptography functional specifications.
6*62c56f98SSadaf Ebrahimi
7*62c56f98SSadaf Ebrahimi## Secure element driver interface testing
8*62c56f98SSadaf Ebrahimi
9*62c56f98SSadaf Ebrahimi### Secure element driver interfaces
10*62c56f98SSadaf Ebrahimi
11*62c56f98SSadaf Ebrahimi#### Opaque driver interface
12*62c56f98SSadaf Ebrahimi
13*62c56f98SSadaf EbrahimiThe [unified driver interface](../../proposed/psa-driver-interface.md) supports both transparent drivers (for accelerators) and opaque drivers (for secure elements).
14*62c56f98SSadaf Ebrahimi
15*62c56f98SSadaf EbrahimiDrivers exposing this interface need to be registered at compile time by declaring their JSON description file.
16*62c56f98SSadaf Ebrahimi
17*62c56f98SSadaf Ebrahimi#### Dynamic secure element driver interface
18*62c56f98SSadaf Ebrahimi
19*62c56f98SSadaf EbrahimiThe 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.
20*62c56f98SSadaf Ebrahimi
21*62c56f98SSadaf EbrahimiThe 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.
22*62c56f98SSadaf Ebrahimi
23*62c56f98SSadaf Ebrahimi### SE driver interface unit tests
24*62c56f98SSadaf Ebrahimi
25*62c56f98SSadaf EbrahimiThis 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.
26*62c56f98SSadaf Ebrahimi
27*62c56f98SSadaf EbrahimiMany SE driver interface unit tests could be covered by running the existing API tests with a key in a secure element.
28*62c56f98SSadaf Ebrahimi
29*62c56f98SSadaf Ebrahimi#### SE driver registration
30*62c56f98SSadaf Ebrahimi
31*62c56f98SSadaf EbrahimiThis applies to dynamic drivers only.
32*62c56f98SSadaf Ebrahimi
33*62c56f98SSadaf Ebrahimi* Test `psa_register_se_driver` with valid and with invalid arguments.
34*62c56f98SSadaf Ebrahimi* Make at least one failing call to `psa_register_se_driver` followed by a successful call.
35*62c56f98SSadaf Ebrahimi* Make at least one test that successfully registers the maximum number of drivers and fails to register one more.
36*62c56f98SSadaf Ebrahimi
37*62c56f98SSadaf Ebrahimi#### Dispatch to SE driver
38*62c56f98SSadaf Ebrahimi
39*62c56f98SSadaf EbrahimiFor each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
40*62c56f98SSadaf Ebrahimi
41*62c56f98SSadaf Ebrahimi* 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.
42*62c56f98SSadaf Ebrahimi* Make at least one test with a key that is not in a secure element that checks that the driver method is not called.
43*62c56f98SSadaf Ebrahimi* 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`.
44*62c56f98SSadaf Ebrahimi* 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`.
45*62c56f98SSadaf Ebrahimi* 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).
46*62c56f98SSadaf Ebrahimi* At least one test should register the same driver structure with multiple lifetime values and check that the driver receives the expected lifetime value.
47*62c56f98SSadaf Ebrahimi
48*62c56f98SSadaf EbrahimiSome 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.
49*62c56f98SSadaf Ebrahimi
50*62c56f98SSadaf Ebrahimi#### SE driver inputs
51*62c56f98SSadaf Ebrahimi
52*62c56f98SSadaf EbrahimiFor each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
53*62c56f98SSadaf Ebrahimi
54*62c56f98SSadaf Ebrahimi* Wherever the specification guarantees parameters that satisfy certain preconditions, check these preconditions whenever practical.
55*62c56f98SSadaf Ebrahimi* 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.
56*62c56f98SSadaf Ebrahimi* 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).
57*62c56f98SSadaf Ebrahimi
58*62c56f98SSadaf Ebrahimi#### SE driver outputs
59*62c56f98SSadaf Ebrahimi
60*62c56f98SSadaf EbrahimiFor 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.
61*62c56f98SSadaf Ebrahimi
62*62c56f98SSadaf Ebrahimi* Correct outputs.
63*62c56f98SSadaf Ebrahimi* Incorrect outputs such as an invalid output length.
64*62c56f98SSadaf Ebrahimi* Expected errors (e.g. `PSA_ERROR_INVALID_SIGNATURE` from a signature verification method).
65*62c56f98SSadaf Ebrahimi* Unexpected errors. At least test that if the driver returns `PSA_ERROR_GENERIC_ERROR`, this is propagated correctly.
66*62c56f98SSadaf Ebrahimi
67*62c56f98SSadaf EbrahimiKey creation functions invoke multiple methods and need more complex error handling:
68*62c56f98SSadaf Ebrahimi
69*62c56f98SSadaf Ebrahimi* Check the consequence of errors detected at each stage (slot number allocation or validation, key creation method, storage accesses).
70*62c56f98SSadaf Ebrahimi* Check that the storage ends up in the expected state. At least make sure that no intermediate file remains after a failure.
71*62c56f98SSadaf Ebrahimi
72*62c56f98SSadaf Ebrahimi#### Persistence of SE keys
73*62c56f98SSadaf Ebrahimi
74*62c56f98SSadaf EbrahimiThe following tests must be performed at least one for each key creation method (import, generate, ...).
75*62c56f98SSadaf Ebrahimi
76*62c56f98SSadaf Ebrahimi* Test that keys in a secure element survive `psa_close_key(); psa_open_key()`.
77*62c56f98SSadaf Ebrahimi* Test that keys in a secure element survive `mbedtls_psa_crypto_free(); psa_crypto_init()`.
78*62c56f98SSadaf Ebrahimi* Test that the driver's persistent data survives `mbedtls_psa_crypto_free(); psa_crypto_init()`.
79*62c56f98SSadaf Ebrahimi* Test that `psa_destroy_key()` does not leave any trace of the key.
80*62c56f98SSadaf Ebrahimi
81*62c56f98SSadaf Ebrahimi#### Resilience for SE drivers
82*62c56f98SSadaf Ebrahimi
83*62c56f98SSadaf EbrahimiCreating 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.
84*62c56f98SSadaf Ebrahimi
85*62c56f98SSadaf Ebrahimi* 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.
86*62c56f98SSadaf Ebrahimi* This must be done for each key creation method and for key destruction.
87*62c56f98SSadaf Ebrahimi* This must be done for each possible flow, including error cases (e.g. a key creation that fails midway due to `OUT_OF_MEMORY`).
88*62c56f98SSadaf Ebrahimi* The recovery during `psa_crypto_init` can itself be interrupted. Test those interruptions too.
89*62c56f98SSadaf Ebrahimi* Two things need to be tested: the key that is being created or destroyed, and the driver's persistent storage.
90*62c56f98SSadaf Ebrahimi* 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`).
91*62c56f98SSadaf Ebrahimi
92*62c56f98SSadaf EbrahimiThis 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.
93*62c56f98SSadaf Ebrahimi
94*62c56f98SSadaf Ebrahimi### SE driver system tests
95*62c56f98SSadaf Ebrahimi
96*62c56f98SSadaf Ebrahimi#### Real-world use case
97*62c56f98SSadaf Ebrahimi
98*62c56f98SSadaf EbrahimiWe must have at least one driver that is close to real-world conditions:
99*62c56f98SSadaf Ebrahimi
100*62c56f98SSadaf Ebrahimi* With its own source tree.
101*62c56f98SSadaf Ebrahimi* Running on actual hardware.
102*62c56f98SSadaf Ebrahimi* Run the full driver validation test suite (which does not yet exist).
103*62c56f98SSadaf Ebrahimi* Run at least one test application (e.g. the Mbed OS TLS example).
104*62c56f98SSadaf Ebrahimi
105*62c56f98SSadaf EbrahimiThis requirement shall be fulfilled by the [Microchip ATECC508A driver](https://github.com/ARMmbed/mbed-os-atecc608a/).
106*62c56f98SSadaf Ebrahimi
107*62c56f98SSadaf Ebrahimi#### Complete driver
108*62c56f98SSadaf Ebrahimi
109*62c56f98SSadaf EbrahimiWe should have at least one driver that covers the whole interface:
110*62c56f98SSadaf Ebrahimi
111*62c56f98SSadaf Ebrahimi* With its own source tree.
112*62c56f98SSadaf Ebrahimi* Implementing all the methods.
113*62c56f98SSadaf Ebrahimi* Run the full driver validation test suite (which does not yet exist).
114*62c56f98SSadaf Ebrahimi
115*62c56f98SSadaf EbrahimiA PKCS#11 driver would be a good candidate. It would be useful as part of our product offering.
116*62c56f98SSadaf Ebrahimi
117*62c56f98SSadaf Ebrahimi## Transparent driver interface testing
118*62c56f98SSadaf Ebrahimi
119*62c56f98SSadaf EbrahimiThe [unified driver interface](../../proposed/psa-driver-interface.md) defines interfaces for accelerators.
120*62c56f98SSadaf Ebrahimi
121*62c56f98SSadaf Ebrahimi### Test requirements
122*62c56f98SSadaf Ebrahimi
123*62c56f98SSadaf Ebrahimi#### Requirements for transparent driver testing
124*62c56f98SSadaf Ebrahimi
125*62c56f98SSadaf EbrahimiEvery 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.
126*62c56f98SSadaf Ebrahimi
127*62c56f98SSadaf Ebrahimi#### Requirements for fallback
128*62c56f98SSadaf Ebrahimi
129*62c56f98SSadaf EbrahimiThe 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.
130*62c56f98SSadaf Ebrahimi
131*62c56f98SSadaf Ebrahimi## Entropy and randomness interface testing
132*62c56f98SSadaf Ebrahimi
133*62c56f98SSadaf EbrahimiTODO
134