From 136920bcdd856371e54ad039f52f3a72c25bbb71 Mon Sep 17 00:00:00 2001 From: TNEd Date: Tue, 6 Jun 2017 12:02:17 +0200 Subject: [PATCH] 4K fixes for authentication --- .../Application/MifareClassic.c | 566 ++++++++++-------- 1 file changed, 304 insertions(+), 262 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/MifareClassic.c b/Firmware/Chameleon-Mini/Application/MifareClassic.c index e843b30..61867c7 100644 --- a/Firmware/Chameleon-Mini/Application/MifareClassic.c +++ b/Firmware/Chameleon-Mini/Application/MifareClassic.c @@ -33,6 +33,7 @@ #define MEM_KEY_SIZE 6 /* Bytes */ #define MEM_ACC_GPB_SIZE 4 /* Bytes */ #define MEM_SECTOR_ADDR_MASK 0xFC +#define MEM_BIGSECTOR_ADDR_MASK 0xF0 #define MEM_BYTES_PER_BLOCK 16 /* Bytes */ #define MEM_VALUE_SIZE 4 /* Bytes */ @@ -302,12 +303,24 @@ INLINE uint8_t GetAccessCondition(uint8_t Block) /* Check */ if ( ((InvSAcc0 ^ Acc1) & 0xf0) || /* C1x */ ((InvSAcc0 ^ Acc2) & 0x0f) || /* C2x */ - ((InvSAcc1 ^ Acc2) & 0xf0) || /* C1x */ - ((InvSAcc1 ^ Acc0) & 0x0f)) /* C3x */ + ((InvSAcc1 ^ Acc2) & 0xf0)) /* C3x */ { return(NO_ACCESS); } - Block &= 3; + /* Fix for MFClassic 4K cards */ + if(Block<128) + Block &= 3; + else { + Block &= 15; + if (Block& 15) + Block=3; + else if (Block<=4) + Block=0; + else if (Block<=9) + Block=1; + else + Block=2; + } Acc0 = ~Acc0; /* C1x Bits to bit 0..3 */ Acc1 = Acc2; /* C2x Bits to bit 0..3 */ @@ -376,7 +389,24 @@ void MifareClassicAppInit1K(void) FromHalt = false; } +void MifareClassicAppInit1K7B(void) +{ + State = STATE_IDLE; + CardATQAValue = MFCLASSIC_1K_7B_ATQA_VALUE; + CardSAKValue = MFCLASSIC_1K_SAK_VALUE; + FromHalt = false; +} + + void MifareClassicAppInit4K(void) +{ + State = STATE_IDLE; + CardATQAValue = MFCLASSIC_4K_ATQA_VALUE; + CardSAKValue = MFCLASSIC_4K_SAK_VALUE; + FromHalt = false; +} + +void MifareClassicAppInit4K7B(void) { State = STATE_IDLE; CardATQAValue = MFCLASSIC_4K_7B_ATQA_VALUE; @@ -573,77 +603,77 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) return ACK_NAK_FRAME_SIZE; } } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) { - if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) { - uint16_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - uint16_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); - uint16_t SectorStartAddress = (uint16_t)SectorAddress * MEM_BYTES_PER_BLOCK; - uint8_t Key[6]; - uint8_t Uid[4]; - uint8_t CardNonce[4]; + //uint16_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + uint16_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + uint16_t AccessOffset = MEM_KEY_A_OFFSET + MEM_KEY_SIZE; + uint16_t SectorStartAddress; + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[8]; - /* Fix for MFClassic 4k cards */ - if(Buffer[1] >= 128) - { - SectorStartAddress += MEM_KEY_BIGSECTOR_OFFSET; - } + /* Fix for MFClassic 4k cards */ + if(Buffer[1] >= 128) { + SectorStartAddress = (Buffer[1] & MEM_BIGSECTOR_ADDR_MASK) * MEM_BYTES_PER_BLOCK ; + KeyOffset += MEM_KEY_BIGSECTOR_OFFSET; + AccessOffset += MEM_KEY_BIGSECTOR_OFFSET; + } else { + SectorStartAddress = (Buffer[1] & MEM_SECTOR_ADDR_MASK) * MEM_BYTES_PER_BLOCK ; + } - LogEntry(LOG_INFO_APP_CMD_AUTH, Buffer, 2); + LogEntry(LOG_INFO_APP_CMD_AUTH, Buffer, 2); + /* set KeyInUse for global use to keep info about authentication */ + KeyInUse = Buffer[0] & 1; + CurrentAddress = SectorStartAddress / MEM_BYTES_PER_BLOCK; + //if (!AccessConditions[MEM_ACC_GPB_SIZE-1] ||(CurrentAddress != AccessAddress)) { + /* Get access conditions from the sector trailor */ + MemoryReadBlock(AccessConditions, SectorStartAddress + AccessOffset, MEM_ACC_GPB_SIZE); + AccessAddress = CurrentAddress; + //} - KeyInUse = Buffer[0] & 1; - CurrentAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - if (!AccessConditions[MEM_ACC_GPB_SIZE-1] ||(CurrentAddress != AccessAddress)) { - /* Get access conditions from the sector trailor */ - MemoryReadBlock(AccessConditions, SectorStartAddress + MEM_KEY_A_OFFSET + MEM_KEY_SIZE, MEM_ACC_GPB_SIZE); - AccessAddress = CurrentAddress; - } - /* Generate a random nonce and read UID and key from memory */ - RandomGetBuffer(CardNonce, sizeof(CardNonce)); - if (ActiveConfiguration.UidSize == 7) - MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); - else - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + if (ActiveConfiguration.UidSize == 7) + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryReadBlock(Key, SectorStartAddress + KeyOffset, MEM_KEY_SIZE); - MemoryReadBlock(Key, SectorStartAddress + KeyOffset, MEM_KEY_SIZE); + /* Precalculate the reader response from card-nonce */ + for (uint8_t i=0; i= 128) - { - SectorStartAddress += MEM_KEY_BIGSECTOR_OFFSET; - } + return ACK_NAK_FRAME_SIZE; + } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B) ) { + if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) + { + /* Nested authentication. */ + //uint16_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; + uint16_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET); + uint16_t AccOffset = MEM_KEY_A_OFFSET + MEM_KEY_SIZE; + uint16_t SectorStartAddress; + uint8_t Key[6]; + uint8_t Uid[4]; + uint8_t CardNonce[8]; - LogEntry(LOG_INFO_APP_CMD_AUTH, Buffer, 2); + /* Fix for MFClassic 4k cards */ + if(Buffer[1] >= 128) { + SectorStartAddress = (Buffer[1] & MEM_BIGSECTOR_ADDR_MASK) * MEM_BYTES_PER_BLOCK ; + KeyOffset += MEM_KEY_BIGSECTOR_OFFSET; + AccOffset += MEM_KEY_BIGSECTOR_OFFSET; + } else { + SectorStartAddress = (Buffer[1] & MEM_SECTOR_ADDR_MASK) * MEM_BYTES_PER_BLOCK ; + } - KeyInUse = Buffer[0] & 1; - CurrentAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK; - if (CurrentAddress != AccessAddress) { - /* Get access conditions from the sector trailor */ - MemoryReadBlock(AccessConditions, SectorStartAddress + MEM_KEY_A_OFFSET + MEM_KEY_SIZE, MEM_ACC_GPB_SIZE); - AccessAddress = CurrentAddress; - } + LogEntry(LOG_INFO_APP_CMD_AUTH, Buffer, 2); + /* set KeyInUse for global use to keep info about authentication */ + KeyInUse = Buffer[0] & 1; + CurrentAddress = SectorStartAddress / MEM_BYTES_PER_BLOCK; + if (CurrentAddress != AccessAddress) { + /* Get access conditions from the sector trailor */ + MemoryReadBlock(AccessConditions, SectorStartAddress + AccOffset, MEM_ACC_GPB_SIZE); + AccessAddress = CurrentAddress; + } - /* Generate a random nonce and read UID and key from memory */ - RandomGetBuffer(CardNonce, sizeof(CardNonce)); - if (ActiveConfiguration.UidSize == 7) - MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); - else - MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); - MemoryReadBlock(Key, SectorStartAddress + KeyOffset, MEM_KEY_SIZE); + /* Generate a random nonce and read UID and key from memory */ + RandomGetBuffer(CardNonce, sizeof(CardNonce)); + if (ActiveConfiguration.UidSize == 7) + MemoryReadBlock(Uid, MEM_UID_CL2_ADDRESS, MEM_UID_CL2_SIZE); + else + MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE); + MemoryReadBlock(Key, SectorStartAddress + KeyOffset, MEM_KEY_SIZE); - /* Precalculate the reader response from card-nonce */ - for (uint8_t i=0; i