-
- uint8_t blockNo = 0, keyNo = 0;
- uint8_t e_RndB[8] = {0x00};
- uint32_t cuid = 0;
- unsigned char RndARndB[16] = {0x00};
- uint8_t key[16] = {0x00};
- DES_cblock RndA, RndB;
- DES_cblock iv;
- DES_key_schedule ks1,ks2;
- DES_cblock key1,key2;
-
- //
- memset(iv, 0, 8);
-
- if (strlen(Cmd)<1) {
- PrintAndLog("Usage: hf mfu auth k <key number>");
- PrintAndLog(" sample: hf mfu auth k 0");
- return 0;
- }
-
- //Change key to user defined one
- if (strchr(Cmd,'k') != 0){
- //choose a key
- keyNo = param_get8(Cmd, 1);
- switch(keyNo){
- case 0:
- memcpy(key,key1_blnk_data,16);
- break;
- case 1:
- memcpy(key,key2_defa_data,16);
- break;
- case 2:
- memcpy(key,key4_nfc_data,16);
- break;
- case 3:
- memcpy(key,key5_ones_data,16);
- break;
- default:
- memcpy(key,key3_3des_data,16);
- break;
- }
- }else{
- memcpy(key,key3_3des_data,16);
- }
- memcpy(key1,key,8);
- memcpy(key2,key+8,8);
- DES_set_key((DES_cblock *)key1,&ks1);
- DES_set_key((DES_cblock *)key2,&ks2);
-
- //Auth1
- UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
- SendCommand(&c);
- UsbCommand resp;
- if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
- uint8_t isOK = resp.arg[0] & 0xff;
- cuid = resp.arg[1];
- uint8_t * data= resp.d.asBytes;
-
- if (isOK){
- PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
- memcpy(e_RndB,data+1,8);
- }
- } else {
- PrintAndLog("Command execute timeout");
- }
-
- //Do crypto magic
- DES_random_key(&RndA);
- DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
- PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
- PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
- rol(RndB,8);
- memcpy(RndARndB,RndA,8);
- memcpy(RndARndB+8,RndB,8);
- PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
- DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
- PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
-
- //Auth2
- UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
- memcpy(d.d.asBytes,RndARndB, 16);
- SendCommand(&d);
-
- UsbCommand respb;
- if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
- uint8_t isOK = respb.arg[0] & 0xff;
- uint8_t * data2= respb.d.asBytes;
-
- if (isOK){
- PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
- }
-
- } else {
- PrintAndLog("Command execute timeout");
- }
- return 1;
+
+ uint8_t default_keys[7][16] = {
+ { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
+ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
+ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
+ { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
+ { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },// all ones
+ { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },// all FF
+ { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
+ };
+
+ char cmdp = param_getchar(Cmd, 0);
+
+ uint8_t keyNo = 0;
+ bool errors = false;
+ //Change key to user defined one
+ if (cmdp == 'k' || cmdp == 'K'){
+ keyNo = param_get8(Cmd, 1);
+ if(keyNo > 6) errors = true;
+ }
+
+ if (cmdp == 'h' || cmdp == 'H') {
+ errors = true;
+ }
+
+ if (errors) {
+ PrintAndLog("Usage: hf mfu cauth k <key number>");
+ PrintAndLog(" 0 (default): 3DES standard key");
+ PrintAndLog(" 1 : all 0x00 key");
+ PrintAndLog(" 2 : 0x00-0x0F key");
+ PrintAndLog(" 3 : nfc key");
+ PrintAndLog(" 4 : all 0x01 key");
+ PrintAndLog(" 5 : all 0xff key");
+ PrintAndLog(" 6 : 0x00-0xFF key");
+ PrintAndLog("\n sample : hf mfu cauth k");
+ PrintAndLog(" : hf mfu cauth k 3");
+ return 0;
+ }
+
+ uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
+ //uint8_t enc_random_a[8] = { 0 };
+ uint8_t random_b[8] = { 0 };
+ uint8_t enc_random_b[8] = { 0 };
+ uint8_t random_a_and_b[16] = { 0 };
+ des3_context ctx = { 0 };
+ uint8_t *key = default_keys[keyNo];
+ uint8_t blockNo = 0;
+ uint32_t cuid = 0;
+
+ //Auth1
+ UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
+ SendCommand(&c);
+ UsbCommand resp;
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+ uint8_t isOK = resp.arg[0] & 0xff;
+ cuid = resp.arg[1];
+ uint8_t * data= resp.d.asBytes;
+
+ if (isOK){
+ memcpy(enc_random_b,data+1,8);
+ } else {
+ PrintAndLog("Auth failed");
+ return 2;
+ }
+ } else {
+ PrintAndLog("Command execute timeout");
+ return 1;
+ }
+ uint8_t iv[8] = { 0 };
+
+ PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
+ PrintAndLog(" enc(RndB):%s",sprint_hex(enc_random_b, 8));
+
+ des3_set2key_dec(&ctx, key);
+
+ des3_crypt_cbc(&ctx // des3_context *ctx
+ , DES_DECRYPT // int mode
+ , sizeof(random_b) // size_t length
+ , iv // unsigned char iv[8]
+ , enc_random_b // const unsigned char *input
+ , random_b // unsigned char *output
+ );
+
+ PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
+
+ rol(random_b,8);
+ memcpy(random_a_and_b ,random_a,8);
+ memcpy(random_a_and_b+8,random_b,8);
+
+ PrintAndLog(" A+B:%s",sprint_hex(random_a_and_b, 16));
+
+ des3_set2key_enc(&ctx, key);
+
+ des3_crypt_cbc(&ctx // des3_context *ctx
+ , DES_ENCRYPT // int mode
+ , sizeof(random_a_and_b) // size_t length
+ , enc_random_b // unsigned char iv[8]
+ , random_a_and_b // const unsigned char *input
+ , random_a_and_b // unsigned char *output
+ );
+
+ PrintAndLog("enc(A+B):%s",sprint_hex(random_a_and_b, 16));
+
+ //Auth2
+ UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
+ memcpy(d.d.asBytes,random_a_and_b, 16);
+ SendCommand(&d);
+
+ UsbCommand respb;
+ if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
+ uint8_t isOK = respb.arg[0] & 0xff;
+ uint8_t * data2= respb.d.asBytes;
+
+ if (isOK){
+ PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
+
+ uint8_t foo[8] = { 0 };
+ uint8_t bar[8] = { 0 };
+ memcpy(foo, data2+1, 8);
+ des3_set2key_dec(&ctx, key);
+
+ des3_crypt_cbc(&ctx // des3_context *ctx
+ , DES_DECRYPT // int mode
+ , 8 // size_t length
+ , enc_random_b // unsigned char iv[8]
+ , foo // const unsigned char *input
+ , bar // unsigned char *output
+ );
+
+ PrintAndLog("--> : %s : <-- Should be equal to our RndA",sprint_hex(bar, 8));
+
+
+ } else {
+ return 2;
+ }
+
+ } else {
+ PrintAndLog("Command execute timeout");
+ return 1;
+ }
+ return 0;