Skip to content

Microcode update / Side-channel Mitigation

Intel SGX is susceptible to certain side channel attacks 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 also execute the a script that we provide:

curl -fssl https://raw.githubusercontent.com/SconeDocs/SH/master/install_microcode.sh | bash

In case your microcode is already up-to-date, it will print a message like this:

Already newest version of microcode installed:  [ 0.000000] microcode: microcode updated early to revision 0xca, date = 2019-10-03

In case your microcode is not yet up-to-date, it will print a message like this:

Updated microcode from version:
                    to version:  [ 0.000000] microcode: microcode updated early to revision 0xca, date = 2019-10-03

When you do not have the newest microcode installed, 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

  1. We have published an alternative to switching off hyperthreading in Usenix ATC 2018: we ensure that both hyperthreads of a core run inside of the same enclave.