2019-06-01 01:08:55 -07:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2011-10-05 01:54:46 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2011 Intel Corporation
|
|
|
|
*
|
|
|
|
* Author:
|
|
|
|
* Dmitry Kasatkin <dmitry.kasatkin@intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/err.h>
|
2013-08-13 05:47:43 -07:00
|
|
|
#include <linux/sched.h>
|
2014-11-05 08:01:13 -07:00
|
|
|
#include <linux/slab.h>
|
2013-08-13 05:47:43 -07:00
|
|
|
#include <linux/cred.h>
|
2020-10-02 10:38:15 -07:00
|
|
|
#include <linux/kernel_read_file.h>
|
2011-10-05 01:54:46 -07:00
|
|
|
#include <linux/key-type.h>
|
|
|
|
#include <linux/digsig.h>
|
2018-02-12 18:26:20 -07: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 08:14:26 -07:00
|
|
|
#include <crypto/public_key.h>
|
|
|
|
#include <keys/system_keyring.h>
|
2011-10-05 01:54:46 -07:00
|
|
|
|
|
|
|
#include "integrity.h"
|
|
|
|
|
|
|
|
static struct key *keyring[INTEGRITY_KEYRING_MAX];
|
|
|
|
|
2018-09-07 13:22:23 -07:00
|
|
|
static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
|
2015-10-22 11:26:10 -07:00
|
|
|
#ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
|
2011-10-05 01:54:46 -07:00
|
|
|
"_evm",
|
|
|
|
"_ima",
|
2013-08-13 05:47:43 -07:00
|
|
|
#else
|
2015-10-22 11:26:10 -07:00
|
|
|
".evm",
|
2013-08-13 05:47:43 -07:00
|
|
|
".ima",
|
|
|
|
#endif
|
2018-12-08 13:26:59 -07:00
|
|
|
".platform",
|
2022-01-25 19:58:28 -07:00
|
|
|
".machine",
|
2011-10-05 01:54:46 -07:00
|
|
|
};
|
|
|
|
|
2016-04-07 01:45:23 -07:00
|
|
|
#ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
|
2023-05-22 16:09:43 -07:00
|
|
|
#define restrict_link_to_ima restrict_link_by_digsig_builtin_and_secondary
|
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 08:14:26 -07:00
|
|
|
#else
|
2023-05-22 16:09:43 -07:00
|
|
|
#define restrict_link_to_ima restrict_link_by_digsig_builtin
|
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 08:14:26 -07:00
|
|
|
#endif
|
|
|
|
|
2019-06-27 19:19:30 -07:00
|
|
|
static struct key *integrity_keyring_from_id(const unsigned int id)
|
2011-10-05 01:54:46 -07:00
|
|
|
{
|
2019-06-27 19:19:30 -07:00
|
|
|
if (id >= INTEGRITY_KEYRING_MAX)
|
|
|
|
return ERR_PTR(-EINVAL);
|
2011-10-05 01:54:46 -07:00
|
|
|
|
|
|
|
if (!keyring[id]) {
|
|
|
|
keyring[id] =
|
2019-07-10 18:43:43 -07:00
|
|
|
request_key(&key_type_keyring, keyring_name[id], NULL);
|
2011-10-05 01:54:46 -07: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;
|
2019-06-27 19:19:30 -07:00
|
|
|
return ERR_PTR(err);
|
2011-10-05 01:54:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-27 19:19:30 -07:00
|
|
|
return keyring[id];
|
|
|
|
}
|
|
|
|
|
|
|
|
int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
|
|
|
|
const char *digest, int digestlen)
|
|
|
|
{
|
|
|
|
struct key *keyring;
|
|
|
|
|
|
|
|
if (siglen < 2)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
keyring = integrity_keyring_from_id(id);
|
|
|
|
if (IS_ERR(keyring))
|
|
|
|
return PTR_ERR(keyring);
|
|
|
|
|
2013-10-10 00:12:03 -07:00
|
|
|
switch (sig[1]) {
|
2013-02-06 15:12:08 -07:00
|
|
|
case 1:
|
2013-10-10 00:12:03 -07:00
|
|
|
/* v1 API expect signature without xattr type */
|
2019-06-27 19:19:30 -07:00
|
|
|
return digsig_verify(keyring, sig + 1, siglen - 1, digest,
|
|
|
|
digestlen);
|
ima: support fs-verity file digest based version 3 signatures
IMA may verify a file's integrity against a "good" value stored in the
'security.ima' xattr or as an appended signature, based on policy. When
the "good value" is stored in the xattr, the xattr may contain a file
hash or signature. In either case, the "good" value is preceded by a
header. The first byte of the xattr header indicates the type of data
- hash, signature - stored in the xattr. To support storing fs-verity
signatures in the 'security.ima' xattr requires further differentiating
the fs-verity signature from the existing IMA signature.
In addition the signatures stored in 'security.ima' xattr, need to be
disambiguated. Instead of directly signing the fs-verity digest, a new
signature format version 3 is defined as the hash of the ima_file_id
structure, which identifies the type of signature and the digest.
The IMA policy defines "which" files are to be measured, verified, and/or
audited. For those files being verified, the policy rules indicate "how"
the file should be verified. For example to require a file be signed,
the appraise policy rule must include the 'appraise_type' option.
appraise_type:= [imasig] | [imasig|modsig] | [sigv3]
where 'imasig' is the original or signature format v2 (default),
where 'modsig' is an appended signature,
where 'sigv3' is the signature format v3.
The policy rule must also indicate the type of digest, if not the IMA
default, by first specifying the digest type:
digest_type:= [verity]
The following policy rule requires fsverity signatures. The rule may be
constrained, for example based on a fsuuid or LSM label.
appraise func=BPRM_CHECK digest_type=verity appraise_type=sigv3
Acked-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2021-11-24 08:56:33 -07:00
|
|
|
case 2: /* regular file data hash based signature */
|
|
|
|
case 3: /* struct ima_file_id data based signature */
|
2019-06-27 19:19:30 -07:00
|
|
|
return asymmetric_verify(keyring, sig, siglen, digest,
|
|
|
|
digestlen);
|
2013-02-06 15:12:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return -EOPNOTSUPP;
|
2011-10-05 01:54:46 -07:00
|
|
|
}
|
2013-08-13 05:47:43 -07:00
|
|
|
|
2019-06-27 19:19:30 -07:00
|
|
|
int integrity_modsig_verify(const unsigned int id, const struct modsig *modsig)
|
|
|
|
{
|
|
|
|
struct key *keyring;
|
|
|
|
|
|
|
|
keyring = integrity_keyring_from_id(id);
|
|
|
|
if (IS_ERR(keyring))
|
|
|
|
return PTR_ERR(keyring);
|
|
|
|
|
|
|
|
return ima_modsig_verify(keyring, modsig);
|
|
|
|
}
|
|
|
|
|
2019-06-17 00:44:52 -07:00
|
|
|
static int __init __integrity_init_keyring(const unsigned int id,
|
2019-07-10 18:43:43 -07:00
|
|
|
key_perm_t perm,
|
2019-06-17 00:44:52 -07:00
|
|
|
struct key_restriction *restriction)
|
2013-08-13 05:47:43 -07:00
|
|
|
{
|
|
|
|
const struct cred *cred = current_cred();
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
|
2019-07-10 18:43:43 -07:00
|
|
|
KGIDT_INIT(0), cred, perm,
|
2018-12-08 13:27:00 -07: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 08:14:24 -07:00
|
|
|
if (IS_ERR(keyring[id])) {
|
2013-08-13 05:47:43 -07: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 02:59:28 -07:00
|
|
|
} else {
|
|
|
|
if (id == INTEGRITY_KEYRING_PLATFORM)
|
|
|
|
set_platform_trusted_keys(keyring[id]);
|
2023-08-15 04:27:20 -07:00
|
|
|
if (id == INTEGRITY_KEYRING_MACHINE && imputed_trust_enabled())
|
2022-01-25 19:58:30 -07:00
|
|
|
set_machine_trusted_keys(keyring[id]);
|
2021-04-09 07:35:07 -07:00
|
|
|
if (id == INTEGRITY_KEYRING_IMA)
|
|
|
|
load_module_cert(keyring[id]);
|
2013-08-13 05:47:43 -07:00
|
|
|
}
|
2018-12-08 13:26:59 -07:00
|
|
|
|
2013-08-13 05:47:43 -07:00
|
|
|
return err;
|
|
|
|
}
|
2014-11-05 08:01:13 -07:00
|
|
|
|
2018-12-08 13:26:59 -07:00
|
|
|
int __init integrity_init_keyring(const unsigned int id)
|
|
|
|
{
|
|
|
|
struct key_restriction *restriction;
|
2019-07-10 18:43:43 -07:00
|
|
|
key_perm_t perm;
|
2022-11-11 03:13:17 -07:00
|
|
|
int ret;
|
2019-07-10 18:43:43 -07:00
|
|
|
|
|
|
|
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
|
|
|
|
| KEY_USR_READ | KEY_USR_SEARCH;
|
2018-12-08 13:26:59 -07:00
|
|
|
|
2022-01-25 19:58:28 -07:00
|
|
|
if (id == INTEGRITY_KEYRING_PLATFORM ||
|
2023-03-02 09:46:52 -07:00
|
|
|
(id == INTEGRITY_KEYRING_MACHINE &&
|
|
|
|
!IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING))) {
|
2018-12-08 13:26:59 -07:00
|
|
|
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;
|
|
|
|
|
2023-03-02 09:46:52 -07:00
|
|
|
if (id == INTEGRITY_KEYRING_MACHINE)
|
|
|
|
restriction->check = restrict_link_by_ca;
|
|
|
|
else
|
|
|
|
restriction->check = restrict_link_to_ima;
|
2022-01-25 19:58:28 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* MOK keys can only be added through a read-only runtime services
|
|
|
|
* UEFI variable during boot. No additional keys shall be allowed to
|
|
|
|
* load into the machine keyring following init from userspace.
|
|
|
|
*/
|
|
|
|
if (id != INTEGRITY_KEYRING_MACHINE)
|
|
|
|
perm |= KEY_USR_WRITE;
|
2018-12-08 13:26:59 -07:00
|
|
|
|
|
|
|
out:
|
2022-11-11 03:13:17 -07:00
|
|
|
ret = __integrity_init_keyring(id, perm, restriction);
|
|
|
|
if (ret)
|
|
|
|
kfree(restriction);
|
|
|
|
return ret;
|
2018-12-08 13:26:59 -07:00
|
|
|
}
|
|
|
|
|
2021-02-10 01:01:31 -07:00
|
|
|
static int __init integrity_add_key(const unsigned int id, const void *data,
|
|
|
|
off_t size, key_perm_t perm)
|
2014-11-05 08:01:13 -07:00
|
|
|
{
|
|
|
|
key_ref_t key;
|
2018-12-08 13:27:00 -07:00
|
|
|
int rc = 0;
|
2014-11-05 08:01:13 -07:00
|
|
|
|
|
|
|
if (!keyring[id])
|
|
|
|
return -EINVAL;
|
|
|
|
|
2018-12-08 13:27:00 -07:00
|
|
|
key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
|
2019-07-10 18:43:43 -07:00
|
|
|
NULL, data, size, perm,
|
2018-12-08 13:27:00 -07:00
|
|
|
KEY_ALLOC_NOT_IN_QUOTA);
|
|
|
|
if (IS_ERR(key)) {
|
|
|
|
rc = PTR_ERR(key);
|
2024-01-08 17:24:28 -07:00
|
|
|
if (id != INTEGRITY_KEYRING_MACHINE)
|
|
|
|
pr_err("Problem loading X.509 certificate %d\n", rc);
|
2018-12-08 13:27:00 -07:00
|
|
|
} 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)
|
|
|
|
{
|
2020-10-02 10:38:13 -07:00
|
|
|
void *data = NULL;
|
2020-10-02 10:38:17 -07:00
|
|
|
size_t size;
|
2018-12-08 13:27:00 -07:00
|
|
|
int rc;
|
2019-07-10 18:43:43 -07:00
|
|
|
key_perm_t perm;
|
2018-12-08 13:27:00 -07:00
|
|
|
|
2020-10-02 10:38:25 -07:00
|
|
|
rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
|
2017-09-10 00:49:45 -07:00
|
|
|
READING_X509_CERTIFICATE);
|
|
|
|
if (rc < 0) {
|
|
|
|
pr_err("Unable to open file: %s (%d)", path, rc);
|
2014-11-05 08:01:13 -07:00
|
|
|
return rc;
|
2017-09-10 00:49:45 -07:00
|
|
|
}
|
2020-10-02 10:38:17 -07:00
|
|
|
size = rc;
|
2014-11-05 08:01:13 -07:00
|
|
|
|
2019-07-10 18:43:43 -07:00
|
|
|
perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
|
|
|
|
|
2018-12-08 13:27:00 -07:00
|
|
|
pr_info("Loading X.509 certificate: %s\n", path);
|
2019-07-10 18:43:43 -07:00
|
|
|
rc = integrity_add_key(id, (const void *)data, size, perm);
|
2018-12-08 13:27:00 -07:00
|
|
|
|
2017-09-10 00:49:45 -07:00
|
|
|
vfree(data);
|
2018-12-08 13:27:00 -07:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int __init integrity_load_cert(const unsigned int id, const char *source,
|
2019-07-10 18:43:43 -07:00
|
|
|
const void *data, size_t len, key_perm_t perm)
|
2018-12-08 13:27:00 -07:00
|
|
|
{
|
|
|
|
if (!data)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
pr_info("Loading X.509 certificate: %s\n", source);
|
2019-07-10 18:43:43 -07:00
|
|
|
return integrity_add_key(id, data, len, perm);
|
2014-11-05 08:01:13 -07:00
|
|
|
}
|