def findNewValue(self, mode="linear"): """ Find new value for this parameter """ if str.lower(mode) == "linear": self.cnt += 1 if self.cnt == self.paramRepeat: # Done this one, next step self.cnt = 0 newval = self.paramValueItem.getValue() + self.paramStep if newval > self.paramRange[1]: newval = self.paramRange[0] self.rangeComplete.emit(self.paramNum) # Cast type to required value newval = self.paramType(newval) self.paramValueItem.setValue(newval) parameter = self.paramScript+[newval] try: Parameter.setParameter(parameter) except: raise StopIteration("Choose a valid Parameter Path/Value combination. Got: " + str(parameter)) else: raise ValueError("Unknown Increment Type %s" % mode)
def updateParams(self, _=None): rng = self.findParam('range').getValue() # Force to be valid values curval = self.findParam('curval').getValue() curval = max(curval, rng[0]) curval = min(curval, rng[1]) self.findParam('curval').setLimits(rng) self.findParam('curval').setValue(curval) self.paramRange = rng self.paramValueItem = self.findParam('curval') self.paramStep = self.findParam('step').getValue() self.paramRepeat = self.findParam('repeat').getValue() self.paramType = self.findParam('datatype').getValue() try: self.paramScript = eval(self.findParam('parampath').getValue()) except SyntaxError as e: logging.error('Syntax Error: %s' % str(e)) try: Parameter.setParameter(self.paramScript+[curval]) except: pass self.tracesrequired = math.ceil(((self.paramRange[1] - self.paramRange[0]) / self.paramStep) * self.paramRepeat)+1 self.tracesreqChanged.emit(self.paramNum, self.tracesrequired)
def __init__(self, oadcInstance): self.serialNumber = '' self._serialnumbers = [''] self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ { 'name': 'Refresh Device List', 'type': 'action', 'action': self.serialRefresh }, { 'name': 'Device Serial Number', 'key': 'snum', 'type': 'list', 'values': [''], 'get': self.getSerialNumber, 'set': self.setSelectedDevice }, ]) self.ser = None if (openadc_qt is None) or (ft is None): raise ImportError("Needed imports for FTDI missing") else: self.scope = oadcInstance
def __init__(self, cwGUI): self.cwGUI = cwGUI self.locked = False self.utilList = [] self.scriptList = [] self.scriptList.append({'widget':MainScriptEditor(self.cwGUI)}) self.scriptList[0]['filename'] = self.scriptList[0]['widget'].filename self.scriptList[0]['dockname'] = 'Auto-Generated' self.defaultEditor = self.scriptList[0] autogen = (self.defaultEditor['dockname'], self.defaultEditor['filename']) self.preprocessingListGUI = [None, None, None, None] self.setAttack(self.cwGUI.api.valid_attacks.get("CPA", None), blockSignal=True) self.getParams().addChildren([ {'name':'Attack Script', 'type':'group', 'children':[ {'name':'Filename', 'key':'attackfilelist', 'type':'filelist', 'values':{autogen:0}, 'value':0, 'editor':self.editorControl,}, ]}, {'name':'Pre-Processing', 'type':'group', 'children':[ {'name':'Module #%d' % step, 'type':'list', 'values':self.cwGUI.api.valid_preprocessingModules, 'get':partial(self.getPreprocessing, step), 'set':partial(self.setPreprocessing, step)} for step in range(0, len(self.preprocessingListGUI)) ]}, {'name':'Attack', 'type':'group', 'children':[ {'name':'Module', 'type':'list', 'values':self.cwGUI.api.valid_attacks, 'get':self.getAttack, 'set':self.setAttack}, ]}, ]) self.params.init() self.preprocessingParams = Parameter(name="Preprocessing", type='group') self.attackParams = Parameter(name="Attack", type='group') self.params.getChild(['Attack','Module']).stealDynamicParameters(self.attackParams) self.cwGUI.api.sigTracesChanged.connect(self.updateAttackTraceLimits)
def updateParams(self, _=None): rng = self.findParam("range").getValue() # Force to be valid values curval = self.findParam("curval").getValue() curval = max(curval, rng[0]) curval = min(curval, rng[1]) self.findParam("curval").setLimits(rng) self.findParam("curval").setValue(curval) self.paramRange = rng self.paramValueItem = self.findParam("curval") self.paramStep = self.findParam("step").getValue() self.paramRepeat = self.findParam("repeat").getValue() self.paramType = self.findParam("datatype").getValue() try: self.paramScript = eval(self.findParam("parampath").getValue()) except SyntaxError as e: logging.error("Syntax Error: %s" % str(e)) try: Parameter.setParameter(self.paramScript + [curval]) except: pass self.tracesrequired = ( math.ceil(((self.paramRange[1] - self.paramRange[0]) / self.paramStep) * self.paramRepeat) + 1 ) self.tracesreqChanged.emit(self.paramNum, self.tracesrequired)
def findNewValue(self, mode="linear"): """ Find new value for this parameter """ if str.lower(mode) == "linear": self.cnt += 1 if self.cnt == self.paramRepeat: # Done this one, next step self.cnt = 0 newval = self.paramValueItem.getValue() + self.paramStep if newval > self.paramRange[1]: newval = self.paramRange[0] self.rangeComplete.emit(self.paramNum) # Cast type to required value newval = self.paramType(newval) self.paramValueItem.setValue(newval) parameter = self.paramScript + [newval] try: Parameter.setParameter(parameter) except: raise StopIteration("Choose a valid Parameter Path/Value combination. Got: " + str(parameter)) else: raise ValueError("Unknown Increment Type %s" % mode)
def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d' % num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect( self.reloadScripts) par = Parameter(name='Pre-Processing Mod. #%d' % num, type="group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts()
def __init__(self, oa): self.oldlow = None self.oldhigh = None self.oa = oa self.sadref = [0] try: # Update SAD calculation when data changes ResultsBase.registeredObjects["Trace Output Plot"].dataChanged.connect(self.dataChanged) outwid = ResultsBase.registeredObjects["Trace Output Plot"] rangewidget = {'name':'Point Range', 'key':'pointrng', 'type':'rangegraph', 'limits':(0, 0), 'value':(0, 0), 'default':(0, 0), 'graphwidget':outwid, 'action':self.updateSADTraceRef, 'fixedsize':128} except KeyError: rangewidget = {'name':'Point Range', 'key':'pointrng', 'type':'range', 'limits':(0, 0), 'value':(0, 0), 'default':(0, 0), 'action':self.updateSADTraceRef, 'fixedsize':128} self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ # {'name':'Open SAD Viewer', 'type':'action'}, {'name':'SAD Ref From Captured', 'key':'sad', 'type':'group', 'children':[ rangewidget, {'name':'Set SAD Reference from Current Trace', 'key':'docopyfromcapture', 'type':'action', 'action':self.copyFromCaptureTrace}, {'name':'SAD Reference vs. Cursor', 'key':'sadrefcur', 'type':'int', 'value':0, 'limits':(-1, 100E6), 'readonly':True}, ]}, {'name':'SAD Threshold', 'type':'int', 'limits':(0, 100000), 'default':0, 'set':self.setThreshold, 'get':self.getThreshold} ])
def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d'% num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect(self.reloadScripts) par = Parameter(name = 'Pre-Processing Mod. #%d'% num, type = "group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts()
def setupTraceParam(self): #--- find or create group (attack can pre-create the group to influence parameter order) try: self.traceParams = self.findParam('tracesetup') except KeyError: self.traceParams = Parameter(self, name='Trace Setup', key='tracesetup', type='group') self.params.append(self.traceParams) #--- update children self.traceParams.clearChildren() self.traceParams.addChildren([ {'name':'Starting Trace', 'key':'strace', 'type':'int', 'value':0, 'action':self.updateGenericScript}, {'name':'Traces per Attack', 'key':'atraces', 'type':'int', 'limits':(1, 1E6), 'value':1, 'action':self.updateGenericScript}, {'name':'Attack Runs', 'key':'runs', 'type':'int', 'limits':(1, 1E6), 'value':1, 'action':self.updateGenericScript}, {'name':'Reporting Interval', 'key':'reportinterval', 'type':'int', 'value':10, 'action':self.updateGenericScript}, ]) # TODO: # if self.hasMultipleRuns: # else: # if not self.hasMultipleRuns: # self.traceParams.addChildren([ # {'name':'First Trace', 'key':'trace_first', 'type':'int', 'value':0, 'action':self.updateGenericScript}, # {'name':'Last Trace', 'key':'trace_last', 'type':'int', 'value':-1, 'action':self.updateGenericScript}, # ]) self.addFunction("init", "setTraceStart", "0") self.addFunction("init", "setTracesPerAttack", "1") self.addFunction("init", "setIterations", "1") self.addFunction("init", "setReportingInterval", "10")
def __init__(self, api): self._api = api self.valid_preprocessingModules = pluginmanager.getPluginsInDictFromPackage( "chipwhisperer.analyzer.preprocessing", False, False) self.params = Parameter(name="Preprocessing Settings", type='group') self._moduleParams = [ Parameter(name='self.ppmod[%d]' % (i), type='group') for i in range(self._num_modules) ] self._initModules() self.params.addChildren([ { 'name': 'Selected Modules', 'type': 'group', 'children': [{ 'name': 'self.ppmod[%d]' % (step), 'type': 'list', 'values': self.valid_preprocessingModules, 'get': partial(self.getModule, step), 'set': partial(self.setModule, step) } for step in range(0, len(self._modules))] }, ]) for m in self._moduleParams: self.params.append(m)
class ChipWhispererExtra(Parameterized): _name = 'CW Extra' def __init__(self, parentParam, cwtype, scope, oa): #self.cwADV = CWAdvTrigger() if cwtype == "cwrev2": self.cwEXTRA = CWExtraSettings(self, oa) elif cwtype == "cwlite": self.cwEXTRA = CWExtraSettings(self, oa, hasFPAFPB=False, hasGlitchOut=True, hasPLL=False) else: raise ValueError("Unknown ChipWhisperer: %s" % cwtype) self.enableGlitch = True if self.enableGlitch: self.glitch = ChipWhispererGlitch.ChipWhispererGlitch(self, cwtype, scope, oa) self.params = Parameter(name=self.getName(), type='group') self.params.append(self.cwEXTRA.getParams()) self.params.append(self.glitch.getParams()) def armPreScope(self): if self.enableGlitch: self.glitch.armPreScope() def armPostScope(self): if self.enableGlitch: self.glitch.armPostScope()
def __init__(self, standalone=False): self.standalone = standalone self.serialnum = None self.params = Parameter(name=self.getName(), type='group') if standalone: self.setSerial = self._setSerial
def __init__(self): self._attack = None self.valid_attacks = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.attacks", True, True) self.params = Parameter(name="Attack Settings", type="group") self.params.addChildren([ {'name': 'Attack', 'type':'list', 'values':self.valid_attacks, 'get':self.getAttack, 'set':self.setAttack} ])
class OpenADCInterface_FTDI(Parameterized, Plugin): _name = "FTDI (SASEBO-W/SAKURA-G)" def __init__(self, oadcInstance): self.serialNumber = '' self._serialnumbers = [''] self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ { 'name': 'Refresh Device List', 'type': 'action', 'action': self.serialRefresh }, { 'name': 'Device Serial Number', 'key': 'snum', 'type': 'list', 'values': [''], 'get': self.getSerialNumber, 'set': self.setSelectedDevice }, ]) self.ser = None if (openadc_qt is None) or (ft is None): raise ImportError("Needed imports for FTDI missing") else: self.scope = oadcInstance def getSerialNumber(self): return self.serialNumber @setupSetParam("Device Serial Number") def setSelectedDevice(self, snum): self.serialNumber = snum def con(self): if self.ser is None: try: self.dev = ft.openEx(str(self.serialNumber), ft.ftd2xx.OPEN_BY_SERIAL_NUMBER) self.dev.setBitMode(0x00, 0x40) self.dev.setTimeouts(500, 500) self.dev.setLatencyTimer(2) self.ser = self except ft.ftd2xx.DeviceError, e: self.ser = None raise IOError("Could not open %s: %s" % (self.serialNumber, e)) try: self.scope.con(self.ser) logging.info('OpenADC Found, Connecting') except IOError as e: exctype, value = sys.exc_info()[:2] raise IOError("OpenADC Error: %s" % (str(exctype) + str(value)) + " - " + e.message)
def dcmTimeout(self): try: self.qtadc.sc.getStatus() # The following happen with signals, so a failure will likely occur outside of the try...except # For this reason we do the call to .getStatus() to verify USB connection first Parameter.setParameter(['OpenADC', 'Clock Setup', 'Refresh Status', None], blockSignal=True) Parameter.setParameter(['OpenADC', 'Trigger Setup', 'Refresh Status', None], blockSignal=True) except Exception as e: self.dis() raise e
def setupTraceParam(self): self.traceParams = Parameter(self, name='Trace Setup', type='group', children=[ {'name':'Starting Trace', 'key':'strace', 'type':'int', 'value':0, 'action':self.updateGenericScript}, {'name':'Traces per Attack', 'key':'atraces', 'type':'int', 'limits':(1, 1E6), 'value':1, 'action':self.updateGenericScript}, {'name':'Attack Runs', 'key':'runs', 'type':'int', 'limits':(1, 1E6), 'value':1, 'action':self.updateGenericScript}, {'name':'Reporting Interval', 'key':'reportinterval', 'type':'int', 'value':10, 'action':self.updateGenericScript}, ]) self.addFunction("init", "setTraceStart", "0") self.addFunction("init", "setTracesPerAttack", "1") self.addFunction("init", "setIterations", "1") self.addFunction("init", "setReportingInterval", "10")
def __init__(self, prog_name="ChipWhisperer", prog_ver=""): self.valid_traces = None self._trace_format = None self.params = Parameter(name="Project Settings", type="group") self.params.addChildren([ { 'name': 'Trace Format', 'type': 'list', 'values': self.valid_traces, 'get': self.get_trace_format, 'set': self.set_trace_format }, ]) #self.findParam("Trace Format").setValue(TraceContainerNative(project=self), addToList=True) self._trace_format = TraceContainerNative(project=self) #self.traceParam = Parameter(name="Trace Settings", type='group', addLoadSave=True).register() #self.params.getChild('Trace Format').stealDynamicParameters(self.traceParam) self.sigFilenameChanged = util.Signal() self.sigStatusChanged = util.Signal() self.dirty = util.Observable(True) self.settingsDict = { 'Project Name': "Untitled", 'Project File Version': "1.00", 'Project Author': "Unknown" } self.datadirectory = "" self.config = ConfigObjProj(callback=self.configObjChanged) self._traceManager = TraceManager().register() self._traceManager.dirty.connect(self.__dirtyCallback) self.setFilename(Project.untitledFileName) self.setProgramName(prog_name) self.setProgramVersion(prog_ver) self._segments = Segments(self) self._traces = Traces(self) self._keys = IndividualIterable(self._traceManager.get_known_key, self._traceManager.num_traces) self._textins = IndividualIterable(self._traceManager.get_textin, self._traceManager.num_traces) self._textouts = IndividualIterable(self._traceManager.get_textout, self._traceManager.num_traces) self._waves = IndividualIterable(self._traceManager.get_trace, self._traceManager.num_traces) if __debug__: logging.debug('Created: ' + str(self))
def setupPointsParam(self): #--- find or create group (attack can pre-create the group to influence parameter order) try: self.pointsParams = self.findParam('pointsetup') except KeyError: self.pointsParams = Parameter(self, name='Point Setup', key='pointsetup', type='group') self.params.append(self.pointsParams) #--- update children self.pointsParams.clearChildren() self.pointsParams.addChildren(self.getPointList())
def dcmTimeout(self): if self.connectStatus.value(): try: self.qtadc.sc.getStatus() # The following happen with signals, so a failure will likely occur outside of the try...except # For this reason we do the call to .getStatus() to verify USB connection first Parameter.setParameter(['OpenADC', 'Clock Setup', 'Refresh Status', None], blockSignal=True) Parameter.setParameter(['OpenADC', 'Trigger Setup', 'Refresh Status', None], blockSignal=True) except USBError: self.dis() raise Warning("Error in the scope. It may have been disconnected.") except Exception as e: self.dis() raise e
class OpenADCInterface_FTDI(Parameterized, Plugin): _name = "FTDI (SASEBO-W/SAKURA-G)" def __init__(self, oadcInstance): self.serialNumber = '' self._serialnumbers = [''] self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh Device List', 'type':'action', 'action':self.serialRefresh}, {'name':'Device Serial Number', 'key':'snum', 'type':'list', 'values':[''], 'get':self.getSerialNumber, 'set':self.setSelectedDevice}, ]) self.ser = None if (openadc_qt is None) or (ft is None): raise ImportError("Needed imports for FTDI missing") else: self.scope = oadcInstance def getSerialNumber(self): return self.serialNumber @setupSetParam("Device Serial Number") def setSelectedDevice(self, snum): self.serialNumber = snum def __del__(self): if self.ser != None: self.ser.close() def con(self): if self.ser == None: try: self.dev = ft.openEx(str(self.serialNumber), ft.ftd2xx.OPEN_BY_SERIAL_NUMBER) self.dev.setBitMode(0x00, 0x40) self.dev.setTimeouts(500, 500) self.dev.setLatencyTimer(2) self.ser = self except ft.ftd2xx.DeviceError, e: self.ser = None raise IOError("Could not open %s: %s" % (self.serialNumber, e)) try: self.scope.con(self.ser) print("OpenADC Found, Connecting") except IOError,e: exctype, value = sys.exc_info()[:2] raise IOError("OpenADC Error: %s"%(str(exctype) + str(value)) + " - " + e.message)
def __init__(self, cwGUI): self.cwGUI = cwGUI self.locked = False self.utilList = [] self.scriptList = [] self.scriptList.append({'widget':MainScriptEditor(self.cwGUI)}) self.scriptList[0]['filename'] = self.scriptList[0]['widget'].filename self.scriptList[0]['dockname'] = 'Auto-Generated' self.defaultEditor = self.scriptList[0] autogen = (self.defaultEditor['dockname'], self.defaultEditor['filename']) self.preprocessingListGUI = [None, None, None, None] self.setAttack(self.cwGUI.api.valid_attacks.get("CPA", None), blockSignal=True) self.getParams().addChildren([ {'name':'Attack Script', 'type':'group', 'children':[ {'name':'Filename', 'key':'attackfilelist', 'type':'filelist', 'values':{autogen:0}, 'value':0, 'editor':self.editorControl,}, ]}, {'name':'Pre-Processing', 'type':'group', 'children':[ {'name':'Module #%d' % step, 'type':'list', 'values':self.cwGUI.api.valid_preprocessingModules, 'get':partial(self.getPreprocessing, step), 'set':partial(self.setPreprocessing, step)} for step in range(0, len(self.preprocessingListGUI)) ]}, {'name':'Attack', 'type':'group', 'children':[ {'name':'Module', 'type':'list', 'values':self.cwGUI.api.valid_attacks, 'get':self.getAttack, 'set':self.setAttack}, ]}, ]) self.params.init() self.preprocessingParams = Parameter(name="Preprocessing", type='group') self.attackParams = Parameter(name="Attack", type='group') self.params.getChild(['Attack','Module']).stealDynamicParameters(self.attackParams) self.cwGUI.api.sigTracesChanged.connect(self.updateAttackTraceLimits)
def __init__(self, oa): self.oldlow = None self.oldhigh = None self.oa = oa self.sadref = [0] try: # Update SAD calculation when data changes ResultsBase.registeredObjects["Trace Output Plot"].dataChanged.connect(self.dataChanged) outwid = ResultsBase.registeredObjects["Trace Output Plot"] rangewidget = {'name':'Point Range', 'key':'pointrng', 'type':'rangegraph', 'limits':(0, 0), 'value':(0, 0), 'default':(0, 0), 'graphwidget':outwid, 'action':self.updateSADTraceRef, 'fixedsize':128} except KeyError: rangewidget = {'name':'Point Range', 'key':'pointrng', 'type':'range', 'limits':(0, 0), 'value':(0, 0), 'default':(0, 0), 'action':self.updateSADTraceRef, 'fixedsize':128} self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ # {'name':'Open SAD Viewer', 'type':'action'}, {'name':'SAD Ref From Captured', 'key':'sad', 'type':'group', 'children':[ rangewidget, {'name':'Set SAD Reference from Current Trace', 'key':'docopyfromcapture', 'type':'action', 'action':self.copyFromCaptureTrace}, {'name':'SAD Reference vs. Cursor', 'key':'sadrefcur', 'type':'int', 'value':0, 'limits':(-1, 100E6), 'readonly':True}, ]}, {'name':'SAD Threshold', 'type':'int', 'limits':(0, 100000), 'default':0, 'set':self.setThreshold, 'get':self.getThreshold} ])
def __init__(self, standalone=False): self.standalone = standalone self.serialnum = None self.params = Parameter(name=self.getName(), type='group') if standalone: self.setSerial = self._setSerial
class AttackSettings(Parameterized): def __init__(self): self._attack = None self.valid_attacks = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.attacks", True, True) self.params = Parameter(name="Attack Settings", type="group") self.params.addChildren([ {'name': 'Attack', 'type':'list', 'values':self.valid_attacks, 'get':self.getAttack, 'set':self.setAttack} ]) @setupSetParam("Attack") def setAttack(self, atk): self._attack = atk if self._attack is not None: self.params.append(self._attack.params) def getAttack(self): return self._attack
def __init__(self, parentParam=None, configfile=None): self.configfile = configfile self.fmt = None self.params = Parameter(name=self._name, type='group').register() self.params.addChildren([ {'name':'Config File', 'key':'cfgfile', 'type':'str', 'readonly':True, 'value':''}, {'name':'Format', 'key':'format', 'type':'str', 'readonly':True, 'value':''}, ]) self.clear()
def __init__(self, oaiface, hwinfo=None): self.oa = oaiface self._hwinfo = hwinfo self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh Status', 'type':'action', 'linked':[('ADC Clock', 'DCM Locked'), ('ADC Clock', 'ADC Freq'), ('CLKGEN Settings', 'DCM Locked'), 'Freq Counter'], 'help':'%namehdr%' + 'Update if the Digital Clock Manager (DCM) are "locked" and their operating frequency.'}, {'name':'Reset DCMs', 'type':'action', 'action':self.resetDcms, 'linked':[('CLKGEN Settings', 'Multiply'), ('CLKGEN Settings', 'Divide')], 'help':'%namehdr%' + 'When the input frequency to the DCM blocks changes, it can cause them to become "unlocked". When they are "unlocked" they are NOT ' + 'generating a reliable output frequency. You must press the "Reset" button to cause them to re-lock. This is currently not automatically ' + 'done as during regular operation they shouldn\'t become unlocked.\n\nHowever every time you change the DCM block source, it will cause ' + 'the blocks to lose lock.'}, {'name': 'ADC Clock', 'type':'group', 'children': [ {'name': 'Source', 'type':'list', 'values':{"EXTCLK Direct":("extclk", 4, "clkgen"), "EXTCLK x4 via DCM":("dcm", 4, "extclk"), "EXTCLK x1 via DCM":("dcm", 1, "extclk"), "CLKGEN x4 via DCM":("dcm", 4, "clkgen"), "CLKGEN x1 via DCM":("dcm", 1, "clkgen")}, 'set':self.setAdcSource, 'get':self.adcSource, 'help':'%namehdr%' + 'The ADC sample clock is generated from this source. Options are either an external input (which input set elsewhere) or an internal clock generator. Details of each option:\n\n' + '=================== ====================== =================== ===============\n' + ' Name Description Input Freq Range Fine Phase Adj.\n' + '=================== ====================== =================== ===============\n' + ' EXCLK Direct Connects sample clock 1-105 MHz NO\n' + ' external pin directly.\n' + ' EXTCLK xN via DCM Takes external pin, 5-105 MHz (x1) YES\n\n' + ' multiplies frequency 5-26.25 MHz (x4) \n\n' + ' xN and feeds to ADC. \n' + ' CLKGEN xN via DCM Multiples CLKGEN by 5-105 MHz (x1) YES\n\n' + ' xN and feeds to ADC. 5-26.25 MHz (x4) \n\n' + '=================== ====================== =================== ===============\n'}, {'name': 'Phase Adjust', 'type':'int', 'limits':(-255, 255), 'set':self.setPhase, 'get':self.phase, 'help':'%namehdr%' + 'Makes small amount of adjustment to sampling point compared to the clock source. This can be used to improve the stability ' + 'of the measurement. Total phase adjustment range is < 5nS regardless of input frequency.'}, {'name': 'ADC Freq', 'type': 'int', 'siPrefix':True, 'suffix': 'Hz', 'readonly':True, 'get':self.adcFrequency}, {'name': 'DCM Locked', 'type':'bool', 'get':self.dcmADCLocked, 'readonly':True}, {'name':'Reset ADC DCM', 'type':'action', 'action':lambda _ : self.resetDcms(True, False), 'linked':['Phase Adjust']}, ]}, {'name': 'Freq Counter', 'type': 'str', 'readonly':True, 'get':lambda: str(self.extFrequency()) + " Hz"}, {'name': 'Freq Counter Src', 'type':'list', 'values':{'EXTCLK Input':0, 'CLKGEN Output':1}, 'set':self.setFreqSrc, 'get':self.freqSrc}, {'name': 'CLKGEN Settings', 'type':'group', 'children': [ {'name':'Input Source', 'type':'list', 'values':["system", "extclk"], 'set':self.setClkgenSrc, 'get':self.clkgenSrc}, {'name':'Multiply', 'type':'int', 'limits':(2, 256), "default":2, 'set':self.setClkgenMul, 'get':self.clkgenMul, 'linked':['Current Frequency']}, {'name':'Divide', 'type':'int', 'limits':(1, 256), 'set':self.setClkgenDiv, 'get':self.clkgenDiv, 'linked':['Current Frequency']}, {'name':'Desired Frequency', 'type':'float', 'limits':(3.3E6, 200E6), 'default':0, 'step':1E6, 'siPrefix':True, 'suffix':'Hz', 'set':self.autoMulDiv, 'get':self.getClkgen, 'linked':['Multiply', 'Divide']}, {'name':'Current Frequency', 'type':'str', 'default':0, 'readonly':True, 'get':lambda: str(self.getClkgen()) + " Hz"}, {'name':'DCM Locked', 'type':'bool', 'default':False, 'get':self.clkgenLocked, 'readonly':True}, {'name':'Reset CLKGEN DCM', 'type':'action', 'action':lambda _ : self.resetDcms(False, True), 'linked':['Multiply', 'Divide']}, ]} ]) self.params.refreshAllParameters()
def __init__(self, parent): super(GlitchExplorerDialog, self).__init__(parent) self.setWindowTitle("Glitch Explorer") self.setMinimumWidth(500) self.mainLayout = QVBoxLayout() self.mainSplitter = QSplitter(self) self.mainSplitter.setOrientation(Qt.Vertical) self.tableList = [] self.tuneParamList = [] #Add default table self.table = QTableWidget(1,1) # self.table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.mainSplitter.addWidget(self.table) self.getParams().register() self.getParams().addChildren([ {'name':'Clear Output Table', 'type':'action', 'action':self.clearTable}, {'name':'Plot Widget', 'type':'action', 'action':self.openPlotWidget}, {'name':'Reset', 'type':'action', 'action':self.reset, 'tip':"Resets all Tuning Parameters to its minimum value."}, {'name':'Tuning Parameters', 'key':'numtune', 'type':'int', 'value':0, 'limits':(0, 4), 'action':self.updateParameters, 'readonly':False}, {'name':'Traces Required', 'key':'tracesreq', 'type':'int', 'value':1, 'limits':(1, 1E99), 'readonly':True, 'children':[ {'name':'Use this value', 'type':'action', 'action':lambda _: Parameter.setParameter(['Generic Settings', 'Acquisition Settings', 'Number of Traces',self.findParam('tracesreq').getValue()])}, ]}, {'name':'Normal Response', 'type':'str', 'key':'normalresp', 'value':'s.startswith("Bad")'}, {'name':'Successful Response', 'type':'str', 'key':'successresp', 'value':'s.startswith("Welcome")'}, {'name':'Recordings', 'type':'group', 'expanded':False, 'children':[ {'name':'Load existing', 'type':'action', 'key':'open', 'action':lambda _:self.loadRecordings()}, {'name':'Autosave Multi-Capture Results', 'type':'bool', 'key':'saveresults', 'value':True}, {'name':'Autosaved filename', 'type':'str', 'key':'savefilename', 'value':'', "readonly":True}, {'name':'Notes', 'type':'text', 'key':'savenotes', 'value':""}, ]}, ]) self.paramTree = ParameterTree() self.paramTree.addParameters(self.getParams()._PyQtGraphParameter) self.mainSplitter.addWidget(self.paramTree) self.statusLabel = QLabel("") self.mainSplitter.addWidget(self.statusLabel) # self.mainSplitter.setHandleWidth(100) self.mainLayout.addWidget(self.mainSplitter) self.setLayout(self.mainLayout) self.hide() #Do an update self.table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.table.horizontalHeader().setResizeMode(QHeaderView.Interactive) self.clearTable() self._campaignRunning = False
def __init__(self, oadcInstance): self.portName = '' self.ser = None self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh List', 'type':'action', 'action':self.serialRefresh}, {'name':'Selected Port', 'type':'list', 'values':[''], 'get':self.getPortName, 'set':self.setPortName}, ]) self.scope = oadcInstance
def __init__(self, oadcInstance): self.portName = '' self.ser = None self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ { 'name': 'Refresh List', 'type': 'action', 'action': self.serialRefresh }, { 'name': 'Selected Port', 'type': 'list', 'values': [''], 'get': self.getPortName, 'set': self.setPortName }, ]) self.scope = oadcInstance
def setupTraceParam(self): self.traceParams = Parameter(self, name='Trace Setup', type='group', children=[ {'name':'Starting Trace', 'key':'strace', 'type':'int', 'value':0, 'action':lambda _:self.updateGenericScript()}, {'name':'Traces per Attack', 'key':'atraces', 'type':'int', 'limits':(1, 1E6), 'value':1, 'action':lambda _:self.updateGenericScript()}, {'name':'Attack Runs', 'key':'runs', 'type':'int', 'limits':(1, 1E6), 'value':1, 'action':lambda _:self.updateGenericScript()}, {'name':'Reporting Interval', 'key':'reportinterval', 'type':'int', 'value':10, 'action':lambda _:self.updateGenericScript()}, ]) self.addFunction("init", "setTraceStart", "0") self.addFunction("init", "setTracesPerAttack", "1") self.addFunction("init", "setIterations", "1") self.addFunction("init", "setReportingInterval", "10")
def __init__(self): logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) CWCoreAPI.instance = self self.sigNewProject = util.Signal() self.sigConnectStatus = util.Signal() self.sigAttackChanged = util.Signal() self.sigNewInputData = util.Signal() self.sigNewTextResponse = util.Signal() self.sigTraceDone = util.Signal() self.sigCampaignStart = util.Signal() self.sigCampaignDone = util.Signal() self.executingScripts = util.Observable(False) self.valid_scopes = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.scopes", True, True) self.valid_targets = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.targets", True, True) self.valid_traces = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.common.traces", True, True) self.valid_aux = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.auxiliary", True, True) self.valid_acqPatterns = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.acq_patterns", True, False) self.settings = Settings() # Initialize default values self._project = self._scope = self._target = self._traceFormat = self._acqPattern = self._attack = None self._acqPattern = self.valid_acqPatterns["Basic"] self._auxList = AuxList() self._numTraces = 50 self._numTraceSets = 1 # Storage for last key/plaintext/ciphertext self._lastKey = None self._lastTextin = None self._lastTextout = None self._lastExpected = None self.params = Parameter(name='Generic Settings', type='group', addLoadSave=True).register() self.params.addChildren([ {'name':'Scope Module', 'key':'scopeMod', 'type':'list', 'values':self.valid_scopes, 'get':self.getScope, 'set':self.setScope}, {'name':'Target Module', 'key':'targetMod', 'type':'list', 'values':self.valid_targets, 'get':self.getTarget, 'set':self.setTarget}, {'name':'Acquisition Settings', 'type':'group', 'children':[ {'name':'Number of Traces', 'type':'int', 'limits':(1, 1E9), 'get':self.getNumTraces, 'set':self.setNumTraces, 'linked':['Traces per Set']}, {'name':'Number of Sets', 'type':'int', 'limits':(1, 1E6), 'get':self.getNumTraceSets, 'set':self.setNumTraceSets, 'linked':['Traces per Set'], 'tip': 'Break acquisition into N sets, ' 'which may cause data to be saved more frequently. The default capture driver requires that NTraces/NSets is small enough to avoid running out of system memory ' 'as each segment is buffered into RAM before being written to disk.'}, {'name':'Traces per Set', 'type':'int', 'readonly':True, 'get':self.tracesPerSet}, {'name':'Key/Text Pattern', 'type':'list', 'values':self.valid_acqPatterns, 'get':self.getAcqPattern, 'set':self.setAcqPattern}, ]}, ]) self.scopeParam = Parameter(name="Scope Settings", type='group', addLoadSave=True).register() self.params.getChild('Scope Module').stealDynamicParameters(self.scopeParam) self.targetParam = Parameter(name="Target Settings", type='group', addLoadSave=True).register() self.params.getChild('Target Module').stealDynamicParameters(self.targetParam) # Aux settings self.auxParam = self._auxList.getParams().register() # Note: Project settings are set up in setProject() self.newProject()
def __init__(self, oaiface): self.oa = oaiface self.oa.hwInfo = self self.sysFreq = 0 self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name': 'Version', 'type': 'str', 'get':self.versions, 'readonly':True}, {'name': 'Synth Date', 'type': 'str', 'get':self.synthDate, 'readonly':True}, {'name': 'System Freq', 'type': 'int', 'siPrefix':True, 'suffix': 'Hz', 'get':self.sysFrequency, 'readonly':True}, {'name': 'Max Samples', 'type': 'int', 'get':self.maxSamples, 'readonly':True} ]) self.vers = None
def reloadGuiActions(self): # Remove all old actions that don't apply for new selection if hasattr(self, "_ToolMenuItems"): for act in self._ToolMenuItems: self.toolMenu.removeAction(act) self._ToolMenuItems = [] self._ToolMenuItems.append(self.toolMenu.addSeparator()) for act in Parameter.getAllParameters("menu"): self._ToolMenuItems.append(QAction(act.getName(), self, statusTip=act.getTip(), triggered=act.callAction)) for act in self._ToolMenuItems: self.toolMenu.addAction(act)
def reloadGuiActions(self): # Remove all old actions that don't apply for new selection if hasattr(self,"_ToolMenuItems"): for act in self._ToolMenuItems: self.toolMenu.removeAction(act) self._ToolMenuItems = [] self._ToolMenuItems.append(self.toolMenu.addSeparator()) for act in Parameter.getAllParameters("menu"): self._ToolMenuItems.append(QAction(act.getName(), self, statusTip=act.getTip(), triggered=act.callAction)) for act in self._ToolMenuItems: self.toolMenu.addAction(act)
def setupCommonScripts(self): # Setup parameer tree self.getParams().addChildren([{ 'name': 'Enabled', 'key': 'enabled', 'type': 'bool', 'default': self.getEnabled(), 'get': self.getEnabled, 'set': self.setEnabled }]) self.commonScriptParams = [] self.paramCommonScripts = Parameter(name='Common Scripts', type='group', children=self.commonScriptParams) for example in self.exampleScripts: self.paramCommonScripts.append(example.getParams()) example.scriptsUpdated.connect(self.updateScripts) example.runScriptFunction.connect(self.runScriptFunction.emit) self.getParams().append(self.paramCommonScripts) self.paramCommonScripts.hide() self.updateScripts()
def __init__(self, parentParam, oadcInstance): self.portName = '' self.ser = None self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh List', 'type':'action', 'action':lambda _: self.serialRefresh()}, {'name':'Selected Port', 'type':'list', 'values':[''], 'get':self.getPortName, 'set':self.setPortName}, ]) if (openadc_qt is None) or (serial is None): raise ImportError("Needed imports for serial missing") else: self.scope = oadcInstance
def __init__(self, oaiface): self.oa = oaiface self.maxsamples = 0 self.presamples_desired = 0 self.presamples_actual = 0 self.presampleTempMargin = 24 self._timeout = 2 self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name': 'Refresh Status', 'type':'action', 'linked':['Digital Pin State'], 'visible':False, 'help':'%namehdr%'+ 'Refreshes the "Digital Pin State" status.'}, {'name': 'Source', 'type': 'list', 'values':["digital", "analog"], 'set':self.setSource, 'get':self.source, 'help':'%namehdr%'+ 'Selects if trigger system is based on digital signal (including internally generated), or an ADC level. Currently ' + 'only the digital trigger system is supported.'}, {'name': 'Digital Pin State', 'type':'bool', 'readonly':True, 'get':self.extTriggerPin, 'help':'%namehdr%'+ 'Gives the status of the digital signal being used as the trigger signal, either high or low.'}, {'name': 'Mode', 'type':'list', 'values':["rising edge", "falling edge", "low", "high"], 'default':"low", 'set':self.setMode, 'get':self.mode, 'help':'%namehdr%'+ 'When using a digital system, sets the trigger mode:\n\n' ' =============== ==============================\n' + ' Mode Description\n' + ' =============== ==============================\n' + ' Rising Edge Trigger on rising edge only.\n' + ' Falling Edge Trigger on falling edge only.\n' + ' Low Trigger when line is "low".\n' + ' High Trigger when line is "high".\n' + ' =============== ==============================\n\n' + 'Note the "Trigger Mode" should be set to "Rising Edge" if using either the "SAD Trigger" or "IO Trigger" modes.' }, {'name': 'Timeout (secs)', 'type':'float', 'step':1, 'limits':(0, 1E99), 'set':self.setTimeout, 'get':self.timeout, 'help':'%namehdr%'+ 'If no trigger occurs in this many seconds, force the trigger.'}, {'name': 'Offset', 'type':'int', 'limits':(0, 4294967294), 'set':self.setOffset, 'get':self.offset, 'help':'%namehdr%'+ 'Delays this many samples after the trigger event before recording samples. Based on the ADC clock cycles. ' + 'If using a 4x mode for example, an offset of "1000" would mean we skip 250 cycles of the target device.'}, {'name': 'Pre-Trigger Samples', 'type':'int', 'limits':(0, 1000000), 'set':self.setPresamples, 'get':self.presamples, 'help':'%namehdr%'+ 'Record a certain number of samples before the main samples are captured. If "offset" is set to 0, this means ' + 'recording samples BEFORE the trigger event.'}, {'name': 'Total Samples', 'type':'int', 'limits':(0, 1000000), 'set':self.setMaxSamples, 'get':self.maxSamples, 'help':'%namehdr%'+ 'Total number of samples to record. Note the api system has an upper limit, and may have a practical lower limit (i.e.,' + ' if this value is set too low the system may not api samples. Suggest to always set > 256 samples.'}, ])
def __init__(self, oadcInstance): self.serialNumber = '' self._serialnumbers = [''] self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh Device List', 'type':'action', 'action':self.serialRefresh}, {'name':'Device Serial Number', 'key':'snum', 'type':'list', 'values':[''], 'get':self.getSerialNumber, 'set':self.setSelectedDevice}, ]) self.ser = None if (openadc_qt is None) or (ft is None): raise ImportError("Needed imports for FTDI missing") else: self.scope = oadcInstance
def copyFromCaptureTrace(self, _=None): """ Send reference data to hardware from the trace window """ ds_param = Parameter.findParameter( ['OpenADC', 'Trigger Setup', 'Downsample Factor']) if ds_param is not None and ds_param.getValue() != 1: logging.warning( "OpenADC downsampling is enabled - SAD trigger will not work") data = self.getCaptueTraceRef() if len(data) != 128: logging.warning('Reference IS NOT 128 samples long, got %d' % len(data)) self.findParam(['sad', 'sadref']).setValue(self.packTrace(data))
def setupCommonScripts(self): # Setup parameer tree self.getParams().addChildren([ {'name':'Enabled', 'key':'enabled', 'type':'bool', 'default':self.getEnabled(), 'get':self.getEnabled, 'set':self.setEnabled} ]) self.commonScriptParams = [] self.paramCommonScripts = Parameter(name='Common Scripts', type='group', children=self.commonScriptParams) for example in self.exampleScripts: self.paramCommonScripts.append(example.getParams()) example.scriptsUpdated.connect(self.updateScripts) example.runScriptFunction.connect(self.runScriptFunction.emit) self.getParams().append(self.paramCommonScripts) self.paramCommonScripts.hide() self.updateScripts()
def __init__(self): super(AuxList, self).__init__() self._next_id = 1 # List aux modules and parameter groups for each timing self._aux_items = OrderedDict() self._param_groups = {} for t in self._valid_timings.keys(): self._aux_items[t] = [] self._param_groups[t] = Parameter(name=self._valid_timings[t], type='group') self.getParams().append(self._param_groups[t]) self.getParams().addChildren([ {'name':'Help', 'type':'action', 'action':self._showHelp} ]) self.getParams().refreshAllParameters()
def setTriggerModule(self, module): #When using special modes, force rising edge & stop user from easily changing if module != self.MODULE_BASIC: Parameter.findParameter(['OpenADC', 'Trigger Setup', 'Mode']).setValue("rising edge", ignoreReadonly=True) Parameter.findParameter(['OpenADC', 'Trigger Setup', 'Mode']).setReadonly(True) else: Parameter.findParameter(['OpenADC', 'Trigger Setup', 'Mode']).setReadonly(False) resp = self.oa.sendMessage(CODE_READ, ADDR_TRIGMOD, Validate=False, maxResp=1) resp[0] &= 0xF8 resp[0] |= module self.oa.sendMessage(CODE_WRITE, ADDR_TRIGMOD, resp)
def setTriggerModule(self, module): #When using special modes, force rising edge & stop user from easily changing if module != self.MODULE_BASIC: Parameter.findParameter(['OpenADC', 'Trigger Setup', 'Mode']).setValue("rising edge", ignoreReadonly=True) Parameter.findParameter(['OpenADC', 'Trigger Setup', 'Mode']).setReadonly(True) else: Parameter.findParameter(['OpenADC', 'Trigger Setup', 'Mode']).setReadonly(False) resp = self.oa.sendMessage(CODE_READ, ADDR_TRIGMOD, Validate=False, maxResp=1) resp[0] &= 0xF8 resp[0] |= module self.oa.sendMessage(CODE_WRITE, ADDR_TRIGMOD, resp)
def __init__(self, oaiface): self.oa = oaiface self.gainlow_cached = False self.gain_cached = 0 self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name': 'Mode', 'type': 'list', 'values': {"high", "low"}, 'default': 'low', 'set':self.setMode, 'get':self.mode, 'help': '%namehdr%'+ 'Sets the AD8331 Low Noise Amplifier into to "High" or "Low" gain mode. Low mode ranges from ' + '-4.5dB to +43.5dB, and High mode ranges from +7.5dB to +55.5dB. Better performance is found ' + 'using the "High" gain mode typically.'}, {'name': 'Setting', 'type': 'int', 'limits': (0, 78), 'default': 0, 'set':self.setGain, 'get':self.gain, 'linked':['Result'], 'help':'%namehdr%'+ 'Sets the AD8331 gain value. This is a unitless number which ranges from 0 (minimum) to 78 (maximum).' + ' The resulting gain in dB is given in the "calculated" output.'}, {'name': 'Result', 'type': 'float', 'suffix':'dB', 'readonly':True, 'get':self.gainDB, 'help':'%namehdr%'+ 'Gives the gain the AD8331 should have, based on the "High/Low" setting and the "gain setting".'}, ])
class ChipWhispererComm(Parameterized): _name = "Sakurag" CODE_READ = 0x80 CODE_WRITE = 0xC0 ADDR_STATUS = 49 ADDR_FIFO = 50 FLAG_RESET = 0x01 FLAG_WRFULL = 0x02 FLAG_RDEMPTY = 0x04 def __init__(self, standalone=False): self.standalone = standalone self.serialnum = None self.params = Parameter(name=self.getName(), type='group') if standalone: self.setSerial = self._setSerial def _setSerial(self, serialnum): self.serialnum = serialnum def reset(self): self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) time.sleep(0.05) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) def con(self, scope = None): if scope and scope.qtadc and scope.qtadc.sc: self.oa = scope.qtadc.sc else: if self.serialnum is not None: self.qtadc = openadc_qt.OpenADCQt() self.params.append(self.qtadc.getParams()) self.oaiface = ftdi.OpenADCInterface_FTDI(None, self.qtadc) self.params.append(self.oaiface.getParams()) self.oaiface.setSerialNumberLimits([self.serialnum]) self.oaiface.setSelectedDevice(self.serialnum) self.oaiface.con() self.oa = self.qtadc.sc else: raise Warning("No OpenADC detected - did you connect in scope module already and/or set serial number (hit 'REFRESH')?") # Reset AES Core self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) return True def disconnect(self): return def flush(self): while (self.readStatus() & self.FLAG_RDEMPTY) != self.FLAG_RDEMPTY: self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) def readStatus(self): b = self.oa.sendMessage(self.CODE_READ, self.ADDR_STATUS, Validate=False) return b[0] def writeMsg(self, msg): for b in msg: # while (self.readStatus() & self.FLAG_WRFULL) == self.FLAG_WRFULL: # pass self.oa.sendMessage(self.CODE_WRITE, self.ADDR_FIFO, [b], Validate=False) def readMsg(self, nbytes): msg = bytearray() for i in range(0, nbytes): if self.readStatus() & self.FLAG_RDEMPTY: pass b = self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) msg.append(b[0]) return msg def write(self, address, MSB, LSB): msg = bytearray(5) msg[0] = 0x01 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB msg[3] = MSB msg[4] = LSB # msg = bytearray(strmsg) # print "Write: %x %x %x %x %x"%(msg[0],msg[1],msg[2],msg[3],msg[4]) self.writeMsg(msg) def read(self, address): self.flush() msg = bytearray(3) msg[0] = 0x00 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB self.writeMsg(msg) # print "Write: %x %x %x"%(msg[0],msg[1],msg[2]), msg = self.readMsg(2) # print " Read: %x %x"%(msg[0],msg[1]) # Order = MSB, LSB return msg def read128(self, address): self.flush() msg = bytearray(3 * 8) for i in range(0, 8): msg[i * 3] = 0x00 msg[i * 3 + 1] = (address >> 8) & 0xFF msg[i * 3 + 2] = (address & 0xFF) + (i * 2) self.writeMsg(str(msg)) msg = self.readMsg(16) return bytearray(msg) def close(self): pass
class OpenADCInterface_FTDI(Parameterized): _name = "FTDI (SASEBO-W/SAKURA-G)" def __init__(self, oadcInstance): self.serialNumber = '' self._serialnumbers = [''] self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh Device List', 'type':'action', 'action':self.serialRefresh}, {'name':'Device Serial Number', 'key':'snum', 'type':'list', 'values':[''], 'get':self.getSerialNumber, 'set':self.setSelectedDevice}, ]) self.ser = None if (openadc_qt is None) or (ft is None): raise ImportError("Needed imports for FTDI missing") else: self.scope = oadcInstance def getSerialNumber(self): return self.serialNumber @setupSetParam("Device Serial Number") def setSelectedDevice(self, snum): self.serialNumber = snum def con(self): if self.ser is None: try: self.dev = ft.openEx(str(self.serialNumber), ft.ftd2xx.OPEN_BY_SERIAL_NUMBER) self.dev.setBitMode(0x00, 0x40) self.dev.setTimeouts(500, 500) self.dev.setLatencyTimer(2) self.ser = self except ft.ftd2xx.DeviceError as e: self.ser = None raise IOError("Could not open %s: %s" % (self.serialNumber, e)) try: self.scope.con(self.ser) logging.info('OpenADC Found, Connecting') except IOError as e: exctype, value = sys.exc_info()[:2] raise IOError("OpenADC Error: %s" % (str(exctype) + str(value)) + " - " + e.message) def dis(self): self.ser = None if hasattr(self, 'dev'): self.dev.close() del self.dev def __del__(self): self.dis() def serialRefresh(self, _=None): serialnames = ft.listDevices() if serialnames == None: serialnames = [""] self.setSerialNumberLimits(serialnames) self.findParam('snum').setValue(serialnames[0]) def setSerialNumberLimits(self, newitems): for s in newitems: if s not in self._serialnumbers: self._serialnumbers.append(s) self.findParam('snum').setLimits(self._serialnumbers) def read(self, N=0, debug=False): return bytearray(self.dev.read(N)) def write(self, data, debug=False): return self.dev.write(data)
def __init__(self): CWCoreAPI.instance = self self.sigNewProject = util.Signal() self.sigNewScopeData = util.Signal() self.sigConnectStatus = util.Signal() self.sigAttackChanged = util.Signal() self.sigNewInputData = util.Signal() self.sigNewTextResponse = util.Signal() self.sigTraceDone = util.Signal() self.sigCampaignStart = util.Signal() self.sigCampaignDone = util.Signal() self.sigTracesChanged = util.Signal() self.executingScripts = util.Observable(False) self.valid_scopes = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.scopes", True, True) self.valid_targets = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.targets", True, True) self.valid_traces = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.common.traces", True, True) self.valid_aux = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.auxiliary", True, True) self.valid_acqPatterns = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.acq_patterns", True, False) self.valid_attacks = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.attacks", True, False) self.valid_preprocessingModules = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.preprocessing", False, True) self.settings = Settings() # Initialize default values self._project = self._scope = self._target = self._attack = self._traceFormat = self._acqPattern = None self._attack = self.valid_attacks.get("CPA", None) self._acqPattern = self.valid_acqPatterns["Basic"] self._auxList = [None] # TODO: implement it as a list in the whole class self._numTraces = 50 self._numTraceSets = 1 self.params = Parameter(name='Generic Settings', type='group', addLoadSave=True).register() self.params.addChildren([ {'name':'Scope Module', 'key':'scopeMod', 'type':'list', 'values':self.valid_scopes, 'get':self.getScope, 'set':self.setScope}, {'name':'Target Module', 'key':'targetMod', 'type':'list', 'values':self.valid_targets, 'get':self.getTarget, 'set':self.setTarget}, {'name':'Trace Format', 'type':'list', 'values':self.valid_traces, 'get':self.getTraceFormat, 'set':self.setTraceFormat}, {'name':'Auxiliary Module', 'type':'list', 'values':self.valid_aux, 'get':self.getAuxModule, 'set':self.setAux}, {'name':'Acquisition Settings', 'type':'group', 'children':[ {'name':'Number of Traces', 'type':'int', 'limits':(1, 1E9), 'get':self.getNumTraces, 'set':self.setNumTraces, 'linked':['Traces per Set']}, {'name':'Number of Sets', 'type':'int', 'limits':(1, 1E6), 'get':self.getNumTraceSets, 'set':self.setNumTraceSets, 'linked':['Traces per Set'], 'tip': 'Break acquisition into N sets, ' 'which may cause data to be saved more frequently. The default capture driver requires that NTraces/NSets is small enough to avoid running out of system memory ' 'as each segment is buffered into RAM before being written to disk.'}, {'name':'Traces per Set', 'type':'int', 'readonly':True, 'get':self.tracesPerSet}, {'name':'Key/Text Pattern', 'type':'list', 'values':self.valid_acqPatterns, 'get':self.getAcqPattern, 'set':self.setAcqPattern}, ]}, ]) self.scopeParam = Parameter(name="Scope Settings", type='group', addLoadSave=True).register() self.params.getChild('Scope Module').stealDynamicParameters(self.scopeParam) self.targetParam = Parameter(name="Target Settings", type='group', addLoadSave=True).register() self.params.getChild('Target Module').stealDynamicParameters(self.targetParam) self.traceParam = Parameter(name="Trace Settings", type='group', addLoadSave=True).register() self.params.getChild('Trace Format').stealDynamicParameters(self.traceParam) self.auxParam = Parameter(name="Aux Settings", type='group', addLoadSave=True).register() self.params.getChild('Auxiliary Module').stealDynamicParameters(self.auxParam) # self.attackParam = Parameter(name="Attack Settings", type='group') # self.params.getChild('Attack Module').getDynamicParameters(self.attackParam) self.newProject()
def setParameter(self, pathAndValue): """Set the parameter value, given its path. It should be registered in Parameter.registeredParameters""" Parameter.setParameter(pathAndValue)
def getParameter(self, path): """Return the value of a registered parameter""" return Parameter.getParameter(path)
class ChipWhispererSAD(Parameterized): """ Communicates and drives with the Sum of Absolute Differences (SAD) Module inside the ChipWhisperer System. You need to configure the trigger module as active & set the trigger polarity to "high" for this to work. """ _name = 'SAD Trigger Module' STATUS_RUNNING_MASK = 1 << 3 STATUS_RESET_MASK = 1 << 0 STATUS_START_MASK = 1 << 1 def __init__(self, oa): self.oldlow = None self.oldhigh = None self.oa = oa self.sadref = [0] try: # Update SAD calculation when data changes ResultsBase.registeredObjects["Trace Output Plot"].dataChanged.connect(self.dataChanged) outwid = ResultsBase.registeredObjects["Trace Output Plot"] rangewidget = {'name':'Point Range', 'key':'pointrng', 'type':'rangegraph', 'limits':(0, 0), 'value':(0, 0), 'default':(0, 0), 'graphwidget':outwid, 'action':self.updateSADTraceRef, 'fixedsize':128} except KeyError: rangewidget = {'name':'Point Range', 'key':'pointrng', 'type':'range', 'limits':(0, 0), 'value':(0, 0), 'default':(0, 0), 'action':self.updateSADTraceRef, 'fixedsize':128} self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ # {'name':'Open SAD Viewer', 'type':'action'}, {'name':'SAD Ref From Captured', 'key':'sad', 'type':'group', 'children':[ rangewidget, {'name':'Set SAD Reference from Current Trace', 'key':'docopyfromcapture', 'type':'action', 'action':self.copyFromCaptureTrace}, {'name':'SAD Reference vs. Cursor', 'key':'sadrefcur', 'type':'int', 'value':0, 'limits':(-1, 100E6), 'readonly':True}, ]}, {'name':'SAD Threshold', 'type':'int', 'limits':(0, 100000), 'default':0, 'set':self.setThreshold, 'get':self.getThreshold} ]) def dataChanged(self, data, offset): """ Called when data in the trace window has changed. Used to update the limits for the point selection dialog. """ low = offset up = offset + len(data) - 1 if self.oldlow != low or self.oldup != up: self.oldlow = low self.oldup = up self.findParam(['sad', 'pointrng']).setLimits((low, up)) self.findParam(['sad', 'pointrng']).setValue((low, min(up, low + 128))) self.updateSADTraceRef() def getCaptueTraceRef(self): """ Get the reference data for SAD algorithm from the api trace window """ try: waveformWidget = ResultsBase.registeredObjects["Trace Output Plot"] except KeyError: print "SAD Trigger: Not running in GUI mode, no data source" return [0.0]*128 pstart = self.findParam(['sad', 'pointrng']).getValue()[0] - waveformWidget.lastStartOffset pend = self.findParam(['sad', 'pointrng']).getValue()[1] - waveformWidget.lastStartOffset data = waveformWidget.lastTraceData[pstart:pend] data = np.array(data) data = (data + 0.5) * 1024 return data def copyFromCaptureTrace(self, _=None): """ Send reference data to hardware from the trace window """ data = self.getCaptueTraceRef() if len(data) != 128: print "WARNING: Reference IS NOT 128 samples long, got %d"%len(data) self.sadref = data.copy() self.setRefWaveform(data) def updateSADTraceRef(self, ignored=None): """ Update the calculated SAD value parameter """ data = self.getCaptueTraceRef() diff = data - self.sadref diff = sum(abs(diff)) self.findParam(['sad','sadrefcur']).setValue(diff, ignoreReadonly=True) def reset(self): """ Reset the SAD hardware block. The ADC clock must be running! """ data = self.oa.sendMessage(CODE_READ, sadcfgaddr, maxResp=4) data[0] = 0x01 self.oa.sendMessage(CODE_WRITE, sadcfgaddr, data) if self.checkStatus(): raise IOError("SAD Reset in progress, but SAD reports still running. Is ADC Clock stopped?") data[0] = 0x00 self.oa.sendMessage(CODE_WRITE, sadcfgaddr, data) def start(self): """ Start the SAD algorithm, which causes the reference data to be loaded from the FIFO """ data = self.oa.sendMessage(CODE_READ, sadcfgaddr, maxResp=4) data[0] = 0x02 self.oa.sendMessage(CODE_WRITE, sadcfgaddr, data, Validate=False) data[0] = 0x00 self.oa.sendMessage(CODE_WRITE, sadcfgaddr, data, Validate=False) def checkStatus(self): """ Check if the SAD module is running & outputting valid data """ data = self.oa.sendMessage(CODE_READ, sadcfgaddr, maxResp=4) if not (data[0] & self.STATUS_RUNNING_MASK): return False else: return True def getThreshold(self): """ Get the threshold. When the SAD output falls below this threshold the system triggers """ data = self.oa.sendMessage(CODE_READ, sadcfgaddr, maxResp=4) threshold = data[1] threshold |= data[2] << 8 threshold |= data[3] << 16 return threshold @setupSetParam("SAD Threshold") def setThreshold(self, threshold): """ Set the threshold. When the SAD output falls below this threshold the system triggers """ data = self.oa.sendMessage(CODE_READ, sadcfgaddr, maxResp=4) data[1] = threshold & 0xff data[2] = (threshold >> 8) & 0xff data[3] = (threshold >> 16) & 0xff self.oa.sendMessage(CODE_WRITE, sadcfgaddr, data, Validate=False) if self.checkStatus() == False: raise IOError("SAD Threshold set, but SAD compare not running. No valid trigger will be present. Did you load a reference waveform?") def setRefWaveform(self, dataRef): """ Download a reference waveform. Resets the SAD module & starts it again after loading the new data. ADC Clock must be running! """ dataRefInt = [int(i) for i in dataRef] self.reset() # print dataRefInt dataRefInt = dataRefInt[::-1] wavedata = [] for d in dataRefInt: wavedata.append((d >> 8) & 0xff) wavedata.append(d & 0xff) self.oa.sendMessage(CODE_WRITE, saddataaddr, wavedata, Validate=False) self.start()
class PreprocessingSettings(Parameterized): _num_modules = 4 def __init__(self, api): self._api = api self.valid_preprocessingModules = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.preprocessing", False, False) self.params = Parameter(name="Preprocessing Settings", type='group') self._moduleParams = [ Parameter(name='self.ppmod[%d]' % (i), type='group') for i in range(self._num_modules) ] self._initModules() self.params.addChildren([ {'name':'Selected Modules', 'type':'group', 'children':[ {'name':'self.ppmod[%d]' % (step), 'type':'list', 'values':self.valid_preprocessingModules, 'get':partial(self.getModule, step), 'set':partial(self.setModule, step)} for step in range(0, len(self._modules)) ]}, ]) for m in self._moduleParams: self.params.append(m) def _initModules(self): self._modules = [None]*self._num_modules for i in range(self._num_modules): mod = PassThrough(name="Preprocessing Module ppmod[%d]" % (i)) self.setModule(i, mod) def getModule(self, num): return self._modules[num].__class__ # TODO: calling this from the command line causes a cosmetic bug @setupSetParam("") def setModule(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ if module is None: raise ValueError("Received None as module in setModule()" % module) if num == 0: trace_source = self._api.project().traceManager() else: trace_source = self._modules[num-1] if self._modules[num] is not None: self._modules[num].deregister() self._moduleParams[num].clearChildren() if inspect.isclass(module): module = module(name="Preprocessing Module #%d" % (num+1)) self._modules[num] = module self._modules[num].setTraceSource(trace_source) self._moduleParams[num].append(self._modules[num].getParams()) if (num+1) < len(self._modules) and self._modules[num+1] is not None: self._modules[num+1].setTraceSource(module) def __getitem__(self, idx): return self._modules[idx] def __setitem__(self, idx, module): self.setModule(idx, module) logging.warning("Selected Modules parameter list didn't update during setModule call in PreprocessingSettings") def __str__(self): return str(self._modules) def __repr__(self): return str(self)
class ChipWhispererComm(Parameterized): _name = "Sakurag" CODE_READ = 0x80 CODE_WRITE = 0xC0 ADDR_STATUS = 49 ADDR_FIFO = 50 FLAG_RESET = 0x01 FLAG_WRFULL = 0x02 FLAG_RDEMPTY = 0x04 def __init__(self, standalone=False): self.standalone = standalone self.serialnum = None self.params = Parameter(name=self.getName(), type='group') if standalone: self.setSerial = self._setSerial def _setSerial(self, serialnum): self.serialnum = serialnum def reset(self): self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) time.sleep(0.05) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) def con(self, scope=None): if scope and scope.qtadc and scope.qtadc.sc: self.oa = scope.qtadc.sc else: if self.serialnum is not None: self.qtadc = openadc_qt.OpenADCQt() self.params.append(self.qtadc.getParams()) self.oaiface = ftdi.OpenADCInterface_FTDI(None, self.qtadc) self.params.append(self.oaiface.getParams()) self.oaiface.setSerialNumberLimits([self.serialnum]) self.oaiface.setSelectedDevice(self.serialnum) self.oaiface.con() self.oa = self.qtadc.sc else: raise Warning( "No OpenADC detected - did you connect the scope module and/or set serial number (hit 'REFRESH')?" ) # Reset AES Core self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) return True def disconnect(self): return def flush(self): while (self.readStatus() & self.FLAG_RDEMPTY) != self.FLAG_RDEMPTY: self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) def readStatus(self): b = self.oa.sendMessage(self.CODE_READ, self.ADDR_STATUS, Validate=False) return b[0] def writeMsg(self, msg): for b in msg: # while (self.readStatus() & self.FLAG_WRFULL) == self.FLAG_WRFULL: # pass self.oa.sendMessage(self.CODE_WRITE, self.ADDR_FIFO, [b], Validate=False) def readMsg(self, nbytes): msg = bytearray() for i in range(0, nbytes): if self.readStatus() & self.FLAG_RDEMPTY: pass b = self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) msg.append(b[0]) return msg def write(self, address, MSB, LSB): msg = bytearray(5) msg[0] = 0x01 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB msg[3] = MSB msg[4] = LSB # msg = bytearray(strmsg) # print "Write: %x %x %x %x %x"%(msg[0],msg[1],msg[2],msg[3],msg[4]) self.writeMsg(msg) def read(self, address): self.flush() msg = bytearray(3) msg[0] = 0x00 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB self.writeMsg(msg) # print "Write: %x %x %x"%(msg[0],msg[1],msg[2]), msg = self.readMsg(2) # print " Read: %x %x"%(msg[0],msg[1]) # Order = MSB, LSB return msg def read128(self, address): self.flush() msg = bytearray(3 * 8) for i in range(0, 8): msg[i * 3] = 0x00 msg[i * 3 + 1] = (address >> 8) & 0xFF msg[i * 3 + 2] = (address & 0xFF) + (i * 2) self.writeMsg(str(msg)) msg = self.readMsg(16) return bytearray(msg) def close(self): pass
class OpenADCInterface_Serial(Parameterized): _name = "Serial Port (LX9)" def __init__(self, oadcInstance): self.portName = '' self.ser = None self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ { 'name': 'Refresh List', 'type': 'action', 'action': self.serialRefresh }, { 'name': 'Selected Port', 'type': 'list', 'values': [''], 'get': self.getPortName, 'set': self.setPortName }, ]) self.scope = oadcInstance def getPortName(self): return self.portName @setupSetParam("Selected Port") def setPortName(self, snum): self.portName = snum def con(self): if self.ser is None: self.ser = serial.Serial() self.ser.port = self.portName self.ser.baudrate = 512000 self.ser.timeout = 2 # 2 second timeout attempts = 4 while attempts > 0: try: self.ser.open() attempts = 0 except serial.SerialException as e: attempts -= 1 self.ser = None if attempts == 0: raise IOError("Could not open %s" % self.ser.name) try: self.scope.con(self.ser) logging.info('OpenADC Found, Connecting') except IOError as e: exctype, value = sys.exc_info()[:2] raise IOError("OpenADC Error (Serial Port): %s" % (str(exctype) + str(value))) def dis(self): if self.ser is not None: self.ser.close() self.ser = None def __del__(self): if self.ser is not None: self.ser.close() def serialRefresh(self, _=None): serialnames = scan.scan() if serialnames is None or len(serialnames) == 0: serialnames = [" "] p = self.params.getChild('Selected Port') p.setLimits(serialnames) p.setValue(serialnames[0])
class AttackScriptGen(Parameterized): _name = "Attack Script Generator" def __init__(self, cwGUI): self.cwGUI = cwGUI self.locked = False self.utilList = [] self.scriptList = [] self.scriptList.append({'widget':MainScriptEditor(self.cwGUI)}) self.scriptList[0]['filename'] = self.scriptList[0]['widget'].filename self.scriptList[0]['dockname'] = 'Auto-Generated' self.defaultEditor = self.scriptList[0] autogen = (self.defaultEditor['dockname'], self.defaultEditor['filename']) self.preprocessingListGUI = [None, None, None, None] self.setAttack(self.cwGUI.api.valid_attacks.get("CPA", None), blockSignal=True) self.getParams().addChildren([ {'name':'Attack Script', 'type':'group', 'children':[ {'name':'Filename', 'key':'attackfilelist', 'type':'filelist', 'values':{autogen:0}, 'value':0, 'editor':self.editorControl,}, ]}, {'name':'Pre-Processing', 'type':'group', 'children':[ {'name':'Module #%d' % step, 'type':'list', 'values':self.cwGUI.api.valid_preprocessingModules, 'get':partial(self.getPreprocessing, step), 'set':partial(self.setPreprocessing, step)} for step in range(0, len(self.preprocessingListGUI)) ]}, {'name':'Attack', 'type':'group', 'children':[ {'name':'Module', 'type':'list', 'values':self.cwGUI.api.valid_attacks, 'get':self.getAttack, 'set':self.setAttack}, ]}, ]) self.params.init() self.preprocessingParams = Parameter(name="Preprocessing", type='group') self.attackParams = Parameter(name="Attack", type='group') self.params.getChild(['Attack','Module']).stealDynamicParameters(self.attackParams) self.cwGUI.api.sigTracesChanged.connect(self.updateAttackTraceLimits) def flushTimer(self): """Flush all pending script updates""" [p.updateDelayTimer.flush() for p in self.preprocessingListGUI if p is not None] self.attack.updateDelayTimer.flush() def updateAttackTraceLimits(self): self.attack.setTraceLimits(self.cwGUI.api.project().traceManager().numTraces(), self.cwGUI.api.project().traceManager().numPoints()) def editorControl(self, filename, filedesc, default=False, bringToFront=True): """This is the call-back from the script editor file list, which opens editors""" # Find filename thisEditor = None for e in self.scriptList: if e['filename'] == filename: thisEditor = e break if thisEditor is None: thisEditor = {'widget':MainScriptEditor(parent=self.cwGUI, filename=filename)} thisEditor['filename'] = filename thisEditor['dockname'] = filedesc self.scriptList.append(thisEditor) # Update all docks if required thisEditor['dockname'] = filedesc self.editorDocks() if bringToFront: thisEditor['dock'].show() thisEditor['dock'].raise_() if default: # Set as default for attacks etc self.defaultEditor = thisEditor def editorDocks(self): """Ensure we have a script editor window for each referenced analyzer script file""" for script in self.scriptList: dockname = "Analysis Script: %s" % script['dockname'] # No previous dock, do setup if 'dock' not in script.keys(): self.__runScriptConverter = partial(self.runScriptFunction, filename=script['filename']) script['widget'].editWindow.runFunction.connect(self.__runScriptConverter) script['dock'] = self.cwGUI.addDock(script['widget'], name=dockname, area=Qt.BottomDockWidgetArea) script['dock'].setWindowTitle(dockname) def getPreprocessing(self, num): return self.preprocessingListGUI[num] @setupSetParam("") def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d'% num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect(self.reloadScripts) par = Parameter(name = 'Pre-Processing Mod. #%d'% num, type = "group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts() def getAttack(self): return self.attack @setupSetParam(["Attack","Module"]) def setAttack(self, module): self.attack = module if module: self.updateAttackTraceLimits() self.reloadScripts() self.attack.scriptsUpdated.connect(self.reloadScripts) self.attack.runScriptFunction.connect(self.runScriptFunction) def runScriptFunction(self, funcName, filename=None): """Loads a given script and runs a specific function within it.""" mod = self.setupScriptModule(filename) self.cwGUI.api.runScriptModule(mod, funcName) def setupScriptModule(self, filename=None): """Loads a given script as a module for dynamic run-time insertion. Args: filename (str): The full filename to open. If None it opens the auto-generated script instead. """ if filename and filename != self.defaultEditor['filename']: raise Warning("Script Error: Cannot run script from non-default function") return self.defaultEditor['widget'].loadModule() def reloadScripts(self): """Rewrite the auto-generated analyzer script, using settings from the GUI""" if self.cwGUI.api.executingScripts.value(): self.cwGUI.api.executingScripts.connect(self.reloadScripts) return self.cwGUI.api.executingScripts.disconnect(self.reloadScripts) # Auto-Generated is always first mse = self.scriptList[0]['widget'] mse.saveSliderPosition() mse.editWindow.clear() mse.append("# Date Auto-Generated: %s" % datetime.now().strftime('%Y.%m.%d-%H.%M.%S'), 0) mse.append("from chipwhisperer.common.api.CWCoreAPI import CWCoreAPI", 0) mse.append("from chipwhisperer.common.scripts.base import UserScriptBase", 0) # Get imports from preprocessing mse.append("# Imports from Preprocessing", 0) mse.append("import chipwhisperer.analyzer.preprocessing as preprocessing", 0) for p in self.preprocessingListGUI: if p: imports = p.getImportStatements() for i in imports: mse.append(i, 0) # Get imports from attack mse.append("# Imports from Attack", 0) if self.attack: for i in self.attack.getImportStatements(): mse.append(i, 0) # Some other imports mse.append("# Imports from utilList", 0) for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for i in util.getImportStatements(): mse.append(i, 0) mse.append("", 0) # Add main class mse.append("class UserScript(UserScriptBase):", 0) mse.append("name = \"Auto-generated\"",1) mse.append("description = \"Auto-generated Attack Script\"",1) mse.append("def __init__(self, api):", 1) mse.append("UserScriptBase.__init__(self, api)") mse.append("self.initProject()") mse.append("self.initPreprocessing()") mse.append("self.initAnalysis()") mse.append("self.initReporting()") mse.append("def initProject(self):", 1) mse.append("pass") mse.append("def initPreprocessing(self):", 1) # Get init from preprocessing lastOutput = "self.api.project().traceManager()" for i, p in enumerate(self.preprocessingListGUI): if p and p.getName() != "None": classname = type(p).__name__ instname = "ppMod%d" % i mse.append("%s = preprocessing.%s.%s(%s)" % (instname, classname, classname, lastOutput)) for s in p.getStatements('init'): mse.append(s.replace("self.", instname + ".").replace("UserScript.", "self.")) mse.append("%s.init()" % (instname)) lastOutput = instname mse.append("self.traces = %s" % lastOutput) # Get init from analysis mse.append("def initAnalysis(self):", 1) if self.attack: mse.append('self.attack = %s()' % type(self.attack).__name__) for s in self.attack.getStatements('init'): mse.append(s.replace("self.", "self.attack.").replace("UserScript.", "self.")) else: mse.append('pass') # Get init from reporting mse.append("def initReporting(self):", 1) mse.append("# Configures the attack observers (usually a set of GUI widgets)") if len(ResultsBase.registeredObjects)>0: for k, v in ResultsBase.registeredObjects.iteritems(): if hasattr(v,"setTraceSource"): mse.append("self.api.getResults(\"%s\").setTraceSource(self.traces)" % k) if hasattr(v,"setAnalysisSource"): mse.append("self.api.getResults(\"%s\").setAnalysisSource(self.attack)" % k) else: mse.append("pass") # Do the attack mse.append("def run(self):", 1) mse.append("self.attack.processTraces()") # Get other commands from attack module if self.attack: for k in self.attack._smartstatements: if k == 'init' or k == 'go' or k == 'done': pass else: mse.append("def %s(self):" % k, 1) for s in self.attack.getStatements(k): mse.append(s.replace("self.", "self.attack.").replace("UserScript.", "self.")) # Get other commands from other utilities for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for k in util._smartstatements: util._smartstatements[k].addSelfReplacement("utilList[%d]." % index) util._smartstatements[k].addSelfReplacement("cwagui.attackScriptGen.") #TODO-temp hack statements = util.getStatements(k) if len(statements) > 0: mse.append("def %s_%s(self):" % (util.__class__.__name__, k), 1) mse.append("self.cwagui = CWAnalyzerGUI.getInstance()") #TODO - temp hack for s in statements: mse.append(s.replace("UserScript.", "self.")) mse.append("if __name__ == '__main__':\n" " import chipwhisperer.analyzer.ui.CWAnalyzerGUI as cwa\n" " from chipwhisperer.common.utils.parameter import Parameter\n" " Parameter.usePyQtGraph = True # Comment if you don't need the GUI\n" " api = CWCoreAPI() # Instantiate the API\n" " app = cwa.makeApplication(\"Analyzer\") # Comment if you don't need the GUI\n" " gui = cwa.CWAnalyzerGUI(api) # Comment if you don't need the GUI\n" " gui.show() # Comment if you don't need the GUI\n" " api.runScriptClass(UserScript) # Run UserScript through the API\n" " app.exec_() # Comment if you don't need the GUI\n", 0) mse.restoreSliderPosition() self.cwGUI.api.runScriptModule(self.setupScriptModule(), None)
class AttackScriptGen(Parameterized): _name = "Attack Script Generator" def __init__(self, cwGUI): self.cwGUI = cwGUI self.locked = False self.utilList = [] self.scriptList = [] self.scriptList.append({'widget': MainScriptEditor(self.cwGUI)}) self.scriptList[0]['filename'] = self.scriptList[0]['widget'].filename self.scriptList[0]['dockname'] = 'Auto-Generated' self.defaultEditor = self.scriptList[0] autogen = (self.defaultEditor['dockname'], self.defaultEditor['filename']) self.preprocessingListGUI = [None, None, None, None] self.setAttack(self.cwGUI.api.valid_attacks.get("CPA", None), blockSignal=True) self.getParams().addChildren([ { 'name': 'Attack Script', 'type': 'group', 'children': [ { 'name': 'Filename', 'key': 'attackfilelist', 'type': 'filelist', 'values': { autogen: 0 }, 'value': 0, 'editor': self.editorControl, }, ] }, { 'name': 'Pre-Processing', 'type': 'group', 'children': [{ 'name': 'Module #%d' % step, 'type': 'list', 'values': self.cwGUI.api.valid_preprocessingModules, 'get': partial(self.getPreprocessing, step), 'set': partial(self.setPreprocessing, step) } for step in range(0, len(self.preprocessingListGUI))] }, { 'name': 'Attack', 'type': 'group', 'children': [ { 'name': 'Module', 'type': 'list', 'values': self.cwGUI.api.valid_attacks, 'get': self.getAttack, 'set': self.setAttack }, ] }, ]) self.params.init() self.preprocessingParams = Parameter(name="Preprocessing", type='group') self.attackParams = Parameter(name="Attack", type='group') self.params.getChild(['Attack', 'Module' ]).stealDynamicParameters(self.attackParams) def projectChanged(self): if self.attack: self.attack.findParam('input').setValue( TraceSource.registeredObjects["Trace Management"]) def flushTimer(self): """Flush all pending script updates""" [ p.updateDelayTimer.flush() for p in self.preprocessingListGUI if p is not None ] self.attack.updateDelayTimer.flush() def editorControl(self, filename, filedesc, default=False, bringToFront=True): """This is the call-back from the script editor file list, which opens editors""" # Find filename thisEditor = None for e in self.scriptList: if e['filename'] == filename: thisEditor = e break if thisEditor is None: thisEditor = { 'widget': MainScriptEditor(parent=self.cwGUI, filename=filename) } thisEditor['filename'] = filename thisEditor['dockname'] = filedesc self.scriptList.append(thisEditor) # Update all docks if required thisEditor['dockname'] = filedesc self.editorDocks() if bringToFront: thisEditor['dock'].show() thisEditor['dock'].raise_() if default: # Set as default for attacks etc self.defaultEditor = thisEditor def editorDocks(self): """Ensure we have a script editor window for each referenced analyzer script file""" for script in self.scriptList: dockname = "Analysis Script: %s" % script['dockname'] # No previous dock, do setup if 'dock' not in script.keys(): self.__runScriptConverter = partial( self.runScriptFunction, filename=script['filename']) script['widget'].editWindow.runFunction.connect( self.__runScriptConverter) script['dock'] = self.cwGUI.addDock( script['widget'], name=dockname, area=Qt.BottomDockWidgetArea) script['dock'].setWindowTitle(dockname) def getPreprocessing(self, num): return self.preprocessingListGUI[num] @setupSetParam("") def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d' % num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect( self.reloadScripts) par = Parameter(name='Pre-Processing Mod. #%d' % num, type="group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts() def getAttack(self): return self.attack @setupSetParam(["Attack", "Module"]) def setAttack(self, module): self.attack = module if module: self.reloadScripts() self.attack.scriptsUpdated.connect(self.reloadScripts) self.attack.runScriptFunction.connect(self.runScriptFunction) self.attack.findParam('input').setValue( TraceSource.registeredObjects["Trace Management"]) def runScriptFunction(self, funcName, filename=None): """Loads a given script and runs a specific function within it.""" mod = self.setupScriptModule(filename) self.cwGUI.api.runScriptModule(mod, funcName) def setupScriptModule(self, filename=None): """Loads a given script as a module for dynamic run-time insertion. Args: filename (str): The full filename to open. If None it opens the auto-generated script instead. """ if filename and filename != self.defaultEditor['filename']: raise Warning( "Script Error: Cannot run script from non-default function") return self.defaultEditor['widget'].loadModule() def reloadScripts(self): """Rewrite the auto-generated analyzer script, using settings from the GUI""" if self.cwGUI.api.executingScripts.value(): self.cwGUI.api.executingScripts.connect(self.reloadScripts) return self.cwGUI.api.executingScripts.disconnect(self.reloadScripts) # Auto-Generated is always first mse = self.scriptList[0]['widget'] mse.saveSliderPosition() mse.editWindow.clear() mse.append( "# Date Auto-Generated: %s" % datetime.now().strftime('%Y.%m.%d-%H.%M.%S'), 0) mse.append("from chipwhisperer.common.api.CWCoreAPI import CWCoreAPI", 0) mse.append( "from chipwhisperer.common.scripts.base import UserScriptBase", 0) # Get imports from preprocessing mse.append("# Imports from Preprocessing", 0) for p in self.preprocessingListGUI: if p: imports = p.getImportStatements() for i in imports: mse.append(i, 0) # Get imports from attack mse.append("# Imports from Attack", 0) if self.attack: for i in self.attack.getImportStatements(): mse.append(i, 0) # Some other imports mse.append("# Imports from utilList", 0) for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for i in util.getImportStatements(): mse.append(i, 0) mse.append("", 0) # Add main class mse.append("class UserScript(UserScriptBase):", 0) mse.append("_name = \"Auto-generated\"", 1) mse.append("_description = \"Auto-generated Attack Script\"", 1) mse.append("def __init__(self, api):", 1) mse.append("UserScriptBase.__init__(self, api)") mse.append("self.initProject()") mse.append("self.initPreprocessing()") mse.append("self.initAnalysis()") mse.append("self.initReporting()") mse.append("def initProject(self):", 1) mse.append("pass") mse.append("def initPreprocessing(self):", 1) # Get init from preprocessing lastOutput = "self.api.project().traceManager()" for i, p in enumerate(self.preprocessingListGUI): if p and p.getName() != "None": classname = type(p).__name__ instname = "ppMod%d" % i mse.append( "%s = %s.%s(%s)" % (instname, sys.modules[p.__class__.__module__].__name__, classname, lastOutput)) for s in p.getStatements('init'): mse.append( s.replace("self.", instname + ".").replace( "UserScript.", "self.")) mse.append("%s.init()" % (instname)) lastOutput = instname mse.append("self.traces = %s" % lastOutput) # Get init from analysis mse.append("def initAnalysis(self):", 1) if self.attack: mse.append('self.attack = %s()' % type(self.attack).__name__) for s in self.attack.getStatements('init'): mse.append( s.replace("self.", "self.attack.").replace("UserScript.", "self.")) else: mse.append('pass') # Get init from reporting mse.append("def initReporting(self):", 1) mse.append( "# Configures the attack observers (usually a set of GUI widgets)") if len(ResultsBase.registeredObjects) > 0: for k, v in ResultsBase.registeredObjects.iteritems(): if hasattr(v, "setTraceSource"): mse.append( "self.api.getResults(\"%s\").setTraceSource(self.traces)" % k) if hasattr(v, "setAnalysisSource"): mse.append( "self.api.getResults(\"%s\").setAnalysisSource(self.attack)" % k) else: mse.append("pass") # Do the attack mse.append("def run(self):", 1) mse.append("self.attack.processTraces()") # Get other commands from attack module if self.attack: for k in self.attack._smartstatements: if k == 'init' or k == 'go' or k == 'done': pass else: mse.append("def %s(self):" % k, 1) for s in self.attack.getStatements(k): mse.append( s.replace("self.", "self.attack.").replace( "UserScript.", "self.")) # Get other commands from other utilities for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for k in util._smartstatements: util._smartstatements[k].addSelfReplacement( "utilList[%d]." % index) util._smartstatements[k].addSelfReplacement( "cwagui.attackScriptGen.") #TODO-temp hack statements = util.getStatements(k) if len(statements) > 0: mse.append( "def %s_%s(self):" % (util.__class__.__name__, k), 1) mse.append("self.cwagui = CWAnalyzerGUI.getInstance()" ) #TODO - temp hack for s in statements: mse.append(s.replace("UserScript.", "self.")) mse.append( "if __name__ == '__main__':\n" " import chipwhisperer.analyzer.ui.CWAnalyzerGUI as cwa\n" " from chipwhisperer.common.utils.parameter import Parameter\n" " Parameter.usePyQtGraph = True # Comment if you don't need the GUI\n" " api = CWCoreAPI() # Instantiate the API\n" " app = cwa.makeApplication(\"Analyzer\") # Comment if you don't need the GUI\n" " gui = cwa.CWAnalyzerGUI(api) # Comment if you don't need the GUI\n" " api.runScriptClass(UserScript) # Run UserScript through the API\n" " app.exec_() # Comment if you don't need the GUI\n", 0) mse.restoreSliderPosition() self.cwGUI.api.runScriptModule(self.setupScriptModule(), None)
class OpenADCInterface_Serial(Parameterized, Plugin): _name = "Serial Port (LX9)" def __init__(self, parentParam, oadcInstance): self.portName = '' self.ser = None self.params = Parameter(name=self.getName(), type='group') self.params.addChildren([ {'name':'Refresh List', 'type':'action', 'action':lambda _: self.serialRefresh()}, {'name':'Selected Port', 'type':'list', 'values':[''], 'get':self.getPortName, 'set':self.setPortName}, ]) if (openadc_qt is None) or (serial is None): raise ImportError("Needed imports for serial missing") else: self.scope = oadcInstance def getPortName(self): return self.portName @setupSetParam("Selected Port") def setPortName(self, snum): self.portName = snum def __del__(self): if self.ser != None: self.ser.close() def con(self): if self.ser == None: self.ser = serial.Serial() self.ser.port = self.portName self.ser.baudrate = 512000 self.ser.timeout = 2 # 2 second timeout attempts = 4 while attempts > 0: try: self.ser.open() attempts = 0 except serial.SerialException as e: attempts = attempts - 1 self.ser = None if attempts == 0: raise IOError("Could not open %s" % self.ser.name) try: self.scope.con(self.ser) print("OpenADC Found, Connecting") except IOError as e: exctype, value = sys.exc_info()[:2] raise IOError("OpenADC Error (Serial Port): %s" % (str(exctype) + str(value))) def dis(self): if self.ser != None: self.ser.close() self.ser = None def serialRefresh(self): serialnames = scan.scan() if serialnames == None or len(serialnames) == 0: serialnames = [" "] p = self.params.getChild('Selected Port') p.setLimits(serialnames) p.setValue(serialnames[0]) def getTextName(self): try: return self.ser.name except: return "None?"
class CWCoreAPI(Parameterized): """ ChipWisperer API Class. Provides access to the most important parts of the tool. It has a singleton method called CWCoreAPI.getInstance() that returns a reference to the API instance. """ __name__ = "ChipWhisperer" __organization__ = "NewAE Technology Inc." __version__ = "V3.1.9" _name = 'Generic Settings' instance = None def __init__(self): CWCoreAPI.instance = self self.sigNewProject = util.Signal() self.sigNewScopeData = util.Signal() self.sigConnectStatus = util.Signal() self.sigAttackChanged = util.Signal() self.sigNewInputData = util.Signal() self.sigNewTextResponse = util.Signal() self.sigTraceDone = util.Signal() self.sigCampaignStart = util.Signal() self.sigCampaignDone = util.Signal() self.sigTracesChanged = util.Signal() self.executingScripts = util.Observable(False) self.valid_scopes = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.scopes", True, True) self.valid_targets = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.targets", True, True) self.valid_traces = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.common.traces", True, True) self.valid_aux = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.auxiliary", True, True) self.valid_acqPatterns = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.acq_patterns", True, False) self.valid_attacks = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.attacks", True, False) self.valid_preprocessingModules = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.preprocessing", False, True) self.settings = Settings() # Initialize default values self._project = self._scope = self._target = self._attack = self._traceFormat = self._acqPattern = None self._attack = self.valid_attacks.get("CPA", None) self._acqPattern = self.valid_acqPatterns["Basic"] self._auxList = [None] # TODO: implement it as a list in the whole class self._numTraces = 50 self._numTraceSets = 1 self.params = Parameter(name='Generic Settings', type='group', addLoadSave=True).register() self.params.addChildren([ {'name':'Scope Module', 'key':'scopeMod', 'type':'list', 'values':self.valid_scopes, 'get':self.getScope, 'set':self.setScope}, {'name':'Target Module', 'key':'targetMod', 'type':'list', 'values':self.valid_targets, 'get':self.getTarget, 'set':self.setTarget}, {'name':'Trace Format', 'type':'list', 'values':self.valid_traces, 'get':self.getTraceFormat, 'set':self.setTraceFormat}, {'name':'Auxiliary Module', 'type':'list', 'values':self.valid_aux, 'get':self.getAuxModule, 'set':self.setAux}, {'name':'Acquisition Settings', 'type':'group', 'children':[ {'name':'Number of Traces', 'type':'int', 'limits':(1, 1E9), 'get':self.getNumTraces, 'set':self.setNumTraces, 'linked':['Traces per Set']}, {'name':'Number of Sets', 'type':'int', 'limits':(1, 1E6), 'get':self.getNumTraceSets, 'set':self.setNumTraceSets, 'linked':['Traces per Set'], 'tip': 'Break acquisition into N sets, ' 'which may cause data to be saved more frequently. The default capture driver requires that NTraces/NSets is small enough to avoid running out of system memory ' 'as each segment is buffered into RAM before being written to disk.'}, {'name':'Traces per Set', 'type':'int', 'readonly':True, 'get':self.tracesPerSet}, {'name':'Key/Text Pattern', 'type':'list', 'values':self.valid_acqPatterns, 'get':self.getAcqPattern, 'set':self.setAcqPattern}, ]}, ]) self.scopeParam = Parameter(name="Scope Settings", type='group', addLoadSave=True).register() self.params.getChild('Scope Module').stealDynamicParameters(self.scopeParam) self.targetParam = Parameter(name="Target Settings", type='group', addLoadSave=True).register() self.params.getChild('Target Module').stealDynamicParameters(self.targetParam) self.traceParam = Parameter(name="Trace Settings", type='group', addLoadSave=True).register() self.params.getChild('Trace Format').stealDynamicParameters(self.traceParam) self.auxParam = Parameter(name="Aux Settings", type='group', addLoadSave=True).register() self.params.getChild('Auxiliary Module').stealDynamicParameters(self.auxParam) # self.attackParam = Parameter(name="Attack Settings", type='group') # self.params.getChild('Attack Module').getDynamicParameters(self.attackParam) self.newProject() def getResults(self, name): """Return the requested result widget. It should be registered.""" return ResultsBase.registeredObjects[name] def getScope(self): """Return the current scope module object.""" return self._scope @setupSetParam("Scope Module") def setScope(self, driver): """Set the current scope module object.""" if self.getScope(): self.getScope().dis() self._scope = driver if self.getScope(): self.getScope().dataUpdated.connect(self.sigNewScopeData.emit) self.getScope().connectStatus.connect(self.sigConnectStatus.emit) def getTarget(self): """Return the current target module object.""" return self._target @setupSetParam("Target Module") def setTarget(self, driver): """Set the current target module object.""" if self.getTarget(): self.getTarget().dis() self._target = driver if self.getTarget(): self.getTarget().newInputData.connect(self.sigNewInputData.emit) self.getTarget().connectStatus.connect(self.sigConnectStatus.emit) def getAuxModule(self): """Return a list with the auxiliary modules.""" return self._auxList[0] def getAuxList(self): """Return a list with the auxiliary modules.""" return self._auxList @setupSetParam("Auxiliary Module") def setAux(self, aux): """Set the first aux module. Will be updated to support more modules.""" self._auxList = [aux] def getAcqPattern(self): """Return the selected acquisition pattern.""" return self._acqPattern @setupSetParam("Key/Text Pattern") def setAcqPattern(self, pat): """Set the current acquisition pattern.""" self._acqPattern = pat if self._acqPattern is not None: self._acqPattern.getParams().remove() self.getParams().append(self._acqPattern.getParams()) def getNewTrace(self, format): """Return a new trace object for the specified format.""" if format is None: raise Warning("No trace format selected.") tmp = copy.copy(format) tmp.clear() starttime = datetime.now() prefix = starttime.strftime('%Y.%m.%d-%H.%M.%S') + "_" tmp.config.setConfigFilename(CWCoreAPI.getInstance().project().datadirectory + "traces/config_" + prefix + ".cfg") tmp.config.setAttr("prefix", prefix) tmp.config.setAttr("date", starttime.strftime('%Y-%m-%d %H:%M:%S')) return tmp def getTraceFormat(self): """Return the selected trace format.""" return self._traceFormat @setupSetParam("Trace Format") def setTraceFormat(self, format): """Set the current trace format for acquisition.""" self._traceFormat = format def getAttack(self): """Return the current attack module. NOT BEING USED AT THE MOMENT""" return self._attack def setAttack(self, attack): """Set the current attack module. NOT BEING USED AT THE MOMENT""" self._attack = attack if self.getAttack(): self.getAttack().setTraceLimits(self.project().traceManager().numTraces(), self.project().traceManager().numPoints()) self.sigAttackChanged.emit() def project(self): """Return the current opened project""" return self._project def setProject(self, proj): """Set the current opened project""" self._project = proj self.sigNewProject.emit() def newProject(self): """Create a new project""" self.setProject(ProjectFormat()) self.project().setProgramName(self.__name__) self.project().setProgramVersion(self.__version__) self.project().traceManager().sigTracesChanged.connect(self.sigTracesChanged.emit) def openProject(self, fname): """Open project file""" self.newProject() self.project().load(fname) try: ResultsBase.registeredObjects["Trace Output Plot"].setTraceSource(TraceSource.registeredObjects["Trace Management"]) except KeyError: pass def saveProject(self, fname=None): """Save the current opened project to file""" if fname is not None: self.project().setFilename(fname) self.project().save() def connectScope(self): """Connect to the selected scope""" try: if self.getScope(): self.getScope().con() try: # Sets the Plot Widget input (if it exists) to the last added TraceSource ResultsBase.registeredObjects["Trace Output Plot"].setTraceSource( TraceSource.registeredObjects[next(reversed(TraceSource.registeredObjects))]) except KeyError: pass except Warning: sys.excepthook(*sys.exc_info()) return False return True def disconnectScope(self): """Disconnect the current scope""" self.getScope().dis() def connectTarget(self): """Connect to the selected target""" try: if self.getTarget(): self.getTarget().con(scope=self.getScope()) except Warning: sys.excepthook(*sys.exc_info()) return False return True def disconnectTarget(self): """Disconnect the current target""" self.getTarget().dis() def doConDis(self): """DEPRECATED: It is here just for compatibility reasons""" print "Method doConDis() is deprecated... use connect() or disconnect() instead" return self.connect() def connect(self): """Connect both: scope and target""" return self.connectScope() and self.connectTarget() def disconnect(self): """Disconnect both: scope and target""" self.disconnectScope() self.disconnectTarget() def getNumTraces(self): """Return the total number or traces for acquisition purposes""" return self._numTraces @setupSetParam("Number of Traces") def setNumTraces(self, n): """Set the total number or traces for acquisition purposes""" self._numTraces = n def getNumTraceSets(self): """Return the number of sets/segments""" return self._numTraceSets @setupSetParam("Number of Sets") def setNumTraceSets(self, s): """Set the number of sets/segments""" self._numTraceSets = s def tracesPerSet(self): """Return the number of traces in each set/segment""" return int(self._numTraces / self._numTraceSets) def capture1(self): """Capture one trace""" try: ac = AcquisitionController(self.getScope(), self.getTarget(), writer=None, auxList=self._auxList, keyTextPattern=self.getAcqPattern()) ac.sigNewTextResponse.connect(self.sigNewTextResponse.emit) return ac.doSingleReading() except Warning: sys.excepthook(*sys.exc_info()) return False def captureM(self, progressBar = None): """Capture multiple traces and save its result""" if not progressBar: progressBar = ProgressBarText() with progressBar: progressBar.setStatusMask("Current Segment = %d Current Trace = %d", (0,0)) progressBar.setMaximum(self._numTraces) waveBuffer = None tcnt = 0 setSize = self.tracesPerSet() for i in range(0, self._numTraceSets): if progressBar.wasAborted(): break if self.getTraceFormat() is not None: currentTrace = self.getNewTrace(self.getTraceFormat()) # Load trace writer information prefix = currentTrace.config.attr("prefix")[:-1] currentTrace.config.setAttr("targetHW", self.getTarget().getName() if self.getTarget() is not None else "None") currentTrace.config.setAttr("targetSW", os.path.split(Programmer.lastFlashedFile)[1]) currentTrace.config.setAttr("scopeName", self.getScope().getName() if self.getScope() is not None else "None") currentTrace.config.setAttr("scopeSampleRate", 0) currentTrace.config.setAttr("notes", "AckPattern: " + str(self.getAcqPattern()) + "; Aux: " + ', '.join(item.getName() for item in self._auxList if item)) currentTrace.setTraceHint(setSize) if waveBuffer is not None: currentTrace.setTraceBuffer(waveBuffer) else: currentTrace = None prefix = datetime.now().strftime('%Y.%m.%d-%H.%M.%S') for aux in self._auxList: if aux: aux.setPrefix(prefix) ac = AcquisitionController(self.getScope(), self.getTarget(), currentTrace, self._auxList, self.getAcqPattern()) ac.setMaxtraces(setSize) ac.sigNewTextResponse.connect(self.sigNewTextResponse.emit) ac.sigTraceDone.connect(self.sigTraceDone.emit) __pb = lambda: progressBar.updateStatus(i*setSize + ac.currentTrace + 1, (i, ac.currentTrace)) ac.sigTraceDone.connect(__pb) self.sigCampaignStart.emit(prefix) ac.doReadings(tracesDestination=self.project().traceManager(), progressBar=progressBar) self.sigCampaignDone.emit() self.project().saveAllSettings(os.path.dirname(currentTrace.config.configFilename()) + "/%s_settings.cwset" % prefix, onlyVisibles=True) tcnt += setSize if currentTrace is not None: waveBuffer = currentTrace.traces # Re-use the wave buffer to avoid memory reallocation if progressBar.wasAborted(): break if currentTrace is not None: currentTrace.unloadAllTraces() # Required in order to make the GC work properly :( self._traceFormat.unloadAllTraces() def runScriptModule(self, mod, funcName="run"): """Execute the function in the Plugin classes of the specified module""" try: classes = pluginmanager.getPluginClassesFromModules([mod]) if len(classes) == 0: raise Warning("No UserScriptBase class found") for c in classes: self.runScriptClass(c, funcName) except Exception as e: sys.excepthook(Warning, "Could not execute Script Module %s: '%s'" % (str(mod), "".join(traceback.format_exception_only(sys.exc_info()[0], e.message)).rstrip("\n ") ), sys.exc_info()[2]) def runScriptClass(self, scriptClass, funcName="run"): """Execute the funcName function in the specified class.""" try: self.executingScripts.setValue(True) m = scriptClass(self) if funcName is not None: eval('m.%s()' % funcName) except Exception as e: sys.excepthook(Warning, "Could not execute method %s in script class %s: '%s'" % (funcName, scriptClass.__name__, "".join(traceback.format_exception_only(sys.exc_info()[0], e.message)).rstrip("\n ") ), sys.exc_info()[2]) finally: self.executingScripts.setValue(False) def getParameter(self, path): """Return the value of a registered parameter""" return Parameter.getParameter(path) def setParameter(self, pathAndValue): """Set the parameter value, given its path. It should be registered in Parameter.registeredParameters""" Parameter.setParameter(pathAndValue) @staticmethod def getInstance(): """Implements the singleton pattern/anti-pattern. Returns a reference to the API instance.""" return CWCoreAPI.instance
def addResponse(self, resp): """ Add a response from the system to glitch table + logs """ normeval = self.findParam("normalresp").getValue() succeval = self.findParam("successresp").getValue() if len(normeval) > 0: # Check if Normal normresult = eval(normeval, {"s": resp}, {}) else: normresult = False # Check if Successful if len(succeval) > 0: # Check if Normal succresult = eval(succeval, {"s": resp}, {}) else: succresult = False # Check ? if not isinstance(normresult, bool): raise ValueError( "Result of 'normal' eval() not a bool, got %s (result: %s)" % (type(normresult), normresult) ) if not isinstance(succresult, bool): raise ValueError( "Result of 'success' eval() not a bool, got %s (result: %s)" % (type(succresult), succresult) ) if normresult and succresult: logging.warning("Both normresult and succresult True!") starttime = datetime.now() respstr = str(bytearray(resp.encode("utf-8"))) # respstr = ' '.join(["%02x" % t for t in bytearray(resp)]) settingsList = [] for i in range(0, len(self.tuneParamList)): try: settingsList.append(Parameter.getParameter(self.tuneParamList[i].paramScript)) except: raise StopIteration( 'Choose a valid Parameter Path for Tuning Parameter "%s" . Got: %s' % (self.tuneParamList[i].name(), self.tuneParamList[i].paramScript) ) newdata = { "input": "", "output": respstr, "normal": normresult, "success": succresult, "settings": settingsList, "date": starttime, } self.tableList.append(newdata) self.appendToTable(newdata) self.updateStatus() if self._campaignRunning and self.findParam(["Recordings", "saveresults"]).getValue(): if self._autosavef is None: # File previously not open try: self._autosavef = open(self._autosavefname, "w") except Exception as e: self.findParam(["Recordings", "saveresults"]).setValue(False) raise Warning( "Could not save recordings to file: %s. Reason: %s. Disabling it in order to continue." % (self._autosavefname, str(e)) ) self.findParam(["Recordings", "savefilename"]).setValue(self._autosavefname, ignoreReadonly=True) # Add notes pickle.dump({"notes": self.findParam(["Recordings", "savenotes"]).getValue()}, self._autosavef) # Add headers cmds = [ self.tuneParamList[i].findParam("parampath").getValue() for i in range(0, len(self.tuneParamList)) ] pickle.dump({"commands": cmds}, self._autosavef) # Add data pickle.dump({"data": newdata}, self._autosavef)
def __init__(self, cwtype, scope, oa): # Setup FPGA partial configuration dataZ self.prCon = pr.PartialReconfigConnection() self.prEnabled = False self.oa = oa # Glitch width/offset # Note that these are ints scaled by 256/100 self._width = 26 self._offset = 26 # These ranges are updated during __init__: see below self._min_width = 0 self._max_width = 100 self._min_offset = 0 self._max_offset = 100 # Single-shot arm timing self._ssarm = 2 self.params = Parameter(name=self.getName(), type='group').register() self.params.addChildren([ { 'name': 'Clock Source', 'type': 'list', 'values': { 'Target IO-IN': self.CLKSOURCE0_BIT, 'CLKGEN': self.CLKSOURCE1_BIT }, 'set': self.setGlitchClkSource, 'get': self.glitchClkSource }, { 'name': 'Glitch Width (as % of period)', 'key': 'width', 'type': 'float', 'limits': (self._min_width, self._max_width), 'step': 0.39062, 'readonly': True, 'set': self.setGlitchWidth, 'get': self.getGlitchWidth }, { 'name': 'Glitch Width (fine adjust)', 'key': 'widthfine', 'type': 'int', 'limits': (-255, 255), 'set': self.setGlitchWidthFine, 'get': self.getGlitchWidthFine }, { 'name': 'Glitch Offset (as % of period)', 'key': 'offset', 'type': 'float', 'limits': (self._min_offset, self._max_offset), 'step': 0.39062, 'readonly': True, 'set': self.setGlitchOffset, 'get': self.getGlitchOffset }, { 'name': 'Glitch Offset (fine adjust)', 'key': 'offsetfine', 'type': 'int', 'limits': (-255, 255), 'set': self.setGlitchOffsetFine, 'get': self.getGlitchOffsetFine }, { 'name': 'Glitch Trigger', 'type': 'list', 'values': { 'Ext Trigger:Continous': 1, 'Manual': 0, 'Continuous': 2, 'Ext Trigger:Single-Shot': 3 }, 'set': self.setGlitchTrigger, 'get': self.glitchTrigger }, { 'name': 'Single-Shot Arm', 'type': 'list', 'key': 'ssarm', 'values': { 'Before Scope Arm': 1, 'After Scope Arm': 2 }, 'set': self.setArmTiming, 'get': self.getArmTiming }, { 'name': 'Ext Trigger Offset', 'type': 'int', 'range': (0, 50000000), 'set': self.setTriggerOffset, 'get': self.triggerOffset }, { 'name': 'Repeat', 'type': 'int', 'limits': (1, 255), 'set': self.setNumGlitches, 'get': self.numGlitches }, { 'name': 'Manual Trigger / Single-Shot Arm', 'type': 'action', 'action': self.glitchManual }, { 'name': 'Output Mode', 'type': 'list', 'values': { 'Clock XORd': 0, 'Clock ORd': 1, 'Glitch Only': 2, 'Clock Only': 3, 'Enable Only': 4 }, 'set': self.setGlitchType, 'get': self.glitchType }, { 'name': 'Read Status', 'type': 'action', 'action': self.checkLocked }, { 'name': 'Reset DCM', 'type': 'action', 'action': self.actionResetDCMs }, ]) # Check if we've got partial reconfiguration stuff for this scope try: if cwtype == "cwrev2" or cwtype == "cwcrev2": settingprefix = "cwcrev2" partialbasename = "s6lx25" self.glitchPR = pr.PartialReconfigDataMulti() elif cwtype == "cwlite": settingprefix = "cwlite" partialbasename = "cwlite" self.glitchPR = pr.PartialReconfigDataMulti() elif cwtype == "cw1200": settingprefix = "cw1200" partialbasename = "cw1200" self.glitchPR = pr.PartialReconfigDataMulti() else: raise ValueError("Invalid ChipWhisperer Mode: %s" % cwtype) if scope.getFWConfig().loader._release_mode != "debug": if scope.getFWConfig().loader._release_mode == "builtin": filelike = scope.getFWConfig().loader._bsBuiltinData zfile = zipfile.ZipFile(filelike) elif scope.getFWConfig().loader._release_mode == "zipfile": fileloc = scope.getFWConfig().loader._bsZipLoc if zipfile.is_zipfile(fileloc): zfile = zipfile.ZipFile(fileloc, "r") else: logging.warning( 'Partial Reconfiguration DISABLED: no zip-file for FPGA' ) zfile = None else: logging.warning( 'Partial Reconfiguration DISABLED: no PR data for FPGA' ) zfile = None raise ValueError("Unknown FPGA mode: %s" % scope.getFWConfig().loader._release_mode) if zfile: self.glitchPR.load( zfile.open("%s-glitchwidth.p" % partialbasename)) self.glitchPR.load( zfile.open("%s-glitchoffset.p" % partialbasename)) self.prEnabled = True else: self.prEnabled = False else: logging.warning( 'Partial Reconfiguration DISABLED: Debug bitstream mode') self.prEnabled = False except IOError as e: logging.error(str(e)) self.prEnabled = False except ValueError as e: logging.error(str(e)) self.prEnabled = False except OSError as e: # Also catches WindowsError logging.error(str(e)) self.prEnabled = False if self.prEnabled: # Enable glitch width, check what we've got access to self.findParam('width').setReadonly(False) self._min_width = self.glitchPR.limitList[0][0] / 2.55 self._max_width = self.glitchPR.limitList[0][1] / 2.55 self.findParam('width').setLimits( (self._min_width, self._max_width)) self.findParam('offset').setReadonly(False) self._min_offset = self.glitchPR.limitList[1][0] / 2.55 self._max_offset = self.glitchPR.limitList[1][1] / 2.55 self.findParam('offset').setLimits( (self._min_offset, self._max_offset)) self.setOpenADC(oa) self.glitchSettings = GlitchSettings(self)