The kernel crypto API user space interface supports different use cases with the asynchronous I/O operations which are illustrated in the following sections. These sections also illustrate the API calls to be used to follow the respective use cases.
All APIs that perform synchronous operation do not have different purposes and thus do not require special precautions when using them.
The different use cases round asynchronous I/O revolve around different ways how to send data to the kernel and to retrieve processed data.
Using the kcapi_cipher_*_aio and kcapi_aead_*_aio API calls, a caller can supply one or more IOVECs of data to the kernel. However, the caller can only supply one IV to the kernel.
The API calls only allow specifying one integer defining the number of IOVECs in the arrays of the input data as well as the output data. The libkcapi library uses the input and output IOVECs as pairs. I.e. the first IOVEC of the input array relate to the first IOVEC of the output array, and so on.
The kernel invokes the cipher operation when a recvmsg system call is processed. The AIO handling transforms each output IOVEC into one separate invocation of the recvmsg handler that processes the data submitted with the corresponding input IOVEC. This means, each output IOVEC will trigger one cipher operation. When multiple IOVECs are processed by the kernel's AIO handling, all resulting recvmsg calls are invoked with the in the data same order specified by the list of IOVECs.
WARNING: Currently, it is not guaranteed that the drivers perform the proper serialization of the parallel processing of the different IOVECs. For example, when providing two IOVECs, they may be both using the initially set IV. Thus, they are not chained. User space is able to serialize the AIO operation in this case by invoking the AIO API calls with input/output IOVEC arrays holding one entry each only. However, this would imply that this type of invocation will not be different from a synchronous invocation.
The kernel and thus libkcapi supports the use case where several of the aforementioned multiple staged cipher operations are can be performed in parallel which are totally isolated from each other. In this case, different IVs are used.
Using the kcapi_handle_reinit libkcapi API call, the caller can obtain a new cipher handle from an existing handle. Both share the same key and cipher -- the kernel crypto API maintains the same TFM data structure for both. However, both cipher handles can now encrypt or decrypt data completely isolated from each other. Specifically, the following data of a cipher operation is isolated between the different cipher handles -- this is all data that is not set with a setsockopt(2) system call:
Input: plaintext (encryption) or ciphertext (decryption)
Output: plaintext (decryption) or ciphertext (encryption)
IV
AEAD: associated authenticated data (AAD) and its length
AEAD: tag
The following data is shared between the different cipher handles -- this covers all data that can be set with a setsockopt(2) system call:
Key
AEAD: Tag length
This means that the "multiple staged cipher operations" discussed above can be performed with each cipher handle independently.
The call kcapi_handle_reinit does not open another socket, but implies that only a new accept(2) system call is performed.