Merge pull request #1253 from mwalker33/Desfire-Change-Key

Desfire change key
This commit is contained in:
Iceman 2021-04-23 07:06:22 +02:00 committed by GitHub
commit 96e9d0f5cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1155,6 +1155,20 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
// AID == 000000 6bits LSB needs to be 0 // AID == 000000 6bits LSB needs to be 0
key_no &= 0x0F; key_no &= 0x0F;
/*
Desfire treats Des keys as TDes but with the first half = 2nd half
As such, we should be able to convert the Des to TDes then run the code as TDes
*/
if (new_algo == MFDES_ALGO_DES) {
memcpy(&new_key[8],new_key,8);
new_algo = MFDES_ALGO_3DES;
}
if (old_algo == MFDES_ALGO_DES) {
memcpy(&old_key[8],old_key,8);
old_algo = MFDES_ALGO_3DES;
}
/* /*
* Because new crypto methods can be setup only at application creation, * Because new crypto methods can be setup only at application creation,
* changing the card master key to one of them require a key_no tweak. * changing the card master key to one of them require a key_no tweak.
@ -1193,11 +1207,13 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
uint8_t new_key_length = 16; uint8_t new_key_length = 16;
switch (new_algo) { switch (new_algo) {
/*
// We have converted the DES to 3DES above,so this will never hit
case MFDES_ALGO_DES: case MFDES_ALGO_DES:
// double
memcpy(data + cmdcnt + 1, new_key, new_key_length); memcpy(data + cmdcnt + 1, new_key, new_key_length);
memcpy(data + cmdcnt + 1 + new_key_length, new_key, new_key_length); memcpy(data + cmdcnt + 1 + new_key_length, new_key, new_key_length);
break; break;
*/
case MFDES_ALGO_3DES: case MFDES_ALGO_3DES:
case MFDES_ALGO_AES: case MFDES_ALGO_AES:
new_key_length = 16; new_key_length = 16;
@ -1209,9 +1225,6 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
break; break;
} }
if ((tag->authenticated_key_no & 0x0f) != (key_no & 0x0f)) { if ((tag->authenticated_key_no & 0x0f) != (key_no & 0x0f)) {
if (old_key) { if (old_key) {
for (uint32_t n = 0; n < new_key_length; n++) { for (uint32_t n = 0; n < new_key_length; n++) {
@ -1232,7 +1245,10 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
case AS_LEGACY: case AS_LEGACY:
iso14443a_crc_append(data + 1, cmdcnt); iso14443a_crc_append(data + 1, cmdcnt);
cmdcnt += 2; cmdcnt += 2;
iso14443a_crc(new_key, new_key_length, data + cmdcnt);
// iso14443a_crc(new_key, new_key_length, data + cmdcnt);
// Add offset + 1 for key no. at start
iso14443a_crc(new_key, new_key_length, data + 1 + cmdcnt);
cmdcnt += 2; cmdcnt += 2;
break; break;
case AS_NEW: case AS_NEW:
@ -1258,11 +1274,19 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
uint8_t *p = mifare_cryto_preprocess_data(tag, data + 1, (size_t *)&cmdcnt, 0, MDCM_ENCIPHERED | ENC_COMMAND | NO_CRC); uint8_t *p = mifare_cryto_preprocess_data(tag, data + 1, (size_t *)&cmdcnt, 0, MDCM_ENCIPHERED | ENC_COMMAND | NO_CRC);
apdu.Lc = (uint8_t)cmdcnt + 1; apdu.Lc = (uint8_t)cmdcnt + 1;
apdu.data = p; // apdu.data = p;
// the above data pointed to from p did not have the key no. at the start, so copy preprocessed data after the key no.
memcpy (&data[1], p, cmdcnt);
apdu.data = data;
uint32_t recv_len = 0; uint32_t recv_len = 0;
uint16_t sw = 0; uint16_t sw = 0;
int res = send_desfire_cmd(&apdu, true, NULL, &recv_len, &sw, 0, true);
// If we call send_desfire with 2nd option (turn field on), it will turn off then on
// leading to loosing the authentication on the aid, so lets not turn on here.
// int res = send_desfire_cmd(&apdu, true, NULL, &recv_len, &sw, 0, true);
int res = send_desfire_cmd(&apdu, false, NULL, &recv_len, &sw, 0, true);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, _RED_(" Can't change key -> %s"), GetErrorString(res, &sw)); PrintAndLogEx(WARNING, _RED_(" Can't change key -> %s"), GetErrorString(res, &sw));