From db1780fbc1bc6e7571e40d28ce5fe739e6970084 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 9 Aug 2021 20:06:10 +0300 Subject: [PATCH] chk works --- client/src/cmdhfmfdes.c | 645 ++-------------------------------------- 1 file changed, 30 insertions(+), 615 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index fcf7257d6..4c5b393c1 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -85,8 +85,6 @@ typedef struct mfdes_authinput { uint8_t kdfInput[31]; } PACKED mfdes_authinput_t; -static mfdes_authinput_t currentauth[0xF] = {{.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}, {.keyno = -1}}; - typedef struct mfdes_auth_res { uint8_t sessionkeylen; uint8_t sessionkey[24]; @@ -261,137 +259,6 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { //04 01 01 01 00 1A 05 } -static int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) { - - *result_len = 0; - if (sw) *sw = 0; - - uint16_t isw = 0; - int res = 0; - - if (activate_field) { - DropFieldDesfire(); - msleep(50); - } - - // select? - uint8_t data[APDU_RES_LEN] = {0}; - - // COMPUTE APDU - int datalen = 0; - //if (APDUEncodeS(&apdu, false, IncludeLe ? 0x100 : 0x00, data, &datalen)) { - if (APDUEncodeS(&apdu, false, 0x100, data, &datalen)) { - PrintAndLogEx(ERR, "APDU encoding error."); - return PM3_EAPDU_ENCODEFAIL; - } - - if (GetAPDULogging() || (g_debugMode > 1)) - PrintAndLogEx(SUCCESS, ">>>> %s", sprint_hex(data, datalen)); - - res = ExchangeAPDU14a(data, datalen, activate_field, leavefield_on, result, max_result_len, (int *)result_len); - if (res != PM3_SUCCESS) { - return res; - } - - if (activate_field) { - PrintAndLogEx(DEBUG, "field up"); - tag->rf_field_on = true; - } - - if (GetAPDULogging() || (g_debugMode > 1)) - PrintAndLogEx(SUCCESS, "<<<< %s", sprint_hex(result, *result_len)); - - if (*result_len < 2) { - return PM3_SUCCESS; - } - - *result_len -= 2; - isw = (result[*result_len] << 8) + result[*result_len + 1]; - if (sw) - *sw = isw; - - if (isw != 0x9000 && isw != status(MFDES_S_OPERATION_OK) && isw != status(MFDES_S_SIGNATURE) && isw != status(MFDES_S_ADDITIONAL_FRAME) && isw != status(MFDES_S_NO_CHANGES)) { - if (GetAPDULogging()) { - if (isw >> 8 == 0x61) { - PrintAndLogEx(ERR, "APDU chaining len: 0x%02x -->", isw & 0xff); - } else { - PrintAndLogEx(ERR, "APDU(%02x%02x) ERROR: [0x%4X] %s", apdu.CLA, apdu.INS, isw, GetAPDUCodeDescription(isw >> 8, isw & 0xff)); - return PM3_EAPDU_FAIL; - } - } - return PM3_EAPDU_FAIL; - } - return PM3_SUCCESS; -} - -static int send_desfire_cmd(sAPDU *apdu, bool select, uint8_t *dest, uint32_t *recv_len, uint16_t *sw, uint32_t splitbysize, bool readalldata) { - if (apdu == NULL) { - PrintAndLogEx(DEBUG, "APDU=NULL"); - return PM3_EINVARG; - } - if (sw == NULL) { - PrintAndLogEx(DEBUG, "SW=NULL"); - return PM3_EINVARG; - } - if (recv_len == NULL) { - PrintAndLogEx(DEBUG, "RECV_LEN=NULL"); - return PM3_EINVARG; - } - - *sw = 0; - uint8_t data[255 * 5] = {0x00}; - uint32_t resplen = 0; - uint32_t pos = 0; - uint32_t i = 1; - int res = DESFIRESendApdu(select, true, *apdu, data, sizeof(data), &resplen, sw); - if (res != PM3_SUCCESS) { - PrintAndLogEx(DEBUG, "%s", DesfireGetErrorString(res, sw)); - DropFieldDesfire(); - return res; - } - if (dest != NULL) { - memcpy(dest, data, resplen); - } - - pos += resplen; - if (!readalldata) { - if (*sw == status(MFDES_ADDITIONAL_FRAME)) { - *recv_len = pos; - return PM3_SUCCESS; - } - return res; - } - - while (*sw == status(MFDES_ADDITIONAL_FRAME)) { - apdu->INS = MFDES_ADDITIONAL_FRAME; //0xAF - apdu->Lc = 0; - apdu->P1 = 0; - apdu->P2 = 0; - - res = DESFIRESendApdu(false, true, *apdu, data, sizeof(data), &resplen, sw); - if (res != PM3_SUCCESS) { - PrintAndLogEx(DEBUG, "%s", DesfireGetErrorString(res, sw)); - DropFieldDesfire(); - return res; - } - - if (dest != NULL) { - if (splitbysize) { - memcpy(&dest[i * splitbysize], data, resplen); - i += 1; - } else { - memcpy(&dest[pos], data, resplen); - } - } - pos += resplen; - - if (*sw != status(MFDES_ADDITIONAL_FRAME)) break; - } - - *recv_len = (splitbysize) ? i : pos; - return PM3_SUCCESS; -} - static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) { if (major == 0x00) @@ -442,306 +309,6 @@ static int mfdes_get_info(mfdes_info_res_t *info) { return PM3_SUCCESS; } -static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload) { - // 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) - // 4 different crypto arg1 DES, 3DES, 3K3DES, AES - // 3 different communication modes, PLAIN,MAC,CRYPTO - tag->authenticated_key_no = NOT_YET_AUTHENTICATED; - tag->session_key = NULL; - - mbedtls_aes_context ctx; - - uint8_t keybytes[24]; - // Crypt constants - uint8_t IV[16] = {0x00}; - uint8_t RndA[16] = {0x00}; - uint8_t RndB[16] = {0x00}; - uint8_t encRndB[16] = {0x00}; - uint8_t rotRndB[16] = {0x00}; //RndB' - uint8_t both[32 + 1] = {0x00}; // ek/dk_keyNo(RndA+RndB') - - // Generate Random Value - uint32_t ng = msclock(); - uint32_t value = prng_successor(ng, 32); - num_to_bytes(value, 4, &RndA[0]); - value = prng_successor(ng, 32); - num_to_bytes(value, 4, &RndA[4]); - value = prng_successor(ng, 32); - num_to_bytes(value, 4, &RndA[8]); - value = prng_successor(ng, 32); - num_to_bytes(value, 4, &RndA[12]); - - // Part 1 - memcpy(keybytes, payload->key, payload->keylen); - - struct desfire_key dkey = {0}; - desfirekey_t key = &dkey; - - if (payload->algo == MFDES_ALGO_AES) { - mbedtls_aes_init(&ctx); - Desfire_aes_key_new(keybytes, key); - } else if (payload->algo == MFDES_ALGO_3DES) { - Desfire_3des_key_new_with_version(keybytes, key); - } else if (payload->algo == MFDES_ALGO_DES) { - Desfire_des_key_new(keybytes, key); - } else if (payload->algo == MFDES_ALGO_3K3DES) { - Desfire_3k3des_key_new_with_version(keybytes, key); - } - - if (payload->kdfAlgo == MFDES_KDF_ALGO_AN10922) { - mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen); - PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - } else if (payload->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) { - // We will overrite any provided KDF input since a gallagher specific KDF was requested. - payload->kdfInputLen = 11; - - if (mfdes_kdf_input_gallagher(tag->info.uid, tag->info.uidlen, payload->keyno, tag->selected_application, payload->kdfInput, &payload->kdfInputLen) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); - } - - mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen); - PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen)); - PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - - } - - uint8_t subcommand = MFDES_AUTHENTICATE; - tag->authentication_scheme = AS_LEGACY; - - if (payload->mode == MFDES_AUTH_AES) { - subcommand = MFDES_AUTHENTICATE_AES; - tag->authentication_scheme = AS_NEW; - } else if (payload->mode == MFDES_AUTH_ISO) { - subcommand = MFDES_AUTHENTICATE_ISO; - tag->authentication_scheme = AS_NEW; - } - - uint32_t recv_len = 0; - uint16_t sw = 0; - uint8_t recv_data[256] = {0}; - - if (payload->mode != MFDES_AUTH_PICC) { - // Let's send our auth command - uint8_t data[] = {payload->keyno}; - sAPDU apdu = {0x90, subcommand, 0x00, 0x00, 0x01, data}; - int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false); - if (res != PM3_SUCCESS) { - return 1; - } - } - // else { - /* - cmd[0] = AUTHENTICATE; - cmd[1] = payload->keyno; - len = DesfireAPDU(cmd, 2, resp); - */ - //} - - if (!recv_len) { - return 2; - } - - if (sw != status(MFDES_ADDITIONAL_FRAME)) { - return 3; - } - - uint32_t expectedlen = 8; - if (payload->algo == MFDES_ALGO_AES || payload->algo == MFDES_ALGO_3K3DES) { - expectedlen = 16; - } - - if (recv_len != expectedlen) { - return 4; - } - uint32_t rndlen = recv_len; - - // Part 2 - if (payload->mode != MFDES_AUTH_PICC) { - memcpy(encRndB, recv_data, rndlen); - } else { - memcpy(encRndB, recv_data + 2, rndlen); - } - - // Part 3 - if (payload->algo == MFDES_ALGO_AES) { - if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - return 5; - } - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndB, RndB); - } else if (payload->algo == MFDES_ALGO_DES) - des_decrypt(RndB, encRndB, key->data); - else if (payload->algo == MFDES_ALGO_3DES) - tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 2); - else if (payload->algo == MFDES_ALGO_3K3DES) { - tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 3); - } - - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "encRndB: %s", sprint_hex(encRndB, 8)); - PrintAndLogEx(DEBUG, "RndB: %s", sprint_hex(RndB, 8)); - } - - // - Rotate RndB by 8 bits - memcpy(rotRndB, RndB, rndlen); - rol(rotRndB, rndlen); - - uint8_t encRndA[16] = {0x00}; - - // - Encrypt our response - if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_PICC) { - des_decrypt(encRndA, RndA, key->data); - memcpy(both, encRndA, rndlen); - - for (uint32_t x = 0; x < rndlen; x++) { - rotRndB[x] = rotRndB[x] ^ encRndA[x]; - } - - des_decrypt(encRndB, rotRndB, key->data); - memcpy(both + rndlen, encRndB, rndlen); - } else if (payload->mode == MFDES_AUTH_ISO) { - if (payload->algo == MFDES_ALGO_3DES) { - uint8_t tmp[16] = {0x00}; - memcpy(tmp, RndA, rndlen); - memcpy(tmp + rndlen, rotRndB, rndlen); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, 16)); - } - tdes_nxp_send(tmp, both, 16, key->data, IV, 2); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 16)); - } - } else if (payload->algo == MFDES_ALGO_3K3DES) { - uint8_t tmp[32] = {0x00}; - memcpy(tmp, RndA, rndlen); - memcpy(tmp + rndlen, rotRndB, rndlen); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); - } - tdes_nxp_send(tmp, both, 32, key->data, IV, 3); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); - } - } - } else if (payload->mode == MFDES_AUTH_AES) { - uint8_t tmp[32] = {0x00}; - memcpy(tmp, RndA, rndlen); - memcpy(tmp + rndlen, rotRndB, rndlen); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); - } - if (payload->algo == MFDES_ALGO_AES) { - if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { - return 6; - } - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); - } - } - } - - uint32_t bothlen = 16; - if (payload->algo == MFDES_ALGO_AES || payload->algo == MFDES_ALGO_3K3DES) { - bothlen = 32; - } - if (payload->mode != MFDES_AUTH_PICC) { - sAPDU apdu = {0x90, MFDES_ADDITIONAL_FRAME, 0x00, 0x00, bothlen, both}; - int res = send_desfire_cmd(&apdu, false, recv_data, &recv_len, &sw, 0, false); - if (res != PM3_SUCCESS) { - return 7; - } - } else { - /*cmd[0] = ADDITIONAL_FRAME; - memcpy(cmd + 1, both, 16); - len = DesfireAPDU(cmd, 1 + 16, resp); - - if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Sending auth command %02X " _RED_("failed"),subcommand); - return PM3_ESOFT; - }*/ - } - - if (!recv_len) { - return 8; - } - - if (payload->mode != MFDES_AUTH_PICC) { - if (sw != status(MFDES_S_OPERATION_OK)) { - return 9; - } - } else { - /*if (resp[1] != 0x00) { - PrintAndLogEx(ERR,"Authentication failed. Card timeout."); - return PM3_ESOFT; - }*/ - } - - // Part 4 - // tag->session_key = &default_key; - struct desfire_key *p = realloc(tag->session_key, sizeof(struct desfire_key)); - if (!p) { - PrintAndLogEx(FAILED, "Cannot allocate memory for session keys"); - free(tag->session_key); - return PM3_EMALLOC; - } - tag->session_key = p; - - memset(tag->session_key, 0x00, sizeof(struct desfire_key)); - - Desfire_session_key_new(RndA, RndB, key, tag->session_key); - - if (payload->mode != MFDES_AUTH_PICC) { - memcpy(encRndA, recv_data, rndlen); - } else { - memcpy(encRndA, recv_data + 2, rndlen); - } - - if (payload->mode == MFDES_AUTH_DES || payload->mode == MFDES_AUTH_ISO || payload->mode == MFDES_AUTH_PICC) { - if (payload->algo == MFDES_ALGO_DES) - des_decrypt(encRndA, encRndA, key->data); - else if (payload->algo == MFDES_ALGO_3DES) - tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 2); - else if (payload->algo == MFDES_ALGO_3K3DES) - tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 3); - } else if (payload->mode == MFDES_AUTH_AES) { - if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - return 10; - } - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndA, encRndA); - } - - rol(RndA, rndlen); - for (uint32_t x = 0; x < rndlen; x++) { - if (RndA[x] != encRndA[x]) { - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); - PrintAndLogEx(DEBUG, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); - } - return 11; - } - } - - // If the 3Des key first 8 bytes = 2nd 8 Bytes then we are really using Singe Des - // As such we need to set the session key such that the 2nd 8 bytes = 1st 8 Bytes - if (payload->algo == MFDES_ALGO_3DES) { - if (memcmp(key->data, &key->data[8], 8) == 0) - memcpy(&tag->session_key->data[8], tag->session_key->data, 8); - } - - rpayload->sessionkeylen = payload->keylen; - memcpy(rpayload->sessionkey, tag->session_key->data, rpayload->sessionkeylen); - memset(tag->ivect, 0, MAX_CRYPTO_BLOCK_SIZE); - tag->authenticated_key_no = payload->keyno; - - if (tag->authentication_scheme == AS_NEW) { - cmac_generate_subkeys(tag->session_key, MCD_RECEIVE); - } - return PM3_SUCCESS; -} - /*static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t new_algo, uint8_t *old_key, uint8_t old_algo, uint8_t aes_version) { if (new_key == NULL || old_key == NULL) { @@ -1034,54 +601,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat return PM3_SUCCESS; } -static int handler_desfire_select_application(uint8_t *aid) { - if (g_debugMode > 1) { - if (aid == NULL) { - PrintAndLogEx(ERR, "AID=NULL"); - } - } - if (aid == NULL) { - return PM3_EINVARG; - } - - sAPDU apdu = {0x90, MFDES_SELECT_APPLICATION, 0x00, 0x00, 0x03, aid}; //0x5a - uint32_t recv_len = 0; - uint16_t sw = 0; - - int res = send_desfire_cmd(&apdu, !tag->rf_field_on, NULL, &recv_len, &sw, sizeof(dfname_t), true); - if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, - _RED_(" Can't select AID 0x%X -> %s"), - (aid[2] << 16) + (aid[1] << 8) + aid[0], - DesfireGetErrorString(res, &sw) - ); - DropFieldDesfire(); - return res; - } - memcpy(&tag->selected_application, aid, 3); - return PM3_SUCCESS; -} - -static int handler_desfire_fileids(uint8_t *dest, uint32_t *file_ids_len) { - if (g_debugMode > 1) { - if (dest == NULL) PrintAndLogEx(ERR, "DEST=NULL"); - if (file_ids_len == NULL) PrintAndLogEx(ERR, "FILE_IDS_LEN=NULL"); - } - if (dest == NULL || file_ids_len == NULL) return PM3_EINVARG; - sAPDU apdu = {0x90, MFDES_GET_FILE_IDS, 0x00, 0x00, 0x00, NULL}; //0x6f - uint32_t recv_len = 0; - uint16_t sw = 0; - *file_ids_len = 0; - int res = send_desfire_cmd(&apdu, false, dest, &recv_len, &sw, 0, true); - if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, _RED_(" Can't get file ids -> %s"), DesfireGetErrorString(res, &sw)); - DropFieldDesfire(); - return res; - } - *file_ids_len = recv_len; - return res; -} - static void swap24(uint8_t *data) { if (data == NULL) return; uint8_t tmp = data[0]; @@ -1089,111 +608,6 @@ static void swap24(uint8_t *data) { data[2] = tmp; }; -static int desfire_authenticate(int cmdAuthMode, int cmdAuthAlgo, uint8_t *aid, uint8_t *key, int cmdKeyNo, uint8_t cmdKdfAlgo, uint8_t kdfInputLen, uint8_t *kdfInput, mfdes_auth_res_t *rpayload) { - switch (cmdAuthMode) { - case MFDES_AUTH_DES: - if (cmdAuthAlgo != MFDES_ALGO_DES && cmdAuthAlgo != MFDES_ALGO_3DES) { - PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth des mode"); - return PM3_EINVARG; - } - break; - case MFDES_AUTH_ISO: - if (cmdAuthAlgo != MFDES_ALGO_3DES && cmdAuthAlgo != MFDES_ALGO_3K3DES) { - PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth iso mode"); - return PM3_EINVARG; - } - break; - case MFDES_AUTH_AES: - if (cmdAuthAlgo != MFDES_ALGO_AES) { - PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth aes mode"); - return PM3_EINVARG; - } - break; - case MFDES_AUTH_PICC: - if (cmdAuthAlgo != MFDES_AUTH_DES) { - PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth picc mode"); - return PM3_EINVARG; - } - break; - default: - PrintAndLogEx(WARNING, "Wrong Auth mode (%d) -> (1=normal, 2=iso, 3=aes)", cmdAuthMode); - return PM3_EINVARG; - } - - int keylength = 16; - - switch (cmdAuthAlgo) { - case MFDES_ALGO_3DES: - keylength = 16; - break; - case MFDES_ALGO_3K3DES: - keylength = 24; - break; - case MFDES_ALGO_AES: - keylength = 16; - break; - default: - cmdAuthAlgo = MFDES_ALGO_DES; - keylength = 8; - break; - } - - switch (cmdKdfAlgo) { - case MFDES_KDF_ALGO_AN10922: - // TODO: 2TDEA and 3TDEA keys use an input length of 1-15 bytes - if (cmdAuthAlgo != MFDES_ALGO_AES) { - PrintAndLogEx(FAILED, "Crypto algo not valid for the KDF AN10922 algo."); - return PM3_EINVARG; - } - if (kdfInputLen < 1 || kdfInputLen > 31) { - PrintAndLogEx(FAILED, "KDF AN10922 algo requires an input of length 1-31 bytes."); - return PM3_EINVARG; - } - break; - case MFDES_KDF_ALGO_GALLAGHER: - // TODO: 2TDEA and 3TDEA keys use an input length of 1-15 bytes - if (cmdAuthAlgo != MFDES_ALGO_AES) { - PrintAndLogEx(FAILED, "Crypto algo not valid for the KDF AN10922 algo."); - return PM3_EINVARG; - } - break; - // KDF input arg is ignored as it'll be generated. - case MFDES_KDF_ALGO_NONE: - break; - default: - PrintAndLogEx(WARNING, "KDF algo %d is not supported.", cmdKdfAlgo); - return PM3_EINVARG; - } - - // KEY - int res = handler_desfire_select_application(aid); - if (res != PM3_SUCCESS) return res; - - if (memcmp(aid, "\x00\x00\x00", 3) != 0) { - uint8_t file_ids[33] = {0}; - uint32_t file_ids_len = 0; - res = handler_desfire_fileids(file_ids, &file_ids_len); - if (res != PM3_SUCCESS) return res; - } - - mfdes_authinput_t payload; - payload.keylen = keylength; - memcpy(payload.key, key, keylength); - payload.mode = cmdAuthMode; - payload.algo = cmdAuthAlgo; - payload.keyno = cmdKeyNo; - payload.kdfAlgo = cmdKdfAlgo; - payload.kdfInputLen = kdfInputLen; - memcpy(payload.kdfInput, kdfInput, kdfInputLen); - - int error = handler_desfire_auth(&payload, rpayload); - if (error == PM3_SUCCESS) { - memcpy(¤tauth[payload.keyno], &payload, sizeof(mfdes_authinput_t)); - } - - return error; -} - static int CmdHF14ADesInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes info", @@ -1417,6 +831,7 @@ static void DesFill2bPattern( } static int AuthCheckDesfire(DesfireContext *dctx, + DesfireSecureChannel secureChannel, uint8_t *aid, uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t deskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t aeskeyListLen, @@ -1501,7 +916,6 @@ static int AuthCheckDesfire(DesfireContext *dctx, PrintAndLogEx(NORMAL, ""); } - int error; bool badlen = false; if (des) { @@ -1510,18 +924,18 @@ static int AuthCheckDesfire(DesfireContext *dctx, if (usedkeys[keyno] == 1 && foundKeys[0][keyno][0] == 0) { for (uint32_t curkey = 0; curkey < deskeyListLen; curkey++) { - mfdes_auth_res_t rpayload; - error = desfire_authenticate(MFDES_AUTH_DES, MFDES_ALGO_DES, aid, deskeyList[curkey], keyno, 0, 0, NULL, &rpayload); - if (error == PM3_SUCCESS) { + DesfireSetKeyNoClear(dctx, keyno, T_DES, deskeyList[curkey]); + res = DesfireAuthenticate(dctx, secureChannel, false); + if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "AID 0x%06X, Found DES Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(deskeyList[curkey], 8)); foundKeys[0][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[0][keyno][1], deskeyList[curkey], 8); break; - } else if (error < 7) { + } else if (res < 7) { badlen = true; - DropFieldDesfire(); - res = handler_desfire_select_application(aid); + DropField(); + res = DesfireSelectAIDHex(dctx, curaid, false, 0); if (res != PM3_SUCCESS) { return res; } @@ -1542,18 +956,18 @@ static int AuthCheckDesfire(DesfireContext *dctx, if (usedkeys[keyno] == 1 && foundKeys[1][keyno][0] == 0) { for (uint32_t curkey = 0; curkey < aeskeyListLen; curkey++) { - mfdes_auth_res_t rpayload; - error = desfire_authenticate(MFDES_AUTH_DES, MFDES_ALGO_3DES, aid, aeskeyList[curkey], keyno, 0, 0, NULL, &rpayload); - if (error == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3DES Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); + DesfireSetKeyNoClear(dctx, keyno, T_3DES, deskeyList[curkey]); + res = DesfireAuthenticate(dctx, secureChannel, false); + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 2TDEA Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); foundKeys[1][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[1][keyno][1], aeskeyList[curkey], 16); break; - } else if (error < 7) { + } else if (res < 7) { badlen = true; - DropFieldDesfire(); - res = handler_desfire_select_application(aid); + DropField(); + res = DesfireSelectAIDHex(dctx, curaid, false, 0); if (res != PM3_SUCCESS) { return res; } @@ -1574,18 +988,18 @@ static int AuthCheckDesfire(DesfireContext *dctx, if (usedkeys[keyno] == 1 && foundKeys[2][keyno][0] == 0) { for (uint32_t curkey = 0; curkey < aeskeyListLen; curkey++) { - mfdes_auth_res_t rpayload; - error = desfire_authenticate(MFDES_AUTH_AES, MFDES_ALGO_AES, aid, aeskeyList[curkey], keyno, cmdKdfAlgo, kdfInputLen, kdfInput, &rpayload); - if (error == PM3_SUCCESS) { + DesfireSetKeyNoClear(dctx, keyno, T_AES, deskeyList[curkey]); + res = DesfireAuthenticate(dctx, secureChannel, false); + if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "AID 0x%06X, Found AES Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(aeskeyList[curkey], 16)); foundKeys[2][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[2][keyno][1], aeskeyList[curkey], 16); break; - } else if (error < 7) { + } else if (res < 7) { badlen = true; - DropFieldDesfire(); - res = handler_desfire_select_application(aid); + DropField(); + res = DesfireSelectAIDHex(dctx, curaid, false, 0); if (res != PM3_SUCCESS) { return res; } @@ -1606,18 +1020,18 @@ static int AuthCheckDesfire(DesfireContext *dctx, if (usedkeys[keyno] == 1 && foundKeys[3][keyno][0] == 0) { for (uint32_t curkey = 0; curkey < k3kkeyListLen; curkey++) { - mfdes_auth_res_t rpayload; - error = desfire_authenticate(MFDES_AUTH_ISO, MFDES_ALGO_3K3DES, aid, k3kkeyList[curkey], keyno, 0, 0, NULL, &rpayload); - if (error == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3K3 Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24)); + DesfireSetKeyNoClear(dctx, keyno, T_3K3DES, deskeyList[curkey]); + res = DesfireAuthenticate(dctx, secureChannel, false); + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "AID 0x%06X, Found 3TDEA Key %u : " _GREEN_("%s"), curaid, keyno, sprint_hex(k3kkeyList[curkey], 24)); foundKeys[3][keyno][0] = 0x01; *result = true; memcpy(&foundKeys[3][keyno][1], k3kkeyList[curkey], 16); break; - } else if (error < 7) { + } else if (res < 7) { badlen = true; - DropFieldDesfire(); - res = handler_desfire_select_application(aid); + DropField(); + res = DesfireSelectAIDHex(dctx, curaid, false, 0); if (res != PM3_SUCCESS) { return res; } @@ -1631,7 +1045,7 @@ static int AuthCheckDesfire(DesfireContext *dctx, } } } - DropFieldDesfire(); + DropField(); return PM3_SUCCESS; } @@ -1826,6 +1240,7 @@ static int CmdHF14aDesChk(const char *Cmd) { DesfireSetKdf(&dctx, cmdKDFAlgo, kdfInput, kdfInputLen); DesfireSetCommandSet(&dctx, DCCNativeISO); DesfireSetCommMode(&dctx, DCMPlain); + DesfireSecureChannel secureChannel = DACEV1; // save card UID to dctx DesfireGetCardUID(&dctx); @@ -1855,7 +1270,7 @@ static int CmdHF14aDesChk(const char *Cmd) { uint32_t curaid = (app_ids[x * 3] & 0xFF) + ((app_ids[(x * 3) + 1] & 0xFF) << 8) + ((app_ids[(x * 3) + 2] & 0xFF) << 16); PrintAndLogEx(ERR, "Checking aid 0x%06X...", curaid); - res = AuthCheckDesfire(&dctx, &app_ids[x * 3], deskeyList, deskeyListLen, aeskeyList, aeskeyListLen, k3kkeyList, k3kkeyListLen, cmdKDFAlgo, kdfInputLen, kdfInput, foundKeys, &result, (verbose == false)); + res = AuthCheckDesfire(&dctx, secureChannel, &app_ids[x * 3], deskeyList, deskeyListLen, aeskeyList, aeskeyListLen, k3kkeyList, k3kkeyListLen, cmdKDFAlgo, kdfInputLen, kdfInput, foundKeys, &result, (verbose == false)); if (res == PM3_EOPABORTED) { break; }