Working toward decrypting 15.4 packets in CCSPI.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 21 Sep 2012 08:34:29 +0000 (08:34 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 21 Sep 2012 08:34:29 +0000 (08:34 +0000)
Nonces and regions are completely variable, so promiscuous sniffing will be hard.

git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1265 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETCCSPI.py
client/goodfet.ccspi

index 0acbdb7..3b787d5 100644 (file)
@@ -131,6 +131,11 @@ class GoodFETCCSPI(GoodFET):
         self.poke(0x14,sync);
         return;
     
+    def RF_setkey(self,key):
+        """Sets the first key for encryption to the given argument."""
+        print "ERROR: Forgot to set the key.";
+        
+        return;
     def RF_setfreq(self,frequency):
         """Set the frequency in Hz."""
         mhz=frequency/1000000;
@@ -171,11 +176,8 @@ class GoodFETCCSPI(GoodFET):
         return rssival^0x80;
     lastpacket=range(0,0xff);
     def RF_rxpacket(self):
-        """Get a packet from the radio.  Returns None if none is waiting.  In
-        order to not require the SFD, FIFO, or FIFOP lines, this
-        implementation works by comparing the buffer to the older
-        contents.
-        """
+        """Get a packet from the radio.  Returns None if none is
+        waiting."""
         
         data="\0";
         self.data=data;
@@ -185,9 +187,23 @@ class GoodFETCCSPI(GoodFET):
         self.lastpacket=buffer;
         if(len(buffer)==0):
             return None;
-        #self.strobe(0x08);         #SFLUSHRX
         
         return buffer;
+    def RF_rxpacketdec(self):
+        """Get and decrypt a packet from the radio.  Returns None if
+        none is waiting."""
+        
+        data="\0";
+        self.data=data;
+        self.writecmd(self.CCSPIAPP,0x90,len(data),data);
+        buffer=self.data;
+        
+        self.lastpacket=buffer;
+        if(len(buffer)==0):
+            return None;
+        
+        return buffer;
+
     def RF_txpacket(self,packet):
         """Send a packet through the radio."""
         self.writecmd(self.CCSPIAPP,0x81,len(packet),packet);
index b40d123..6654e27 100755 (executable)
@@ -29,6 +29,7 @@ if(len(sys.argv)==1):
     print "\n%s surf" % sys.argv[0];
     print "%s sniff [chan]" % sys.argv[0];
     print "%s bsniff [chan]" % sys.argv[0];
+    print "%s sniffcrypt 0x$key [chan]" % sys.argv[0];
     print "%s sniffdissect" % sys.argv[0];
     
     print "\n%s txtoscount [-i|-r]   TinyOS BlinkToLED" % sys.argv[0];
@@ -238,6 +239,39 @@ if(sys.argv[1]=="bsniff"):
         client.printpacket(packet);
         sys.stdout.flush();
 
+if(sys.argv[1]=="sniffcrypt"):
+    print "Zigbee crypto is pretty damned complicated, and this doesn't work yet.";
+    #Just broadcast.
+    client.RF_promiscuity(1);
+    client.RF_setsmac(0xFFFFFFFF);
+    client.RF_autocrc(1);
+    #client.poke(0x19, 0x03C7); #SECCTRL0, enabling CCM crypto w/ KEY0
+    client.poke(0x19, 0x03C6); #SECCTRL0, enabling CTRL crypto w/ KEY0
+    
+    #What follows is the nonce.
+    client.poke(0x20, 0x000a); #SECCTRL1, skipping 10 bytes of header
+    
+    if len(sys.argv)>2:
+        key=int(sys.argv[2],16);
+        print "Setting KEY0 to %x" % key;
+        client.RF_setkey(key);
+    if len(sys.argv)>3:
+        freq=eval(sys.argv[3]);
+        if freq>100:
+            client.RF_setfreq(freq);
+        else:
+            client.RF_setchan(freq);
+    client.CC_RFST_RX();
+    print "Listening as %010x on %i MHz" % (client.RF_getsmac(),
+                                            client.RF_getfreq()/10**6);
+    #Now we're ready to get packets.
+    while 1:
+        packet=None;
+        while packet==None:
+            packet=client.RF_rxpacketdec();
+        client.printpacket(packet);
+        sys.stdout.flush();
+
 if(sys.argv[1]=="txtest"):
     if len(sys.argv)>2:
         freq=eval(sys.argv[2]);