@@ -51,11 +51,6 @@ static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = {
5151};
5252
5353
54- typedef struct iclass_block {
55- uint8_t d [8 ];
56- } iclass_block_t ;
57-
58-
5954// iclass / picopass chip config structures and shared routines
6055typedef struct {
6156 uint8_t app_limit ; //[8]
@@ -882,11 +877,11 @@ static int CmdHFiClassReader_Dump(const char *Cmd) {
882877 if (keyNbr < ICLASS_KEYS_MAX ) {
883878 memcpy (KEY , iClass_Key_Table [keyNbr ], 8 );
884879 } else {
885- PrintAndLog ("\nERROR: Credit KeyNbr is invalid\n" );
880+ PrintAndLog ("\nERROR: Debit KeyNbr is invalid\n" );
886881 errors = true;
887882 }
888883 } else {
889- PrintAndLog ("\nERROR: Credit Key is incorrect length\n" );
884+ PrintAndLog ("\nERROR: Debit Key is incorrect length\n" );
890885 errors = true;
891886 }
892887 cmdp += 2 ;
@@ -925,7 +920,6 @@ static int CmdHFiClassReader_Dump(const char *Cmd) {
925920
926921 // if only credit key is given: try for AA1 as well (not for iclass but for some picopass this will work)
927922 if (!have_debit_key && have_credit_key ) {
928- use_credit_key = true;
929923 memcpy (KEY , CreditKEY , 8 );
930924 }
931925
@@ -959,7 +953,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) {
959953 }
960954
961955 // authenticate with debit key (or credit key if we have no debit key) and get div_key - later store in dump block 3
962- if (!iClass_authenticate (tag_data , KEY , MAC , div_key , use_credit_key , elite , rawkey , NRMAC_replay , verbose )){
956+ if (!iClass_authenticate (tag_data , KEY , MAC , div_key , false , elite , rawkey , NRMAC_replay , verbose )) {
963957 DropField ();
964958 return 0 ;
965959 }
@@ -1098,23 +1092,25 @@ static void usage_hf_iclass_writeblock(void) {
10981092 PrintAndLog (" c : If 'c' is specified, the key set is assumed to be the credit key\n" );
10991093 PrintAndLog (" e : If 'e' is specified, elite computations applied to key" );
11001094 PrintAndLog (" r : If 'r' is specified, no computations applied to key" );
1095+ PrintAndLog (" o : override protection and allow modification of blocks 0...4" );
11011096 PrintAndLog ("Samples:" );
11021097 PrintAndLog (" hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B" );
11031098 PrintAndLog (" hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c" );
1104- PrintAndLog (" hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA n 0 " );
1099+ PrintAndLog (" hf iclass writeblk b 03 d AAAAAAAAAAAAAAAA k 001122334455667B c o " );
11051100}
11061101
11071102
11081103static int CmdHFiClass_WriteBlock (const char * Cmd ) {
1109- uint8_t blockno = 0 ;
1110- uint8_t bldata [8 ]= { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
1111- uint8_t KEY [8 ]= { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 };
1104+ uint8_t blockno = 0 ;
1105+ uint8_t bldata [8 ] = { 0 };
1106+ uint8_t KEY [8 ] = { 0 };
11121107 uint8_t keyNbr = 0 ;
11131108 uint8_t dataLen = 0 ;
11141109 char tempStr [50 ] = {0 };
11151110 bool use_credit_key = false;
11161111 bool elite = false;
11171112 bool rawkey = false;
1113+ bool override_protection = false;
11181114 bool errors = false;
11191115 uint8_t cmdp = 0 ;
11201116
@@ -1174,6 +1170,11 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
11741170 rawkey = true;
11751171 cmdp ++ ;
11761172 break ;
1173+ case 'o' :
1174+ case 'O' :
1175+ override_protection = true;
1176+ cmdp ++ ;
1177+ break ;
11771178 default :
11781179 PrintAndLog ("Unknown parameter '%c'\n" , param_getchar (Cmd , cmdp ));
11791180 errors = true;
@@ -1194,14 +1195,26 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
11941195 usage_hf_iclass_writeblock ();
11951196 return 0 ;
11961197 }
1198+
1199+ if (blockno < 5 ) {
1200+ if (override_protection ) {
1201+ PrintAndLog ("Info: modifying keys, e-purse or configuration block." );
1202+ } else {
1203+ PrintAndLog ("You are going to modify keys, e-purse or configuration block." );
1204+ PrintAndLog ("You must add the 'o' (override) option to confirm that you know what you are doing" );
1205+ return 0 ;
1206+ }
1207+ }
1208+
11971209 int ans = WriteBlock (blockno , bldata , KEY , use_credit_key , elite , rawkey , false, true);
1210+
11981211 DropField ();
11991212 return ans ;
12001213}
12011214
12021215
12031216static void usage_hf_iclass_clone (void ) {
1204- PrintAndLog ("Usage: hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> c e|r" );
1217+ PrintAndLog ("Usage: hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> c e|r o " );
12051218 PrintAndLog ("Options:" );
12061219 PrintAndLog (" f <filename>: specify a filename to clone from" );
12071220 PrintAndLog (" b <Block> : The first block to clone as 2 hex symbols" );
@@ -1210,10 +1223,13 @@ static void usage_hf_iclass_clone(void) {
12101223 PrintAndLog (" c : If 'c' is specified, the key set is assumed to be the credit key\n" );
12111224 PrintAndLog (" e : If 'e' is specified, elite computations applied to key" );
12121225 PrintAndLog (" r : If 'r' is specified, no computations applied to key" );
1226+ PrintAndLog (" o : override protection and allow modification of target blocks 0...4" );
12131227 PrintAndLog ("Samples:" );
12141228 PrintAndLog (" hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e" );
12151229 PrintAndLog (" hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0" );
12161230 PrintAndLog (" hf iclass clone f iclass_tagdump-121345.bin b 06 l 19 k 0 e" );
1231+ PrintAndLog (" hf iclass clone f iclass_tagdump-121345.bin b 06 l 19 k 0 e" );
1232+ PrintAndLog (" hf iclass clone f iclass_tagdump-121345.bin b 03 l 19 k 0 e o" );
12171233}
12181234
12191235
@@ -1229,6 +1245,7 @@ static int CmdHFiClassCloneTag(const char *Cmd) {
12291245 bool use_credit_key = false;
12301246 bool elite = false;
12311247 bool rawkey = false;
1248+ bool override_protection = false;
12321249 bool errors = false;
12331250 uint8_t cmdp = 0 ;
12341251
@@ -1297,6 +1314,11 @@ static int CmdHFiClassCloneTag(const char *Cmd) {
12971314 rawkey = true;
12981315 cmdp ++ ;
12991316 break ;
1317+ case 'o' :
1318+ case 'O' :
1319+ override_protection = true;
1320+ cmdp ++ ;
1321+ break ;
13001322 default :
13011323 PrintAndLog ("Unknown parameter '%c'\n" , param_getchar (Cmd , cmdp ));
13021324 errors = true;
@@ -1313,75 +1335,74 @@ static int CmdHFiClassCloneTag(const char *Cmd) {
13131335 return 0 ;
13141336 }
13151337
1316- FILE * f ;
1317-
1318- iclass_block_t tag_data [USB_CMD_DATA_SIZE /12 ];
1319-
1320- if ((endblock - startblock + 1 )* 12 > USB_CMD_DATA_SIZE ) {
1321- PrintAndLog ("Trying to write too many blocks at once. Max: %d" , USB_CMD_DATA_SIZE /8 );
1338+ if (startblock < 5 ) {
1339+ if (override_protection ) {
1340+ PrintAndLog ("Info: modifying keys, e-purse or configuration block." );
1341+ } else {
1342+ PrintAndLog ("You are going to modify keys, e-purse or configuration block." );
1343+ PrintAndLog ("You must add the 'o' (override) option to confirm that you know what you are doing" );
1344+ return 0 ;
1345+ }
1346+ }
1347+
1348+ if ((endblock - startblock + 1 ) * 12 > USB_CMD_DATA_SIZE ) {
1349+ PrintAndLog ("Trying to write too many blocks at once. Max: %d" , USB_CMD_DATA_SIZE /12 );
13221350 }
1351+
13231352 // file handling and reading
1353+ FILE * f ;
13241354 f = fopen (filename ,"rb" );
13251355 if (!f ) {
13261356 PrintAndLog ("Failed to read from file '%s'" , filename );
13271357 return 1 ;
13281358 }
13291359
1330- if (startblock < 5 ) {
1331- PrintAndLog ("You cannot write key blocks this way. yet... make your start block > 4" );
1332- fclose (f );
1333- return 0 ;
1334- }
1335- // now read data from the file from block 6 --- 19
1336- // ok we will use this struct [data 8 bytes][MAC 4 bytes] for each block calculate all mac number for each data
1337- // then copy to usbcommand->asbytes; the max is 32 - 6 = 24 block 12 bytes each block 288 bytes then we can only accept to clone 21 blocks at the time,
1338- // else we have to create a share memory
1339- int i ;
1360+ uint8_t tag_data [USB_CMD_DATA_SIZE /12 ][8 ];
13401361 fseek (f , startblock * 8 , SEEK_SET );
1341- if (fread (tag_data , sizeof (iclass_block_t ), endblock - startblock + 1 , f ) == 0 ) {
1342- PrintAndLog ("File reading error." );
1343- fclose (f );
1344- return 2 ;
1362+ for (int i = 0 ; i < endblock - startblock + 1 ; i ++ ) {
1363+ if (fread (& tag_data [i ], 1 , 8 , f ) == 0 ) {
1364+ PrintAndLog ("File reading error." );
1365+ fclose (f );
1366+ return 2 ;
1367+ }
13451368 }
13461369
1347- uint8_t MAC [4 ]= {0x00 ,0x00 ,0x00 ,0x00 };
1348- uint8_t div_key [8 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 };
1370+ uint8_t MAC [4 ] = {0x00 , 0x00 , 0x00 , 0x00 };
1371+ uint8_t div_key [8 ] = {0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 };
13491372 uint8_t CSN [8 ];
13501373
1351- if (!iClass_select (CSN , true, false, false ) || !iClass_authenticate (CSN , KEY , MAC , div_key , use_credit_key , elite , rawkey , false, true)) {
1374+ if (!iClass_select (CSN , true, true, true ) || !iClass_authenticate (CSN , KEY , MAC , div_key , use_credit_key , elite , rawkey , false, true)) {
13521375 DropField ();
13531376 return 0 ;
13541377 }
13551378
13561379 UsbCommand w = {CMD_ICLASS_CLONE , {startblock , endblock }};
13571380 uint8_t * ptr ;
1358- // calculate all mac for every the block we will write
1359- for (i = startblock ; i <= endblock ; i ++ ) {
1360- Calc_wb_mac (i , tag_data [i - startblock ].d , div_key , MAC );
1361- // usb command d start pointer = d + (i - 6) * 12
1362- // memcpy(pointer,tag_data[i - 6],8) 8 bytes
1363- // memcpy(pointer + 8,mac,sizoof(mac) 4 bytes;
1364- // next one
1365- ptr = w .d .asBytes + (i - startblock ) * 12 ;
1366- memcpy (ptr , & (tag_data [i - startblock ].d [0 ]), 8 );
1367- memcpy (ptr + 8 ,MAC , 4 );
1381+ // calculate MAC for every block we will write
1382+ for (int i = 0 ; i < endblock - startblock + 1 ; i ++ ) {
1383+ Calc_wb_mac (startblock + i , tag_data [i ], div_key , MAC );
1384+ ptr = w .d .asBytes + i * 12 ;
1385+ memcpy (ptr , tag_data [i ], 8 );
1386+ memcpy (ptr + 8 , MAC , 4 );
13681387 }
1388+
13691389 uint8_t p [12 ];
1370- for ( i = 0 ; i <= endblock - startblock ; i ++ ){
1371- memcpy ( p , w . d . asBytes + ( i * 12 ), 12 );
1372- printf ( "Block |%02x|" , i + startblock );
1373- printf ( " %02x%02x%02x%02x%02x%02x%02x%02x |" , p [ 0 ], p [ 1 ], p [ 2 ], p [ 3 ], p [ 4 ], p [ 5 ], p [ 6 ], p [ 7 ]);
1374- printf ( " MAC |%02x%02x%02x%02x|\n" , p [ 8 ],p [9 ],p [10 ],p [11 ]);
1390+ PrintAndLog ( "Cloning" );
1391+ for ( int i = 0 ; i < endblock - startblock + 1 ; i ++ ){
1392+ memcpy ( p , w . d . asBytes + ( i * 12 ), 12 );
1393+ PrintAndLog ( "Block | %02x| %02x%02x%02x%02x%02x%02x%02x%02x | MAC |%02x%02x%02x%02x|" ,
1394+ i + startblock , p [ 0 ], p [ 1 ], p [ 2 ], p [ 3 ], p [ 4 ], p [ 5 ], p [ 6 ], p [ 7 ], p [ 8 ], p [9 ], p [10 ], p [11 ]);
13751395 }
13761396
13771397 UsbCommand resp ;
13781398 SendCommand (& w );
1379- if (!WaitForResponseTimeout (CMD_ACK ,& resp ,4500 )) {
1399+ if (!WaitForResponseTimeout (CMD_ACK , & resp , 4500 )) {
13801400 PrintAndLog ("Command execute timeout" );
13811401 DropField ();
13821402 return 0 ;
13831403 }
13841404
1405+ DropField ();
13851406 return 1 ;
13861407}
13871408
0 commit comments