Commit | Line | Data |
---|---|---|
9a83b465 DH |
1 | ============================================= |
2 | ASYMMETRIC / PUBLIC-KEY CRYPTOGRAPHY KEY TYPE | |
3 | ============================================= | |
4 | ||
5 | Contents: | |
6 | ||
7 | - Overview. | |
8 | - Key identification. | |
9 | - Accessing asymmetric keys. | |
10 | - Signature verification. | |
11 | - Asymmetric key subtypes. | |
12 | - Instantiation data parsers. | |
13 | ||
14 | ||
15 | ======== | |
16 | OVERVIEW | |
17 | ======== | |
18 | ||
19 | The "asymmetric" key type is designed to be a container for the keys used in | |
20 | public-key cryptography, without imposing any particular restrictions on the | |
21 | form or mechanism of the cryptography or form of the key. | |
22 | ||
23 | The asymmetric key is given a subtype that defines what sort of data is | |
24 | associated with the key and provides operations to describe and destroy it. | |
25 | However, no requirement is made that the key data actually be stored in the | |
26 | key. | |
27 | ||
28 | A completely in-kernel key retention and operation subtype can be defined, but | |
29 | it would also be possible to provide access to cryptographic hardware (such as | |
30 | a TPM) that might be used to both retain the relevant key and perform | |
31 | operations using that key. In such a case, the asymmetric key would then | |
32 | merely be an interface to the TPM driver. | |
33 | ||
34 | Also provided is the concept of a data parser. Data parsers are responsible | |
35 | for extracting information from the blobs of data passed to the instantiation | |
36 | function. The first data parser that recognises the blob gets to set the | |
37 | subtype of the key and define the operations that can be done on that key. | |
38 | ||
39 | A data parser may interpret the data blob as containing the bits representing a | |
40 | key, or it may interpret it as a reference to a key held somewhere else in the | |
41 | system (for example, a TPM). | |
42 | ||
43 | ||
44 | ================== | |
45 | KEY IDENTIFICATION | |
46 | ================== | |
47 | ||
48 | If a key is added with an empty name, the instantiation data parsers are given | |
49 | the opportunity to pre-parse a key and to determine the description the key | |
50 | should be given from the content of the key. | |
51 | ||
52 | This can then be used to refer to the key, either by complete match or by | |
53 | partial match. The key type may also use other criteria to refer to a key. | |
54 | ||
55 | The asymmetric key type's match function can then perform a wider range of | |
56 | comparisons than just the straightforward comparison of the description with | |
57 | the criterion string: | |
58 | ||
59 | (1) If the criterion string is of the form "id:<hexdigits>" then the match | |
60 | function will examine a key's fingerprint to see if the hex digits given | |
61 | after the "id:" match the tail. For instance: | |
62 | ||
63 | keyctl search @s asymmetric id:5acc2142 | |
64 | ||
65 | will match a key with fingerprint: | |
66 | ||
67 | 1A00 2040 7601 7889 DE11 882C 3823 04AD 5ACC 2142 | |
68 | ||
69 | (2) If the criterion string is of the form "<subtype>:<hexdigits>" then the | |
70 | match will match the ID as in (1), but with the added restriction that | |
71 | only keys of the specified subtype (e.g. tpm) will be matched. For | |
72 | instance: | |
73 | ||
74 | keyctl search @s asymmetric tpm:5acc2142 | |
75 | ||
76 | Looking in /proc/keys, the last 8 hex digits of the key fingerprint are | |
77 | displayed, along with the subtype: | |
78 | ||
79 | 1a39e171 I----- 1 perm 3f010000 0 0 asymmetri modsign.0: DSA 5acc2142 [] | |
80 | ||
81 | ||
82 | ========================= | |
83 | ACCESSING ASYMMETRIC KEYS | |
84 | ========================= | |
85 | ||
86 | For general access to asymmetric keys from within the kernel, the following | |
87 | inclusion is required: | |
88 | ||
89 | #include <crypto/public_key.h> | |
90 | ||
91 | This gives access to functions for dealing with asymmetric / public keys. | |
92 | Three enums are defined there for representing public-key cryptography | |
93 | algorithms: | |
94 | ||
95 | enum pkey_algo | |
96 | ||
97 | digest algorithms used by those: | |
98 | ||
99 | enum pkey_hash_algo | |
100 | ||
101 | and key identifier representations: | |
102 | ||
103 | enum pkey_id_type | |
104 | ||
105 | Note that the key type representation types are required because key | |
106 | identifiers from different standards aren't necessarily compatible. For | |
107 | instance, PGP generates key identifiers by hashing the key data plus some | |
108 | PGP-specific metadata, whereas X.509 has arbitrary certificate identifiers. | |
109 | ||
110 | The operations defined upon a key are: | |
111 | ||
112 | (1) Signature verification. | |
113 | ||
114 | Other operations are possible (such as encryption) with the same key data | |
115 | required for verification, but not currently supported, and others | |
116 | (eg. decryption and signature generation) require extra key data. | |
117 | ||
118 | ||
119 | SIGNATURE VERIFICATION | |
120 | ---------------------- | |
121 | ||
122 | An operation is provided to perform cryptographic signature verification, using | |
123 | an asymmetric key to provide or to provide access to the public key. | |
124 | ||
125 | int verify_signature(const struct key *key, | |
126 | const struct public_key_signature *sig); | |
127 | ||
128 | The caller must have already obtained the key from some source and can then use | |
129 | it to check the signature. The caller must have parsed the signature and | |
130 | transferred the relevant bits to the structure pointed to by sig. | |
131 | ||
132 | struct public_key_signature { | |
133 | u8 *digest; | |
134 | u8 digest_size; | |
135 | enum pkey_hash_algo pkey_hash_algo : 8; | |
136 | u8 nr_mpi; | |
137 | union { | |
138 | MPI mpi[2]; | |
139 | ... | |
140 | }; | |
141 | }; | |
142 | ||
143 | The algorithm used must be noted in sig->pkey_hash_algo, and all the MPIs that | |
144 | make up the actual signature must be stored in sig->mpi[] and the count of MPIs | |
145 | placed in sig->nr_mpi. | |
146 | ||
147 | In addition, the data must have been digested by the caller and the resulting | |
148 | hash must be pointed to by sig->digest and the size of the hash be placed in | |
149 | sig->digest_size. | |
150 | ||
151 | The function will return 0 upon success or -EKEYREJECTED if the signature | |
152 | doesn't match. | |
153 | ||
154 | The function may also return -ENOTSUPP if an unsupported public-key algorithm | |
155 | or public-key/hash algorithm combination is specified or the key doesn't | |
156 | support the operation; -EBADMSG or -ERANGE if some of the parameters have weird | |
157 | data; or -ENOMEM if an allocation can't be performed. -EINVAL can be returned | |
158 | if the key argument is the wrong type or is incompletely set up. | |
159 | ||
160 | ||
161 | ======================= | |
162 | ASYMMETRIC KEY SUBTYPES | |
163 | ======================= | |
164 | ||
165 | Asymmetric keys have a subtype that defines the set of operations that can be | |
166 | performed on that key and that determines what data is attached as the key | |
167 | payload. The payload format is entirely at the whim of the subtype. | |
168 | ||
169 | The subtype is selected by the key data parser and the parser must initialise | |
170 | the data required for it. The asymmetric key retains a reference on the | |
171 | subtype module. | |
172 | ||
173 | The subtype definition structure can be found in: | |
174 | ||
175 | #include <keys/asymmetric-subtype.h> | |
176 | ||
177 | and looks like the following: | |
178 | ||
179 | struct asymmetric_key_subtype { | |
180 | struct module *owner; | |
181 | const char *name; | |
182 | ||
183 | void (*describe)(const struct key *key, struct seq_file *m); | |
184 | void (*destroy)(void *payload); | |
185 | int (*verify_signature)(const struct key *key, | |
186 | const struct public_key_signature *sig); | |
187 | }; | |
188 | ||
189 | Asymmetric keys point to this with their type_data[0] member. | |
190 | ||
191 | The owner and name fields should be set to the owning module and the name of | |
192 | the subtype. Currently, the name is only used for print statements. | |
193 | ||
194 | There are a number of operations defined by the subtype: | |
195 | ||
196 | (1) describe(). | |
197 | ||
198 | Mandatory. This allows the subtype to display something in /proc/keys | |
199 | against the key. For instance the name of the public key algorithm type | |
200 | could be displayed. The key type will display the tail of the key | |
201 | identity string after this. | |
202 | ||
203 | (2) destroy(). | |
204 | ||
205 | Mandatory. This should free the memory associated with the key. The | |
206 | asymmetric key will look after freeing the fingerprint and releasing the | |
207 | reference on the subtype module. | |
208 | ||
209 | (3) verify_signature(). | |
210 | ||
211 | Optional. These are the entry points for the key usage operations. | |
212 | Currently there is only the one defined. If not set, the caller will be | |
213 | given -ENOTSUPP. The subtype may do anything it likes to implement an | |
214 | operation, including offloading to hardware. | |
215 | ||
216 | ||
217 | ========================== | |
218 | INSTANTIATION DATA PARSERS | |
219 | ========================== | |
220 | ||
221 | The asymmetric key type doesn't generally want to store or to deal with a raw | |
222 | blob of data that holds the key data. It would have to parse it and error | |
223 | check it each time it wanted to use it. Further, the contents of the blob may | |
224 | have various checks that can be performed on it (eg. self-signatures, validity | |
225 | dates) and may contain useful data about the key (identifiers, capabilities). | |
226 | ||
227 | Also, the blob may represent a pointer to some hardware containing the key | |
228 | rather than the key itself. | |
229 | ||
230 | Examples of blob formats for which parsers could be implemented include: | |
231 | ||
232 | - OpenPGP packet stream [RFC 4880]. | |
233 | - X.509 ASN.1 stream. | |
234 | - Pointer to TPM key. | |
235 | - Pointer to UEFI key. | |
236 | ||
237 | During key instantiation each parser in the list is tried until one doesn't | |
238 | return -EBADMSG. | |
239 | ||
240 | The parser definition structure can be found in: | |
241 | ||
242 | #include <keys/asymmetric-parser.h> | |
243 | ||
244 | and looks like the following: | |
245 | ||
246 | struct asymmetric_key_parser { | |
247 | struct module *owner; | |
248 | const char *name; | |
249 | ||
250 | int (*parse)(struct key_preparsed_payload *prep); | |
251 | }; | |
252 | ||
253 | The owner and name fields should be set to the owning module and the name of | |
254 | the parser. | |
255 | ||
256 | There is currently only a single operation defined by the parser, and it is | |
257 | mandatory: | |
258 | ||
259 | (1) parse(). | |
260 | ||
261 | This is called to preparse the key from the key creation and update paths. | |
262 | In particular, it is called during the key creation _before_ a key is | |
263 | allocated, and as such, is permitted to provide the key's description in | |
264 | the case that the caller declines to do so. | |
265 | ||
266 | The caller passes a pointer to the following struct with all of the fields | |
267 | cleared, except for data, datalen and quotalen [see | |
268 | Documentation/security/keys.txt]. | |
269 | ||
270 | struct key_preparsed_payload { | |
271 | char *description; | |
272 | void *type_data[2]; | |
273 | void *payload; | |
274 | const void *data; | |
275 | size_t datalen; | |
276 | size_t quotalen; | |
277 | }; | |
278 | ||
279 | The instantiation data is in a blob pointed to by data and is datalen in | |
280 | size. The parse() function is not permitted to change these two values at | |
281 | all, and shouldn't change any of the other values _unless_ they are | |
282 | recognise the blob format and will not return -EBADMSG to indicate it is | |
283 | not theirs. | |
284 | ||
285 | If the parser is happy with the blob, it should propose a description for | |
286 | the key and attach it to ->description, ->type_data[0] should be set to | |
287 | point to the subtype to be used, ->payload should be set to point to the | |
288 | initialised data for that subtype, ->type_data[1] should point to a hex | |
289 | fingerprint and quotalen should be updated to indicate how much quota this | |
290 | key should account for. | |
291 | ||
292 | When clearing up, the data attached to ->type_data[1] and ->description | |
293 | will be kfree()'d and the data attached to ->payload will be passed to the | |
294 | subtype's ->destroy() method to be disposed of. A module reference for | |
295 | the subtype pointed to by ->type_data[0] will be put. | |
296 | ||
297 | ||
298 | If the data format is not recognised, -EBADMSG should be returned. If it | |
299 | is recognised, but the key cannot for some reason be set up, some other | |
300 | negative error code should be returned. On success, 0 should be returned. | |
301 | ||
302 | The key's fingerprint string may be partially matched upon. For a | |
303 | public-key algorithm such as RSA and DSA this will likely be a printable | |
304 | hex version of the key's fingerprint. | |
305 | ||
306 | Functions are provided to register and unregister parsers: | |
307 | ||
308 | int register_asymmetric_key_parser(struct asymmetric_key_parser *parser); | |
309 | void unregister_asymmetric_key_parser(struct asymmetric_key_parser *subtype); | |
310 | ||
311 | Parsers may not have the same name. The names are otherwise only used for | |
312 | displaying in debugging messages. |