Beispiel #1
0
    def __init__(self, psClass=None):
        self.ps = psClass
        self.dataUpdated = util.Signal()

        chlist = {}
        for t in self.ps.CHANNELS:
            if self.ps.CHANNELS[t] < self.ps.CHANNELS['MaxChannels']:
                chlist[t] = self.ps.CHANNELS[t]

        # Rebuild channel range as string + api value
        chRange = util.DictType()
        for key in sorted(self.ps.CHANNEL_RANGE):
            chRange[ key['rangeStr'] ] = key['rangeV']

        self.getParams().addChildren([
            {'name':'Trace Measurement', 'key':'trace', 'type':'group', 'children':[
                {'name':'Source', 'key':'tracesource', 'type':'list', 'values':chlist, 'value':0, 'action':self.updateCurrentSettings},
                {'name':'Probe Att.', 'key':'traceprobe', 'type':'list', 'values':{'1:1':1, '1:10':10}, 'value':1, 'action':self.updateCurrentSettings},
                {'name':'Coupling', 'key':'tracecouple', 'type':'list', 'values':self.ps.CHANNEL_COUPLINGS, 'value':0, 'action':self.updateCurrentSettings},
                {'name':'Y-Range', 'key':'traceyrange', 'type':'list', 'values':chRange, 'value':1.0, 'action':self.updateCurrentSettings},
            ]},
            {'name':'Trigger', 'key':'trig', 'type':'group', 'children':[
                {'name':'Source', 'key':'trigsource', 'type':'list', 'values':chlist, 'value':1, 'action':self.updateCurrentSettings},
                {'name':'Probe Att.', 'key':'trigprobe', 'type':'list', 'values':{'1:1':1, '1:10':10}, 'value':10, 'action':self.updateCurrentSettings},
                {'name':'Coupling', 'key':'trigcouple', 'type':'list', 'values':self.ps.CHANNEL_COUPLINGS, 'value':1, 'action':self.updateCurrentSettings},
                {'name':'Y-Range', 'key':'trigrange', 'type':'list', 'values':chRange, 'value':5.0, 'action':self.updateCurrentSettings},
                {'name':'Trigger Direction', 'key':'trigtype', 'type':'list', 'values':self.ps.THRESHOLD_TYPE, 'value':self.ps.THRESHOLD_TYPE["Rising"], 'action':self.updateCurrentSettings},
                {'name':'Trigger Level', 'key':'triglevel', 'type':'float', 'step':1E-2, 'siPrefix':True, 'suffix':'V', 'limits':(-5, 5), 'value':0.5, 'action':self.updateCurrentSettings},
            ]},
            {'name':'Sample Rate', 'key':'samplerate', 'type':'int', 'step':1E6, 'limits':(10000, 5E9), 'value':100E6, 'action':self.updateSampleRateFreq, 'siPrefix':True, 'suffix': 'S/s'},
            {'name':'Sample Length', 'key':'samplelength', 'type':'int', 'step':250, 'limits':(1, 500E6), 'value':500, 'action':self.updateSampleRateFreq},
            {'name':'Sample Offset', 'key':'sampleoffset', 'type':'int', 'step':1000, 'limits':(0, 100E6), 'value':0, 'action':self.updateSampleRateFreq},
        ])
    def calculatePGE(self):
        """Calculate the Partial Guessing Entropy (PGE)"""
        if not self._analysisSource:
            raise Warning("Attack not set/executed yet")

        stats = self._analysisSource.getStatistics()
        pge = stats.pge_total
        allpge = util.DictType()

        for i in pge:
            tnum = i['trace']
            if not tnum in allpge:
                allpge[tnum] = [{'pgesum':0, 'trials':0} for z in range(0,stats.numSubkeys)]

            allpge[tnum][i['subkey']]['pgesum'] += i['pge']
            allpge[tnum][i['subkey']]['trials'] += 1

        for (tnum, plist) in allpge.iteritems():
            for j in plist:
                if j['trials'] > 0:
                    j['pge'] = float(j['pgesum']) / float(j['trials'])
                    # print "%d "%j['trials'],
                else:
                    j['pge'] = None

        return allpge
Beispiel #3
0
class ResultsBase(Parameterized):
    """
    Base class for the output widgets:
    To be uses in conjunct with chipwhisperer.common.utils.analysissource/tracesource
    """
    registeredObjects = util.DictType()
    sigRegisteredObjectsChanged = util.Signal()
    __classParameter = None
    __classes = None

    def getWidget(self):
        return None

    # @classmethod  #TODO: Finish this method
    # def deregister(self, name):
    #     if self.registeredObjects.pop(name, None):
    #         self.sigRegisteredObjectsChanged.emit(None)

    @classmethod
    def getClasses(cls):
        if not cls.__classes:
            cls.__classes = getPluginsInDictFromPackage(
                "chipwhisperer.common.results", False, False)
        return cls.__classes

    @classmethod
    def getClassParameter(cls):
        if not cls.__classParameter:
            cls.__classParameter = Parameter(name="Results",
                                             type='group').register()
        return cls.__classParameter

    @classmethod
    def createNew(cls, className, instanceName=None):
        # To do it manually using the python console:
        # from chipwhisperer.common.results.base import ResultsBase
        # ResultsBase.createNew("Trace Output Plot", "Channel 2")

        if instanceName in cls.registeredObjects:
            raise Warning(
                "Result widget \"%s\" already exists, choose a different name"
                % instanceName)

        obj = cls.getClasses()[className](instanceName)
        cls.registeredObjects[obj.getName()] = obj
        cls.sigRegisteredObjectsChanged.emit(obj)
        cls.getClassParameter().append(obj.getParams())
        return obj
Beispiel #4
0
    def __init__(self):
        TargetTemplate.__init__(self)
        self.hw = None

        conntypes = util.DictType()
        conntypes['Select Interface type...'] = None
        conntypes['CW Bitstream, with OpenADC'] = ChipWhispererComm(
            standalone=False)
        conntypes['CW Bitstream, no OpenADC'] = ChipWhispererComm(
            standalone=True)
        conntypes['Original Bitstream'] = FTDIComm()

        self.fixedStart = True
        self.hw = None
        self.getParams().addChildren([
            {
                'name': 'Connection via:',
                'key': 'conn',
                'type': 'list',
                'values': conntypes,
                'set': self.setConn,
                'get': self.getConn,
                'default': None
            },
            {
                'name': 'Reset FPGA',
                'key': 'reset',
                'type': 'action',
                'action': self.reset,
                'visible': False
            },
            {
                'name': 'USB Serial #:',
                'key': 'serno',
                'type': 'list',
                'values': ['Press Refresh'],
                'value': 'Press Refresh',
                'visible': False
            },
            {
                'name': 'Enumerate Attached Devices',
                'key': 'pushsno',
                'type': 'action',
                'action': self.refreshSerial,
                'visible': False
            },
        ])
Beispiel #5
0
class TraceSource(object):
    """
    It has traces as output
    Keeps a dictionary with all the registered objets and emits a signal when a new one is added
    """
    registeredObjects = util.DictType()
    registeredObjects["None"] = None
    sigRegisteredObjectsChanged = util.Signal()

    def __init__(self, name="Unknown"):
        self.sigTracesChanged = util.Signal()
        self.name = name
        self.uuid = str(uuid.uuid4())

    def getTrace(self, n):
        """Return the trace with number n in the current TraceSource object"""
        return None

    def numPoints(self):
        return 0

    def numTraces(self):
        return 0

    def offset(self):
        return 0

    def getSampleRate(self):
        """Return the Sample Rate used to generate the traces"""
        return 0

    def getTextin(self, n):
        """Get text-in number n"""
        raise NotImplementedError

    def getTextout(self, n):
        """Get text-out number n"""
        raise NotImplementedError

    def getKnownKey(self, n=None):
        """Get known-key number n"""
        raise NotImplementedError

    def getSegmentList(self):
        """Return a list of segments."""
        raise NotImplementedError

    def getAuxData(self, n, auxDic):
        """Return data about a segment"""
        raise NotImplementedError

    def getSegment(self, n):
        """Return the trace segment with the specified trace in the list with all enabled segments."""
        raise NotImplementedError

    def register(self):
        """Register the current TraceSource object in a list and emit a signal to inform it was updated"""
        self.registeredObjects[self.name] = self
        self.sigRegisteredObjectsChanged.emit()
        return self

    def deregister(self):
        """Deregister the current TraceSource and emit a signal to inform this event"""
        try:
            #Only deregister if UUID matches (NB: don't use direct comparison in case later we adjust repr() )
            if TraceSource.registeredObjects[self.name].uuid == self.uuid:
                if TraceSource.registeredObjects.pop(self.name, None):
                    TraceSource.sigRegisteredObjectsChanged.emit()
        except KeyError:
            pass

    @classmethod
    def deregisterObject(cls, name, uuid = None):
        """Deregister the TraceSource and emit a signal to inform this event"""
        try:
            if (uuid is None) or (cls.registeredObjects[name].uuid == uuid):
                if cls.registeredObjects.pop(name, None):
                    cls.sigRegisteredObjectsChanged.emit()
        except KeyError:
            pass
Beispiel #6
0
class ModelsBase(Parameterized):
    _name = 'Crypto Model'

    hwModels = util.DictType()
    hwModels_toStr = []

    ##Generate this table with:
    #HW = []
    #for n in range(0, 256):
    #    HW = HW + [bin(n).count("1")]
    HW = [
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
        2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
        2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
        4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
        3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
        4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
    ]

    def __init__(self, numSubKeys, permPerSubkey, model=None):
        self.sigParametersChanged = util.Signal()
        self.numSubKeys = numSubKeys
        self.permPerSubkey = permPerSubkey
        self.numRoundKeys = 0
        self.model = model
        self.getParams().addChildren([
            {
                'name': 'Hardware Model',
                'type': 'list',
                'values': self.hwModels,
                'get': self.getHwModel,
                'set': self.setHwModel
            },
            {
                'name': 'Number of SubKeys',
                'type': 'int',
                'get': self.getNumSubKeys,
                'readonly': True
            },
            {
                'name': 'Number of Permutations',
                'type': 'int',
                'get': self.getPermPerSubkey,
                'readonly': True
            },
        ])

    @classmethod
    def getHW(cls, n):
        return cls.HW[n]

    def processKnownKey(self, inpkey):
        return inpkey

    def leakage(self, pt, ct, guess, bnum, state):
        pass

    def getNumSubKeys(self):
        return self.numSubKeys

    def getPermPerSubkey(self):
        return self.permPerSubkey

    def getNumRoundKeys(self):
        return self.numRoundKeys

    def getHwModel(self):
        return self.model

    def keyScheduleRounds(self,
                          inputkey,
                          inputround,
                          desiredround,
                          returnSubkeys=True):
        pass

    def getRoundKeys(self, key, iniRound):
        ret = []
        for targetRound in range(0, self.numRoundKeys + 1):
            ret.append(
                self.keyScheduleRounds(key,
                                       iniRound,
                                       targetRound,
                                       returnSubkeys=False))
        return ret

    @setupSetParam("Hardware Model")
    def setHwModel(self, model):
        self.model = model
        self.sigParametersChanged.emit()

    def getHwModelString(self):
        return sys.modules[
            self.__class__.
            __module__].__name__ + '.' + self.__class__.__name__ + '.' + self.hwModels_toStr[
                self.model]

    def binary_list_to_subkeys(self, bitlist, nrBits):
        ret = []
        pos = 0
        while pos <= len(bitlist) - nrBits:
            out = 0
            for bit in range(nrBits):
                out = (out << 1) | bitlist[pos + bit]
            ret.append(out)
            pos += nrBits
        return ret

    def array_of_bytes_to_bin(self, bytes, nrBits):
        init = np.array([], dtype=bool)
        for byte in bytes:
            init = np.concatenate(
                (init, np.unpackbits(np.uint8(byte))[8 - nrBits:]), axis=0)
        return init

    def _VccToGnd(self, var):
        """Convert from number of 1's to number of 0's... used when shunt inserted in GND path"""
        return 8 - var
Beispiel #7
0
class ModelsBase(Parameterized):
    _name = 'Crypto Model'

    hwModels = util.DictType()
    hwModels_toStr = []

    ##Generate this table with:
    #HW = []
    #for n in range(0, 256):
    #    HW = HW + [bin(n).count("1")]
    HW = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3,
          4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,
          4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2,
          3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,
          4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4,
          5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
          3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
          3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
          4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
          6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5,
          5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6,
          7, 7, 8]

    def __init__(self, numSubKeys, permPerSubkey, model=None):
        self.sigParametersChanged = util.Signal()
        self.numSubKeys = numSubKeys
        self.permPerSubkey = permPerSubkey
        self.numRoundKeys = 0
        self.model = model
        #Update interal models (if required)
        self._updateHwModel()

        if model.name in self.hwModels.keys():
            if self.hwModels[model.name] != model:
                self.hwModels[str(model)] = model
        else:
            self.hwModels[model.name] = model

        self.getParams().addChildren([
            {'name':'Hardware Model', 'type':'list', 'values':self.hwModels, 'get':self.getHwModel, 'set':self.setHwModel, 'addToList':True},
            {'name':'Number of SubKeys', 'type':'int', 'get':self.getNumSubKeys, 'readonly':True},
            {'name':'Number of Permutations', 'type':'int', 'get':self.getPermPerSubkey, 'readonly':True},
        ])

    @classmethod
    def getHW(cls, n):
        return cls.HW[n]

    def processKnownKey(self, inpkey):
        return inpkey

    def leakage(self, pt, ct, guess, bnum, state):
        pass

    def getNumSubKeys(self):
        return self.numSubKeys

    def getPermPerSubkey(self):
        return self.permPerSubkey

    def getNumRoundKeys(self):
        return self.numRoundKeys

    def getHwModel(self):
        return self.model

    def keyScheduleRounds(self, inputkey, inputround, desiredround, returnSubkeys=True):
        raise NotImplementedError()

    def getRoundKeys(self, key, iniRound):
        ret = []
        for targetRound in range(0, self.numRoundKeys+1):
            ret.append(self.keyScheduleRounds(key, iniRound, targetRound, returnSubkeys=False))
        return ret

    @setupSetParam("Hardware Model")
    def setHwModel(self, model, kwargs=None):
        self.model = model
        self.model_kwargs = kwargs
        self._updateHwModel()
        self.sigParametersChanged.emit()

    def _updateHwModel(self):
        """" Re-implement this to update leakage model """
        pass

    def _VccToGnd(self, var):
        """Convert from number of 1's to number of 0's... used when shunt inserted in GND path"""
        return 8-var
Beispiel #8
0
#
#    You should have received a copy of the GNU General Public License
#    along with chipwhisperer.  If not, see <http://www.gnu.org/licenses/>.

from chipwhisperer.analyzer.models.aes.funcs import sbox, inv_sbox
from chipwhisperer.analyzer.models.aes.key_schedule import keyScheduleRounds
from chipwhisperer.common.utils import util

LEAK_HW_SBOXOUT_FIRSTROUND = 1
LEAK_HD_LASTROUND_STATE = 2
LEAK_HD_SBOX_IN_OUT = 3
LEAK_HD_SBOX_IN_SUCCESSIVE = 4
LEAK_HD_SBOX_OUT_SUCCESSIVE = 5
LEAK_HW_INVSBOXOUT_FIRSTROUND = 6

leakagemodels = util.DictType()
leakagemodels[
    'HW: AES SBox Output, First Round (Enc)'] = 'LEAK_HW_SBOXOUT_FIRSTROUND'
leakagemodels[
    'HW: AES Inv SBox Output, First Round (Dec)'] = 'LEAK_HW_INVSBOXOUT_FIRSTROUND'
leakagemodels['HD: AES Last-Round State'] = 'LEAK_HD_LASTROUND_STATE'
leakagemodels['HD: AES SBox Input to Output'] = 'LEAK_HD_SBOX_IN_OUT'
leakagemodels['HD: AES SBox Input i to i+1'] = 'LEAK_HD_SBOX_IN_SUCCESSIVE'
leakagemodels['HD: AES SBox Output i to i+1'] = 'LEAK_HD_SBOX_OUT_SUCCESSIVE'

numSubKeys = 16
permPerSubkey = 256

##Generate this table with:
#HW = []
#for n in range(0, 256):