| Introduction |
| ============ |
| |
| The concepts of the kernel crypto API visible to kernel space is fully |
| applicable to the user space interface as well. Therefore, the kernel crypto API |
| high level discussion for the in-kernel use cases applies here as well. |
| |
| The major difference, however, is that user space can only act as a consumer |
| and never as a provider of a transformation or cipher algorithm. |
| |
| The following covers the user space interface exported by the kernel crypto |
| API. A working example of this description is libkcapi that can be obtained from |
| [1]. That library can be used by user space applications that require |
| cryptographic services from the kernel. |
| |
| Some details of the in-kernel kernel crypto API aspects do not |
| apply to user space, however. This includes the difference between synchronous |
| and asynchronous invocations. The user space API call is fully synchronous. |
| In addition, only a subset of all cipher types are available as documented |
| below. |
| |
| |
| User space API general remarks |
| ============================== |
| |
| The kernel crypto API is accessible from user space. Currently, the following |
| ciphers are accessible: |
| |
| * Message digest including keyed message digest (HMAC, CMAC) |
| |
| * Symmetric ciphers |
| |
| Note, AEAD ciphers are currently not supported via the symmetric cipher |
| interface. |
| |
| The interface is provided via Netlink using the type AF_ALG. In addition, the |
| setsockopt option type is SOL_ALG. In case the user space header files do not |
| export these flags yet, use the following macros: |
| |
| #ifndef AF_ALG |
| #define AF_ALG 38 |
| #endif |
| #ifndef SOL_ALG |
| #define SOL_ALG 279 |
| #endif |
| |
| A cipher is accessed with the same name as done for the in-kernel API calls. |
| This includes the generic vs. unique naming schema for ciphers as well as the |
| enforcement of priorities for generic names. |
| |
| To interact with the kernel crypto API, a Netlink socket must be created by |
| the user space application. User space invokes the cipher operation with the |
| send/write system call family. The result of the cipher operation is obtained |
| with the read/recv system call family. |
| |
| The following API calls assume that the Netlink socket descriptor is already |
| opened by the user space application and discusses only the kernel crypto API |
| specific invocations. |
| |
| To initialize a Netlink interface, the following sequence has to be performed |
| by the consumer: |
| |
| 1. Create a socket of type AF_ALG with the struct sockaddr_alg parameter |
| specified below for the different cipher types. |
| |
| 2. Invoke bind with the socket descriptor |
| |
| 3. Invoke accept with the socket descriptor. The accept system call |
| returns a new file descriptor that is to be used to interact with |
| the particular cipher instance. When invoking send/write or recv/read |
| system calls to send data to the kernel or obtain data from the |
| kernel, the file descriptor returned by accept must be used. |
| |
| In-place cipher operation |
| ========================= |
| |
| Just like the in-kernel operation of the kernel crypto API, the user space |
| interface allows the cipher operation in-place. That means that the input buffer |
| used for the send/write system call and the output buffer used by the read/recv |
| system call may be one and the same. This is of particular interest for |
| symmetric cipher operations where a copying of the output data to its final |
| destination can be avoided. |
| |
| If a consumer on the other hand wants to maintain the plaintext and the |
| ciphertext in different memory locations, all a consumer needs to do is to |
| provide different memory pointers for the encryption and decryption operation. |
| |
| Message digest API |
| ================== |
| |
| The message digest type to be used for the cipher operation is selected when |
| invoking the bind syscall. bind requires the caller to provide a filled |
| struct sockaddr data structure. This data structure must be filled as follows: |
| |
| struct sockaddr_alg sa = { |
| .salg_family = AF_ALG, |
| .salg_type = "hash", /* this selects the hash logic in the kernel */ |
| .salg_name = "sha1" /* this is the cipher name */ |
| }; |
| |
| The salg_type value "hash" applies to message digests and keyed message digests. |
| Though, a keyed message digest is referenced by the appropriate salg_name. |
| Please see below for the setsockopt interface that explains how the key can be |
| set for a keyed message digest. |
| |
| Using the send() system call, the application provides the data that should be |
| processed with the message digest. The send system call allows the following |
| flags to be specified: |
| |
| * MSG_MORE: If this flag is set, the send system call acts like a |
| message digest update function where the final hash is not |
| yet calculated. If the flag is not set, the send system call |
| calculates the final message digest immediately. |
| |
| With the recv() system call, the application can read the message digest from |
| the kernel crypto API. If the buffer is too small for the message digest, the |
| flag MSG_TRUNC is set by the kernel. |
| |
| In order to set a message digest key, the calling application must use the |
| setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC operation is |
| performed without the initial HMAC state change caused by the key. |
| |
| |
| Symmetric cipher API |
| ==================== |
| |
| The operation is very similar to the message digest discussion. During |
| initialization, the struct sockaddr data structure must be filled as follows: |
| |
| struct sockaddr_alg sa = { |
| .salg_family = AF_ALG, |
| .salg_type = "skcipher", /* this selects the symmetric cipher */ |
| .salg_name = "cbc(aes)" /* this is the cipher name */ |
| }; |
| |
| Before data can be sent to the kernel using the write/send system call family, |
| the consumer must set the key. The key setting is described with the setsockopt |
| invocation below. |
| |
| Using the sendmsg() system call, the application provides the data that should |
| be processed for encryption or decryption. In addition, the IV is specified |
| with the data structure provided by the sendmsg() system call. |
| |
| The sendmsg system call parameter of struct msghdr is embedded into the |
| struct cmsghdr data structure. See recv(2) and cmsg(3) for more information |
| on how the cmsghdr data structure is used together with the send/recv system |
| call family. That cmsghdr data structure holds the following information |
| specified with a separate header instances: |
| |
| * specification of the cipher operation type with one of these flags: |
| ALG_OP_ENCRYPT - encryption of data |
| ALG_OP_DECRYPT - decryption of data |
| |
| * specification of the IV information marked with the flag ALG_SET_IV |
| |
| The send system call family allows the following flag to be specified: |
| |
| * MSG_MORE: If this flag is set, the send system call acts like a |
| cipher update function where more input data is expected |
| with a subsequent invocation of the send system call. |
| |
| Note: The kernel reports -EINVAL for any unexpected data. The caller must |
| make sure that all data matches the constraints given in /proc/crypto for the |
| selected cipher. |
| |
| With the recv() system call, the application can read the result of the |
| cipher operation from the kernel crypto API. The output buffer must be at least |
| as large as to hold all blocks of the encrypted or decrypted data. If the output |
| data size is smaller, only as many blocks are returned that fit into that |
| output buffer size. |
| |
| Setsockopt interface |
| ==================== |
| |
| In addition to the read/recv and send/write system call handling to send and |
| retrieve data subject to the cipher operation, a consumer also needs to set |
| the additional information for the cipher operation. This additional information |
| is set using the setsockopt system call that must be invoked with the file |
| descriptor of the open cipher (i.e. the file descriptor returned by the |
| accept system call). |
| |
| Each setsockopt invocation must use the level SOL_ALG. |
| |
| The setsockopt interface allows setting the following data using the mentioned |
| optname: |
| |
| * ALG_SET_KEY -- Setting the key. Key setting is applicable to: |
| |
| - the skcipher cipher type (symmetric ciphers) |
| |
| - the hash cipher type (keyed message digests) |
| |
| User space API example |
| ====================== |
| |
| Please see [1] for libkcapi which provides an easy-to-use wrapper around the |
| aforementioned Netlink kernel interface. [1] also contains a test application |
| that invokes all libkcapi API calls. |
| |
| [1] http://www.chronox.de/libkcapi.html |
| |
| Author |
| ====== |
| |
| Stephan Mueller <smueller@chronox.de> |