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

Bug#850339: initramfs-tools: Support Linux Integrity



Package: initramfs-tools
Version: 0.103ubuntu4.3
Severity: wishlist

Linux implements the Integrity Measurement Architecture (IMA) and the Extended
Verfication Module (EVM).

IMA measures application and libraries as they are started and, using a policy,
it can also verify the signatures associated with the applications and
libraries. For this to work the operating system has load a policy and keys
into the kernel. This should be done when the system is booted.

EVM protects file metadata against offline tampering. It does this by signing
(HMAC, public key signature) file attributes. For this to work the operating
system has to load the key used for verfication and signing into the kernel.
This should be done when the system is booted.



-- Package-specific info:
-- initramfs sizes
-- /proc/cmdline
BOOT_IMAGE=/vmlinuz-4.2.0-18-generic root=/dev/mapper/sbct--5--vg-root ro

-- resume
RESUME=/dev/mapper/sbct--5--vg-swap_1
-- /proc/filesystems
	ext3
	ext2
	ext4
	vfat
	fuseblk
	btrfs

-- lsmod
Module                  Size  Used by
binfmt_misc            20480  1 
xt_recent              20480  0 
xt_nat                 16384  1 
veth                   16384  0 
ipt_MASQUERADE         16384  21 
nf_nat_masquerade_ipv4    16384  1 ipt_MASQUERADE
iptable_nat            16384  1 
nf_nat_ipv4            16384  1 iptable_nat
br_netfilter           24576  0 
bridge                114688  1 br_netfilter
stp                    16384  1 bridge
llc                    16384  2 stp,bridge
pci_stub               16384  1 
vboxpci                24576  0 
vboxnetadp             28672  0 
vboxnetflt             28672  0 
vboxdrv               413696  3 vboxnetadp,vboxnetflt,vboxpci
cmac                   16384  0 
rmd160                 20480  0 
dm_thin_pool           61440  3 
dm_persistent_data     65536  1 dm_thin_pool
dm_bio_prison          16384  1 dm_thin_pool
dm_bufio               28672  1 dm_persistent_data
libcrc32c              16384  1 dm_persistent_data
joydev                 20480  0 
xfrm_user              32768  2 
ah6                    20480  0 
ah4                    16384  0 
esp6                   20480  0 
esp4                   20480  0 
xfrm4_mode_beet        16384  0 
xfrm4_tunnel           16384  0 
tunnel4                16384  1 xfrm4_tunnel
xfrm4_mode_tunnel      16384  0 
xfrm4_mode_transport    16384  0 
xfrm6_mode_transport    16384  0 
xfrm6_mode_ro          16384  0 
xfrm6_mode_beet        16384  0 
xfrm6_mode_tunnel      16384  0 
ipcomp                 16384  0 
ipcomp6                16384  0 
xfrm6_tunnel           16384  1 ipcomp6
tunnel6                16384  1 xfrm6_tunnel
xfrm_ipcomp            16384  2 ipcomp,ipcomp6
af_key                 36864  0 
xfrm_algo              16384  7 ah4,ah6,esp4,esp6,af_key,xfrm_user,xfrm_ipcomp
camellia_generic       32768  0 
camellia_x86_64        53248  0 
cast6_generic          24576  0 
cast5_generic          24576  0 
cast_common            16384  2 cast5_generic,cast6_generic
deflate                16384  0 
cts                    16384  0 
ctr                    16384  0 
gcm                    20480  0 
crypto_null            16384  1 gcm
ccm                    20480  0 
serpent_sse2_x86_64    53248  0 
serpent_generic        32768  1 serpent_sse2_x86_64
blowfish_generic       16384  0 
blowfish_x86_64        24576  0 
blowfish_common        20480  2 blowfish_generic,blowfish_x86_64
twofish_generic        20480  0 
twofish_x86_64_3way    28672  0 
xts                    16384  3 camellia_x86_64,serpent_sse2_x86_64,twofish_x86_64_3way
twofish_x86_64         16384  1 twofish_x86_64_3way
twofish_common         24576  3 twofish_generic,twofish_x86_64_3way,twofish_x86_64
xcbc                   16384  0 
sha256_ssse3           24576  0 
sha512_ssse3           45056  0 
des_generic            24576  0 
ip6t_REJECT            16384  1 
nf_reject_ipv6         16384  1 ip6t_REJECT
nf_log_ipv6            16384  5 
xt_hl                  16384  6 
ip6t_rt                16384  3 
nf_conntrack_ipv6      20480  8 
nf_defrag_ipv6         36864  1 nf_conntrack_ipv6
ipt_REJECT             16384  1 
nf_reject_ipv4         16384  1 ipt_REJECT
nf_log_ipv4            16384  5 
nf_log_common          16384  2 nf_log_ipv4,nf_log_ipv6
xt_LOG                 16384  10 
xt_limit               16384  13 
xt_tcpudp              16384  30 
xt_addrtype            16384  6 
nf_conntrack_ipv4      16384  28 
nf_defrag_ipv4         16384  1 nf_conntrack_ipv4
xt_conntrack           16384  35 
ip6table_filter        16384  1 
ip6_tables             28672  1 ip6table_filter
cdc_ether              16384  0 
usbnet                 40960  1 cdc_ether
input_leds             16384  0 
mii                    16384  1 usbnet
nf_conntrack_netbios_ns    16384  0 
nf_conntrack_broadcast    16384  1 nf_conntrack_netbios_ns
nf_nat_ftp             16384  0 
nf_nat                 24576  4 nf_nat_ftp,nf_nat_ipv4,xt_nat,nf_nat_masquerade_ipv4
nf_conntrack_ftp       24576  1 nf_nat_ftp
nf_conntrack          106496  10 nf_nat_ftp,nf_conntrack_netbios_ns,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_broadcast,nf_conntrack_ftp,nf_conntrack_ipv4,nf_conntrack_ipv6
ipmi_ssif              24576  0 
iptable_filter         16384  1 
ip_tables              28672  2 iptable_filter,iptable_nat
x_tables               36864  16 ip6table_filter,xt_hl,xt_recent,ip_tables,xt_tcpudp,ipt_MASQUERADE,xt_limit,xt_conntrack,xt_LOG,xt_nat,iptable_filter,ip6t_rt,ipt_REJECT,ip6_tables,xt_addrtype,ip6t_REJECT
ipmi_devintf           20480  0 
gpio_ich               16384  0 
intel_powerclamp       16384  0 
coretemp               16384  0 
kvm_intel             163840  0 
kvm                   503808  1 kvm_intel
crct10dif_pclmul       16384  0 
crc32_pclmul           16384  0 
ghash_clmulni_intel    16384  0 
aesni_intel           167936  0 
aes_x86_64             20480  1 aesni_intel
lrw                    16384  4 camellia_x86_64,serpent_sse2_x86_64,aesni_intel,twofish_x86_64_3way
gf128mul               16384  2 lrw,xts
ipmi_si                57344  0 
glue_helper            16384  4 camellia_x86_64,serpent_sse2_x86_64,aesni_intel,twofish_x86_64_3way
ablk_helper            16384  2 serpent_sse2_x86_64,aesni_intel
cryptd                 20480  3 ghash_clmulni_intel,aesni_intel,ablk_helper
serio_raw              16384  0 
ipmi_msghandler        49152  3 ipmi_ssif,ipmi_devintf,ipmi_si
8250_fintek            16384  0 
i7core_edac            24576  0 
mac_hid                16384  0 
ioatdma                65536  0 
edac_core              53248  2 i7core_edac
lpc_ich                24576  0 
shpchp                 36864  0 
dca                    16384  1 ioatdma
i5500_temp             16384  0 
bnep                   20480  2 
rfcomm                 69632  0 
bluetooth             512000  10 bnep,rfcomm
parport_pc             32768  0 
ppdev                  20480  0 
lp                     20480  0 
parport                49152  3 lp,ppdev,parport_pc
nls_iso8859_1          16384  1 
btrfs                 950272  0 
xor                    24576  1 btrfs
raid6_pq              102400  1 btrfs
ums_cypress            16384  0 
uas                    24576  0 
usb_storage            69632  2 uas,ums_cypress
hid_generic            16384  0 
usbhid                 49152  0 
mptsas                 61440  3 
psmouse               126976  0 
hid                   118784  2 hid_generic,usbhid
mptscsih               40960  1 mptsas
mptbase                98304  2 mptsas,mptscsih
bnx2                   81920  0 
scsi_transport_sas     45056  1 mptsas

-- /etc/initramfs-tools/modules

-- /etc/kernel-img.conf
# Kernel image management overrides
# See kernel-img.conf(5) for details
do_symlinks = yes
do_bootloader = no
do_initrd = yes
link_in_boot = no

-- /etc/initramfs-tools/initramfs.conf
MODULES=most
BUSYBOX=y
COMPCACHE_SIZE=""
COMPRESS=gzip
BOOT=local
DEVICE=
NFSROOT=auto

-- /etc/initramfs-tools/update-initramfs.conf
update_initramfs=yes
backup_initramfs=no

-- /proc/mdstat
Personalities : 
unused devices: <none>

-- mkinitramfs hooks
/etc/initramfs-tools/hooks/:

/usr/share/initramfs-tools/hooks:
biosdevname
btrfs
busybox
compcache
console_setup
dmsetup
fixrtc
framebuffer
fuse
kbd
klibc
kmod
lvm2
mountall
ntfs_3g
plymouth
thermal
udev
watershed


-- System Information:
Debian Release: jessie/sid
  APT prefers trusty-updates
  APT policy: (500, 'trusty-updates'), (500, 'trusty-security'), (500, 'trusty-proposed'), (500, 'trusty'), (100, 'trusty-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.2.0-18-generic (SMP w/16 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages initramfs-tools depends on:
ii  busybox-initramfs    1:1.21.0-1ubuntu1
ii  cpio                 2.11+dfsg-1ubuntu1.2
ii  findutils            4.4.2-7
ii  initramfs-tools-bin  0.103ubuntu4.3
ii  klibc-utils          2.0.3-0ubuntu1.14.04.1
ii  module-init-tools    15-0ubuntu6
ii  udev                 204-5ubuntu20.19
ii  util-linux           2.20.1-5.1ubuntu20.7

initramfs-tools recommends no packages.

Versions of packages initramfs-tools suggests:
ii  bash-completion  1:2.1-4ubuntu0.2

-- no debconf information
>From 2cc02716745722b9ddf7ab849293034fea9cd424 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@us.ibm.com>
Date: Thu, 5 Jan 2017 13:57:55 -0500
Subject: [PATCH 1/3] initramfs-tools: add script for loading kernel masterkey

We are adding a script for loading the kernel master key,
which is a symmetric key that is used to decrypt other keys
in the system. The kernel master key can either be a trusted
or a user key.

A config file /etc/default/masterkey allows to configure
the type of key and its location. By default it is expected
to be found under /etc/keys/kmk-trusted.blob.

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

diff --git a/hooks/masterkey b/hooks/masterkey
new file mode 100755
index 0000000..b32a936
--- /dev/null
+++ b/hooks/masterkey
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+PREREQ=""
+
+prereqs()
+{
+	echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+copy_exec /bin/keyctl
+copy_exec /bin/uname
diff --git a/scripts/init-top/masterkey b/scripts/init-top/masterkey
new file mode 100755
index 0000000..62f4cdf
--- /dev/null
+++ b/scripts/init-top/masterkey
@@ -0,0 +1,105 @@
+#!/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 97masterkey/masterkey.sh
+#
+PREREQ=""
+
+prereqs()
+{
+	echo "$PREREQ"
+}
+
+case $1 in
+# get pre-requisites
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /scripts/functions
+
+NEWROOT="${rootmnt}"
+MASTERKEYSCONFIG="${NEWROOT}/etc/default/masterkey"
+MULTIKERNELMODE="NO"
+PCRLOCKNUM=11
+
+getarg()
+{
+	att=$1
+
+	sed -n 's/.*'${att}'\([^ ]\+\).*/\1/p' /proc/cmdline
+}
+
+load_masterkey()
+{
+	# read the configuration from the config file
+	[ -f "${MASTERKEYSCONFIG}" ] && \
+		. ${MASTERKEYSCONFIG}
+
+	# override the kernel master key path name from the 'masterkey=' parameter
+	# in the kernel command line
+	MASTERKEYARG=$(getarg masterkey=)
+	[ -n "${MASTERKEYARG}" ] && \
+		MASTERKEY=${MASTERKEYARG}
+
+	# override the kernel master key type from the 'masterkeytype=' parameter
+	# in the kernel command line
+	MASTERKEYTYPEARG=$(getarg masterkeytype=)
+	[ -n "${MASTERKEYTYPEARG}" ] &&  \
+		MASTERKEYTYPE=${MASTERKEYTYPEARG}
+
+	# set default values
+	[ -z "${MASTERKEYTYPE}" ] && \
+		MASTERKEYTYPE="trusted"
+
+	if [ -z "${MASTERKEY}" ]; then
+		# append the kernel version to the default masterkey path name
+		# if MULTIKERNELMODE is set to YES
+		if [ "${MULTIKERNELMODE}" = "YES" ]; then
+			MASTERKEY="/etc/keys/kmk-${MASTERKEYTYPE}-$(uname -r).blob"
+		else
+			MASTERKEY="/etc/keys/kmk-${MASTERKEYTYPE}.blob"
+		fi
+	fi
+
+	# set the kernel master key path name
+	MASTERKEYPATH="${NEWROOT}${MASTERKEY}"
+
+	# check for kernel master key's existence
+	if [ ! -f "${MASTERKEYPATH}" ]; then
+		[ "$quiet" != "y" ] && _log_msg "masterkey: kernel master key file not found: ${MASTERKEYPATH}\n"
+		return 1
+	fi
+
+	# read the kernel master key blob
+	KEYBLOB=$(cat ${MASTERKEYPATH})
+
+	# add the 'load' prefix if the key type is 'trusted'
+	[ "${MASTERKEYTYPE}" = "trusted" ] && \
+		KEYBLOB="load ${KEYBLOB} pcrlock=${PCRLOCKNUM}"
+
+	# load the kernel master key
+	_log_msg "masterkey: Loading the kernel master key\n"
+	keyctl add "${MASTERKEYTYPE}" "kmk-${MASTERKEYTYPE}" "${KEYBLOB}" @u >/dev/null
+	if [ $? -ne 0 ]; then
+		_log_msg "masterkey: failed to load the kernel master key: kmk-${MASTERKEYTYPE}\n"
+		return 1
+	fi
+
+	_log_msg "masterkey: Loaded masterkey ${MASTERKEYPATH}\n"
+
+	return 0
+}
+
+load_masterkey
-- 
1.9.1

>From 93936ac494d01c65ae0cf5a1e0811b6812ab6e53 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@us.ibm.com>
Date: Thu, 5 Jan 2017 14:09:55 -0500
Subject: [PATCH 2/3] initramfs-tools: Add script for loading EVM key

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
-- 
1.9.1

>From a1d85cb2fafa2a3b6ebecd32e3325ac2c7108360 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@us.ibm.com>
Date: Thu, 5 Jan 2017 14:35:14 -0500
Subject: [PATCH 3/3] initramfs-tools: Add scripts for loading IMA keys and
 policy

Add a script for loading certificates used by the Linux Integrity
Measurement Architecture (IMA) for verifying file signatures. The
script will first look for the availability of the .ima keyring
and load all keys it finds on it. If the .ima keyring is not
available, it will try using _ima. The difference between .ima and
_ima is that certificates loaded onto the .ima keyring must have
been signed by a CA known to the kernel, whereas _ima accepts plain
public keys.

Add a script for loading the IMA policy. A configuration file
can be provided in /etc/default/ima where the location of the
policy can be set. The default location is /etc/default/ima-policy.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 hooks/ima                        | 22 +++++++++++
 scripts/init-top/ima-keys-load   | 80 ++++++++++++++++++++++++++++++++++++++++
 scripts/init-top/ima-policy-load | 70 +++++++++++++++++++++++++++++++++++
 3 files changed, 172 insertions(+)
 create mode 100755 hooks/ima
 create mode 100755 scripts/init-top/ima-keys-load
 create mode 100755 scripts/init-top/ima-policy-load

diff --git a/hooks/ima b/hooks/ima
new file mode 100755
index 0000000..3284707
--- /dev/null
+++ b/hooks/ima
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+PREREQ=""
+
+prereqs()
+{
+	echo "$PREREQ"
+}
+
+case $1 in
+prereqs)
+	prereqs
+	exit 0
+	;;
+esac
+
+. /usr/share/initramfs-tools/hook-functions
+copy_exec /usr/bin/evmctl
+copy_exec /bin/findmnt
+copy_exec /bin/keyctl
+copy_exec /bin/mount
+copy_exec /bin/ls
diff --git a/scripts/init-top/ima-keys-load b/scripts/init-top/ima-keys-load
new file mode 100755
index 0000000..e007d57
--- /dev/null
+++ b/scripts/init-top/ima-keys-load
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+# (c) Copyright IBM Corporation 2015, 2016, 2017
+#
+# Mimi Zohar <zohar@linux.vnet.ibm.com>
+# Stefan Berger <stefanb@linux.vnet.ibm.com>
+#
+# This file has been derived from Dracut's 98integrity/ima-keys-load.sh
+#
+
+PREREQ=""
+
+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}"
+IMASECDIR="${SECURITYFSDIR}/ima"
+IMACONFIG="${NEWROOT}/etc/default/ima"
+
+load_x509_keys()
+{
+	KEYRING_ID=$1
+
+	# override the default configuration
+	if [ -f "${IMACONFIG}" ]; then
+		. ${IMACONFIG}
+	fi
+
+	if [ -z "${IMAKEYDIR}" ]; then
+		IMAKEYSDIR="/etc/keys/ima"
+	fi
+
+	PUBKEY_LIST=`ls ${NEWROOT}${IMAKEYSDIR}/*`
+	for PUBKEY in ${PUBKEY_LIST}; do
+		X509ID=$(evmctl import ${PUBKEY} ${KEYRING_ID} 2>/dev/null)
+		[ $? -ne 0 ] && _log_msg "integrity: IMA x509 cert not loaded on keyring: ${PUBKEY}\n"
+	done
+
+	[ "$quiet" != "y" ] && keyctl show  ${KEYRING_ID}
+
+	return 0
+}
+
+# check kernel support for IMA
+if [ ! -e "${IMASECDIR}" ]; then
+	[ "$quiet" != "y" ] && _log_msg "integrity: IMA kernel support is disabled\n"
+	return 0
+fi
+
+# get the .ima keyring id
+line="$(sed -n 's/\([^ ]\+\).*keyring\s\+\.ima:.*/\1/p' /proc/keys)"
+if [ -n "$line" ]; then
+	_ima_id=$(printf "%d" "0x$line")
+else
+	_ima_id=`keyctl search @u keyring _ima`
+	if [ -z "${_ima_id}" ]; then
+		_ima_id=`keyctl newring _ima @u`
+	fi
+fi
+
+# load the IMA public key(s)
+load_x509_keys ${_ima_id}
diff --git a/scripts/init-top/ima-policy-load b/scripts/init-top/ima-policy-load
new file mode 100755
index 0000000..4965db4
--- /dev/null
+++ b/scripts/init-top/ima-policy-load
@@ -0,0 +1,70 @@
+#!/bin/sh
+#
+# Licensed under the GPLv2
+#
+# Copyright (C) 2010 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/ima-policy-load.sh
+#
+
+PREREQ=""
+
+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}"
+IMASECDIR="${SECURITYFSDIR}/ima"
+IMACONFIG="${NEWROOT}/etc/default/ima"
+IMAPOLICY="/etc/default/ima-policy"
+
+load_ima_policy()
+{
+	# check kernel support for IMA
+	if [ ! -e "${IMASECDIR}" ]; then
+		[ "$quiet" != "y" ] && _log_msg "integrity: IMA kernel support is disabled\n"
+		return 0
+	fi
+
+	# override the default configuration
+	[ -f "${IMACONFIG}" ] && \
+		. ${IMACONFIG}
+
+	# set the IMA policy path name
+	IMAPOLICYPATH="${NEWROOT}${IMAPOLICY}"
+
+	# check the existence of the IMA policy file
+	if [ -f "${IMAPOLICYPATH}" ]; then
+		echo -n "${IMAPOLICYPATH}" > ${IMASECDIR}/policy || \
+			cat "${IMAPOLICYPATH}" > ${IMASECDIR}/policy
+		[ $? -ne 0 ] && _log_msg "integrity: Failed to load IMA policy\n" \
+			     || _log_msg "integrity: Loaded IMA policy\n"
+	fi
+
+	return 0
+}
+
+load_ima_policy
-- 
1.9.1


Reply to: