2019-06-01 16:08:55 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2011-10-05 16:54:46 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2011 Intel Corporation
|
|
|
|
*
|
|
|
|
* Author:
|
|
|
|
* Dmitry Kasatkin <dmitry.kasatkin@intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
|
|
|
|
#include <linux/err.h>
|
2013-08-13 20:47:43 +08:00
|
|
|
#include <linux/sched.h>
|
2014-11-05 23:01:13 +08:00
|
|
|
#include <linux/slab.h>
|
2013-08-13 20:47:43 +08:00
|
|
|
#include <linux/cred.h>
|
2011-10-05 16:54:46 +08:00
|
|
|
#include <linux/key-type.h>
|
|
|
|
#include <linux/digsig.h>
|
2018-02-13 09:26:20 +08:00
|
|
|
#include <linux/vmalloc.h>
|
KEYS: Move the point of trust determination to __key_link()
Move the point at which a key is determined to be trustworthy to
__key_link() so that we use the contents of the keyring being linked in to
to determine whether the key being linked in is trusted or not.
What is 'trusted' then becomes a matter of what's in the keyring.
Currently, the test is done when the key is parsed, but given that at that
point we can only sensibly refer to the contents of the system trusted
keyring, we can only use that as the basis for working out the
trustworthiness of a new key.
With this change, a trusted keyring is a set of keys that once the
trusted-only flag is set cannot be added to except by verification through
one of the contained keys.
Further, adding a key into a trusted keyring, whilst it might grant
trustworthiness in the context of that keyring, does not automatically
grant trustworthiness in the context of a second keyring to which it could
be secondarily linked.
To accomplish this, the authentication data associated with the key source
must now be retained. For an X.509 cert, this means the contents of the
AuthorityKeyIdentifier and the signature data.
If system keyrings are disabled then restrict_link_by_builtin_trusted()
resolves to restrict_link_reject(). The integrity digital signature code
still works correctly with this as it was previously using
KEY_FLAG_TRUSTED_ONLY, which doesn't permit anything to be added if there
is no system keyring against which trust can be determined.
Signed-off-by: David Howells <dhowells@redhat.com>
2016-04-06 23:14:26 +08:00
|
|
|
#include <crypto/public_key.h>
|
|
|
|
#include <keys/system_keyring.h>
|
2011-10-05 16:54:46 +08:00
|
|
|
|
|
|
|
#include "integrity.h"
|
|
|
|
|
|
|
|
static struct key *keyring[INTEGRITY_KEYRING_MAX];
|
|
|
|
|
2018-09-08 04:22:23 +08:00
|
|
|
static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
|
2015-10-23 02:26:10 +08:00
|
|
|
#ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
|
2011-10-05 16:54:46 +08:00
|
|
|
"_evm",
|
|
|
|
"_ima",
|
2013-08-13 20:47:43 +08:00
|
|
|
#else
|
2015-10-23 02:26:10 +08:00
|
|
|
".evm",
|
2013-08-13 20:47:43 +08:00
|
|
|
".ima",
|
|
|
|
#endif
|
2018-12-09 04:26:59 +08:00
|
|
|
".platform",
|
2011-10-05 16:54:46 +08:00
|
|
|
};
|
|
|
|
|
2016-04-07 16:45:23 +08:00
|
|
|
#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
|
|
|
|
#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
|
KEYS: Move the point of trust determination to __key_link()
Move the point at which a key is determined to be trustworthy to
__key_link() so that we use the contents of the keyring being linked in to
to determine whether the key being linked in is trusted or not.
What is 'trusted' then becomes a matter of what's in the keyring.
Currently, the test is done when the key is parsed, but given that at that
point we can only sensibly refer to the contents of the system trusted
keyring, we can only use that as the basis for working out the
trustworthiness of a new key.
With this change, a trusted keyring is a set of keys that once the
trusted-only flag is set cannot be added to except by verification through
one of the contained keys.
Further, adding a key into a trusted keyring, whilst it might grant
trustworthiness in the context of that keyring, does not automatically
grant trustworthiness in the context of a second keyring to which it could
be secondarily linked.
To accomplish this, the authentication data associated with the key source
must now be retained. For an X.509 cert, this means the contents of the
AuthorityKeyIdentifier and the signature data.
If system keyrings are disabled then restrict_link_by_builtin_trusted()
resolves to restrict_link_reject(). The integrity digital signature code
still works correctly with this as it was previously using
KEY_FLAG_TRUSTED_ONLY, which doesn't permit anything to be added if there
is no system keyring against which trust can be determined.
Signed-off-by: David Howells <dhowells@redhat.com>
2016-04-06 23:14:26 +08:00
|
|
|
#else
|
2016-04-07 16:45:23 +08:00
|
|
|
#define restrict_link_to_ima restrict_link_by_builtin_trusted
|
KEYS: Move the point of trust determination to __key_link()
Move the point at which a key is determined to be trustworthy to
__key_link() so that we use the contents of the keyring being linked in to
to determine whether the key being linked in is trusted or not.
What is 'trusted' then becomes a matter of what's in the keyring.
Currently, the test is done when the key is parsed, but given that at that
point we can only sensibly refer to the contents of the system trusted
keyring, we can only use that as the basis for working out the
trustworthiness of a new key.
With this change, a trusted keyring is a set of keys that once the
trusted-only flag is set cannot be added to except by verification through
one of the contained keys.
Further, adding a key into a trusted keyring, whilst it might grant
trustworthiness in the context of that keyring, does not automatically
grant trustworthiness in the context of a second keyring to which it could
be secondarily linked.
To accomplish this, the authentication data associated with the key source
must now be retained. For an X.509 cert, this means the contents of the
AuthorityKeyIdentifier and the signature data.
If system keyrings are disabled then restrict_link_by_builtin_trusted()
resolves to restrict_link_reject(). The integrity digital signature code
still works correctly with this as it was previously using
KEY_FLAG_TRUSTED_ONLY, which doesn't permit anything to be added if there
is no system keyring against which trust can be determined.
Signed-off-by: David Howells <dhowells@redhat.com>
2016-04-06 23:14:26 +08:00
|
|
|
#endif
|
|
|
|
|
2011-10-05 16:54:46 +08:00
|
|
|
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
2013-10-10 14:56:13 +08:00
|
|
|
const char *digest, int digestlen)
|
2011-10-05 16:54:46 +08:00
|
|
|
{
|
2016-08-01 21:19:10 +08:00
|
|
|
if (id >= INTEGRITY_KEYRING_MAX || siglen < 2)
|
2011-10-05 16:54:46 +08:00
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
if (!keyring[id]) {
|
|
|
|
keyring[id] =
|
2019-07-11 09:43:43 +08:00
|
|
|
request_key(&key_type_keyring, keyring_name[id], NULL);
|
2011-10-05 16:54:46 +08:00
|
|
|
if (IS_ERR(keyring[id])) {
|
|
|
|
int err = PTR_ERR(keyring[id]);
|
|
|
|
pr_err("no %s keyring: %d\n", keyring_name[id], err);
|
|
|
|
keyring[id] = NULL;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-10 15:12:03 +08:00
|
|
|
switch (sig[1]) {
|
2013-02-07 06:12:08 +08:00
|
|
|
case 1:
|
2013-10-10 15:12:03 +08:00
|
|
|
/* v1 API expect signature without xattr type */
|
|
|
|
return digsig_verify(keyring[id], sig + 1, siglen - 1,
|
2013-02-07 06:12:08 +08:00
|
|
|
digest, digestlen);
|
|
|
|
case 2:
|
|
|
|
return asymmetric_verify(keyring[id], sig, siglen,
|
|
|
|
digest, digestlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EOPNOTSUPP;
|
2011-10-05 16:54:46 +08:00
|
|
|
}
|
2013-08-13 20:47:43 +08:00
|
|
|
|
2019-06-17 15:44:52 +08:00
|
|
|
static int __init __integrity_init_keyring(const unsigned int id,
|
2019-07-11 09:43:43 +08:00
|
|
|
key_perm_t perm,
|
2019-06-17 15:44:52 +08:00
|
|
|
struct key_restriction *restriction)
|
2013-08-13 20:47:43 +08:00
|
|
|
{
|
|
|
|
const struct cred *cred = current_cred();
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
|
2019-07-11 09:43:43 +08:00
|
|
|
KGIDT_INIT(0), cred, perm,
|
2018-12-09 04:27:00 +08:00
|
|
|
KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
|
KEYS: Add a facility to restrict new links into a keyring
Add a facility whereby proposed new links to be added to a keyring can be
vetted, permitting them to be rejected if necessary. This can be used to
block public keys from which the signature cannot be verified or for which
the signature verification fails. It could also be used to provide
blacklisting.
This affects operations like add_key(), KEYCTL_LINK and KEYCTL_INSTANTIATE.
To this end:
(1) A function pointer is added to the key struct that, if set, points to
the vetting function. This is called as:
int (*restrict_link)(struct key *keyring,
const struct key_type *key_type,
unsigned long key_flags,
const union key_payload *key_payload),
where 'keyring' will be the keyring being added to, key_type and
key_payload will describe the key being added and key_flags[*] can be
AND'ed with KEY_FLAG_TRUSTED.
[*] This parameter will be removed in a later patch when
KEY_FLAG_TRUSTED is removed.
The function should return 0 to allow the link to take place or an
error (typically -ENOKEY, -ENOPKG or -EKEYREJECTED) to reject the
link.
The pointer should not be set directly, but rather should be set
through keyring_alloc().
Note that if called during add_key(), preparse is called before this
method, but a key isn't actually allocated until after this function
is called.
(2) KEY_ALLOC_BYPASS_RESTRICTION is added. This can be passed to
key_create_or_update() or key_instantiate_and_link() to bypass the
restriction check.
(3) KEY_FLAG_TRUSTED_ONLY is removed. The entire contents of a keyring
with this restriction emplaced can be considered 'trustworthy' by
virtue of being in the keyring when that keyring is consulted.
(4) key_alloc() and keyring_alloc() take an extra argument that will be
used to set restrict_link in the new key. This ensures that the
pointer is set before the key is published, thus preventing a window
of unrestrictedness. Normally this argument will be NULL.
(5) As a temporary affair, keyring_restrict_trusted_only() is added. It
should be passed to keyring_alloc() as the extra argument instead of
setting KEY_FLAG_TRUSTED_ONLY on a keyring. This will be replaced in
a later patch with functions that look in the appropriate places for
authoritative keys.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
2016-04-06 23:14:24 +08:00
|
|
|
if (IS_ERR(keyring[id])) {
|
2013-08-13 20:47:43 +08:00
|
|
|
err = PTR_ERR(keyring[id]);
|
|
|
|
pr_info("Can't allocate %s keyring (%d)\n",
|
|
|
|
keyring_name[id], err);
|
|
|
|
keyring[id] = NULL;
|
2019-01-21 17:59:28 +08:00
|
|
|
} else {
|
|
|
|
if (id == INTEGRITY_KEYRING_PLATFORM)
|
|
|
|
set_platform_trusted_keys(keyring[id]);
|
2013-08-13 20:47:43 +08:00
|
|
|
}
|
2018-12-09 04:26:59 +08:00
|
|
|
|
2013-08-13 20:47:43 +08:00
|
|
|
return err;
|
|
|
|
}
|
2014-11-05 23:01:13 +08:00
|
|
|
|
2018-12-09 04:26:59 +08:00
|
|
|
int __init integrity_init_keyring(const unsigned int id)
|
|
|
|
{
|
|
|
|
struct key_restriction *restriction;
|
2019-07-11 09:43:43 +08:00
|
|
|
key_perm_t perm;
|
|
|
|
|
|
|
|
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
|
|
|
|
| KEY_USR_READ | KEY_USR_SEARCH;
|
2018-12-09 04:26:59 +08:00
|
|
|
|
|
|
|
if (id == INTEGRITY_KEYRING_PLATFORM) {
|
|
|
|
restriction = NULL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
|
|
|
|
if (!restriction)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
restriction->check = restrict_link_to_ima;
|
2019-07-11 09:43:43 +08:00
|
|
|
perm |= KEY_USR_WRITE;
|
2018-12-09 04:26:59 +08:00
|
|
|
|
|
|
|
out:
|
2019-07-11 09:43:43 +08:00
|
|
|
return __integrity_init_keyring(id, perm, restriction);
|
2018-12-09 04:26:59 +08:00
|
|
|
}
|
|
|
|
|
2019-07-11 09:43:43 +08:00
|
|
|
int __init integrity_add_key(const unsigned int id, const void *data,
|
|
|
|
off_t size, key_perm_t perm)
|
2014-11-05 23:01:13 +08:00
|
|
|
{
|
|
|
|
key_ref_t key;
|
2018-12-09 04:27:00 +08:00
|
|
|
int rc = 0;
|
2014-11-05 23:01:13 +08:00
|
|
|
|
|
|
|
if (!keyring[id])
|
|
|
|
return -EINVAL;
|
|
|
|
|
2018-12-09 04:27:00 +08:00
|
|
|
key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
|
2019-07-11 09:43:43 +08:00
|
|
|
NULL, data, size, perm,
|
2018-12-09 04:27:00 +08:00
|
|
|
KEY_ALLOC_NOT_IN_QUOTA);
|
|
|
|
if (IS_ERR(key)) {
|
|
|
|
rc = PTR_ERR(key);
|
|
|
|
pr_err("Problem loading X.509 certificate %d\n", rc);
|
|
|
|
} else {
|
|
|
|
pr_notice("Loaded X.509 cert '%s'\n",
|
|
|
|
key_ref_to_ptr(key)->description);
|
|
|
|
key_ref_put(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int __init integrity_load_x509(const unsigned int id, const char *path)
|
|
|
|
{
|
|
|
|
void *data;
|
|
|
|
loff_t size;
|
|
|
|
int rc;
|
2019-07-11 09:43:43 +08:00
|
|
|
key_perm_t perm;
|
2018-12-09 04:27:00 +08:00
|
|
|
|
2017-09-10 15:49:45 +08:00
|
|
|
rc = kernel_read_file_from_path(path, &data, &size, 0,
|
|
|
|
READING_X509_CERTIFICATE);
|
|
|
|
if (rc < 0) {
|
|
|
|
pr_err("Unable to open file: %s (%d)", path, rc);
|
2014-11-05 23:01:13 +08:00
|
|
|
return rc;
|
2017-09-10 15:49:45 +08:00
|
|
|
}
|
2014-11-05 23:01:13 +08:00
|
|
|
|
2019-07-11 09:43:43 +08:00
|
|
|
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
|
|
|
|
|
2018-12-09 04:27:00 +08:00
|
|
|
pr_info("Loading X.509 certificate: %s\n", path);
|
2019-07-11 09:43:43 +08:00
|
|
|
rc = integrity_add_key(id, (const void *)data, size, perm);
|
2018-12-09 04:27:00 +08:00
|
|
|
|
2017-09-10 15:49:45 +08:00
|
|
|
vfree(data);
|
2018-12-09 04:27:00 +08:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int __init integrity_load_cert(const unsigned int id, const char *source,
|
2019-07-11 09:43:43 +08:00
|
|
|
const void *data, size_t len, key_perm_t perm)
|
2018-12-09 04:27:00 +08:00
|
|
|
{
|
|
|
|
if (!data)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
pr_info("Loading X.509 certificate: %s\n", source);
|
2019-07-11 09:43:43 +08:00
|
|
|
return integrity_add_key(id, data, len, perm);
|
2014-11-05 23:01:13 +08:00
|
|
|
}
|