| 		============================================= | 
 | 		ASYMMETRIC / PUBLIC-KEY CRYPTOGRAPHY KEY TYPE | 
 | 		============================================= | 
 |  | 
 | Contents: | 
 |  | 
 |   - Overview. | 
 |   - Key identification. | 
 |   - Accessing asymmetric keys. | 
 |     - Signature verification. | 
 |   - Asymmetric key subtypes. | 
 |   - Instantiation data parsers. | 
 |   - Keyring link restrictions. | 
 |  | 
 |  | 
 | ======== | 
 | 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 asymmetric 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 (*query)(const struct kernel_pkey_params *params, | 
 | 			     struct kernel_pkey_query *info); | 
 | 		int (*eds_op)(struct kernel_pkey_params *params, | 
 | 			      const void *in, void *out); | 
 | 		int (*verify_signature)(const struct key *key, | 
 | 					const struct public_key_signature *sig); | 
 | 	}; | 
 |  | 
 | Asymmetric keys point to this with their payload[asym_subtype] 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) query(). | 
 |  | 
 |      Mandatory.  This is a function for querying the capabilities of a key. | 
 |  | 
 |  (4) eds_op(). | 
 |  | 
 |      Optional.  This is the entry point for the encryption, decryption and | 
 |      signature creation operations (which are distinguished by the operation ID | 
 |      in the parameter struct).  The subtype may do anything it likes to | 
 |      implement an operation, including offloading to hardware. | 
 |  | 
 |  (5) verify_signature(). | 
 |  | 
 |      Optional.  This is the entry point for signature verification.  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. | 
 |  - PKCS#8 private key [RFC 5208]. | 
 |  - PKCS#5 encrypted private key [RFC 2898]. | 
 |  | 
 | 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/core.rst]. | 
 |  | 
 | 	struct key_preparsed_payload { | 
 | 		char		*description; | 
 | 		void		*payload[4]; | 
 | 		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, ->payload[asym_subtype] should be | 
 |      set to point to the subtype to be used, ->payload[asym_crypto] should be | 
 |      set to point to the initialised data for that subtype, | 
 |      ->payload[asym_key_ids] should point to one or more hex fingerprints and | 
 |      quotalen should be updated to indicate how much quota this key should | 
 |      account for. | 
 |  | 
 |      When clearing up, the data attached to ->payload[asym_key_ids] and | 
 |      ->description will be kfree()'d and the data attached to | 
 |      ->payload[asm_crypto] will be passed to the subtype's ->destroy() method | 
 |      to be disposed of.  A module reference for the subtype pointed to by | 
 |      ->payload[asym_subtype] 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. | 
 |  | 
 |  | 
 | ========================= | 
 | KEYRING LINK RESTRICTIONS | 
 | ========================= | 
 |  | 
 | Keyrings created from userspace using add_key can be configured to check the | 
 | signature of the key being linked.  Keys without a valid signature are not | 
 | allowed to link. | 
 |  | 
 | Several restriction methods are available: | 
 |  | 
 |  (1) Restrict using the kernel builtin trusted keyring | 
 |  | 
 |      - Option string used with KEYCTL_RESTRICT_KEYRING: | 
 |        - "builtin_trusted" | 
 |  | 
 |      The kernel builtin trusted keyring will be searched for the signing key. | 
 |      If the builtin trusted keyring is not configured, all links will be | 
 |      rejected.  The ca_keys kernel parameter also affects which keys are used | 
 |      for signature verification. | 
 |  | 
 |  (2) Restrict using the kernel builtin and secondary trusted keyrings | 
 |  | 
 |      - Option string used with KEYCTL_RESTRICT_KEYRING: | 
 |        - "builtin_and_secondary_trusted" | 
 |  | 
 |      The kernel builtin and secondary trusted keyrings will be searched for the | 
 |      signing key.  If the secondary trusted keyring is not configured, this | 
 |      restriction will behave like the "builtin_trusted" option.  The ca_keys | 
 |      kernel parameter also affects which keys are used for signature | 
 |      verification. | 
 |  | 
 |  (3) Restrict using a separate key or keyring | 
 |  | 
 |      - Option string used with KEYCTL_RESTRICT_KEYRING: | 
 |        - "key_or_keyring:<key or keyring serial number>[:chain]" | 
 |  | 
 |      Whenever a key link is requested, the link will only succeed if the key | 
 |      being linked is signed by one of the designated keys.  This key may be | 
 |      specified directly by providing a serial number for one asymmetric key, or | 
 |      a group of keys may be searched for the signing key by providing the | 
 |      serial number for a keyring. | 
 |  | 
 |      When the "chain" option is provided at the end of the string, the keys | 
 |      within the destination keyring will also be searched for signing keys. | 
 |      This allows for verification of certificate chains by adding each | 
 |      certificate in order (starting closest to the root) to a keyring.  For | 
 |      instance, one keyring can be populated with links to a set of root | 
 |      certificates, with a separate, restricted keyring set up for each | 
 |      certificate chain to be validated: | 
 |  | 
 | 	# Create and populate a keyring for root certificates | 
 | 	root_id=`keyctl add keyring root-certs "" @s` | 
 | 	keyctl padd asymmetric "" $root_id < root1.cert | 
 | 	keyctl padd asymmetric "" $root_id < root2.cert | 
 |  | 
 | 	# Create and restrict a keyring for the certificate chain | 
 | 	chain_id=`keyctl add keyring chain "" @s` | 
 | 	keyctl restrict_keyring $chain_id asymmetric key_or_keyring:$root_id:chain | 
 |  | 
 | 	# Attempt to add each certificate in the chain, starting with the | 
 | 	# certificate closest to the root. | 
 | 	keyctl padd asymmetric "" $chain_id < intermediateA.cert | 
 | 	keyctl padd asymmetric "" $chain_id < intermediateB.cert | 
 | 	keyctl padd asymmetric "" $chain_id < end-entity.cert | 
 |  | 
 |      If the final end-entity certificate is successfully added to the "chain" | 
 |      keyring, we can be certain that it has a valid signing chain going back to | 
 |      one of the root certificates. | 
 |  | 
 |      A single keyring can be used to verify a chain of signatures by | 
 |      restricting the keyring after linking the root certificate: | 
 |  | 
 | 	# Create a keyring for the certificate chain and add the root | 
 | 	chain2_id=`keyctl add keyring chain2 "" @s` | 
 | 	keyctl padd asymmetric "" $chain2_id < root1.cert | 
 |  | 
 | 	# Restrict the keyring that already has root1.cert linked.  The cert | 
 | 	# will remain linked by the keyring. | 
 | 	keyctl restrict_keyring $chain2_id asymmetric key_or_keyring:0:chain | 
 |  | 
 | 	# Attempt to add each certificate in the chain, starting with the | 
 | 	# certificate closest to the root. | 
 | 	keyctl padd asymmetric "" $chain2_id < intermediateA.cert | 
 | 	keyctl padd asymmetric "" $chain2_id < intermediateB.cert | 
 | 	keyctl padd asymmetric "" $chain2_id < end-entity.cert | 
 |  | 
 |      If the final end-entity certificate is successfully added to the "chain2" | 
 |      keyring, we can be certain that there is a valid signing chain going back | 
 |      to the root certificate that was added before the keyring was restricted. | 
 |  | 
 |  | 
 | In all of these cases, if the signing key is found the signature of the key to | 
 | be linked will be verified using the signing key.  The requested key is added | 
 | to the keyring only if the signature is successfully verified.  -ENOKEY is | 
 | returned if the parent certificate could not be found, or -EKEYREJECTED is | 
 | returned if the signature check fails or the key is blacklisted.  Other errors | 
 | may be returned if the signature check could not be performed. |