cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

system_keyring.c (10152B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* System trusted keyring for trusted public keys
      3 *
      4 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#include <linux/export.h>
      9#include <linux/kernel.h>
     10#include <linux/sched.h>
     11#include <linux/cred.h>
     12#include <linux/err.h>
     13#include <linux/slab.h>
     14#include <linux/uidgid.h>
     15#include <linux/verification.h>
     16#include <keys/asymmetric-type.h>
     17#include <keys/system_keyring.h>
     18#include <crypto/pkcs7.h>
     19
     20static struct key *builtin_trusted_keys;
     21#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
     22static struct key *secondary_trusted_keys;
     23#endif
     24#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
     25static struct key *machine_trusted_keys;
     26#endif
     27#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
     28static struct key *platform_trusted_keys;
     29#endif
     30
     31extern __initconst const u8 system_certificate_list[];
     32extern __initconst const unsigned long system_certificate_list_size;
     33extern __initconst const unsigned long module_cert_size;
     34
     35/**
     36 * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
     37 *
     38 * Restrict the addition of keys into a keyring based on the key-to-be-added
     39 * being vouched for by a key in the built in system keyring.
     40 */
     41int restrict_link_by_builtin_trusted(struct key *dest_keyring,
     42				     const struct key_type *type,
     43				     const union key_payload *payload,
     44				     struct key *restriction_key)
     45{
     46	return restrict_link_by_signature(dest_keyring, type, payload,
     47					  builtin_trusted_keys);
     48}
     49
     50#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
     51/**
     52 * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
     53 *   addition by both builtin and secondary keyrings
     54 *
     55 * Restrict the addition of keys into a keyring based on the key-to-be-added
     56 * being vouched for by a key in either the built-in or the secondary system
     57 * keyrings.
     58 */
     59int restrict_link_by_builtin_and_secondary_trusted(
     60	struct key *dest_keyring,
     61	const struct key_type *type,
     62	const union key_payload *payload,
     63	struct key *restrict_key)
     64{
     65	/* If we have a secondary trusted keyring, then that contains a link
     66	 * through to the builtin keyring and the search will follow that link.
     67	 */
     68	if (type == &key_type_keyring &&
     69	    dest_keyring == secondary_trusted_keys &&
     70	    payload == &builtin_trusted_keys->payload)
     71		/* Allow the builtin keyring to be added to the secondary */
     72		return 0;
     73
     74	return restrict_link_by_signature(dest_keyring, type, payload,
     75					  secondary_trusted_keys);
     76}
     77
     78/**
     79 * Allocate a struct key_restriction for the "builtin and secondary trust"
     80 * keyring. Only for use in system_trusted_keyring_init().
     81 */
     82static __init struct key_restriction *get_builtin_and_secondary_restriction(void)
     83{
     84	struct key_restriction *restriction;
     85
     86	restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
     87
     88	if (!restriction)
     89		panic("Can't allocate secondary trusted keyring restriction\n");
     90
     91	if (IS_ENABLED(CONFIG_INTEGRITY_MACHINE_KEYRING))
     92		restriction->check = restrict_link_by_builtin_secondary_and_machine;
     93	else
     94		restriction->check = restrict_link_by_builtin_and_secondary_trusted;
     95
     96	return restriction;
     97}
     98#endif
     99#ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
    100void __init set_machine_trusted_keys(struct key *keyring)
    101{
    102	machine_trusted_keys = keyring;
    103
    104	if (key_link(secondary_trusted_keys, machine_trusted_keys) < 0)
    105		panic("Can't link (machine) trusted keyrings\n");
    106}
    107
    108/**
    109 * restrict_link_by_builtin_secondary_and_machine - Restrict keyring addition.
    110 * @dest_keyring: Keyring being linked to.
    111 * @type: The type of key being added.
    112 * @payload: The payload of the new key.
    113 * @restrict_key: A ring of keys that can be used to vouch for the new cert.
    114 *
    115 * Restrict the addition of keys into a keyring based on the key-to-be-added
    116 * being vouched for by a key in either the built-in, the secondary, or
    117 * the machine keyrings.
    118 */
    119int restrict_link_by_builtin_secondary_and_machine(
    120	struct key *dest_keyring,
    121	const struct key_type *type,
    122	const union key_payload *payload,
    123	struct key *restrict_key)
    124{
    125	if (machine_trusted_keys && type == &key_type_keyring &&
    126	    dest_keyring == secondary_trusted_keys &&
    127	    payload == &machine_trusted_keys->payload)
    128		/* Allow the machine keyring to be added to the secondary */
    129		return 0;
    130
    131	return restrict_link_by_builtin_and_secondary_trusted(dest_keyring, type,
    132							      payload, restrict_key);
    133}
    134#endif
    135
    136/*
    137 * Create the trusted keyrings
    138 */
    139static __init int system_trusted_keyring_init(void)
    140{
    141	pr_notice("Initialise system trusted keyrings\n");
    142
    143	builtin_trusted_keys =
    144		keyring_alloc(".builtin_trusted_keys",
    145			      GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
    146			      ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
    147			      KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
    148			      KEY_ALLOC_NOT_IN_QUOTA,
    149			      NULL, NULL);
    150	if (IS_ERR(builtin_trusted_keys))
    151		panic("Can't allocate builtin trusted keyring\n");
    152
    153#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
    154	secondary_trusted_keys =
    155		keyring_alloc(".secondary_trusted_keys",
    156			      GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
    157			      ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
    158			       KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
    159			       KEY_USR_WRITE),
    160			      KEY_ALLOC_NOT_IN_QUOTA,
    161			      get_builtin_and_secondary_restriction(),
    162			      NULL);
    163	if (IS_ERR(secondary_trusted_keys))
    164		panic("Can't allocate secondary trusted keyring\n");
    165
    166	if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0)
    167		panic("Can't link trusted keyrings\n");
    168#endif
    169
    170	return 0;
    171}
    172
    173/*
    174 * Must be initialised before we try and load the keys into the keyring.
    175 */
    176device_initcall(system_trusted_keyring_init);
    177
    178__init int load_module_cert(struct key *keyring)
    179{
    180	if (!IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG))
    181		return 0;
    182
    183	pr_notice("Loading compiled-in module X.509 certificates\n");
    184
    185	return x509_load_certificate_list(system_certificate_list,
    186					  module_cert_size, keyring);
    187}
    188
    189/*
    190 * Load the compiled-in list of X.509 certificates.
    191 */
    192static __init int load_system_certificate_list(void)
    193{
    194	const u8 *p;
    195	unsigned long size;
    196
    197	pr_notice("Loading compiled-in X.509 certificates\n");
    198
    199#ifdef CONFIG_MODULE_SIG
    200	p = system_certificate_list;
    201	size = system_certificate_list_size;
    202#else
    203	p = system_certificate_list + module_cert_size;
    204	size = system_certificate_list_size - module_cert_size;
    205#endif
    206
    207	return x509_load_certificate_list(p, size, builtin_trusted_keys);
    208}
    209late_initcall(load_system_certificate_list);
    210
    211#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
    212
    213/**
    214 * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system data.
    215 * @data: The data to be verified (NULL if expecting internal data).
    216 * @len: Size of @data.
    217 * @pkcs7: The PKCS#7 message that is the signature.
    218 * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
    219 *					(void *)1UL for all trusted keys).
    220 * @usage: The use to which the key is being put.
    221 * @view_content: Callback to gain access to content.
    222 * @ctx: Context for callback.
    223 */
    224int verify_pkcs7_message_sig(const void *data, size_t len,
    225			     struct pkcs7_message *pkcs7,
    226			     struct key *trusted_keys,
    227			     enum key_being_used_for usage,
    228			     int (*view_content)(void *ctx,
    229						 const void *data, size_t len,
    230						 size_t asn1hdrlen),
    231			     void *ctx)
    232{
    233	int ret;
    234
    235	/* The data should be detached - so we need to supply it. */
    236	if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {
    237		pr_err("PKCS#7 signature with non-detached data\n");
    238		ret = -EBADMSG;
    239		goto error;
    240	}
    241
    242	ret = pkcs7_verify(pkcs7, usage);
    243	if (ret < 0)
    244		goto error;
    245
    246	if (!trusted_keys) {
    247		trusted_keys = builtin_trusted_keys;
    248	} else if (trusted_keys == VERIFY_USE_SECONDARY_KEYRING) {
    249#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
    250		trusted_keys = secondary_trusted_keys;
    251#else
    252		trusted_keys = builtin_trusted_keys;
    253#endif
    254	} else if (trusted_keys == VERIFY_USE_PLATFORM_KEYRING) {
    255#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
    256		trusted_keys = platform_trusted_keys;
    257#else
    258		trusted_keys = NULL;
    259#endif
    260		if (!trusted_keys) {
    261			ret = -ENOKEY;
    262			pr_devel("PKCS#7 platform keyring is not available\n");
    263			goto error;
    264		}
    265
    266		ret = is_key_on_revocation_list(pkcs7);
    267		if (ret != -ENOKEY) {
    268			pr_devel("PKCS#7 platform key is on revocation list\n");
    269			goto error;
    270		}
    271	}
    272	ret = pkcs7_validate_trust(pkcs7, trusted_keys);
    273	if (ret < 0) {
    274		if (ret == -ENOKEY)
    275			pr_devel("PKCS#7 signature not signed with a trusted key\n");
    276		goto error;
    277	}
    278
    279	if (view_content) {
    280		size_t asn1hdrlen;
    281
    282		ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);
    283		if (ret < 0) {
    284			if (ret == -ENODATA)
    285				pr_devel("PKCS#7 message does not contain data\n");
    286			goto error;
    287		}
    288
    289		ret = view_content(ctx, data, len, asn1hdrlen);
    290	}
    291
    292error:
    293	pr_devel("<==%s() = %d\n", __func__, ret);
    294	return ret;
    295}
    296
    297/**
    298 * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
    299 * @data: The data to be verified (NULL if expecting internal data).
    300 * @len: Size of @data.
    301 * @raw_pkcs7: The PKCS#7 message that is the signature.
    302 * @pkcs7_len: The size of @raw_pkcs7.
    303 * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
    304 *					(void *)1UL for all trusted keys).
    305 * @usage: The use to which the key is being put.
    306 * @view_content: Callback to gain access to content.
    307 * @ctx: Context for callback.
    308 */
    309int verify_pkcs7_signature(const void *data, size_t len,
    310			   const void *raw_pkcs7, size_t pkcs7_len,
    311			   struct key *trusted_keys,
    312			   enum key_being_used_for usage,
    313			   int (*view_content)(void *ctx,
    314					       const void *data, size_t len,
    315					       size_t asn1hdrlen),
    316			   void *ctx)
    317{
    318	struct pkcs7_message *pkcs7;
    319	int ret;
    320
    321	pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);
    322	if (IS_ERR(pkcs7))
    323		return PTR_ERR(pkcs7);
    324
    325	ret = verify_pkcs7_message_sig(data, len, pkcs7, trusted_keys, usage,
    326				       view_content, ctx);
    327
    328	pkcs7_free_message(pkcs7);
    329	pr_devel("<==%s() = %d\n", __func__, ret);
    330	return ret;
    331}
    332EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
    333
    334#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
    335
    336#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
    337void __init set_platform_trusted_keys(struct key *keyring)
    338{
    339	platform_trusted_keys = keyring;
    340}
    341#endif