Hi,
I’m trying to converge to using an external oscilloscope to capture traces for SCA (it’ll enable me to do more advanced attacks and also become more independent). As a first step I’m capturing traces parallel with the CW Lite, and using the UFO board with the STMF303 shield. My problem is that for the traces captured with the CW Lite, I can extract all 16 subkeys of the AES-128 using CPA. But when I run the CPA code on the traces captured by the oscilloscope, nothing converges to the correct subkey.
The way I’ve hooked things up is by using the T-connection on the UFO board, where one output goes to the CW Lite, and the other to my LeCroy WaveRunner 8208 oscilloscope. The connection to the scope goes through a 30 dB PA303 amplifier from Langer. The CW clock is HS2/OUT, and the CW Lite and scope are not using the same clock reference (would this really be necesssary?). Furthermore, I’ve connected CH2 of my scope to the trigger pin on the UFO board, so the triggering should be synchronized.
My main routine for collecting traces in Python is this:
time_stamp1 = time.time()
for i in trange(num_of_traces, desc='Capturing traces'):
key, text = ktp.next()
key = bytearray([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF])
# key = bytearray([0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c])
# text = bytearray([0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a])
# start LeCroy trigger
if (start_trigger()==False):
print("Triggering Error!")
break
trace = cw.capture_trace(scope, target, text, key)
if trace is None:
continue
trc = get_channel(num_of_samples, 'C1') # Capturing trace from LeCroy oscilloscope
traces_LeCroy[i,:] = trc
traces[i,:] = trace.wave
keys[i,:] = trace.key
pt[i,:] = trace.textin
ct[i,:] = trace.textout
time_stamp2 = time.time()-time_stamp1
print("\n\nTime elapsed: {:.2f} seconds".format(time_stamp2))
print("Rate of trace collection: {:.2f} tr/s".format(num_of_traces/time_stamp2))
keys = np.uint8(keys)
pt = np.uint8(pt)
ct = np.uint8(ct)
for i in range(1):
print("\nTrace {}:".format(i))
print("\tKey: \t\t\t{}".format(bytearray(keys[i,:]).hex(' ')))
print("\tPlaintext: \t\t{}".format(bytearray(pt[i,:]).hex(' ')))
print("\tCiphertext: \t{}".format(bytearray(ct[i,:]).hex(' ')))
Here is a screenshot from the scope for one of the trace captures:
The purple signal (CH2) is the trigger signal from the UFO board, and the mustard coloured signal is the trace. At least to me it looks like the AES-128 rounds are quite visible. However, as mentioned in the beginning, I am not able to extract any of the subkeys from the LeCroy traces using CPA, whereas the CW Lite traces converges to the correct subkeys after 30-40 traces.
This is my first time trying to do this on anything else other than the CW Lite, so I’d appreaciate any feedback as to what might be wrong. My LeCroy scope has a very accurate 10 MHz input/ouput reference clock, in case I need to synchronize something, but is that really necessary? The scope samples at 100 MS/s and collects 200 kS of data with a 12-bit resolution.
Thanks!