1
0
mirror of https://git.code.sf.net/p/linux-ima/ima-evm-utils synced 2025-04-28 14:43:37 +02:00

Refactored to remove redundant hash initialization code

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
This commit is contained in:
Dmitry Kasatkin 2012-05-18 16:49:28 +03:00
parent ef74ed1ab2
commit 307f8162eb

View File

@ -494,14 +494,11 @@ static int sign_evm(const char *file, const char *key)
return 0; return 0;
} }
static int calc_file_hash(const char *file, uint8_t *hash) static int add_file_hash(const char *file, EVP_MD_CTX *ctx)
{ {
EVP_MD_CTX ctx;
const EVP_MD *md;
uint8_t *data; uint8_t *data;
int err, size, bs = DATA_SIZE; int err, size, bs = DATA_SIZE;
size_t len; size_t len;
unsigned int mdlen;
FILE *fp; FILE *fp;
data = malloc(bs); data = malloc(bs);
@ -516,18 +513,6 @@ static int calc_file_hash(const char *file, uint8_t *hash)
return -1; return -1;
} }
md = EVP_get_digestbyname(hash_algo);
if (!md) {
log_err("EVP_get_digestbyname() failed\n");
return 1;
}
err = EVP_DigestInit(&ctx, md);
if (!err) {
log_err("EVP_DigestInit() failed\n");
return 1;
}
for (size = get_fdsize(fileno(fp)); size; size -= len) { for (size = get_fdsize(fileno(fp)); size; size -= len) {
len = MIN(size, bs); len = MIN(size, bs);
err = fread(data, len, 1, fp); err = fread(data, len, 1, fp);
@ -538,24 +523,17 @@ static int calc_file_hash(const char *file, uint8_t *hash)
} }
break; break;
} }
err = EVP_DigestUpdate(&ctx, data, len); err = EVP_DigestUpdate(ctx, data, len);
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
} }
} }
err = EVP_DigestFinal(&ctx, hash, &mdlen);
if (!err) {
log_err("EVP_DigestFinal() failed\n");
return 1;
}
fclose(fp); fclose(fp);
free(data); free(data);
return mdlen; return 0;
} }
struct dirent_list { struct dirent_list {
@ -563,12 +541,9 @@ struct dirent_list {
struct dirent de; struct dirent de;
}; };
static int calc_dir_hash(const char *file, uint8_t *hash) static int add_dir_hash(const char *file, EVP_MD_CTX *ctx)
{ {
EVP_MD_CTX ctx;
const EVP_MD *md;
int err; int err;
unsigned int mdlen;
struct dirent *de; struct dirent *de;
DIR *dir; DIR *dir;
struct dirent_list *head = NULL, *pos, *prev, *cur; struct dirent_list *head = NULL, *pos, *prev, *cur;
@ -580,18 +555,6 @@ static int calc_dir_hash(const char *file, uint8_t *hash)
return -1; return -1;
} }
md = EVP_get_digestbyname(hash_algo);
if (!md) {
log_err("EVP_get_digestbyname() failed\n");
return 1;
}
err = EVP_DigestInit(&ctx, md);
if (!err) {
log_err("EVP_DigestInit() failed\n");
return 1;
}
while ((de = readdir(dir))) { while ((de = readdir(dir))) {
/*log_debug("entry: ino: %lu, %s\n", de->d_ino, de->d_name);*/ /*log_debug("entry: ino: %lu, %s\n", de->d_ino, de->d_name);*/
for (prev = NULL, pos = head; pos; prev = pos, pos = pos->next) { for (prev = NULL, pos = head; pos; prev = pos, pos = pos->next) {
@ -611,17 +574,17 @@ static int calc_dir_hash(const char *file, uint8_t *hash)
pos = cur->next; pos = cur->next;
ino = cur->de.d_ino; ino = cur->de.d_ino;
log_debug("entry: ino: %llu, %s\n", (unsigned long long)ino, cur->de.d_name); log_debug("entry: ino: %llu, %s\n", (unsigned long long)ino, cur->de.d_name);
err = EVP_DigestUpdate(&ctx, cur->de.d_name, strlen(cur->de.d_name)); err = EVP_DigestUpdate(ctx, cur->de.d_name, strlen(cur->de.d_name));
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
} }
err = EVP_DigestUpdate(&ctx, &ino, sizeof(ino)); err = EVP_DigestUpdate(ctx, &ino, sizeof(ino));
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
} }
err = EVP_DigestUpdate(&ctx, &cur->de.d_type, sizeof(cur->de.d_type)); err = EVP_DigestUpdate(ctx, &cur->de.d_type, sizeof(cur->de.d_type));
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
@ -629,22 +592,18 @@ static int calc_dir_hash(const char *file, uint8_t *hash)
free(cur); free(cur);
} }
err = EVP_DigestFinal(&ctx, hash, &mdlen);
if (!err) {
log_err("EVP_DigestFinal() failed\n");
return 1;
}
closedir(dir); closedir(dir);
return mdlen; return 0;
} }
static int hash_ima(const char *file) static int calc_hash(const char *file, uint8_t *hash)
{ {
unsigned char hash[65] = "\x01"; /* MAX hash size + 1 */
int len, err;
struct stat st; struct stat st;
EVP_MD_CTX ctx;
const EVP_MD *md;
unsigned int mdlen;
int err;
/* Need to know the file length */ /* Need to know the file length */
err = stat(file, &st); err = stat(file, &st);
@ -653,10 +612,48 @@ static int hash_ima(const char *file)
return err; return err;
} }
if (S_ISDIR(st.st_mode)) md = EVP_get_digestbyname(hash_algo);
len = calc_dir_hash(file, hash + 1); if (!md) {
else log_err("EVP_get_digestbyname() failed\n");
len = calc_file_hash(file, hash + 1); return 1;
}
err = EVP_DigestInit(&ctx, md);
if (!err) {
log_err("EVP_DigestInit() failed\n");
return 1;
}
switch (st.st_mode & S_IFMT) {
case S_IFREG:
err = add_file_hash(file, &ctx);
break;
case S_IFDIR:
err = add_dir_hash(file, &ctx);
break;
default:
log_errno("Unsupported file type");
return -1;
}
if (err)
return err;
err = EVP_DigestFinal(&ctx, hash, &mdlen);
if (!err) {
log_err("EVP_DigestFinal() failed\n");
return 1;
}
return mdlen;
}
static int hash_ima(const char *file)
{
unsigned char hash[65] = "\x01"; /* MAX hash size + 1 */
int len, err;
len = calc_hash(file, hash + 1);
if (len <= 1) if (len <= 1)
return len; return len;
@ -696,7 +693,7 @@ static int sign_ima(const char *file, const char *key)
unsigned char sig[1024] = "\x03"; unsigned char sig[1024] = "\x03";
int len, err; int len, err;
len = calc_file_hash(file, hash); len = calc_hash(file, hash);
if (len <= 1) if (len <= 1)
return len; return len;