1*62c56f98SSadaf EbrahimiPSA Cryptoprocessor Driver Interface 2*62c56f98SSadaf Ebrahimi==================================== 3*62c56f98SSadaf Ebrahimi 4*62c56f98SSadaf EbrahimiThis document describes an interface for cryptoprocessor drivers in the PSA cryptography API. This interface complements the [PSA Cryptography API specification](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface), which describes the interface between a PSA Cryptography implementation and an application. 5*62c56f98SSadaf Ebrahimi 6*62c56f98SSadaf EbrahimiThis specification is work in progress and should be considered to be in a beta stage. There is ongoing work to implement this interface in Mbed TLS, which is the reference implementation of the PSA Cryptography API. At this stage, Arm does not expect major changes, but minor changes are expected based on experience from the first implementation and on external feedback. 7*62c56f98SSadaf Ebrahimi 8*62c56f98SSadaf EbrahimiFor a practical guide, with a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html). 9*62c56f98SSadaf Ebrahimi 10*62c56f98SSadaf Ebrahimi## Introduction 11*62c56f98SSadaf Ebrahimi 12*62c56f98SSadaf Ebrahimi### Purpose of the driver interface 13*62c56f98SSadaf Ebrahimi 14*62c56f98SSadaf EbrahimiThe PSA Cryptography API defines an interface that allows applications to perform cryptographic operations in a uniform way regardless of how the operations are performed. Under the hood, different keys may be stored and used in different hardware or in different logical partitions, and different algorithms may involve different hardware or software components. 15*62c56f98SSadaf Ebrahimi 16*62c56f98SSadaf EbrahimiThe driver interface allows implementations of the PSA Cryptography API to be built compositionally. An implementation of the PSA Cryptography API is composed of a **core** and zero or more **drivers**. The core handles key management, enforces key usage policies, and dispatches cryptographic operations either to the applicable driver or to built-in code. 17*62c56f98SSadaf Ebrahimi 18*62c56f98SSadaf EbrahimiFunctions in the PSA Cryptography API invoke functions in the core. Code from the core calls drivers as described in the present document. 19*62c56f98SSadaf Ebrahimi 20*62c56f98SSadaf Ebrahimi### Types of drivers 21*62c56f98SSadaf Ebrahimi 22*62c56f98SSadaf EbrahimiThe PSA Cryptography driver interface supports two types of cryptoprocessors, and accordingly two types of drivers. 23*62c56f98SSadaf Ebrahimi 24*62c56f98SSadaf Ebrahimi* **Transparent** drivers implement cryptographic operations on keys that are provided in cleartext at the beginning of each operation. They are typically used for hardware **accelerators**. When a transparent driver is available for a particular combination of parameters (cryptographic algorithm, key type and size, etc.), it is used instead of the default software implementation. Transparent drivers can also be pure software implementations that are distributed as plug-ins to a PSA Cryptography implementation (for example, an alternative implementation with different performance characteristics, or a certified implementation). 25*62c56f98SSadaf Ebrahimi* **Opaque** drivers implement cryptographic operations on keys that can only be used inside a protected environment such as a **secure element**, a hardware security module, a smartcard, a secure enclave, etc. An opaque driver is invoked for the specific [key location](#lifetimes-and-locations) that the driver is registered for: the dispatch is based on the key's lifetime. 26*62c56f98SSadaf Ebrahimi 27*62c56f98SSadaf Ebrahimi### Requirements 28*62c56f98SSadaf Ebrahimi 29*62c56f98SSadaf EbrahimiThe present specification was designed to fulfill the following high-level requirements. 30*62c56f98SSadaf Ebrahimi 31*62c56f98SSadaf Ebrahimi[Req.plugins] It is possible to combine multiple drivers from different providers into the same implementation, without any prior arrangement other than choosing certain names and values from disjoint namespaces. 32*62c56f98SSadaf Ebrahimi 33*62c56f98SSadaf Ebrahimi[Req.compile] It is possible to compile the code of each driver and of the core separately, and link them together. A small amount of glue code may need to be compiled once the list of drivers is available. 34*62c56f98SSadaf Ebrahimi 35*62c56f98SSadaf Ebrahimi[Req.types] Support drivers for the following types of hardware: accelerators that operate on keys in cleartext; cryptoprocessors that can wrap keys with a built-in keys but not store user keys; and cryptoprocessors that store key material. 36*62c56f98SSadaf Ebrahimi 37*62c56f98SSadaf Ebrahimi[Req.portable] The interface between drivers and the core does not involve any platform-specific consideration. Driver calls are simple C function calls. Interactions with platform-specific hardware happen only inside the driver (and in fact a driver need not involve any hardware at all). 38*62c56f98SSadaf Ebrahimi 39*62c56f98SSadaf Ebrahimi[Req.location] Applications can tell which location values correspond to which secure element drivers. 40*62c56f98SSadaf Ebrahimi 41*62c56f98SSadaf Ebrahimi[Req.fallback] Accelerator drivers can specify that they do not fully support a cryptographic mechanism and that a fallback to core code may be necessary. Conversely, if an accelerator fully supports cryptographic mechanism, the core must be able to omit code for this mechanism. 42*62c56f98SSadaf Ebrahimi 43*62c56f98SSadaf Ebrahimi[Req.mechanisms] Drivers can specify which mechanisms they support. A driver's code will not be invoked for cryptographic mechanisms that it does not support. 44*62c56f98SSadaf Ebrahimi 45*62c56f98SSadaf Ebrahimi## Overview of drivers 46*62c56f98SSadaf Ebrahimi 47*62c56f98SSadaf Ebrahimi### Deliverables for a driver 48*62c56f98SSadaf Ebrahimi 49*62c56f98SSadaf EbrahimiTo write a driver, you need to implement some functions with C linkage, and to declare these functions in a **driver description file**. The driver description file declares which functions the driver implements and what cryptographic mechanisms they support. If the driver description references custom types, macros or constants, you also need to provide C header files defining those elements. 50*62c56f98SSadaf Ebrahimi 51*62c56f98SSadaf EbrahimiThe concrete syntax for a driver description file is JSON. The structure of this JSON file is specified in the section [“Driver description syntax”](#driver-description-syntax). 52*62c56f98SSadaf Ebrahimi 53*62c56f98SSadaf EbrahimiA driver therefore consists of: 54*62c56f98SSadaf Ebrahimi 55*62c56f98SSadaf Ebrahimi* A driver description file (in JSON format). 56*62c56f98SSadaf Ebrahimi* C header files defining the types required by the driver description. The names of these header files are declared in the driver description file. 57*62c56f98SSadaf Ebrahimi* An object file compiled for the target platform defining the entry point functions specified by the driver description. Implementations may allow drivers to be provided as source files and compiled with the core instead of being pre-compiled. 58*62c56f98SSadaf Ebrahimi 59*62c56f98SSadaf EbrahimiHow to provide the driver description file, the C header files and the object code is implementation-dependent. 60*62c56f98SSadaf Ebrahimi 61*62c56f98SSadaf Ebrahimi### Driver description syntax 62*62c56f98SSadaf Ebrahimi 63*62c56f98SSadaf EbrahimiThe concrete syntax for a driver description file is JSON. 64*62c56f98SSadaf Ebrahimi 65*62c56f98SSadaf EbrahimiIn addition to the properties described here, any JSON object may have a property called `"_comment"` of type string, which will be ignored. 66*62c56f98SSadaf Ebrahimi 67*62c56f98SSadaf EbrahimiPSA Cryptography core implementations may support additional properties. Such properties must use names consisting of the implementation's name, a slash, and additional characters. For example, the Yoyodyne implementation may use property names such as `"yoyodyne/foo"` and `"yoyodyne/widgets/girth"`. 68*62c56f98SSadaf Ebrahimi 69*62c56f98SSadaf Ebrahimi#### Driver description list 70*62c56f98SSadaf Ebrahimi 71*62c56f98SSadaf EbrahimiPSA Cryptography core implementations should support multiple drivers. The driver description files are passed to the implementation as an ordered list in an unspecified manner. This may be, for example, a list of file names passed on a command line, or a JSON list whose elements are individual driver descriptions. 72*62c56f98SSadaf Ebrahimi 73*62c56f98SSadaf Ebrahimi#### Driver description top-level element 74*62c56f98SSadaf Ebrahimi 75*62c56f98SSadaf EbrahimiA driver description is a JSON object containing the following properties: 76*62c56f98SSadaf Ebrahimi 77*62c56f98SSadaf Ebrahimi* `"prefix"` (mandatory, string). This must be a valid, non-empty prefix for a C identifier. All the types and functions provided by the driver have a name that starts with this prefix unless overridden with a `"name"` element in the applicable capability as described below. 78*62c56f98SSadaf Ebrahimi* `"type"` (mandatory, string). One of `"transparent"` or `"opaque"`. 79*62c56f98SSadaf Ebrahimi* `"headers"` (optional, array of strings). A list of header files. These header files must define the types, macros and constants referenced by the driver description. They may declare the entry point functions, but this is not required. They may include other PSA headers and standard headers of the platform. Whether they may include other headers is implementation-specific. If omitted, the list of headers is empty. The header files must be present at the specified location relative to a directory on the compiler's include path when compiling glue code between the core and the drivers. 80*62c56f98SSadaf Ebrahimi* `"capabilities"` (mandatory, array of [capabilities](#driver-description-capability)). 81*62c56f98SSadaf EbrahimiA list of **capabilities**. Each capability describes a family of functions that the driver implements for a certain class of cryptographic mechanisms. 82*62c56f98SSadaf Ebrahimi* `"key_context"` (not permitted for transparent drivers, mandatory for opaque drivers): information about the [representation of keys](#key-format-for-opaque-drivers). 83*62c56f98SSadaf Ebrahimi* `"persistent_state_size"` (not permitted for transparent drivers, optional for opaque drivers, integer or string). The size in bytes of the [persistent state of the driver](#opaque-driver-persistent-state). This may be either a non-negative integer or a C constant expression of type `size_t`. 84*62c56f98SSadaf Ebrahimi* `"location"` (not permitted for transparent drivers, optional for opaque drivers, integer or string). The [location value](#lifetimes-and-locations) for which this driver is invoked. In other words, this determines the lifetimes for which the driver is invoked. This may be either a non-negative integer or a C constant expression of type `psa_key_location_t`. 85*62c56f98SSadaf Ebrahimi 86*62c56f98SSadaf Ebrahimi### Driver description capability 87*62c56f98SSadaf Ebrahimi 88*62c56f98SSadaf Ebrahimi#### Capability syntax 89*62c56f98SSadaf Ebrahimi 90*62c56f98SSadaf EbrahimiA capability declares a family of functions that the driver implements for a certain class of cryptographic mechanisms. The capability specifies which key types and algorithms are covered and the names of the types and functions that implement it. 91*62c56f98SSadaf Ebrahimi 92*62c56f98SSadaf EbrahimiA capability is a JSON object containing the following properties: 93*62c56f98SSadaf Ebrahimi 94*62c56f98SSadaf Ebrahimi* `"entry_points"` (mandatory, list of strings). Each element is the name of a [driver entry point](#driver-entry-points) or driver entry point family. An entry point is a function defined by the driver. If specified, the core will invoke this capability of the driver only when performing one of the specified operations. The driver must implement all the specified entry points, as well as the types if applicable. 95*62c56f98SSadaf Ebrahimi* `"algorithms"` (optional, list of strings). Each element is an [algorithm specification](#algorithm-specifications). If specified, the core will invoke this capability of the driver only when performing one of the specified algorithms. If omitted, the core will invoke this capability for all applicable algorithms. 96*62c56f98SSadaf Ebrahimi* `"key_types"` (optional, list of strings). Each element is a [key type specification](#key-type-specifications). If specified, the core will invoke this capability of the driver only for operations involving a key with one of the specified key types. If omitted, the core will invoke this capability of the driver for all applicable key types. 97*62c56f98SSadaf Ebrahimi* `"key_sizes"` (optional, list of integers). If specified, the core will invoke this capability of the driver only for operations involving a key with one of the specified key sizes. If omitted, the core will invoke this capability of the driver for all applicable key sizes. Key sizes are expressed in bits. 98*62c56f98SSadaf Ebrahimi* `"names"` (optional, object). A mapping from entry point names described by the `"entry_points"` property, to the name of the C function in the driver that implements the corresponding function. If a function is not listed here, name of the driver function that implements it is the driver's prefix followed by an underscore (`_`) followed by the function name. If this property is omitted, it is equivalent to an empty object (so each entry point *suffix* is implemented by a function called *prefix*`_`*suffix*). 99*62c56f98SSadaf Ebrahimi* `"fallback"` (optional for transparent drivers, not permitted for opaque drivers, boolean). If present and true, the driver may return `PSA_ERROR_NOT_SUPPORTED`, in which case the core should call another driver or use built-in code to perform this operation. If absent or false, the driver is expected to fully support the mechanisms described by this capability. See the section “[Fallback](#fallback)” for more information. 100*62c56f98SSadaf Ebrahimi 101*62c56f98SSadaf Ebrahimi#### Capability semantics 102*62c56f98SSadaf Ebrahimi 103*62c56f98SSadaf EbrahimiWhen the PSA Cryptography implementation performs a cryptographic mechanism, it invokes available driver entry points as described in the section [“Driver entry points”](#driver-entry-points). 104*62c56f98SSadaf Ebrahimi 105*62c56f98SSadaf EbrahimiA driver is considered available for a cryptographic mechanism that invokes a given entry point if all of the following conditions are met: 106*62c56f98SSadaf Ebrahimi 107*62c56f98SSadaf Ebrahimi* The driver specification includes a capability whose `"entry_points"` list either includes the entry point or includes an entry point family that includes the entry point. 108*62c56f98SSadaf Ebrahimi* If the mechanism involves an algorithm: 109*62c56f98SSadaf Ebrahimi * either the capability does not have an `"algorithms"` property; 110*62c56f98SSadaf Ebrahimi * or the value of the capability's `"algorithms"` property includes an [algorithm specification](#algorithm-specifications) that matches this algorithm. 111*62c56f98SSadaf Ebrahimi* If the mechanism involves a key: 112*62c56f98SSadaf Ebrahimi * either the key is transparent (its location is `PSA_KEY_LOCATION_LOCAL_STORAGE`) and the driver is transparent; 113*62c56f98SSadaf Ebrahimi * or the key is opaque (its location is not `PSA_KEY_LOCATION_LOCAL_STORAGE`) and the driver is an opaque driver whose location is the key's location. 114*62c56f98SSadaf Ebrahimi* If the mechanism involves a key: 115*62c56f98SSadaf Ebrahimi * either the capability does not have a `"key_types"` property; 116*62c56f98SSadaf Ebrahimi * or the value of the capability's `"key_types"` property includes a [key type specification](#key-type-specifications) that matches this algorithm. 117*62c56f98SSadaf Ebrahimi* If the mechanism involves a key: 118*62c56f98SSadaf Ebrahimi * either the capability does not have a `"key_sizes"` property; 119*62c56f98SSadaf Ebrahimi * or the value of the capability's `"key_sizes"` property includes the key's size. 120*62c56f98SSadaf Ebrahimi 121*62c56f98SSadaf EbrahimiIf a driver includes multiple applicable capabilities for a given combination of entry point, algorithm, key type and key size, and all the capabilities map the entry point to the same function name, the driver is considered available for this cryptographic mechanism. If a driver includes multiple applicable capabilities for a given combination of entry point, algorithm, key type and key size, and at least two of these capabilities map the entry point to the different function names, the driver specification is invalid. 122*62c56f98SSadaf Ebrahimi 123*62c56f98SSadaf EbrahimiIf multiple transparent drivers have applicable capabilities for a given combination of entry point, algorithm, key type and key size, the first matching driver in the [specification list](#driver-description-list) is invoked. If the capability has [fallback](#fallback) enabled and the first driver returns `PSA_ERROR_NOT_SUPPORTED`, the next matching driver is invoked, and so on. 124*62c56f98SSadaf Ebrahimi 125*62c56f98SSadaf EbrahimiIf multiple opaque drivers have the same location, the list of driver specifications is invalid. 126*62c56f98SSadaf Ebrahimi 127*62c56f98SSadaf Ebrahimi#### Capability examples 128*62c56f98SSadaf Ebrahimi 129*62c56f98SSadaf EbrahimiExample 1: the following capability declares that the driver can perform deterministic ECDSA signatures (but not signature verification) using any hash algorithm and any curve that the core supports. If the prefix of this driver is `"acme"`, the function that performs the signature is called `acme_sign_hash`. 130*62c56f98SSadaf Ebrahimi``` 131*62c56f98SSadaf Ebrahimi{ 132*62c56f98SSadaf Ebrahimi "entry_points": ["sign_hash"], 133*62c56f98SSadaf Ebrahimi "algorithms": ["PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH)"], 134*62c56f98SSadaf Ebrahimi} 135*62c56f98SSadaf Ebrahimi``` 136*62c56f98SSadaf Ebrahimi 137*62c56f98SSadaf EbrahimiExample 2: the following capability declares that the driver can perform deterministic ECDSA signatures using SHA-256 or SHA-384 with a SECP256R1 or SECP384R1 private key (with either hash being possible in combination with either curve). If the prefix of this driver is `"acme"`, the function that performs the signature is called `acme_sign_hash`. 138*62c56f98SSadaf Ebrahimi``` 139*62c56f98SSadaf Ebrahimi{ 140*62c56f98SSadaf Ebrahimi "entry_points": ["sign_hash"], 141*62c56f98SSadaf Ebrahimi "algorithms": ["PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)", 142*62c56f98SSadaf Ebrahimi "PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384)"], 143*62c56f98SSadaf Ebrahimi "key_types": ["PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)"], 144*62c56f98SSadaf Ebrahimi "key_sizes": [256, 384] 145*62c56f98SSadaf Ebrahimi} 146*62c56f98SSadaf Ebrahimi``` 147*62c56f98SSadaf Ebrahimi 148*62c56f98SSadaf Ebrahimi### Algorithm and key specifications 149*62c56f98SSadaf Ebrahimi 150*62c56f98SSadaf Ebrahimi#### Algorithm specifications 151*62c56f98SSadaf Ebrahimi 152*62c56f98SSadaf EbrahimiAn algorithm specification is a string consisting of a `PSA_ALG_xxx` macro that specifies a cryptographic algorithm or an algorithm wildcard policy defined by the PSA Cryptography API. If the macro takes arguments, the string must have the syntax of a C macro call and each argument must be an algorithm specification or a decimal or hexadecimal literal with no suffix, depending on the expected type of argument. 153*62c56f98SSadaf Ebrahimi 154*62c56f98SSadaf EbrahimiSpaces are optional after commas. Whether other whitespace is permitted is implementation-specific. 155*62c56f98SSadaf Ebrahimi 156*62c56f98SSadaf EbrahimiValid examples: 157*62c56f98SSadaf Ebrahimi``` 158*62c56f98SSadaf EbrahimiPSA_ALG_SHA_256 159*62c56f98SSadaf EbrahimiPSA_ALG_HMAC(PSA_ALG_SHA_256) 160*62c56f98SSadaf EbrahimiPSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)) 161*62c56f98SSadaf EbrahimiPSA_ALG_RSA_PSS(PSA_ALG_ANY_HASH) 162*62c56f98SSadaf Ebrahimi``` 163*62c56f98SSadaf Ebrahimi 164*62c56f98SSadaf Ebrahimi#### Key type specifications 165*62c56f98SSadaf Ebrahimi 166*62c56f98SSadaf EbrahimiAn algorithm specification is a string consisting of a `PSA_KEY_TYPE_xxx` macro that specifies a key type defined by the PSA Cryptography API. If the macro takes an argument, the string must have the syntax of a C macro call and each argument must be the name of a constant of suitable type (curve or group). 167*62c56f98SSadaf Ebrahimi 168*62c56f98SSadaf EbrahimiThe name `_` may be used instead of a curve or group to indicate that the capability concerns all curves or groups. 169*62c56f98SSadaf Ebrahimi 170*62c56f98SSadaf EbrahimiValid examples: 171*62c56f98SSadaf Ebrahimi``` 172*62c56f98SSadaf EbrahimiPSA_KEY_TYPE_AES 173*62c56f98SSadaf EbrahimiPSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) 174*62c56f98SSadaf EbrahimiPSA_KEY_TYPE_ECC_KEY_PAIR(_) 175*62c56f98SSadaf Ebrahimi``` 176*62c56f98SSadaf Ebrahimi 177*62c56f98SSadaf Ebrahimi### Driver entry points 178*62c56f98SSadaf Ebrahimi 179*62c56f98SSadaf Ebrahimi#### Overview of driver entry points 180*62c56f98SSadaf Ebrahimi 181*62c56f98SSadaf EbrahimiDrivers define functions, each of which implements an aspect of a capability of a driver, such as a cryptographic operation, a part of a cryptographic operation, or a key management action. These functions are called the **entry points** of the driver. Most driver entry points correspond to a particular function in the PSA Cryptography API. For example, if a call to `psa_sign_hash()` is dispatched to a driver, it invokes the driver's `sign_hash` function. 182*62c56f98SSadaf Ebrahimi 183*62c56f98SSadaf EbrahimiAll driver entry points return a status of type `psa_status_t` which should use the status codes documented for PSA services in general and for PSA Cryptography in particular: `PSA_SUCCESS` indicates that the function succeeded, and `PSA_ERROR_xxx` values indicate that an error occurred. 184*62c56f98SSadaf Ebrahimi 185*62c56f98SSadaf EbrahimiThe signature of a driver entry point generally looks like the signature of the PSA Cryptography API that it implements, with some modifications. This section gives an overview of modifications that apply to whole classes of entry points. Refer to the reference section for each entry point or entry point family for details. 186*62c56f98SSadaf Ebrahimi 187*62c56f98SSadaf Ebrahimi* For entry points that operate on an existing key, the `psa_key_id_t` parameter is replaced by a sequence of three parameters that describe the key: 188*62c56f98SSadaf Ebrahimi 1. `const psa_key_attributes_t *attributes`: the key attributes. 189*62c56f98SSadaf Ebrahimi 2. `const uint8_t *key_buffer`: a key material or key context buffer. 190*62c56f98SSadaf Ebrahimi 3. `size_t key_buffer_size`: the size of the key buffer in bytes. 191*62c56f98SSadaf Ebrahimi 192*62c56f98SSadaf Ebrahimi For transparent drivers, the key buffer contains the key material, in the same format as defined for `psa_export_key()` and `psa_export_public_key()` in the PSA Cryptography API. For opaque drivers, the content of the key buffer is entirely up to the driver. 193*62c56f98SSadaf Ebrahimi 194*62c56f98SSadaf Ebrahimi* For entry points that involve a multi-part operation, the operation state type (`psa_XXX_operation_t`) is replaced by a driver-specific operation state type (*prefix*`_XXX_operation_t`). 195*62c56f98SSadaf Ebrahimi 196*62c56f98SSadaf Ebrahimi* For entry points that are involved in key creation, the `psa_key_id_t *` output parameter is replaced by a sequence of parameters that convey the key context: 197*62c56f98SSadaf Ebrahimi 1. `uint8_t *key_buffer`: a buffer for the key material or key context. 198*62c56f98SSadaf Ebrahimi 2. `size_t key_buffer_size`: the size of the key buffer in bytes. 199*62c56f98SSadaf Ebrahimi 2. `size_t *key_buffer_length`: the length of the data written to the key buffer in bytes. 200*62c56f98SSadaf Ebrahimi 201*62c56f98SSadaf EbrahimiSome entry points are grouped in families that must be implemented as a whole. If a driver supports an entry point family, it must provide all the entry points in the family. 202*62c56f98SSadaf Ebrahimi 203*62c56f98SSadaf EbrahimiDrivers can also have entry points related to random generation. A transparent driver can provide a [random generation interface](#random-generation-entry-points). Separately, transparent and opaque drivers can have [entropy collection entry points](#entropy-collection-entry-point). 204*62c56f98SSadaf Ebrahimi 205*62c56f98SSadaf Ebrahimi#### General considerations on driver entry point parameters 206*62c56f98SSadaf Ebrahimi 207*62c56f98SSadaf EbrahimiBuffer parameters for driver entry points obey the following conventions: 208*62c56f98SSadaf Ebrahimi 209*62c56f98SSadaf Ebrahimi* An input buffer has the type `const uint8_t *` and is immediately followed by a parameter of type `size_t` that indicates the buffer size. 210*62c56f98SSadaf Ebrahimi* An output buffer has the type `uint8_t *` and is immediately followed by a parameter of type `size_t` that indicates the buffer size. A third parameter of type `size_t *` is provided to report the actual length of the data written in the buffer if the function succeeds. 211*62c56f98SSadaf Ebrahimi* An in-out buffer has the type `uint8_t *` and is immediately followed by a parameter of type `size_t` that indicates the buffer size. In-out buffers are only used when the input and the output have the same length. 212*62c56f98SSadaf Ebrahimi 213*62c56f98SSadaf EbrahimiBuffers of size 0 may be represented with either a null pointer or a non-null pointer. 214*62c56f98SSadaf Ebrahimi 215*62c56f98SSadaf EbrahimiInput buffers and other input-only parameters (`const` pointers) may be in read-only memory. Overlap is possible between input buffers, and between an input buffer and an output buffer, but not between two output buffers or between a non-buffer parameter and another parameter. 216*62c56f98SSadaf Ebrahimi 217*62c56f98SSadaf Ebrahimi#### Driver entry points for single-part cryptographic operations 218*62c56f98SSadaf Ebrahimi 219*62c56f98SSadaf EbrahimiThe following driver entry points perform a cryptographic operation in one shot (single-part operation): 220*62c56f98SSadaf Ebrahimi 221*62c56f98SSadaf Ebrahimi* `"hash_compute"` (transparent drivers only): calculation of a hash. Called by `psa_hash_compute()` and `psa_hash_compare()`. To verify a hash with `psa_hash_compare()`, the core calls the driver's `"hash_compute"` entry point and compares the result with the reference hash value. 222*62c56f98SSadaf Ebrahimi* `"mac_compute"`: calculation of a MAC. Called by `psa_mac_compute()` and possibly `psa_mac_verify()`. To verify a mac with `psa_mac_verify()`, the core calls an applicable driver's `"mac_verify"` entry point if there is one, otherwise the core calls an applicable driver's `"mac_compute"` entry point and compares the result with the reference MAC value. 223*62c56f98SSadaf Ebrahimi* `"mac_verify"`: verification of a MAC. Called by `psa_mac_verify()`. This entry point is mainly useful for drivers of secure elements that verify a MAC without revealing the correct MAC. Although transparent drivers may implement this entry point in addition to `"mac_compute"`, it is generally not useful because the core can call the `"mac_compute"` entry point and compare with the expected MAC value. 224*62c56f98SSadaf Ebrahimi* `"cipher_encrypt"`: unauthenticated symmetric cipher encryption. Called by `psa_cipher_encrypt()`. 225*62c56f98SSadaf Ebrahimi* `"cipher_decrypt"`: unauthenticated symmetric cipher decryption. Called by `psa_cipher_decrypt()`. 226*62c56f98SSadaf Ebrahimi* `"aead_encrypt"`: authenticated encryption with associated data. Called by `psa_aead_encrypt()`. 227*62c56f98SSadaf Ebrahimi* `"aead_decrypt"`: authenticated decryption with associated data. Called by `psa_aead_decrypt()`. 228*62c56f98SSadaf Ebrahimi* `"asymmetric_encrypt"`: asymmetric encryption. Called by `psa_asymmetric_encrypt()`. 229*62c56f98SSadaf Ebrahimi* `"asymmetric_decrypt"`: asymmetric decryption. Called by `psa_asymmetric_decrypt()`. 230*62c56f98SSadaf Ebrahimi* `"sign_hash"`: signature of an already calculated hash. Called by `psa_sign_hash()` and possibly `psa_sign_message()`. To sign a message with `psa_sign_message()`, the core calls an applicable driver's `"sign_message"` entry point if there is one, otherwise the core calls an applicable driver's `"hash_compute"` entry point followed by an applicable driver's `"sign_hash"` entry point. 231*62c56f98SSadaf Ebrahimi* `"verify_hash"`: verification of an already calculated hash. Called by `psa_verify_hash()` and possibly `psa_verify_message()`. To verify a message with `psa_verify_message()`, the core calls an applicable driver's `"verify_message"` entry point if there is one, otherwise the core calls an applicable driver's `"hash_compute"` entry point followed by an applicable driver's `"verify_hash"` entry point. 232*62c56f98SSadaf Ebrahimi* `"sign_message"`: signature of a message. Called by `psa_sign_message()`. 233*62c56f98SSadaf Ebrahimi* `"verify_message"`: verification of a message. Called by `psa_verify_message()`. 234*62c56f98SSadaf Ebrahimi* `"key_agreement"`: key agreement without a subsequent key derivation. Called by `psa_raw_key_agreement()` and possibly `psa_key_derivation_key_agreement()`. 235*62c56f98SSadaf Ebrahimi 236*62c56f98SSadaf Ebrahimi### Driver entry points for multi-part operations 237*62c56f98SSadaf Ebrahimi 238*62c56f98SSadaf Ebrahimi#### General considerations on multi-part operations 239*62c56f98SSadaf Ebrahimi 240*62c56f98SSadaf EbrahimiThe entry points that implement each step of a multi-part operation are grouped into a family. A driver that implements a multi-part operation must define all of the entry points in this family as well as a type that represents the operation context. The lifecycle of a driver operation context is similar to the lifecycle of an API operation context: 241*62c56f98SSadaf Ebrahimi 242*62c56f98SSadaf Ebrahimi1. The core initializes operation context objects to either all-bits-zero or to logical zero (`{0}`), at its discretion. 243*62c56f98SSadaf Ebrahimi1. The core calls the `xxx_setup` entry point for this operation family. If this fails, the core destroys the operation context object without calling any other driver entry point on it. 244*62c56f98SSadaf Ebrahimi1. The core calls other entry points that manipulate the operation context object, respecting the constraints. 245*62c56f98SSadaf Ebrahimi1. If any entry point fails, the core calls the driver's `xxx_abort` entry point for this operation family, then destroys the operation context object without calling any other driver entry point on it. 246*62c56f98SSadaf Ebrahimi1. If a “finish” entry point fails, the core destroys the operation context object without calling any other driver entry point on it. The finish entry points are: *prefix*`_mac_sign_finish`, *prefix*`_mac_verify_finish`, *prefix*`_cipher_finish`, *prefix*`_aead_finish`, *prefix*`_aead_verify`. 247*62c56f98SSadaf Ebrahimi 248*62c56f98SSadaf EbrahimiIf a driver implements a multi-part operation but not the corresponding single-part operation, the core calls the driver's multipart operation entry points to perform the single-part operation. 249*62c56f98SSadaf Ebrahimi 250*62c56f98SSadaf Ebrahimi#### Multi-part operation entry point family `"hash_multipart"` 251*62c56f98SSadaf Ebrahimi 252*62c56f98SSadaf EbrahimiThis family corresponds to the calculation of a hash in multiple steps. 253*62c56f98SSadaf Ebrahimi 254*62c56f98SSadaf EbrahimiThis family applies to transparent drivers only. 255*62c56f98SSadaf Ebrahimi 256*62c56f98SSadaf EbrahimiThis family requires the following type and entry points: 257*62c56f98SSadaf Ebrahimi 258*62c56f98SSadaf Ebrahimi* Type `"hash_operation_t"`: the type of a hash operation context. It must be possible to copy a hash operation context byte by byte, therefore hash operation contexts must not contain any embedded pointers (except pointers to global data that do not change after the setup step). 259*62c56f98SSadaf Ebrahimi* `"hash_setup"`: called by `psa_hash_setup()`. 260*62c56f98SSadaf Ebrahimi* `"hash_update"`: called by `psa_hash_update()`. 261*62c56f98SSadaf Ebrahimi* `"hash_finish"`: called by `psa_hash_finish()` and `psa_hash_verify()`. 262*62c56f98SSadaf Ebrahimi* `"hash_abort"`: called by all multi-part hash functions of the PSA Cryptography API. 263*62c56f98SSadaf Ebrahimi 264*62c56f98SSadaf EbrahimiTo verify a hash with `psa_hash_verify()`, the core calls the driver's *prefix*`_hash_finish` entry point and compares the result with the reference hash value. 265*62c56f98SSadaf Ebrahimi 266*62c56f98SSadaf EbrahimiFor example, a driver with the prefix `"acme"` that implements the `"hash_multipart"` entry point family must define the following type and entry points (assuming that the capability does not use the `"names"` property to declare different type and entry point names): 267*62c56f98SSadaf Ebrahimi 268*62c56f98SSadaf Ebrahimi``` 269*62c56f98SSadaf Ebrahimitypedef ... acme_hash_operation_t; 270*62c56f98SSadaf Ebrahimipsa_status_t acme_hash_setup(acme_hash_operation_t *operation, 271*62c56f98SSadaf Ebrahimi psa_algorithm_t alg); 272*62c56f98SSadaf Ebrahimipsa_status_t acme_hash_update(acme_hash_operation_t *operation, 273*62c56f98SSadaf Ebrahimi const uint8_t *input, 274*62c56f98SSadaf Ebrahimi size_t input_length); 275*62c56f98SSadaf Ebrahimipsa_status_t acme_hash_finish(acme_hash_operation_t *operation, 276*62c56f98SSadaf Ebrahimi uint8_t *hash, 277*62c56f98SSadaf Ebrahimi size_t hash_size, 278*62c56f98SSadaf Ebrahimi size_t *hash_length); 279*62c56f98SSadaf Ebrahimipsa_status_t acme_hash_abort(acme_hash_operation_t *operation); 280*62c56f98SSadaf Ebrahimi``` 281*62c56f98SSadaf Ebrahimi 282*62c56f98SSadaf Ebrahimi#### Operation family `"mac_multipart"` 283*62c56f98SSadaf Ebrahimi 284*62c56f98SSadaf EbrahimiTODO 285*62c56f98SSadaf Ebrahimi 286*62c56f98SSadaf Ebrahimi#### Operation family `"mac_verify_multipart"` 287*62c56f98SSadaf Ebrahimi 288*62c56f98SSadaf EbrahimiTODO 289*62c56f98SSadaf Ebrahimi 290*62c56f98SSadaf Ebrahimi#### Operation family `"cipher_encrypt_multipart"` 291*62c56f98SSadaf Ebrahimi 292*62c56f98SSadaf EbrahimiTODO 293*62c56f98SSadaf Ebrahimi 294*62c56f98SSadaf Ebrahimi#### Operation family `"cipher_decrypt_multipart"` 295*62c56f98SSadaf Ebrahimi 296*62c56f98SSadaf EbrahimiTODO 297*62c56f98SSadaf Ebrahimi 298*62c56f98SSadaf Ebrahimi#### Operation family `"aead_encrypt_multipart"` 299*62c56f98SSadaf Ebrahimi 300*62c56f98SSadaf EbrahimiTODO 301*62c56f98SSadaf Ebrahimi 302*62c56f98SSadaf Ebrahimi#### Operation family `"aead_decrypt_multipart"` 303*62c56f98SSadaf Ebrahimi 304*62c56f98SSadaf EbrahimiTODO 305*62c56f98SSadaf Ebrahimi 306*62c56f98SSadaf Ebrahimi### Driver entry points for key derivation 307*62c56f98SSadaf Ebrahimi 308*62c56f98SSadaf EbrahimiKey derivation is more complex than other multipart operations for several reasons: 309*62c56f98SSadaf Ebrahimi 310*62c56f98SSadaf Ebrahimi* There are multiple inputs and outputs. 311*62c56f98SSadaf Ebrahimi* Multiple drivers can be involved. This happens when an operation combines a key agreement and a subsequent symmetric key derivation, each of which can have independent drivers. This also happens when deriving an asymmetric key, where processing the secret input and generating the key output might involve different drivers. 312*62c56f98SSadaf Ebrahimi* When multiple drivers are involved, they are not always independent: if the secret input is managed by an opaque driver, it might not allow the core to retrieve the intermediate output and pass it to another driver. 313*62c56f98SSadaf Ebrahimi* The involvement of an opaque driver cannot be determined as soon as the operation is set up (since `psa_key_derivation_setup()` does not determine the key input). 314*62c56f98SSadaf Ebrahimi 315*62c56f98SSadaf Ebrahimi#### Key derivation driver dispatch logic 316*62c56f98SSadaf Ebrahimi 317*62c56f98SSadaf EbrahimiThe core decides whether to dispatch a key derivation operation to a driver based on the location associated with the input step `PSA_KEY_DERIVATION_INPUT_SECRET`. 318*62c56f98SSadaf Ebrahimi 319*62c56f98SSadaf Ebrahimi1. If this step is passed via `psa_key_derivation_input_key()` for a key in a secure element: 320*62c56f98SSadaf Ebrahimi * If the driver for this secure element implements the `"key_derivation"` family for the specified algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points. 321*62c56f98SSadaf Ebrahimi Note that for all currently specified algorithms, the key type for the secret input does not matter. 322*62c56f98SSadaf Ebrahimi * Otherwise the core calls the secure element driver's [`"export_key"`](#key-management-with-opaque-drivers) entry point. 323*62c56f98SSadaf Ebrahimi2. Otherwise ([or on fallback?](#fallback-for-key-derivation-in-opaque-drivers)), if there is a transparent driver for the specified algorithm, the core calls that driver's `"key_derivation_setup"` and subsequent entry points. 324*62c56f98SSadaf Ebrahimi3. Otherwise, or on fallback, the core uses its built-in implementation. 325*62c56f98SSadaf Ebrahimi 326*62c56f98SSadaf Ebrahimi#### Summary of entry points for the operation family `"key_derivation"` 327*62c56f98SSadaf Ebrahimi 328*62c56f98SSadaf EbrahimiA key derivation driver has the following entry points: 329*62c56f98SSadaf Ebrahimi 330*62c56f98SSadaf Ebrahimi* `"key_derivation_setup"` (mandatory): always the first entry point to be called. This entry point provides the [initial inputs](#key-derivation-driver-initial-inputs). See [“Key derivation driver setup”](#key-derivation-driver-setup). 331*62c56f98SSadaf Ebrahimi* `"key_derivation_input_step"` (mandatory if the driver supports a key derivation algorithm with long inputs, otherwise ignored): provide an extra input for the key derivation. This entry point is only mandatory in drivers that support algorithms that have extra inputs. See [“Key derivation driver long inputs”](#key-derivation-driver-long-inputs). 332*62c56f98SSadaf Ebrahimi* `"key_derivation_output_bytes"` (mandatory): derive cryptographic material and output it. See [“Key derivation driver outputs”](#key-derivation-driver-outputs). 333*62c56f98SSadaf Ebrahimi* `"key_derivation_output_key"`, `"key_derivation_verify_bytes"`, `"key_derivation_verify_key"` (optional, opaque drivers only): derive key material which remains inside the same secure element. See [“Key derivation driver outputs”](#key-derivation-driver-outputs). 334*62c56f98SSadaf Ebrahimi* `"key_derivation_set_capacity"` (mandatory for opaque drivers that implement `"key_derivation_output_key"` for “cooked”, i.e. non-raw-data key types; ignored for other opaque drivers; not permitted for transparent drivers): update the capacity policy on the operation. See [“Key derivation driver operation capacity”](#key-derivation-driver-operation-capacity). 335*62c56f98SSadaf Ebrahimi* `"key_derivation_abort"` (mandatory): always the last entry point to be called. 336*62c56f98SSadaf Ebrahimi 337*62c56f98SSadaf EbrahimiFor naming purposes, here and in the following subsection, this specification takes the example of a driver with the prefix `"acme"` that implements the `"key_derivation"` entry point family with a capability that does not use the `"names"` property to declare different type and entry point names. Such a driver must implement the following type and functions, as well as the entry points listed above and described in the following subsections: 338*62c56f98SSadaf Ebrahimi``` 339*62c56f98SSadaf Ebrahimitypedef ... acme_key_derivation_operation_t; 340*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_abort(acme_key_derivation_operation_t *operation); 341*62c56f98SSadaf Ebrahimi``` 342*62c56f98SSadaf Ebrahimi 343*62c56f98SSadaf Ebrahimi#### Key derivation driver initial inputs 344*62c56f98SSadaf Ebrahimi 345*62c56f98SSadaf EbrahimiThe core conveys the initial inputs for a key derivation via an opaque data structure of type `psa_crypto_driver_key_derivation_inputs_t`. 346*62c56f98SSadaf Ebrahimi 347*62c56f98SSadaf Ebrahimi``` 348*62c56f98SSadaf Ebrahimitypedef ... psa_crypto_driver_key_derivation_inputs_t; // implementation-specific type 349*62c56f98SSadaf Ebrahimi``` 350*62c56f98SSadaf Ebrahimi 351*62c56f98SSadaf EbrahimiA driver receiving an argument that points to a `psa_crypto_driver_key_derivation_inputs_t` can retrieve its contents by calling one of the type-specific functions below. To determine the correct function, the driver can call `psa_crypto_driver_key_derivation_get_input_type()`. 352*62c56f98SSadaf Ebrahimi 353*62c56f98SSadaf Ebrahimi``` 354*62c56f98SSadaf Ebrahimienum psa_crypto_driver_key_derivation_input_type_t { 355*62c56f98SSadaf Ebrahimi PSA_KEY_DERIVATION_INPUT_TYPE_INVALID = 0, 356*62c56f98SSadaf Ebrahimi PSA_KEY_DERIVATION_INPUT_TYPE_OMITTED, 357*62c56f98SSadaf Ebrahimi PSA_KEY_DERIVATION_INPUT_TYPE_BYTES, 358*62c56f98SSadaf Ebrahimi PSA_KEY_DERIVATION_INPUT_TYPE_KEY, 359*62c56f98SSadaf Ebrahimi PSA_KEY_DERIVATION_INPUT_TYPE_INTEGER, 360*62c56f98SSadaf Ebrahimi // Implementations may add other values, and may freely choose the 361*62c56f98SSadaf Ebrahimi // numerical values for each identifer except as explicitly specified 362*62c56f98SSadaf Ebrahimi // above. 363*62c56f98SSadaf Ebrahimi}; 364*62c56f98SSadaf Ebrahimipsa_crypto_driver_key_derivation_input_type_t psa_crypto_driver_key_derivation_get_input_type( 365*62c56f98SSadaf Ebrahimi const psa_crypto_driver_key_derivation_inputs_t *inputs, 366*62c56f98SSadaf Ebrahimi psa_key_derivation_step_t step); 367*62c56f98SSadaf Ebrahimi``` 368*62c56f98SSadaf Ebrahimi 369*62c56f98SSadaf EbrahimiThe function `psa_crypto_driver_key_derivation_get_input_type()` determines whether a given step is present and how to access its value: 370*62c56f98SSadaf Ebrahimi 371*62c56f98SSadaf Ebrahimi* `PSA_KEY_DERIVATION_INPUT_TYPE_INVALID`: the step is invalid for the algorithm of the operation that the inputs are for. 372*62c56f98SSadaf Ebrahimi* `PSA_KEY_DERIVATION_INPUT_TYPE_OMITTED`: the step is optional for the algorithm of the operation that the inputs are for, and has been omitted. 373*62c56f98SSadaf Ebrahimi* `PSA_KEY_DERIVATION_INPUT_TYPE_BYTES`: the step is valid and present and is a transparent byte string. Call `psa_crypto_driver_key_derivation_get_input_size()` to obtain the size of the input data. Call `psa_crypto_driver_key_derivation_get_input_bytes()` to make a copy of the input data (design note: [why a copy?](#key-derivation-inputs-and-buffer-ownership)). 374*62c56f98SSadaf Ebrahimi* `PSA_KEY_DERIVATION_INPUT_TYPE_KEY`: the step is valid and present and is a byte string passed via a key object. Call `psa_crypto_driver_key_derivation_get_input_key()` to obtain a pointer to the key context. 375*62c56f98SSadaf Ebrahimi* `PSA_KEY_DERIVATION_INPUT_TYPE_INTEGER`: the step is valid and present and is an integer. Call `psa_crypto_driver_key_derivation_get_input_integer()` to retrieve the integer value. 376*62c56f98SSadaf Ebrahimi 377*62c56f98SSadaf Ebrahimi``` 378*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_key_derivation_get_input_size( 379*62c56f98SSadaf Ebrahimi const psa_crypto_driver_key_derivation_inputs_t *inputs, 380*62c56f98SSadaf Ebrahimi psa_key_derivation_step_t step, 381*62c56f98SSadaf Ebrahimi size_t *size); 382*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_key_derivation_get_input_bytes( 383*62c56f98SSadaf Ebrahimi const psa_crypto_driver_key_derivation_inputs_t *inputs, 384*62c56f98SSadaf Ebrahimi psa_key_derivation_step_t step, 385*62c56f98SSadaf Ebrahimi uint8_t *buffer, size_t buffer_size, size_t *buffer_length); 386*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_key_derivation_get_input_key( 387*62c56f98SSadaf Ebrahimi const psa_crypto_driver_key_derivation_inputs_t *inputs, 388*62c56f98SSadaf Ebrahimi psa_key_derivation_step_t step, 389*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes, 390*62c56f98SSadaf Ebrahimi uint8_t** p_key_buffer, size_t *key_buffer_size); 391*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_key_derivation_get_input_integer( 392*62c56f98SSadaf Ebrahimi const psa_crypto_driver_key_derivation_inputs_t *inputs, 393*62c56f98SSadaf Ebrahimi psa_key_derivation_step_t step, 394*62c56f98SSadaf Ebrahimi uint64_t *value); 395*62c56f98SSadaf Ebrahimi``` 396*62c56f98SSadaf Ebrahimi 397*62c56f98SSadaf EbrahimiThe get-data functions take the following parameters: 398*62c56f98SSadaf Ebrahimi 399*62c56f98SSadaf Ebrahimi* The first parameter `inputs` must be a pointer passed by the core to a key derivation driver setup entry point which has not returned yet. 400*62c56f98SSadaf Ebrahimi* The `step` parameter indicates the input step whose content the driver wants to retrieve. 401*62c56f98SSadaf Ebrahimi* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_size`, the core sets `*size` to the size of the specified input in bytes. 402*62c56f98SSadaf Ebrahimi* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_bytes`, the core fills the first *N* bytes of `buffer` with the specified input and sets `*buffer_length` to *N*, where *N* is the length of the input in bytes. The value of `buffer_size` must be at least *N*, otherwise this function fails with the status `PSA_ERROR_BUFFER_TOO_SMALL`. 403*62c56f98SSadaf Ebrahimi* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_key`, the core sets `*key_buffer` to a pointer to a buffer containing the key context and `*key_buffer_size` to the size of the key context in bytes. The key context buffer remains valid for the duration of the driver entry point. If the driver needs to access the key context after the current entry point returns, it must make a copy of the key context. 404*62c56f98SSadaf Ebrahimi* On a successful invocation of `psa_crypto_driver_key_derivation_get_input_integer`, the core sets `*value` to the value of the specified input. 405*62c56f98SSadaf Ebrahimi 406*62c56f98SSadaf EbrahimiThese functions can return the following statuses: 407*62c56f98SSadaf Ebrahimi 408*62c56f98SSadaf Ebrahimi* `PSA_SUCCESS`: the call succeeded and the requested value has been copied to the output parameter (`size`, `buffer`, `value` or `p_key_buffer`) and if applicable the size of the value has been written to the applicable parameter (`buffer_length`, `key_buffer_size`). 409*62c56f98SSadaf Ebrahimi* `PSA_ERROR_DOES_NOT_EXIST`: the input step is valid for this particular algorithm, but it is not part of the initial inputs. This is not a fatal error. The driver will receive the input later as a [long input](#key-derivation-driver-long-inputs). 410*62c56f98SSadaf Ebrahimi* `PSA_ERROR_INVALID_ARGUMENT`: the input type is not compatible with this function or was omitted. Call `psa_crypto_driver_key_derivation_get_input_type()` to find out the actual type of this input step. This is not a fatal error and the driver can, for example, subsequently call the appropriate function on the same step. 411*62c56f98SSadaf Ebrahimi* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_key_derivation_get_input_bytes` only): the output buffer is too small. This is not a fatal error and the driver can, for example, subsequently call the same function again with a larger buffer. Call `psa_crypto_driver_key_derivation_get_input_size` to obtain the required size. 412*62c56f98SSadaf Ebrahimi* The core may return other errors such as `PSA_ERROR_CORRUPTION_DETECTED` or `PSA_ERROR_COMMUNICATION_FAILURE` to convey implementation-specific error conditions. Portable drivers should treat such conditions as fatal errors. 413*62c56f98SSadaf Ebrahimi 414*62c56f98SSadaf Ebrahimi#### Key derivation driver setup 415*62c56f98SSadaf Ebrahimi 416*62c56f98SSadaf EbrahimiA key derivation driver must implement the following entry point: 417*62c56f98SSadaf Ebrahimi``` 418*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_setup( 419*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 420*62c56f98SSadaf Ebrahimi psa_algorithm_t alg, 421*62c56f98SSadaf Ebrahimi const psa_crypto_driver_key_derivation_inputs_t *inputs); 422*62c56f98SSadaf Ebrahimi``` 423*62c56f98SSadaf Ebrahimi 424*62c56f98SSadaf Ebrahimi* `operation` is a zero-initialized operation object. 425*62c56f98SSadaf Ebrahimi* `alg` is the algorithm for the key derivation operation. It does not include a key agreement component. 426*62c56f98SSadaf Ebrahimi* `inputs` is an opaque pointer to the [initial inputs](#key-derivation-driver-initial-inputs) for the key derivation. 427*62c56f98SSadaf Ebrahimi 428*62c56f98SSadaf Ebrahimi#### Key derivation driver long inputs 429*62c56f98SSadaf Ebrahimi 430*62c56f98SSadaf EbrahimiSome key derivation algorithms take long inputs which it would not be practical to pass in the [initial inputs](#key-derivation-driver-initial-inputs). A driver that implements a key derivation algorithm that takes such inputs must provide a `"key_derivation_input_step"` entry point. The core calls this entry point for all the long inputs after calling `"acme_key_derivation_setup"`. A long input step may be fragmented into multiple calls of `psa_key_derivation_input_bytes()`, and the core may reassemble or refragment those fragments before passing them to the driver. Calls to this entry point for different step values occur in an unspecified order and may be interspersed. 431*62c56f98SSadaf Ebrahimi 432*62c56f98SSadaf Ebrahimi``` 433*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_input_step( 434*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 435*62c56f98SSadaf Ebrahimi psa_key_derivation_step_t step, 436*62c56f98SSadaf Ebrahimi const uint8_t *input, size_t input_length); 437*62c56f98SSadaf Ebrahimi``` 438*62c56f98SSadaf Ebrahimi 439*62c56f98SSadaf EbrahimiAt the time of writing, no standard key derivation algorithm has long inputs. It is likely that such algorithms will be added in the future. 440*62c56f98SSadaf Ebrahimi 441*62c56f98SSadaf Ebrahimi#### Key derivation driver operation capacity 442*62c56f98SSadaf Ebrahimi 443*62c56f98SSadaf EbrahimiThe core keeps track of an operation's capacity and enforces it. The core guarantees that it will not request output beyond the capacity of the operation, with one exception: opaque drivers that support [`"key_derivation_output_key"`](#key-derivation-driver-outputs), i.e. for key types where the derived key material is not a direct copy of the key derivation's output stream. 444*62c56f98SSadaf Ebrahimi 445*62c56f98SSadaf EbrahimiSuch drivers must enforce the capacity limitation and must return `PSA_ERROR_INSUFFICIENT_CAPACITY` from any output request that exceeds the operation's capacity. Such drivers must provide the following entry point: 446*62c56f98SSadaf Ebrahimi``` 447*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_set_capacity( 448*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 449*62c56f98SSadaf Ebrahimi size_t capacity); 450*62c56f98SSadaf Ebrahimi``` 451*62c56f98SSadaf Ebrahimi`capacity` is guaranteed to be less or equal to any value previously set through this entry point, and is guaranteed not to be `PSA_KEY_DERIVATION_UNLIMITED_CAPACITY`. 452*62c56f98SSadaf Ebrahimi 453*62c56f98SSadaf EbrahimiIf this entry point has not been called, the operation has an unlimited capacity. 454*62c56f98SSadaf Ebrahimi 455*62c56f98SSadaf Ebrahimi#### Key derivation driver outputs 456*62c56f98SSadaf Ebrahimi 457*62c56f98SSadaf EbrahimiA key derivation driver must provide the following entry point: 458*62c56f98SSadaf Ebrahimi``` 459*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_output_bytes( 460*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 461*62c56f98SSadaf Ebrahimi uint8_t *output, size_t length); 462*62c56f98SSadaf Ebrahimi``` 463*62c56f98SSadaf Ebrahimi 464*62c56f98SSadaf EbrahimiAn opaque key derivation driver may provide the following entry points: 465*62c56f98SSadaf Ebrahimi``` 466*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_output_key( 467*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes, 468*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 469*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); 470*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_verify_bytes( 471*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 472*62c56f98SSadaf Ebrahimi const uint8_t *expected output, size_t length); 473*62c56f98SSadaf Ebrahimipsa_status_t acme_key_derivation_verify_key( 474*62c56f98SSadaf Ebrahimi acme_key_derivation_operation_t *operation, 475*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, size_t key_buffer_size); 476*62c56f98SSadaf Ebrahimi``` 477*62c56f98SSadaf Ebrahimi 478*62c56f98SSadaf EbrahimiThe core calls a key derivation driver's output entry point when the application calls `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()` or `psa_key_derivation_verify_key()`. 479*62c56f98SSadaf Ebrahimi 480*62c56f98SSadaf EbrahimiIf the key derivation's `PSA_KEY_DERIVATION_INPUT_SECRET` input is in a secure element and the derivation operation is handled by that secure element, the core performs the following steps: 481*62c56f98SSadaf Ebrahimi 482*62c56f98SSadaf Ebrahimi* For a call to `psa_key_derivation_output_key()`: 483*62c56f98SSadaf Ebrahimi 484*62c56f98SSadaf Ebrahimi 1. If the derived key is in the same secure element, if the driver has an `"key_derivation_output_key"` entry point, call that entry point. If the driver has no such entry point, or if that entry point returns `PSA_ERROR_NOT_SUPPORTED`, continue with the following steps, otherwise stop. 485*62c56f98SSadaf Ebrahimi 1. If the driver's capabilities indicate that its `"import_key"` entry point does not support the derived key, stop and return `PSA_ERROR_NOT_SUPPORTED`. 486*62c56f98SSadaf Ebrahimi 1. Otherwise proceed as for `psa_key_derivation_output_bytes()`, then import the resulting key material. 487*62c56f98SSadaf Ebrahimi 488*62c56f98SSadaf Ebrahimi* For a call to `psa_key_derivation_verify_key()`: 489*62c56f98SSadaf Ebrahimi 1. If the driver has a `"key_derivation_verify_key"` entry point, call it and stop. 490*62c56f98SSadaf Ebrahimi 1. Call the driver's `"export_key"` entry point on the key object that contains the expected value, then proceed as for `psa_key_derivation_verify_bytes()`. 491*62c56f98SSadaf Ebrahimi 492*62c56f98SSadaf Ebrahimi* For a call to `psa_key_derivation_verify_bytes()`: 493*62c56f98SSadaf Ebrahimi 1. If the driver has a `"key_derivation_verify_bytes"` entry point, call that entry point on the expected output, then stop. 494*62c56f98SSadaf Ebrahimi 1. Otherwise, proceed as for `psa_key_derivation_output_bytes()`, and compare the resulting output to the expected output inside the core. 495*62c56f98SSadaf Ebrahimi 496*62c56f98SSadaf Ebrahimi* For a call to `psa_key_derivation_output_bytes()`: 497*62c56f98SSadaf Ebrahimi 1. Call the `"key_derivation_output_bytes"` entry point. The core may call this entry point multiple times to implement a single call from the application when deriving a cooked (non-raw) key as described below, or if the output size exceeds some implementation limit. 498*62c56f98SSadaf Ebrahimi 499*62c56f98SSadaf EbrahimiIf the key derivation operation is not handled by an opaque driver as described above, the core calls the `"key_derivation_output_bytes"` from the applicable transparent driver (or multiple drivers in succession if fallback applies). In some cases, the core then calls additional entry points in the same or another driver: 500*62c56f98SSadaf Ebrahimi 501*62c56f98SSadaf Ebrahimi* For a call to `psa_key_derivation_output_key()` for some key types, the core calls a transparent driver's `"derive_key"` entry point. See [“Transparent cooked key derivation”](#transparent-cooked-key-derivation). 502*62c56f98SSadaf Ebrahimi* For a call to `psa_key_derivation_output_key()` where the derived key is in a secure element, call that secure element driver's `"import_key"` entry point. 503*62c56f98SSadaf Ebrahimi 504*62c56f98SSadaf Ebrahimi#### Transparent cooked key derivation 505*62c56f98SSadaf Ebrahimi 506*62c56f98SSadaf EbrahimiKey derivation is said to be *raw* for some key types, where the key material of a derived (8×*n*)-bit key consists of the next *n* bytes of output from the key derivation, and *cooked* otherwise. When deriving a raw key, the core only calls the driver's `"output_bytes"` entry point, except when deriving a key entirely inside a secure element as described in [“Key derivation driver outputs”](#key-derivation-driver-outputs). When deriving a cooked key, the core calls a transparent driver's `"derive_key"` entry point if available. 507*62c56f98SSadaf Ebrahimi 508*62c56f98SSadaf EbrahimiA capability for cooked key derivation contains the following properties (this is not a subset of [the usual entry point properties](#capability-syntax)): 509*62c56f98SSadaf Ebrahimi 510*62c56f98SSadaf Ebrahimi* `"entry_points"` (mandatory, list of strings). Must be `["derive_key"]`. 511*62c56f98SSadaf Ebrahimi* `"derived_types"` (mandatory, list of strings). Each element is a [key type specification](#key-type-specifications). This capability only applies when deriving a key of the specified type. 512*62c56f98SSadaf Ebrahimi* `"derived_sizes"` (optional, list of integers). Each element is a size for the derived key, in bits. This capability only applies when deriving a key of the specified sizes. If absent, this capability applies to all sizes for the specified types. 513*62c56f98SSadaf Ebrahimi* `"memory"` (optional, boolean). If present and true, the driver must define a type `"derive_key_memory_t"` and the core will allocate an object of that type as specified below. 514*62c56f98SSadaf Ebrahimi* `"names"` (optional, object). A mapping from entry point names to C function and type names, as usual. 515*62c56f98SSadaf Ebrahimi* `"fallback"` (optional, boolean). If present and true, the driver may return `PSA_ERROR_NOT_SUPPORTED` if it only partially supports the specified mechanism, as usual. 516*62c56f98SSadaf Ebrahimi 517*62c56f98SSadaf EbrahimiA transparent driver with the prefix `"acme"` that implements cooked key derivation must provide the following type and function: 518*62c56f98SSadaf Ebrahimi 519*62c56f98SSadaf Ebrahimi``` 520*62c56f98SSadaf Ebrahimitypedef ... acme_derive_key_memory_t; // only if the "memory" property is true 521*62c56f98SSadaf Ebrahimipsa_status_t acme_derive_key( 522*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes, 523*62c56f98SSadaf Ebrahimi const uint8_t *input, size_t input_length, 524*62c56f98SSadaf Ebrahimi acme_derive_key_memory_t *memory, // if the "memory" property is false: void* 525*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); 526*62c56f98SSadaf Ebrahimi``` 527*62c56f98SSadaf Ebrahimi 528*62c56f98SSadaf Ebrahimi* `attributes` contains the attributes of the specified key. Note that only the key type and the bit-size are guaranteed to be set. 529*62c56f98SSadaf Ebrahimi* `input` is a buffer of `input_length` bytes which contains the raw key stream, i.e. the data that `psa_key_derivation_output_bytes()` would return. 530*62c56f98SSadaf Ebrahimi* If `"memory"` property in the driver capability is true, `memory` is a data structure that the driver may use to store data between successive calls of the `"derive_key"` entry point to derive the same key. If the `"memory"` property is false or absent, the `memory` parameter is a null pointer. 531*62c56f98SSadaf Ebrahimi* `key_buffer` is a buffer for the output material, in the appropriate [export format](#key-format-for-transparent-drivers) for the key type. Its size is `key_buffer_size` bytes. 532*62c56f98SSadaf Ebrahimi* On success, `*key_buffer_length` must contain the number of bytes written to `key_buffer`. 533*62c56f98SSadaf Ebrahimi 534*62c56f98SSadaf EbrahimiThis entry point may return the following statuses: 535*62c56f98SSadaf Ebrahimi 536*62c56f98SSadaf Ebrahimi* `PSA_SUCCESS`: a key was derived successfully. The driver has placed the representation of the key in `key_buffer`. 537*62c56f98SSadaf Ebrahimi* `PSA_ERROR_NOT_SUPPORTED` (for the first call only) (only if fallback is enabled): the driver cannot fulfill this request, but a fallback driver might. 538*62c56f98SSadaf Ebrahimi* `PSA_ERROR_INSUFFICIENT_DATA`: the core must call the `"derive_key"` entry point again with the same `memory` object and with subsequent data from the key stream. 539*62c56f98SSadaf Ebrahimi* Any other error is a fatal error. 540*62c56f98SSadaf Ebrahimi 541*62c56f98SSadaf EbrahimiThe core calls the `"derive_key"` entry point in a loop until it returns a status other than `PSA_ERROR_INSUFFICIENT_DATA`. Each call has a successive fragment of the key stream. The `memory` object is guaranteed to be the same for successive calls, but note that its address may change between calls. Before the first call, `*memory` is initialized to all-bits-zero. 542*62c56f98SSadaf Ebrahimi 543*62c56f98SSadaf EbrahimiFor standard key types, the `"derive_key"` entry point is called with a certain input length as follows: 544*62c56f98SSadaf Ebrahimi 545*62c56f98SSadaf Ebrahimi* `PSA_KEY_TYPE_DES`: the length of the key. 546*62c56f98SSadaf Ebrahimi* `PSA_KEY_TYPE_ECC_KEY_PAIR(…)`, `PSA_KEY_TYPE_DH_KEY_PAIR(…)`: $m$ bytes, where the bit-size of the key $n$ satisfies $8 (m-1) < n \le 8 m$. 547*62c56f98SSadaf Ebrahimi* `PSA_KEY_TYPE_RSA_KEY_PAIR`: an implementation-defined length. A future version of this specification may specify a length. 548*62c56f98SSadaf Ebrahimi* Other key types: not applicable. 549*62c56f98SSadaf Ebrahimi 550*62c56f98SSadaf EbrahimiSee [“Open questions around cooked key derivation”](#open-questions-around-cooked-key-derivation) for some points that may not be fully settled. 551*62c56f98SSadaf Ebrahimi 552*62c56f98SSadaf Ebrahimi#### Key agreement 553*62c56f98SSadaf Ebrahimi 554*62c56f98SSadaf EbrahimiThe core always decouples key agreement from symmetric key derivation. 555*62c56f98SSadaf Ebrahimi 556*62c56f98SSadaf EbrahimiTo implement a call to `psa_key_derivation_key_agreement()` where the private key is in a secure element that has a `"key_agreement_to_key"` entry point which is applicable for the given key type and algorithm, the core calls the secure element driver as follows: 557*62c56f98SSadaf Ebrahimi 558*62c56f98SSadaf Ebrahimi1. Call the `"key_agreement_to_key"` entry point to create a key object containing the shared secret. The key object is volatile and has the type `PSA_KEY_TYPE_DERIVE`. 559*62c56f98SSadaf Ebrahimi2. Call the `"key_derivation_setup"` entry point, passing the resulting key object . 560*62c56f98SSadaf Ebrahimi3. Perform the rest of the key derivation, up to and including the call to the `"key_derivation_abort"` entry point. 561*62c56f98SSadaf Ebrahimi4. Call the `"destroy_key"` entry point to destroy the key containing the key object. 562*62c56f98SSadaf Ebrahimi 563*62c56f98SSadaf EbrahimiIn other cases, the core treats `psa_key_derivation_key_agreement()` as if it was a call to `psa_raw_key_agreement()` followed by a call to `psa_key_derivation_input_bytes()` on the shared secret. 564*62c56f98SSadaf Ebrahimi 565*62c56f98SSadaf EbrahimiThe entry points related to key agreement have the following prototypes for a driver with the prefix `"acme"`: 566*62c56f98SSadaf Ebrahimi``` 567*62c56f98SSadaf Ebrahimipsa_status_t acme_key_agreement(psa_algorithm_t alg, 568*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *our_attributes, 569*62c56f98SSadaf Ebrahimi const uint8_t *our_key_buffer, 570*62c56f98SSadaf Ebrahimi size_t our_key_buffer_length, 571*62c56f98SSadaf Ebrahimi const uint8_t *peer_key, 572*62c56f98SSadaf Ebrahimi size_t peer_key_length, 573*62c56f98SSadaf Ebrahimi uint8_t *output, 574*62c56f98SSadaf Ebrahimi size_t output_size, 575*62c56f98SSadaf Ebrahimi size_t *output_length); 576*62c56f98SSadaf Ebrahimipsa_status_t acme_key_agreement_to_key(psa_algorithm_t alg, 577*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *our_attributes, 578*62c56f98SSadaf Ebrahimi const uint8_t *our_key_buffer, 579*62c56f98SSadaf Ebrahimi size_t our_key_buffer_length, 580*62c56f98SSadaf Ebrahimi const uint8_t *peer_key, 581*62c56f98SSadaf Ebrahimi size_t peer_key_length, 582*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *shared_secret_attributes, 583*62c56f98SSadaf Ebrahimi uint8_t *shared_secret_key_buffer, 584*62c56f98SSadaf Ebrahimi size_t shared_secret_key_buffer_size, 585*62c56f98SSadaf Ebrahimi size_t *shared_secret_key_buffer_length); 586*62c56f98SSadaf Ebrahimi``` 587*62c56f98SSadaf Ebrahimi 588*62c56f98SSadaf EbrahimiNote that unlike most other key creation entry points, in `"acme_key_agreement_to_key"`, the attributes for the shared secret are not placed near the beginning, but rather grouped with the other parameters related to the shared secret at the end of the parameter list. This is to avoid potential confusion with the attributes of the private key that is passed as an input. 589*62c56f98SSadaf Ebrahimi 590*62c56f98SSadaf Ebrahimi### Driver entry points for PAKE 591*62c56f98SSadaf Ebrahimi 592*62c56f98SSadaf EbrahimiA PAKE operation is divided into two stages: collecting inputs and computation. Core side is responsible for keeping inputs and core set-data functions do not have driver entry points. Collected inputs are available for drivers via get-data functions for `password`, `role` and `cipher_suite`. 593*62c56f98SSadaf Ebrahimi 594*62c56f98SSadaf Ebrahimi### PAKE driver dispatch logic 595*62c56f98SSadaf EbrahimiThe core decides whether to dispatch a PAKE operation to a driver based on the location of the provided password. 596*62c56f98SSadaf EbrahimiWhen all inputs are collected and `"psa_pake_output"` or `"psa_pake_input"` is called for the first time `"pake_setup"` driver entry point is invoked. 597*62c56f98SSadaf Ebrahimi 598*62c56f98SSadaf Ebrahimi1. If the location of the `password` is the local storage 599*62c56f98SSadaf Ebrahimi- if there is a transparent driver for the specified ciphersuite, the core calls that driver's `"pake_setup"` and subsequent entry points. 600*62c56f98SSadaf Ebrahimi- otherwise, or on fallback, the core uses its built-in implementation. 601*62c56f98SSadaf Ebrahimi2. If the location of the `password` is the location of a secure element 602*62c56f98SSadaf Ebrahimi- the core calls the `"pake_setup"` entry point of the secure element driver and subsequent entry points. 603*62c56f98SSadaf Ebrahimi 604*62c56f98SSadaf Ebrahimi### Summary of entry points for PAKE 605*62c56f98SSadaf Ebrahimi 606*62c56f98SSadaf EbrahimiA PAKE driver has the following entry points: 607*62c56f98SSadaf Ebrahimi* `"pake_setup"` (mandatory): always the first entry point to be called. It is called when all inputs are collected and the computation stage starts. 608*62c56f98SSadaf Ebrahimi* `"pake_output"` (mandatory): derive cryptographic material for the specified step and output it. 609*62c56f98SSadaf Ebrahimi* `"pake_input"` (mandatory): provides cryptographic material in the format appropriate for the specified step. 610*62c56f98SSadaf Ebrahimi* `"pake_get_implicit_key"` (mandatory): returns implicitly confirmed shared secret from a PAKE. 611*62c56f98SSadaf Ebrahimi* `"pake_abort"` (mandatory): always the last entry point to be called. 612*62c56f98SSadaf Ebrahimi 613*62c56f98SSadaf EbrahimiFor naming purposes, here and in the following subsection, this specification takes the example of a driver with the prefix `"acme"` that implements the PAKE entry point family with a capability that does not use the `"names"` property to declare different type and entry point names. Such a driver must implement the following type and functions, as well as the entry points listed above and described in the following subsections: 614*62c56f98SSadaf Ebrahimi``` 615*62c56f98SSadaf Ebrahimitypedef ... acme_pake_operation_t; 616*62c56f98SSadaf Ebrahimipsa_status_t acme_pake_abort( acme_pake_operation_t *operation ); 617*62c56f98SSadaf Ebrahimi``` 618*62c56f98SSadaf Ebrahimi 619*62c56f98SSadaf Ebrahimi#### PAKE driver inputs 620*62c56f98SSadaf Ebrahimi 621*62c56f98SSadaf EbrahimiThe core conveys the initial inputs for a PAKE operation via an opaque data structure of type `psa_crypto_driver_pake_inputs_t`. 622*62c56f98SSadaf Ebrahimi 623*62c56f98SSadaf Ebrahimi``` 624*62c56f98SSadaf Ebrahimitypedef ... psa_crypto_driver_pake_inputs_t; // implementation-specific type 625*62c56f98SSadaf Ebrahimi``` 626*62c56f98SSadaf Ebrahimi 627*62c56f98SSadaf EbrahimiA driver receiving an argument that points to a `psa_crypto_driver_pake_inputs_t` can retrieve its contents by calling one of the get-data functions below. 628*62c56f98SSadaf Ebrahimi 629*62c56f98SSadaf Ebrahimi``` 630*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_password_len( 631*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 632*62c56f98SSadaf Ebrahimi size_t *password_len); 633*62c56f98SSadaf Ebrahimi 634*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_password_bytes( 635*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 636*62c56f98SSadaf Ebrahimi uint8_t *buffer, size_t buffer_size, size_t *buffer_length); 637*62c56f98SSadaf Ebrahimi 638*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_password_key( 639*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 640*62c56f98SSadaf Ebrahimi uint8_t** p_key_buffer, size_t *key_buffer_size, 641*62c56f98SSadaf Ebrahimi const psa_key_attributes_t *attributes); 642*62c56f98SSadaf Ebrahimi 643*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_user_len( 644*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 645*62c56f98SSadaf Ebrahimi size_t *user_len); 646*62c56f98SSadaf Ebrahimi 647*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_user( 648*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 649*62c56f98SSadaf Ebrahimi uint8_t *user_id, size_t user_id_size, size_t *user_id_len); 650*62c56f98SSadaf Ebrahimi 651*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_peer_len( 652*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 653*62c56f98SSadaf Ebrahimi size_t *peer_len); 654*62c56f98SSadaf Ebrahimi 655*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_peer( 656*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 657*62c56f98SSadaf Ebrahimi uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length); 658*62c56f98SSadaf Ebrahimi 659*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_pake_get_cipher_suite( 660*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs, 661*62c56f98SSadaf Ebrahimi psa_pake_cipher_suite_t *cipher_suite); 662*62c56f98SSadaf Ebrahimi``` 663*62c56f98SSadaf EbrahimiThe get-data functions take the following parameters: 664*62c56f98SSadaf Ebrahimi 665*62c56f98SSadaf EbrahimiThe first parameter `inputs` must be a pointer passed by the core to a PAKE driver setup entry point. 666*62c56f98SSadaf EbrahimiNext parameters are return buffers (must not be null pointers). 667*62c56f98SSadaf Ebrahimi 668*62c56f98SSadaf EbrahimiThese functions can return the following statuses: 669*62c56f98SSadaf Ebrahimi* `PSA_SUCCESS`: value has been successfully obtained 670*62c56f98SSadaf Ebrahimi* `PSA_ERROR_BAD_STATE`: the inputs are not ready 671*62c56f98SSadaf Ebrahimi* `PSA_ERROR_BUFFER_TOO_SMALL` (`psa_crypto_driver_pake_get_password_bytes` and `psa_crypto_driver_pake_get_password_key` only): the output buffer is too small. This is not a fatal error and the driver can, for example, subsequently call the same function again with a larger buffer. Call `psa_crypto_driver_pake_get_password_len` to obtain the required size. 672*62c56f98SSadaf Ebrahimi 673*62c56f98SSadaf Ebrahimi#### PAKE driver setup 674*62c56f98SSadaf Ebrahimi 675*62c56f98SSadaf Ebrahimi``` 676*62c56f98SSadaf Ebrahimipsa_status_t acme_pake_setup( acme_pake_operation_t *operation, 677*62c56f98SSadaf Ebrahimi const psa_crypto_driver_pake_inputs_t *inputs ); 678*62c56f98SSadaf Ebrahimi``` 679*62c56f98SSadaf Ebrahimi 680*62c56f98SSadaf Ebrahimi* `operation` is a zero-initialized operation object. 681*62c56f98SSadaf Ebrahimi* `inputs` is an opaque pointer to the [inputs](#pake-driver-inputs) for the PAKE operation. 682*62c56f98SSadaf Ebrahimi 683*62c56f98SSadaf EbrahimiThe setup driver function should preserve the inputs using get-data functions. 684*62c56f98SSadaf Ebrahimi 685*62c56f98SSadaf EbrahimiThe pointer output by `psa_crypto_driver_pake_get_password_key` is only valid until the "pake_setup" entry point returns. Opaque drivers must copy all relevant data from the key buffer during the "pake_setup" entry point and must not store the pointer itself. 686*62c56f98SSadaf Ebrahimi 687*62c56f98SSadaf Ebrahimi#### PAKE driver output 688*62c56f98SSadaf Ebrahimi 689*62c56f98SSadaf Ebrahimi``` 690*62c56f98SSadaf Ebrahimipsa_status_t acme_pake_output(acme_pake_operation_t *operation, 691*62c56f98SSadaf Ebrahimi psa_crypto_driver_pake_step_t step, 692*62c56f98SSadaf Ebrahimi uint8_t *output, 693*62c56f98SSadaf Ebrahimi size_t output_size, 694*62c56f98SSadaf Ebrahimi size_t *output_length); 695*62c56f98SSadaf Ebrahimi``` 696*62c56f98SSadaf Ebrahimi 697*62c56f98SSadaf Ebrahimi* `operation` is an operation object. 698*62c56f98SSadaf Ebrahimi* `step` computation step based on which driver should perform an action. 699*62c56f98SSadaf Ebrahimi* `output` buffer where the output is to be written. 700*62c56f98SSadaf Ebrahimi* `output_size` size of the output buffer in bytes. 701*62c56f98SSadaf Ebrahimi* `output_length` the number of bytes of the returned output. 702*62c56f98SSadaf Ebrahimi 703*62c56f98SSadaf EbrahimiFor `PSA_ALG_JPAKE` the following steps are available for output operation: 704*62c56f98SSadaf Ebrahimi`step` can be one of the following values: 705*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X1_STEP_KEY_SHARE` Round 1: output our key share (for ephemeral private key X1) 706*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X1_STEP_ZK_PUBLIC` Round 1: output Schnorr NIZKP public key for the X1 key 707*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X1_STEP_ZK_PROOF` Round 1: output Schnorr NIZKP proof for the X1 key 708*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2_STEP_KEY_SHARE` Round 1: output our key share (for ephemeral private key X2) 709*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2_STEP_ZK_PUBLIC` Round 1: output Schnorr NIZKP public key for the X2 key 710*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2_STEP_ZK_PROOF` Round 1: output Schnorr NIZKP proof for the X2 key 711*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2S_STEP_KEY_SHARE` Round 2: output our X2S key 712*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2S_STEP_ZK_PUBLIC` Round 2: output Schnorr NIZKP public key for the X2S key 713*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2S_STEP_ZK_PROOF` Round 2: output Schnorr NIZKP proof for the X2S key 714*62c56f98SSadaf Ebrahimi 715*62c56f98SSadaf Ebrahimi#### PAKE driver input 716*62c56f98SSadaf Ebrahimi``` 717*62c56f98SSadaf Ebrahimipsa_status_t acme_pake_input(acme_pake_operation_t *operation, 718*62c56f98SSadaf Ebrahimi psa_crypto_driver_pake_step_t step, 719*62c56f98SSadaf Ebrahimi uint8_t *input, 720*62c56f98SSadaf Ebrahimi size_t input_size); 721*62c56f98SSadaf Ebrahimi``` 722*62c56f98SSadaf Ebrahimi 723*62c56f98SSadaf Ebrahimi* `operation` is an operation object. 724*62c56f98SSadaf Ebrahimi* `step` computation step based on which driver should perform an action. 725*62c56f98SSadaf Ebrahimi* `input` buffer containing the input. 726*62c56f98SSadaf Ebrahimi* `input_length` length of the input in bytes. 727*62c56f98SSadaf Ebrahimi 728*62c56f98SSadaf EbrahimiFor `PSA_ALG_JPAKE` the following steps are available for input operation: 729*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X1_STEP_KEY_SHARE` Round 1: input key share from peer (for ephemeral private key X1) 730*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X1_STEP_ZK_PUBLIC` Round 1: input Schnorr NIZKP public key for the X1 key 731*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X1_STEP_ZK_PROOF` Round 1: input Schnorr NIZKP proof for the X1 key 732*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2_STEP_KEY_SHARE` Round 1: input key share from peer (for ephemeral private key X2) 733*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2_STEP_ZK_PUBLIC` Round 1: input Schnorr NIZKP public key for the X2 key 734*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X2_STEP_ZK_PROOF` Round 1: input Schnorr NIZKP proof for the X2 key 735*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X4S_STEP_KEY_SHARE` Round 2: input X4S key from peer 736*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X4S_STEP_ZK_PUBLIC` Round 2: input Schnorr NIZKP public key for the X4S key 737*62c56f98SSadaf Ebrahimi* `PSA_JPAKE_X4S_STEP_ZK_PROOF` Round 2: input Schnorr NIZKP proof for the X4S key 738*62c56f98SSadaf Ebrahimi 739*62c56f98SSadaf EbrahimiThe core checks that `input_length` is not greater than `PSA_PAKE_INPUT_SIZE(alg, prim, step)` and 740*62c56f98SSadaf Ebrahimithe driver can rely on that. 741*62c56f98SSadaf Ebrahimi 742*62c56f98SSadaf Ebrahimi### PAKE driver get implicit key 743*62c56f98SSadaf Ebrahimi 744*62c56f98SSadaf Ebrahimi``` 745*62c56f98SSadaf Ebrahimipsa_status_t acme_pake_get_implicit_key( 746*62c56f98SSadaf Ebrahimi acme_pake_operation_t *operation, 747*62c56f98SSadaf Ebrahimi uint8_t *output, size_t output_size, 748*62c56f98SSadaf Ebrahimi size_t *output_length ); 749*62c56f98SSadaf Ebrahimi``` 750*62c56f98SSadaf Ebrahimi 751*62c56f98SSadaf Ebrahimi* `operation` The driver PAKE operation object to use. 752*62c56f98SSadaf Ebrahimi* `output` Buffer where the implicit key is to be written. 753*62c56f98SSadaf Ebrahimi* `output_size` Size of the output buffer in bytes. 754*62c56f98SSadaf Ebrahimi* `output_length` On success, the number of bytes of the implicit key. 755*62c56f98SSadaf Ebrahimi 756*62c56f98SSadaf Ebrahimi### Driver entry points for key management 757*62c56f98SSadaf Ebrahimi 758*62c56f98SSadaf EbrahimiThe driver entry points for key management differ significantly between [transparent drivers](#key-management-with-transparent-drivers) and [opaque drivers](#key-management-with-opaque-drivers). This section describes common elements. Refer to the applicable section for each driver type for more information. 759*62c56f98SSadaf Ebrahimi 760*62c56f98SSadaf EbrahimiThe entry points that create or format key data have the following prototypes for a driver with the prefix `"acme"`: 761*62c56f98SSadaf Ebrahimi 762*62c56f98SSadaf Ebrahimi``` 763*62c56f98SSadaf Ebrahimipsa_status_t acme_import_key(const psa_key_attributes_t *attributes, 764*62c56f98SSadaf Ebrahimi const uint8_t *data, 765*62c56f98SSadaf Ebrahimi size_t data_length, 766*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 767*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 768*62c56f98SSadaf Ebrahimi size_t *key_buffer_length, 769*62c56f98SSadaf Ebrahimi size_t *bits); // additional parameter, see below 770*62c56f98SSadaf Ebrahimipsa_status_t acme_generate_key(const psa_key_attributes_t *attributes, 771*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 772*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 773*62c56f98SSadaf Ebrahimi size_t *key_buffer_length); 774*62c56f98SSadaf Ebrahimi``` 775*62c56f98SSadaf EbrahimiAdditionally, opaque drivers can create keys through their [`"key_derivation_output_key"`](#key-derivation-driver-outputs) and [`"key_agreement_key"`](#key-agreement) entry points. Transparent drivers can create key material through their [`"derive_key"`](#transparent-cooked-key-derivation) entry point. 776*62c56f98SSadaf Ebrahimi 777*62c56f98SSadaf EbrahimiTODO: copy 778*62c56f98SSadaf Ebrahimi 779*62c56f98SSadaf Ebrahimi* The key attributes (`attributes`) have the same semantics as in the PSA Cryptography application interface. 780*62c56f98SSadaf Ebrahimi* For the `"import_key"` entry point, the input in the `data` buffer is either the export format or an implementation-specific format that the core documents as an acceptable input format for `psa_import_key()`. 781*62c56f98SSadaf Ebrahimi* The size of the key data buffer `key_buffer` is sufficient for the internal representation of the key. For a transparent driver, this is the key's [export format](#key-format-for-transparent-drivers). For an opaque driver, this is the size determined from the driver description and the key attributes, as specified in the section [“Key format for opaque drivers”](#key-format-for-opaque-drivers). 782*62c56f98SSadaf Ebrahimi* For an opaque driver with an `"allocate_key"` entry point, the content of the key data buffer on entry is the output of that entry point. 783*62c56f98SSadaf Ebrahimi* The `"import_key"` entry point must determine or validate the key size and set `*bits` as described in the section [“Key size determination on import”](#key-size-determination-on-import) below. 784*62c56f98SSadaf Ebrahimi 785*62c56f98SSadaf EbrahimiAll key creation entry points must ensure that the resulting key is valid as specified in the section [“Key validation”](#key-validation) below. This is primarily important for import entry points since the key data comes from the application. 786*62c56f98SSadaf Ebrahimi 787*62c56f98SSadaf Ebrahimi#### Key size determination on import 788*62c56f98SSadaf Ebrahimi 789*62c56f98SSadaf EbrahimiThe `"import_key"` entry point must determine or validate the key size. 790*62c56f98SSadaf EbrahimiThe PSA Cryptography API exposes the key size as part of the key attributes. 791*62c56f98SSadaf EbrahimiWhen importing a key, the key size recorded in the key attributes can be either a size specified by the caller of the API (who may not be trusted), or `0` which indicates that the size must be calculated from the data. 792*62c56f98SSadaf Ebrahimi 793*62c56f98SSadaf EbrahimiWhen the core calls the `"import_key"` entry point to process a call to `psa_import_key`, it passes an `attributes` structure such that `psa_get_key_bits(attributes)` is the size passed by the caller of `psa_import_key`. If this size is `0`, the `"import_key"` entry point must set the `bits` input-output parameter to the correct key size. The semantics of `bits` is as follows: 794*62c56f98SSadaf Ebrahimi 795*62c56f98SSadaf Ebrahimi* The core sets `*bits` to `psa_get_key_bits(attributes)` before calling the `"import_key"` entry point. 796*62c56f98SSadaf Ebrahimi* If `*bits == 0`, the driver must determine the key size from the data and set `*bits` to this size. If the key size cannot be determined from the data, the driver must return `PSA_ERROR_INVALID_ARGUMENT` (as of version 1.0 of the PSA Cryptography API specification, it is possible to determine the key size for all standard key types). 797*62c56f98SSadaf Ebrahimi* If `*bits != 0`, the driver must check the value of `*bits` against the data and return `PSA_ERROR_INVALID_ARGUMENT` if it does not match. If the driver entry point changes `*bits` to a different value but returns `PSA_SUCCESS`, the core will consider the key as invalid and the import will fail. 798*62c56f98SSadaf Ebrahimi 799*62c56f98SSadaf Ebrahimi#### Key validation 800*62c56f98SSadaf Ebrahimi 801*62c56f98SSadaf EbrahimiKey creation entry points must produce valid key data. Key data is _valid_ if operations involving the key are guaranteed to work functionally and not to cause indirect security loss. Operation functions are supposed to receive valid keys, and should not have to check and report invalid keys. For example: 802*62c56f98SSadaf Ebrahimi 803*62c56f98SSadaf Ebrahimi* If a cryptographic mechanism is defined as having keying material of a certain size, or if the keying material involves integers that have to be in a certain range, key creation must ensure that the keying material has an appropriate size and falls within an appropriate range. 804*62c56f98SSadaf Ebrahimi* If a cryptographic operation involves a division by an integer which is provided as part of a key, key creation must ensure that this integer is nonzero. 805*62c56f98SSadaf Ebrahimi* If a cryptographic operation involves two keys A and B (or more), then the creation of A must ensure that using it does not risk compromising B. This applies even if A's policy does not explicitly allow a problematic operation, but A is exportable. In particular, public keys that can potentially be used for key agreement are considered invalid and must not be created if they risk compromising the private key. 806*62c56f98SSadaf Ebrahimi* On the other hand, it is acceptable for import to accept a key that cannot be verified as valid if using this key would at most compromise the key itself and material that is secured with this key. For example, RSA key import does not need to verify that the primes are actually prime. Key import may accept an insecure key if the consequences of the insecurity are no worse than a leak of the key prior to its import. 807*62c56f98SSadaf Ebrahimi 808*62c56f98SSadaf EbrahimiWith opaque drivers, the key context can only be used by code from the same driver, so key validity is primarily intended to report key creation errors at creation time rather than during an operation. With transparent drivers, the key context can potentially be used by code from a different provider, so key validity is critical for interoperability. 809*62c56f98SSadaf Ebrahimi 810*62c56f98SSadaf EbrahimiThis section describes some minimal validity requirements for standard key types. 811*62c56f98SSadaf Ebrahimi 812*62c56f98SSadaf Ebrahimi* For symmetric key types, check that the key size is suitable for the type. 813*62c56f98SSadaf Ebrahimi* For DES (`PSA_KEY_TYPE_DES`), additionally verify the parity bits. 814*62c56f98SSadaf Ebrahimi* For RSA (`PSA_KEY_TYPE_RSA_PUBLIC_KEY`, `PSA_KEY_TYPE_RSA_KEY_PAIR`), check the syntax of the key and make sanity checks on its components. TODO: what sanity checks? Value ranges (e.g. p < n), sanity checks such as parity, minimum and maximum size, what else? 815*62c56f98SSadaf Ebrahimi* For elliptic curve private keys (`PSA_KEY_TYPE_ECC_KEY_PAIR`), check the size and range. TODO: what else? 816*62c56f98SSadaf Ebrahimi* For elliptic curve public keys (`PSA_KEY_TYPE_ECC_PUBLIC_KEY`), check the size and range, and that the point is on the curve. TODO: what else? 817*62c56f98SSadaf Ebrahimi 818*62c56f98SSadaf Ebrahimi### Entropy collection entry point 819*62c56f98SSadaf Ebrahimi 820*62c56f98SSadaf EbrahimiA driver can declare an entropy source by providing a `"get_entropy"` entry point. This entry point has the following prototype for a driver with the prefix `"acme"`: 821*62c56f98SSadaf Ebrahimi 822*62c56f98SSadaf Ebrahimi``` 823*62c56f98SSadaf Ebrahimipsa_status_t acme_get_entropy(uint32_t flags, 824*62c56f98SSadaf Ebrahimi size_t *estimate_bits, 825*62c56f98SSadaf Ebrahimi uint8_t *output, 826*62c56f98SSadaf Ebrahimi size_t output_size); 827*62c56f98SSadaf Ebrahimi``` 828*62c56f98SSadaf Ebrahimi 829*62c56f98SSadaf EbrahimiThe semantics of the parameters is as follows: 830*62c56f98SSadaf Ebrahimi 831*62c56f98SSadaf Ebrahimi* `flags`: a bit-mask of [entropy collection flags](#entropy-collection-flags). 832*62c56f98SSadaf Ebrahimi* `estimate_bits`: on success, an estimate of the amount of entropy that is present in the `output` buffer, in bits. This must be at least `1` on success. The value is ignored on failure. Drivers should return a conservative estimate, even in circumstances where the quality of the entropy source is degraded due to environmental conditions (e.g. undervolting, low temperature, etc.). 833*62c56f98SSadaf Ebrahimi* `output`: on success, this buffer contains non-deterministic data with an estimated entropy of at least `*estimate_bits` bits. When the entropy is coming from a hardware peripheral, this should preferably be raw or lightly conditioned measurements from a physical process, such that statistical tests run over a sufficiently large amount of output can confirm the entropy estimates. But this specification also permits entropy sources that are fully conditioned, for example when the PSA Cryptography system is running as an application in an operating system and `"get_entropy"` returns data from the random generator in the operating system's kernel. 834*62c56f98SSadaf Ebrahimi* `output_size`: the size of the `output` buffer in bytes. This size should be large enough to allow a driver to pass unconditioned data with a low density of entropy; for example a peripheral that returns eight bytes of data with an estimated one bit of entropy cannot provide meaningful output in less than 8 bytes. 835*62c56f98SSadaf Ebrahimi 836*62c56f98SSadaf EbrahimiNote that there is no output parameter indicating how many bytes the driver wrote to the buffer. Such an output length indication is not necessary because the entropy may be located anywhere in the buffer, so the driver may write less than `output_size` bytes but the core does not need to know this. The output parameter `estimate_bits` contains the amount of entropy, expressed in bits, which may be significantly less than `output_size * 8`. 837*62c56f98SSadaf Ebrahimi 838*62c56f98SSadaf EbrahimiThe entry point may return the following statuses: 839*62c56f98SSadaf Ebrahimi 840*62c56f98SSadaf Ebrahimi* `PSA_SUCCESS`: success. The output buffer contains some entropy. 841*62c56f98SSadaf Ebrahimi* `PSA_ERROR_INSUFFICIENT_ENTROPY`: no entropy is available without blocking. This is only permitted if the `PSA_DRIVER_GET_ENTROPY_BLOCK` flag is clear. The core may call `get_entropy` again later, giving time for entropy to be gathered or for adverse environmental conditions to be rectified. 842*62c56f98SSadaf Ebrahimi* Other error codes indicate a transient or permanent failure of the entropy source. 843*62c56f98SSadaf Ebrahimi 844*62c56f98SSadaf EbrahimiUnlike most other entry points, if multiple transparent drivers include a `"get_entropy"` point, the core will call all of them (as well as the entry points from opaque drivers). Fallback is not applicable to `"get_entropy"`. 845*62c56f98SSadaf Ebrahimi 846*62c56f98SSadaf Ebrahimi#### Entropy collection flags 847*62c56f98SSadaf Ebrahimi 848*62c56f98SSadaf Ebrahimi* `PSA_DRIVER_GET_ENTROPY_BLOCK`: If this flag is set, the driver should block until it has at least one bit of entropy. If this flag is clear, the driver should avoid blocking if no entropy is readily available. 849*62c56f98SSadaf Ebrahimi* `PSA_DRIVER_GET_ENTROPY_KEEPALIVE`: This flag is intended to help with energy management for entropy-generating peripherals. If this flag is set, the driver should expect another call to `acme_get_entropy` after a short time. If this flag is clear, the core is not expecting to call the `"get_entropy"` entry point again within a short amount of time (but it may do so nonetheless). 850*62c56f98SSadaf Ebrahimi 851*62c56f98SSadaf Ebrahimi#### Entropy collection and blocking 852*62c56f98SSadaf Ebrahimi 853*62c56f98SSadaf EbrahimiThe intent of the `BLOCK` and `KEEPALIVE` [flags](#entropy-collection-flags) is to support drivers for TRNG (True Random Number Generator, i.e. an entropy source peripheral) that have a long ramp-up time, especially on platforms with multiple entropy sources. 854*62c56f98SSadaf Ebrahimi 855*62c56f98SSadaf EbrahimiHere is a suggested call sequence for entropy collection that leverages these flags: 856*62c56f98SSadaf Ebrahimi 857*62c56f98SSadaf Ebrahimi1. The core makes a first round of calls to `"get_entropy"` on every source with the `BLOCK` flag clear and the `KEEPALIVE` flag set, so that drivers can prepare the TRNG peripheral. 858*62c56f98SSadaf Ebrahimi2. The core makes a second round of calls with the `BLOCK` flag set and the `KEEPALIVE` flag clear to gather needed entropy. 859*62c56f98SSadaf Ebrahimi3. If the second round does not collect enough entropy, the core makes more similar rounds, until the total amount of collected entropy is sufficient. 860*62c56f98SSadaf Ebrahimi 861*62c56f98SSadaf Ebrahimi### Miscellaneous driver entry points 862*62c56f98SSadaf Ebrahimi 863*62c56f98SSadaf Ebrahimi#### Driver initialization 864*62c56f98SSadaf Ebrahimi 865*62c56f98SSadaf EbrahimiA driver may declare an `"init"` entry point in a capability with no algorithm, key type or key size. If so, the core calls this entry point once during the initialization of the PSA Cryptography subsystem. If the init entry point of any driver fails, the initialization of the PSA Cryptography subsystem fails. 866*62c56f98SSadaf Ebrahimi 867*62c56f98SSadaf EbrahimiWhen multiple drivers have an init entry point, the order in which they are called is unspecified. It is also unspecified whether other drivers' `"init"` entry points are called if one or more init entry point fails. 868*62c56f98SSadaf Ebrahimi 869*62c56f98SSadaf EbrahimiOn platforms where the PSA Cryptography implementation is a subsystem of a single application, the initialization of the PSA Cryptography subsystem takes place during the call to `psa_crypto_init()`. On platforms where the PSA Cryptography implementation is separate from the application or applications, the initialization of the PSA Cryptography subsystem takes place before or during the first time an application calls `psa_crypto_init()`. 870*62c56f98SSadaf Ebrahimi 871*62c56f98SSadaf EbrahimiThe init entry point does not take any parameter. 872*62c56f98SSadaf Ebrahimi 873*62c56f98SSadaf Ebrahimi### Combining multiple drivers 874*62c56f98SSadaf Ebrahimi 875*62c56f98SSadaf EbrahimiTo declare a cryptoprocessor can handle both cleartext and wrapped keys, you need to provide two driver descriptions, one for a transparent driver and one for an opaque driver. You can use the mapping in capabilities' `"names"` property to arrange for multiple driver entry points to map to the same C function. 876*62c56f98SSadaf Ebrahimi 877*62c56f98SSadaf Ebrahimi## Transparent drivers 878*62c56f98SSadaf Ebrahimi 879*62c56f98SSadaf Ebrahimi### Key format for transparent drivers 880*62c56f98SSadaf Ebrahimi 881*62c56f98SSadaf EbrahimiThe format of a key for transparent drivers is the same as in applications. Refer to the documentation of [`psa_export_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) and [`psa_export_public_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_public_key) in the PSA Cryptography API specification. For custom key types defined by an implementation, refer to the documentation of that implementation. 882*62c56f98SSadaf Ebrahimi 883*62c56f98SSadaf Ebrahimi### Key management with transparent drivers 884*62c56f98SSadaf Ebrahimi 885*62c56f98SSadaf EbrahimiTransparent drivers may provide the following key management entry points: 886*62c56f98SSadaf Ebrahimi 887*62c56f98SSadaf Ebrahimi* [`"import_key"`](#key-import-with-transparent-drivers): called by `psa_import_key()`, only when importing a key pair or a public key (key such that `PSA_KEY_TYPE_IS_ASYMMETRIC` is true). 888*62c56f98SSadaf Ebrahimi* `"generate_key"`: called by `psa_generate_key()`, only when generating a key pair (key such that `PSA_KEY_TYPE_IS_KEY_PAIR` is true). 889*62c56f98SSadaf Ebrahimi* `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()`, only when deriving a key pair (key such that `PSA_KEY_TYPE_IS_KEY_PAIR` is true). 890*62c56f98SSadaf Ebrahimi* `"export_public_key"`: called by the core to obtain the public key of a key pair. The core may call this function at any time to obtain the public key, which can be for `psa_export_public_key()` but also at other times, including during a cryptographic operation that requires the public key such as a call to `psa_verify_message()` on a key pair object. 891*62c56f98SSadaf Ebrahimi 892*62c56f98SSadaf EbrahimiTransparent drivers are not involved when exporting, copying or destroying keys, or when importing, generating or deriving symmetric keys. 893*62c56f98SSadaf Ebrahimi 894*62c56f98SSadaf Ebrahimi#### Key import with transparent drivers 895*62c56f98SSadaf Ebrahimi 896*62c56f98SSadaf EbrahimiAs discussed in [the general section about key management entry points](#driver-entry-points-for-key-management), the key import entry points has the following prototype for a driver with the prefix `"acme"`: 897*62c56f98SSadaf Ebrahimi``` 898*62c56f98SSadaf Ebrahimipsa_status_t acme_import_key(const psa_key_attributes_t *attributes, 899*62c56f98SSadaf Ebrahimi const uint8_t *data, 900*62c56f98SSadaf Ebrahimi size_t data_length, 901*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 902*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 903*62c56f98SSadaf Ebrahimi size_t *key_buffer_length, 904*62c56f98SSadaf Ebrahimi size_t *bits); 905*62c56f98SSadaf Ebrahimi``` 906*62c56f98SSadaf Ebrahimi 907*62c56f98SSadaf EbrahimiThis entry point has several roles: 908*62c56f98SSadaf Ebrahimi 909*62c56f98SSadaf Ebrahimi1. Parse the key data in the input buffer `data`. The driver must support the export format for the key types that the entry point is declared for. It may support additional formats as specified in the description of [`psa_import_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) in the PSA Cryptography API specification. 910*62c56f98SSadaf Ebrahimi2. Validate the key data. The necessary validation is described in the section [“Key validation”](#key-validation) above. 911*62c56f98SSadaf Ebrahimi3. [Determine the key size](#key-size-determination-on-import) and output it through `*bits`. 912*62c56f98SSadaf Ebrahimi4. Copy the validated key data from `data` to `key_buffer`. The output must be in the canonical format documented for [`psa_export_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_key) or [`psa_export_public_key()`](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html#c.psa_export_public_key), so if the input is not in this format, the entry point must convert it. 913*62c56f98SSadaf Ebrahimi 914*62c56f98SSadaf Ebrahimi### Random generation entry points 915*62c56f98SSadaf Ebrahimi 916*62c56f98SSadaf EbrahimiA transparent driver may provide an operation family that can be used as a cryptographic random number generator. The random generation mechanism must obey the following requirements: 917*62c56f98SSadaf Ebrahimi 918*62c56f98SSadaf Ebrahimi* The random output must be of cryptographic quality, with a uniform distribution. Therefore, if the random generator includes an entropy source, this entropy source must be fed through a CSPRNG (cryptographically secure pseudo-random number generator). 919*62c56f98SSadaf Ebrahimi* Random generation is expected to be fast. (If a device can provide entropy but is slow at generating random data, declare it as an [entropy driver](#entropy-collection-entry-point) instead.) 920*62c56f98SSadaf Ebrahimi* The random generator should be able to incorporate entropy provided by an outside source. If it isn't, the random generator can only be used if it's the only entropy source on the platform. (A random generator peripheral can be declared as an [entropy source](#entropy-collection-entry-point) instead of a random generator; this way the core will combine it with other entropy sources.) 921*62c56f98SSadaf Ebrahimi* The random generator may either be deterministic (in the sense that it always returns the same data when given the same entropy inputs) or non-deterministic (including its own entropy source). In other words, this interface is suitable both for PRNG (pseudo-random number generator, also known as DRBG (deterministic random bit generator)) and for NRBG (non-deterministic random bit generator). 922*62c56f98SSadaf Ebrahimi 923*62c56f98SSadaf EbrahimiIf no driver implements the random generation entry point family, the core provides an unspecified random generation mechanism. 924*62c56f98SSadaf Ebrahimi 925*62c56f98SSadaf EbrahimiThis operation family requires the following type, entry points and parameters (TODO: where exactly are the parameters in the JSON structure?): 926*62c56f98SSadaf Ebrahimi 927*62c56f98SSadaf Ebrahimi* Type `"random_context_t"`: the type of a random generation context. 928*62c56f98SSadaf Ebrahimi* `"init_random"` (entry point, optional): if this function is present, [the core calls it once](#random-generator-initialization) after allocating a `"random_context_t"` object. 929*62c56f98SSadaf Ebrahimi* `"add_entropy"` (entry point, optional): the core calls this function to [inject entropy](#entropy-injection). This entry point is optional if the driver is for a peripheral that includes an entropy source of its own, however [random generator drivers without entropy injection](#random-generator-drivers-without-entropy-injection) have limited portability since they can only be used on platforms with no other entropy source. This entry point is mandatory if `"initial_entropy_size"` is nonzero. 930*62c56f98SSadaf Ebrahimi* `"get_random"` (entry point, mandatory): the core calls this function whenever it needs to [obtain random data](#the-get_random-entry-point). 931*62c56f98SSadaf Ebrahimi* `"initial_entropy_size"` (integer, mandatory): the minimum number of bytes of entropy that the core must supply before the driver can output random data. This can be `0` if the driver is for a peripheral that includes an entropy source of its own. 932*62c56f98SSadaf Ebrahimi* `"reseed_entropy_size"` (integer, optional): the minimum number of bytes of entropy that the core should supply via [`"add_entropy"`](#entropy-injection) when the driver runs out of entropy. This value is also a hint for the size to supply if the core makes additional calls to `"add_entropy"`, for example to enforce prediction resistance. If omitted, the core should pass an amount of entropy corresponding to the expected security strength of the device (for example, pass 32 bytes of entropy when reseeding to achieve a security strength of 256 bits). If specified, the core should pass the larger of `"reseed_entropy_size"` and the amount corresponding to the security strength. 933*62c56f98SSadaf Ebrahimi 934*62c56f98SSadaf EbrahimiRandom generation is not parametrized by an algorithm. The choice of algorithm is up to the driver. 935*62c56f98SSadaf Ebrahimi 936*62c56f98SSadaf Ebrahimi#### Random generator initialization 937*62c56f98SSadaf Ebrahimi 938*62c56f98SSadaf EbrahimiThe `"init_random"` entry point has the following prototype for a driver with the prefix `"acme"`: 939*62c56f98SSadaf Ebrahimi 940*62c56f98SSadaf Ebrahimi``` 941*62c56f98SSadaf Ebrahimipsa_status_t acme_init_random(acme_random_context_t *context); 942*62c56f98SSadaf Ebrahimi``` 943*62c56f98SSadaf Ebrahimi 944*62c56f98SSadaf EbrahimiThe core calls this entry point once after allocating a random generation context. Initially, the context object is all-bits-zero. 945*62c56f98SSadaf Ebrahimi 946*62c56f98SSadaf EbrahimiIf a driver does not have an `"init_random"` entry point, the context object passed to the first call to `"add_entropy"` or `"get_random"` will be all-bits-zero. 947*62c56f98SSadaf Ebrahimi 948*62c56f98SSadaf Ebrahimi#### Entropy injection 949*62c56f98SSadaf Ebrahimi 950*62c56f98SSadaf EbrahimiThe `"add_entropy"` entry point has the following prototype for a driver with the prefix `"acme"`: 951*62c56f98SSadaf Ebrahimi 952*62c56f98SSadaf Ebrahimi``` 953*62c56f98SSadaf Ebrahimipsa_status_t acme_add_entropy(acme_random_context_t *context, 954*62c56f98SSadaf Ebrahimi const uint8_t *entropy, 955*62c56f98SSadaf Ebrahimi size_t entropy_size); 956*62c56f98SSadaf Ebrahimi``` 957*62c56f98SSadaf Ebrahimi 958*62c56f98SSadaf EbrahimiThe semantics of the parameters is as follows: 959*62c56f98SSadaf Ebrahimi 960*62c56f98SSadaf Ebrahimi* `context`: a random generation context. On the first call to `"add_entropy"`, this object has been initialized by a call to the driver's `"init_random"` entry point if one is present, and to all-bits-zero otherwise. 961*62c56f98SSadaf Ebrahimi* `entropy`: a buffer containing full-entropy data to seed the random generator. “Full-entropy” means that the data is uniformly distributed and independent of any other observable quantity. 962*62c56f98SSadaf Ebrahimi* `entropy_size`: the size of the `entropy` buffer in bytes. It is guaranteed to be at least `1`, but it may be smaller than the amount of entropy that the driver needs to deliver random data, in which case the core will call the `"add_entropy"` entry point again to supply more entropy. 963*62c56f98SSadaf Ebrahimi 964*62c56f98SSadaf EbrahimiThe core calls this function to supply entropy to the driver. The driver must mix this entropy into its internal state. The driver must mix the whole supplied entropy, even if there is more than what the driver requires, to ensure that all entropy sources are mixed into the random generator state. The driver may mix additional entropy of its own. 965*62c56f98SSadaf Ebrahimi 966*62c56f98SSadaf EbrahimiThe core may call this function at any time. For example, to enforce prediction resistance, the core can call `"add_entropy"` immediately after each call to `"get_random"`. The core must call this function in two circumstances: 967*62c56f98SSadaf Ebrahimi 968*62c56f98SSadaf Ebrahimi* Before the first call to the `"get_random"` entry point, to supply `"initial_entropy_size"` bytes of entropy. 969*62c56f98SSadaf Ebrahimi* After a call to the `"get_random"` entry point returns less than the required amount of random data, to supply at least `"reseed_entropy_size"` bytes of entropy. 970*62c56f98SSadaf Ebrahimi 971*62c56f98SSadaf EbrahimiWhen the driver requires entropy, the core can supply it with one or more successive calls to the `"add_entropy"` entry point. If the required entropy size is zero, the core does not need to call `"add_entropy"`. 972*62c56f98SSadaf Ebrahimi 973*62c56f98SSadaf Ebrahimi#### Combining entropy sources with a random generation driver 974*62c56f98SSadaf Ebrahimi 975*62c56f98SSadaf EbrahimiThis section provides guidance on combining one or more [entropy sources](#entropy-collection-entry-point) (each having a `"get_entropy"` entry point) with a random generation driver (with an `"add_entropy"` entry point). 976*62c56f98SSadaf Ebrahimi 977*62c56f98SSadaf EbrahimiNote that `"get_entropy"` returns data with an estimated amount of entropy that is in general less than the buffer size. The core must apply a mixing algorithm to the output of `"get_entropy"` to obtain full-entropy data. 978*62c56f98SSadaf Ebrahimi 979*62c56f98SSadaf EbrahimiFor example, the core may use a simple mixing scheme based on a pseudorandom function family $(F_k)$ with an $E$-bit output where $E = 8 \cdot \mathtt{entropy_size}$ and $\mathtt{entropy_size}$ is the desired amount of entropy in bytes (typically the random driver's `"initial_entropy_size"` property for the initial seeding and the `"reseed_entropy_size"` property for subsequent reseeding). The core calls the `"get_entropy"` points of the available entropy drivers, outputting a string $s_i$ and an entropy estimate $e_i$ on the $i$th call. It does so until the total entropy estimate $e_1 + e_2 + \ldots + e_n$ is at least $E$. The core then calculates $F_k(0)$ where $k = s_1 || s_2 || \ldots || s_n$. This value is a string of $\mathtt{entropy_size}$, and since $(F_k)$ is a pseudorandom function family, $F_k(0)$ is uniformly distributed over strings of $\mathtt{entropy_size}$ bytes. Therefore $F_k(0)$ is a suitable value to pass to `"add_entropy"`. 980*62c56f98SSadaf Ebrahimi 981*62c56f98SSadaf EbrahimiNote that the mechanism above is only given as an example. Implementations may choose a different mechanism, for example involving multiple pools or intermediate compression functions. 982*62c56f98SSadaf Ebrahimi 983*62c56f98SSadaf Ebrahimi#### Random generator drivers without entropy injection 984*62c56f98SSadaf Ebrahimi 985*62c56f98SSadaf EbrahimiRandom generator drivers should have the capability to inject additional entropy through the `"add_entropy"` entry point. This ensures that the random generator depends on all the entropy sources that are available on the platform. A driver where a call to `"add_entropy"` does not affect the state of the random generator is not compliant with this specification. 986*62c56f98SSadaf Ebrahimi 987*62c56f98SSadaf EbrahimiHowever, a driver may omit the `"add_entropy"` entry point. This limits the driver's portability: implementations of the PSA Cryptography specification may reject drivers without an `"add_entropy"` entry point, or only accept such drivers in certain configurations. In particular, the `"add_entropy"` entry point is required if: 988*62c56f98SSadaf Ebrahimi 989*62c56f98SSadaf Ebrahimi* the integration of PSA Cryptography includes an entropy source that is outside the driver; or 990*62c56f98SSadaf Ebrahimi* the core saves random data in persistent storage to be preserved across platform resets. 991*62c56f98SSadaf Ebrahimi 992*62c56f98SSadaf Ebrahimi#### The `"get_random"` entry point 993*62c56f98SSadaf Ebrahimi 994*62c56f98SSadaf EbrahimiThe `"get_random"` entry point has the following prototype for a driver with the prefix `"acme"`: 995*62c56f98SSadaf Ebrahimi 996*62c56f98SSadaf Ebrahimi``` 997*62c56f98SSadaf Ebrahimipsa_status_t acme_get_random(acme_random_context_t *context, 998*62c56f98SSadaf Ebrahimi uint8_t *output, 999*62c56f98SSadaf Ebrahimi size_t output_size, 1000*62c56f98SSadaf Ebrahimi size_t *output_length); 1001*62c56f98SSadaf Ebrahimi``` 1002*62c56f98SSadaf Ebrahimi 1003*62c56f98SSadaf EbrahimiThe semantics of the parameters is as follows: 1004*62c56f98SSadaf Ebrahimi 1005*62c56f98SSadaf Ebrahimi* `context`: a random generation context. If the driver's `"initial_entropy_size"` property is nonzero, the core must have called `"add_entropy"` at least once with a total of at least `"initial_entropy_size"` bytes of entropy before it calls `"get_random"`. Alternatively, if the driver's `"initial_entropy_size"` property is zero and the core did not call `"add_entropy"`, or if the driver has no `"add_entropy"` entry point, the core must have called `"init_random"` if present, and otherwise the context is all-bits zero. 1006*62c56f98SSadaf Ebrahimi* `output`: on success (including partial success), the first `*output_length` bytes of this buffer contain cryptographic-quality random data. The output is not used on error. 1007*62c56f98SSadaf Ebrahimi* `output_size`: the size of the `output` buffer in bytes. 1008*62c56f98SSadaf Ebrahimi* `*output_length`: on success (including partial success), the number of bytes of random data that the driver has written to the `output` buffer. This is preferably `output_size`, but the driver is allowed to return less data if it runs out of entropy as described below. The core sets this value to 0 on entry. The value is not used on error. 1009*62c56f98SSadaf Ebrahimi 1010*62c56f98SSadaf EbrahimiThe driver may return the following status codes: 1011*62c56f98SSadaf Ebrahimi 1012*62c56f98SSadaf Ebrahimi* `PSA_SUCCESS`: the `output` buffer contains `*output_length` bytes of cryptographic-quality random data. Note that this may be less than `output_size`; in this case the core should call the driver's `"add_entropy"` method to supply at least `"reseed_entropy_size"` bytes of entropy before calling `"get_random"` again. 1013*62c56f98SSadaf Ebrahimi* `PSA_ERROR_INSUFFICIENT_ENTROPY`: the core must supply additional entropy by calling the `"add_entropy"` entry point with at least `"reseed_entropy_size"` bytes. 1014*62c56f98SSadaf Ebrahimi* `PSA_ERROR_NOT_SUPPORTED`: the random generator is not available. This is only permitted if the driver specification for random generation has the [fallback property](#fallback) enabled. 1015*62c56f98SSadaf Ebrahimi* Other error codes such as `PSA_ERROR_COMMUNICATION_FAILURE` or `PSA_ERROR_HARDWARE_FAILURE` indicate a transient or permanent error. 1016*62c56f98SSadaf Ebrahimi 1017*62c56f98SSadaf Ebrahimi### Fallback 1018*62c56f98SSadaf Ebrahimi 1019*62c56f98SSadaf EbrahimiSometimes cryptographic accelerators only support certain cryptographic mechanisms partially. The capability description language allows specifying some restrictions, including restrictions on key sizes, but it cannot cover all the possibilities that may arise in practice. Furthermore, it may be desirable to deploy the same binary image on different devices, only some of which have a cryptographic accelerators. 1020*62c56f98SSadaf EbrahimiFor these purposes, a transparent driver can declare that it only supports a [capability](#driver-description-capability) partially, by setting the capability's `"fallback"` property to true. 1021*62c56f98SSadaf Ebrahimi 1022*62c56f98SSadaf EbrahimiIf a transparent driver entry point is part of a capability which has a true `"fallback"` property and returns `PSA_ERROR_NOT_SUPPORTED`, the core will call the next transparent driver that supports the mechanism, if there is one. The core considers drivers in the order given by the [driver description list](#driver-description-list). 1023*62c56f98SSadaf Ebrahimi 1024*62c56f98SSadaf EbrahimiIf all the available drivers have fallback enabled and return `PSA_ERROR_NOT_SUPPORTED`, the core will perform the operation using built-in code. 1025*62c56f98SSadaf EbrahimiAs soon as a driver returns any value other than `PSA_ERROR_NOT_SUPPORTED` (`PSA_SUCCESS` or a different error code), this value is returned to the application, without attempting to call any other driver or built-in code. 1026*62c56f98SSadaf Ebrahimi 1027*62c56f98SSadaf EbrahimiIf a transparent driver entry point is part of a capability where the `"fallback"` property is false or omitted, the core should not include any other code for this capability, whether built in or in another transparent driver. 1028*62c56f98SSadaf Ebrahimi 1029*62c56f98SSadaf Ebrahimi## Opaque drivers 1030*62c56f98SSadaf Ebrahimi 1031*62c56f98SSadaf EbrahimiOpaque drivers allow a PSA Cryptography implementation to delegate cryptographic operations to a separate environment that might not allow exporting key material in cleartext. The opaque driver interface is designed so that the core never inspects the representation of a key. The opaque driver interface is designed to support two subtypes of cryptoprocessors: 1032*62c56f98SSadaf Ebrahimi 1033*62c56f98SSadaf Ebrahimi* Some cryptoprocessors do not have persistent storage for individual keys. The representation of a key is the key material wrapped with a master key which is located in the cryptoprocessor and never exported from it. The core stores this wrapped key material on behalf of the cryptoprocessor. 1034*62c56f98SSadaf Ebrahimi* Some cryptoprocessors have persistent storage for individual keys. The representation of a key is an identifier such as label or slot number. The core stores this identifier. 1035*62c56f98SSadaf Ebrahimi 1036*62c56f98SSadaf Ebrahimi### Key format for opaque drivers 1037*62c56f98SSadaf Ebrahimi 1038*62c56f98SSadaf EbrahimiThe format of a key for opaque drivers is an opaque blob. The content of this blob is fully up to the driver. The core merely stores this blob. 1039*62c56f98SSadaf Ebrahimi 1040*62c56f98SSadaf EbrahimiNote that since the core stores the key context blob as it is in memory, it must only contain data that is meaningful after a reboot. In particular, it must not contain any pointers or transient handles. 1041*62c56f98SSadaf Ebrahimi 1042*62c56f98SSadaf EbrahimiThe `"key_context"` property in the [driver description](#driver-description-top-level-element) specifies how to calculate the size of the key context as a function of the key type and size. This is an object with the following properties: 1043*62c56f98SSadaf Ebrahimi 1044*62c56f98SSadaf Ebrahimi* `"base_size"` (integer or string, optional): this many bytes are included in every key context. If omitted, this value defaults to 0. 1045*62c56f98SSadaf Ebrahimi* `"key_pair_size"` (integer or string, optional): this many bytes are included in every key context for a key pair. If omitted, this value defaults to 0. 1046*62c56f98SSadaf Ebrahimi* `"public_key_size"` (integer or string, optional): this many bytes are included in every key context for a public key. If omitted, this value defaults to 0. 1047*62c56f98SSadaf Ebrahimi* `"symmetric_factor"` (integer or string, optional): every key context for a symmetric key includes this many times the key size. If omitted, this value defaults to 0. 1048*62c56f98SSadaf Ebrahimi* `"store_public_key"` (boolean, optional): If specified and true, for a key pair, the key context includes space for the public key. If omitted or false, no additional space is added for the public key. 1049*62c56f98SSadaf Ebrahimi* `"size_function"` (string, optional): the name of a function that returns the number of bytes that the driver needs in a key context for a key. This may be a pointer to function. This must be a C identifier; more complex expressions are not permitted. If the core uses this function, it supersedes all the other properties except for `"builtin_key_size"` (where applicable, if present). 1050*62c56f98SSadaf Ebrahimi* `"builtin_key_size"` (integer or string, optional): If specified, this overrides all other methods (including the `"size_function"` entry point) to determine the size of the key context for [built-in keys](#built-in-keys). This allows drivers to efficiently represent application keys as wrapped key material, but built-in keys by an internal identifier that takes up less space. 1051*62c56f98SSadaf Ebrahimi 1052*62c56f98SSadaf EbrahimiThe integer properties must be C language constants. A typical value for `"base_size"` is `sizeof(acme_key_context_t)` where `acme_key_context_t` is a type defined in a driver header file. 1053*62c56f98SSadaf Ebrahimi 1054*62c56f98SSadaf Ebrahimi#### Size of a dynamically allocated key context 1055*62c56f98SSadaf Ebrahimi 1056*62c56f98SSadaf EbrahimiIf the core supports dynamic allocation for the key context and chooses to use it, and the driver specification includes the `"size_function"` property, the size of the key context is at least 1057*62c56f98SSadaf Ebrahimi``` 1058*62c56f98SSadaf Ebrahimisize_function(key_type, key_bits) 1059*62c56f98SSadaf Ebrahimi``` 1060*62c56f98SSadaf Ebrahimiwhere `size_function` is the function named in the `"size_function"` property, `key_type` is the key type and `key_bits` is the key size in bits. The prototype of the size function is 1061*62c56f98SSadaf Ebrahimi``` 1062*62c56f98SSadaf Ebrahimisize_t size_function(psa_key_type_t key_type, size_t key_bits); 1063*62c56f98SSadaf Ebrahimi``` 1064*62c56f98SSadaf Ebrahimi 1065*62c56f98SSadaf Ebrahimi#### Size of a statically allocated key context 1066*62c56f98SSadaf Ebrahimi 1067*62c56f98SSadaf EbrahimiIf the core does not support dynamic allocation for the key context or chooses not to use it, or if the driver specification does not include the `"size_function"` property, the size of the key context for a key of type `key_type` and of size `key_bits` bits is: 1068*62c56f98SSadaf Ebrahimi 1069*62c56f98SSadaf Ebrahimi* For a key pair (`PSA_KEY_TYPE_IS_KEY_PAIR(key_type)` is true): 1070*62c56f98SSadaf Ebrahimi ``` 1071*62c56f98SSadaf Ebrahimi base_size + key_pair_size + public_key_overhead 1072*62c56f98SSadaf Ebrahimi ``` 1073*62c56f98SSadaf Ebrahimi where `public_key_overhead = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE(key_type, key_bits)` if the `"store_public_key"` property is true and `public_key_overhead = 0` otherwise. 1074*62c56f98SSadaf Ebrahimi 1075*62c56f98SSadaf Ebrahimi* For a public key (`PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)` is true): 1076*62c56f98SSadaf Ebrahimi ``` 1077*62c56f98SSadaf Ebrahimi base_size + public_key_size 1078*62c56f98SSadaf Ebrahimi ``` 1079*62c56f98SSadaf Ebrahimi 1080*62c56f98SSadaf Ebrahimi* For a symmetric key (not a key pair or public key): 1081*62c56f98SSadaf Ebrahimi ``` 1082*62c56f98SSadaf Ebrahimi base_size + symmetric_factor * key_bytes 1083*62c56f98SSadaf Ebrahimi ``` 1084*62c56f98SSadaf Ebrahimi where `key_bytes = ((key_bits + 7) / 8)` is the key size in bytes. 1085*62c56f98SSadaf Ebrahimi 1086*62c56f98SSadaf Ebrahimi#### Key context size for a secure element with storage 1087*62c56f98SSadaf Ebrahimi 1088*62c56f98SSadaf EbrahimiIf the key is stored in the secure element and the driver only needs to store a label for the key, use `"base_size"` as the size of the label plus any other metadata that the driver needs to store, and omit the other properties. 1089*62c56f98SSadaf Ebrahimi 1090*62c56f98SSadaf EbrahimiIf the key is stored in the secure element, but the secure element does not store the public part of a key pair and cannot recompute it on demand, additionally use the `"store_public_key"` property with the value `true`. Note that this only influences the size of the key context: the driver code must copy the public key to the key context and retrieve it on demand in its `export_public_key` entry point. 1091*62c56f98SSadaf Ebrahimi 1092*62c56f98SSadaf Ebrahimi#### Key context size for a secure element without storage 1093*62c56f98SSadaf Ebrahimi 1094*62c56f98SSadaf EbrahimiIf the key is stored in wrapped form outside the secure element, and the wrapped form of the key plus any metadata has up to *N* bytes of overhead, use *N* as the value of the `"base_size"` property and set the `"symmetric_factor"` property to 1. Set the `"key_pair_size"` and `"public_key_size"` properties appropriately for the largest supported key pair and the largest supported public key respectively. 1095*62c56f98SSadaf Ebrahimi 1096*62c56f98SSadaf Ebrahimi### Key management with opaque drivers 1097*62c56f98SSadaf Ebrahimi 1098*62c56f98SSadaf EbrahimiOpaque drivers may provide the following key management entry points: 1099*62c56f98SSadaf Ebrahimi 1100*62c56f98SSadaf Ebrahimi* `"export_key"`: called by `psa_export_key()`, or by `psa_copy_key()` when copying a key from or to a different [location](#lifetimes-and-locations), or [as a fallback for key derivation](#key-derivation-driver-dispatch-logic). 1101*62c56f98SSadaf Ebrahimi* `"export_public_key"`: called by the core to obtain the public key of a key pair. The core may call this entry point at any time to obtain the public key, which can be for `psa_export_public_key()` but also at other times, including during a cryptographic operation that requires the public key such as a call to `psa_verify_message()` on a key pair object. 1102*62c56f98SSadaf Ebrahimi* `"import_key"`: called by `psa_import_key()`, or by `psa_copy_key()` when copying a key from another location. 1103*62c56f98SSadaf Ebrahimi* `"generate_key"`: called by `psa_generate_key()`. 1104*62c56f98SSadaf Ebrahimi* `"key_derivation_output_key"`: called by `psa_key_derivation_output_key()`. 1105*62c56f98SSadaf Ebrahimi* `"copy_key"`: called by `psa_copy_key()` when copying a key within the same [location](#lifetimes-and-locations). 1106*62c56f98SSadaf Ebrahimi* `"get_builtin_key"`: called by functions that access a key to retrieve information about a [built-in key](#built-in-keys). 1107*62c56f98SSadaf Ebrahimi 1108*62c56f98SSadaf EbrahimiIn addition, secure elements that store the key material internally must provide the following two entry points: 1109*62c56f98SSadaf Ebrahimi 1110*62c56f98SSadaf Ebrahimi* `"allocate_key"`: called by `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()` or `psa_copy_key()` before creating a key in the location of this driver. 1111*62c56f98SSadaf Ebrahimi* `"destroy_key"`: called by `psa_destroy_key()`. 1112*62c56f98SSadaf Ebrahimi 1113*62c56f98SSadaf Ebrahimi#### Key creation in a secure element without storage 1114*62c56f98SSadaf Ebrahimi 1115*62c56f98SSadaf EbrahimiThis section describes the key creation process for secure elements that do not store the key material. The driver must obtain a wrapped form of the key material which the core will store. A driver for such a secure element has no `"allocate_key"` or `"destroy_key"` entry point. 1116*62c56f98SSadaf Ebrahimi 1117*62c56f98SSadaf EbrahimiWhen creating a key with an opaque driver which does not have an `"allocate_key"` or `"destroy_key"` entry point: 1118*62c56f98SSadaf Ebrahimi 1119*62c56f98SSadaf Ebrahimi1. The core allocates memory for the key context. 1120*62c56f98SSadaf Ebrahimi2. The core calls the driver's import, generate, derive or copy entry point. 1121*62c56f98SSadaf Ebrahimi3. The core saves the resulting wrapped key material and any other data that the key context may contain. 1122*62c56f98SSadaf Ebrahimi 1123*62c56f98SSadaf EbrahimiTo destroy a key, the core simply destroys the wrapped key material, without invoking driver code. 1124*62c56f98SSadaf Ebrahimi 1125*62c56f98SSadaf Ebrahimi#### Key management in a secure element with storage 1126*62c56f98SSadaf Ebrahimi 1127*62c56f98SSadaf EbrahimiThis section describes the key creation and key destruction processes for secure elements that have persistent storage for the key material. A driver for such a secure element has two mandatory entry points: 1128*62c56f98SSadaf Ebrahimi 1129*62c56f98SSadaf Ebrahimi* `"allocate_key"`: this function obtains an internal identifier for the key. This may be, for example, a unique label or a slot number. 1130*62c56f98SSadaf Ebrahimi* `"destroy_key"`: this function invalidates the internal identifier and destroys the associated key material. 1131*62c56f98SSadaf Ebrahimi 1132*62c56f98SSadaf EbrahimiThese functions have the following prototypes for a driver with the prefix `"acme"`: 1133*62c56f98SSadaf Ebrahimi``` 1134*62c56f98SSadaf Ebrahimipsa_status_t acme_allocate_key(const psa_key_attributes_t *attributes, 1135*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 1136*62c56f98SSadaf Ebrahimi size_t key_buffer_size); 1137*62c56f98SSadaf Ebrahimipsa_status_t acme_destroy_key(const psa_key_attributes_t *attributes, 1138*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer, 1139*62c56f98SSadaf Ebrahimi size_t key_buffer_size); 1140*62c56f98SSadaf Ebrahimi``` 1141*62c56f98SSadaf Ebrahimi 1142*62c56f98SSadaf EbrahimiWhen creating a persistent key with an opaque driver which has an `"allocate_key"` entry point: 1143*62c56f98SSadaf Ebrahimi 1144*62c56f98SSadaf Ebrahimi1. The core calls the driver's `"allocate_key"` entry point. This function typically allocates an internal identifier for the key without modifying the state of the secure element and stores the identifier in the key context. This function should not modify the state of the secure element. It may modify the copy of the persistent state of the driver in memory. 1145*62c56f98SSadaf Ebrahimi 1146*62c56f98SSadaf Ebrahimi1. The core saves the key context to persistent storage. 1147*62c56f98SSadaf Ebrahimi 1148*62c56f98SSadaf Ebrahimi1. The core calls the driver's key creation entry point. 1149*62c56f98SSadaf Ebrahimi 1150*62c56f98SSadaf Ebrahimi1. The core saves the updated key context to persistent storage. 1151*62c56f98SSadaf Ebrahimi 1152*62c56f98SSadaf EbrahimiIf a failure occurs after the `"allocate_key"` step but before the call to the second driver entry point, the core will do one of the following: 1153*62c56f98SSadaf Ebrahimi 1154*62c56f98SSadaf Ebrahimi* Fail the creation of the key without indicating this to the driver. This can happen, in particular, if the device loses power immediately after the key allocation entry point returns. 1155*62c56f98SSadaf Ebrahimi* Call the driver's `"destroy_key"` entry point. 1156*62c56f98SSadaf Ebrahimi 1157*62c56f98SSadaf EbrahimiTo destroy a key, the core calls the driver's `"destroy_key"` entry point. 1158*62c56f98SSadaf Ebrahimi 1159*62c56f98SSadaf EbrahimiNote that the key allocation and destruction entry points must not rely solely on the key identifier in the key attributes to identify a key. Some implementations of the PSA Cryptography API store keys on behalf of multiple clients, and different clients may use the same key identifier to designate different keys. The manner in which the core distinguishes keys that have the same identifier but are part of the key namespace for different clients is implementation-dependent and is not accessible to drivers. Some typical strategies to allocate an internal key identifier are: 1160*62c56f98SSadaf Ebrahimi 1161*62c56f98SSadaf Ebrahimi* Maintain a set of free slot numbers which is stored either in the secure element or in the driver's persistent storage. To allocate a key slot, find a free slot number, mark it as occupied and store the number in the key context. When the key is destroyed, mark the slot number as free. 1162*62c56f98SSadaf Ebrahimi* Maintain a monotonic counter with a practically unbounded range in the secure element or in the driver's persistent storage. To allocate a key slot, increment the counter and store the current value in the key context. Destroying a key does not change the counter. 1163*62c56f98SSadaf Ebrahimi 1164*62c56f98SSadaf EbrahimiTODO: explain constraints on how the driver updates its persistent state for resilience 1165*62c56f98SSadaf Ebrahimi 1166*62c56f98SSadaf EbrahimiTODO: some of the above doesn't apply to volatile keys 1167*62c56f98SSadaf Ebrahimi 1168*62c56f98SSadaf Ebrahimi#### Key creation entry points in opaque drivers 1169*62c56f98SSadaf Ebrahimi 1170*62c56f98SSadaf EbrahimiThe key creation entry points have the following prototypes for a driver with the prefix `"acme"`: 1171*62c56f98SSadaf Ebrahimi 1172*62c56f98SSadaf Ebrahimi``` 1173*62c56f98SSadaf Ebrahimipsa_status_t acme_import_key(const psa_key_attributes_t *attributes, 1174*62c56f98SSadaf Ebrahimi const uint8_t *data, 1175*62c56f98SSadaf Ebrahimi size_t data_length, 1176*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 1177*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 1178*62c56f98SSadaf Ebrahimi size_t *key_buffer_length, 1179*62c56f98SSadaf Ebrahimi size_t *bits); 1180*62c56f98SSadaf Ebrahimipsa_status_t acme_generate_key(const psa_key_attributes_t *attributes, 1181*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 1182*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 1183*62c56f98SSadaf Ebrahimi size_t *key_buffer_length); 1184*62c56f98SSadaf Ebrahimi``` 1185*62c56f98SSadaf Ebrahimi 1186*62c56f98SSadaf EbrahimiIf the driver has an [`"allocate_key"` entry point](#key-management-in-a-secure-element-with-storage), the core calls the `"allocate_key"` entry point with the same attributes on the same key buffer before calling the key creation entry point. 1187*62c56f98SSadaf Ebrahimi 1188*62c56f98SSadaf EbrahimiTODO: derivation, copy 1189*62c56f98SSadaf Ebrahimi 1190*62c56f98SSadaf Ebrahimi#### Key export entry points in opaque drivers 1191*62c56f98SSadaf Ebrahimi 1192*62c56f98SSadaf EbrahimiThe key export entry points have the following prototypes for a driver with the prefix `"acme"`: 1193*62c56f98SSadaf Ebrahimi 1194*62c56f98SSadaf Ebrahimi``` 1195*62c56f98SSadaf Ebrahimipsa_status_t acme_export_key(const psa_key_attributes_t *attributes, 1196*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer, 1197*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 1198*62c56f98SSadaf Ebrahimi uint8_t *data, 1199*62c56f98SSadaf Ebrahimi size_t data_size, 1200*62c56f98SSadaf Ebrahimi size_t *data_length); 1201*62c56f98SSadaf Ebrahimipsa_status_t acme_export_public_key(const psa_key_attributes_t *attributes, 1202*62c56f98SSadaf Ebrahimi const uint8_t *key_buffer, 1203*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 1204*62c56f98SSadaf Ebrahimi uint8_t *data, 1205*62c56f98SSadaf Ebrahimi size_t data_size, 1206*62c56f98SSadaf Ebrahimi size_t *data_length); 1207*62c56f98SSadaf Ebrahimi``` 1208*62c56f98SSadaf Ebrahimi 1209*62c56f98SSadaf EbrahimiThe core will only call `acme_export_public_key` on a private key. Drivers implementers may choose to store the public key in the key context buffer or to recalculate it on demand. If the key context includes the public key, it needs to have an adequate size; see [“Key format for opaque drivers”](#key-format-for-opaque-drivers). 1210*62c56f98SSadaf Ebrahimi 1211*62c56f98SSadaf EbrahimiThe core guarantees that the size of the output buffer (`data_size`) is sufficient to export any key with the given attributes. The driver must set `*data_length` to the exact size of the exported key. 1212*62c56f98SSadaf Ebrahimi 1213*62c56f98SSadaf Ebrahimi### Opaque driver persistent state 1214*62c56f98SSadaf Ebrahimi 1215*62c56f98SSadaf EbrahimiThe core maintains persistent state on behalf of an opaque driver. This persistent state consists of a single byte array whose size is given by the `"persistent_state_size"` property in the [driver description](#driver-description-top-level-element). 1216*62c56f98SSadaf Ebrahimi 1217*62c56f98SSadaf EbrahimiThe core loads the persistent state in memory before it calls the driver's [init entry point](#driver-initialization). It is adjusted to match the size declared by the driver, in case a driver upgrade changes the size: 1218*62c56f98SSadaf Ebrahimi 1219*62c56f98SSadaf Ebrahimi* The first time the driver is loaded on a system, the persistent state is all-bits-zero. 1220*62c56f98SSadaf Ebrahimi* If the stored persistent state is smaller than the declared size, the core pads the persistent state with all-bits-zero at the end. 1221*62c56f98SSadaf Ebrahimi* If the stored persistent state is larger than the declared size, the core truncates the persistent state to the declared size. 1222*62c56f98SSadaf Ebrahimi 1223*62c56f98SSadaf EbrahimiThe core provides the following callback functions, which an opaque driver may call while it is processing a call from the driver: 1224*62c56f98SSadaf Ebrahimi``` 1225*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_get_persistent_state(uint_8_t **persistent_state_ptr); 1226*62c56f98SSadaf Ebrahimipsa_status_t psa_crypto_driver_commit_persistent_state(size_t from, size_t length); 1227*62c56f98SSadaf Ebrahimi``` 1228*62c56f98SSadaf Ebrahimi 1229*62c56f98SSadaf Ebrahimi`psa_crypto_driver_get_persistent_state` sets `*persistent_state_ptr` to a pointer to the first byte of the persistent state. This pointer remains valid during a call to a driver entry point. Once the entry point returns, the pointer is no longer valid. The core guarantees that calls to `psa_crypto_driver_get_persistent_state` within the same entry point return the same address for the persistent state, but this address may change between calls to an entry point. 1230*62c56f98SSadaf Ebrahimi 1231*62c56f98SSadaf Ebrahimi`psa_crypto_driver_commit_persistent_state` updates the persistent state in persistent storage. Only the portion at byte offsets `from` inclusive to `from + length` exclusive is guaranteed to be updated; it is unspecified whether changes made to other parts of the state are taken into account. The driver must call this function after updating the persistent state in memory and before returning from the entry point, otherwise it is unspecified whether the persistent state is updated. 1232*62c56f98SSadaf Ebrahimi 1233*62c56f98SSadaf EbrahimiThe core will not update the persistent state in storage while an entry point is running except when the entry point calls `psa_crypto_driver_commit_persistent_state`. It may update the persistent state in storage after an entry point returns. 1234*62c56f98SSadaf Ebrahimi 1235*62c56f98SSadaf EbrahimiIn a multithreaded environment, the driver may only call these two functions from the thread that is executing the entry point. 1236*62c56f98SSadaf Ebrahimi 1237*62c56f98SSadaf Ebrahimi#### Built-in keys 1238*62c56f98SSadaf Ebrahimi 1239*62c56f98SSadaf EbrahimiOpaque drivers may declare built-in keys. Built-in keys can be accessed, but not created, through the PSA Cryptography API. 1240*62c56f98SSadaf Ebrahimi 1241*62c56f98SSadaf EbrahimiA built-in key is identified by its location and its **slot number**. Drivers that support built-in keys must provide a `"get_builtin_key"` entry point to retrieve the key data and metadata. The core calls this entry point when it needs to access the key, typically because the application requested an operation on the key. The core may keep information about the key in cache, and successive calls to access the same slot number should return the same data. This entry point has the following prototype: 1242*62c56f98SSadaf Ebrahimi 1243*62c56f98SSadaf Ebrahimi``` 1244*62c56f98SSadaf Ebrahimipsa_status_t acme_get_builtin_key(psa_drv_slot_number_t slot_number, 1245*62c56f98SSadaf Ebrahimi psa_key_attributes_t *attributes, 1246*62c56f98SSadaf Ebrahimi uint8_t *key_buffer, 1247*62c56f98SSadaf Ebrahimi size_t key_buffer_size, 1248*62c56f98SSadaf Ebrahimi size_t *key_buffer_length); 1249*62c56f98SSadaf Ebrahimi``` 1250*62c56f98SSadaf Ebrahimi 1251*62c56f98SSadaf EbrahimiIf this function returns `PSA_SUCCESS` or `PSA_ERROR_BUFFER_TOO_SMALL`, it must fill `attributes` with the attributes of the key (except for the key identifier). On success, this function must also fill `key_buffer` with the key context. 1252*62c56f98SSadaf Ebrahimi 1253*62c56f98SSadaf EbrahimiOn entry, `psa_get_key_lifetime(attributes)` is the location at which the driver was declared and a persistence level with which the platform is attempting to register the key. The driver entry point may choose to change the lifetime (`psa_set_key_lifetime(attributes, lifetime)`) of the reported key attributes to one with the same location but a different persistence level, in case the driver has more specific knowledge about the actual persistence level of the key which is being retrieved. For example, if a driver knows it cannot delete a key, it may override the persistence level in the lifetime to `PSA_KEY_PERSISTENCE_READ_ONLY`. The standard attributes other than the key identifier and lifetime have the value conveyed by `PSA_KEY_ATTRIBUTES_INIT`. 1254*62c56f98SSadaf Ebrahimi 1255*62c56f98SSadaf EbrahimiThe output parameter `key_buffer` points to a writable buffer of `key_buffer_size` bytes. If the driver has a [`"builtin_key_size"` property](#key-format-for-opaque-drivers) property, `key_buffer_size` has this value, otherwise `key_buffer_size` has the value determined from the key type and size. 1256*62c56f98SSadaf Ebrahimi 1257*62c56f98SSadaf EbrahimiTypically, for a built-in key, the key context is a reference to key material that is kept inside the secure element, similar to the format returned by [`"allocate_key"`](#key-management-in-a-secure-element-with-storage). A driver may have built-in keys even if it doesn't have an `"allocate_key"` entry point. 1258*62c56f98SSadaf Ebrahimi 1259*62c56f98SSadaf EbrahimiThis entry point may return the following status values: 1260*62c56f98SSadaf Ebrahimi 1261*62c56f98SSadaf Ebrahimi* `PSA_SUCCESS`: the requested key exists, and the output parameters `attributes` and `key_buffer` contain the key metadata and key context respectively, and `*key_buffer_length` contains the length of the data written to `key_buffer`. 1262*62c56f98SSadaf Ebrahimi* `PSA_ERROR_BUFFER_TOO_SMALL`: `key_buffer_size` is insufficient. In this case, the driver must pass the key's attributes in `*attributes`. In particular, `get_builtin_key(slot_number, &attributes, NULL, 0)` is a way for the core to obtain the key's attributes. 1263*62c56f98SSadaf Ebrahimi* `PSA_ERROR_DOES_NOT_EXIST`: the requested key does not exist. 1264*62c56f98SSadaf Ebrahimi* Other error codes such as `PSA_ERROR_COMMUNICATION_FAILURE` or `PSA_ERROR_HARDWARE_FAILURE` indicate a transient or permanent error. 1265*62c56f98SSadaf Ebrahimi 1266*62c56f98SSadaf EbrahimiThe core will pass authorized requests to destroy a built-in key to the [`"destroy_key"`](#key-management-in-a-secure-element-with-storage) entry point if there is one. If built-in keys must not be destroyed, it is up to the driver to reject such requests. 1267*62c56f98SSadaf Ebrahimi 1268*62c56f98SSadaf Ebrahimi## How to use drivers from an application 1269*62c56f98SSadaf Ebrahimi 1270*62c56f98SSadaf Ebrahimi### Using transparent drivers 1271*62c56f98SSadaf Ebrahimi 1272*62c56f98SSadaf EbrahimiTransparent drivers linked into the library are automatically used for the mechanisms that they implement. 1273*62c56f98SSadaf Ebrahimi 1274*62c56f98SSadaf Ebrahimi### Using opaque drivers 1275*62c56f98SSadaf Ebrahimi 1276*62c56f98SSadaf EbrahimiEach opaque driver is assigned a [location](#lifetimes-and-locations). The driver is invoked for all actions that use a key in that location. A key's location is indicated by its lifetime. The application chooses the key's lifetime when it creates the key. 1277*62c56f98SSadaf Ebrahimi 1278*62c56f98SSadaf EbrahimiFor example, the following snippet creates an AES-GCM key which is only accessible inside the secure element designated by the location `PSA_KEY_LOCATION_acme`. 1279*62c56f98SSadaf Ebrahimi``` 1280*62c56f98SSadaf Ebrahimipsa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 1281*62c56f98SSadaf Ebrahimipsa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( 1282*62c56f98SSadaf Ebrahimi PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_acme)); 1283*62c56f98SSadaf Ebrahimipsa_set_key_identifier(&attributes, 42); 1284*62c56f98SSadaf Ebrahimipsa_set_key_type(&attributes, PSA_KEY_TYPE_AES); 1285*62c56f98SSadaf Ebrahimipsa_set_key_size(&attributes, 128); 1286*62c56f98SSadaf Ebrahimipsa_set_key_algorithm(&attributes, PSA_ALG_GCM); 1287*62c56f98SSadaf Ebrahimipsa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); 1288*62c56f98SSadaf Ebrahimipsa_key_id_t key; 1289*62c56f98SSadaf Ebrahimipsa_generate_key(&attributes, &key); 1290*62c56f98SSadaf Ebrahimi``` 1291*62c56f98SSadaf Ebrahimi 1292*62c56f98SSadaf Ebrahimi## Using opaque drivers from an application 1293*62c56f98SSadaf Ebrahimi 1294*62c56f98SSadaf Ebrahimi### Lifetimes and locations 1295*62c56f98SSadaf Ebrahimi 1296*62c56f98SSadaf EbrahimiThe PSA Cryptography API, version 1.0.0, defines [lifetimes](https://armmbed.github.io/mbed-crypto/html/api/keys/attributes.html?highlight=psa_key_lifetime_t#c.psa_key_lifetime_t) as an attribute of a key that indicates where the key is stored and which application and system actions will create and destroy it. The lifetime is expressed as a 32-bit value (`typedef uint32_t psa_key_lifetime_t`). An upcoming version of the PSA Cryptography API defines more structure for lifetime values to separate these two aspects of the lifetime: 1297*62c56f98SSadaf Ebrahimi 1298*62c56f98SSadaf Ebrahimi* Bits 0–7 are a _persistence level_. This value indicates what device management actions can cause it to be destroyed. In particular, it indicates whether the key is volatile or persistent. 1299*62c56f98SSadaf Ebrahimi* Bits 8–31 are a _location indicator_. This value indicates where the key material is stored and where operations on the key are performed. Location values can be stored in a variable of type `psa_key_location_t`. 1300*62c56f98SSadaf Ebrahimi 1301*62c56f98SSadaf EbrahimiAn opaque driver is attached to a specific location. Keys in the default location (`PSA_KEY_LOCATION_LOCAL_STORAGE = 0`) are transparent: the core has direct access to the key material. For keys in a location that is managed by an opaque driver, only the secure element has access to the key material and can perform operations on the key, while the core only manipulates a wrapped form of the key or an identifier of the key. 1302*62c56f98SSadaf Ebrahimi 1303*62c56f98SSadaf Ebrahimi### Creating a key in a secure element 1304*62c56f98SSadaf Ebrahimi 1305*62c56f98SSadaf EbrahimiThe core defines a compile-time constant for each opaque driver indicating its location called `PSA_KEY_LOCATION_`*prefix* where *prefix* is the value of the `"prefix"` property in the driver description. For convenience, Mbed TLS also declares a compile-time constant for the corresponding lifetime with the default persistence called `PSA_KEY_LIFETIME_`*prefix*. Therefore, to declare an opaque key in the location with the prefix `foo` with the default persistence, call `psa_set_key_lifetime` during the key creation as follows: 1306*62c56f98SSadaf Ebrahimi``` 1307*62c56f98SSadaf Ebrahimipsa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_foo); 1308*62c56f98SSadaf Ebrahimi``` 1309*62c56f98SSadaf Ebrahimi 1310*62c56f98SSadaf EbrahimiTo declare a volatile key: 1311*62c56f98SSadaf Ebrahimi``` 1312*62c56f98SSadaf Ebrahimipsa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( 1313*62c56f98SSadaf Ebrahimi PSA_KEY_LOCATION_foo, 1314*62c56f98SSadaf Ebrahimi PSA_KEY_PERSISTENCE_VOLATILE)); 1315*62c56f98SSadaf Ebrahimi``` 1316*62c56f98SSadaf Ebrahimi 1317*62c56f98SSadaf EbrahimiGenerally speaking, to declare a key with a specified persistence: 1318*62c56f98SSadaf Ebrahimi``` 1319*62c56f98SSadaf Ebrahimipsa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( 1320*62c56f98SSadaf Ebrahimi PSA_KEY_LOCATION_foo, 1321*62c56f98SSadaf Ebrahimi persistence)); 1322*62c56f98SSadaf Ebrahimi``` 1323*62c56f98SSadaf Ebrahimi 1324*62c56f98SSadaf Ebrahimi## Open questions 1325*62c56f98SSadaf Ebrahimi 1326*62c56f98SSadaf Ebrahimi### Value representation 1327*62c56f98SSadaf Ebrahimi 1328*62c56f98SSadaf Ebrahimi#### Integers 1329*62c56f98SSadaf Ebrahimi 1330*62c56f98SSadaf EbrahimiIt would be better if there was a uniform requirement on integer values. Do they have to be JSON integers? C preprocessor integers (which could be e.g. a macro defined in some header file)? C compile-time constants (allowing `sizeof`)? 1331*62c56f98SSadaf Ebrahimi 1332*62c56f98SSadaf EbrahimiThis choice is partly driven by the use of the values, so they might not be uniform. Note that if the value can be zero and it's plausible that the core would want to statically allocate an array of the given size, the core needs to know whether the value is 0 so that it could use code like 1333*62c56f98SSadaf Ebrahimi``` 1334*62c56f98SSadaf Ebrahimi#if ACME_FOO_SIZE != 0 1335*62c56f98SSadaf Ebrahimi uint8_t foo[ACME_FOO_SIZE]; 1336*62c56f98SSadaf Ebrahimi#endif 1337*62c56f98SSadaf Ebrahimi``` 1338*62c56f98SSadaf Ebrahimi 1339*62c56f98SSadaf Ebrahimi### Driver declarations 1340*62c56f98SSadaf Ebrahimi 1341*62c56f98SSadaf Ebrahimi#### Declaring driver entry points 1342*62c56f98SSadaf Ebrahimi 1343*62c56f98SSadaf EbrahimiThe core may want to provide declarations for the driver entry points so that it can compile code using them. At the time of writing this paragraph, the driver headers must define types but there is no obligation for them to declare functions. The core knows what the function names and argument types are, so it can generate prototypes. 1344*62c56f98SSadaf Ebrahimi 1345*62c56f98SSadaf EbrahimiIt should be ok for driver functions to be function-like macros or function pointers. 1346*62c56f98SSadaf Ebrahimi 1347*62c56f98SSadaf Ebrahimi#### Driver location values 1348*62c56f98SSadaf Ebrahimi 1349*62c56f98SSadaf EbrahimiHow does a driver author decide which location values to use? It should be possible to combine drivers from different sources. Use the same vendor assignment as for PSA services? 1350*62c56f98SSadaf Ebrahimi 1351*62c56f98SSadaf EbrahimiCan the driver assembly process generate distinct location values as needed? This can be convenient, but it's also risky: if you upgrade a device, you need the location values to be the same between builds. 1352*62c56f98SSadaf Ebrahimi 1353*62c56f98SSadaf EbrahimiThe current plan is for Arm to maintain a registry of vendors and assign a location namespace to each vendor. Parts of the namespace would be reserved for implementations and integrators. 1354*62c56f98SSadaf Ebrahimi 1355*62c56f98SSadaf Ebrahimi#### Multiple transparent drivers 1356*62c56f98SSadaf Ebrahimi 1357*62c56f98SSadaf EbrahimiWhen multiple transparent drivers implement the same mechanism, which one is called? The first one? The last one? Unspecified? Or is this an error (excluding capabilities with fallback enabled)? 1358*62c56f98SSadaf Ebrahimi 1359*62c56f98SSadaf EbrahimiThe current choice is that the first one is used, which allows having a preference order on drivers, but may mask integration errors. 1360*62c56f98SSadaf Ebrahimi 1361*62c56f98SSadaf Ebrahimi### Driver function interfaces 1362*62c56f98SSadaf Ebrahimi 1363*62c56f98SSadaf Ebrahimi#### Driver function parameter conventions 1364*62c56f98SSadaf Ebrahimi 1365*62c56f98SSadaf EbrahimiShould 0-size buffers be guaranteed to have a non-null pointers? 1366*62c56f98SSadaf Ebrahimi 1367*62c56f98SSadaf EbrahimiShould drivers really have to cope with overlap? 1368*62c56f98SSadaf Ebrahimi 1369*62c56f98SSadaf EbrahimiShould the core guarantee that the output buffer size has the size indicated by the applicable buffer size macro (which may be an overestimation)? 1370*62c56f98SSadaf Ebrahimi 1371*62c56f98SSadaf Ebrahimi#### Key derivation inputs and buffer ownership 1372*62c56f98SSadaf Ebrahimi 1373*62c56f98SSadaf EbrahimiWhy is `psa_crypto_driver_key_derivation_get_input_bytes` a copy, rather than giving a pointer? 1374*62c56f98SSadaf Ebrahimi 1375*62c56f98SSadaf EbrahimiThe main reason is to avoid complex buffer ownership. A driver entry point does not own memory after the entry point return. This is generally necessary because an API function does not own memory after the entry point returns. In the case of key derivation inputs, this could be relaxed because the driver entry point is making callbacks to the core: these functions could return a pointer that is valid until the driver entry point returns, which would allow the driver to process the data immediately (e.g. hash it rather than copy it). 1376*62c56f98SSadaf Ebrahimi 1377*62c56f98SSadaf Ebrahimi### Partial computations in drivers 1378*62c56f98SSadaf Ebrahimi 1379*62c56f98SSadaf Ebrahimi#### Substitution points 1380*62c56f98SSadaf Ebrahimi 1381*62c56f98SSadaf EbrahimiEarlier drafts of the driver interface had a concept of _substitution points_: places in the calculation where a driver may be called. Some hardware doesn't do the whole calculation, but only the “main” part. This goes both for transparent and opaque drivers. Some common examples: 1382*62c56f98SSadaf Ebrahimi 1383*62c56f98SSadaf Ebrahimi* A processor that performs the RSA exponentiation, but not the padding. The driver should be able to leverage the padding code in the core. 1384*62c56f98SSadaf Ebrahimi* A processor that performs a block cipher operation only for a single block, or only in ECB mode, or only in CTR mode. The core would perform the block mode (CBC, CTR, CCM, ...). 1385*62c56f98SSadaf Ebrahimi 1386*62c56f98SSadaf EbrahimiThis concept, or some other way to reuse portable code such as specifying inner functions like `psa_rsa_pad` in the core, should be added to the specification. 1387*62c56f98SSadaf Ebrahimi 1388*62c56f98SSadaf Ebrahimi### Key management 1389*62c56f98SSadaf Ebrahimi 1390*62c56f98SSadaf Ebrahimi#### Mixing drivers in key derivation 1391*62c56f98SSadaf Ebrahimi 1392*62c56f98SSadaf EbrahimiHow does `psa_key_derivation_output_key` work when the extraction part and the expansion part use different drivers? 1393*62c56f98SSadaf Ebrahimi 1394*62c56f98SSadaf Ebrahimi#### Public key calculation 1395*62c56f98SSadaf Ebrahimi 1396*62c56f98SSadaf EbrahimiECC key pairs are represented as the private key value only. The public key needs to be calculated from that. Both transparent drivers and opaque drivers provide a function to calculate the public key (`"export_public_key"`). 1397*62c56f98SSadaf Ebrahimi 1398*62c56f98SSadaf EbrahimiThe specification doesn't mention when the public key might be calculated. The core may calculate it on creation, on demand, or anything in between. Opaque drivers have a choice of storing the public key in the key context or calculating it on demand and can convey whether the core should store the public key with the `"store_public_key"` property. Is this good enough or should the specification include non-functional requirements? 1399*62c56f98SSadaf Ebrahimi 1400*62c56f98SSadaf Ebrahimi#### Symmetric key validation with transparent drivers 1401*62c56f98SSadaf Ebrahimi 1402*62c56f98SSadaf EbrahimiShould the entry point be called for symmetric keys as well? 1403*62c56f98SSadaf Ebrahimi 1404*62c56f98SSadaf Ebrahimi#### Support for custom import formats 1405*62c56f98SSadaf Ebrahimi 1406*62c56f98SSadaf Ebrahimi[“Driver entry points for key management”](#driver-entry-points-for-key-management) states that the input to `"import_key"` can be an implementation-defined format. Is this a good idea? It reduces driver portability, since a core that accepts a custom format would not work with a driver that doesn't accept this format. On the other hand, if a driver accepts a custom format, the core should let it through because the driver presumably handles it more efficiently (in terms of speed and code size) than the core could. 1407*62c56f98SSadaf Ebrahimi 1408*62c56f98SSadaf EbrahimiAllowing custom formats also causes a problem with import: the core can't know the size of the key representation until it knows the bit-size of the key, but determining the bit-size of the key is part of the job of the `"import_key"` entry point. For standard key types, this could plausibly be an issue for RSA private keys, where an implementation might accept a custom format that omits the CRT parameters (or that omits *d*). 1409*62c56f98SSadaf Ebrahimi 1410*62c56f98SSadaf Ebrahimi### Opaque drivers 1411*62c56f98SSadaf Ebrahimi 1412*62c56f98SSadaf Ebrahimi#### Opaque driver persistent state 1413*62c56f98SSadaf Ebrahimi 1414*62c56f98SSadaf EbrahimiThe driver is allowed to update the state at any time. Is this ok? 1415*62c56f98SSadaf Ebrahimi 1416*62c56f98SSadaf EbrahimiAn example use case for updating the persistent state at arbitrary times is to renew a key that is used to encrypt communications between the application processor and the secure element. 1417*62c56f98SSadaf Ebrahimi 1418*62c56f98SSadaf Ebrahimi`psa_crypto_driver_get_persistent_state` does not identify the calling driver, so the driver needs to remember which driver it's calling. This may require a thread-local variable in a multithreaded core. Is this ok? 1419*62c56f98SSadaf Ebrahimi 1420*62c56f98SSadaf Ebrahimi#### Open questions around cooked key derivation 1421*62c56f98SSadaf Ebrahimi 1422*62c56f98SSadaf Ebrahimi`"derive_key"` is not a clear name. Can we use a better one? 1423*62c56f98SSadaf Ebrahimi 1424*62c56f98SSadaf EbrahimiFor the `"derive_key"` entry point, how does the core choose `input_length`? Doesn't the driver know better? Should there be a driver entry point to determine the length, or should there be a callback that allows the driver to retrieve the input? Note that for some key types, it's impossible to predict the amount of input in advance, because it depends on some complex calculation or even on random data, e.g. if doing a randomized pseudo-primality test. However, for all key types except RSA, the specification mandates how the key is derived, which practically dictates how the pseudorandom key stream is consumed. So it's probably ok. 1425*62c56f98SSadaf Ebrahimi 1426*62c56f98SSadaf Ebrahimi#### Fallback for key derivation in opaque drivers 1427*62c56f98SSadaf Ebrahimi 1428*62c56f98SSadaf EbrahimiShould [dispatch to an opaque driver](#key-derivation-driver-dispatch-logic) allow fallback, so that if `"key_derivation_setup"` returns `PSA_ERROR_NOT_SUPPORTED` then the core exports the key from the secure element instead? 1429*62c56f98SSadaf Ebrahimi 1430*62c56f98SSadaf EbrahimiShould the ["`key_derivation_output_key`"](#key-derivation-driver-outputs) capability indicate which key types the driver can derive? How should fallback work? For example, consider a secure element that implements HMAC, HKDF and ECDSA, and that can derive an HMAC key from HKDF without exporting intermediate material but can only import or randomly generate ECC keys. How does this driver convey that it can't derive an ECC key with HKDF, but it can let the core do this and import the resulting key? 1431*62c56f98SSadaf Ebrahimi 1432*62c56f98SSadaf Ebrahimi### Randomness 1433*62c56f98SSadaf Ebrahimi 1434*62c56f98SSadaf Ebrahimi#### Input to `"add_entropy"` 1435*62c56f98SSadaf Ebrahimi 1436*62c56f98SSadaf EbrahimiShould the input to the [`"add_entropy"` entry point](#entropy-injection) be a full-entropy buffer (with data from all entropy sources already mixed), raw entropy direct from the entropy sources, or give the core a choice? 1437*62c56f98SSadaf Ebrahimi 1438*62c56f98SSadaf Ebrahimi* Raw data: drivers must implement entropy mixing. `"add_entropy"` needs an extra parameter to indicate the amount of entropy in the data. The core must not do any conditioning. 1439*62c56f98SSadaf Ebrahimi* Choice: drivers must implement entropy mixing. `"add_entropy"` needs an extra parameter to indicate the amount of entropy in the data. The core may do conditioning if it wants, but doesn't have to. 1440*62c56f98SSadaf Ebrahimi* Full entropy: drivers don't need to do entropy mixing. 1441*62c56f98SSadaf Ebrahimi 1442*62c56f98SSadaf Ebrahimi#### Flags for `"get_entropy"` 1443*62c56f98SSadaf Ebrahimi 1444*62c56f98SSadaf EbrahimiAre the [entropy collection flags](#entropy-collection-flags) well-chosen? 1445*62c56f98SSadaf Ebrahimi 1446*62c56f98SSadaf Ebrahimi#### Random generator instantiations 1447*62c56f98SSadaf Ebrahimi 1448*62c56f98SSadaf EbrahimiMay the core instantiate a random generation context more than once? In other words, can there be multiple objects of type `acme_random_context_t`? 1449*62c56f98SSadaf Ebrahimi 1450*62c56f98SSadaf EbrahimiFunctionally, one RNG is as good as any. If the core wants some parts of the system to use a deterministic generator for reproducibility, it can't use this interface anyway, since the RNG is not necessarily deterministic. However, for performance on multiprocessor systems, a multithreaded core could prefer to use one RNG instance per thread. 1451*62c56f98SSadaf Ebrahimi 1452*62c56f98SSadaf Ebrahimi<!-- 1453*62c56f98SSadaf EbrahimiLocal Variables: 1454*62c56f98SSadaf Ebrahimitime-stamp-line-limit: 40 1455*62c56f98SSadaf Ebrahimitime-stamp-start: "Time-stamp: *\"" 1456*62c56f98SSadaf Ebrahimitime-stamp-end: "\"" 1457*62c56f98SSadaf Ebrahimitime-stamp-format: "%04Y/%02m/%02d %02H:%02M:%02S %Z" 1458*62c56f98SSadaf Ebrahimitime-stamp-time-zone: "GMT" 1459*62c56f98SSadaf EbrahimiEnd: 1460*62c56f98SSadaf Ebrahimi--> 1461