* [PATCH 00/10] ima-evm-utils
@ 2018-01-22 14:53 Mimi Zohar
2018-01-22 14:53 ` [PATCH 01/10] ima-evm-utils: fix "ima_measurement" template fields length Mimi Zohar
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:53 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
Before upgrading to the new OpenSSL 1.1 API, let's clean up the code
a bit and add some missing functionality:
- option to specify the pcr sysfs location
- verify the measurement list using multiple keys
- verify the measurement list using multiple pcrs
- verify a measurement signature against the measurement list digest
- for completeness, extend "ima_verify" to verify the local security.ima hash
Mimi
Mimi Zohar (10):
ima-evm-utils: fix "ima_measurement" template fields length
ima-evm-utils: revert the change to use printf instead of log_info()
ima-evm-utils: fix spelling error
ima-evm-utils: remove the unnecessary display of the keyid
ima-evm-utils: support verifying the measurement list using multiple
keys
ima-evm-utils: indicate measurement list signature verification
failure
ima-evm-utils: add support for specifying the pcr file location
ima-evm-utils: verify the measurement list signature based on the list
digest
ima-evm-utils: verify IMA file hashes stored as xattrs
ima-evm-utils: add support for validating multiple pcrs
README | 2 +-
src/evmctl.c | 94 ++++++++++++++++++++++++++++-----------
src/imaevm.h | 7 ++-
src/libimaevm.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 199 insertions(+), 39 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 01/10] ima-evm-utils: fix "ima_measurement" template fields length
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
@ 2018-01-22 14:53 ` Mimi Zohar
2018-01-22 14:53 ` [PATCH 02/10] ima-evm-utils: revert the change to use printf instead of log_info() Mimi Zohar
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:53 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
The template data field length is uint32_t, not uint8_t.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/evmctl.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 313a0c5..a6c6e01 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1342,7 +1342,7 @@ void ima_ng_show(struct template_entry *entry)
char *algo, *path;
/* get binary digest */
- field_len = *(uint8_t *)fieldp;
+ field_len = *(uint32_t *)fieldp;
fieldp += sizeof(field_len);
total_len -= sizeof(field_len);
@@ -1356,7 +1356,7 @@ void ima_ng_show(struct template_entry *entry)
total_len -= field_len;
/* get path */
- field_len = *(uint8_t *)fieldp;
+ field_len = *(uint32_t *)fieldp;
fieldp += sizeof(field_len);
total_len -= sizeof(field_len);
@@ -1368,7 +1368,7 @@ void ima_ng_show(struct template_entry *entry)
if (!strcmp(entry->name, "ima-sig")) {
/* get signature */
- field_len = *(uint8_t *)fieldp;
+ field_len = *(uint32_t *)fieldp;
fieldp += sizeof(field_len);
total_len -= sizeof(field_len);
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 02/10] ima-evm-utils: revert the change to use printf instead of log_info()
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
2018-01-22 14:53 ` [PATCH 01/10] ima-evm-utils: fix "ima_measurement" template fields length Mimi Zohar
@ 2018-01-22 14:53 ` Mimi Zohar
2018-01-22 14:53 ` [PATCH 03/10] ima-evm-utils: fix spelling error Mimi Zohar
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:53 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
Using log_info() was commented out and replaced with printf. Revert
this change and use log_info().
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/libimaevm.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index eedffb4..610b0b7 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -402,8 +402,7 @@ int verify_hash_v1(const unsigned char *hash, int size, unsigned char *sig, int
log_err("Verification failed: %d\n", err);
return -1;
} else {
- /*log_info("Verification is OK\n");*/
- printf("Verification is OK\n");
+ log_info("Verification is OK\n");
}
return 0;
@@ -447,8 +446,7 @@ int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int
return -1;
}
- /*log_info("Verification is OK\n");*/
- printf("Verification is OK\n");
+ log_info("Verification is OK\n");
return 0;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 03/10] ima-evm-utils: fix spelling error
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
2018-01-22 14:53 ` [PATCH 01/10] ima-evm-utils: fix "ima_measurement" template fields length Mimi Zohar
2018-01-22 14:53 ` [PATCH 02/10] ima-evm-utils: revert the change to use printf instead of log_info() Mimi Zohar
@ 2018-01-22 14:53 ` Mimi Zohar
2018-01-22 14:53 ` [PATCH 04/10] ima-evm-utils: remove the unnecessary display of the keyid Mimi Zohar
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:53 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/evmctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index a6c6e01..746fc09 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1310,7 +1310,7 @@ void ima_extend_pcr(uint8_t *pcr, uint8_t *digest, int length)
SHA1_Final(pcr, &ctx);
}
-static int ima_verify_tamplate_hash(struct template_entry *entry)
+static int ima_verify_template_hash(struct template_entry *entry)
{
uint8_t digest[SHA_DIGEST_LENGTH];
@@ -1446,7 +1446,7 @@ static int ima_measurement(const char *file)
}
if (validate)
- ima_verify_tamplate_hash(&entry);
+ ima_verify_template_hash(&entry);
if (!strcmp(entry.name, "ima"))
ima_show(&entry);
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 04/10] ima-evm-utils: remove the unnecessary display of the keyid
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (2 preceding siblings ...)
2018-01-22 14:53 ` [PATCH 03/10] ima-evm-utils: fix spelling error Mimi Zohar
@ 2018-01-22 14:53 ` Mimi Zohar
2018-01-22 14:54 ` [PATCH 05/10] ima-evm-utils: support verifying the measurement list using multiple keys Mimi Zohar
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:53 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
Callers of calc_keyid_v2() can display the keyid, when desired.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/libimaevm.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 610b0b7..a92deed 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -606,8 +606,6 @@ void calc_keyid_v2(uint32_t *keyid, char *str, RSA *key)
log_debug_dump(keyid, 4);
sprintf(str, "%x", __be32_to_cpup(keyid));
- log_info("keyid: %s\n", str);
-
free(pkey);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 05/10] ima-evm-utils: support verifying the measurement list using multiple keys
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (3 preceding siblings ...)
2018-01-22 14:53 ` [PATCH 04/10] ima-evm-utils: remove the unnecessary display of the keyid Mimi Zohar
@ 2018-01-22 14:54 ` Mimi Zohar
2018-01-22 14:54 ` [PATCH 06/10] ima-evm-utils: indicate measurement list signature verification failure Mimi Zohar
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:54 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
On a running system, different software packages might be signed by
different parties. Support verifying signatures in the measurement
list using multiple public keys(eg. -k "key1, key2, ...").
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
README | 2 +-
src/evmctl.c | 4 +++
src/imaevm.h | 1 +
src/libimaevm.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/README b/README
index da828cf..1c4bc7a 100644
--- a/README
+++ b/README
@@ -31,7 +31,7 @@ COMMANDS
ima_sign [--sigfile] [--key key] [--pass password] file
ima_verify file
ima_hash file
- ima_measurement file
+ ima_measurement [--key "key1, key2, ..."] file
ima_fix [-t fdsxm] path
sign_hash [--key key] [--pass password]
hmac [--imahash | --imasig ] file
diff --git a/src/evmctl.c b/src/evmctl.c
index 746fc09..e0ed93d 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1419,6 +1419,10 @@ static int ima_measurement(const char *file)
return -1;
}
+ /* Support multiple public keys */
+ if (params.keyfile)
+ init_public_keys(params.keyfile);
+
while (fread(&entry.header, sizeof(entry.header), 1, fp)) {
ima_extend_pcr(pcr, entry.header.digest, SHA_DIGEST_LENGTH);
diff --git a/src/imaevm.h b/src/imaevm.h
index e397743..ea6a7b1 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -205,5 +205,6 @@ int key2bin(RSA *key, unsigned char *pub);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen);
+void init_public_keys(const char *keyfiles);
#endif
diff --git a/src/libimaevm.c b/src/libimaevm.c
index a92deed..0ad290a 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -408,6 +408,61 @@ int verify_hash_v1(const unsigned char *hash, int size, unsigned char *sig, int
return 0;
}
+struct public_key_entry {
+ struct public_key_entry *next;
+ uint32_t keyid;
+ char name[9];
+ RSA *key;
+};
+static struct public_key_entry *public_keys = NULL;
+
+static RSA *find_keyid(uint32_t keyid)
+{
+ struct public_key_entry *entry;
+
+ for (entry = public_keys; entry != NULL; entry = entry->next) {
+ if (entry->keyid == keyid)
+ return entry->key;
+ }
+ return NULL;
+}
+
+void init_public_keys(const char *keyfiles)
+{
+ struct public_key_entry *entry;
+ char *tmp_keyfiles;
+ char *keyfile;
+ int i = 1;
+
+ tmp_keyfiles = strdup(keyfiles);
+
+ while ((keyfile = strsep(&tmp_keyfiles, ", \t")) != NULL) {
+ if (!keyfile)
+ break;
+ if ((*keyfile == '\0') || (*keyfile == ' ') ||
+ (*keyfile == '\t'))
+ continue;
+
+ entry = malloc(sizeof(struct public_key_entry));
+ if (!entry) {
+ perror("malloc");
+ break;
+ }
+
+ entry->key = read_pub_key(keyfile, 1);
+ if (!entry->key) {
+ free(entry);
+ continue;
+ }
+
+ calc_keyid_v2(&entry->keyid, entry->name, entry->key);
+ sprintf(entry->name, "%x", __be32_to_cpup(&entry->keyid));
+ log_info("key %d: %s %s\n", i++, entry->name, keyfile);
+ entry->next = public_keys;
+ public_keys = entry;
+ }
+}
+
int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int siglen, const char *keyfile)
{
int err, len;
@@ -419,12 +474,22 @@ int verify_hash_v2(const unsigned char *hash, int size, unsigned char *sig, int
log_info("hash: ");
log_dump(hash, size);
- key = read_pub_key(keyfile, 1);
- if (!key)
- return 1;
+ if (public_keys) {
+ key = find_keyid(hdr->keyid);
+ if (!key) {
+ log_err("Unknown keyid: %x\n",
+ __be32_to_cpup(&hdr->keyid));
+ return -1;
+ }
+ } else {
+ key = read_pub_key(keyfile, 1);
+ if (!key)
+ return 1;
+ }
- err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr), out, key, RSA_PKCS1_PADDING);
- RSA_free(key);
+
+ err = RSA_public_decrypt(siglen - sizeof(*hdr), sig + sizeof(*hdr),
+ out, key, RSA_PKCS1_PADDING);
if (err < 0) {
log_err("RSA_public_decrypt() failed: %d\n", err);
return 1;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 06/10] ima-evm-utils: indicate measurement list signature verification failure
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (4 preceding siblings ...)
2018-01-22 14:54 ` [PATCH 05/10] ima-evm-utils: support verifying the measurement list using multiple keys Mimi Zohar
@ 2018-01-22 14:54 ` Mimi Zohar
2018-01-22 14:54 ` [PATCH 07/10] ima-evm-utils: add support for specifying the pcr file location Mimi Zohar
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:54 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
Walking the measurement list and calculating the PCR to compare
against the TPM is only the first step. The next step is verifying
the file signatures contained in the measurement list. This patch
differentiates between the two.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/evmctl.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index e0ed93d..f791a5b 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1333,13 +1333,14 @@ void ima_show(struct template_entry *entry)
log_debug_dump(entry->header.digest, sizeof(entry->header.digest));
}
-void ima_ng_show(struct template_entry *entry)
+int ima_ng_show(struct template_entry *entry)
{
uint8_t *fieldp = entry->template;
uint32_t field_len;
int total_len = entry->template_len, digest_len, len, sig_len;
uint8_t *digest, *sig = NULL;
char *algo, *path;
+ int err = 0;
/* get binary digest */
field_len = *(uint32_t *)fieldp;
@@ -1392,12 +1393,13 @@ void ima_ng_show(struct template_entry *entry)
if (sig) {
log_info(" ");
log_dump(sig, sig_len);
- ima_verify_signature(path, sig, sig_len);
+ err = ima_verify_signature(path, sig, sig_len);
} else
log_info("\n");
if (total_len)
log_err("Remain unprocessed data: %d\n", total_len);
+ return err;
}
static int ima_measurement(const char *file)
@@ -1407,6 +1409,7 @@ static int ima_measurement(const char *file)
struct template_entry entry = { .template = 0 };
FILE *fp;
int err = -1;
+ int verify_sig_failed = 0;
memset(fox, 0xff, SHA_DIGEST_LENGTH);
@@ -1452,10 +1455,12 @@ static int ima_measurement(const char *file)
if (validate)
ima_verify_template_hash(&entry);
- if (!strcmp(entry.name, "ima"))
+ if (!strcmp(entry.name, "ima")) {
ima_show(&entry);
- else
- ima_ng_show(&entry);
+ } else {
+ if (ima_ng_show(&entry) != 0)
+ verify_sig_failed = 1;
+ }
}
tpm_pcr_read(10, pcr10, sizeof(pcr10));
@@ -1469,6 +1474,8 @@ static int ima_measurement(const char *file)
if (memcmp(pcr, pcr10, sizeof(pcr))) {
log_err("PCRAgg does not match PCR-10\n");
goto out;
+ } else if (verify_sig_failed == 1) {
+ log_err("PCRAgg matches PCR-10, but list contains unknown keys or invalid signatures\n");
}
err = 0;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 07/10] ima-evm-utils: add support for specifying the pcr file location
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (5 preceding siblings ...)
2018-01-22 14:54 ` [PATCH 06/10] ima-evm-utils: indicate measurement list signature verification failure Mimi Zohar
@ 2018-01-22 14:54 ` Mimi Zohar
2018-01-22 14:54 ` [PATCH 08/10] ima-evm-utils: verify the measurement list signature based on the list digest Mimi Zohar
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:54 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
The location of the PCRs differs from system to system. This
patch defines a new "--pcrs <filename>" option.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
README | 2 +-
src/evmctl.c | 12 +++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/README b/README
index 1c4bc7a..f9706f8 100644
--- a/README
+++ b/README
@@ -31,7 +31,7 @@ COMMANDS
ima_sign [--sigfile] [--key key] [--pass password] file
ima_verify file
ima_hash file
- ima_measurement [--key "key1, key2, ..."] file
+ ima_measurement [--key "key1, key2, ..."] [--pcrs <sysfs file>] file
ima_fix [-t fdsxm] path
sign_hash [--key key] [--pass password]
hmac [--imahash | --imasig ] file
diff --git a/src/evmctl.c b/src/evmctl.c
index f791a5b..310ff4e 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -112,6 +112,7 @@ static char *generation_str;
static char *caps_str;
static char *ima_str;
static char *selinux_str;
+static char *pcrs_sysfs;
static char *search_type;
static int recursive;
static int msize;
@@ -1258,7 +1259,11 @@ static int tpm_pcr_read(int idx, uint8_t *pcr, int len)
sprintf(pcr_str, "PCR-%d", idx);
- fp = fopen(pcrs, "r");
+
+ if (pcrs_sysfs)
+ fp = fopen(pcrs_sysfs, "r");
+ else
+ fp = fopen(pcrs, "r");
if (!fp) {
log_err("Unable to open %s\n", pcrs);
return -1;
@@ -1593,6 +1598,7 @@ static void usage(void)
" --ima use custom IMA signature for EVM\n"
" --selinux use custom Selinux label for EVM\n"
" --caps use custom Capabilities for EVM(unspecified: from FS, empty: do not use)\n"
+ " --pcrs specify local sysfs pcr file\n"
" -v increase verbosity level\n"
" -h, --help display this help and exit\n"
"\n");
@@ -1644,6 +1650,7 @@ static struct option opts[] = {
{"ima", 1, 0, 135},
{"selinux", 1, 0, 136},
{"caps", 2, 0, 137},
+ {"pcrs", 1, 0, 138},
{}
};
@@ -1792,6 +1799,9 @@ int main(int argc, char *argv[])
caps_str = optarg;
hmac_flags |= HMAC_FLAG_CAPS_SET;
break;
+ case 138:
+ pcrs_sysfs = optarg;
+ break;
case '?':
exit(1);
break;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 08/10] ima-evm-utils: verify the measurement list signature based on the list digest
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (6 preceding siblings ...)
2018-01-22 14:54 ` [PATCH 07/10] ima-evm-utils: add support for specifying the pcr file location Mimi Zohar
@ 2018-01-22 14:54 ` Mimi Zohar
2018-01-22 14:54 ` [PATCH 09/10] ima-evm-utils: verify IMA file hashes stored as xattrs Mimi Zohar
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:54 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
Instead of verifying file signatures included in the measurement list,
by calculating the local file hash, verify the file signature based on the
digest contained in the measurement list.
This patch defines a new option named "--list".
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
README | 2 +-
src/evmctl.c | 14 ++++++++++++--
src/imaevm.h | 2 +-
src/libimaevm.c | 10 +++++++++-
4 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/README b/README
index f9706f8..f60a9fd 100644
--- a/README
+++ b/README
@@ -31,7 +31,7 @@ COMMANDS
ima_sign [--sigfile] [--key key] [--pass password] file
ima_verify file
ima_hash file
- ima_measurement [--key "key1, key2, ..."] [--pcrs <sysfs file>] file
+ ima_measurement [--key "key1, key2, ..."] [--pcrs <sysfs file>] [--list] file
ima_fix [-t fdsxm] path
sign_hash [--key key] [--pass password]
hmac [--imahash | --imasig ] file
diff --git a/src/evmctl.c b/src/evmctl.c
index 310ff4e..5d1c6ea 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -114,6 +114,7 @@ static char *ima_str;
static char *selinux_str;
static char *pcrs_sysfs;
static char *search_type;
+static int measurement_list;
static int recursive;
static int msize;
static dev_t fs_dev;
@@ -793,7 +794,7 @@ static int verify_ima(const char *file)
}
}
- return ima_verify_signature(file, sig, len);
+ return ima_verify_signature(file, sig, len, NULL, 0);
}
static int cmd_verify_ima(struct command *cmd)
@@ -1398,7 +1399,11 @@ int ima_ng_show(struct template_entry *entry)
if (sig) {
log_info(" ");
log_dump(sig, sig_len);
- err = ima_verify_signature(path, sig, sig_len);
+ if (measurement_list)
+ err = ima_verify_signature(path, sig, sig_len,
+ digest, digest_len);
+ else
+ err = ima_verify_signature(path, sig, sig_len, NULL, 0);
} else
log_info("\n");
@@ -1599,6 +1604,7 @@ static void usage(void)
" --selinux use custom Selinux label for EVM\n"
" --caps use custom Capabilities for EVM(unspecified: from FS, empty: do not use)\n"
" --pcrs specify local sysfs pcr file\n"
+ " --list measurement list verification\n"
" -v increase verbosity level\n"
" -h, --help display this help and exit\n"
"\n");
@@ -1651,6 +1657,7 @@ static struct option opts[] = {
{"selinux", 1, 0, 136},
{"caps", 2, 0, 137},
{"pcrs", 1, 0, 138},
+ {"list", 0, 0, 139},
{}
};
@@ -1802,6 +1809,9 @@ int main(int argc, char *argv[])
case 138:
pcrs_sysfs = optarg;
break;
+ case 139:
+ measurement_list = 1;
+ break;
case '?':
exit(1);
break;
diff --git a/src/imaevm.h b/src/imaevm.h
index ea6a7b1..f5cee7d 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -204,7 +204,7 @@ int key2bin(RSA *key, unsigned char *pub);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen);
-int ima_verify_signature(const char *file, unsigned char *sig, int siglen);
+int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
void init_public_keys(const char *keyfiles);
#endif
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 0ad290a..247100f 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -580,7 +580,8 @@ int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int sig
return verify_hash(hash, size, sig, siglen, key);
}
-int ima_verify_signature(const char *file, unsigned char *sig, int siglen)
+int ima_verify_signature(const char *file, unsigned char *sig, int siglen,
+ unsigned char *digest, int digestlen)
{
unsigned char hash[64];
int hashlen, sig_hash_algo;
@@ -598,6 +599,13 @@ int ima_verify_signature(const char *file, unsigned char *sig, int siglen)
/* Use hash algorithm as retrieved from signature */
params.hash_algo = pkey_hash_algo[sig_hash_algo];
+ /*
+ * Validate the signature based on the digest included in the
+ * measurement list, not by calculating the local file digest.
+ */
+ if (digestlen > 0)
+ return verify_hash(digest, digestlen, sig + 1, siglen - 1);
+
hashlen = ima_calc_hash(file, hash);
if (hashlen <= 1)
return hashlen;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 09/10] ima-evm-utils: verify IMA file hashes stored as xattrs
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (7 preceding siblings ...)
2018-01-22 14:54 ` [PATCH 08/10] ima-evm-utils: verify the measurement list signature based on the list digest Mimi Zohar
@ 2018-01-22 14:54 ` Mimi Zohar
2018-01-22 14:54 ` [PATCH 10/10] ima-evm-utils: add support for validating multiple pcrs Mimi Zohar
2018-01-28 19:01 ` [PATCH 00/10] ima-evm-utils Mimi Zohar
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:54 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
evmctl "ima_verify" verifies file signatures stored as xattrs on the
local filesystem. This patch adds support for verifying the file hashes
stored as xattrs.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/evmctl.c | 3 +++
src/imaevm.h | 1 +
src/libimaevm.c | 42 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+)
diff --git a/src/evmctl.c b/src/evmctl.c
index 5d1c6ea..9142ed4 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -794,6 +794,9 @@ static int verify_ima(const char *file)
}
}
+ if (sig[0] == IMA_XATTR_DIGEST_NG || sig[0] == IMA_XATTR_DIGEST)
+ return ima_verify_hash(file, sig, len);
+
return ima_verify_signature(file, sig, len, NULL, 0);
}
diff --git a/src/imaevm.h b/src/imaevm.h
index f5cee7d..d624571 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -205,6 +205,7 @@ int key2bin(RSA *key, unsigned char *pub);
int sign_hash(const char *algo, const unsigned char *hash, int size, const char *keyfile, const char *keypass, unsigned char *sig);
int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen);
int ima_verify_signature(const char *file, unsigned char *sig, int siglen, unsigned char *digest, int digestlen);
+int ima_verify_hash(const char *file, unsigned char *digest, int digestlen);
void init_public_keys(const char *keyfiles);
#endif
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 247100f..bc9c496 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -49,6 +49,7 @@
#include <dirent.h>
#include <string.h>
#include <stdio.h>
+#include <linux/hash_info.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
@@ -613,6 +614,47 @@ int ima_verify_signature(const char *file, unsigned char *sig, int siglen,
return verify_hash(hash, hashlen, sig + 1, siglen - 1);
}
+int ima_verify_hash(const char *file, unsigned char *digest, int digestlen)
+{
+ unsigned char hash[64];
+ int hashlen, hash_algo = HASH_ALGO_SHA1;
+
+ if (digest[0] == IMA_XATTR_DIGEST_NG)
+ hash_algo = digest[1];
+
+ if (hash_algo < 0 || hash_algo > HASH_ALGO__LAST) {
+ log_err("Invalid signature\n");
+ return -1;
+ }
+
+ /* Use hash algorithm as retrieved from xattr */
+ params.hash_algo = pkey_hash_algo[hash_algo];
+
+ hashlen = ima_calc_hash(file, hash);
+ if (hashlen <= 1)
+ return hashlen;
+
+ if (digest[0] == IMA_XATTR_DIGEST_NG) {
+ if (hashlen != digestlen - 2 ||
+ memcmp(digest + 2, hash, hashlen)) {
+ log_err("Hash ng verification failed\n");
+ return -1;
+ }
+ log_info("Hash verification is OK\n");
+ return 0;
+ } else if (digest[0] == IMA_XATTR_DIGEST) {
+ if (hashlen != digestlen - 1 ||
+ memcmp(digest + 1, hash, hashlen)) {
+ log_err("Hash verification failed\n");
+ return -1;
+ }
+ log_info("Hash verification is OK\n");
+ return 0;
+ }
+ log_err("Unknown security.ima format\n");
+ return -1;
+}
+
/*
* Create binary key representation suitable for kernel
*/
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 10/10] ima-evm-utils: add support for validating multiple pcrs
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (8 preceding siblings ...)
2018-01-22 14:54 ` [PATCH 09/10] ima-evm-utils: verify IMA file hashes stored as xattrs Mimi Zohar
@ 2018-01-22 14:54 ` Mimi Zohar
2018-01-28 19:01 ` [PATCH 00/10] ima-evm-utils Mimi Zohar
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-22 14:54 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
Mimi Zohar
The IMA measurement list may contain records for different PCRs. This
patch walks the measurement list, calculating a PCR aggregate value for
each PCR.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
---
src/evmctl.c | 44 +++++++++++++++++++++++++++-----------------
src/imaevm.h | 3 +++
2 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 9142ed4..5029235 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1417,13 +1417,16 @@ int ima_ng_show(struct template_entry *entry)
static int ima_measurement(const char *file)
{
- uint8_t pcr[SHA_DIGEST_LENGTH] = {0,};
- uint8_t pcr10[SHA_DIGEST_LENGTH];
+ uint8_t pcr[NUM_PCRS][SHA_DIGEST_LENGTH] = {{0}};
+ uint8_t hwpcr[SHA_DIGEST_LENGTH];
struct template_entry entry = { .template = 0 };
FILE *fp;
int err = -1;
- int verify_sig_failed = 0;
+ bool verify_sig_failed[NUM_PCRS] = {0,};
+ bool verify_failed = false;
+ int i;
+ memset(zero, 0, SHA_DIGEST_LENGTH);
memset(fox, 0xff, SHA_DIGEST_LENGTH);
log_debug("Initial PCR value: ");
@@ -1440,7 +1443,8 @@ static int ima_measurement(const char *file)
init_public_keys(params.keyfile);
while (fread(&entry.header, sizeof(entry.header), 1, fp)) {
- ima_extend_pcr(pcr, entry.header.digest, SHA_DIGEST_LENGTH);
+ ima_extend_pcr(pcr[entry.header.pcr], entry.header.digest,
+ SHA_DIGEST_LENGTH);
if (!fread(entry.name, entry.header.name_len, 1, fp)) {
log_err("Unable to read template name\n");
@@ -1472,29 +1476,35 @@ static int ima_measurement(const char *file)
ima_show(&entry);
} else {
if (ima_ng_show(&entry) != 0)
- verify_sig_failed = 1;
+ verify_sig_failed[entry.header.pcr] = true;
}
}
- tpm_pcr_read(10, pcr10, sizeof(pcr10));
- log_info("PCRAgg: ");
- log_dump(pcr, sizeof(pcr));
+ for (i = 0; i < NUM_PCRS; i++) {
+ if (memcmp(pcr[i], zero, SHA_DIGEST_LENGTH) == 0)
+ continue;
+
+ log_info("PCRAgg %.2d: ", i);
+ log_dump(pcr[i], SHA_DIGEST_LENGTH);
- log_info("PCR-10: ");
- log_dump(pcr10, sizeof(pcr10));
+ tpm_pcr_read(i, hwpcr, sizeof(hwpcr));
+ log_info("HW PCR-%d: ", i);
+ log_dump(hwpcr, sizeof(hwpcr));
- if (memcmp(pcr, pcr10, sizeof(pcr))) {
- log_err("PCRAgg does not match PCR-10\n");
- goto out;
- } else if (verify_sig_failed == 1) {
- log_err("PCRAgg matches PCR-10, but list contains unknown keys or invalid signatures\n");
+ if (memcmp(pcr[i], hwpcr, sizeof(SHA_DIGEST_LENGTH)) != 0) {
+ log_err("PCRAgg %d does not match HW PCR-%d\n", i, i);
+
+ verify_failed = true;
+ } else if (verify_sig_failed[i] == true) {
+ log_err("PCRAgg %d matches PCR-%d, but list contains unknown keys or invalid signatures\n", i, i);
+ }
}
- err = 0;
+ if (!verify_failed)
+ err = 0;
out:
fclose(fp);
-
return err;
}
diff --git a/src/imaevm.h b/src/imaevm.h
index d624571..0507947 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -188,6 +188,9 @@ struct RSA_ASN1_template {
size_t size;
};
+#define NUM_PCRS 20
+#define DEFAULT_PCR 10
+
extern const struct RSA_ASN1_template RSA_ASN1_templates[PKEY_HASH__LAST];
extern struct libevm_params params;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 00/10] ima-evm-utils
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
` (9 preceding siblings ...)
2018-01-22 14:54 ` [PATCH 10/10] ima-evm-utils: add support for validating multiple pcrs Mimi Zohar
@ 2018-01-28 19:01 ` Mimi Zohar
10 siblings, 0 replies; 12+ messages in thread
From: Mimi Zohar @ 2018-01-28 19:01 UTC (permalink / raw)
To: linux-integrity
Cc: Dmitry Kasatkin, Roberto Sassu, Bruno E . O . Meneguele,
James Bottomley
On Mon, 2018-01-22 at 09:53 -0500, Mimi Zohar wrote:
> Before upgrading to the new OpenSSL 1.1 API, let's clean up the code
> a bit and add some missing functionality:
> - option to specify the pcr sysfs location
> - verify the measurement list using multiple keys
> - verify the measurement list using multiple pcrs
> - verify a measurement signature against the measurement list digest
> - for completeness, extend "ima_verify" to verify the local security.ima hash
With James' "ima-evm-utils: Add backward compatible support for
openssl 1.1" patch, which supports both OpenSSL 1.0 and 1.1, there is
no rush for including all these changes now.
For example instead of specifying the pcr sysfs location, a better
solution would be for the TPM device driver to export this
information.
The next branch contains the proposed changes for ima-evm-utils
version 1.1, which I'm hoping to release within the next day or so.
thanks,
Mimi
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2018-01-28 19:01 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-22 14:53 [PATCH 00/10] ima-evm-utils Mimi Zohar
2018-01-22 14:53 ` [PATCH 01/10] ima-evm-utils: fix "ima_measurement" template fields length Mimi Zohar
2018-01-22 14:53 ` [PATCH 02/10] ima-evm-utils: revert the change to use printf instead of log_info() Mimi Zohar
2018-01-22 14:53 ` [PATCH 03/10] ima-evm-utils: fix spelling error Mimi Zohar
2018-01-22 14:53 ` [PATCH 04/10] ima-evm-utils: remove the unnecessary display of the keyid Mimi Zohar
2018-01-22 14:54 ` [PATCH 05/10] ima-evm-utils: support verifying the measurement list using multiple keys Mimi Zohar
2018-01-22 14:54 ` [PATCH 06/10] ima-evm-utils: indicate measurement list signature verification failure Mimi Zohar
2018-01-22 14:54 ` [PATCH 07/10] ima-evm-utils: add support for specifying the pcr file location Mimi Zohar
2018-01-22 14:54 ` [PATCH 08/10] ima-evm-utils: verify the measurement list signature based on the list digest Mimi Zohar
2018-01-22 14:54 ` [PATCH 09/10] ima-evm-utils: verify IMA file hashes stored as xattrs Mimi Zohar
2018-01-22 14:54 ` [PATCH 10/10] ima-evm-utils: add support for validating multiple pcrs Mimi Zohar
2018-01-28 19:01 ` [PATCH 00/10] ima-evm-utils Mimi Zohar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).