def spa_hard(): ser = Serial("/embsec/spa_lab/spa_hard") client = sc.DataClient(path='password') # dat = client.fetch('1234') # sc.plot_trace(dat, smooth=20) # dat = client.fetch('5678') # sc.plot_trace(dat, smooth=20) # sc.show_plot() correct_pin = 1234 # set this to the answer you find, the code below will submit it ser.write('{}\n'.format(correct_pin).encode()) # send PIN return ser.read_until() # gets flag
def dpa_setup(ser): ser = Serial("/embsec/dpa_lab/dpa_setup") datafile = h5py.File('aes_decrypt_powertraces_test_target.hdf5', 'r') datasets = datafile.keys() init = True partA_buf = [ ] # lists of traces in partition A, indexed by key candidate. Individual traces will be numpy arrays! partB_buf = [] partA_cnt = [ ] # list of number of traces in each partition, indexed by byte under examination partB_cnt = [] avg_buf = None # average of all traces avg_cnt = 0 trim = False skeycan = 0 # the index to the sub-key of the round 10 key we are examining! # The loop below iterates through all traces in the file, and performs 16 key guesses on # the key byte indexed by skeycan. So, this performs DPA for 16 key guesses of just one # byte of the (round 10) key. If you want to keep this current code structure, you will # need to manually change the for loop bounds to perform more guesses. You will also # need to change skeycan to test out other sub-key bytes. for name in datasets: # iterate through all traces in the hdf5 file print("Processing: %s" % name) ds = datafile[name] trace = np.array( ds) # this is your current trace! As **a numpy array** ciphertext_hex = ds.attrs[metaname] ciphertext = binascii.unhexlify(ciphertext_hex) # If requested, truncate the trace before analysis. # This can be used to cut out problematic noisey sections while accelerating # computation and reducing memory needs (great for key attacks) if trim: trace = trace[:trim] if init: # sets up the partition buffers initially for x in range(16): # just work on 16 possible key bytes, for now. partA_buf.append(0 * trace) # initialize all 'traces' to zero partB_buf.append(0 * trace) partA_cnt.append(0) partB_cnt.append(0) avg_buf = 0 * trace init = False for x in range( 0, 16): # just work on 16 key candidates, more is too slow. ham = hamming( ciphertext[skeycan]) # hmmm ... is this what we want? if ham > 4: partA_buf[ x] += trace # add the trace to the list of traces for that key candidate partA_cnt[ x] += 1 # increment the count for this partition and key candidate elif ham < 4: partB_buf[x] += trace partB_cnt[x] += 1 pass avg_buf += trace avg_cnt += 1 result = dict() avg_buf = avg_buf / avg_cnt result['avg trace'] = avg_buf result['trace cnt'] = avg_cnt absmax = [] for x in range(16): means = (partA_buf[x] / partA_cnt[x]) - (partB_buf[x] / partB_cnt[x]) result[x] = means absmax.append(np.max(np.abs(means))) result['absmax'] = absmax # Plot the maximum value of the absolute value of each DPA hypothesis plt.figure() plt.title("AbsMax of DPA Hypotheses (%d traces)" % result['trace cnt']) plt.plot(result['absmax']) # Plot the mean trace and all DPA Ciphertext Byte outputs plt.figure() plt.plot(result['avg trace'], label='Mean Trace') dpaPlotScale = 20 for x in range(16): plt.plot(np.abs(result[x]) * dpaPlotScale, label="CT DPA Byte %d" % x) plt.legend(loc='upper right') plt.title("Ciphertext (CT) DPA Results (%d traces)" % result['trace cnt']) plt.show() # The next couple lines are to send the key you found / get a flag (if applicable) key_answer = bytes(16) # your key you found! As a byte array ser.write(key_answer) return ser.read_until()
def test_script(): ser = Serial('/embsec/review_python/skeleton_script') ser_dat = pickle.dumps((mylist, mydict, mysum)) ser.write(ser_dat + b'\n') return ser.read_until()