Add hf mfu aesauth

This commit is contained in:
Philippe Teuwen 2025-03-19 09:08:36 +01:00
commit c657ddf135
6 changed files with 90 additions and 7 deletions

View file

@ -3,9 +3,10 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Change `hf mfu sim` deny OTP changes with all zeros (@iceman1001) - Added `hf mfu aesauth` based on existing UL AES support (@doegox)
- Changed `hf mfu sim` deny OTP changes with all zeros (@iceman1001)
- Added missing file in CMakeLists.txt (@iceman1001) - Added missing file in CMakeLists.txt (@iceman1001)
- Major update to `lf em 4x70` internals on ARM side; Enabling improved debugging and reliability (@henrygab) - Changed `lf em 4x70` internals on ARM side; Enabling improved debugging and reliability (@henrygab)
- Improved `pcf7931` generic readability of the code. Unified datatypes and added documentation/explainations (@tinooo) - Improved `pcf7931` generic readability of the code. Unified datatypes and added documentation/explainations (@tinooo)
- Improved `lf pcf7931` read code - fixed some checks for more stability (@tinooo) - Improved `lf pcf7931` read code - fixed some checks for more stability (@tinooo)
- Changed `trace list -t seos` - improved annotation (@iceman1001) - Changed `trace list -t seos` - improved annotation (@iceman1001)
@ -19,7 +20,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Changed `mem spiffs tree` - ID is now shown in decimal (@iceman1001) - Changed `mem spiffs tree` - ID is now shown in decimal (@iceman1001)
- Added sample wiegand format 56bit (@iceman1001) - Added sample wiegand format 56bit (@iceman1001)
- Changed Wiegand formats to include number of bits (@iceman1001) - Changed Wiegand formats to include number of bits (@iceman1001)
- Fix compilation warning in hitagS (@iceman1001) - Fixed compilation warning in hitagS (@iceman1001)
- Added new wiegand format H800002 (@jmichelp) - Added new wiegand format H800002 (@jmichelp)
- Changed `Makefile.platform.sample` file - now have clear instructions for generating images for other proxmark3 hardware (@iceman1001) - Changed `Makefile.platform.sample` file - now have clear instructions for generating images for other proxmark3 hardware (@iceman1001)
- Changed `doc/magic_cards_notes.md` - now contains documentation for iKey LLC's MF4 tag (@team-orangeBlue) - Changed `doc/magic_cards_notes.md` - now contains documentation for iKey LLC's MF4 tag (@team-orangeBlue)

View file

@ -483,7 +483,7 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
// send & receive // send & receive
len = mifare_sendcmd(MIFARE_ULAES_AUTH_2, enc_rnd_ab, sizeof(enc_rnd_ab), resp, sizeof(resp), respPar, NULL); len = mifare_sendcmd(MIFARE_ULAES_AUTH_2, enc_rnd_ab, sizeof(enc_rnd_ab), resp, sizeof(resp), respPar, NULL);
if (len != 19) { if (len != 19) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len); if (g_dbglevel >= DBG_INFO) Dbprintf("Cmd Error: %02x - expected 19 got " _RED_("%u"), resp[0], len);
return 0; return 0;
} }
@ -492,7 +492,7 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(random_b), IV, resp + 1, random_b); mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(random_b), IV, resp + 1, random_b);
if (memcmp(random_b, random_a, 16) != 0) { if (memcmp(random_b, random_a, 16) != 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("failed authentication"); if (g_dbglevel >= DBG_INFO) Dbprintf("failed authentication");
return 0; return 0;
} }

View file

@ -3892,6 +3892,69 @@ static int CmdHF14AMfUCAuth(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
//-------------------------------------------------------------------------------
// Ultralight AES Methods
//-------------------------------------------------------------------------------
// Ultralight AES Authentication
//
static int CmdHF14AMfUAESAuth(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfu aesauth",
"Tests AES key on Mifare Ultralight AES tags.\n"
"If no key is specified, null key will be tried.\n"
"Key index 0: DataProtKey (default)\n"
"Key index 1: UIDRetrKey\n"
"Key index 2: OriginalityKey\n",
"hf mfu aesauth\n"
"hf mfu aesauth --key <32 bytes> --index <0..2>"
);
void *argtable[] = {
arg_param_begin,
arg_str0(NULL, "key", "<hex>", "AES key (32 hex bytes)"),
arg_int0("i", "index", "<0..2>", "Key index, default: 0"),
arg_lit0("k", NULL, "Keep field on (only if a key is provided)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int ak_len = 0;
uint8_t authentication_key[32] = {0};
uint8_t *authKeyPtr = authentication_key;
CLIGetHexWithReturn(ctx, 1, authentication_key, &ak_len);
int key_index = arg_get_int_def(ctx, 2, 0);
bool keep_field_on = arg_get_lit(ctx, 3);
CLIParserFree(ctx);
if (ak_len == 0) {
// default to null key
ak_len = 32;
}
if (ak_len != 32) {
PrintAndLogEx(WARNING, "Invalid key length");
return PM3_EINVARG;
}
if (key_index < 0 || key_index > 2) {
PrintAndLogEx(WARNING, "Invalid key index");
return PM3_EINVARG;
}
int result = ulaes_requestAuthentication(authKeyPtr, key_index, !keep_field_on);
const char *key_type[] = { "DataProtKey", "UIDRetrKey", "OriginalityKey" };
if (result == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Authentication with " _YELLOW_("%s") " " _GREEN_("%s") " ( " _GREEN_("ok")" )",
key_type[key_index], sprint_hex_inrow(authKeyPtr, ak_len));
} else {
PrintAndLogEx(WARNING, "Authentication with " _YELLOW_("%s") " ( " _RED_("fail") " )",
key_type[key_index]);
}
return result;
}
/** /**
A test function to validate that the polarssl-function works the same A test function to validate that the polarssl-function works the same
was as the openssl-implementation. was as the openssl-implementation.
@ -5915,6 +5978,7 @@ static command_t CommandTable[] = {
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("operations") " -----------------------"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("operations") " -----------------------"},
{"cauth", CmdHF14AMfUCAuth, IfPm3Iso14443a, "Ultralight-C - Authentication"}, {"cauth", CmdHF14AMfUCAuth, IfPm3Iso14443a, "Ultralight-C - Authentication"},
{"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Ultralight-C - Set 3DES key"}, {"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Ultralight-C - Set 3DES key"},
{"aesauth", CmdHF14AMfUAESAuth, IfPm3Iso14443a, "Ultralight-AES - Authentication"},
{"dump", CmdHF14AMfUDump, IfPm3Iso14443a, "Dump MIFARE Ultralight family tag to binary file"}, {"dump", CmdHF14AMfUDump, IfPm3Iso14443a, "Dump MIFARE Ultralight family tag to binary file"},
{"incr", CmdHF14AMfUIncr, IfPm3Iso14443a, "Increments Ev1/NTAG counter"}, {"incr", CmdHF14AMfUIncr, IfPm3Iso14443a, "Increments Ev1/NTAG counter"},
{"info", CmdHF14AMfUInfo, IfPm3Iso14443a, "Tag information"}, {"info", CmdHF14AMfUInfo, IfPm3Iso14443a, "Tag information"},

View file

@ -430,6 +430,7 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf mfu otptear" }, { 0, "hf mfu otptear" },
{ 0, "hf mfu cauth" }, { 0, "hf mfu cauth" },
{ 0, "hf mfu setpwd" }, { 0, "hf mfu setpwd" },
{ 0, "hf mfu aesauth" },
{ 0, "hf mfu dump" }, { 0, "hf mfu dump" },
{ 0, "hf mfu incr" }, { 0, "hf mfu incr" },
{ 0, "hf mfu info" }, { 0, "hf mfu info" },

View file

@ -7062,6 +7062,22 @@
], ],
"usage": "hf mfp wrp [-hv] -a <hex> [-d <hex>]" "usage": "hf mfp wrp [-hv] -a <hex> [-d <hex>]"
}, },
"hf mfu aesauth": {
"command": "hf mfu aesauth",
"description": "Tests AES key on Mifare Ultralight AES tags. If no key is specified, null key will be tried. Key index 0: DataProtKey (default) Key index 1: UIDRetrKey Key index 2: OriginalityKey",
"notes": [
"hf mfu aesauth",
"hf mfu aesauth --key <32 bytes> --index <0..2>"
],
"offline": false,
"options": [
"-h, --help This help",
"--key <hex> AES key (32 hex bytes)",
"-i, --index <0..2> Key index, default: 0",
"-k Keep field on (only if a key is provided)"
],
"usage": "hf mfu aesauth [-hk] [--key <hex>] [-i <0..2>]"
},
"hf mfu amiibo": { "hf mfu amiibo": {
"command": "hf mfu amiibo", "command": "hf mfu amiibo",
"description": "Tries to read all memory from amiibo tag and decrypt it", "description": "Tries to read all memory from amiibo tag and decrypt it",
@ -13230,8 +13246,8 @@
} }
}, },
"metadata": { "metadata": {
"commands_extracted": 760, "commands_extracted": 761,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2025-03-18T06:54:58" "extracted_on": "2025-03-19T08:33:58"
} }
} }

View file

@ -617,6 +617,7 @@ Check column "offline" for their availability.
|`hf mfu otptear `|N |`Tear-off test on OTP bits` |`hf mfu otptear `|N |`Tear-off test on OTP bits`
|`hf mfu cauth `|N |`Ultralight-C - Authentication` |`hf mfu cauth `|N |`Ultralight-C - Authentication`
|`hf mfu setpwd `|N |`Ultralight-C - Set 3DES key` |`hf mfu setpwd `|N |`Ultralight-C - Set 3DES key`
|`hf mfu aesauth `|N |`Ultralight-AES - Authentication`
|`hf mfu dump `|N |`Dump MIFARE Ultralight family tag to binary file` |`hf mfu dump `|N |`Dump MIFARE Ultralight family tag to binary file`
|`hf mfu incr `|N |`Increments Ev1/NTAG counter` |`hf mfu incr `|N |`Increments Ev1/NTAG counter`
|`hf mfu info `|N |`Tag information` |`hf mfu info `|N |`Tag information`