Tools and Examples
To generate keys use scripts in ima-evm-utils repository (directory: "examples"). To generate root CA x509 certificate use script:
When the certificate is ready copy it (file ima-local-ca.x509) to kernel source code directory. Then build the kernel. This certificate will be used to verify all keys imported to the kernel while runtime. Next use:
This scritp will generate ima x509 certificate (x509_ima.der). This certificate will be signed with ima-local-ca.x509 root CA. Keys generated in this step will be used e.g. to signed/verify policy. Copy the certificate the the device - the best place for it is: /etc/keys/x509_ima.der.
Loading keys to the kernel
After runnig the device you can cat /proc/keys file which gives you:
# cat /proc/keys 0912593f I------ 1 perm 1f0b0000 0 0 keyring .system_keyring: 1 1078d463 I------ 1 perm 1f030000 0 0 keyring .dns_resolver: empty 134a4d0c I------ 1 perm 1f030000 0 0 asymmetri IMA-CA: IMA/EVM certificate signing key: fe790d339e2c213e9b76714fe912fcabc80618ae: X509.RSA c80618ae  1fc6b440 I--Q--- 1 perm 1f3f0000 0 65534 keyring _uid_ses.0: 1 226b9803 I------ 1 perm 1f0f0000 0 0 keyring .ima: empty 23fb3e44 I--Q--- 3 perm 1f3f0000 0 65534 keyring _uid.0: empty 2cf51b46 I--Q--- 7 perm 3f030000 0 0 keyring _ses: 1 2ede7cde I------ 1 perm 1f030000 0 0 keyring .id_resolver: empty
Now you can use command:
# evmctl import /path/to/certificate/x509_ima.der 0x226b9803 299972270
Notice that 226b9803 is .ima keyring ID in hex (old version od evmctl may not support hex values - then you have to convert it to decimal). In response you get ID of key impored to the kernel. You can display imported key using cat /proc/keys, or using keyctrl tool:
# keyctl show 0x226b9803 Keyring 577476611 --alswrv 0 0 keyring: .ima 299972270 --als--v 0 0 \_ asymmetric: Desktop: developer signing key: ea0d15728b3c952f63043cace6f35bff0188eff4
The best way to load the key into the .ima keyring at startup is to enable IMA_LOAD_X509 option in kernel .config ("Load X509 certificate to the '.ima' trusted keyring"), and add path to the certificate to IMA_X509_PATH variable. The default path is /etc/ima/x509_ima.der.
To load the policy it must be signed with key from .ima keyring. Let say that policy is stored in /home/user/policy file. To sign it you should use command:
evmctl ima_sign -f -k /path/to/ima_private_key.pem /home/user/policy
This command will generate policy.sig file which contains signature. File policy.sig is created in the same directory. Next you can load the policy to the kernel using command:
echo "/home/user/policy" > /sys/kernel/security/ima/policy
Kernel takes path to policy as a param, and next try to load a file with the same name and .sig extension as a signature (/home/user/policy.sig in our example). Then verify it and loads it if verification succeed. There should be no message on success. You can check the currently loaded policy by:
The policy is effective just right after load. Notice that the policy will be changed even if IMA is in disable mode.
On system start the build-in kernel policy is effective. After start kernel tries to load a new policy from /etc/ima/policy (signature should be placed in /etc/ima/policy.sig).
To label file with ima signature instead of ima hash you should use command:
evmctl ima_sign -k /path/to/ima_private_key.pem /path/to/file
This is the same commad as before - the only different is -f param. If the -f is used then signature is stored in file.sig file instead of security.ima xattr.
You can label many files using -r option (recursive):
evmctl ima_sign -r -k /path/to/ima_private_key.pem /path/to/dir
You can find more details and examples in README file in ima-evm-utils.
Important: The IMA private key should not be present on the target. Label the generated image mounted on host machine. This is much safer method.