security/integrity/digsig_asymmetric.c

Source file repositories/reference/linux-study-clean/security/integrity/digsig_asymmetric.c

File Facts

System
Linux kernel
Corpus path
security/integrity/digsig_asymmetric.c
Extension
.c
Size
7736 bytes
Lines
303
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!IS_ERR(kref)) {
			pr_err("Key '%s' is in ima_blacklist_keyring\n", name);
			return ERR_PTR(-EKEYREJECTED);
		}
	}

	if (keyring) {
		/* search in specific keyring */
		key_ref_t kref;

		kref = keyring_search(make_key_ref(keyring, 1),
				      &key_type_asymmetric, name, true);
		if (IS_ERR(kref))
			key = ERR_CAST(kref);
		else
			key = key_ref_to_ptr(kref);
	} else {
		key = request_key(&key_type_asymmetric, name, NULL);
	}

	if (IS_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:
		case -ENOTDIR:
		case -EAGAIN:
			return ERR_PTR(-ENOKEY);
		default:
			return key;
		}
	}

	pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key));

	return key;
}

/**
 * asymmetric_verify_common -- sigv2 and sigv3 common verify function
 * @key: The key to use for signature verification; caller must free it
 * @pk: The associated public key; must not be NULL
 * @sig: The xattr signature
 * @siglen: The length of the xattr signature; must be at least
 *          sizeof(struct signature_v2_hdr)
 * @data: The data to verify the signature on
 * @datalen: Length of @data
 */
static int asymmetric_verify_common(const struct key *key,
				    const struct public_key *pk,
				    const char *sig, int siglen,
				    const char *data, int datalen)
{
	struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
	struct public_key_signature pks;
	int ret;

	siglen -= sizeof(*hdr);

	if (siglen != be16_to_cpu(hdr->sig_size))
		return -EBADMSG;

	if (hdr->hash_algo >= HASH_ALGO__LAST)
		return -ENOPKG;

	memset(&pks, 0, sizeof(pks));

	pks.hash_algo = hash_algo_name[hdr->hash_algo];
	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.m = (u8 *)data;
	pks.m_size = datalen;

Annotation

Implementation Notes