total_crashes += 1 crash_trace[i] = 1 print("crashed") print(f"\n=== {total_faults} faults found ===") print(f"=== {total_crashes} crashes ===") # get an 'original' side channel trace e.reset() e.trace = 1 e.trace_regs = 1 e.mem_trace = 0 e['r0'] = 0xcafecafe e['lr'] = 0xaaaaaaaa e.start(e.functions['storage_containsPin'], 0xaaaaaaaa) # list(map(print, e.sca_address_trace)) import numpy as np trace = np.array(e.sca_values_trace, dtype=np.uint8) fault_trace = trace.max() - np.array(fault_trace, dtype=np.uint8)[:trace.shape[0]] * trace.max() # crash_trace = -trace.max() + np.array(crash_trace, dtype=np.uint8)[:trace.shape[0]] * trace.max() from rainbow.utils.plot import viewer # viewer(e.sca_address_trace, np.array([trace, fault_trace, crash_trace])) viewer(e.sca_address_trace, np.array([trace, fault_trace]), highlight=1)
values = np.array(values, dtype=np.uint8) lgst_dim = max(map(len, traces)) # we're gonna split each 32bit value in 8 bit chunks lgst_dim *= 4 tmp = np.zeros((len(traces), lgst_dim), dtype=np.float32) for i, t in enumerate(traces): for x in range(len(t)): for j in range(4): tmp[i][x * 4 + j] = (t[x] >> (8 * j)) & 0xFF return values, tmp, addresses if __name__ == "__main__": _, func = generate_targetf() values, traces, addresses = get_traces(func, 10, 1000000) from lascar import TraceBatchContainer, Session t = TraceBatchContainer(traces, values) s = Session(t) s.run() from rainbow.utils.plot import viewer viewer(addresses, s["var"].finalize())
s.run() return np.array([s[eng]._finalize() for eng in s.engines if eng not in ['mean', 'var']]) if __name__ == "__main__": import random STORED_PIN = "1874" N = 500 print("Setting up emulator") e = rainbow_stm32(sca_mode=True, local_vars=globals()) e.load("trezor.elf") print("Generating", N, "traces") values = [] traces = [] for i in range(N): input_pin = "".join(random.choice("123456789") for _ in range(len(STORED_PIN))) comparePin(e, input_pin, STORED_PIN) values.append([ord(x) - ord("1") for x in input_pin + STORED_PIN]) traces.append(e.sca_values_trace.copy()) print("Using Lascar to get an NICV") res = show_nicv(values, traces, nr_digits = len(STORED_PIN)) from rainbow.utils.plot import viewer viewer(e.sca_address_trace, res)
values = np.array(values, dtype=np.uint8) lgst_dim = max(map(len, traces)) # we're gonna split each 32bit value in 8 bit chunks lgst_dim *= 4 tmp = np.zeros((len(traces), lgst_dim), dtype=np.float32) for i, t in enumerate(traces): for x in range(len(t)): for j in range(4): tmp[i][x * 4 + j] = (t[x] >> (8 * j)) & 0xFF return values, tmp, addresses if __name__ == "__main__": _, func = generate_targetf() values, traces, addresses = get_traces(func, 10, 1000000) from lascar import TraceBatchContainer, Session t = TraceBatchContainer(traces, values) s = Session(t) s.run() from rainbow.utils.plot import viewer viewer(addresses, s.engines["var"].finalize())