diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c2d9cb6c..aff7f4e4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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... ## [unreleased][unreleased] + - Changed `hf mfu info` - should not try pwd against a UL-AES (@iceman1001) - Fixed `hf mfu info` - tag type identification now properly handles 64bits (@iceman1001) - Changed `hf st info` - reworked the output (@iceman1001) - Rename `smart relay` to `smart pcsc` and add support for contact interface (@gm3197) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 57c36490a..832fef61b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1639,6 +1639,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFAREU_READBL: { + MifareUReadBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; } @@ -1646,6 +1647,16 @@ static void PacketReceived(PacketCommandNG *packet) { MifareUC_Auth(packet->oldarg[0], packet->data.asBytes); break; } + case CMD_HF_MIFAREULAES_AUTH: { + struct p { + bool turn_off_field; + uint8_t keyno; + uint8_t key[18]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareUL_AES_Auth(payload->turn_off_field, payload->keyno, payload->key); + break; + } case CMD_HF_MIFAREU_READCARD: { MifareUReadCard(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; @@ -1801,8 +1812,6 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_CIDENT: { - - struct p { uint8_t is_mfc; uint8_t keytype; @@ -2025,7 +2034,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t skipMode; uint8_t skipRatio; } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; uint16_t len = 0; int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len, payload->skipMode, payload->skipRatio); @@ -2059,12 +2068,12 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint32_t new_clk; } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; SmartCardSetClock(payload->new_clk); break; } case CMD_SMART_RAW: { - SmartCardRaw((smart_card_raw_t *)packet->data.asBytes); + SmartCardRaw((smart_card_raw_t *) packet->data.asBytes); break; } case CMD_SMART_UPLOAD: { @@ -2075,7 +2084,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t crc; uint8_t data[400]; } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; uint8_t *mem = BigBuf_get_addr(); memcpy(mem + payload->idx, payload->data, payload->bytes_in_packet); @@ -2094,7 +2103,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t fw_size; uint16_t crc; } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; uint8_t *fwdata = BigBuf_get_addr(); uint8_t a = 0, b = 0; @@ -2139,7 +2148,7 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint32_t waittime; } PACKED; - struct p *payload = (struct p *) &packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; uint16_t available; uint16_t pre_available = 0; @@ -2182,7 +2191,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t waittime; uint8_t data[]; } PACKED; - struct p *payload = (struct p *) &packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; usart_writebuffer_sync(payload->data, packet->length - sizeof(payload)); uint16_t available; @@ -2226,7 +2235,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t baudrate; uint8_t parity; } PACKED; - struct p *payload = (struct p *) &packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; usart_init(payload->baudrate, payload->parity); reply_ng(CMD_USART_CONFIG, PM3_SUCCESS, NULL, 0); break; @@ -2350,7 +2359,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint16_t offset; uint8_t data[PM3_CMD_DATA_SIZE - sizeof(uint8_t) - sizeof(uint16_t)]; } PACKED; - struct p *payload = (struct p *)packet->data.asBytes; + struct p *payload = (struct p *) packet->data.asBytes; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index 2358fa8b1..6bfc19416 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -119,7 +119,56 @@ void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, un } } +void aes128_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8]) { + if (length % 8) return; + mbedtls_aes_setkey_dec(&actx, key, 128); + + uint8_t i; + unsigned char temp[8]; + uint8_t *tin = (uint8_t *) in; + uint8_t *tout = (uint8_t *) out; + + while (length > 0) { + memcpy(temp, tin, 8); + + mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_DECRYPT, tin, tout); + + for (i = 0; i < 8; i++) { + tout[i] = (unsigned char)(tout[i] ^ iv[i]); + } + + memcpy(iv, temp, 8); + + tin += 8; + tout += 8; + length -= 8; + } +} + +void aes128_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8]) { + if (length % 8) return; + + mbedtls_aes_setkey_enc(&actx, key, 128); + + uint8_t i; + uint8_t *tin = (uint8_t *) in; + uint8_t *tout = (uint8_t *) out; + + while (length > 0) { + for (i = 0; i < 8; i++) { + tin[i] = (unsigned char)(tin[i] ^ iv[i]); + } + + mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_ENCRYPT, tin, tout); + + memcpy(iv, tout, 8); + + tin += 8; + tout += 8; + length -= 8; + } +} void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key) { uint8_t data[8]; diff --git a/armsrc/desfire_crypto.h b/armsrc/desfire_crypto.h index c7f3dd004..d3cb8793d 100644 --- a/armsrc/desfire_crypto.h +++ b/armsrc/desfire_crypto.h @@ -179,6 +179,10 @@ void des_encrypt(void *out, const void *in, const void *key); void des_decrypt(void *out, const void *in, const void *key); void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode); void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode); + +void aes128_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8]); +void aes128_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8]); + void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key); void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key); void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 1fb89404a..cacbaac06 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -281,6 +281,36 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) { reply_mix(CMD_ACK, 1, 0, 0, 0, 0); } +void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes) { + + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + clear_trace(); + set_tracing(true); + + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); + reply_ng(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT, NULL, 0); + return; + }; + + if (!mifare_ultra_aes_auth(keyno, keybytes)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Authentication failed"); + reply_ng(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT, NULL, 0); + return; + } + + if (turn_off_field) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + } + reply_ng(CMD_HF_MIFAREULAES_AUTH, PM3_SUCCESS, NULL, 0); +} + // Arg0 = BlockNo, // Arg1 = UsePwd bool // datain = PWD bytes, @@ -361,8 +391,8 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) // params uint8_t blockNo = arg0; uint16_t blocks = arg1; - bool useKey = (arg2 == 1); //UL_C - bool usePwd = (arg2 == 2); //UL_EV1/NTAG + bool useKey = (arg2 == 1); // UL_C + bool usePwd = (arg2 == 2); // UL_EV1/NTAG uint32_t countblocks = 0; uint8_t *dataout = BigBuf_malloc(CARD_MEMORY_SIZE); if (dataout == NULL) { @@ -407,7 +437,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) break; } - len = mifare_ultra_readblock(blockNo + i, dataout + 4 * i); + len = mifare_ultra_readblock(blockNo + i, dataout + (4 * i)); if (len) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Read block %d error", i); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 5f21a3a9d..e795f8f09 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -27,6 +27,8 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes); +void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes); + void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index aca7ed989..7e5505bd4 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -378,6 +378,92 @@ int mifare_ultra_auth(uint8_t *keybytes) { return 1; } +int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) { + + /// aes-128 + uint8_t random_a[8] = {1, 1, 1, 1, 1, 1, 1, 1}; + uint8_t random_b[8] = {0x00}; + uint8_t enc_random_b[8] = {0x00}; + uint8_t rnd_ab[16] = {0x00}; + uint8_t IV[8] = {0x00}; + uint8_t key[16] = {0x00}; + memcpy(key, keybytes, sizeof(key)); + + uint16_t len = 0; + uint8_t resp[19] = {0x00}; + uint8_t respPar[3] = {0, 0, 0}; + + // REQUEST AUTHENTICATION + len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULAES_AUTH_1, keyno, resp, respPar, NULL); + if (len != 11) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); + return 0; + } + + // tag nonce. + memcpy(enc_random_b, resp + 1, 8); + + // decrypt nonce. + aes128_nxp_receive((void *)enc_random_b, (void *)random_b, sizeof(random_b), (const void *)key, IV); + + rol(random_b, 8); + memcpy(rnd_ab, random_a, 8); + memcpy(rnd_ab + 8, random_b, 8); + + if (g_dbglevel >= DBG_EXTENDED) { + Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", + enc_random_b[0], enc_random_b[1], enc_random_b[2], enc_random_b[3], enc_random_b[4], enc_random_b[5], enc_random_b[6], enc_random_b[7]); + + Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x", + random_b[0], random_b[1], random_b[2], random_b[3], random_b[4], random_b[5], random_b[6], random_b[7]); + + Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[0], rnd_ab[1], rnd_ab[2], rnd_ab[3], rnd_ab[4], rnd_ab[5], rnd_ab[6], rnd_ab[7]); + + Dbprintf("rnd_ab: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[8], rnd_ab[9], rnd_ab[10], rnd_ab[11], rnd_ab[12], rnd_ab[13], rnd_ab[14], rnd_ab[15]); + } + + // encrypt out, in, length, key, iv + aes128_nxp_send(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b); + + len = mifare_sendcmd(MIFARE_ULAES_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL); + if (len != 11) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); + return 0; + } + + uint8_t enc_resp[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t resp_random_a[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + memcpy(enc_resp, resp + 1, 8); + + // decrypt out, in, length, key, iv + aes128_nxp_receive(enc_resp, resp_random_a, 8, key, enc_random_b); + if (memcmp(resp_random_a, random_a, 8) != 0) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("failed authentication"); + return 0; + } + + if (g_dbglevel >= DBG_EXTENDED) { + Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[0], rnd_ab[1], rnd_ab[2], rnd_ab[3], + rnd_ab[4], rnd_ab[5], rnd_ab[6], rnd_ab[7]); + + Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", + rnd_ab[8], rnd_ab[9], rnd_ab[10], rnd_ab[11], + rnd_ab[12], rnd_ab[13], rnd_ab[14], rnd_ab[15]); + + Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x", + random_a[0], random_a[1], random_a[2], random_a[3], + random_a[4], random_a[5], random_a[6], random_a[7]); + + Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x", + resp_random_a[0], resp_random_a[1], resp_random_a[2], resp_random_a[3], + resp_random_a[4], resp_random_a[5], resp_random_a[6], resp_random_a[7]); + } + return 1; +} + static int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { uint16_t len = 0; uint8_t bt[2] = {0x00, 0x00}; diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 792d5dd27..662534397 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -87,6 +87,7 @@ int mifare_classic_value(struct Crypto1State *pcs, uint8_t blockNo, uint8_t *blo // Ultralight/NTAG... int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack); int mifare_ultra_auth(uint8_t *keybytes); +int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes); int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 705b66808..c89659f9c 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -56,6 +56,16 @@ static int CmdHelp(const char *Cmd); +static uint8_t default_aes_keys[][16] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // all zeroes + { 0x42, 0x52, 0x45, 0x41, 0x4b, 0x4d, 0x45, 0x49, 0x46, 0x59, 0x4f, 0x55, 0x43, 0x41, 0x4e, 0x21 }, // 3des std key + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, // 0x00-0x0F + { 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46 }, // NFC-key + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, // all ones + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, // all FF + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF } // 11 22 33 +}; + static uint8_t default_3des_keys[][16] = { { 0x42, 0x52, 0x45, 0x41, 0x4b, 0x4d, 0x45, 0x49, 0x46, 0x59, 0x4f, 0x55, 0x43, 0x41, 0x4e, 0x21 }, // 3des std key { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // all zeroes @@ -295,14 +305,56 @@ static int ulc_requestAuthentication(uint8_t *nonce, uint16_t nonceLength) { return len; } +static int ulev1_requestAuthentication(uint8_t *pwd, uint8_t *pack, uint16_t packLength) { + + uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]}; + int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength); + // NACK tables different tags, but between 0-9 is a NEGATIVE response. + // ACK == 0xA + if (len == 1 && pack[0] <= 0x09) + return -1; + return len; +} + +/* +Default AES key is 00-00h. Both the data and UID one. +Data key is 00, UID is 01. Authenticity is 02h +Auth is 1A[Key ID][CRC] - AF[RndB] - AF[RndA][RndB'] - 00[RndA'] +*/ +static int ulaes_requestAuthentication(uint8_t *key, uint8_t keyno, bool switch_off_field) { + struct p { + bool turn_off_field; + uint8_t keyno; + uint8_t key[16]; + } PACKED payload; + + payload.turn_off_field = switch_off_field; + payload.keyno = keyno; + memcpy(payload.key, key, sizeof(payload.key)); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFAREULAES_AUTH, (uint8_t*)&payload, sizeof(payload)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_MIFAREULAES_AUTH, &resp, 1500) == false) { + return PM3_ETIMEOUT; + } + if (resp.status != PM3_SUCCESS) { + return resp.status; + } + return PM3_SUCCESS; +} + static int ulc_authentication(uint8_t *key, bool switch_off_field) { clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 0; - if (resp.oldarg[0] == 1) return 1; - + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + return 0; + } + if (resp.oldarg[0] == 1) { + return 1; + } return 0; } @@ -394,17 +446,59 @@ static int try_default_3des_keys(uint8_t **correct_key) { return res; } -static int ulev1_requestAuthentication(uint8_t *pwd, uint8_t *pack, uint16_t packLength) { +static int try_default_aes_keys(void) { - uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]}; - int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength); - // NACK tables different tags, but between 0-9 is a NEGATIVE response. - // ACK == 0xA - if (len == 1 && pack[0] <= 0x09) - return -1; - return len; + uint8_t dbg_curr = DBG_NONE; + if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) { + return PM3_ESOFT; + } + + if (setDeviceDebugLevel(DBG_NONE, false) != PM3_SUCCESS) { + return PM3_ESOFT; + } + + int res = PM3_ESOFT; + + PrintAndLogEx(INFO, ""); + PrintAndLogEx(SUCCESS, "--- " _CYAN_("Known UL-AES keys")); + + for (uint8_t i = 0; i < ARRAYLEN(default_aes_keys); ++i) { + uint8_t *key = default_aes_keys[i]; + + for (uint8_t keyno = 0; keyno < 2; keyno++) { + + if (ulaes_requestAuthentication(key, keyno, true) == PM3_SUCCESS) { + + char keystr[20] = {0}; + switch(keyno) { + case 0: + sprintf(keystr, "Data key"); + break; + case 1: + sprintf(keystr, "UID key"); + break; + case 2: + sprintf(keystr, "Authenticity key"); + break; + default: + break; + } + PrintAndLogEx(SUCCESS, "Found %s keyno %02X - %s ( "_GREEN_("ok") " )" + , keystr + , keyno + , sprint_hex_inrow(key, 16) + ); + + res = PM3_SUCCESS; + } + } + } + + setDeviceDebugLevel(dbg_curr, false); + return res; } + static int ul_auth_select(iso14a_card_select_t *card, uint64_t tagtype, bool hasAuthKey, uint8_t *authkey, uint8_t *pack, uint8_t packSize) { if (hasAuthKey && (tagtype & MFU_TT_UL_C)) { //will select card automatically and close connection on error @@ -2026,6 +2120,23 @@ static int CmdHF14AMfUInfo(const char *Cmd) { } } + // Specific UL-AES + if (tagtype & MFU_TT_UL_AES) { + + // print AES configuration etc.. + + DropField(); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "--- " _CYAN_("Known AES keys")); + + // also try to diversify default keys.. look into CmdHF14AMfGenDiverseKeys + if (try_default_aes_keys() != PM3_SUCCESS) { + PrintAndLogEx(INFO, "n/a"); + } + PrintAndLogEx(INFO, "Done!"); + } + + // do counters and signature first (don't neet auth) // ul counters are different than ntag counters @@ -2119,6 +2230,11 @@ static int CmdHF14AMfUInfo(const char *Cmd) { } } + // Don't check passwords for Ul AES :) + if (tagtype == MFU_TT_UL_AES) { + goto out; + } + // AUTHLIMIT, (number of failed authentications) // 0 = limitless. // 1-7 = limit. No automatic tries then. diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 06cc63b55..e8fe0f4f9 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -692,9 +692,11 @@ typedef struct { #define CMD_HF_MIFARE_MFKEY 0x0631 #define CMD_HF_MIFARE_PERSONALIZE_UID 0x0632 -//ultralightC +// ultralight-C #define CMD_HF_MIFAREUC_AUTH 0x0724 -//0x0725 and 0x0726 no longer used +// Ultralight AES +#define CMD_HF_MIFAREULAES_AUTH 0x0725 +// 0x0726 no longer used #define CMD_HF_MIFAREUC_SETPWD 0x0727 // mifare desfire diff --git a/include/protocols.h b/include/protocols.h index 7b15b235c..322c6c321 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -224,6 +224,9 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_ULNANO_WRITESIG 0xA9 #define MIFARE_ULNANO_LOCKSIG 0xAC +#define MIFARE_ULAES_AUTH_1 0x1A +#define MIFARE_ULAES_AUTH_2 0xAF + // NTAG i2k 2K uses sector 0, and sector 1 to have access to // block 0x00-0xFF. #define NTAG_I2C_SELECT_SECTOR 0xC2