evmctl man page

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml1…"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>evmctl</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"/></head><body><div xml:lang="en" class="refentry"><a id="idm140261592448112"/><div class="titlepage"/><div class="refnamediv"><h2>Name</h2><p>evmctl — IMA/EVM signing utility</p></div><div class="refsynopsisdiv"><a id="_synopsis"/><h2>Synopsis</h2><p>evmctl [options] <command> [OPTIONS]</p></div><div class="refsect1"><a id="_description"/><h2>DESCRIPTION</h2><p>The evmctl utility can be used for producing and verifying digital signatures, which are used by Linux kernel integrity subsystem (IMA/EVM). It can be also used to import keys into the kernel keyring.</p></div><div class="refsect1"><a id="_commands"/><h2>COMMANDS</h2><pre class="literallayout">--version help <command> import [--rsa] pubkey keyring sign [-r] [--imahash | --imasig ] [--key key] [--pass password] file verify file ima_sign [--sigfile] [--key key] [--pass password] file ima_verify file ima_hash file ima_measurement file ima_fix [-t fdsxm] path sign_hash [--key key] [--pass password] hmac [--imahash | --imasig ] file</pre></div><div class="refsect1"><a id="_options"/><h2>OPTIONS</h2><pre class="literallayout">-a, --hashalgo sha1 (default), sha224, sha256, sha384, sha512 -s, --imasig make IMA signature -d, --imahash make IMA hash -f, --sigfile store IMA signature in .sig file instead of xattr
--rsa use RSA key type and signing scheme v1 -k, --key path to signing key (default: /etc/keys/{privkey,pubkey}_evm.pem) -p, --pass password for encrypted signing key -r, --recursive recurse into directories (sign) -t, --type file types to fix 'fdsxm' (f: file, d: directory, s: block/char/symlink)
x - skip fixing if both ima and evm xattrs exist (use with caution)
m - stay on the same filesystem (like 'find -xdev') -n print result to stdout instead of setting xattr -u, --uuid use custom FS UUID for EVM (unspecified: from FS, empty: do not use)
--smack use extra SMACK xattrs for EVM
--m32 force EVM hmac/signature for 32 bit target system
--m64 force EVM hmac/signature for 64 bit target system -v increase verbosity level -h, --help display this help and exit</pre></div><div class="refsect1"><a id="_introduction"/><h2>INTRODUCTION</h2><p>Linux kernel integrity subsystem is comprised of a number of different components including the Integrity Measurement Architecture (IMA), Extended Verification Module (EVM), IMA-appraisal extension, digital signature verification extension and audit measurement log support.</p><p>The evmctl utility is used for producing and verifying digital signatures, which are used by the Linux kernel integrity subsystem. It is also used for importing keys into the kernel keyring.</p><p>Linux integrity subsystem allows to use IMA and EVM signatures. EVM signature protects file metadata, such as file attributes and extended attributes. IMA signature protects file content.</p><p>For more detailed information about integrity subsystem it is recommended to follow resources in RESOURCES section.</p></div><div class="refsect1"><a id="_evm_hmac_and_signature_metadata"/><h2>EVM HMAC and signature metadata</h2><p>EVM protects file metadata by including following attributes into HMAC and signature calculation: inode number, inode generation, UID, GID, file mode, security.selinux, security.SMACK64, security.ima, security.capability.</p><p>EVM HMAC and signature in may also include additional file and file system attributes. Currently supported additional attributes are filesystem UUID and extra SMACK extended attributes.</p><p>Kernel configuration option CONFIG_EVM_ATTR_FSUUID controls whether to include filesystem UUID into HMAC and enabled by default. Therefore evmctl also includes fsuuid by default. Providing <span class="emphasis"><em>--uuid</em></span> option without parameter allows to disable usage of fs uuid. Providing <span class="emphasis"><em>--uuid=UUID</em></span> option with parameter allows to use custom UUID.</p><p>Kernel configuration option CONFIG_EVM_EXTRA_SMACK_XATTRS controls whether to include additional SMACK extended attributes into HMAC. They are following: security.SMACK64EXEC, security.SMACK64TRANSMUTE and security.SMACK64MMAP. evmctl <span class="emphasis"><em>--smack</em></span> options enables that.</p></div><div class="refsect1"><a id="_key_and_signature_formats"/><h2>Key and signature formats</h2><p>Linux integrity subsystem supports two type of signature and respectively two key formats.</p><p>First key format (v1) is pure RSA key encoded in PEM a format and uses own signature format. It is now non-default format and requires to provide evmctl <span class="emphasis"><em>--rsa</em></span> option for signing and importing the key.</p><p>Second key format uses X509 DER encoded public key certificates and uses asymmetric key support in the kernel (since kernel 3.9). CONFIG_INTEGRITY_ASYMMETRIC_KEYS must be enabled (default).</p></div><div class="refsect1"><a id="_integrity_keyrings"/><h2>Integrity keyrings</h2><p>Integrity subsystem uses dedicated IMA/EVM keyrings to search for signature verification keys - <span class="emphasis"><em>_ima</em></span> and <span class="emphasis"><em>_evm</em></span> respectively.</p><p>Since 3.13 IMA allows to declare IMA keyring as trusted. It allows only to load keys, signed by a key from the system keyring (.system). It means self-signed keys are not allowed. This is a default behavior unless CONFIG_IMA_TRUSTED_KEYRING is undefined. IMA trusted keyring is has different name <span class="emphasis"><em>.ima</em></span>. Trusted keyring requires X509 public key certificates. Old version RSA public keys are not compatible with trusted keyring.</p></div><div class="refsect1"><a id="_generate_evm_encrypted_keys"/><h2>Generate EVM encrypted keys</h2><p>EVM encrypted key is used for EVM HMAC calculation:</p><pre class="literallayout"># create and save the key kernel master key (user type) # LMK is used to encrypt encrypted keys keyctl add user kmk "`dd if=/dev/urandom bs=1 count=32 2&gt;/dev/null`" @u keyctl pipe `keyctl search @u user kmk` &gt; /etc/keys/kmk</pre><pre class="literallayout"># create the EVM encrypted key keyctl add encrypted evm-key "new user:kmk 32" @u keyctl pipe `keyctl search @u encrypted evm-key` &gt;/etc/keys/evm-key</pre></div><div class="refsect1"><a id="_generate_evm_trusted_keys_tpm_based"/><h2>Generate EVM trusted keys (TPM based)</h2><p>Trusted EVM keys are keys which a generate with the help of TPM. They are not related to integrity trusted keys.</p><pre class="literallayout"># create and save the key kernel master key (user type) keyctl add trusted kmk "new 32" @u keyctl pipe `keyctl search @u trusted kmk` &gt;kmk</pre><pre class="literallayout"># create the EVM trusted key keyctl add encrypted evm-key "new trusted:kmk 32" @u keyctl pipe `keyctl search @u encrypted evm-key` &gt;evm-key</pre></div><div class="refsect1"><a id="_generate_signing_and_verification_keys"/><h2>Generate signing and verification keys</h2><p>Generate private key in plain text format:</p><pre class="literallayout">openssl genrsa -out privkey_evm.pem 1024</pre><p>Generate encrypted private key:</p><pre class="literallayout">openssl genrsa -des3 -out privkey_evm.pem 1024</pre><p>Make encrypted private key from unencrypted:</p><pre class="literallayout">openssl rsa -in /etc/keys/privkey_evm.pem -out privkey_evm_enc.pem -des3</pre><p>Generate self-signed X509 public key certificate and private key for using kernel asymmetric keys support:</p><pre class="literallayout">openssl req -new -nodes -utf8 -sha1 -days 36500 -batch -x509 -config x509_evm.genkey -outform DER -out x509_evm.der -keyout privkey_evm.pem</pre><p>Configuration file x509_evm.genkey:</p><pre class="literallayout"># Begining of the file [ req ] default_bits = 1024 distinguished_name = req_distinguished_name prompt = no string_mask = utf8only x509_extensions = myexts</pre><pre class="literallayout">[ req_distinguished_name ] O = Magrathea CN = Glacier signing key emailAddress = slartibartfast@magrathea.h2g2</pre><pre class="literallayout">[ myexts ] basicConstraints=critical,CA:FALSE keyUsage=digitalSignature subjectKeyIdentifier=hash authorityKeyIdentifier=keyid # EOF</pre><p>Generate public key for using RSA key format:</p><pre class="literallayout">openssl rsa -pubout -in privkey_evm.pem -out pubkey_evm.pem</pre><p>Copy keys to /etc/keys:</p><pre class="literallayout"> cp pubkey_evm.pem /etc/keys
scp pubkey_evm.pem target:/etc/keys or
cp x509_evm.pem /etc/keys
scp x509_evm.pem target:/etc/keys</pre></div><div class="refsect1"><a id="_generate_trusted_keys"/><h2>Generate trusted keys</h2><p>Generation of trusted keys is a bit more complicated process and involves following steps:</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"> Creation of local IMA certification authority (CA).
It consist of private and public key certificate which are used
to sign and verify other keys. </li><li class="listitem"> Build Linux kernel with embedded local IMA CA X509 certificate.
It is used to verify other keys added to the <span class="emphasis"><em>.ima</em></span> trusted keyring </li><li class="listitem"> Generate IMA private signing key and verification public key certificate,
which is signed using local IMA CA private key. </li></ul></div><p>Configuration file ima-local-ca.genkey:</p><pre class="literallayout"># Begining of the file [ req ] default_bits = 2048 distinguished_name = req_distinguished_name prompt = no string_mask = utf8only x509_extensions = v3_ca</pre><pre class="literallayout">[ req_distinguished_name ] O = IMA-CA CN = IMA/EVM certificate signing key emailAddress = ca@ima-ca</pre><pre class="literallayout">[ v3_ca ] basicConstraints=CA:TRUE subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer # keyUsage = cRLSign, keyCertSign # EOF</pre><p>Generate private key and X509 public key certificate:</p><pre class="literallayout">openssl req -new -x509 -utf8 -sha1 -days 3650 -batch -config $GENKEY -outform DER -out ima-local-ca.x509 -keyout ima-local-ca.priv</pre><p>Produce X509 in DER format for using while building the kernel:</p><pre class="literallayout">openssl x509 -inform DER -in ima-local-ca.x509 -out ima-local-ca.pem</pre><p>Configuration file ima.genkey:</p><pre class="literallayout"># Begining of the file [ req ] default_bits = 1024 distinguished_name = req_distinguished_name prompt = no string_mask = utf8only x509_extensions = v3_usr</pre><pre class="literallayout">[ req_distinguished_name ] O = `hostname` CN = `whoami` signing key emailAddress = `whoami`@`hostname`</pre><pre class="literallayout">[ v3_usr ] basicConstraints=critical,CA:FALSE #basicConstraints=CA:FALSE keyUsage=digitalSignature #keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid #authorityKeyIdentifier=keyid,issuer # EOF</pre><p>Generate private key and X509 public key certificate signing request:</p><pre class="literallayout">openssl req -new -nodes -utf8 -sha1 -days 365 -batch -config $GENKEY -out csr_ima.pem -keyout privkey_ima.pem</pre><p>Sign X509 public key certificate signing request with local IMA CA private key:</p><pre class="literallayout">openssl x509 -req -in csr_ima.pem -days 365 -extfile $GENKEY -extensions v3_usr -CA ima-local-ca.pem -CAkey ima-local-ca.priv -CAcreateserial -outform DER -out x509_ima.der</pre></div><div class="refsect1"><a id="_sign_file_data_and_metadata"/><h2>Sign file data and metadata</h2><p>Default key locations:</p><pre class="literallayout">Private RSA key: /etc/keys/privkey_evm.pem Public RSA key: /etc/keys/pubkey_evm.pem X509 certificate: /etc/keys/x509_evm.der</pre><p>Options to remember: <span class="emphasis"><em>-k</em></span>, <span class="emphasis"><em>-r</em></span>, <span class="emphasis"><em>--rsa</em></span>, <span class="emphasis"><em>--uuid</em></span>, <span class="emphasis"><em>--smack</em></span>.</p><p>Sign file with EVM signature and calculate hash value for IMA:</p><pre class="literallayout">evmctl sign --imahash test.txt</pre><p>Sign file with both IMA and EVM signatures:</p><pre class="literallayout">evmctl sign --imasig test.txt:</pre><p>Sign file with IMA signature:</p><pre class="literallayout">evmctl ima_sign test.txt</pre><p>Sign recursively whole filesystem:</p><pre class="literallayout">evmctl -r sign --imahash /</pre><p>Fix recursively whole filesystem:</p><pre class="literallayout">evmctl -r ima_fix /</pre><p>Sign filesystem selectively using <span class="emphasis"><em>find</em></span> command:</p><pre class="literallayout">find / ( -fstype rootfs -o -fstype ext4 -exec evmctl sign --imahash '{}' ;</pre><p>Fix filesystem selectively using <span class="emphasis"><em>find</em></span> command:</p><pre class="literallayout">find / ( -fstype rootfs -o -fstype ext4 -exec sh -c "&lt; '{}'" ;</pre></div><div class="refsect1"><a id="_initialize_ima_evm_at_early_boot"/><h2>Initialize IMA/EVM at early boot</h2><p>IMA/EVM initialization should be normally done from initial RAM file system before mounting root filesystem.</p><p>Here is Ubuntu initramfs example script (/etc/initramfs-tools/scripts/local-top/ima.sh)</p><pre class="literallayout"># mount securityfs if not mounted SECFS=/sys/kernel/security grep -q $SECFS /proc/mounts || mount -n -t securityfs securityfs $SECFS</pre><pre class="literallayout"># search for IMA trusted keyring, then for untrusted ima_id="`awk '/.ima/ { printf "%d", "0x"$1; }' /proc/keys`" if [ -z "$ima_id" ]; then
ima_id=`keyctl search @u keyring _ima 2&gt;/dev/null`
if [ -z "$ima_id" ]; then
ima_id=`keyctl newring _ima @u`
fi fi # import IMA X509 certificate evmctl import /etc/keys/x509_ima.der $ima_id</pre><pre class="literallayout"># search for EVM keyring evm_id=`keyctl search @u keyring _evm 2&gt;/dev/null` if [ -z "$evm_id" ]; then
evm_id=`keyctl newring _evm @u` fi # import EVM X509 certificate evmctl import /etc/keys/x509_evm.der $evm_id</pre><pre class="literallayout"># a) import EVM encrypted key cat /etc/keys/kmk | keyctl padd user kmk @u keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u # OR # b) import EVM trusted key keyctl add trusted kmk "load `cat /etc/keys/kmk`" @u keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u</pre><pre class="literallayout"># enable EVM echo "1" > /sys/kernel/security/evm</pre><p>Optionally it is possible also to forbid adding, removing of new public keys and certificates into keyrings and revoking keys using <span class="emphasis"><em>keyctl setperm</em></span> command:</p><pre class="literallayout"># protect EVM keyring keyctl setperm $evm_id 0x0b0b0000 # protect IMA keyring keyctl setperm $ima_id 0x0b0b0000 # protecting IMA key from revoking (against DoS) ima_key=`evmctl import /etc/keys/x509_ima.der $ima_id` keyctl setperm $ima_key 0x0b0b0000</pre><p>When using plain RSA public keys in PEM format, use <span class="emphasis"><em>evmctl import --rsa</em></span> for importing keys:</p><pre class="literallayout">evmctl import --rsa /etc/keys/pubkey_evm.pem $evm_id</pre><p>Latest version of keyctl allows to import X509 public key certificates:</p><pre class="literallayout">cat /etc/keys/x509_ima.der | keyctl padd asymmetric '' @ima_id</pre></div><div class="refsect1"><a id="_files"/><h2>FILES</h2><p>Examples of scripts to generate X509 public key certificates:</p><pre class="literallayout">/usr/share/doc/ima-evm-utils/ima-genkey-self.sh /usr/share/doc/ima-evm-utils/ima-genkey.sh /usr/share/doc/ima-evm-utils/ima-gen-local-ca.sh</pre></div><div class="refsect1"><a id="_author"/><h2>AUTHOR</h2><p>Written by Dmitry Kasatkin, <dmitry.kasatkin at gmail.com> and others.</p></div><div class="refsect1"><a id="_resources"/><h2>RESOURCES</h2><pre class="literallayout">http://sourceforge.net/p/linux-ima/wiki… http://sourceforge.net/p/linux-ima/ima-…</pre></div><div class="refsect1"><a id="_copying"/><h2>COPYING</h2><p>Copyright (C) 2012 - 2014 Linux Integrity Project. Free use of this software is granted under the terms of the GNU Public License (GPL).</p></div></div></body></html>