Skip to content

Commit

Permalink
Update minimal
Browse files Browse the repository at this point in the history
  • Loading branch information
ChipWhisperer-Bot committed Dec 18, 2024
1 parent 55b3206 commit 8e2d2c3
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 453 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,3 @@ Stuck? If you need a hand, there are a few places you can ask for help:
---

ChipWhisperer is a trademark of NewAE Technology Inc., registered in the US, Europe, and China.

14 changes: 0 additions & 14 deletions chipwhisperer/capture/api/cwcommon.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from ...hardware.naeusb.naeusb import NAEUSB
from ...common.utils import util
from ...hardware.naeusb.fpga import FPGA
from typing import Callable, Union, Dict, Tuple, cast, List, Optional

import io
Expand Down Expand Up @@ -112,19 +111,6 @@ def _getNAEUSB(self) -> NAEUSB:
def _getFWPy(self) -> List[int]:
raise NotImplementedError("_getFWPy method required")

def _get_fpga_programmer(self) -> FPGA:
raise NotImplementedError("_get_fpga_programmer method required")

def was_fpga_prog_on_con(self):
""" Whether or not the ChipWhisperer's FPGA was programmed last time it was connected to
Will raise NotImplementedError if the device does not have an FPGA.
Returns:
True if the FPGA was programmed, False otherwise.
"""
return self._get_fpga_programmer()._programmed

@property
def latest_fw(self) -> Dict[str, int]:
"Get the newest firmware as a dict with elements major, minor and debug"
Expand Down
31 changes: 22 additions & 9 deletions chipwhisperer/capture/scopes/cwhardware/ChipWhispererSAM3Update.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ def auto_program(self, fw_path=None):
if fw_path:
if not os.path.exists(fw_path):
raise OSError("File {} does not exist. Firmware has not been erased.".format(fw_path))
if (not self._hw_type) and (not fw_path):
raise OSError("Unable to detect chipwhisperer hardware type and firmware not specified")
if not self._hw_type:
raise OSError("Unable to detect chipwhisperer hardware type")
before = serial.tools.list_ports.comports()
before = get_at91_ports()
# time.sleep(0.5)
Expand Down Expand Up @@ -219,12 +219,9 @@ def program(self, port, fw_path=None, hardware_type=None, bypass_warning=False):
'cwlite',
'cwnano',
'cw305',
'cw310',
'cw340',
'cw1200',
'cwbergen',
'cwhusky',
'cwhuskyplus'
'cwhusky'
]


Expand All @@ -244,10 +241,26 @@ def program(self, port, fw_path=None, hardware_type=None, bypass_warning=False):
message = 'Invalid hardware type {}, needs to be one of: ({})'
raise TypeError(message.format(hardware_type, ', '.join(type_whitelist)))
else:
from ....hardware.firmware.open_fw import mcufw
if hardware_type == 'cwlite':
from ....hardware.firmware.cwlite import getsome
name = 'SAM3U_CW1173.bin'
elif hardware_type == 'cwnano':
from ....hardware.firmware.cwnano import getsome
name = 'SAM3U_CWNANO.bin'
elif hardware_type == 'cw305':
from ....hardware.firmware.cw305 import getsome
name = 'SAM3U_CW305.bin'
elif hardware_type == 'cw1200':
from ....hardware.firmware.cw1200 import getsome
name = 'CW1200_SAM3UFW.bin'
elif hardware_type == 'cwbergen':
from ....hardware.firmware.cwbergen import getsome
name = 'CW310.bin'
elif hardware_type == 'cwhusky':
from ....hardware.firmware.cwhusky import getsome
name = 'Husky.bin'
self.logfunc('Loading {} firmware...'.format(hardware_type))
fw_data = mcufw(hardware_type, False)
name = "{}/mcufw.bin".format(hardware_type)
fw_data = getsome(name).read()

if fw_path:
self.logfunc("Opening firmware...")
Expand Down
166 changes: 55 additions & 111 deletions chipwhisperer/capture/targets/CW305.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import re
import io
from ._base import TargetTemplate
from .SimpleSerial2 import SimpleSerial2
from .SimpleSerial2 import SimpleSerial2, SimpleSerial2_CDC
from ...hardware.naeusb.naeusb import NAEUSB,packuint32
from ...hardware.naeusb.pll_cdce906 import PLLCDCE906
from ...hardware.naeusb.fpga import FPGA
Expand All @@ -39,7 +39,6 @@
from ...common.utils.util import camel_case_deprecated
from ..scopes.cwhardware.ChipWhispererSAM3Update import SAMFWLoader
from ..api.cwcommon import ChipWhispererCommonInterface
from collections import OrderedDict

from ...logging import *

Expand Down Expand Up @@ -121,8 +120,8 @@ class CW305(TargetTemplate, ChipWhispererCommonInterface):


def _getFWPy(self):
from ...hardware.firmware.open_fw import fwver
return fwver("cw305")
from ...hardware.firmware.cw305 import fwver
return fwver

def __init__(self):
import chipwhisperer as cw
Expand All @@ -135,8 +134,6 @@ def __init__(self):
self.REG_USER_LED = None
self.REG_CRYPT_CIPHEROUT = None
self.REG_BUILDTIME = None
self.REG_CRYPT_TYPE = None
self.REG_CRYPT_REV = None

self._naeusb = None
self.pll = None
Expand All @@ -148,8 +145,8 @@ def __init__(self):
self.oa = None

self._woffset_sam3U = 0x000
self.default_verilog_defines = 'cw305_aes_defines.v'
self.default_verilog_defines_full_path = os.path.dirname(cw.__file__) + '/../../firmware/fpgas/aes/hdl/' + self.default_verilog_defines
self.default_verilog_defines = 'cw305_defines.v'
self.default_verilog_defines_full_path = os.path.dirname(cw.__file__) + '/../../hardware/victims/cw305_artixtarget/fpga/common/' + self.default_verilog_defines
self.registers = 12 # number of registers we expect to find
self.bytecount_size = 7 # pBYTECNT_SIZE in Verilog

Expand All @@ -163,26 +160,6 @@ def __init__(self):
def _getNAEUSB(self):
return self._naeusb

def _dict_repr(self):
rtn = OrderedDict()
rtn['target_name'] = self.target_name
rtn['fpga_buildtime'] = self.fpga_buildtime
rtn['core_type'] = self.core_type
rtn['crypt_type'] = self.crypt_type
rtn['crypt_rev'] = self.crypt_rev
rtn['platform'] = self.platform
for prop in self.__dir__():
if 'REG_' in prop:
if getattr(self, prop): # this some stock registers are delcared as None and may remain so
rtn[prop] = getattr(self, prop)
return rtn

def __repr__(self):
return util.dict_to_str(self._dict_repr())

def __str__(self):
return self.__repr__()

def slurp_defines(self, defines_files=None):
""" Parse Verilog defines file so we can access register and bit
definitions by name and avoid 'magic numbers'.
Expand Down Expand Up @@ -255,36 +232,6 @@ def get_fpga_buildtime(self):
def fpga_buildtime(self):
return self.get_fpga_buildtime()

@property
def crypt_type(self):
""" Returns the value of the target's REG_CRYPT_TYPE register (if it exists).
"""
if self.REG_CRYPT_TYPE is None:
target_logger.error("target.REG_CRYPT_TYPE unset. Have you given target a verilog defines file?")
return self.fpga_read(self.REG_CRYPT_TYPE, 1)[0]

@property
def crypt_rev(self):
""" Returns the value of the target's REG_CRYPT_REV register (if it exists).
"""
if self.REG_CRYPT_REV is None:
target_logger.error("target.REG_CRYPT_REV unset. Have you given target a verilog defines file?")
return self.fpga_read(self.REG_CRYPT_REV, 1)[0]

@property
def core_type(self):
""" Infers the target core type from the target's REG_CRYPT_TYPE register (if it exists).
"""
ctype = self.crypt_type
if ctype == 2:
return 'AES'
elif ctype == 3:
return 'ECC'
elif ctype == 4:
return 'AES pipeline'
else:
return 'unknown'


def fpga_write(self, addr, data):
"""Write to an address on the FPGA
Expand Down Expand Up @@ -438,12 +385,8 @@ def vccint_get(self):
resp = self._naeusb.readCtrl(CW305_USB.REQ_VCCINT, dlen=3)
return float(resp[1] | (resp[2] << 8)) / 1000.0

def _get_fpga_programmer(self):
if self.platform != 'cw305':
raise NotImplementedError("Not supported for non CW305 boards")
return self.fpga

def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files=None, slurp=True, prog_speed=20E6, hw_location=None, sn=None, platform='cw305', version=None, program=True):
def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files=None, slurp=True,
prog_speed=20E6, hw_location=None, sn=None, platform='cw305', version=None, program=True, cdc_port=None):
"""Connect to CW305 board, and download bitstream.
If the target has already been programmed it skips reprogramming
Expand All @@ -455,14 +398,13 @@ def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files
force (bool): Whether or not to force reprogramming.
fpga_id (string): '100t', '35t', or None. If bsfile is None and fpga_id specified,
program with AES firmware for fpga_id
defines_files (list, optional): list of Verilog define files to parse
defines_files (list, optional): path to cw305_defines.v
slurp (bool, optional): Whether or not to slurp the Verilog defines.
platform (string, optional): 'cw305', or 'ss2' for non-CW305 target FPGA platforms.
The latter is intended for target designs using the ss2.v
simpleserial-to-parallel wrapper.
version (optional): when required to differentiate from multiple possible bitfiles
for a particular target (to be used with fpga_id)
program (bool, optional): for ss2 platforms, program the FPGA
"""
self.platform = platform
if platform == 'cw305':
Expand All @@ -477,16 +419,11 @@ def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files
if self.fpga.isFPGAProgrammed() == False or force:
if bsfile is None:
if not fpga_id is None:
from ...hardware.firmware.open_fw import getsome_generator
getsome = getsome_generator("cw305")
from chipwhisperer.hardware.firmware.cw305 import getsome
if self.target_name == 'AES':
bsdata = getsome(f"AES_{fpga_id}.bit")
elif self.target_name == 'Cryptech ecdsa256-v1 pmul':
if version is None or version == 0:
version = ''
else:
version = '_attempt' + str(version)
bsdata = getsome(f"ECDSA256v1_pmul{version}_{fpga_id}.bit")
bsdata = getsome(f"ECDSA256v1_pmul_{fpga_id}.bit")
elif self.target_name == 'Pipelined AES':
if version is None:
version = 0
Expand All @@ -506,7 +443,7 @@ def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files
target_logger.warning(("FPGA Bitstream not configured or '%s' not a file." % str(bsfile)))
else:
starttime = datetime.now()
status = self.fpga.FPGAProgram(bsfile, exceptOnDoneFailure=False, prog_speed=prog_speed)
status = self.fpga.FPGAProgram(open(bsfile, "rb"), exceptOnDoneFailure=False, prog_speed=prog_speed)
stoptime = datetime.now()
if status:
target_logger.info('FPGA Config OK, time: %s' % str(stoptime - starttime))
Expand All @@ -518,51 +455,58 @@ def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files
self.toggle_user_led = True
self.check_done = True

elif 'cdc' in self.platform:
if force or sn or hw_location:
target_logger.warning("force, sn and hw_location parameters have no effect on this platform")

if cdc_port is None:
raise ValueError("Must specify cdc_port")

ss2 = SimpleSerial2_CDC()
ss2.con(scope, dev_path=cdc_port)
self.ss2 = ss2
self.pll = SS2_CW305_NoPll()
self._naeusb = None
self.bytecount_size = 8

elif 'ss2' in self.platform:
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")

if program:
if self.platform == 'ss2_ice40':
self.fpga = LatticeICE40(scope)
self._fpga_id = 'cw312t_ice40'
else:
self.fpga = CW312T_XC7A35T(scope)
self._fpga_id = 'cw312t_a35'

if bsfile is None:
if self.platform == 'ss2_ice40':
self.fpga = LatticeICE40(scope)
self._fpga_id = 'cw312t_ice40'
from chipwhisperer.hardware.firmware.cwtargetice40 import getsome
if self.target_name == 'AES':
bsfile = getsome(f"iCE40UP5K_SS2.bin")
else:
raise ValueError('Unknown target!')
else:
self.fpga = CW312T_XC7A35T(scope)
self._fpga_id = 'cw312t_a35'

if bsfile is None:
if self.platform == 'ss2_ice40':
from ...hardware.firmware.open_fw import getsome_generator
getsome = getsome_generator("cwtargetice40")
if self.target_name == 'AES':
bsfile = getsome(f"iCE40UP5K_SS2.bin")
else:
raise ValueError('Unknown target!')
from chipwhisperer.hardware.firmware.xc7a35 import getsome
if self.target_name == 'AES':
bsfile = getsome(f"AES_cw312t_a35.bit")
elif self.target_name == 'Cryptech ecdsa256-v1 pmul':
bsfile = getsome(f"ECDSA256v1_pmul_cw312t_a35.bit")
elif self.target_name == 'Pipelined AES':
if version is None:
version = 0
bsfile = getsome(f"Pipelined_AES_cw312t_a35_half{version}.bit")
else:
from ...hardware.firmware.open_fw import getsome_generator
getsome = getsome_generator("xc7a35")
if self.target_name == 'AES':
bsfile = getsome(f"AES_cw312t_a35.bit")
elif self.target_name == 'Cryptech ecdsa256-v1 pmul':
if version is None or version == 0:
version = ''
else:
version = '_attempt' + str(version)
bsfile = getsome(f"ECDSA256v1_pmul{version}_{fpga_id}.bit")
elif self.target_name == 'Pipelined AES':
if version is None:
version = 0
bsfile = getsome(f"Pipelined_AES_cw312t_a35_half{version}.bit")
else:
raise ValueError('Unknown target!')
raise ValueError('Unknown target!')

if self.platform == 'ss2_ice40':
self.fpga.erase_and_init()
self.fpga.program(bsfile, sck_speed=prog_speed, start=True, use_fast_usb=False)
else:
self.fpga.program(bsfile, sck_speed=prog_speed)
if self.platform == 'ss2_ice40':
self.fpga.erase_and_init()
self.fpga.program(bsfile, sck_speed=prog_speed, start=True, use_fast_usb=False)
else:
self.fpga.program(bsfile, sck_speed=prog_speed)

ss2 = SimpleSerial2()
ss2.con(scope)
Expand All @@ -571,8 +515,8 @@ def _con(self, scope=None, bsfile=None, force=False, fpga_id=None, defines_files
self.ss2 = ss2
self.pll = SS2_CW305_NoPll()
self._naeusb = None
self.bytecount_size = 8

self.bytecount_size = 8
else:
raise ValueError("Invalid platform %s. Use 'cw305' or 'ss2'." % platform)

Expand Down
Loading

0 comments on commit 8e2d2c3

Please sign in to comment.