security/keys/trusted-keys/trusted_caam.c

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

File Facts

System
Linux kernel
Corpus path
security/keys/trusted-keys/trusted_caam.c
Extension
.c
Size
4208 bytes
Lines
192
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

switch (token) {
		case opt_key_enc_algo:
			res = kstrtou16(args[0].from, 16, &key_enc_algo);
			if (res < 0)
				return -EINVAL;
			pkey_info->key_enc_algo = key_enc_algo;
			break;
		default:
			return -EINVAL;
		}
	}
	return 0;
}

static bool is_key_pkey(char **datablob)
{
	char *c = NULL;

	do {
		/* Second argument onwards,
		 * determine if tied to HW
		 */
		c = strsep(datablob, " \t");
		if (c && (strcmp(c, "pk") == 0))
			return true;
	} while (c);

	return false;
}

static int trusted_caam_seal(struct trusted_key_payload *p, char *datablob)
{
	int ret;
	struct caam_blob_info info = {
		.input  = p->key,  .input_len   = p->key_len,
		.output = p->blob, .output_len  = MAX_BLOB_SIZE,
		.key_mod = KEYMOD, .key_mod_len = sizeof(KEYMOD) - 1,
	};

	/*
	 * If it is to be treated as protected key,
	 * read next arguments too.
	 */
	if (is_key_pkey(&datablob)) {
		info.pkey_info.plain_key_sz = p->key_len;
		info.pkey_info.is_pkey = 1;
		ret = get_pkey_options(datablob, &info.pkey_info);
		if (ret < 0)
			return 0;
		dump_options(&info.pkey_info);
	}

	ret = caam_encap_blob(blobifier, &info);
	if (ret)
		return ret;

	p->blob_len = info.output_len;
	if (info.pkey_info.is_pkey) {
		p->key_len = p->blob_len + sizeof(struct caam_pkey_info);
		memcpy(p->key, &info.pkey_info, sizeof(struct caam_pkey_info));
		memcpy(p->key + sizeof(struct caam_pkey_info), p->blob, p->blob_len);
	}

	return 0;
}

static int trusted_caam_unseal(struct trusted_key_payload *p, char *datablob)
{
	int ret;
	struct caam_blob_info info = {
		.input   = p->blob,  .input_len  = p->blob_len,
		.output  = p->key,   .output_len = MAX_KEY_SIZE,
		.key_mod = KEYMOD,  .key_mod_len = sizeof(KEYMOD) - 1,
	};

	if (is_key_pkey(&datablob)) {
		info.pkey_info.plain_key_sz = p->blob_len - CAAM_BLOB_OVERHEAD;
		info.pkey_info.is_pkey = 1;
		ret = get_pkey_options(datablob, &info.pkey_info);
		if (ret < 0)
			return 0;
		dump_options(&info.pkey_info);

		p->key_len = p->blob_len + sizeof(struct caam_pkey_info);
		memcpy(p->key, &info.pkey_info, sizeof(struct caam_pkey_info));
		memcpy(p->key + sizeof(struct caam_pkey_info), p->blob, p->blob_len);

		return 0;
	}

Annotation

Implementation Notes