+ return 0;
+}
+
+int hf_iclass_eload_usage()
+{
+ PrintAndLog("Loads iclass tag-dump into emulator memory on device");
+ PrintAndLog("Usage: hf iclass eload f <filename>");
+ PrintAndLog("");
+ PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
+ return 0;
+
+}
+
+int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
+ UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
+ memcpy(c.d.asBytes, data, blocksCount * 16);
+ SendCommand(&c);
+ return 0;
+}
+int CmdHFiClassELoad(const char *Cmd)
+{
+
+ char opt = param_getchar(Cmd, 0);
+ if (strlen(Cmd)<1 || opt == 'h')
+ return hf_iclass_eload_usage();
+
+ //File handling and reading
+ FILE *f;
+ char filename[FILE_PATH_SIZE];
+ if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
+ {
+ f = fopen(filename, "rb");
+ }else{
+ return hf_iclass_eload_usage();
+ }
+
+ if(!f) {
+ PrintAndLog("Failed to read from file '%s'", filename);
+ return 1;
+ }
+
+ fseek(f, 0, SEEK_END);
+ long fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ uint8_t *dump = malloc(fsize);
+
+
+ size_t bytes_read = fread(dump, 1, fsize, f);
+ fclose(f);
+
+ printIclassDumpInfo(dump);
+ //Validate
+
+ if (bytes_read < fsize)
+ {
+ prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize );
+ free(dump);
+ return 1;
+ }
+ //Send to device
+ uint32_t bytes_sent = 0;
+ uint32_t bytes_remaining = bytes_read;
+
+ while(bytes_remaining > 0){
+ uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining);
+ UsbCommand c = {CMD_ICLASS_EML_MEMSET, {bytes_sent,bytes_in_packet,0}};
+ memcpy(c.d.asBytes, dump, bytes_in_packet);
+ SendCommand(&c);
+ bytes_remaining -= bytes_in_packet;
+ bytes_sent += bytes_in_packet;
+ }
+ free(dump);
+ PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent);
+ return 0;
+}
+
+int usage_hf_iclass_decrypt()
+{
+ PrintAndLog("Usage: hf iclass decrypt f <tagdump> o ");
+ PrintAndLog("");
+ PrintAndLog("OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside");
+ PrintAndLog("in the working directory. The file should be 16 bytes binary data");
+ PrintAndLog("");
+ PrintAndLog("example: hf iclass decrypt f tagdump_12312342343.bin");
+ PrintAndLog("");
+ PrintAndLog("OBS! This is pretty stupid implementation, it tries to decrypt every block after block 6. ");
+ PrintAndLog("Correct behaviour would be to decrypt only the application areas where the key is valid,");
+ PrintAndLog("which is defined by the configuration block.");
+ return 1;
+}
+
+int readKeyfile(const char *filename, size_t len, uint8_t* buffer)
+{
+ FILE *f = fopen(filename, "rb");
+ if(!f) {
+ PrintAndLog("Failed to read from file '%s'", filename);
+ return 1;
+ }
+ fseek(f, 0, SEEK_END);
+ long fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ size_t bytes_read = fread(buffer, 1, len, f);
+ fclose(f);
+ if(fsize != len)
+ {
+ PrintAndLog("Warning, file size is %d, expected %d", fsize, len);
+ return 1;
+ }
+ if(bytes_read != len)
+ {
+ PrintAndLog("Warning, could only read %d bytes, expected %d" ,bytes_read, len);
+ return 1;
+ }
+ return 0;
+}
+
+int CmdHFiClassDecrypt(const char *Cmd)
+{
+ uint8_t key[16] = { 0 };
+ if(readKeyfile("iclass_decryptionkey.bin", 16, key))
+ {
+ usage_hf_iclass_decrypt();
+ return 1;
+ }
+ PrintAndLog("Decryption file found... ");
+ char opt = param_getchar(Cmd, 0);
+ if (strlen(Cmd)<1 || opt == 'h')
+ return usage_hf_iclass_decrypt();
+
+ //Open the tagdump-file
+ FILE *f;
+ char filename[FILE_PATH_SIZE];
+ if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
+ {
+ f = fopen(filename, "rb");
+ }else{
+ return usage_hf_iclass_decrypt();
+ }
+
+ fseek(f, 0, SEEK_END);
+ long fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ uint8_t enc_dump[8] = {0};
+ uint8_t *decrypted = malloc(fsize);
+ des3_context ctx = { DES_DECRYPT ,{ 0 } };
+ des3_set2key_dec( &ctx, key);
+ size_t bytes_read = fread(enc_dump, 1, 8, f);
+
+ //Use the first block (CSN) for filename
+ char outfilename[FILE_PATH_SIZE] = { 0 };
+ snprintf(outfilename,FILE_PATH_SIZE,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted",
+ enc_dump[0],enc_dump[1],enc_dump[2],enc_dump[3],
+ enc_dump[4],enc_dump[5],enc_dump[6],enc_dump[7]);
+
+ size_t blocknum =0;
+ while(bytes_read == 8)
+ {
+ if(blocknum < 7)
+ {
+ memcpy(decrypted+(blocknum*8), enc_dump, 8);
+ }else{
+ des3_crypt_ecb(&ctx, enc_dump,decrypted +(blocknum*8) );
+ }
+ printvar("decrypted block", decrypted +(blocknum*8), 8);
+ bytes_read = fread(enc_dump, 1, 8, f);
+ blocknum++;
+ }
+ fclose(f);
+
+ saveFile(outfilename,"bin", decrypted, blocknum*8);
+
+ return 0;