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 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 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()
Beispiel #4
0
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
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)
Beispiel #6
0
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 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)
Beispiel #8
0
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
Beispiel #9
0
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)
Beispiel #10
0
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__ = "V4.0.2"
    _name = 'Generic Settings'
    instance = None

    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 updateLastKeyText(self, key, textin, textout, exp):
        """Callback for acq controller signal - update key/textin/textout
        """
        self._lastKey = key
        self._lastTextin = textin
        self._lastTextout = textout
        self._lastExpected = exp

        self.sigNewTextResponse.emit(key, textin, textout, exp)

    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():
            # Don't do anything if we're not changing scopes
            if self.getScope() is driver:
                return
            else:
                self.getScope().dis()
        self._scope = driver
        if self.getScope():
            self.getScope().connectStatus.connect(self.sigConnectStatus.emit)
            self.scopeParam.append(self.getScope().params)
            try:
                ResultsBase.registeredObjects["Trace Output Plot"].setTraceSource(
                    TraceSource.registeredObjects[next(reversed(TraceSource.registeredObjects))])
            except KeyError:
                pass
            if self.getScope().getStatus():
                self.getScope().connectStatus.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():
            # Don't do anything if we're not changing targets
            if self.getTarget() is driver:
                return
            self.getTarget().dis()
        self._target = driver
        if self.getTarget():
            self.targetParam.append(self.getTarget().params)
            self.getTarget().newInputData.connect(self.sigNewInputData.emit)
            self.getTarget().connectStatus.connect(self.sigConnectStatus.emit)
            if self.getTarget().getStatus():
                self.getTarget().connectStatus.emit()


    def getAuxList(self):
        return self._auxList

    def setAuxList(self, new_list):
        self._auxList = new_list

    def getAuxFunctions(self, only_enabled):
        """TODO: doc
        """
        return self._auxList.getDict(only_enabled)

    def getAcqPattern(self):
        """Return the selected acquisition pattern."""
        return self._acqPattern

    def getAttack(self):
        return self._attack

    @setupSetParam(["Attack Settings", "Attack"])
    def setAttack(self, atk):
        self._attack = atk
        #if self._attack is not None:
        #    self.attackParam.append(self._attack.params)

    @setupSetParam(["Acquisition Settings", "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."""
        if self._project is not None:
            return self._project.getTraceFormat()
        else:
            return None

    def setTraceFormat(self, format):
        """Set the current trace format for acquisition."""
        if self._project is not None:
            self._project.setTraceFormat(format)

    def project(self):
        """Return the current opened project"""
        return self._project

    def setProject(self, proj):
        """Set the current opened project"""
        self._project = proj
        self.params.append(proj.getParams())
        self.sigNewProject.emit()

    def newProject(self):
        """Create a new project"""
        self.setProject(ProjectFormat(self.__name__, self.__version__))

    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"""
        logging.warning('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(["Acquisition Settings", "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(["Acquisition Settings", "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:
            aux_dict = self.getAuxFunctions(True)
            ac = AcquisitionController(self.getScope(), self.getTarget(), writer=None, aux=aux_dict, keyTextPattern=self.getAcqPattern())
            ac.sigNewTextResponse.connect(self.updateLastKeyText)
            if self.getTarget():
                self.getTarget().init()
            return ac.doSingleReading()
        except Warning:
            sys.excepthook(*sys.exc_info())
            return False

    def captureM(self, progressBar=None, scope=None, target=None, project=None, aux_list=None, ktp=None, N=1, seg_size=None):
        """Capture multiple traces and save its result"""
        if not progressBar:
            progressBar = ProgressBarText()

        if seg_size is None:
            seg_size = 1000
        trace_mgr = project.traceManager() if project is not None else None
        trace_fmt = project.getTraceFormat() if project is not None else None
        aux_dict = aux_list.getDict(True) if aux_list is not None else None
        segments = int(math.ceil(N / float(seg_size)))

        with progressBar:
            progressBar.setStatusMask("Current Segment = %d Current Trace = %d", (0,0))
            progressBar.setMaximum(N)

            waveBuffer = None
            tcnt = 0
            for i in range(0, segments):
                if progressBar.wasAborted(): break

                this_seg_size = min(seg_size, N - i*seg_size)
                if trace_fmt is not None:
                    currentTrace = self.getNewTrace(trace_fmt)
                    # Load trace writer information
                    prefix = currentTrace.config.attr("prefix")[:-1]
                    currentTrace.config.setAttr("targetHW", target.getName() if target is not None else "None")
                    currentTrace.config.setAttr("targetSW", os.path.split(Programmer.lastFlashedFile)[1])
                    currentTrace.config.setAttr("scopeName", scope.getName() if scope is not None else "None")
                    notes_str = "AckPattern: " + str(ktp) + "; "
                    notes_str += "Aux: "
                    if aux_dict is not None:
                        for t in aux_dict.keys():
                            notes_str += "%s" % t + ", ".join([str(item) for item in aux_dict[t] if item])
                    currentTrace.config.setAttr("notes", notes_str)
                    currentTrace.setTraceHint(this_seg_size)

                    if waveBuffer is not None:
                        currentTrace.setTraceBuffer(waveBuffer)
                else:
                    currentTrace = None
                    prefix = datetime.now().strftime('%Y.%m.%d-%H.%M.%S')

                if aux_dict is not None:
                    for func in aux_dict['set_prefix']:
                        func(prefix)

                ac = AcquisitionController(scope, target, currentTrace, aux_dict, ktp)
                ac.setMaxtraces(this_seg_size)
                ac.sigNewTextResponse.connect(self.updateLastKeyText)
                ac.sigTraceDone.connect(self.sigTraceDone.emit)
                __pb = lambda: progressBar.updateStatus(i*seg_size + ac.currentTrace + 1, (i, ac.currentTrace))
                ac.sigTraceDone.connect(__pb)
                self.sigCampaignStart.emit(prefix)
                ac.doReadings(tracesDestination=trace_mgr, progressBar=progressBar)

                if currentTrace is not None:
                    project.saveAllSettings(os.path.dirname(currentTrace.config.configFilename()) + "/%s_settings.cwset" % prefix, onlyVisibles=True)
                    waveBuffer = currentTrace.traces  # Re-use the wave buffer to avoid memory reallocation
                self.sigCampaignDone.emit()
                tcnt += seg_size

                if progressBar.wasAborted():
                    break

            if currentTrace is not None:
                currentTrace.unloadAllTraces()  # Required in order to make the GC work properly :(
                trace_fmt.unloadAllTraces()
        return True

    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")
            return [self.runScriptClass(c, funcName) for c in classes]
        except Exception as e:
            sys.excepthook(Warning, "Could not execute Script Module %s: '%s:%s'" %
                             (str(mod),
                              "".join(traceback.format_exception_only(sys.exc_info()[0], e.message)).rstrip("\n "),
                              str(e).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:
                return eval('m.%s()' % funcName)
        except Exception as e:
                sys.excepthook(Warning, "Could not execute method %s in script class %s: '%s:%s'" %
                               (funcName,
                                scriptClass.__name__,
                                "".join(traceback.format_exception_only(sys.exc_info()[0], e.message)).rstrip("\n "),
                                str(e).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 getLastKey(self):
        return self._lastKey

    def getLastTextin(self):
        return self._lastTextin

    def getLastTextout(self):
        return self._lastTextout

    def getLastExpected(self):
        return self._lastExpected
class TraceExplorerDialog(AutoScript, Parameterized):
    """Open dialog to explore trace properties, data graphs, etc"""
    _name = "Trace Explorer"

    def __init__(self, parent):
        AutoScript.__init__(self)
        self.enabled = False
        self.autoScriptInit()

        # Add example scripts to this list
        self.exampleScripts = [PartitionDisplay(self), TextDisplay(self)]

        # Add Scripts
        self.setupCommonScripts()

        self.progressBar = ProgressBar(show=False)

    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 getEnabled(self):
        return self.enabled

    @setupSetParam("Enabled")
    def setEnabled(self, enabled):
        self.enabled = enabled
        self.paramCommonScripts.show(enabled)
        self.updateChildren()

####COMMON SCRIPTING STUFF

    def getProgressIndicator(self):
        return self.progressBar

    def updateChildren(self):
        for example in self.exampleScripts:
            if hasattr(example, 'updateScript'):
                example.updateScript("traceexplorer_show")
        self.updateScripts()

    def updateScripts(self):
        for index, example in enumerate(self.exampleScripts):
            if hasattr(example, "_smartstatements"):
                for k in example._smartstatements:
                    statements = example.getStatements(k)
                    if len(statements) > 0:
                        prefix = example.__class__.__name__ + "_"
                        self._smartstatements[prefix +
                                              k] = example._smartstatements[k]
                        self._smartstatements[prefix + k].addSelfReplacement(
                            "exampleScripts[%d]." % index)

                for k in example.getImportStatements():
                    self.importsAppend(k)

        self.scriptsUpdated.emit()
class TraceExplorerDialog(AutoScript, Parameterized):
    """Open dialog to explore trace properties, data graphs, etc"""
    _name = "Trace Explorer"
    def __init__(self, parent):
        AutoScript.__init__(self)
        self.enabled = False
        self.autoScriptInit()

        # Add example scripts to this list
        self.exampleScripts = [PartitionDisplay(self), TextDisplay(self)]

        # Add Scripts
        self.setupCommonScripts()

        self.progressBar = ProgressBar(show=False)

    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 getEnabled(self):
        return self.enabled

    @setupSetParam("Enabled")
    def setEnabled(self, enabled):
        self.enabled = enabled
        self.paramCommonScripts.show(enabled)
        self.updateChildren()

####COMMON SCRIPTING STUFF

    def getProgressIndicator(self):
        return self.progressBar

    def updateChildren(self):
        for example in self.exampleScripts:
            if hasattr(example, 'updateScript'):
                example.updateScript("traceexplorer_show")
        self.updateScripts()

    def updateScripts(self):
        for index, example in enumerate(self.exampleScripts):
            if hasattr(example, "_smartstatements"):
                for k in example._smartstatements:
                    statements = example.getStatements(k)
                    if len(statements) > 0:
                        prefix = example.__class__.__name__ + "_"
                        self._smartstatements[prefix + k] = example._smartstatements[k]
                        self._smartstatements[prefix + k].addSelfReplacement("exampleScripts[%d]." % index)

                for k in example.getImportStatements():
                    self.importsAppend(k)

        self.scriptsUpdated.emit()