Skip to content

Commit

Permalink
Merge pull request RfidResearchGroup#94 from nvx/bugfix/iclass_update
Browse files Browse the repository at this point in the history
fix bug with iclass UPDATE command
  • Loading branch information
iceman1001 authored Jul 9, 2022
2 parents e24a1dd + 7667c24 commit bb13d08
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions Firmware/Chameleon-Mini/Application/IClass.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ uint16_t IClassAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
IClassDoTagMAC2(CipherState, FrameBuf + 1, FrameBuf, CurrentKey);
return ISO15693_APP_EARLY_SEND;
case ICLASS_CMD_UPDATE: // ADDRESS(1) DATA(8) SIGN(4)|CRC16(2)
if ((FrameBytes != 11 && FrameBytes != 13) || State != STATE_SELECTED) {
if ((FrameBytes != 12 && FrameBytes != 14) || State != STATE_SELECTED) {
return ISO15693_APP_NO_RESPONSE;
}

Expand Down Expand Up @@ -501,11 +501,8 @@ uint16_t IClassAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {

uint8_t blockOffset = FrameBuf[1] * ICLASS_BLOCK_SIZE;
uint8_t block[ICLASS_BLOCK_SIZE];
if (!persMode && (FrameBuf[1] == ICLASS_BLOCK_KD || FrameBuf[1] == ICLASS_BLOCK_KD)) {
MemoryReadBlock(block, blockOffset, ICLASS_BLOCK_SIZE);
for (uint8_t i = 0; i < sizeof(ICLASS_BLOCK_SIZE); i++)
block[i] ^= FrameBuf[i+2];
} else if (FrameBuf[1] == ICLASS_BLOCK_CFG) {
switch (FrameBuf[1]) {
case ICLASS_BLOCK_CFG:
block[0] = cfgBlock[0]; // Applications Limit
block[1] = cfgBlock[1] & FrameBuf[3]; // OTP
block[2] = cfgBlock[2] & FrameBuf[4]; // OTP
Expand All @@ -525,16 +522,26 @@ uint16_t IClassAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
// Fuses allows setting Crypt1/0 from 1 to 0 only during application mode
block[7] &= FrameBuf[9] | ~ICLASS_FUSE_CRYPT10;
}
} else if (FrameBuf[1] == ICLASS_BLOCK_EPURSE) {
break;
case ICLASS_BLOCK_EPURSE:
// ePurse updates swap first and second half of the block each update
memcpy(block+4, FrameBuf+2, 4);
memcpy(block, FrameBuf+6, 4);
} else {
break;
case ICLASS_BLOCK_KD:
case ICLASS_BLOCK_KC:
if (!persMode) {
MemoryReadBlock(block, blockOffset, ICLASS_BLOCK_SIZE);
for (uint8_t i = 0; i < sizeof(ICLASS_BLOCK_SIZE); i++)
block[i] ^= FrameBuf[i+2];
break;
}
// fallthrough to default case when personalisation mode
default:
memcpy(block, FrameBuf+2, ICLASS_BLOCK_SIZE);
break;
}

// TODO: Epurse swapping first/second half

MemoryWriteBlock(block, blockOffset, ICLASS_BLOCK_SIZE);

if ((FrameBuf[1] == CurrentKeyBlockNum || FrameBuf[1] == ICLASS_BLOCK_EPURSE) && !DetectionMode)
Expand Down

0 comments on commit bb13d08

Please sign in to comment.