Target API for CW312T_A35

Goal

Power analysis with CWHUSKY, CW313 interposer, and CW312T_A35 target running whatever I feel like putting on there (eventually).

Examples

Examples setup(s) from chipwhisperer/demos/, building off of CW305

target = cw.target(scope, cw.targets.CW305, force=True, fpga_id=fpga_id, platform=platform)
target = cw.target(scope, cw.targets.CW305_AES_PIPELINED, force=force, fpga_id=fpga_id, platform=platform, version=half_pipe)

with

force = True # to force bistream programming
fpga_id = 'cw312t_a35' # some ad hoc thing
platform = 'ss2' # simple serial 2

and some manually set parameters, generic

import chipwhisperer as cw
scope = cw.scope()
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"

and specific to the target,

if TARGET_PLATFORM == 'CW312T_A35':
    scope.gain.db = 45 # this is a good setting for the inductive shunt; if using another, adjust as needed
    scope.io.hs2 = 'clkgen'
    fpga_id = 'cw312t_a35'
    platform = 'ss2'

and

if TARGET_PLATFORM == 'CW312T_A35':
    scope.clock.clkgen_freq = 7.37e6
    scope.io.hs2 = 'clkgen'
    if scope._is_husky:
        scope.clock.clkgen_src = 'system'
        scope.clock.adc_mul = 4
        scope.clock.reset_dcms()

The target setup uses cw.target(), which basically calls _con()

def target(scope : Optional[scopes.ScopeTypes],
    target_type : type = targets.SimpleSerial,
    **kwargs) -> targets.TargetTypes:
    """Create a target object and connect to it.

    Args:
       scope (ScopeTemplate): Scope object that we're connecting to the target
           through.
       target_type (TargetTemplate, optional): Target type to connect to.
           Defaults to targets.SimpleSerial. Types can be found in
           chipwhisperer.targets.
       **kwargs: Additional keyword arguments to pass to target setup. Rarely
           needed.

    Returns:
        Connected target object specified by target_type.
    """
    rtn = target_type()
    rtn.con(scope, **kwargs)

    # need to check
    if type(rtn) in (targets.SimpleSerial, targets.SimpleSerial2) \
        and scope and scope._getNAEUSB().check_feature("SERIAL_200_BUFFER"):
        rtn.ser.cwlite_usart._max_read = 128
    return rtn

and which interacts with platform = 'ss2' and fpga_id = 'cw312t_a35' (in CW305.py) via

        elif platform == 'ss2':
            if force or sn or hw_location:
                target_logger.warning("force, sn and hw_location parameters have no effect on this platform")
            if not scope:
                raise ValueError("scope must be specified")
            self.fpga = CW312T_XC7A35T(scope)
            if not fpga_id is None:
                if fpga_id != 'cw312t_a35':
                    raise ValueError(f"Invalid fpga {fpga_id}")
            self._fpga_id = fpga_id

            if bsfile is None:
                from chipwhisperer.hardware.firmware.xc7a35 import getsome
                if self.target_name == 'AES':
                    bsfile = getsome(f"AES_{fpga_id}.bit")
                elif self.target_name == 'Cryptech ecdsa256-v1 pmul':
                    bsfile = getsome(f"ECDSA256v1_pmul_{fpga_id}.bit")
                elif self.target_name == 'Pipelined AES':
                    if version is None:
                        version = 0
                    bsfile = getsome(f"Pipelined_AES_{fpga_id}_half{version}.bit")
                else:
                    raise ValueError('Unknown target!')

            self.fpga.program(bsfile, sck_speed=prog_speed)

            ss2 = SimpleSerial2()
            ss2.con(scope)
            if scope._getNAEUSB().check_feature("SERIAL_200_BUFFER"):
                ss2.ser.cwlite_usart._max_read = 128
            self.ss2 = ss2
            self.pll = SS2_CW305_NoPll()
            self._naeusb = None
            self.bytecount_size = 8

which leads to investigation of

from ...hardware.naeusb.programmer_targetfpga import CW312T_XC7A35T
from chipwhisperer.hardware.firmware.xc7a35 import getsome

giving some programmer and grabbing some specific bitstreams (hardcoded in xc7a35.py copied from chipwhisperer/hardware/victims/cw308_ufo_target/xc7a35/vivado/).

Comments/questions

  • Will the target API documentation (and scripts) be updated to reflect the newer hardware? At the moment, the CW312T_A35 is treated like a subset of the CW305 (because it has the same FPGA) and maybe like a UFO target (as it’s connected to the capture unit through the CW313 interposer).
  • Is there documentation on the ss2 protocol?
  • Which part more specifically is the FPGA on the CW312? Vivado gives quite a few options starting with xc7a35t..., magnifying the print on the FPGA gives XC7A35TCSG324(ABX2201D6624095A) but there still seems to be a few options.
  • Can someone explain the best way currently to:
    • Create a target object corresponding to the CW312T_A35 target,
    • program a bitstream through the USB → Husky → 313 → target,
    • Set scope parameters for this Husky+target combo.
  • I’ll be back with questions on triggering/UART/top-level entity :grin:.

Thanks for any help anyone can provide!

No updates are planned at the moment. The CW312T_A35 is indeed presented as a subset of the CW305, because that’s exactly what it is.

There sure is: chipwhisperer/hardware/victims/cw308_ufo_target/xc7a35 at develop · newaetech/chipwhisperer · GitHub

You can find the answer in any of the example projects (xc7a35tcsg324-1).

Like it’s shown here, or any of the other CW305 notebooks.

There is no one-size-fits-all set of scope parameters. Every one of our Jupyter notebooks show how to set up the scope parameters for the particular example being taught in that notebook.

Thank you for your response.

I traced this one line

target = cw.target(scope, cw.targets.CW305, force=True, fpga_id=fpga_id, platform=platform)

as far as I could as shown above. It doesn’t exactly roll off the tongue. I don’t want to sound rude, I’m just a customer with a day job making a good-faith effort at using your product. I’m a mathematician without much background in electrical engineering, computer science, etc. I don’t need instruction on crypto or statistics, but I could use plenty of instruction in other areas. What I would like from your product is a relatively painless abstract layer between my PC and my FPGA or microcontroller, some advantage over buying a scope and a soldering iron (and learning to use them).

I guess there’s no royal road to side-channel analysis but I was hoping for a shortcut. In any case, I’ll continue my efforts when I have the time.