Merge branch 'ofw-dev' into dev

This commit is contained in:
MX 2023-05-26 16:51:11 +03:00
commit 3c452e6ddb
No known key found for this signature in database
GPG Key ID: 7CCC66B7DBDD1C83
6 changed files with 56 additions and 14 deletions

View File

@ -19,7 +19,7 @@ void nfc_scene_mf_ultralight_menu_on_enter(void* context) {
Submenu* submenu = nfc->submenu; Submenu* submenu = nfc->submenu;
MfUltralightData* data = &nfc->dev->dev_data.mf_ul_data; MfUltralightData* data = &nfc->dev->dev_data.mf_ul_data;
if(!mf_ul_is_full_capture(data)) { if(!mf_ul_is_full_capture(data) && data->type != MfUltralightTypeULC) {
submenu_add_item( submenu_add_item(
submenu, submenu,
"Unlock", "Unlock",
@ -29,12 +29,14 @@ void nfc_scene_mf_ultralight_menu_on_enter(void* context) {
} }
submenu_add_item( submenu_add_item(
submenu, "Save", SubmenuIndexSave, nfc_scene_mf_ultralight_menu_submenu_callback, nfc); submenu, "Save", SubmenuIndexSave, nfc_scene_mf_ultralight_menu_submenu_callback, nfc);
submenu_add_item( if(mf_ul_emulation_supported(data)) {
submenu, submenu_add_item(
"Emulate", submenu,
SubmenuIndexEmulate, "Emulate",
nfc_scene_mf_ultralight_menu_submenu_callback, SubmenuIndexEmulate,
nfc); nfc_scene_mf_ultralight_menu_submenu_callback,
nfc);
}
submenu_add_item( submenu_add_item(
submenu, "Info", SubmenuIndexInfo, nfc_scene_mf_ultralight_menu_submenu_callback, nfc); submenu, "Info", SubmenuIndexInfo, nfc_scene_mf_ultralight_menu_submenu_callback, nfc);

View File

@ -43,7 +43,8 @@ void nfc_scene_saved_menu_on_enter(void* context) {
nfc); nfc);
} }
} else if( } else if(
nfc->dev->format == NfcDeviceSaveFormatMifareUl || (nfc->dev->format == NfcDeviceSaveFormatMifareUl &&
mf_ul_emulation_supported(&nfc->dev->dev_data.mf_ul_data)) ||
nfc->dev->format == NfcDeviceSaveFormatNfcV || nfc->dev->format == NfcDeviceSaveFormatNfcV ||
nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { nfc->dev->format == NfcDeviceSaveFormatMifareClassic) {
submenu_add_item( submenu_add_item(
@ -74,6 +75,7 @@ void nfc_scene_saved_menu_on_enter(void* context) {
submenu_add_item( submenu_add_item(
submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc); submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
if(nfc->dev->format == NfcDeviceSaveFormatMifareUl && if(nfc->dev->format == NfcDeviceSaveFormatMifareUl &&
nfc->dev->dev_data.mf_ul_data.type != MfUltralightTypeULC &&
!mf_ul_is_full_capture(&nfc->dev->dev_data.mf_ul_data)) { !mf_ul_is_full_capture(&nfc->dev->dev_data.mf_ul_data)) {
submenu_add_item( submenu_add_item(
submenu, submenu,

View File

@ -2061,6 +2061,7 @@ Function,-,mf_df_prepare_read_records,uint16_t,"uint8_t*, uint8_t, uint32_t, uin
Function,-,mf_df_prepare_select_application,uint16_t,"uint8_t*, uint8_t[3]" Function,-,mf_df_prepare_select_application,uint16_t,"uint8_t*, uint8_t[3]"
Function,-,mf_df_read_card,_Bool,"FuriHalNfcTxRxContext*, MifareDesfireData*" Function,-,mf_df_read_card,_Bool,"FuriHalNfcTxRxContext*, MifareDesfireData*"
Function,-,mf_ul_check_card_type,_Bool,"uint8_t, uint8_t, uint8_t" Function,-,mf_ul_check_card_type,_Bool,"uint8_t, uint8_t, uint8_t"
Function,-,mf_ul_emulation_supported,_Bool,MfUltralightData*
Function,-,mf_ul_is_full_capture,_Bool,MfUltralightData* Function,-,mf_ul_is_full_capture,_Bool,MfUltralightData*
Function,-,mf_ul_prepare_emulation,void,"MfUltralightEmulator*, MfUltralightData*" Function,-,mf_ul_prepare_emulation,void,"MfUltralightEmulator*, MfUltralightData*"
Function,-,mf_ul_prepare_emulation_response,_Bool,"uint8_t*, uint16_t, uint8_t*, uint16_t*, uint32_t*, void*" Function,-,mf_ul_prepare_emulation_response,_Bool,"uint8_t*, uint16_t, uint8_t*, uint16_t*, uint32_t*, void*"

1 entry status name type params
2061 Function - mf_df_prepare_select_application uint16_t uint8_t*, uint8_t[3]
2062 Function - mf_df_read_card _Bool FuriHalNfcTxRxContext*, MifareDesfireData*
2063 Function - mf_ul_check_card_type _Bool uint8_t, uint8_t, uint8_t
2064 Function - mf_ul_emulation_supported _Bool MfUltralightData*
2065 Function - mf_ul_is_full_capture _Bool MfUltralightData*
2066 Function - mf_ul_prepare_emulation void MfUltralightEmulator*, MfUltralightData*
2067 Function - mf_ul_prepare_emulation_response _Bool uint8_t*, uint16_t, uint8_t*, uint16_t*, uint32_t*, void*

View File

@ -45,6 +45,8 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) {
return "NTAG I2C Plus 2K"; return "NTAG I2C Plus 2K";
} else if(type == MfUltralightTypeNTAG203) { } else if(type == MfUltralightTypeNTAG203) {
return "NTAG203"; return "NTAG203";
} else if(type == MfUltralightTypeULC) {
return "Mifare Ultralight C";
} else if(type == MfUltralightTypeUL11 && full_name) { } else if(type == MfUltralightTypeUL11 && full_name) {
return "Mifare Ultralight 11"; return "Mifare Ultralight 11";
} else if(type == MfUltralightTypeUL21 && full_name) { } else if(type == MfUltralightTypeUL21 && full_name) {

View File

@ -79,6 +79,8 @@ static MfUltralightFeatures mf_ul_get_features(MfUltralightType type) {
MfUltralightSupportSectorSelect; MfUltralightSupportSectorSelect;
case MfUltralightTypeNTAG203: case MfUltralightTypeNTAG203:
return MfUltralightSupportCompatWrite | MfUltralightSupportCounterInMemory; return MfUltralightSupportCompatWrite | MfUltralightSupportCounterInMemory;
case MfUltralightTypeULC:
return MfUltralightSupportCompatWrite | MfUltralightSupport3DesAuth;
default: default:
// Assumed original MFUL 512-bit // Assumed original MFUL 512-bit
return MfUltralightSupportCompatWrite; return MfUltralightSupportCompatWrite;
@ -95,6 +97,11 @@ static void mf_ul_set_version_ntag203(MfUltralightReader* reader, MfUltralightDa
reader->pages_to_read = 42; reader->pages_to_read = 42;
} }
static void mf_ul_set_version_ulc(MfUltralightReader* reader, MfUltralightData* data) {
data->type = MfUltralightTypeULC;
reader->pages_to_read = 48;
}
bool mf_ultralight_read_version( bool mf_ultralight_read_version(
FuriHalNfcTxRxContext* tx_rx, FuriHalNfcTxRxContext* tx_rx,
MfUltralightReader* reader, MfUltralightReader* reader,
@ -175,7 +182,7 @@ bool mf_ultralight_authenticate(FuriHalNfcTxRxContext* tx_rx, uint32_t key, uint
do { do {
FURI_LOG_D(TAG, "Authenticating"); FURI_LOG_D(TAG, "Authenticating");
tx_rx->tx_data[0] = MF_UL_AUTH; tx_rx->tx_data[0] = MF_UL_PWD_AUTH;
nfc_util_num2bytes(key, 4, &tx_rx->tx_data[1]); nfc_util_num2bytes(key, 4, &tx_rx->tx_data[1]);
tx_rx->tx_bits = 40; tx_rx->tx_bits = 40;
tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault;
@ -716,6 +723,21 @@ bool mf_ultralight_read_tearing_flags(FuriHalNfcTxRxContext* tx_rx, MfUltralight
return flag_read == 2; return flag_read == 2;
} }
static bool mf_ul_probe_3des_auth(FuriHalNfcTxRxContext* tx_rx) {
tx_rx->tx_data[0] = MF_UL_AUTHENTICATE_1;
tx_rx->tx_data[1] = 0;
tx_rx->tx_bits = 16;
tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault;
bool rc = furi_hal_nfc_tx_rx(tx_rx, 50) && tx_rx->rx_bits == 9 * 8 &&
tx_rx->rx_data[0] == 0xAF;
// Reset just in case, we're not going to finish authenticating and need to if tag doesn't support auth
furi_hal_nfc_sleep();
furi_hal_nfc_activate_nfca(300, NULL);
return rc;
}
bool mf_ul_read_card( bool mf_ul_read_card(
FuriHalNfcTxRxContext* tx_rx, FuriHalNfcTxRxContext* tx_rx,
MfUltralightReader* reader, MfUltralightReader* reader,
@ -733,16 +755,20 @@ bool mf_ul_read_card(
mf_ultralight_read_signature(tx_rx, data); mf_ultralight_read_signature(tx_rx, data);
} }
} else { } else {
// No GET_VERSION command, check for NTAG203 by reading last page (41)
uint8_t dummy[16]; uint8_t dummy[16];
if(mf_ultralight_read_pages_direct(tx_rx, 41, dummy)) { // No GET_VERSION command, check if AUTHENTICATE command available (detect UL C).
if(mf_ul_probe_3des_auth(tx_rx)) {
mf_ul_set_version_ulc(reader, data);
} else if(mf_ultralight_read_pages_direct(tx_rx, 41, dummy)) {
// No AUTHENTICATE, check for NTAG203 by reading last page (41)
mf_ul_set_version_ntag203(reader, data); mf_ul_set_version_ntag203(reader, data);
reader->supported_features = mf_ul_get_features(data->type);
} else { } else {
// We're really an original Mifare Ultralight, reset tag for safety // We're really an original Mifare Ultralight, reset tag for safety
furi_hal_nfc_sleep(); furi_hal_nfc_sleep();
furi_hal_nfc_activate_nfca(300, NULL); furi_hal_nfc_activate_nfca(300, NULL);
} }
reader->supported_features = mf_ul_get_features(data->type);
} }
card_read = mf_ultralight_read_pages(tx_rx, reader, data); card_read = mf_ultralight_read_pages(tx_rx, reader, data);
@ -1228,6 +1254,10 @@ static void mf_ul_emulate_write(
emulator->data_changed = true; emulator->data_changed = true;
} }
bool mf_ul_emulation_supported(MfUltralightData* data) {
return data->type != MfUltralightTypeULC;
}
void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle) { void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle) {
emulator->comp_write_cmd_started = false; emulator->comp_write_cmd_started = false;
emulator->sector_select_cmd_started = false; emulator->sector_select_cmd_started = false;
@ -1732,7 +1762,7 @@ bool mf_ul_prepare_emulation_response(
} }
} }
} }
} else if(cmd == MF_UL_AUTH) { } else if(cmd == MF_UL_PWD_AUTH) {
if(emulator->supported_features & MfUltralightSupportAuth) { if(emulator->supported_features & MfUltralightSupportAuth) {
if(buff_rx_len == (1 + 4) * 8) { if(buff_rx_len == (1 + 4) * 8) {
// Record password sent by PCD // Record password sent by PCD

View File

@ -16,7 +16,8 @@
#define MF_UL_COMP_WRITE (0xA0) #define MF_UL_COMP_WRITE (0xA0)
#define MF_UL_READ_CNT (0x39) #define MF_UL_READ_CNT (0x39)
#define MF_UL_INC_CNT (0xA5) #define MF_UL_INC_CNT (0xA5)
#define MF_UL_AUTH (0x1B) #define MF_UL_AUTHENTICATE_1 (0x1A)
#define MF_UL_PWD_AUTH (0x1B)
#define MF_UL_READ_SIG (0x3C) #define MF_UL_READ_SIG (0x3C)
#define MF_UL_CHECK_TEARING (0x3E) #define MF_UL_CHECK_TEARING (0x3E)
#define MF_UL_READ_VCSL (0x4B) #define MF_UL_READ_VCSL (0x4B)
@ -41,6 +42,7 @@ typedef enum {
typedef enum { typedef enum {
MfUltralightTypeUnknown, MfUltralightTypeUnknown,
MfUltralightTypeNTAG203, MfUltralightTypeNTAG203,
MfUltralightTypeULC,
// Below have config pages and GET_VERSION support // Below have config pages and GET_VERSION support
MfUltralightTypeUL11, MfUltralightTypeUL11,
MfUltralightTypeUL21, MfUltralightTypeUL21,
@ -77,6 +79,7 @@ typedef enum {
MfUltralightSupportAsciiMirror = 1 << 11, MfUltralightSupportAsciiMirror = 1 << 11,
// NTAG203 counter that's in memory rather than through a command // NTAG203 counter that's in memory rather than through a command
MfUltralightSupportCounterInMemory = 1 << 12, MfUltralightSupportCounterInMemory = 1 << 12,
MfUltralightSupport3DesAuth = 1 << 13,
} MfUltralightFeatures; } MfUltralightFeatures;
typedef enum { typedef enum {
@ -237,6 +240,8 @@ bool mf_ul_read_card(
MfUltralightReader* reader, MfUltralightReader* reader,
MfUltralightData* data); MfUltralightData* data);
bool mf_ul_emulation_supported(MfUltralightData* data);
void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle); void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle);
void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data); void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data);