change key works with lrp

This commit is contained in:
merlokk 2021-08-19 19:32:07 +03:00
commit a567eb9506
3 changed files with 23 additions and 17 deletions

View file

@ -2126,6 +2126,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
"Change crypto algorithm for PICC key is possible, but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete\n" "Change crypto algorithm for PICC key is possible, but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete\n"
"\n" "\n"
"hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00\n" "hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00\n"
"hf mfdes changekey --appisoid df01 -t aes -s lrp --newkeyno 01 -> change key 01 via lrp channel"
"hf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one\n" "hf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one\n"
"hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key\n" "hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key\n"
"hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0\n" "hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0\n"
@ -2144,6 +2145,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"), arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"), arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of application (3 hex bytes, big endian)"), arg_str0(NULL, "aid", "<app id hex>", "Application ID of application (3 hex bytes, big endian)"),
arg_str0(NULL, "appisoid", "<isoid hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
arg_str0(NULL, "oldalgo", "<DES/2TDEA/3TDEA/AES>", "Old key crypto algorithm: DES, 2TDEA, 3TDEA, AES"), arg_str0(NULL, "oldalgo", "<DES/2TDEA/3TDEA/AES>", "Old key crypto algorithm: DES, 2TDEA, 3TDEA, AES"),
arg_str0(NULL, "oldkey", "<old key>", "Old key (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"), arg_str0(NULL, "oldkey", "<old key>", "Old key (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
arg_int0(NULL, "newkeyno", "<keyno>", "Key number for change"), arg_int0(NULL, "newkeyno", "<keyno>", "Key number for change"),
@ -2159,15 +2161,16 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; uint32_t id = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL); DesfireISOSelectWay selectway = ISW6bAID;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
if (res) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
} }
int oldkeytype = dctx.keyType; int oldkeytype = dctx.keyType;
if (CLIGetOptionList(arg_get_str(ctx, 12), DesfireAlgoOpts, &oldkeytype)) { if (CLIGetOptionList(arg_get_str(ctx, 13), DesfireAlgoOpts, &oldkeytype)) {
CLIParserFree(ctx); CLIParserFree(ctx);
return PM3_ESOFT; return PM3_ESOFT;
} }
@ -2175,7 +2178,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
uint8_t oldkey[DESFIRE_MAX_KEY_SIZE] = {0}; uint8_t oldkey[DESFIRE_MAX_KEY_SIZE] = {0};
uint8_t keydata[200] = {0}; uint8_t keydata[200] = {0};
int oldkeylen = sizeof(keydata); int oldkeylen = sizeof(keydata);
CLIGetHexWithReturn(ctx, 13, keydata, &oldkeylen); CLIGetHexWithReturn(ctx, 14, keydata, &oldkeylen);
if (oldkeylen && oldkeylen != desfire_get_key_length(oldkeytype)) { if (oldkeylen && oldkeylen != desfire_get_key_length(oldkeytype)) {
PrintAndLogEx(ERR, "%s old key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts, oldkeytype), desfire_get_key_length(oldkeytype), oldkeylen); PrintAndLogEx(ERR, "%s old key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts, oldkeytype), desfire_get_key_length(oldkeytype), oldkeylen);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -2184,10 +2187,10 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
if (oldkeylen) if (oldkeylen)
memcpy(oldkey, keydata, oldkeylen); memcpy(oldkey, keydata, oldkeylen);
uint8_t newkeynum = arg_get_int_def(ctx, 14, 0); uint8_t newkeynum = arg_get_int_def(ctx, 15, 0);
int newkeytype = oldkeytype; int newkeytype = oldkeytype;
if (CLIGetOptionList(arg_get_str(ctx, 15), DesfireAlgoOpts, &newkeytype)) { if (CLIGetOptionList(arg_get_str(ctx, 16), DesfireAlgoOpts, &newkeytype)) {
CLIParserFree(ctx); CLIParserFree(ctx);
return PM3_ESOFT; return PM3_ESOFT;
} }
@ -2195,7 +2198,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
uint8_t newkey[DESFIRE_MAX_KEY_SIZE] = {0}; uint8_t newkey[DESFIRE_MAX_KEY_SIZE] = {0};
memset(keydata, 0x00, sizeof(keydata)); memset(keydata, 0x00, sizeof(keydata));
int keylen = sizeof(keydata); int keylen = sizeof(keydata);
CLIGetHexWithReturn(ctx, 16, keydata, &keylen); CLIGetHexWithReturn(ctx, 17, keydata, &keylen);
if (keylen && keylen != desfire_get_key_length(newkeytype)) { if (keylen && keylen != desfire_get_key_length(newkeytype)) {
PrintAndLogEx(ERR, "%s new key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts, newkeytype), desfire_get_key_length(newkeytype), keylen); PrintAndLogEx(ERR, "%s new key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts, newkeytype), desfire_get_key_length(newkeytype), keylen);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -2205,7 +2208,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
memcpy(newkey, keydata, keylen); memcpy(newkey, keydata, keylen);
uint32_t newkeyver = 0x100; uint32_t newkeyver = 0x100;
if (CLIGetUint32Hex(ctx, 17, 0x100, &newkeyver, NULL, 1, "Key version must have 1 bytes length")) { if (CLIGetUint32Hex(ctx, 18, 0x100, &newkeyver, NULL, 1, "Key version must have 1 bytes length")) {
CLIParserFree(ctx); CLIParserFree(ctx);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2219,14 +2222,14 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
memcpy(oldkey, dctx.key, desfire_get_key_length(dctx.keyType)); memcpy(oldkey, dctx.key, desfire_get_key_length(dctx.keyType));
} }
if (appid == 0x000000) { if (DesfireMFSelected(selectway, id)) {
PrintAndLogEx(WARNING, "Changing the root aid (0x000000)"); if (verbose)
PrintAndLogEx(WARNING, "Changing the PICC level keys");
PrintAndLogEx(INFO, _CYAN_("Changing PICC key"));
} else {
PrintAndLogEx(INFO, _CYAN_("Changing key for ") _YELLOW_("%s"), DesfireWayIDStr(selectway, id));
} }
if (appid)
PrintAndLogEx(INFO, _CYAN_("Changing key in the application: ") _YELLOW_("%06x"), appid);
else
PrintAndLogEx(INFO, _CYAN_("Changing PICC key"));
PrintAndLogEx(INFO, "auth key %d: %s [%d] %s", dctx.keyNum, CLIGetOptionListStr(DesfireAlgoOpts, dctx.keyType), desfire_get_key_length(dctx.keyType), sprint_hex(dctx.key, desfire_get_key_length(dctx.keyType))); PrintAndLogEx(INFO, "auth key %d: %s [%d] %s", dctx.keyNum, CLIGetOptionListStr(DesfireAlgoOpts, dctx.keyType), desfire_get_key_length(dctx.keyType), sprint_hex(dctx.key, desfire_get_key_length(dctx.keyType)));
PrintAndLogEx(INFO, "changing key number " _YELLOW_("0x%02x") " (%d)", newkeynum, newkeynum); PrintAndLogEx(INFO, "changing key number " _YELLOW_("0x%02x") " (%d)", newkeynum, newkeynum);
PrintAndLogEx(INFO, "old key: %s [%d] %s", CLIGetOptionListStr(DesfireAlgoOpts, oldkeytype), desfire_get_key_length(oldkeytype), sprint_hex(oldkey, desfire_get_key_length(oldkeytype))); PrintAndLogEx(INFO, "old key: %s [%d] %s", CLIGetOptionListStr(DesfireAlgoOpts, oldkeytype), desfire_get_key_length(oldkeytype), sprint_hex(oldkey, desfire_get_key_length(oldkeytype)));
@ -2234,14 +2237,15 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
if (newkeyver < 0x100 || newkeytype == T_AES) if (newkeyver < 0x100 || newkeytype == T_AES)
PrintAndLogEx(INFO, "new key version: 0x%02x", newkeyver & 0x00); PrintAndLogEx(INFO, "new key version: 0x%02x", newkeyver & 0x00);
res = DesfireSelectAndAuthenticate(&dctx, securechann, appid, verbose); res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, false, verbose);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
DropField(); DropField();
PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
return res; return res;
} }
DesfireSetCommMode(&dctx, DCMEncryptedPlain); DesfireSetCommMode(&dctx, DCMEncryptedPlain);
res = DesfireChangeKey(&dctx, (appid == 0x000000) && (newkeynum == 0) && (dctx.keyNum == 0), newkeynum, newkeytype, newkeyver, newkey, oldkeytype, oldkey, true); res = DesfireChangeKey(&dctx, (DesfireMFSelected(selectway, id)) && (newkeynum == 0) && (dctx.keyNum == 0), newkeynum, newkeytype, newkeyver, newkey, oldkeytype, oldkey, true);
if (res == PM3_SUCCESS) { if (res == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Change key " _GREEN_("ok") " "); PrintAndLogEx(SUCCESS, "Change key " _GREEN_("ok") " ");
} else { } else {

View file

@ -2749,7 +2749,7 @@ int DesfireChangeKey(DesfireContext *dctx, bool change_master_key, uint8_t newke
desfire_crc32(nkeybuf, nkeylen, &cdata[cdatalen]); desfire_crc32(nkeybuf, nkeylen, &cdata[cdatalen]);
cdatalen += 4; cdatalen += 4;
} }
} else if (dctx->secureChannel == DACEV2) { } else if (dctx->secureChannel == DACEV2 || dctx->secureChannel == DACLRP) {
// EV2 : <PrevKey XOR Newkey> [<AES NewKeyVer>] // EV2 : <PrevKey XOR Newkey> [<AES NewKeyVer>]
if (newkeynum != dctx->keyNum) { if (newkeynum != dctx->keyNum) {
desfire_crc32(nkeybuf, nkeylen, &cdata[cdatalen]); desfire_crc32(nkeybuf, nkeylen, &cdata[cdatalen]);

View file

@ -152,6 +152,8 @@ static const AllowedChannelModesS AllowedChannelModes[] = {
{MFDES_GET_UID, DACLRP, DCCNative, DCMEncrypted}, {MFDES_GET_UID, DACLRP, DCCNative, DCMEncrypted},
{MFDES_CHANGE_FILE_SETTINGS, DACLRP, DCCNative, DCMEncrypted}, {MFDES_CHANGE_FILE_SETTINGS, DACLRP, DCCNative, DCMEncrypted},
{MFDES_CHANGE_CONFIGURATION, DACLRP, DCCNative, DCMEncrypted}, {MFDES_CHANGE_CONFIGURATION, DACLRP, DCCNative, DCMEncrypted},
{MFDES_CHANGE_KEY, DACLRP, DCCNative, DCMEncryptedPlain},
}; };
#define CMD_HEADER_LEN_ALL 0xffff #define CMD_HEADER_LEN_ALL 0xffff