You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
4.8 KiB
166 lines
4.8 KiB
#!/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' |
|
# EMX509: 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 |
|
|
|
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 |
|
KEYBLOB=$(cat "${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 |
|
if [ "${RD_DEBUG}" = "yes" ]; then |
|
info "integrity: EVM x509 cert file not found: ${EVMX509PATH}" |
|
fi |
|
return 1 |
|
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 |
|
|
|
# load the EVM public key onto the EVM keyring |
|
# FIXME: EVMX509ID unused? |
|
# shellcheck disable=SC2034 |
|
if ! EVMX509ID=$(evmctl import "${EVMX509PATH}" "${evm_pubid}"); then |
|
info "integrity: failed to load the EVM X509 cert ${EVMX509PATH}" |
|
return 1 |
|
fi |
|
|
|
if [ "${RD_DEBUG}" = "yes" ]; then |
|
keyctl show @u |
|
fi |
|
|
|
return 0 |
|
} |
|
|
|
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 EVM_ALLOW_METADATA_WRITES=4 |
|
|
|
# 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" |
|
if [ "$((evm_configured & EVM_INIT_X509))" -ne 0 ]; then |
|
# Older kernels did not support EVM_ALLOW_METADATA_WRITES, try for |
|
# newer ones first that need it when an x509 is used |
|
echo $((evm_configured | EVM_ALLOW_METADATA_WRITES | EVM_ACTIVATION_BITS)) > "${EVMSECFILE}" \ |
|
|| echo $((evm_configured | EVM_ACTIVATION_BITS)) > "${EVMSECFILE}" |
|
else |
|
echo $((evm_configured | EVM_ACTIVATION_BITS)) > "${EVMSECFILE}" |
|
fi |
|
|
|
if [ "$((evm_configured & EVM_INIT_HMAC))" -ne 0 ]; then |
|
# unload the EVM encrypted key |
|
unload_evm_key || return 1 |
|
fi |
|
|
|
return 0 |
|
} |
|
|
|
enable_evm
|
|
|