Merge pull request #572 from mwalker33/Keri-MS

Partial Keri MS
This commit is contained in:
Iceman 2020-02-23 10:18:42 +01:00 committed by GitHub
commit bb9c53ae7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -54,6 +54,103 @@ static int usage_lf_keri_sim(void) {
return PM3_SUCCESS;
}
typedef enum {Scramble = 0,Descramble = 1} KeriMSScramble_t;
static int CmdKeriMSScramble (KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID, uint32_t *CardID)
{
// 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;
// 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) {
*FC = 0;
*ID = 0;
for (CardIdx = 0; CardIdx < 32; CardIdx++) {
// Get Bit State
BitState = (*CardID >> CardIdx) & 1;
// Card ID
if (CardToID[CardIdx] < 32) {
*ID = *ID | (BitState << CardToID[CardIdx]);
// Remove when all bits are known
IDDecodeState[31-CardToID[CardIdx]] = '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 - 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] = '?';
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, "Partial Keri MS decode");
PrintAndLogEx(SUCCESS, "BitState ID : %s",IDDecodeState);
PrintAndLogEx(SUCCESS, "BitState FC : %s",FCDecodeState);
}
if (Action == Scramble)
{
*CardID = 0; // set to 0
for (CardIdx = 0; CardIdx < 32; CardIdx++)
{
// Card ID
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 and parity/check bits
/*
Add Parity and Fixed bits
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) {
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;
}
static int CmdKeriDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
@ -103,6 +200,25 @@ 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 cardid = 0;
// Just need to the low 32 bits without the 111 trailer
CmdKeriMSScramble (Descramble,&fc,&cardid,&raw2);
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
if (invert) {
PrintAndLogEx(INFO, "Had to Invert - probably KERI");