The following block initializes the chipwhisperer, as always
import chipwhisperer as cw
import time
WARNING:ChipWhisperer Other:ChipWhisperer update available! See https://chipwhisperer.readthedocs.io/en/latest/installing.html for updating instructions
# Path to the Speck .hex file for reflashing
PATH="/home/msc/documents/obsidian_notes/master-aits/subjects/implementation_attacks_and_countermeasures/praktikum/speck_cpa_cw/cw_firmware/simple-speck-CWLITEARM.hex"
PATH="/home/juan/documents/master-aits/subjects/implementation_attacks_and_countermeasures/praktikum/speck_cpa_cw/cw_firmware/simple-speck-CWLITEARM.hex"
PATH="/home/juan/documents/master-aits/subjects/implementation_attacks_and_countermeasures/praktikum/speck_cpa_cw/cw_firmware_masked/simple-speck-CWLITEARM.hex"
PATH="/home/msc/documents/obsidian_notes/master-aits/subjects/implementation_attacks_and_countermeasures/praktikum/speck_cpa_cw/cw_firmware_hiding/simple-speck-CWLITEARM.hex"
scope.dis()
def flash(scope, prog):
cw.program_target(scope, prog, PATH)
def reset_target(scope):
scope.io.nrst = 'low'
time.sleep(0.05)
scope.io.nrst = 'high_z'
time.sleep(0.05)
try:
if not scope.connectStatus:
scope.con()
except NameError:
scope = cw.scope()
try:
target = cw.target(scope)
except IOError:
print("INFO: Caught exception on reconnecting to target - attempting to reconnect to scope first.")
print("INFO: This is a work-around when USB has died without Python knowing. Ignore errors above this line.")
scope = cw.scope()
target = cw.target(scope)
print("INFO: Found ChipWhispererðŸ˜")
prog = cw.programmers.STM32FProgrammer
time.sleep(0.05)
scope.default_setup()
INFO: Found ChipWhispererðŸ˜
Reset the target if required:
reset_target(scope)
Reflash the target if required:
flash(scope, prog)
Detected known STMF32: STM32F302xB(C)/303xB(C) Extended erase (0x44), this can take ten seconds or more Attempting to program 10563 bytes at 0x8000000 STM32F Programming flash... STM32F Reading flash... Verified flash OK, 10563 bytes
Set an encryption key:
# 32 bytes of encryption key
#encryption_key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
# 8 byte encryption key
encryption_key = b"\x11\x22\x33\x44\x55\x66\x77\x88"
if len(encryption_key) == 8:
target.simpleserial_write("s", encryption_key)
Get the encryption key:
target.simpleserial_write("k", b'\x00'*4)
print(target.simpleserial_read("o", 8))
CWbytearray(b'11 22 33 44 55 66 77 88')
Encrypt a 4-byte block:
#pt = b"\x70\x6f\x6f\x6e\x65\x72\x2e\x20\x49\x6e\x20\x74\x68\x6f\x73\x65"
pt = b"\x4c\x69\x74\x65"
target.simpleserial_write("e", pt)
print(target.simpleserial_read("c", 4))
CWbytearray(b'5d 7c 46 6d')
Output is supposed to be: CWbytearray(b'5d 7c 46 6d')
The following code snippet traces the encryption process with random plaintetext 2000 times
from tqdm.notebook import trange
import random
import numpy as np
ktp = cw.ktp.Basic()
trace_array = []
trace_array_mean = []
textin_array = []
pt = b"\x4c\x69\x74\x65"
reference_pt = pt
N = 800
random.seed(0x5222223)
# Capturing the traces for the random plaintexts
for i in trange(N, desc='Capturing traces with random plaintextsd'):
pt = bytes([random.randint(0, 255) for i in range(4)])
scope.arm()
target.simpleserial_write('e', pt)
ret = scope.capture()
if ret:
print("Target timed out!")
continue
response = target.simpleserial_read('c', 4)
trace_array.append(scope.get_last_trace())
textin_array.append(pt)
for i in trange(N, desc='Capturing reference traces'):
scope.arm()
target.simpleserial_write('e', reference_pt)
ret = scope.capture()
if ret:
print("Target timed out!")
continue
response = target.simpleserial_read('c', 4)
trace_array_mean.append(scope.get_last_trace())
trace_array = np.array(trace_array)
trace_array_mean = np.array(trace_array_mean)
Capturing traces with random plaintextsd: 0%| | 0/800 [00:00<?, ?it/s]
Capturing reference traces: 0%| | 0/800 [00:00<?, ?it/s]
np.save("sample_traces/800_encryption_traces_hiding.npy", trace_array)
np.save("sample_traces/800_plaintext_traces_hiding.npy", textin_array)
If no CW is available, load the trace array from a file
import numpy as np
trace_array = np.load("sample_traces/2200_encryption_traces.npy")
textin_array = np.load("sample_traces/2200_plaintext_traces.npy")
[0;31m---------------------------------------------------------------------------[0m [0;31mFileNotFoundError[0m Traceback (most recent call last) [0;32m/tmp/ipykernel_3602764/924883979.py[0m in [0;36m<module>[0;34m[0m [1;32m 1[0m [0;32mimport[0m [0mnumpy[0m [0;32mas[0m [0mnp[0m[0;34m[0m[0;34m[0m[0m [0;32m----> 2[0;31m [0mtrace_array[0m [0;34m=[0m [0mnp[0m[0;34m.[0m[0mload[0m[0;34m([0m[0;34m"sample_traces/2200_encryption_traces.npy"[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m [0m[1;32m 3[0m [0mtextin_array[0m [0;34m=[0m [0mnp[0m[0;34m.[0m[0mload[0m[0;34m([0m[0;34m"sample_traces/2200_plaintext_traces.npy"[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m [0;32m/usr/lib/python3.10/site-packages/numpy/lib/npyio.py[0m in [0;36mload[0;34m(file, mmap_mode, allow_pickle, fix_imports, encoding)[0m [1;32m 415[0m [0mown_fid[0m [0;34m=[0m [0;32mFalse[0m[0;34m[0m[0;34m[0m[0m [1;32m 416[0m [0;32melse[0m[0;34m:[0m[0;34m[0m[0;34m[0m[0m [0;32m--> 417[0;31m [0mfid[0m [0;34m=[0m [0mstack[0m[0;34m.[0m[0menter_context[0m[0;34m([0m[0mopen[0m[0;34m([0m[0mos_fspath[0m[0;34m([0m[0mfile[0m[0;34m)[0m[0;34m,[0m [0;34m"rb"[0m[0;34m)[0m[0;34m)[0m[0;34m[0m[0;34m[0m[0m [0m[1;32m 418[0m [0mown_fid[0m [0;34m=[0m [0;32mTrue[0m[0;34m[0m[0;34m[0m[0m [1;32m 419[0m [0;34m[0m[0m [0;31mFileNotFoundError[0m: [Errno 2] No such file or directory: 'sample_traces/2200_encryption_traces.npy'
%matplotlib notebook
import matplotlib.pylab as plt
plt.figure()
plt.plot(trace_array[2], 'orange')
#plt.plot(trace_array[4], 'g')
plt.show()
def mean(n):
n[np.isnan(n)] = 0
return n.mean(0)
def var(n):
n[np.isnan(n)] = 0
return n.var(0)
def ttest(a,b,c,d,e,f):
t = (a-b)/((c/e + d/f)**0.5)
return t
%matplotlib notebook
import matplotlib.pylab as plt
f1 = trace_array.shape[0]
a1 = mean(trace_array)
c1 = var(trace_array)
b1 = mean(trace_array_mean)
d1 = var(trace_array_mean)
t = ttest(a1, b1, c1, d1, f1, f1)
plt.plot(t)
plt.plot([4.5] * scope.adc.samples, color="red")
plt.plot([-4.5] * scope.adc.samples, color="red")
plt.show()