Exemplo n.º 1
0
    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')
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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