security/keys/trusted-keys/trusted_core.c

Source file repositories/reference/linux-study-clean/security/keys/trusted-keys/trusted_core.c

File Facts

System
Linux kernel
Corpus path
security/keys/trusted-keys/trusted_core.c
Extension
.c
Size
9743 bytes
Lines
411
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: exported/initcall integration point
Status
integration 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 (ret != key_len) {
			pr_info("key_create failed (%d)\n", ret);
			ret = -EIO;
			goto out;
		}

		ret = static_call(trusted_key_seal)(payload, datablob);
		if (ret < 0)
			pr_info("key_seal failed (%d)\n", ret);
		break;
	default:
		ret = -EINVAL;
	}
out:
	kfree_sensitive(orig_datablob);
	if (!ret)
		rcu_assign_keypointer(key, payload);
	else
		kfree_sensitive(payload);
	return ret;
}

static void trusted_rcu_free(struct rcu_head *rcu)
{
	struct trusted_key_payload *p;

	p = container_of(rcu, struct trusted_key_payload, rcu);
	kfree_sensitive(p);
}

/*
 * trusted_update - reseal an existing key with new PCR values
 */
static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
{
	struct trusted_key_payload *p;
	struct trusted_key_payload *new_p;
	size_t datalen = prep->datalen;
	char *datablob, *orig_datablob;
	int ret = 0;

	if (key_is_negative(key))
		return -ENOKEY;
	p = key->payload.data[0];
	if (!p->migratable)
		return -EPERM;
	if (datalen == 0 || datalen > 32767 || !prep->data)
		return -EINVAL;

	orig_datablob = datablob = kmalloc(datalen + 1, GFP_KERNEL);
	if (!datablob)
		return -ENOMEM;

	new_p = trusted_payload_alloc(key);
	if (!new_p) {
		ret = -ENOMEM;
		goto out;
	}

	memcpy(datablob, prep->data, datalen);
	datablob[datalen] = '\0';
	ret = datablob_parse(&datablob, new_p);
	if (ret != Opt_update) {
		ret = -EINVAL;
		kfree_sensitive(new_p);
		goto out;
	}

	/* copy old key values, and reseal with new pcrs */
	new_p->migratable = p->migratable;
	new_p->key_len = p->key_len;
	memcpy(new_p->key, p->key, p->key_len);
	dump_payload(p);
	dump_payload(new_p);

	ret = static_call(trusted_key_seal)(new_p, datablob);
	if (ret < 0) {
		pr_info("key_seal failed (%d)\n", ret);
		kfree_sensitive(new_p);
		goto out;
	}

	rcu_assign_keypointer(key, new_p);
	call_rcu(&p->rcu, trusted_rcu_free);
out:
	kfree_sensitive(orig_datablob);
	return ret;
}

/*

Annotation

Implementation Notes