1*62c56f98SSadaf EbrahimiPSA Cryptography API implementation and PSA driver interface 2*62c56f98SSadaf Ebrahimi=========================================================== 3*62c56f98SSadaf Ebrahimi 4*62c56f98SSadaf Ebrahimi## Introduction 5*62c56f98SSadaf Ebrahimi 6*62c56f98SSadaf EbrahimiThe [PSA Cryptography API specification](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface) defines an interface to cryptographic operations for which the Mbed TLS library provides a reference implementation. The PSA Cryptography API specification is complemented by the PSA driver interface specification which defines an interface for cryptoprocessor drivers. 7*62c56f98SSadaf Ebrahimi 8*62c56f98SSadaf EbrahimiThis document describes the high level organization of the Mbed TLS PSA Cryptography API implementation which is tightly related to the PSA driver interface. 9*62c56f98SSadaf Ebrahimi 10*62c56f98SSadaf Ebrahimi## High level organization of the Mbed TLS PSA Cryptography API implementation 11*62c56f98SSadaf EbrahimiIn one sentence, the Mbed TLS PSA Cryptography API implementation is made of a core and PSA drivers as defined in the PSA driver interface. The key point is that software cryptographic operations are organized as PSA drivers: they interact with the core through the PSA driver interface. 12*62c56f98SSadaf Ebrahimi 13*62c56f98SSadaf Ebrahimi### Rationale 14*62c56f98SSadaf Ebrahimi 15*62c56f98SSadaf Ebrahimi* Addressing software and hardware cryptographic implementations through the same C interface reduces the core code size and its call graph complexity. The core and its dispatching to software and hardware implementations are consequently easier to test and validate. 16*62c56f98SSadaf Ebrahimi* The organization of the software cryptographic implementations in drivers promotes modularization of those implementations. 17*62c56f98SSadaf Ebrahimi* As hardware capabilities, software cryptographic functionalities can be described by a JSON driver description file as defined in the PSA driver interface. 18*62c56f98SSadaf Ebrahimi* Along with JSON driver description files, the PSA driver specification defines the deliverables for a driver to be included into the Mbed TLS PSA Cryptography implementation. This provides a natural framework to integrate third party or alternative software implementations of cryptographic operations. 19*62c56f98SSadaf Ebrahimi 20*62c56f98SSadaf Ebrahimi## The Mbed TLS PSA Cryptography API implementation core 21*62c56f98SSadaf Ebrahimi 22*62c56f98SSadaf EbrahimiThe core implements all the APIs as defined in the PSA Cryptography API specification but does not perform on its own any cryptographic operation. The core relies on PSA drivers to actually 23*62c56f98SSadaf Ebrahimiperform the cryptographic operations. The core is responsible for: 24*62c56f98SSadaf Ebrahimi 25*62c56f98SSadaf Ebrahimi* the key store. 26*62c56f98SSadaf Ebrahimi* checking PSA API arguments and translating them into valid arguments for the necessary calls to the PSA driver interface. 27*62c56f98SSadaf Ebrahimi* dispatching the cryptographic operations to the appropriate PSA drivers. 28*62c56f98SSadaf Ebrahimi 29*62c56f98SSadaf EbrahimiThe sketch of an Mbed TLS PSA cryptographic API implementation is thus: 30*62c56f98SSadaf Ebrahimi```C 31*62c56f98SSadaf Ebrahimipsa_status_t psa_api( ... ) 32*62c56f98SSadaf Ebrahimi{ 33*62c56f98SSadaf Ebrahimi psa_status_t status; 34*62c56f98SSadaf Ebrahimi 35*62c56f98SSadaf Ebrahimi /* Pre driver interface call processing: validation of arguments, building 36*62c56f98SSadaf Ebrahimi * of arguments for the call to the driver interface, ... */ 37*62c56f98SSadaf Ebrahimi 38*62c56f98SSadaf Ebrahimi ... 39*62c56f98SSadaf Ebrahimi 40*62c56f98SSadaf Ebrahimi /* Call to the driver interface */ 41*62c56f98SSadaf Ebrahimi status = psa_driver_wrapper_<entry_point>( ... ); 42*62c56f98SSadaf Ebrahimi if( status != PSA_SUCCESS ) 43*62c56f98SSadaf Ebrahimi return( status ); 44*62c56f98SSadaf Ebrahimi 45*62c56f98SSadaf Ebrahimi /* Post driver interface call processing: validation of the values returned 46*62c56f98SSadaf Ebrahimi * by the driver, finalization of the values to return to the caller, 47*62c56f98SSadaf Ebrahimi * clean-up in case of error ... */ 48*62c56f98SSadaf Ebrahimi} 49*62c56f98SSadaf Ebrahimi``` 50*62c56f98SSadaf EbrahimiThe code of most PSA APIs is expected to match precisely the above layout. However, it is likely that the code structure of some APIs will be more complicated with several calls to the driver interface, mainly to encompass a larger variety of hardware designs. For example, to encompass hardware accelerators that are capable of verifying a MAC and those that are only capable of computing a MAC, the psa_mac_verify() API could call first psa_driver_wrapper_mac_verify() and then fallback to psa_driver_wrapper_mac_compute(). 51*62c56f98SSadaf Ebrahimi 52*62c56f98SSadaf EbrahimiThe implementations of `psa_driver_wrapper_<entry_point>` functions are generated by the build system based on the JSON driver description files of the various PSA drivers making up the Mbed TLS PSA Cryptography API implementation. The implementations are splited into two parts. The static ones are generated in a psa_crypto_driver_wrappers.h header file, the non-static ones are generated in a psa_crypto_driver_wrappers_no_static.c C file and the function prototypes declared in a psa_crypto_driver_wrappers_no_static.h header file. 53*62c56f98SSadaf Ebrahimi 54*62c56f98SSadaf EbrahimiThe psa_driver_wrapper_<entry_point>() functions dispatch cryptographic operations to accelerator drivers, secure element drivers as well as to the software implementations of cryptographic operations. 55*62c56f98SSadaf Ebrahimi 56*62c56f98SSadaf EbrahimiNote that the implementation allows to build the library with only a C compiler by shipping a generated file corresponding to a pure software implementation. The driver entry points and their code in this generated file are guarded by pre-processor directives based on PSA_WANT_xyz macros (see [Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](psa-conditional-inclusion-c.html). That way, it is possible to compile and include in the library only the desired cryptographic operations. 57*62c56f98SSadaf Ebrahimi 58*62c56f98SSadaf Ebrahimi### Key creation 59*62c56f98SSadaf Ebrahimi 60*62c56f98SSadaf EbrahimiKey creation implementation in Mbed TLS PSA core is articulated around three internal functions: psa_start_key_creation(), psa_finish_key_creation() and psa_fail_key_creation(). Implementations of key creation PSA APIs, namely psa_import_key(), psa_generate_key(), psa_key_derivation_output_key() and psa_copy_key() go by the following sequence: 61*62c56f98SSadaf Ebrahimi 1. Check the input parameters. 62*62c56f98SSadaf Ebrahimi 2. Call psa_start_key_creation() that allocates a key slot, prepares it with the specified key attributes, and in case of a volatile key assign it a volatile key identifier. 63*62c56f98SSadaf Ebrahimi 3. Generate or copy the key material into the key slot. This entails the allocation of the buffer to store the key material. 64*62c56f98SSadaf Ebrahimi 4. Call psa_finish_key_creation() that mostly saves persistent keys into persistent storage. 65*62c56f98SSadaf Ebrahimi 66*62c56f98SSadaf EbrahimiIn case of any error occurring at step 3 or 4, psa_fail_key_creation() is called. It wipes and cleans the slot especially the key material: reset to zero of the RAM memory that contained the key material, free the allocated buffer. 67*62c56f98SSadaf Ebrahimi 68*62c56f98SSadaf Ebrahimi 69*62c56f98SSadaf Ebrahimi## Mbed TLS PSA Cryptography API implementation drivers 70*62c56f98SSadaf Ebrahimi 71*62c56f98SSadaf EbrahimiA driver of the Mbed TLS PSA Cryptography API implementation (Mbed TLS PSA driver in the following) is a driver in the sense that it is compliant with the PSA driver interface specification. But it is not an actual driver that drives some hardware. It implements cryptographic operations purely in software. 72*62c56f98SSadaf Ebrahimi 73*62c56f98SSadaf EbrahimiAn Mbed TLS PSA driver C file is named psa_crypto_<driver_name>.c and its associated header file psa_crypto_<driver_name>.h. The functions implementing a driver entry point as defined in the PSA driver interface specification are named as mbedtls_psa_<driver name>_<entry point>(). As an example, the psa_crypto_rsa.c and psa_crypto_rsa.h are the files containing the Mbed TLS PSA driver implementing RSA cryptographic operations. This RSA driver implements among other entry points the "import_key" entry point. The function implementing this entry point is named mbedtls_psa_rsa_import_key(). 74*62c56f98SSadaf Ebrahimi 75*62c56f98SSadaf Ebrahimi## How to implement a new cryptographic mechanism 76*62c56f98SSadaf Ebrahimi 77*62c56f98SSadaf EbrahimiSummary of files to modify when adding a new algorithm or key type: 78*62c56f98SSadaf Ebrahimi 79*62c56f98SSadaf Ebrahimi* [ ] PSA Crypto API draft, if not already done — [PSA standardization](#psa-standardization) 80*62c56f98SSadaf Ebrahimi* [ ] `include/psa/crypto_values.h` or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros) 81*62c56f98SSadaf Ebrahimi* [ ] `include/psa/crypto_config.h`, `tests/include/test/drivers/crypto_config_test_driver_extension.h` — [Preprocessor symbols](#preprocessor-symbols) 82*62c56f98SSadaf Ebrahimi* Occasionally `library/check_crypto_config.h` — [Preprocessor symbols](#preprocessor-symbols) 83*62c56f98SSadaf Ebrahimi* [ ] `include/mbedtls/config_psa.h` — [Preprocessor symbols](#preprocessor-symbols) 84*62c56f98SSadaf Ebrahimi* [ ] `library/psa_crypto.c`, `library/psa_crypto_*.[hc]` — [Implementation of the mechanisms](#implementation-of-the-mechanisms) 85*62c56f98SSadaf Ebrahimi* [ ] `include/psa/crypto_builtin_*.h` — [Translucent data structures](#translucent-data-structures) 86*62c56f98SSadaf Ebrahimi* [ ] `tests/suites/test_suite_psa_crypto_metadata.data` — [New functions and macros](#new-functions-and-macros) 87*62c56f98SSadaf Ebrahimi* (If adding `PSA_IS_xxx`) `tests/suites/test_suite_psa_crypto_metadata.function` — [New functions and macros](#new-functions-and-macros) 88*62c56f98SSadaf Ebrahimi* [ ] `tests/suites/test_suite_psa_crypto*.data`, `tests/suites/test_suite_psa_crypto*.function` — [Unit tests](#unit-tests) 89*62c56f98SSadaf Ebrahimi* [ ] `scripts/mbedtls_dev/crypto_knowledge.py`, `scripts/mbedtls_dev/asymmetric_key_data.py` — [Unit tests](#unit-tests) 90*62c56f98SSadaf Ebrahimi* [ ] `ChangeLog.d/*.txt` — changelog entry 91*62c56f98SSadaf Ebrahimi 92*62c56f98SSadaf EbrahimiSummary of files to modify when adding new API functions: 93*62c56f98SSadaf Ebrahimi 94*62c56f98SSadaf Ebrahimi* [ ] `include/psa/crypto.h` and `include/psa/crypto_sizes.h`, or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros) 95*62c56f98SSadaf Ebrahimi* [ ] `library/psa_crypto.c`, `scripts/data_files/driver_templates/*.jinja` — [Implementation of the mechanisms](#implementation-of-the-mechanisms) 96*62c56f98SSadaf Ebrahimi* [ ] If adding stateful functions: `include/psa/crypto_struct.h`, `include/psa/crypto_builtin_*.h`, `include/psa/crypto_driver_contexts_*.h` — [Translucent data structures](#translucent-data-structures) 97*62c56f98SSadaf Ebrahimi* [ ] `tests/suites/test_suite_psa_crypto.data`, `tests/suites/test_suite_psa_crypto.function`, `tests/suites/test_suite_psa_crypto_driver_wrappers.*` — [Unit tests](#unit-tests) 98*62c56f98SSadaf Ebrahimi 99*62c56f98SSadaf EbrahimiNote that this is just a basic guide. In some cases, you won't need to change all the files listed here. In some cases, you may need to change other files. 100*62c56f98SSadaf Ebrahimi 101*62c56f98SSadaf Ebrahimi### PSA standardization 102*62c56f98SSadaf Ebrahimi 103*62c56f98SSadaf EbrahimiTypically, if there's enough demand for a cryptographic mechanism in Mbed TLS, there's enough demand for it to be part of the official PSA Cryptography specification. Therefore the first step before implementing a new mechanism should be to approach the PSA Cryptography working group in Arm for standardization. 104*62c56f98SSadaf Ebrahimi 105*62c56f98SSadaf EbrahimiAt the time of writing, all cryptographic mechanisms that are accessible through `psa_xxx` APIs in in Mbed TLS are current or upcoming PSA standards. Mbed TLS implements some extensions to the PSA API that offer extra integration customization or extra key policies. 106*62c56f98SSadaf Ebrahimi 107*62c56f98SSadaf EbrahimiMbed TLS routinely implements cryptographic mechanisms that are not yet part of a published PSA standard, but that are scheduled to be part of a future version of the standard. The Mbed TLS implementation validates the feasibility of the upcoming PSA standard. The PSA Cryptography working group and the Mbed TLS development team communicate during the elaboration of the new interfaces. 108*62c56f98SSadaf Ebrahimi 109*62c56f98SSadaf Ebrahimi### New functions and macros 110*62c56f98SSadaf Ebrahimi 111*62c56f98SSadaf EbrahimiIf a mechanism requires new functions, they should follow the design guidelines in the PSA Cryptography API specification. 112*62c56f98SSadaf Ebrahimi 113*62c56f98SSadaf EbrahimiFunctions that are part of the current or upcoming API are declared in `include/psa/crypto.h`, apart from structure accessors defined in `include/psa/crypto_struct.h`. Functions that have output buffers have associated sufficient-output-size macros in `include/psa/crypto_sizes.h`. 114*62c56f98SSadaf Ebrahimi 115*62c56f98SSadaf EbrahimiConstants (algorithm identifiers, key type identifiers, etc.) and associated destructor macros (e.g. `PSA_IS_xxx()`) are defined in `include/psa/crypto_values.h`. 116*62c56f98SSadaf Ebrahimi 117*62c56f98SSadaf EbrahimiFunctions and macros that are not intended for standardization, or that are at a stage where the draft standard might still evolve significantly, are declared in `include/psa/crypto_extra.h`. 118*62c56f98SSadaf Ebrahimi 119*62c56f98SSadaf EbrahimiThe PSA Cryptography API specification defines both names and values for certain kinds of constants: algorithms (`PSA_ALG_xxx`), key types (`PSA_KEY_TYPE_xxx`), ECC curve families (`PSA_ECC_FAMILY_xxx`), DH group families (`PSA_DH_FAMILY_xxx`). If Mbed TLS defines an algorithm or a key type that is not part of a current or upcoming PSA standard, pick a value with the `VENDOR` flag set. If Mbed TLS defines an ECC curve or DH group family that is not part of a current or upcoming PSA standard, define a vendor key type and use the family identifier only with this vendor key type. 120*62c56f98SSadaf Ebrahimi 121*62c56f98SSadaf EbrahimiNew constants must have a test case in `tests/suites/test_suite_psa_crypto_metadata.data` that verifies that `PSA_IS_xxx` macros behave properly with the new constant. New `PSA_IS_xxx` macros must be declared in `tests/suites/test_suite_psa_crypto_metadata.function`. 122*62c56f98SSadaf Ebrahimi 123*62c56f98SSadaf Ebrahimi### Preprocessor symbols 124*62c56f98SSadaf Ebrahimi 125*62c56f98SSadaf EbrahimiEach cryptographic mechanism is optional and can be selected by the application at build time. For each feature `PSA_ttt_xxx`: 126*62c56f98SSadaf Ebrahimi 127*62c56f98SSadaf Ebrahimi* The feature is available to applications when the preprocessor symbol `PSA_WANT_ttt_xxx` is defined. These symbols are set: 128*62c56f98SSadaf Ebrahimi * If `MBEDTLS_PSA_CRYPTO_CONFIG` is disabled: based on the available mechanisms in Mbed TLS, deduced from `mbedtls/mbedtls_config.h` by code in `include/mbedtls/config_psa.h`. 129*62c56f98SSadaf Ebrahimi * if `MBEDTLS_PSA_CRYPTO_CONFIG` is enabled: in the application configuration file `include/psa/crypto_config.h` (or `MBEDTLS_PSA_CRYPTO_CONFIG_FILE`, plus `MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`), with code in `include/mbedtls/config_psa.h` deducing the necessary underlying `MBEDTLS_xxx` symbols. 130*62c56f98SSadaf Ebrahimi* For transparent keys (keys that are not in a secure element), the feature is implemented by Mbed TLS if `MBEDTLS_PSA_BUILTIN_ttt_xxx` is defined, and by an accelerator driver if `MBEDTLS_PSA_ACCEL_ttt_xxx` is defined. `MBEDTLS_PSA_BUILTIN_ttt_xxx` constants are set in `include/mbedtls/config_psa.h` based on the application requests `PSA_WANT_ttt_xxx` and the accelerator driver declarations `MBEDTLS_PSA_ACCEL_ttt_xxx`. 131*62c56f98SSadaf Ebrahimi* For the testing of the driver dispatch code, `tests/include/test/drivers/crypto_config_test_driver_extension.h` sets additional `MBEDTLS_PSA_ACCEL_xxx` symbols. 132*62c56f98SSadaf Ebrahimi 133*62c56f98SSadaf EbrahimiFor more details, see *[Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](../proposed/psa-conditional-inclusion-c.html)*. 134*62c56f98SSadaf Ebrahimi 135*62c56f98SSadaf EbrahimiSome mechanisms require other mechanisms. For example, you can't do GCM without a block cipher, or RSA-PSS without RSA keys. When mechanism A requires mechanism B, `include/mbedtls/config_psa.h` ensures that B is enabled whenever A is enabled. When mechanism A requires at least one of a set {B1, B2, B3, ...} but there is no particular reason why enabling A would enable any of the specific Bi's, it's up to the application to choose Bi's and the file `library/check_crypto_config.h` contains compile-time constraints to ensure that at least one Bi is enabled. 136*62c56f98SSadaf Ebrahimi 137*62c56f98SSadaf Ebrahimi### Implementation of the mechanisms 138*62c56f98SSadaf Ebrahimi 139*62c56f98SSadaf EbrahimiThe general structure of a cryptographic operation function is: 140*62c56f98SSadaf Ebrahimi 141*62c56f98SSadaf Ebrahimi1. API function defined in `library/psa_crypto.c`. The entry point performs generic checks that don't depend on whether the mechanism is implemented in software or in a driver and looks up keys in the key store. 142*62c56f98SSadaf Ebrahimi2. Driver dispatch code in `scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja`, `scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja` or files included from there. 143*62c56f98SSadaf Ebrahimi3. Built-in implementation in `library/psa_crypto_*.c` (with function declarations in the corresponding `.h` file). These files typically contain the implementation of modes of operation over basic building blocks that are defined elsewhere. For example, HMAC is implemented in `library/psa_crypto_mac.c` but the underlying hash functions are implemented in `library/sha*.c` and `library/md*.c`. 144*62c56f98SSadaf Ebrahimi4. Basic cryptographic building blocks in `library/*.c`. 145*62c56f98SSadaf Ebrahimi 146*62c56f98SSadaf EbrahimiWhen implementing a new algorithm or key type, there are typically things to change in `library/crypto.c` (e.g. buffer size calculations, algorithm/key-type compatibility) and in the built-in implementation, but not in the driver dispatch code. 147*62c56f98SSadaf Ebrahimi 148*62c56f98SSadaf Ebrahimi### Translucent data structures 149*62c56f98SSadaf Ebrahimi 150*62c56f98SSadaf EbrahimiSome mechanisms require state to be kept between function calls. Keys and key-like data is kept in the key store, which PSA manages internally. Other state, for example the state of multipart operations, is kept in structures allocated by the caller. 151*62c56f98SSadaf Ebrahimi 152*62c56f98SSadaf EbrahimiThe size of operation structures needs to be known at compile time, since callers may allocate them on the stack. Therefore these structures are defined in a public header: `include/psa/crypto_struct.h` for the parts that are independent of the underlying implementation, `include/psa/crypto_builtin_*` for parts that are specific to the Mbed TLS built-in implementation, `include/psa/crypto_driver_*.h` for structures implemented by drivers. 153*62c56f98SSadaf Ebrahimi 154*62c56f98SSadaf Ebrahimi### Unit tests 155*62c56f98SSadaf Ebrahimi 156*62c56f98SSadaf EbrahimiA number of unit tests are automatically generated by `tests/scripts/generate_psa_tests.py` based on the algorithms and key types declared in `include/psa/crypto_values.h` and `include/psa/crypto_extra.h`: 157*62c56f98SSadaf Ebrahimi 158*62c56f98SSadaf Ebrahimi* Attempt to create a key with a key type that is not supported. 159*62c56f98SSadaf Ebrahimi* Attempt to perform an operation with a combination of key type and algorithm that is not valid or not supported. 160*62c56f98SSadaf Ebrahimi* Storage and retrieval of a persistent key. 161*62c56f98SSadaf Ebrahimi 162*62c56f98SSadaf EbrahimiWhen adding a new key type or algorithm: 163*62c56f98SSadaf Ebrahimi 164*62c56f98SSadaf Ebrahimi* `scripts/mbedtls_dev/crypto_knowledge.py` contains knowledge about the compatibility of key types, key sizes and algorithms. 165*62c56f98SSadaf Ebrahimi* `scripts/mbedtls_dev/asymmetric_key_data.py` contains valid key data for asymmetric key types. 166*62c56f98SSadaf Ebrahimi 167*62c56f98SSadaf EbrahimiOther things need to be tested manually, either in `tests/suites/test_sutie_psa_crypto.data` or in another file. For example (this is not an exhaustive list): 168*62c56f98SSadaf Ebrahimi 169*62c56f98SSadaf Ebrahimi* Known answer tests. 170*62c56f98SSadaf Ebrahimi* Potential edge cases (e.g. data less/equal/more than the block size, number equal to zero in asymmetric cryptography). 171*62c56f98SSadaf Ebrahimi* Tests with invalid keys (e.g. wrong size or format). 172*62c56f98SSadaf Ebrahimi* Tests with invalid data (e.g. wrong size or format, output buffer too small, invalid padding). 173*62c56f98SSadaf Ebrahimi* For new functions: incorrect function call sequence, driver dispatch (in `tests/suites/test_suite_psa_crypto_driver_wrappers.*`). 174*62c56f98SSadaf Ebrahimi* For key derivation algorithms: variation on the sequence of input steps, variation on the output size. 175*62c56f98SSadaf Ebrahimi 176