When trying to recover the 14th round key using the inverse_sbox_output (from cwa.leakage_models) this is what I get when running the attack with the Chipwhisperer Analyzer
The correlation is also completely off!
I 've tried to see if there was any jitter by plotting 5 traces as shown below:
But I wouldn’t say jitter is the problem.
(I use the Chipwhisperer Lite 2part with XMEGA as the target device)
Any suggestions on what to try on, would be more than welcomed, since I am really stuck!
–Update-- : The attack.point_range attribute was the problem, as soon as I removed the option and the attach run for all 15000 traces, it recovered the key correctly. However, it is clear that the decryption key(first half of it) that you provided is different than that of project.key(encryption key for AES-128), and this is also depicted in the table with our best guesses and the PGE which is referred to the previously used AES 128 encryption key. How can we update the Chipwhisperer analyzer to use/take in count the actual decryption key as the “correct one” (I’ ve already know that the ktp.next() method can return a different key as long as we set the _fixedKey attribute is set to False.) My own estimation is that the Bootloader uses a different (first half) decryption key, and just setting our leakage model to inverse_sbox_output obviously is not enough to just notify the Chipwhisperer analyzer about Bootloader’s correct key. So how do we notify the analyzer to do that and show in red characters the correct key (since you provided) with it’s corresponding PGE (obviously this is not a real life scenario since in the first place we don’t have any clue about bootloader’s key)?
–Update 2 --: After experimenting with the default jupyter_callback (from cwa module) I have built my own callback, like demonstrated in the orginal function in case someone wanted the correct key to be highlighted in green text.
code[key = [0xea, 0x79, 0x79, 0x20, 0xc8, 0x71, 0x44, 0x7d, 0x46, 0x62, 0x5f, 0x51, 0x85, 0xc1, 0x3b, 0xcb]
def format_stat(stat):
fmt="{:02X}
{:.3f}"
if (type(stat) is int) or (type(stat) is float):
return str(stat)
return str(fmt.format(stat[0], stat[2]))
def color_corr_key(row):
global key
ret = [""] * 16
for i,bnum in enumerate(row):
try:
if (type(bnum) is int) or (type(bnum) is float):
continue
if bnum[0] == key[i]:
ret[i] = “color: green”
else:
ret[i] = “”
except Exception as e:
print(“bnum: {}, key: {}”.format(bnum, key))
return ret
from IPython.display import clear_output
import numpy as np
import pandas as pd
def stats_callback():
results = attack.results
results.set_known_key(key)
stat_data = results.find_maximums()
df = pd.DataFrame(stat_data).transpose()
clear_output(wait=True)
display(df.head().style.format(format_stat).apply(color_corr_key,axis=1))]