In our previous blog post, we’ve shown how we extracted the secret key from the ESP32’s hardware AES accelerator using a *Power Analysis* attack. In this blog post, we measure the electromagnetic emissions from the chip in order to extract the same secret key.

Important, please read our previous blog post on power analysis first if you have not done that yet. Espressif released an advisory after Ledger demonstrated the hardware AES accelerator of the ESP32 chip is vulnerable.

## Test code

We decided to optimize the test application by setting the trigger signal high and low closer to the AES operation. During our *Power Analysis* attack, we used a ROM API function call (i.e., `ets_aes_crypt`

) to perform an AES encryption. This function performs several operations (e.g., copying of data to input registers), that also can be implemented in the bootloader where our test code is implemented as well.

We dumped the ROM and reversed this function in order to implement our own. This allows us to set the trigger high signal much closer to the start of the AES operation and the trigger low signal much closer to the end of the AES operation. The resulting test code is shown below.

```
...
// copy input to AES engine from input buffer
*(uint32_t *)(0x3FF01030) = (uint32_t *)&input_buffer[0];
*(uint32_t *)(0x3FF01030 + 4) = (uint32_t *)&input_buffer[4];
*(uint32_t *)(0x3FF01030 + 8) = (uint32_t *)&input_buffer[8];
*(uint32_t *)(0x3FF01030 + 12) = (uint32_t *)&input_buffer[12];
// set trigger high
GPIO_OUTPUT_SET(26,1);
// start AES engine
*(uint32_t *)(0x3FF01000) = 1;
// poll AES engine to be ready
do {
asm volatile ("memw");
} while(*(uint32_t *)(0x3FF01004) != 1);
// set trigger low
GPIO_OUTPUT_SET(26,0);
// copy output from AES engine to output buffer
*(uint32_t *)&output_buffer[0] = *(uint32_t *)(0x3FF01030);
*(uint32_t *)&output_buffer[4] = *(uint32_t *)(0x3FF01030 + 4);
*(uint32_t *)&output_buffer[8] = *(uint32_t *)(0x3FF01030 + 8);
*(uint32_t *)&output_buffer[12] = *(uint32_t *)(0x3FF01030 + 12);
...
```

Execution the above test application results in a trigger window (i.e., time between trigger up and down) of roughly 1.0 μs as is shown below. This trigger window was 3.1 μs when we used to ROM API function.

This trigger window is significantly smaller than the trigger we used during the *Power Analysis* attack. This should facilitate smaller traces as we have to measure less samples, this should yield a faster acquisition speed.

We performed a quick *Known Key Correlation* analysis by measuring the power in order to identify where in this trigger window the AES operation is performed. Note, this measurement was made without the delay that’s shown in the trigger window trace shown above.

The intermediate correlation tells us that round 1 of the AES operation is started around sample 150. According to Espressif (see Section 22.3.5 in the Technical Reference Manual), the AES encryption should take between 11 and 15 clock cycles. We use this information in order to optimize the acquisition for the EM Analysis described in the remainder of this blog post. We could measure e.g. sample 150 to sample 200. However, we decided to take a sub-optimal approach by simply measuring the first 200 samples.

## Setup

We use Riscure’s High Precision EM Probe to measure the electromagnetic emissions coming from the chip. The output of this EM probe, as well as the GPIO pin for the trigger, is connected to a Picoscope 3206D oscilloscope. We use a standard FTDI-based USB-to-UART adapter for communication.

The probe is placed in Riscure’s EM Probe Station which allows us to adjust the location of the probe automatically. This is convenient as we will have to find locations where we can measure electromagnetic emissions related to AES operation.

A diagram of the power analysis setup that we used is shown below.

The actual setup in our lab is shown below.

We use Riscure’s FiPy to control the setup during the acquisition. This is a Python framework that is configured through the browser and can be used to configure the EM Probe station. The menu to configure the EM Probe Station is shown below.

We define a square grid by setting three reference points: top left corner (A), to right corner (B) and bottom right corner (C). Even though this Python framework is typically used for Fault Injection attacks, it can be used conveniently for SCA acquisition as well.

Needless to say, we prefer to use our custom board, even though we could use a standard development board for this *EM Analysis* attack, as no specific modifications are required. We prefer our custom board as it allows us to perform *Power Analysis* and *EM Analysis* conveniently at the same time.

## Location

One of the most significant advantages of *EM Analysis* over *Power Analysis* is that you do not need to make a power cut in order to measure a specific component of a chip. The *EM Probe* is simply placed on top of the chip in order to measure the electromagnetic emissions. One significant disadvantage is that it is required to find a good location to place the *EM Probe* in order to measure electromagnetic emissions that are related to the cryptographic operation.

Usually, a good location for the *EM Probe* is found by performing a XYZ scan across the surface of the chip. For example, this can be done in a grid of 20x20 (i.e., 400 locations) or 30x30 (i.e., 900 locations). As you can imagine, the larger the grid the longer it takes to complete.

At each location a measurement is taken and the frequency spectrum is computed. This allows you to determine what frequencies are prominently present during the execution of the cryptographic operation. This activity often results in nice and interesting pictures as is shown below.

For this research, we are interested in finding the location of the hardware AES engine. As far as we know, this engine is running at the same speed as the processor, which we configured to be 80 MHz. We tried out a few strategies for determining at what location the *EM Probe* picks up EM emissions related to the AES operation.

For example, we performed a XY *Spectrum Analysis* with executing the AES operation and without executing it. Our hypothesis was, that using these differential measurements would allow us to determine at what location there is activity related to the AES operation. Unfortunately, after trying this, and a bunch other things, we were unable to identify a good location.

Therefore, we decided to take a different approach, leveraging our super fast acquisition method, described in our previous blog post. This method, based on Picoscope’s *Rapid Block Mode*, enable us to measure thousands of encryption operations per second (i.e., 1e9 per day). This allows us to perform a *Known Key Correlation* at each location, in a reasonably sized grid, as long as we do not take too many measurements.

We performed a XY scan in a 30x30 grid across the chip’s surface (i.e., 900 locations in total). For each location, we take 1,500 averaged traces, where for each trace 1,000 measurements are averaged with the same data. In other words, for each location we have a trace set consisting of 1500 averaged traces, representing 1.5M encryption operations. We average the traces because the level of noise is much more significant than during the *Power Analysis* attack. For each location, it took ~75 seconds to acquire the trace set, which means, with some additional time required for moving the *EM Probe* across the chip’s surface, that the entire XY scan took roughly a day to complete. This lengthy process also shows the importance of being able to automate this process.

Then, for each resulting trace set, we performed a *Known Key Correlation* analysis. Whenever the EM Probe picks up EM emissions related to the AES engine’s operation, we should see correlation peaks at a specific moment in time. Interestingly, we identified multiple, significantly different, locations on the chip’s surface. We selected, by visually analyzing the traces, two seemingly good locations for which the intermediate correlation traces are shown below.

The above traces show intermediate leakage at the same sample (i.e., 158), which is expected for a hardware AES accelerator. To identify the location on the grid, we summed the absolute correlation values (i.e., for each intermediate) at sample 158 for each location and plotted the result on a 30x30 grid.

Then, using the color map shown above, we color the locations depending on the resulting correlation value (i.e., dark is low correlation and light is high correlation). The actual location of the probe, in the real-world and on the resulting scatter plot are shown below.

The scatter plot shows that our manual selection is within or close to the regions that show good correlation (i.e, dots are light colored). Even though there are other, potentially better, locations where we observe good correlation, we will focus only on location A and B for the remainder of this blog post.

**Averaged traces**

An averaged trace, where 1,000 encryption operations with the same data are averaged, is shown below for location A and B. There is no distinctive pattern visible, which shows that identifying a good location merely based on the shape of the trace is not possible. The distorted signal in the first 80 ns of the traces is related to the trigger (i.e., not related to the cryptographic operation).

To analyze location A and B in more detail, we acquire for each location a trace set of 10,000 averaged traces. Each averaged trace consists of 1,000 averaged measurements during the encryption of the same input data. In total this yields us a trace set that represents 10M encryption operation in total. We measure only 200 samples, as we know this should include the AES operation. We use an acquisition speed of 500 MSa/s. The total time it took to acquire this trace set for each location is ~8 minutes.

Please note, a faster method that could be used to determine if a location is good is a so-called t-test, the underlying equation used by Test Vector Leakage Assessment (TVLA), which is a testing methodology for evaluating the resistance of a cryptographic algorithm to side-channel leakage. It can also be perfectly used for finding the optimal locations for placing the EM Probe on the chip’s surface. Even though we were aware of this method, we did not use it.

## Known Key Correlation

We compute the correlation with the intermediate state, after the SBox in Round1, using the *Known Key Correlation* module from Riscure’s Inspector software. This effectively mean that we target the `HW(SBox Out)`

leakage model, which we already know is effective for extracting the key from the ESP32’s AES engine.

The resulting correlation trace for location A, including a zoomed version, is shown below. As expected, it shows significant correlation at sample 158. This shows that we were successful in moving the EM Probe back to the same location that was identified during the XY scan. The correlation at this point is negative.

The resulting correlation trace for location B, including a zoomed version, is shown below. As expected, it shows significant correlation at sample 158. This shows that we were successful in moving the EM Probe back to the same location that was identified during the XY scan. The correlation at this point is positive.

The correlation traces for location A and location B indicate significant correlation at a specific sample (i.e., 158). This result is different from what we obtained in our Power Analysis attack, where the leakage was spread across multiple samples. As we use the same trigger, this cannot be attributed to a jittery signal.

We believe that this is related to the fact that our measured power consumption is a function of the power consumption of different components relevant to the cryptographic operation, which may leak at different clock cycles due to the propagation of data propagation path (i.e., relevant data is processed at a different point in time).

On the other hand, the spatial nature of EM measurements allows to focus on a specific area of the chip. This allows leakage to be mostly found within a single sample, as most of the leaking components would have a short data propagation path between them, and would be operating on data within a shorter time frame.

## Known Key Analysis

Using the trace sets, containing 10,000 averaged traces, we perform a known key analysis using the *Known Key Analysis* module from Riscure’s Inspector software. This gives us an idea how many traces are required to extract the entire key.

The *Key Rank Evolution* for Location A is shown below. It shows that already at 4,000 averaged traces the key bytes fully converge to zero (i.e., correct key bytes rank 1). This indicates to us that we can extract the entire key with much less than the 10,0000 averaged traces we acquired.

The *Key Rank Evolution* for Location B is shown below. It shows that already at 6,000 averaged traces the key bytes fully converge to zero (i.e., correct key bytes rank 1). This indicates to us that we can extract the entire key with much less than the 10,0000 averaged traces we acquired.

Based on the above *Key Rank Evolution* plots, we are confident we are able to extract the entire key without any knowledge of the key.

## First Order Analysis

We perform a first order analysis using the *First Order Analysis* module from Riscure’s Inspector software. This is the same type of attack an attacker would have to perform without any knowledge of the key.

**Location A**

For location A, we were able to extract the entire key with a little bit of brute forcing with 2500 averaged traces, in ~1.5 seconds, as is shown below. The brute forcing is required as not all the key bytes were guessed correctly.

```
Results after 2500 traces
Best score for Round 0: Key: Column 0, Row 0 with rdm: 2.0651:
+ rank: 1, candidate: 0 (0x00), confidence: 0.1145 at position: 158
- rank: 2, candidate: 162 (0xA2), confidence: 0.0804 at position: 158
- rank: 3, candidate: 36 (0x24), confidence: 0.0662 at position: 158
- rank: 4, candidate: 245 (0xF5), confidence: 0.0643 at position: 158
Best score for Round 0: Key: Column 0, Row 1 with rdm: 4.2601:
+ rank: 1, candidate: 17 (0x11), confidence: 0.1164 at position: 158
- rank: 2, candidate: 154 (0x9A), confidence: 0.0537 at position: 158
- rank: 3, candidate: 233 (0xE9), confidence: 0.0525 at position: 158
- rank: 4, candidate: 215 (0xD7), confidence: 0.0521 at position: 158
Best score for Round 0: Key: Column 0, Row 2 with rdm: 0.1037:
- rank: 1, candidate: 3 (0x03), confidence: 0.0564 at position: 158
- rank: 2, candidate: 212 (0xD4), confidence: 0.0551 at position: 158
- rank: 3, candidate: 78 (0x4E), confidence: 0.0534 at position: 158
- rank: 4, candidate: 8 (0x08), confidence: 0.0490 at position: 158
Best score for Round 0: Key: Column 0, Row 3 with rdm: 0.9572:
+ rank: 1, candidate: 51 (0x33), confidence: 0.0737 at position: 158
- rank: 2, candidate: 96 (0x60), confidence: 0.0605 at position: 158
- rank: 3, candidate: 55 (0x37), confidence: 0.0577 at position: 158
- rank: 4, candidate: 2 (0x02), confidence: 0.0546 at position: 158
Best score for Round 0: Key: Column 1, Row 0 with rdm: 2.2417:
+ rank: 1, candidate: 68 (0x44), confidence: 0.0950 at position: 158
- rank: 2, candidate: 233 (0xE9), confidence: 0.0618 at position: 158
- rank: 3, candidate: 255 (0xFF), confidence: 0.0610 at position: 158
- rank: 4, candidate: 221 (0xDD), confidence: 0.0608 at position: 158
Best score for Round 0: Key: Column 1, Row 1 with rdm: 0.4459:
+ rank: 1, candidate: 85 (0x55), confidence: 0.0847 at position: 158
- rank: 2, candidate: 110 (0x6E), confidence: 0.0786 at position: 158
- rank: 3, candidate: 159 (0x9F), confidence: 0.0582 at position: 158
- rank: 4, candidate: 240 (0xF0), confidence: 0.0545 at position: 158
Best score for Round 0: Key: Column 1, Row 2 with rdm: 1.8712:
+ rank: 1, candidate: 102 (0x66), confidence: 0.0906 at position: 158
- rank: 2, candidate: 219 (0xDB), confidence: 0.0643 at position: 158
- rank: 3, candidate: 19 (0x13), confidence: 0.0582 at position: 158
- rank: 4, candidate: 195 (0xC3), confidence: 0.0571 at position: 158
Best score for Round 0: Key: Column 1, Row 3 with rdm: 0.2740:
+ rank: 1, candidate: 119 (0x77), confidence: 0.0657 at position: 158
- rank: 2, candidate: 76 (0x4C), confidence: 0.0616 at position: 158
- rank: 3, candidate: 188 (0xBC), confidence: 0.0583 at position: 158
- rank: 4, candidate: 246 (0xF6), confidence: 0.0576 at position: 158
Best score for Round 0: Key: Column 2, Row 0 with rdm: 1.8463:
+ rank: 1, candidate: 136 (0x88), confidence: 0.0824 at position: 158
- rank: 2, candidate: 254 (0xFE), confidence: 0.0583 at position: 158
- rank: 3, candidate: 97 (0x61), confidence: 0.0520 at position: 158
- rank: 4, candidate: 48 (0x30), confidence: 0.0509 at position: 158
Best score for Round 0: Key: Column 2, Row 1 with rdm: 1.5553:
+ rank: 1, candidate: 153 (0x99), confidence: 0.0831 at position: 158
- rank: 2, candidate: 67 (0x43), confidence: 0.0629 at position: 158
- rank: 3, candidate: 30 (0x1E), confidence: 0.0558 at position: 158
- rank: 4, candidate: 90 (0x5A), confidence: 0.0551 at position: 158
Best score for Round 0: Key: Column 2, Row 2 with rdm: 1.7023:
- rank: 1, candidate: 42 (0x2A), confidence: 0.0999 at position: 158
+ rank: 2, candidate: 170 (0xAA), confidence: 0.0746 at position: 158
- rank: 3, candidate: 168 (0xA8), confidence: 0.0694 at position: 158
- rank: 4, candidate: 139 (0x8B), confidence: 0.0614 at position: 158
Best score for Round 0: Key: Column 2, Row 3 with rdm: 1.5761:
+ rank: 1, candidate: 187 (0xBB), confidence: 0.0873 at position: 158
- rank: 2, candidate: 86 (0x56), confidence: 0.0658 at position: 158
- rank: 3, candidate: 186 (0xBA), confidence: 0.0631 at position: 158
- rank: 4, candidate: 11 (0x0B), confidence: 0.0611 at position: 158
Best score for Round 0: Key: Column 3, Row 0 with rdm: 0.2054:
+ rank: 1, candidate: 204 (0xCC), confidence: 0.0805 at position: 158
- rank: 2, candidate: 182 (0xB6), confidence: 0.0773 at position: 158
- rank: 3, candidate: 12 (0x0C), confidence: 0.0675 at position: 158
- rank: 4, candidate: 132 (0x84), confidence: 0.0609 at position: 158
Best score for Round 0: Key: Column 3, Row 1 with rdm: 2.6011:
+ rank: 1, candidate: 221 (0xDD), confidence: 0.1137 at position: 158
- rank: 2, candidate: 206 (0xCE), confidence: 0.0725 at position: 158
- rank: 3, candidate: 214 (0xD6), confidence: 0.0699 at position: 158
- rank: 4, candidate: 227 (0xE3), confidence: 0.0660 at position: 158
Best score for Round 0: Key: Column 3, Row 2 with rdm: 2.9664:
+ rank: 1, candidate: 238 (0xEE), confidence: 0.0937 at position: 158
- rank: 2, candidate: 43 (0x2B), confidence: 0.0567 at position: 158
- rank: 3, candidate: 102 (0x66), confidence: 0.0516 at position: 158
- rank: 4, candidate: 70 (0x46), confidence: 0.0499 at position: 158
Best score for Round 0: Key: Column 3, Row 3 with rdm: 2.1367:
+ rank: 1, candidate: 255 (0xFF), confidence: 0.1104 at position: 158
- rank: 2, candidate: 11 (0x0B), confidence: 0.0757 at position: 158
- rank: 3, candidate: 4 (0x04), confidence: 0.0712 at position: 158
- rank: 4, candidate: 233 (0xE9), confidence: 0.0651 at position: 158
Unverified key: (0x001103334455667788992abbccddeeff)
Preparing for key enumeration (SKEA)
Press abort to stop searching
Starting SKEA algorithm to a maximum of 30 bits
Wed Feb 08 15:04:19 CET 2023: explored search space of 20 bits... (2.41M keys/sec, max remaining time: 000h 07m 24s, ETA: Wed Feb 08 15:11:43 CET 2023)
Process finished after evaluating 1.90M key candidates
Correct key found: 00112233445566778899aabbccddeeff
Runtime (s): 1.5172439
```

When we perform the analysis on 5,000 averaged traces, we are able to extract the entire key without brute forcing in ~1.3 seconds.

**Location B**

For location B, we were able to extract the entire key without brute forcing with 5,000 averaged traces, in ~1.3 seconds, as is shown below.

```
Results after 5000 traces
Best score for Round 0: Key: Column 0, Row 0 with rdm: 1.9495:
+ rank: 1, candidate: 0 (0x00), confidence: 0.0817 at position: 158
- rank: 2, candidate: 127 (0x7F), confidence: 0.0581 at position: 158
- rank: 3, candidate: 201 (0xC9), confidence: 0.0529 at position: 158
- rank: 4, candidate: 250 (0xFA), confidence: 0.0522 at position: 158
Best score for Round 0: Key: Column 0, Row 1 with rdm: 2.5242:
+ rank: 1, candidate: 17 (0x11), confidence: 0.0804 at position: 158
- rank: 2, candidate: 2 (0x02), confidence: 0.0533 at position: 158
- rank: 3, candidate: 215 (0xD7), confidence: 0.0491 at position: 158
- rank: 4, candidate: 7 (0x07), confidence: 0.0388 at position: 158
Best score for Round 0: Key: Column 0, Row 2 with rdm: 3.3484:
+ rank: 1, candidate: 34 (0x22), confidence: 0.0810 at position: 158
- rank: 2, candidate: 49 (0x31), confidence: 0.0470 at position: 158
- rank: 3, candidate: 63 (0x3F), confidence: 0.0414 at position: 158
- rank: 4, candidate: 57 (0x39), confidence: 0.0407 at position: 158
Best score for Round 0: Key: Column 0, Row 3 with rdm: 0.1426:
+ rank: 1, candidate: 51 (0x33), confidence: 0.0454 at position: 158
- rank: 2, candidate: 33 (0x21), confidence: 0.0440 at position: 158
- rank: 3, candidate: 193 (0xC1), confidence: 0.0410 at position: 158
- rank: 4, candidate: 239 (0xEF), confidence: 0.0409 at position: 158
Best score for Round 0: Key: Column 1, Row 0 with rdm: 3.6023:
+ rank: 1, candidate: 68 (0x44), confidence: 0.0927 at position: 158
- rank: 2, candidate: 249 (0xF9), confidence: 0.0525 at position: 158
- rank: 3, candidate: 87 (0x57), confidence: 0.0448 at position: 158
- rank: 4, candidate: 98 (0x62), confidence: 0.0447 at position: 158
Best score for Round 0: Key: Column 1, Row 1 with rdm: 2.2057:
+ rank: 1, candidate: 85 (0x55), confidence: 0.0806 at position: 158
- rank: 2, candidate: 204 (0xCC), confidence: 0.0559 at position: 158
- rank: 3, candidate: 25 (0x19), confidence: 0.0480 at position: 158
- rank: 4, candidate: 22 (0x16), confidence: 0.0424 at position: 158
Best score for Round 0: Key: Column 1, Row 2 with rdm: 2.2359:
+ rank: 1, candidate: 102 (0x66), confidence: 0.0823 at position: 158
- rank: 2, candidate: 109 (0x6D), confidence: 0.0561 at position: 158
- rank: 3, candidate: 105 (0x69), confidence: 0.0523 at position: 158
- rank: 4, candidate: 53 (0x35), confidence: 0.0483 at position: 158
Best score for Round 0: Key: Column 1, Row 3 with rdm: 3.5057:
+ rank: 1, candidate: 119 (0x77), confidence: 0.0911 at position: 158
- rank: 2, candidate: 72 (0x48), confidence: 0.0520 at position: 158
- rank: 3, candidate: 43 (0x2B), confidence: 0.0450 at position: 158
- rank: 4, candidate: 32 (0x20), confidence: 0.0432 at position: 158
Best score for Round 0: Key: Column 2, Row 0 with rdm: 2.4459:
+ rank: 1, candidate: 136 (0x88), confidence: 0.0775 at position: 158
- rank: 2, candidate: 13 (0x0D), confidence: 0.0503 at position: 158
- rank: 3, candidate: 174 (0xAE), confidence: 0.0479 at position: 158
- rank: 4, candidate: 53 (0x35), confidence: 0.0474 at position: 158
Best score for Round 0: Key: Column 2, Row 1 with rdm: 2.3875:
+ rank: 1, candidate: 153 (0x99), confidence: 0.0636 at position: 158
- rank: 2, candidate: 21 (0x15), confidence: 0.0401 at position: 158
- rank: 3, candidate: 87 (0x57), confidence: 0.0372 at position: 158
- rank: 4, candidate: 240 (0xF0), confidence: 0.0363 at position: 158
Best score for Round 0: Key: Column 2, Row 2 with rdm: 2.8678:
+ rank: 1, candidate: 170 (0xAA), confidence: 0.0772 at position: 158
- rank: 2, candidate: 198 (0xC6), confidence: 0.0455 at position: 158
- rank: 3, candidate: 221 (0xDD), confidence: 0.0445 at position: 158
- rank: 4, candidate: 204 (0xCC), confidence: 0.0443 at position: 158
Best score for Round 0: Key: Column 2, Row 3 with rdm: 4.1119:
+ rank: 1, candidate: 187 (0xBB), confidence: 0.0884 at position: 158
- rank: 2, candidate: 25 (0x19), confidence: 0.0445 at position: 158
- rank: 3, candidate: 252 (0xFC), confidence: 0.0430 at position: 158
- rank: 4, candidate: 115 (0x73), confidence: 0.0417 at position: 158
Best score for Round 0: Key: Column 3, Row 0 with rdm: 1.1710:
+ rank: 1, candidate: 204 (0xCC), confidence: 0.0678 at position: 158
- rank: 2, candidate: 31 (0x1F), confidence: 0.0546 at position: 158
- rank: 3, candidate: 209 (0xD1), confidence: 0.0528 at position: 158
- rank: 4, candidate: 160 (0xA0), confidence: 0.0522 at position: 158
Best score for Round 0: Key: Column 3, Row 1 with rdm: 1.2794:
+ rank: 1, candidate: 221 (0xDD), confidence: 0.0710 at position: 158
- rank: 2, candidate: 198 (0xC6), confidence: 0.0574 at position: 158
- rank: 3, candidate: 145 (0x91), confidence: 0.0489 at position: 158
- rank: 4, candidate: 178 (0xB2), confidence: 0.0402 at position: 158
Best score for Round 0: Key: Column 3, Row 2 with rdm: 2.2306:
+ rank: 1, candidate: 238 (0xEE), confidence: 0.0632 at position: 158
- rank: 2, candidate: 13 (0x0D), confidence: 0.0421 at position: 158
- rank: 3, candidate: 234 (0xEA), confidence: 0.0414 at position: 158
- rank: 4, candidate: 108 (0x6C), confidence: 0.0394 at position: 158
Best score for Round 0: Key: Column 3, Row 3 with rdm: 4.4732:
+ rank: 1, candidate: 255 (0xFF), confidence: 0.0998 at position: 158
- rank: 2, candidate: 154 (0x9A), confidence: 0.0504 at position: 158
- rank: 3, candidate: 17 (0x11), confidence: 0.0444 at position: 158
- rank: 4, candidate: 86 (0x56), confidence: 0.0419 at position: 158
Unverified key: (0x00112233445566778899aabbccddeeff)
Process finished after evaluating 1.00 key candidates
Correct key found: 00112233445566778899aabbccddeeff
Runtime (s): 1.3346911
```

The level of correlation is quite similar for both locations, even though the probe is on a significantly different location on the chip’s surface. Optimizing the analysis using a faster tool like Jlsca is not required as the analysis required to extract the entire key is fast enough in Riscure’s Inspector.

## Final words

It took us longer to extract the entire key for *EM Analysis*, from start to end, than *Power Analysis*. The most time consuming activities include finding a good location for placing the *EM Probe* and a slight increase in the required (averaged) measurements that are required. Still, we are able to extract the entire key in less than a day.

It’s really target dependent if *EM Analysis* or *Power Analysis* is preferred. For example, the target modifications required for *Power Analysis* may simply be too complex (e.g., complex PCB, complex SoC, etc.) in order to measure the power efficiently. On the other hand, placing the *EM Probe* on a location where the EM emissions can be measured may be not trivial (e.g., heat sinks, stacked chips, shields, etc.).

We believe there are definitely opportunities to improve our *EM Analysis* by:

- finding a better location
- using different EM Probe tips
- using different EM probes (e.g., Langer Microprobe)
- making invasive modifications to the ESP32 chip (e.g., decapping)
- take measurements from the back-side of the chip
- high-end oscilloscope
- analog filters
- pre-processing of traces
- …

Needless to say, some of the above improvements may also yield disadvantages, such as an increased attack complexity, requirements on expertise, requirement on tooling, etc.

Feel free to reach out for questions or remarks related to this research. As always, we are available to give training related to our research, during which you will gain hands-on experience exploiting the vulnerabilities described in this blog post.

- Raelize.