Trigger not working (1 - Connecting to Hardware)

I am running this code on my setup (CW Huskey, UFO Board, STM32F415 target, see picture), and once it managed to capture a proper trace, but every other time it only captures noise, and I either get a ADC clipped error or a trigger to soon error. I am using the simpleserial-base firmware, with the only change being a short loop before the trigger, to add a small delay, and CW 6.0.

import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial) #cw.targets.SimpleSerial can be omitted
scope.default_setup()

import time
msg = bytearray([0]*16) #simpleserial uses bytearrays
#scope.gain.gain = 15
scope.arm()
time.sleep(1)
target.simpleserial_write('p', msg)
scope.capture()
print(scope.errors.adc)
scope.errors.clear()
cw.plot(scope.get_last_trace())

Setup:

This is for a college project, so I have no experience with CW, but my tutor also had no idea what was wrong.

As a first step, you should remove the delay between arming the scope and sending your plaintext. As for clipping, that’s a matter of what you have scope.gain.db set to. Try lowering that.

Can you post a picture of your power trace?

Lowering the db from the default 25 to 24 seems to be enough.
This is what it looks like with your suggestions, sadly I didn’t screenshot the time it worked.


It seems I don’t get a trigger to soon error anymore, but I still get “(ChipWhisperer Scope WARNING|File _OpenADCInterface.py:732) Timeout in OpenADC capture(), no trigger seen! Trigger forced, data is invalid. Status: 13” in my output, and again with status 12.

Can you try toggling the nRST pin after running default setup? There may be some issues with the startup of the clock that can cause the target not to boot correctly.

Added this to my code after default setup:

scope.io.nrst = False
scope.io.nrst = True

Trace now looks like this, is that what is expected? Errors are gone and it is at least not only noise anymore

That seems more reasonable. You shouldn’t actually see much with the default simpleserial-base firmware, as you’re not doing anything after the trigger. In the future, I recommend adding a time.sleep(0.25) between and after the nRST toggle as well.

Testing a bit further, it seems that with any more complex task, I still only capture noise, e.g. I now tried to do Lab 2.1B and these are my traces, looking nothing like what is expected (green is the correct trace).
All I did is replace my code with this, taken from the solution for 2.1B

def reset_target(scope):
    scope.io.nrst = 'low'
    time.sleep(0.05)
    scope.io.nrst = 'high_z'
    time.sleep(0.05)

def cap_pass_trace(pass_guess):
    reset_target(scope)
    num_char = target.in_waiting()
    while num_char > 0:
        target.read(num_char, 10)
        time.sleep(0.01)
        num_char = target.in_waiting()

    scope.arm()
    time.sleep(1)
    target.write(pass_guess)
    ret = scope.capture()
    if ret:
        print('Timeout happened during acquisition')

    trace = scope.get_last_trace()
    return trace

%matplotlib notebook
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
for c in 'abcdefgijklmnopqrstuvwxyz0123456789h':
    trace = cap_pass_trace(c + "\n")
    if c == 'h':
        ax1.plot(trace[0:200], 'g')
        ax2.plot(trace, 'g')
    else:
        ax1.plot(trace[0:200])
        ax2.plot(trace)
fig1.show()
fig2.show()




Yes, I made sure to flash the correct firmware before testing.

You may need to swap over to the adjustable voltage regulator - the F4 has an internal 1.2V LDO which needs to be bypassed via the decoupling cap pins. We feed in 1.2V, but this might not be enough to overpower the regulator fully. Try measuring out something like 1.25V on the adj reg (adjustable via the white pot on the right side of the board), then swap over to it by changing the jumper on the FILT pin.

It’s still not working, only thing noticeable is that if I enter the correct password, I see the idling behavior after, but sending single characters, they all seem to be just noise. Are my switches/jumpers all set correctly, because otherwise, I am truly out of ideas.

I missed this before, but you shouldn’t have a delay after arming your scope. Can you try using the code from Lab 2_1B verbatim to see if that works?

No idea where that debugging tip came from, but running the original code (except resetting the target at the beginning and lowering db) yields the exact same results, here’s a picture of the difference between the traces and a reference trace, where one should clearly be different:

The diff in cell before the full attack is 94 for x (correct) while the others are 60-70, so there is a small difference but the baseline is far noisier than shown in the example. Adjusting the threshold to 75 in the full attack, I get the correct password. Switching back J14 I have the same results.

I also managed to perform the AES DPA/Lab 3.3 (my real goal), but I had to capture 12000 traces instead of the default 2500, so I guess it’s fine for now, and maybe the reference images in the notebooks are just overly ideal versions of what you see, maybe it looks like that with another target.

The DPA lab isn’t a great evaluation, the CPA lab is much better for that. We haven’t done much with the particular combination of the F4 and the Husky, but you shouldn’t be seeing that much noise. Can you try running print(scope) just before you capture and posting the output?

My partner currently has the hardware, but I asked him to do that.
We had a meeting with the tutor today and after some testing and seeing clear results with a CWLITE, they said that apparently edge timings are less consistent on the Husky, leading to noisier traces, but you probably know better if that makes sense or not.

I’m not sure what they mean by edge timings, but everything related to clocking and timing is much tighter on the Husky compared to the Lite. You might be seeing some additional high frequency noise on the lines between the LNA and ADC (there’s a low pass filter between the two on new revisions of the Husky), but this seems especially bad. I’d like to make sure everything is working correctly internally by examining the settings; if the PLL isn’t being locked correctly, for example, that can mess up the capture.

Alex

This is the output:

cwhusky Device
sn             = 50203220325531583330353231323033
fpga_buildtime = 6/10/2022, 10:40
fw_version = 
    major = 1
    minor = 5
    debug = 0
gain = 
    mode = high
    gain = 22
    db   = 25.091743119266056
adc = 
    state                    = True
    basic_mode               = rising_edge
    timeout                  = 2
    offset                   = 0
    presamples               = 0
    samples                  = 5000
    decimate                 = 1
    trig_count               = 938959816
    stream_mode              = False
    test_mode                = False
    bits_per_sample          = 12
    segments                 = 1
    segment_cycles           = 0
    segment_cycle_counter_en = False
    clip_errors_disabled     = False
    lo_gain_errors_disabled  = False
    errors                   = False
clock = 
    clkgen_src             = system
    clkgen_freq            = 7370129.87012987
    adc_mul                = 4
    adc_freq               = 29480519.48051948
    freq_ctr               = 0
    clkgen_locked          = True
    adc_phase              = 0
    extclk_monitor_enabled = False
    extclk_error           = False
    extclk_tolerance       = 102.996826171875
trigger = 
    module   = basic
    triggers = tio4
io = 
    tio1         = serial_rx
    tio2         = serial_tx
    tio3         = high_z
    tio4         = high_z
    pdid         = high_z
    pdic         = high_z
    nrst         = high_z
    glitch_hp    = False
    glitch_lp    = False
    extclk_src   = hs1
    hs2          = clkgen
    target_pwr   = True
    tio_states   = (1, 1, 1, 1)
    cdc_settings = bytearray(b'\x00\x00\x00\x00')
    aux_io_mcx   = high_z
    glitch_trig  = trigger
glitch = 
    enabled           = False
    mmcm_locked       = False
    num_glitches      = 1
    clk_src           = target
    width             = 0
    offset            = 0
    trigger_src       = manual
    arm_timing        = after_scope
    ext_offset        = 0
    repeat            = 1
    output            = clock_xor
    phase_shift_steps = 4592
ADS4128 = 
    mode      = normal
    low_speed = True
    hi_perf   = 2
LA = 
    present                  = True
    enabled                  = False
    clkgen_enabled           = False
    locked                   = False
    clk_source               = pll
    trigger_source           = glitch
    oversampling_factor      = 1
    sampling_clock_frequency = 0.0
    downsample               = 1
    capture_group            = glitch
    capture_depth            = 0
trace = 
    present      = True
    enabled      = False
    errors       = False
    trace_synced = False
    trace_mode   = parallel
    trace_width  = 4
    clock = 
        fe_clock_alive   = True
        fe_clock_src     = target_clock
        clkgen_enabled   = False
        fe_freq          = 7370281.219482422
        swo_clock_locked = False
        swo_clock_freq   = 0.0
    capture = 
        trigger_source         = trace trigger, rule #0
        use_husky_arm          = False
        raw                    = True
        rules_enabled          = []
        rules                  = []
        mode                   = while_trig
        count                  = 0
        max_triggers           = 1
        triggers_generated     = 0
        record_syncs           = False
        matched_pattern_data   = 0000000000000000
        matched_pattern_counts = [0, 0, 0, 0, 0, 0, 0, 0]
XADC = 
    status                               = good
    current temperature [C]              = 48.7
    maximum temperature [C]              = 51.1
    user temperature alarm trigger [C]   = 80.0
    user temperature reset trigger [C]   = 59.9
    device temperature alarm trigger [C] = 89.9
    device temperature reset trigger [C] = 59.9
    vccint                               = 0.998
    vccaux                               = 1.796
    vccbram                              = 0.998
userio = 
    mode       = normal
    direction  = 0
    drive_data = 0
    status     = 511
LEDs = 
    setting = 0 (default, as labelled)
errors = 
    XADC errors  = False
    ADC errors   = False
    extclk error = False
    trace errors = False

So, it might just have been that the first Husky is broken. During the meeting we tried another one and while the trace visually looks similar, I noticed the numbers were better, and I got to test it now and both the password attack as well as the DPA work with the original numbers, using the new Husky
Maybe the second one is one of the new revisions you mentioned?

Some images with the new Husky:



With the diff, you can even spot 3 spots where all traces except the one for the correct letter are close to 0.