On 9/6/22 15:50, Mimi Zohar wrote:
Calculating the EVM HMAC and labeling the filesystem was originally
included in ima-evm-utils for debugging purposes only. For now,
instead of removing EVM HMAC support just replace the low level
HMAC_ calls with EVP_ calls.
The '-a, --hashalgo' specifies the IMA hash or signature algorithm.
The kernel EVM HMAC is limited to SHA1. Fix ima-evm-utils by hard
coding the EVM HMAC algorithm to SHA1.
Reviewed-by: Petr Vorel <pvorel@xxxxxxx>
Signed-off-by: Mimi Zohar <zohar@xxxxxxxxxxxxx>
---
src/evmctl.c | 57 +++++++++++++++++++++++++++++-----------------------
1 file changed, 32 insertions(+), 25 deletions(-)
diff --git a/src/evmctl.c b/src/evmctl.c
index 641504047a36..a9b2f1040787 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -1159,12 +1159,12 @@ static int cmd_setxattr_ima(struct command *cmd)
static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hash)
{
- const EVP_MD *md;
+ size_t mdlen;
+ EVP_MD_CTX *pctx;
+ EVP_PKEY *pkey = NULL;
struct stat st;
int err = -1;
uint32_t generation = 0;
- HMAC_CTX *pctx;
- unsigned int mdlen;
char **xattrname;
unsigned char xattr_value[1024];
unsigned char *key;
@@ -1175,10 +1175,8 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
struct h_misc_64 hmac_misc;
int hmac_size;
#if OPENSSL_VERSION_NUMBER < 0x10100000
- HMAC_CTX ctx;
+ EVP_MD_CTX ctx;
pctx = &ctx;
-#else
- pctx = HMAC_CTX_new();
#endif
key = file2bin(keyfile, NULL, &keylen);
@@ -1226,19 +1224,26 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
goto out;
}
- md = EVP_get_digestbyname(imaevm_params.hash_algo);
- if (!md) {
- log_err("EVP_get_digestbyname(%s) failed\n",
- imaevm_params.hash_algo);
hash_algo was expected to always be sha1 before because now you seem to
hard code it to EVP_sha1() below? Following what I see here this seems
to indeed be the only hash supported for HMAC:
https://elixir.bootlin.com/linux/latest/source/security/integrity/evm/evm_crypto.c#L38
--> Reviewed-by: Stefan Berger <stefanb@xxxxxxxxxxxxx>
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ pctx = EVP_MD_CTX_new();
+ if (!pctx) {
+ log_err("EVP_MD_CTX_new failed\n");
goto out;
}
+#endif
- err = !HMAC_Init_ex(pctx, evmkey, sizeof(evmkey), md, NULL);
- if (err) {
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, evmkey, sizeof(evmkey));
+ if (!pkey) {
log_err("HMAC_Init() failed\n");
goto out;
}
+ err = EVP_DigestSignInit(pctx, NULL, EVP_sha1(), NULL, pkey);
+ if (err != 1) {
+ log_err("EVP_DigestSignInit() failed\n");
+ goto out;
+ }
+
for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
err = lgetxattr(file, *xattrname, xattr_value, sizeof(xattr_value));
if (err < 0) {
@@ -1249,12 +1254,12 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
log_info("skipping xattr: %s\n", *xattrname);
continue;
}
- /*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(pctx, xattr_value, err);
- if (err) {
- log_err("HMAC_Update() failed\n");
+
+ err = EVP_DigestSignUpdate(pctx, xattr_value, err);
+ if (err != 1) {
+ log_err("EVP_DigestSignUpdate() failed\n");
goto out_ctx_cleanup;
}
}
@@ -1293,23 +1298,24 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size);
- err = !HMAC_Update(pctx, (const unsigned char *)&hmac_misc, hmac_size);
- if (err) {
+ err = EVP_DigestSignUpdate(pctx, &hmac_misc, hmac_size);
+ if (err != 1) {
log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup;
}
- err = !HMAC_Final(pctx, hash, &mdlen);
- if (err)
+ err = EVP_DigestSignFinal(pctx, hash, &mdlen);
+ if (err != 1)
log_err("HMAC_Final() failed\n");
out_ctx_cleanup:
-#if OPENSSL_VERSION_NUMBER < 0x10100000
- HMAC_CTX_cleanup(pctx);
-#else
- HMAC_CTX_free(pctx);
+ EVP_PKEY_free(pkey);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+ EVP_MD_CTX_free(pctx);
#endif
out:
free(key);
- return err ?: mdlen;
+ if (err == 1)
+ return mdlen;
+ return err;
}
static int hmac_evm(const char *file, const char *key)
@@ -1333,6 +1339,7 @@ static int hmac_evm(const char *file, const char *key)
err = lsetxattr(file, xattr_evm, sig, len + 1, 0);
if (err < 0) {
log_err("setxattr failed: %s\n", file);
+ errno = 0;
return err;
}
}