atsha204a: Add support for ATECC508A
authorMichalis Pappas <mpappas@fastmail.fm>
Fri, 15 Jun 2018 09:29:21 +0000 (12:29 +0300)
committerUwe Hermann <uwe@hermann-uwe.de>
Tue, 30 Apr 2019 17:07:27 +0000 (19:07 +0200)
decoders/atsha204a/pd.py

index 2fb9b520982f684021d16d8afd9b888221a76123..053e32523ce99704dbc1348950bc36e62ae51a76 100644 (file)
@@ -26,19 +26,25 @@ WORD_ADDR_COMMAND       = 0x03
 
 WORD_ADDR = {0x00: 'RESET', 0x01: 'SLEEP', 0x02: 'IDLE', 0x03: 'COMMAND'}
 
+OPCODE_COUNTER          = 0x24
 OPCODE_DERIVE_KEY       = 0x1c
 OPCODE_DEV_REV          = 0x30
+OPCODE_ECDH             = 0x43
 OPCODE_GEN_DIG          = 0x15
+OPCODE_GEN_KEY          = 0x40
 OPCODE_HMAC             = 0x11
 OPCODE_CHECK_MAC        = 0x28
 OPCODE_LOCK             = 0x17
 OPCODE_MAC              = 0x08
 OPCODE_NONCE            = 0x16
 OPCODE_PAUSE            = 0x01
+OPCODE_PRIVWRITE        = 0x46
 OPCODE_RANDOM           = 0x1b
 OPCODE_READ             = 0x02
 OPCODE_SHA              = 0x47
+OPCODE_SIGN             = 0x41
 OPCODE_UPDATE_EXTRA     = 0x20
+OPCODE_VERIFY           = 0x45
 OPCODE_WRITE            = 0x12
 
 OPCODES = {
@@ -53,8 +59,14 @@ OPCODES = {
     0x1b: 'Random',
     0x1c: 'DeriveKey',
     0x20: 'UpdateExtra',
+    0x24: 'Counter',
     0x28: 'CheckMac',
     0x30: 'DevRev',
+    0x40: 'GenKey',
+    0x41: 'Sign',
+    0x43: 'ECDH',
+    0x45: 'Verify',
+    0x46: 'PrivWrite',
     0x47: 'SHA',
 }
 
@@ -177,11 +189,15 @@ class Decoder(srd.Decoder):
 
     def put_param1(self, s):
         op = self.opcode
-        if op in (OPCODE_CHECK_MAC, OPCODE_DEV_REV, OPCODE_HMAC, \
-                OPCODE_MAC, OPCODE_NONCE, OPCODE_RANDOM, OPCODE_SHA):
+        if op in (OPCODE_CHECK_MAC, OPCODE_COUNTER, OPCODE_DEV_REV,     \
+                  OPCODE_ECDH, OPCODE_GEN_KEY, OPCODE_HMAC, OPCODE_MAC, \
+                  OPCODE_NONCE, OPCODE_RANDOM, OPCODE_SHA, OPCODE_SIGN, \
+                  OPCODE_VERIFY):
             self.putx(s, [3, ['Mode: %02X' % s[2]]])
         elif op == OPCODE_DERIVE_KEY:
             self.putx(s, [3, ['Random: %s' % s[2]]])
+        elif op == OPCODE_PRIVWRITE:
+            self.putx(s, [3, ['Encrypted: {}'.format('Yes' if s[2] & 0x40 else 'No')]])
         elif op == OPCODE_GEN_DIG:
             self.putx(s, [3, ['Zone: %s' % ZONES[s[2]]]])
         elif op == OPCODE_LOCK:
@@ -203,6 +219,9 @@ class Decoder(srd.Decoder):
         op = self.opcode
         if op == OPCODE_DERIVE_KEY:
             self.puty(s, [4, ['TargetKey: {:02x} {:02x}'.format(s[1][2], s[0][2])]])
+        elif op in (OPCODE_COUNTER, OPCODE_ECDH, OPCODE_GEN_KEY, OPCODE_PRIVWRITE, \
+                    OPCODE_SIGN, OPCODE_VERIFY):
+            self.puty(s, [4, ['KeyID: {:02x} {:02x}'.format(s[1][2], s[0][2])]])
         elif op in (OPCODE_NONCE, OPCODE_PAUSE, OPCODE_RANDOM):
             self.puty(s, [4, ['Zero: {:02x} {:02x}'.format(s[1][2], s[0][2])]])
         elif op in (OPCODE_HMAC, OPCODE_MAC, OPCODE_CHECK_MAC, OPCODE_GEN_DIG):
@@ -221,15 +240,33 @@ class Decoder(srd.Decoder):
             return
         op = self.opcode
         if op == OPCODE_CHECK_MAC:
-            self.putz(s[0][0], s[31][1], [5, ['ClientChal: %s' % ' '.join(format(i[2], '02x') for i in s[0:31])]])
-            self.putz(s[32][0], s[63][1], [5, ['ClientResp: %s' % ' '.join(format(i[2], '02x') for i in s[32:63])]])
-            self.putz(s[64][0], s[76][1], [5, ['OtherData: %s' % ' '.join(format(i[2], '02x') for i in s[64:76])]])
+            self.putz(s[0][0], s[31][1], [5, ['ClientChal: %s' % ' '.join(format(i[2], '02x') for i in s[0:32])]])
+            self.putz(s[32][0], s[63][1], [5, ['ClientResp: %s' % ' '.join(format(i[2], '02x') for i in s[32:64])]])
+            self.putz(s[64][0], s[76][1], [5, ['OtherData: %s' % ' '.join(format(i[2], '02x') for i in s[64:77])]])
         elif op == OPCODE_DERIVE_KEY:
             self.putz(s[0][0], s[31][1], [5, ['MAC: %s' % ' '.join(format(i[2], '02x') for i in s)]])
-        elif op == OPCODE_GEN_DIG:
+        elif op == OPCODE_ECDH:
+                self.putz(s[0][0], s[31][1], [5, ['Pub X: %s' % ' '.join(format(i[2], '02x') for i in s[0:32])]])
+                self.putz(s[32][0], s[63][1], [5, ['Pub Y: %s' % ' '.join(format(i[2], '02x') for i in s[32:64])]])
+        elif op in (OPCODE_GEN_DIG, OPCODE_GEN_KEY):
             self.putz(s[0][0], s[3][1], [5, ['OtherData: %s' % ' '.join(format(i[2], '02x') for i in s)]])
         elif op == OPCODE_MAC:
             self.putz(s[0][0], s[31][1], [5, ['Challenge: %s' % ' '.join(format(i[2], '02x') for i in s)]])
+        elif op == OPCODE_PRIVWRITE:
+            if len(s) > 36: # Key + MAC.
+                self.putz(s[0][0], s[-35][1], [5, ['Value: %s' % ' '.join(format(i[2], '02x') for i in s)]])
+                self.putz(s[-32][0], s[-1][1], [5, ['MAC: %s' % ' '.join(format(i[2], '02x') for i in s)]])
+            else: # Just value.
+                self.putz(s[0][0], s[-1][1], [5, ['Value: %s' % ' '.join(format(i[2], '02x') for i in s)]])
+        elif op == OPCODE_VERIFY:
+            if len(s) >= 64: # ECDSA components
+                self.putz(s[0][0], s[31][1], [5, ['ECDSA R: %s' % ' '.join(format(i[2], '02x') for i in s[0:32])]])
+                self.putz(s[32][0], s[63][1], [5, ['ECDSA S: %s' % ' '.join(format(i[2], '02x') for i in s[32:64])]])
+            if len(s) >= 128: # Public key components
+                self.putz(s[64][0], s[95][1], [5, ['Pub X: %s' % ' '.join(format(i[2], '02x') for i in s[64:96])]])
+                self.putz(s[96][0], s[127][1], [5, ['Pub Y: %s' % ' '.join(format(i[2], '02x') for i in s[96:128])]])
+            if len(s) == 147: # OtherData
+                self.putz(s[128][0], s[146][1], [5, ['OtherData: %s' % ' '.join(format(i[2], '02x') for i in s[128:147])]])
         elif op == OPCODE_WRITE:
             if len(s) > 32: # Value + MAC.
                 self.putz(s[0][0], s[-31][1], [5, ['Value: %s' % ' '.join(format(i[2], '02x') for i in s)]])