diff options
Diffstat (limited to 'modules.d/98integrity/evm-enable.sh')
-rwxr-xr-x | modules.d/98integrity/evm-enable.sh | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/modules.d/98integrity/evm-enable.sh b/modules.d/98integrity/evm-enable.sh new file mode 100755 index 0000000..fbae5f3 --- /dev/null +++ b/modules.d/98integrity/evm-enable.sh @@ -0,0 +1,169 @@ +#!/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> + +EVMSECFILE="${SECURITYFSDIR}/evm" +EVMCONFIG="${NEWROOT}/etc/sysconfig/evm" +EVMKEYDESC="evm-key" +EVMKEYTYPE="encrypted" +EVMKEYID="" +EVM_ACTIVATION_BITS=0 + +# The following variables can be set in /etc/sysconfig/evm: +# EVMKEY: path to the symmetric key; defaults to /etc/keys/evm-trusted.blob +# EVMKEYDESC: Description of the symmetric key; default is 'evm-key' +# EVMKEYTYPE: Type of the symmetric key; default is 'encrypted' +# EVMX509: path to x509 cert; default is /etc/keys/x509_evm.der +# EVM_ACTIVATION_BITS: additional EVM activation bits, such as +# EVM_SETUP_COMPLETE; default is 0 +# EVMKEYSDIR: Directory with more x509 certs; default is /etc/keys/evm/ + +load_evm_key() { + # read the configuration from the config file + # shellcheck disable=SC1090 + [ -f "${EVMCONFIG}" ] \ + && . "${EVMCONFIG}" + + # override the EVM key path name from the 'evmkey=' parameter in the kernel + # command line + if EVMKEYARG=$(getarg evmkey=); then + EVMKEY=${EVMKEYARG} + fi + + # 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 + if [ "${RD_DEBUG}" = "yes" ]; then + info "integrity: EVM encrypted key file not found: ${EVMKEYPATH}" + fi + return 1 + fi + + # read the EVM encrypted key blob + read -r KEYBLOB < "${EVMKEYPATH}" + + # load the EVM encrypted key + if ! EVMKEYID=$(keyctl add ${EVMKEYTYPE} ${EVMKEYDESC} "load ${KEYBLOB}" @u); then + info "integrity: failed to load the EVM encrypted key: ${EVMKEYDESC}" + return 1 + fi + return 0 +} + +load_evm_x509() { + info "Load EVM IMA X509" + + # override the EVM key path name from the 'evmx509=' parameter in + # the kernel command line + if EVMX509ARG=$(getarg evmx509=); then + EVMX509=${EVMX509ARG} + fi + + # 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 + EVMX509PATH="" + fi + + local evm_pubid line + if line=$(keyctl describe %keyring:.evm); then + # the kernel already setup a trusted .evm keyring so use that one + evm_pubid=${line%%:*} + else + # look for an existing regular keyring + evm_pubid=$(keyctl search @u keyring _evm) + if [ -z "${evm_pubid}" ]; then + # create a new regular _evm keyring + evm_pubid=$(keyctl newring _evm @u) + fi + fi + + if [ -z "${EVMKEYSDIR}" ]; then + EVMKEYSDIR="/etc/keys/evm" + fi + # load the default EVM public key onto the EVM keyring along + # with all the other ones in $EVMKEYSDIR + local key_imported=1 + for PUBKEY in ${EVMX509PATH} "${NEWROOT}${EVMKEYSDIR}"/*; do + if [ ! -f "${PUBKEY}" ]; then + if [ "${RD_DEBUG}" = "yes" ]; then + info "integrity: EVM x509 cert file not found: ${PUBKEY}" + fi + continue + fi + if ! evmctl import "${PUBKEY}" "${evm_pubid}"; then + info "integrity: failed to load the EVM X509 cert ${PUBKEY}" + return 1 + fi + key_imported=0 + done + + if [ "${RD_DEBUG}" = "yes" ]; then + keyctl show @u + fi + + return ${key_imported} +} + +unload_evm_key() { + # unlink the EVM encrypted key + keyctl unlink "${EVMKEYID}" @u || { + info "integrity: failed to unlink the EVM encrypted key: ${EVMKEYDESC}" + return 1 + } + + return 0 +} + +enable_evm() { + # check kernel support for EVM + if [ ! -e "${EVMSECFILE}" ]; then + if [ "${RD_DEBUG}" = "yes" ]; then + info "integrity: EVM kernel support is disabled" + fi + return 0 + fi + + local evm_configured=0 + local EVM_INIT_HMAC=1 EVM_INIT_X509=2 + + # try to load the EVM encrypted key + load_evm_key && evm_configured=${EVM_INIT_HMAC} + + # try to load the EVM public key + load_evm_x509 && evm_configured=$((evm_configured | EVM_INIT_X509)) + + # only enable EVM if a key or x509 certificate could be loaded + if [ $evm_configured -eq 0 ]; then + return 1 + fi + + # initialize EVM + info "Enabling EVM" + echo $((evm_configured | EVM_ACTIVATION_BITS)) > "${EVMSECFILE}" + + if [ "$((evm_configured & EVM_INIT_HMAC))" -ne 0 ]; then + # unload the EVM encrypted key + unload_evm_key || return 1 + fi + + return 0 +} + +enable_evm |