Skip to content

Commit

Permalink
Merge branch 'next-keys2' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/jmorris/linux-security

Pull keys updates from James Morris:
 "Provide five new operations in the key_type struct that can be used to
  provide access to asymmetric key operations. These will be implemented
  for the asymmetric key type in a later patch and may refer to a key
  retained in RAM by the kernel or a key retained in crypto hardware.

     int (*asym_query)(const struct kernel_pkey_params *params,
                       struct kernel_pkey_query *info);
     int (*asym_eds_op)(struct kernel_pkey_params *params,
                        const void *in, void *out);
     int (*asym_verify_signature)(struct kernel_pkey_params *params,
                                  const void *in, const void *in2);

  Since encrypt, decrypt and sign are identical in their interfaces,
  they're rolled together in the asym_eds_op() operation and there's an
  operation ID in the params argument to distinguish them.

  Verify is different in that we supply the data and the signature
  instead and get an error value (or 0) as the only result on the
  expectation that this may well be how a hardware crypto device may
  work"

* 'next-keys2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (22 commits)
  KEYS: asym_tpm: Add support for the sign operation [ver #2]
  KEYS: asym_tpm: Implement tpm_sign [ver #2]
  KEYS: asym_tpm: Implement signature verification [ver #2]
  KEYS: asym_tpm: Implement the decrypt operation [ver #2]
  KEYS: asym_tpm: Implement tpm_unbind [ver #2]
  KEYS: asym_tpm: Add loadkey2 and flushspecific [ver #2]
  KEYS: Move trusted.h to include/keys [ver #2]
  KEYS: trusted: Expose common functionality [ver #2]
  KEYS: asym_tpm: Implement encryption operation [ver #2]
  KEYS: asym_tpm: Implement pkey_query [ver #2]
  KEYS: Add parser for TPM-based keys [ver #2]
  KEYS: asym_tpm: extract key size & public key [ver #2]
  KEYS: asym_tpm: add skeleton for asym_tpm [ver #2]
  crypto: rsa-pkcs1pad: Allow hash to be optional [ver #2]
  KEYS: Implement PKCS#8 RSA Private Key parser [ver #2]
  KEYS: Implement encrypt, decrypt and sign for software asymmetric key [ver #2]
  KEYS: Allow the public_key struct to hold a private key [ver #2]
  KEYS: Provide software public key query function [ver #2]
  KEYS: Make the X.509 and PKCS7 parsers supply the sig encoding type [ver #2]
  KEYS: Provide missing asymmetric key subops for new key type ops [ver #2]
  ...
  • Loading branch information
torvalds committed Nov 1, 2018
2 parents 7260935 + 64ae16d commit baa888d
Show file tree
Hide file tree
Showing 29 changed files with 2,516 additions and 61 deletions.
26 changes: 21 additions & 5 deletions Documentation/crypto/asymmetric-keys.txt
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ and looks like the following:

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);
};
Expand All @@ -207,12 +211,22 @@ There are a number of operations defined by the subtype:
asymmetric key will look after freeing the fingerprint and releasing the
reference on the subtype module.

(3) verify_signature().
(3) query().

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.
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.


==========================
Expand All @@ -234,6 +248,8 @@ Examples of blob formats for which parsers could be implemented include:
- 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.
Expand Down
217 changes: 217 additions & 0 deletions Documentation/security/keys/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ The keyctl syscall functions are:
and either the buffer length or the OtherInfo length exceeds the
allowed length.


* Restrict keyring linkage::

long keyctl(KEYCTL_RESTRICT_KEYRING, key_serial_t keyring,
Expand Down Expand Up @@ -890,6 +891,116 @@ The keyctl syscall functions are:
applicable to the asymmetric key type.


* Query an asymmetric key::

long keyctl(KEYCTL_PKEY_QUERY,
key_serial_t key_id, unsigned long reserved,
struct keyctl_pkey_query *info);
Get information about an asymmetric key. The information is returned in
the keyctl_pkey_query struct::

__u32 supported_ops;
__u32 key_size;
__u16 max_data_size;
__u16 max_sig_size;
__u16 max_enc_size;
__u16 max_dec_size;
__u32 __spare[10];

``supported_ops`` contains a bit mask of flags indicating which ops are
supported. This is constructed from a bitwise-OR of::

KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

``key_size`` indicated the size of the key in bits.

``max_*_size`` indicate the maximum sizes in bytes of a blob of data to be
signed, a signature blob, a blob to be encrypted and a blob to be
decrypted.

``__spare[]`` must be set to 0. This is intended for future use to hand
over one or more passphrases needed unlock a key.

If successful, 0 is returned. If the key is not an asymmetric key,
EOPNOTSUPP is returned.


* Encrypt, decrypt, sign or verify a blob using an asymmetric key::

long keyctl(KEYCTL_PKEY_ENCRYPT,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);
long keyctl(KEYCTL_PKEY_DECRYPT,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);
long keyctl(KEYCTL_PKEY_SIGN,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
void *out);
long keyctl(KEYCTL_PKEY_VERIFY,
const struct keyctl_pkey_params *params,
const char *info,
const void *in,
const void *in2);
Use an asymmetric key to perform a public-key cryptographic operation a
blob of data. For encryption and verification, the asymmetric key may
only need the public parts to be available, but for decryption and signing
the private parts are required also.

The parameter block pointed to by params contains a number of integer
values::

__s32 key_id;
__u32 in_len;
__u32 out_len;
__u32 in2_len;

``key_id`` is the ID of the asymmetric key to be used. ``in_len`` and
``in2_len`` indicate the amount of data in the in and in2 buffers and
``out_len`` indicates the size of the out buffer as appropriate for the
above operations.

For a given operation, the in and out buffers are used as follows::

Operation ID in,in_len out,out_len in2,in2_len
======================= =============== =============== ===============
KEYCTL_PKEY_ENCRYPT Raw data Encrypted data -
KEYCTL_PKEY_DECRYPT Encrypted data Raw data -
KEYCTL_PKEY_SIGN Raw data Signature -
KEYCTL_PKEY_VERIFY Raw data - Signature

``info`` is a string of key=value pairs that supply supplementary
information. These include:

``enc=<encoding>`` The encoding of the encrypted/signature blob. This
can be "pkcs1" for RSASSA-PKCS1-v1.5 or
RSAES-PKCS1-v1.5; "pss" for "RSASSA-PSS"; "oaep" for
"RSAES-OAEP". If omitted or is "raw", the raw output
of the encryption function is specified.

``hash=<algo>`` If the data buffer contains the output of a hash
function and the encoding includes some indication of
which hash function was used, the hash function can be
specified with this, eg. "hash=sha256".

The ``__spare[]`` space in the parameter block must be set to 0. This is
intended, amongst other things, to allow the passing of passphrases
required to unlock a key.

If successful, encrypt, decrypt and sign all return the amount of data
written into the output buffer. Verification returns 0 on success.


Kernel Services
===============

Expand Down Expand Up @@ -1483,6 +1594,112 @@ The structure has a number of fields, some of which are mandatory:
attempted key link operation. If there is no match, -EINVAL is returned.


* ``int (*asym_eds_op)(struct kernel_pkey_params *params,
const void *in, void *out);``
``int (*asym_verify_signature)(struct kernel_pkey_params *params,
const void *in, const void *in2);``

These methods are optional. If provided the first allows a key to be
used to encrypt, decrypt or sign a blob of data, and the second allows a
key to verify a signature.

In all cases, the following information is provided in the params block::

struct kernel_pkey_params {
struct key *key;
const char *encoding;
const char *hash_algo;
char *info;
__u32 in_len;
union {
__u32 out_len;
__u32 in2_len;
};
enum kernel_pkey_operation op : 8;
};
This includes the key to be used; a string indicating the encoding to use
(for instance, "pkcs1" may be used with an RSA key to indicate
RSASSA-PKCS1-v1.5 or RSAES-PKCS1-v1.5 encoding or "raw" if no encoding);
the name of the hash algorithm used to generate the data for a signature
(if appropriate); the sizes of the input and output (or second input)
buffers; and the ID of the operation to be performed.

For a given operation ID, the input and output buffers are used as
follows::

Operation ID in,in_len out,out_len in2,in2_len
======================= =============== =============== ===============
kernel_pkey_encrypt Raw data Encrypted data -
kernel_pkey_decrypt Encrypted data Raw data -
kernel_pkey_sign Raw data Signature -
kernel_pkey_verify Raw data - Signature

asym_eds_op() deals with encryption, decryption and signature creation as
specified by params->op. Note that params->op is also set for
asym_verify_signature().

Encrypting and signature creation both take raw data in the input buffer
and return the encrypted result in the output buffer. Padding may have
been added if an encoding was set. In the case of signature creation,
depending on the encoding, the padding created may need to indicate the
digest algorithm - the name of which should be supplied in hash_algo.

Decryption takes encrypted data in the input buffer and returns the raw
data in the output buffer. Padding will get checked and stripped off if
an encoding was set.

Verification takes raw data in the input buffer and the signature in the
second input buffer and checks that the one matches the other. Padding
will be validated. Depending on the encoding, the digest algorithm used
to generate the raw data may need to be indicated in hash_algo.

If successful, asym_eds_op() should return the number of bytes written
into the output buffer. asym_verify_signature() should return 0.

A variety of errors may be returned, including EOPNOTSUPP if the operation
is not supported; EKEYREJECTED if verification fails; ENOPKG if the
required crypto isn't available.


* ``int (*asym_query)(const struct kernel_pkey_params *params,
struct kernel_pkey_query *info);``

This method is optional. If provided it allows information about the
public or asymmetric key held in the key to be determined.

The parameter block is as for asym_eds_op() and co. but in_len and out_len
are unused. The encoding and hash_algo fields should be used to reduce
the returned buffer/data sizes as appropriate.

If successful, the following information is filled in::

struct kernel_pkey_query {
__u32 supported_ops;
__u32 key_size;
__u16 max_data_size;
__u16 max_sig_size;
__u16 max_enc_size;
__u16 max_dec_size;
};

The supported_ops field will contain a bitmask indicating what operations
are supported by the key, including encryption of a blob, decryption of a
blob, signing a blob and verifying the signature on a blob. The following
constants are defined for this::

KEYCTL_SUPPORTS_{ENCRYPT,DECRYPT,SIGN,VERIFY}

The key_size field is the size of the key in bits. max_data_size and
max_sig_size are the maximum raw data and signature sizes for creation and
verification of a signature; max_enc_size and max_dec_size are the maximum
raw data and signature sizes for encryption and decryption. The
max_*_size fields are measured in bytes.

If successful, 0 will be returned. If the key doesn't support this,
EOPNOTSUPP will be returned.


Request-Key Callback Service
============================

Expand Down
31 changes: 31 additions & 0 deletions crypto/asymmetric_keys/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
appropriate hash algorithms (such as SHA-1) must be available.
ENOPKG will be reported if the requisite algorithm is unavailable.

config ASYMMETRIC_TPM_KEY_SUBTYPE
tristate "Asymmetric TPM backed private key subtype"
depends on TCG_TPM
depends on TRUSTED_KEYS
select CRYPTO_HMAC
select CRYPTO_SHA1
select CRYPTO_HASH_INFO
help
This option provides support for TPM backed private key type handling.
Operations such as sign, verify, encrypt, decrypt are performed by
the TPM after the private key is loaded.

config X509_CERTIFICATE_PARSER
tristate "X.509 certificate parser"
depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
Expand All @@ -31,6 +43,25 @@ config X509_CERTIFICATE_PARSER
data and provides the ability to instantiate a crypto key from a
public key packet found inside the certificate.

config PKCS8_PRIVATE_KEY_PARSER
tristate "PKCS#8 private key parser"
depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select ASN1
select OID_REGISTRY
help
This option provides support for parsing PKCS#8 format blobs for
private key data and provides the ability to instantiate a crypto key
from that data.

config TPM_KEY_PARSER
tristate "TPM private key parser"
depends on ASYMMETRIC_TPM_KEY_SUBTYPE
select ASN1
help
This option provides support for parsing TPM format blobs for
private key data and provides the ability to instantiate a crypto key
from that data.

config PKCS7_MESSAGE_PARSER
tristate "PKCS#7 message parser"
depends on X509_CERTIFICATE_PARSER
Expand Down
25 changes: 25 additions & 0 deletions crypto/asymmetric_keys/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ asymmetric_keys-y := \
signature.o

obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
obj-$(CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE) += asym_tpm.o

#
# X.509 Certificate handling
Expand All @@ -29,6 +30,19 @@ $(obj)/x509_cert_parser.o: \
$(obj)/x509.asn1.o: $(obj)/x509.asn1.c $(obj)/x509.asn1.h
$(obj)/x509_akid.asn1.o: $(obj)/x509_akid.asn1.c $(obj)/x509_akid.asn1.h

#
# PKCS#8 private key handling
#
obj-$(CONFIG_PKCS8_PRIVATE_KEY_PARSER) += pkcs8_key_parser.o
pkcs8_key_parser-y := \
pkcs8.asn1.o \
pkcs8_parser.o

$(obj)/pkcs8_parser.o: $(obj)/pkcs8.asn1.h
$(obj)/pkcs8-asn1.o: $(obj)/pkcs8.asn1.c $(obj)/pkcs8.asn1.h

clean-files += pkcs8.asn1.c pkcs8.asn1.h

#
# PKCS#7 message handling
#
Expand Down Expand Up @@ -61,3 +75,14 @@ verify_signed_pefile-y := \

$(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h
$(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h

#
# TPM private key parsing
#
obj-$(CONFIG_TPM_KEY_PARSER) += tpm_key_parser.o
tpm_key_parser-y := \
tpm.asn1.o \
tpm_parser.o

$(obj)/tpm_parser.o: $(obj)/tpm.asn1.h
$(obj)/tpm.asn1.o: $(obj)/tpm.asn1.c $(obj)/tpm.asn1.h
Loading

0 comments on commit baa888d

Please sign in to comment.