diff --git a/applications/main/nfc/nfc_cli.c b/applications/main/nfc/nfc_cli.c index b2b85f6d3..a6475ca68 100644 --- a/applications/main/nfc/nfc_cli.c +++ b/applications/main/nfc/nfc_cli.c @@ -67,7 +67,7 @@ static void nfc_cli_emulate(Cli* cli, FuriString* args) { }; while(!cli_cmd_interrupt_received(cli)) { - if(furi_hal_nfc_listen(¶ms, false, 100)) { + if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 100)) { printf("Reader detected\r\n"); furi_hal_nfc_sleep(); } diff --git a/applications/main/u2f/scenes/u2f_scene_main.c b/applications/main/u2f/scenes/u2f_scene_main.c index abf78c841..af7f1159b 100644 --- a/applications/main/u2f/scenes/u2f_scene_main.c +++ b/applications/main/u2f/scenes/u2f_scene_main.c @@ -101,7 +101,6 @@ void u2f_scene_main_on_enter(void* context) { if(app->u2f_ready == true) { u2f_set_event_callback(app->u2f_instance, u2f_scene_main_event_callback, app); app->u2f_hid = u2f_hid_start(app->u2f_instance); - app->u2f_nfc = u2f_nfc_start(app->u2f_instance); u2f_view_set_ok_callback(app->u2f_view, u2f_scene_main_ok_callback, app); } else { u2f_free(app->u2f_instance); @@ -118,7 +117,6 @@ void u2f_scene_main_on_exit(void* context) { furi_timer_free(app->timer); if(app->u2f_ready == true) { u2f_hid_stop(app->u2f_hid); - u2f_nfc_stop(app->u2f_nfc); u2f_free(app->u2f_instance); } } diff --git a/applications/main/u2f/u2f.c b/applications/main/u2f/u2f.c index ff90329c5..767733ce6 100644 --- a/applications/main/u2f/u2f.c +++ b/applications/main/u2f/u2f.c @@ -16,7 +16,6 @@ #define U2F_CMD_REGISTER 0x01 #define U2F_CMD_AUTHENTICATE 0x02 #define U2F_CMD_VERSION 0x03 -#define U2F_CMD_APPLET_SELECTION 0xA4 typedef enum { U2fCheckOnly = 0x07, // "check-only" - only check key handle, don't send auth response @@ -38,6 +37,11 @@ typedef struct { } __attribute__((packed)) U2fKeyHandle; typedef struct { + uint8_t cla; + uint8_t ins; + uint8_t p1; + uint8_t p2; + uint8_t len[3]; uint8_t challenge[32]; uint8_t app_id[32]; } __attribute__((packed)) U2fRegisterReq; @@ -50,6 +54,11 @@ typedef struct { } __attribute__((packed)) U2fRegisterResp; typedef struct { + uint8_t cla; + uint8_t ins; + uint8_t p1; + uint8_t p2; + uint8_t len[3]; uint8_t challenge[32]; uint8_t app_id[32]; U2fKeyHandle key_handle; @@ -63,14 +72,10 @@ typedef struct { static const uint8_t ver_str[] = {"U2F_V2"}; -// NFC applet selection fields -static const uint8_t rid_ac_ax[] = {0xA0, 0x00, 0x00, 0x06, 0x47, 0x2F, 0x00, 0x01}; - static const uint8_t state_no_error[] = {0x90, 0x00}; static const uint8_t state_not_supported[] = {0x6D, 0x00}; static const uint8_t state_user_missing[] = {0x69, 0x85}; static const uint8_t state_wrong_data[] = {0x6A, 0x80}; -static const uint8_t state_app_not_found[] = {0x6A, 0x82}; struct U2fData { uint8_t device_key[32]; @@ -83,16 +88,6 @@ struct U2fData { void* context; }; -static void* apdu_command_data(U2fApduCommand* cmd) { - // Short encoding is a single byte. - // Extended length encoding is 0 byte followed by MSB and LSB bytes. - if(cmd->len[0] == 0) { - return cmd->len + 3; - } else { - return cmd->len + 1; - } -} - static int u2f_uecc_random(uint8_t* dest, unsigned size) { furi_hal_random_fill_buf(dest, size); return 1; @@ -183,10 +178,9 @@ static uint8_t u2f_der_encode_signature(uint8_t* der, uint8_t* sig) { return len; } -static uint16_t u2f_register(U2fData* U2F, const uint8_t* in_buf, uint8_t* out_buf) { - U2fApduCommand* cmd = (U2fApduCommand*)in_buf; - U2fRegisterReq* req = apdu_command_data(cmd); - U2fRegisterResp* resp = (U2fRegisterResp*)out_buf; +static uint16_t u2f_register(U2fData* U2F, uint8_t* buf) { + U2fRegisterReq* req = (U2fRegisterReq*)buf; + U2fRegisterResp* resp = (U2fRegisterResp*)buf; U2fKeyHandle handle; uint8_t private[32]; U2fPubKey pub_key; @@ -196,13 +190,13 @@ static uint16_t u2f_register(U2fData* U2F, const uint8_t* in_buf, uint8_t* out_b if(u2f_data_check(false) == false) { U2F->ready = false; if(U2F->callback != NULL) U2F->callback(U2fNotifyError, U2F->context); - memcpy(&out_buf[0], state_not_supported, 2); + memcpy(&buf[0], state_not_supported, 2); return 2; } if(U2F->callback != NULL) U2F->callback(U2fNotifyRegister, U2F->context); if(U2F->user_present == false) { - memcpy(&out_buf[0], state_user_missing, 2); + memcpy(&buf[0], state_user_missing, 2); return 2; } U2F->user_present = false; @@ -253,10 +247,9 @@ static uint16_t u2f_register(U2fData* U2F, const uint8_t* in_buf, uint8_t* out_b return (sizeof(U2fRegisterResp) + cert_len + signature_len + 2); } -static uint16_t u2f_authenticate(U2fData* U2F, const uint8_t* in_buf, uint8_t* out_buf) { - U2fApduCommand* cmd = (U2fApduCommand*)in_buf; - U2fAuthReq* req = apdu_command_data(cmd); - U2fAuthResp* resp = (U2fAuthResp*)out_buf; +static uint16_t u2f_authenticate(U2fData* U2F, uint8_t* buf) { + U2fAuthReq* req = (U2fAuthReq*)buf; + U2fAuthResp* resp = (U2fAuthResp*)buf; uint8_t priv_key[32]; uint8_t mac_control[32]; hmac_sha256_context hmac_ctx; @@ -269,7 +262,7 @@ static uint16_t u2f_authenticate(U2fData* U2F, const uint8_t* in_buf, uint8_t* o if(u2f_data_check(false) == false) { U2F->ready = false; if(U2F->callback != NULL) U2F->callback(U2fNotifyError, U2F->context); - memcpy(&out_buf[0], state_not_supported, 2); + memcpy(&buf[0], state_not_supported, 2); return 2; } @@ -277,8 +270,8 @@ static uint16_t u2f_authenticate(U2fData* U2F, const uint8_t* in_buf, uint8_t* o if(U2F->user_present == true) { flags |= 1; } else { - if(cmd->p1 == U2fEnforce) { - memcpy(&out_buf[0], state_user_missing, 2); + if(req->p1 == U2fEnforce) { + memcpy(&buf[0], state_user_missing, 2); return 2; } } @@ -309,12 +302,12 @@ static uint16_t u2f_authenticate(U2fData* U2F, const uint8_t* in_buf, uint8_t* o if(memcmp(req->key_handle.hash, mac_control, 32) != 0) { FURI_LOG_W(TAG, "Wrong handle!"); - memcpy(&out_buf[0], state_wrong_data, 2); + memcpy(&buf[0], state_wrong_data, 2); return 2; } - if(cmd->p1 == U2fCheckOnly) { // Check-only: don't need to send full response - memcpy(&out_buf[0], state_user_missing, 2); + if(req->p1 == U2fCheckOnly) { // Check-only: don't need to send full response + memcpy(&buf[0], state_user_missing, 2); return 2; } @@ -334,50 +327,22 @@ static uint16_t u2f_authenticate(U2fData* U2F, const uint8_t* in_buf, uint8_t* o return (sizeof(U2fAuthResp) + signature_len + 2); } -uint16_t u2f_applet_selection(const uint8_t* in_buf, uint8_t* out_buf) { - U2fApduCommand* cmd = (U2fApduCommand*)in_buf; - uint8_t* data = apdu_command_data(cmd); - - FURI_LOG_D( - TAG, - "len=%d %02x%02x%02x%02x%02x%02x%02x%02x", - cmd->len[0], - data[0], - data[1], - data[2], - data[3], - data[4], - data[5], - data[6], - data[7]); - - if(cmd->len[0] != 8 || memcmp(rid_ac_ax, data, 8) != 0) { - memcpy(&out_buf[0], state_app_not_found, 2); - return 2; - } - - memcpy(&out_buf[0], ver_str, 6); - memcpy(&out_buf[6], state_no_error, 2); - return 8; -} - -uint16_t u2f_msg_parse(U2fData* U2F, const uint8_t* in_buf, uint16_t in_len, uint8_t* out_buf) { +uint16_t u2f_msg_parse(U2fData* U2F, uint8_t* buf, uint16_t len) { furi_assert(U2F); if(!U2F->ready) return 0; - if((in_buf[0] != 0x00) && (in_len < 5)) return 0; - FURI_LOG_D(TAG, "ins=0x%02x", in_buf[1]); - if(in_buf[1] == U2F_CMD_REGISTER) { // Register request - return u2f_register(U2F, in_buf, out_buf); - } else if(in_buf[1] == U2F_CMD_AUTHENTICATE) { // Authenticate request - return u2f_authenticate(U2F, in_buf, out_buf); - } else if(in_buf[1] == U2F_CMD_VERSION) { // Get U2F version string - memcpy(&out_buf[0], ver_str, 6); - memcpy(&out_buf[6], state_no_error, 2); + if((buf[0] != 0x00) && (len < 5)) return 0; + if(buf[1] == U2F_CMD_REGISTER) { // Register request + return u2f_register(U2F, buf); + + } else if(buf[1] == U2F_CMD_AUTHENTICATE) { // Authenticate request + return u2f_authenticate(U2F, buf); + + } else if(buf[1] == U2F_CMD_VERSION) { // Get U2F version string + memcpy(&buf[0], ver_str, 6); + memcpy(&buf[6], state_no_error, 2); return 8; - } else if(in_buf[1] == U2F_CMD_APPLET_SELECTION) { - return u2f_applet_selection(in_buf, out_buf); } else { - memcpy(&out_buf[0], state_not_supported, 2); + memcpy(&buf[0], state_not_supported, 2); return 2; } return 0; diff --git a/applications/main/u2f/u2f.h b/applications/main/u2f/u2f.h index e7508dfa5..dcd7c3ff2 100644 --- a/applications/main/u2f/u2f.h +++ b/applications/main/u2f/u2f.h @@ -6,14 +6,6 @@ extern "C" { #include -typedef struct { - uint8_t cla; - uint8_t ins; - uint8_t p1; - uint8_t p2; - uint8_t len[]; -} __attribute__((packed)) U2fApduCommand; - typedef enum { U2fNotifyRegister, U2fNotifyAuth, @@ -38,7 +30,7 @@ void u2f_set_event_callback(U2fData* instance, U2fEvtCallback callback, void* co void u2f_confirm_user_present(U2fData* instance); -uint16_t u2f_msg_parse(U2fData* instance, const uint8_t* in_buf, uint16_t len, uint8_t* out_buf); +uint16_t u2f_msg_parse(U2fData* instance, uint8_t* buf, uint16_t len); void u2f_wink(U2fData* instance); diff --git a/applications/main/u2f/u2f_app_i.h b/applications/main/u2f/u2f_app_i.h index cfaf3a929..2896684c3 100644 --- a/applications/main/u2f/u2f_app_i.h +++ b/applications/main/u2f/u2f_app_i.h @@ -13,7 +13,6 @@ #include #include #include "views/u2f_view.h" -#include "u2f_nfc.h" #include "u2f_hid.h" #include "u2f.h" @@ -55,7 +54,6 @@ struct U2fApp { Widget* widget; FuriTimer* timer; U2fHid* u2f_hid; - U2fNfc* u2f_nfc; U2fView* u2f_view; U2fData* u2f_instance; GpioCustomEvent event_cur; diff --git a/applications/main/u2f/u2f_hid.c b/applications/main/u2f/u2f_hid.c index 4ca49a3bb..9b625c1f3 100644 --- a/applications/main/u2f/u2f_hid.c +++ b/applications/main/u2f/u2f_hid.c @@ -140,11 +140,8 @@ static bool u2f_hid_parse_request(U2fHid* u2f_hid) { } else if(u2f_hid->packet.cmd == U2F_HID_MSG) { // MSG - U2F message if((u2f_hid->lock == true) && (u2f_hid->packet.cid != u2f_hid->lock_cid)) return false; - uint16_t resp_len = u2f_msg_parse( - u2f_hid->u2f_instance, - u2f_hid->packet.payload, - u2f_hid->packet.len, - u2f_hid->packet.payload); + uint16_t resp_len = + u2f_msg_parse(u2f_hid->u2f_instance, u2f_hid->packet.payload, u2f_hid->packet.len); if(resp_len > 0) { u2f_hid->packet.len = resp_len; u2f_hid_send_response(u2f_hid); diff --git a/applications/main/u2f/u2f_nfc.c b/applications/main/u2f/u2f_nfc.c deleted file mode 100644 index 8c0439982..000000000 --- a/applications/main/u2f/u2f_nfc.c +++ /dev/null @@ -1,182 +0,0 @@ -#include "u2f_nfc.h" -#include "furi_hal.h" -#include "u2f.h" - -#define TAG "U2F_NFC" - -typedef enum { - WorkerEvtReserved = (1 << 0), - WorkerEvtStop = (1 << 1), -} WorkerEvtFlags; - -struct U2fNfc { - FuriThread* thread; - U2fData* u2f_instance; - uint8_t payload[65535]; - uint16_t payload_len; - uint16_t payload_cursor; -}; - -static uint16_t - u2f_callback(U2fNfc* u2f_nfc, const uint8_t* buff_rx, uint16_t buff_rx_len, uint8_t* buff_tx) { - U2fApduCommand* cmd = (U2fApduCommand*)buff_rx; - if(cmd->ins == 0xC0) { - if(u2f_nfc->payload_len == 0) { - FURI_LOG_E(TAG, "requested block but not chaining"); - buff_tx[0] = 0x69; - buff_tx[1] = 0x00; - return 2; - } - - FURI_LOG_T(TAG, "continued chaining %d/%d", u2f_nfc->payload_cursor, u2f_nfc->payload_len); - - uint16_t max_resp_len = cmd->len[0]; - if(max_resp_len == 0) { - max_resp_len = 256; - } - - uint16_t remaining_len = (u2f_nfc->payload_len - 2) - u2f_nfc->payload_cursor; - if(remaining_len > max_resp_len) { - memcpy(buff_tx, &u2f_nfc->payload[u2f_nfc->payload_cursor], max_resp_len); - remaining_len -= max_resp_len; - buff_tx[max_resp_len] = 0x61; - if(remaining_len >= 256) { - buff_tx[max_resp_len + 1] = 0x00; - } else { - buff_tx[max_resp_len + 1] = remaining_len; - } - u2f_nfc->payload_cursor += max_resp_len; - return max_resp_len + 2; - } else { - memcpy( - buff_tx, - &u2f_nfc->payload[u2f_nfc->payload_cursor], - u2f_nfc->payload_len - u2f_nfc->payload_cursor); - u2f_nfc->payload_len = 0; - return remaining_len; - } - } - - // Presence is implied by touching the NFC devices. - u2f_confirm_user_present(u2f_nfc->u2f_instance); - - u2f_nfc->payload_len = - u2f_msg_parse(u2f_nfc->u2f_instance, buff_rx, buff_rx_len, u2f_nfc->payload); - - // If this is extended format, send entire response at once - if(cmd->len[0] == 0) { - FURI_LOG_T(TAG, "single extended response"); - memcpy(&buff_tx, u2f_nfc->payload, u2f_nfc->payload_len); - uint16_t len = u2f_nfc->payload_len; - u2f_nfc->payload_len = 0; - return len; - } - - // Otherwise, we need to do chaining. - uint16_t max_resp_len = 256; - - // If this message happens to be less than the chaining size, send it all at once. - if((u2f_nfc->payload_len - 2) <= max_resp_len) { - FURI_LOG_T(TAG, "single short response"); - memcpy(buff_tx, u2f_nfc->payload, u2f_nfc->payload_len); - uint16_t len = u2f_nfc->payload_len; - u2f_nfc->payload_len = 0; - return len; - } else { - memcpy(buff_tx, u2f_nfc->payload, max_resp_len); - buff_tx[max_resp_len] = 0x61; - uint16_t remaining_len = (u2f_nfc->payload_len - 2) - max_resp_len; - if(remaining_len >= max_resp_len) { - buff_tx[max_resp_len + 1] = 0x00; - } else { - buff_tx[max_resp_len + 1] = remaining_len; - } - u2f_nfc->payload_cursor = max_resp_len; - FURI_LOG_T( - TAG, "started u2f chaining %d/%d", u2f_nfc->payload_cursor, u2f_nfc->payload_len); - return max_resp_len + 2; - } -} - -static int32_t u2f_nfc_worker(void* context) { - U2fNfc* u2f_nfc = context; - FURI_LOG_D(TAG, "Init"); - while(furi_hal_nfc_is_busy()) { - furi_delay_ms(10); - } - FuriHalNfcDevData params = { - // TODO: Randomize this or something? - .uid = {0xCF, 0x72, 0xd4, 0x40}, - .uid_len = 4, - .atqa = {0x00, 0x04}, - .sak = 0x20, - .type = FuriHalNfcTypeA, - .interface = FuriHalNfcInterfaceIsoDep, - }; - - furi_hal_nfc_exit_sleep(); - - FURI_LOG_D(TAG, "Start"); - - while(1) { - uint32_t flags = furi_thread_flags_wait(WorkerEvtStop, FuriFlagWaitAny, 10); - if(flags != FuriFlagErrorTimeout) { - furi_check((flags & FuriFlagError) == 0); - if(flags & WorkerEvtStop) break; - } - if(!furi_hal_nfc_listen(¶ms, false, 200)) { - FURI_LOG_T(TAG, "wtf"); - continue; - } - FuriHalNfcTxRxContext tx_rx = {}; - tx_rx.tx_bits = 0; - tx_rx.tx_rx_type = FuriHalNfcTxRxTypeDefault; - if(!furi_hal_nfc_tx_rx(&tx_rx, 300)) continue; - if(tx_rx.rx_bits == 0) continue; - u2f_nfc->payload_len = 0; - u2f_nfc->payload_cursor = 0; - while(true) { - uint16_t payload_len = - u2f_callback(u2f_nfc, tx_rx.rx_data, tx_rx.rx_bits / 8, tx_rx.tx_data); - tx_rx.rx_bits = 0; - FURI_LOG_T(TAG, "payload_len=%d", payload_len); - if(payload_len == 0) { - break; - } else { - tx_rx.tx_bits = payload_len * 8; - tx_rx.tx_rx_type = FuriHalNfcTxRxTypeDefault; - if(!furi_hal_nfc_tx_rx(&tx_rx, 300)) break; - if(tx_rx.rx_bits == 0) break; - } - } - } - - FURI_LOG_D(TAG, "Cleanup"); - furi_hal_nfc_sleep(); - FURI_LOG_D(TAG, "End"); - return 0; -} - -U2fNfc* u2f_nfc_start(U2fData* u2f_inst) { - U2fNfc* u2f_nfc = malloc(sizeof(U2fNfc)); - u2f_nfc->u2f_instance = u2f_inst; - u2f_nfc->payload_len = 0; - u2f_nfc->payload_cursor = 0; - - u2f_nfc->thread = furi_thread_alloc(); - furi_thread_set_name(u2f_nfc->thread, "U2fNFCWorker"); - furi_thread_set_stack_size(u2f_nfc->thread, 4096); - furi_thread_set_context(u2f_nfc->thread, u2f_nfc); - furi_thread_set_callback(u2f_nfc->thread, u2f_nfc_worker); - furi_thread_start(u2f_nfc->thread); - - return u2f_nfc; -} - -void u2f_nfc_stop(U2fNfc* u2f_nfc) { - furi_assert(u2f_nfc); - furi_thread_flags_set(furi_thread_get_id(u2f_nfc->thread), WorkerEvtStop); - furi_thread_join(u2f_nfc->thread); - furi_thread_free(u2f_nfc->thread); - free(u2f_nfc); -} diff --git a/applications/main/u2f/u2f_nfc.h b/applications/main/u2f/u2f_nfc.h deleted file mode 100644 index 3ac9186f7..000000000 --- a/applications/main/u2f/u2f_nfc.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "u2f.h" - -typedef struct U2fNfc U2fNfc; - -U2fNfc* u2f_nfc_start(U2fData* u2f_inst); - -void u2f_nfc_stop(U2fNfc* u2f_hid); - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 35fd8015d..d04c22bc9 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,13.0,, +Version,+,12.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1198,7 +1198,7 @@ Function,+,furi_hal_nfc_field_on,void, Function,-,furi_hal_nfc_init,void, Function,+,furi_hal_nfc_is_busy,_Bool, Function,+,furi_hal_nfc_is_init,_Bool, -Function,+,furi_hal_nfc_listen,_Bool,"FuriHalNfcDevData*, _Bool, uint32_t" +Function,+,furi_hal_nfc_listen,_Bool,"uint8_t*, uint8_t, uint8_t*, uint8_t, _Bool, uint32_t" Function,+,furi_hal_nfc_listen_rx,_Bool,"FuriHalNfcTxRxContext*, uint32_t" Function,+,furi_hal_nfc_listen_sleep,void, Function,+,furi_hal_nfc_listen_start,void,FuriHalNfcDevData* diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index 5e851254d..6381d1a91 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -205,7 +205,13 @@ bool furi_hal_nfc_activate_nfca(uint32_t timeout, uint32_t* cuid) { return true; } -bool furi_hal_nfc_listen(FuriHalNfcDevData* nfc_data, bool activate_after_sak, uint32_t timeout) { +bool furi_hal_nfc_listen( + uint8_t* uid, + uint8_t uid_len, + uint8_t* atqa, + uint8_t sak, + bool activate_after_sak, + uint32_t timeout) { rfalNfcState state = rfalNfcGetState(); if(state == RFAL_NFC_STATE_NOTINIT) { rfalNfcInitialize(); @@ -226,18 +232,16 @@ bool furi_hal_nfc_listen(FuriHalNfcDevData* nfc_data, bool activate_after_sak, u .notifyCb = NULL, .activate_after_sak = activate_after_sak, }; - if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { - params.compMode = RFAL_COMPLIANCE_MODE_ISO; - } else if(FURI_BIT(nfc_data->sak, 5)) { + if(FURI_BIT(sak, 5)) { params.compMode = RFAL_COMPLIANCE_MODE_EMV; } else { params.compMode = RFAL_COMPLIANCE_MODE_NFC; } - params.lmConfigPA.nfcidLen = nfc_data->uid_len; - memcpy(params.lmConfigPA.nfcid, nfc_data->uid, nfc_data->uid_len); - params.lmConfigPA.SENS_RES[0] = nfc_data->atqa[0]; - params.lmConfigPA.SENS_RES[1] = nfc_data->atqa[1]; - params.lmConfigPA.SEL_RES = nfc_data->sak; + params.lmConfigPA.nfcidLen = uid_len; + memcpy(params.lmConfigPA.nfcid, uid, uid_len); + params.lmConfigPA.SENS_RES[0] = atqa[0]; + params.lmConfigPA.SENS_RES[1] = atqa[1]; + params.lmConfigPA.SEL_RES = sak; rfalNfcDiscover(¶ms); // Disable EMD suppression. diff --git a/firmware/targets/furi_hal_include/furi_hal_nfc.h b/firmware/targets/furi_hal_include/furi_hal_nfc.h index 06cd46ba4..d3f6de602 100644 --- a/firmware/targets/furi_hal_include/furi_hal_nfc.h +++ b/firmware/targets/furi_hal_include/furi_hal_nfc.h @@ -154,7 +154,6 @@ bool furi_hal_nfc_activate_nfca(uint32_t timeout, uint32_t* cuid); /** NFC listen * * @param uid pointer to uid buffer - * @param nfc_data pointer to FuriHalNfcDevData * @param uid_len uid length * @param atqa pointer to atqa * @param sak sak @@ -163,7 +162,13 @@ bool furi_hal_nfc_activate_nfca(uint32_t timeout, uint32_t* cuid); * * @return true on success */ -bool furi_hal_nfc_listen(FuriHalNfcDevData* nfc_data, bool activate_after_sak, uint32_t timeout); +bool furi_hal_nfc_listen( + uint8_t* uid, + uint8_t uid_len, + uint8_t* atqa, + uint8_t sak, + bool activate_after_sak, + uint32_t timeout); /** Start Target Listen mode * @note RFAL free implementation diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index a67c64c3c..4138bf033 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -776,7 +776,7 @@ void nfc_worker_emulate_uid(NfcWorker* nfc_worker) { // Need to save ATS to support ISO-14443A-4 emulation while(nfc_worker->state == NfcWorkerStateUidEmulate) { - if(furi_hal_nfc_listen(data, false, 100)) { + if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, false, 100)) { if(furi_hal_nfc_tx_rx(&tx_rx, 100)) { reader_data->size = tx_rx.rx_bits / 8; if(reader_data->size > 0) { @@ -834,7 +834,7 @@ void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) { } while(nfc_worker->state == NfcWorkerStateEmulateApdu) { //-V1044 - if(furi_hal_nfc_listen(¶ms, false, 300)) { + if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) { FURI_LOG_D(TAG, "POS terminal detected"); if(emv_card_emulation(&tx_rx)) { FURI_LOG_D(TAG, "EMV card emulated"); diff --git a/scripts/flipper/assets/icon.py b/scripts/flipper/assets/icon.py index c31eab0b7..ed85b024e 100644 --- a/scripts/flipper/assets/icon.py +++ b/scripts/flipper/assets/icon.py @@ -60,10 +60,7 @@ class ImageTools: with Image.open(file) as im: with io.BytesIO() as output: bw = im.convert("1") - try: - bw = ImageOps.invert(bw) - except OSError: - bw = bw.point(lambda x: 255 - x) + bw = ImageOps.invert(bw) bw.save(output, format="XBM") return output.getvalue()