2 # GoodFET Client Library
4 # (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
6 # This code is being rewritten and refactored. You've been warned!
8 import sys, time, string, cStringIO, struct, glob, serial, os, random;
11 from GoodFET import *;
14 plot "< sqlite3 glitch.db 'select time,vcc,glitchcount from glitches where count=0;'" \
17 "< sqlite3 glitch.db 'select time,vcc,count from glitches where count>0;'" \
20 "< sqlite3 glitch.db 'select time,vcc,count from glitches where count>0 and lock>0;'" \
25 script_timevccrange="""
26 plot "< sqlite3 glitch.db 'select time,vcc,glitchcount from glitches where count=0;'" \
29 "< sqlite3 glitch.db 'select time,vcc,count from glitches where count>0;'" \
32 "< sqlite3 glitch.db 'select time,max(vcc),count from glitches where count=0 group by time ;'" with lines title "Max", \
33 "< sqlite3 glitch.db 'select time,min(vcc),count from glitches where count>0 group by time ;'" with lines title "Min"
36 class GoodFETGlitch(GoodFET):
38 def __init__(self, *args, **kargs):
39 print "Initializing GoodFET Glitcher."
40 #Database connection w/ 30 second timeout.
41 self.db=sqlite3.connect("glitch.db",30000);
42 self.db.execute("create table if not exists glitches(time,vcc,gnd,trials,glitchcount,count,lock)");
43 self.db.execute("create index if not exists glitchvcc on glitches(vcc);");
44 self.db.execute("create index if not exists glitchtime on glitches(time);");
46 def setup(self,arch="avr"):
47 self.client=getClient(arch);
50 import Gnuplot, Gnuplot.PlotItems, Gnuplot.funcutils
52 print "gnuplot-py is missing. Can't graph."
54 g = Gnuplot.Gnuplot(debug=1);
57 g.title('Glitch Training Set');
58 g.xlabel('Time (16MHz)');
59 g.ylabel('VCC (DAC12)');
61 g('set datafile separator "|"');
72 import Gnuplot, Gnuplot.PlotItems, Gnuplot.funcutils
74 # print "py-gnuplot or py-numpy is missing. Can't graph."
76 g = Gnuplot.Gnuplot(debug=1);
79 g.title('Glitch Training Set');
80 g.xlabel('Time (16MHz)');
81 g.ylabel('VCC (DAC12)');
83 g('set datafile separator "|"');
85 g('set output "timevcc.png"');
91 lock=0; #1 locks, 0 unlocked
93 vstop=0xfff; #Could be as high as 0xFFF
96 tstop=-1; #<0 defaults to full range
98 self.scan(lock,trials,vstart,vstop,tstart,tstop);
100 def scan(self,lock,trials=1,vstart=0,vstop=0xfff,tstart=0,tstop=-1):
105 tstop=client.glitchstarttime(); #Really long; only use for initial investigation.
106 print "-- Start takes %04i cycles." % tstop;
112 while(client.eeprompeek(0)!=self.secret):
113 print "-- Setting secret";
116 #Flash the secret to the first two bytes of CODE memory.
118 client.eeprompoke(0,self.secret);
119 client.eeprompoke(1,self.secret);
122 #Lock chip to unlock it later.
125 voltages=range(vstart,vstop,1);
126 times=range(tstart,tstop,1);
128 gnd=0; #TODO, glitch GND.
130 random.shuffle(voltages);
131 #random.shuffle(times);
134 if not self.vccexplored(vcc):
135 print "Exploring vcc=%i" % vcc;
138 self.scanat(trials,vcc,gnd,time)
142 print "Voltage %i already explored." % vcc;
144 def vccexplored(self,vcc):
146 c.execute("select vcc from glitches where vcc=? limit 1;",[vcc]);
151 def scanat(self,trials,vcc,gnd,time):
154 client.glitchRate(time);
155 client.glitchVoltages(gnd, vcc); #drop voltage target
158 #print "-- (%5i,%5i)" % (time,vcc);
160 for i in range(0,trials):
161 client.glitchstart();
163 #Try to read *0, which is secret if read works.
164 a=client.eeprompeek(0x0);
165 if self.lock>0: #locked
166 if(a!=0 and a!=0xFF and a!=self.secret):
169 print "-- %04x: %02x HELL YEAH! " % (time, a);
176 #print "values (%i,%i,%i,%i,%i);" % (
177 # time,vcc,gnd,gcount,scount);
178 self.db.execute("insert into glitches(time,vcc,gnd,trials,glitchcount,count,lock)"
179 "values (%i,%i,%i,%i,%i,%i,%i);" % (
180 time,vcc,gnd,trials,gcount,scount,self.lock));