From 9c61ac1375779108d005951967b83016f0a1e4aa Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 12 Sep 2019 16:13:36 +0300 Subject: [PATCH 01/33] additional fido CA --- client/fido/additional_ca.c | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 7ea103004..3c10a9de9 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -37,6 +37,7 @@ // Name: Yubico U2F Root CA Serial 457200631 // Issued: 2014-08-01 // https://github.com/Yubico/developers.yubico.com/tree/master/static/U2F +// https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/7DwVE5vbRQysYTJrf95b3a #define YUBICO_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ "MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \ @@ -75,6 +76,83 @@ "jQGd7rwSZuE5RWUPVygYhUstQO9zNUOs\r\n" \ "-----END CERTIFICATE-----\r\n" +// FEITIAN U2F +// https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/eS7v8sum4jxp7kgLQ5Qqcg +#define FEITIAN_U2F_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBfjCCASWgAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDDAxGVCBGSURP\r\n" \ + "IDAyMDAwIBcNMTYwNTAxMDAwMDAwWhgPMjA1MDA1MDEwMDAwMDBaMBcxFTATBgNV\r\n" \ + "BAMMDEZUIEZJRE8gMDIwMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNBmrRqV\r\n" \ + "OxztTJVN19vtdqcL7tKQeol2nnM2/yYgvksZnr50SKbVgIEkzHQVOu80LVEE3lVh\r\n" \ + "eO1HjggxAlT6o4WjYDBeMB0GA1UdDgQWBBRJFWQt1bvG3jM6XgmV/IcjNtO/CzAf\r\n" \ + "BgNVHSMEGDAWgBRJFWQt1bvG3jM6XgmV/IcjNtO/CzAMBgNVHRMEBTADAQH/MA4G\r\n" \ + "A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNHADBEAiAwfPqgIWIUB+QBBaVGsdHy\r\n" \ + "0s5RMxlkzpSX/zSyTZmUpQIgB2wJ6nZRM8oX/nA43Rh6SJovM2XwCCH//+LirBAb\r\n" \ + "B0M=\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// FEITIAN FIDO2 +#define FEITIAN_FIDO2_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIB2DCCAX6gAwIBAgIQGBUrQbdDrm20FZnDsX2CBTAKBggqhkjOPQQDAjBLMQsw\r\n" \ + "CQYDVQQGEwJVUzEdMBsGA1UECgwURmVpdGlhbiBUZWNobm9sb2dpZXMxHTAbBgNV\r\n" \ + "BAMMFEZlaXRpYW4gRklETyBSb290IENBMCAXDTE4MDQwMTAwMDAwMFoYDzIwNDgw\r\n" \ + "MzMxMjM1OTU5WjBLMQswCQYDVQQGEwJVUzEdMBsGA1UECgwURmVpdGlhbiBUZWNo\r\n" \ + "bm9sb2dpZXMxHTAbBgNVBAMMFEZlaXRpYW4gRklETyBSb290IENBMFkwEwYHKoZI\r\n" \ + "zj0CAQYIKoZIzj0DAQcDQgAEsFYEEhiJuqqnMgQjSiivBjV7DGCTf4XBBH/B7uvZ\r\n" \ + "sKxXShF0L8uDISWUvcExixRs6gB3oldSrjox6L8T94NOzqNCMEAwHQYDVR0OBBYE\r\n" \ + "FEu9hyYRrRyJzwRYvnDSCIxrFiO3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\r\n" \ + "BAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIDHSb2mbNDAUNXvpPU0oWKeNye0fQ2l9\r\n" \ + "D01AR2+sLZdhAiEAo3wz684IFMVsCCRmuJqxH6FQRESNqezuo1E+KkGxWuM=\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// https://hypersecu.com/support/downloads +// HyperFIDO U2F Security Key Attestation CA +// Issuer: CN=FT FIDO 0100 +#define HYPERFIDO_U2F_1_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBjTCCATOgAwIBAgIBATAKBggqhkjOPQQDAjAXMRUwEwYDVQQDEwxGVCBGSURP\r\n" \ + "IDAxMDAwHhcNMTQwNzAxMTUzNjI2WhcNNDQwNzAzMTUzNjI2WjAXMRUwEwYDVQQD\r\n" \ + "EwxGVCBGSURPIDAxMDAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASxdLxJx8ol\r\n" \ + "S3DS5cIHzunPF0gg69d+o8ZVCMJtpRtlfBzGuVL4YhaXk2SC2gptPTgmpZCV2vbN\r\n" \ + "fAPi5gOF0vbZo3AwbjAdBgNVHQ4EFgQUXt4jWlYDgwhaPU+EqLmeM9LoPRMwPwYD\r\n" \ + "VR0jBDgwNoAUXt4jWlYDgwhaPU+EqLmeM9LoPROhG6QZMBcxFTATBgNVBAMTDEZU\r\n" \ + "IEZJRE8gMDEwMIIBATAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIQC2\r\n" \ + "D9o9cconKTo8+4GZPyZBJ3amc8F0/kzyidX9dhrAIAIgM9ocs5BW/JfmshVP9Mb+\r\n" \ + "Joa/kgX4dWbZxrk0ioTfJZg=\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// Issuer: CN= HYPERFIDO 0200 +#define HYPERFIDO_U2F_2_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBxzCCAWygAwIBAgICEAswCgYIKoZIzj0EAwIwOjELMAkGA1UEBhMCQ0ExEjAQ\r\n" \ + "BgNVBAoMCUhZUEVSU0VDVTEXMBUGA1UEAwwOSFlQRVJGSURPIDAyMDAwIBcNMTgw\r\n" \ + "MTAxMDAwMDAwWhgPMjA0NzEyMzEyMzU5NTlaMDoxCzAJBgNVBAYTAkNBMRIwEAYD\r\n" \ + "VQQKDAlIWVBFUlNFQ1UxFzAVBgNVBAMMDkhZUEVSRklETyAwMjAwMFkwEwYHKoZI\r\n" \ + "zj0CAQYIKoZIzj0DAQcDQgAErKUI1G0S7a6IOLlmHipLlBuxTYjsEESQvzQh3dB7\r\n" \ + "dvxxWWm7kWL91rq6S7ayZG0gZPR+zYqdFzwAYDcG4+aX66NgMF4wHQYDVR0OBBYE\r\n" \ + "FLZYcfMMwkQAGbt3ryzZFPFypmsIMB8GA1UdIwQYMBaAFLZYcfMMwkQAGbt3ryzZ\r\n" \ + "FPFypmsIMAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMC\r\n" \ + "A0kAMEYCIQCG2/ppMGt7pkcRie5YIohS3uDPIrmiRcTjqDclKVWg0gIhANcPNDZH\r\n" \ + "E2/zZ+uB5ThG9OZus+xSb4knkrbAyXKX2zm/\r\n" \ + "-----END CERTIFICATE-----\r\n" + +// NXP +// https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/JKP5CiDehdMMPwtG5i7to5 +#define NXP_U2F_CA \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIBjzCCATWgAwIBAgIJASNFZ4mrze8BMAoGCCqGSM49BAMCMCgxJjAkBgNVBAMM\r\n" \ + "HU5YUCBTZW1pY29uZHVjdG9yIFUyRiBSb290IENBMB4XDTE1MTIxNjE2MDUxMFoX\r\n" \ + "DTI1MTIxMzE2MDUxMFowGjEYMBYGA1UEAwwPTlhQIEZJRE8gVTJGIHYwMFkwEwYH\r\n" \ + "KoZIzj0CAQYIKoZIzj0DAQcDQgAExbuQcVAAX7IPwqVVVX/ni3Ch3Zzo04WkSsr5\r\n" \ + "nHXpEarB+sd846FAi/o3a7oF1+u/oV65syguDD/0FaUGuUgTpKNWMFQwDAYDVR0T\r\n" \ + "AQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHwYDVR0jBBgwFoAUpaNTDgOg8hGDmawL\r\n" \ + "bDydVSoNNPgwEwYLKwYBBAGC5RwCAQEEBAMCBDAwCgYIKoZIzj0EAwIDSAAwRQIh\r\n" \ + "AJlr23jig2LxRM1PpgMAQXnZJy/HnkRB9O8KD0o2oK/mAiBG5EK1S3yVHdkkVGTJ\r\n" \ + "Q12ffuK8Op7Nx89cszCr0WyIhQ==\r\n" \ + "-----END CERTIFICATE-----\r\n" + /* Concatenation of all additional CA certificates in PEM format if available */ -const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA; +const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA \ + FEITIAN_U2F_CA FEITIAN_FIDO2_CA HYPERFIDO_U2F_1_CA HYPERFIDO_U2F_2_CA NXP_U2F_CA; const size_t additional_ca_pem_len = sizeof(additional_ca_pem); From 3726df62a485447b8971ba7d262defc5c3765847 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 11:11:54 +0200 Subject: [PATCH 02/33] chg: enhanced verify t55xx write. We set config to the cloned block0, whats left is to identify the offset, which we try to do. --- client/cmdlfawid.c | 15 ++++++++ client/cmdlffdx.c | 15 ++++++++ client/cmdlfguard.c | 15 ++++++++ client/cmdlfindala.c | 24 ++++++------ client/cmdlfjablotron.c | 15 ++++++++ client/cmdlfkeri.c | 14 +++++++ client/cmdlfnedap.c | 35 +++++++++--------- client/cmdlfnedap.h | 13 +++++++ client/cmdlfnoralsy.c | 9 +++-- client/cmdlfpresco.c | 13 +++---- client/cmdlfpyramid.c | 8 ++-- client/cmdlft55xx.c | 82 ++++++++++++++++++++++++++++++----------- client/cmdlft55xx.h | 3 ++ client/cmdlfvisa2000.c | 10 +++-- 14 files changed, 202 insertions(+), 69 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 2360906a4..934335c64 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -26,6 +26,7 @@ #include "cmdlf.h" // lf read #include "protocols.h" // for T55xx config register definitions #include "util_posix.h" +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); /* @@ -414,6 +415,7 @@ static int CmdAWIDClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone AWID %u to T55x7 with FC: %u, CN: %u", fmtlen, fc, cn); print_blocks(blocks, 4); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -437,7 +439,20 @@ static int CmdAWIDClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 2e48918fb..233783b33 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -24,6 +24,7 @@ #include "crc16.h" // for checksum crc-16_ccitt #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite /* FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) @@ -296,6 +297,7 @@ static int CmdFdxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid); print_blocks(blocks, 5); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -318,7 +320,20 @@ static int CmdFdxClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 22f7141fc..036597f0f 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -21,6 +21,7 @@ #include "cmdlf.h" #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -183,6 +184,7 @@ static int CmdGuardClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); print_blocks(blocks, 4); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -205,7 +207,20 @@ static int CmdGuardClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 3fd3be59e..8d62e37ae 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -468,21 +468,21 @@ static int CmdIndalaClone(const char *Cmd) { if (isLongUid) { PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t datawords[7] = {0}; - datawords[0] = bytes_to_num(data, 4); - datawords[1] = bytes_to_num(data + 4, 4); - datawords[2] = bytes_to_num(data + 8, 4); - datawords[3] = bytes_to_num(data + 12, 4); - datawords[4] = bytes_to_num(data + 16, 4); - datawords[5] = bytes_to_num(data + 20, 4); - datawords[6] = bytes_to_num(data + 24, 4); + uint32_t blocks[7] = {0}; + blocks[0] = bytes_to_num(data, 4); + blocks[1] = bytes_to_num(data + 4, 4); + blocks[2] = bytes_to_num(data + 8, 4); + blocks[3] = bytes_to_num(data + 12, 4); + blocks[4] = bytes_to_num(data + 16, 4); + blocks[5] = bytes_to_num(data + 20, 4); + blocks[6] = bytes_to_num(data + 24, 4); clearCommandBuffer(); - SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, datawords, sizeof(datawords)); + SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, blocks, sizeof(blocks)); } else { PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t datawords[2] = {0}; - datawords[0] = bytes_to_num(data, 4); - datawords[1] = bytes_to_num(data + 4, 4); + uint32_t blocks[2] = {0}; + blocks[0] = bytes_to_num(data, 4); + blocks[1] = bytes_to_num(data + 4, 4); clearCommandBuffer(); SendCommandOLD(CMD_LF_INDALA_CLONE, 0, 0, 0, datawords, sizeof(datawords)); } diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 9cc663895..919610293 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -24,6 +24,7 @@ #include "cmdlf.h" #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // parityTest +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -170,6 +171,7 @@ static int CmdJablotronClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode); print_blocks(blocks, 3); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -192,7 +194,20 @@ static int CmdJablotronClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 384aad0b6..9f01f2f7f 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -22,6 +22,7 @@ #include "cmdlf.h" #include "protocols.h" // for T55xx config register definitions #include "lfdemod.h" // preamble test +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -159,6 +160,7 @@ static int CmdKeriClone(const char *Cmd) { blocks[2] = data & 0xFFFFFFFF; print_blocks(blocks, 3); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -181,8 +183,20 @@ static int CmdKeriClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; } + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index 3a4ebd131..ec2837d7a 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -9,20 +9,6 @@ #include "cmdlfnedap.h" -#include - -#include -#include - -#include "cmdparser.h" // command_t -#include "comms.h" -#include "crc16.h" -#include "cmdlft55xx.h" -#include "ui.h" -#include "cmddata.h" -#include "cmdlf.h" -#include "lfdemod.h" - #define FIXED_71 0x71 #define FIXED_40 0x40 #define UNKNOWN_A 0x00 @@ -469,6 +455,7 @@ int CmdLFNedapClone(const char *Cmd) { PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to T55x7"); print_blocks(blocks, max); + uint8_t res = 0; PacketResponseNG resp; // fast push mode @@ -490,10 +477,24 @@ int CmdLFNedapClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + else { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); + PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); } - PrintAndLogEx(NORMAL, "\n"); - PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); - PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); return PM3_SUCCESS; } diff --git a/client/cmdlfnedap.h b/client/cmdlfnedap.h index fda0e130e..74fdd30fb 100644 --- a/client/cmdlfnedap.h +++ b/client/cmdlfnedap.h @@ -11,6 +11,19 @@ #include "common.h" +#include + +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" +#include "crc16.h" +#include "cmdlft55xx.h" // verifywrite +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" + int CmdLFNedap(const char *Cmd); int demodNedap(void); diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 146c6b350..2d9481782 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -177,13 +177,14 @@ static int CmdNoralsyClone(const char *Cmd) { return PM3_ETIMEOUT; } - // write block0, needs a detect. - if (i == 0) - t55xxAquireAndDetect(false, 0, blocks[i], false); + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; - } if ( res == 0 ) diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index a9c74d9ac..39587c5ea 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -144,16 +144,15 @@ static int CmdPrescoClone(const char *Cmd) { return PM3_ETIMEOUT; } - // write block0, needs a detect. if (i == 0) { - printf("enter detect "); - bool ok = t55xxAquireAndDetect(false, 0, blocks[i], false); - printf(" b0 = '%c' \n", (ok) ? 'Y':'N'); + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; } - if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) { + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; - printf(" i = %d \n", i); - } + } if ( res == 0 ) diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index d0f116bf4..90e5c23d7 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -254,9 +254,11 @@ static int CmdPyramidClone(const char *Cmd) { return PM3_ETIMEOUT; } - // write block0, needs a detect. - if (i == 0) - t55xxAquireAndDetect(false, 0, blocks[i], false); + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1afa169c9..06dac9c24 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -405,6 +405,32 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass } } +bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { + + if (verbose) + PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); + + for ( uint8_t m = 0; m < 4; m++) { + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { + continue; + } + + if (DecodeT55xxBlock() == false) { + continue; + } + + for( uint16_t i = 0; DemodBufferLen - 32; i++) { + uint32_t tmp = PackBits(i, 32, DemodBuffer); + if ( tmp == known_block0 ) { + config.offset = i; + config.downlink_mode = m; + return true; + } + } + } + return false; +} + bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { if (verbose) @@ -417,6 +443,7 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, if (tryDetectModulationEx(m, verbose, known_block0) == false) continue; + config.downlink_mode = m; return true; } return false; @@ -491,6 +518,36 @@ void printT5xxHeader(uint8_t page) { PrintAndLogEx(SUCCESS, "----+----------+----------------------------------+-------"); } +void SetConfigWithBlock0(uint32_t block0) { + // T55x7 + uint32_t extend = (block0 >> (32 - 15)) & 0x01; + uint32_t dbr; + if (extend) + dbr = (block0 >> (32 - 14)) & 0x3F; + else + dbr = (block0 >> (32 - 14)) & 0x07; + + uint32_t datamod = (block0 >> (32 - 20)) & 0x1F; + bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); + bool sst = (bool)((block0 >> (32 - 29)) & 0x01); + bool inv = (bool)((block0 >> (32 - 31)) & 0x01); + + config.modulation = datamod; + config.bitrate = dbr; + + // FSK1a, FSK2a + if ( datamod == DEMOD_FSK1a || datamod == DEMOD_FSK2a || datamod == DEMOD_BIa ) + config.inverted = 1; + else + config.inverted = inv; + + config.Q5 = 0; + config.ST = sst; + config.usepwd = pwd; + config.offset = 0; + config.block0 = block0; +} + static int CmdT55xxSetConfig(const char *Cmd) { // No args @@ -621,30 +678,11 @@ static int CmdT55xxSetConfig(const char *Cmd) { if ( gotconf ) { - // Q5 - - + // Q5 - to be implemented + // T55x7 - uint32_t extend = (block0 >> (32 - 15)) & 0x01; - uint32_t dbr; - if (extend) - dbr = (block0 >> (32 - 14)) & 0x3F; - else - dbr = (block0 >> (32 - 14)) & 0x07; + SetConfigWithBlock0(block0); - uint32_t datamod = (block0 >> (32 - 20)) & 0x1F; - bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); - bool sst = (bool)((block0 >> (32 - 29)) & 0x01); - bool inv = (bool)((block0 >> (32 - 31)) & 0x01); - - config.modulation = datamod; - config.bitrate = dbr; - config.inverted = inv; - config.Q5 = 0; - config.ST = sst; - config.usepwd = pwd; - config.offset = 0; - config.block0 = block0; } else { config.block0 = 0; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index f388a39af..182377deb 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -131,6 +131,8 @@ void Set_t55xx_Config(t55xx_conf_block_t conf); int CmdLFT55XX(const char *Cmd); +void SetConfigWithBlock0(uint32_t block0); + char *GetPskCfStr(uint32_t id, bool q5); char *GetBitRateStr(uint32_t id, bool xmode); char *GetSaferStr(uint32_t id); @@ -143,6 +145,7 @@ void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); +bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index 51cedb925..f23a7c5a8 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -189,11 +189,13 @@ static int CmdVisa2kClone(const char *Cmd) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); return PM3_ETIMEOUT; - } + } - // write block0, needs a detect. - if (i == 0) - t55xxAquireAndDetect(false, 0, blocks[i], false); + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; From 4c08477ef71d29641c59ad7b5589ccbab1d3e565 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 11:33:05 +0200 Subject: [PATCH 03/33] chg: 'lf indala clone' - refactored , uses NG --- armsrc/appmain.c | 11 ------ armsrc/lfops.c | 31 +--------------- armsrc/lfops.h | 2 -- client/cmdlfindala.c | 86 +++++++++++++++++++++++++++++++++++--------- client/util.c | 2 +- include/pm3_cmd.h | 11 ++++-- 6 files changed, 80 insertions(+), 63 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 058a4709e..06ea02e50 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -769,17 +769,6 @@ static void PacketReceived(PacketCommandNG *packet) { SimulateTagLowFrequencyBidir(packet->oldarg[0], packet->oldarg[1]); break; } - case CMD_LF_INDALA_CLONE: { - CopyIndala64toT55x7(packet->data.asDwords[0], packet->data.asDwords[1]); - break; - } - case CMD_LF_INDALA224_CLONE: { - CopyIndala224toT55x7( - packet->data.asDwords[0], packet->data.asDwords[1], packet->data.asDwords[2], packet->data.asDwords[3], - packet->data.asDwords[4], packet->data.asDwords[5], packet->data.asDwords[6] - ); - break; - } case CMD_LF_T55XX_READBL: { struct p { uint32_t password; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 47c8011f8..fd1fa36e1 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1712,7 +1712,7 @@ void T55xxWriteBlock(uint8_t *data) { c->flags &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0 LED_A_ON(); - T55xx_SendCMD(c->data, c->pwd, c->flags | (c->blockno << 9)) ; //, false); + T55xx_SendCMD(c->data, c->pwd, c->flags | (c->blockno << 9)); // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, // so wait a little more) @@ -1744,7 +1744,6 @@ void T55xxWriteBlock(uint8_t *data) { // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - // cmd_send(CMD_ACK,0,0,0,0,0); reply_ng(CMD_LF_T55XX_WRITEBL, PM3_SUCCESS, NULL, 0); LED_A_OFF(); } @@ -2049,34 +2048,6 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo) { LED_D_OFF(); } -// Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) { - //Program the 2 data blocks for supplied 64bit UID - // and the Config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) - uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; - LED_D_ON(); - WriteT55xx(data, 0, 3); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); - LED_D_OFF(); -} -// Clone Indala 224-bit tag by UID to T55x7 -void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7) { - //Program the 7 data blocks for supplied 224bit UID - uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7}; - // and the block 0 for Indala224 format - //Config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) - data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; - LED_D_ON(); - WriteT55xx(data, 0, 8); - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - LED_D_OFF(); -} // clone viking tag to T55xx void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { diff --git a/armsrc/lfops.h b/armsrc/lfops.h index 99d1b29eb..a88f05800 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -46,8 +46,6 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); -void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 -void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 void T55xxResetRead(uint8_t flags); //id T55xxWriteBlock(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); void T55xxWriteBlock(uint8_t *data); diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 8d62e37ae..da13766db 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -25,6 +25,8 @@ #include "lfdemod.h" // parityTest, bitbytes_to_byte #include "cmddata.h" #include "cmdlf.h" // lf_read +#include "protocols.h" // t55 defines +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); @@ -439,10 +441,12 @@ static int CmdIndalaSim(const char *Cmd) { return PM3_SUCCESS; } -// iceman - needs refactoring static int CmdIndalaClone(const char *Cmd) { bool isLongUid = false; + uint32_t blocks[8] = {0}; + uint8_t max = 0; + uint8_t data[7 * 4]; int datalen = 0; @@ -466,27 +470,77 @@ static int CmdIndalaClone(const char *Cmd) { CLIGetHexWithReturn(2, data, &datalen); CLIParserFree(); +/* + //TODO add selection of chip for Q5 or T55x7 + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); +*/ + if (isLongUid) { + // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t blocks[7] = {0}; - blocks[0] = bytes_to_num(data, 4); - blocks[1] = bytes_to_num(data + 4, 4); - blocks[2] = bytes_to_num(data + 8, 4); - blocks[3] = bytes_to_num(data + 12, 4); - blocks[4] = bytes_to_num(data + 16, 4); - blocks[5] = bytes_to_num(data + 20, 4); - blocks[6] = bytes_to_num(data + 24, 4); - clearCommandBuffer(); - SendCommandOLD(CMD_LF_INDALA224_CLONE, 0, 0, 0, blocks, sizeof(blocks)); + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); + blocks[2] = bytes_to_num(data + 4, 4); + blocks[3] = bytes_to_num(data + 8, 4); + blocks[4] = bytes_to_num(data + 12, 4); + blocks[5] = bytes_to_num(data + 16, 4); + blocks[6] = bytes_to_num(data + 20, 4); + blocks[7] = bytes_to_num(data + 24, 4); + max = 8; } else { + // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); - uint32_t blocks[2] = {0}; - blocks[0] = bytes_to_num(data, 4); - blocks[1] = bytes_to_num(data + 4, 4); - clearCommandBuffer(); - SendCommandOLD(CMD_LF_INDALA_CLONE, 0, 0, 0, datawords, sizeof(datawords)); + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); + blocks[1] = bytes_to_num(data, 4); + blocks[2] = bytes_to_num(data + 4, 4); + max = 3; } + print_blocks(blocks, max); + + uint8_t res = 0; + PacketResponseNG resp; + + // fast push mode + conn.block_after_ACK = true; + for (uint8_t i = 0; i < max; i++) { + if (i == max - 1) { + // Disable fast mode on last packet + conn.block_after_ACK = false; + } + clearCommandBuffer(); + t55xx_write_block_t ng; + ng.data = blocks[i]; + ng.pwd = 0; + ng.blockno = i; + ng.flags = 0; + + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/client/util.c b/client/util.c index 6877e8835..55b114fdb 100644 --- a/client/util.c +++ b/client/util.c @@ -390,7 +390,7 @@ void print_blocks(uint32_t *data, size_t len) { PrintAndLogEx(ERR, "..empty data"); } else { for (uint8_t i = 0; i < len; i++) - PrintAndLogEx(SUCCESS, " %02d | 0x%08X", i, data[i]); + PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]); } } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index d79433fcf..4982f4a60 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -242,6 +242,14 @@ typedef struct { uint8_t keytype; } PACKED mfc_eload_t; +typedef struct { + uint8_t status; + uint8_t CSN[8]; + uint8_t CONFIG[8]; + uint8_t CC[8]; + uint8_t AIA[8]; +} PACKED iclass_reader_t; + // For the bootloader #define CMD_DEVICE_INFO 0x0000 #define CMD_SETUP_WRITE 0x0001 @@ -345,9 +353,6 @@ typedef struct { #define CMD_SET_ADC_MUX 0x020F #define CMD_LF_HID_CLONE 0x0210 #define CMD_LF_EM410X_WRITE 0x0211 -#define CMD_LF_INDALA_CLONE 0x0212 -// for 224 bits UID -#define CMD_LF_INDALA224_CLONE 0x0213 #define CMD_LF_T55XX_READBL 0x0214 #define CMD_LF_T55XX_WRITEBL 0x0215 #define CMD_LF_T55XX_RESET_READ 0x0216 From e5c31886ebd9bbb1b23a0fac76922f97396b3102 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 11:41:34 +0200 Subject: [PATCH 04/33] chg: 'lf io clone' - refactored, uses NG --- armsrc/appmain.c | 4 ---- armsrc/lfops.c | 12 ------------ armsrc/lfops.h | 1 - client/cmdlfio.c | 44 ++++++++++++++++++++++++++++++++++++++++---- include/pm3_cmd.h | 1 - 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 06ea02e50..7d29da0ee 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -730,10 +730,6 @@ static void PacketReceived(PacketCommandNG *packet) { CmdIOdemodFSK(packet->oldarg[0], &high, &low, 1); break; } - case CMD_LF_IO_CLONE: { - CopyIOtoT55x7(packet->oldarg[0], packet->oldarg[1]); - break; - } case CMD_LF_EM410X_DEMOD: { uint32_t high; uint64_t low; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index fd1fa36e1..57b2b75cd 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2036,18 +2036,6 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { LED_D_OFF(); } -void CopyIOtoT55x7(uint32_t hi, uint32_t lo) { - uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; - //TODO add selection of chip for Q5 or T55x7 - // data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT; - - LED_D_ON(); - // Program the data blocks for supplied ID - // and the block 0 config - WriteT55xx(data, 0, 3); - LED_D_OFF(); -} - // clone viking tag to T55xx void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { diff --git a/armsrc/lfops.h b/armsrc/lfops.h index a88f05800..bf246b529 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -42,7 +42,6 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26 void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol); void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); -void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567 void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567 void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5); void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 87fa17b02..b71302ea9 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -24,6 +24,7 @@ #include "lfdemod.h" // parityTest, bitbytes_to_byte #include "protocols.h" // for T55xx config register definitions #include "cmddata.h" +#include "cmdlft55xx.h" // verifywrite static int CmdHelp(const char *Cmd); /* @@ -243,7 +244,6 @@ static int CmdIOProxSim(const char *Cmd) { static int CmdIOProxClone(const char *Cmd) { - uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; uint16_t cn = 0; uint8_t version = 0, fc = 0; uint8_t bits[64]; @@ -268,7 +268,9 @@ static int CmdIOProxClone(const char *Cmd) { return PM3_ESOFT; } - if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') + uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; + + if (tolower(param_getchar(Cmd, 3) == 'q')) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; blocks[1] = bytebits_to_byte(bits, 32); @@ -277,8 +279,42 @@ static int CmdIOProxClone(const char *Cmd) { PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); print_blocks(blocks, 3); - clearCommandBuffer(); - SendCommandMIX(CMD_LF_IO_CLONE, blocks[1], blocks[2], 0, NULL, 0); + uint8_t res = 0; + PacketResponseNG resp; + + // fast push mode + conn.block_after_ACK = true; + for (uint8_t i = 0; i < 3; i++) { + if (i == 2) { + // Disable fast mode on last packet + conn.block_after_ACK = false; + } + clearCommandBuffer(); + t55xx_write_block_t ng; + ng.data = blocks[i]; + ng.pwd = 0; + ng.blockno = i; + ng.flags = 0; + + SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng)); + if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } + + if (i == 0) { + SetConfigWithBlock0(blocks[0]); + if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + continue; + } + + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) + res++; + } + + if ( res == 0 ) + PrintAndLogEx(SUCCESS, "Success writing to tag"); + return PM3_SUCCESS; } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 4982f4a60..13995a429 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -361,7 +361,6 @@ typedef struct { #define CMD_LF_EM4X_READWORD 0x0218 #define CMD_LF_EM4X_WRITEWORD 0x0219 #define CMD_LF_IO_DEMOD 0x021A -#define CMD_LF_IO_CLONE 0x021B #define CMD_LF_EM410X_DEMOD 0x021c // Sampling configuration for LF reader/sniffer #define CMD_LF_SAMPLING_SET_CONFIG 0x021d From 412f016b94df0926e995c4aa59a6479bacc13ec9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 16 Sep 2019 12:36:04 +0200 Subject: [PATCH 05/33] chg: 'lf t55xx config' - can set config based on a block0, offset and Q5 lf t55xx config c 000880E0 o 10 - sets a T55x7 w offset 10 lf t55xx config c 000880E0 o 6 Q5 - sets a Q5/T5555 w offset 6 --- client/cmdlft55xx.c | 14 ++++++-------- client/cmdlft55xx.h | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 6b42b4688..88c6b3162 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -519,6 +519,9 @@ void printT5xxHeader(uint8_t page) { } void SetConfigWithBlock0(uint32_t block0) { + SetConfigWithBlock0Ex(block0, 0, false); +} +void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5) { // T55x7 uint32_t extend = (block0 >> (32 - 15)) & 0x01; uint32_t dbr; @@ -541,10 +544,10 @@ void SetConfigWithBlock0(uint32_t block0) { else config.inverted = inv; - config.Q5 = 0; + config.Q5 = Q5; config.ST = sst; config.usepwd = pwd; - config.offset = 0; + config.offset = offset; config.block0 = block0; } @@ -677,12 +680,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { if (errors) return usage_t55xx_config(); if ( gotconf ) { - - // Q5 - to be implemented - - // T55x7 - SetConfigWithBlock0(block0); - + SetConfigWithBlock0Ex(block0, config.offset, config.Q5); } else { config.block0 = 0; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 182377deb..d4e217372 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -132,6 +132,7 @@ void Set_t55xx_Config(t55xx_conf_block_t conf); int CmdLFT55XX(const char *Cmd); void SetConfigWithBlock0(uint32_t block0); +void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5); char *GetPskCfStr(uint32_t id, bool q5); char *GetBitRateStr(uint32_t id, bool xmode); From c5ea6b54ce8535652dbef92779fcc91d15cd31fa Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:37:18 +0300 Subject: [PATCH 06/33] add ignoring results of some tests --- client/emv/cmdemv.c | 17 +++++++++++++++-- client/emv/test/cryptotest.c | 6 +++--- client/emv/test/cryptotest.h | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 8656e4902..8bb630074 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1714,8 +1714,21 @@ static int CmdEMVList(const char *Cmd) { } static int CmdEMVTest(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - return ExecuteCryptoTests(true); + CLIParserInit("emv test", + "Executes tests\n", + "Usage:\n\temv test\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("iI", "ignore", "ignore timing tests for VM"), + arg_param_end + }; + CLIExecWithReturn(Cmd, argtable, true); + + bool ignoreTimeTest = arg_get_lit(1); + CLIParserFree(); + + return ExecuteCryptoTests(true, ignoreTimeTest); } static int CmdEMVRoca(const char *Cmd) { diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index 937ff7e8e..b8ea1239e 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -33,7 +33,7 @@ #include "crypto/libpcrypto.h" #include "emv/emv_roca.h" -int ExecuteCryptoTests(bool verbose) { +int ExecuteCryptoTests(bool verbose, bool ignore_time) { int res; bool TestFail = false; @@ -56,7 +56,7 @@ int ExecuteCryptoTests(bool verbose) { if (res) TestFail = true; res = mbedtls_entropy_self_test(verbose); - if (res) TestFail = true; + if (res && !ignore_time) TestFail = true; // retry for CI (when resources too low) for (int i = 0; i < 3; i++) { @@ -65,7 +65,7 @@ int ExecuteCryptoTests(bool verbose) { break; PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1); } - if (res) TestFail = true; + if (res && !ignore_time) TestFail = true; res = mbedtls_ctr_drbg_self_test(verbose); if (res) TestFail = true; diff --git a/client/emv/test/cryptotest.h b/client/emv/test/cryptotest.h index 74a317e4e..aeecce556 100644 --- a/client/emv/test/cryptotest.h +++ b/client/emv/test/cryptotest.h @@ -12,5 +12,5 @@ #define __CRYPTOTEST_H #include -int ExecuteCryptoTests(bool verbose); +int ExecuteCryptoTests(bool verbose, bool ignore_time); #endif From e8cd43f1affe8d922877470762b3cdf98d1a090a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 16 Sep 2019 17:39:00 +0300 Subject: [PATCH 07/33] added parameter --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index af725ef93..a32c6a56a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -383,7 +383,7 @@ test_script: #proxmark crypto tests - ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test'"} "Test?s? ? OK" + ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK" if ($global:TestsPassed) { From abe5ca47a57899071df4a20202b647b809d00f86 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 17 Sep 2019 17:42:12 +0200 Subject: [PATCH 08/33] thinfilm: reduce timeout, no need to wait so long --- armsrc/iso14443a.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c49d93a1f..348317a8a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2044,8 +2044,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint8_t *rec } } - // timeout already in ms + 10ms guard time - if (GetTickCount() - receive_timer > 1160) + if (GetTickCount() - receive_timer > 100) break; } *received_len = Demod.len; From d3651cc0757a02b590ef4668a2d6297f0076d40e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 17 Sep 2019 19:13:00 +0200 Subject: [PATCH 09/33] chg 'hw status' - reply NG.... thanks @cjbrigato --- armsrc/appmain.c | 2 +- client/cmdhw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7d29da0ee..257a4a5b6 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -343,7 +343,7 @@ void SendStatus(void) { Flashmem_print_info(); #endif - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_ng(CMD_STATUS, PM3_SUCCESS, NULL, 0); } void SendCapabilities(void) { diff --git a/client/cmdhw.c b/client/cmdhw.c index c81efda9e..c363fdc25 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -502,7 +502,7 @@ static int CmdStatus(const char *Cmd) { clearCommandBuffer(); PacketResponseNG resp; SendCommandNG(CMD_STATUS, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) + if (WaitForResponseTimeout(CMD_STATUS, &resp, 2000) == false) PrintAndLogEx(WARNING, "Status command failed. Communication speed test timed out"); return PM3_SUCCESS; } From 7abc10c63a388458cecdb29d0cee0cba25916468 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:20:07 +0200 Subject: [PATCH 10/33] add: 'wiegand commands' - wiegand manipulation like encoding / decoding of credentials. From offical repo (@grauerfuchs) Adapted and converted to fit this repo. --- client/cmdmain.c | 4 +- client/cmdwiegand.c | 205 ++++++++++ client/cmdwiegand.h | 20 + client/util.c | 17 + client/util.h | 1 + client/wiegand_formats.c | 715 +++++++++++++++++++++++++++++++++++ client/wiegand_formats.h | 48 +++ client/wiegand_formatutils.c | 185 +++++++++ client/wiegand_formatutils.h | 49 +++ 9 files changed, 1243 insertions(+), 1 deletion(-) create mode 100644 client/cmdwiegand.c create mode 100644 client/cmdwiegand.h create mode 100644 client/wiegand_formats.c create mode 100644 client/wiegand_formats.h create mode 100644 client/wiegand_formatutils.c create mode 100644 client/wiegand_formatutils.h diff --git a/client/cmdmain.c b/client/cmdmain.c index eba34b2ca..4b6013d80 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -32,6 +32,7 @@ #include "cmdflashmem.h" // rdv40 flashmem commands #include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands #include "cmdusart.h" // rdv40 FPC USART commands +#include "cmdwiegand.h" // wiegand commands #include "ui.h" #include "util_posix.h" @@ -98,11 +99,12 @@ static command_t CommandTable[] = { {"mem", CmdFlashMem, IfPm3Flash, "{ Flash Memory manipulation... }"}, {"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"}, {"rem", CmdRem, AlwaysAvailable, "Add text to row in log file"}, - {"reveng", CmdRev, AlwaysAvailable, "{ Crc calculations from the RevEng software }"}, + {"reveng", CmdRev, AlwaysAvailable, "{ CRC calculations from RevEng software }"}, {"sc", CmdSmartcard, IfPm3Smartcard, "{ Smart card ISO7816 commands... }"}, {"script", CmdScript, AlwaysAvailable, "{ Scripting commands }"}, {"trace", CmdTrace, AlwaysAvailable, "{ Trace manipulation... }"}, {"usart", CmdUsart, IfPm3FpcUsartFromUsb, "{ USART commands... }"}, + {"wiegand", CmdWiegand, AlwaysAvailable, "{ Wiegand format manipulation... }"}, {"quit", CmdQuit, AlwaysAvailable, ""}, {"exit", CmdQuit, AlwaysAvailable, "Exit program"}, {NULL, NULL, NULL, NULL} diff --git a/client/cmdwiegand.c b/client/cmdwiegand.c new file mode 100644 index 000000000..0b567d514 --- /dev/null +++ b/client/cmdwiegand.c @@ -0,0 +1,205 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Trace commands +//----------------------------------------------------------------------------- +#include "cmdwiegand.h" + +#include +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" +#include "pm3_cmd.h" +#include "protocols.h" +#include "parity.h" // oddparity +#include "cmdhflist.h" // annotations +#include "wiegand_formats.h" +#include "wiegand_formatutils.h" +#include "util.h" + +static int CmdHelp(const char *Cmd); + +static int usage_wiegand_list() { + PrintAndLogEx(NORMAL, "List available wiegand formats"); + return PM3_SUCCESS; +} +static int usage_wiegand_encode() { + PrintAndLogEx(NORMAL, "Encode wiegand formatted number to raw hex"); + PrintAndLogEx(NORMAL, "Usage: wiegand encode [w ] [ ] {...}"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " w see `wiegand list` for available formats"); + PrintAndLogEx(NORMAL, " c card number"); + PrintAndLogEx(NORMAL, " f facility code"); + PrintAndLogEx(NORMAL, " i issue Level"); + PrintAndLogEx(NORMAL, " o OEM code"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "samples:"); + PrintAndLogEx(NORMAL, " wiegand encode w H10301 f 101 c 1337"); + return PM3_SUCCESS; +} +static int usage_wiegand_decode() { + PrintAndLogEx(NORMAL, "Decode raw hex to wiegand format"); + PrintAndLogEx(NORMAL, "Usage: wiegand decode [id]

"); + PrintAndLogEx(NORMAL, " p ignore invalid parity"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Samples:"); + PrintAndLogEx(NORMAL, " wiegand decode 2006f623ae"); + return PM3_SUCCESS; +} + +void PrintTagId(wiegand_message_t *packed){ + if (packed->Top != 0) { + PrintAndLogEx(SUCCESS, "Card ID: %X%08X%08X", + (uint32_t)packed->Top, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; + } else { + PrintAndLogEx(SUCCESS, "Card ID: %X%08X", + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; + } +} + +int CmdWiegandList(const char *Cmd) { + bool errors = false; + char cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_wiegand_list(); + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + HIDListFormats(); + return PM3_SUCCESS; +} + +int CmdWiegandEncode(const char *Cmd) { + + int format_idx = -1; + char format[16] = {0}; + + wiegand_card_t data; + memset(&data, 0, sizeof(wiegand_card_t)); + + bool errors = false; + char cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_wiegand_encode(); + case 'w': + param_getstr(Cmd, cmdp + 1, format, sizeof(format)); + format_idx = HIDFindCardFormat(format); + if (format_idx == -1) { + PrintAndLogEx(WARNING, "Unknown format: %s", format); + errors = true; + } + cmdp += 2; + break; + case 'i': + data.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'f': + data.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'c': + data.CardNumber = param_get64ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'o': + data.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (errors || cmdp == 0) return usage_wiegand_encode(); + + wiegand_message_t packed; + memset(&packed, 0, sizeof(wiegand_message_t)); + + if (HIDPack(format_idx, &data, &packed) == false) { + PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); + return PM3_ESOFT; + } + + PrintTagId(&packed); + return PM3_SUCCESS; +} + +int CmdWiegandDecode(const char *Cmd) { + + uint32_t top = 0, mid = 0, bot = 0; + bool ignore_parity = false, gothex = false; + bool errors = false; + char cmdp = 0; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + uint32_t strlen = param_getlength(Cmd, cmdp); + strlen++; // null termin + if ( strlen > 2 ) { + char *s = calloc(strlen, sizeof(uint8_t)); + param_getstr(Cmd, cmdp, s, strlen); + hexstring_to_u96(&top, &mid, &bot, s); + free(s); + gothex = true; + cmdp++; + continue; + } + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_wiegand_decode(); + case 'p': + ignore_parity = true; + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + if (gothex == false) + errors = true; + + if (errors || cmdp < 1) return usage_wiegand_decode(); + + wiegand_message_t packed = initialize_message_object(top, mid, bot); + + HIDTryUnpack(&packed, ignore_parity); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"list", CmdWiegandList, AlwaysAvailable, "List available wiegand formats"}, + {"encode", CmdWiegandEncode, AlwaysAvailable, "Convert "}, + {"decode", CmdWiegandDecode, AlwaysAvailable, "Convert raw hex to wiegand format"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdWiegand(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/cmdwiegand.h b/client/cmdwiegand.h new file mode 100644 index 000000000..2c6e8fb40 --- /dev/null +++ b/client/cmdwiegand.h @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2019 iceman +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Trace commands +//----------------------------------------------------------------------------- + +#ifndef CMDWIEGAND_H__ +#define CMDWIEGAND_H__ + +#include "common.h" + +int CmdWiegand(const char *Cmd); +int CmdWiegandList(const char *Cmd); +int CmdWiegandEncode(const char *Cmd); +int CmdWiegandDecode(const char *Cmd); +#endif diff --git a/client/util.c b/client/util.c index 55b114fdb..f74605562 100644 --- a/client/util.c +++ b/client/util.c @@ -878,3 +878,20 @@ char *strmcopy(const char *buf) { } return str; } + +/** + * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers, one nibble + * at a time. + * + * Returns the number of nibbles (4 bits) entered. + */ +int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str) { + int n = 0, i = 0; + + while (sscanf(&str[i++], "%1x", &n ) == 1) { + *hi2 = (*hi2 << 4) | (*hi >> 28); + *hi = (*hi << 4) | (*lo >> 28); + *lo = (*lo << 4) | (n & 0xf); + } + return i - 1; +} diff --git a/client/util.h b/client/util.h index 7cfea0f8b..df69493d2 100644 --- a/client/util.h +++ b/client/util.h @@ -98,4 +98,5 @@ void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); char *strmcopy(const char *buf); +int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str); #endif diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c new file mode 100644 index 000000000..7228abd82 --- /dev/null +++ b/client/wiegand_formats.c @@ -0,0 +1,715 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// HID card format packing/unpacking routines +//----------------------------------------------------------------------------- +#include "wiegand_formats.h" + +bool Pack_H10301(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) 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 = 26; // Set number of bits + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0xFF) << 17; + packed->Bot |= oddparity32((packed->Bot >> 1) & 0xFFF) & 1; + packed->Bot |= (evenparity32((packed->Bot >> 13) & 0xFFF) & 1) << 25; + return add_HID_header(packed); +} + +bool Unpack_H10301(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + if (packed->Length != 26) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = (packed->Bot >> 17) & 0xFF; + card->ParityValid = + (oddparity32((packed->Bot >> 1) & 0xFFF) == (packed->Bot & 1)) && + ((evenparity32((packed->Bot >> 13) & 0xFFF) & 1) == ((packed->Bot >> 25) & 1)); + return true; +} + +bool Pack_Tecom27(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x7FF) 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 = 27; + set_nonlinear_field(packed, card->FacilityCode, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + set_nonlinear_field(packed, card->CardNumber, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + return add_HID_header(packed); +} + +bool Unpack_Tecom27(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 27) return false; // Wrong length? Stop here. + + card->CardNumber = get_nonlinear_field(packed, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + card->FacilityCode = get_nonlinear_field(packed, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + return true; +} + +bool Pack_2804W(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFF) 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 = 28; + set_linear_field(packed, card->FacilityCode, 4, 8); + set_linear_field(packed, card->CardNumber, 12, 15); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26})) + , 2); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 13)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 0, 27)) + , 27); + return add_HID_header(packed); +} + +bool Unpack_2804W(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 28) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 4, 8); + card->CardNumber = get_linear_field(packed, 12, 15); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 13))) && + (get_bit_by_position(packed, 2) == oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26}))) && + (get_bit_by_position(packed, 27) == oddparity32(get_linear_field(packed, 0, 27))); + return true; +} + +bool Pack_ATSW30(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) 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 = 30; + set_linear_field(packed, card->FacilityCode, 1, 12); + set_linear_field(packed, card->CardNumber, 13, 16); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 12)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 13, 16)) + , 29); + return add_HID_header(packed); +} + +bool Unpack_ATSW30(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 30) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 12); + card->CardNumber = get_linear_field(packed, 13, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 12))) && + (get_bit_by_position(packed, 29) == oddparity32(get_linear_field(packed, 13, 16))); + return true; +} + +bool Pack_ADT31(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0F) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFFFF) 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 = 31; + set_linear_field(packed, card->FacilityCode, 1, 4); + set_linear_field(packed, card->CardNumber, 5, 23); + // Parity not known, but 4 bits are unused. + return add_HID_header(packed); +} + +bool Unpack_ADT31(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 31) return false; // Wrong length? Stop here. + card->FacilityCode = get_linear_field(packed, 1, 4); + card->CardNumber = get_linear_field(packed, 5, 23); + return true; +} + +bool Pack_Kastle(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 32; // Set number of bits + set_bit_by_position(packed, 1, 1); // Always 1 + set_linear_field(packed, card->IssueLevel, 2, 5); + set_linear_field(packed, card->FacilityCode, 7, 8); + set_linear_field(packed, card->CardNumber, 15, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31); + return add_HID_header(packed); +} + +bool Unpack_Kastle(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format + + card->IssueLevel = get_linear_field(packed, 2, 5); + card->FacilityCode = get_linear_field(packed, 7, 8); + card->CardNumber = get_linear_field(packed, 15, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17))); + return true; +} + +bool Pack_D10202(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x007F) return false; // Can't encode FC. + if (card->CardNumber > 0x00FFFFFF) 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 = 33; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 7); + set_linear_field(packed, card->CardNumber, 8, 24); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 16, 16)), 32); + return add_HID_header(packed); +} + +bool Unpack_D10202(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 33) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 8, 24); + card->FacilityCode = get_linear_field(packed, 1, 7); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 32) == oddparity32(get_linear_field(packed, 16, 16))); + return true; +} + +bool Pack_H10306(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + 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 + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x7FFF) << 17; + packed->Mid |= (card->FacilityCode & 0x8000) >> 15; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) << 1; + packed->Bot |= ( oddparity32(packed->Bot & 0x0001FFFE) & 1); + return add_HID_header(packed); +} + +bool Unpack_H10306(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = ((packed->Mid & 1) << 15) | ((packed->Bot >> 17) & 0xFF); + card->ParityValid = + ((evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) == ((packed->Mid >> 1) & 1)) && + ((oddparity32(packed->Bot & 0x0001FFFE) & 1) == ((packed->Bot & 1))); + return true; +} + +bool Pack_N10002(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) 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->CardNumber, 17, 16); + return add_HID_header(packed); +} + +bool Unpack_N10002(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 17, 16); + card->FacilityCode = get_linear_field(packed, 9, 8); + return true; +} + +bool Pack_C1k35s(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFFF) 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 = 35; // Set number of bits + packed->Bot |= (card->CardNumber & 0x000FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000007FF) << 21; + packed->Mid |= (card->FacilityCode & 0x00000800) >> 11; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 1; + packed->Bot |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 2; + return add_HID_header(packed); +} + +bool Unpack_C1k35s(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 35) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x000FFFFF; + card->FacilityCode = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 1) & 1)) && + ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 2) & 1)); + return true; +} + +bool Pack_H10320(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 99999999) 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 = 36; // Set number of bits + // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++){ + set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7-idx)) % 10, idx * 4, 4); + } + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}) + ), 32); + set_bit_by_position(packed, oddparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}) + ), 33); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}) + ), 34); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}) + ), 35); + return add_HID_header(packed); +} + +bool Unpack_H10320(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++){ + uint64_t val = get_linear_field(packed, idx * 4, 4); + if (val > 9){ + // Violation of BCD; Zero and exit. + card->CardNumber = 0; + return false; + } else { + card->CardNumber += val * pow(10, 7-idx); + } + } + card->ParityValid = + (get_bit_by_position(packed, 32) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}))) && + (get_bit_by_position(packed, 33) == oddparity32(get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}))) && + (get_bit_by_position(packed, 34) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}))) && + (get_bit_by_position(packed, 35) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}))); + return true; +} + +bool Pack_S12906(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->IssueLevel > 0x03) return false; // Can't encode IL. + if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 8); + set_linear_field(packed, card->IssueLevel, 9, 2); + set_linear_field(packed, card->CardNumber, 11, 24); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 17, 18)), 35); + return add_HID_header(packed); +} + +bool Unpack_S12906(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 8); + card->IssueLevel = get_linear_field(packed, 9, 2); + card->CardNumber = get_linear_field(packed, 11, 24); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 17, 18))); + return true; +} + +bool Pack_Sie36(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) 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 = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 18); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34})) + , 0); + set_bit_by_position(packed, + evenparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34})) + , 35); + return add_HID_header(packed); +} + +bool Unpack_Sie36(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 18); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34}))) && + (get_bit_by_position(packed, 35) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34}))); + return true; +} + +bool Pack_C15001(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0x000003FF) return false; // Can't encode OEM. + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->OEM, 1, 10); + set_linear_field(packed, card->FacilityCode, 11, 8); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 17)), 35); + return add_HID_header(packed); +} + +bool Unpack_C15001(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->OEM = get_linear_field(packed, 1, 10); + card->FacilityCode = get_linear_field(packed, 11, 8); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 18, 17))); + return true; +} + +bool Pack_H10302(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 0x00000007FFFFFFFF) 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 = 37; // Set number of bits + set_linear_field(packed, card->CardNumber, 1, 35); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 18)), 36); + return add_HID_header(packed); +} + +bool Unpack_H10302(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 37) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 1, 35); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && + (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); + return true; +} + +bool Pack_H10304(wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0007FFFF) 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 = 37; // Set number of bits + packed->Bot |= (card->CardNumber & 0x0007FFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x00000FFF) << 20; + packed->Mid |= (card->FacilityCode & 0x0000F000) >> 12; + packed->Mid |= (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) & 1) << 4; + packed->Bot |= ( oddparity32(packed->Bot & 0x0007FFFE) & 1); + return add_HID_header(packed); +} + +bool Unpack_H10304(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 37) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x0007FFFF; + card->FacilityCode = ((packed->Mid & 0xF) << 12) | ((packed->Bot >> 20)); + card->ParityValid = + (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) == ((packed->Mid >> 4) & 1)) && + (oddparity32( packed->Bot & 0x0007FFFE) == (packed->Bot & 1)); + return true; +} + +bool Pack_P10001(wiegand_card_t* card, wiegand_message_t* packed){ + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) 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 = 40; // Set number of bits + set_linear_field(packed, 0xF, 0, 4); + set_linear_field(packed, card->FacilityCode, 4, 12); + set_linear_field(packed, card->CardNumber, 16, 16); + set_linear_field(packed, + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + , 32, 8); + return add_HID_header(packed); +} + +bool Unpack_P10001(wiegand_message_t* packed, wiegand_card_t* card){ + + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 40) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 16, 16); + card->FacilityCode = get_linear_field(packed, 4, 12); + card->ParityValid = ( + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + ) == get_linear_field(packed, 32, 8); + return true; +} + +bool Pack_C1k48s(wiegand_card_t* card, wiegand_message_t* packed){ + + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x003FFFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x007FFFFF) 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 = 48; // Set number of bits + packed->Bot |= (card->CardNumber & 0x007FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000000FF) << 24; + packed->Mid |= (card->FacilityCode & 0x003FFF00) >> 8; + packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 14; + packed->Bot |= ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 15; + return add_HID_header(packed); +} + +bool Unpack_C1k48s(wiegand_message_t* packed, wiegand_card_t* card){ + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 48) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x007FFFFF; + card->FacilityCode = ((packed->Mid & 0x00003FFF) << 8) | ((packed->Bot >> 24)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 14) & 1)) && + ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 15) & 1)); + return true; +} + +static const cardformat_t FormatTable[] = { + {"H10301", Pack_H10301, Unpack_H10301, "HID H10301 26-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"Tecom27", Pack_Tecom27, Unpack_Tecom27, "Tecom 27-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"2804W", Pack_2804W, Unpack_2804W, "2804 Wiegand", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"ATSW30", Pack_ATSW30, Unpack_ATSW30, "ATS Wiegand 30-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"ADT31", Pack_ADT31, Unpack_ADT31, "HID ADT 31-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"Kastle", Pack_Kastle, Unpack_Kastle, "Kastle 32-bit", {1, 1, 1, 0, 1}}, // from @xilni; PR #23 on RfidResearchGroup/proxmark3 + {"D10202", Pack_D10202, Unpack_D10202, "HID D10202 33-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"H10306", Pack_H10306, Unpack_H10306, "HID H10306 34-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"N10002", Pack_N10002, Unpack_N10002, "HID N10002 34-bit", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"C1k35s", Pack_C1k35s, Unpack_C1k35s, "HID Corporate 1000 35-bit standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"C15001", Pack_C15001, Unpack_C15001, "HID KeySpan 36-bit", {1, 1, 0, 1, 1}}, // from Proxmark forums + {"S12906", Pack_S12906, Unpack_S12906, "HID Simplex 36-bit", {1, 1, 1, 0, 1}}, // from cardinfo.barkweb.com.au + {"Sie36", Pack_Sie36, Unpack_Sie36, "HID 36-bit Siemens", {1, 1, 0, 0, 1}}, // from cardinfo.barkweb.com.au + {"H10320", Pack_H10320, Unpack_H10320, "HID H10320 36-bit BCD", {1, 0, 0, 0, 1}}, // from Proxmark forums + {"H10302", Pack_H10302, Unpack_H10302, "HID H10302 37-bit huge ID", {1, 0, 0, 0, 1}}, // from Proxmark forums + {"H10304", Pack_H10304, Unpack_H10304, "HID H10304 37-bit", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit" }, // from cardinfo.barkweb.com.au + {"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit standard layout", {1, 1, 0, 0, 1}}, // imported from old pack/unpack + {NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array +}; + +void HIDListFormats(){ + if (FormatTable[0].Name == NULL) + return; + + PrintAndLogEx(NORMAL, "%-10s %s", "Name", "Description"); + PrintAndLogEx(NORMAL, "------------------------------------------------------------"); + + int i = 0; + while (FormatTable[i].Name) { + PrintAndLogEx(NORMAL, _YELLOW_("%-10s")" %-30s", FormatTable[i].Name, FormatTable[i].Descrp); + ++i; + } + PrintAndLogEx(NORMAL, ""); + return; +} + +cardformat_t HIDGetCardFormat(int idx){ + return FormatTable[idx]; +} + +int HIDFindCardFormat(const char *format) { + + if (FormatTable[0].Name == NULL) + return -1; + + int i = 0; + +// str_lower + + while (FormatTable[i].Name && strcmp(FormatTable[i].Name, format)) { + ++i; + } + + if (FormatTable[i].Name) + return i; + + return -1; +} + +bool HIDPack(int format_idx, wiegand_card_t* card, wiegand_message_t* packed){ + memset(packed, 0, sizeof(wiegand_message_t)); + + if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) + return false; + + return FormatTable[format_idx].Pack(card, packed); +} + +void HIDDisplayUnpackedCard(wiegand_card_t* card, const cardformat_t format){ + +/* + PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); + + if (format.Fields.hasFacilityCode) + PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); + + if (format.Fields.hasCardNumber) + PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); + + if (format.Fields.hasIssueLevel) + PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); + + if (format.Fields.hasOEMCode) + PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); + + if (format.Fields.hasParity) + PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); +*/ + + char s[80] = {0}; + if (format.Fields.hasFacilityCode) + snprintf(s, sizeof(s), "FC: %d", card->FacilityCode); + + if (format.Fields.hasCardNumber) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: %" PRIu64, card->CardNumber); + + if (format.Fields.hasIssueLevel) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel); + + if (format.Fields.hasOEMCode) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d",card->OEM); + + if (format.Fields.hasParity) + snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid"); + + PrintAndLogEx(SUCCESS, "%s [%s - %s]", s, format.Name, format.Descrp); +} + +bool HIDTryUnpack(wiegand_message_t* packed, bool ignore_parity){ + if (FormatTable[0].Name == NULL) + return false; + + bool result = false; + int i = 0; + wiegand_card_t card; + memset(&card, 0, sizeof(wiegand_card_t)); + + while (FormatTable[i].Name) { + if (FormatTable[i].Unpack(packed, &card)) { + if (ignore_parity || !FormatTable[i].Fields.hasParity || card.ParityValid) { + result = true; + HIDDisplayUnpackedCard(&card, FormatTable[i]); + } + } + ++i; + } + if ( result == false ) { + PrintAndLogEx(SUCCESS, "Unknown. Bit len %d", packed->Length); + } + + return result; +} diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h new file mode 100644 index 000000000..c904f789a --- /dev/null +++ b/client/wiegand_formats.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Wiegand format packing/unpacking routines +//----------------------------------------------------------------------------- + +#ifndef WIEGAND_FORMATS_H__ +#define WIEGAND_FORMATS_H__ + +#include // memset +#include +#include +#include +#include +#include +#include "cmddata.h" +#include "wiegand_formatutils.h" +#include "parity.h" // for parity +#include "ui.h" + +typedef struct { + bool hasCardNumber; + bool hasFacilityCode; + bool hasIssueLevel; + bool hasOEMCode; + bool hasParity; +} cardformatdescriptor_t; + +// Structure for defined Wiegand card formats available for packing/unpacking +typedef struct { + const char* Name; + bool (*Pack)(wiegand_card_t* card, wiegand_message_t* packed); + bool (*Unpack)(wiegand_message_t* packed, wiegand_card_t* card); + const char* Descrp; + cardformatdescriptor_t Fields; +} cardformat_t; + +void HIDListFormats(); +int HIDFindCardFormat(const char *format); +cardformat_t HIDGetCardFormat(int idx); +bool HIDPack(int FormatIndex, wiegand_card_t* card, wiegand_message_t* packed); +bool HIDTryUnpack(wiegand_message_t* packed, bool ignoreParity); + +#endif diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c new file mode 100644 index 000000000..dd3678daf --- /dev/null +++ b/client/wiegand_formatutils.c @@ -0,0 +1,185 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Wiegand card format packing/unpacking support functions +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include "wiegand_formatutils.h" +#include "ui.h" + +bool get_bit_by_position(wiegand_message_t* data, uint8_t pos){ + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + bool result = false; + if (pos > 95) + result = false; + else if (pos > 63) + result = (data->Top >> (pos - 64)) & 1; + else if (pos > 31) + result = (data->Mid >> (pos - 32)) & 1; + else + result = (data->Bot >> pos) & 1; + return result; +} +bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos){ + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + if (pos > 95) { + return false; + } else if (pos > 63) { + if (value) + data->Top |= (1 << (pos - 64)); + else + data->Top &= ~(1 << (pos - 64)); + return true; + } else if (pos > 31) { + if (value) + data->Mid |= (1 << (pos - 32)); + else + data->Mid &= ~(1 << (pos - 32)); + return true; + } else { + if (value) + data->Bot |= (1 << pos); + else + data->Bot &= ~(1 << pos); + return true; + } +} +/** + * Safeguard the data by doing a manual deep copy + * + * At the time of the initial writing, the struct does not contain pointers. That doesn't + * mean it won't eventually contain one, however. To prevent memory leaks and erroneous + * aliasing, perform the copy function manually instead. Hence, this function. + * + * If the definition of the wiegand_message struct changes, this function must also + * be updated to match. + */ +void message_datacopy(wiegand_message_t* src, wiegand_message_t* dest){ + dest->Bot = src->Bot; + dest->Mid = src->Mid; + dest->Top = src->Top; + dest->Length = src->Length; +} +/** + * + * Yes, this is horribly inefficient for linear data. + * The current code is a temporary measure to have a working function in place + * until all the bugs shaken from the block/chunk version of the code. + * + */ +uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length){ + uint64_t result = 0; + for (uint8_t i = 0; i < length; i++ ) { + result = (result << 1) | get_bit_by_position(data, firstBit + i); + } + return result; +} +bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length){ + wiegand_message_t tmpdata; + message_datacopy(data, &tmpdata); + bool result = true; + for (int i = 0; i < length; i++){ + result &= set_bit_by_position(&tmpdata, (value >> ((length - i) - 1)) & 1, firstBit + i); + } + if (result) + message_datacopy(&tmpdata, data); + + return result; +} + +uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits){ + uint64_t result = 0; + for (int i = 0; i < numBits; i++){ + result = (result << 1) | (get_bit_by_position(data, *(bits+i)) & 1); + } + return result; +} +bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits){ + + wiegand_message_t tmpdata; + message_datacopy(data, &tmpdata); + + bool result = true; + for (int i = 0; i < numBits; i++){ + result &= set_bit_by_position(&tmpdata, (value >> ((numBits - i) - 1)) & 1, *(bits + i)); + } + + if (result) + message_datacopy(&tmpdata, data); + + return result; +} + +uint8_t get_length_from_header(wiegand_message_t* data) { + uint8_t len = 0; + uint32_t hfmt = 0; // for calculating card length + + if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits + hfmt = data->Top & 0x000FFFFF; + len = 64; + } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits + hfmt = data->Mid & 0xFFFFFFC0; + len = 32; + } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; + hfmt = 0; + len = 37; + } else if ((data->Mid & 0x0000001F) > 0){ // 36-32 bits + printf("a\n"); + hfmt = data->Mid & 0x0000001F; + len = 32; + } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits + hfmt = data->Bot; + len = 0; + } else { + hfmt = data->Bot; + len = 0; + } + + while (hfmt > 1) { + hfmt >>= 1; + len++; + } + return len; +} + +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot){ + wiegand_message_t result; + memset(&result, 0, sizeof(wiegand_message_t)); + + result.Top = top; + result.Mid = mid; + result.Bot = bot; + result.Length = get_length_from_header(&result); + return result; +} + +bool add_HID_header(wiegand_message_t* data){ + if (data->Length > 84 || data->Length == 0) return false; // Invalid value + + if (data->Length >= 64){ + data->Top |= 1 << (data->Length - 64); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length > 37){ + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length == 37){ + // No header bits added to 37-bit cards + } else if (data->Length >= 32){ + data->Mid |= 0x20; // Bit 37; standard header + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + } else { + data->Mid |= 0x20; // Bit 37; standard header + data->Bot |= 1 << data->Length; // leading 1: start bit + } + return true; +} diff --git a/client/wiegand_formatutils.h b/client/wiegand_formatutils.h new file mode 100644 index 000000000..d9e74bcb2 --- /dev/null +++ b/client/wiegand_formatutils.h @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2018 grauerfuchs +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Weigand card format packing/unpacking support functions +//----------------------------------------------------------------------------- + +#ifndef WIEGAND_FORMATUTILS_H__ +#define WIEGAND_FORMATUTILS_H__ + +#include +#include +#include + +// Structure for packed wiegand messages +// Always align lowest value (last transmitted) bit to ordinal position 0 (lowest valued bit bottom) +typedef struct { + uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) + uint32_t Top; // Bits in x<<64 positions + uint32_t Mid; // Bits in x<<32 positions + uint32_t Bot; // Lowest ordinal positions +} wiegand_message_t; + +// Structure for unpacked wiegand card, like HID prox +typedef struct { + uint32_t FacilityCode; + uint64_t CardNumber; + uint32_t IssueLevel; + uint32_t OEM; + bool ParityValid; // Only valid for responses +} wiegand_card_t; + +bool get_bit_by_position(wiegand_message_t* data, uint8_t pos); +bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos); + +uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length); +bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length); + +uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits); +bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits); + +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot); + +bool add_HID_header(wiegand_message_t* data); + +#endif From a33965f1dd4a5a7e09732c06ae462b0a905d4f4f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:22:45 +0200 Subject: [PATCH 11/33] textual --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c062f6f83..783b596c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add `wiegand list/encode/decode` - wiegand format manipulation. Adapted to fit here. (@grauerfuchs) - Add `lf t55xx protect` - sets password and enables password protection on t55x7 tag (@iceman1001) - Chg `lf t55xx wipe` - now accepts user provided configuration block (@iceman1001) - Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox) From fa36018befe3ef3a294386a70da1a9b68413d328 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:42:59 +0200 Subject: [PATCH 12/33] also compile... --- client/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index 6fee6eae8..dcbb23110 100644 --- a/client/Makefile +++ b/client/Makefile @@ -230,6 +230,7 @@ CMDSRCS = crapto1/crapto1.c \ cmdflashmemspiffs.c \ cmdsmartcard.c \ cmdusart.c \ + cmdwiegand.c \ cmdparser.c \ cmdmain.c \ pm3_binlib.c \ @@ -238,7 +239,9 @@ CMDSRCS = crapto1/crapto1.c \ pm3_bitlib.c \ cmdcrc.c \ bucketsort.c \ - flash.c + flash.c \ + wiegand_formats.c \ + wiegand_formatutils.c cpu_arch = $(shell uname -m) ifneq ($(findstring 86, $(cpu_arch)), ) From 2626c31d3dad8c3dac0a9344d75c9029eb9e0abd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 19:43:55 +0200 Subject: [PATCH 13/33] links --- client/cmdlfhid.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index d4d52fa9f..2059066dc 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -5,7 +5,17 @@ // at your option, any later version. See the LICENSE.txt file for the text of // the license. //----------------------------------------------------------------------------- -// Low frequency HID commands +// Low frequency HID commands (known) +// +// Useful resources: +// RF interface, programming a T55x7 clone, 26-bit HID H10301 encoding: +// http://www.proxmark.org/files/Documents/125%20kHz%20-%20HID/HID_format_example.pdf +// +// "Understanding Card Data Formats" +// https://www.hidglobal.com/sites/default/files/hid-understanding_card_data_formats-wp-en.pdf +// +// "What Format Do You Need?" +// https://www.hidglobal.com/sites/default/files/resource_files/hid-prox-br-en.pdf //----------------------------------------------------------------------------- #include "cmdlfhid.h" From bb051df683aa855d404ee4ab1ddf9aa72d1076dc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Sep 2019 20:15:29 +0200 Subject: [PATCH 14/33] ..memset --- client/wiegand_formats.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h index c904f789a..102c2b0cb 100644 --- a/client/wiegand_formats.h +++ b/client/wiegand_formats.h @@ -11,7 +11,7 @@ #ifndef WIEGAND_FORMATS_H__ #define WIEGAND_FORMATS_H__ -#include // memset +#include // memset #include #include #include From 895410aec04fe510c682deb56cd617fdb78769e5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:47:12 +0200 Subject: [PATCH 15/33] style --- client/cmdlfnedap.c | 6 +- client/cmdlfnoralsy.c | 6 +- client/cmdlfpresco.c | 6 +- client/cmdlfpyramid.c | 8 +- client/cmdlfviking.c | 8 +- client/cmdlfvisa2000.c | 10 +- client/cmdwiegand.c | 30 +- client/util.c | 4 +- client/util.h | 2 +- client/wiegand_formats.c | 1026 +++++++++++++++++----------------- client/wiegand_formats.h | 24 +- client/wiegand_formatutils.c | 266 ++++----- client/wiegand_formatutils.h | 32 +- 13 files changed, 714 insertions(+), 714 deletions(-) diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c index ec2837d7a..b186a1354 100644 --- a/client/cmdlfnedap.c +++ b/client/cmdlfnedap.c @@ -480,15 +480,15 @@ int CmdLFNedapClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); else { PrintAndLogEx(NORMAL, ""); diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c index 2d9481782..fe469720b 100644 --- a/client/cmdlfnoralsy.c +++ b/client/cmdlfnoralsy.c @@ -179,15 +179,15 @@ static int CmdNoralsyClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c index 39587c5ea..f563e2ef8 100644 --- a/client/cmdlfpresco.c +++ b/client/cmdlfpresco.c @@ -146,7 +146,7 @@ static int CmdPrescoClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } @@ -155,9 +155,9 @@ static int CmdPrescoClone(const char *Cmd) { } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c index 90e5c23d7..216e0834e 100644 --- a/client/cmdlfpyramid.c +++ b/client/cmdlfpyramid.c @@ -256,18 +256,18 @@ static int CmdPyramidClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 45fe9ffb6..9bbbeaa7e 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -90,14 +90,14 @@ static int CmdVikingClone(const char *Cmd) { uint8_t blocks[8]; } PACKED payload; payload.Q5 = Q5; - + num_to_bytes(rawID, 8, &payload.blocks[0]); PrintAndLogEx(INFO, "Preparing to clone Viking tag - ID " _YELLOW_("%08X")" raw " _YELLOW_("%s"), id, sprint_hex(payload.blocks, sizeof(payload.blocks))); - + clearCommandBuffer(); - - SendCommandNG(CMD_LF_VIKING_CLONE, (uint8_t*)&payload, sizeof(payload)); + + SendCommandNG(CMD_LF_VIKING_CLONE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_LF_VIKING_CLONE, &resp, T55XX_WRITE_TIMEOUT)) { PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c index f23a7c5a8..9f80a830d 100644 --- a/client/cmdlfvisa2000.c +++ b/client/cmdlfvisa2000.c @@ -169,7 +169,7 @@ static int CmdVisa2kClone(const char *Cmd) { uint8_t res = 0; PacketResponseNG resp; - + // fast push mode conn.block_after_ACK = true; for (uint8_t i = 0; i < 4; i++) { @@ -193,15 +193,15 @@ static int CmdVisa2kClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - - if ( res == 0 ) + + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdwiegand.c b/client/cmdwiegand.c index 0b567d514..8c1b5e8cb 100644 --- a/client/cmdwiegand.c +++ b/client/cmdwiegand.c @@ -20,7 +20,7 @@ #include "cmdhflist.h" // annotations #include "wiegand_formats.h" #include "wiegand_formatutils.h" -#include "util.h" +#include "util.h" static int CmdHelp(const char *Cmd); @@ -52,18 +52,18 @@ static int usage_wiegand_decode() { return PM3_SUCCESS; } -void PrintTagId(wiegand_message_t *packed){ +void PrintTagId(wiegand_message_t *packed) { if (packed->Top != 0) { PrintAndLogEx(SUCCESS, "Card ID: %X%08X%08X", - (uint32_t)packed->Top, - (uint32_t)packed->Mid, - (uint32_t)packed->Bot) - ; + (uint32_t)packed->Top, + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; } else { PrintAndLogEx(SUCCESS, "Card ID: %X%08X", - (uint32_t)packed->Mid, - (uint32_t)packed->Bot) - ; + (uint32_t)packed->Mid, + (uint32_t)packed->Bot) + ; } } @@ -88,7 +88,7 @@ int CmdWiegandEncode(const char *Cmd) { int format_idx = -1; char format[16] = {0}; - + wiegand_card_t data; memset(&data, 0, sizeof(wiegand_card_t)); @@ -133,12 +133,12 @@ int CmdWiegandEncode(const char *Cmd) { wiegand_message_t packed; memset(&packed, 0, sizeof(wiegand_message_t)); - + if (HIDPack(format_idx, &data, &packed) == false) { PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); return PM3_ESOFT; } - + PrintTagId(&packed); return PM3_SUCCESS; } @@ -152,7 +152,7 @@ int CmdWiegandDecode(const char *Cmd) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { uint32_t strlen = param_getlength(Cmd, cmdp); strlen++; // null termin - if ( strlen > 2 ) { + if (strlen > 2) { char *s = calloc(strlen, sizeof(uint8_t)); param_getstr(Cmd, cmdp, s, strlen); hexstring_to_u96(&top, &mid, &bot, s); @@ -176,11 +176,11 @@ int CmdWiegandDecode(const char *Cmd) { } if (gothex == false) errors = true; - + if (errors || cmdp < 1) return usage_wiegand_decode(); wiegand_message_t packed = initialize_message_object(top, mid, bot); - + HIDTryUnpack(&packed, ignore_parity); return PM3_SUCCESS; } diff --git a/client/util.c b/client/util.c index f74605562..da1b5d0e2 100644 --- a/client/util.c +++ b/client/util.c @@ -885,10 +885,10 @@ char *strmcopy(const char *buf) { * * Returns the number of nibbles (4 bits) entered. */ -int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str) { +int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str) { int n = 0, i = 0; - while (sscanf(&str[i++], "%1x", &n ) == 1) { + while (sscanf(&str[i++], "%1x", &n) == 1) { *hi2 = (*hi2 << 4) | (*hi >> 28); *hi = (*hi << 4) | (*lo >> 28); *lo = (*lo << 4) | (n & 0xf); diff --git a/client/util.h b/client/util.h index df69493d2..7d6c6460e 100644 --- a/client/util.h +++ b/client/util.h @@ -98,5 +98,5 @@ void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); char *strmcopy(const char *buf); -int hexstring_to_u96(uint32_t* hi2, uint32_t* hi, uint32_t* lo, const char* str); +int hexstring_to_u96(uint32_t *hi2, uint32_t *hi, uint32_t *lo, const char *str); #endif diff --git a/client/wiegand_formats.c b/client/wiegand_formats.c index 7228abd82..4e2541cbd 100644 --- a/client/wiegand_formats.c +++ b/client/wiegand_formats.c @@ -9,574 +9,574 @@ //----------------------------------------------------------------------------- #include "wiegand_formats.h" -bool Pack_H10301(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFF) 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 = 26; // Set number of bits - packed->Bot |= (card->CardNumber & 0xFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0xFF) << 17; - packed->Bot |= oddparity32((packed->Bot >> 1) & 0xFFF) & 1; - packed->Bot |= (evenparity32((packed->Bot >> 13) & 0xFFF) & 1) << 25; - return add_HID_header(packed); +bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) 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 = 26; // Set number of bits + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0xFF) << 17; + packed->Bot |= oddparity32((packed->Bot >> 1) & 0xFFF) & 1; + packed->Bot |= (evenparity32((packed->Bot >> 13) & 0xFFF) & 1) << 25; + return add_HID_header(packed); } -bool Unpack_H10301(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - if (packed->Length != 26) return false; // Wrong length? Stop here. - - card->CardNumber = (packed->Bot >> 1) & 0xFFFF; - card->FacilityCode = (packed->Bot >> 17) & 0xFF; - card->ParityValid = - (oddparity32((packed->Bot >> 1) & 0xFFF) == (packed->Bot & 1)) && - ((evenparity32((packed->Bot >> 13) & 0xFFF) & 1) == ((packed->Bot >> 25) & 1)); - return true; +bool Unpack_H10301(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + if (packed->Length != 26) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = (packed->Bot >> 17) & 0xFF; + card->ParityValid = + (oddparity32((packed->Bot >> 1) & 0xFFF) == (packed->Bot & 1)) && + ((evenparity32((packed->Bot >> 13) & 0xFFF) & 1) == ((packed->Bot >> 25) & 1)); + return true; } -bool Pack_Tecom27(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x7FF) 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 = 27; - set_nonlinear_field(packed, card->FacilityCode, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); - set_nonlinear_field(packed, card->CardNumber, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); - return add_HID_header(packed); +bool Pack_Tecom27(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x7FF) 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 = 27; + set_nonlinear_field(packed, card->FacilityCode, 10, (uint8_t[]) {15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + set_nonlinear_field(packed, card->CardNumber, 16, (uint8_t[]) {0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + return add_HID_header(packed); } -bool Unpack_Tecom27(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 27) return false; // Wrong length? Stop here. - - card->CardNumber = get_nonlinear_field(packed, 16, (uint8_t[]){0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); - card->FacilityCode = get_nonlinear_field(packed, 10, (uint8_t[]){15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); - return true; +bool Unpack_Tecom27(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 27) return false; // Wrong length? Stop here. + + card->CardNumber = get_nonlinear_field(packed, 16, (uint8_t[]) {0, 1, 13, 12, 9, 26, 20, 16, 17, 21, 25, 7, 8, 11, 4, 5}); + card->FacilityCode = get_nonlinear_field(packed, 10, (uint8_t[]) {15, 19, 24, 23, 22, 18, 6, 10, 14, 3, 2}); + return true; } -bool Pack_2804W(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. - if (card->CardNumber > 0x7FFF) 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 = 28; - set_linear_field(packed, card->FacilityCode, 4, 8); - set_linear_field(packed, card->CardNumber, 12, 15); - set_bit_by_position(packed, - oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26})) +bool Pack_2804W(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0FF) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFF) 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 = 28; + set_linear_field(packed, card->FacilityCode, 4, 8); + set_linear_field(packed, card->CardNumber, 12, 15); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]) {4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26})) , 2); - set_bit_by_position(packed, - evenparity32(get_linear_field(packed, 1, 13)) - , 0); - set_bit_by_position(packed, - oddparity32(get_linear_field(packed, 0, 27)) - , 27); - return add_HID_header(packed); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 13)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 0, 27)) + , 27); + return add_HID_header(packed); } -bool Unpack_2804W(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 28) return false; // Wrong length? Stop here. - - card->FacilityCode = get_linear_field(packed, 4, 8); - card->CardNumber = get_linear_field(packed, 12, 15); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 13))) && - (get_bit_by_position(packed, 2) == oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]){4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26}))) && +bool Unpack_2804W(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 28) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 4, 8); + card->CardNumber = get_linear_field(packed, 12, 15); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 13))) && + (get_bit_by_position(packed, 2) == oddparity32(get_nonlinear_field(packed, 16, (uint8_t[]) {4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26}))) && (get_bit_by_position(packed, 27) == oddparity32(get_linear_field(packed, 0, 27))); - return true; + return true; } -bool Pack_ATSW30(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFFF) 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 = 30; - set_linear_field(packed, card->FacilityCode, 1, 12); - set_linear_field(packed, card->CardNumber, 13, 16); - set_bit_by_position(packed, - evenparity32(get_linear_field(packed, 1, 12)) - , 0); - set_bit_by_position(packed, - oddparity32(get_linear_field(packed, 13, 16)) - , 29); - return add_HID_header(packed); +bool Pack_ATSW30(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFFF) 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 = 30; + set_linear_field(packed, card->FacilityCode, 1, 12); + set_linear_field(packed, card->CardNumber, 13, 16); + set_bit_by_position(packed, + evenparity32(get_linear_field(packed, 1, 12)) + , 0); + set_bit_by_position(packed, + oddparity32(get_linear_field(packed, 13, 16)) + , 29); + return add_HID_header(packed); } -bool Unpack_ATSW30(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 30) return false; // Wrong length? Stop here. - - card->FacilityCode = get_linear_field(packed, 1, 12); - card->CardNumber = get_linear_field(packed, 13, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 12))) && - (get_bit_by_position(packed, 29) == oddparity32(get_linear_field(packed, 13, 16))); - return true; +bool Unpack_ATSW30(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 30) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 12); + card->CardNumber = get_linear_field(packed, 13, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 12))) && + (get_bit_by_position(packed, 29) == oddparity32(get_linear_field(packed, 13, 16))); + return true; } -bool Pack_ADT31(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0F) return false; // Can't encode FC. - if (card->CardNumber > 0x7FFFFF) 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 = 31; - set_linear_field(packed, card->FacilityCode, 1, 4); - set_linear_field(packed, card->CardNumber, 5, 23); - // Parity not known, but 4 bits are unused. - return add_HID_header(packed); +bool Pack_ADT31(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x0F) return false; // Can't encode FC. + if (card->CardNumber > 0x7FFFFF) 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 = 31; + set_linear_field(packed, card->FacilityCode, 1, 4); + set_linear_field(packed, card->CardNumber, 5, 23); + // Parity not known, but 4 bits are unused. + return add_HID_header(packed); } -bool Unpack_ADT31(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 31) return false; // Wrong length? Stop here. - card->FacilityCode = get_linear_field(packed, 1, 4); - card->CardNumber = get_linear_field(packed, 5, 23); - return true; +bool Unpack_ADT31(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 31) return false; // Wrong length? Stop here. + card->FacilityCode = get_linear_field(packed, 1, 4); + card->CardNumber = get_linear_field(packed, 5, 23); + return true; } -bool Pack_Kastle(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. - if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits. - if (card->OEM > 0) return false; // Not used in this format - - packed->Length = 32; // Set number of bits - set_bit_by_position(packed, 1, 1); // Always 1 - set_linear_field(packed, card->IssueLevel, 2, 5); - set_linear_field(packed, card->FacilityCode, 7, 8); - set_linear_field(packed, card->CardNumber, 15, 16); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31); - return add_HID_header(packed); +bool Pack_Kastle(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x00FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0x001F) return false; // IL is only 5 bits. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 32; // Set number of bits + set_bit_by_position(packed, 1, 1); // Always 1 + set_linear_field(packed, card->IssueLevel, 2, 5); + set_linear_field(packed, card->FacilityCode, 7, 8); + set_linear_field(packed, card->CardNumber, 15, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 14, 17)), 31); + return add_HID_header(packed); } -bool Unpack_Kastle(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 32) return false; // Wrong length? Stop here. - if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format - - card->IssueLevel = get_linear_field(packed, 2, 5); - card->FacilityCode = get_linear_field(packed, 7, 8); - card->CardNumber = get_linear_field(packed, 15, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && - (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17))); - return true; +bool Unpack_Kastle(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 32) return false; // Wrong length? Stop here. + if (get_bit_by_position(packed, 1) != 1) return false; // Always 1 in this format + + card->IssueLevel = get_linear_field(packed, 2, 5); + card->FacilityCode = get_linear_field(packed, 7, 8); + card->CardNumber = get_linear_field(packed, 15, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 31) == oddparity32(get_linear_field(packed, 14, 17))); + return true; } -bool Pack_D10202(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x007F) return false; // Can't encode FC. - if (card->CardNumber > 0x00FFFFFF) 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 = 33; // Set number of bits - set_linear_field(packed, card->FacilityCode, 1, 7); - set_linear_field(packed, card->CardNumber, 8, 24); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 16, 16)), 32); - return add_HID_header(packed); +bool Pack_D10202(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x007F) return false; // Can't encode FC. + if (card->CardNumber > 0x00FFFFFF) 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 = 33; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 7); + set_linear_field(packed, card->CardNumber, 8, 24); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 16)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 16, 16)), 32); + return add_HID_header(packed); } -bool Unpack_D10202(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 33) return false; // Wrong length? Stop here. - - card->CardNumber = get_linear_field(packed, 8, 24); - card->FacilityCode = get_linear_field(packed, 1, 7); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && - (get_bit_by_position(packed, 32) == oddparity32(get_linear_field(packed, 16, 16))); - return true; +bool Unpack_D10202(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 33) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 8, 24); + card->FacilityCode = get_linear_field(packed, 1, 7); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 16))) && + (get_bit_by_position(packed, 32) == oddparity32(get_linear_field(packed, 16, 16))); + return true; } -bool Pack_H10306(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - 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 - packed->Bot |= (card->CardNumber & 0xFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x7FFF) << 17; - packed->Mid |= (card->FacilityCode & 0x8000) >> 15; - packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) << 1; - packed->Bot |= ( oddparity32(packed->Bot & 0x0001FFFE) & 1); - return add_HID_header(packed); +bool Pack_H10306(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + 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 + packed->Bot |= (card->CardNumber & 0xFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x7FFF) << 17; + packed->Mid |= (card->FacilityCode & 0x8000) >> 15; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) << 1; + packed->Bot |= (oddparity32(packed->Bot & 0x0001FFFE) & 1); + return add_HID_header(packed); } -bool Unpack_H10306(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 34) return false; // Wrong length? Stop here. - - card->CardNumber = (packed->Bot >> 1) & 0xFFFF; - card->FacilityCode = ((packed->Mid & 1) << 15) | ((packed->Bot >> 17) & 0xFF); - card->ParityValid = - ((evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) == ((packed->Mid >> 1) & 1)) && - ((oddparity32(packed->Bot & 0x0001FFFE) & 1) == ((packed->Bot & 1))); - return true; +bool Unpack_H10306(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0xFFFF; + card->FacilityCode = ((packed->Mid & 1) << 15) | ((packed->Bot >> 17) & 0xFF); + card->ParityValid = + ((evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xFFFE0000)) & 1) == ((packed->Mid >> 1) & 1)) && + ((oddparity32(packed->Bot & 0x0001FFFE) & 1) == ((packed->Bot & 1))); + return true; } -bool Pack_N10002(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFF) 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->CardNumber, 17, 16); - return add_HID_header(packed); +bool Pack_N10002(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) 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->CardNumber, 17, 16); + return add_HID_header(packed); } -bool Unpack_N10002(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 34) return false; // Wrong length? Stop here. - - card->CardNumber = get_linear_field(packed, 17, 16); - card->FacilityCode = get_linear_field(packed, 9, 8); - return true; +bool Unpack_N10002(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 34) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 17, 16); + card->FacilityCode = get_linear_field(packed, 9, 8); + return true; } -bool Pack_C1k35s(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. - if (card->CardNumber > 0xFFFFF) 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 +bool Pack_C1k35s(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); - packed->Length = 35; // Set number of bits - packed->Bot |= (card->CardNumber & 0x000FFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x000007FF) << 21; - packed->Mid |= (card->FacilityCode & 0x00000800) >> 11; - packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 1; - packed->Bot |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) & 1); - packed->Mid |= ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 2; - return add_HID_header(packed); + if (card->FacilityCode > 0xFFF) return false; // Can't encode FC. + if (card->CardNumber > 0xFFFFF) 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 = 35; // Set number of bits + packed->Bot |= (card->CardNumber & 0x000FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000007FF) << 21; + packed->Mid |= (card->FacilityCode & 0x00000800) >> 11; + packed->Mid |= (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 1; + packed->Bot |= (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 2; + return add_HID_header(packed); } -bool Unpack_C1k35s(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 35) return false; // Wrong length? Stop here. - - card->CardNumber = (packed->Bot >> 1) & 0x000FFFFF; - card->FacilityCode = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); - card->ParityValid = - (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 1) & 1)) && - ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && - ( oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 2) & 1)); - return true; +bool Unpack_C1k35s(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 35) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x000FFFFF; + card->FacilityCode = ((packed->Mid & 1) << 11) | ((packed->Bot >> 21)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00000001) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 1) & 1)) && + (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + (oddparity32((packed->Mid & 0x00000003) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 2) & 1)); + return true; } -bool Pack_H10320(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) - if (card->CardNumber > 99999999) 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 = 36; // Set number of bits - // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. - for (uint32_t idx = 0; idx < 8; idx++){ - set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7-idx)) % 10, idx * 4, 4); - } - set_bit_by_position(packed, evenparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}) - ), 32); - set_bit_by_position(packed, oddparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}) - ), 33); - set_bit_by_position(packed, evenparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}) - ), 34); - set_bit_by_position(packed, evenparity32( - get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}) - ), 35); - return add_HID_header(packed); -} +bool Pack_H10320(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); -bool Unpack_H10320(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 36) return false; // Wrong length? Stop here. - - // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. - for (uint32_t idx = 0; idx < 8; idx++){ - uint64_t val = get_linear_field(packed, idx * 4, 4); - if (val > 9){ - // Violation of BCD; Zero and exit. - card->CardNumber = 0; - return false; - } else { - card->CardNumber += val * pow(10, 7-idx); + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 99999999) 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 = 36; // Set number of bits + // This card is BCD-encoded rather than binary. Set the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++) { + set_linear_field(packed, (uint64_t)(card->CardNumber / pow(10, 7 - idx)) % 10, idx * 4, 4); } - } - card->ParityValid = - (get_bit_by_position(packed, 32) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){0, 4, 8, 12, 16, 20, 24, 28}))) && - (get_bit_by_position(packed, 33) == oddparity32(get_nonlinear_field(packed, 8, (uint8_t[]){1, 5, 9, 13, 17, 21, 25, 29}))) && - (get_bit_by_position(packed, 34) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){2, 6, 10, 14, 18, 22, 28, 30}))) && - (get_bit_by_position(packed, 35) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]){3, 7, 11, 15, 19, 23, 29, 31}))); - return true; + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {0, 4, 8, 12, 16, 20, 24, 28}) + ), 32); + set_bit_by_position(packed, oddparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {1, 5, 9, 13, 17, 21, 25, 29}) + ), 33); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {2, 6, 10, 14, 18, 22, 28, 30}) + ), 34); + set_bit_by_position(packed, evenparity32( + get_nonlinear_field(packed, 8, (uint8_t[]) {3, 7, 11, 15, 19, 23, 29, 31}) + ), 35); + return add_HID_header(packed); } -bool Pack_S12906(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0xFF) return false; // Can't encode FC. - if (card->IssueLevel > 0x03) return false; // Can't encode IL. - if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. - if (card->OEM > 0) return false; // Not used in this format +bool Unpack_H10320(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); - packed->Length = 36; // Set number of bits - set_linear_field(packed, card->FacilityCode, 1, 8); - set_linear_field(packed, card->IssueLevel, 9, 2); - set_linear_field(packed, card->CardNumber, 11, 24); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 1, 17)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 17, 18)), 35); - return add_HID_header(packed); + if (packed->Length != 36) return false; // Wrong length? Stop here. + + // This card is BCD-encoded rather than binary. Get the 4-bit groups independently. + for (uint32_t idx = 0; idx < 8; idx++) { + uint64_t val = get_linear_field(packed, idx * 4, 4); + if (val > 9) { + // Violation of BCD; Zero and exit. + card->CardNumber = 0; + return false; + } else { + card->CardNumber += val * pow(10, 7 - idx); + } + } + card->ParityValid = + (get_bit_by_position(packed, 32) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {0, 4, 8, 12, 16, 20, 24, 28}))) && + (get_bit_by_position(packed, 33) == oddparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {1, 5, 9, 13, 17, 21, 25, 29}))) && + (get_bit_by_position(packed, 34) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {2, 6, 10, 14, 18, 22, 28, 30}))) && + (get_bit_by_position(packed, 35) == evenparity32(get_nonlinear_field(packed, 8, (uint8_t[]) {3, 7, 11, 15, 19, 23, 29, 31}))); + return true; } -bool Unpack_S12906(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 36) return false; // Wrong length? Stop here. - - card->FacilityCode = get_linear_field(packed, 1, 8); - card->IssueLevel = get_linear_field(packed, 9, 2); - card->CardNumber = get_linear_field(packed, 11, 24); - card->ParityValid = - (get_bit_by_position(packed, 0) == oddparity32(get_linear_field(packed, 1, 17))) && - (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 17, 18))); - return true; +bool Pack_S12906(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0xFF) return false; // Can't encode FC. + if (card->IssueLevel > 0x03) return false; // Can't encode IL. + if (card->CardNumber > 0x00FFFFFF) return false; // Can't encode CN. + if (card->OEM > 0) return false; // Not used in this format + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 8); + set_linear_field(packed, card->IssueLevel, 9, 2); + set_linear_field(packed, card->CardNumber, 11, 24); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 17, 18)), 35); + return add_HID_header(packed); } -bool Pack_Sie36(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. - if (card->CardNumber > 0x0000FFFF) 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 = 36; // Set number of bits - set_linear_field(packed, card->FacilityCode, 1, 18); - set_linear_field(packed, card->CardNumber, 19, 16); - set_bit_by_position(packed, - oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34})) - , 0); - set_bit_by_position(packed, - evenparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34})) - , 35); - return add_HID_header(packed); +bool Unpack_S12906(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 8); + card->IssueLevel = get_linear_field(packed, 9, 2); + card->CardNumber = get_linear_field(packed, 11, 24); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 17, 18))); + return true; } -bool Unpack_Sie36(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); +bool Pack_Sie36(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); - if (packed->Length != 36) return false; // Wrong length? Stop here. + if (card->FacilityCode > 0x0003FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) 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 - card->FacilityCode = get_linear_field(packed, 1, 18); - card->CardNumber = get_linear_field(packed, 19, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34}))) && - (get_bit_by_position(packed, 35) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]){1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34}))); - return true; + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->FacilityCode, 1, 18); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, + oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34})) + , 0); + set_bit_by_position(packed, + evenparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34})) + , 35); + return add_HID_header(packed); } -bool Pack_C15001(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. - if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. - if (card->IssueLevel > 0) return false; // Not used in this format - if (card->OEM > 0x000003FF) return false; // Can't encode OEM. - - packed->Length = 36; // Set number of bits - set_linear_field(packed, card->OEM, 1, 10); - set_linear_field(packed, card->FacilityCode, 11, 8); - set_linear_field(packed, card->CardNumber, 19, 16); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 17)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 17)), 35); - return add_HID_header(packed); +bool Unpack_Sie36(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->FacilityCode = get_linear_field(packed, 1, 18); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25, 27, 28, 30, 31, 33, 34}))) && + (get_bit_by_position(packed, 35) == oddparity32(get_nonlinear_field(packed, 23, (uint8_t[]) {1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34}))); + return true; } -bool Unpack_C15001(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 36) return false; // Wrong length? Stop here. - - card->OEM = get_linear_field(packed, 1, 10); - card->FacilityCode = get_linear_field(packed, 11, 8); - card->CardNumber = get_linear_field(packed, 19, 16); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 17))) && - (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 18, 17))); - return true; +bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0x000000FF) return false; // Can't encode FC. + if (card->CardNumber > 0x0000FFFF) return false; // Can't encode CN. + if (card->IssueLevel > 0) return false; // Not used in this format + if (card->OEM > 0x000003FF) return false; // Can't encode OEM. + + packed->Length = 36; // Set number of bits + set_linear_field(packed, card->OEM, 1, 10); + set_linear_field(packed, card->FacilityCode, 11, 8); + set_linear_field(packed, card->CardNumber, 19, 16); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 17)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 17)), 35); + return add_HID_header(packed); } -bool Pack_H10302(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) - if (card->CardNumber > 0x00000007FFFFFFFF) 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 +bool Unpack_C15001(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); - packed->Length = 37; // Set number of bits - set_linear_field(packed, card->CardNumber, 1, 35); - set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)), 0); - set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 18)), 36); - return add_HID_header(packed); + if (packed->Length != 36) return false; // Wrong length? Stop here. + + card->OEM = get_linear_field(packed, 1, 10); + card->FacilityCode = get_linear_field(packed, 11, 8); + card->CardNumber = get_linear_field(packed, 19, 16); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 17))) && + (get_bit_by_position(packed, 35) == oddparity32(get_linear_field(packed, 18, 17))); + return true; } -bool Unpack_H10302(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); - - if (packed->Length != 37) return false; // Wrong length? Stop here. - - card->CardNumber = get_linear_field(packed, 1, 35); - card->ParityValid = - (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && - (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); - return true; +bool Pack_H10302(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (card->FacilityCode > 0) return false; // Can't encode FC. (none in this format) + if (card->CardNumber > 0x00000007FFFFFFFF) 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 = 37; // Set number of bits + set_linear_field(packed, card->CardNumber, 1, 35); + set_bit_by_position(packed, evenparity32(get_linear_field(packed, 1, 18)), 0); + set_bit_by_position(packed, oddparity32(get_linear_field(packed, 18, 18)), 36); + return add_HID_header(packed); } -bool Pack_H10304(wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. - if (card->CardNumber > 0x0007FFFF) 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 = 37; // Set number of bits - packed->Bot |= (card->CardNumber & 0x0007FFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x00000FFF) << 20; - packed->Mid |= (card->FacilityCode & 0x0000F000) >> 12; - packed->Mid |= (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) & 1) << 4; - packed->Bot |= ( oddparity32(packed->Bot & 0x0007FFFE) & 1); - return add_HID_header(packed); +bool Unpack_H10302(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 37) return false; // Wrong length? Stop here. + + card->CardNumber = get_linear_field(packed, 1, 35); + card->ParityValid = + (get_bit_by_position(packed, 0) == evenparity32(get_linear_field(packed, 1, 18))) && + (get_bit_by_position(packed, 36) == oddparity32(get_linear_field(packed, 18, 18))); + return true; } -bool Unpack_H10304(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); +bool Pack_H10304(wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); - if (packed->Length != 37) return false; // Wrong length? Stop here. + if (card->FacilityCode > 0x0000FFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x0007FFFF) 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 - card->CardNumber = (packed->Bot >> 1) & 0x0007FFFF; - card->FacilityCode = ((packed->Mid & 0xF) << 12) | ((packed->Bot >> 20)); - card->ParityValid = - (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) == ((packed->Mid >> 4) & 1)) && - (oddparity32( packed->Bot & 0x0007FFFE) == (packed->Bot & 1)); - return true; + packed->Length = 37; // Set number of bits + packed->Bot |= (card->CardNumber & 0x0007FFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x00000FFF) << 20; + packed->Mid |= (card->FacilityCode & 0x0000F000) >> 12; + packed->Mid |= (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) & 1) << 4; + packed->Bot |= (oddparity32(packed->Bot & 0x0007FFFE) & 1); + return add_HID_header(packed); } -bool Pack_P10001(wiegand_card_t* card, wiegand_message_t* packed){ +bool Unpack_H10304(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); - memset(packed, 0, sizeof(wiegand_message_t)); + if (packed->Length != 37) return false; // Wrong length? Stop here. - if (card->FacilityCode > 0xFFF) 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 = 40; // Set number of bits - set_linear_field(packed, 0xF, 0, 4); - set_linear_field(packed, card->FacilityCode, 4, 12); - set_linear_field(packed, card->CardNumber, 16, 16); - set_linear_field(packed, - get_linear_field(packed, 0, 8) ^ - get_linear_field(packed, 8, 8) ^ - get_linear_field(packed, 16, 8) ^ - get_linear_field(packed, 24, 8) - , 32, 8); - return add_HID_header(packed); + card->CardNumber = (packed->Bot >> 1) & 0x0007FFFF; + card->FacilityCode = ((packed->Mid & 0xF) << 12) | ((packed->Bot >> 20)); + card->ParityValid = + (evenparity32((packed->Mid & 0x0000000F) ^ (packed->Bot & 0xFFFC0000)) == ((packed->Mid >> 4) & 1)) && + (oddparity32(packed->Bot & 0x0007FFFE) == (packed->Bot & 1)); + return true; } -bool Unpack_P10001(wiegand_message_t* packed, wiegand_card_t* card){ +bool Pack_P10001(wiegand_card_t *card, wiegand_message_t *packed) { - memset(card, 0, sizeof(wiegand_card_t)); + memset(packed, 0, sizeof(wiegand_message_t)); - if (packed->Length != 40) return false; // Wrong length? Stop here. + if (card->FacilityCode > 0xFFF) 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 - card->CardNumber = get_linear_field(packed, 16, 16); - card->FacilityCode = get_linear_field(packed, 4, 12); - card->ParityValid = ( - get_linear_field(packed, 0, 8) ^ - get_linear_field(packed, 8, 8) ^ - get_linear_field(packed, 16, 8) ^ - get_linear_field(packed, 24, 8) - ) == get_linear_field(packed, 32, 8); - return true; + packed->Length = 40; // Set number of bits + set_linear_field(packed, 0xF, 0, 4); + set_linear_field(packed, card->FacilityCode, 4, 12); + set_linear_field(packed, card->CardNumber, 16, 16); + set_linear_field(packed, + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + , 32, 8); + return add_HID_header(packed); } -bool Pack_C1k48s(wiegand_card_t* card, wiegand_message_t* packed){ +bool Unpack_P10001(wiegand_message_t *packed, wiegand_card_t *card) { - memset(packed, 0, sizeof(wiegand_message_t)); + memset(card, 0, sizeof(wiegand_card_t)); - if (card->FacilityCode > 0x003FFFFF) return false; // Can't encode FC. - if (card->CardNumber > 0x007FFFFF) 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 + if (packed->Length != 40) return false; // Wrong length? Stop here. - packed->Length = 48; // Set number of bits - packed->Bot |= (card->CardNumber & 0x007FFFFF) << 1; - packed->Bot |= (card->FacilityCode & 0x000000FF) << 24; - packed->Mid |= (card->FacilityCode & 0x003FFF00) >> 8; - packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 14; - packed->Bot |= ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) & 1); - packed->Mid |= ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 15; - return add_HID_header(packed); + card->CardNumber = get_linear_field(packed, 16, 16); + card->FacilityCode = get_linear_field(packed, 4, 12); + card->ParityValid = ( + get_linear_field(packed, 0, 8) ^ + get_linear_field(packed, 8, 8) ^ + get_linear_field(packed, 16, 8) ^ + get_linear_field(packed, 24, 8) + ) == get_linear_field(packed, 32, 8); + return true; } -bool Unpack_C1k48s(wiegand_message_t* packed, wiegand_card_t* card){ - memset(card, 0, sizeof(wiegand_card_t)); +bool Pack_C1k48s(wiegand_card_t *card, wiegand_message_t *packed) { - if (packed->Length != 48) return false; // Wrong length? Stop here. + memset(packed, 0, sizeof(wiegand_message_t)); - card->CardNumber = (packed->Bot >> 1) & 0x007FFFFF; - card->FacilityCode = ((packed->Mid & 0x00003FFF) << 8) | ((packed->Bot >> 24)); - card->ParityValid = - (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 14) & 1)) && - ( oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && - ( oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 15) & 1)); - return true; + if (card->FacilityCode > 0x003FFFFF) return false; // Can't encode FC. + if (card->CardNumber > 0x007FFFFF) 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 = 48; // Set number of bits + packed->Bot |= (card->CardNumber & 0x007FFFFF) << 1; + packed->Bot |= (card->FacilityCode & 0x000000FF) << 24; + packed->Mid |= (card->FacilityCode & 0x003FFF00) >> 8; + packed->Mid |= (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) & 1) << 14; + packed->Bot |= (oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) & 1); + packed->Mid |= (oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) & 1) << 15; + return add_HID_header(packed); +} + +bool Unpack_C1k48s(wiegand_message_t *packed, wiegand_card_t *card) { + memset(card, 0, sizeof(wiegand_card_t)); + + if (packed->Length != 48) return false; // Wrong length? Stop here. + + card->CardNumber = (packed->Bot >> 1) & 0x007FFFFF; + card->FacilityCode = ((packed->Mid & 0x00003FFF) << 8) | ((packed->Bot >> 24)); + card->ParityValid = + (evenparity32((packed->Mid & 0x00001B6D) ^ (packed->Bot & 0xB6DB6DB6)) == ((packed->Mid >> 14) & 1)) && + (oddparity32((packed->Mid & 0x000036DB) ^ (packed->Bot & 0x6DB6DB6C)) == ((packed->Bot >> 0) & 1)) && + (oddparity32((packed->Mid & 0x00007FFF) ^ (packed->Bot & 0xFFFFFFFF)) == ((packed->Mid >> 15) & 1)); + return true; } static const cardformat_t FormatTable[] = { @@ -601,7 +601,7 @@ static const cardformat_t FormatTable[] = { {NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array }; -void HIDListFormats(){ +void HIDListFormats() { if (FormatTable[0].Name == NULL) return; @@ -617,58 +617,58 @@ void HIDListFormats(){ return; } -cardformat_t HIDGetCardFormat(int idx){ +cardformat_t HIDGetCardFormat(int idx) { return FormatTable[idx]; } int HIDFindCardFormat(const char *format) { - if (FormatTable[0].Name == NULL) + if (FormatTable[0].Name == NULL) return -1; - + int i = 0; // str_lower - + while (FormatTable[i].Name && strcmp(FormatTable[i].Name, format)) { ++i; } if (FormatTable[i].Name) return i; - + return -1; } -bool HIDPack(int format_idx, wiegand_card_t* card, wiegand_message_t* packed){ - memset(packed, 0, sizeof(wiegand_message_t)); - - if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) - return false; - - return FormatTable[format_idx].Pack(card, packed); +bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed) { + memset(packed, 0, sizeof(wiegand_message_t)); + + if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0]))) + return false; + + return FormatTable[format_idx].Pack(card, packed); } -void HIDDisplayUnpackedCard(wiegand_card_t* card, const cardformat_t format){ +void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) { -/* - PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); + /* + PrintAndLogEx(SUCCESS, " Format: %s (%s)", format.Name, format.Descrp); - if (format.Fields.hasFacilityCode) - PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); + if (format.Fields.hasFacilityCode) + PrintAndLogEx(SUCCESS, "Facility Code: %d",card->FacilityCode); - if (format.Fields.hasCardNumber) - PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); + if (format.Fields.hasCardNumber) + PrintAndLogEx(SUCCESS, " Card Number: %d",card->CardNumber); - if (format.Fields.hasIssueLevel) - PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); + if (format.Fields.hasIssueLevel) + PrintAndLogEx(SUCCESS, " Issue Level: %d",card->IssueLevel); - if (format.Fields.hasOEMCode) - PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); + if (format.Fields.hasOEMCode) + PrintAndLogEx(SUCCESS, " OEM Code: %d",card->OEM); - if (format.Fields.hasParity) - PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); -*/ + if (format.Fields.hasParity) + PrintAndLogEx(SUCCESS, " Parity: %s",card->ParityValid ? "Valid" : "Invalid"); + */ char s[80] = {0}; if (format.Fields.hasFacilityCode) @@ -681,23 +681,23 @@ void HIDDisplayUnpackedCard(wiegand_card_t* card, const cardformat_t format){ snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel); if (format.Fields.hasOEMCode) - snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d",card->OEM); + snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d", card->OEM); if (format.Fields.hasParity) snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid"); - + PrintAndLogEx(SUCCESS, "%s [%s - %s]", s, format.Name, format.Descrp); } -bool HIDTryUnpack(wiegand_message_t* packed, bool ignore_parity){ - if (FormatTable[0].Name == NULL) +bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity) { + if (FormatTable[0].Name == NULL) return false; bool result = false; int i = 0; wiegand_card_t card; memset(&card, 0, sizeof(wiegand_card_t)); - + while (FormatTable[i].Name) { if (FormatTable[i].Unpack(packed, &card)) { if (ignore_parity || !FormatTable[i].Fields.hasParity || card.ParityValid) { @@ -707,9 +707,9 @@ bool HIDTryUnpack(wiegand_message_t* packed, bool ignore_parity){ } ++i; } - if ( result == false ) { + if (result == false) { PrintAndLogEx(SUCCESS, "Unknown. Bit len %d", packed->Length); } - + return result; } diff --git a/client/wiegand_formats.h b/client/wiegand_formats.h index 102c2b0cb..e3aca4b9c 100644 --- a/client/wiegand_formats.h +++ b/client/wiegand_formats.h @@ -23,26 +23,26 @@ #include "ui.h" typedef struct { - bool hasCardNumber; - bool hasFacilityCode; - bool hasIssueLevel; - bool hasOEMCode; - bool hasParity; + bool hasCardNumber; + bool hasFacilityCode; + bool hasIssueLevel; + bool hasOEMCode; + bool hasParity; } cardformatdescriptor_t; // Structure for defined Wiegand card formats available for packing/unpacking typedef struct { - const char* Name; - bool (*Pack)(wiegand_card_t* card, wiegand_message_t* packed); - bool (*Unpack)(wiegand_message_t* packed, wiegand_card_t* card); - const char* Descrp; - cardformatdescriptor_t Fields; + const char *Name; + bool (*Pack)(wiegand_card_t *card, wiegand_message_t *packed); + bool (*Unpack)(wiegand_message_t *packed, wiegand_card_t *card); + const char *Descrp; + cardformatdescriptor_t Fields; } cardformat_t; void HIDListFormats(); int HIDFindCardFormat(const char *format); cardformat_t HIDGetCardFormat(int idx); -bool HIDPack(int FormatIndex, wiegand_card_t* card, wiegand_message_t* packed); -bool HIDTryUnpack(wiegand_message_t* packed, bool ignoreParity); +bool HIDPack(int FormatIndex, wiegand_card_t *card, wiegand_message_t *packed); +bool HIDTryUnpack(wiegand_message_t *packed, bool ignoreParity); #endif diff --git a/client/wiegand_formatutils.c b/client/wiegand_formatutils.c index dd3678daf..a4529955d 100644 --- a/client/wiegand_formatutils.c +++ b/client/wiegand_formatutils.c @@ -15,171 +15,171 @@ #include "wiegand_formatutils.h" #include "ui.h" -bool get_bit_by_position(wiegand_message_t* data, uint8_t pos){ - if (pos >= data->Length) return false; - pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. - bool result = false; - if (pos > 95) - result = false; - else if (pos > 63) - result = (data->Top >> (pos - 64)) & 1; - else if (pos > 31) - result = (data->Mid >> (pos - 32)) & 1; - else - result = (data->Bot >> pos) & 1; - return result; +bool get_bit_by_position(wiegand_message_t *data, uint8_t pos) { + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + bool result = false; + if (pos > 95) + result = false; + else if (pos > 63) + result = (data->Top >> (pos - 64)) & 1; + else if (pos > 31) + result = (data->Mid >> (pos - 32)) & 1; + else + result = (data->Bot >> pos) & 1; + return result; } -bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos){ - if (pos >= data->Length) return false; - pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. - if (pos > 95) { - return false; - } else if (pos > 63) { - if (value) - data->Top |= (1 << (pos - 64)); - else - data->Top &= ~(1 << (pos - 64)); - return true; - } else if (pos > 31) { - if (value) - data->Mid |= (1 << (pos - 32)); - else - data->Mid &= ~(1 << (pos - 32)); - return true; - } else { - if (value) - data->Bot |= (1 << pos); - else - data->Bot &= ~(1 << pos); - return true; - } +bool set_bit_by_position(wiegand_message_t *data, bool value, uint8_t pos) { + if (pos >= data->Length) return false; + pos = (data->Length - pos) - 1; // invert ordering; Indexing goes from 0 to 1. Subtract 1 for weight of bit. + if (pos > 95) { + return false; + } else if (pos > 63) { + if (value) + data->Top |= (1 << (pos - 64)); + else + data->Top &= ~(1 << (pos - 64)); + return true; + } else if (pos > 31) { + if (value) + data->Mid |= (1 << (pos - 32)); + else + data->Mid &= ~(1 << (pos - 32)); + return true; + } else { + if (value) + data->Bot |= (1 << pos); + else + data->Bot &= ~(1 << pos); + return true; + } } /** * Safeguard the data by doing a manual deep copy - * + * * At the time of the initial writing, the struct does not contain pointers. That doesn't * mean it won't eventually contain one, however. To prevent memory leaks and erroneous * aliasing, perform the copy function manually instead. Hence, this function. - * + * * If the definition of the wiegand_message struct changes, this function must also * be updated to match. */ -void message_datacopy(wiegand_message_t* src, wiegand_message_t* dest){ - dest->Bot = src->Bot; - dest->Mid = src->Mid; - dest->Top = src->Top; - dest->Length = src->Length; +void message_datacopy(wiegand_message_t *src, wiegand_message_t *dest) { + dest->Bot = src->Bot; + dest->Mid = src->Mid; + dest->Top = src->Top; + dest->Length = src->Length; } /** * - * Yes, this is horribly inefficient for linear data. + * Yes, this is horribly inefficient for linear data. * The current code is a temporary measure to have a working function in place * until all the bugs shaken from the block/chunk version of the code. * */ -uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length){ - uint64_t result = 0; - for (uint8_t i = 0; i < length; i++ ) { - result = (result << 1) | get_bit_by_position(data, firstBit + i); - } - return result; +uint64_t get_linear_field(wiegand_message_t *data, uint8_t firstBit, uint8_t length) { + uint64_t result = 0; + for (uint8_t i = 0; i < length; i++) { + result = (result << 1) | get_bit_by_position(data, firstBit + i); + } + return result; } -bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length){ - wiegand_message_t tmpdata; - message_datacopy(data, &tmpdata); - bool result = true; - for (int i = 0; i < length; i++){ - result &= set_bit_by_position(&tmpdata, (value >> ((length - i) - 1)) & 1, firstBit + i); - } - if (result) - message_datacopy(&tmpdata, data); - - return result; -} - -uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits){ - uint64_t result = 0; - for (int i = 0; i < numBits; i++){ - result = (result << 1) | (get_bit_by_position(data, *(bits+i)) & 1); - } - return result; -} -bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits){ - +bool set_linear_field(wiegand_message_t *data, uint64_t value, uint8_t firstBit, uint8_t length) { wiegand_message_t tmpdata; message_datacopy(data, &tmpdata); - bool result = true; - for (int i = 0; i < numBits; i++){ - result &= set_bit_by_position(&tmpdata, (value >> ((numBits - i) - 1)) & 1, *(bits + i)); + for (int i = 0; i < length; i++) { + result &= set_bit_by_position(&tmpdata, (value >> ((length - i) - 1)) & 1, firstBit + i); } - if (result) message_datacopy(&tmpdata, data); return result; } -uint8_t get_length_from_header(wiegand_message_t* data) { - uint8_t len = 0; - uint32_t hfmt = 0; // for calculating card length - - if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits - hfmt = data->Top & 0x000FFFFF; - len = 64; - } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits - hfmt = data->Mid & 0xFFFFFFC0; - len = 32; - } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; - hfmt = 0; - len = 37; - } else if ((data->Mid & 0x0000001F) > 0){ // 36-32 bits - printf("a\n"); - hfmt = data->Mid & 0x0000001F; - len = 32; - } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits - hfmt = data->Bot; - len = 0; - } else { - hfmt = data->Bot; - len = 0; - } +uint64_t get_nonlinear_field(wiegand_message_t *data, uint8_t numBits, uint8_t *bits) { + uint64_t result = 0; + for (int i = 0; i < numBits; i++) { + result = (result << 1) | (get_bit_by_position(data, *(bits + i)) & 1); + } + return result; +} +bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBits, uint8_t *bits) { - while (hfmt > 1) { - hfmt >>= 1; - len++; - } - return len; + wiegand_message_t tmpdata; + message_datacopy(data, &tmpdata); + + bool result = true; + for (int i = 0; i < numBits; i++) { + result &= set_bit_by_position(&tmpdata, (value >> ((numBits - i) - 1)) & 1, *(bits + i)); + } + + if (result) + message_datacopy(&tmpdata, data); + + return result; } -wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot){ - wiegand_message_t result; - memset(&result, 0, sizeof(wiegand_message_t)); - - result.Top = top; - result.Mid = mid; - result.Bot = bot; - result.Length = get_length_from_header(&result); - return result; +uint8_t get_length_from_header(wiegand_message_t *data) { + uint8_t len = 0; + uint32_t hfmt = 0; // for calculating card length + + if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits + hfmt = data->Top & 0x000FFFFF; + len = 64; + } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits + hfmt = data->Mid & 0xFFFFFFC0; + len = 32; + } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; + hfmt = 0; + len = 37; + } else if ((data->Mid & 0x0000001F) > 0) { // 36-32 bits + printf("a\n"); + hfmt = data->Mid & 0x0000001F; + len = 32; + } else if (data->Top == 0 && data->Mid == 0) { //< 32 bits + hfmt = data->Bot; + len = 0; + } else { + hfmt = data->Bot; + len = 0; + } + + while (hfmt > 1) { + hfmt >>= 1; + len++; + } + return len; } -bool add_HID_header(wiegand_message_t* data){ - if (data->Length > 84 || data->Length == 0) return false; // Invalid value +wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot) { + wiegand_message_t result; + memset(&result, 0, sizeof(wiegand_message_t)); - if (data->Length >= 64){ - data->Top |= 1 << (data->Length - 64); // leading 1: start bit - data->Top |= 0x09e00000; // Extended-length header - } else if (data->Length > 37){ - data->Mid |= 1 << (data->Length - 32); // leading 1: start bit - data->Top |= 0x09e00000; // Extended-length header - } else if (data->Length == 37){ - // No header bits added to 37-bit cards - } else if (data->Length >= 32){ - data->Mid |= 0x20; // Bit 37; standard header - data->Mid |= 1 << (data->Length - 32); // leading 1: start bit - } else { - data->Mid |= 0x20; // Bit 37; standard header - data->Bot |= 1 << data->Length; // leading 1: start bit - } - return true; + result.Top = top; + result.Mid = mid; + result.Bot = bot; + result.Length = get_length_from_header(&result); + return result; +} + +bool add_HID_header(wiegand_message_t *data) { + if (data->Length > 84 || data->Length == 0) return false; // Invalid value + + if (data->Length >= 64) { + data->Top |= 1 << (data->Length - 64); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length > 37) { + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + data->Top |= 0x09e00000; // Extended-length header + } else if (data->Length == 37) { + // No header bits added to 37-bit cards + } else if (data->Length >= 32) { + data->Mid |= 0x20; // Bit 37; standard header + data->Mid |= 1 << (data->Length - 32); // leading 1: start bit + } else { + data->Mid |= 0x20; // Bit 37; standard header + data->Bot |= 1 << data->Length; // leading 1: start bit + } + return true; } diff --git a/client/wiegand_formatutils.h b/client/wiegand_formatutils.h index d9e74bcb2..534bea4f3 100644 --- a/client/wiegand_formatutils.h +++ b/client/wiegand_formatutils.h @@ -18,32 +18,32 @@ // Structure for packed wiegand messages // Always align lowest value (last transmitted) bit to ordinal position 0 (lowest valued bit bottom) typedef struct { - uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) - uint32_t Top; // Bits in x<<64 positions - uint32_t Mid; // Bits in x<<32 positions - uint32_t Bot; // Lowest ordinal positions + uint8_t Length; // Number of encoded bits in wiegand message (excluding headers and preamble) + uint32_t Top; // Bits in x<<64 positions + uint32_t Mid; // Bits in x<<32 positions + uint32_t Bot; // Lowest ordinal positions } wiegand_message_t; // Structure for unpacked wiegand card, like HID prox typedef struct { - uint32_t FacilityCode; - uint64_t CardNumber; - uint32_t IssueLevel; - uint32_t OEM; - bool ParityValid; // Only valid for responses + uint32_t FacilityCode; + uint64_t CardNumber; + uint32_t IssueLevel; + uint32_t OEM; + bool ParityValid; // Only valid for responses } wiegand_card_t; -bool get_bit_by_position(wiegand_message_t* data, uint8_t pos); -bool set_bit_by_position(wiegand_message_t* data, bool value, uint8_t pos); +bool get_bit_by_position(wiegand_message_t *data, uint8_t pos); +bool set_bit_by_position(wiegand_message_t *data, bool value, uint8_t pos); -uint64_t get_linear_field(wiegand_message_t* data, uint8_t firstBit, uint8_t length); -bool set_linear_field(wiegand_message_t* data, uint64_t value, uint8_t firstBit, uint8_t length); +uint64_t get_linear_field(wiegand_message_t *data, uint8_t firstBit, uint8_t length); +bool set_linear_field(wiegand_message_t *data, uint64_t value, uint8_t firstBit, uint8_t length); -uint64_t get_nonlinear_field(wiegand_message_t* data, uint8_t numBits, uint8_t* bits); -bool set_nonlinear_field(wiegand_message_t* data, uint64_t value, uint8_t numBits, uint8_t* bits); +uint64_t get_nonlinear_field(wiegand_message_t *data, uint8_t numBits, uint8_t *bits); +bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBits, uint8_t *bits); wiegand_message_t initialize_message_object(uint32_t top, uint32_t mid, uint32_t bot); -bool add_HID_header(wiegand_message_t* data); +bool add_HID_header(wiegand_message_t *data); #endif From ffd03dadaae9b2a7fa3f0571c266b498e282f49d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:48:32 +0200 Subject: [PATCH 16/33] style --- client/cmdlfawid.c | 6 +++--- client/cmdlffdx.c | 6 +++--- client/cmdlfguard.c | 6 +++--- client/cmdlfindala.c | 32 ++++++++++++++++---------------- client/cmdlfio.c | 10 +++++----- client/cmdlfjablotron.c | 10 +++++----- client/cmdlfkeri.c | 10 +++++----- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 934335c64..056d95af4 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -442,15 +442,15 @@ static int CmdAWIDClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 233783b33..85529609d 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -323,15 +323,15 @@ static int CmdFdxClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 036597f0f..fe00d1187 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -210,15 +210,15 @@ static int CmdGuardClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index da13766db..673ed1438 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -444,7 +444,7 @@ static int CmdIndalaSim(const char *Cmd) { static int CmdIndalaClone(const char *Cmd) { bool isLongUid = false; - uint32_t blocks[8] = {0}; + uint32_t blocks[8] = {0}; uint8_t max = 0; uint8_t data[7 * 4]; @@ -470,17 +470,17 @@ static int CmdIndalaClone(const char *Cmd) { CLIGetHexWithReturn(2, data, &datalen); CLIParserFree(); -/* - //TODO add selection of chip for Q5 or T55x7 - - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) - // T5567WriteBlock(0x603E10E2,0); - - // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; - //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) - // T5567WriteBlock(0x603E1042,0); -*/ + /* + //TODO add selection of chip for Q5 or T55x7 + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK2 | 7 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) + // T5567WriteBlock(0x603E10E2,0); + + // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; + //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) + // T5567WriteBlock(0x603E1042,0); + */ if (isLongUid) { // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) @@ -495,7 +495,7 @@ static int CmdIndalaClone(const char *Cmd) { blocks[7] = bytes_to_num(data + 24, 4); max = 8; } else { - // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) + // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag with RawID %s", sprint_hex(data, datalen)); blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); blocks[1] = bytes_to_num(data, 4); @@ -530,15 +530,15 @@ static int CmdIndalaClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); return PM3_SUCCESS; diff --git a/client/cmdlfio.c b/client/cmdlfio.c index b71302ea9..7b3e777c6 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -269,7 +269,7 @@ static int CmdIOProxClone(const char *Cmd) { } uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - + if (tolower(param_getchar(Cmd, 3) == 'q')) blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; @@ -304,17 +304,17 @@ static int CmdIOProxClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c index 919610293..13a1d6e1f 100644 --- a/client/cmdlfjablotron.c +++ b/client/cmdlfjablotron.c @@ -197,17 +197,17 @@ static int CmdJablotronClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; + res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c index 9f01f2f7f..49d3c2a33 100644 --- a/client/cmdlfkeri.c +++ b/client/cmdlfkeri.c @@ -186,17 +186,17 @@ static int CmdKeriClone(const char *Cmd) { if (i == 0) { SetConfigWithBlock0(blocks[0]); - if ( t55xxAquireAndCompareBlock0(false, 0, blocks[0], false) ) + if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false)) continue; } - + if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false) - res++; + res++; } - if ( res == 0 ) + if (res == 0) PrintAndLogEx(SUCCESS, "Success writing to tag"); - + return PM3_SUCCESS; } From 21a7de38b840ae5b8d044380885ed3fdad5ec771 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:54:34 +0200 Subject: [PATCH 17/33] style --- armsrc/lfops.c | 18 ++--- client/cmdlft55xx.c | 153 ++++++++++++++++++------------------ client/cmdlft55xx.h | 4 +- client/fido/additional_ca.c | 14 ++-- client/scripting.c | 4 +- 5 files changed, 96 insertions(+), 97 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 57b2b75cd..ab0467c85 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -918,7 +918,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo */ // special start of frame marker containing invalid Manchester bit sequences - uint8_t bits[8+8*2+84*2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; + uint8_t bits[8 + 8 * 2 + 84 * 2] = { 0, 0, 0, 1, 1, 1, 0, 1 }; uint8_t bitlen = 0; uint16_t n = 8; @@ -928,9 +928,9 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo DbpString("Tags can only have 84 bits."); return; } - bitlen = 8+8*2+84*2; + bitlen = 8 + 8 * 2 + 84 * 2; hi2 |= 0x9E00000; // 9E: long format identifier - manchesterEncodeUint32(hi2, 16+12, bits, &n); + manchesterEncodeUint32(hi2, 16 + 12, bits, &n); manchesterEncodeUint32(hi, 32, bits, &n); manchesterEncodeUint32(lo, 32, bits, &n); } else { @@ -939,7 +939,7 @@ void CmdHIDsimTAGEx(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); return; } - bitlen = 8+44*2; + bitlen = 8 + 44 * 2; manchesterEncodeUint32(hi, 12, bits, &n); manchesterEncodeUint32(lo, 32, bits, &n); } @@ -2038,14 +2038,14 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { // clone viking tag to T55xx void CopyVikingtoT55xx(uint8_t *blocks, uint8_t Q5) { - + uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), 0, 0}; - if (Q5) + if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; - + data[1] = bytes_to_num(blocks, 4); - data[2] = bytes_to_num(blocks +4, 4); - + data[2] = bytes_to_num(blocks + 4, 4); + // Program the data blocks for supplied ID and the block 0 config WriteT55xx(data, 0, 3); LED_D_OFF(); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 88c6b3162..a41cd9f40 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -44,7 +44,7 @@ //static uint8_t bit_rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; // Default configuration -t55xx_conf_block_t config = { +t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, @@ -52,7 +52,7 @@ t55xx_conf_block_t config = { .Q5 = false, .usepwd = false, .downlink_mode = refFixedBit - }; +}; t55xx_conf_block_t Get_t55xx_Config() { return config; @@ -86,7 +86,7 @@ static int usage_t55xx_config() { PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as Q5(T5555) chip instead of T55x7"); PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); + print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx config d FSK - FSK demodulation"); @@ -331,17 +331,17 @@ static int usage_t55xx_protect() { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " lf t55xx protect n 01020304 - sets new password to 01020304"); - PrintAndLogEx(NORMAL, " lf t55xx protect p 11223344 - use pwd 11223344 to set newpwd to 00000000"); + PrintAndLogEx(NORMAL, " lf t55xx protect p 11223344 - use pwd 11223344 to set newpwd to 00000000"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } static int CmdHelp(const char *Cmd); -static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password ) { +static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password) { PrintAndLogEx(INFO, "Checking current configuration"); - + bool testmode = false; uint32_t block0 = 0; @@ -350,25 +350,25 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass PrintAndLogEx(WARNING, "Failed to read block0, use `p` password parameter?"); return false; } - + if (GetT55xxBlockData(&block0) == false) return false; - bool isPwdBitAlreadySet = (block0 >> (32-28) & 1); + bool isPwdBitAlreadySet = (block0 >> (32 - 28) & 1); if (isPwdBitAlreadySet) { PrintAndLogEx(INFO, "PWD bit is already set"); usepwd = true; } - // set / clear pwd bit + // set / clear pwd bit if (lock) { block0 |= 1 << 4; } else { block0 &= ~(1 << 4); } - // write new password - if ( t55xxWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, testmode, password, downlink_mode, new_password ) != PM3_SUCCESS ) { + // write new password + if (t55xxWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, testmode, password, downlink_mode, new_password) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to write new password"); return false; } else { @@ -377,22 +377,22 @@ static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t pass // validate new password uint32_t curr_password = (isPwdBitAlreadySet) ? new_password : password; - + if (t55xxVerifyWrite(T55x7_PWD_BLOCK, T55x7_PAGE0, usepwd, override, curr_password, downlink_mode, new_password) == false) { PrintAndLogEx(WARNING, "Failed to validate the password write. aborting."); return false; } else { PrintAndLogEx(SUCCESS, "Validated new password"); } - + // write config - if ( t55xxWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, testmode, curr_password, downlink_mode, block0 ) != PM3_SUCCESS ) { + if (t55xxWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, usepwd, testmode, curr_password, downlink_mode, block0) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to write modified configuration block %08X", block0); return false; } else { PrintAndLogEx(SUCCESS, "Wrote modified configuration block"); } - + // validate new config. If all went well, card should now demand pwd, hence override = 0. override = 0; if (t55xxVerifyWrite(T55x7_CONFIGURATION_BLOCK, T55x7_PAGE0, true, override, new_password, downlink_mode, block0) == false) { @@ -409,34 +409,34 @@ bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_ if (verbose) PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); - - for ( uint8_t m = 0; m < 4; m++) { + + for (uint8_t m = 0; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) { continue; } - + if (DecodeT55xxBlock() == false) { continue; } - - for( uint16_t i = 0; DemodBufferLen - 32; i++) { + + for (uint16_t i = 0; DemodBufferLen - 32; i++) { uint32_t tmp = PackBits(i, 32, DemodBuffer); - if ( tmp == known_block0 ) { + if (tmp == known_block0) { config.offset = i; config.downlink_mode = m; return true; } } } - return false; + return false; } bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose) { if (verbose) PrintAndLogEx(INFO, "Block0 write detected, running `detect` to see if validation is possible"); - - for ( uint8_t m = 0; m < 4; m++) { + + for (uint8_t m = 0; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; @@ -446,14 +446,14 @@ bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, config.downlink_mode = m; return true; } - return false; + return false; } bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data) { uint32_t read_data = 0; - - if (downlink_mode == 0xFF) + + if (downlink_mode == 0xFF) downlink_mode = config.downlink_mode; int res = T55xxReadBlockEx(block, page1, usepwd, override, password, downlink_mode, false); @@ -462,15 +462,15 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, if (GetT55xxBlockData(&read_data) == false) return false; - } else if ( res == PM3_EWRONGANSVER) { - - // could't decode. Lets see if this was a block 0 write and try read/detect it auto. + } else if (res == PM3_EWRONGANSVER) { + + // could't decode. Lets see if this was a block 0 write and try read/detect it auto. // this messes up with ppls config.. if (block == 0 && page1 == false) { if (t55xxAquireAndDetect(usepwd, password, data, true) == false) return false; - + return t55xxVerifyWrite(block, page1, usepwd, 2, password, config.downlink_mode, data); } } @@ -479,7 +479,7 @@ bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, } int t55xxWrite(uint8_t block, bool page1, bool usepwd, bool testMode, uint32_t password, uint8_t downlink_mode, uint32_t data) { - + uint8_t flags; flags = (usepwd) ? 0x1 : 0; flags |= (page1) ? 0x2 : 0; @@ -534,16 +534,16 @@ void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5) { bool pwd = (bool)((block0 >> (32 - 28)) & 0x01); bool sst = (bool)((block0 >> (32 - 29)) & 0x01); bool inv = (bool)((block0 >> (32 - 31)) & 0x01); - + config.modulation = datamod; config.bitrate = dbr; - + // FSK1a, FSK2a - if ( datamod == DEMOD_FSK1a || datamod == DEMOD_FSK2a || datamod == DEMOD_BIa ) + if (datamod == DEMOD_FSK1a || datamod == DEMOD_FSK2a || datamod == DEMOD_BIa) config.inverted = 1; else config.inverted = inv; - + config.Q5 = Q5; config.ST = sst; config.usepwd = pwd; @@ -564,7 +564,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { bool errors = false; uint32_t block0 = 0; bool gotconf = false; - + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { char tmp = tolower(param_getchar(Cmd, cmdp)); switch (tmp) { @@ -679,8 +679,8 @@ static int CmdT55xxSetConfig(const char *Cmd) { //Validations if (errors) return usage_t55xx_config(); - if ( gotconf ) { - SetConfigWithBlock0Ex(block0, config.offset, config.Q5); + if (gotconf) { + SetConfigWithBlock0Ex(block0, config.offset, config.Q5); } else { config.block0 = 0; } @@ -928,9 +928,9 @@ static int CmdT55xxDetect(const char *Cmd) { return PM3_ESOFT; if (useGB == false) { - - if ( try_all_dl_modes ) { - + + if (try_all_dl_modes) { + for (uint8_t m = downlink_mode; m < 4; m++) { if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, m) == false) continue; @@ -942,7 +942,7 @@ static int CmdT55xxDetect(const char *Cmd) { break; } } else { - + if (AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } @@ -951,10 +951,10 @@ static int CmdT55xxDetect(const char *Cmd) { } else { found = tryDetectModulation(downlink_mode, T55XX_PrintConfig); } - + if (found == false) PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'")); - + return PM3_SUCCESS; } @@ -1146,13 +1146,13 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa if (hits > 1) { PrintAndLogEx(SUCCESS, "Found [%d] possible matches for modulation.", hits); for (int i = 0; i < hits; ++i) { - + bool wanted = false; if (wanted_conf > 0) wanted = (wanted_conf == tests[i].block0); - + retval = testKnownConfigBlock(tests[i].block0); - if (retval || wanted ) { + if (retval || wanted) { PrintAndLogEx(NORMAL, "--[%d]--------------- << selected this", i + 1); config.modulation = tests[i].modulation; config.bitrate = tests[i].bitrate; @@ -1167,7 +1167,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa } if (print_config) - printConfiguration(tests[i]); + printConfiguration(tests[i]); } } return retval; @@ -1327,14 +1327,14 @@ static bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk) si += 3; //uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1; if (maxBlk == 0) continue; - + //test modulation if (!testQ5Modulation(mode, modread)) continue; if (bitRate != clk) continue; - + *fndBitRate = convertQ5bitRate(bitRate); if (*fndBitRate < 0) continue; - + *offset = idx; return true; @@ -1427,7 +1427,7 @@ int printConfiguration(t55xx_conf_block_t b) { PrintAndLogEx(NORMAL, " Offset : %d", b.offset); PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0); - PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr (b.downlink_mode)); + PrintAndLogEx(NORMAL, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -1550,19 +1550,19 @@ static int CmdT55xxWriteBlock(const char *Cmd) { PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : ""); - if ( t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS ) { + if (t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Write failed"); return PM3_ESOFT; } if (validate) { bool isOK = t55xxVerifyWrite(block, page1, usepwd, 1, password, downlink_mode, data); - if (isOK) + if (isOK) PrintAndLogEx(SUCCESS, "Write OK, validation successful"); else PrintAndLogEx(WARNING, "Write could not validate the written data"); } - + return PM3_SUCCESS; } @@ -2201,23 +2201,22 @@ char *GetModulationStr(uint32_t id, bool xmode) { return buf; } -char *GetDownlinkModeStr (uint8_t downlink_mode) -{ +char *GetDownlinkModeStr(uint8_t downlink_mode) { static char buf[30]; char *retStr = buf; switch (downlink_mode) { case T55XX_DLMODE_FIXED : - snprintf(retStr, sizeof(buf),"default/fixed bit length"); + snprintf(retStr, sizeof(buf), "default/fixed bit length"); break; case T55XX_DLMODE_LLR : - snprintf(retStr, sizeof(buf),"long leading reference"); + snprintf(retStr, sizeof(buf), "long leading reference"); break; case T55XX_DLMODE_LEADING_ZERO : - snprintf(retStr, sizeof(buf),"leading zero reference"); + snprintf(retStr, sizeof(buf), "leading zero reference"); break; case T55XX_DLMODE_1OF4 : - snprintf(retStr, sizeof(buf),"1 of 4 coding reference"); + snprintf(retStr, sizeof(buf), "1 of 4 coding reference"); break; default: snprintf(retStr, sizeof(buf), _RED_("(Unknown)")); @@ -2428,7 +2427,7 @@ static int CmdT55xxWipe(const char *Cmd) { if (errors) return usage_t55xx_wipe(); - PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5)? "Q5 / T5555 tag" : "T55x7 tag"); + PrintAndLogEx(INFO, "\nBegin wiping %s", (Q5) ? "Q5 / T5555 tag" : "T55x7 tag"); // default config blocks. if (gotconf == false) { @@ -2441,17 +2440,17 @@ static int CmdT55xxWipe(const char *Cmd) { snprintf(msg, sizeof(msg), "User provided configuration block %08X", block0); else snprintf(msg, sizeof(msg), "Default configation block %08X", block0); - + PrintAndLogEx(INFO, "%s", msg); - // Creating cmd string for write block :) + // Creating cmd string for write block :) snprintf(ptrData, sizeof(writeData), "b 0 "); if (usepwd) { snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password); } snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d %08X", block0); - + if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); @@ -2464,7 +2463,7 @@ static int CmdT55xxWipe(const char *Cmd) { memset(writeData, 0x00, sizeof(writeData)); } - + // Check and rest t55xx downlink mode. if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000"); @@ -2615,7 +2614,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { continue; } - found = tryDetectModulation(dl_mode,T55XX_PrintConfig); + found = tryDetectModulation(dl_mode, T55XX_PrintConfig); if (found) { PrintAndLogEx(SUCCESS, "Found valid password: [ " _GREEN_("%08X") " ]", curr_password); dl_mode = 4; // Exit other downlink mode checks @@ -2733,7 +2732,7 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) { // if (getSignalProperties()->isnoise == false) { // } else { - if (tryDetectModulation(dl_mode,T55XX_PrintConfig)) { + if (tryDetectModulation(dl_mode, T55XX_PrintConfig)) { return 1 + (dl_mode << 1); } // } @@ -2992,8 +2991,8 @@ static int CmdT55xxDetectPage1(const char *Cmd) { useGB = true; cmdp++; break; - case 'r': - //ICEMAN STRANGE + case 'r': + //ICEMAN STRANGE downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode == 4) try_all_dl_modes = true; @@ -3028,7 +3027,7 @@ static int CmdT55xxDetectPage1(const char *Cmd) { } else { found = tryDetectP1(false); } - + if (found) { PrintAndLogEx(SUCCESS, "T55xx chip found!"); T55xx_Print_DownlinkMode(found_mode); @@ -3181,8 +3180,8 @@ static int CmdT55xxProtect(const char *Cmd) { override = 1; cmdp += 2; break; - case 'r': - //ICEMAN STRANGE + case 'r': + //ICEMAN STRANGE downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); if (downlink_mode > 3) downlink_mode = 0; @@ -3198,15 +3197,15 @@ static int CmdT55xxProtect(const char *Cmd) { if (gotnewpwd == false) return usage_t55xx_protect(); - + if (errors || cmdp == 0) return usage_t55xx_protect(); // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ESOFT; - + // lock - if ( t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false ) { + if (t55xxProtect(true, usepwd, override, password, downlink_mode, new_password) == false) { PrintAndLogEx(WARNING, "Command failed. Did you run `lf t55xx detect` before?"); return PM3_ESOFT; } diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index d4e217372..1b70ca9ca 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -141,14 +141,14 @@ char *GetQ5ModulationStr(uint32_t id); char *GetModulationStr(uint32_t id, bool xmode); char *GetModelStrFromCID(uint32_t cid); char *GetSelectedModulationStr(uint8_t id); -char *GetDownlinkModeStr (uint8_t dlmode); +char *GetDownlinkModeStr(uint8_t dlmode); void printT5xxHeader(uint8_t page); void printT55xxBlock(uint8_t blockNum); int printConfiguration(t55xx_conf_block_t b); bool t55xxAquireAndCompareBlock0(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); bool t55xxAquireAndDetect(bool usepwd, uint32_t password, uint32_t known_block0, bool verbose); -bool t55xxVerifyWrite( uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); +bool t55xxVerifyWrite(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t data); int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode); int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, bool verbose); diff --git a/client/fido/additional_ca.c b/client/fido/additional_ca.c index 3c10a9de9..1f383c741 100644 --- a/client/fido/additional_ca.c +++ b/client/fido/additional_ca.c @@ -89,7 +89,7 @@ "A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAgNHADBEAiAwfPqgIWIUB+QBBaVGsdHy\r\n" \ "0s5RMxlkzpSX/zSyTZmUpQIgB2wJ6nZRM8oX/nA43Rh6SJovM2XwCCH//+LirBAb\r\n" \ "B0M=\r\n" \ - "-----END CERTIFICATE-----\r\n" + "-----END CERTIFICATE-----\r\n" // FEITIAN FIDO2 #define FEITIAN_FIDO2_CA \ @@ -104,7 +104,7 @@ "FEu9hyYRrRyJzwRYvnDSCIxrFiO3MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\r\n" \ "BAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIDHSb2mbNDAUNXvpPU0oWKeNye0fQ2l9\r\n" \ "D01AR2+sLZdhAiEAo3wz684IFMVsCCRmuJqxH6FQRESNqezuo1E+KkGxWuM=\r\n" \ - "-----END CERTIFICATE-----\r\n" + "-----END CERTIFICATE-----\r\n" // https://hypersecu.com/support/downloads // HyperFIDO U2F Security Key Attestation CA @@ -135,9 +135,9 @@ "FPFypmsIMAwGA1UdEwQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMC\r\n" \ "A0kAMEYCIQCG2/ppMGt7pkcRie5YIohS3uDPIrmiRcTjqDclKVWg0gIhANcPNDZH\r\n" \ "E2/zZ+uB5ThG9OZus+xSb4knkrbAyXKX2zm/\r\n" \ - "-----END CERTIFICATE-----\r\n" - -// NXP + "-----END CERTIFICATE-----\r\n" + +// NXP // https://fido-mds-parser.appspot.com/?url=https://mds.fidoalliance.org/metadata/JKP5CiDehdMMPwtG5i7to5 #define NXP_U2F_CA \ "-----BEGIN CERTIFICATE-----\r\n" \ @@ -151,8 +151,8 @@ "AJlr23jig2LxRM1PpgMAQXnZJy/HnkRB9O8KD0o2oK/mAiBG5EK1S3yVHdkkVGTJ\r\n" \ "Q12ffuK8Op7Nx89cszCr0WyIhQ==\r\n" \ "-----END CERTIFICATE-----\r\n" - + /* Concatenation of all additional CA certificates in PEM format if available */ const char additional_ca_pem[] = GLOBALSIGN_CA YUBICO_CA SOLOKEY_CA \ - FEITIAN_U2F_CA FEITIAN_FIDO2_CA HYPERFIDO_U2F_1_CA HYPERFIDO_U2F_2_CA NXP_U2F_CA; + FEITIAN_U2F_CA FEITIAN_FIDO2_CA HYPERFIDO_U2F_1_CA HYPERFIDO_U2F_2_CA NXP_U2F_CA; const size_t additional_ca_pem_len = sizeof(additional_ca_pem); diff --git a/client/scripting.c b/client/scripting.c index 586ab0940..8054ff9b4 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -930,7 +930,7 @@ static int l_T55xx_readblock(lua_State *L) { return returnToLuaWithError(L, "Failed to read config block"); } - if (!tryDetectModulation(0,true)) { // Default to prev. behaviour (default dl mode and print config) + if (!tryDetectModulation(0, true)) { // Default to prev. behaviour (default dl mode and print config) PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits."); return 0; } else { @@ -1006,7 +1006,7 @@ static int l_T55xx_detect(lua_State *L) { } } - isok = tryDetectModulation(0,true); // Default to prev. behaviour (default dl mode and print config) + isok = tryDetectModulation(0, true); // Default to prev. behaviour (default dl mode and print config) if (isok == false) { return returnToLuaWithError(L, "Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'"); } From a604f641b3c1767081238d84cbb81b863e972e4c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 10:55:34 +0200 Subject: [PATCH 18/33] style --- client/cmdlfpac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c index 6ea0af7d6..175d56ad4 100644 --- a/client/cmdlfpac.c +++ b/client/cmdlfpac.c @@ -63,7 +63,7 @@ static int CmdPacClone(const char *Cmd) { } static int CmdPacSim(const char *Cmd) { - + // NRZ sim. PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); return PM3_SUCCESS; From aa2f80795d427d8ff06f2cb21dfb8ed88a1e36c9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 12:13:39 +0200 Subject: [PATCH 19/33] mem spibaud uses NG. And a simplification of tuning --- armsrc/appmain.c | 42 ++++++++++++++++++++++-------------------- client/cmdflashmem.c | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 257a4a5b6..0ac021400 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -208,13 +208,13 @@ void MeasureAntennaTuning(void) { uint16_t MeasureAntennaTuningHfData(void) { uint16_t volt = 0; // in mV - volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + uint16_t avg = AvgAdc(ADC_CHAN_HF); + volt = (MAX_ADC_HF_VOLTAGE * avg) >> 10; bool use_high = (volt > MAX_ADC_HF_VOLTAGE - 300); - if (!use_high) { - volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - } else { + if (use_high) { volt = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; +// volt = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; } return volt; } @@ -787,7 +787,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t password; uint8_t flags; } PACKED; - struct p *payload = (struct p *) packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; T55xxWakeUp(payload->password, payload->flags); break; } @@ -846,7 +846,7 @@ static void PacketReceived(PacketCommandNG *packet) { bool Q5; uint8_t blocks[8]; } PACKED; - struct p *payload = (struct p*)packet->data.asBytes; + struct p *payload = (struct p *)packet->data.asBytes; CopyVikingtoT55xx(payload->blocks, payload->Q5); break; } @@ -1236,22 +1236,22 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_ICLASS_READBL: { -/* - struct p { - uint8_t blockno; - } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; - */ - iClass_ReadBlk( packet->data.asBytes[0] ); + /* + struct p { + uint8_t blockno; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + */ + iClass_ReadBlk(packet->data.asBytes[0]); break; } case CMD_HF_ICLASS_AUTH: { //check -/* - struct p { - uint8_t mac[4]; - } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; -*/ + /* + struct p { + uint8_t mac[4]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + */ iClass_Authentication(packet->data.asBytes); break; } @@ -1665,7 +1665,9 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_FLASHMEM_SET_SPIBAUDRATE: { - FlashmemSetSpiBaudrate(packet->oldarg[0]); + if (packet->length != sizeof(uint32_t)) + break; + FlashmemSetSpiBaudrate(packet->data.asDwords[0]); break; } case CMD_FLASHMEM_WRITE: { diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index ce5b37f44..be59dc4f7 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -117,7 +117,7 @@ static int CmdFlashmemSpiBaudrate(const char *Cmd) { usage_flashmem_spibaud(); return PM3_EINVARG; } - SendCommandMIX(CMD_FLASHMEM_SET_SPIBAUDRATE, baudrate, 0, 0, NULL, 0); + SendCommandNG(CMD_FLASHMEM_SET_SPIBAUDRATE, (uint8_t*)&baudrate, sizeof(uint32_t)); return PM3_SUCCESS; } From a3161ae9a2ca58e7debcf08f0b8cada09429f147 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 13:12:48 +0200 Subject: [PATCH 20/33] fix 'lf em 4x50_read - now checks if have enough data in Graphbuffer --- client/cmdlfem4x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index b7948b14c..e7b1c2b06 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -821,6 +821,12 @@ int EM4x50Read(const char *Cmd, bool verbose) { uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; size_t size = getFromGraphBuf(bits); + + if (size < 4000) { + if (verbose || g_debugMode) PrintAndLogEx(ERR, "Error: EM4x50 - Too little data in Graphbuffer"); + return PM3_ESOFT; + } + computeSignalProperties(bits, size); signal_t *sp = getSignalProperties(); From e5ffcfd51359a84b65c3beb4ac9b48f3db3efa52 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Sep 2019 13:46:38 +0200 Subject: [PATCH 21/33] chg: 'lf hid brute' - use new wiegand formats. see helptext for more details --- client/cmdlfhid.c | 346 +++++++++++----------------------------------- 1 file changed, 77 insertions(+), 269 deletions(-) diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 2059066dc..20baa6449 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -35,40 +35,24 @@ #include "cmdlf.h" // lf_read #include "util_posix.h" #include "lfdemod.h" +#include "wiegand_formats.h" #ifndef BITS # define BITS 96 #endif static int CmdHelp(const char *Cmd); -/* -static int usage_lf_hid_read(void) { + +static int usage_lf_hid_watch(void) { PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single HID card."); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid read [h] [1]"); + PrintAndLogEx(NORMAL, "Usage: lf hid watch [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " 1 : (optional) stop after reading a single card"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid read"); - PrintAndLogEx(NORMAL, " lf hid read 1"); - return PM3_SUCCESS; -} -*/ -static int usage_lf_hid_wiegand(void) { - PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid wiegand [h] [OEM] [FC] [CN]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " OEM - OEM number / site code"); - PrintAndLogEx(NORMAL, " FC - facility code"); - PrintAndLogEx(NORMAL, " CN - card number"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid wiegand 0 101 2001"); + PrintAndLogEx(NORMAL, " lf hid watch"); return PM3_SUCCESS; } static int usage_lf_hid_sim(void) { @@ -101,19 +85,21 @@ static int usage_lf_hid_brute(void) { PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step"); PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535"); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] a f c d "); + PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w [ (decimal)>] {...}"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " a : 26|33|34|35|37|40|44|84"); - PrintAndLogEx(NORMAL, " f : 8-bit value HID facility code"); - PrintAndLogEx(NORMAL, " c : (optional) cardnumber to start with, max 65535"); + PrintAndLogEx(NORMAL, " w : see `wiegand list` for available formats"); + PrintAndLogEx(NORMAL, " f : facility code"); + PrintAndLogEx(NORMAL, " c : card number to start with"); + PrintAndLogEx(NORMAL, " i : issue level"); + PrintAndLogEx(NORMAL, " o : OEM code"); PrintAndLogEx(NORMAL, " d : delay betweens attempts in ms. Default 1000ms"); PrintAndLogEx(NORMAL, " v : verbose logging, show all tries"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hid brute a 26 f 224"); - PrintAndLogEx(NORMAL, " lf hid brute a 26 f 21 d 2000"); - PrintAndLogEx(NORMAL, " lf hid brute v a 26 f 21 c 200 d 2000"); + PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 224"); + PrintAndLogEx(NORMAL, " lf hid brute w H10301 f 21 d 2000"); + PrintAndLogEx(NORMAL, " lf hid brute v w H10301 f 21 c 200 d 2000"); return PM3_SUCCESS; } @@ -128,17 +114,33 @@ static int sendPing(void) { return PM3_ETIMEOUT; return PM3_SUCCESS; } -static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, bool verbose) { +static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, bool verbose) { + + wiegand_message_t packed; + memset(&packed, 0, sizeof(wiegand_message_t)); + + if (HIDPack(format_idx, card, &packed) == false) { + PrintAndLogEx(WARNING, "The card data could not be encoded in the selected format."); + return PM3_ESOFT; + } - // this should be optional. if (verbose) - PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn); + PrintAndLogEx(INFO, "Trying FC: %u; CN: %u; Issue level: %u; OEM: %u", card->FacilityCode, card->CardNumber, card->IssueLevel, card->OEM); - calcWiegand(fmtlen, fc, cn, bits, 0); + lf_hidsim_t payload; + payload.hi2 = packed.Top; + payload.hi = packed.Mid; + payload.lo = packed.Bot; clearCommandBuffer(); - SendCommandMIX(CMD_LF_HID_SIMULATE, bytebits_to_byte(bits, 32), bytebits_to_byte(bits + 32, 32), 0, NULL, 0); + SendCommandNG(CMD_LF_HID_SIMULATE, (uint8_t *)&payload, sizeof(payload)); +/* + PacketResponseNG resp; + WaitForResponse(CMD_LF_HID_SIMULATE, &resp); + if (resp.status == PM3_EOPABORTED) + return resp.status; +*/ msleep(delay); return sendPing(); } @@ -258,18 +260,18 @@ static int CmdHIDRead(const char *Cmd) { lf_read(true, 12000); return CmdHIDDemod(Cmd); } -/* + // this read loops on device side. // uses the demod in lfops.c -static int CmdHIDRead_device(const char *Cmd) { +static int CmdHIDWatch(const char *Cmd) { - if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read(); - uint8_t findone = (Cmd[0] == '1') ? 1 : 0; + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if ( strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_watch(); clearCommandBuffer(); - SendCommandMIX(CMD_LF_HID_DEMOD, findone, 0, 0, NULL, 0); + SendCommandMIX(CMD_LF_HID_DEMOD, 0, 0, 0, NULL, 0); return PM3_SUCCESS; } -*/ + static int CmdHIDSim(const char *Cmd) { lf_hidsim_t payload; payload.longFMT = 0; @@ -319,8 +321,8 @@ static int CmdHIDClone(const char *Cmd) { uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t n = 0, i = 0; - uint8_t ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h') return usage_lf_hid_clone(); + uint8_t ctmp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_clone(); uint8_t longid[1] = {0}; if (strchr(Cmd, 'l') != 0) { i++; @@ -348,202 +350,9 @@ static int CmdHIDClone(const char *Cmd) { } /* -// struct to handle wiegand -typedef struct { - uint8_t FormatLen; - uint8_t SiteCode; - uint8_t FacilityCode; - uint8_t CardNumber; - uint8_t *Wiegand; - size_t Wiegand_n; -} wiegand_t; -*/ - -static void addHIDMarker(uint8_t fmtlen, uint8_t *out) { - // temp array - uint8_t arr[BITS]; - memset(arr, 0, BITS); - - // copy inpu - uint8_t pos = sizeof(arr) - fmtlen; - memcpy(arr + pos, out, fmtlen); - - switch (fmtlen) { - case 26: { - // start sentinel, BITS-bit 27 = 1 - arr[BITS - 27] = 1; - // fmt smaller than 37 used, bit37 = 1 - arr[BITS - 38] = 1; - memcpy(out, arr, BITS); - break; - } - case 34: - // start sentinel, BITS-bit 27 = 1 - arr[BITS - 35] = 1; - - // fmt smaller than 37 used, bit37 = 1 - arr[BITS - 38] = 1; - memcpy(out, arr, BITS); - break; - default: - break; - } -} - -// static void getParity34(uint32_t *hi, uint32_t *lo){ -// uint32_t result = 0; -// int i; - -// // even parity -// for (i = 7;i >= 0;i--) -// result ^= (*hi >> i) & i; -// for (i = 31;i >= 24;i--) -// result ^= (*lo >> i) & 1; - -// *hi |= result << 2; - -// // odd parity bit -// result = 0; -// for (i = 23;i >= 1;i--) -// result ^= (*lo >> i) & 1; - -// *lo |= !result; -// } -// static void getParity37H(uint32_t *hi, uint32_t *lo){ -// uint32_t result = 0; -// int i; - -// // even parity -// for (i = 4;i >= 0;i--) -// result ^= (*hi >> i) & 1; -// for (i = 31;i >= 20;i--) -// result ^= (*lo >> i) & 1; -// *hi |= result << 4; - -// // odd parity -// result = 0; -// for (i = 19;i >= 1;i--) -// result ^= (*lo >> i) & 1; -// *lo |= result; -// } - -//static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ -static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out) { - uint8_t wiegand[24]; - num_to_bytebits(fc, 8, wiegand); - num_to_bytebits(cardno, 16, wiegand + 8); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); -} -// static void calc33(uint16_t fc, uint32_t cardno, uint8_t *out){ -// } -static void calc34(uint16_t fc, uint32_t cardno, uint8_t *out) { - uint8_t wiegand[32]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cardno, 16, wiegand + 16); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); -} -// static void calc35(uint16_t fc, uint32_t cardno, uint8_t *out){ -// *lo = ((cardno & 0xFFFFF) << 1) | fc << 21; -// *hi = (1 << 5) | ((fc >> 11) & 1); -// } -static void calc36(uint8_t oem, uint16_t fc, uint32_t cardno, uint8_t *out) { - // FC 1 - 16 - 16 bit - // cardno 17 - 33 - 16 bit - // oem 34 - 35 - 2 bit - // Odd Parity 0th bit 1-18 - // Even Parity 36th bit 19-35 - uint8_t wiegand[34]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cardno & 0xFFFF, 16, wiegand + 16); - num_to_bytebits(oem, 2, wiegand + 32); - wiegand_add_parity_swapped(out, wiegand, sizeof(wiegand)); -} -static void calc37S(uint16_t fc, uint32_t cardno, uint8_t *out) { - // FC 2 - 17 - 16 bit - // cardno 18 - 36 - 19 bit - // Even P1 1 - 19 - // Odd P37 19 - 36 - uint8_t wiegand[35]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cardno, 19, wiegand + 16); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); -} -static void calc37H(uint64_t cardno, uint8_t *out) { - // SC NONE - // cardno 1-35 34 bits - // Even Parity 0th bit 1-18 - // Odd Parity 36th bit 19-35 - uint8_t wiegand[37]; - num_to_bytebits((uint32_t)(cardno >> 32), 2, wiegand); - num_to_bytebits((uint32_t)(cardno >> 0), 32, wiegand + 2); - wiegand_add_parity(out, wiegand, sizeof(wiegand)); - - PrintAndLogEx(NORMAL, "%x %x\n", (uint32_t)(cardno >> 32), (uint32_t)cardno); -} -// static void calc40(uint64_t cardno, uint8_t *out){ -// cardno = (cardno & 0xFFFFFFFFFF); -// *lo = ((cardno & 0xFFFFFFFF) << 1 ); -// *hi = (cardno >> 31); -// } - -void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem) { - uint32_t cn32 = (cardno & 0xFFFFFFFF); - switch (fmtlen) { - case 26: - calc26(fc, cn32, bits); - break; - // case 33 : calc33(fc, cn32, bits); break; - case 34: - calc34(fc, cn32, bits); - break; - // case 35 : calc35(fc, cn32, bits); break; - case 36: - calc36(oem, fc, cn32, bits); - break; - case 37: - calc37S(fc, cn32, bits); - break; - case 38: - calc37H(cardno, bits); - break; - // case 40 : calc40(cardno, bits); break; - // case 44 : { break; } - // case 84 : { break; } - default: - break; - } -} - -static int CmdHIDWiegand(const char *Cmd) { - uint32_t oem = 0, fc = 0; - uint64_t cardnum = 0; - uint8_t bits[BITS] = {0}; - uint8_t *bs = bits; - - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 3 || ctmp == 'h') return usage_lf_hid_wiegand(); - - oem = param_get8(Cmd, 0); - fc = param_get32ex(Cmd, 1, 0, 10); - cardnum = param_get64ex(Cmd, 2, 0, 10); - - uint8_t fmtlen[] = {26, 33, 34, 35, 36, 37, 38, 40}; - PrintAndLogEx(NORMAL, "HID | OEM | FC | CN | Wiegand | HID Formatted"); PrintAndLogEx(NORMAL, "----+-----+------+---------+-----------+--------------------"); - for (uint8_t i = 0; i < ARRAYLEN(fmtlen); i++) { - memset(bits, 0x00, sizeof(bits)); - calcWiegand(fmtlen[i], fc, cardnum, bs, oem); - PrintAndLogEx(NORMAL, "ice:: %s \n", sprint_bin(bs, fmtlen[i])); - uint64_t wiegand = (uint64_t)bytebits_to_byte(bs, 32) << 32 | bytebits_to_byte(bs + 32, 32); - - addHIDMarker(fmtlen[i], bs); - PrintAndLogEx(NORMAL, "ice:: %s\n", sprint_bin(bs, BITS)); - uint64_t blocks = (uint64_t)bytebits_to_byte(bs + 32, 32) << 32 | bytebits_to_byte(bs + 64, 32); - uint8_t shifts = 64 - fmtlen[i]; - wiegand >>= shifts; - - PrintAndLogEx(NORMAL, " %u | %03u | %03u | %" PRIu64 " | %" PRIX64 " | %" PRIX64, + PrintAndLogEx(NORMAL, " %u | %03u | %03u | %" PRIu64 " | %" PRIX64 " | %" PRIX64, fmtlen[i], oem, fc, @@ -553,26 +362,33 @@ static int CmdHIDWiegand(const char *Cmd) { ); } PrintAndLogEx(NORMAL, "----+-----+-----+-------+-----------+--------------------"); - return PM3_SUCCESS; -} +*/ static int CmdHIDBrute(const char *Cmd) { bool errors = false, verbose = false; - uint32_t fc = 0, cn = 0, delay = 1000; - uint8_t fmtlen = 0; - uint8_t bits[96]; - memset(bits, 0, sizeof(bits)); + uint32_t delay = 1000; uint8_t cmdp = 0; + int format_idx = -1; + char format[16] = {0}; + wiegand_card_t data; + memset(&data, 0, sizeof(wiegand_card_t)); while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_lf_hid_brute(); - case 'f': - fc = param_get32ex(Cmd, cmdp + 1, 0, 10); - if (!fc) + case 'w': + param_getstr(Cmd, cmdp + 1, format, sizeof(format)); + format_idx = HIDFindCardFormat(format); + if (format_idx == -1) { + PrintAndLogEx(WARNING, "Unknown format: %s", format); errors = true; + } + cmdp += 2; + break; + case 'c': + data.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; case 'd': @@ -580,24 +396,17 @@ static int CmdHIDBrute(const char *Cmd) { delay = param_get32ex(Cmd, cmdp + 1, 1000, 10); cmdp += 2; break; - case 'c': - cn = param_get32ex(Cmd, cmdp + 1, 0, 10); - // truncate cardnumber. - cn &= 0xFFFF; + case 'f': + data.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; break; - case 'a': - fmtlen = param_get8(Cmd, cmdp + 1); + case 'i': + data.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; + case 'o': + data.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10); cmdp += 2; - bool is_ftm_ok = false; - uint8_t ftms[] = {26, 33, 34, 35, 37}; - for (uint8_t i = 0; i < ARRAYLEN(ftms); i++) { - if (ftms[i] == fmtlen) { - is_ftm_ok = true; - } - } - // negated - errors = !is_ftm_ok; break; case 'v': verbose = true; @@ -609,15 +418,11 @@ static int CmdHIDBrute(const char *Cmd) { break; } } - if (fc == 0) errors = true; if (errors) return usage_lf_hid_brute(); PrintAndLogEx(INFO, "Brute-forcing HID reader"); PrintAndLogEx(INFO, "Press pm3-button to abort simulation or run another command"); - uint16_t up = cn; - uint16_t down = cn; - // main loop for (;;) { @@ -632,13 +437,16 @@ static int CmdHIDBrute(const char *Cmd) { } // Do one up - if (up < 0xFFFF) - if (sendTry(fmtlen, fc, up++, delay, bits, verbose) != PM3_SUCCESS) return PM3_ESOFT; + if (data.CardNumber < 0xFFFF) { + data.CardNumber++; + if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + } // Do one down (if cardnumber is given) - if (cn > 1) - if (down > 1) - if (sendTry(fmtlen, fc, --down, delay, bits, verbose) != PM3_SUCCESS) return PM3_ESOFT; + if (data.CardNumber > 1) { + data.CardNumber--; + if (sendTry(format_idx, &data, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT; + } } return PM3_SUCCESS; } @@ -649,8 +457,8 @@ static command_t CommandTable[] = { {"read", CmdHIDRead, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdHIDClone, IfPm3Lf, "clone HID to T55x7"}, {"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"}, - {"wiegand", CmdHIDWiegand, AlwaysAvailable, "convert facility code/card number to Wiegand code"}, {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"}, + {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; From 238e41c6833d5a8e51babdc11f3138ed29985b13 Mon Sep 17 00:00:00 2001 From: Iceman Date: Fri, 20 Sep 2019 13:19:19 +0200 Subject: [PATCH 22/33] Update cheatsheet.md --- doc/cheatsheet.md | 76 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 4a61ae7d2..3fc446ec8 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -9,7 +9,7 @@ |[Sim Module](#Sim-Module)|[Hitag](#Hitag)|| |[Lua Scripts](#Lua-Scripts)||| |[Smart Card](#Smart-Card)||| - +|[Wiegand convertion](#Wiegand-manipulation)||| ## Generic ^[Top](#top) @@ -62,7 +62,7 @@ Options --- k : *Access Key as 16 hex symbols or 1 hex to select key from memory -pm3 --> hf iclass dump k AFA785A7DAB33378 +m3 --> hf iclass dump k 0 ``` Read iClass Block @@ -72,7 +72,7 @@ Options b : The block number as 2 hex symbols k : Access Key as 16 hex symbols or 1 hex to select key from memory -pm3 --> hf iclass readblk b 7 k AFA785A7DAB33378 +pm3 --> hf iclass rdbl b 7 k 0 ``` Write to iClass Block @@ -83,7 +83,7 @@ b : The block number as 2 hex symbols d : Set the Data to write as 16 hex symbols k : Access Key as 16 hex symbols or 1 hex to select key from memory -pm3 --> hf iclass writeblk b 07 d 6ce099fe7e614fd0 k AFA785A7DAB33378 +pm3 --> hf iclass wrbl b 07 d 6ce099fe7e614fd0 k 0 ``` Print keystore @@ -107,7 +107,7 @@ pm3 --> hf iclass managekeys n 0 k AFA785A7DAB33378 Encrypt iClass Block ``` -pm3 --> hf iclass encryptblk 0000000f2aa3dba8 +pm3 --> hf iclass encrypt 0000000f2aa3dba8 ``` Load iClass dump into memory for simulation @@ -116,7 +116,7 @@ Options --- f : load iclass tag-dump filename -pm3 --> hf iclass eload f iclass_tagdump-db883702f8ff12e0.bin +pm3 --> hf iclass eload f hf-iclass-db883702f8ff12e0.bin ``` Simulate iClass @@ -124,6 +124,7 @@ Simulate iClass Options --- 0 simulate the given CSN +2 Runs part 1 of LOCLASS attack 1 simulate default CSN 3 Full simulation using emulator memory (see 'hf iclass eload') @@ -132,14 +133,14 @@ pm3 --> hf iclass sim 3 Clone iClass Legacy Sequence ``` -pm3 --> hf iclass readblk b 7 k AFA785A7DAB33378 -pm3 --> hf iclass writeblk b 07 d 6ce099fe7e614fd0 k AFA785A7DAB33378 +pm3 --> hf iclass rdbl b 7 k 0 +pm3 --> hf iclass wrbl b 7 d 6ce099fe7e614fd0 k 0 ``` Simulate iClass Sequence ``` -pm3 --> hf iclass dump k AFA785A7DAB33378 -pm3 --> hf iclass eload f iclass_tagdump-db883702f8ff12e0.bin +pm3 --> hf iclass dump k 0 +pm3 --> hf iclass eload f hf-iclass-db883702f8ff12e0.bin pm3 --> hf iclass sim 3 ``` @@ -224,6 +225,14 @@ Options pm3 --> hf mf wrbl 0 A FFFFFFFFFFFF d3a2859f6b880400c801002000000016 ``` +Run autopwn +``` +Options +--- + +pm3 --> hf mf autopwn +``` + Run Hardnested attack ``` Options @@ -241,8 +250,8 @@ Options [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL -pm3 --> hf mf eload 353C2AA6 -pm3 --> hf mf eload 1 353C2AA6 +pm3 --> hf mf eload hf-mf-353C2AA6 +pm3 --> hf mf eload 1 hf-mf-353C2AA6 ``` Simulate Mifare @@ -268,6 +277,37 @@ pm3 --> hf mf dump pm3 --> hf mf restore 1 u 4A6CE843 k hf-mf-A29558E4-key.bin f hf-mf-A29558E4-data.bin ``` +## Wiegand manipulation +^[Top](#top) + +List all available weigand formats in client +``` +pm3 --> wiegand list +``` + +Convert Site & Facility code to Wiegand raw hex +``` +Options +--- +w o f c i +w : wiegand format to use +o : OEM number / site code +f : facility code +c : card number +i : issue level + +pm3 --> wiegand encode 0 56 150 +``` + +Convert Site & Facility code from Wiegand raw hex to numbers +``` +Options +--- +p : ignore parity errors + +pm3 --> wiegand decode 2006f623ae +``` + ## HID Prox ^[Top](#top) @@ -281,18 +321,6 @@ Demodulate HID Prox card pm3 --> lf hid demod ``` -Convert Site & Facility code to Wiegand -``` -Options ---- - -OEM : OEM number / site code -FC : facility code -CN : card number - -pm3 --> lf hid wiegand 0 56 150 -``` - Simulate Prox card ``` From 93915858eacf3bd8b31f87bab9180752d6751f5c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 08:47:12 +0200 Subject: [PATCH 23/33] fix `data load` now not crashing client when entering a folder path without filename --- client/cmddata.c | 2 ++ client/fileutils.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index 792cf6a96..d1df2be65 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1676,6 +1676,8 @@ static int CmdLoad(const char *Cmd) { int len = 0; len = strlen(Cmd); + if (len == 0) return PM3_EFILE; + if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE; memcpy(filename, Cmd, len); diff --git a/client/fileutils.c b/client/fileutils.c index 23553d15c..717787293 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -1014,8 +1014,14 @@ out: int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { if (foundpath == NULL) return PM3_EINVARG; + if (searchname == NULL || strlen(searchname) == 0) + return PM3_EINVARG; + if (searchname[ strlen(searchname)-1] == '/') + return PM3_EINVARG; + char *filename = filenamemcopy(searchname, suffix); - if (filename == NULL) return PM3_EMALLOC; + if (filename == NULL || strlen(filename) == 0) + return PM3_EMALLOC; int res = searchFinalFile(foundpath, pm3dir, filename, silent); if (res != PM3_SUCCESS) { if ((res == PM3_EFILE) && (!silent)) From f7510dc6aaef16f32a9cdfc8880498d05ab57690 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 11:12:36 +0200 Subject: [PATCH 24/33] better detection of directory (@doegox) --- client/fileutils.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 717787293..3599ec6f4 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -69,6 +69,23 @@ int fileExists(const char *filename) { return result == 0; } +/** + * @brief checks if path is file or directory. + * @param filename + * @return + */ +int is_regular_file(const char *filename) { +#ifdef _WIN32 + struct _stat st; + _stat(filename, &st); + return S_ISREG(_st.st_mode); +#else + struct stat st; + stat(filename, &st); + return S_ISREG(st.st_mode); +#endif +} + static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; @@ -1016,9 +1033,11 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con return PM3_EINVARG; if (searchname == NULL || strlen(searchname) == 0) return PM3_EINVARG; - if (searchname[ strlen(searchname)-1] == '/') + + if (is_regular_file(searchname) == 0) return PM3_EINVARG; + char *filename = filenamemcopy(searchname, suffix); if (filename == NULL || strlen(filename) == 0) return PM3_EMALLOC; From 862bf1b793e80c65931e7eaae2e269cea812b9d3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 11:48:55 +0200 Subject: [PATCH 25/33] fix for ps3.2 compilation --- client/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/fileutils.c b/client/fileutils.c index 3599ec6f4..450672935 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -78,7 +78,7 @@ int is_regular_file(const char *filename) { #ifdef _WIN32 struct _stat st; _stat(filename, &st); - return S_ISREG(_st.st_mode); + return S_ISREG(st.st_mode); #else struct stat st; stat(filename, &st); From e7d67fc2b0d09fcd5a44aefa40c15dacdeb23453 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Sep 2019 16:31:45 +0200 Subject: [PATCH 26/33] fix for checking directory --- client/fileutils.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 450672935..35fa735ea 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -70,7 +70,7 @@ int fileExists(const char *filename) { } /** - * @brief checks if path is file or directory. + * @brief checks if path is file. * @param filename * @return */ @@ -85,6 +85,23 @@ int is_regular_file(const char *filename) { return S_ISREG(st.st_mode); #endif } +/** + * @brief checks if path is directory. + * @param filename + * @return + */ +int is_directory(const char *filename) { +#ifdef _WIN32 + struct _stat st; + _stat(filename, &st); + return S_ISDIR(st.st_mode); +#else + struct stat st; + stat(filename, &st); + return S_ISDIR(st.st_mode); +#endif +} + static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; @@ -1029,12 +1046,14 @@ out: } int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) { + if (foundpath == NULL) return PM3_EINVARG; + if (searchname == NULL || strlen(searchname) == 0) return PM3_EINVARG; - if (is_regular_file(searchname) == 0) + if (is_directory(searchname) != 0) return PM3_EINVARG; From 782feb934ac5ec5f25f91ce2a5deeba2a651357a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 18:32:07 +0200 Subject: [PATCH 27/33] split slow tests --- client/cmdhficlass.c | 6 ++++-- client/emv/cmdemv.c | 6 ++++-- client/emv/test/crypto_test.c | 16 +++++++++++++--- client/emv/test/crypto_test.h | 2 +- client/emv/test/cryptotest.c | 4 ++-- client/emv/test/cryptotest.h | 2 +- client/loclass/elite_crack.c | 5 +++-- client/loclass/elite_crack.h | 2 +- pm3test.sh | 17 ++++++++++++++--- 9 files changed, 43 insertions(+), 17 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 5f8ed9fbc..691072174 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -229,10 +229,11 @@ static int usage_hf_iclass_sniff(void) { return PM3_SUCCESS; } static int usage_hf_iclass_loclass(void) { - PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]"); + PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [h] [t [l]] [f ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h Show this help"); PrintAndLogEx(NORMAL, " t Perform self-test"); + PrintAndLogEx(NORMAL, " t l Perform self-test, including long ones"); PrintAndLogEx(NORMAL, " f Bruteforce iclass dumpfile"); PrintAndLogEx(NORMAL, " An iclass dumpfile is assumed to consist of an arbitrary number of"); PrintAndLogEx(NORMAL, " malicious CSNs, and their protocol responses"); @@ -1831,10 +1832,11 @@ static int CmdHFiClass_loclass(const char *Cmd) { return PM3_EFILE; } } else if (opt == 't') { + char opt2 = tolower(param_getchar(Cmd, 1)); int errors = testCipherUtils(); errors += testMAC(); errors += doKeyTests(0); - errors += testElite(); + errors += testElite(opt2=='l'); if (errors) PrintAndLogEx(ERR, "There were errors!!!"); return PM3_ESOFT; } diff --git a/client/emv/cmdemv.c b/client/emv/cmdemv.c index 8bb630074..d45181060 100644 --- a/client/emv/cmdemv.c +++ b/client/emv/cmdemv.c @@ -1716,19 +1716,21 @@ static int CmdEMVList(const char *Cmd) { static int CmdEMVTest(const char *Cmd) { CLIParserInit("emv test", "Executes tests\n", - "Usage:\n\temv test\n"); + "Usage:\n\temv test [l]\n"); void *argtable[] = { arg_param_begin, arg_lit0("iI", "ignore", "ignore timing tests for VM"), + arg_lit0("lL", "long", "run long tests too"), arg_param_end }; CLIExecWithReturn(Cmd, argtable, true); bool ignoreTimeTest = arg_get_lit(1); + bool runSlowTests = arg_get_lit(2); CLIParserFree(); - return ExecuteCryptoTests(true, ignoreTimeTest); + return ExecuteCryptoTests(true, ignoreTimeTest, runSlowTests); } static int CmdEMVRoca(const char *Cmd) { diff --git a/client/emv/test/crypto_test.c b/client/emv/test/crypto_test.c index cdf22a995..4a40952a8 100644 --- a/client/emv/test/crypto_test.c +++ b/client/emv/test/crypto_test.c @@ -301,8 +301,9 @@ close_pub: return ret; } -int exec_crypto_test(bool verbose) { - unsigned int keylengths[] = {1024, 1152, 1408, 1984, 2048, 3072, 4096}; +int exec_crypto_test(bool verbose, bool include_slow_tests) { + unsigned int keylengths[] = {1024, 2048}; + unsigned int extra_keylengths[] = {1152, 1408, 1984, 3072, 4096}; int i; int ret; fprintf(stdout, "\n"); @@ -322,6 +323,15 @@ int exec_crypto_test(bool verbose) { return ret; } } - + if (include_slow_tests) { + for (i = 0; i < ARRAYLEN(extra_keylengths); i++) { + unsigned int kl = extra_keylengths[i]; + ret = test_genkey(kl, message, kl / 8, verbose); + if (ret) { + fprintf(stderr, "Crypto generate key[%u] test: failed\n", kl); + return ret; + } + } + } return 0; } diff --git a/client/emv/test/crypto_test.h b/client/emv/test/crypto_test.h index 024a950d5..4b8fcf074 100644 --- a/client/emv/test/crypto_test.h +++ b/client/emv/test/crypto_test.h @@ -17,5 +17,5 @@ #define __CRYPTO_TEST_H #include -int exec_crypto_test(bool verbose); +int exec_crypto_test(bool verbose, bool include_slow_tests); #endif diff --git a/client/emv/test/cryptotest.c b/client/emv/test/cryptotest.c index b8ea1239e..f343ebbea 100644 --- a/client/emv/test/cryptotest.c +++ b/client/emv/test/cryptotest.c @@ -33,7 +33,7 @@ #include "crypto/libpcrypto.h" #include "emv/emv_roca.h" -int ExecuteCryptoTests(bool verbose, bool ignore_time) { +int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests) { int res; bool TestFail = false; @@ -94,7 +94,7 @@ int ExecuteCryptoTests(bool verbose, bool ignore_time) { res = exec_cda_test(verbose); if (res) TestFail = true; - res = exec_crypto_test(verbose); + res = exec_crypto_test(verbose, include_slow_tests); if (res) TestFail = true; res = roca_self_test(); diff --git a/client/emv/test/cryptotest.h b/client/emv/test/cryptotest.h index aeecce556..579a5a66d 100644 --- a/client/emv/test/cryptotest.h +++ b/client/emv/test/cryptotest.h @@ -12,5 +12,5 @@ #define __CRYPTOTEST_H #include -int ExecuteCryptoTests(bool verbose, bool ignore_time); +int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests); #endif diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index bf9aee5b3..c7a617f6a 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -637,7 +637,7 @@ static int _testHash1() { return 0; } -int testElite() { +int testElite(bool slowtests) { PrintAndLogEx(INFO, "Testing iClass Elite functinality..."); PrintAndLogEx(INFO, "Testing hash2"); uint8_t k_cus[8] = {0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xC1, 0x1B, 0x39}; @@ -669,6 +669,7 @@ int testElite() { errors += _testHash1(); PrintAndLogEx(INFO, "Testing key diversification ..."); errors += _test_iclass_key_permutation(); - errors += _testBruteforce(); + if (slowtests) + errors += _testBruteforce(); return errors; } diff --git a/client/loclass/elite_crack.h b/client/loclass/elite_crack.h index 819d3de47..8b357ac66 100644 --- a/client/loclass/elite_crack.h +++ b/client/loclass/elite_crack.h @@ -124,7 +124,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]); * @brief Test function * @return */ -int testElite(void); +int testElite(bool slowtests); /** Here are some pretty optimal values that can be used to recover necessary data in only diff --git a/pm3test.sh b/pm3test.sh index 8785bf8df..de9134ba1 100755 --- a/pm3test.sh +++ b/pm3test.sh @@ -3,6 +3,12 @@ PM3PATH=$(dirname "$0") cd "$PM3PATH" || exit 1 +if [ "$1" == "long" ]; then + SLOWTESTS=true +else + SLOWTESTS=false +fi + C_RED='\033[0;31m' C_GREEN='\033[0;32m' C_YELLOW='\033[0;33m' @@ -95,9 +101,14 @@ while true; do printf "\n${C_BLUE}Testing HF:${C_NC}\n" if ! CheckExecute "hf mf offline text" "./client/proxmark3 -c 'hf mf'" "at_enc"; then break; fi - if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi - if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "verified ok"; then break; fi - if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi + if $SLOWTESTS; then + if ! CheckExecute "hf mf hardnested test" "./client/proxmark3 -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi + if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t l'" "verified ok"; then break; fi + if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test -l'" "Test(s) \[ OK"; then break; fi + else + if ! CheckExecute "hf iclass test" "./client/proxmark3 -c 'hf iclass loclass t'" "OK!"; then break; fi + if ! CheckExecute "emv test" "./client/proxmark3 -c 'emv test'" "Test(s) \[ OK"; then break; fi + fi printf "\n${C_BLUE}Testing tools:${C_NC}\n" # Need a decent example for mfkey32... From 51f48301c883c85dd97210f8fa9a0984ad7ef506 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 19:09:54 +0200 Subject: [PATCH 28/33] appveyor tests --- appveyor.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a32c6a56a..db9223c17 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -376,13 +376,14 @@ test_script: ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc" - ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" - - ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok" - - #proxmark crypto tests +# Long tests: +# ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" +# ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok" +# ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK" +# Short tests: + ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "OK!" ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK" From d395bda489261e1d737e60103037125b652a416e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 19:20:59 +0200 Subject: [PATCH 29/33] yaml comments... --- appveyor.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index db9223c17..a817ff1ac 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -378,11 +378,11 @@ test_script: #proxmark crypto tests -# Long tests: -# ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" -# ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok" -# ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK" -# Short tests: + # Long tests: + # ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:" + # ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t l'"} "verified ok" + # ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i -l'"} "Test?s? ? OK" + # Short tests: ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "OK!" ExecTest "emv test" "emv test" {bash -lc "cd ~/client;./proxmark3 -c 'emv test -i'"} "Test?s? ? OK" From d46edd9a53d917a97b742def167a7870633adf8a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 20:22:17 +0200 Subject: [PATCH 30/33] change is_* return to bool --- client/fileutils.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/fileutils.c b/client/fileutils.c index 35fa735ea..6efe4c17b 100644 --- a/client/fileutils.c +++ b/client/fileutils.c @@ -74,15 +74,15 @@ int fileExists(const char *filename) { * @param filename * @return */ -int is_regular_file(const char *filename) { +bool is_regular_file(const char *filename) { #ifdef _WIN32 struct _stat st; _stat(filename, &st); - return S_ISREG(st.st_mode); + return S_ISREG(st.st_mode) != 0; #else struct stat st; stat(filename, &st); - return S_ISREG(st.st_mode); + return S_ISREG(st.st_mode) != 0; #endif } /** @@ -90,15 +90,15 @@ int is_regular_file(const char *filename) { * @param filename * @return */ -int is_directory(const char *filename) { +bool is_directory(const char *filename) { #ifdef _WIN32 struct _stat st; _stat(filename, &st); - return S_ISDIR(st.st_mode); + return S_ISDIR(st.st_mode) != 0; #else struct stat st; stat(filename, &st); - return S_ISDIR(st.st_mode); + return S_ISDIR(st.st_mode) != 0; #endif } @@ -1053,7 +1053,7 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con if (searchname == NULL || strlen(searchname) == 0) return PM3_EINVARG; - if (is_directory(searchname) != 0) + if (is_directory(searchname)) return PM3_EINVARG; From 00344adfd392fdb6de653fd5efd9ef8c9a0f16f5 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 21 Sep 2019 13:25:28 -0500 Subject: [PATCH 31/33] subtle change for clarity Both interface-raspberrypi.cfg and interface-raspberrypi2.cfg gave conflicting instructions for the dd return value. This should clear that up. --- tools/jtag_openocd/interface-raspberrypi2.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jtag_openocd/interface-raspberrypi2.cfg b/tools/jtag_openocd/interface-raspberrypi2.cfg index b779cd290..dc97479d5 100644 --- a/tools/jtag_openocd/interface-raspberrypi2.cfg +++ b/tools/jtag_openocd/interface-raspberrypi2.cfg @@ -17,7 +17,7 @@ interface bcm2835gpio # This file is meant for recent versions of Raspberry Pi # You can check yours with: # dd if=/proc/device-tree/soc/ranges bs=4 skip=1 count=1 2>/dev/null|xxd -p -# if it returns 20000000, use interface-raspberrypi2.cfg +# if it returns 20000000, use interface-raspberrypi.cfg # if it returns 3F000000, you're fine bcm2835gpio_peripheral_base 0x3F000000 From 6422cc6d132c37d1cfdb9717fd31e9c5ae266bcc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 23:25:21 +0200 Subject: [PATCH 32/33] Fix mfc gen1b/gen1b detection --- armsrc/mifarecmd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 089a320ad..e07b59795 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1997,11 +1997,8 @@ void MifareCIdent() { // Generation 1 test ReaderTransmitBitsPar(wupC1, 7, NULL, NULL); - - if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - + if (ReaderReceive(rec, recpar) && (rec[0] == 0x0a)) { ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { isGen = GEN_1B; goto OUT; @@ -2017,7 +2014,7 @@ void MifareCIdent() { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - Dbprintf("cident AA55C396 == %08X", cuid); +// Dbprintf("cident AA55C396 == %08X", cuid); if (cuid == 0xAA55C396) { isGen = GEN_UNFUSED; goto OUT; From 11dcc4787d1dd0c9f7dce64cce92503c791283a4 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 21 Sep 2019 23:50:32 +0200 Subject: [PATCH 33/33] mfc magic: add some defines --- armsrc/mifarecmd.c | 16 +++++----------- client/mifare/mifarehost.c | 8 ++++---- include/protocols.h | 5 +++++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e07b59795..4a469e6e1 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1977,11 +1977,6 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } void MifareCIdent() { -#define GEN_1A 1 -#define GEN_1B 2 -#define GEN_2 4 -#define GEN_UNFUSED 5 - // variables uint8_t isGen = 0; uint8_t rec[1] = {0x00}; @@ -2000,10 +1995,10 @@ void MifareCIdent() { if (ReaderReceive(rec, recpar) && (rec[0] == 0x0a)) { ReaderTransmit(wupC2, sizeof(wupC2), NULL); if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) { - isGen = GEN_1B; + isGen = MAGIC_GEN_1B; goto OUT; }; - isGen = GEN_1A; + isGen = MAGIC_GEN_1A; goto OUT; } @@ -2014,20 +2009,19 @@ void MifareCIdent() { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { -// Dbprintf("cident AA55C396 == %08X", cuid); if (cuid == 0xAA55C396) { - isGen = GEN_UNFUSED; + isGen = MAGIC_GEN_UNFUSED; goto OUT; } ReaderTransmit(rats, sizeof(rats), NULL); res = ReaderReceive(buf, par); if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) { - isGen = GEN_2; + isGen = MAGIC_GEN_2; goto OUT; } if (memcmp(buf, "\x0D\x78\x00\x71\x02\x88\x49\xA1\x30\x20\x15\x06\x08\x56\x3D", 15) == 0) { - isGen = GEN_2; + isGen = MAGIC_GEN_2; } }; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 429605a4e..e4cec00c0 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -1033,16 +1033,16 @@ void detect_classic_magic(void) { } switch (isGeneration) { - case 1: + case MAGIC_GEN_1A: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1a): " _GREEN_("YES")); break; - case 2: + case MAGIC_GEN_1B: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 1b): " _GREEN_("YES")); break; - case 4: + case MAGIC_GEN_2: PrintAndLogEx(SUCCESS, "Answers to magic commands (GEN 2 / CUID): " _GREEN_("YES")); break; - case 5: + case MAGIC_GEN_UNFUSED: PrintAndLogEx(SUCCESS, "Answers to magic commands (Write Once / FUID): " _GREEN_("YES")); break; default: diff --git a/include/protocols.h b/include/protocols.h index 9b47266c3..747e4e346 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -205,6 +205,11 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MAGIC_WIPE 0x40 #define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E +// by CMD_HF_MIFARE_CIDENT +#define MAGIC_GEN_1A 1 +#define MAGIC_GEN_1B 2 +#define MAGIC_GEN_2 4 +#define MAGIC_GEN_UNFUSED 5 /** 06 00 = INITIATE 0E xx = SELECT ID (xx = Chip-ID)