X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFETGlitch.py;h=06bb511eb98fffcc3ef4867163a750591597930f;hp=637b2d1564c65d2b93df357d9d456d0deb8137b2;hb=4e119f07426373a75db57b798e65a485bfc39322;hpb=500045b9c7757d4bf0fea912f4acdef5ee47c6f6 diff --git a/client/GoodFETGlitch.py b/client/GoodFETGlitch.py index 637b2d1..06bb511 100644 --- a/client/GoodFETGlitch.py +++ b/client/GoodFETGlitch.py @@ -38,7 +38,7 @@ title "Success", \ 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); @@ -55,7 +55,7 @@ class GoodFETGlitch(GoodFET): 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.""" @@ -70,7 +70,7 @@ class GoodFETGlitch(GoodFET): 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. @@ -82,17 +82,40 @@ class GoodFETGlitch(GoodFET): sys.stdout.flush(); self.db.execute("drop table if exists glitchrange;"); self.db.execute("create table glitchrange(time integer primary key asc,max,min);"); - self.db.execute("insert into glitchrange(time,max,min) select distinct time, 0, 0 from glitches;"); - self.db.commit(); - print "Maximums..."; - sys.stdout.flush(); - self.db.execute("update glitchrange set max=(select max(vcc) from glitches where glitches.time=glitchrange.time and count=0);"); self.db.commit(); - print "Minimums..."; + print "Calculating ranges..."; sys.stdout.flush(); - self.db.execute("update glitchrange set min=(select min(vcc) from glitches where glitches.time=glitchrange.time and count>0);"); + + maxes={}; + mins={}; + + c=self.db.cursor(); + 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]; + 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 glitchcount<2: + try: oldmin=mins[t]; + except: oldmin=0x10000; + if v0;"); + 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,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; @@ -142,10 +179,18 @@ class GoodFETGlitch(GoodFET): c=self.db.cursor(); c.execute("select time,min,max from glitchrange where max-min>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); @@ -154,7 +199,7 @@ class GoodFETGlitch(GoodFET): 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 @@ -163,26 +208,30 @@ class GoodFETGlitch(GoodFET): 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."; + print "Learning phase complete, beginning 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; + self.secret=0x49; - while(client.eeprompeek(0)!=self.secret): + while(client.getsecret()!=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); + print "-- Secret was %02x" % client.getsecret(); + client.setsecret(self.secret); sys.stdout.flush() - + #Lock chip to unlock it later. if lock>0: client.lock(); @@ -197,7 +246,7 @@ class GoodFETGlitch(GoodFET): #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: @@ -215,10 +264,10 @@ class GoodFETGlitch(GoodFET): rows=c.fetchall(); for a in rows: return True; + c.close(); return False; def scanat(self,lock,trials,vcc,gnd,time): client=self.client; - db=self.db; client.glitchRate(time); client.glitchVoltages(gnd, vcc); #drop voltage target gcount=0; @@ -229,7 +278,7 @@ class GoodFETGlitch(GoodFET): 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; @@ -243,11 +292,13 @@ class GoodFETGlitch(GoodFET): scount+=1; #print "values (%i,%i,%i,%i,%i);" % ( # time,vcc,gnd,gcount,scount); - if(lock>0): + if(lock==0): self.db.execute("insert into glitches(time,vcc,gnd,trials,glitchcount,count,lock)" "values (%i,%i,%i,%i,%i,%i,%i);" % ( time,vcc,gnd,trials,gcount,scount,lock)); - else: + elif scount>0: + print "INSERTING AN EXPLOIT point, t=%i and vcc=%i" % (time,vcc); self.db.execute("insert into exploits(time,vcc,gnd,trials,count)" "values (%i,%i,%i,%i,%i);" % ( time,vcc,gnd,trials,scount)); + self.db.commit(); #Don't leave a lock open.