Stephan Mueller | 3b72c81 | 2016-10-21 04:54:22 +0200 | [diff] [blame] | 1 | User Space Interface |
| 2 | ==================== |
| 3 | |
| 4 | Introduction |
| 5 | ------------ |
| 6 | |
| 7 | The concepts of the kernel crypto API visible to kernel space is fully |
| 8 | applicable to the user space interface as well. Therefore, the kernel |
| 9 | crypto API high level discussion for the in-kernel use cases applies |
| 10 | here as well. |
| 11 | |
| 12 | The major difference, however, is that user space can only act as a |
| 13 | consumer and never as a provider of a transformation or cipher |
| 14 | algorithm. |
| 15 | |
| 16 | The following covers the user space interface exported by the kernel |
| 17 | crypto API. A working example of this description is libkcapi that can |
| 18 | be obtained from [1]. That library can be used by user space |
| 19 | applications that require cryptographic services from the kernel. |
| 20 | |
| 21 | Some details of the in-kernel kernel crypto API aspects do not apply to |
| 22 | user space, however. This includes the difference between synchronous |
| 23 | and asynchronous invocations. The user space API call is fully |
| 24 | synchronous. |
| 25 | |
| 26 | [1] http://www.chronox.de/libkcapi.html |
| 27 | |
| 28 | User Space API General Remarks |
| 29 | ------------------------------ |
| 30 | |
| 31 | The kernel crypto API is accessible from user space. Currently, the |
| 32 | following ciphers are accessible: |
| 33 | |
| 34 | - Message digest including keyed message digest (HMAC, CMAC) |
| 35 | |
| 36 | - Symmetric ciphers |
| 37 | |
| 38 | - AEAD ciphers |
| 39 | |
| 40 | - Random Number Generators |
| 41 | |
| 42 | The interface is provided via socket type using the type AF_ALG. In |
| 43 | addition, the setsockopt option type is SOL_ALG. In case the user space |
| 44 | header files do not export these flags yet, use the following macros: |
| 45 | |
| 46 | :: |
| 47 | |
| 48 | #ifndef AF_ALG |
| 49 | #define AF_ALG 38 |
| 50 | #endif |
| 51 | #ifndef SOL_ALG |
| 52 | #define SOL_ALG 279 |
| 53 | #endif |
| 54 | |
| 55 | |
| 56 | A cipher is accessed with the same name as done for the in-kernel API |
| 57 | calls. This includes the generic vs. unique naming schema for ciphers as |
| 58 | well as the enforcement of priorities for generic names. |
| 59 | |
| 60 | To interact with the kernel crypto API, a socket must be created by the |
| 61 | user space application. User space invokes the cipher operation with the |
| 62 | send()/write() system call family. The result of the cipher operation is |
| 63 | obtained with the read()/recv() system call family. |
| 64 | |
| 65 | The following API calls assume that the socket descriptor is already |
| 66 | opened by the user space application and discusses only the kernel |
| 67 | crypto API specific invocations. |
| 68 | |
| 69 | To initialize the socket interface, the following sequence has to be |
| 70 | performed by the consumer: |
| 71 | |
| 72 | 1. Create a socket of type AF_ALG with the struct sockaddr_alg |
| 73 | parameter specified below for the different cipher types. |
| 74 | |
| 75 | 2. Invoke bind with the socket descriptor |
| 76 | |
| 77 | 3. Invoke accept with the socket descriptor. The accept system call |
| 78 | returns a new file descriptor that is to be used to interact with the |
| 79 | particular cipher instance. When invoking send/write or recv/read |
| 80 | system calls to send data to the kernel or obtain data from the |
| 81 | kernel, the file descriptor returned by accept must be used. |
| 82 | |
| 83 | In-place Cipher operation |
| 84 | ------------------------- |
| 85 | |
| 86 | Just like the in-kernel operation of the kernel crypto API, the user |
| 87 | space interface allows the cipher operation in-place. That means that |
| 88 | the input buffer used for the send/write system call and the output |
| 89 | buffer used by the read/recv system call may be one and the same. This |
| 90 | is of particular interest for symmetric cipher operations where a |
| 91 | copying of the output data to its final destination can be avoided. |
| 92 | |
| 93 | If a consumer on the other hand wants to maintain the plaintext and the |
| 94 | ciphertext in different memory locations, all a consumer needs to do is |
| 95 | to provide different memory pointers for the encryption and decryption |
| 96 | operation. |
| 97 | |
| 98 | Message Digest API |
| 99 | ------------------ |
| 100 | |
| 101 | The message digest type to be used for the cipher operation is selected |
| 102 | when invoking the bind syscall. bind requires the caller to provide a |
| 103 | filled struct sockaddr data structure. This data structure must be |
| 104 | filled as follows: |
| 105 | |
| 106 | :: |
| 107 | |
| 108 | struct sockaddr_alg sa = { |
| 109 | .salg_family = AF_ALG, |
| 110 | .salg_type = "hash", /* this selects the hash logic in the kernel */ |
| 111 | .salg_name = "sha1" /* this is the cipher name */ |
| 112 | }; |
| 113 | |
| 114 | |
| 115 | The salg_type value "hash" applies to message digests and keyed message |
| 116 | digests. Though, a keyed message digest is referenced by the appropriate |
| 117 | salg_name. Please see below for the setsockopt interface that explains |
| 118 | how the key can be set for a keyed message digest. |
| 119 | |
| 120 | Using the send() system call, the application provides the data that |
| 121 | should be processed with the message digest. The send system call allows |
| 122 | the following flags to be specified: |
| 123 | |
| 124 | - MSG_MORE: If this flag is set, the send system call acts like a |
| 125 | message digest update function where the final hash is not yet |
| 126 | calculated. If the flag is not set, the send system call calculates |
| 127 | the final message digest immediately. |
| 128 | |
| 129 | With the recv() system call, the application can read the message digest |
| 130 | from the kernel crypto API. If the buffer is too small for the message |
| 131 | digest, the flag MSG_TRUNC is set by the kernel. |
| 132 | |
| 133 | In order to set a message digest key, the calling application must use |
| 134 | the setsockopt() option of ALG_SET_KEY. If the key is not set the HMAC |
| 135 | operation is performed without the initial HMAC state change caused by |
| 136 | the key. |
| 137 | |
| 138 | Symmetric Cipher API |
| 139 | -------------------- |
| 140 | |
| 141 | The operation is very similar to the message digest discussion. During |
| 142 | initialization, the struct sockaddr data structure must be filled as |
| 143 | follows: |
| 144 | |
| 145 | :: |
| 146 | |
| 147 | struct sockaddr_alg sa = { |
| 148 | .salg_family = AF_ALG, |
| 149 | .salg_type = "skcipher", /* this selects the symmetric cipher */ |
| 150 | .salg_name = "cbc(aes)" /* this is the cipher name */ |
| 151 | }; |
| 152 | |
| 153 | |
| 154 | Before data can be sent to the kernel using the write/send system call |
| 155 | family, the consumer must set the key. The key setting is described with |
| 156 | the setsockopt invocation below. |
| 157 | |
| 158 | Using the sendmsg() system call, the application provides the data that |
| 159 | should be processed for encryption or decryption. In addition, the IV is |
| 160 | specified with the data structure provided by the sendmsg() system call. |
| 161 | |
| 162 | The sendmsg system call parameter of struct msghdr is embedded into the |
| 163 | struct cmsghdr data structure. See recv(2) and cmsg(3) for more |
| 164 | information on how the cmsghdr data structure is used together with the |
| 165 | send/recv system call family. That cmsghdr data structure holds the |
| 166 | following information specified with a separate header instances: |
| 167 | |
| 168 | - specification of the cipher operation type with one of these flags: |
| 169 | |
| 170 | - ALG_OP_ENCRYPT - encryption of data |
| 171 | |
| 172 | - ALG_OP_DECRYPT - decryption of data |
| 173 | |
| 174 | - specification of the IV information marked with the flag ALG_SET_IV |
| 175 | |
| 176 | The send system call family allows the following flag to be specified: |
| 177 | |
| 178 | - MSG_MORE: If this flag is set, the send system call acts like a |
| 179 | cipher update function where more input data is expected with a |
| 180 | subsequent invocation of the send system call. |
| 181 | |
| 182 | Note: The kernel reports -EINVAL for any unexpected data. The caller |
| 183 | must make sure that all data matches the constraints given in |
| 184 | /proc/crypto for the selected cipher. |
| 185 | |
| 186 | With the recv() system call, the application can read the result of the |
| 187 | cipher operation from the kernel crypto API. The output buffer must be |
| 188 | at least as large as to hold all blocks of the encrypted or decrypted |
| 189 | data. If the output data size is smaller, only as many blocks are |
| 190 | returned that fit into that output buffer size. |
| 191 | |
| 192 | AEAD Cipher API |
| 193 | --------------- |
| 194 | |
| 195 | The operation is very similar to the symmetric cipher discussion. During |
| 196 | initialization, the struct sockaddr data structure must be filled as |
| 197 | follows: |
| 198 | |
| 199 | :: |
| 200 | |
| 201 | struct sockaddr_alg sa = { |
| 202 | .salg_family = AF_ALG, |
| 203 | .salg_type = "aead", /* this selects the symmetric cipher */ |
| 204 | .salg_name = "gcm(aes)" /* this is the cipher name */ |
| 205 | }; |
| 206 | |
| 207 | |
| 208 | Before data can be sent to the kernel using the write/send system call |
| 209 | family, the consumer must set the key. The key setting is described with |
| 210 | the setsockopt invocation below. |
| 211 | |
| 212 | In addition, before data can be sent to the kernel using the write/send |
| 213 | system call family, the consumer must set the authentication tag size. |
| 214 | To set the authentication tag size, the caller must use the setsockopt |
| 215 | invocation described below. |
| 216 | |
| 217 | Using the sendmsg() system call, the application provides the data that |
| 218 | should be processed for encryption or decryption. In addition, the IV is |
| 219 | specified with the data structure provided by the sendmsg() system call. |
| 220 | |
| 221 | The sendmsg system call parameter of struct msghdr is embedded into the |
| 222 | struct cmsghdr data structure. See recv(2) and cmsg(3) for more |
| 223 | information on how the cmsghdr data structure is used together with the |
| 224 | send/recv system call family. That cmsghdr data structure holds the |
| 225 | following information specified with a separate header instances: |
| 226 | |
| 227 | - specification of the cipher operation type with one of these flags: |
| 228 | |
| 229 | - ALG_OP_ENCRYPT - encryption of data |
| 230 | |
| 231 | - ALG_OP_DECRYPT - decryption of data |
| 232 | |
| 233 | - specification of the IV information marked with the flag ALG_SET_IV |
| 234 | |
| 235 | - specification of the associated authentication data (AAD) with the |
| 236 | flag ALG_SET_AEAD_ASSOCLEN. The AAD is sent to the kernel together |
| 237 | with the plaintext / ciphertext. See below for the memory structure. |
| 238 | |
| 239 | The send system call family allows the following flag to be specified: |
| 240 | |
| 241 | - MSG_MORE: If this flag is set, the send system call acts like a |
| 242 | cipher update function where more input data is expected with a |
| 243 | subsequent invocation of the send system call. |
| 244 | |
| 245 | Note: The kernel reports -EINVAL for any unexpected data. The caller |
| 246 | must make sure that all data matches the constraints given in |
| 247 | /proc/crypto for the selected cipher. |
| 248 | |
| 249 | With the recv() system call, the application can read the result of the |
| 250 | cipher operation from the kernel crypto API. The output buffer must be |
| 251 | at least as large as defined with the memory structure below. If the |
| 252 | output data size is smaller, the cipher operation is not performed. |
| 253 | |
| 254 | The authenticated decryption operation may indicate an integrity error. |
| 255 | Such breach in integrity is marked with the -EBADMSG error code. |
| 256 | |
| 257 | AEAD Memory Structure |
| 258 | ~~~~~~~~~~~~~~~~~~~~~ |
| 259 | |
| 260 | The AEAD cipher operates with the following information that is |
| 261 | communicated between user and kernel space as one data stream: |
| 262 | |
| 263 | - plaintext or ciphertext |
| 264 | |
| 265 | - associated authentication data (AAD) |
| 266 | |
| 267 | - authentication tag |
| 268 | |
| 269 | The sizes of the AAD and the authentication tag are provided with the |
| 270 | sendmsg and setsockopt calls (see there). As the kernel knows the size |
| 271 | of the entire data stream, the kernel is now able to calculate the right |
| 272 | offsets of the data components in the data stream. |
| 273 | |
| 274 | The user space caller must arrange the aforementioned information in the |
| 275 | following order: |
| 276 | |
| 277 | - AEAD encryption input: AAD \|\| plaintext |
| 278 | |
| 279 | - AEAD decryption input: AAD \|\| ciphertext \|\| authentication tag |
| 280 | |
| 281 | The output buffer the user space caller provides must be at least as |
| 282 | large to hold the following data: |
| 283 | |
| 284 | - AEAD encryption output: ciphertext \|\| authentication tag |
| 285 | |
| 286 | - AEAD decryption output: plaintext |
| 287 | |
| 288 | Random Number Generator API |
| 289 | --------------------------- |
| 290 | |
| 291 | Again, the operation is very similar to the other APIs. During |
| 292 | initialization, the struct sockaddr data structure must be filled as |
| 293 | follows: |
| 294 | |
| 295 | :: |
| 296 | |
| 297 | struct sockaddr_alg sa = { |
| 298 | .salg_family = AF_ALG, |
| 299 | .salg_type = "rng", /* this selects the symmetric cipher */ |
| 300 | .salg_name = "drbg_nopr_sha256" /* this is the cipher name */ |
| 301 | }; |
| 302 | |
| 303 | |
| 304 | Depending on the RNG type, the RNG must be seeded. The seed is provided |
| 305 | using the setsockopt interface to set the key. For example, the |
| 306 | ansi_cprng requires a seed. The DRBGs do not require a seed, but may be |
| 307 | seeded. |
| 308 | |
| 309 | Using the read()/recvmsg() system calls, random numbers can be obtained. |
| 310 | The kernel generates at most 128 bytes in one call. If user space |
| 311 | requires more data, multiple calls to read()/recvmsg() must be made. |
| 312 | |
| 313 | WARNING: The user space caller may invoke the initially mentioned accept |
| 314 | system call multiple times. In this case, the returned file descriptors |
| 315 | have the same state. |
| 316 | |
| 317 | Zero-Copy Interface |
| 318 | ------------------- |
| 319 | |
| 320 | In addition to the send/write/read/recv system call family, the AF_ALG |
| 321 | interface can be accessed with the zero-copy interface of |
| 322 | splice/vmsplice. As the name indicates, the kernel tries to avoid a copy |
| 323 | operation into kernel space. |
| 324 | |
| 325 | The zero-copy operation requires data to be aligned at the page |
| 326 | boundary. Non-aligned data can be used as well, but may require more |
| 327 | operations of the kernel which would defeat the speed gains obtained |
| 328 | from the zero-copy interface. |
| 329 | |
| 330 | The system-interent limit for the size of one zero-copy operation is 16 |
| 331 | pages. If more data is to be sent to AF_ALG, user space must slice the |
| 332 | input into segments with a maximum size of 16 pages. |
| 333 | |
| 334 | Zero-copy can be used with the following code example (a complete |
| 335 | working example is provided with libkcapi): |
| 336 | |
| 337 | :: |
| 338 | |
| 339 | int pipes[2]; |
| 340 | |
| 341 | pipe(pipes); |
| 342 | /* input data in iov */ |
| 343 | vmsplice(pipes[1], iov, iovlen, SPLICE_F_GIFT); |
| 344 | /* opfd is the file descriptor returned from accept() system call */ |
| 345 | splice(pipes[0], NULL, opfd, NULL, ret, 0); |
| 346 | read(opfd, out, outlen); |
| 347 | |
| 348 | |
| 349 | Setsockopt Interface |
| 350 | -------------------- |
| 351 | |
| 352 | In addition to the read/recv and send/write system call handling to send |
| 353 | and retrieve data subject to the cipher operation, a consumer also needs |
| 354 | to set the additional information for the cipher operation. This |
| 355 | additional information is set using the setsockopt system call that must |
| 356 | be invoked with the file descriptor of the open cipher (i.e. the file |
| 357 | descriptor returned by the accept system call). |
| 358 | |
| 359 | Each setsockopt invocation must use the level SOL_ALG. |
| 360 | |
| 361 | The setsockopt interface allows setting the following data using the |
| 362 | mentioned optname: |
| 363 | |
| 364 | - ALG_SET_KEY -- Setting the key. Key setting is applicable to: |
| 365 | |
| 366 | - the skcipher cipher type (symmetric ciphers) |
| 367 | |
| 368 | - the hash cipher type (keyed message digests) |
| 369 | |
| 370 | - the AEAD cipher type |
| 371 | |
| 372 | - the RNG cipher type to provide the seed |
| 373 | |
| 374 | - ALG_SET_AEAD_AUTHSIZE -- Setting the authentication tag size for |
| 375 | AEAD ciphers. For a encryption operation, the authentication tag of |
| 376 | the given size will be generated. For a decryption operation, the |
| 377 | provided ciphertext is assumed to contain an authentication tag of |
| 378 | the given size (see section about AEAD memory layout below). |
| 379 | |
| 380 | User space API example |
| 381 | ---------------------- |
| 382 | |
| 383 | Please see [1] for libkcapi which provides an easy-to-use wrapper around |
| 384 | the aforementioned Netlink kernel interface. [1] also contains a test |
| 385 | application that invokes all libkcapi API calls. |
| 386 | |
| 387 | [1] http://www.chronox.de/libkcapi.html |