diff options
| author | David Howells <dhowells@redhat.com> | 2012-09-13 10:17:21 -0400 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-10-07 23:20:12 -0400 |
| commit | 9a83b46578df149160b1da057656d2f0cfcbb5b6 (patch) | |
| tree | c1f5191fee0d8e82be1c3e47e7f7882c1af9be67 /Documentation | |
| parent | aacf29bf1bf133f6219e6f8969d4ebc2ac76458f (diff) | |
KEYS: Document asymmetric key type
In-source documentation for the asymmetric key type. This will be located in:
Documentation/crypto/asymmetric-keys.txt
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation')
| -rw-r--r-- | Documentation/crypto/asymmetric-keys.txt | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt new file mode 100644 index 000000000000..b7675904a747 --- /dev/null +++ b/Documentation/crypto/asymmetric-keys.txt | |||
| @@ -0,0 +1,312 @@ | |||
| 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. | ||
