diff mbox

[09/10] ima-evm-utils: verify IMA file hashes stored as xattrs

Message ID 1516632845-7087-10-git-send-email-zohar@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Mimi Zohar Jan. 22, 2018, 2:54 p.m. UTC
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 mbox

Patch

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
  */