Add support for portable EVM format

Add a --portable argument that generates EVM signatures without using
the inode number and generation or fs UUID.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

Changelog:
- immutable and portable flags are exclusive, prevent enabling both.
This commit is contained in:
Matthew Garrett 2017-11-16 10:21:11 -08:00 committed by mimi
parent 233dedffe9
commit 4928548d9d
3 changed files with 37 additions and 12 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 ] [--key key] [--pass password] file sign [-r] [--imahash | --imasig ] [--portable] [--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,6 +46,7 @@ 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)
@ -95,7 +96,8 @@ 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. custom UUID. Providing the '--portable' option will disable usage of the fs 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

@ -117,6 +117,7 @@ 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
@ -418,8 +419,10 @@ 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);
hmac->ino = st.st_ino; if (!evm_portable) {
hmac->generation = generation; hmac->ino = st.st_ino;
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;
@ -427,8 +430,10 @@ 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);
hmac->ino = st.st_ino; if (!evm_portable) {
hmac->generation = generation; hmac->ino = st.st_ino;
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;
@ -436,8 +441,10 @@ 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);
hmac->ino = st.st_ino; if (!evm_portable) {
hmac->generation = generation; hmac->ino = st.st_ino;
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;
@ -452,7 +459,8 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
return 1; return 1;
} }
if (!evm_immutable && !(hmac_flags & HMAC_FLAG_NO_UUID)) { if (!evm_immutable && !evm_portable &&
!(hmac_flags & HMAC_FLAG_NO_UUID)) {
err = get_uuid(&st, uuid); err = get_uuid(&st, uuid);
if (err) if (err)
return -1; return -1;
@ -489,7 +497,10 @@ static int sign_evm(const char *file, const char *key)
/* add header */ /* add header */
len++; len++;
sig[0] = EVM_IMA_XATTR_DIGSIG; if (evm_portable)
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 */
@ -1552,6 +1563,7 @@ 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"
@ -1610,6 +1622,7 @@ 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},
@ -1666,7 +1679,7 @@ int main(int argc, char *argv[])
g_argc = argc; g_argc = argc;
while (1) { while (1) {
c = getopt_long(argc, argv, "hvnsda:p::fu::k:t:ri", opts, &lind); c = getopt_long(argc, argv, "hvnsda:op::fu::k:t:ri", opts, &lind);
if (c == -1) if (c == -1)
break; break;
@ -1713,7 +1726,16 @@ int main(int argc, char *argv[])
params.keyfile = optarg; params.keyfile = optarg;
break; break;
case 'i': case 'i':
evm_immutable = true; if (evm_portable)
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,6 +82,7 @@ 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 {