diff mbox series

[v4,ima-evm-utils,1/2] set default hash algorithm in configuration time

Message ID 20210820230001.102249-2-bmeneg@redhat.com (mailing list archive)
State New, archived
Headers show
Series make default hash algorithm dynamic | expand

Commit Message

Bruno Meneguele Aug. 20, 2021, 11 p.m. UTC
The default hash algorithm for evmctl is today hardcoded libimaevm.c file.
To facilitate different distributions and users to set their own default
hash algorithm this patch adds the --with-default-hash=<algo> option to the
configuration script.

The algorithm chosen by the user will then be checked if is available in the
kernel, otherwise IMA won't be able to verify files hashed by the user. For
that, the file exposed by the kernel crypto API (/proc/crypto) is filtered
by an AWK script in order to check the algorithm's name and the module
providing it. Initally, only "module: kernel" is accepted, following IMA's
CONFIG_CRYPTO_SHA1/SHA256 dependency.

Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>
---
Changelog:
v3 - remove wrong m4 script comment

 README                  |  2 +-
 configure.ac            |  1 +
 m4/default-hash-algo.m4 | 46 +++++++++++++++++++++++++++++++++++++++++
 src/evmctl.c            |  4 ++--
 src/imaevm.h            |  4 ++++
 src/libimaevm.c         |  2 +-
 6 files changed, 55 insertions(+), 4 deletions(-)
 create mode 100644 m4/default-hash-algo.m4

Comments

Mimi Zohar Aug. 25, 2021, 9:43 p.m. UTC | #1
Hi Bruno,

On Fri, 2021-08-20 at 20:00 -0300, Bruno Meneguele wrote:
> The default hash algorithm for evmctl is today hardcoded libimaevm.c file.
> To facilitate different distributions and users to set their own default
> hash algorithm this patch adds the --with-default-hash=<algo> option to the
> configuration script.
> 
> The algorithm chosen by the user will then be checked if is available in the
> kernel, otherwise IMA won't be able to verify files hashed by the user. For
> that, the file exposed by the kernel crypto API (/proc/crypto) is filtered
> by an AWK script in order to check the algorithm's name and the module
> providing it. Initally, only "module: kernel" is accepted, following IMA's
> CONFIG_CRYPTO_SHA1/SHA256 dependency.

There's a difference between preventing an evmctl user from
unintentionally using an unsupported algorithm and the distro, or
whoever is building the package, defining the wrong default hash
algorithm.

My preference would be to allow any hash algorithm defined in
hash_info.h (kernel_headers package) as the default.

thanks,

Mimi
Bruno Meneguele Aug. 26, 2021, 1:35 p.m. UTC | #2
On Wed, Aug 25, 2021 at 05:43:50PM -0400, Mimi Zohar wrote:
> Hi Bruno,
> 
> On Fri, 2021-08-20 at 20:00 -0300, Bruno Meneguele wrote:
> > The default hash algorithm for evmctl is today hardcoded libimaevm.c file.
> > To facilitate different distributions and users to set their own default
> > hash algorithm this patch adds the --with-default-hash=<algo> option to the
> > configuration script.
> > 
> > The algorithm chosen by the user will then be checked if is available in the
> > kernel, otherwise IMA won't be able to verify files hashed by the user. For
> > that, the file exposed by the kernel crypto API (/proc/crypto) is filtered
> > by an AWK script in order to check the algorithm's name and the module
> > providing it. Initally, only "module: kernel" is accepted, following IMA's
> > CONFIG_CRYPTO_SHA1/SHA256 dependency.
> 
> There's a difference between preventing an evmctl user from
> unintentionally using an unsupported algorithm and the distro, or
> whoever is building the package, defining the wrong default hash
> algorithm.
> 
> My preference would be to allow any hash algorithm defined in
> hash_info.h (kernel_headers package) as the default.
> 

Good point. Considering we already depend on the kernel-headers pkg and
we also allow the user to specify a custom path for headers, it's indeed
better to keep the consistency.

I'll prepare a v5 using the kernel-headers instead of /proc/crypto.

> thanks,
> 
> Mimi
>
diff mbox series

Patch

diff --git a/README b/README
index 87cd3b5cd7da..4e35826cd982 100644
--- a/README
+++ b/README
@@ -41,7 +41,7 @@  COMMANDS
 OPTIONS
 -------
 
-  -a, --hashalgo     sha1 (default), sha224, sha256, sha384, sha512
+  -a, --hashalgo     sha1, sha224, sha256, sha384, sha512
   -s, --imasig       make IMA signature
   -d, --imahash      make IMA hash
   -f, --sigfile      store IMA signature in .sig file instead of xattr
diff --git a/configure.ac b/configure.ac
index a2d91b3db202..1c45f7f757ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,6 +62,7 @@  else
 fi
 
 EVMCTL_MANPAGE_DOCBOOK_XSL
+AX_DEFAULT_HASH_ALGO
 
 # for gcov
 #CFLAGS="$CFLAGS -Wall -fprofile-arcs -ftest-coverage"
diff --git a/m4/default-hash-algo.m4 b/m4/default-hash-algo.m4
new file mode 100644
index 000000000000..a0b98e645fb1
--- /dev/null
+++ b/m4/default-hash-algo.m4
@@ -0,0 +1,46 @@ 
+dnl Copyright (c) 2021 Bruno Meneguele <bmeneg@redhat.com>
+dnl Check hash algorithm availability in the kernel
+
+AC_DEFUN([AX_DEFAULT_HASH_ALGO], [
+	CRYPTO_FILE="/proc/crypto"
+
+	AC_ARG_WITH([default_hash],
+		AS_HELP_STRING([--with-default-hash=ALGORITHM], [specifies the default hash algorithm to be used]),
+		[HASH_ALGO=$withval],
+		[HASH_ALGO=sha1])
+
+	AC_CHECK_FILE([$CRYPTO_FILE],
+		[HAVE_CRYPTO_FILE=yes],
+		[AC_MSG_WARN([$CRYPTO_FILE file not found.])])
+
+	if test "x$HAVE_CRYPTO_FILE" = "x"; then
+		AC_MSG_RESULT([using $HASH_ALGO algorithm as default hash algorith])
+		AC_DEFINE_UNQUOTED(DEFAULT_HASH_ALGO, "$HASH_ALGO", [Define default hash algorithm])
+	else
+		awk_script=$(cat <<-'EOF'
+			/^$/ { have_name = 0 }
+			/^name.*/ {
+				if ($3 == hashalgo) {
+					have_name = 1
+				}
+			}
+			/^module.*/ {
+				if (have_name && $3 == "kernel") {
+					exit 1
+				}
+			}
+		EOF
+		)
+
+		AC_PROG_AWK()
+		$AWK -v hashalgo=$HASH_ALGO '$awk_script' $CRYPTO_FILE &>/dev/null
+		have_hash=$?
+
+		if test "x$have_hash" = "x"; then
+			AC_MSG_ERROR([$HASH_ALGO algorithm specified, but not provided by the kernel], 1)
+		else
+			AC_MSG_NOTICE([using $HASH_ALGO as default hash algorithm])
+			AC_DEFINE_UNQUOTED(DEFAULT_HASH_ALGO, "$HASH_ALGO", [Define default hash algorithm])
+		fi
+	fi
+])
diff --git a/src/evmctl.c b/src/evmctl.c
index c999589943aa..d9385a225e88 100644
--- a/src/evmctl.c
+++ b/src/evmctl.c
@@ -2500,7 +2500,7 @@  static void usage(void)
 
 	printf(
 		"\n"
-		"  -a, --hashalgo     sha1 (default), sha224, sha256, sha384, sha512, streebog256, streebog512\n"
+		"  -a, --hashalgo     sha1, sha224, sha256, sha384, sha512, streebog256, streebog512 (default: %s)\n"
 		"  -s, --imasig       make IMA signature\n"
 		"  -d, --imahash      make IMA hash\n"
 		"  -f, --sigfile      store IMA signature in .sig file instead of xattr\n"
@@ -2534,7 +2534,7 @@  static void usage(void)
 		"      --ignore-violations ignore ToMToU measurement violations\n"
 		"  -v                 increase verbosity level\n"
 		"  -h, --help         display this help and exit\n"
-		"\n");
+		"\n", DEFAULT_HASH_ALGO);
 }
 
 struct command cmds[] = {
diff --git a/src/imaevm.h b/src/imaevm.h
index 491f136c105f..cc3dfd2e9163 100644
--- a/src/imaevm.h
+++ b/src/imaevm.h
@@ -74,6 +74,10 @@ 
 #define log_err(fmt, args...)		do_log(LOG_ERR, fmt, ##args)
 #define log_errno(fmt, args...)		do_log(LOG_ERR, fmt ": errno: %s (%d)\n", ##args, strerror(errno), errno)
 
+#ifndef DEFAULT_HASH_ALGO
+#define DEFAULT_HASH_ALGO "sha1"
+#endif
+
 #define	DATA_SIZE	4096
 #define SHA1_HASH_LEN   20
 
diff --git a/src/libimaevm.c b/src/libimaevm.c
index 8e9615796153..2555e58a873b 100644
--- a/src/libimaevm.c
+++ b/src/libimaevm.c
@@ -88,7 +88,7 @@  static const char *const pkey_hash_algo_kern[PKEY_HASH__LAST] = {
 struct libimaevm_params imaevm_params = {
 	.verbose = LOG_INFO,
 	.x509 = 1,
-	.hash_algo = "sha1",
+	.hash_algo = DEFAULT_HASH_ALGO,
 };
 
 static void __attribute__ ((constructor)) libinit(void);