Skip to content

Commit

Permalink
[FL-3576] Ultralight static lock bytes implementation (#3094)
Browse files Browse the repository at this point in the history
* Function for static lock bytes processing added

* Static lock bytes processing added to preparation and CMD_WRITE

* Static lock bytes added to COMP_WRITE command
  • Loading branch information
RebornedBrain authored Sep 19, 2023
1 parent a1ef31b commit 9e374a4
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 14 deletions.
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

0 comments on commit 9e374a4

Please sign in to comment.