diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index a94c03a61d8f..826525e22b45 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -22,7 +22,7 @@ struct trusted_key_payload {
 	unsigned int key_len;
 	unsigned int blob_len;
 	unsigned char migratable;
-	unsigned char key[MAX_KEY_SIZE + 1];
+	unsigned char  *key;
 	unsigned char blob[MAX_BLOB_SIZE];
 };
 
diff --git a/include/keys/trusted_tpm.h b/include/keys/trusted_tpm.h
index a56d8e1298f2..5aa254c70820 100644
--- a/include/keys/trusted_tpm.h
+++ b/include/keys/trusted_tpm.h
@@ -47,6 +47,21 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
 			struct trusted_key_payload *payload,
 			struct trusted_key_options *options);
 
+#if defined(CONFIG_TRUSTED_KEYS) || \
+	(defined(CONFIG_TRUSTED_KEYS_MODULE) && defined(CONFIG_ENCRYPTED_KEYS_MODULE))
+void trusted_key_enable_access(void);
+void trusted_key_disable_access(void);
+#else
+static inline void trusted_key_enable_access(void)
+{
+
+}
+static inline void trusted_key_disable_access(void)
+{
+
+}
+#endif
+
 #define TPM_DEBUG 0
 
 #if TPM_DEBUG
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 192e531c146f..d996e9fd2dec 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -20,6 +20,7 @@
 #include <linux/err.h>
 #include <keys/user-type.h>
 #include <keys/trusted-type.h>
+#include <keys/trusted_tpm.h>
 #include <keys/encrypted-type.h>
 #include <linux/key-type.h>
 #include <linux/random.h>
@@ -344,10 +345,12 @@ static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen,
 }
 
 enum derived_key_type { ENC_KEY, AUTH_KEY };
+enum master_key_type { TRUSTED_KEY, USER_KEY };
 
 /* Derive authentication/encryption key from trusted key */
 static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
-			   const u8 *master_key, size_t master_keylen)
+			   const u8 *master_key, size_t master_keylen,
+			   enum master_key_type m_key_type)
 {
 	u8 *derived_buf;
 	unsigned int derived_buf_len;
@@ -366,8 +369,13 @@ static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
 	else
 		strcpy(derived_buf, "ENC_KEY");
 
+	if (unlikely(m_key_type == TRUSTED_KEY))
+		trusted_key_enable_access();
 	memcpy(derived_buf + strlen(derived_buf) + 1, master_key,
 	       master_keylen);
+	if (unlikely(m_key_type == TRUSTED_KEY))
+		trusted_key_disable_access();
+
 	ret = crypto_shash_tfm_digest(hash_tfm, derived_buf, derived_buf_len,
 				      derived_key);
 	kfree_sensitive(derived_buf);
@@ -408,7 +416,8 @@ static struct skcipher_request *init_skcipher_req(const u8 *key,
 }
 
 static struct key *request_master_key(struct encrypted_key_payload *epayload,
-				      const u8 **master_key, size_t *master_keylen)
+				      const u8 **master_key, size_t *master_keylen,
+				      enum master_key_type *m_key_type)
 {
 	struct key *mkey = ERR_PTR(-EINVAL);
 
@@ -417,11 +426,13 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
 		mkey = request_trusted_key(epayload->master_desc +
 					   KEY_TRUSTED_PREFIX_LEN,
 					   master_key, master_keylen);
+		*m_key_type = TRUSTED_KEY;
 	} else if (!strncmp(epayload->master_desc, KEY_USER_PREFIX,
 			    KEY_USER_PREFIX_LEN)) {
 		mkey = request_user_key(epayload->master_desc +
 					KEY_USER_PREFIX_LEN,
 					master_key, master_keylen);
+		*m_key_type = USER_KEY;
 	} else
 		goto out;
 
@@ -486,13 +497,14 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload,
 }
 
 static int datablob_hmac_append(struct encrypted_key_payload *epayload,
-				const u8 *master_key, size_t master_keylen)
+				const u8 *master_key, size_t master_keylen,
+				enum master_key_type m_key_type)
 {
 	u8 derived_key[HASH_SIZE];
 	u8 *digest;
 	int ret;
 
-	ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
+	ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen, m_key_type);
 	if (ret < 0)
 		goto out;
 
@@ -509,7 +521,7 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
 /* verify HMAC before decrypting encrypted key */
 static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
 				const u8 *format, const u8 *master_key,
-				size_t master_keylen)
+				size_t master_keylen, enum master_key_type m_key_type)
 {
 	u8 derived_key[HASH_SIZE];
 	u8 digest[HASH_SIZE];
@@ -517,7 +529,7 @@ static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
 	char *p;
 	unsigned short len;
 
-	ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
+	ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen, m_key_type);
 	if (ret < 0)
 		goto out;
 
@@ -664,6 +676,7 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
 	size_t master_keylen;
 	size_t asciilen;
 	int ret;
+	enum master_key_type m_key_type;
 
 	encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
 	asciilen = (ivsize + 1 + encrypted_datalen + HASH_SIZE) * 2;
@@ -685,17 +698,17 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
 	if (ret < 0)
 		return -EINVAL;
 
-	mkey = request_master_key(epayload, &master_key, &master_keylen);
+	mkey = request_master_key(epayload, &master_key, &master_keylen, &m_key_type);
 	if (IS_ERR(mkey))
 		return PTR_ERR(mkey);
 
-	ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
+	ret = datablob_hmac_verify(epayload, format, master_key, master_keylen, m_key_type);
 	if (ret < 0) {
 		pr_err("encrypted_key: bad hmac (%d)\n", ret);
 		goto out;
 	}
 
-	ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen);
+	ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen, m_key_type);
 	if (ret < 0)
 		goto out;
 
@@ -908,6 +921,7 @@ static long encrypted_read(const struct key *key, char *buffer,
 	char *ascii_buf;
 	size_t asciiblob_len;
 	int ret;
+	enum master_key_type m_key_type;
 
 	epayload = dereference_key_locked(key);
 
@@ -919,11 +933,11 @@ static long encrypted_read(const struct key *key, char *buffer,
 	if (!buffer || buflen < asciiblob_len)
 		return asciiblob_len;
 
-	mkey = request_master_key(epayload, &master_key, &master_keylen);
+	mkey = request_master_key(epayload, &master_key, &master_keylen, &m_key_type);
 	if (IS_ERR(mkey))
 		return PTR_ERR(mkey);
 
-	ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen);
+	ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen, m_key_type);
 	if (ret < 0)
 		goto out;
 
@@ -931,7 +945,7 @@ static long encrypted_read(const struct key *key, char *buffer,
 	if (ret < 0)
 		goto out;
 
-	ret = datablob_hmac_append(epayload, master_key, master_keylen);
+	ret = datablob_hmac_append(epayload, master_key, master_keylen, m_key_type);
 	if (ret < 0)
 		goto out;
 
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index b9fe02e5f84f..62e6c5eb8e2b 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -26,9 +26,49 @@
 #include <linux/capability.h>
 #include <linux/tpm.h>
 #include <linux/tpm_command.h>
+#include <linux/pkeys.h>
+#include <linux/vmalloc.h>
+#include <uapi/asm-generic/mman-common.h>
 
 #include <keys/trusted_tpm.h>
 
+#define PKEY_INVALID (INT_MIN)
+static int trusted_keys_pkey = PKEY_INVALID;
+
+#if defined(CONFIG_TRUSTED_KEYS) || \
+	(defined(CONFIG_TRUSTED_KEYS_MODULE) && defined(CONFIG_ENCRYPTED_KEYS_MODULE))
+void trusted_key_disable_access(void)
+{
+	if (trusted_keys_pkey == PKEY_INVALID)
+		return;
+
+	pks_mknoaccess(trusted_keys_pkey, false);
+
+}
+EXPORT_SYMBOL_GPL(trusted_key_disable_access);
+
+void trusted_key_enable_access(void)
+{
+	if (trusted_keys_pkey == PKEY_INVALID)
+		return;
+
+	pks_mkrdwr(trusted_keys_pkey, false);
+}
+EXPORT_SYMBOL_GPL(trusted_key_enable_access);
+#endif
+
+static void trusted_payload_free(struct trusted_key_payload *p)
+{
+	if (!p)
+		return;
+
+	trusted_key_enable_access();
+	memzero_explicit(p->key, MAX_KEY_SIZE + 1);
+	trusted_key_disable_access();
+	vfree(p->key);
+	kzfree(p);
+}
+
 static const char hmac_alg[] = "hmac(sha1)";
 static const char hash_alg[] = "sha1";
 static struct tpm_chip *chip;
@@ -663,12 +703,15 @@ static int key_seal(struct trusted_key_payload *p,
 	if (ret)
 		return ret;
 
+	trusted_key_enable_access();
 	/* include migratable flag at end of sealed key */
 	p->key[p->key_len] = p->migratable;
 
 	ret = tpm_seal(&tb, o->keytype, o->keyhandle, o->keyauth,
 		       p->key, p->key_len + 1, p->blob, &p->blob_len,
 		       o->blobauth, o->pcrinfo, o->pcrinfo_len);
+	trusted_key_disable_access();
+
 	if (ret < 0)
 		pr_info("trusted_key: srkseal failed (%d)\n", ret);
 
@@ -689,6 +732,7 @@ static int key_unseal(struct trusted_key_payload *p,
 	if (ret)
 		return ret;
 
+	trusted_key_enable_access();
 	ret = tpm_unseal(&tb, o->keyhandle, o->keyauth, p->blob, p->blob_len,
 			 o->blobauth, p->key, &p->key_len);
 	if (ret < 0)
@@ -696,6 +740,7 @@ static int key_unseal(struct trusted_key_payload *p,
 	else
 		/* pull migratable flag out of sealed key */
 		p->migratable = p->key[--p->key_len];
+	trusted_key_disable_access();
 
 	tpm_buf_destroy(&tb);
 	return ret;
@@ -928,15 +973,26 @@ static struct trusted_key_options *trusted_options_alloc(void)
 
 static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
 {
-	struct trusted_key_payload *p = NULL;
+	struct trusted_key_payload *p;
 	int ret;
 
 	ret = key_payload_reserve(key, sizeof *p);
 	if (ret < 0)
-		return p;
+		return NULL;
 	p = kzalloc(sizeof *p, GFP_KERNEL);
-	if (p)
+	if (p) {
 		p->migratable = 1; /* migratable by default */
+		if (trusted_keys_pkey == PKEY_INVALID)
+			p->key = vmalloc(MAX_KEY_SIZE + 1);
+		else
+			p->key = vmalloc_pks(MAX_KEY_SIZE + 1, trusted_keys_pkey);
+
+		if (!(p->key)) {
+			kfree(p);
+			return NULL;
+		}
+	}
+
 	return p;
 }
 
@@ -1012,7 +1068,9 @@ static int trusted_instantiate(struct key *key,
 		break;
 	case Opt_new:
 		key_len = payload->key_len;
+		trusted_key_enable_access();
 		ret = tpm_get_random(chip, payload->key, key_len);
+		trusted_key_disable_access();
 		if (ret != key_len) {
 			pr_info("trusted_key: key_create failed (%d)\n", ret);
 			goto out;
@@ -1036,7 +1094,7 @@ static int trusted_instantiate(struct key *key,
 	if (!ret)
 		rcu_assign_keypointer(key, payload);
 	else
-		kfree_sensitive(payload);
+		trusted_payload_free(payload);
 	return ret;
 }
 
@@ -1045,7 +1103,7 @@ 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_payload_free(p);
 }
 
 /*
@@ -1087,34 +1145,38 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
 	ret = datablob_parse(datablob, new_p, new_o);
 	if (ret != Opt_update) {
 		ret = -EINVAL;
-		kfree_sensitive(new_p);
+		trusted_payload_free(new_p);
 		goto out;
 	}
 
 	if (!new_o->keyhandle) {
 		ret = -EINVAL;
-		kfree_sensitive(new_p);
+		trusted_payload_free(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;
+
+	trusted_key_enable_access();
 	memcpy(new_p->key, p->key, p->key_len);
+	trusted_key_disable_access();
+
 	dump_payload(p);
 	dump_payload(new_p);
 
 	ret = key_seal(new_p, new_o);
 	if (ret < 0) {
 		pr_info("trusted_key: key_seal failed (%d)\n", ret);
-		kfree_sensitive(new_p);
+		trusted_payload_free(new_p);
 		goto out;
 	}
 	if (new_o->pcrlock) {
 		ret = pcrlock(new_o->pcrlock);
 		if (ret < 0) {
 			pr_info("trusted_key: pcrlock failed (%d)\n", ret);
-			kfree_sensitive(new_p);
+			trusted_payload_free(new_p);
 			goto out;
 		}
 	}
@@ -1219,7 +1281,7 @@ static int __init init_digests(void)
 
 static int __init init_trusted(void)
 {
-	int ret;
+	int ret, key_id;
 
 	/* encrypted_keys.ko depends on successful load of this module even if
 	 * TPM is not used.
@@ -1237,6 +1299,14 @@ static int __init init_trusted(void)
 	ret = register_key_type(&key_type_trusted);
 	if (ret < 0)
 		goto err_release;
+
+	/* Attempt to reserve a PKS key for protecting the trusted keys.
+	 * Note the pkey is never free'ed. This is run at init time and
+	 * we either get the key or we do not.
+	 */
+	key_id = pks_key_alloc("Keyring Trusted Keys");
+	if (key_id >= 0)
+		trusted_keys_pkey = key_id;
 	return 0;
 err_release:
 	trusted_shash_release();
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 08ec7f48f01d..67281394523f 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -8,6 +8,8 @@
 #include <linux/err.h>
 #include <linux/tpm.h>
 #include <linux/tpm_command.h>
+#include <linux/pkeys.h>
+#include <uapi/asm-generic/mman-common.h>
 
 #include <keys/trusted-type.h>
 #include <keys/trusted_tpm.h>
@@ -96,7 +98,11 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 	tpm_buf_append_u16(&buf, TPM_DIGEST_SIZE);
 	tpm_buf_append(&buf, options->blobauth, TPM_DIGEST_SIZE);
 	tpm_buf_append_u16(&buf, payload->key_len + 1);
+
+	trusted_key_enable_access();
 	tpm_buf_append(&buf, payload->key, payload->key_len);
+	trusted_key_disable_access();
+
 	tpm_buf_append_u8(&buf, payload->migratable);
 
 	/* public */
@@ -278,7 +284,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
 		}
 		data = &buf.data[TPM_HEADER_SIZE + 6];
 
+		trusted_key_enable_access();
 		memcpy(payload->key, data, data_len - 1);
+		trusted_key_disable_access();
+
 		payload->key_len = data_len - 1;
 		payload->migratable = data[data_len - 1];
 	}
