--- /dev/null
+#!/usr/bin/env python
+# GoodFET Client Library
+#
+# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+#
+# This code is being rewritten and refactored. You've been warned!
+
+import sys, time, string, cStringIO, struct, glob, serial, os, random;
+import sqlite3;
+
+from GoodFET import *;
+
+class GoodFETGlitch(GoodFET):
+
+ def __init__(self, *args, **kargs):
+ print "Initializing GoodFET Glitcher."
+ #Database connection and tables.
+ self.db=sqlite3.connect("glitch.db");
+ self.db.execute("create table if not exists glitches(time,vcc,gnd,trials,glitchcount,count,lock)");
+ self.client=0;
+ def setup(self,arch="avr"):
+ self.client=getClient(arch);
+ def learn(self):
+ #Learning phase
+ trials=1;
+ lock=0; #1 locks, 0 unlocked
+ vstart=0;
+ vstop=0xFFF; #Smaller range sometimes helps.
+ vstep=1;
+ tstart=0;
+ tstop=-1; #<0 defaults to full range
+ tstep=0x1; #Must be 1
+ self.scan(lock,trials,vstart,vstop,tstart,tstop);
+ def scan(self,lock,trials=1,vstart=0,vstop=0xfff,tstart=0,tstop=-1):
+ client=self.client;
+ self.lock=lock;
+ client.serInit();
+ if tstop<0:
+ tstop=client.glitchstarttime(); #Really long; only use for initial investigation.
+ print "-- Start takes %04i cycles." % tstop;
+ client.start();
+ client.erase();
+
+ self.secret=0x69;
+
+ 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();
+ voltages=range(vstart,vstop,1);
+ times=range(tstart,tstop,1);
+
+ gnd=0; #TODO, glitch GND.
+ vcc=0xfff;
+ random.shuffle(voltages);
+ random.shuffle(times);
+
+ count=0; #Commit counter.
+ for vcc in voltages:
+ for time in times:
+ self.scanat(trials,vcc,gnd,time)
+ sys.stdout.flush()
+ count+=trials;
+ if count>1000:
+ count=0;
+ self.db.commit();
+
+ def scanat(self,trials,vcc,gnd,time):
+ client=self.client;
+ db=self.db;
+ client.glitchRate(time);
+ client.glitchVoltages(gnd, vcc); #drop voltage target
+ gcount=0;
+ scount=0;
+ print "-- (%i,%i)" % (time,vcc);
+ sys.stdout.flush();
+ for i in range(0,trials):
+ client.glitchstart();
+
+ #Try to read *0, which is secret if read works.
+ a=client.eeprompeek(0x0);
+ if self.lock>0: #locked
+ if(a!=0 and a!=0xFF and a!=self.secret):
+ gcount+=1;
+ if(a==self.secret):
+ print "-- %04x: %02x HELL YEAH! " % (time, a);
+ scount+=1;
+ else: #unlocked
+ if(a!=self.secret):
+ gcount+=1;
+ if(a==self.secret):
+ scount+=1;
+ print "values (%i,%i,%i,%i,%i);" % (
+ time,vcc,gnd,gcount,scount);
+ 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,self.lock));
--- /dev/null
+#!/usr/bin/env python
+
+import sys,binascii,time,random;
+
+sys.path.append('../../../trunk/client/')
+
+from GoodFETAVR import GoodFETAVR;
+from GoodFETGlitch import *;
+from intelhex import IntelHex16bit, IntelHex;
+
+import sqlite3;
+
+
+glitcher=GoodFETGlitch();
+
+if(len(sys.argv)==1):
+ print "Usage: %s chip verb [objects]\n" % sys.argv[0];
+ print "%s avr learn" % sys.argv[0];
+ print """
+This populates a database, glitch.db, with a record of all attempted
+glitches. Graphs can then be generated from the results, allowing
+results to be replicated on different hardware and models. The general
+sequence for a new chip is to first run 'goodfet $foo learn' for an evening,
+then to FINISHME"""
+ sys.exit();
+
+
+glitcher.setup(sys.argv[1]);
+
+if(sys.argv[2]=="learn"):
+ glitcher.learn();