diff options
Diffstat (limited to 'security/integrity/digsig_asymmetric.c')
| -rw-r--r-- | security/integrity/digsig_asymmetric.c | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index d775e03fbbcc..457c0a396caf 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -1,17 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2013 Intel Corporation * * Author: * Dmitry Kasatkin <dmitry.kasatkin@intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include <linux/err.h> #include <linux/ratelimit.h> #include <linux/key-type.h> @@ -39,7 +33,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) key_ref_t kref; kref = keyring_search(make_key_ref(key, 1), - &key_type_asymmetric, name); + &key_type_asymmetric, name, true); if (!IS_ERR(kref)) { pr_err("Key '%s' is in ima_blacklist_keyring\n", name); return ERR_PTR(-EKEYREJECTED); @@ -51,7 +45,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) key_ref_t kref; kref = keyring_search(make_key_ref(keyring, 1), - &key_type_asymmetric, name); + &key_type_asymmetric, name, true); if (IS_ERR(kref)) key = ERR_CAST(kref); else @@ -61,8 +55,14 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) } if (IS_ERR(key)) { - pr_err_ratelimited("Request for unknown key '%s' err %ld\n", - name, PTR_ERR(key)); + if (keyring) + pr_err_ratelimited("Request for unknown key '%s' in '%s' keyring. err %ld\n", + name, keyring->description, + PTR_ERR(key)); + else + pr_err_ratelimited("Request for unknown key '%s' err %ld\n", + name, PTR_ERR(key)); + switch (PTR_ERR(key)) { /* Hide some search errors */ case -EACCES: @@ -84,8 +84,9 @@ int asymmetric_verify(struct key *keyring, const char *sig, { struct public_key_signature pks; struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig; + const struct public_key *pk; struct key *key; - int ret = -ENOMEM; + int ret; if (siglen <= sizeof(*hdr)) return -EBADMSG; @@ -104,38 +105,29 @@ int asymmetric_verify(struct key *keyring, const char *sig, memset(&pks, 0, sizeof(pks)); - pks.pkey_algo = "rsa"; pks.hash_algo = hash_algo_name[hdr->hash_algo]; - pks.encoding = "pkcs1"; + + pk = asymmetric_key_public_key(key); + pks.pkey_algo = pk->pkey_algo; + if (!strcmp(pk->pkey_algo, "rsa")) { + pks.encoding = "pkcs1"; + } else if (!strncmp(pk->pkey_algo, "ecdsa-", 6)) { + /* edcsa-nist-p192 etc. */ + pks.encoding = "x962"; + } else if (!strcmp(pk->pkey_algo, "ecrdsa")) { + pks.encoding = "raw"; + } else { + ret = -ENOPKG; + goto out; + } + pks.digest = (u8 *)data; pks.digest_size = datalen; pks.s = hdr->sig; pks.s_size = siglen; ret = verify_signature(key, &pks); +out: key_put(key); pr_debug("%s() = %d\n", __func__, ret); return ret; } - -/** - * integrity_kernel_module_request - prevent crypto-pkcs1pad(rsa,*) requests - * @kmod_name: kernel module name - * - * We have situation, when public_key_verify_signature() in case of RSA - * algorithm use alg_name to store internal information in order to - * construct an algorithm on the fly, but crypto_larval_lookup() will try - * to use alg_name in order to load kernel module with same name. - * Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules, - * we are safe to fail such module request from crypto_larval_lookup(). - * - * In this way we prevent modprobe execution during digsig verification - * and avoid possible deadlock if modprobe and/or it's dependencies - * also signed with digsig. - */ -int integrity_kernel_module_request(char *kmod_name) -{ - if (strncmp(kmod_name, "crypto-pkcs1pad(rsa,", 20) == 0) - return -EINVAL; - - return 0; -} |
