mirror of
https://git.code.sf.net/p/linux-ima/ima-evm-utils
synced 2025-04-28 06:33:36 +02:00
directory hash calculation
Directory integrity verification requires directory hash value to be set to security.ima. This patch provides directory hash calculation. Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
This commit is contained in:
parent
874c0fd45c
commit
b60f927609
92
src/evmctl.c
92
src/evmctl.c
@ -43,6 +43,7 @@
|
|||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <attr/xattr.h>
|
#include <attr/xattr.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
@ -543,15 +544,106 @@ static int calc_file_hash(const char *file, uint8_t *hash)
|
|||||||
return mdlen;
|
return mdlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dirent_list {
|
||||||
|
struct dirent_list *next;
|
||||||
|
struct dirent de;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int calc_dir_hash(const char *file, uint8_t *hash)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX ctx;
|
||||||
|
const EVP_MD *md;
|
||||||
|
int err;
|
||||||
|
unsigned int mdlen;
|
||||||
|
struct dirent *de;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent_list *head = NULL, *pos, *prev, *cur;
|
||||||
|
uint64_t ino;
|
||||||
|
|
||||||
|
dir = opendir(file);
|
||||||
|
if (!dir) {
|
||||||
|
log_errno("Unable to open %s", file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenSSL_add_all_digests();
|
||||||
|
|
||||||
|
md = EVP_get_digestbyname(hash_algo);
|
||||||
|
if (!md) {
|
||||||
|
log_errno("EVP_get_digestbyname() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = EVP_DigestInit(&ctx, md);
|
||||||
|
if (!err) {
|
||||||
|
log_errno("EVP_DigestInit() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((de = readdir(dir))) {
|
||||||
|
//printf("entry: ino: %lu, %s\n", de->d_ino, de->d_name);
|
||||||
|
for (prev = NULL, pos = head; pos; prev = pos, pos = pos->next) {
|
||||||
|
if (de->d_ino < pos->de.d_ino)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur = malloc(sizeof(*cur));
|
||||||
|
cur->de = *de;
|
||||||
|
cur->next = pos;
|
||||||
|
if (!head || !prev)
|
||||||
|
head = cur;
|
||||||
|
else
|
||||||
|
prev->next = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cur = head; cur; cur = pos) {
|
||||||
|
pos = cur->next;
|
||||||
|
ino = cur->de.d_ino;
|
||||||
|
log_debug("entry: ino: %llu, %s\n", ino, cur->de.d_name);
|
||||||
|
err = EVP_DigestUpdate(&ctx, cur->de.d_name, strlen(cur->de.d_name));
|
||||||
|
if (!err) {
|
||||||
|
log_errno("EVP_DigestUpdate() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
err = EVP_DigestUpdate(&ctx, &ino, sizeof(ino));
|
||||||
|
if (!err) {
|
||||||
|
log_errno("EVP_DigestUpdate() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
free(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = EVP_DigestFinal(&ctx, hash, &mdlen);
|
||||||
|
if (!err) {
|
||||||
|
log_errno("EVP_DigestFinal() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return mdlen;
|
||||||
|
}
|
||||||
|
|
||||||
static int hash_ima(const char *file)
|
static int hash_ima(const char *file)
|
||||||
{
|
{
|
||||||
unsigned char hash[65] = "\x01";// MAX hash size + 1
|
unsigned char hash[65] = "\x01";// MAX hash size + 1
|
||||||
int err;
|
int err;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
/* Need to know the file length */
|
||||||
|
err = stat(file, &st);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode))
|
||||||
|
err = calc_dir_hash(file, hash + 1);
|
||||||
|
else
|
||||||
err = calc_file_hash(file, hash + 1);
|
err = calc_file_hash(file, hash + 1);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (verbose >= LOG_INFO)
|
||||||
|
log_info("hash: ");
|
||||||
|
|
||||||
if (!set_xattr || verbose >= LOG_INFO)
|
if (!set_xattr || verbose >= LOG_INFO)
|
||||||
dump(hash, err + 1);
|
dump(hash, err + 1);
|
||||||
|
|
||||||
|
@ -10,5 +10,5 @@ dir=${1:-/}
|
|||||||
|
|
||||||
echo "Label: $dir"
|
echo "Label: $dir"
|
||||||
|
|
||||||
find $dir \( -fstype rootfs -o -fstype ext3 -o -fstype ext4 \) -type f -uid 0 -exec evmctl hmac --imahash $verbose '{}' \;
|
find $dir \( -fstype rootfs -o -fstype ext3 -o -fstype ext4 \) \( -type f -o -type d \) -uid 0 -exec evmctl hmac --imahash $verbose '{}' \;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user