newaetech / chipwhisperer

ChipWhisperer - the complete open-source toolchain for side-channel power analysis and glitching attacks
http://chipwhisperer.com
Other
1.11k stars 282 forks source link

CW-Nano: Clipping of Power Traces #406

Closed rprimas closed 2 years ago

rprimas commented 2 years ago

Hello,

I am currently doing some experiments with a CW-Nano board and I am experiencing some inconsistencies with power trace captures. More concretely, if I execute a simple jupyter script that flashes a simple AES encryption binary onto the victim and perform some power measurements, the recorded samples are within ADC range sometimes but partially out of the ADC range at other times. It seems like whenever I remove/insert the CW-Nano and restart the jupyter script, the ADC range might be different (and stays like that until I close the connection). Since the CW-Nano has a fixed gain amplifier I am not sure how the ADC range is determined and if one can influence it via the python interface. Do you have any idea what could cause this issue or how I could avoid it? I have added some plots that show power traces of the same binary using the same jupyter script but with a disconnect/reconnect of the CW-Nano between the executions.

PS: I do experience the same capture issues on another CW-Nano board. I am currently using the most recent version of the CW framework from the development branch.

Regards, Robert trace1 trace2

colinoflynn commented 2 years ago

We'll have to see if we see that too. Changes in gain like that "feel" like a phase shift thing - the clock for the ADC & target is always derived from the same source, but if the divider locks on a different "offset" you may see that type of change.

Can you change the ADC sample clock to be 2x the target clock (15 MHz ADC sample clock), I think the default is 7.5 MHz for both (or if I'm wrong, change it to be the same - basically just want to toggle between some different frequencies for the ADC)?

If we can't replicate here we can swap your HW - we're actually fully out of Nano stock here but have more coming in next week (physically in shipping to us now, so should exist).

rishubn commented 2 years ago

@colinoflynn

We've tried it on 4 different boards and all experience this issue. Changing the ADC clock didn't improve anything (actually introduced misalignment in the traces) We suspect it could be a firmware issue because power cycling the board sometimes fixes the issue, but there always is a non-zero offset.

colinoflynn commented 2 years ago

Interesting! Still not sure where the gain offset/change comes from... as you say there is no connection there, so it's not some hidden thing we are aware of. I'd still be suspicious the "actual cause" is somehow clocking related: since the clock is something that relocks on power cycles, if it was a case of some constant phase offset between different clocks that changes on power cycle you'd see that.

As a minor note we'd occasionally see that clipping 'problem' too, although we found the information was typically still present on e.g. the negative spike (that wasn't clipped), so in terms of attack performance wasn't affected. Of course this is less helpful if you are trying to profile attacks... so will still need to investigate here.

alex-dewar commented 2 years ago

Resetting the SAM4S seems to do the same thing as power cycling here. I'd also guess that this is some sort of clock issue, as the ADC is external and being read via DMA. The only reasonable things I think we can do related to the clock would be resetting the PLLA on the SAM4S and toggling the enable pin on the clock buffer. Anything else would end up killing the USB, in which case there isn't really an advantage over just resetting the SAM4S

alex-dewar commented 2 years ago

Yeah, as @colinoflynn suggested, this is a phase offset issue. I'm not too sure what the exact conditions are to get this phase to reset (doing anything to the PLL seemed to have no effect), but swapping the outputs to the second PLL and back does get the phase to reset.

alex-dewar commented 2 years ago

Closing, as this should be fixed by 294ea073b1b7f34d1b743b3704ac5031801dbaa1

colinoflynn commented 2 years ago

Thanks @alex-dewar for checking into that, another long-term one killed :)

rishubn commented 1 year ago

We are still experiencing this issue on several CWNANOs with 0.5.7 The triggering behavior is exactly the same as described in the OP.

image

alex-dewar commented 1 year ago

Hi,

You'll have to call scope.reset_clock_phase() until you get traces that don't clip. Unfortunately, I don't think there's a way to make the phase offset between the two clocks consistent.

Alex

cassiersg commented 1 year ago

I'm trying to work around the issue.

The documentation of scope.reset_clock_phase() mentions "Warning: causes an interruption in the target clock. You may need to reset the target."

How can this be done ?

alex-dewar commented 1 year ago
scope.io.nrst = 0
time.sleep(0.1)
scope.io.nrst = None
time.sleep(0.1)
cassiersg commented 1 year ago

Thanks !

For anyone looking into this issue, I'm using the following snippet:

trace_ok = False
while not trace_ok:
    scope.reset_clock_phase()
    # Reset the target
    scope.io.nrst = 0
    time.sleep(0.01)
    scope.io.nrst = None
    time.sleep(0.01)
    # Acquire a test trace
    scope.adc.samples = 10000
    target.flush()
    scope.arm()
    target.simpleserial_write('a', bytearray(np.random.randint(0, 256, (16,), np.uint8)))
    scope.capture()
    trace = scope.get_last_trace()
    mint = np.min(trace)
    maxt = np.max(trace)
    trace_ok = maxt <= 0.47 and mint >= -0.47
    print("ok:", trace_ok, np.min(trace), np.max(trace))

(with an AES flashed on the board)