mirror of
https://github.com/torvalds/linux
synced 2026-07-21 17:50:43 +09:00
Merge tag 'for-next-keys-7.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull keys update from Jarkko Sakkinen: "This contains only bug fixes" * tag 'for-next-keys-7.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP keys: request_key: replace BUG with return -EINVAL keys: Pin request_key_auth payload in instantiate paths keys: prevent slab cache merging for key_jar keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE) KEYS: Use acquire when reading state in keyring search keys/trusted_keys: mark 'migratable' as __ro_after_init keys: use kmalloc_flex in user_preparse KEYS: trusted: Debugging as a feature KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG KEYS: fix overflow in keyctl_pkey_params_get_2()
This commit is contained in:
@@ -7872,6 +7872,22 @@ Kernel parameters
|
||||
first trust source as a backend which is initialized
|
||||
successfully during iteration.
|
||||
|
||||
trusted.debug= [KEYS]
|
||||
Format: <bool>
|
||||
Enable trusted keys debug traces at runtime when
|
||||
CONFIG_TRUSTED_KEYS_DEBUG=y.
|
||||
|
||||
To make the traces visible after enabling the option,
|
||||
use trusted.dyndbg='+p' as needed. By convention,
|
||||
the subsystem uses pr_debug() for these traces.
|
||||
|
||||
SAFETY: The traces can leak sensitive data, so be
|
||||
cautious before enabling this. They remain inactive
|
||||
unless this parameter is set this option to a true
|
||||
value.
|
||||
|
||||
Default: false
|
||||
|
||||
trusted.rng= [KEYS]
|
||||
Format: <string>
|
||||
The RNG used to generate key material for trusted keys.
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
#define _KEYS_REQUEST_KEY_AUTH_TYPE_H
|
||||
|
||||
#include <linux/key.h>
|
||||
#include <linux/refcount.h>
|
||||
|
||||
/*
|
||||
* Authorisation record for request_key().
|
||||
*/
|
||||
struct request_key_auth {
|
||||
struct rcu_head rcu;
|
||||
refcount_t usage;
|
||||
struct key *target_key;
|
||||
struct key *dest_keyring;
|
||||
const struct cred *cred;
|
||||
|
||||
@@ -83,18 +83,21 @@ struct trusted_key_source {
|
||||
|
||||
extern struct key_type key_type_trusted;
|
||||
|
||||
#define TRUSTED_DEBUG 0
|
||||
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
|
||||
extern bool trusted_debug;
|
||||
|
||||
#if TRUSTED_DEBUG
|
||||
static inline void dump_payload(struct trusted_key_payload *p)
|
||||
{
|
||||
pr_info("key_len %d\n", p->key_len);
|
||||
print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
|
||||
16, 1, p->key, p->key_len, 0);
|
||||
pr_info("bloblen %d\n", p->blob_len);
|
||||
print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
|
||||
16, 1, p->blob, p->blob_len, 0);
|
||||
pr_info("migratable %d\n", p->migratable);
|
||||
if (!trusted_debug)
|
||||
return;
|
||||
|
||||
pr_debug("key_len %d\n", p->key_len);
|
||||
print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
|
||||
16, 1, p->key, p->key_len, 0);
|
||||
pr_debug("bloblen %d\n", p->blob_len);
|
||||
print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
|
||||
16, 1, p->blob, p->blob_len, 0);
|
||||
pr_debug("migratable %d\n", p->migratable);
|
||||
}
|
||||
#else
|
||||
static inline void dump_payload(struct trusted_key_payload *p)
|
||||
|
||||
@@ -87,7 +87,6 @@ config ENCRYPTED_KEYS
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_CBC
|
||||
select CRYPTO_LIB_SHA256
|
||||
select CRYPTO_RNG
|
||||
help
|
||||
This option provides support for create/encrypting/decrypting keys
|
||||
in the kernel. Encrypted keys are instantiated using kernel
|
||||
|
||||
@@ -343,9 +343,9 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
|
||||
return -ENOMEM;
|
||||
|
||||
if (key_type)
|
||||
strcpy(derived_buf, "AUTH_KEY");
|
||||
strscpy(derived_buf, "AUTH_KEY", HASH_SIZE);
|
||||
else
|
||||
strcpy(derived_buf, "ENC_KEY");
|
||||
strscpy(derived_buf, "ENC_KEY", HASH_SIZE);
|
||||
|
||||
memcpy(derived_buf + strlen(derived_buf) + 1, master_key,
|
||||
master_keylen);
|
||||
|
||||
@@ -208,6 +208,8 @@ extern struct key *request_key_auth_new(struct key *target,
|
||||
const void *callout_info,
|
||||
size_t callout_len,
|
||||
struct key *dest_keyring);
|
||||
struct request_key_auth *request_key_auth_get(struct key *authkey);
|
||||
void request_key_auth_put(struct request_key_auth *rka);
|
||||
|
||||
extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
|
||||
|
||||
|
||||
@@ -1275,7 +1275,7 @@ void __init key_init(void)
|
||||
{
|
||||
/* allocate a slab in which we can store keys */
|
||||
key_jar = kmem_cache_create("key_jar", sizeof(struct key),
|
||||
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
|
||||
0, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_NO_MERGE, NULL);
|
||||
|
||||
/* add the special key types */
|
||||
list_add_tail(&key_type_keyring.link, &key_types_list);
|
||||
|
||||
@@ -1197,9 +1197,13 @@ static long keyctl_instantiate_key_common(key_serial_t id,
|
||||
if (!instkey)
|
||||
goto error;
|
||||
|
||||
rka = instkey->payload.data[0];
|
||||
if (rka->target_key->serial != id)
|
||||
rka = request_key_auth_get(instkey);
|
||||
if (!rka) {
|
||||
ret = -EKEYREVOKED;
|
||||
goto error;
|
||||
}
|
||||
if (rka->target_key->serial != id)
|
||||
goto error_put_rka;
|
||||
|
||||
/* pull the payload in if one was supplied */
|
||||
payload = NULL;
|
||||
@@ -1208,7 +1212,7 @@ static long keyctl_instantiate_key_common(key_serial_t id,
|
||||
ret = -ENOMEM;
|
||||
payload = kvmalloc(plen, GFP_KERNEL);
|
||||
if (!payload)
|
||||
goto error;
|
||||
goto error_put_rka;
|
||||
|
||||
ret = -EFAULT;
|
||||
if (!copy_from_iter_full(payload, plen, from))
|
||||
@@ -1234,6 +1238,8 @@ static long keyctl_instantiate_key_common(key_serial_t id,
|
||||
|
||||
error2:
|
||||
kvfree_sensitive(payload, plen);
|
||||
error_put_rka:
|
||||
request_key_auth_put(rka);
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
@@ -1358,15 +1364,19 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error,
|
||||
if (!instkey)
|
||||
goto error;
|
||||
|
||||
rka = instkey->payload.data[0];
|
||||
if (rka->target_key->serial != id)
|
||||
rka = request_key_auth_get(instkey);
|
||||
if (!rka) {
|
||||
ret = -EKEYREVOKED;
|
||||
goto error;
|
||||
}
|
||||
if (rka->target_key->serial != id)
|
||||
goto error_put_rka;
|
||||
|
||||
/* find the destination keyring if present (which must also be
|
||||
* writable) */
|
||||
ret = get_instantiation_keyring(ringid, rka, &dest_keyring);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
goto error_put_rka;
|
||||
|
||||
/* instantiate the key and link it into a keyring */
|
||||
ret = key_reject_and_link(rka->target_key, timeout, error,
|
||||
@@ -1379,6 +1389,8 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error,
|
||||
if (ret == 0)
|
||||
keyctl_change_reqkey_auth(NULL);
|
||||
|
||||
error_put_rka:
|
||||
request_key_auth_put(rka);
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -138,28 +138,35 @@ static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_par
|
||||
if (uparams.in_len > info.max_dec_size ||
|
||||
uparams.out_len > info.max_enc_size)
|
||||
return -EINVAL;
|
||||
|
||||
params->out_len = info.max_enc_size;
|
||||
break;
|
||||
case KEYCTL_PKEY_DECRYPT:
|
||||
if (uparams.in_len > info.max_enc_size ||
|
||||
uparams.out_len > info.max_dec_size)
|
||||
return -EINVAL;
|
||||
|
||||
params->out_len = info.max_dec_size;
|
||||
break;
|
||||
case KEYCTL_PKEY_SIGN:
|
||||
if (uparams.in_len > info.max_data_size ||
|
||||
uparams.out_len > info.max_sig_size)
|
||||
return -EINVAL;
|
||||
|
||||
params->out_len = info.max_sig_size;
|
||||
break;
|
||||
case KEYCTL_PKEY_VERIFY:
|
||||
if (uparams.in_len > info.max_data_size ||
|
||||
uparams.in2_len > info.max_sig_size)
|
||||
return -EINVAL;
|
||||
|
||||
params->out_len = info.max_sig_size;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
params->in_len = uparams.in_len;
|
||||
params->out_len = uparams.out_len; /* Note: same as in2_len */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -238,7 +245,8 @@ long keyctl_pkey_e_d_s(int op,
|
||||
params.op = kernel_pkey_sign;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
ret = -EOPNOTSUPP;
|
||||
goto error_params;
|
||||
}
|
||||
|
||||
in = memdup_user(_in, params.in_len);
|
||||
|
||||
@@ -576,7 +576,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
|
||||
struct keyring_search_context *ctx = iterator_data;
|
||||
const struct key *key = keyring_ptr_to_key(object);
|
||||
unsigned long kflags = READ_ONCE(key->flags);
|
||||
short state = READ_ONCE(key->state);
|
||||
short state = key_read_state(key);
|
||||
|
||||
kenter("{%d}", key->serial);
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
|
||||
|
||||
case KEY_REQKEY_DEFL_GROUP_KEYRING:
|
||||
default:
|
||||
BUG();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,6 +23,7 @@ static void request_key_auth_describe(const struct key *, struct seq_file *);
|
||||
static void request_key_auth_revoke(struct key *);
|
||||
static void request_key_auth_destroy(struct key *);
|
||||
static long request_key_auth_read(const struct key *, char *, size_t);
|
||||
static void request_key_auth_rcu_disposal(struct rcu_head *);
|
||||
|
||||
/*
|
||||
* The request-key authorisation key type definition.
|
||||
@@ -115,6 +116,31 @@ static void free_request_key_auth(struct request_key_auth *rka)
|
||||
kfree(rka);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take a reference to the request-key authorisation payload so callers can
|
||||
* drop authkey->sem before doing operations that may sleep.
|
||||
*/
|
||||
struct request_key_auth *request_key_auth_get(struct key *authkey)
|
||||
{
|
||||
struct request_key_auth *rka;
|
||||
|
||||
down_read(&authkey->sem);
|
||||
rka = dereference_key_locked(authkey);
|
||||
if (rka && !test_bit(KEY_FLAG_REVOKED, &authkey->flags))
|
||||
refcount_inc(&rka->usage);
|
||||
else
|
||||
rka = NULL;
|
||||
up_read(&authkey->sem);
|
||||
|
||||
return rka;
|
||||
}
|
||||
|
||||
void request_key_auth_put(struct request_key_auth *rka)
|
||||
{
|
||||
if (rka && refcount_dec_and_test(&rka->usage))
|
||||
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispose of the request_key_auth record under RCU conditions
|
||||
*/
|
||||
@@ -136,8 +162,10 @@ static void request_key_auth_revoke(struct key *key)
|
||||
struct request_key_auth *rka = dereference_key_locked(key);
|
||||
|
||||
kenter("{%d}", key->serial);
|
||||
if (!rka)
|
||||
return;
|
||||
rcu_assign_keypointer(key, NULL);
|
||||
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
|
||||
request_key_auth_put(rka);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,7 +178,7 @@ static void request_key_auth_destroy(struct key *key)
|
||||
kenter("{%d}", key->serial);
|
||||
if (rka) {
|
||||
rcu_assign_keypointer(key, NULL);
|
||||
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
|
||||
request_key_auth_put(rka);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +202,7 @@ struct key *request_key_auth_new(struct key *target, const char *op,
|
||||
rka = kzalloc_obj(*rka);
|
||||
if (!rka)
|
||||
goto error;
|
||||
refcount_set(&rka->usage, 1);
|
||||
rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
|
||||
if (!rka->callout_info)
|
||||
goto error_free_rka;
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
config HAVE_TRUSTED_KEYS
|
||||
bool
|
||||
|
||||
config HAVE_TRUSTED_KEYS_DEBUG
|
||||
bool
|
||||
|
||||
config TRUSTED_KEYS_DEBUG
|
||||
bool "Debug trusted keys"
|
||||
depends on HAVE_TRUSTED_KEYS_DEBUG
|
||||
default n
|
||||
help
|
||||
Trusted key backends and core code that support debug traces can
|
||||
opt-in that feature here. Traces must only use debug level output, as
|
||||
sensitive data may pass by. In the kernel-command line traces can be
|
||||
enabled via trusted.dyndbg='+p'.
|
||||
|
||||
SAFETY: Debug dumps are inactive at runtime until trusted.debug is set
|
||||
to a true value on the kernel command-line. Use at your utmost
|
||||
consideration when enabling this feature on a production build. The
|
||||
general advice is not to do this.
|
||||
|
||||
config TRUSTED_KEYS_TPM
|
||||
bool "TPM-based trusted keys"
|
||||
depends on TCG_TPM >= TRUSTED_KEYS
|
||||
default y
|
||||
select HAVE_TRUSTED_KEYS_DEBUG
|
||||
select CRYPTO_HASH_INFO
|
||||
select CRYPTO_LIB_SHA1
|
||||
select CRYPTO_LIB_UTILS
|
||||
@@ -23,6 +42,7 @@ config TRUSTED_KEYS_TEE
|
||||
bool "TEE-based trusted keys"
|
||||
depends on TEE >= TRUSTED_KEYS
|
||||
default y
|
||||
select HAVE_TRUSTED_KEYS_DEBUG
|
||||
select HAVE_TRUSTED_KEYS
|
||||
help
|
||||
Enable use of the Trusted Execution Environment (TEE) as trusted
|
||||
@@ -33,6 +53,7 @@ config TRUSTED_KEYS_CAAM
|
||||
depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
|
||||
select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
|
||||
default y
|
||||
select HAVE_TRUSTED_KEYS_DEBUG
|
||||
select HAVE_TRUSTED_KEYS
|
||||
help
|
||||
Enable use of NXP's Cryptographic Accelerator and Assurance Module
|
||||
@@ -42,6 +63,7 @@ config TRUSTED_KEYS_DCP
|
||||
bool "DCP-based trusted keys"
|
||||
depends on CRYPTO_DEV_MXS_DCP >= TRUSTED_KEYS
|
||||
default y
|
||||
select HAVE_TRUSTED_KEYS_DEBUG
|
||||
select HAVE_TRUSTED_KEYS
|
||||
help
|
||||
Enable use of NXP's DCP (Data Co-Processor) as trusted key backend.
|
||||
@@ -50,6 +72,7 @@ config TRUSTED_KEYS_PKWM
|
||||
bool "PKWM-based trusted keys"
|
||||
depends on PSERIES_PLPKS >= TRUSTED_KEYS
|
||||
default y
|
||||
select HAVE_TRUSTED_KEYS_DEBUG
|
||||
select HAVE_TRUSTED_KEYS
|
||||
help
|
||||
Enable use of IBM PowerVM Key Wrapping Module (PKWM) as a trusted key backend.
|
||||
|
||||
@@ -28,10 +28,13 @@ static const match_table_t key_tokens = {
|
||||
{opt_err, NULL}
|
||||
};
|
||||
|
||||
#ifdef CAAM_DEBUG
|
||||
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
|
||||
static inline void dump_options(const struct caam_pkey_info *pkey_info)
|
||||
{
|
||||
pr_info("key encryption algo %d\n", pkey_info->key_enc_algo);
|
||||
if (!trusted_debug)
|
||||
return;
|
||||
|
||||
pr_debug("key encryption algo %d\n", pkey_info->key_enc_algo);
|
||||
}
|
||||
#else
|
||||
static inline void dump_options(const struct caam_pkey_info *pkey_info)
|
||||
|
||||
@@ -31,6 +31,12 @@ static char *trusted_rng = "default";
|
||||
module_param_named(rng, trusted_rng, charp, 0);
|
||||
MODULE_PARM_DESC(rng, "Select trusted key RNG");
|
||||
|
||||
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
|
||||
bool trusted_debug;
|
||||
module_param_named(debug, trusted_debug, bool, 0);
|
||||
MODULE_PARM_DESC(debug, "Enable trusted keys debug traces (default: 0)");
|
||||
#endif
|
||||
|
||||
static char *trusted_key_source;
|
||||
module_param_named(source, trusted_key_source, charp, 0);
|
||||
MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam, dcp or pkwm)");
|
||||
@@ -59,7 +65,7 @@ DEFINE_STATIC_CALL_NULL(trusted_key_unseal,
|
||||
DEFINE_STATIC_CALL_NULL(trusted_key_get_random,
|
||||
*trusted_key_sources[0].ops->get_random);
|
||||
static void (*trusted_key_exit)(void);
|
||||
static unsigned char migratable;
|
||||
static unsigned char migratable __ro_after_init;
|
||||
|
||||
enum {
|
||||
Opt_err,
|
||||
|
||||
@@ -46,38 +46,44 @@ enum {
|
||||
SRK_keytype = 4
|
||||
};
|
||||
|
||||
#define TPM_DEBUG 0
|
||||
|
||||
#if TPM_DEBUG
|
||||
#ifdef CONFIG_TRUSTED_KEYS_DEBUG
|
||||
static inline void dump_options(struct trusted_key_options *o)
|
||||
{
|
||||
pr_info("sealing key type %d\n", o->keytype);
|
||||
pr_info("sealing key handle %0X\n", o->keyhandle);
|
||||
pr_info("pcrlock %d\n", o->pcrlock);
|
||||
pr_info("pcrinfo %d\n", o->pcrinfo_len);
|
||||
print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
|
||||
16, 1, o->pcrinfo, o->pcrinfo_len, 0);
|
||||
if (!trusted_debug)
|
||||
return;
|
||||
|
||||
pr_debug("sealing key type %d\n", o->keytype);
|
||||
pr_debug("sealing key handle %0X\n", o->keyhandle);
|
||||
pr_debug("pcrlock %d\n", o->pcrlock);
|
||||
pr_debug("pcrinfo %d\n", o->pcrinfo_len);
|
||||
print_hex_dump_debug("pcrinfo ", DUMP_PREFIX_NONE,
|
||||
16, 1, o->pcrinfo, o->pcrinfo_len, 0);
|
||||
}
|
||||
|
||||
static inline void dump_sess(struct osapsess *s)
|
||||
{
|
||||
print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
|
||||
16, 1, &s->handle, 4, 0);
|
||||
pr_info("secret:\n");
|
||||
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
|
||||
16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
|
||||
pr_info("trusted-key: enonce:\n");
|
||||
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
|
||||
16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
|
||||
if (!trusted_debug)
|
||||
return;
|
||||
|
||||
print_hex_dump_debug("trusted-key: handle ", DUMP_PREFIX_NONE,
|
||||
16, 1, &s->handle, 4, 0);
|
||||
pr_debug("secret:\n");
|
||||
print_hex_dump_debug("", DUMP_PREFIX_NONE,
|
||||
16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
|
||||
pr_debug("trusted-key: enonce:\n");
|
||||
print_hex_dump_debug("", DUMP_PREFIX_NONE,
|
||||
16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
|
||||
}
|
||||
|
||||
static inline void dump_tpm_buf(unsigned char *buf)
|
||||
{
|
||||
int len;
|
||||
|
||||
pr_info("\ntpm buffer\n");
|
||||
if (!trusted_debug)
|
||||
return;
|
||||
pr_debug("\ntpm buffer\n");
|
||||
len = LOAD32(buf, TPM_SIZE_OFFSET);
|
||||
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
|
||||
print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
|
||||
}
|
||||
#else
|
||||
static inline void dump_options(struct trusted_key_options *o)
|
||||
|
||||
@@ -64,7 +64,7 @@ int user_preparse(struct key_preparsed_payload *prep)
|
||||
if (datalen == 0 || datalen > 32767 || !prep->data)
|
||||
return -EINVAL;
|
||||
|
||||
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
|
||||
upayload = kmalloc_flex(*upayload, data, datalen);
|
||||
if (!upayload)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user