security/keys/trusted-keys/trusted_dcp.c

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

File Facts

System
Linux kernel
Corpus path
security/keys/trusted-keys/trusted_dcp.c
Extension
.c
Size
8881 bytes
Lines
357
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

struct dcp_blob_fmt {
	__u8 fmt_version;
	__u8 blob_key[AES_KEYSIZE_128];
	__u8 nonce[AES_KEYSIZE_128];
	__le32 payload_len;
	__u8 payload[];
} __packed;

static bool use_otp_key;
module_param_named(dcp_use_otp_key, use_otp_key, bool, 0);
MODULE_PARM_DESC(dcp_use_otp_key, "Use OTP instead of UNIQUE key for sealing");

static bool skip_zk_test;
module_param_named(dcp_skip_zk_test, skip_zk_test, bool, 0);
MODULE_PARM_DESC(dcp_skip_zk_test, "Don't test whether device keys are zero'ed");

static unsigned int calc_blob_len(unsigned int payload_len)
{
	return sizeof(struct dcp_blob_fmt) + payload_len + DCP_BLOB_AUTHLEN;
}

static int do_dcp_crypto(u8 *in, u8 *out, bool do_encrypt)
{
	struct skcipher_request *req = NULL;
	struct scatterlist src_sg, dst_sg;
	struct crypto_skcipher *tfm;
	u8 paes_key[DCP_PAES_KEYSIZE];
	DECLARE_CRYPTO_WAIT(wait);
	int res = 0;

	if (use_otp_key)
		paes_key[0] = DCP_PAES_KEY_OTP;
	else
		paes_key[0] = DCP_PAES_KEY_UNIQUE;

	tfm = crypto_alloc_skcipher("ecb-paes-dcp", CRYPTO_ALG_INTERNAL,
				    CRYPTO_ALG_INTERNAL);
	if (IS_ERR(tfm)) {
		res = PTR_ERR(tfm);
		tfm = NULL;
		goto out;
	}

	req = skcipher_request_alloc(tfm, GFP_NOFS);
	if (!req) {
		res = -ENOMEM;
		goto out;
	}

	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
				      CRYPTO_TFM_REQ_MAY_SLEEP,
				      crypto_req_done, &wait);
	res = crypto_skcipher_setkey(tfm, paes_key, sizeof(paes_key));
	if (res < 0)
		goto out;

	sg_init_one(&src_sg, in, AES_KEYSIZE_128);
	sg_init_one(&dst_sg, out, AES_KEYSIZE_128);
	skcipher_request_set_crypt(req, &src_sg, &dst_sg, AES_KEYSIZE_128,
				   NULL);

	if (do_encrypt)
		res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
	else
		res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);

out:
	skcipher_request_free(req);
	crypto_free_skcipher(tfm);

	return res;
}

static int do_aead_crypto(u8 *in, u8 *out, size_t len, u8 *key, u8 *nonce,
			  bool do_encrypt)
{
	struct aead_request *aead_req = NULL;
	struct scatterlist src_sg, dst_sg;
	struct crypto_aead *aead;
	int ret;
	DECLARE_CRYPTO_WAIT(wait);

	aead = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
	if (IS_ERR(aead)) {
		ret = PTR_ERR(aead);
		goto out;
	}

	ret = crypto_aead_setauthsize(aead, DCP_BLOB_AUTHLEN);
	if (ret < 0) {

Annotation

Implementation Notes