[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#850339: [PATCH 2/3] initramfs-tools: Add script for loading EVM key



From: Stefan Berger <stefanb@us.ibm.com>

Add a script for loading the EVM (extended verification module) key.
Either a symmetric key or an x.509 certificate can be loaded using the
scripts.

A config file /etc/default/evm allows to configure parameters of the
key.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hooks/evm            |  20 ++++++
 scripts/init-top/evm | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 196 insertions(+)
 create mode 100755 hooks/evm
 create mode 100755 scripts/init-top/evm

diff --git a/hooks/evm b/hooks/evm
new file mode 100755
index 0000000..0961bab
--- /dev/null
+++ b/hooks/evm
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+PREREQ="masterkey"
+
+prereqs()
+{
+	echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+copy_exec /bin/findmnt
+copy_exec /bin/keyctl
+copy_exec /usr/bin/evmctl
diff --git a/scripts/init-top/evm b/scripts/init-top/evm
new file mode 100755
index 0000000..236139b
--- /dev/null
+++ b/scripts/init-top/evm
@@ -0,0 +1,176 @@
+#!/bin/sh
+
+# Licensed under the GPLv2
+#
+# Copyright (C) 2011 Politecnico di Torino, Italy
+#                    TORSEC group -- http://security.polito.it
+# Roberto Sassu <roberto.sassu@polito.it>
+#
+#
+# (c) Copyright IBM Corporation 2016,2017
+#
+# Stefan Berger <stefanb@linux.vnet.ibm.com>
+#
+# This file has been derived from Dracut's 98integrity/evm-enable.sh
+#
+
+PREREQ="masterkey"
+
+prereqs()
+{
+	echo "$PREREQ"
+}
+
+case $1 in
+# get pre-requisites
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /scripts/functions
+
+SECURITYFSDIR=`findmnt -t securityfs -n -o TARGET`
+if  [ ! $SECURITYFSDIR ]; then
+	SECURITYFSDIR="/sys/kernel/security"
+	mount -t securityfs -o nosuid,noexec,nodev securityfs ${SECURITYFSDIR} >/dev/null 2>&1
+fi
+
+NEWROOT="${rootmnt}"
+EVMSECFILE="${SECURITYFSDIR}/evm"
+EVMCONFIG="${NEWROOT}/etc/default/evm"
+EVMKEYDESC="evm-key"
+EVMKEYTYPE="encrypted"
+EVMKEYID=""
+
+getarg()
+{
+	att=$1
+
+	sed -n 's/.*'${att}'\([^ ]\+\).*/\1/p' /proc/cmdline
+}
+
+load_evm_key()
+{
+	# read the configuration from the config file
+	[ -f "${EVMCONFIG}" ] && \
+		. ${EVMCONFIG}
+
+	# override the EVM key path name from the 'evmkey=' parameter in the kernel
+	# command line
+	EVMKEYARG=$(getarg evmkey=)
+	[ -n "${EVMKEYARG}" ] && \
+		EVMKEY=${EVMKEYARG}
+
+	# set the default value
+	[ -z "${EVMKEY}" ] && \
+		EVMKEY="/etc/keys/evm-trusted.blob";
+
+	# set the EVM key path name
+	EVMKEYPATH="${NEWROOT}${EVMKEY}"
+
+	# check for EVM encrypted key's existence
+	if [ ! -f "${EVMKEYPATH}" ]; then
+		[ "$quiet" != "y" ] && _log_msg "integrity: EVM encrypted key file not found: ${EVMKEYPATH}\n"
+		return 1
+	fi
+
+	# read the EVM encrypted key blob
+	KEYBLOB=$(cat ${EVMKEYPATH})
+
+	# load the EVM encrypted key
+	EVMKEYID=$(keyctl add ${EVMKEYTYPE} ${EVMKEYDESC} "load ${KEYBLOB}" @u)
+	[ $? -eq 0 ] || {
+		_log_msg "integrity: failed to load the EVM encrypted key: ${EVMKEYDESC}\n";
+		return 1;
+	}
+
+	_log_msg "integrity: Loaded EVM key ${EVMKEYPATH}\n"
+
+	return 0
+}
+
+load_evm_x509()
+{
+	[ "$quiet" != "y" ] && _log_msg "integrity: Load EVM IMA X509\n"
+
+	# override the EVM key path name from the 'evmx509=' parameter in
+	# the kernel command line
+	EVMX509ARG=$(getarg evmx509=)
+	[ -n "${EVMX509ARG}" ] && \
+		EVMX509=${EVMX509ARG}
+
+	# set the default value
+	[ -z "${EVMX509}" ] && \
+		EVMX509="/etc/keys/x509_evm.der";
+
+	# set the EVM public key path name
+	EVMX509PATH="${NEWROOT}${EVMX509}"
+
+	# check for EVM public key's existence
+	if [ ! -f "${EVMX509PATH}" ]; then
+		[ "$quiet" != "y" ] && _log_msg "integrity: EVM x509 cert file not found: ${EVMX509PATH}\n"
+		return 1
+	fi
+
+	# load the EVM public key onto the EVM keyring
+	line="$(sed -n 's/\([^ ]\+\).*keyring\s\+\.evm:.*/\1/p' /proc/keys)"
+	if [ -n "$line" ]; then
+		evm_pubid=$(printf "%d" "0x$line")
+	else
+		evm_pubid=`keyctl search $u keyring _evm`
+		if [ -z "${evm_pubid}" ]; then
+			evm_pubid=`keyctl newring _evm @u`
+		fi
+	fi
+	EVMX509ID=$(evmctl import ${EVMX509PATH} ${evm_pubid} 2>/dev/null)
+	if [ $? -ne 0 ]; then
+		[ "$quiet" != "y" ] && _log_msg "integrity: failed to load the EVM X509 cert ${EVMX509PATH}\n"
+		return 1
+	fi
+
+	_log_msg "integrity: Loaded EVM x509 cert ${EVMX509PATH}\n"
+
+	[ "$quiet" != "y" ] && keyctl show @u
+
+	return 0
+}
+
+unload_evm_key()
+{
+	# unlink the EVM encrypted key
+	keyctl unlink ${EVMKEYID} @u || {
+		_log_msg "integrity: failed to unlink the EVM encrypted key: ${EVMKEYDESC}\n";
+		return 1;
+	}
+
+	return 0
+}
+
+enable_evm()
+{
+	# check kernel support for EVM
+	if [ ! -e "${EVMSECFILE}" ]; then
+		[ "$quiet" != "y" ] && _log_msg "integrity: EVM kernel support is disabled\n"
+		return 0
+	fi
+
+	# load the EVM encrypted key
+	load_evm_key || return 1
+
+	# load the EVM public key, if it exists
+	load_evm_x509
+
+	# initialize EVM
+	echo 1 > ${EVMSECFILE}
+	[ $? -ne 0 ] && _log_msg "integrity: Could not enable EVM\n" \
+		     || _log_msg "integrity: Enabled EVM\n"
+
+	# unload the EVM encrypted key
+	unload_evm_key || return 1
+
+	return 0
+}
+
+enable_evm
-- 
2.8.3


Reply to: