Commit 1486141a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'keys-trusted-next-6.11-rc4' of...

Merge tag 'keys-trusted-next-6.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull key fixes from Jarkko Sakkinen:
 "Two bug fixes for a memory corruption bug and a memory leak bug in the
  DCP trusted keys type.

  Just as a reminder DCP was a crypto coprocessor in i.MX SoCs"

* tag 'keys-trusted-next-6.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  KEYS: trusted: dcp: fix leak of blob encryption key
  KEYS: trusted: fix DCP blob payload length assignment
parents 670c12ce 0e28bf61
Loading
Loading
Loading
Loading
+22 −13
Original line number Diff line number Diff line
@@ -186,20 +186,21 @@ static int do_aead_crypto(u8 *in, u8 *out, size_t len, u8 *key, u8 *nonce,
	return ret;
}

static int decrypt_blob_key(u8 *key)
static int decrypt_blob_key(u8 *encrypted_key, u8 *plain_key)
{
	return do_dcp_crypto(key, key, false);
	return do_dcp_crypto(encrypted_key, plain_key, false);
}

static int encrypt_blob_key(u8 *key)
static int encrypt_blob_key(u8 *plain_key, u8 *encrypted_key)
{
	return do_dcp_crypto(key, key, true);
	return do_dcp_crypto(plain_key, encrypted_key, true);
}

static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)
{
	struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
	int blen, ret;
	u8 plain_blob_key[AES_KEYSIZE_128];

	blen = calc_blob_len(p->key_len);
	if (blen > MAX_BLOB_SIZE)
@@ -207,30 +208,36 @@ static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)

	b->fmt_version = DCP_BLOB_VERSION;
	get_random_bytes(b->nonce, AES_KEYSIZE_128);
	get_random_bytes(b->blob_key, AES_KEYSIZE_128);
	get_random_bytes(plain_blob_key, AES_KEYSIZE_128);

	ret = do_aead_crypto(p->key, b->payload, p->key_len, b->blob_key,
	ret = do_aead_crypto(p->key, b->payload, p->key_len, plain_blob_key,
			     b->nonce, true);
	if (ret) {
		pr_err("Unable to encrypt blob payload: %i\n", ret);
		return ret;
		goto out;
	}

	ret = encrypt_blob_key(b->blob_key);
	ret = encrypt_blob_key(plain_blob_key, b->blob_key);
	if (ret) {
		pr_err("Unable to encrypt blob key: %i\n", ret);
		return ret;
		goto out;
	}

	b->payload_len = get_unaligned_le32(&p->key_len);
	put_unaligned_le32(p->key_len, &b->payload_len);
	p->blob_len = blen;
	return 0;
	ret = 0;

out:
	memzero_explicit(plain_blob_key, sizeof(plain_blob_key));

	return ret;
}

static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
{
	struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
	int blen, ret;
	u8 plain_blob_key[AES_KEYSIZE_128];

	if (b->fmt_version != DCP_BLOB_VERSION) {
		pr_err("DCP blob has bad version: %i, expected %i\n",
@@ -248,14 +255,14 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
		goto out;
	}

	ret = decrypt_blob_key(b->blob_key);
	ret = decrypt_blob_key(b->blob_key, plain_blob_key);
	if (ret) {
		pr_err("Unable to decrypt blob key: %i\n", ret);
		goto out;
	}

	ret = do_aead_crypto(b->payload, p->key, p->key_len + DCP_BLOB_AUTHLEN,
			     b->blob_key, b->nonce, false);
			     plain_blob_key, b->nonce, false);
	if (ret) {
		pr_err("Unwrap of DCP payload failed: %i\n", ret);
		goto out;
@@ -263,6 +270,8 @@ static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)

	ret = 0;
out:
	memzero_explicit(plain_blob_key, sizeof(plain_blob_key));

	return ret;
}