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: