mirror of
				https://github.com/RfidResearchGroup/proxmark3.git
				synced 2025-11-04 11:38:03 +08:00 
			
		
		
		
	a bunch of minor textual changes, hiding things when no compilation support for it, also fixed the loop in keyroll generation. Added the skeleton SAM command
This commit is contained in:
		
							parent
							
								
									4b64a45899
								
							
						
					
					
						commit
						c5c829bce2
					
				
					 4 changed files with 143 additions and 54 deletions
				
			
		
							
								
								
									
										20
									
								
								CHANGELOG.md
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								CHANGELOG.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,6 +3,8 @@ 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]
 | 
			
		||||
 - Fixed `hf iclass config` - now loops correct in keyroll generation (@iceman1001)
 | 
			
		||||
 - Added `hf iclass sam` - skeleton command (@iceman1001)
 | 
			
		||||
 - Changed `lf cotag demo` - a new decoder (@iceman1001)
 | 
			
		||||
 - Changed `hf legic view/eview/info` - now in verbose mode will print raw hex dump (@iceman1001)
 | 
			
		||||
 - Added new test for cotag demod using data commands in pm3_test.sh (@iceman1001)
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +17,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 | 
			
		|||
 - Added `hf mfp list` - interprets MIFARE Plus commands in traces (@DidierA)
 | 
			
		||||
 - Changed `hf legic sim` - loop and return codes on deviceside updated to DEFINES (@iceman1001)
 | 
			
		||||
 - Changed `hf legic einfo` - now accepts the three different cardsizes as params (@iceman1001)
 | 
			
		||||
 - Fix `lf cotag reader -1` - now doesn't fail (@iceman1001)
 | 
			
		||||
 - Fixed `lf cotag reader -1` - now doesn't fail (@iceman1001)
 | 
			
		||||
 - Added support for LZ4 compressed hadnested tables (@doegox)
 | 
			
		||||
 - Changed `emv reader -v` - now tries to print found transactions logs (@iceman1001)
 | 
			
		||||
 - Added ISO4217 currency lookup (@iceman1001)
 | 
			
		||||
| 
						 | 
				
			
			@ -23,10 +25,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 | 
			
		|||
 - Changed `emv reader -v` - now can decode track1/2 data if found (@iceman1001)
 | 
			
		||||
 - Added `emv reader` - act as a EMV reader (@iceman1001)
 | 
			
		||||
 - Added support for Apple Wallet NFC Passes with the Value Added Services protocol implementation (@gm3197)
 | 
			
		||||
 - Fix compiling liblua on iOS (@The-SamminAter)
 | 
			
		||||
 - Fixed compiling liblua on iOS (@The-SamminAter)
 | 
			
		||||
 - Changed `hf_mf_luxeo_dump.lua` - now have list of keys to iterate (@iceman1001)
 | 
			
		||||
 - Fixed the timeout of TCP connections (@wh201906)
 | 
			
		||||
 - Made the connection timeout configurable (@wh201906)
 | 
			
		||||
 - Changed the connection timeout configurable (@wh201906)
 | 
			
		||||
 | 
			
		||||
## [Seven.4.16717][2023-06-25]
 | 
			
		||||
 - Change `hf 14a info` - now identifes QL88 tags (@iceman1001)
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +45,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 | 
			
		|||
 - Added more default keys (@iceman1001)  Thanks anon!
 | 
			
		||||
 - Fixed `pm3-flash-all` shell script now correctly identify the if running on outdated bootloader (@iceman1001)
 | 
			
		||||
 - Fixed `hf 15693/iclass sniff` trace timings (@nvx)
 | 
			
		||||
 - Fix LegicCash segment handling in `hf_legic.lua` script (@jmichelp)
 | 
			
		||||
 - Fixed LegicCash segment handling in `hf_legic.lua` script (@jmichelp)
 | 
			
		||||
 - Fixed `trace list` - now handles marking of crc bytes w color a bit better (@iceman1001)
 | 
			
		||||
 - Changed `hf mfu pwdgen -r` - now generates pwd/pack for Philips Sonicare, thanks @ckuenzi, @atc1441 (@iceman1001)
 | 
			
		||||
 - Changed `hf mfu info` - now detects Philips Sonicare devices (@iceman1001)
 | 
			
		||||
| 
						 | 
				
			
			@ -133,11 +135,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 | 
			
		|||
 - Changed `hf mfu info` - now also does a simple OTP fingerprinting (@iceman1001)
 | 
			
		||||
 - Changed `hf mf wrbl` - now checks for strict readonly ACL's in the data to write (@iceman1001)
 | 
			
		||||
 - Changed `hf mf view` - verbose printing if strict readonly ACL's exists in dump file (@iceman1001)
 | 
			
		||||
 - Add command `piv authsign` to get a buffer signed by the selected key (@jmichelp)
 | 
			
		||||
 - Add command `piv scan` which tries to read all known containers on PIV (@jmichelp)
 | 
			
		||||
 - Add support for PIV commands, over wired and contactless interfaces (@jmichelp)
 | 
			
		||||
 - Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx)
 | 
			
		||||
 - Improved NXP SLI/SLIX series tag identification (@nvx)
 | 
			
		||||
 - Added command `piv authsign` to get a buffer signed by the selected key (@jmichelp)
 | 
			
		||||
 - Added command `piv scan` which tries to read all known containers on PIV (@jmichelp)
 | 
			
		||||
 - Added support for PIV commands, over wired and contactless interfaces (@jmichelp)
 | 
			
		||||
 - Added `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx)
 | 
			
		||||
 - Change and improved NXP SLI/SLIX series tag identification (@nvx)
 | 
			
		||||
 - Fixed buffer overflow in "lf em 4x05 sniff" (@HeinrichsH)
 | 
			
		||||
 - Fixed potential NULL array printing (@jmichelp)
 | 
			
		||||
 - Added PIV aid to resource file (@jmichelp)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,6 @@
 | 
			
		|||
#include "crypto/asn1utils.h"      // ASN1 decoder
 | 
			
		||||
#include "preferences.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PICOPASS_BLOCK_SIZE    8
 | 
			
		||||
#define NUM_CSNS               9
 | 
			
		||||
#define ICLASS_KEYS_MAX        8
 | 
			
		||||
| 
						 | 
				
			
			@ -400,9 +399,10 @@ static int generate_config_card(const iclass_config_card_item_t *o,  uint8_t *ke
 | 
			
		|||
 | 
			
		||||
        // encrypted 0xFF
 | 
			
		||||
        PrintAndLogEx(INFO, "Setting 0xFF's... " NOLF);
 | 
			
		||||
        for (uint8_t i = 0x16; i <= app1_limit; i++) {
 | 
			
		||||
        for (uint16_t i = 0x16; i < (app1_limit + 1); i++) {
 | 
			
		||||
            memcpy(data + (i * 8), ffs, sizeof(ffs));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )");
 | 
			
		||||
 | 
			
		||||
        // revert potential modified app1_limit
 | 
			
		||||
| 
						 | 
				
			
			@ -443,14 +443,14 @@ static void fuse_config(const picopass_hdr_t *hdr) {
 | 
			
		|||
 | 
			
		||||
    uint16_t otp = (hdr->conf.otp[1] << 8 | hdr->conf.otp[0]);
 | 
			
		||||
 | 
			
		||||
    PrintAndLogEx(INFO, "    Raw: " _YELLOW_("%s"), sprint_hex((uint8_t *)&hdr->conf, 8));
 | 
			
		||||
    PrintAndLogEx(INFO, "         " _YELLOW_("%02X") ".....................  app limit", hdr->conf.app_limit);
 | 
			
		||||
    PrintAndLogEx(INFO, "            " _YELLOW_("%04X") " ( %5u )......  OTP", otp, otp);
 | 
			
		||||
    PrintAndLogEx(INFO, "                  " _YELLOW_("%02X") "............  block write lock", hdr->conf.block_writelock);
 | 
			
		||||
    PrintAndLogEx(INFO, "                     " _YELLOW_("%02X") ".........  chip", hdr->conf.chip_config);
 | 
			
		||||
    PrintAndLogEx(INFO, "                        " _YELLOW_("%02X") "......  mem", hdr->conf.mem_config);
 | 
			
		||||
    PrintAndLogEx(INFO, "                           " _YELLOW_("%02X") "...  EAS", hdr->conf.eas);
 | 
			
		||||
    PrintAndLogEx(INFO, "                              " _YELLOW_("%02X") "  fuses", hdr->conf.fuses);
 | 
			
		||||
    PrintAndLogEx(INFO, "    Raw... " _YELLOW_("%s"), sprint_hex((uint8_t *)&hdr->conf, 8));
 | 
			
		||||
    PrintAndLogEx(INFO, "           " _YELLOW_("%02X") " ( %3u ).............  app limit", hdr->conf.app_limit, hdr->conf.app_limit);
 | 
			
		||||
    PrintAndLogEx(INFO, "              " _YELLOW_("%04X") " ( %5u )......  OTP", otp, otp);
 | 
			
		||||
    PrintAndLogEx(INFO, "                    " _YELLOW_("%02X") "............  block write lock", hdr->conf.block_writelock);
 | 
			
		||||
    PrintAndLogEx(INFO, "                       " _YELLOW_("%02X") ".........  chip", hdr->conf.chip_config);
 | 
			
		||||
    PrintAndLogEx(INFO, "                          " _YELLOW_("%02X") "......  mem", hdr->conf.mem_config);
 | 
			
		||||
    PrintAndLogEx(INFO, "                             " _YELLOW_("%02X") "...  EAS", hdr->conf.eas);
 | 
			
		||||
    PrintAndLogEx(INFO, "                                " _YELLOW_("%02X") "  fuses", hdr->conf.fuses);
 | 
			
		||||
 | 
			
		||||
    uint8_t fuses = hdr->conf.fuses;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -594,47 +594,47 @@ static void mem_app_config(const picopass_hdr_t *hdr) {
 | 
			
		|||
    PrintAndLogEx(INFO, " * Kd, Debit key, AA1    Kc, Credit key, AA2 *");
 | 
			
		||||
    uint8_t keyAccess = isset(mem, 0x01);
 | 
			
		||||
    if (keyAccess) {
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA1....... debit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA1...... debit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA2....... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA2...... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA1..... debit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA1.... debit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA2..... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA2.... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Debit........ debit or credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Credit....... credit");
 | 
			
		||||
    } else {
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA1....... debit or credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA1...... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA2....... debit or credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA2...... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA1..... debit or credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA1.... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Read AA2..... debit or credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Write AA2.... credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Debit........ debit or credit");
 | 
			
		||||
        PrintAndLogEx(INFO, "    Credit....... credit");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_picopass_info(const picopass_hdr_t *hdr) {
 | 
			
		||||
    PrintAndLogEx(INFO, "-------------------- " _CYAN_("card configuration") " --------------------");
 | 
			
		||||
    PrintAndLogEx(INFO, "-------------------- " _CYAN_("Card configuration") " --------------------");
 | 
			
		||||
    fuse_config(hdr);
 | 
			
		||||
    mem_app_config(hdr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_picopass_header(const picopass_hdr_t *hdr) {
 | 
			
		||||
    PrintAndLogEx(INFO, "--------------------------- " _CYAN_("card") " ---------------------------");
 | 
			
		||||
    PrintAndLogEx(SUCCESS, "    CSN: " _GREEN_("%s") " uid", sprint_hex(hdr->csn, sizeof(hdr->csn)));
 | 
			
		||||
    PrintAndLogEx(SUCCESS, " Config: %s Card configuration", sprint_hex((uint8_t *)&hdr->conf, sizeof(hdr->conf)));
 | 
			
		||||
    PrintAndLogEx(SUCCESS, "E-purse: %s Card challenge, CC", sprint_hex(hdr->epurse, sizeof(hdr->epurse)));
 | 
			
		||||
    PrintAndLogEx(INFO, "--------------------------- " _CYAN_("Card") " ---------------------------");
 | 
			
		||||
    PrintAndLogEx(SUCCESS, "    CSN... " _GREEN_("%s") " uid", sprint_hex(hdr->csn, sizeof(hdr->csn)));
 | 
			
		||||
    PrintAndLogEx(SUCCESS, " Config... %s card configuration", sprint_hex((uint8_t *)&hdr->conf, sizeof(hdr->conf)));
 | 
			
		||||
    PrintAndLogEx(SUCCESS, "E-purse... %s card challenge, CC", sprint_hex(hdr->epurse, sizeof(hdr->epurse)));
 | 
			
		||||
 | 
			
		||||
    if (memcmp(hdr->key_d, zeros, sizeof(zeros)) && memcmp(hdr->key_d, empty, sizeof(empty))) {
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kd: " _YELLOW_("%s") " debit key", sprint_hex(hdr->key_d, sizeof(hdr->key_d)));
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kd... " _YELLOW_("%s") " debit key", sprint_hex(hdr->key_d, sizeof(hdr->key_d)));
 | 
			
		||||
    } else {
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kd: %s debit key ( hidden )", sprint_hex(hdr->key_d, sizeof(hdr->key_d)));
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kd... %s debit key ( hidden )", sprint_hex(hdr->key_d, sizeof(hdr->key_d)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (memcmp(hdr->key_c, zeros, sizeof(zeros)) && memcmp(hdr->key_c, empty, sizeof(empty))) {
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kc: " _YELLOW_("%s") " credit key", sprint_hex(hdr->key_c, sizeof(hdr->key_c)));
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kc... " _YELLOW_("%s") " credit key", sprint_hex(hdr->key_c, sizeof(hdr->key_c)));
 | 
			
		||||
    } else {
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kc: %s credit key ( hidden )", sprint_hex(hdr->key_c, sizeof(hdr->key_c)));
 | 
			
		||||
        PrintAndLogEx(SUCCESS, "     Kc... %s credit key ( hidden )", sprint_hex(hdr->key_c, sizeof(hdr->key_c)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PrintAndLogEx(SUCCESS, "    AIA: %s Application Issuer area", sprint_hex(hdr->app_issuer_area, sizeof(hdr->app_issuer_area)));
 | 
			
		||||
    PrintAndLogEx(SUCCESS, "    AIA... %s application issuer area", sprint_hex(hdr->app_issuer_area, sizeof(hdr->app_issuer_area)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CmdHFiClassList(const char *Cmd) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2469,7 +2469,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
 | 
			
		|||
        return PM3_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    // crypto helper available.
 | 
			
		||||
    PrintAndLogEx(INFO, "----------------------------- " _CYAN_("cardhelper") " -----------------------------");
 | 
			
		||||
    PrintAndLogEx(INFO, "----------------------------- " _CYAN_("Cardhelper") " -----------------------------");
 | 
			
		||||
 | 
			
		||||
    switch (blockno) {
 | 
			
		||||
        case 6: {
 | 
			
		||||
| 
						 | 
				
			
			@ -2509,7 +2509,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
 | 
			
		|||
 | 
			
		||||
                PrintAndLogEx(SUCCESS, "      bin : %s", pbin);
 | 
			
		||||
                PrintAndLogEx(INFO, "");
 | 
			
		||||
                PrintAndLogEx(INFO, "------------------------------ " _CYAN_("wiegand") " -------------------------------");
 | 
			
		||||
                PrintAndLogEx(INFO, "------------------------------ " _CYAN_("Wiegand") " -------------------------------");
 | 
			
		||||
                wiegand_message_t packed = initialize_message_object(top, mid, bot, 0);
 | 
			
		||||
                HIDTryUnpack(&packed);
 | 
			
		||||
            } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -4147,6 +4147,48 @@ static int CmdHFiClassConfigCard(const char *Cmd) {
 | 
			
		|||
    return PM3_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CmdHFiClassSAM(const char *Cmd) {
 | 
			
		||||
    CLIParserContext *ctx;
 | 
			
		||||
    CLIParserInit(&ctx, "hf iclass sam",
 | 
			
		||||
                  "Manage via SAM\n",
 | 
			
		||||
                  "hf iclass sam\n"
 | 
			
		||||
                 );
 | 
			
		||||
 | 
			
		||||
    void *argtable[] = {
 | 
			
		||||
        arg_param_begin,
 | 
			
		||||
        arg_str0("d", "data", "<hex>", "data"),
 | 
			
		||||
        arg_lit0("v", "verbose", "verbose output"),
 | 
			
		||||
        arg_param_end
 | 
			
		||||
    };
 | 
			
		||||
    CLIExecWithReturn(ctx, Cmd, argtable, true);
 | 
			
		||||
    int dlen = 0;
 | 
			
		||||
    uint8_t data[128] = {0};
 | 
			
		||||
    CLIGetHexWithReturn(ctx, 1, data, &dlen);
 | 
			
		||||
 | 
			
		||||
    bool verbose = arg_get_lit(ctx, 2);
 | 
			
		||||
    CLIParserFree(ctx);
 | 
			
		||||
 | 
			
		||||
    Iso7816CommandChannel channel = CC_CONTACT;
 | 
			
		||||
    if (IfPm3Smartcard() == false) {
 | 
			
		||||
        if (channel == CC_CONTACT) {
 | 
			
		||||
            PrintAndLogEx(WARNING, "PM3 does not have SMARTCARD support, exiting");
 | 
			
		||||
            return PM3_EDEVNOTSUPP;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int res = IsHIDSamPresent(verbose);
 | 
			
		||||
    if (res != PM3_SUCCESS) {
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SetAPDULogging(verbose);
 | 
			
		||||
 | 
			
		||||
// do things with sending apdus..
 | 
			
		||||
 | 
			
		||||
    SetAPDULogging(false);
 | 
			
		||||
    return PM3_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static command_t CommandTable[] = {
 | 
			
		||||
    {"-----------", CmdHelp,                    AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"},
 | 
			
		||||
    {"help",        CmdHelp,                    AlwaysAvailable, "This help"},
 | 
			
		||||
| 
						 | 
				
			
			@ -4156,7 +4198,7 @@ static command_t CommandTable[] = {
 | 
			
		|||
    {"list",        CmdHFiClassList,            AlwaysAvailable, "List iclass history"},
 | 
			
		||||
    {"rdbl",        CmdHFiClass_ReadBlock,      IfPm3Iclass,     "Read Picopass / iCLASS block"},
 | 
			
		||||
    {"reader",      CmdHFiClassReader,          IfPm3Iclass,     "Act like a Picopass / iCLASS reader"},
 | 
			
		||||
    {"restore",     CmdHFiClassRestore,        IfPm3Iclass,      "Restore a dump file onto a Picopass / iCLASS tag"},
 | 
			
		||||
    {"restore",     CmdHFiClassRestore,         IfPm3Iclass,      "Restore a dump file onto a Picopass / iCLASS tag"},
 | 
			
		||||
    {"sniff",       CmdHFiClassSniff,           IfPm3Iclass,     "Eavesdrop Picopass / iCLASS communication"},
 | 
			
		||||
    {"wrbl",        CmdHFiClass_WriteBlock,     IfPm3Iclass,     "Write Picopass / iCLASS block"},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4165,7 +4207,7 @@ static command_t CommandTable[] = {
 | 
			
		|||
    {"chk",         CmdHFiClassCheckKeys,       IfPm3Iclass,     "Check keys"},
 | 
			
		||||
    {"loclass",     CmdHFiClass_loclass,        AlwaysAvailable, "Use loclass to perform bruteforce reader attack"},
 | 
			
		||||
    {"lookup",      CmdHFiClassLookUp,          AlwaysAvailable, "Uses authentication trace to check for key in dictionary file"},
 | 
			
		||||
    {"-----------", CmdHelp,                    AlwaysAvailable, "--------------------- " _CYAN_("simulation") " ---------------------"},
 | 
			
		||||
    {"-----------", CmdHelp,                    IfPm3Iclass,     "--------------------- " _CYAN_("simulation") " ---------------------"},
 | 
			
		||||
    {"sim",         CmdHFiClassSim,             IfPm3Iclass,     "Simulate iCLASS tag"},
 | 
			
		||||
    {"eload",       CmdHFiClassELoad,           IfPm3Iclass,     "Load Picopass / iCLASS dump file into emulator memory"},
 | 
			
		||||
    {"esave",       CmdHFiClassESave,           IfPm3Iclass,     "Save emulator memory to file"},
 | 
			
		||||
| 
						 | 
				
			
			@ -4180,6 +4222,8 @@ static command_t CommandTable[] = {
 | 
			
		|||
    {"managekeys",  CmdHFiClassManageKeys,      AlwaysAvailable, "Manage keys to use with iclass commands"},
 | 
			
		||||
    {"permutekey",  CmdHFiClassPermuteKey,      AlwaysAvailable, "Permute function from 'heart of darkness' paper"},
 | 
			
		||||
    {"view",        CmdHFiClassView,            AlwaysAvailable, "Display content from tag dump file"},
 | 
			
		||||
    {"-----------", CmdHelp,                    IfPm3Smartcard,  "--------------------- " _CYAN_("SAM") " ---------------------"},
 | 
			
		||||
    {"sam",         CmdHFiClassSAM,             IfPm3Smartcard,  "SAM tests"},
 | 
			
		||||
    {NULL, NULL, NULL, NULL}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,26 +35,68 @@
 | 
			
		|||
// look for CardHelper
 | 
			
		||||
bool IsCardHelperPresent(bool verbose) {
 | 
			
		||||
 | 
			
		||||
    if (IfPm3Smartcard()) {
 | 
			
		||||
        int resp_len = 0;
 | 
			
		||||
        uint8_t version[] = {0x96, 0x69, 0x00, 0x00, 0x00};
 | 
			
		||||
        uint8_t resp[30] = {0};
 | 
			
		||||
        ExchangeAPDUSC(verbose, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len);
 | 
			
		||||
    if (IfPm3Smartcard() == false) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        if (resp_len < 8) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    int resp_len = 0;
 | 
			
		||||
    uint8_t version[] = {0x96, 0x69, 0x00, 0x00, 0x00};
 | 
			
		||||
    uint8_t resp[30] = {0};
 | 
			
		||||
    ExchangeAPDUSC(verbose, version, sizeof(version), true, true, resp, sizeof(resp), &resp_len);
 | 
			
		||||
 | 
			
		||||
        if (strstr("CryptoHelper", (char *)resp) == 0) {
 | 
			
		||||
            if (verbose) {
 | 
			
		||||
                PrintAndLogEx(INFO, "Found smart card helper");
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
    if (resp_len < 8) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strstr("CryptoHelper", (char *)resp) == 0) {
 | 
			
		||||
        if (verbose) {
 | 
			
		||||
            PrintAndLogEx(INFO, "Found smart card helper");
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IsHIDSamPresent(bool verbose) {
 | 
			
		||||
 | 
			
		||||
    if (IfPm3Smartcard() == false) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // detect SAM
 | 
			
		||||
    smart_card_atr_t card;
 | 
			
		||||
    smart_select(verbose, &card);
 | 
			
		||||
    if (!card.atr_len) {
 | 
			
		||||
        PrintAndLogEx(ERR, "Can't get ATR from a smart card");
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // SAM identification
 | 
			
		||||
    uint8_t sam_atr[] = {0x3B, 0x95, 0x96, 0x80, 0xB1, 0xFE, 0x55, 0x1F, 0xC7, 0x47, 0x72, 0x61, 0x63, 0x65, 0x13};
 | 
			
		||||
    if (memcmp(card.atr, sam_atr, card.atr_len) < 0) {
 | 
			
		||||
 | 
			
		||||
        uint8_t sam_atr2[] = {0x3b, 0x90, 0x96, 0x91, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0xc7, 0xd4};
 | 
			
		||||
        if (memcmp(card.atr, sam_atr2, card.atr_len) < 0) {
 | 
			
		||||
            if (verbose) {
 | 
			
		||||
                PrintAndLogEx(SUCCESS, "Not detecting a SAM");
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Suspect some SAMs has version name in their ATR
 | 
			
		||||
    uint8_t T0 = card.atr[1];
 | 
			
		||||
    uint8_t K = T0 & 0x0F;
 | 
			
		||||
    if (K > 4 && verbose) {
 | 
			
		||||
        if (byte_strstr(card.atr, card.atr_len, (const uint8_t*)"Grace", 5)> -1) {
 | 
			
		||||
            PrintAndLogEx(SUCCESS, "SAM (Grace) detected");
 | 
			
		||||
        } else if (byte_strstr(card.atr, card.atr_len, (const uint8_t*)"Hopper", 6) > -1) {
 | 
			
		||||
            PrintAndLogEx(SUCCESS, "SAM (Hopper) detected");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool executeCrypto(uint8_t ins, uint8_t *src, uint8_t *dest) {
 | 
			
		||||
    uint8_t cmd[] = {0x96, ins, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 | 
			
		||||
    memcpy(cmd + 5, src, 8);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
#include <ctype.h>
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
bool IsHIDSamPresent(bool verbose);
 | 
			
		||||
bool IsCardHelperPresent(bool verbose);
 | 
			
		||||
bool Encrypt(uint8_t *src, uint8_t *dest);
 | 
			
		||||
bool Decrypt(uint8_t *src, uint8_t *dest);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue