|
| 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. |
0 commit comments