On 5/12/22 14:30, Mimi Zohar wrote:
ima-evm-utils does not attempt to calculate or even read the fs-verity
file hash, but can verify the fs-verity signature based on the fsverity
file hash, both contained in the measurement list record.
For the time being only fs-verity supports signature format v3 (sigv3).
To differentiate between the existing IMA and fs-verity file signatures,
modify the verify_hash() 'sig' argument to be a pointer to the entire
xattr, including the xattr type.
Example:
evmctl ima_measurement --key <DER encoded public key> \
--verify-sig /sys/kernel/security/ima/binary_runtime_measurements
Signed-off-by: Mimi Zohar <zohar@xxxxxxxxxxxxx>
---
src/evmctl.c | 11 +++++++++--
src/libimaevm.c | 50 +++++++++++++++++++++++++++++++++++++------------
2 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 9152b0a5c7c2..593eed80f96a 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -909,7 +909,7 @@ static int verify_evm(const char *file)
return mdlen;
assert(mdlen <= sizeof(hash));
- return verify_hash(file, hash, mdlen, sig + 1, len - 1);
+ return verify_hash(file, hash, mdlen, sig, len);
}
static int cmd_verify_evm(struct command *cmd)
@@ -1572,7 +1572,8 @@ void ima_ng_show(struct template_entry *entry)
fieldp += field_len;
total_len -= field_len;
- if (!strcmp(entry->name, "ima-sig")) {
+ if (!strcmp(entry->name, "ima-sig") ||
+ !strcmp(entry->name, "ima-sigv2")) {
/* get signature */
field_len = *(uint32_t *)fieldp;
fieldp += sizeof(field_len);
@@ -1618,11 +1619,17 @@ void ima_ng_show(struct template_entry *entry)
log_info(" ");
log_dump(sig, sig_len);
}
+
+ /*
+ * Either verify the signature against the hash contained in
+ * the measurement list or calculate the hash.
+ */
if (verify_list_sig)
err = ima_verify_signature(path, sig, sig_len,
digest, digest_len);
else
err = ima_verify_signature(path, sig, sig_len, NULL, 0);
+
if (!err && imaevm_params.verbose > LOG_INFO)
log_info("%s: verification is OK\n", path);
} else {
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 7c2ed5fb0556..8a37551132d6 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -534,11 +534,21 @@ int calc_hash_sigv3(enum evm_ima_xattr_type type, const char *algo,
return -EINVAL;
}
- if ((hash_algo = imaevm_get_hash_algo(algo)) < 0) {
- log_err("Hash algorithm %s not supported\n", algo);
- return -EINVAL;
+ /*
+ * Calculating the hash is based on the fsverity hash algorithm,
+ * while verifying the signature is based on the hash algorithm
+ * contained in the signature header.
+ */
+ if (algo) {
+ if ((hash_algo = imaevm_get_hash_algo(algo)) < 0) {
+ log_err("Hash algorithm %s not supported\n", algo);
+ return -EINVAL;
+ }
+ file_id.hash_algorithm = hash_algo;
+ } else {
+ algo = imaevm_params.hash_algo;
+ file_id.hash_algorithm = imaevm_get_hash_algo(algo);
You should probably compare this also against '< 0' as it was before. If
you do it outside the if-else the two cases can share this:
if (!algo)
algo = imaevm_params.hash_algo;
if ((hash_algo = imaevm_get_hash_algo(algo)) < 0) {
log_err("Hash algorithm %s not supported\n", algo);
return -EINVAL;
}
file_id.hash_algorithm = hash_algo;