KEYS: Document asymmetric key type
authorDavid Howells <dhowells@redhat.com>
Thu, 13 Sep 2012 14:17:21 +0000 (15:17 +0100)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 8 Oct 2012 03:20:12 +0000 (13:50 +1030)
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>
Documentation/crypto/asymmetric-keys.txt [new file with mode: 0644]

diff --git a/Documentation/crypto/asymmetric-keys.txt b/Documentation/crypto/asymmetric-keys.txt
new file mode 100644 (file)
index 0000000..b767590
--- /dev/null
@@ -0,0 +1,312 @@
+               =============================================
+               ASYMMETRIC / PUBLIC-KEY CRYPTOGRAPHY KEY TYPE
+               =============================================
+
+Contents:
+
+  - Overview.
+  - Key identification.
+  - Accessing asymmetric keys.
+    - Signature verification.
+  - Asymmetric key subtypes.
+  - Instantiation data parsers.
+
+
+========
+OVERVIEW
+========
+
+The "asymmetric" key type is designed to be a container for the keys used in
+public-key cryptography, without imposing any particular restrictions on the
+form or mechanism of the cryptography or form of the key.
+
+The asymmetric key is given a subtype that defines what sort of data is
+associated with the key and provides operations to describe and destroy it.
+However, no requirement is made that the key data actually be stored in the
+key.
+
+A completely in-kernel key retention and operation subtype can be defined, but
+it would also be possible to provide access to cryptographic hardware (such as
+a TPM) that might be used to both retain the relevant key and perform
+operations using that key.  In such a case, the asymmetric key would then
+merely be an interface to the TPM driver.
+
+Also provided is the concept of a data parser.  Data parsers are responsible
+for extracting information from the blobs of data passed to the instantiation
+function.  The first data parser that recognises the blob gets to set the
+subtype of the key and define the operations that can be done on that key.
+
+A data parser may interpret the data blob as containing the bits representing a
+key, or it may interpret it as a reference to a key held somewhere else in the
+system (for example, a TPM).
+
+
+==================
+KEY IDENTIFICATION
+==================
+
+If a key is added with an empty name, the instantiation data parsers are given
+the opportunity to pre-parse a key and to determine the description the key
+should be given from the content of the key.
+
+This can then be used to refer to the key, either by complete match or by
+partial match.  The key type may also use other criteria to refer to a key.
+
+The asymmetric key type's match function can then perform a wider range of
+comparisons than just the straightforward comparison of the description with
+the criterion string:
+
+ (1) If the criterion string is of the form "id:<hexdigits>" then the match
+     function will examine a key's fingerprint to see if the hex digits given
+     after the "id:" match the tail.  For instance:
+
+       keyctl search @s asymmetric id:5acc2142
+
+     will match a key with fingerprint:
+
+       1A00 2040 7601 7889 DE11  882C 3823 04AD 5ACC 2142
+
+ (2) If the criterion string is of the form "<subtype>:<hexdigits>" then the
+     match will match the ID as in (1), but with the added restriction that
+     only keys of the specified subtype (e.g. tpm) will be matched.  For
+     instance:
+
+       keyctl search @s asymmetric tpm:5acc2142
+
+Looking in /proc/keys, the last 8 hex digits of the key fingerprint are
+displayed, along with the subtype:
+
+       1a39e171 I-----     1 perm 3f010000     0     0 asymmetri modsign.0: DSA 5acc2142 []
+
+
+=========================
+ACCESSING ASYMMETRIC KEYS
+=========================
+
+For general access to asymmetric keys from within the kernel, the following
+inclusion is required:
+
+       #include <crypto/public_key.h>
+
+This gives access to functions for dealing with asymmetric / public keys.
+Three enums are defined there for representing public-key cryptography
+algorithms:
+
+       enum pkey_algo
+
+digest algorithms used by those:
+
+       enum pkey_hash_algo
+
+and key identifier representations:
+
+       enum pkey_id_type
+
+Note that the key type representation types are required because key
+identifiers from different standards aren't necessarily compatible.  For
+instance, PGP generates key identifiers by hashing the key data plus some
+PGP-specific metadata, whereas X.509 has arbitrary certificate identifiers.
+
+The operations defined upon a key are:
+
+ (1) Signature verification.
+
+Other operations are possible (such as encryption) with the same key data
+required for verification, but not currently supported, and others
+(eg. decryption and signature generation) require extra key data.
+
+
+SIGNATURE VERIFICATION
+----------------------
+
+An operation is provided to perform cryptographic signature verification, using
+an asymmetric key to provide or to provide access to the public key.
+
+       int verify_signature(const struct key *key,
+                            const struct public_key_signature *sig);
+
+The caller must have already obtained the key from some source and can then use
+it to check the signature.  The caller must have parsed the signature and
+transferred the relevant bits to the structure pointed to by sig.
+
+       struct public_key_signature {
+               u8 *digest;
+               u8 digest_size;
+               enum pkey_hash_algo pkey_hash_algo : 8;
+               u8 nr_mpi;
+               union {
+                       MPI mpi[2];
+                       ...
+               };
+       };
+
+The algorithm used must be noted in sig->pkey_hash_algo, and all the MPIs that
+make up the actual signature must be stored in sig->mpi[] and the count of MPIs
+placed in sig->nr_mpi.
+
+In addition, the data must have been digested by the caller and the resulting
+hash must be pointed to by sig->digest and the size of the hash be placed in
+sig->digest_size.
+
+The function will return 0 upon success or -EKEYREJECTED if the signature
+doesn't match.
+
+The function may also return -ENOTSUPP if an unsupported public-key algorithm
+or public-key/hash algorithm combination is specified or the key doesn't
+support the operation; -EBADMSG or -ERANGE if some of the parameters have weird
+data; or -ENOMEM if an allocation can't be performed.  -EINVAL can be returned
+if the key argument is the wrong type or is incompletely set up.
+
+
+=======================
+ASYMMETRIC KEY SUBTYPES
+=======================
+
+Asymmetric keys have a subtype that defines the set of operations that can be
+performed on that key and that determines what data is attached as the key
+payload.  The payload format is entirely at the whim of the subtype.
+
+The subtype is selected by the key data parser and the parser must initialise
+the data required for it.  The asymmetric key retains a reference on the
+subtype module.
+
+The subtype definition structure can be found in:
+
+       #include <keys/asymmetric-subtype.h>
+
+and looks like the following:
+
+       struct asymmetric_key_subtype {
+               struct module           *owner;
+               const char              *name;
+
+               void (*describe)(const struct key *key, struct seq_file *m);
+               void (*destroy)(void *payload);
+               int (*verify_signature)(const struct key *key,
+                                       const struct public_key_signature *sig);
+       };
+
+Asymmetric keys point to this with their type_data[0] member.
+
+The owner and name fields should be set to the owning module and the name of
+the subtype.  Currently, the name is only used for print statements.
+
+There are a number of operations defined by the subtype:
+
+ (1) describe().
+
+     Mandatory.  This allows the subtype to display something in /proc/keys
+     against the key.  For instance the name of the public key algorithm type
+     could be displayed.  The key type will display the tail of the key
+     identity string after this.
+
+ (2) destroy().
+
+     Mandatory.  This should free the memory associated with the key.  The
+     asymmetric key will look after freeing the fingerprint and releasing the
+     reference on the subtype module.
+
+ (3) verify_signature().
+
+     Optional.  These are the entry points for the key usage operations.
+     Currently there is only the one defined.  If not set, the caller will be
+     given -ENOTSUPP.  The subtype may do anything it likes to implement an
+     operation, including offloading to hardware.
+
+
+==========================
+INSTANTIATION DATA PARSERS
+==========================
+
+The asymmetric key type doesn't generally want to store or to deal with a raw
+blob of data that holds the key data.  It would have to parse it and error
+check it each time it wanted to use it.  Further, the contents of the blob may
+have various checks that can be performed on it (eg. self-signatures, validity
+dates) and may contain useful data about the key (identifiers, capabilities).
+
+Also, the blob may represent a pointer to some hardware containing the key
+rather than the key itself.
+
+Examples of blob formats for which parsers could be implemented include:
+
+ - OpenPGP packet stream [RFC 4880].
+ - X.509 ASN.1 stream.
+ - Pointer to TPM key.
+ - Pointer to UEFI key.
+
+During key instantiation each parser in the list is tried until one doesn't
+return -EBADMSG.
+
+The parser definition structure can be found in:
+
+       #include <keys/asymmetric-parser.h>
+
+and looks like the following:
+
+       struct asymmetric_key_parser {
+               struct module   *owner;
+               const char      *name;
+
+               int (*parse)(struct key_preparsed_payload *prep);
+       };
+
+The owner and name fields should be set to the owning module and the name of
+the parser.
+
+There is currently only a single operation defined by the parser, and it is
+mandatory:
+
+ (1) parse().
+
+     This is called to preparse the key from the key creation and update paths.
+     In particular, it is called during the key creation _before_ a key is
+     allocated, and as such, is permitted to provide the key's description in
+     the case that the caller declines to do so.
+
+     The caller passes a pointer to the following struct with all of the fields
+     cleared, except for data, datalen and quotalen [see
+     Documentation/security/keys.txt].
+
+       struct key_preparsed_payload {
+               char            *description;
+               void            *type_data[2];
+               void            *payload;
+               const void      *data;
+               size_t          datalen;
+               size_t          quotalen;
+       };
+
+     The instantiation data is in a blob pointed to by data and is datalen in
+     size.  The parse() function is not permitted to change these two values at
+     all, and shouldn't change any of the other values _unless_ they are
+     recognise the blob format and will not return -EBADMSG to indicate it is
+     not theirs.
+
+     If the parser is happy with the blob, it should propose a description for
+     the key and attach it to ->description, ->type_data[0] should be set to
+     point to the subtype to be used, ->payload should be set to point to the
+     initialised data for that subtype, ->type_data[1] should point to a hex
+     fingerprint and quotalen should be updated to indicate how much quota this
+     key should account for.
+
+     When clearing up, the data attached to ->type_data[1] and ->description
+     will be kfree()'d and the data attached to ->payload will be passed to the
+     subtype's ->destroy() method to be disposed of.  A module reference for
+     the subtype pointed to by ->type_data[0] will be put.
+
+
+     If the data format is not recognised, -EBADMSG should be returned.  If it
+     is recognised, but the key cannot for some reason be set up, some other
+     negative error code should be returned.  On success, 0 should be returned.
+
+     The key's fingerprint string may be partially matched upon.  For a
+     public-key algorithm such as RSA and DSA this will likely be a printable
+     hex version of the key's fingerprint.
+
+Functions are provided to register and unregister parsers:
+
+       int register_asymmetric_key_parser(struct asymmetric_key_parser *parser);
+       void unregister_asymmetric_key_parser(struct asymmetric_key_parser *subtype);
+
+Parsers may not have the same name.  The names are otherwise only used for
+displaying in debugging messages.