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@xxxxxxxxxxxxxxxxxx> --- 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