What's the problem?
Let assume that you want to sign the working device. The device have kernel with IMA/EMV support. The Root CA is compiled in kernel. It means you did steps 1-3 from scenario 1 (preparing Tizen image protected by IMA/EVM), but then you've run the device with standard image with IMA/EVM disable mode (or fix or ignored). Assume that you run the kernel with params:
rootflags= i_version ima_tcb ima_template_fmt=d-ng|n-ng|status
Let's assume that you've setup the ssh conection to the device and you can connect as a root to it using command:
Assume that you want only the path-based policy which looks like this:
dont_measure fsmagic=0x9fa0 dont_measure fsmagic=0x62656572 dont_measure fsmagic=0x64626720 dont_measure fsmagic=0x1021994 dont_measure fsmagic=0x1cd1 dont_measure fsmagic=0x42494e4d dont_measure fsmagic=0x73636673 dont_measure fsmagic=0xf97cff8c measure path=vda:/usr/lib measure path=vda:/usr/bin measure path=vda:/usr/sbin measure path=vda:/lib measure path=vda:/bin measure path=vda:/sbin dont_appraise fsmagic=0x9fa0 dont_appraise fsmagic=0x62656572 dont_appraise fsmagic=0x64626720 dont_appraise fsmagic=0x1021994 dont_appraise fsmagic=0x858458f6 dont_appraise fsmagic=0x1cd1 dont_appraise fsmagic=0x42494e4d dont_appraise fsmagic=0x73636673 dont_appraise fsmagic=0xf97cff8c dont_appraise fsmagic=0x27e0eb appraise path=vda:/urs/lib appraise path=vda:/usr/bin appraise path=vda:/usr/sbin appraise path=vda:/bin appraise path=vda:/lib appraise path=vda:/sbin
Save this file on your host machine.
Moving files to device
You need to copy to the device:
- your IMA/EVM x509 certificate,
- policy (and its signature but you can sign the policy on the host or on the device. We'll show how to generate the signature on the device - generating it on host looks exactly the same),
- optional - private key to IMA/EVM certificate.
There are two ways of signing files. You can either use evmctl command on device or write your own service that will sign all your files remotely. This client-service application could work like this:
- Your private key is on host machine (server has access to it).
- You login into the device and run the client application.
- Client application opens file on device.
- Reads its content and calculates hash of the content.
- Sends the hash to server on your host machine.
- Server calculates the signature based on hash from client and private key.
- Server sends signature to client.
- Client gets the signature and sets it as a security.ima extended attribute.
- Client reads next file... (client application do actions 3-8 for every file included in policy).
This method is a little bit complicated so for our example we will copy the private key to the device.
scp /path/to/x509_ima.der device:/etc/ima/x509_ima.der scp /path/to/x509_ima.der device:/etc/ima/x509_evm.der scp /path/to/policy device:/etc/ima/ima_policy scp /path/to/the/privkey_ima.pem device:/root/privkey_ima.pem
Next you should make sure that the IMA and EVM are disabled. You can do this using im-console (remember to run ima-evm-server before) tool:
im-console -s ima dis im-console -s evm dis
Or directly using kernel interfaces:
echo 0 > /sys/kernel/security/ima/ima_state echo 0 > /sys/kernel/security/evm
Now you should add keys to keyrings. If keys are in locations /etc/ima/x509_ima.der and /etc/ima/x509_evm.der then kernel will load them at every reboot - but assume you want to avoid rebooting the target at the moment. Just do:
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  19771d83 I------ 1 perm 1f0f0000 0 0 keyring .evm: 1 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
You want to add keys for .ima keyring and .evm keyring. Check the IDs of these keyrings, and do:
evmctl import /etc/ima/x509_ima.der 0x226b9803 evmctl import /etc/ima/x509_evm.der 0x19771d83
You can do "cat /proc/keys" again - you should see the keys added to the keyrings.
Now you need to sign and apply the policy. Your policy should be in /etc/ima/ima_policy - kernel will load the policy from this location at every boot. But again - we don't want to reboot the device. To sign the policy run:
evmctl ima_sign -f -k /root/privkey_ima.pem /etc/ima/ima_policy
To load it into the kernel run:
echo "/etc/ima/ima_policy" > /sys/kernel/security/ima/policy
Now you need to label your files. Run the commands:
evmctl sign -r --imasig -k /root/ima_private_key.pem /urs/lib evmctl sign -r --imasig -k /root/ima_private_key.pem /urs/bin evmctl sign -r --imasig -k /root/ima_private_key.pem /urs/sbin evmctl sign -r --imasig -k /root/ima_private_key.pem /lib evmctl sign -r --imasig -k /root/ima_private_key.pem /bin evmctl sign -r --imasig -k /root/ima_private_key.pem /sbin
You can verify some random file:
evmctl ima_verify -k /etc/ima/x509_ima.der /usr/bin/bash
It should gave to you: Verification is OK.
You can turn on IMA and EVM in enforce mode.
im-console -s ima enf im-console -s evm ena
Or directly using kernel interfaces:
echo 1 > /sys/kernel/security/ima/ima_state echo 1 > /sys/kernel/security/evm
At the end you should remove your private key from the device:
Basically that's all. Your device is protected by the IMA/EVM. You can check how it works. Try to open any file from /usr/bin/ - it should succeed. Then try to create a random file in /usr/bin/ and then cat it - it should failed because it have no signature
cat /usr/bin/temp_file_test cat: /usr/bin/temp_file_test: Permission denied
But you should notice one thing: until now you've run your device in IMA/EVM disable mode - this mean that next time when you boot it, it will be booted also in IMA/EVM disable mode. To change that you should add to kernel booting param:
If it's not possible to add any param to the kernel you should as early at boot time as it possible turn on IMA in enforce mode. Write init script which will do this:
echo 1 > /sys/kernel/security/ima/ima_state