#
# This code is being rewritten and refactored. You've been warned!
-import sys, time, string, cStringIO, struct, glob, serial, os, random;
+import sys, time, string, cStringIO, struct, glob, os, random;
import sqlite3;
from GoodFET import *;
class GoodFETGlitch(GoodFET):
def __init__(self, *args, **kargs):
- print "Initializing GoodFET Glitcher."
+ print "# Initializing GoodFET Glitcher."
#Database connection w/ 30 second timeout.
self.db=sqlite3.connect("glitch.db",30000);
self.client=0;
def setup(self,arch="avr"):
self.client=getClient(arch);
- self.client.serInit();
+ self.client.serInit(); #No timeout
def glitchvoltages(self,time):
"""Returns list of voltages to train at."""
min=r[0];
max=r[1];
if(min==None or max==None): return [];
-
+
spread=max-min;
return range(min,max,1);
#If we get here, there are no points. Return empty set.
mins={};
c=self.db.cursor();
- c.execute("select time,vcc,count from glitches;"); #Limit 10000 for testing.
+ c.execute("select time,vcc,glitchcount,count from glitches;"); #Limit 10000 for testing.
progress=0;
for r in c:
progress=progress+1;
if progress % 1000000==0: print "%09i rows crunched." % progress;
t=r[0];
v=r[1];
- count=r[2];
- if count==0:
+ glitchcount=r[2];
+ count=r[3];
+ # FIXME: Threse thresholds suck.
+ if count<2:
try: oldmax=maxes[t];
except: oldmax=-1;
if v>oldmax: maxes[t]=v;
- elif count==1:
+ elif glitchcount<2:
try: oldmin=mins[t];
except: oldmin=0x10000;
if v<oldmin: mins[t]=v;
g('set term png');
g('set output "timevcc.png"');
g(script_timevcc);
-
+ def points(self):
+ c=self.db.cursor();
+ c.execute("select time,vcc,gnd,glitchcount,count from glitches where lock=0 and glitchcount>0;");
+ print "time vcc gnd glitchcount count";
+ for r in c:
+ print "%i %i %i %i %i" % r;
+ def rpoints(self):
+ c=self.db.cursor();
+ c.execute("select time,vcc,gnd,glitchcount,count from glitches where lock=0 and glitchcount>0;");
+ print "time vcc gnd glitchcount count";
+ for r in c:
+ print "%i %i %i %i %i" % r;
#GnuPlot sucks for large sets. Switch to viewpoints soon.
# sqlite3 glitch.db "select time,vcc,count from glitches where count=0" | vp -l -d "|" -I
- def explore(self,tstart=0,tstop=-1, trials=1):
+ def explore(self,times=None, trials=10):
"""Exploration phase. Uses thresholds to find exploitable points."""
gnd=0;
self.scansetup(1); #Lock the chip, place key in eeprom.
- if tstop<0:
+ if times==None:
+ tstart=0;
tstop=self.client.glitchstarttime();
- times=range(tstart,tstop);
+ times=range(tstart,tstop);
random.shuffle(times);
#self.crunch();
count=0.0;
rows=c.fetchall();
c.close();
random.shuffle(rows);
+ print "Exploring %i times." % len(times);
+ mins={};
+ maxes={};
for r in rows:
t=r[0];
- min=r[1];
- max=r[2];
+ mins[t]=r[1];
+ maxes[t]=r[2];
+ for t in times:
+ min=mins[t];
+ max=maxes[t];
voltages=range(min,max,1);
count=count+1.0;
print "%02.02f Exploring %04i points in t=%04i." % (count/total,len(voltages),t);
self.scanat(1,trials,vcc,gnd,t);
def learn(self):
"""Learning phase. Finds thresholds at which the chip screws up."""
- trials=1;
+ trials=30;
lock=0; #1 locks, 0 unlocked
vstart=0;
vstop=1024; #Could be as high as 0xFFF, but upper range is useless
tstop=self.client.glitchstarttime();
tstep=0x1; #Must be 1
self.scan(lock,trials,range(vstart,vstop),range(tstart,tstop));
- print "Learning phase complete, beginning to expore.";
- self.explore();
+ print "Learning phase complete, begin to crunch.";
+ self.crunch();
+ #print "Crunch phase complete, beginning to explore.";
+ #self.explore();
def scansetup(self,lock):
client=self.client;
+ client.verbose=0;
client.start();
client.erase();
+ print "Scanning %s" % client.infostring();
- self.secret=0x69;
+ #Kind of arbitrary.
+ #16 bit minimum.
+ self.secret=0xdead;
+
+
+ print "-- Setting secret";
+ client.start();
+
+ #Flash the secret, to try and recover it later.
+ client.erase();
+ print "-- Secret was %02x" % client.getsecret();
+ client.setsecret(self.secret);
+ print "-- Secret set to %02x" % client.getsecret();
+ sys.stdout.flush()
+ if(client.getsecret()!=self.secret):
+ print "Secret failed to set. Exiting for safety.";
+ sys.exit();
- while(client.eeprompeek(0)!=self.secret):
- print "-- Setting secret";
- client.start();
-
- #Flash the secret to the first two bytes of CODE memory.
- client.erase();
- client.eeprompoke(0,self.secret);
- client.eeprompoke(1,self.secret);
- sys.stdout.flush()
-
#Lock chip to unlock it later.
if lock>0:
client.lock();
#random.shuffle(times);
for vcc in voltages:
- if lock<0 and not self.vccexplored(vcc):
+ if not self.vccexplored(vcc):
print "Exploring vcc=%i" % vcc;
sys.stdout.flush();
for time in times:
client.glitchstart();
#Try to read *0, which is secret if read works.
- a=client.eeprompeek(0x0);
+ a=client.getsecret();
if lock>0: #locked
if(a!=0 and a!=0xFF and a!=self.secret):
gcount+=1;