Skip to contentSkip to conversation

integrity: EVM as an integrity service provider

PATCH In review Mimi Zohar 5 participants 12 messages Mar 23, 2007 – Mar 27, 2007

Subsystems (3)
lore
Share & tools
lore

Mimi Zohar

author
#0 lore raw

PATCH 3/7 integrity: EVM as an integrity service provider

This is a re-release of EVM as an integrity service provider. The initial EVM release was as an LSM module. It has been substantially rewritten to provide support for the new integrity service framework API, which permits applications, such as LSM modules, to verify the integrity of the metadata and data of a file.

EVM maintains an HMAC-sha1 associated with each file across an extensible set of extended attributes, ensuring that the extended attributes are protected against integrity attacks. The HMAC-sha1 is stored as an extended attribute security.evm.hmac. EVM depends on the Kernel Key Retention System to provide it with the kernel master key for the HMAC operation. The kernel master key is loaded onto the root's keyring by 'loadkernkey', which either uses the TPM sealed secrect key, if available, or a password requested from the console.

The integrity measurement of the file data, stored in the extended attribute security.evm.hash (md5) or security.evm.sha1, is protected by the HMAC. EVM maintains the integrity measurement of the file data, unless the file is defined as either FIXED or NOHASH.

The integrity service framework API defines three calls:
integrity_verify_metadata(), integrity_verify_data(), and integrity_measure(). For integrity_verify_metadata(), EVM determines whether or not the HMAC calculated for the set of extended attributes matches the HMAC stored as an extended attribute; for integrity_verify_data(), EVM determines whether or not the integrity measurement of the file data matches the value stored as an extended attribute; and for integrity_measure(), if IMA is configured and enabled, EVM passes the integrity measurement to it.

---

security/evm/evm_config.c new file +129 -0
Index: linux-2.6.21-rc4-mm1/security/evm/evm_config.c
===================================================================
@@ -0,0 +1,129 @@
+/*
+ * EVM - Extended Verification Module
+ *
+ * Copyright (C) 2005,2006,2007 IBM Corporation
+ * Author: Mimi Zohar <[email protected]>
+ * 	   Kylene Hall <[email protected]>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation, version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include "evm.h"
+
+/*
+ * Configuration data
+ */
+struct evm_xattr_config *evm_config_xattrdata;
+int evm_config_xattrnum = 0;	/* number of extended attributes */
+
+/*
+ * inode->i_integrity information
+ */
+void display_config(const char *name)
+{
+	struct evm_xattr_config *config_p;
+
+	for_each_xattr(config_p, evm_config_xattrdata, evm_config_xattrnum)
+	    printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
+}
+
+/*
+ * Initialize the Extended Verification module
+ */
+int evm_init_config(struct evm_xattr_config *evm_data, int evm_datasize)
+{
+	ssize_t error = 0;
+
+	if (evm_datasize > 0) {
+		evm_config_xattrdata = evm_data;
+		evm_config_xattrnum = evm_datasize;
+		display_config(__FUNCTION__);
+
+	} else {
+		printk(KERN_INFO "%s: config file definition missing\n",
+		       __FUNCTION__);
+		return -EINVAL;
+	}
+	return error;
+}
+
+static char *get_tag(char *buf_start, char *buf_end, char delimiter,
+		     int *taglen)
+{
+	char *bufp = buf_start;
+	char *tag;
+
+	/* Get start of tag */
+	while (bufp < buf_end) {
+		if (*bufp == ' ')	/* skip blanks */
+			while ((*bufp == ' ') && (bufp++ < buf_end)) ;
+		else if (*bufp == '#') {	/* skip comment */
+			while ((*bufp != '\n') && (bufp++ < buf_end)) ;
+			bufp++;
+		} else if (*bufp == '\n')	/* skip newline */
+			bufp++;
+		else if (*bufp == '\t')	/* skip tabs */
+			bufp++;
+		else
+			break;
+	}
+	if (bufp < buf_end)
+		tag = bufp;
+	else
+		return NULL;
+
+	/* Get tag */
+	*taglen = 0;
+	while ((bufp < buf_end) && (*taglen == 0)) {
+		if ((*bufp == delimiter) || (*bufp == '\n'))
+			*taglen = bufp - tag;
+		bufp++;
+	}
+	if (*taglen == 0)	/* Didn't find end delimiter */
+		*taglen = bufp - tag;
+	return tag;
+}
+
+struct evm_xattr_config *evm_parse_config(char *data, unsigned long datalen,
+					  int *xattrnum)
+{
+	char *datap, *dataend, *tag;
+	int num_xattr = 0;
+	struct evm_xattr_config *config_xattrdata = NULL, *config_p;
+	int taglen;
+
+	/* Get number of extended attribute definitions */
+	datap = data;
+	dataend = data + datalen;
+
+	while ((tag = get_tag(datap, dataend, ' ', &taglen)) != NULL) {
+		datap = tag + taglen;
+		num_xattr++;
+	}
+	*xattrnum = num_xattr;
+
+	datap = data;
+	config_xattrdata =
+	    kmalloc(num_xattr * sizeof(struct evm_xattr_config), GFP_KERNEL);
+	if (!config_xattrdata)
+		return NULL;
+
+	/* Get the list of hmac protected extended attributes */
+	config_p = config_xattrdata;
+	while ((tag = get_tag(datap, dataend, ' ', &taglen)) != NULL) {
+		datap = tag == NULL ? dataend : tag + taglen;
+		memset(config_p->xattr_name, 0, sizeof config_p->xattr_name);
+		memcpy(config_p->xattr_name, tag, taglen);
+		config_p++;
+	}
+	return config_xattrdata;
+}
+
+inline void evm_cleanup_config(void)
+{
+	kfree(evm_config_xattrdata);
+}
security/evm/evm_crypto.c new file +350 -0

350 lines not on this page · raw message

security/evm/evm.h new file +85 -0

85 lines not on this page · raw message

security/evm/evm_secfs.c new file +201 -0

201 lines not on this page · raw message

security/evm/Kconfig new file +17 -0
Index: linux-2.6.21-rc4-mm1/security/evm/Kconfig
===================================================================
@@ -0,0 +1,17 @@
+config INTEGRITY_EVM
+	boolean "EVM support"
+	depends on INTEGRITY && KEYS
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	default 0
+	help
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.
+
+	  If you are unsure how to answer this question, answer N.
+
security/evm/Makefile new file +5 -0
Index: linux-2.6.21-rc4-mm1/security/evm/Makefile
===================================================================
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_INTEGRITY_EVM) += evm.o
+
+evm-y := evm_main.o evm_config.o evm_crypto.o evm_secfs.o
+
security/Makefile +1 -0
Index: linux-2.6.21-rc4-mm1/security/Makefile
===================================================================
@@ -13,6 +13,7 @@ endif
 # Object file lists
 obj-$(CONFIG_SECURITY)			+= security.o dummy.o inode.o
 obj-$(CONFIG_INTEGRITY)		+= integrity.o integrity_dummy.o
+obj-$(CONFIG_INTEGRITY_EVM)		+= evm/
 # Must precede capability.o in order to stack properly.
 obj-$(CONFIG_SECURITY_SLIM)		+= slim/
 obj-$(CONFIG_SECURITY_SELINUX)		+= selinux/built-in.o
security/evm/evm_main.c new file +931 -0

931 lines not on this page · raw message

security/Kconfig +1 -0
Index: linux-2.6.21-rc4-mm1/security/Kconfig
===================================================================
@@ -46,6 +46,7 @@ config INTEGRITY
 	  configured into your kernel.
 
 	  If you are unsure how to answer this question, answer N.
+source security/evm/Kconfig
 
 config SECURITY
 	bool "Enable different security models"
fs/namei.c +22 -0
Index: linux-2.6.21-rc4-mm1/fs/namei.c
===================================================================
@@ -2616,6 +2616,27 @@ int generic_readlink(struct dentry *dent
 	return PTR_ERR(cookie);
 }
 
+int kernel_readlink(struct dentry *dentry, char **buffer, int *buflen)
+{
+	struct nameidata nd;
+	void *cookie;
+
+	nd.depth = 0;
+	cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
+	if (!IS_ERR(cookie)) {
+		char *link;
+
+		link = nd_get_link(&nd);
+		if (IS_ERR(link))
+			return PTR_ERR(link);
+		*buffer = kstrdup(link, GFP_KERNEL);
+		*buflen = (*buffer == NULL) ? 0 : strlen(*buffer);
+		if (dentry->d_inode->i_op->put_link)
+			dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+	}
+	return PTR_ERR(cookie);
+}
+
 int vfs_follow_link(struct nameidata *nd, const char *link)
 {
 	return __vfs_follow_link(nd, link);
@@ -2758,6 +2779,7 @@ EXPORT_SYMBOL(vfs_mkdir);
 EXPORT_SYMBOL(vfs_mknod);
 EXPORT_SYMBOL(generic_permission);
 EXPORT_SYMBOL(vfs_readlink);
+EXPORT_SYMBOL(kernel_readlink);
 EXPORT_SYMBOL(vfs_rename);
 EXPORT_SYMBOL(vfs_rmdir);
 EXPORT_SYMBOL(vfs_symlink);
#1 lore raw
Quoted 1 line · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

This is a re-release of EVM as an integrity service provider.

What a huge set of patches.

Frankly, I don't know how we're going to get these reviewed and mergeable and merged - there doesn't seem to be a lot of interest and personally I only have a vague idea of what it all even does.

This patch does worrisome-looking things with VFS internals (anything which takes inode_lock is fishy).

Bunch of cleanups, pretty obvious:

 fs/sysfs/mount.c          |    3 ---
 include/linux/magic.h     |    1 +
 security/evm/evm.h        |    2 --
 security/evm/evm_config.c |   19 ++++++++++---------
 security/evm/evm_crypto.c |    8 +++-----
 security/evm/evm_main.c   |   10 ++++------
 6 files changed, 18 insertions(+), 25 deletions(-)
fs/sysfs/mount.c renamed from fs/sysfs/mount.c~integrity-evm-as-an-integrity-service-provider-tidy +0 -3
diff -puN fs/sysfs/mount.c~integrity-evm-as-an-integrity-service-provider-tidy fs/sysfs/mount.c
@@ -12,9 +12,6 @@
 
 #include "sysfs.h"
 
-/* Random magic number */
-#define SYSFS_MAGIC 0x62656572
-
 struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
 struct kmem_cache *sysfs_dir_cachep;
include/linux/magic.h renamed from include/linux/magic.h~integrity-evm-as-an-integrity-service-provider-tidy +1 -0
diff -puN include/linux/magic.h~integrity-evm-as-an-integrity-service-provider-tidy include/linux/magic.h
@@ -20,6 +20,7 @@
 #define MINIX2_SUPER_MAGIC	0x2468		/* minix V2 fs */
 #define MINIX2_SUPER_MAGIC2	0x2478		/* minix V2 fs, 30 char names */
 #define MINIX3_SUPER_MAGIC	0x4d5a		/* minix V3 fs */
+#define SYSFS_MAGIC		0x62656572
 
 #define MSDOS_SUPER_MAGIC	0x4d44		/* MD */
 #define NCP_SUPER_MAGIC		0x564c		/* Guess, what 0x564c is :-) */
security/evm/evm.h renamed from security/evm/evm.h~integrity-evm-as-an-integrity-service-provider-tidy +0 -2
diff -puN security/evm/evm.h~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm.h
@@ -8,7 +8,6 @@
 #include <linux/spinlock_types.h>
 #include <linux/integrity.h>
 
-#define DEVFS_SUPER_MAGIC	0x1373
 #define MAX_DIGEST_SIZE 	20	/* 160-bits */
 
 extern char *evm_hmac, *evm_hash;
@@ -48,7 +47,6 @@ struct evm_iint_cache {
 	struct mutex mutex;
 };
 
-extern void display_config(const char *);
 extern struct evm_xattr_config *evm_parse_config(char *data,
 						 unsigned long datalen,
 						 int *datasize);
security/evm/evm_config.c renamed from security/evm/evm_config.c~integrity-evm-as-an-integrity-service-provider-tidy +10 -9
diff -puN security/evm/evm_config.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_config.c
@@ -18,17 +18,17 @@
  * Configuration data
  */
 struct evm_xattr_config *evm_config_xattrdata;
-int evm_config_xattrnum = 0;	/* number of extended attributes */
+int evm_config_xattrnum;	/* number of extended attributes */
 
 /*
  * inode->i_integrity information
  */
-void display_config(const char *name)
+static void display_config(const char *name)
 {
 	struct evm_xattr_config *config_p;
 
 	for_each_xattr(config_p, evm_config_xattrdata, evm_config_xattrnum)
-	    printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
+		printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
 }
 
 /*
@@ -42,7 +42,6 @@ int evm_init_config(struct evm_xattr_con
 		evm_config_xattrdata = evm_data;
 		evm_config_xattrnum = evm_datasize;
 		display_config(__FUNCTION__);
-
 	} else {
 		printk(KERN_INFO "%s: config file definition missing\n",
 		       __FUNCTION__);
@@ -60,9 +59,11 @@ static char *get_tag(char *buf_start, ch
 	/* Get start of tag */
 	while (bufp < buf_end) {
 		if (*bufp == ' ')	/* skip blanks */
-			while ((*bufp == ' ') && (bufp++ < buf_end)) ;
+			while ((*bufp == ' ') && (bufp++ < buf_end))
+				;
 		else if (*bufp == '#') {	/* skip comment */
-			while ((*bufp != '\n') && (bufp++ < buf_end)) ;
+			while ((*bufp != '\n') && (bufp++ < buf_end))
+				;
 			bufp++;
 		} else if (*bufp == '\n')	/* skip newline */
 			bufp++;
@@ -107,8 +108,8 @@ struct evm_xattr_config *evm_parse_confi
 	*xattrnum = num_xattr;
 
 	datap = data;
-	config_xattrdata =
-	    kmalloc(num_xattr * sizeof(struct evm_xattr_config), GFP_KERNEL);
+	config_xattrdata = kmalloc(num_xattr * sizeof(struct evm_xattr_config),
+				GFP_KERNEL);
 	if (!config_xattrdata)
 		return NULL;
 
@@ -123,7 +124,7 @@ struct evm_xattr_config *evm_parse_confi
 	return config_xattrdata;
 }
 
-inline void evm_cleanup_config(void)
+void evm_cleanup_config(void)
 {
 	kfree(evm_config_xattrdata);
 }
security/evm/evm_crypto.c renamed from security/evm/evm_crypto.c~integrity-evm-as-an-integrity-service-provider-tidy +3 -5
diff -puN security/evm/evm_crypto.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_crypto.c
@@ -33,7 +33,7 @@
 static unsigned char tpm_key[MAX_TPMKEY];
 static int tpm_keylen = MAX_TPMKEY;
 
-int update_file_hash(struct dentry *dentry, struct file *f,
+static int update_file_hash(struct dentry *dentry, struct file *f,
 		     struct hash_desc *desc)
 {
 	struct file *file = f;
@@ -217,11 +217,9 @@ int evm_calc_hmac(struct dentry *dentry,
 	struct scatterlist sg[1];
 	char *fname;
 	int error = 0;
-
 	struct evm_xattr_config *config_p;
 	int xattr_size = 0;
 	char *xattr_value = NULL;
-
 	struct h_misc {
 		unsigned long ino;
 		__u32 generation;
@@ -278,7 +276,7 @@ int evm_calc_hmac(struct dentry *dentry,
 					__FUNCTION__, fname,
 					config_p->xattr_name);
 		}
-	};
+	}
 	kfree(xattr_value);
 	memset(hmac_misc, 0, sizeof misc);
 	hmac_misc->ino = inode->i_ino;
@@ -331,7 +329,7 @@ int evm_init_tpmkernkey(void)
 
 	kmk = request_key(&key_type_user, TPMKEY, NULL);
 	if (IS_ERR(kmk)) {
-		return (-1);
+		return -1;
 	} else {
 		down_read(&kmk->sem);
 		ukp = kmk->payload.data;
security/evm/evm_main.c renamed from security/evm/evm_main.c~integrity-evm-as-an-integrity-service-provider-tidy +4 -6
diff -puN security/evm/evm_main.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_main.c
@@ -24,6 +24,7 @@
 #include <linux/proc_fs.h>
 #include <linux/xattr.h>
 #include <linux/file.h>
+#include <linux/magic.h>
 #include <linux/writeback.h>
 #include "evm_integrity.h"
 #include "evm.h"
@@ -363,10 +364,7 @@ static int evm_verify_data(struct dentry
  */
 static int skip_measurement(struct inode *inode, int mask)
 {
-#define SYSFS_MAGIC 0x62656572
-
-	if ((inode->i_sb->s_magic == DEVFS_SUPER_MAGIC) ||
-	    (inode->i_sb->s_magic == PROC_SUPER_MAGIC) ||
+	if ((inode->i_sb->s_magic == PROC_SUPER_MAGIC) ||
 	    (inode->i_sb->s_magic == SYSFS_MAGIC)) {
 		return 1;	/*can't measure */
 	}
@@ -877,9 +875,9 @@ static void evm_enable_integrity(void)
 
 static void evm_cleanup_integrity(void)
 {
-	if (evm_install) {
+	if (evm_install)
 		unregister_integrity(&evm_install_ops);
-	} else
+	else
 		unregister_integrity(&evm_integrity_ops);
 }
 

_

maintainer
#2 lore raw
Quoted 9 lines · Andrew Morton
Quoted 1 line · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

This is a re-release of EVM as an integrity service provider.

What a huge set of patches.

Frankly, I don't know how we're going to get these reviewed and mergeable and merged - there doesn't seem to be a lot of interest and personally I only have a vague idea of what it all even does.

Mimi,

would it make sense to work with just the integrity subsystem first, then when they've been sitting for awhile without breaking anything and people are done giving comments, look at EVM, then after awhile at IMA?

You've sent out all the patches so you can point people back to this submission if they ask "why isn't there a user" :)

Just a thought. Cause it *is* a lot of patches...

-serge

Quoted 207 lines

This patch does worrisome-looking things with VFS internals (anything which takes inode_lock is fishy).

Bunch of cleanups, pretty obvious:

 fs/sysfs/mount.c          |    3 ---
 include/linux/magic.h     |    1 +
 security/evm/evm.h        |    2 --
 security/evm/evm_config.c |   19 ++++++++++---------
 security/evm/evm_crypto.c |    8 +++-----
 security/evm/evm_main.c   |   10 ++++------
 6 files changed, 18 insertions(+), 25 deletions(-)

diff -puN fs/sysfs/mount.c~integrity-evm-as-an-integrity-service-provider-tidy fs/sysfs/mount.c

fs/sysfs/mount.c renamed from fs/sysfs/mount.c~integrity-evm-as-an-integrity-service-provider-tidy +0 -3
@@ -12,9 +12,6 @@
 
 #include "sysfs.h"
 
-/* Random magic number */
-#define SYSFS_MAGIC 0x62656572
-
 struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
 struct kmem_cache *sysfs_dir_cachep;

diff -puN include/linux/magic.h~integrity-evm-as-an-integrity-service-provider-tidy include/linux/magic.h

include/linux/magic.h renamed from include/linux/magic.h~integrity-evm-as-an-integrity-service-provider-tidy +1 -0
@@ -20,6 +20,7 @@
 #define MINIX2_SUPER_MAGIC	0x2468		/* minix V2 fs */
 #define MINIX2_SUPER_MAGIC2	0x2478		/* minix V2 fs, 30 char names */
 #define MINIX3_SUPER_MAGIC	0x4d5a		/* minix V3 fs */
+#define SYSFS_MAGIC		0x62656572
 
 #define MSDOS_SUPER_MAGIC	0x4d44		/* MD */
 #define NCP_SUPER_MAGIC		0x564c		/* Guess, what 0x564c is :-) */

diff -puN security/evm/evm.h~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm.h

security/evm/evm.h renamed from security/evm/evm.h~integrity-evm-as-an-integrity-service-provider-tidy +0 -2
@@ -8,7 +8,6 @@
 #include <linux/spinlock_types.h>
 #include <linux/integrity.h>
 
-#define DEVFS_SUPER_MAGIC	0x1373
 #define MAX_DIGEST_SIZE 	20	/* 160-bits */
 
 extern char *evm_hmac, *evm_hash;
@@ -48,7 +47,6 @@ struct evm_iint_cache {
 	struct mutex mutex;
 };
 
-extern void display_config(const char *);
 extern struct evm_xattr_config *evm_parse_config(char *data,
 						 unsigned long datalen,
 						 int *datasize);

diff -puN security/evm/evm_config.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_config.c

security/evm/evm_config.c renamed from security/evm/evm_config.c~integrity-evm-as-an-integrity-service-provider-tidy +10 -9
@@ -18,17 +18,17 @@
  * Configuration data
  */
 struct evm_xattr_config *evm_config_xattrdata;
-int evm_config_xattrnum = 0;	/* number of extended attributes */
+int evm_config_xattrnum;	/* number of extended attributes */
 
 /*
  * inode->i_integrity information
  */
-void display_config(const char *name)
+static void display_config(const char *name)
 {
 	struct evm_xattr_config *config_p;
 
 	for_each_xattr(config_p, evm_config_xattrdata, evm_config_xattrnum)
-	    printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
+		printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
 }
 
 /*
@@ -42,7 +42,6 @@ int evm_init_config(struct evm_xattr_con
 		evm_config_xattrdata = evm_data;
 		evm_config_xattrnum = evm_datasize;
 		display_config(__FUNCTION__);
-
 	} else {
 		printk(KERN_INFO "%s: config file definition missing\n",
 		       __FUNCTION__);
@@ -60,9 +59,11 @@ static char *get_tag(char *buf_start, ch
 	/* Get start of tag */
 	while (bufp < buf_end) {
 		if (*bufp == ' ')	/* skip blanks */
-			while ((*bufp == ' ') && (bufp++ < buf_end)) ;
+			while ((*bufp == ' ') && (bufp++ < buf_end))
+				;
 		else if (*bufp == '#') {	/* skip comment */
-			while ((*bufp != '\n') && (bufp++ < buf_end)) ;
+			while ((*bufp != '\n') && (bufp++ < buf_end))
+				;
 			bufp++;
 		} else if (*bufp == '\n')	/* skip newline */
 			bufp++;
@@ -107,8 +108,8 @@ struct evm_xattr_config *evm_parse_confi
 	*xattrnum = num_xattr;
 
 	datap = data;
-	config_xattrdata =
-	    kmalloc(num_xattr * sizeof(struct evm_xattr_config), GFP_KERNEL);
+	config_xattrdata = kmalloc(num_xattr * sizeof(struct evm_xattr_config),
+				GFP_KERNEL);
 	if (!config_xattrdata)
 		return NULL;
 
@@ -123,7 +124,7 @@ struct evm_xattr_config *evm_parse_confi
 	return config_xattrdata;
 }
 
-inline void evm_cleanup_config(void)
+void evm_cleanup_config(void)
 {
 	kfree(evm_config_xattrdata);
 }

diff -puN security/evm/evm_crypto.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_crypto.c

security/evm/evm_crypto.c renamed from security/evm/evm_crypto.c~integrity-evm-as-an-integrity-service-provider-tidy +3 -5
@@ -33,7 +33,7 @@
 static unsigned char tpm_key[MAX_TPMKEY];
 static int tpm_keylen = MAX_TPMKEY;
 
-int update_file_hash(struct dentry *dentry, struct file *f,
+static int update_file_hash(struct dentry *dentry, struct file *f,
 		     struct hash_desc *desc)
 {
 	struct file *file = f;
@@ -217,11 +217,9 @@ int evm_calc_hmac(struct dentry *dentry,
 	struct scatterlist sg[1];
 	char *fname;
 	int error = 0;
-
 	struct evm_xattr_config *config_p;
 	int xattr_size = 0;
 	char *xattr_value = NULL;
-
 	struct h_misc {
 		unsigned long ino;
 		__u32 generation;
@@ -278,7 +276,7 @@ int evm_calc_hmac(struct dentry *dentry,
 					__FUNCTION__, fname,
 					config_p->xattr_name);
 		}
-	};
+	}
 	kfree(xattr_value);
 	memset(hmac_misc, 0, sizeof misc);
 	hmac_misc->ino = inode->i_ino;
@@ -331,7 +329,7 @@ int evm_init_tpmkernkey(void)
 
 	kmk = request_key(&key_type_user, TPMKEY, NULL);
 	if (IS_ERR(kmk)) {
-		return (-1);
+		return -1;
 	} else {
 		down_read(&kmk->sem);
 		ukp = kmk->payload.data;

diff -puN security/evm/evm_main.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_main.c

security/evm/evm_main.c renamed from security/evm/evm_main.c~integrity-evm-as-an-integrity-service-provider-tidy +4 -6
@@ -24,6 +24,7 @@
 #include <linux/proc_fs.h>
 #include <linux/xattr.h>
 #include <linux/file.h>
+#include <linux/magic.h>
 #include <linux/writeback.h>
 #include "evm_integrity.h"
 #include "evm.h"
@@ -363,10 +364,7 @@ static int evm_verify_data(struct dentry
  */
 static int skip_measurement(struct inode *inode, int mask)
 {
-#define SYSFS_MAGIC 0x62656572
-
-	if ((inode->i_sb->s_magic == DEVFS_SUPER_MAGIC) ||
-	    (inode->i_sb->s_magic == PROC_SUPER_MAGIC) ||
+	if ((inode->i_sb->s_magic == PROC_SUPER_MAGIC) ||
 	    (inode->i_sb->s_magic == SYSFS_MAGIC)) {
 		return 1;	/*can't measure */
 	}
@@ -877,9 +875,9 @@ static void evm_enable_integrity(void)
 
 static void evm_cleanup_integrity(void)
 {
-	if (evm_install) {
+	if (evm_install)
 		unregister_integrity(&evm_install_ops);
-	} else
+	else
 		unregister_integrity(&evm_integrity_ops);
 }
 

_

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

author
#3 lore raw
Quoted 18 lines · Serge E. Hallyn
Quoted 9 lines · Andrew Morton
Quoted 1 line · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

This is a re-release of EVM as an integrity service provider.

What a huge set of patches.

Frankly, I don't know how we're going to get these reviewed and mergeable and merged - there doesn't seem to be a lot of interest and personally I only have a vague idea of what it all even does.

Mimi,

would it make sense to work with just the integrity subsystem first, then when they've been sitting for awhile without breaking anything and people are done giving comments, look at EVM, then after awhile at IMA?

Quoted 6 lines

You've sent out all the patches so you can point people back to this submission if they ask "why isn't there a user" :)

Just a thought. Cause it *is* a lot of patches...

-serge

I don't have a problem with Serge's suggestion of including just the integrity patches at this point, if that is preferable. The integrity patches would be: integrity-new-hooks.patch, integrity-new-hooks-fix.patch, integrity-fs-hook-placement.patch and, the one I just submitted, integrity_dummy_verify_metadata.patch. Then as Serge recommended, release the remainder of the code in smaller pieces.

Mimi Zohar

Quoted 207 lines
Quoted 207 lines

This patch does worrisome-looking things with VFS internals (anything which takes inode_lock is fishy).

Bunch of cleanups, pretty obvious:

 fs/sysfs/mount.c          |    3 ---
 include/linux/magic.h     |    1 +
 security/evm/evm.h        |    2 --
 security/evm/evm_config.c |   19 ++++++++++---------
 security/evm/evm_crypto.c |    8 +++-----
 security/evm/evm_main.c   |   10 ++++------
 6 files changed, 18 insertions(+), 25 deletions(-)

diff -puN fs/sysfs/mount.c~integrity-evm-as-an-integrity-service-provider-tidy fs/sysfs/mount.c

fs/sysfs/mount.c renamed from fs/sysfs/mount.c~integrity-evm-as-an-integrity-service-provider-tidy +0 -3
@@ -12,9 +12,6 @@
 
 #include "sysfs.h"
 
-/* Random magic number */
-#define SYSFS_MAGIC 0x62656572
-
 struct vfsmount *sysfs_mount;
 struct super_block * sysfs_sb = NULL;
 struct kmem_cache *sysfs_dir_cachep;

diff -puN include/linux/magic.h~integrity-evm-as-an-integrity-service-provider-tidy include/linux/magic.h

include/linux/magic.h renamed from include/linux/magic.h~integrity-evm-as-an-integrity-service-provider-tidy +1 -0
@@ -20,6 +20,7 @@
 #define MINIX2_SUPER_MAGIC	0x2468		/* minix V2 fs */
 #define MINIX2_SUPER_MAGIC2	0x2478		/* minix V2 fs, 30 char names */
 #define MINIX3_SUPER_MAGIC	0x4d5a		/* minix V3 fs */
+#define SYSFS_MAGIC		0x62656572
 
 #define MSDOS_SUPER_MAGIC	0x4d44		/* MD */
 #define NCP_SUPER_MAGIC		0x564c		/* Guess, what 0x564c is :-) */

diff -puN security/evm/evm.h~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm.h

security/evm/evm.h renamed from security/evm/evm.h~integrity-evm-as-an-integrity-service-provider-tidy +0 -2
@@ -8,7 +8,6 @@
 #include <linux/spinlock_types.h>
 #include <linux/integrity.h>
 
-#define DEVFS_SUPER_MAGIC	0x1373
 #define MAX_DIGEST_SIZE 	20	/* 160-bits */
 
 extern char *evm_hmac, *evm_hash;
@@ -48,7 +47,6 @@ struct evm_iint_cache {
 	struct mutex mutex;
 };
 
-extern void display_config(const char *);
 extern struct evm_xattr_config *evm_parse_config(char *data,
 						 unsigned long datalen,
 						 int *datasize);

diff -puN security/evm/evm_config.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_config.c

security/evm/evm_config.c renamed from security/evm/evm_config.c~integrity-evm-as-an-integrity-service-provider-tidy +10 -9
@@ -18,17 +18,17 @@
  * Configuration data
  */
 struct evm_xattr_config *evm_config_xattrdata;
-int evm_config_xattrnum = 0;	/* number of extended attributes */
+int evm_config_xattrnum;	/* number of extended attributes */
 
 /*
  * inode->i_integrity information
  */
-void display_config(const char *name)
+static void display_config(const char *name)
 {
 	struct evm_xattr_config *config_p;
 
 	for_each_xattr(config_p, evm_config_xattrdata, evm_config_xattrnum)
-	    printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
+		printk(KERN_INFO "%s: %s\n", name, config_p->xattr_name);
 }
 
 /*
@@ -42,7 +42,6 @@ int evm_init_config(struct evm_xattr_con
 		evm_config_xattrdata = evm_data;
 		evm_config_xattrnum = evm_datasize;
 		display_config(__FUNCTION__);
-
 	} else {
 		printk(KERN_INFO "%s: config file definition missing\n",
 		       __FUNCTION__);
@@ -60,9 +59,11 @@ static char *get_tag(char *buf_start, ch
 	/* Get start of tag */
 	while (bufp < buf_end) {
 		if (*bufp == ' ')	/* skip blanks */
-			while ((*bufp == ' ') && (bufp++ < buf_end)) ;
+			while ((*bufp == ' ') && (bufp++ < buf_end))
+				;
 		else if (*bufp == '#') {	/* skip comment */
-			while ((*bufp != '\n') && (bufp++ < buf_end)) ;
+			while ((*bufp != '\n') && (bufp++ < buf_end))
+				;
 			bufp++;
 		} else if (*bufp == '\n')	/* skip newline */
 			bufp++;
@@ -107,8 +108,8 @@ struct evm_xattr_config *evm_parse_confi
 	*xattrnum = num_xattr;
 
 	datap = data;
-	config_xattrdata =
-	    kmalloc(num_xattr * sizeof(struct evm_xattr_config), GFP_KERNEL);
+	config_xattrdata = kmalloc(num_xattr * sizeof(struct evm_xattr_config),
+				GFP_KERNEL);
 	if (!config_xattrdata)
 		return NULL;
 
@@ -123,7 +124,7 @@ struct evm_xattr_config *evm_parse_confi
 	return config_xattrdata;
 }
 
-inline void evm_cleanup_config(void)
+void evm_cleanup_config(void)
 {
 	kfree(evm_config_xattrdata);
 }

diff -puN security/evm/evm_crypto.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_crypto.c

security/evm/evm_crypto.c renamed from security/evm/evm_crypto.c~integrity-evm-as-an-integrity-service-provider-tidy +3 -5
@@ -33,7 +33,7 @@
 static unsigned char tpm_key[MAX_TPMKEY];
 static int tpm_keylen = MAX_TPMKEY;
 
-int update_file_hash(struct dentry *dentry, struct file *f,
+static int update_file_hash(struct dentry *dentry, struct file *f,
 		     struct hash_desc *desc)
 {
 	struct file *file = f;
@@ -217,11 +217,9 @@ int evm_calc_hmac(struct dentry *dentry,
 	struct scatterlist sg[1];
 	char *fname;
 	int error = 0;
-
 	struct evm_xattr_config *config_p;
 	int xattr_size = 0;
 	char *xattr_value = NULL;
-
 	struct h_misc {
 		unsigned long ino;
 		__u32 generation;
@@ -278,7 +276,7 @@ int evm_calc_hmac(struct dentry *dentry,
 					__FUNCTION__, fname,
 					config_p->xattr_name);
 		}
-	};
+	}
 	kfree(xattr_value);
 	memset(hmac_misc, 0, sizeof misc);
 	hmac_misc->ino = inode->i_ino;
@@ -331,7 +329,7 @@ int evm_init_tpmkernkey(void)
 
 	kmk = request_key(&key_type_user, TPMKEY, NULL);
 	if (IS_ERR(kmk)) {
-		return (-1);
+		return -1;
 	} else {
 		down_read(&kmk->sem);
 		ukp = kmk->payload.data;

diff -puN security/evm/evm_main.c~integrity-evm-as-an-integrity-service-provider-tidy security/evm/evm_main.c

security/evm/evm_main.c renamed from security/evm/evm_main.c~integrity-evm-as-an-integrity-service-provider-tidy +4 -6
@@ -24,6 +24,7 @@
 #include <linux/proc_fs.h>
 #include <linux/xattr.h>
 #include <linux/file.h>
+#include <linux/magic.h>
 #include <linux/writeback.h>
 #include "evm_integrity.h"
 #include "evm.h"
@@ -363,10 +364,7 @@ static int evm_verify_data(struct dentry
  */
 static int skip_measurement(struct inode *inode, int mask)
 {
-#define SYSFS_MAGIC 0x62656572
-
-	if ((inode->i_sb->s_magic == DEVFS_SUPER_MAGIC) ||
-	    (inode->i_sb->s_magic == PROC_SUPER_MAGIC) ||
+	if ((inode->i_sb->s_magic == PROC_SUPER_MAGIC) ||
 	    (inode->i_sb->s_magic == SYSFS_MAGIC)) {
 		return 1;	/*can't measure */
 	}
@@ -877,9 +875,9 @@ static void evm_enable_integrity(void)
 
 static void evm_cleanup_integrity(void)
 {
-	if (evm_install) {
+	if (evm_install)
 		unregister_integrity(&evm_install_ops);
-	} else
+	else
 		unregister_integrity(&evm_integrity_ops);
 }
 

_

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

#4 lore raw
In reply to Mimi Zohar
Quoted 9 lines · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

+++ linux-2.6.21-rc4-mm1/security/evm/Kconfig

security/evm/Kconfig new file +7 -0
@@ -0,0 +1,17 @@
+config INTEGRITY_EVM
+	boolean "EVM support"
+	depends on INTEGRITY && KEYS
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	default 0

security/evm/Kconfig line 17

Quoted 10 lines
security/evm/Kconfig new file +10 -0
+	help
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.
+
+	  If you are unsure how to answer this question, answer N.
+

Is no dependency upon TPM needed?

#5 lore raw

Hi!

Quoted 8 lines
Quoted 8 lines

+++ linux-2.6.21-rc4-mm1/security/evm/Kconfig

security/evm/Kconfig new file +6 -0
@@ -0,0 +1,17 @@
+config INTEGRITY_EVM
+	boolean "EVM support"
+	depends on INTEGRITY && KEYS
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
Quoted 8 lines

security/evm/Kconfig line 14

Quoted 8 lines
security/evm/Kconfig new file +8 -0
+	default 0
+	help
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.

What is identity provider good for? Can you explain it a bit more, or perhaps point to Doc*/ somewhere?
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#6 lore raw
Quoted 10 lines · Pavel Machek
Quoted 6 lines

security/evm/Kconfig line 14

Quoted 6 lines
security/evm/Kconfig new file +6 -0
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.

What is identity provider good for? Can you explain it a bit more, or perhaps point to Doc*/ somewhere?
Pavel

There are some papers and related userspace code at
http://www.research.ibm.com/gsal/tcpa
which describe the architecture in more detail, but basically this integrity provider is designed to complement mandatory access control systems like selinux and slim. Such systems can protect a running system against on-line attacks, but do not protect against off-line attacks (booting Knoppix and changing executables or their selinux labels), or against attacks which find weaknesses in the kernel or the LSM module itself.

Using a TPM or passphrase, EVM can verify the integrity of all files (including the kernel and initrd) and their labels before they are referenced. Using a TPM, EVM/IMA can attest to the integrity of all files to a third party, even if the kernel or modules have been compromised. (An attack can block the attestation, but cannot forge valid TPM signatures.)

In response to customer demand, we are actively working to develop and test this attestation in enterprise server environments, integrated with both selinux and AppArmor.

dave

#7 lore raw

Hi!

Quoted 10 lines
Quoted 9 lines
Quoted 6 lines

security/evm/Kconfig line 14

Quoted 6 lines
security/evm/Kconfig new file +6 -0
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.

What is identity provider good for? Can you explain it a bit more, or perhaps point to Doc*/ somewhere?

Quoted 9 lines

There are some papers and related userspace code at
http://www.research.ibm.com/gsal/tcpa
which describe the architecture in more detail, but basically this integrity provider is designed to complement mandatory access control systems like selinux and slim. Such systems can protect a running system against on-line attacks, but do not protect against off-line attacks (booting Knoppix and changing executables or their selinux labels), or against attacks which find weaknesses in the kernel or the LSM module itself.

Thanks. Can this go to Doc*/ somewhere?

...but... If I can attack your system using knoppix, I can get at your data, already, right? So you'll need to encrypt your data, anyway?

Quoted 2 lines

Using a TPM or passphrase, EVM can verify the integrity of all files (including the kernel and initrd) and their labels before they are

How does passphrase work here?

...so you have your data encrypted, and you have bootloader that verifies kernel/initrd (you need that, anyway). Because you data are encrypted, knoppix attack will not work... assuming crypto does some integrity checks, but IIRC crypto needs to do that.

Pavel,
who is afraid, that this code will come back and bite him. He has nightmares of opening PS4 box as a christmas gift, then not being able to hack his new hardware.

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#8 lore raw
Quoted 11 lines · Pavel Machek
Quoted 9 lines

There are some papers and related userspace code at
http://www.research.ibm.com/gsal/tcpa
which describe the architecture in more detail, but basically this integrity provider is designed to complement mandatory access control systems like selinux and slim. Such systems can protect a running system against on-line attacks, but do not protect against off-line attacks (booting Knoppix and changing executables or their selinux labels), or against attacks which find weaknesses in the kernel or the LSM module itself.

Thanks. Can this go to Doc*/ somewhere?

yes, we will add that.

Quoted 3 lines

...but... If I can attack your system using knoppix, I can get at your data, already, right? So you'll need to encrypt your data, anyway?

no reason to encrypt system files, which are public, and encryption by itself does not provide the desired integrity - you still end up having to verify the integrity.

Quoted 5 lines
Quoted 3 lines

Using a TPM or passphrase, EVM can verify the integrity of all files (including the kernel and initrd) and their labels before they are

How does passphrase work here?

ah, misstated that - the passphrase can be used to HMAC all other files, but not the kernel and initrd. Only the TPM/BIOS/Loader can do that.

Quoted 5 lines

...so you have your data encrypted, and you have bootloader that verifies kernel/initrd (you need that, anyway). Because you data are encrypted, knoppix attack will not work... assuming crypto does some integrity checks, but IIRC crypto needs to do that.

most encryption is slower than hmac, and does not provide integrity. There are some crypto modes (e.g. IAPM) which do both encryption and integrity, but they are patented, and have overhead above the cost of just encryption or integrity checking by themselves.

Quoted 2 lines

Pavel,

author
#9 lore raw
In reply to Andrew Morton
Quoted 15 lines · Andrew Morton
Quoted 13 lines · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

+++ linux-2.6.21-rc4-mm1/security/evm/Kconfig

security/evm/Kconfig new file +11 -0
@@ -0,0 +1,17 @@
+config INTEGRITY_EVM
+	boolean "EVM support"
+	depends on INTEGRITY && KEYS
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	default 0
+	help
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
Quoted 8 lines

security/evm/Kconfig line 17

Quoted 6 lines
security/evm/Kconfig new file +6 -0
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.
+
+	  If you are unsure how to answer this question, answer N.
+

Is no dependency upon TPM needed?

It's obviously preferable to have and use a TPM, but if one is not available you can use a pass-phrase.

Mimi Zoharar

#10 lore raw
Quoted 25 lines · On Sun, 25 Mar 2007 23:13:02 -0400 Mimi Zohar <[email protected]> wrote:
Quoted 15 lines · Andrew Morton
Quoted 13 lines · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

+++ linux-2.6.21-rc4-mm1/security/evm/Kconfig

security/evm/Kconfig new file +11 -0
@@ -0,0 +1,17 @@
+config INTEGRITY_EVM
+	boolean "EVM support"
+	depends on INTEGRITY && KEYS
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	default 0
+	help
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
Quoted 8 lines

security/evm/Kconfig line 17

Quoted 6 lines
security/evm/Kconfig new file +6 -0
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.
+
+	  If you are unsure how to answer this question, answer N.
+

Is no dependency upon TPM needed?

Quoted 3 lines

It's obviously preferable to have and use a TPM, but if one is not available you can use a pass-phrase.

So it will compile and run OK with CONFIG_TPM=n? And with CONFIG_INTEGRITY_EVM=y, CONFIG_TPM=m?

author
#11 lore raw
Quoted 27 lines · Andrew Morton
Quoted 25 lines · On Sun, 25 Mar 2007 23:13:02 -0400 Mimi Zohar <[email protected]> wrote:
Quoted 23 lines · Andrew Morton
Quoted 9 lines · On Fri, 23 Mar 2007 12:09:36 -0400 Mimi Zohar <[email protected]> wrote:

+++ linux-2.6.21-rc4-mm1/security/evm/Kconfig

security/evm/Kconfig new file +7 -0
@@ -0,0 +1,17 @@
+config INTEGRITY_EVM
+	boolean "EVM support"
+	depends on INTEGRITY && KEYS
+	select CRYPTO_HMAC
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	default 0

security/evm/Kconfig line 17

Quoted 10 lines
security/evm/Kconfig new file +10 -0
+	help
+	  The Extended Verification Module is an integrity provider.
+	  An extensible set of extended attributes, as defined in
+	  /etc/evm.conf, are HMAC protected against modification
+	  using the TPM's KERNEL ROOT KEY, if configured, or with a
+	  pass-phrase.  Possible extended attributes include authenticity,
+	  integrity, and revision level.
+
+	  If you are unsure how to answer this question, answer N.
+

Is no dependency upon TPM needed?

Quoted 6 lines
Quoted 3 lines

It's obviously preferable to have and use a TPM, but if one is not available you can use a pass-phrase.

So it will compile and run OK with CONFIG_TPM=n? And with CONFIG_INTEGRITY_EVM=y, CONFIG_TPM=m?

Sorry, I guess I wasn't clear. If you are using a TPM, then it has to be builtin. In addition, if you don't enable a TPM, then you can't enable IMA either.

Mimi