Skip to content

Parameter validation responsibilties in the Crypto Driver Interface #332

@athoelke

Description

@athoelke

The Driver interfaces split an implementation of the Crypto API into three layers: Core, Dispatcher, and Driver. It is both unneccesary and inefficient to validate all parameters in every layer, but it is important that every parameter is validated in at least one layer.

Defining the requirements and responsibilities for validation enables consistent, correct and optimal validation.

Overall, there are three (partly conflicting) goals:

  1. Simplicity of the specifications: providing a few simple rules and reducing special cases to a minimum - to ease driver development and spec evolution.
  2. Efficiency: minimize redundant checking of the same preconditions in core and drivers.
  3. Stability: reduce required changes to existing core and driver implementations.

The duty of input validation for arguments is predominantly split between Core and Drivers. The following observations direct the proposed approach:

  • The dispatch layer is a critical point of integration between the Core and Drivers, and as it will be generated from Driver manifests or hand-crafted, this layer should not be burdened with additional complexity beyond ensuring that Driver entry-points are only ever called with parameters that match the corresponding capability filter.

  • Although specific algorithm and key-type compatibility could be validated by the Core (e.g. a ChaCha20 key cannot be used with any cipher-block-mode algorithm), the algorithm and key type can be checked without additional cost by a switch statement in the Driver.

  • Policy enforcement is best implemented by the Core. This reduces complexity for the Drivers, and also permits implementation-specific policy support in the Core - for example, keys that have an additional permitted algorithm.

    Drivers should still have visibility of policy attributes, in order to enforce Driver-specific policy for its entry points.

  • For multi-part operation objects:

    • The Core is best placed to manage the general lifecycle of operation objects.
    • A driver is selected by the Dispatcher during the initial call when a key is provided, and must be used for all subsequent calls.
    • Only a Driver knows what is stored in its part of the operation object.
  • The requirements for the psa_key_check_usage() function introduce an additional complications - as some of the validation is repeated here outside of a call to the associated cryptographic operation.

The following proposal aims to meet all three goals:

PSA Core

  • Input validation of:

    • Algorithm categories, key type categories, and compatibility between the two
    • Correct sequence steps of multi-part operations
    • Key policy and key management
    • Output buffer sizes: application API macros are available to the Core, and the key- and algorithm-specific variants should provide an efficient, if not absolutely precise, bound for the size.
  • When the Core is isolated from the Application, the Core must validate that the Application has access to the input and output memory buffers

  • Cleanup of core-specific part of operation object

  • Cleanup of output buffers in case of an error

PSA Dispatcher

  • Make sure driver calls are dispatched to matching entry points only; if no entry-point matches, return NOT_SUPPORTED
  • Record the driver selected during the first/setup call in the multi-part operation object, and reuse that value for subsequent functions on the object.
  • No additional validation required.

PSA Driver

  • Input validation of:

    • Algorithm, key type, key size, except for the check for categories that is done by the Core
    • Validation of transparent key buffers provided by the Core (not from Application) - i.e. validating key material length. This is to identity possible corruption of key data.
  • Cleanup of driver context of operation object

[Note that although drivers can compute an exact size for output buffers, prefer to keep the Driver implementation simple and rely on output buffer bounds available to the Core through the Application API macros. The Driver should still not read or write outside of any buffer provided to the entry point.]

Additional requirements

  • With this approach, a Driver that uses the DIspatch Interface to chain a call to another Driver must:

    • Provide valid parameters
    • Use multi-part operations in a valid sequence
    • Use keys for permitted cryptographic operations
    • Supply a lerge enough output buffer when required

    This is because such calls bypass the Core implementation of the application API.

  • Some implementations operate without dynamic memory. In such an implementation, the Driver will be given direct access to Application memory buffers, as it is not possible to copy application buffers into private memory. This can still be the case for an implementation that does use dynamic memory allocation.

    Therefore, Drivers should in general:

    • Treat input buffers as volatile (read once, unless the algorithm cannot be implemented in a single pass of the data)
    • Not use output buffers for storing intermediate data.

    [Note: There is an outstanding issue that such an implementation also cannot meet the current API requirements relating to overlapping buffers.]

Open Issues

  • Approach to implementing psa_check_key_usage().

    • In the Core, should psa_check_key_usage() only do the same checks that are required from the Core (above), or include some of the more detailed algorithm/key compatibility checks?
    • We probably want a Dispatch layer implementation for this function, in order to report on whether there is any driver that is able to provide the requested functionality for the key and algorithm. We would need to define how the usage parameter mapped to matching capabilities?
    • Could a driver optionally provide an entry-point to provide a more precise response for this function? - maybe this is an option open for the future if we find that we cannot deliver the primary use cases for psa_check_key_usage() without this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    API designRelated the design of the APICrypto DriverIssue or PR related to the Crypto Driver Interface

    Type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions