-
- 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 keyNo = 0;
+ bool errors = false;
+
+ char cmdp = param_getchar(Cmd, 0);
+
+ //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 *key = default_3des_keys[keyNo];
+ if (try3DesAuthentication(key)>0)
+ PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 16));
+ else
+ PrintAndLog("Authentication failed");
+
+ return 0;
+}
+
+int try3DesAuthentication( uint8_t *key){
+
+ uint8_t blockNo = 0;
+ uint32_t cuid = 0;
+
+ des3_context ctx = { 0 };
+
+ uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
+ uint8_t random_b[8] = { 0 };
+ uint8_t enc_random_b[8] = { 0 };
+ uint8_t rnd_ab[16] = { 0 };
+ uint8_t iv[8] = { 0 };
+
+ UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
+ SendCommand(&c);
+ UsbCommand resp;
+ if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return -1;
+ if ( !(resp.arg[0] & 0xff) ) return -2;
+
+ cuid = resp.arg[1];
+ memcpy(enc_random_b,resp.d.asBytes+1,8);
+
+ des3_set2key_dec(&ctx, key);
+ // context, mode, length, IV, input, output
+ des3_crypt_cbc( &ctx, DES_DECRYPT, sizeof(random_b), iv , enc_random_b , random_b);
+
+ rol(random_b,8);
+ memcpy(rnd_ab ,random_a,8);
+ memcpy(rnd_ab+8,random_b,8);
+
+ //PrintAndLog(" RndA :%s", sprint_hex(random_a, 8));
+ //PrintAndLog(" enc(RndB) :%s", sprint_hex(enc_random_b, 8));
+ //PrintAndLog(" RndB :%s", sprint_hex(random_b, 8));
+ //PrintAndLog(" A+B :%s", sprint_hex(rnd_ab, 16));
+
+ des3_set2key_enc(&ctx, key);
+ // context, mode, length, IV, input, output
+ des3_crypt_cbc(&ctx, DES_ENCRYPT, sizeof(rnd_ab), enc_random_b, rnd_ab, rnd_ab);
+
+ //Auth2
+ c.cmd = CMD_MIFAREUC_AUTH2;
+ c.arg[0] = cuid;
+ memcpy(c.d.asBytes, rnd_ab, 16);
+ SendCommand(&c);
+
+ if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
+ if ( !(resp.arg[0] & 0xff)) return -2;
+
+ uint8_t enc_resp[8] = { 0 };
+ uint8_t resp_random_a[8] = { 0 };
+ memcpy(enc_resp, resp.d.asBytes+1, 8);
+
+ des3_set2key_dec(&ctx, key);
+ // context, mode, length, IV, input, output
+ des3_crypt_cbc( &ctx, DES_DECRYPT, 8, enc_random_b, enc_resp, resp_random_a);
+
+ //PrintAndLog(" enc(A+B) :%s", sprint_hex(rnd_ab, 16));
+ //PrintAndLog(" enc(RndA') :%s", sprint_hex(enc_resp, 8));
+
+ if ( !memcmp(resp_random_a, random_a, 8))
+ return 1;
+ return 0;
+}
+
+/**
+A test function to validate that the polarssl-function works the same
+was as the openssl-implementation.
+Commented out, since it requires openssl
+
+int CmdTestDES(const char * cmd)
+{
+ uint8_t key[16] = {0x00};
+
+ memcpy(key,key3_3des_data,16);
+ DES_cblock RndA, RndB;
+
+ PrintAndLog("----------OpenSSL DES implementation----------");
+ {
+ uint8_t e_RndB[8] = {0x00};
+ unsigned char RndARndB[16] = {0x00};
+
+ DES_cblock iv = { 0 };
+ DES_key_schedule ks1,ks2;
+ DES_cblock key1,key2;
+
+ 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);
+
+ DES_random_key(&RndA);
+ PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
+ PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
+ //void DES_ede2_cbc_encrypt(const unsigned char *input,
+ // unsigned char *output, long length, DES_key_schedule *ks1,
+ // DES_key_schedule *ks2, DES_cblock *ivec, int enc);
+ DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
+
+ PrintAndLog(" RndB:%s",sprint_hex(RndB, 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));
+
+ }
+ PrintAndLog("----------PolarSSL implementation----------");
+ {
+ uint8_t random_a[8] = { 0 };
+ 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 };
+
+ memcpy(random_a, RndA,8);
+
+ uint8_t output[8] = { 0 };
+ uint8_t iv[8] = { 0 };
+
+ PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
+ PrintAndLog(" e_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(" RA+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(RA+B):%s",sprint_hex(random_a_and_b, 16));
+ }
+ return 0;