CW Lite and iCE40 target board

Hi.

Are there options to debug loading of the bitstream into the iCE40?
I am trying to run iCE40 target board inserted into the CW313 and attached to the CW Lite but something goes wrong with pushing the bitstream.
I use the code from the jupyter samples:

import chipwhisperer as cw

TARGET_PLATFORM = 'CW312T_ICE40'

scope = cw.scope()
if scope._is_husky:
    scope.adc.samples = 80
else:
    scope.adc.samples = 129
scope.adc.offset = 0
scope.adc.basic_mode = "rising_edge"
scope.trigger.triggers = "tio4"
scope.io.tio1 = "serial_rx"
scope.io.tio2 = "serial_tx"
scope.io.hs2 = "disabled" 

if TARGET_PLATFORM in ['CW312T_A35', 'CW312T_ICE40']:
    scope.io.hs2 = 'clkgen'
    fpga_id = None # not needed
    if TARGET_PLATFORM == 'CW312T_A35':
        platform = 'ss2_a35'
        scope.gain.db = 45 # this is a good setting for the inductive shunt; if using another, adjust as needed
    else:
        platform = 'ss2_ice40'
        scope.gain.db = 15
else:
    scope.gain.db = 25
    scope.io.hs2 = "disabled"
    platform = 'cw305'
    if TARGET_PLATFORM == 'CW305_100t':
        fpga_id = '100t'
    elif TARGET_PLATFORM == 'CW305_35t':
        fpga_id = '35t'

# On the CW305, setting force=False only programs the FPGA if it is currently unprogrammed, whereas force=True programs the FPGA regardless.
# This option isn't available on the CW312T_A35 or CW312T_ICE40.
target = cw.target(scope, cw.targets.CW305, force=True, fpga_id=fpga_id, platform=platform)

But the line
target = cw.target(scope, cw.targets.CW305, force=True, fpga_id=fpga_id, platform=platform)
causes fast blinking the D3 LED(green) and turned on D4 LED(red) which indicates something wrong with pushing the bitstream.
Normaly, both D3, D4 LED’s should be turned off when bitstream is written into the iCE40.

The red LED flashing rate reflects the target’s clock rate; it’s flashing fast because CW-lite behaves a bit different than Husky in that it comes up with a faster clock until it’s set otherwise. Just add a scope.default_setup() at the top of the notebook, just after scope = cw.scope(), and it should work fine.

1 Like

Thanks. This helped!

Every time when I use CW Lite for SCA I enjoy of it. It very reliably collects the power traces so that the key is guessed precisely and gives completely correct key.
It is still unclear to me why I cannot get the similar results with CW Husky :frowning:
Even with pretty reliable iCE40 target, the first byte of the key cannot be guessed using the CW Husky.

@jpthibault More pictures to compare captured traces by Husky and Lite from the iCE40 FPGA
Husky has significant jitter. This won’t allow to recover the AES key correctly.

  1. I’m able to get full key recovery with Husky. The number of traces required can vary from run to run, but that’s not specific to Husky, it can happen with CW-lite as well.
  2. I wouldn’t call that “jitter”, and it doesn’t prevent AES key recovery. That looks like a single outlying trace, and it would be the first trace from your capture. When the target has been sitting idle, the first capture is going to look different from subsequent ones, due to the capacitive and inductive elements of the target. You could simply throw away the first trace (or not – it really shouldn’t affect attack results significantly). This BTW is definitely not specific to Husky, you should see it with CW-Lite as well, and you will see it with any target.

@jpthibault

  1. I tried to capture traces by Husky more than 10 times collecting the traces in the range 5000 - 20000. Any try was not able to guess the first byte. CW Lite is very-very reliable. Every attempt guesses each byte of the key correctly. 5000 traces is more than enough for CW Lite.
  2. To get the power traces I used the same key and the same plaintext. Ideally, it should give thin line on the plot equal to single trace. In other words, every trace overlaps other traces very precisely without any shiftings. So, I called ‘jitter’ the deviation from this ideal line.
    For CW Lite this deviation is fairly small but CW Husky has much greater deviation.

    Arrows point at the jitter value.

That is not how this works. Any real target will have noise, and the leakage that’s exploited by side-channel attacks may well be underneath that noise floor (which is why attacks need lots of traces); in this scenario, the viability of side-channel attacks cannot be quantified by the naked eye. Consider also that since Husky has a 12-bit ADC vs Lite’s 10-bit ADC, with Husky you’re getting 2 extra bits of that noise.