From d7c3cc8028b304fd9f2f06af86274aae5bce05cf Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 16 Feb 2020 20:48:53 +1100 Subject: [PATCH 1/4] Update cmdlfkeri.c --- client/cmdlfkeri.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index aadc8676d..1d49117d1 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -53,6 +53,57 @@ static int usage_lf_keri_sim(void) { PrintAndLogEx(NORMAL, " lf keri sim 112233"); return PM3_SUCCESS; } +static int CmdKeriMSDescramble (uint32_t *FC, uint32_t *ID, uint32_t CardID) +{ + uint8_t CardToID [] = { 0xff,0xff,0xff,0xff,0x0d,0x0c,0x11,0x05,0xff,0x06,0xff,0x12,0x08,0xff,0x00,0x07, + 0x0a,0xff,0xff,0x0b,0x04,0x01,0xff,0x13,0xff,0x14,0x02,0xff,0x03,0x09,0xff,0xff }; + uint8_t CardToFC [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff }; + uint8_t CardIdx; // 0 - 31 + bool BitState; + int idx; + + char IDDecodeState[33] = {0x00}; + char FCDecodeState[33] = {0x00}; + + memset (IDDecodeState,'-',32); + memset (FCDecodeState,'-',32); + + + + *FC = 0; + *ID = 0; + + for (CardIdx = 0; CardIdx < 32; CardIdx++) { + // Get Bit State + BitState = (CardID >> CardIdx) & 1; + //if (BitState) { // its a 1 + idx = CardToID[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *ID = *ID | (1 << idx); + IDDecodeState[idx] = '0'+BitState; + } + //else + // IDDecodeState[CardIdx] = '-'; + + idx = CardToFC[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *FC = *FC | (1 << idx); + FCDecodeState[idx] = '0'+BitState; + } + //else + // IDDecodeState[CardIdx] = '-'; + + // } + } + + PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); + PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); + + return PM3_SUCCESS; +} static int CmdKeriDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far @@ -103,6 +154,18 @@ static int CmdKeriDemod(const char *Cmd) { PrintAndLogEx(SUCCESS, "KERI Tag Found -- Internal ID: %u", ID); PrintAndLogEx(SUCCESS, "Raw: %08X%08X", raw1, raw2); +/* + Descramble Data. +*/ + uint32_t fc = 0; + uint32_t imprintID = 0; + + // Just need to the low 32 bits without the 111 trailer + CmdKeriMSDescramble (&fc,&imprintID,raw2); + + PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - imprint id %d\n",fc,imprintID); + +// End Descramble test if (invert) { PrintAndLogEx(INFO, "Had to Invert - probably KERI"); From c6ceeed6d563760305a3ebf91ecb2d4739d7b504 Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Mon, 17 Feb 2020 21:49:43 +1100 Subject: [PATCH 2/4] Update cmdlfkeri.c --- client/cmdlfkeri.c | 131 ++++++++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 36 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 1d49117d1..d10063edb 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -53,55 +53,112 @@ static int usage_lf_keri_sim(void) { PrintAndLogEx(NORMAL, " lf keri sim 112233"); return PM3_SUCCESS; } -static int CmdKeriMSDescramble (uint32_t *FC, uint32_t *ID, uint32_t CardID) + +typedef enum {Scramble = 0,Descramble = 1} KeriMSScramble_t; + +static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID, uint32_t *CardID) { uint8_t CardToID [] = { 0xff,0xff,0xff,0xff,0x0d,0x0c,0x11,0x05,0xff,0x06,0xff,0x12,0x08,0xff,0x00,0x07, 0x0a,0xff,0xff,0x0b,0x04,0x01,0xff,0x13,0xff,0x14,0x02,0xff,0x03,0x09,0xff,0xff }; uint8_t CardToFC [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff }; + + uint8_t IDToCard [] = { 0x0e,0x15,0x1a,0x1c,0x14,0x07,0x09,0x0f,0x0c,0x1d,0x10,0x13,0x05,0x04,0xff,0xff, + 0xff,0x06,0x0b,0x17,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + uint8_t FCToCard [] = { 0xff,0x1e,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + uint8_t CardIdx; // 0 - 31 bool BitState; int idx; - char IDDecodeState[33] = {0x00}; - char FCDecodeState[33] = {0x00}; - - memset (IDDecodeState,'-',32); - memset (FCDecodeState,'-',32); - - + if (Action == Descramble) { + char IDDecodeState[33] = {0x00}; + char FCDecodeState[33] = {0x00}; - *FC = 0; - *ID = 0; + memset (IDDecodeState,'-',32); + memset (FCDecodeState,'-',32); - for (CardIdx = 0; CardIdx < 32; CardIdx++) { - // Get Bit State - BitState = (CardID >> CardIdx) & 1; - //if (BitState) { // its a 1 - idx = CardToID[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *ID = *ID | (1 << idx); - IDDecodeState[idx] = '0'+BitState; + *FC = 0; + *ID = 0; + + for (CardIdx = 0; CardIdx < 32; CardIdx++) { + // Get Bit State + BitState = (*CardID >> CardIdx) & 1; + //if (BitState) { // its a 1 + idx = CardToID[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *ID = *ID | (1 << idx); + IDDecodeState[31-idx] = '0'+BitState; + } + + idx = CardToFC[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + if (BitState) + *FC = *FC | (1 << idx); + FCDecodeState[31-idx] = '0'+BitState; + } } - //else - // IDDecodeState[CardIdx] = '-'; - - idx = CardToFC[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *FC = *FC | (1 << idx); - FCDecodeState[idx] = '0'+BitState; - } - //else - // IDDecodeState[CardIdx] = '-'; - // } + // Patch for bit order group unknown + // Reverse order for easy mapping for unknowns + // I know that these bit groups are a in the correct location, unknown order. + if (IDDecodeState[31-17] == '1') IDDecodeState[31-17] = '?'; + if (IDDecodeState[31-18] == '1') IDDecodeState[31-18] = '?'; + if (IDDecodeState[31-19] == '1') IDDecodeState[31-19] = '?'; + if (IDDecodeState[31-20] == '1') IDDecodeState[31-20] = '?'; + + if (FCDecodeState[31- 1] == '1') FCDecodeState[31- 1] = '?'; + if (FCDecodeState[31- 2] == '1') FCDecodeState[31- 2] = '?'; + + PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); + PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } + if (Action == Scramble) + { + // PrintAndLogEx(SUCCESS, "Scramble FC : %d - ID %d",*FC,*ID); + *CardID = 0; // set to 0 - PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); - PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); + for (CardIdx = 0; CardIdx < 32; CardIdx++) + { + // Card ID + BitState = (*ID >> CardIdx) & 1; + if (BitState) { + idx = IDToCard[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + *CardID |= (1 << idx); + } + } + // FC + BitState = (*FC >> CardIdx) & 1; + if (BitState) { + idx = FCToCard[CardIdx]; + if ((idx >= 0) && (idx <= 32)) { + *CardID |= (1 << idx); + } + } + } + // Fixed bits + /* + Add Parity and Fixed bits + Bit 3 - Note Used/Fixed 1 + Bit 31 - 1 Fixed + Bit 0,1 - 2 Bit Parity + */ + *CardID |= (1 << 3); + // Check/Parity Bits + int Parity = 1; + for (CardIdx = 4; CardIdx <= 31; CardIdx += 2) { + Parity = Parity ^ ((*CardID >> CardIdx) & 11); + } + *CardID = *CardID | Parity; + + // Bit 31 was fixed but not in check/parity bits + *CardID |= (1 << 31); + PrintAndLogEx(SUCCESS, "Scrambled FC : %d - Card ID : %d to RAW : E0000000%08X",*FC,*ID,*CardID); + } return PM3_SUCCESS; } @@ -158,13 +215,15 @@ static int CmdKeriDemod(const char *Cmd) { Descramble Data. */ uint32_t fc = 0; - uint32_t imprintID = 0; + uint32_t cardid = 0; // Just need to the low 32 bits without the 111 trailer - CmdKeriMSDescramble (&fc,&imprintID,raw2); + CmdKeriMSScramble (Descramble,&fc,&cardid,&raw2); - PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - imprint id %d\n",fc,imprintID); + PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - Card ID %d\n",fc,cardid); + uint32_t testCard = 0; + CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); // End Descramble test if (invert) { From f32efd10fedaee60c8d3613fd50eaf2c33abbd6e Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Fri, 21 Feb 2020 22:21:56 +1100 Subject: [PATCH 3/4] Update cmdlfkeri.c --- client/cmdlfkeri.c | 89 ++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index d10063edb..892dfaf5f 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -58,50 +58,42 @@ typedef enum {Scramble = 0,Descramble = 1} KeriMSScramble_t; static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID, uint32_t *CardID) { - uint8_t CardToID [] = { 0xff,0xff,0xff,0xff,0x0d,0x0c,0x11,0x05,0xff,0x06,0xff,0x12,0x08,0xff,0x00,0x07, - 0x0a,0xff,0xff,0x0b,0x04,0x01,0xff,0x13,0xff,0x14,0x02,0xff,0x03,0x09,0xff,0xff }; - uint8_t CardToFC [] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xff }; - - uint8_t IDToCard [] = { 0x0e,0x15,0x1a,0x1c,0x14,0x07,0x09,0x0f,0x0c,0x1d,0x10,0x13,0x05,0x04,0xff,0xff, - 0xff,0x06,0x0b,0x17,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; - uint8_t FCToCard [] = { 0xff,0x1e,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; + // 255 = Not used/Unknown other values are the bit offset in the ID/FC values + uint8_t CardToID [] = { 255,255,255,255, 13, 12, 17, 5,255, 6,255, 18, 8,255, 0, 7, + 10,255,255, 11, 4, 1,255, 19,255, 20, 2,255, 3, 9,255,255 }; + uint8_t CardToFC [] = { 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255, 2,255,255,255,255,255,255,255,255,255,255,255, 1,255 }; uint8_t CardIdx; // 0 - 31 bool BitState; - int idx; + + // Used to track known bit states - remove when all bit maps are known + char IDDecodeState[33] = {0x00}; + char FCDecodeState[33] = {0x00}; + memset (IDDecodeState,'-',32); + memset (FCDecodeState,'-',32); if (Action == Descramble) { - char IDDecodeState[33] = {0x00}; - char FCDecodeState[33] = {0x00}; - - memset (IDDecodeState,'-',32); - memset (FCDecodeState,'-',32); - *FC = 0; *ID = 0; - for (CardIdx = 0; CardIdx < 32; CardIdx++) { // Get Bit State BitState = (*CardID >> CardIdx) & 1; - //if (BitState) { // its a 1 - idx = CardToID[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *ID = *ID | (1 << idx); - IDDecodeState[31-idx] = '0'+BitState; + // Card ID + if (CardToID[CardIdx] < 32) { + *ID = *ID | (BitState << CardToID[CardIdx]); + // Remove when all bits are known + IDDecodeState[31-CardToID[CardIdx]] = '0'+BitState; } - - idx = CardToFC[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - if (BitState) - *FC = *FC | (1 << idx); - FCDecodeState[31-idx] = '0'+BitState; + // Card FC + if (CardToFC[CardIdx] < 32) { + *FC = *FC | (BitState << CardToFC[CardIdx]); + // Remove when all bits are known + FCDecodeState[31-CardToFC[CardIdx]] = '0'+BitState; } } - // Patch for bit order group unknown + // Patch for bit order group unknown - remove when all Keri MS Bits maps are known // Reverse order for easy mapping for unknowns // I know that these bit groups are a in the correct location, unknown order. if (IDDecodeState[31-17] == '1') IDDecodeState[31-17] = '?'; @@ -115,38 +107,34 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } + if (Action == Scramble) { - // PrintAndLogEx(SUCCESS, "Scramble FC : %d - ID %d",*FC,*ID); *CardID = 0; // set to 0 for (CardIdx = 0; CardIdx < 32; CardIdx++) { // Card ID - BitState = (*ID >> CardIdx) & 1; - if (BitState) { - idx = IDToCard[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - *CardID |= (1 << idx); - } - } - // FC - BitState = (*FC >> CardIdx) & 1; - if (BitState) { - idx = FCToCard[CardIdx]; - if ((idx >= 0) && (idx <= 32)) { - *CardID |= (1 << idx); - } - } + if (CardToID[CardIdx] < 32) { + if ((*ID & (1 << CardToID[CardIdx])) > 0) + *CardID |= (1 << CardIdx); + } + // Card FC + if (CardToFC[CardIdx] < 32) { + if ((*ID & (1 << CardToFC[CardIdx])) > 0) + *CardID |= (1 << CardIdx); + } } - // Fixed bits + + // Fixed bits and parity/check bits /* Add Parity and Fixed bits - Bit 3 - Note Used/Fixed 1 - Bit 31 - 1 Fixed + Bit 3 - Note Used/Fixed 1 - TBC + Bit 31 - 1 Fixed Not in check/parity Bit 0,1 - 2 Bit Parity */ *CardID |= (1 << 3); + // Check/Parity Bits int Parity = 1; for (CardIdx = 4; CardIdx <= 31; CardIdx += 2) { @@ -156,7 +144,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I // Bit 31 was fixed but not in check/parity bits *CardID |= (1 << 31); - + PrintAndLogEx(SUCCESS, "Scrambled FC : %d - Card ID : %d to RAW : E0000000%08X",*FC,*ID,*CardID); } return PM3_SUCCESS; @@ -224,6 +212,7 @@ static int CmdKeriDemod(const char *Cmd) { uint32_t testCard = 0; CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); + // End Descramble test if (invert) { From f2ae1ff57abf9eea3a867988921db5a097d4196a Mon Sep 17 00:00:00 2001 From: mwalker33 Date: Sun, 23 Feb 2020 11:21:55 +1100 Subject: [PATCH 4/4] Update cmdlfkeri.c --- client/cmdlfkeri.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 892dfaf5f..b0f45da04 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -104,6 +104,7 @@ static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *I if (FCDecodeState[31- 1] == '1') FCDecodeState[31- 1] = '?'; if (FCDecodeState[31- 2] == '1') FCDecodeState[31- 2] = '?'; + PrintAndLogEx(SUCCESS, "Partial Keri MS decode"); PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState); PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState); } @@ -210,8 +211,12 @@ static int CmdKeriDemod(const char *Cmd) { PrintAndLogEx (SUCCESS,"Descrambled MS : FC %d - Card ID %d\n",fc,cardid); +/* + Scamble: For dev testing only, will/should move to the create keri-ms code when added. + uint32_t testCard = 0; CmdKeriMSScramble (Scramble,&fc,&cardid,&testCard); +*/ // End Descramble test