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
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
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 }, ])
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
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
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
# # 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):