def do_invariant_test(ktp_class, platform, N=10000, key_len=16):
    # may not be working
    scope, target = setup_device(platform)
    #scope.adc.offset = 20000
    ktp = ktp_class(key_len)
    #ktp = FixedVRandomKey(key_len)
    #store = zarr.DirectoryStore('SFvR/{}-{}-{}-{}.zarr'.format(platform, ktp._name, N, key_len))
    #root = zarr.group(store=store, overwrite=True)
    root = zarr.group("")
    zgroup1 = root.zeros('traces/group1', shape=(N, scope.adc.samples), chunks=(2500, None), dtype='float64')
    zgroup2 = root.zeros('traces/group2', shape=(N, scope.adc.samples), chunks=(2500, None), dtype='float64')

    group1 = zgroup1[:,:]
    group2 = zgroup2[:,:]
    for i in trange(N):
        key, text = ktp.next_group_A()
        trace = cw.capture_trace(scope, target, text, key)
        while trace is None:
            trace = cw.capture_trace(scope, target, text, key)

        if not verify_AES(text, key, trace.textout):
            raise ValueError("Encryption failed")
        group1[i,:] = trace.wave[:]

        key, text = ktp.next_group_B() 
        trace = cw.capture_trace(scope, target, text, key)
        while trace is None:
            trace = cw.capture_trace(scope, target, text, key)

        group2[i,:] = trace.wave[:]
        if not verify_AES(text, key, trace.textout):
            raise ValueError("Encryption failed")
Exemple #2
0
def capture_rand(scope, target, N=10000, key_len=16, waves=None, textins=None):
    """ Capture traces for a rand_v_rand TVLA t-test

    Args:
        scope (CW scope object): Setup scope object
        target (CW target object): Setup target object
        N (int): Number of traces to capture
        key_len (int): 16 for AES-128, 32 for AES-256
        waves (np.array): Optional array object for storing traces in
        textins (np.array): Optional array object for storing plaintexts in

    Returns:
        waves, textins
    """
    ktp = FixedVRandomText(key_len)
    if waves is None:
        waves = np.zeros((N, scope.adc.samples), dtype='float64')
    if textins is None:
        textins = np.zeros((N, 16), dtype='uint8')
    for i in trange(N):
        key, text = ktp.next_group_B()
        trace = cw.capture_trace(scope, target, text, key)
        while trace is None:
            trace = cw.capture_trace(scope, target, text, key)
        if not verify_AES(text, key, trace.textout):
            raise ValueError("Encryption failed")

        waves[i,:] = trace.wave[:]
        textins[i,:] = np.array(text)[:]

    return waves, textins
def random_v_random_capture(platform, key_len=16, N=10000):
    #may not be working
    scope,target = setup_device(platform)
    ktp = FixedVRandomText(key_len)
    store = zarr.DirectoryStore('data/{}-{}-{}.zarr'.format(platform,N,key_len))
    root = zarr.group(store=store, overwrite=True)

    zwaves = root.zeros('traces/waves', shape=(2*N, scope.adc.samples), chunks=(2500, None), dtype='float64')
    ztextins = root.zeros('traces/textins', shape=(2*N, 16), chunks=(2500, None), dtype='uint8')

    waves = zwaves[:,:]
    textins = ztextins[:,:]
    
    for i in trange(2*N):
        key, text = ktp.next_group_B()
        trace = cw.capture_trace(scope, target, text, key)
        while trace is None:
            trace = cw.capture_trace(scope, target, text, key)

        if not verify_AES(text, key, trace.textout):
            raise ValueError("Encryption failed")
        #project.traces.append(trace)
        waves[i, :] = trace.wave
        textins[i, :] = np.array(text)
    zwaves[:,:] = waves[:,:]
    ztextins[:,:] = textins[:,:]
    print("Last encryption took {} samples".format(scope.adc.trig_count))
Exemple #4
0
 def _capture(self) -> cw.Trace:
     key, pt = self._ktp.new_pair()
     trace = cw.capture_trace(self._scope, self._target, pt, key)
     if self._is_defective_trace(trace):
         for _ in range(3):
             trace = cw.capture_trace(self._scope, self._target, pt, key)
             if not self._is_defective_trace(trace):
                 return trace
         else:
             raise RuntimeError(
                 "Unable to capture the valid trace from CW device.")
     return trace
def run_capture(capture_cfg, ot, ktp):
    """Run ChipWhisperer capture.

  Args:
    capture_cfg: Dictionary with capture configuration settings.
    ot: Initialized OpenTitan target.
    ktp: Key and plaintext generator.
  """
    key, text = ktp.next()

    cipher = AES.new(bytes(key), AES.MODE_ECB)
    print(f'Using key: {binascii.b2a_hex(bytes(key))}')

    project_file = capture_cfg['project_name']
    project = cw.create_project(project_file, overwrite=True)

    for i in tqdm(range(capture_cfg['num_traces']), desc='Capturing',
                  ncols=80):
        key, text = ktp.next()
        ret = cw.capture_trace(ot.scope, ot.target, text, key, ack=False)
        if not ret:
            print('Failed capture')
            continue

        expected = binascii.b2a_hex(cipher.encrypt(bytes(text)))
        got = binascii.b2a_hex(ret.textout)
        assert (got == expected), (
            f'Incorrect encryption result!\ngot: {got}\nexpected: {expected}\n'
        )

        project.traces.append(ret)

        ot.target.flush()

    project.save()
Exemple #6
0
def main():
    args = parse_args()

    # Set up boards
    scope, target = initialize()

    # Capture traces
    traces = []
    keygen = chipwhisperer.ktp.Basic()
    keygen.fixed_key = True
    keygen.fixed_plaintext = False
    while len(traces) <= args.traces:
        # Get next key and plaintext
        key, text = keygen.next()

        trace = chipwhisperer.capture_trace(scope, target, text, key)
        if trace is None:
            continue
        traces.append(trace)

    # Pull out the data that we want from the traces
    trace_array = [trace.wave for trace in traces]
    plaintext_array = [trace.textin for trace in traces]

    # Save to json in zip
    with ZipFile(args.output, "w") as zipfile:
        with zipfile.open("traces.json", "w") as tracefile:
            traces = {
                "traces": trace_array,
                "plaintexts": plaintext_array,
            }
            json.dump(tracefile)
Exemple #7
0
def capture_non_specific(scope, target, ktp_class, N=10000, key_len=16, group1=None, group2=None):
    """ Capture data for a non-specific TVLA t-test

    Args:
        scope (CW scope object): Already setup scope object
        target (CW target object): Already setup target object
        ktp_class (ktp): Non specific KTP object (FixedVRandText, Key, etc)
        N (int): Number of traces to capture for each dataset (will end up with 2*N traces total)
        key_len (int): 16 for AES-128, 32 for AES-256
        group1 (np.array): Optional array object for storing traces in
        group2 (np.array): Optional array object for storing traces in

    Returns:
        group1, group2
    """
    ktp = ktp_class(key_len)
    if group1 is None:
        group1 = np.zeros((N, scope.adc.samples), dtype='float64')
    if group2 is None:
        group2 = np.zeros((N, scope.adc.samples), dtype='float64')
    for i in trange(N):
        key, text = ktp.next_group_A()

        trace = cw.capture_trace(scope, target, text, key)
        while trace is None:
            trace = cw.capture_trace(scope, target, text, key)

        if not verify_AES(text, key, trace.textout):
            raise ValueError("Encryption failed")
        group1[i,:] = trace.wave[:]

        key, text = ktp.next_group_B() 
        trace = cw.capture_trace(scope, target, text, key)
        while trace is None:
            trace = cw.capture_trace(scope, target, text, key)

        group2[i,:] = trace.wave[:]
        if not verify_AES(text, key, trace.textout):
            raise ValueError("Encryption failed")

    return group1, group2
Exemple #8
0
def capture_aes(ot, ktp):
    """A generator for capturing AES traces.

    Args:
      ot: Initialized OpenTitan target.
      ktp: Key and plaintext generator.
    """
    key, _ = ktp.next()
    tqdm.write(f'Using key: {binascii.b2a_hex(bytes(key))}')
    cipher = AES.new(bytes(key), AES.MODE_ECB)
    while True:
        _, text = ktp.next()
        ret = cw.capture_trace(ot.scope, ot.target, text, key, ack=False)
        if not ret:
            raise RuntimeError('Capture failed.')
        expected = binascii.b2a_hex(cipher.encrypt(bytes(text)))
        got = binascii.b2a_hex(ret.textout)
        if got != expected:
            raise RuntimeError(f'Bad ciphertext: {got} != {expected}.')
        yield ret
Exemple #9
0
def capture_kmac(ot, ktp):
    """A generator for capturing KMAC traces.

    Args:
      ot: Initialized OpenTitan target.
      ktp: Key and plaintext generator.
    """
    key, _ = ktp.next()
    tqdm.write(f'Using key: {binascii.b2a_hex(bytes(key))}')
    ot.target.simpleserial_write('k', key)
    while True:
        _, text = ktp.next()
        ret = cw.capture_trace(ot.scope, ot.target, text, key, ack=False)
        if not ret:
            raise RuntimeError('Capture failed.')
        expected = binascii.b2a_hex(
            pyxkcp.kmac128(key, ktp.key_len, text, ktp.text_len,
                           ot.target.output_len, b'\x00', 0))
        got = binascii.b2a_hex(ret.textout)
        if got != expected:
            raise RuntimeError(f'Bad digest: {got} != {expected}.')
        yield ret
# capture traces...
N = 50000  #total traces = 2*n

from cwtvla.ktp import FixedVRandomText, verify_AES
import numpy as np

key_len = 16
ktp = FixedVRandomText(key_len)

group1 = np.zeros((N, scope.adc.samples), dtype='float64')
group2 = np.zeros((N, scope.adc.samples), dtype='float64')
for i in trange(N):
    key, text = ktp.next_group_A()

    trace = cw.capture_trace(scope, target, text, key)
    while trace is None:
        trace = cw.capture_trace(scope, target, text, key)

    if not verify_AES(text, key, trace.textout):
        raise ValueError("Encryption failed")
    group1[i, :] = trace.wave[:]

    key, text = ktp.next_group_B()
    trace = cw.capture_trace(scope, target, text, key)
    while trace is None:
        trace = cw.capture_trace(scope, target, text, key)

    group2[i, :] = trace.wave[:]
    if not verify_AES(text, key, trace.textout):
        raise ValueError("Encryption failed")