···823823 A process must have search permission on the key for this function to be824824 successful.825825826826+ (*) Compute a Diffie-Hellman shared secret or public key827827+828828+ long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,829829+ char *buffer, size_t buflen);830830+831831+ The params struct contains serial numbers for three keys:832832+833833+ - The prime, p, known to both parties834834+ - The local private key835835+ - The base integer, which is either a shared generator or the836836+ remote public key837837+838838+ The value computed is:839839+840840+ result = base ^ private (mod prime)841841+842842+ If the base is the shared generator, the result is the local843843+ public key. If the base is the remote public key, the result is844844+ the shared secret.845845+846846+ The buffer length must be at least the length of the prime, or zero.847847+848848+ If the buffer length is nonzero, the length of the result is849849+ returned when it is successfully calculated and copied in to the850850+ buffer. When the buffer length is zero, the minimum required851851+ buffer length is returned.852852+853853+ This function will return error EOPNOTSUPP if the key type is not854854+ supported, error ENOKEY if the key could not be found, or error855855+ EACCES if the key is not readable by the caller.826856827857===============828858KERNEL SERVICES···1029999 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,10301000 const struct cred *cred,10311001 key_perm_t perm,10021002+ int (*restrict_link)(struct key *,10031003+ const struct key_type *,10041004+ unsigned long,10051005+ const union key_payload *),10321006 unsigned long flags,10331007 struct key *dest);10341008···10431009 Error EDQUOT can be returned if the keyring would overload the quota (pass10441010 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted10451011 towards the user's quota). Error ENOMEM can also be returned.10121012+10131013+ If restrict_link not NULL, it should point to a function that will be10141014+ called each time an attempt is made to link a key into the new keyring.10151015+ This function is called to check whether a key may be added into the keying10161016+ or not. Callers of key_create_or_update() within the kernel can pass10171017+ KEY_ALLOC_BYPASS_RESTRICTION to suppress the check. An example of using10181018+ this is to manage rings of cryptographic keys that are set up when the10191019+ kernel boots where userspace is also permitted to add keys - provided they10201020+ can be verified by a key the kernel already has.10211021+10221022+ When called, the restriction function will be passed the keyring being10231023+ added to, the key flags value and the type and payload of the key being10241024+ added. Note that when a new key is being created, this is called between10251025+ payload preparsing and actual key creation. The function should return 010261026+ to allow the link or an error to reject it.10271027+10281028+ A convenience function, restrict_link_reject, exists to always return10291029+ -EPERM to in this case.104610301047103110481032(*) To check the validity of a key, this function can be called:
+4-14
arch/x86/kernel/kexec-bzimage64.c
···1919#include <linux/kernel.h>2020#include <linux/mm.h>2121#include <linux/efi.h>2222-#include <linux/verify_pefile.h>2323-#include <keys/system_keyring.h>2222+#include <linux/verification.h>24232524#include <asm/bootparam.h>2625#include <asm/setup.h>···528529#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG529530static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)530531{531531- bool trusted;532532- int ret;533533-534534- ret = verify_pefile_signature(kernel, kernel_len,535535- system_trusted_keyring,536536- VERIFYING_KEXEC_PE_SIGNATURE,537537- &trusted);538538- if (ret < 0)539539- return ret;540540- if (!trusted)541541- return -EKEYREJECTED;542542- return 0;532532+ return verify_pefile_signature(kernel, kernel_len,533533+ NULL,534534+ VERIFYING_KEXEC_PE_SIGNATURE);543535}544536#endif545537
+9
certs/Kconfig
···1717config SYSTEM_TRUSTED_KEYRING1818 bool "Provide system-wide ring of trusted keys"1919 depends on KEYS2020+ depends on ASYMMETRIC_KEY_TYPE2021 help2122 Provide a system keyring to which trusted keys can be added. Keys in2223 the keyring are considered to be trusted. Keys may be added at will···5554 help5655 This is the number of bytes reserved in the kernel image for a5756 certificate to be inserted.5757+5858+config SECONDARY_TRUSTED_KEYRING5959+ bool "Provide a keyring to which extra trustable keys may be added"6060+ depends on SYSTEM_TRUSTED_KEYRING6161+ help6262+ If set, provide a keyring to which extra keys may be added, provided6363+ those keys are not blacklisted and are vouched for by a key built6464+ into the kernel or already in the secondary trusted keyring.58655966endmenu
+113-26
certs/system_keyring.c
···1818#include <keys/system_keyring.h>1919#include <crypto/pkcs7.h>20202121-struct key *system_trusted_keyring;2222-EXPORT_SYMBOL_GPL(system_trusted_keyring);2121+static struct key *builtin_trusted_keys;2222+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING2323+static struct key *secondary_trusted_keys;2424+#endif23252426extern __initconst const u8 system_certificate_list[];2527extern __initconst const unsigned long system_certificate_list_size;26282929+/**3030+ * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA3131+ *3232+ * Restrict the addition of keys into a keyring based on the key-to-be-added3333+ * being vouched for by a key in the built in system keyring.3434+ */3535+int restrict_link_by_builtin_trusted(struct key *keyring,3636+ const struct key_type *type,3737+ const union key_payload *payload)3838+{3939+ return restrict_link_by_signature(builtin_trusted_keys, type, payload);4040+}4141+4242+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING4343+/**4444+ * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring4545+ * addition by both builtin and secondary keyrings4646+ *4747+ * Restrict the addition of keys into a keyring based on the key-to-be-added4848+ * being vouched for by a key in either the built-in or the secondary system4949+ * keyrings.5050+ */5151+int restrict_link_by_builtin_and_secondary_trusted(5252+ struct key *keyring,5353+ const struct key_type *type,5454+ const union key_payload *payload)5555+{5656+ /* If we have a secondary trusted keyring, then that contains a link5757+ * through to the builtin keyring and the search will follow that link.5858+ */5959+ if (type == &key_type_keyring &&6060+ keyring == secondary_trusted_keys &&6161+ payload == &builtin_trusted_keys->payload)6262+ /* Allow the builtin keyring to be added to the secondary */6363+ return 0;6464+6565+ return restrict_link_by_signature(secondary_trusted_keys, type, payload);6666+}6767+#endif6868+2769/*2828- * Load the compiled-in keys7070+ * Create the trusted keyrings2971 */3072static __init int system_trusted_keyring_init(void)3173{3232- pr_notice("Initialise system trusted keyring\n");7474+ pr_notice("Initialise system trusted keyrings\n");33753434- system_trusted_keyring =3535- keyring_alloc(".system_keyring",7676+ builtin_trusted_keys =7777+ keyring_alloc(".builtin_trusted_keys",3678 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),3779 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |3880 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),3939- KEY_ALLOC_NOT_IN_QUOTA, NULL);4040- if (IS_ERR(system_trusted_keyring))4141- panic("Can't allocate system trusted keyring\n");8181+ KEY_ALLOC_NOT_IN_QUOTA,8282+ NULL, NULL);8383+ if (IS_ERR(builtin_trusted_keys))8484+ panic("Can't allocate builtin trusted keyring\n");42854343- set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);8686+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING8787+ secondary_trusted_keys =8888+ keyring_alloc(".secondary_trusted_keys",8989+ KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),9090+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |9191+ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |9292+ KEY_USR_WRITE),9393+ KEY_ALLOC_NOT_IN_QUOTA,9494+ restrict_link_by_builtin_and_secondary_trusted,9595+ NULL);9696+ if (IS_ERR(secondary_trusted_keys))9797+ panic("Can't allocate secondary trusted keyring\n");9898+9999+ if (key_link(secondary_trusted_keys, builtin_trusted_keys) < 0)100100+ panic("Can't link trusted keyrings\n");101101+#endif102102+44103 return 0;45104}46105···13576 if (plen > end - p)13677 goto dodgy_cert;13778138138- key = key_create_or_update(make_key_ref(system_trusted_keyring, 1),7979+ key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1),13980 "asymmetric",14081 NULL,14182 p,···14384 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |14485 KEY_USR_VIEW | KEY_USR_READ),14586 KEY_ALLOC_NOT_IN_QUOTA |146146- KEY_ALLOC_TRUSTED |147147- KEY_ALLOC_BUILT_IN);8787+ KEY_ALLOC_BUILT_IN |8888+ KEY_ALLOC_BYPASS_RESTRICTION);14889 if (IS_ERR(key)) {14990 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",15091 PTR_ERR(key));···167108#ifdef CONFIG_SYSTEM_DATA_VERIFICATION168109169110/**170170- * Verify a PKCS#7-based signature on system data.171171- * @data: The data to be verified.111111+ * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.112112+ * @data: The data to be verified (NULL if expecting internal data).172113 * @len: Size of @data.173114 * @raw_pkcs7: The PKCS#7 message that is the signature.174115 * @pkcs7_len: The size of @raw_pkcs7.116116+ * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,117117+ * (void *)1UL for all trusted keys).175118 * @usage: The use to which the key is being put.119119+ * @view_content: Callback to gain access to content.120120+ * @ctx: Context for callback.176121 */177177-int system_verify_data(const void *data, unsigned long len,178178- const void *raw_pkcs7, size_t pkcs7_len,179179- enum key_being_used_for usage)122122+int verify_pkcs7_signature(const void *data, size_t len,123123+ const void *raw_pkcs7, size_t pkcs7_len,124124+ struct key *trusted_keys,125125+ enum key_being_used_for usage,126126+ int (*view_content)(void *ctx,127127+ const void *data, size_t len,128128+ size_t asn1hdrlen),129129+ void *ctx)180130{181131 struct pkcs7_message *pkcs7;182182- bool trusted;183132 int ret;184133185134 pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len);···195128 return PTR_ERR(pkcs7);196129197130 /* The data should be detached - so we need to supply it. */198198- if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) {131131+ if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) {199132 pr_err("PKCS#7 signature with non-detached data\n");200133 ret = -EBADMSG;201134 goto error;···205138 if (ret < 0)206139 goto error;207140208208- ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);209209- if (ret < 0)141141+ if (!trusted_keys) {142142+ trusted_keys = builtin_trusted_keys;143143+ } else if (trusted_keys == (void *)1UL) {144144+#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING145145+ trusted_keys = secondary_trusted_keys;146146+#else147147+ trusted_keys = builtin_trusted_keys;148148+#endif149149+ }150150+ ret = pkcs7_validate_trust(pkcs7, trusted_keys);151151+ if (ret < 0) {152152+ if (ret == -ENOKEY)153153+ pr_err("PKCS#7 signature not signed with a trusted key\n");210154 goto error;155155+ }211156212212- if (!trusted) {213213- pr_err("PKCS#7 signature not signed with a trusted key\n");214214- ret = -ENOKEY;157157+ if (view_content) {158158+ size_t asn1hdrlen;159159+160160+ ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen);161161+ if (ret < 0) {162162+ if (ret == -ENODATA)163163+ pr_devel("PKCS#7 message does not contain data\n");164164+ goto error;165165+ }166166+167167+ ret = view_content(ctx, data, len, asn1hdrlen);215168 }216169217170error:···239152 pr_devel("<==%s() = %d\n", __func__, ret);240153 return ret;241154}242242-EXPORT_SYMBOL_GPL(system_verify_data);155155+EXPORT_SYMBOL_GPL(verify_pkcs7_signature);243156244157#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
+3-3
crypto/asymmetric_keys/Kconfig
···11menuconfig ASYMMETRIC_KEY_TYPE22- tristate "Asymmetric (public-key cryptographic) key type"22+ bool "Asymmetric (public-key cryptographic) key type"33 depends on KEYS44 help55 This option provides support for a key type that holds the data for···40404141config PKCS7_TEST_KEY4242 tristate "PKCS#7 testing key type"4343- depends on PKCS7_MESSAGE_PARSER4444- select SYSTEM_TRUSTED_KEYRING4343+ depends on SYSTEM_DATA_VERIFICATION4544 help4645 This option provides a type of key that can be loaded up from a4746 PKCS#7 message - provided the message is signed by a trusted key. If···5354config SIGNED_PE_FILE_VERIFICATION5455 bool "Support for PE file signature verification"5556 depends on PKCS7_MESSAGE_PARSER=y5757+ depends on SYSTEM_DATA_VERIFICATION5658 select ASN15759 select OID_REGISTRY5860 help
···99 * 2 of the Licence, or (at your option) any later version.1010 */11111212+#include <keys/asymmetric-type.h>1313+1214extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id);13151416extern int __asymmetric_key_hex_to_key_id(const char *id,
+94-2
crypto/asymmetric_keys/asymmetric_type.c
···3535static DECLARE_RWSEM(asymmetric_key_parsers_sem);36363737/**3838+ * find_asymmetric_key - Find a key by ID.3939+ * @keyring: The keys to search.4040+ * @id_0: The first ID to look for or NULL.4141+ * @id_1: The second ID to look for or NULL.4242+ * @partial: Use partial match if true, exact if false.4343+ *4444+ * Find a key in the given keyring by identifier. The preferred identifier is4545+ * the id_0 and the fallback identifier is the id_1. If both are given, the4646+ * lookup is by the former, but the latter must also match.4747+ */4848+struct key *find_asymmetric_key(struct key *keyring,4949+ const struct asymmetric_key_id *id_0,5050+ const struct asymmetric_key_id *id_1,5151+ bool partial)5252+{5353+ struct key *key;5454+ key_ref_t ref;5555+ const char *lookup;5656+ char *req, *p;5757+ int len;5858+5959+ if (id_0) {6060+ lookup = id_0->data;6161+ len = id_0->len;6262+ } else {6363+ lookup = id_1->data;6464+ len = id_1->len;6565+ }6666+6767+ /* Construct an identifier "id:<keyid>". */6868+ p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);6969+ if (!req)7070+ return ERR_PTR(-ENOMEM);7171+7272+ if (partial) {7373+ *p++ = 'i';7474+ *p++ = 'd';7575+ } else {7676+ *p++ = 'e';7777+ *p++ = 'x';7878+ }7979+ *p++ = ':';8080+ p = bin2hex(p, lookup, len);8181+ *p = 0;8282+8383+ pr_debug("Look up: \"%s\"\n", req);8484+8585+ ref = keyring_search(make_key_ref(keyring, 1),8686+ &key_type_asymmetric, req);8787+ if (IS_ERR(ref))8888+ pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));8989+ kfree(req);9090+9191+ if (IS_ERR(ref)) {9292+ switch (PTR_ERR(ref)) {9393+ /* Hide some search errors */9494+ case -EACCES:9595+ case -ENOTDIR:9696+ case -EAGAIN:9797+ return ERR_PTR(-ENOKEY);9898+ default:9999+ return ERR_CAST(ref);100100+ }101101+ }102102+103103+ key = key_ref_to_ptr(ref);104104+ if (id_0 && id_1) {105105+ const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);106106+107107+ if (!kids->id[0]) {108108+ pr_debug("First ID matches, but second is missing\n");109109+ goto reject;110110+ }111111+ if (!asymmetric_key_id_same(id_1, kids->id[1])) {112112+ pr_debug("First ID matches, but second does not\n");113113+ goto reject;114114+ }115115+ }116116+117117+ pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));118118+ return key;119119+120120+reject:121121+ key_put(key);122122+ return ERR_PTR(-EKEYREJECTED);123123+}124124+EXPORT_SYMBOL_GPL(find_asymmetric_key);125125+126126+/**38127 * asymmetric_key_generate_id: Construct an asymmetric key ID39128 * @val_1: First binary blob40129 * @len_1: Length of first binary blob···420331 pr_devel("==>%s()\n", __func__);421332422333 if (subtype) {423423- subtype->destroy(prep->payload.data[asym_crypto]);334334+ subtype->destroy(prep->payload.data[asym_crypto],335335+ prep->payload.data[asym_auth]);424336 module_put(subtype->owner);425337 }426338 asymmetric_key_free_kids(kids);···436346 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);437347 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids];438348 void *data = key->payload.data[asym_crypto];349349+ void *auth = key->payload.data[asym_auth];439350440351 key->payload.data[asym_crypto] = NULL;441352 key->payload.data[asym_subtype] = NULL;442353 key->payload.data[asym_key_ids] = NULL;354354+ key->payload.data[asym_auth] = NULL;443355444356 if (subtype) {445445- subtype->destroy(data);357357+ subtype->destroy(data, auth);446358 module_put(subtype->owner);447359 }448360
···1313#include <linux/key.h>1414#include <linux/err.h>1515#include <linux/module.h>1616+#include <linux/verification.h>1617#include <linux/key-type.h>1717-#include <keys/asymmetric-type.h>1818-#include <crypto/pkcs7.h>1918#include <keys/user-type.h>2020-#include <keys/system_keyring.h>2121-#include "pkcs7_parser.h"22192320MODULE_LICENSE("GPL");2421MODULE_DESCRIPTION("PKCS#7 testing key type");···2629 "Usage to specify when verifying the PKCS#7 message");27302831/*3232+ * Retrieve the PKCS#7 message content.3333+ */3434+static int pkcs7_view_content(void *ctx, const void *data, size_t len,3535+ size_t asn1hdrlen)3636+{3737+ struct key_preparsed_payload *prep = ctx;3838+ const void *saved_prep_data;3939+ size_t saved_prep_datalen;4040+ int ret;4141+4242+ saved_prep_data = prep->data;4343+ saved_prep_datalen = prep->datalen;4444+ prep->data = data;4545+ prep->datalen = len;4646+4747+ ret = user_preparse(prep);4848+4949+ prep->data = saved_prep_data;5050+ prep->datalen = saved_prep_datalen;5151+ return ret;5252+}5353+5454+/*2955 * Preparse a PKCS#7 wrapped and validated data blob.3056 */3157static int pkcs7_preparse(struct key_preparsed_payload *prep)3258{3359 enum key_being_used_for usage = pkcs7_usage;3434- struct pkcs7_message *pkcs7;3535- const void *data, *saved_prep_data;3636- size_t datalen, saved_prep_datalen;3737- bool trusted;3838- int ret;3939-4040- kenter("");41604261 if (usage >= NR__KEY_BEING_USED_FOR) {4362 pr_err("Invalid usage type %d\n", usage);4463 return -EINVAL;4564 }46654747- saved_prep_data = prep->data;4848- saved_prep_datalen = prep->datalen;4949- pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen);5050- if (IS_ERR(pkcs7)) {5151- ret = PTR_ERR(pkcs7);5252- goto error;5353- }5454-5555- ret = pkcs7_verify(pkcs7, usage);5656- if (ret < 0)5757- goto error_free;5858-5959- ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted);6060- if (ret < 0)6161- goto error_free;6262- if (!trusted)6363- pr_warn("PKCS#7 message doesn't chain back to a trusted key\n");6464-6565- ret = pkcs7_get_content_data(pkcs7, &data, &datalen, false);6666- if (ret < 0)6767- goto error_free;6868-6969- prep->data = data;7070- prep->datalen = datalen;7171- ret = user_preparse(prep);7272- prep->data = saved_prep_data;7373- prep->datalen = saved_prep_datalen;7474-7575-error_free:7676- pkcs7_free_message(pkcs7);7777-error:7878- kleave(" = %d", ret);7979- return ret;6666+ return verify_pkcs7_signature(NULL, 0,6767+ prep->data, prep->datalen,6868+ NULL, usage,6969+ pkcs7_view_content, prep);8070}81718272/*
+34-25
crypto/asymmetric_keys/pkcs7_parser.c
···4444static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)4545{4646 if (sinfo) {4747- kfree(sinfo->sig.s);4848- kfree(sinfo->sig.digest);4949- kfree(sinfo->signing_cert_id);4747+ public_key_signature_free(sinfo->sig);5048 kfree(sinfo);5149 }5250}···123125 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);124126 if (!ctx->sinfo)125127 goto out_no_sinfo;128128+ ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),129129+ GFP_KERNEL);130130+ if (!ctx->sinfo->sig)131131+ goto out_no_sig;126132127133 ctx->data = (unsigned long)data;128134 ctx->ppcerts = &ctx->certs;···152150 ctx->certs = cert->next;153151 x509_free_certificate(cert);154152 }153153+out_no_sig:155154 pkcs7_free_signed_info(ctx->sinfo);156155out_no_sinfo:157156 pkcs7_free_message(ctx->msg);···168165 * @pkcs7: The preparsed PKCS#7 message to access169166 * @_data: Place to return a pointer to the data170167 * @_data_len: Place to return the data length171171- * @want_wrapper: True if the ASN.1 object header should be included in the data168168+ * @_headerlen: Size of ASN.1 header not included in _data172169 *173173- * Get access to the data content of the PKCS#7 message, including, optionally,174174- * the header of the ASN.1 object that contains it. Returns -ENODATA if the175175- * data object was missing from the message.170170+ * Get access to the data content of the PKCS#7 message. The size of the171171+ * header of the ASN.1 object that contains it is also provided and can be used172172+ * to adjust *_data and *_data_len to get the entire object.173173+ *174174+ * Returns -ENODATA if the data object was missing from the message.176175 */177176int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,178177 const void **_data, size_t *_data_len,179179- bool want_wrapper)178178+ size_t *_headerlen)180179{181181- size_t wrapper;182182-183180 if (!pkcs7->data)184181 return -ENODATA;185182186186- wrapper = want_wrapper ? pkcs7->data_hdrlen : 0;187187- *_data = pkcs7->data - wrapper;188188- *_data_len = pkcs7->data_len + wrapper;183183+ *_data = pkcs7->data;184184+ *_data_len = pkcs7->data_len;185185+ if (_headerlen)186186+ *_headerlen = pkcs7->data_hdrlen;189187 return 0;190188}191189EXPORT_SYMBOL_GPL(pkcs7_get_content_data);···222218223219 switch (ctx->last_oid) {224220 case OID_md4:225225- ctx->sinfo->sig.hash_algo = "md4";221221+ ctx->sinfo->sig->hash_algo = "md4";226222 break;227223 case OID_md5:228228- ctx->sinfo->sig.hash_algo = "md5";224224+ ctx->sinfo->sig->hash_algo = "md5";229225 break;230226 case OID_sha1:231231- ctx->sinfo->sig.hash_algo = "sha1";227227+ ctx->sinfo->sig->hash_algo = "sha1";232228 break;233229 case OID_sha256:234234- ctx->sinfo->sig.hash_algo = "sha256";230230+ ctx->sinfo->sig->hash_algo = "sha256";235231 break;236232 case OID_sha384:237237- ctx->sinfo->sig.hash_algo = "sha384";233233+ ctx->sinfo->sig->hash_algo = "sha384";238234 break;239235 case OID_sha512:240240- ctx->sinfo->sig.hash_algo = "sha512";236236+ ctx->sinfo->sig->hash_algo = "sha512";241237 break;242238 case OID_sha224:243243- ctx->sinfo->sig.hash_algo = "sha224";239239+ ctx->sinfo->sig->hash_algo = "sha224";240240+ break;244241 default:245242 printk("Unsupported digest algo: %u\n", ctx->last_oid);246243 return -ENOPKG;···260255261256 switch (ctx->last_oid) {262257 case OID_rsaEncryption:263263- ctx->sinfo->sig.pkey_algo = "rsa";258258+ ctx->sinfo->sig->pkey_algo = "rsa";264259 break;265260 default:266261 printk("Unsupported pkey algo: %u\n", ctx->last_oid);···620615{621616 struct pkcs7_parse_context *ctx = context;622617623623- ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL);624624- if (!ctx->sinfo->sig.s)618618+ ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);619619+ if (!ctx->sinfo->sig->s)625620 return -ENOMEM;626621627627- ctx->sinfo->sig.s_size = vlen;622622+ ctx->sinfo->sig->s_size = vlen;628623 return 0;629624}630625···660655661656 pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);662657663663- sinfo->signing_cert_id = kid;658658+ sinfo->sig->auth_ids[0] = kid;664659 sinfo->index = ++ctx->sinfo_index;665660 *ctx->ppsinfo = sinfo;666661 ctx->ppsinfo = &sinfo->next;667662 ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);668663 if (!ctx->sinfo)664664+ return -ENOMEM;665665+ ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),666666+ GFP_KERNEL);667667+ if (!ctx->sinfo->sig)669668 return -ENOMEM;670669 return 0;671670}
+4-7
crypto/asymmetric_keys/pkcs7_parser.h
···2222 struct pkcs7_signed_info *next;2323 struct x509_certificate *signer; /* Signing certificate (in msg->certs) */2424 unsigned index;2525- bool trusted;2625 bool unsupported_crypto; /* T if not usable due to missing crypto */27262827 /* Message digest - the digest of the Content Data (or NULL) */···4041#define sinfo_has_ms_statement_type 54142 time64_t signing_time;42434343- /* Issuing cert serial number and issuer's name [PKCS#7 or CMS ver 1]4444- * or issuing cert's SKID [CMS ver 3].4545- */4646- struct asymmetric_key_id *signing_cert_id;4747-4844 /* Message signature.4945 *5046 * This contains the generated digest of _either_ the Content Data or5147 * the Authenticated Attributes [RFC2315 9.3]. If the latter, one of5248 * the attributes contains the digest of the the Content Data within5349 * it.5050+ *5151+ * THis also contains the issuing cert serial number and issuer's name5252+ * [PKCS#7 or CMS ver 1] or issuing cert's SKID [CMS ver 3].5453 */5555- struct public_key_signature sig;5454+ struct public_key_signature *sig;5655};57565857struct pkcs7_message {
+14-29
crypto/asymmetric_keys/pkcs7_trust.c
···2727 struct pkcs7_signed_info *sinfo,2828 struct key *trust_keyring)2929{3030- struct public_key_signature *sig = &sinfo->sig;3030+ struct public_key_signature *sig = sinfo->sig;3131 struct x509_certificate *x509, *last = NULL, *p;3232 struct key *key;3333- bool trusted;3433 int ret;35343635 kenter(",%u,", sinfo->index);···41424243 for (x509 = sinfo->signer; x509; x509 = x509->signer) {4344 if (x509->seen) {4444- if (x509->verified) {4545- trusted = x509->trusted;4545+ if (x509->verified)4646 goto verified;4747- }4847 kleave(" = -ENOKEY [cached]");4948 return -ENOKEY;5049 }···5154 /* Look to see if this certificate is present in the trusted5255 * keys.5356 */5454- key = x509_request_asymmetric_key(trust_keyring,5555- x509->id, x509->skid,5656- false);5757+ key = find_asymmetric_key(trust_keyring,5858+ x509->id, x509->skid, false);5759 if (!IS_ERR(key)) {5860 /* One of the X.509 certificates in the PKCS#7 message5961 * is apparently the same as one we already trust.···76807781 might_sleep();7882 last = x509;7979- sig = &last->sig;8383+ sig = last->sig;8084 }81858286 /* No match - see if the root certificate has a signer amongst the8387 * trusted keys.8488 */8585- if (last && (last->akid_id || last->akid_skid)) {8686- key = x509_request_asymmetric_key(trust_keyring,8787- last->akid_id,8888- last->akid_skid,8989- false);8989+ if (last && (last->sig->auth_ids[0] || last->sig->auth_ids[1])) {9090+ key = find_asymmetric_key(trust_keyring,9191+ last->sig->auth_ids[0],9292+ last->sig->auth_ids[1],9393+ false);9094 if (!IS_ERR(key)) {9195 x509 = last;9296 pr_devel("sinfo %u: Root cert %u signer is key %x\n",···100104 /* As a last resort, see if we have a trusted public key that matches101105 * the signed info directly.102106 */103103- key = x509_request_asymmetric_key(trust_keyring,104104- sinfo->signing_cert_id,105105- NULL,106106- false);107107+ key = find_asymmetric_key(trust_keyring,108108+ sinfo->sig->auth_ids[0], NULL, false);107109 if (!IS_ERR(key)) {108110 pr_devel("sinfo %u: Direct signer is key %x\n",109111 sinfo->index, key_serial(key));···116122117123matched:118124 ret = verify_signature(key, sig);119119- trusted = test_bit(KEY_FLAG_TRUSTED, &key->flags);120125 key_put(key);121126 if (ret < 0) {122127 if (ret == -ENOMEM)···127134verified:128135 if (x509) {129136 x509->verified = true;130130- for (p = sinfo->signer; p != x509; p = p->signer) {137137+ for (p = sinfo->signer; p != x509; p = p->signer)131138 p->verified = true;132132- p->trusted = trusted;133133- }134139 }135135- sinfo->trusted = trusted;136140 kleave(" = 0");137141 return 0;138142}···138148 * pkcs7_validate_trust - Validate PKCS#7 trust chain139149 * @pkcs7: The PKCS#7 certificate to validate140150 * @trust_keyring: Signing certificates to use as starting points141141- * @_trusted: Set to true if trustworth, false otherwise142151 *143152 * Validate that the certificate chain inside the PKCS#7 message intersects144153 * keys we already know and trust.···159170 * May also return -ENOMEM.160171 */161172int pkcs7_validate_trust(struct pkcs7_message *pkcs7,162162- struct key *trust_keyring,163163- bool *_trusted)173173+ struct key *trust_keyring)164174{165175 struct pkcs7_signed_info *sinfo;166176 struct x509_certificate *p;167177 int cached_ret = -ENOKEY;168178 int ret;169169-170170- *_trusted = false;171179172180 for (p = pkcs7->certs; p; p = p->next)173181 p->seen = false;···179193 cached_ret = -ENOPKG;180194 continue;181195 case 0:182182- *_trusted |= sinfo->trusted;183196 cached_ret = 0;184197 continue;185198 default:
+46-61
crypto/asymmetric_keys/pkcs7_verify.c
···2525static int pkcs7_digest(struct pkcs7_message *pkcs7,2626 struct pkcs7_signed_info *sinfo)2727{2828+ struct public_key_signature *sig = sinfo->sig;2829 struct crypto_shash *tfm;2930 struct shash_desc *desc;3030- size_t digest_size, desc_size;3131- void *digest;3131+ size_t desc_size;3232 int ret;33333434- kenter(",%u,%s", sinfo->index, sinfo->sig.hash_algo);3434+ kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);35353636- if (!sinfo->sig.hash_algo)3636+ if (!sinfo->sig->hash_algo)3737 return -ENOPKG;38383939 /* Allocate the hashing algorithm we're going to need and find out how4040 * big the hash operational data will be.4141 */4242- tfm = crypto_alloc_shash(sinfo->sig.hash_algo, 0, 0);4242+ tfm = crypto_alloc_shash(sinfo->sig->hash_algo, 0, 0);4343 if (IS_ERR(tfm))4444 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);45454646 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);4747- sinfo->sig.digest_size = digest_size = crypto_shash_digestsize(tfm);4747+ sig->digest_size = crypto_shash_digestsize(tfm);48484949 ret = -ENOMEM;5050- digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,5151- GFP_KERNEL);5252- if (!digest)5050+ sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);5151+ if (!sig->digest)5352 goto error_no_desc;54535555- desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));5454+ desc = kzalloc(desc_size, GFP_KERNEL);5555+ if (!desc)5656+ goto error_no_desc;5757+5658 desc->tfm = tfm;5759 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;5860···6260 ret = crypto_shash_init(desc);6361 if (ret < 0)6462 goto error;6565- ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len, digest);6363+ ret = crypto_shash_finup(desc, pkcs7->data, pkcs7->data_len,6464+ sig->digest);6665 if (ret < 0)6766 goto error;6868- pr_devel("MsgDigest = [%*ph]\n", 8, digest);6767+ pr_devel("MsgDigest = [%*ph]\n", 8, sig->digest);69687069 /* However, if there are authenticated attributes, there must be a7170 * message digest attribute amongst them which corresponds to the···8178 goto error;8279 }83808484- if (sinfo->msgdigest_len != sinfo->sig.digest_size) {8181+ if (sinfo->msgdigest_len != sig->digest_size) {8582 pr_debug("Sig %u: Invalid digest size (%u)\n",8683 sinfo->index, sinfo->msgdigest_len);8784 ret = -EBADMSG;8885 goto error;8986 }90879191- if (memcmp(digest, sinfo->msgdigest, sinfo->msgdigest_len) != 0) {8888+ if (memcmp(sig->digest, sinfo->msgdigest,8989+ sinfo->msgdigest_len) != 0) {9290 pr_debug("Sig %u: Message digest doesn't match\n",9391 sinfo->index);9492 ret = -EKEYREJECTED;···10197 * convert the attributes from a CONT.0 into a SET before we10298 * hash it.10399 */104104- memset(digest, 0, sinfo->sig.digest_size);100100+ memset(sig->digest, 0, sig->digest_size);105101106102 ret = crypto_shash_init(desc);107103 if (ret < 0)···111107 if (ret < 0)112108 goto error;113109 ret = crypto_shash_finup(desc, sinfo->authattrs,114114- sinfo->authattrs_len, digest);110110+ sinfo->authattrs_len, sig->digest);115111 if (ret < 0)116112 goto error;117117- pr_devel("AADigest = [%*ph]\n", 8, digest);113113+ pr_devel("AADigest = [%*ph]\n", 8, sig->digest);118114 }119115120120- sinfo->sig.digest = digest;121121- digest = NULL;122122-123116error:124124- kfree(digest);117117+ kfree(desc);125118error_no_desc:126119 crypto_free_shash(tfm);127120 kleave(" = %d", ret);···145144 * PKCS#7 message - but I can't be 100% sure of that. It's146145 * possible this will need element-by-element comparison.147146 */148148- if (!asymmetric_key_id_same(x509->id, sinfo->signing_cert_id))147147+ if (!asymmetric_key_id_same(x509->id, sinfo->sig->auth_ids[0]))149148 continue;150149 pr_devel("Sig %u: Found cert serial match X.509[%u]\n",151150 sinfo->index, certix);152151153153- if (x509->pub->pkey_algo != sinfo->sig.pkey_algo) {152152+ if (x509->pub->pkey_algo != sinfo->sig->pkey_algo) {154153 pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",155154 sinfo->index);156155 continue;···165164 */166165 pr_debug("Sig %u: Issuing X.509 cert not found (#%*phN)\n",167166 sinfo->index,168168- sinfo->signing_cert_id->len, sinfo->signing_cert_id->data);167167+ sinfo->sig->auth_ids[0]->len, sinfo->sig->auth_ids[0]->data);169168 return 0;170169}171170···175174static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,176175 struct pkcs7_signed_info *sinfo)177176{177177+ struct public_key_signature *sig;178178 struct x509_certificate *x509 = sinfo->signer, *p;179179 struct asymmetric_key_id *auth;180180 int ret;···190188 x509->subject,191189 x509->raw_serial_size, x509->raw_serial);192190 x509->seen = true;193193- ret = x509_get_sig_params(x509);194194- if (ret < 0)195195- goto maybe_missing_crypto_in_x509;191191+ if (x509->unsupported_key)192192+ goto unsupported_crypto_in_x509;196193197194 pr_debug("- issuer %s\n", x509->issuer);198198- if (x509->akid_id)195195+ sig = x509->sig;196196+ if (sig->auth_ids[0])199197 pr_debug("- authkeyid.id %*phN\n",200200- x509->akid_id->len, x509->akid_id->data);201201- if (x509->akid_skid)198198+ sig->auth_ids[0]->len, sig->auth_ids[0]->data);199199+ if (sig->auth_ids[1])202200 pr_debug("- authkeyid.skid %*phN\n",203203- x509->akid_skid->len, x509->akid_skid->data);201201+ sig->auth_ids[1]->len, sig->auth_ids[1]->data);204202205205- if ((!x509->akid_id && !x509->akid_skid) ||206206- strcmp(x509->subject, x509->issuer) == 0) {203203+ if (x509->self_signed) {207204 /* If there's no authority certificate specified, then208205 * the certificate must be self-signed and is the root209206 * of the chain. Likewise if the cert is its own210207 * authority.211208 */212212- pr_debug("- no auth?\n");213213- if (x509->raw_subject_size != x509->raw_issuer_size ||214214- memcmp(x509->raw_subject, x509->raw_issuer,215215- x509->raw_issuer_size) != 0)216216- return 0;217217-218218- ret = x509_check_signature(x509->pub, x509);219219- if (ret < 0)220220- goto maybe_missing_crypto_in_x509;209209+ if (x509->unsupported_sig)210210+ goto unsupported_crypto_in_x509;221211 x509->signer = x509;222212 pr_debug("- self-signed\n");223213 return 0;···218224 /* Look through the X.509 certificates in the PKCS#7 message's219225 * list to see if the next one is there.220226 */221221- auth = x509->akid_id;227227+ auth = sig->auth_ids[0];222228 if (auth) {223229 pr_debug("- want %*phN\n", auth->len, auth->data);224230 for (p = pkcs7->certs; p; p = p->next) {···228234 goto found_issuer_check_skid;229235 }230236 } else {231231- auth = x509->akid_skid;237237+ auth = sig->auth_ids[1];232238 pr_debug("- want %*phN\n", auth->len, auth->data);233239 for (p = pkcs7->certs; p; p = p->next) {234240 if (!p->skid)···248254 /* We matched issuer + serialNumber, but if there's an249255 * authKeyId.keyId, that must match the CA subjKeyId also.250256 */251251- if (x509->akid_skid &&252252- !asymmetric_key_id_same(p->skid, x509->akid_skid)) {257257+ if (sig->auth_ids[1] &&258258+ !asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {253259 pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",254260 sinfo->index, x509->index, p->index);255261 return -EKEYREJECTED;···261267 sinfo->index);262268 return 0;263269 }264264- ret = x509_check_signature(p->pub, x509);270270+ ret = public_key_verify_signature(p->pub, p->sig);265271 if (ret < 0)266272 return ret;267273 x509->signer = p;···273279 might_sleep();274280 }275281276276-maybe_missing_crypto_in_x509:282282+unsupported_crypto_in_x509:277283 /* Just prune the certificate chain at this point if we lack some278284 * crypto module to go further. Note, however, we don't want to set279279- * sinfo->missing_crypto as the signed info block may still be285285+ * sinfo->unsupported_crypto as the signed info block may still be280286 * validatable against an X.509 cert lower in the chain that we have a281287 * trusted copy of.282288 */283283- if (ret == -ENOPKG)284284- return 0;285285- return ret;289289+ return 0;286290}287291288292/*···324332 }325333326334 /* Verify the PKCS#7 binary against the key */327327- ret = public_key_verify_signature(sinfo->signer->pub, &sinfo->sig);335335+ ret = public_key_verify_signature(sinfo->signer->pub, sinfo->sig);328336 if (ret < 0)329337 return ret;330338···367375 enum key_being_used_for usage)368376{369377 struct pkcs7_signed_info *sinfo;370370- struct x509_certificate *x509;371378 int enopkg = -ENOPKG;372372- int ret, n;379379+ int ret;373380374381 kenter("");375382···408417 break;409418 default:410419 return -EINVAL;411411- }412412-413413- for (n = 0, x509 = pkcs7->certs; x509; x509 = x509->next, n++) {414414- ret = x509_get_sig_params(x509);415415- if (ret < 0)416416- return ret;417420 }418421419422 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
+14-6
crypto/asymmetric_keys/public_key.c
···3939/*4040 * Destroy a public key algorithm key.4141 */4242-void public_key_destroy(void *payload)4242+void public_key_free(struct public_key *key)4343{4444- struct public_key *key = payload;4545-4646- if (key)4444+ if (key) {4745 kfree(key->key);4848- kfree(key);4646+ kfree(key);4747+ }4948}5050-EXPORT_SYMBOL_GPL(public_key_destroy);4949+EXPORT_SYMBOL_GPL(public_key_free);5050+5151+/*5252+ * Destroy a public key algorithm key.5353+ */5454+static void public_key_destroy(void *payload0, void *payload3)5555+{5656+ public_key_free(payload0);5757+ public_key_signature_free(payload3);5858+}51595260struct public_key_completion {5361 struct completion completion;
+108
crypto/asymmetric_keys/restrict.c
···11+/* Instantiate a public key crypto key from an X.509 Certificate22+ *33+ * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.44+ * Written by David Howells (dhowells@redhat.com)55+ *66+ * This program is free software; you can redistribute it and/or77+ * modify it under the terms of the GNU General Public Licence88+ * as published by the Free Software Foundation; either version99+ * 2 of the Licence, or (at your option) any later version.1010+ */1111+1212+#define pr_fmt(fmt) "ASYM: "fmt1313+#include <linux/module.h>1414+#include <linux/kernel.h>1515+#include <linux/err.h>1616+#include <crypto/public_key.h>1717+#include "asymmetric_keys.h"1818+1919+static bool use_builtin_keys;2020+static struct asymmetric_key_id *ca_keyid;2121+2222+#ifndef MODULE2323+static struct {2424+ struct asymmetric_key_id id;2525+ unsigned char data[10];2626+} cakey;2727+2828+static int __init ca_keys_setup(char *str)2929+{3030+ if (!str) /* default system keyring */3131+ return 1;3232+3333+ if (strncmp(str, "id:", 3) == 0) {3434+ struct asymmetric_key_id *p = &cakey.id;3535+ size_t hexlen = (strlen(str) - 3) / 2;3636+ int ret;3737+3838+ if (hexlen == 0 || hexlen > sizeof(cakey.data)) {3939+ pr_err("Missing or invalid ca_keys id\n");4040+ return 1;4141+ }4242+4343+ ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);4444+ if (ret < 0)4545+ pr_err("Unparsable ca_keys id hex string\n");4646+ else4747+ ca_keyid = p; /* owner key 'id:xxxxxx' */4848+ } else if (strcmp(str, "builtin") == 0) {4949+ use_builtin_keys = true;5050+ }5151+5252+ return 1;5353+}5454+__setup("ca_keys=", ca_keys_setup);5555+#endif5656+5757+/**5858+ * restrict_link_by_signature - Restrict additions to a ring of public keys5959+ * @trust_keyring: A ring of keys that can be used to vouch for the new cert.6060+ * @type: The type of key being added.6161+ * @payload: The payload of the new key.6262+ *6363+ * Check the new certificate against the ones in the trust keyring. If one of6464+ * those is the signing key and validates the new certificate, then mark the6565+ * new certificate as being trusted.6666+ *6767+ * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a6868+ * matching parent certificate in the trusted list, -EKEYREJECTED if the6969+ * signature check fails or the key is blacklisted and some other error if7070+ * there is a matching certificate but the signature check cannot be performed.7171+ */7272+int restrict_link_by_signature(struct key *trust_keyring,7373+ const struct key_type *type,7474+ const union key_payload *payload)7575+{7676+ const struct public_key_signature *sig;7777+ struct key *key;7878+ int ret;7979+8080+ pr_devel("==>%s()\n", __func__);8181+8282+ if (!trust_keyring)8383+ return -ENOKEY;8484+8585+ if (type != &key_type_asymmetric)8686+ return -EOPNOTSUPP;8787+8888+ sig = payload->data[asym_auth];8989+ if (!sig->auth_ids[0] && !sig->auth_ids[1])9090+ return 0;9191+9292+ if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))9393+ return -EPERM;9494+9595+ /* See if we have a key that signed this one. */9696+ key = find_asymmetric_key(trust_keyring,9797+ sig->auth_ids[0], sig->auth_ids[1],9898+ false);9999+ if (IS_ERR(key))100100+ return -ENOKEY;101101+102102+ if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))103103+ ret = -ENOKEY;104104+ else105105+ ret = verify_signature(key, sig);106106+ key_put(key);107107+ return ret;108108+}
+18
crypto/asymmetric_keys/signature.c
···1515#include <keys/asymmetric-subtype.h>1616#include <linux/export.h>1717#include <linux/err.h>1818+#include <linux/slab.h>1819#include <crypto/public_key.h>1920#include "asymmetric_keys.h"2121+2222+/*2323+ * Destroy a public key signature.2424+ */2525+void public_key_signature_free(struct public_key_signature *sig)2626+{2727+ int i;2828+2929+ if (sig) {3030+ for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)3131+ kfree(sig->auth_ids[i]);3232+ kfree(sig->s);3333+ kfree(sig->digest);3434+ kfree(sig);3535+ }3636+}3737+EXPORT_SYMBOL_GPL(public_key_signature_free);20382139/**2240 * verify_signature - Initiate the use of an asymmetric key to verify a signature
+9-31
crypto/asymmetric_keys/verify_pefile.c
···1616#include <linux/err.h>1717#include <linux/pe.h>1818#include <linux/asn1.h>1919-#include <crypto/pkcs7.h>1919+#include <linux/verification.h>2020#include <crypto/hash.h>2121#include "verify_pefile.h"2222···392392 * verify_pefile_signature - Verify the signature on a PE binary image393393 * @pebuf: Buffer containing the PE binary image394394 * @pelen: Length of the binary image395395- * @trust_keyring: Signing certificates to use as starting points395395+ * @trust_keys: Signing certificate(s) to use as starting points396396 * @usage: The use to which the key is being put.397397- * @_trusted: Set to true if trustworth, false otherwise398397 *399398 * Validate that the certificate chain inside the PKCS#7 message inside the PE400399 * binary image intersects keys we already know and trust.···417418 * May also return -ENOMEM.418419 */419420int verify_pefile_signature(const void *pebuf, unsigned pelen,420420- struct key *trusted_keyring,421421- enum key_being_used_for usage,422422- bool *_trusted)421421+ struct key *trusted_keys,422422+ enum key_being_used_for usage)423423{424424- struct pkcs7_message *pkcs7;425424 struct pefile_context ctx;426426- const void *data;427427- size_t datalen;428425 int ret;429426430427 kenter("");···434439 if (ret < 0)435440 return ret;436441437437- pkcs7 = pkcs7_parse_message(pebuf + ctx.sig_offset, ctx.sig_len);438438- if (IS_ERR(pkcs7))439439- return PTR_ERR(pkcs7);440440- ctx.pkcs7 = pkcs7;441441-442442- ret = pkcs7_get_content_data(ctx.pkcs7, &data, &datalen, false);443443- if (ret < 0 || datalen == 0) {444444- pr_devel("PKCS#7 message does not contain data\n");445445- ret = -EBADMSG;446446- goto error;447447- }448448-449449- ret = mscode_parse(&ctx);442442+ ret = verify_pkcs7_signature(NULL, 0,443443+ pebuf + ctx.sig_offset, ctx.sig_len,444444+ trusted_keys, usage,445445+ mscode_parse, &ctx);450446 if (ret < 0)451447 goto error;452448···448462 * contents.449463 */450464 ret = pefile_digest_pe(pebuf, pelen, &ctx);451451- if (ret < 0)452452- goto error;453453-454454- ret = pkcs7_verify(pkcs7, usage);455455- if (ret < 0)456456- goto error;457457-458458- ret = pkcs7_validate_trust(pkcs7, trusted_keyring, _trusted);459465460466error:461461- pkcs7_free_message(ctx.pkcs7);467467+ kfree(ctx.digest);462468 return ret;463469}
+2-3
crypto/asymmetric_keys/verify_pefile.h
···99 * 2 of the Licence, or (at your option) any later version.1010 */11111212-#include <linux/verify_pefile.h>1312#include <crypto/pkcs7.h>1413#include <crypto/hash_info.h>1514···2223 unsigned sig_offset;2324 unsigned sig_len;2425 const struct section_header *secs;2525- struct pkcs7_message *pkcs7;26262727 /* PKCS#7 MS Individual Code Signing content */2828 const void *digest; /* Digest */···3739/*3840 * mscode_parser.c3941 */4040-extern int mscode_parse(struct pefile_context *ctx);4242+extern int mscode_parse(void *_ctx, const void *content_data, size_t data_len,4343+ size_t asn1hdrlen);
···1717 struct x509_certificate *next;1818 struct x509_certificate *signer; /* Certificate that signed this one */1919 struct public_key *pub; /* Public key details */2020- struct public_key_signature sig; /* Signature parameters */2020+ struct public_key_signature *sig; /* Signature parameters */2121 char *issuer; /* Name of certificate issuer */2222 char *subject; /* Name of certificate subject */2323 struct asymmetric_key_id *id; /* Issuer + Serial number */2424 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */2525- struct asymmetric_key_id *akid_id; /* CA AuthKeyId matching ->id (optional) */2626- struct asymmetric_key_id *akid_skid; /* CA AuthKeyId matching ->skid (optional) */2725 time64_t valid_from;2826 time64_t valid_to;2927 const void *tbs; /* Signed data */···3941 unsigned index;4042 bool seen; /* Infinite recursion prevention */4143 bool verified;4242- bool trusted;4343- bool unsupported_crypto; /* T if can't be verified due to missing crypto */4444+ bool self_signed; /* T if self-signed (check unsupported_sig too) */4545+ bool unsupported_key; /* T if key uses unsupported crypto */4646+ bool unsupported_sig; /* T if signature uses unsupported crypto */4447};45484649/*···5758 * x509_public_key.c5859 */5960extern int x509_get_sig_params(struct x509_certificate *cert);6060-extern int x509_check_signature(const struct public_key *pub,6161- struct x509_certificate *cert);6161+extern int x509_check_for_self_signed(struct x509_certificate *cert);
+82-215
crypto/asymmetric_keys/x509_public_key.c
···2020#include "asymmetric_keys.h"2121#include "x509_parser.h"22222323-static bool use_builtin_keys;2424-static struct asymmetric_key_id *ca_keyid;2525-2626-#ifndef MODULE2727-static struct {2828- struct asymmetric_key_id id;2929- unsigned char data[10];3030-} cakey;3131-3232-static int __init ca_keys_setup(char *str)3333-{3434- if (!str) /* default system keyring */3535- return 1;3636-3737- if (strncmp(str, "id:", 3) == 0) {3838- struct asymmetric_key_id *p = &cakey.id;3939- size_t hexlen = (strlen(str) - 3) / 2;4040- int ret;4141-4242- if (hexlen == 0 || hexlen > sizeof(cakey.data)) {4343- pr_err("Missing or invalid ca_keys id\n");4444- return 1;4545- }4646-4747- ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen);4848- if (ret < 0)4949- pr_err("Unparsable ca_keys id hex string\n");5050- else5151- ca_keyid = p; /* owner key 'id:xxxxxx' */5252- } else if (strcmp(str, "builtin") == 0) {5353- use_builtin_keys = true;5454- }5555-5656- return 1;5757-}5858-__setup("ca_keys=", ca_keys_setup);5959-#endif6060-6161-/**6262- * x509_request_asymmetric_key - Request a key by X.509 certificate params.6363- * @keyring: The keys to search.6464- * @id: The issuer & serialNumber to look for or NULL.6565- * @skid: The subjectKeyIdentifier to look for or NULL.6666- * @partial: Use partial match if true, exact if false.6767- *6868- * Find a key in the given keyring by identifier. The preferred identifier is6969- * the issuer + serialNumber and the fallback identifier is the7070- * subjectKeyIdentifier. If both are given, the lookup is by the former, but7171- * the latter must also match.7272- */7373-struct key *x509_request_asymmetric_key(struct key *keyring,7474- const struct asymmetric_key_id *id,7575- const struct asymmetric_key_id *skid,7676- bool partial)7777-{7878- struct key *key;7979- key_ref_t ref;8080- const char *lookup;8181- char *req, *p;8282- int len;8383-8484- if (id) {8585- lookup = id->data;8686- len = id->len;8787- } else {8888- lookup = skid->data;8989- len = skid->len;9090- }9191-9292- /* Construct an identifier "id:<keyid>". */9393- p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);9494- if (!req)9595- return ERR_PTR(-ENOMEM);9696-9797- if (partial) {9898- *p++ = 'i';9999- *p++ = 'd';100100- } else {101101- *p++ = 'e';102102- *p++ = 'x';103103- }104104- *p++ = ':';105105- p = bin2hex(p, lookup, len);106106- *p = 0;107107-108108- pr_debug("Look up: \"%s\"\n", req);109109-110110- ref = keyring_search(make_key_ref(keyring, 1),111111- &key_type_asymmetric, req);112112- if (IS_ERR(ref))113113- pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));114114- kfree(req);115115-116116- if (IS_ERR(ref)) {117117- switch (PTR_ERR(ref)) {118118- /* Hide some search errors */119119- case -EACCES:120120- case -ENOTDIR:121121- case -EAGAIN:122122- return ERR_PTR(-ENOKEY);123123- default:124124- return ERR_CAST(ref);125125- }126126- }127127-128128- key = key_ref_to_ptr(ref);129129- if (id && skid) {130130- const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);131131- if (!kids->id[1]) {132132- pr_debug("issuer+serial match, but expected SKID missing\n");133133- goto reject;134134- }135135- if (!asymmetric_key_id_same(skid, kids->id[1])) {136136- pr_debug("issuer+serial match, but SKID does not\n");137137- goto reject;138138- }139139- }140140-141141- pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));142142- return key;143143-144144-reject:145145- key_put(key);146146- return ERR_PTR(-EKEYREJECTED);147147-}148148-EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);149149-15023/*15124 * Set up the signature parameters in an X.509 certificate. This involves15225 * digesting the signed data and extracting the signature.15326 */15427int x509_get_sig_params(struct x509_certificate *cert)15528{2929+ struct public_key_signature *sig = cert->sig;15630 struct crypto_shash *tfm;15731 struct shash_desc *desc;158158- size_t digest_size, desc_size;159159- void *digest;3232+ size_t desc_size;16033 int ret;1613416235 pr_devel("==>%s()\n", __func__);16336164164- if (cert->unsupported_crypto)165165- return -ENOPKG;166166- if (cert->sig.s)167167- return 0;3737+ if (!cert->pub->pkey_algo)3838+ cert->unsupported_key = true;16839169169- cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size,170170- GFP_KERNEL);171171- if (!cert->sig.s)4040+ if (!sig->pkey_algo)4141+ cert->unsupported_sig = true;4242+4343+ /* We check the hash if we can - even if we can't then verify it */4444+ if (!sig->hash_algo) {4545+ cert->unsupported_sig = true;4646+ return 0;4747+ }4848+4949+ sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);5050+ if (!sig->s)17251 return -ENOMEM;17352174174- cert->sig.s_size = cert->raw_sig_size;5353+ sig->s_size = cert->raw_sig_size;1755417655 /* Allocate the hashing algorithm we're going to need and find out how17756 * big the hash operational data will be.17857 */179179- tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0);5858+ tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);18059 if (IS_ERR(tfm)) {18160 if (PTR_ERR(tfm) == -ENOENT) {182182- cert->unsupported_crypto = true;183183- return -ENOPKG;6161+ cert->unsupported_sig = true;6262+ return 0;18463 }18564 return PTR_ERR(tfm);18665 }1876618867 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);189189- digest_size = crypto_shash_digestsize(tfm);6868+ sig->digest_size = crypto_shash_digestsize(tfm);19069191191- /* We allocate the hash operational data storage on the end of the192192- * digest storage space.193193- */19470 ret = -ENOMEM;195195- digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,196196- GFP_KERNEL);197197- if (!digest)7171+ sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);7272+ if (!sig->digest)19873 goto error;19974200200- cert->sig.digest = digest;201201- cert->sig.digest_size = digest_size;7575+ desc = kzalloc(desc_size, GFP_KERNEL);7676+ if (!desc)7777+ goto error;20278203203- desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));20479 desc->tfm = tfm;20580 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;2068120782 ret = crypto_shash_init(desc);20883 if (ret < 0)209209- goto error;8484+ goto error_2;21085 might_sleep();211211- ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest);8686+ ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);8787+8888+error_2:8989+ kfree(desc);21290error:21391 crypto_free_shash(tfm);21492 pr_devel("<==%s() = %d\n", __func__, ret);21593 return ret;21694}217217-EXPORT_SYMBOL_GPL(x509_get_sig_params);2189521996/*220220- * Check the signature on a certificate using the provided public key9797+ * Check for self-signedness in an X.509 cert and if found, check the signature9898+ * immediately if we can.22199 */222222-int x509_check_signature(const struct public_key *pub,223223- struct x509_certificate *cert)100100+int x509_check_for_self_signed(struct x509_certificate *cert)224101{225225- int ret;102102+ int ret = 0;226103227104 pr_devel("==>%s()\n", __func__);228105229229- ret = x509_get_sig_params(cert);230230- if (ret < 0)231231- return ret;106106+ if (cert->raw_subject_size != cert->raw_issuer_size ||107107+ memcmp(cert->raw_subject, cert->raw_issuer,108108+ cert->raw_issuer_size) != 0)109109+ goto not_self_signed;232110233233- ret = public_key_verify_signature(pub, &cert->sig);234234- if (ret == -ENOPKG)235235- cert->unsupported_crypto = true;236236- pr_debug("Cert Verification: %d\n", ret);237237- return ret;238238-}239239-EXPORT_SYMBOL_GPL(x509_check_signature);111111+ if (cert->sig->auth_ids[0] || cert->sig->auth_ids[1]) {112112+ /* If the AKID is present it may have one or two parts. If113113+ * both are supplied, both must match.114114+ */115115+ bool a = asymmetric_key_id_same(cert->skid, cert->sig->auth_ids[1]);116116+ bool b = asymmetric_key_id_same(cert->id, cert->sig->auth_ids[0]);240117241241-/*242242- * Check the new certificate against the ones in the trust keyring. If one of243243- * those is the signing key and validates the new certificate, then mark the244244- * new certificate as being trusted.245245- *246246- * Return 0 if the new certificate was successfully validated, 1 if we couldn't247247- * find a matching parent certificate in the trusted list and an error if there248248- * is a matching certificate but the signature check fails.249249- */250250-static int x509_validate_trust(struct x509_certificate *cert,251251- struct key *trust_keyring)252252-{253253- struct key *key;254254- int ret = 1;118118+ if (!a && !b)119119+ goto not_self_signed;255120256256- if (!trust_keyring)257257- return -EOPNOTSUPP;258258-259259- if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))260260- return -EPERM;261261-262262- key = x509_request_asymmetric_key(trust_keyring,263263- cert->akid_id, cert->akid_skid,264264- false);265265- if (!IS_ERR(key)) {266266- if (!use_builtin_keys267267- || test_bit(KEY_FLAG_BUILTIN, &key->flags))268268- ret = x509_check_signature(key->payload.data[asym_crypto],269269- cert);270270- key_put(key);121121+ ret = -EKEYREJECTED;122122+ if (((a && !b) || (b && !a)) &&123123+ cert->sig->auth_ids[0] && cert->sig->auth_ids[1])124124+ goto out;271125 }126126+127127+ ret = -EKEYREJECTED;128128+ if (cert->pub->pkey_algo != cert->sig->pkey_algo)129129+ goto out;130130+131131+ ret = public_key_verify_signature(cert->pub, cert->sig);132132+ if (ret < 0) {133133+ if (ret == -ENOPKG) {134134+ cert->unsupported_sig = true;135135+ ret = 0;136136+ }137137+ goto out;138138+ }139139+140140+ pr_devel("Cert Self-signature verified");141141+ cert->self_signed = true;142142+143143+out:144144+ pr_devel("<==%s() = %d\n", __func__, ret);272145 return ret;146146+147147+not_self_signed:148148+ pr_devel("<==%s() = 0 [not]\n", __func__);149149+ return 0;273150}274151275152/*···168291 pr_devel("Cert Issuer: %s\n", cert->issuer);169292 pr_devel("Cert Subject: %s\n", cert->subject);170293171171- if (!cert->pub->pkey_algo ||172172- !cert->sig.pkey_algo ||173173- !cert->sig.hash_algo) {294294+ if (cert->unsupported_key) {174295 ret = -ENOPKG;175296 goto error_free_cert;176297 }177298178299 pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);179300 pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);180180- pr_devel("Cert Signature: %s + %s\n",181181- cert->sig.pkey_algo,182182- cert->sig.hash_algo);183301184302 cert->pub->id_type = "X509";185303186186- /* Check the signature on the key if it appears to be self-signed */187187- if ((!cert->akid_skid && !cert->akid_id) ||188188- asymmetric_key_id_same(cert->skid, cert->akid_skid) ||189189- asymmetric_key_id_same(cert->id, cert->akid_id)) {190190- ret = x509_check_signature(cert->pub, cert); /* self-signed */191191- if (ret < 0)192192- goto error_free_cert;193193- } else if (!prep->trusted) {194194- ret = x509_validate_trust(cert, get_system_trusted_keyring());195195- if (ret)196196- ret = x509_validate_trust(cert, get_ima_mok_keyring());197197- if (!ret)198198- prep->trusted = 1;304304+ if (cert->unsupported_sig) {305305+ public_key_signature_free(cert->sig);306306+ cert->sig = NULL;307307+ } else {308308+ pr_devel("Cert Signature: %s + %s\n",309309+ cert->sig->pkey_algo, cert->sig->hash_algo);199310 }200311201312 /* Propose a description */···218353 prep->payload.data[asym_subtype] = &public_key_subtype;219354 prep->payload.data[asym_key_ids] = kids;220355 prep->payload.data[asym_crypto] = cert->pub;356356+ prep->payload.data[asym_auth] = cert->sig;221357 prep->description = desc;222358 prep->quotalen = 100;223359···226360 cert->pub = NULL;227361 cert->id = NULL;228362 cert->skid = NULL;363363+ cert->sig = NULL;229364 desc = NULL;230365 ret = 0;231366
···1515#define _LINUX_PUBLIC_KEY_H16161717/*1818- * The use to which an asymmetric key is being put.1919- */2020-enum key_being_used_for {2121- VERIFYING_MODULE_SIGNATURE,2222- VERIFYING_FIRMWARE_SIGNATURE,2323- VERIFYING_KEXEC_PE_SIGNATURE,2424- VERIFYING_KEY_SIGNATURE,2525- VERIFYING_KEY_SELF_SIGNATURE,2626- VERIFYING_UNSPECIFIED_SIGNATURE,2727- NR__KEY_BEING_USED_FOR2828-};2929-extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];3030-3131-/*3218 * Cryptographic data for the public-key subtype of the asymmetric key type.3319 *3420 * Note that this may include private part of the key as well as the public···2741 const char *pkey_algo;2842};29433030-extern void public_key_destroy(void *payload);4444+extern void public_key_free(struct public_key *key);31453246/*3347 * Public key cryptography signature data3448 */3549struct public_key_signature {5050+ struct asymmetric_key_id *auth_ids[2];3651 u8 *s; /* Signature */3752 u32 s_size; /* Number of bytes in signature */3853 u8 *digest;···4255 const char *hash_algo;4356};44575858+extern void public_key_signature_free(struct public_key_signature *sig);5959+4560extern struct asymmetric_key_subtype public_key_subtype;6161+4662struct key;6363+struct key_type;6464+union key_payload;6565+6666+extern int restrict_link_by_signature(struct key *trust_keyring,6767+ const struct key_type *type,6868+ const union key_payload *payload);6969+4770extern int verify_signature(const struct key *key,4871 const struct public_key_signature *sig);4949-5050-struct asymmetric_key_id;5151-extern struct key *x509_request_asymmetric_key(struct key *keyring,5252- const struct asymmetric_key_id *id,5353- const struct asymmetric_key_id *skid,5454- bool partial);55725673int public_key_verify_signature(const struct public_key *pkey,5774 const struct public_key_signature *sig);
+1-1
include/keys/asymmetric-subtype.h
···3232 void (*describe)(const struct key *key, struct seq_file *m);33333434 /* Destroy a key of this subtype */3535- void (*destroy)(void *payload);3535+ void (*destroy)(void *payload_crypto, void *payload_auth);36363737 /* Verify the signature on a key of this subtype (optional) */3838 int (*verify_signature)(const struct key *key,
+10-3
include/keys/asymmetric-type.h
···1515#define _KEYS_ASYMMETRIC_TYPE_H16161717#include <linux/key-type.h>1818+#include <linux/verification.h>18191920extern struct key_type key_type_asymmetric;2021···2423 * follows:2524 */2625enum asymmetric_payload_bits {2727- asym_crypto,2828- asym_subtype,2929- asym_key_ids,2626+ asym_crypto, /* The data representing the key */2727+ asym_subtype, /* Pointer to an asymmetric_key_subtype struct */2828+ asym_key_ids, /* Pointer to an asymmetric_key_ids struct */2929+ asym_auth /* The key's authorisation (signature, parent key ID) */3030};31313232/*···7573{7674 return key->payload.data[asym_key_ids];7775}7676+7777+extern struct key *find_asymmetric_key(struct key *keyring,7878+ const struct asymmetric_key_id *id_0,7979+ const struct asymmetric_key_id *id_1,8080+ bool partial);78817982/*8083 * The payload is at the discretion of the subtype.
···4545 size_t datalen; /* Raw datalen */4646 size_t quotalen; /* Quota length for proposed payload */4747 time_t expiry; /* Expiry time of key */4848- bool trusted; /* True if key is trusted */4948};50495150typedef int (*request_key_actor_t)(struct key_construction *key,
+33-11
include/linux/key.h
···173173#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */174174#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */175175#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */176176-#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */177177-#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */178178-#define KEY_FLAG_BUILTIN 10 /* set if key is builtin */179179-#define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */180180-#define KEY_FLAG_KEEP 12 /* set if key should not be removed */176176+#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */177177+#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */178178+#define KEY_FLAG_KEEP 10 /* set if key should not be removed */181179182180 /* the key type and key description string183181 * - the desc is used to match a key against search criteria···203205 };204206 int reject_error;205207 };208208+209209+ /* This is set on a keyring to restrict the addition of a link to a key210210+ * to it. If this method isn't provided then it is assumed that the211211+ * keyring is open to any addition. It is ignored for non-keyring212212+ * keys.213213+ *214214+ * This is intended for use with rings of trusted keys whereby addition215215+ * to the keyring needs to be controlled. KEY_ALLOC_BYPASS_RESTRICTION216216+ * overrides this, allowing the kernel to add extra keys without217217+ * restriction.218218+ */219219+ int (*restrict_link)(struct key *keyring,220220+ const struct key_type *type,221221+ const union key_payload *payload);206222};207223208224extern struct key *key_alloc(struct key_type *type,···224212 kuid_t uid, kgid_t gid,225213 const struct cred *cred,226214 key_perm_t perm,227227- unsigned long flags);215215+ unsigned long flags,216216+ int (*restrict_link)(struct key *,217217+ const struct key_type *,218218+ const union key_payload *));228219229220230230-#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */231231-#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */232232-#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */233233-#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */234234-#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */221221+#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */222222+#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */223223+#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */224224+#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */225225+#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */235226236227extern void key_revoke(struct key *key);237228extern void key_invalidate(struct key *key);···303288 const struct cred *cred,304289 key_perm_t perm,305290 unsigned long flags,291291+ int (*restrict_link)(struct key *,292292+ const struct key_type *,293293+ const union key_payload *),306294 struct key *dest);295295+296296+extern int restrict_link_reject(struct key *keyring,297297+ const struct key_type *type,298298+ const union key_payload *payload);307299308300extern int keyring_clear(struct key *keyring);309301
+49
include/linux/verification.h
···11+/* Signature verification22+ *33+ * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.44+ * Written by David Howells (dhowells@redhat.com)55+ *66+ * This program is free software; you can redistribute it and/or77+ * modify it under the terms of the GNU General Public Licence88+ * as published by the Free Software Foundation; either version99+ * 2 of the Licence, or (at your option) any later version.1010+ */1111+1212+#ifndef _LINUX_VERIFICATION_H1313+#define _LINUX_VERIFICATION_H1414+1515+/*1616+ * The use to which an asymmetric key is being put.1717+ */1818+enum key_being_used_for {1919+ VERIFYING_MODULE_SIGNATURE,2020+ VERIFYING_FIRMWARE_SIGNATURE,2121+ VERIFYING_KEXEC_PE_SIGNATURE,2222+ VERIFYING_KEY_SIGNATURE,2323+ VERIFYING_KEY_SELF_SIGNATURE,2424+ VERIFYING_UNSPECIFIED_SIGNATURE,2525+ NR__KEY_BEING_USED_FOR2626+};2727+extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR];2828+2929+#ifdef CONFIG_SYSTEM_DATA_VERIFICATION3030+3131+struct key;3232+3333+extern int verify_pkcs7_signature(const void *data, size_t len,3434+ const void *raw_pkcs7, size_t pkcs7_len,3535+ struct key *trusted_keys,3636+ enum key_being_used_for usage,3737+ int (*view_content)(void *ctx,3838+ const void *data, size_t len,3939+ size_t asn1hdrlen),4040+ void *ctx);4141+4242+#ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION4343+extern int verify_pefile_signature(const void *pebuf, unsigned pelen,4444+ struct key *trusted_keys,4545+ enum key_being_used_for usage);4646+#endif4747+4848+#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */4949+#endif /* _LINUX_VERIFY_PEFILE_H */
-22
include/linux/verify_pefile.h
···11-/* Signed PE file verification22- *33- * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.44- * Written by David Howells (dhowells@redhat.com)55- *66- * This program is free software; you can redistribute it and/or77- * modify it under the terms of the GNU General Public Licence88- * as published by the Free Software Foundation; either version99- * 2 of the Licence, or (at your option) any later version.1010- */1111-1212-#ifndef _LINUX_VERIFY_PEFILE_H1313-#define _LINUX_VERIFY_PEFILE_H1414-1515-#include <crypto/public_key.h>1616-1717-extern int verify_pefile_signature(const void *pebuf, unsigned pelen,1818- struct key *trusted_keyring,1919- enum key_being_used_for usage,2020- bool *_trusted);2121-2222-#endif /* _LINUX_VERIFY_PEFILE_H */
+10
include/uapi/linux/keyctl.h
···1212#ifndef _LINUX_KEYCTL_H1313#define _LINUX_KEYCTL_H14141515+#include <linux/types.h>1616+1517/* special process keyring shortcut IDs */1618#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */1719#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */···5957#define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */6058#define KEYCTL_INVALIDATE 21 /* invalidate a key */6159#define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */6060+#define KEYCTL_DH_COMPUTE 23 /* Compute Diffie-Hellman values */6161+6262+/* keyctl structures */6363+struct keyctl_dh_params {6464+ __s32 private;6565+ __s32 prime;6666+ __s32 base;6767+};62686369#endif /* _LINUX_KEYCTL_H */
···155155156156 This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING157157158158-config IMA_MOK_KEYRING159159- bool "Create IMA machine owner keys (MOK) and blacklist keyrings"158158+config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY159159+ bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)"160160+ depends on SYSTEM_TRUSTED_KEYRING161161+ depends on SECONDARY_TRUSTED_KEYRING162162+ depends on INTEGRITY_ASYMMETRIC_KEYS163163+ select INTEGRITY_TRUSTED_KEYRING164164+ default n165165+ help166166+ Keys may be added to the IMA or IMA blacklist keyrings, if the167167+ key is validly signed by a CA cert in the system built-in or168168+ secondary trusted keyrings.169169+170170+ Intermediate keys between those the kernel has compiled in and the171171+ IMA keys to be added may be added to the system secondary keyring,172172+ provided they are validly signed by a key already resident in the173173+ built-in or secondary trusted keyrings.174174+175175+config IMA_BLACKLIST_KEYRING176176+ bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)"160177 depends on SYSTEM_TRUSTED_KEYRING161178 depends on IMA_TRUSTED_KEYRING162179 default n163180 help164164- This option creates IMA MOK and blacklist keyrings. IMA MOK is an165165- intermediate keyring that sits between .system and .ima keyrings,166166- effectively forming a simple CA hierarchy. To successfully import a167167- key into .ima_mok it must be signed by a key which CA is in .system168168- keyring. On turn any key that needs to go in .ima keyring must be169169- signed by CA in either .system or .ima_mok keyrings. IMA MOK is empty170170- at kernel boot.171171-172172- IMA blacklist keyring contains all revoked IMA keys. It is consulted173173- before any other keyring. If the search is successful the requested174174- operation is rejected and error is returned to the caller.181181+ This option creates an IMA blacklist keyring, which contains all182182+ revoked IMA keys. It is consulted before any other keyring. If183183+ the search is successful the requested operation is rejected and184184+ an error is returned to the caller.175185176186config IMA_LOAD_X509177187 bool "Load X509 certificate onto the '.ima' trusted keyring"
···1717#include <linux/cred.h>1818#include <linux/err.h>1919#include <linux/init.h>2020-#include <keys/asymmetric-type.h>2020+#include <keys/system_keyring.h>212122222323-struct key *ima_mok_keyring;2423struct key *ima_blacklist_keyring;25242625/*2727- * Allocate the IMA MOK and blacklist keyrings2626+ * Allocate the IMA blacklist keyring2827 */2928__init int ima_mok_init(void)3029{3131- pr_notice("Allocating IMA MOK and blacklist keyrings.\n");3232-3333- ima_mok_keyring = keyring_alloc(".ima_mok",3434- KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),3535- (KEY_POS_ALL & ~KEY_POS_SETATTR) |3636- KEY_USR_VIEW | KEY_USR_READ |3737- KEY_USR_WRITE | KEY_USR_SEARCH,3838- KEY_ALLOC_NOT_IN_QUOTA, NULL);3030+ pr_notice("Allocating IMA blacklist keyring.\n");39314032 ima_blacklist_keyring = keyring_alloc(".ima_blacklist",4133 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),4234 (KEY_POS_ALL & ~KEY_POS_SETATTR) |4335 KEY_USR_VIEW | KEY_USR_READ |4436 KEY_USR_WRITE | KEY_USR_SEARCH,4545- KEY_ALLOC_NOT_IN_QUOTA, NULL);3737+ KEY_ALLOC_NOT_IN_QUOTA,3838+ restrict_link_by_builtin_trusted, NULL);46394747- if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring))4848- panic("Can't allocate IMA MOK or blacklist keyrings.");4949- set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);4040+ if (IS_ERR(ima_blacklist_keyring))4141+ panic("Can't allocate IMA blacklist keyring.");50425151- set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);5243 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);5344 return 0;5445}
+15
security/keys/Kconfig
···4141 bool "Large payload keys"4242 depends on KEYS4343 depends on TMPFS4444+ select CRYPTO4545+ select CRYPTO_AES4646+ select CRYPTO_ECB4747+ select CRYPTO_RNG4448 help4549 This option provides support for holding large keys within the kernel4650 (for example Kerberos ticket caches). The data may be stored out to···8581 Userspace only ever sees/stores encrypted blobs.86828783 If you are unsure as to whether this is required, answer N.8484+8585+config KEY_DH_OPERATIONS8686+ bool "Diffie-Hellman operations on retained keys"8787+ depends on KEYS8888+ select MPILIB8989+ help9090+ This option provides support for calculating Diffie-Hellman9191+ public keys and shared secrets using values stored as keys9292+ in the kernel.9393+9494+ If you are unsure as to whether this is required, answer N.
···1414#include <linux/file.h>1515#include <linux/shmem_fs.h>1616#include <linux/err.h>1717+#include <linux/scatterlist.h>1718#include <keys/user-type.h>1819#include <keys/big_key-type.h>2020+#include <crypto/rng.h>19212022/*2123 * Layout of key payload words.···3028};31293230/*3131+ * Crypto operation with big_key data3232+ */3333+enum big_key_op {3434+ BIG_KEY_ENC,3535+ BIG_KEY_DEC,3636+};3737+3838+/*3339 * If the data is under this limit, there's no point creating a shm file to3440 * hold it as the permanently resident metadata for the shmem fs will be at3541 * least as large as the data.3642 */3743#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))4444+4545+/*4646+ * Key size for big_key data encryption4747+ */4848+#define ENC_KEY_SIZE 1638493950/*4051 * big_key defined keys take an arbitrary string as the description and an···6550};66516752/*5353+ * Crypto names for big_key data encryption5454+ */5555+static const char big_key_rng_name[] = "stdrng";5656+static const char big_key_alg_name[] = "ecb(aes)";5757+5858+/*5959+ * Crypto algorithms for big_key data encryption6060+ */6161+static struct crypto_rng *big_key_rng;6262+static struct crypto_blkcipher *big_key_blkcipher;6363+6464+/*6565+ * Generate random key to encrypt big_key data6666+ */6767+static inline int big_key_gen_enckey(u8 *key)6868+{6969+ return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE);7070+}7171+7272+/*7373+ * Encrypt/decrypt big_key data7474+ */7575+static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key)7676+{7777+ int ret = -EINVAL;7878+ struct scatterlist sgio;7979+ struct blkcipher_desc desc;8080+8181+ if (crypto_blkcipher_setkey(big_key_blkcipher, key, ENC_KEY_SIZE)) {8282+ ret = -EAGAIN;8383+ goto error;8484+ }8585+8686+ desc.flags = 0;8787+ desc.tfm = big_key_blkcipher;8888+8989+ sg_init_one(&sgio, data, datalen);9090+9191+ if (op == BIG_KEY_ENC)9292+ ret = crypto_blkcipher_encrypt(&desc, &sgio, &sgio, datalen);9393+ else9494+ ret = crypto_blkcipher_decrypt(&desc, &sgio, &sgio, datalen);9595+9696+error:9797+ return ret;9898+}9999+100100+/*68101 * Preparse a big key69102 */70103int big_key_preparse(struct key_preparsed_payload *prep)71104{72105 struct path *path = (struct path *)&prep->payload.data[big_key_path];73106 struct file *file;107107+ u8 *enckey;108108+ u8 *data = NULL;74109 ssize_t written;75110 size_t datalen = prep->datalen;76111 int ret;···13873 /* Create a shmem file to store the data in. This will permit the data13974 * to be swapped out if needed.14075 *141141- * TODO: Encrypt the stored data with a temporary key.7676+ * File content is stored encrypted with randomly generated key.14277 */143143- file = shmem_kernel_file_setup("", datalen, 0);144144- if (IS_ERR(file)) {145145- ret = PTR_ERR(file);7878+ size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher));7979+8080+ /* prepare aligned data to encrypt */8181+ data = kmalloc(enclen, GFP_KERNEL);8282+ if (!data)8383+ return -ENOMEM;8484+8585+ memcpy(data, prep->data, datalen);8686+ memset(data + datalen, 0x00, enclen - datalen);8787+8888+ /* generate random key */8989+ enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL);9090+ if (!enckey) {9191+ ret = -ENOMEM;14692 goto error;14793 }14894149149- written = kernel_write(file, prep->data, prep->datalen, 0);150150- if (written != datalen) {9595+ ret = big_key_gen_enckey(enckey);9696+ if (ret)9797+ goto err_enckey;9898+9999+ /* encrypt aligned data */100100+ ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey);101101+ if (ret)102102+ goto err_enckey;103103+104104+ /* save aligned data to file */105105+ file = shmem_kernel_file_setup("", enclen, 0);106106+ if (IS_ERR(file)) {107107+ ret = PTR_ERR(file);108108+ goto err_enckey;109109+ }110110+111111+ written = kernel_write(file, data, enclen, 0);112112+ if (written != enclen) {151113 ret = written;152114 if (written >= 0)153115 ret = -ENOMEM;···18492 /* Pin the mount and dentry to the key so that we can open it again18593 * later18694 */9595+ prep->payload.data[big_key_data] = enckey;18796 *path = file->f_path;18897 path_get(path);18998 fput(file);9999+ kfree(data);190100 } else {191101 /* Just store the data in a buffer */192102 void *data = kmalloc(datalen, GFP_KERNEL);103103+193104 if (!data)194105 return -ENOMEM;195106···203108204109err_fput:205110 fput(file);111111+err_enckey:112112+ kfree(enckey);206113error:114114+ kfree(data);207115 return ret;208116}209117···217119{218120 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) {219121 struct path *path = (struct path *)&prep->payload.data[big_key_path];122122+220123 path_put(path);221221- } else {222222- kfree(prep->payload.data[big_key_data]);223124 }125125+ kfree(prep->payload.data[big_key_data]);224126}225127226128/*···245147{246148 size_t datalen = (size_t)key->payload.data[big_key_len];247149248248- if (datalen) {150150+ if (datalen > BIG_KEY_FILE_THRESHOLD) {249151 struct path *path = (struct path *)&key->payload.data[big_key_path];152152+250153 path_put(path);251154 path->mnt = NULL;252155 path->dentry = NULL;253253- } else {254254- kfree(key->payload.data[big_key_data]);255255- key->payload.data[big_key_data] = NULL;256156 }157157+ kfree(key->payload.data[big_key_data]);158158+ key->payload.data[big_key_data] = NULL;257159}258160259161/*···286188 if (datalen > BIG_KEY_FILE_THRESHOLD) {287189 struct path *path = (struct path *)&key->payload.data[big_key_path];288190 struct file *file;289289- loff_t pos;191191+ u8 *data;192192+ u8 *enckey = (u8 *)key->payload.data[big_key_data];193193+ size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher));194194+195195+ data = kmalloc(enclen, GFP_KERNEL);196196+ if (!data)197197+ return -ENOMEM;290198291199 file = dentry_open(path, O_RDONLY, current_cred());292292- if (IS_ERR(file))293293- return PTR_ERR(file);200200+ if (IS_ERR(file)) {201201+ ret = PTR_ERR(file);202202+ goto error;203203+ }294204295295- pos = 0;296296- ret = vfs_read(file, buffer, datalen, &pos);297297- fput(file);298298- if (ret >= 0 && ret != datalen)205205+ /* read file to kernel and decrypt */206206+ ret = kernel_read(file, 0, data, enclen);207207+ if (ret >= 0 && ret != enclen) {299208 ret = -EIO;209209+ goto err_fput;210210+ }211211+212212+ ret = big_key_crypt(BIG_KEY_DEC, data, enclen, enckey);213213+ if (ret)214214+ goto err_fput;215215+216216+ ret = datalen;217217+218218+ /* copy decrypted data to user */219219+ if (copy_to_user(buffer, data, datalen) != 0)220220+ ret = -EFAULT;221221+222222+err_fput:223223+ fput(file);224224+error:225225+ kfree(data);300226 } else {301227 ret = datalen;302228 if (copy_to_user(buffer, key->payload.data[big_key_data],···331209 return ret;332210}333211212212+/*213213+ * Register key type214214+ */334215static int __init big_key_init(void)335216{336217 return register_key_type(&key_type_big_key);337218}219219+220220+/*221221+ * Initialize big_key crypto and RNG algorithms222222+ */223223+static int __init big_key_crypto_init(void)224224+{225225+ int ret = -EINVAL;226226+227227+ /* init RNG */228228+ big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);229229+ if (IS_ERR(big_key_rng)) {230230+ big_key_rng = NULL;231231+ return -EFAULT;232232+ }233233+234234+ /* seed RNG */235235+ ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));236236+ if (ret)237237+ goto error;238238+239239+ /* init block cipher */240240+ big_key_blkcipher = crypto_alloc_blkcipher(big_key_alg_name, 0, 0);241241+ if (IS_ERR(big_key_blkcipher)) {242242+ big_key_blkcipher = NULL;243243+ ret = -EFAULT;244244+ goto error;245245+ }246246+247247+ return 0;248248+249249+error:250250+ crypto_free_rng(big_key_rng);251251+ big_key_rng = NULL;252252+ return ret;253253+}254254+338255device_initcall(big_key_init);256256+late_initcall(big_key_crypto_init);
+4
security/keys/compat.c
···132132 case KEYCTL_GET_PERSISTENT:133133 return keyctl_get_persistent(arg2, arg3);134134135135+ case KEYCTL_DH_COMPUTE:136136+ return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),137137+ arg4);138138+135139 default:136140 return -EOPNOTSUPP;137141 }
+160
security/keys/dh.c
···11+/* Crypto operations using stored keys22+ *33+ * Copyright (c) 2016, Intel Corporation44+ *55+ * This program is free software; you can redistribute it and/or66+ * modify it under the terms of the GNU General Public License77+ * as published by the Free Software Foundation; either version88+ * 2 of the License, or (at your option) any later version.99+ */1010+1111+#include <linux/mpi.h>1212+#include <linux/slab.h>1313+#include <linux/uaccess.h>1414+#include <keys/user-type.h>1515+#include "internal.h"1616+1717+/*1818+ * Public key or shared secret generation function [RFC2631 sec 2.1.1]1919+ *2020+ * ya = g^xa mod p;2121+ * or2222+ * ZZ = yb^xa mod p;2323+ *2424+ * where xa is the local private key, ya is the local public key, g is2525+ * the generator, p is the prime, yb is the remote public key, and ZZ2626+ * is the shared secret.2727+ *2828+ * Both are the same calculation, so g or yb are the "base" and ya or2929+ * ZZ are the "result".3030+ */3131+static int do_dh(MPI result, MPI base, MPI xa, MPI p)3232+{3333+ return mpi_powm(result, base, xa, p);3434+}3535+3636+static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi)3737+{3838+ struct key *key;3939+ key_ref_t key_ref;4040+ long status;4141+ ssize_t ret;4242+4343+ key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);4444+ if (IS_ERR(key_ref)) {4545+ ret = -ENOKEY;4646+ goto error;4747+ }4848+4949+ key = key_ref_to_ptr(key_ref);5050+5151+ ret = -EOPNOTSUPP;5252+ if (key->type == &key_type_user) {5353+ down_read(&key->sem);5454+ status = key_validate(key);5555+ if (status == 0) {5656+ const struct user_key_payload *payload;5757+5858+ payload = user_key_payload(key);5959+6060+ if (maxlen == 0) {6161+ *mpi = NULL;6262+ ret = payload->datalen;6363+ } else if (payload->datalen <= maxlen) {6464+ *mpi = mpi_read_raw_data(payload->data,6565+ payload->datalen);6666+ if (*mpi)6767+ ret = payload->datalen;6868+ } else {6969+ ret = -EINVAL;7070+ }7171+ }7272+ up_read(&key->sem);7373+ }7474+7575+ key_put(key);7676+error:7777+ return ret;7878+}7979+8080+long keyctl_dh_compute(struct keyctl_dh_params __user *params,8181+ char __user *buffer, size_t buflen)8282+{8383+ long ret;8484+ MPI base, private, prime, result;8585+ unsigned nbytes;8686+ struct keyctl_dh_params pcopy;8787+ uint8_t *kbuf;8888+ ssize_t keylen;8989+ size_t resultlen;9090+9191+ if (!params || (!buffer && buflen)) {9292+ ret = -EINVAL;9393+ goto out;9494+ }9595+ if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {9696+ ret = -EFAULT;9797+ goto out;9898+ }9999+100100+ keylen = mpi_from_key(pcopy.prime, buflen, &prime);101101+ if (keylen < 0 || !prime) {102102+ /* buflen == 0 may be used to query the required buffer size,103103+ * which is the prime key length.104104+ */105105+ ret = keylen;106106+ goto out;107107+ }108108+109109+ /* The result is never longer than the prime */110110+ resultlen = keylen;111111+112112+ keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base);113113+ if (keylen < 0 || !base) {114114+ ret = keylen;115115+ goto error1;116116+ }117117+118118+ keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private);119119+ if (keylen < 0 || !private) {120120+ ret = keylen;121121+ goto error2;122122+ }123123+124124+ result = mpi_alloc(0);125125+ if (!result) {126126+ ret = -ENOMEM;127127+ goto error3;128128+ }129129+130130+ kbuf = kmalloc(resultlen, GFP_KERNEL);131131+ if (!kbuf) {132132+ ret = -ENOMEM;133133+ goto error4;134134+ }135135+136136+ ret = do_dh(result, base, private, prime);137137+ if (ret)138138+ goto error5;139139+140140+ ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL);141141+ if (ret != 0)142142+ goto error5;143143+144144+ ret = nbytes;145145+ if (copy_to_user(buffer, kbuf, nbytes) != 0)146146+ ret = -EFAULT;147147+148148+error5:149149+ kfree(kbuf);150150+error4:151151+ mpi_free(result);152152+error3:153153+ mpi_free(private);154154+error2:155155+ mpi_free(base);156156+error1:157157+ mpi_free(prime);158158+out:159159+ return ret;160160+}
···491491 */492492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,493493 const struct cred *cred, key_perm_t perm,494494- unsigned long flags, struct key *dest)494494+ unsigned long flags,495495+ int (*restrict_link)(struct key *,496496+ const struct key_type *,497497+ const union key_payload *),498498+ struct key *dest)495499{496500 struct key *keyring;497501 int ret;498502499503 keyring = key_alloc(&key_type_keyring, description,500500- uid, gid, cred, perm, flags);504504+ uid, gid, cred, perm, flags, restrict_link);501505 if (!IS_ERR(keyring)) {502506 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);503507 if (ret < 0) {···513509 return keyring;514510}515511EXPORT_SYMBOL(keyring_alloc);512512+513513+/**514514+ * restrict_link_reject - Give -EPERM to restrict link515515+ * @keyring: The keyring being added to.516516+ * @type: The type of key being added.517517+ * @payload: The payload of the key intended to be added.518518+ *519519+ * Reject the addition of any links to a keyring. It can be overridden by520520+ * passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when521521+ * adding a key to a keyring.522522+ *523523+ * This is meant to be passed as the restrict_link parameter to524524+ * keyring_alloc().525525+ */526526+int restrict_link_reject(struct key *keyring,527527+ const struct key_type *type,528528+ const union key_payload *payload)529529+{530530+ return -EPERM;531531+}516532517533/*518534 * By default, we keys found by getting an exact match on their descriptions.···12151191 up_write(&keyring->sem);12161192}1217119311941194+/*11951195+ * Check addition of keys to restricted keyrings.11961196+ */11971197+static int __key_link_check_restriction(struct key *keyring, struct key *key)11981198+{11991199+ if (!keyring->restrict_link)12001200+ return 0;12011201+ return keyring->restrict_link(keyring, key->type, &key->payload);12021202+}12031203+12181204/**12191205 * key_link - Link a key to a keyring12201206 * @keyring: The keyring to make the link in.···12551221 key_check(keyring);12561222 key_check(key);1257122312581258- if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&12591259- !test_bit(KEY_FLAG_TRUSTED, &key->flags))12601260- return -EPERM;12611261-12621224 ret = __key_link_begin(keyring, &key->index_key, &edit);12631225 if (ret == 0) {12641226 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));12651265- ret = __key_link_check_live_key(keyring, key);12271227+ ret = __key_link_check_restriction(keyring, key);12281228+ if (ret == 0)12291229+ ret = __key_link_check_live_key(keyring, key);12661230 if (ret == 0)12671231 __key_link(key, &edit);12681232 __key_link_end(keyring, &key->index_key, edit);