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")
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))
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()
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)
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
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
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")