diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index c985ecbc0..9a1eccec1 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -416,7 +416,7 @@ static int CmdHIDClone(const char *Cmd) { if (raw_len == 0) { PrintAndLogEx(INFO, "Preparing to clone HID tag"); - HIDTryUnpack(&packed); + HIDUnpack(format_idx, &packed); } else { PrintAndLogEx(INFO, "Preparing to clone HID tag using raw " _YELLOW_("%s"), raw); } diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index d4af63a69..ffbbbf8d1 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -505,14 +505,22 @@ static bool Unpack_H10306(wiegand_message_t *packed, wiegand_card_t *card) { static bool Pack_N10002(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) { memset(packed, 0, sizeof(wiegand_message_t)); - if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->FacilityCode > 0xFFFF) return false; // Can't encode FC. if (card->CardNumber > 0xFFFF) return false; // Can't encode CN. if (card->IssueLevel > 0) return false; // Not used in this format if (card->OEM > 0) return false; // Not used in this format packed->Length = 34; // Set number of bits - set_linear_field(packed, card->FacilityCode, 9, 8); + set_linear_field(packed, card->FacilityCode, 1, 16); set_linear_field(packed, card->CardNumber, 17, 16); + + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 16)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 17, 16)) + , 33); + if (preamble) return add_HID_header(packed); return true; @@ -523,8 +531,13 @@ static bool Unpack_N10002(wiegand_message_t *packed, wiegand_card_t *card) { if (packed->Length != 34) return false; // Wrong length? Stop here. + card->FacilityCode = get_linear_field(packed, 1, 16); card->CardNumber = get_linear_field(packed, 17, 16); - card->FacilityCode = get_linear_field(packed, 9, 8); + + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 33) == oddparity32(get_linear_field(packed, 17, 16))); + return true; } @@ -1417,3 +1430,11 @@ bool HIDTryUnpack(wiegand_message_t *packed) { return ((found_cnt - found_invalid_par) > 0); } + +void HIDUnpack(int idx, wiegand_message_t *packed) { + wiegand_card_t card; + memset(&card, 0, sizeof(wiegand_card_t)); + if (FormatTable[idx].Unpack(packed, &card)) { + hid_print_card(&card, FormatTable[idx]); + } +} diff --git a/client/src/wiegand_formats.h b/client/src/wiegand_formats.h index 080784ae2..313681bab 100644 --- a/client/src/wiegand_formats.h +++ b/client/src/wiegand_formats.h @@ -45,6 +45,7 @@ cardformat_t HIDGetCardFormat(int idx); bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed, bool preamble); bool HIDTryUnpack(wiegand_message_t *packed); void HIDPackTryAll(wiegand_card_t *card, bool preamble); +void HIDUnpack(int idx, wiegand_message_t *packed); void print_wiegand_code(wiegand_message_t *packed); void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed); #endif diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index 9c167f50a..43ad6147d 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -171,7 +171,9 @@ wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t } bool add_HID_header(wiegand_message_t *data) { - if (data->Length > 84 || data->Length == 0) return false; // Invalid value + // Invalid value + if (data->Length > 84 || data->Length == 0) + return false; if (data->Length >= 64) { data->Top |= 1 << (data->Length - 64); // leading 1: start bit