def __getitem__(self, item): if isinstance(item, int): ind = item if ind < 0: ind = self.max + ind + 1 if not (0 <= ind <= self.max): raise IndexError('Index outside of range ({}, {})'.format( 0, self.max)) result = Trace(self.tm.get_trace(ind), self.tm.get_textin(ind), self.tm.get_textout(ind), self.tm.get_known_key(ind)) return result elif isinstance(item, slice): indices = item.indices(self.tm.num_traces()) result = [] for i in range(*indices): result.append( Trace(self.tm.get_trace(i), self.tm.get_textin(i), self.tm.get_textout(i), self.tm.get_known_key(i))) return result else: raise TypeError('Indexing by integer or slice only')
def capture_trace(self, scope, k, operation="pmult", Px=None, Py=None, check=True): """Capture a trace, running the specified test vector or operation (pmult or siggen). Does all individual steps needed to capture a trace (arming the scope, running the test vector or operation, getting the trace data back, etc.) Args: scope (ScopeTemplate): Scope object to use for capture. k (int): multiplier for pmult operation (string, optional): Operation to run. 'pmult': run a point multiplication. Requires Px, Py, and k be supplied. check: if set, verify the result (using ecpy) Px (int, optional): X coordinate of curve point for pmult. Generator point is used if not given. Py (int, optional): Y coordinate of curve point for pmult. Generator point is used if not given. Returns: :class:`Trace <chipwhisperer.common.traces.Trace>` or None if capture timed out. Raises: Warning or OSError: Error during capture. """ scope.arm() start_cycles = scope.adc.trig_count if operation == 'pmult': textout = self.run_pmult(k, Px, Py, check=check, verbose=False) else: logging.error("Please supply a valid operation to run.") cycles = scope.adc.trig_count - start_cycles ret = scope.capture() if ret: logging.warning("Timeout happened during capture") return None textin = {'operation': operation, 'Px': Px, 'Py': Py, 'k': k} textout['cycles'] = cycles wave = scope.get_last_trace() if check and cycles != self.pmul_cycles: logging.warning( "Operation took %d cycles (%d more than we expect it to)" % (cycles, cycles - self.pmul_cycles)) if len(wave) >= 1: return Trace(wave, textin, textout, None) else: return None
def __next__(self): if self.n > self.max: raise StopIteration result = Trace( self.tm.get_trace(self.n), self.tm.get_textin(self.n), self.tm.get_textout(self.n), self.tm.get_known_key(self.n), ) self.n += 1 return result
def preprocess(self): """Process all traces. Returns: Project: A new project containing the processed traces. .. versionadded: 5.1 Add preprocess method to Preprocessing module. """ proj = Project() for i in range(self.num_traces()): proj.traces.append( Trace(self.get_trace(i), self.get_textin(i), self.get_textout(i), self.get_known_key(i))) return proj
def preprocess(self): """Process all traces. Returns: Project: A new project containing the processed traces. .. versionadded: 5.1 Add preprocess method to Preprocessing module. """ proj = Project() for i in range(self.num_traces()): if self.get_trace(i) is None: logging.warn("Wave {} ({}) is invalid. Skipping ".format( i, self.get_trace(i))) continue proj.traces.append( Trace(self.get_trace(i), self.get_textin(i), self.get_textout(i), self.get_known_key(i))) return proj
def capture_trace(scope, target, plaintext, key=None, ack=True): """Capture a trace, sending plaintext and key Does all individual steps needed to capture a trace (arming the scope sending the key/plaintext, getting the trace data back, etc.). Uses target.output_len as the length of the expected target reponse for simpleserial. Args: scope (ScopeTemplate): Scope object to use for capture. target (TargetTemplate): Target object to read/write text from. plaintext (bytearray): Plaintext to send to the target. Should be unencoded bytearray (will be converted to SimpleSerial when it's sent). If None, don't send plaintext. key (bytearray, optional): Key to send to target. Should be unencoded bytearray. If None, don't send key. Defaults to None. ack (bool, optional): Check for ack when reading response from target. Defaults to True. Returns: :class:`Trace <chipwhisperer.common.traces.Trace>` or None if capture timed out. Raises: Warning or OSError: Error during capture. Example: Capturing a trace:: import chipwhisperer as cw scope = cw.scope() scope.default_setup() target = cw.target() ktp = cw.ktp.Basic() key, pt = ktp.new_pair() trace = cw.capture_trace(scope, target, pt, key) .. versionadded:: 5.1 Added to simplify trace capture. .. versionchanged:: 5.2 Added ack parameter and use of target.output_len """ import signal, logging # useful to delay keyboard interrupt here, # since could interrupt a USB operation # and kill CW until unplugged+replugged class DelayedKeyboardInterrupt: def __enter__(self): self.signal_received = False self.old_handler = signal.signal(signal.SIGINT, self.handler) def handler(self, sig, frame): self.signal_received = (sig, frame) logging.debug('SIGINT received. Delaying KeyboardInterrupt.') def __exit__(self, type, value, traceback): signal.signal(signal.SIGINT, self.old_handler) if self.signal_received: self.old_handler(*self.signal_received) # with DelayedKeyboardInterrupt(): if key: target.set_key(key, ack=ack) scope.arm() if plaintext: target.simpleserial_write('p', plaintext) ret = scope.capture() i = 0 while not target.is_done(): i += 1 time.sleep(0.05) if i > 100: warnings.warn("Target did not finish operation") return None if ret: warnings.warn("Timeout happened during capture") return None response = target.simpleserial_read('r', target.output_len, ack=ack) wave = scope.get_last_trace() if len(wave) >= 1: return Trace(wave, plaintext, response, key) else: return None
def capture_trace(scope, target, plaintext, key=None): """Capture a trace, sending plaintext and key Does all individual steps needed to capture a trace (arming the scope sending the key/plaintext, getting the trace data back, etc.) Args: scope (ScopeTemplate): Scope object to use for capture. target (TargetTemplate): Target object to read/write text from. plaintext (bytearray): Plaintext to send to the target. Should be unencoded bytearray (will be converted to SimpleSerial when it's sent). If None, don't send plaintext. key (bytearray, optional): Key to send to target. Should be unencoded bytearray. If None, don't send key. Defaults to None. Returns: :class:`Trace <chipwhisperer.common.traces.Trace>` or None if capture timed out. Raises: Warning or OSError: Error during capture. Example: Capturing a trace:: import chipwhisperer as cw scope = cw.scope() scope.default_setup() target = cw.target() ktp = cw.ktp.Basic() key, pt = ktp.new_pair() trace = cw.capture_trace(scope, target, pt, key) .. versionadded:: 5.1 Added to simplify trace capture. """ if key: target.set_key(key) scope.arm() if plaintext: target.simpleserial_write('p', plaintext) ret = scope.capture() i = 0 while not target.is_done(): i += 1 time.sleep(0.05) if i > 100: warnings.warn("Target did not finish operation") return None if ret: warnings.warn("Timeout happened during capture") return None response = target.simpleserial_read('r', 16) wave = scope.get_last_trace() if len(wave) >= 1: return Trace(wave, plaintext, response, key) else: return None