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

restrict.c (8499B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* Instantiate a public key crypto key from an X.509 Certificate
      3 *
      4 * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#define pr_fmt(fmt) "ASYM: "fmt
      9#include <linux/module.h>
     10#include <linux/kernel.h>
     11#include <linux/err.h>
     12#include <crypto/public_key.h>
     13#include "asymmetric_keys.h"
     14
     15static bool use_builtin_keys;
     16static struct asymmetric_key_id *ca_keyid;
     17
     18#ifndef MODULE
     19static struct {
     20	struct asymmetric_key_id id;
     21	unsigned char data[10];
     22} cakey;
     23
     24static int __init ca_keys_setup(char *str)
     25{
     26	if (!str)		/* default system keyring */
     27		return 1;
     28
     29	if (strncmp(str, "id:", 3) == 0) {
     30		struct asymmetric_key_id *p = &cakey.id;
     31		size_t hexlen = (strlen(str) - 3) / 2;
     32		int ret;
     33
     34		if (hexlen == 0 || hexlen > sizeof(cakey.data)) {
     35			pr_err("Missing or invalid ca_keys id\n");
     36			return 1;
     37		}
     38
     39		ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);
     40		if (ret < 0)
     41			pr_err("Unparsable ca_keys id hex string\n");
     42		else
     43			ca_keyid = p;	/* owner key 'id:xxxxxx' */
     44	} else if (strcmp(str, "builtin") == 0) {
     45		use_builtin_keys = true;
     46	}
     47
     48	return 1;
     49}
     50__setup("ca_keys=", ca_keys_setup);
     51#endif
     52
     53/**
     54 * restrict_link_by_signature - Restrict additions to a ring of public keys
     55 * @dest_keyring: Keyring being linked to.
     56 * @type: The type of key being added.
     57 * @payload: The payload of the new key.
     58 * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
     59 *
     60 * Check the new certificate against the ones in the trust keyring.  If one of
     61 * those is the signing key and validates the new certificate, then mark the
     62 * new certificate as being trusted.
     63 *
     64 * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
     65 * matching parent certificate in the trusted list, -EKEYREJECTED if the
     66 * signature check fails or the key is blacklisted, -ENOPKG if the signature
     67 * uses unsupported crypto, or some other error if there is a matching
     68 * certificate but the signature check cannot be performed.
     69 */
     70int restrict_link_by_signature(struct key *dest_keyring,
     71			       const struct key_type *type,
     72			       const union key_payload *payload,
     73			       struct key *trust_keyring)
     74{
     75	const struct public_key_signature *sig;
     76	struct key *key;
     77	int ret;
     78
     79	pr_devel("==>%s()\n", __func__);
     80
     81	if (!trust_keyring)
     82		return -ENOKEY;
     83
     84	if (type != &key_type_asymmetric)
     85		return -EOPNOTSUPP;
     86
     87	sig = payload->data[asym_auth];
     88	if (!sig)
     89		return -ENOPKG;
     90	if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
     91		return -ENOKEY;
     92
     93	if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
     94		return -EPERM;
     95
     96	/* See if we have a key that signed this one. */
     97	key = find_asymmetric_key(trust_keyring,
     98				  sig->auth_ids[0], sig->auth_ids[1],
     99				  sig->auth_ids[2], false);
    100	if (IS_ERR(key))
    101		return -ENOKEY;
    102
    103	if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
    104		ret = -ENOKEY;
    105	else
    106		ret = verify_signature(key, sig);
    107	key_put(key);
    108	return ret;
    109}
    110
    111static bool match_either_id(const struct asymmetric_key_id **pair,
    112			    const struct asymmetric_key_id *single)
    113{
    114	return (asymmetric_key_id_same(pair[0], single) ||
    115		asymmetric_key_id_same(pair[1], single));
    116}
    117
    118static int key_or_keyring_common(struct key *dest_keyring,
    119				 const struct key_type *type,
    120				 const union key_payload *payload,
    121				 struct key *trusted, bool check_dest)
    122{
    123	const struct public_key_signature *sig;
    124	struct key *key = NULL;
    125	int ret;
    126
    127	pr_devel("==>%s()\n", __func__);
    128
    129	if (!dest_keyring)
    130		return -ENOKEY;
    131	else if (dest_keyring->type != &key_type_keyring)
    132		return -EOPNOTSUPP;
    133
    134	if (!trusted && !check_dest)
    135		return -ENOKEY;
    136
    137	if (type != &key_type_asymmetric)
    138		return -EOPNOTSUPP;
    139
    140	sig = payload->data[asym_auth];
    141	if (!sig)
    142		return -ENOPKG;
    143	if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
    144		return -ENOKEY;
    145
    146	if (trusted) {
    147		if (trusted->type == &key_type_keyring) {
    148			/* See if we have a key that signed this one. */
    149			key = find_asymmetric_key(trusted, sig->auth_ids[0],
    150						  sig->auth_ids[1],
    151						  sig->auth_ids[2], false);
    152			if (IS_ERR(key))
    153				key = NULL;
    154		} else if (trusted->type == &key_type_asymmetric) {
    155			const struct asymmetric_key_id **signer_ids;
    156
    157			signer_ids = (const struct asymmetric_key_id **)
    158				asymmetric_key_ids(trusted)->id;
    159
    160			/*
    161			 * The auth_ids come from the candidate key (the
    162			 * one that is being considered for addition to
    163			 * dest_keyring) and identify the key that was
    164			 * used to sign.
    165			 *
    166			 * The signer_ids are identifiers for the
    167			 * signing key specified for dest_keyring.
    168			 *
    169			 * The first auth_id is the preferred id, 2nd and
    170			 * 3rd are the fallbacks. If exactly one of
    171			 * auth_ids[0] and auth_ids[1] is present, it may
    172			 * match either signer_ids[0] or signed_ids[1].
    173			 * If both are present the first one may match
    174			 * either signed_id but the second one must match
    175			 * the second signer_id. If neither of them is
    176			 * available, auth_ids[2] is matched against
    177			 * signer_ids[2] as a fallback.
    178			 */
    179			if (!sig->auth_ids[0] && !sig->auth_ids[1]) {
    180				if (asymmetric_key_id_same(signer_ids[2],
    181							   sig->auth_ids[2]))
    182					key = __key_get(trusted);
    183
    184			} else if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
    185				const struct asymmetric_key_id *auth_id;
    186
    187				auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
    188				if (match_either_id(signer_ids, auth_id))
    189					key = __key_get(trusted);
    190
    191			} else if (asymmetric_key_id_same(signer_ids[1],
    192							  sig->auth_ids[1]) &&
    193				   match_either_id(signer_ids,
    194						   sig->auth_ids[0])) {
    195				key = __key_get(trusted);
    196			}
    197		} else {
    198			return -EOPNOTSUPP;
    199		}
    200	}
    201
    202	if (check_dest && !key) {
    203		/* See if the destination has a key that signed this one. */
    204		key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
    205					  sig->auth_ids[1], sig->auth_ids[2],
    206					  false);
    207		if (IS_ERR(key))
    208			key = NULL;
    209	}
    210
    211	if (!key)
    212		return -ENOKEY;
    213
    214	ret = key_validate(key);
    215	if (ret == 0)
    216		ret = verify_signature(key, sig);
    217
    218	key_put(key);
    219	return ret;
    220}
    221
    222/**
    223 * restrict_link_by_key_or_keyring - Restrict additions to a ring of public
    224 * keys using the restrict_key information stored in the ring.
    225 * @dest_keyring: Keyring being linked to.
    226 * @type: The type of key being added.
    227 * @payload: The payload of the new key.
    228 * @trusted: A key or ring of keys that can be used to vouch for the new cert.
    229 *
    230 * Check the new certificate only against the key or keys passed in the data
    231 * parameter. If one of those is the signing key and validates the new
    232 * certificate, then mark the new certificate as being ok to link.
    233 *
    234 * Returns 0 if the new certificate was accepted, -ENOKEY if we
    235 * couldn't find a matching parent certificate in the trusted list,
    236 * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
    237 * unsupported crypto, or some other error if there is a matching certificate
    238 * but the signature check cannot be performed.
    239 */
    240int restrict_link_by_key_or_keyring(struct key *dest_keyring,
    241				    const struct key_type *type,
    242				    const union key_payload *payload,
    243				    struct key *trusted)
    244{
    245	return key_or_keyring_common(dest_keyring, type, payload, trusted,
    246				     false);
    247}
    248
    249/**
    250 * restrict_link_by_key_or_keyring_chain - Restrict additions to a ring of
    251 * public keys using the restrict_key information stored in the ring.
    252 * @dest_keyring: Keyring being linked to.
    253 * @type: The type of key being added.
    254 * @payload: The payload of the new key.
    255 * @trusted: A key or ring of keys that can be used to vouch for the new cert.
    256 *
    257 * Check the new certificate against the key or keys passed in the data
    258 * parameter and against the keys already linked to the destination keyring. If
    259 * one of those is the signing key and validates the new certificate, then mark
    260 * the new certificate as being ok to link.
    261 *
    262 * Returns 0 if the new certificate was accepted, -ENOKEY if we
    263 * couldn't find a matching parent certificate in the trusted list,
    264 * -EKEYREJECTED if the signature check fails, -ENOPKG if the signature uses
    265 * unsupported crypto, or some other error if there is a matching certificate
    266 * but the signature check cannot be performed.
    267 */
    268int restrict_link_by_key_or_keyring_chain(struct key *dest_keyring,
    269					  const struct key_type *type,
    270					  const union key_payload *payload,
    271					  struct key *trusted)
    272{
    273	return key_or_keyring_common(dest_keyring, type, payload, trusted,
    274				     true);
    275}