Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3576] Ultralight static lock bytes implementation #3094

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
832084f
Added callback on FieldOff event from 14443 to mfu
RebornedBrain Aug 31, 2023
0a059ce
Moved command enum and callback type to _i.h file
RebornedBrain Aug 31, 2023
a1646cf
Added context for composite command to mfu_listener
RebornedBrain Aug 31, 2023
9739b23
Functions for composite commands processing added
RebornedBrain Aug 31, 2023
3ffda5d
Composite commands processing logic added
RebornedBrain Aug 31, 2023
e9ca28a
Added COMP_WRITE command implementation
RebornedBrain Aug 31, 2023
27d6b02
Patch with some fixes
RebornedBrain Aug 31, 2023
3ad0f14
Merge branch 'gornek/nfc_refactoring'
RebornedBrain Aug 31, 2023
c416a82
Merge branch 'gornek/nfc_refactoring'
RebornedBrain Sep 1, 2023
6b21e6c
New mfu command result added for composite commands
RebornedBrain Sep 6, 2023
a4566a9
Added variable for storing sector for SECTOR_SELECT cmd
RebornedBrain Sep 6, 2023
6b8f935
Implemented proper way of reset for composite cmds
RebornedBrain Sep 6, 2023
317bd3a
SECTOR_SELECT implementation added
RebornedBrain Sep 6, 2023
6531546
Merge commit '2ad34a725717193dd8f0f5acf2a129d53a2b496f'
RebornedBrain Sep 6, 2023
31243c2
Adjust naming for PR
RebornedBrain Sep 6, 2023
fd349f9
Update api_symbols.csv, nfc.h, and mf_ultralight_listener.c
RebornedBrain Sep 6, 2023
a081f96
Merge branch 'gornek/nfc_refactoring'
RebornedBrain Sep 6, 2023
aadc629
FAST_READ cmd define added
RebornedBrain Sep 7, 2023
a31d95e
Added functions for PWD and PACK pages processing
RebornedBrain Sep 7, 2023
8666710
Tx buffer size increased to maximum nfc package
RebornedBrain Sep 7, 2023
82c0fb3
Added functions for i2c page validation and allocation
RebornedBrain Sep 7, 2023
c2b8b96
READ and FAST_READ commands implementation and adjustments
RebornedBrain Sep 7, 2023
fa13faf
Update api_symbols.csv
RebornedBrain Sep 7, 2023
8888380
Renamed i2c bool switch and fixed FAST_READ where it was hardcoded
RebornedBrain Sep 7, 2023
7128dfc
Replaced some parts of code by defines
RebornedBrain Sep 7, 2023
05bd6cc
Merge branch 'gornek/nfc_refactoring'
RebornedBrain Sep 7, 2023
2476dc8
VCSL cmd added for Ultralights
RebornedBrain Sep 8, 2023
2dc870c
Implementation of VCSL cmd added
RebornedBrain Sep 8, 2023
7cd4801
Merge branch 'flipperdevices:gornek/nfc_refactoring_v1' into gornek/n…
RebornedBrain Sep 11, 2023
9f67885
Merge branch 'flipperdevices:gornek/nfc_refactoring_v1' into gornek/n…
RebornedBrain Sep 13, 2023
ed84285
Merge branch 'flipperdevices:gornek/nfc_refactoring_v1' into gornek/n…
RebornedBrain Sep 13, 2023
9f79717
Merge branch 'flipperdevices:gornek/nfc_refactoring_v1' into gornek/n…
RebornedBrain Sep 14, 2023
15dcde0
Merge branch 'flipperdevices:gornek/nfc_refactoring_v1' into gornek/n…
RebornedBrain Sep 15, 2023
8eaafd9
Merge branch 'flipperdevices:gornek/nfc_refactoring_v1' into gornek/n…
RebornedBrain Sep 18, 2023
2ad0344
Function for static lock bytes processing added
RebornedBrain Sep 19, 2023
7db94fe
Static lock bytes processing added to preparation and CMD_WRITE
RebornedBrain Sep 19, 2023
5c72156
Static lock bytes added to COMP_WRITE command
RebornedBrain Sep 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,24 @@ static MfUltralightCommand

FURI_LOG_D(TAG, "CMD_WRITE");

if(pages_total < start_page ||
!mf_ultralight_listener_check_access(
instance, start_page, MfUltralightListenerAccessTypeWrite)) {
} else {
do {
if(pages_total < start_page ||
!mf_ultralight_listener_check_access(
instance, start_page, MfUltralightListenerAccessTypeWrite))
break;

if(mf_ultralight_static_lock_check_page(instance->static_lock, start_page)) break;

const uint8_t* rx_data = bit_buffer_get_data(buffer);
memcpy(instance->data->page[start_page].data, &rx_data[2], sizeof(MfUltralightPage));

if(start_page == 2)
mf_ultralight_static_lock_bytes_write(
instance->static_lock, *((uint16_t*)&rx_data[4]));
else
memcpy(instance->data->page[start_page].data, &rx_data[2], sizeof(MfUltralightPage));
command = MfUltralightCommandProcessedACK;
}

} while(false);

return command;
}
Expand Down Expand Up @@ -428,7 +438,12 @@ static MfUltralightCommand

const uint8_t* rx_data = bit_buffer_get_data(buffer);
uint8_t start_page = instance->composite_cmd.data;
memcpy(instance->data->page[start_page].data, &rx_data[0], sizeof(MfUltralightPage));

if(start_page == 2)
mf_ultralight_static_lock_bytes_write(
instance->static_lock, *((uint16_t*)&rx_data[2]));
else
memcpy(instance->data->page[start_page].data, &rx_data[0], sizeof(MfUltralightPage));
command = MfUltralightCommandProcessedACK;
} while(false);

Expand All @@ -454,6 +469,11 @@ static MfUltralightCommand
break;
}

if(mf_ultralight_static_lock_check_page(instance->static_lock, start_page)) {
command = MfUltralightCommandNotProcessedNAK;
break;
}

instance->composite_cmd.data = start_page;
command = MfUltralightCommandProcessedACK;
mf_ultralight_composite_command_set_next(instance, mf_ultralight_comp_write_handler_p2);
Expand Down Expand Up @@ -616,6 +636,7 @@ MfUltralightListener* mf_ultralight_listener_alloc(
instance->mirror.ascii_mirror_data = furi_string_alloc();
instance->iso14443_3a_listener = iso14443_3a_listener;
instance->data = data;
mf_ultralight_static_lock_bytes_prepare(instance);
mf_ultralight_listener_prepare_emulation(instance);
mf_ultralight_composite_command_reset(instance);
instance->sector = 0;
Expand Down
70 changes: 63 additions & 7 deletions lib/nfc/protocols/mf_ultralight/mf_ultralight_listener_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,38 @@

#include <furi.h>

#define MF_ULTRALIGHT_I2C_PAGE_IN_BOUNDS(page, start, end) \
(((page) >= (start)) && ((page) <= (end)))
#define MF_ULTRALIGHT_STATIC_BIT_LOCK_OTP_CC 0
#define MF_ULTRALIGHT_STATIC_BIT_LOCK_BL_9_4 1
#define MF_ULTRALIGHT_STATIC_BIT_LOCK_BL_15_10 2

#define MF_ULTRALIGHT_STATIC_BIT_ACTIVE(lock_bits, bit) ((lock_bits & (1U << bit)) != 0)
#define MF_ULTRALIGHT_STATIC_BITS_SET(lock_bits, mask) (lock_bits |= mask)
#define MF_ULTRALIGHT_STATIC_BITS_CLR(lock_bits, mask) (lock_bits &= ~mask)

#define MF_ULTRALIGHT_PAGE_LOCKED(lock_bits, page) MF_ULTRALIGHT_STATIC_BIT_ACTIVE(lock_bits, page)

#define MF_ULTRALIGHT_STATIC_BIT_OTP_CC_LOCKED(lock_bits) \
MF_ULTRALIGHT_STATIC_BIT_ACTIVE(lock_bits, MF_ULTRALIGHT_STATIC_BIT_LOCK_OTP_CC)

#define MF_ULTRALIGHT_STATIC_BITS_9_4_LOCKED(lock_bits) \
MF_ULTRALIGHT_STATIC_BIT_ACTIVE(lock_bits, MF_ULTRALIGHT_STATIC_BIT_LOCK_BL_9_4)

#define MF_ULTRALIGHT_STATIC_BITS_15_10_LOCKED(lock_bits) \
MF_ULTRALIGHT_STATIC_BIT_ACTIVE(lock_bits, MF_ULTRALIGHT_STATIC_BIT_LOCK_BL_15_10)

#define MF_ULTRALIGHT_STATIC_LOCK_L_OTP_CC_MASK (1U << 3)
#define MF_ULTRALIGHT_STATIC_LOCK_L_9_4_MASK \
((1U << 9) | (1U << 8) | (1U << 7) | (1U << 6) | (1U << 5) | (1U << 4))
#define MF_ULTRALIGHT_STATIC_LOCK_L_15_10_MASK \
((1U << 15) | (1U << 14) | (1U << 13) | (1U << 12) | (1U << 11) | (1U << 10))

#define MF_ULTRALIGHT_PAGE_IN_BOUNDS(page, start, end) (((page) >= (start)) && ((page) <= (end)))

#define MF_ULTRALIGHT_I2C_PAGE_ON_SESSION_REG(page) \
MF_ULTRALIGHT_I2C_PAGE_IN_BOUNDS(page, 0x00EC, 0x00ED)
MF_ULTRALIGHT_PAGE_IN_BOUNDS(page, 0x00EC, 0x00ED)

#define MF_ULTRALIGHT_I2C_PAGE_ON_MIRRORED_SESSION_REG(page) \
MF_ULTRALIGHT_I2C_PAGE_IN_BOUNDS(page, 0x00F8, 0x00F9)
MF_ULTRALIGHT_PAGE_IN_BOUNDS(page, 0x00F8, 0x00F9)

static MfUltralightMirrorConf mf_ultralight_mirror_check_mode(
const MfUltralightConfigPages* const config,
Expand Down Expand Up @@ -228,7 +252,7 @@ static bool mf_ultralight_i2c_page_validator_for_sector0(
valid = true;
}
} else if(type == MfUltralightTypeNTAGI2C1K) {
if((start_page <= 0xE2) || MF_ULTRALIGHT_I2C_PAGE_IN_BOUNDS(start_page, 0x00E8, 0x00E9)) {
if((start_page <= 0xE2) || MF_ULTRALIGHT_PAGE_IN_BOUNDS(start_page, 0x00E8, 0x00E9)) {
valid = true;
}
} else if(type == MfUltralightTypeNTAGI2C2K) {
Expand All @@ -246,8 +270,7 @@ static bool mf_ultralight_i2c_page_validator_for_sector1(
if(type == MfUltralightTypeNTAGI2CPlus2K) {
valid = (start_page <= 0xFF && end_page <= 0xFF);
} else if(type == MfUltralightTypeNTAGI2C2K) {
valid =
(MF_ULTRALIGHT_I2C_PAGE_IN_BOUNDS(start_page, 0x00E8, 0x00E9) || (start_page <= 0xE0));
valid = (MF_ULTRALIGHT_PAGE_IN_BOUNDS(start_page, 0x00E8, 0x00E9) || (start_page <= 0xE0));
} else if(type == MfUltralightTypeNTAGI2C1K || type == MfUltralightTypeNTAGI2CPlus1K) {
valid = false;
}
Expand Down Expand Up @@ -368,3 +391,36 @@ uint16_t
}
return result;
}

void mf_ultralight_static_lock_bytes_prepare(MfUltralightListener* instance) {
instance->static_lock = (uint16_t*)&instance->data->page[2].data[2];
}

void mf_ultralight_static_lock_bytes_write(
MfUltralightStaticLockData* const lock_bits,
uint16_t new_bits) {
uint16_t current_locks = *lock_bits;

if(MF_ULTRALIGHT_STATIC_BIT_OTP_CC_LOCKED(current_locks))
MF_ULTRALIGHT_STATIC_BITS_CLR(new_bits, MF_ULTRALIGHT_STATIC_LOCK_L_OTP_CC_MASK);

if(MF_ULTRALIGHT_STATIC_BITS_9_4_LOCKED(current_locks))
MF_ULTRALIGHT_STATIC_BITS_CLR(new_bits, MF_ULTRALIGHT_STATIC_LOCK_L_9_4_MASK);

if(MF_ULTRALIGHT_STATIC_BITS_15_10_LOCKED(current_locks))
MF_ULTRALIGHT_STATIC_BITS_CLR(new_bits, MF_ULTRALIGHT_STATIC_LOCK_L_15_10_MASK);

MF_ULTRALIGHT_STATIC_BITS_SET(current_locks, new_bits);
*lock_bits = current_locks;
}

bool mf_ultralight_static_lock_check_page(
const MfUltralightStaticLockData* const lock_bits,
uint16_t page) {
bool locked = false;
if(MF_ULTRALIGHT_PAGE_IN_BOUNDS(page, 0x0003, 0x000F)) {
uint16_t current_locks = *lock_bits;
locked = MF_ULTRALIGHT_PAGE_LOCKED(current_locks, page);
}
return locked;
}
12 changes: 12 additions & 0 deletions lib/nfc/protocols/mf_ultralight/mf_ultralight_listener_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@ typedef struct {
FuriString* ascii_mirror_data;
} MfUltralightMirrorMode;

typedef uint16_t MfUltralightStaticLockData;

struct MfUltralightListener {
Iso14443_3aListener* iso14443_3a_listener;
MfUltralightListenerAuthState auth_state;
MfUltralightData* data;
BitBuffer* tx_buffer;
MfUltralightFeatureSupport features;
MfUltralightConfigPages* config;
MfUltralightStaticLockData* static_lock;

NfcGenericEvent generic_event;
MfUltralightListenerEvent mfu_event;
Expand Down Expand Up @@ -88,6 +91,15 @@ bool mf_ultralight_i2c_validate_pages(

uint16_t
mf_ultralight_i2c_provide_page_by_requested(uint16_t page, MfUltralightListener* instance);

void mf_ultralight_static_lock_bytes_prepare(MfUltralightListener* instance);
void mf_ultralight_static_lock_bytes_write(
MfUltralightStaticLockData* const lock_bits,
uint16_t new_bits);
bool mf_ultralight_static_lock_check_page(
const MfUltralightStaticLockData* const lock_bits,
uint16_t page);

#ifdef __cplusplus
}
#endif