Message ID | 20220906195021.854090-7-zohar@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | address deprecated warnings | expand |
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@suse.cz> > Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> > --- > 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@linux.ibm.com> > +#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; > } > }
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); +#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; } }