add RfidAccess class
This commit is contained in:
209
RfidAccess.py
Normal file
209
RfidAccess.py
Normal file
@@ -0,0 +1,209 @@
|
||||
class RfidAccess:
|
||||
NEVER = 0
|
||||
KEYA = 1
|
||||
KEYB = 2
|
||||
KEYAB = 3
|
||||
ALLBLOCK = -1
|
||||
|
||||
def __init__(self):
|
||||
self.C1 = 0
|
||||
self.C2 = 0
|
||||
self.C3 = 8
|
||||
self.C1_Inv = 15
|
||||
self.C2_Inv = 15
|
||||
self.C3_Inv = 7
|
||||
self.Valid=False
|
||||
|
||||
def findAccessIndex(self,table,mask,accessbits):
|
||||
for i in range(8):
|
||||
if table[i] == accessbits:
|
||||
if (i & 1) == 0 :
|
||||
self.C2 = self.C2 & ~mask
|
||||
else:
|
||||
self.C2 = self.C2 | mask
|
||||
|
||||
if (i & 2) == 0 :
|
||||
self.C1 = self.C1 & ~mask
|
||||
else:
|
||||
self.C1 = self.C1 | mask
|
||||
|
||||
if (i & 4) == 0:
|
||||
self.C3 = self.C3 & ~mask
|
||||
else:
|
||||
self.C3 = self.C3 | mask
|
||||
|
||||
self.C1_Inv = self.C1 ^ 0xf
|
||||
self.C2_Inv = self.C2 ^ 0xf
|
||||
self.C3_Inv = self.C3 ^ 0xf
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def setTrailerAccess(self,keyA_Write=KEYA, access_Read=KEYA,access_Write=KEYA,keyB_Read=KEYA,keyB_Write=KEYA):
|
||||
#C1 weight 2 , C2 weight 1 , C3 weight 4
|
||||
|
||||
# Key A Wr Access R Access W KeyB R KEYB W
|
||||
access_Index = ( (self.KEYA, self.KEYA, self.NEVER, self.KEYA,self.KEYA),
|
||||
(self.NEVER,self.KEYA,self.NEVER,self.KEYA,self.NEVER),
|
||||
(self.KEYB, self.KEYAB,self.NEVER,self.NEVER,self.NEVER),
|
||||
(self.NEVER,self.KEYAB,self.NEVER,self.NEVER,self.NEVER),
|
||||
(self.KEYA,self.KEYA,self.KEYA,self.KEYA,self.KEYA),
|
||||
(self.KEYB,self.KEYAB,self.KEYB,self.NEVER,self.KEYB),
|
||||
(self.NEVER,self.KEYAB,self.KEYB,self.NEVER,self.NEVER),
|
||||
(self.NEVER,self.KEYAB,self.NEVER,self.NEVER,self.NEVER))
|
||||
if self.findAccessIndex(access_Index,8, (keyA_Write,access_Read,access_Write,keyB_Read,keyB_Write)):
|
||||
return True
|
||||
else:
|
||||
print("Access Trailer method not possible")
|
||||
return False
|
||||
|
||||
|
||||
def setBlockAccess(self, blockID, access_Read=KEYAB, access_Write=KEYAB, access_Inc=KEYAB, access_Dec=KEYAB):
|
||||
# C1 weight 2 , C2 weight 1 , C3 weight 4
|
||||
# Key Read Key Write INCREment decrement/transfer/etc
|
||||
access_Blk_idx=((self.KEYAB, self.KEYAB, self.KEYAB, self.KEYAB,None),
|
||||
(self.KEYAB, self.NEVER, self.NEVER, self.NEVER,None),
|
||||
(self.KEYAB, self.KEYB, self.NEVER, self.NEVER,None),
|
||||
(self.KEYAB, self.KEYB, self.KEYB, self.KEYAB,None),
|
||||
(self.KEYAB, self.NEVER, self.NEVER, self.KEYAB,None),
|
||||
(self.KEYB, self.KEYB, self.NEVER, self.NEVER,None),
|
||||
(self.KEYB, self.NEVER, self.NEVER, self.NEVER,None),
|
||||
(self.NEVER, self.NEVER, self.NEVER, self.NEVER,None))
|
||||
|
||||
if(blockID == self.ALLBLOCK):
|
||||
Mask = 7
|
||||
elif (BlockID<0) or (blockID >3):
|
||||
return false
|
||||
else:
|
||||
Mask = 1 << blockID
|
||||
|
||||
if self.findAccessIndex(access_Blk_idx,Mask,( access_Read, access_Write, access_Inc, access_Dec, None)):
|
||||
return True
|
||||
else:
|
||||
print("**** Error Access Block method not possible")
|
||||
return False
|
||||
|
||||
|
||||
def encodeAccess(self):
|
||||
self.C1 = self.C1 & 0xf
|
||||
self.C2 = self.C2 & 0xf
|
||||
self.C3 = self.C3 & 0xf
|
||||
self.C1_INV = self.C1 ^ 0xf
|
||||
self.C2_INV = self.C2 ^ 0xf
|
||||
self.C3_INV = self.C3 ^ 0xf
|
||||
byte6 = self.C2_INV << 4 | self.C1_INV
|
||||
byte7 = self.C1 << 4 | self.C3_INV
|
||||
byte8 = self.C3 << 4 | self.C2
|
||||
return (byte6, byte7, byte8)
|
||||
|
||||
|
||||
def decodeAccess(self, byte6,byte7,byte8):
|
||||
self.C1_Inv = byte6 & 0xf
|
||||
self.C2_Inv = (byte6 & 0xf0) >> 4
|
||||
self.C3_Inv = byte7 & 0xf
|
||||
self.C1 = (byte7 & 0xf0) >> 4
|
||||
self.C2 = byte8 & 0xf
|
||||
self.C3 = (byte8 & 0xf0) >>4
|
||||
return ((self.C1 ^ self.C1_Inv) & (self.C2 ^ self.C2_Inv) & (self.C3 ^ self.C3_Inv)) & 0xf == 0xf
|
||||
|
||||
|
||||
def showTrailerAccess(self):
|
||||
KeyAWrite = ['key A', 'never', 'key B', 'never', 'key A', 'key B', 'never', 'never']
|
||||
AccessRead = ['key A', 'key A', 'key A|B', 'key A|B', 'key A','key A|B','key A|B','key A|B' ]
|
||||
AccessWrite = ['never', 'never', 'never', 'never', 'key A', 'key B', 'key B', 'never']
|
||||
KeyBRead = ['key A data R/W', 'key A data R', 'never', 'never', 'key A data R/W', 'never', 'never', 'never']
|
||||
KeyBWrite = ['key A data R/W', 'never', 'key B', 'never', 'key A data R/W', 'key B', 'never', 'never']
|
||||
|
||||
index = 0
|
||||
|
||||
if self.C2 & 0x8 > 0:
|
||||
index = 1
|
||||
if self.C1 & 0x8 > 0:
|
||||
index = index + 2
|
||||
if self.C3 & 0x8 > 0:
|
||||
index = index + 4
|
||||
|
||||
|
||||
#print("TrailerAccess idx=",index)
|
||||
print('Access key A read => never')
|
||||
print('Access key A write =>', KeyAWrite[index])
|
||||
print('Access key B read =>', KeyBRead[index])
|
||||
print('Access key B write =>', KeyBWrite[index])
|
||||
print('Access bits read =>', AccessRead[index])
|
||||
print('Access bits write =>', AccessWrite[index])
|
||||
|
||||
|
||||
def showBlockAccess(self,blockID):
|
||||
BlockRead = ['key A|B','key A|B','key A|B','key A|B','key A|B','key B', 'key B', 'never' ]
|
||||
BlockWrite = ['key A|B', 'never', 'key B', 'key B', 'never', 'key B','never', 'never']
|
||||
BlockIncrement = ['key A|B', 'never', 'never', 'key B', 'never', 'never', 'never', 'never']
|
||||
BlockDecrement = ['key A|B', 'never', 'never', 'key A|B', 'key A|B', 'never', 'never', 'never']
|
||||
if blockID == 3:
|
||||
self.showTrailerAccess()
|
||||
else:
|
||||
mask = 1 << blockID
|
||||
index = 0
|
||||
if (self.C2 & mask) > 0:
|
||||
index =1
|
||||
if (self.C1 & mask) > 0:
|
||||
index = index + 2
|
||||
if (self.C3 & mask) > 0:
|
||||
index = index + 4
|
||||
|
||||
print("Block ", blockID, " read =>", BlockRead[index])
|
||||
print("Block ", blockID, " write =>", BlockWrite[index])
|
||||
print("Block ", blockID, " Increment =>", BlockIncrement[index])
|
||||
print("Block ", blockID, " Decrement+ =>", BlockDecrement[index])
|
||||
|
||||
def showAccess(self):
|
||||
print("/--------- SHOW ACCESS ---------\\")
|
||||
AccessB = self.encodeAccess()
|
||||
print('Access Bytes (6,7,8)= (',hex(AccessB[0]),', ',hex(AccessB[1]),', ',hex(AccessB[2]),')')
|
||||
print('(C1, C2, C3) = (',hex(self.C1),', ',hex(self.C2),', ',hex(self.C3),')')
|
||||
for i in range(4):
|
||||
self.showBlockAccess(i)
|
||||
print("\\---------------------------------/")
|
||||
|
||||
|
||||
def fillBlock3(self,keyA=None,keyB=None,block=None):
|
||||
if block is None:
|
||||
block = 16*[0xff]
|
||||
if len(block) != 16:
|
||||
block = 16*[0xff]
|
||||
|
||||
if keyA is not None:
|
||||
if len(keyA) == 6 :
|
||||
block[0:6]=keyA
|
||||
|
||||
if keyB is not None:
|
||||
if len(keyB) == 6 :
|
||||
block[10:16]=keyB
|
||||
b6, b7, b8 = self.encodeAccess()
|
||||
block[6]=b6
|
||||
block[7]=b7
|
||||
block[8]=b8
|
||||
return block
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rfid = RfidAccess()
|
||||
|
||||
|
||||
print("\nEx: Decode access_bits for [0xff, 0x07, 0x80]")
|
||||
if rfid.decodeAccess(0xFF,0x07,0x80):
|
||||
rfid.showAccess()
|
||||
else:
|
||||
print('Invalid Access')
|
||||
|
||||
print("\n\nSet block 0 to 3 to be read by KEYA but R/W with KEYB")
|
||||
rfid.setBlockAccess(rfid.ALLBLOCK, access_Read=rfid.KEYAB, access_Write=rfid.KEYB, access_Inc=rfid.NEVER, access_Dec=rfid.NEVER)
|
||||
print("Set sector trailer to be only set by Key B");
|
||||
rfid.setTrailerAccess(keyA_Write=rfid.KEYB,access_Read=rfid.KEYAB,access_Write=rfid.KEYB,keyB_Read=rfid.NEVER,keyB_Write=rfid.KEYB)
|
||||
rfid.showAccess()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user