Commit | Line | Data |
---|---|---|
3b72c814 SM |
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 | ||
9332a9e7 | 26 | [1] https://www.chronox.de/libkcapi.html |
3b72c814 SM |
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 | ||
8bd1d400 | 330 | The system-inherent limit for the size of one zero-copy operation is 16 |
3b72c814 SM |
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 | ||
9332a9e7 | 387 | [1] https://www.chronox.de/libkcapi.html |