Asynchronous sampling on EM Probe yields not result

hello. I tried to use the crystal and HS1 (and even external scope) to do some asynchronous sampling using the EM Probe on XMEGA and other targets. For 10000 traces I couldnt get a solution (no correct keys at all). While when I turn on synchronous sampling over HS2, I get them pretty fast. Whats the problem here? Should I increase the sampling rate? Should I gather more traces? I tried resyncing the traces but it didnt help. I know synchronous sampling is better but for some case I want to try, I can only sample asynchronously.

You’re running into two challenges here so it may be best to separate them and learn how to deal with them one at a time, instead of simultaneously.

  1. Using an EM probe (with synchronous sampling): probe placement is critical! Have the target continuously running something like AES encryption and move the probe until you can see distinguishing features in the power trace, e.g. the 10 rounds. EM traces will tend to be more noisy, so you’ll need more traces for the attack to succeed.

  2. Asynchronous sampling (with “normal” measurements via the SMA cable, not EM probe): you’ll need a combination of higher sampling rate and more traces. See this paper to see what to expect: https://eprint.iacr.org/2013/294.pdf

Once you have success with 1 and 2, then try combining them.
I hope this helps.
Jean-Pierre

hey, thanks. I know the right position of the probe, tested it in the synchronous sampling. At which sample rate should I start with the EM probe asynchronous measurement? Over the cable it was possible with 50MS, currently 100MS with the EM probe and no result.

I tried using the resync with SAD over 10k samples but got following problem for the given code:

import chipwhisperer.common.api.lascar as cw_lascar
from lascar import *

cw_container = cw_lascar.CWContainer(resync_analyzer, project.textins)

guess_range = range(256)
leakage = cw_lascar.sbox_HW_gen

cpa_engines = [CpaEngine("cpa_%02d" % i, leakage(i), guess_range) for i in range(16)]
#cpa_engines = [CpaEngine("cpa_%02d" % i, (cw_lascar.sbox_HW_gen(i, range(256)) for i in range(16)))]
session = Session(cw_container, engines=cpa_engines).run(batch_size=50)

import chipwhisperer.analyzer as cwa
disp = cw_lascar.LascarDisplay(cpa_engines, list(project.keys[0]))
disp.show_pge()

ValueError: leakages and values dont share the same first dim (number_of_traces): (9616, 50001) (10000, 16)

During the SAD resync computation I got many messages like:

103/10000 [00:07<11:34, 14.26it/s]WARNING:root:Wave 104 (None) is invalid. Skipping

so apparently 384 traces got “deleted”, but how do I put it back into normal so lascar can analyse it? The CW Analyzer works, but its really slow so I would prefer to use lascar for this task

Unfortunately there’s no one-size-fits-all answer! From what I can gather you’re running into trouble with the asynchronous sampling, so I’d still suggest you take the EM probe out of the equation for now and sort out asynchronous sampling in isolation. Clock the target as slow as you can and sample as fast as you can (105 MS/s if you’re using CW hardware?). Look at your resynchronized traces visually: do they appear properly synchronized (this is where not using EM will be very helpful)? If not try a different re-synchronization strategy.

Just a quick question, is it okay to record at 200k samples and then decimate them to 50k for faster computation, or will I lose the “quality” of them?

For asynchronous sampling over the shunt resistor I just had to increase the number of traces from 300 to 1000 and no resync was needed.

When I do it over the EM probe however, I see that the trace(when I plot some of them) kind of sinusoidal (not stight but wavy).

How do I clock the target down as much as I can? I think its running at 7.5~MHz with the crystal, I tried to sample at 100k but it didnt work (for the probe) and with 10k traces

When you say decimate from 200k to 50k samples, if you mean throwing out 3 out of every 4 samples, that’s a terrible idea; that will undo your oversampling. If you mean keeping a 50k sample subset, that’s fine as long as you’ve kept the relevant part of the target operation.

Depends on your target. You can swap in a different crystal, or you can drive the clock from your ChipWhisperer capture hardware in which case you can go as low as ~3.2 MHz by setting scope.clock.clkgen_freq accordingly.

to be honest, using the scipy.signal.decimate function with q=4 so the whole trace gets kind of compressed and a fir/iir filter is added to it

could you tell me why the resync with lascar doesnt work if traces are missing? is it some functionality bug?

You didn’t show all your code so I have to make some guesses here, but when you run a resynchronization algorithm there are parameters for finding an acceptable re-synchronized trace, and if one can’t be found, then that raw trace is discarded. This is not necessarily a problem. As long as most of your traces are getting successfully resynchronized, and they look properly resynchronized, then you don’t need to worry at all about a few traces getting lost in the resync process.
Now if you mix up your pre-resync and post-resync data, they won’t have the same dimensions, and this could be why you’re getting errors in lascar.

im using the code given in the examples, how could I fix this code so it adjusts the case that the traces out of sync are discarded and also the corresponding plaintexts are discarded?

show me your actual code!

#resync traces using SAD

import chipwhisperer.analyzer as cwa
resync_traces = cwa.preprocessing.ResyncSAD(project)
resync_traces.ref_trace = 0
resync_traces.target_window = (1700, 2000)
resync_traces.max_shift = 1500
resync_analyzer = resync_traces.preprocess()

##analyze resynced with lascar

import chipwhisperer.common.api.lascar as cw_lascar
from lascar import *

cw_container = cw_lascar.CWContainer(resync_analyzer, project.textins)

guess_range = range(256)
leakage = cw_lascar.sbox_HW_gen

cpa_engines = [CpaEngine(“cpa_%02d” % i, leakage(i), guess_range) for i in range(16)]
#cpa_engines = [CpaEngine(“cpa_%02d” % i, (cw_lascar.sbox_HW_gen(i, range(256)) for i in range(16)))]
session = Session(cw_container, engines=cpa_engines).run(batch_size=50)

import chipwhisperer.analyzer as cwa
disp = cw_lascar.LascarDisplay(cpa_engines, list(project.keys[0]))
disp.show_pge()

Also I got some questions about other topic

when I recorded 20k traces, the .npy files in /traces were split into two files, does it mean there is some max data size allowed for the trace array to be? it was around 7GB each. so when I insert my own traces recorded with scope, do I also have to split it into half?

which setup should I use for asynchronous testing over the CWPRO? I put the jumpers horizontaly to HS1 and crystal, set the samplerate to 98k and recorded 10k traces over the shunt resistor, it worked.

when I switched to the em probe, recorded 20k traces with 98k samplerate, it didnt work, so I guess I gotta increase the amount of traces even more?

Now Im trying to put the HS1 horizontaly and the first pins of HS1+Crystal verticaly, whats the difference of that?

I dont quite understand the J3 description on CW308 UFO - NewAE Hardware Product Documentation

Instead of project.textins and project.keys, use resync_analyzer.textins and resync_analyzer.keys.

I notice that you’re using the same target_window from our example. Those values aren’t necessarily good ones for your case.

If you put your traces in a CW project (like below), all this is managed for you:

proj = cw.create_project("traces/Lab_Resync.cwp", overwrite=True)
for i in tnrange(num_traces, desc='Capturing traces'):
    key, text = ktp.next()
    trace = cw.capture_trace(scope, target, text, key)
    if not trace:
        continue
   
    proj.traces.append(trace)

What are you trying to achieve here? Unless I’ve misunderstood you, this is not a legal setting.
Your original setting with a single horizontal jumper across the top row, which connects the crystal oscillator to the target clock input, is correct for what you’re trying to do. The other jumper options relate to sending the CW clock to the target or vice-versa; since you’re doing asynchronous sampling, you don’t need to connect any clock between CW and the target.