L1TF (a.k.a. Foreshadow) Mitigation¶
Intel SGX is susceptible to a side channel attack in which an attacker can read the secrets of an enclave E by starting an enclave A on the same core as E. This attack only works for secrets of E stored in a L1 cache and if A and E run on the same core. This attack is referred to as enclave-to-enclave (E2E) attack. E2E does not work if E and A run on different cores since each core has its own dedicated L1 cache.
The current Intel microcode ensures that the L1 cache of a core is flushed when a thread leaves the enclave. In this way, if A runs after E, it will not be able to read any secrets from L1. Note that flushing L1 is an expensive operation. SCONE keeps the threads running inside of an enclave and in this way avoids the cost of flushing L1 on each system call.
The microcode update by Intel protects against L1TF only if hyperthreading is disabled! If enclave A would run on one hyperthread and E on the second hyperthread of the same core, A could still read the values of E stored in L1 using the L1TF side channel. Hence, you must also disable the hyperthreading inside of your BIOS1. If hyperthreading is switched on/off, is checked during attestation. In other words, one can ensure during attestation that the enclave is protected against L1TF.
According to the Intel documentation, an update microcode combined with switched off hyperthreading will fully mitigate L1TF and E2E for Intel SGX.
Microcode Update on Ubuntu¶
Note that the BIOS loads the microcode during boot. The operating system can load a newer version of the microcode, for example, in case there is no new microcode update available yet for your BIOS. In this case, the OS has to load the new microcode on each new boot.
On Ubuntu, you can upgrade your CPU to the newest microcode as follows:
TMPDIR=$(mktemp -d) cd $TMPDIR git clone https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git cd Intel-Linux-Processor-Microcode-Data-Files sudo apt-get update sudo apt-get install -y intel-microcode if [ -f /sys/devices/system/cpu/microcode/reload ] ; then if [ -d /lib/firmware ] ; then mkdir -p OLD cp -rf /lib/firmware/intel-ucode OLD sudo cp -rf intel-ucode /lib/firmware echo "1" | sudo tee /sys/devices/system/cpu/microcode/reload else echo "Error: microcode directory does not exist" fi else echo "Error: is intel-micrcode really installed?" fi
You can check that a new microcode was updated by executing:
dmesg | grep microcode
This will result in an output like
[ 108.121907] microcode: CPU0 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.129335] microcode: CPU0 updated to revision 0xc6, date = 2018-04-17 [ 108.129406] microcode: CPU1 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.129484] microcode: CPU1 updated to revision 0xc6, date = 2018-04-17 [ 108.129539] microcode: CPU2 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.129611] microcode: CPU2 updated to revision 0xc6, date = 2018-04-17 [ 108.129696] microcode: CPU3 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.129768] microcode: CPU3 updated to revision 0xc6, date = 2018-04-17 [ 108.129816] microcode: CPU4 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.129905] microcode: CPU4 updated to revision 0xc6, date = 2018-04-17 [ 108.129953] microcode: CPU5 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.130025] microcode: CPU5 updated to revision 0xc6, date = 2018-04-17 [ 108.130070] microcode: CPU6 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.130142] microcode: CPU6 updated to revision 0xc6, date = 2018-04-17 [ 108.130224] microcode: CPU7 sig=0x506e3, pf=0x2, revision=0xc2 [ 108.130296] microcode: CPU7 updated to revision 0xc6, date = 2018-04-17 [ 108.130298] microcode: Enabling Indirect Branch Prediction Barrier [ 108.130300] microcode: Enabling Indirect Branch Restricted Speculation
When you are sure that this works out, you can load this microcode during reboot as follows:
cat > /tmp/load-intel-ucode.sh << EOF #!/bin/bash echo "1" | sudo tee /sys/devices/system/cpu/microcode/reload EOF sudo mv /tmp/load-intel-ucode.sh /lib/firmware/load-intel-ucode.sh chmod a+x /lib/firmware/load-intel-ucode.sh # the following cmd pops up the editor: add the @reboot... via the editor crontab -e @reboot /lib/firmware/load-intel-ucode.sh
Checking CPU Features¶
CPU microcode updates that protects against side channels like L1TF are not available for all CPUs.
You can check that your microcode has up to date protection features enabled by executing the following:
docker run --rm sconecuratedimages/apps:check_cpuid