1 Commits

5 changed files with 285 additions and 103 deletions

6
README
View File

@ -26,7 +26,7 @@ COMMANDS
--version --version
help <command> help <command>
import [--rsa] pubkey keyring import [--rsa] pubkey keyring
sign [-r] [--imahash | --imasig ] [--portable] [--key key] [--pass password] file sign [-r] [--imahash | --imasig ] [--key key] [--pass password] file
verify file verify file
ima_sign [--sigfile] [--key key] [--pass password] file ima_sign [--sigfile] [--key key] [--pass password] file
ima_verify file ima_verify file
@ -46,7 +46,6 @@ OPTIONS
-f, --sigfile store IMA signature in .sig file instead of xattr -f, --sigfile store IMA signature in .sig file instead of xattr
--rsa use RSA key type and signing scheme v1 --rsa use RSA key type and signing scheme v1
-k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem) -k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)
-o, --portable generate portable EVM signatures
-p, --pass password for encrypted signing key -p, --pass password for encrypted signing key
-r, --recursive recurse into directories (sign) -r, --recursive recurse into directories (sign)
-t, --type file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink) -t, --type file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)
@ -96,8 +95,7 @@ Kernel configuration option CONFIG_EVM_ATTR_FSUUID controls whether to include
filesystem UUID into HMAC and enabled by default. Therefore evmctl also includes filesystem UUID into HMAC and enabled by default. Therefore evmctl also includes
fsuuid by default. Providing '--uuid' option without parameter allows to disable fsuuid by default. Providing '--uuid' option without parameter allows to disable
usage of fs uuid. Providing '--uuid=UUID' option with parameter allows to use usage of fs uuid. Providing '--uuid=UUID' option with parameter allows to use
custom UUID. Providing the '--portable' option will disable usage of the fs uuid custom UUID.
and also the inode number and generation.
Kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS controls whether to Kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS controls whether to
include additional SMACK extended attributes into HMAC. They are following: include additional SMACK extended attributes into HMAC. They are following:

View File

@ -0,0 +1,224 @@
diff -urNp ima-evm-utils-1.0-orig/src/libimaevm.c ima-evm-utils-1.0/src/libimaevm.c
--- ima-evm-utils-1.0-orig/src/libimaevm.c 2015-07-30 15:28:53.000000000 -0300
+++ ima-evm-utils-1.0/src/libimaevm.c 2017-12-01 12:01:28.008705290 -0200
@@ -269,7 +269,7 @@ int ima_calc_hash(const char *file, uint
{
const EVP_MD *md;
struct stat st;
- EVP_MD_CTX ctx;
+ EVP_MD_CTX *ctx;
unsigned int mdlen;
int err;
@@ -286,25 +286,30 @@ int ima_calc_hash(const char *file, uint
return 1;
}
- err = EVP_DigestInit(&ctx, md);
+ ctx = EVP_MD_CTX_new();
+ if (!ctx) {
+ log_err("EVP_MD_CTX_new() failed\n");
+ return 1;
+ }
+ err = EVP_DigestInit_ex(ctx, md, NULL);
if (!err) {
- log_err("EVP_DigestInit() failed\n");
+ log_err("EVP_DigestInit_ex() failed\n");
return 1;
}
switch (st.st_mode & S_IFMT) {
case S_IFREG:
- err = add_file_hash(file, &ctx);
+ err = add_file_hash(file, ctx);
break;
case S_IFDIR:
- err = add_dir_hash(file, &ctx);
+ err = add_dir_hash(file, ctx);
break;
case S_IFLNK:
- err = add_link_hash(file, &ctx);
+ err = add_link_hash(file, ctx);
break;
case S_IFIFO: case S_IFSOCK:
case S_IFCHR: case S_IFBLK:
- err = add_dev_hash(&st, &ctx);
+ err = add_dev_hash(&st, ctx);
break;
default:
log_errno("Unsupported file type");
@@ -314,11 +319,12 @@ int ima_calc_hash(const char *file, uint
if (err)
return err;
- err = EVP_DigestFinal(&ctx, hash, &mdlen);
+ err = EVP_DigestFinal_ex(ctx, hash, &mdlen);
if (!err) {
- log_err("EVP_DigestFinal() failed\n");
+ log_err("EVP_DigestFinal_ex() failed\n");
return 1;
}
+ EVP_MD_CTX_free(ctx);
return mdlen;
}
@@ -547,6 +553,7 @@ int key2bin(RSA *key, unsigned char *pub
{
int len, b, offset = 0;
struct pubkey_hdr *pkh = (struct pubkey_hdr *)pub;
+ const BIGNUM *n, *e;
/* add key header */
pkh->version = 1;
@@ -556,18 +563,19 @@ int key2bin(RSA *key, unsigned char *pub
offset += sizeof(*pkh);
- len = BN_num_bytes(key->n);
- b = BN_num_bits(key->n);
+ RSA_get0_key(key, &n, &e, NULL);
+ len = BN_num_bytes(n);
+ b = BN_num_bits(n);
pub[offset++] = b >> 8;
pub[offset++] = b & 0xff;
- BN_bn2bin(key->n, &pub[offset]);
+ BN_bn2bin(n, &pub[offset]);
offset += len;
- len = BN_num_bytes(key->e);
- b = BN_num_bits(key->e);
+ len = BN_num_bytes(e);
+ b = BN_num_bits(e);
pub[offset++] = b >> 8;
pub[offset++] = b & 0xff;
- BN_bn2bin(key->e, &pub[offset]);
+ BN_bn2bin(e, &pub[offset]);
offset += len;
return offset;
diff -urNp ima-evm-utils-1.0-orig/src/evmctl.c ima-evm-utils-1.0/src/evmctl.c
--- ima-evm-utils-1.0-orig/src/evmctl.c 2015-07-30 15:28:53.000000000 -0300
+++ ima-evm-utils-1.0/src/evmctl.c 2017-12-01 12:00:39.683306265 -0200
@@ -305,7 +305,7 @@ static int calc_evm_hash(const char *fil
struct stat st;
int err;
uint32_t generation = 0;
- EVP_MD_CTX ctx;
+ EVP_MD_CTX *ctx;
unsigned int mdlen;
char **xattrname;
char xattr_value[1024];
@@ -345,9 +345,14 @@ static int calc_evm_hash(const char *fil
return -1;
}
- err = EVP_DigestInit(&ctx, EVP_sha1());
+ ctx = EVP_MD_CTX_new();
+ if (!ctx) {
+ log_err("EVP_MD_CTX_new() failed\n");
+ return 1;
+ }
+ err = EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
if (!err) {
- log_err("EVP_DigestInit() failed\n");
+ log_err("EVP_DigestInit_ex() failed\n");
return 1;
}
@@ -364,7 +369,7 @@ static int calc_evm_hash(const char *fil
/*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err);
- err = EVP_DigestUpdate(&ctx, xattr_value, err);
+ err = EVP_DigestUpdate(ctx, xattr_value, err);
if (!err) {
log_err("EVP_DigestUpdate() failed\n");
return 1;
@@ -412,7 +417,7 @@ static int calc_evm_hash(const char *fil
log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size);
- err = EVP_DigestUpdate(&ctx, &hmac_misc, hmac_size);
+ err = EVP_DigestUpdate(ctx, &hmac_misc, hmac_size);
if (!err) {
log_err("EVP_DigestUpdate() failed\n");
return 1;
@@ -423,18 +428,19 @@ static int calc_evm_hash(const char *fil
if (err)
return -1;
- err = EVP_DigestUpdate(&ctx, (const unsigned char *)uuid, sizeof(uuid));
+ err = EVP_DigestUpdate(ctx, (const unsigned char *)uuid, sizeof(uuid));
if (!err) {
log_err("EVP_DigestUpdate() failed\n");
return 1;
}
}
- err = EVP_DigestFinal(&ctx, hash, &mdlen);
+ err = EVP_DigestFinal_ex(ctx, hash, &mdlen);
if (!err) {
log_err("EVP_DigestFinal() failed\n");
return 1;
}
+ EVP_MD_CTX_free(ctx);
return mdlen;
}
@@ -844,7 +850,7 @@ static int calc_evm_hmac(const char *fil
struct stat st;
int err = -1;
uint32_t generation = 0;
- HMAC_CTX ctx;
+ HMAC_CTX *ctx;
unsigned int mdlen;
char **xattrname;
unsigned char xattr_value[1024];
@@ -900,10 +906,15 @@ static int calc_evm_hmac(const char *fil
goto out;
}
- err = !HMAC_Init(&ctx, evmkey, sizeof(evmkey), EVP_sha1());
+ ctx = HMAC_CTX_new();
+ if (!ctx) {
+ log_err("HMAC_MD_CTX_new() failed\n");
+ goto out;
+ }
+ err = !HMAC_Init_ex(ctx, evmkey, sizeof(evmkey), EVP_sha1(), NULL);
if (err) {
log_err("HMAC_Init() failed\n");
- goto out;
+ goto out_ctx_cleanup;
}
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
@@ -919,7 +930,7 @@ static int calc_evm_hmac(const char *fil
/*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err);
- err = !HMAC_Update(&ctx, xattr_value, err);
+ err = !HMAC_Update(ctx, xattr_value, err);
if (err) {
log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup;
@@ -960,16 +971,16 @@ static int calc_evm_hmac(const char *fil
log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size);
- err = !HMAC_Update(&ctx, (const unsigned char *)&hmac_misc, hmac_size);
+ err = !HMAC_Update(ctx, (const unsigned char *)&hmac_misc, hmac_size);
if (err) {
log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup;
}
- err = !HMAC_Final(&ctx, hash, &mdlen);
+ err = !HMAC_Final(ctx, hash, &mdlen);
if (err)
log_err("HMAC_Final() failed\n");
out_ctx_cleanup:
- HMAC_CTX_cleanup(&ctx);
+ HMAC_CTX_free(ctx);
out:
free(key);
return err ?: mdlen;

View File

@ -117,7 +117,6 @@ static int recursive;
static int msize; static int msize;
static dev_t fs_dev; static dev_t fs_dev;
static bool evm_immutable; static bool evm_immutable;
static bool evm_portable;
#define HMAC_FLAG_NO_UUID 0x0001 #define HMAC_FLAG_NO_UUID 0x0001
#define HMAC_FLAG_CAPS_SET 0x0002 #define HMAC_FLAG_CAPS_SET 0x0002
@ -315,7 +314,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
struct stat st; struct stat st;
int err; int err;
uint32_t generation = 0; uint32_t generation = 0;
EVP_MD_CTX ctx; EVP_MD_CTX *ctx;
unsigned int mdlen; unsigned int mdlen;
char **xattrname; char **xattrname;
char xattr_value[1024]; char xattr_value[1024];
@ -367,9 +366,14 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
return -1; return -1;
} }
err = EVP_DigestInit(&ctx, EVP_sha1()); ctx = EVP_MD_CTX_new();
if (!ctx) {
log_err("EVP_MD_CTX_new() failed\n");
return 1;
}
err = EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
if (!err) { if (!err) {
log_err("EVP_DigestInit() failed\n"); log_err("EVP_DigestInit_ex() failed\n");
return 1; return 1;
} }
@ -399,7 +403,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
/*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/ /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
log_info("name: %s, size: %d\n", *xattrname, err); log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err); log_debug_dump(xattr_value, err);
err = EVP_DigestUpdate(&ctx, xattr_value, err); err = EVP_DigestUpdate(ctx, xattr_value, err);
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
@ -419,10 +423,8 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
struct h_misc *hmac = (struct h_misc *)&hmac_misc; struct h_misc *hmac = (struct h_misc *)&hmac_misc;
hmac_size = sizeof(*hmac); hmac_size = sizeof(*hmac);
if (!evm_portable) { hmac->ino = st.st_ino;
hmac->ino = st.st_ino; hmac->generation = generation;
hmac->generation = generation;
}
hmac->uid = st.st_uid; hmac->uid = st.st_uid;
hmac->gid = st.st_gid; hmac->gid = st.st_gid;
hmac->mode = st.st_mode; hmac->mode = st.st_mode;
@ -430,10 +432,8 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc; struct h_misc_64 *hmac = (struct h_misc_64 *)&hmac_misc;
hmac_size = sizeof(*hmac); hmac_size = sizeof(*hmac);
if (!evm_portable) { hmac->ino = st.st_ino;
hmac->ino = st.st_ino; hmac->generation = generation;
hmac->generation = generation;
}
hmac->uid = st.st_uid; hmac->uid = st.st_uid;
hmac->gid = st.st_gid; hmac->gid = st.st_gid;
hmac->mode = st.st_mode; hmac->mode = st.st_mode;
@ -441,10 +441,8 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc; struct h_misc_32 *hmac = (struct h_misc_32 *)&hmac_misc;
hmac_size = sizeof(*hmac); hmac_size = sizeof(*hmac);
if (!evm_portable) { hmac->ino = st.st_ino;
hmac->ino = st.st_ino; hmac->generation = generation;
hmac->generation = generation;
}
hmac->uid = st.st_uid; hmac->uid = st.st_uid;
hmac->gid = st.st_gid; hmac->gid = st.st_gid;
hmac->mode = st.st_mode; hmac->mode = st.st_mode;
@ -453,30 +451,30 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
log_debug("hmac_misc (%d): ", hmac_size); log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size); log_debug_dump(&hmac_misc, hmac_size);
err = EVP_DigestUpdate(&ctx, &hmac_misc, hmac_size); err = EVP_DigestUpdate(ctx, &hmac_misc, hmac_size);
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
} }
if (!evm_immutable && !evm_portable && if (!evm_immutable && !(hmac_flags & HMAC_FLAG_NO_UUID)) {
!(hmac_flags & HMAC_FLAG_NO_UUID)) {
err = get_uuid(&st, uuid); err = get_uuid(&st, uuid);
if (err) if (err)
return -1; return -1;
err = EVP_DigestUpdate(&ctx, (const unsigned char *)uuid, sizeof(uuid)); err = EVP_DigestUpdate(ctx, (const unsigned char *)uuid, sizeof(uuid));
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); err = EVP_DigestFinal_ex(ctx, hash, &mdlen);
if (!err) { if (!err) {
log_err("EVP_DigestFinal() failed\n"); log_err("EVP_DigestFinal() failed\n");
return 1; return 1;
} }
EVP_MD_CTX_free(ctx);
return mdlen; return mdlen;
} }
@ -497,10 +495,7 @@ static int sign_evm(const char *file, const char *key)
/* add header */ /* add header */
len++; len++;
if (evm_portable) sig[0] = EVM_IMA_XATTR_DIGSIG;
sig[0] = EVM_XATTR_PORTABLE_DIGSIG;
else
sig[0] = EVM_IMA_XATTR_DIGSIG;
if (evm_immutable) if (evm_immutable)
sig[1] = 3; /* immutable signature version */ sig[1] = 3; /* immutable signature version */
@ -839,6 +834,7 @@ static int cmd_convert(struct command *cmd)
return err; return err;
} }
static int cmd_import(struct command *cmd) static int cmd_import(struct command *cmd)
{ {
char *inkey, *ring = NULL; char *inkey, *ring = NULL;
@ -911,42 +907,6 @@ out:
return err; return err;
} }
static int setxattr_ima(const char *file, char *sig_file)
{
unsigned char *sig;
int len, err;
if (sig_file)
sig = file2bin(sig_file, NULL, &len);
else
sig = file2bin(file, "sig", &len);
if (!sig)
return 0;
err = lsetxattr(file, "security.ima", sig, len, 0);
if (err < 0)
log_err("setxattr failed: %s\n", file);
free(sig);
return err;
}
static int cmd_setxattr_ima(struct command *cmd)
{
char *file, *sig = NULL;
if (sigfile)
sig = g_argv[optind++];
file = g_argv[optind++];
if (!file) {
log_err("Parameters missing\n");
print_usage(cmd);
return -1;
}
return setxattr_ima(file, sig);
}
#define MAX_KEY_SIZE 128 #define MAX_KEY_SIZE 128
static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hash) static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hash)
@ -954,7 +914,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
struct stat st; struct stat st;
int err = -1; int err = -1;
uint32_t generation = 0; uint32_t generation = 0;
HMAC_CTX ctx; HMAC_CTX *ctx;
unsigned int mdlen; unsigned int mdlen;
char **xattrname; char **xattrname;
unsigned char xattr_value[1024]; unsigned char xattr_value[1024];
@ -1011,10 +971,15 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
goto out; goto out;
} }
err = !HMAC_Init(&ctx, evmkey, sizeof(evmkey), EVP_sha1()); ctx = HMAC_CTX_new();
if (!ctx) {
log_err("HMAC_MD_CTX_new() failed\n");
goto out;
}
err = !HMAC_Init_ex(ctx, evmkey, sizeof(evmkey), EVP_sha1(), NULL);
if (err) { if (err) {
log_err("HMAC_Init() failed\n"); log_err("HMAC_Init() failed\n");
goto out; goto out_ctx_cleanup;
} }
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) { for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
@ -1030,7 +995,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
/*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/ /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
log_info("name: %s, size: %d\n", *xattrname, err); log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err); log_debug_dump(xattr_value, err);
err = !HMAC_Update(&ctx, xattr_value, err); err = !HMAC_Update(ctx, xattr_value, err);
if (err) { if (err) {
log_err("HMAC_Update() failed\n"); log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup; goto out_ctx_cleanup;
@ -1071,16 +1036,16 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
log_debug("hmac_misc (%d): ", hmac_size); log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size); log_debug_dump(&hmac_misc, hmac_size);
err = !HMAC_Update(&ctx, (const unsigned char *)&hmac_misc, hmac_size); err = !HMAC_Update(ctx, (const unsigned char *)&hmac_misc, hmac_size);
if (err) { if (err) {
log_err("HMAC_Update() failed\n"); log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup; goto out_ctx_cleanup;
} }
err = !HMAC_Final(&ctx, hash, &mdlen); err = !HMAC_Final(ctx, hash, &mdlen);
if (err) if (err)
log_err("HMAC_Final() failed\n"); log_err("HMAC_Final() failed\n");
out_ctx_cleanup: out_ctx_cleanup:
HMAC_CTX_cleanup(&ctx); HMAC_CTX_free(ctx);
out: out:
free(key); free(key);
return err ?: mdlen; return err ?: mdlen;
@ -1563,7 +1528,6 @@ static void usage(void)
" -f, --sigfile store IMA signature in .sig file instead of xattr\n" " -f, --sigfile store IMA signature in .sig file instead of xattr\n"
" --rsa use RSA key type and signing scheme v1\n" " --rsa use RSA key type and signing scheme v1\n"
" -k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)\n" " -k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem)\n"
" -o, --portable generate portable EVM signatures\n"
" -p, --pass password for encrypted signing key\n" " -p, --pass password for encrypted signing key\n"
" -r, --recursive recurse into directories (sign)\n" " -r, --recursive recurse into directories (sign)\n"
" -t, --type file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)\n" " -t, --type file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)\n"
@ -1596,7 +1560,6 @@ struct command cmds[] = {
{"verify", cmd_verify_evm, 0, "file", "Verify EVM signature (for debugging).\n"}, {"verify", cmd_verify_evm, 0, "file", "Verify EVM signature (for debugging).\n"},
{"ima_sign", cmd_sign_ima, 0, "[--sigfile] [--key key] [--pass [password] file", "Make file content signature.\n"}, {"ima_sign", cmd_sign_ima, 0, "[--sigfile] [--key key] [--pass [password] file", "Make file content signature.\n"},
{"ima_verify", cmd_verify_ima, 0, "file", "Verify IMA signature (for debugging).\n"}, {"ima_verify", cmd_verify_ima, 0, "file", "Verify IMA signature (for debugging).\n"},
{"ima_setxattr", cmd_setxattr_ima, 0, "[--sigfile file]", "Set IMA signature from sigfile\n"},
{"ima_hash", cmd_hash_ima, 0, "file", "Make file content hash.\n"}, {"ima_hash", cmd_hash_ima, 0, "file", "Make file content hash.\n"},
{"ima_measurement", cmd_ima_measurement, 0, "file", "Verify measurement list (experimental).\n"}, {"ima_measurement", cmd_ima_measurement, 0, "file", "Verify measurement list (experimental).\n"},
{"ima_fix", cmd_ima_fix, 0, "[-t fdsxm] path", "Recursively fix IMA/EVM xattrs in fix mode.\n"}, {"ima_fix", cmd_ima_fix, 0, "[-t fdsxm] path", "Recursively fix IMA/EVM xattrs in fix mode.\n"},
@ -1622,7 +1585,6 @@ static struct option opts[] = {
{"recursive", 0, 0, 'r'}, {"recursive", 0, 0, 'r'},
{"m32", 0, 0, '3'}, {"m32", 0, 0, '3'},
{"m64", 0, 0, '6'}, {"m64", 0, 0, '6'},
{"portable", 0, 0, 'o'},
{"smack", 0, 0, 128}, {"smack", 0, 0, 128},
{"version", 0, 0, 129}, {"version", 0, 0, 129},
{"inode", 1, 0, 130}, {"inode", 1, 0, 130},
@ -1679,7 +1641,7 @@ int main(int argc, char *argv[])
g_argc = argc; g_argc = argc;
while (1) { while (1) {
c = getopt_long(argc, argv, "hvnsda:op::fu::k:t:ri", opts, &lind); c = getopt_long(argc, argv, "hvnsda:p::fu::k:t:ri", opts, &lind);
if (c == -1) if (c == -1)
break; break;
@ -1726,16 +1688,7 @@ int main(int argc, char *argv[])
params.keyfile = optarg; params.keyfile = optarg;
break; break;
case 'i': case 'i':
if (evm_portable) evm_immutable = true;
log_err("Portable and immutable options are exclusive, ignoring immutable option.");
else
evm_immutable = true;
break;
case 'o':
if (evm_immutable)
log_err("Portable and immutable options are exclusive, ignoring portable option.");
else
evm_portable = true;
break; break;
case 't': case 't':
search_type = optarg; search_type = optarg;

View File

@ -82,7 +82,6 @@ enum evm_ima_xattr_type {
EVM_XATTR_HMAC, EVM_XATTR_HMAC,
EVM_IMA_XATTR_DIGSIG, EVM_IMA_XATTR_DIGSIG,
IMA_XATTR_DIGEST_NG, IMA_XATTR_DIGEST_NG,
EVM_XATTR_PORTABLE_DIGSIG,
}; };
struct h_misc { struct h_misc {

View File

@ -271,7 +271,7 @@ int ima_calc_hash(const char *file, uint8_t *hash)
{ {
const EVP_MD *md; const EVP_MD *md;
struct stat st; struct stat st;
EVP_MD_CTX ctx; EVP_MD_CTX *ctx;
unsigned int mdlen; unsigned int mdlen;
int err; int err;
@ -288,25 +288,30 @@ int ima_calc_hash(const char *file, uint8_t *hash)
return 1; return 1;
} }
err = EVP_DigestInit(&ctx, md); ctx = EVP_MD_CTX_new();
if (!ctx) {
log_err("EVP_MD_CTX_new() failed\n");
return 1;
}
err = EVP_DigestInit_ex(ctx, md, NULL);
if (!err) { if (!err) {
log_err("EVP_DigestInit() failed\n"); log_err("EVP_DigestInit_ex() failed\n");
return 1; return 1;
} }
switch (st.st_mode & S_IFMT) { switch (st.st_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
err = add_file_hash(file, &ctx); err = add_file_hash(file, ctx);
break; break;
case S_IFDIR: case S_IFDIR:
err = add_dir_hash(file, &ctx); err = add_dir_hash(file, ctx);
break; break;
case S_IFLNK: case S_IFLNK:
err = add_link_hash(file, &ctx); err = add_link_hash(file, ctx);
break; break;
case S_IFIFO: case S_IFSOCK: case S_IFIFO: case S_IFSOCK:
case S_IFCHR: case S_IFBLK: case S_IFCHR: case S_IFBLK:
err = add_dev_hash(&st, &ctx); err = add_dev_hash(&st, ctx);
break; break;
default: default:
log_errno("Unsupported file type"); log_errno("Unsupported file type");
@ -316,11 +321,12 @@ int ima_calc_hash(const char *file, uint8_t *hash)
if (err) if (err)
return err; return err;
err = EVP_DigestFinal(&ctx, hash, &mdlen); err = EVP_DigestFinal_ex(ctx, hash, &mdlen);
if (!err) { if (!err) {
log_err("EVP_DigestFinal() failed\n"); log_err("EVP_DigestFinal_ex() failed\n");
return 1; return 1;
} }
EVP_MD_CTX_free(ctx);
return mdlen; return mdlen;
} }
@ -549,6 +555,7 @@ int key2bin(RSA *key, unsigned char *pub)
{ {
int len, b, offset = 0; int len, b, offset = 0;
struct pubkey_hdr *pkh = (struct pubkey_hdr *)pub; struct pubkey_hdr *pkh = (struct pubkey_hdr *)pub;
const BIGNUM *n, *e;
/* add key header */ /* add key header */
pkh->version = 1; pkh->version = 1;
@ -558,18 +565,19 @@ int key2bin(RSA *key, unsigned char *pub)
offset += sizeof(*pkh); offset += sizeof(*pkh);
len = BN_num_bytes(key->n); RSA_get0_key(key, &n, &e, NULL);
b = BN_num_bits(key->n); len = BN_num_bytes(n);
b = BN_num_bits(n);
pub[offset++] = b >> 8; pub[offset++] = b >> 8;
pub[offset++] = b & 0xff; pub[offset++] = b & 0xff;
BN_bn2bin(key->n, &pub[offset]); BN_bn2bin(n, &pub[offset]);
offset += len; offset += len;
len = BN_num_bytes(key->e); len = BN_num_bytes(e);
b = BN_num_bits(key->e); b = BN_num_bits(e);
pub[offset++] = b >> 8; pub[offset++] = b >> 8;
pub[offset++] = b & 0xff; pub[offset++] = b & 0xff;
BN_bn2bin(key->e, &pub[offset]); BN_bn2bin(e, &pub[offset]);
offset += len; offset += len;
return offset; return offset;