Stephan Mueller | e63b673 | 2014-11-12 05:24:53 +0100 | [diff] [blame] | 1 | Introduction |
| 2 | ============ |
| 3 | |
| 4 | The concepts of the kernel crypto API visible to kernel space is fully |
| 5 | applicable to the user space interface as well. Therefore, the kernel crypto API |
| 6 | high level discussion for the in-kernel use cases applies here as well. |
| 7 | |
| 8 | The major difference, however, is that user space can only act as a consumer |
| 9 | and never as a provider of a transformation or cipher algorithm. |
| 10 | |
| 11 | The following covers the user space interface exported by the kernel crypto |
| 12 | API. A working example of this description is libkcapi that can be obtained from |
| 13 | [1]. That library can be used by user space applications that require |
| 14 | cryptographic services from the kernel. |
| 15 | |
| 16 | Some details of the in-kernel kernel crypto API aspects do not |
| 17 | apply to user space, however. This includes the difference between synchronous |
| 18 | and asynchronous invocations. The user space API call is fully synchronous. |
| 19 | In addition, only a subset of all cipher types are available as documented |
| 20 | below. |
| 21 | |
| 22 | |
| 23 | User space API general remarks |
| 24 | ============================== |
| 25 | |
| 26 | The kernel crypto API is accessible from user space. Currently, the following |
| 27 | ciphers are accessible: |
| 28 | |
| 29 | * Message digest including keyed message digest (HMAC, CMAC) |
| 30 | |
| 31 | * Symmetric ciphers |
| 32 | |
| 33 | Note, AEAD ciphers are currently not supported via the symmetric cipher |
| 34 | interface. |
| 35 | |
| 36 | The interface is provided via Netlink using the type AF_ALG. In addition, the |
| 37 | setsockopt option type is SOL_ALG. In case the user space header files do not |
| 38 | export these flags yet, use the following macros: |
| 39 | |
| 40 | #ifndef AF_ALG |
| 41 | #define AF_ALG 38 |
| 42 | #endif |
| 43 | #ifndef SOL_ALG |
| 44 | #define SOL_ALG 279 |
| 45 | #endif |
| 46 | |
| 47 | A cipher is accessed with the same name as done for the in-kernel API calls. |
| 48 | This includes the generic vs. unique naming schema for ciphers as well as the |
| 49 | enforcement of priorities for generic names. |
| 50 | |
| 51 | To interact with the kernel crypto API, a Netlink socket must be created by |
| 52 | the user space application. User space invokes the cipher operation with the |
| 53 | send/write system call family. The result of the cipher operation is obtained |
| 54 | with the read/recv system call family. |
| 55 | |
| 56 | The following API calls assume that the Netlink socket descriptor is already |
| 57 | opened by the user space application and discusses only the kernel crypto API |
| 58 | specific invocations. |
| 59 | |
| 60 | To initialize a Netlink interface, the following sequence has to be performed |
| 61 | by the consumer: |
| 62 | |
| 63 | 1. Create a socket of type AF_ALG with the struct sockaddr_alg parameter |
| 64 | specified below for the different cipher types. |
| 65 | |
| 66 | 2. Invoke bind with the socket descriptor |
| 67 | |
| 68 | 3. Invoke accept with the socket descriptor. The accept system call |
| 69 | returns a new file descriptor that is to be used to interact with |
| 70 | the particular cipher instance. When invoking send/write or recv/read |
| 71 | system calls to send data to the kernel or obtain data from the |
| 72 | kernel, the file descriptor returned by accept must be used. |
| 73 | |
| 74 | In-place cipher operation |
| 75 | ========================= |
| 76 | |
| 77 | Just like the in-kernel operation of the kernel crypto API, the user space |
| 78 | interface allows the cipher operation in-place. That means that the input buffer |
| 79 | used for the send/write system call and the output buffer used by the read/recv |
| 80 | system call may be one and the same. This is of particular interest for |
| 81 | symmetric cipher operations where a copying of the output data to its final |
| 82 | destination can be avoided. |
| 83 | |
| 84 | If a consumer on the other hand wants to maintain the plaintext and the |
| 85 | ciphertext in different memory locations, all a consumer needs to do is to |
| 86 | provide different memory pointers for the encryption and decryption operation. |
| 87 | |
| 88 | Message digest API |
| 89 | ================== |
| 90 | |
| 91 | The message digest type to be used for the cipher operation is selected when |
| 92 | invoking the bind syscall. bind requires the caller to provide a filled |
| 93 | struct sockaddr data structure. This data structure must be filled as follows: |
| 94 | |
| 95 | struct sockaddr_alg sa = { |
| 96 | .salg_family = AF_ALG, |
| 97 | .salg_type = "hash", /* this selects the hash logic in the kernel */ |
| 98 | .salg_name = "sha1" /* this is the cipher name */ |
| 99 | }; |
| 100 | |
| 101 | The salg_type value "hash" applies to message digests and keyed message digests. |
| 102 | Though, a keyed message digest is referenced by the appropriate salg_name. |
| 103 | Please see below for the setsockopt interface that explains how the key can be |
| 104 | set for a keyed message digest. |
| 105 | |
| 106 | Using the send() system call, the application provides the data that should be |
| 107 | processed with the message digest. The send system call allows the following |
| 108 | flags to be specified: |
| 109 | |
| 110 | * MSG_MORE: If this flag is set, the send system call acts like a |
| 111 | message digest update function where the final hash is not |
| 112 | yet calculated. If the flag is not set, the send system call |
| 113 | calculates the final message digest immediately. |
| 114 | |
| 115 | With the recv() system call, the application can read the message digest from |
| 116 | the kernel crypto API. If the buffer is too small for the message digest, the |
| 117 | flag MSG_TRUNC is set by the kernel. |
| 118 | |
| 119 | In order to set a message digest key, the calling application must use the |
| 120 | setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC operation is |
| 121 | performed without the initial HMAC state change caused by the key. |
| 122 | |
| 123 | |
| 124 | Symmetric cipher API |
| 125 | ==================== |
| 126 | |
| 127 | The operation is very similar to the message digest discussion. During |
| 128 | initialization, the struct sockaddr data structure must be filled as follows: |
| 129 | |
| 130 | struct sockaddr_alg sa = { |
| 131 | .salg_family = AF_ALG, |
| 132 | .salg_type = "skcipher", /* this selects the symmetric cipher */ |
| 133 | .salg_name = "cbc(aes)" /* this is the cipher name */ |
| 134 | }; |
| 135 | |
| 136 | Before data can be sent to the kernel using the write/send system call family, |
| 137 | the consumer must set the key. The key setting is described with the setsockopt |
| 138 | invocation below. |
| 139 | |
| 140 | Using the sendmsg() system call, the application provides the data that should |
| 141 | be processed for encryption or decryption. In addition, the IV is specified |
| 142 | with the data structure provided by the sendmsg() system call. |
| 143 | |
| 144 | The sendmsg system call parameter of struct msghdr is embedded into the |
| 145 | struct cmsghdr data structure. See recv(2) and cmsg(3) for more information |
| 146 | on how the cmsghdr data structure is used together with the send/recv system |
| 147 | call family. That cmsghdr data structure holds the following information |
| 148 | specified with a separate header instances: |
| 149 | |
| 150 | * specification of the cipher operation type with one of these flags: |
| 151 | ALG_OP_ENCRYPT - encryption of data |
| 152 | ALG_OP_DECRYPT - decryption of data |
| 153 | |
| 154 | * specification of the IV information marked with the flag ALG_SET_IV |
| 155 | |
| 156 | The send system call family allows the following flag to be specified: |
| 157 | |
| 158 | * MSG_MORE: If this flag is set, the send system call acts like a |
| 159 | cipher update function where more input data is expected |
| 160 | with a subsequent invocation of the send system call. |
| 161 | |
| 162 | Note: The kernel reports -EINVAL for any unexpected data. The caller must |
| 163 | make sure that all data matches the constraints given in /proc/crypto for the |
| 164 | selected cipher. |
| 165 | |
| 166 | With the recv() system call, the application can read the result of the |
| 167 | cipher operation from the kernel crypto API. The output buffer must be at least |
| 168 | as large as to hold all blocks of the encrypted or decrypted data. If the output |
| 169 | data size is smaller, only as many blocks are returned that fit into that |
| 170 | output buffer size. |
| 171 | |
| 172 | Setsockopt interface |
| 173 | ==================== |
| 174 | |
| 175 | In addition to the read/recv and send/write system call handling to send and |
| 176 | retrieve data subject to the cipher operation, a consumer also needs to set |
| 177 | the additional information for the cipher operation. This additional information |
| 178 | is set using the setsockopt system call that must be invoked with the file |
| 179 | descriptor of the open cipher (i.e. the file descriptor returned by the |
| 180 | accept system call). |
| 181 | |
| 182 | Each setsockopt invocation must use the level SOL_ALG. |
| 183 | |
| 184 | The setsockopt interface allows setting the following data using the mentioned |
| 185 | optname: |
| 186 | |
| 187 | * ALG_SET_KEY -- Setting the key. Key setting is applicable to: |
| 188 | |
| 189 | - the skcipher cipher type (symmetric ciphers) |
| 190 | |
| 191 | - the hash cipher type (keyed message digests) |
| 192 | |
| 193 | User space API example |
| 194 | ====================== |
| 195 | |
| 196 | Please see [1] for libkcapi which provides an easy-to-use wrapper around the |
| 197 | aforementioned Netlink kernel interface. [1] also contains a test application |
| 198 | that invokes all libkcapi API calls. |
| 199 | |
| 200 | [1] http://www.chronox.de/libkcapi.html |
| 201 | |
| 202 | Author |
| 203 | ====== |
| 204 | |
| 205 | Stephan Mueller <smueller@chronox.de> |