Husky EM Trace Capture Issue for DESFire EV1 NFC Communication

Hi everyone,

I am working with a ChipWhisperer Husky to capture EM traces from an NFC communication setup using a Langer near-field EM probe and an ACS ACR122U reader communicating with a DESFire EV1 card.

My goal is to capture the raw EM traces during APDU communication using a software trigger. The issue I am facing is that the captured traces mostly look random/noisy, and I cannot clearly see the expected NFC modulation or stable patterns.

I want to understand:

  • What I might be doing wrong in the configuration

  • Whether my trigger setup is incorrect

  • Whether the sampling configuration is unsuitable for NFC EM capture

  • If the gain/filter settings are causing problems

  • How the Husky should ideally be configured for this type of EM acquisition

Current setup:

  • ChipWhisperer Husky

  • ACR122U NFC reader

  • DESFire EV1 card

  • Langer near-field EM probe

  • Software trigger

  • Capturing during APDU transmission

The APDU I am testing with is:
90 60 00 00

The trigger is software-based. I arm the scope, send the APDU, and then manually trigger capture around the communication event.

These are the current acquisition parameters:

FS             = 100_000_000       # 100 MS/s (ChipWhisperer Husky)
NFC_FC         = 13_560_000        # 13.56 MHz carrier
NFC_SUBCARRIER = NFC_FC / 16       # 847,500 Hz
NFC_BIT_RATE   = NFC_FC / 128      # 105,937.5 Hz

# SPB at 100 MS/s
SPB_100M = round(FS / NFC_BIT_RATE)
SPB_TOL  = 4

DEMOD = dict(
    lp_hz = 2_000_000,
    hp_hz = 50_000,
    order = 4,
)

CFG = dict(
    gain_db   = 45,
    n_samples = 200_000,
    offset    = 0,
    decimate  = 1,
)

RAW_WIN_SAMPLES = 150_000

N_CAPTURES = 100
H5_OUT     = 'get_version_v7.h5'

ChipWhisperer configuration:

try:
    scope.dis()
except Exception:
    pass

scope = cw.scope()
scope.default_setup()

scope.gain.mode        = 'high'
scope.gain.db          = CFG['gain_db']
scope.adc.samples      = CFG['n_samples']
scope.adc.offset       = CFG['offset']
scope.adc.decimate     = CFG['decimate']
scope.adc.basic_mode   = 'rising_edge'
scope.trigger.module   = 'ADC'
scope.trigger.level    = 0.05
scope.clock.clkgen_src = 'system'
scope.clock.adc_mul    = 1

What I currently observe:

  • Traces appear highly random

  • No clear stable carrier envelope

  • Difficult to identify modified Miller modulation

  • Alignment between traces seems inconsistent

  • Sometimes the trigger appears too early or too late

I suspect one or more of these may be the issue:

  • Software trigger timing jitter

  • Incorrect trigger source

  • Gain saturation or insufficient gain

  • Probe placement/orientation

  • Sampling window misalignment

  • ACR122U internal timing variability

  • ADC trigger threshold issues

I would really appreciate guidance from anyone who has worked on:

  • NFC EM side-channel acquisition

  • DESFire EV1 trace capture

  • ChipWhisperer Husky for RF/EM analysis

  • Capturing 13.56 MHz carrier activity

  • Modified Miller demodulation

I will also add additional capture code and example traces/results below.

Thanks.

Probe placement and ADC trigger level are going to have a huge effect on the quality of your results.

While triggering on the ADC level might be workable, I would never start that way.

You first need to find a good probe placement; for this, you absolutely need a stable trigger. Find a different way to tie your capture trigger to the APDU send event.

Okay, I understand. The probe placement seems good because we are able to observe strong signal strength from the reader/card communication.

The main issue now appears to be trigger instability and timing jitter between captures. The traces are not aligning consistently, which makes the NFC modulation difficult to analyze.

Could you please suggest a better way to generate a stable trigger synchronized with the APDU transmission?

Currently, we are using a software trigger where we:

  1. Arm the Husky

  2. Send the APDU (90 60 00 00)

  3. Manually trigger capture around the communication event

However, this appears to introduce significant timing jitter.

Any guidance on achieving stable alignment for 13.56 MHz NFC EM captures would be greatly appreciated.

You say that you are manually triggering, yet your code shows scope.trigger.module = 'ADC'. I answered above assuming that you’re using the ADC level trigger.

If you are actually manually triggering the capture (i.e. via the hidden scope.sc.triggerNow()), that is even worse and will always have huge jitter. Don’t do that!

Ideally I would trigger from the APDU, i.e. whatever is sending the APDU gives you a stable trigger pulse on one of Husky’s trigger input pins. If that’s not possible, you’ll have to get creative, and we can’t really help you with that since we don’t have your setup.

Start by carefully reviewing all of Husky’s available triggers; we give a good overview in this notebook. Consider also whether the trigger sequencer could help you.