Commit | Line | Data |
---|---|---|
e63b673f SM |
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> |