jpayne@68: .\" jpayne@68: .\" Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. jpayne@68: .\" Written by David Howells (dhowells@redhat.com) jpayne@68: .\" jpayne@68: .\" This program is free software; you can redistribute it and/or jpayne@68: .\" modify it under the terms of the GNU General Public Licence jpayne@68: .\" as published by the Free Software Foundation; either version jpayne@68: .\" 2 of the Licence, or (at your option) any later version. jpayne@68: .\" jpayne@68: .TH ASYMMETRIC-KEY 7 "8 Nov 2018" Linux "Asymmetric Kernel Key Type" jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH NAME jpayne@68: asymmetric \- Kernel key type for holding asymmetric keys jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH OVERVIEW jpayne@68: .PP jpayne@68: A kernel key of jpayne@68: .B asymmetric jpayne@68: type acts as a handle to an asymmetric key as used for public-key jpayne@68: cryptography. The key material itself may be held inside the kernel or it may jpayne@68: be held in hardware with operations being offloaded. This prevents direct jpayne@68: user access to the cryptographic material. jpayne@68: .PP jpayne@68: Keys may be any asymmetric type (RSA, ECDSA, ...) and may have both private and jpayne@68: public components present or just the public component. jpayne@68: .PP jpayne@68: Asymmetric keys can be made use of by both the kernel and userspace. The jpayne@68: kernel can make use of them for module signature verification and kexec image jpayne@68: verification for example. Userspace is provided with a set of jpayne@68: .BR keyctl ( KEYCTL_PKEY_* ) jpayne@68: calls for querying and using the key. These are wrapped by jpayne@68: .B libkeyutils jpayne@68: as functions named jpayne@68: .BR keyctl_pkey_*() . jpayne@68: .PP jpayne@68: An asymmetric-type key can be loaded by the keyctl utility using a command jpayne@68: line like: jpayne@68: .PP jpayne@68: .in +4n jpayne@68: .EX jpayne@68: openssl x509 -in key.x509 -outform DER | jpayne@68: keyctl padd asymmetric foo @s jpayne@68: .EE jpayne@68: .in jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH DESCRIPTION jpayne@68: .PP jpayne@68: The asymmetric-type key can be viewed as a container that comprises of a jpayne@68: number of components: jpayne@68: .TP jpayne@68: Parsers jpayne@68: The asymmetric key parsers attempt to identify the content of the payload blob jpayne@68: and extract useful data from it with which to instantiate the key. The parser jpayne@68: is only used when adding, instantiating or updating a key and isn't thereafter jpayne@68: associated with the key. jpayne@68: .IP jpayne@68: Available parsers include ones that can deal with jpayne@68: .RB "DER-encoded " X.509 ", DER-encoded " PKCS#8 " and DER-encoded " TPM "-wrapped blobs." jpayne@68: .TP jpayne@68: Public and private keys jpayne@68: These are the cryptographic components of the key pair. The public half jpayne@68: should always be available, but the private half might not be. What jpayne@68: operations are available can be queried, as can the size of the key. The key jpayne@68: material may or may not actually reside in the kernel. jpayne@68: .TP jpayne@68: Identifiers jpayne@68: In addition to the normal key description (which can be generated by the jpayne@68: parser), a number of supplementary identifiers may be available that can be jpayne@68: searched for. These may be obtained, for example, by hashing the public key jpayne@68: material or from the subjectKeyIdentifier in an X.509 certificate. jpayne@68: .IP jpayne@68: Identifier-based searches are selected by passing as the description to jpayne@68: .BR keyctl_search () jpayne@68: a string constructed of hex characters prefixed with either "id:" or "ex:". jpayne@68: The "id:" prefix indicates that a partial tail match is permissible whereas jpayne@68: "ex:" requires an exact match on the full string. The hex characters indicate jpayne@68: the data to match. jpayne@68: .TP jpayne@68: Subtype jpayne@68: This is the driver inside the kernel that accesses the key material and jpayne@68: performs operations on it. It might be entirely software-based or it may jpayne@68: offload the operations to a hardware key store, such as a jpayne@68: .BR TPM . jpayne@68: .PP jpayne@68: Note that expiry times from the payload are ignored as these patches may be jpayne@68: used during boot before the system clock is set. jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH PARSERS jpayne@68: .PP jpayne@68: The asymmetric key parsers can handle keys in a number of forms: jpayne@68: .TP jpayne@68: \fBX.509\fP jpayne@68: DER-encoded X.509 certificates can be accepted. Two identifiers are jpayne@68: constructed: one from from the certificate issuer and serial number and the jpayne@68: other from the subjectKeyIdentifier, if present. If left blank, the key jpayne@68: description will be filled in from the subject field plus either the jpayne@68: subjectKeyIdentifier or the serialNumber. Only the public key is filled in jpayne@68: and only the encrypt and verify operations are supported. jpayne@68: .IP jpayne@68: The signature on the X.509 certificate may be checked by the keyring it is jpayne@68: being added to and it may also be rejected if the key is blacklisted. jpayne@68: .TP jpayne@68: \fBPKCS#8\fP jpayne@68: Unencrypted DER-encoded PKCS#8 key data containers can be accepted. Currently jpayne@68: no identifiers are constructed. The private key and the public key are loaded jpayne@68: from the PKCS#8 blobs. Encrypted PKCS#8 is not currently supported. jpayne@68: .TP jpayne@68: \fBTPM-Wrapped keys\fP jpayne@68: DER-encoded TPM-wrapped TSS key blobs can be accepted. Currently no jpayne@68: identifiers are constructed. The public key is extracted from the blob but jpayne@68: the private key is expected to be resident in the TPM. Encryption and jpayne@68: signature verification is done in software, but decryption and signing are jpayne@68: offloaded to the TPM so as not to expose the private key. jpayne@68: .IP jpayne@68: This parser only supports TPM-1.2 wrappings and enc=pkcs1 encoding type. It jpayne@68: also uses a hard-coded null SRK password; password-protected SRKs are not yet jpayne@68: supported. jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH USERSPACE API jpayne@68: .PP jpayne@68: In addition to the standard keyutils library functions, such as jpayne@68: .IR keyctl_update (), jpayne@68: there are five calls specific to the asymmetric key type (though they are open jpayne@68: to being used by other key types also): jpayne@68: .PP jpayne@68: .RS jpayne@68: \fIkeyctl_pkey_query\fP() jpayne@68: .br jpayne@68: \fIkeyctl_pkey_encrypt\fP() jpayne@68: .br jpayne@68: \fIkeyctl_pkey_decrypt\fP() jpayne@68: .br jpayne@68: \fIkeyctl_pkey_sign\fP() jpayne@68: .br jpayne@68: \fIkeyctl_pkey_verify\fP() jpayne@68: .RE jpayne@68: .PP jpayne@68: The query function can be used to retrieve information about an asymmetric key, jpayne@68: such as the key size, the amount of space required by buffers for the other jpayne@68: operations and which operations are actually supported. jpayne@68: .PP jpayne@68: The other operations form two pairs: encrypt/decrypt and create/verify jpayne@68: signature. Not all of these operations will necessarily be available; jpayne@68: typically, encrypt and verify only require the public key to be available jpayne@68: whereas decrypt and sign require the private key as well. jpayne@68: .PP jpayne@68: All of these operations take an information string parameter that supplies jpayne@68: additional information such as encoding type/form and the password(s) needed to jpayne@68: unlock/unwrap the key. This takes the form of a comma-separated list of jpayne@68: "key[=value]" pairs, the exact set of which depends on the subtype driver used jpayne@68: by a particular key. jpayne@68: .PP jpayne@68: Available parameters include: jpayne@68: .TP jpayne@68: enc= jpayne@68: The encoding type for use in an encrypted blob or a signature. An example jpayne@68: might be "enc=pkcs1". jpayne@68: .TP jpayne@68: hash= jpayne@68: The name of the hash algorithm that was used to digest the data to be signed. jpayne@68: Note that this is only used to construct any encoding that is used in a jpayne@68: signature. The data to be signed or verified must have been parsed by the jpayne@68: caller and the hash passed to \fIkeyctl_pkey_sign\fP() or jpayne@68: \fIkeyctl_pkey_verify\fP() beforehand. An example might be "hash=sha256". jpayne@68: .PP jpayne@68: Note that not all parameters are used by all subtypes. jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH RESTRICTED KEYRINGS jpayne@68: .PP jpayne@68: An additional keyutils function, jpayne@68: .IR keyctl_restrict_keyring (), jpayne@68: can be used to gate a keyring so that a new key can only be added to the jpayne@68: affected keyring if (a) it's an asymmetric key, (b) it's validly signed by a jpayne@68: key in some appropriate keyring and (c) it's not blacklisted. jpayne@68: .PP jpayne@68: .in +4n jpayne@68: .EX jpayne@68: keyctl_restrict_keyring(keyring, "asymmetric", jpayne@68: "key_or_keyring:[:chain]"); jpayne@68: .EE jpayne@68: .in jpayne@68: .PP jpayne@68: Where \fI\fP is the ID of a key or a ring of keys that act as the jpayne@68: authority to permit a new key to be added to the keyring. The \fIchain\fP flag jpayne@68: indicates that keys that have been added to the keyring may also be used to jpayne@68: verify new keys. Authorising keys must themselves be asymmetric-type keys that jpayne@68: can be used to do a signature verification on the key being added. jpayne@68: .PP jpayne@68: Note that there are various system keyrings visible to the root user that may jpayne@68: permit additional keys to be added. These are typically gated by keys that jpayne@68: already exist, preventing unauthorised keys from being used for such things as jpayne@68: module verification. jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH BLACKLISTING jpayne@68: .PP jpayne@68: When the attempt is made to add a key to the kernel, a hash of the public key jpayne@68: is checked against the jpayne@68: .BR blacklist. jpayne@68: This is a system keyring named jpayne@68: .B .blacklist jpayne@68: and contains keys of type jpayne@68: .BR blacklist . jpayne@68: If the blacklist contains a key whose description matches the hash of the new jpayne@68: key, that new key will be rejected with error jpayne@68: .BR EKEYREJECTED . jpayne@68: .PP jpayne@68: The blacklist keyring may be loaded from multiple sources, including a list jpayne@68: compiled into the kernel and the UEFI jpayne@68: .B dbx jpayne@68: variable. Further hashes may also be blacklisted by the administrator. Note jpayne@68: that blacklisting is not retroactive, so an asymmetric key that is already on jpayne@68: the system cannot be blacklisted by adding a matching blacklist entry later. jpayne@68: .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" jpayne@68: .SH VERSIONS jpayne@68: The jpayne@68: .B asymmetric jpayne@68: key type first appeared in v3.7 of the Linux kernel, the jpayne@68: .B restriction jpayne@68: function in v4.11 and the jpayne@68: .B public key operations jpayne@68: in v4.20. jpayne@68: .SH SEE ALSO jpayne@68: .ad l jpayne@68: .nh jpayne@68: .BR keyctl (1), jpayne@68: .BR add_key (2), jpayne@68: .BR keyctl (3), jpayne@68: .BR keyctl_pkey_encrypt (3), jpayne@68: .BR keyctl_pkey_query (3), jpayne@68: .BR keyctl_pkey_sign (3), jpayne@68: .BR keyrings (7), jpayne@68: .BR keyutils (7)