diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index f5f12727771a..1d8201b1fb8a 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -28,9 +28,23 @@ extern int evm_initialized;
 extern char *evm_hmac;
 extern char *evm_hash;
 
-#define EVM_ATTR_FSUUID		0x0001
+/* Extended attributes */
+#define EVM_SELINUX (1L << 0)
+#define EVM_SMACK (1L << 1)
+#define EVM_SMACKEXEC (1L << 2)
+#define EVM_SMACKTRANSMUTE (1L << 3)
+#define EVM_SMACKMMAP (1L << 4)
+#define EVM_IMA (1L << 5)
+#define EVM_CAPS (1L << 6)
+/* Other metadata */
+#define EVM_INODE (1L << 32)
+#define EVM_OWNERSHIP (1L << 33)
+#define EVM_MODE (1L << 34)
+#define EVM_FSUUID (1L << 35)
+/* Behavioural flags */
+#define EVM_HMAC_CONVERT (1L << 63)
 
-extern int evm_hmac_attrs;
+extern u64 evm_default_flags;
 
 extern struct crypto_shash *hmac_tfm;
 extern struct crypto_shash *hash_tfm;
@@ -45,10 +59,10 @@ int evm_update_evmxattr(struct dentry *dentry,
 			size_t req_xattr_value_len);
 int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value,
-		  size_t req_xattr_value_len, char *digest);
+		  size_t req_xattr_value_len, u64 flags, char *digest);
 int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value,
-		  size_t req_xattr_value_len, char *digest);
+		  size_t req_xattr_value_len, u64 flags, char *digest);
 int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
 		  char *hmac_val);
 int evm_init_secfs(void);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 1d32cd20009a..9ce55ac6781e 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -138,7 +138,7 @@ static struct shash_desc *init_desc(char type)
  * protection.)
  */
 static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
-			  char *digest)
+			  u64 flags, char *digest)
 {
 	struct h_misc {
 		unsigned long ino;
@@ -149,8 +149,10 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	} hmac_misc;
 
 	memset(&hmac_misc, 0, sizeof(hmac_misc));
-	hmac_misc.ino = inode->i_ino;
-	hmac_misc.generation = inode->i_generation;
+	if (flags & EVM_INODE) {
+		hmac_misc.ino = inode->i_ino;
+		hmac_misc.generation = inode->i_generation;
+	}
 	/* The hmac uid and gid must be encoded in the initial user
 	 * namespace (not the filesystems user namespace) as encoding
 	 * them in the filesystems user namespace allows an attack
@@ -159,11 +161,14 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	 * filesystem for real on next boot and trust it because
 	 * everything is signed.
 	 */
-	hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
-	hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
-	hmac_misc.mode = inode->i_mode;
+	if (flags & EVM_OWNERSHIP) {
+		hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
+		hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
+	}
+	if (flags & EVM_MODE)
+		hmac_misc.mode = inode->i_mode;
 	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
-	if (evm_hmac_attrs & EVM_ATTR_FSUUID)
+	if (flags & EVM_FSUUID)
 		crypto_shash_update(desc, &inode->i_sb->s_uuid.b[0],
 				    sizeof(inode->i_sb->s_uuid));
 	crypto_shash_final(desc, digest);
@@ -180,15 +185,16 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
 				const char *req_xattr_name,
 				const char *req_xattr_value,
 				size_t req_xattr_value_len,
-				char type, char *digest)
+				char type, u64 flags, char *digest)
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct shash_desc *desc;
-	char **xattrname;
+	char *xattrname;
 	size_t xattr_size = 0;
 	char *xattr_value = NULL;
 	int error;
 	int size;
+	int i;
 
 	if (!(inode->i_opflags & IOP_XATTR))
 		return -EOPNOTSUPP;
@@ -198,15 +204,19 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
 		return PTR_ERR(desc);
 
 	error = -ENODATA;
-	for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
+	for (i = 0; evm_config_xattrnames[i] != NULL; i++) {
+		if (!(flags & (1 << i)))
+			continue;
+
+		xattrname = evm_config_xattrnames[i];
 		if ((req_xattr_name && req_xattr_value)
-		    && !strcmp(*xattrname, req_xattr_name)) {
+		    && !strcmp(xattrname, req_xattr_name)) {
 			error = 0;
 			crypto_shash_update(desc, (const u8 *)req_xattr_value,
 					     req_xattr_value_len);
 			continue;
 		}
-		size = vfs_getxattr_alloc(dentry, *xattrname,
+		size = vfs_getxattr_alloc(dentry, xattrname,
 					  &xattr_value, xattr_size, GFP_NOFS);
 		if (size == -ENOMEM) {
 			error = -ENOMEM;
@@ -219,7 +229,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
 		xattr_size = size;
 		crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
 	}
-	hmac_add_misc(desc, inode, digest);
+	hmac_add_misc(desc, inode, flags, digest);
 
 out:
 	kfree(xattr_value);
@@ -229,18 +239,18 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
 
 int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value, size_t req_xattr_value_len,
-		  char *digest)
+		  u64 flags, char *digest)
 {
 	return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
-				req_xattr_value_len, EVM_XATTR_HMAC, digest);
+			   req_xattr_value_len, EVM_XATTR_HMAC, flags, digest);
 }
 
 int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
 		  const char *req_xattr_value, size_t req_xattr_value_len,
-		  char *digest)
+		  u64 flags, char *digest)
 {
 	return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
-				req_xattr_value_len, IMA_XATTR_DIGEST, digest);
+			 req_xattr_value_len, IMA_XATTR_DIGEST, flags, digest);
 }
 
 /*
@@ -256,7 +266,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 	int rc = 0;
 
 	rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
-			   xattr_value_len, xattr_data.digest);
+			xattr_value_len, evm_default_flags, xattr_data.digest);
 	if (rc == 0) {
 		xattr_data.type = EVM_XATTR_HMAC;
 		rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
@@ -280,7 +290,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
 	}
 
 	crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
-	hmac_add_misc(desc, inode, hmac_val);
+	hmac_add_misc(desc, inode, evm_default_flags, hmac_val);
 	kfree(desc);
 	return 0;
 }
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 44e4f4fda965..52b6fff91f8d 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -35,23 +35,32 @@ static char *integrity_status_msg[] = {
 };
 char *evm_hmac = "hmac(sha1)";
 char *evm_hash = "sha1";
-int evm_hmac_attrs;
 
-char *evm_config_xattrnames[] = {
+u64 evm_default_flags =
 #ifdef CONFIG_SECURITY_SELINUX
-	XATTR_NAME_SELINUX,
+	EVM_SELINUX |
 #endif
 #ifdef CONFIG_SECURITY_SMACK
-	XATTR_NAME_SMACK,
+	EVM_SMACK |
 #ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS
-	XATTR_NAME_SMACKEXEC,
-	XATTR_NAME_SMACKTRANSMUTE,
-	XATTR_NAME_SMACKMMAP,
+	EVM_SMACKEXEC |	EVM_SMACKTRANSMUTE | EVM_SMACKMMAP |
 #endif
 #endif
 #ifdef CONFIG_IMA_APPRAISE
-	XATTR_NAME_IMA,
+	EVM_IMA |
 #endif
+#ifdef CONFIG_EVM_ATTR_FSUUID
+	EVM_FSUUID |
+#endif
+	EVM_CAPS | EVM_INODE | EVM_OWNERSHIP | EVM_MODE;
+
+char *evm_config_xattrnames[] = {
+	XATTR_NAME_SELINUX,
+	XATTR_NAME_SMACK,
+	XATTR_NAME_SMACKEXEC,
+	XATTR_NAME_SMACKTRANSMUTE,
+	XATTR_NAME_SMACKMMAP,
+	XATTR_NAME_IMA,
 	XATTR_NAME_CAPS,
 	NULL
 };
@@ -67,24 +76,26 @@ __setup("evm=", evm_set_fixmode);
 
 static void __init evm_init_config(void)
 {
-#ifdef CONFIG_EVM_ATTR_FSUUID
-	evm_hmac_attrs |= EVM_ATTR_FSUUID;
-#endif
-	pr_info("HMAC attrs: 0x%x\n", evm_hmac_attrs);
+	pr_info("HMAC attrs: 0x%llx\n", evm_default_flags);
 }
 
 static int evm_find_protected_xattrs(struct dentry *dentry)
 {
 	struct inode *inode = d_backing_inode(dentry);
-	char **xattr;
+	char *xattr;
 	int error;
 	int count = 0;
+	int i;
 
 	if (!(inode->i_opflags & IOP_XATTR))
 		return -EOPNOTSUPP;
 
-	for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
-		error = __vfs_getxattr(dentry, inode, *xattr, NULL, 0);
+	for (i = 0; evm_config_xattrnames[i] != NULL; i++) {
+		if (!(evm_default_flags & (1 << i)))
+			continue;
+
+		xattr = evm_config_xattrnames[i];
+		error = __vfs_getxattr(dentry, inode, xattr, NULL, 0);
 		if (error < 0) {
 			if (error == -ENODATA)
 				continue;
@@ -152,7 +163,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			goto out;
 		}
 		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
-				   xattr_value_len, calc.digest);
+			      xattr_value_len, evm_default_flags, calc.digest);
 		if (rc)
 			break;
 		rc = crypto_memneq(xattr_data->digest, calc.digest,
@@ -162,7 +173,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 		break;
 	case EVM_IMA_XATTR_DIGSIG:
 		rc = evm_calc_hash(dentry, xattr_name, xattr_value,
-				xattr_value_len, calc.digest);
+			      xattr_value_len, evm_default_flags, calc.digest);
 		if (rc)
 			break;
 		rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
