diff --git a/applications/main/nfc/nfc_cli.c b/applications/main/nfc/nfc_cli.c index 676e61b0c..a6475ca68 100644 --- a/applications/main/nfc/nfc_cli.c +++ b/applications/main/nfc/nfc_cli.c @@ -1,23 +1,11 @@ #include #include -#include #include #include -#include -#include -#include -#include -#include -#include #include #include - -#include -#include - - static void nfc_cli_print_usage() { printf("Usage:\r\n"); printf("nfc \r\n"); @@ -110,7 +98,6 @@ static void nfc_cli_field(Cli* cli, FuriString* args) { furi_hal_nfc_sleep(); } - static void nfc_cli(Cli* cli, FuriString* args, void* context) { UNUSED(context); FuriString* cmd; diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index 33f37f3e3..2aa564839 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -12,13 +12,13 @@ ADD_SCENE(nfc, save_name, SaveName) ADD_SCENE(nfc, save_success, SaveSuccess) ADD_SCENE(nfc, file_select, FileSelect) ADD_SCENE(nfc, emulate_uid, EmulateUid) -ADD_SCENE(nfc, emulate_nfcv, EmulateNfcV) ADD_SCENE(nfc, nfca_read_success, NfcaReadSuccess) ADD_SCENE(nfc, nfca_menu, NfcaMenu) ADD_SCENE(nfc, nfcv_menu, NfcVMenu) ADD_SCENE(nfc, nfcv_unlock_menu, NfcVUnlockMenu) ADD_SCENE(nfc, nfcv_key_input, NfcVKeyInput) ADD_SCENE(nfc, nfcv_unlock, NfcVUnlock) +ADD_SCENE(nfc, emulate_nfcv, EmulateNfcV) ADD_SCENE(nfc, mf_ultralight_read_success, MfUltralightReadSuccess) ADD_SCENE(nfc, mf_ultralight_data, MfUltralightData) ADD_SCENE(nfc, mf_ultralight_menu, MfUltralightMenu) diff --git a/fbt_options.py b/fbt_options.py index 7c05b1305..11124b936 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -8,13 +8,13 @@ TARGET_HW = 7 # Optimization flags ## Optimize for size -COMPACT = 1 +COMPACT = 0 ## Optimize for debugging experience -DEBUG = 0 +DEBUG = 1 # Suffix to add to files when building distribution # If OS environment has DIST_SUFFIX set, it will be used instead -DIST_SUFFIX = "RevvoX" +DIST_SUFFIX = "local" # Coprocessor firmware COPRO_OB_DATA = "scripts/ob.data" diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 063380743..0b51007d7 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,+,7.35,, +Version,+,7.36,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -669,6 +669,7 @@ Function,-,coshl,long double,long double Function,-,cosl,long double,long double Function,+,crc32_calc_buffer,uint32_t,"uint32_t, const void*, size_t" Function,+,crc32_calc_file,uint32_t,"File*, const FileCrcProgressCb, void*" +Function,-,crypto1_bit,uint8_t,"Crypto1*, uint8_t, int" Function,-,crypto1_byte,uint8_t,"Crypto1*, uint8_t, int" Function,-,crypto1_decrypt,void,"Crypto1*, uint8_t*, uint16_t, uint8_t*" Function,-,crypto1_encrypt,void,"Crypto1*, uint8_t*, uint8_t*, uint16_t, uint8_t*, uint8_t*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index 88b34aae9..c1ce2ebbb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -523,7 +523,6 @@ bool furi_hal_nfc_emulate_nfca( return true; } - static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { furi_assert(tx_rx->nfca_signal); @@ -743,6 +742,13 @@ void furi_hal_nfc_gen_bitstream(FuriHalNfcTxRxContext* tx_rx, uint8_t *buffer, s bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { furi_assert(tx_rx); + ReturnCode ret; + rfalNfcState state = RFAL_NFC_STATE_ACTIVATED; + uint8_t temp_tx_buff[FURI_HAL_NFC_DATA_BUFF_SIZE] = {}; + uint16_t temp_tx_bits = 0; + uint8_t* temp_rx_buff = NULL; + uint16_t* temp_rx_bits = NULL; + /* send and receive data using transparent mode */ if(tx_rx->tx_rx_type == FuriHalNfcTxRxFullyTransparent) { return furi_hal_nfc_fully_transparent_tx_rx(tx_rx, timeout_ms); @@ -752,15 +758,6 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { return furi_hal_nfc_transparent_tx_rx(tx_rx, timeout_ms); } - ReturnCode ret; - rfalNfcState state = RFAL_NFC_STATE_ACTIVATED; - uint8_t temp_tx_buff[FURI_HAL_NFC_DATA_BUFF_SIZE] = {}; - uint16_t temp_tx_bits = 0; - uint8_t* temp_rx_buff = NULL; - uint16_t* temp_rx_bits = NULL; - - //FURI_LOG_D(TAG, "furi_hal_nfc_tx_rx %u", tx_rx->tx_rx_type); - // Prepare data for FIFO if necessary uint32_t flags = furi_hal_nfc_tx_rx_get_flag(tx_rx->tx_rx_type); if(tx_rx->tx_rx_type == FuriHalNfcTxRxTypeRaw) { diff --git a/furi/core/common_defines.h b/furi/core/common_defines.h index c5ffbf454..31be7fff0 100644 --- a/furi/core/common_defines.h +++ b/furi/core/common_defines.h @@ -23,33 +23,18 @@ extern "C" { #define FURI_IS_ISR() (FURI_IS_IRQ_MODE() || FURI_IS_IRQ_MASKED()) #endif -#ifndef FURI_CRITICAL_DEFINE -#define FURI_CRITICAL_DEFINE() \ - uint32_t __isrm = 0; \ - bool __from_isr = false; \ - bool __kernel_running = false; -#endif - -#ifndef FURI_CRITICAL_ENTER_ADV -#define FURI_CRITICAL_ENTER_ADV() \ - do { \ - __isrm = 0; \ - __from_isr = FURI_IS_ISR(); \ - __kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); \ - if(__from_isr) { \ - __isrm = taskENTER_CRITICAL_FROM_ISR(); \ - } else if(__kernel_running) { \ - taskENTER_CRITICAL(); \ - } else { \ - __disable_irq(); \ - } \ - } while(0) -#endif - #ifndef FURI_CRITICAL_ENTER -#define FURI_CRITICAL_ENTER() \ - FURI_CRITICAL_DEFINE(); \ - FURI_CRITICAL_ENTER_ADV(); +#define FURI_CRITICAL_ENTER() \ + uint32_t __isrm = 0; \ + bool __from_isr = FURI_IS_ISR(); \ + bool __kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); \ + if(__from_isr) { \ + __isrm = taskENTER_CRITICAL_FROM_ISR(); \ + } else if(__kernel_running) { \ + taskENTER_CRITICAL(); \ + } else { \ + __disable_irq(); \ + } #endif #ifndef FURI_CRITICAL_EXIT diff --git a/lib/digital_signal/digital_signal.h b/lib/digital_signal/digital_signal.h index 4d25b90c2..8f6142258 100644 --- a/lib/digital_signal/digital_signal.h +++ b/lib/digital_signal/digital_signal.h @@ -46,14 +46,23 @@ typedef struct { DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt); + void digital_signal_free(DigitalSignal* signal); + void digital_signal_add(DigitalSignal* signal, uint32_t ticks); + void digital_signal_add_pulse(DigitalSignal* signal, uint32_t ticks, bool level); + bool digital_signal_append(DigitalSignal* signal_a, DigitalSignal* signal_b); + void digital_signal_prepare(DigitalSignal* signal); + bool digital_signal_get_start_level(DigitalSignal* signal); + uint32_t digital_signal_get_edges_cnt(DigitalSignal* signal); + uint32_t digital_signal_get_edge(DigitalSignal* signal, uint32_t edge_num); + void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio); diff --git a/lib/nfc/protocols/crypto1.c b/lib/nfc/protocols/crypto1.c index 453b08a22..2ac0ff081 100644 --- a/lib/nfc/protocols/crypto1.c +++ b/lib/nfc/protocols/crypto1.c @@ -36,7 +36,7 @@ uint32_t crypto1_filter(uint32_t in) { return FURI_BIT(0xEC57E80A, out); } -static inline uint8_t crypto1_bit(Crypto1* crypto1, uint8_t in, int is_encrypted) { +uint8_t crypto1_bit(Crypto1* crypto1, uint8_t in, int is_encrypted) { furi_assert(crypto1); uint8_t out = crypto1_filter(crypto1->odd); uint32_t feed = out & (!!is_encrypted); @@ -58,15 +58,6 @@ uint8_t crypto1_byte(Crypto1* crypto1, uint8_t in, int is_encrypted) { return out; } -static inline uint8_t crypto1_byte_inline(Crypto1* crypto1, uint8_t in, int is_encrypted) { - furi_assert(crypto1); - uint8_t out = 0; - for(uint8_t i = 0; i < 8; i++) { - out |= crypto1_bit(crypto1, FURI_BIT(in, i), is_encrypted) << i; - } - return out; -} - uint32_t crypto1_word(Crypto1* crypto1, uint32_t in, int is_encrypted) { furi_assert(crypto1); uint32_t out = 0; @@ -101,7 +92,7 @@ void crypto1_decrypt( decrypted_data[0] = decrypted_byte; } else { for(size_t i = 0; i < encrypted_data_bits / 8; i++) { - decrypted_data[i] = crypto1_byte_inline(crypto, 0, 0) ^ encrypted_data[i]; + decrypted_data[i] = crypto1_byte(crypto, 0, 0) ^ encrypted_data[i]; } } } @@ -126,7 +117,7 @@ void crypto1_encrypt( } else { memset(encrypted_parity, 0, plain_data_bits / 8 + 1); for(uint8_t i = 0; i < plain_data_bits / 8; i++) { - encrypted_data[i] = crypto1_byte_inline(crypto, keystream ? keystream[i] : 0, 0) ^ + encrypted_data[i] = crypto1_byte(crypto, keystream ? keystream[i] : 0, 0) ^ plain_data[i]; encrypted_parity[i / 8] |= (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(plain_data[i])) & 0x01) diff --git a/lib/nfc/protocols/crypto1.h b/lib/nfc/protocols/crypto1.h index 5b1402549..450d1534e 100644 --- a/lib/nfc/protocols/crypto1.h +++ b/lib/nfc/protocols/crypto1.h @@ -12,7 +12,7 @@ void crypto1_reset(Crypto1* crypto1); void crypto1_init(Crypto1* crypto1, uint64_t key); -//uint8_t crypto1_bit(Crypto1* crypto1, uint8_t in, int is_encrypted); +uint8_t crypto1_bit(Crypto1* crypto1, uint8_t in, int is_encrypted); uint8_t crypto1_byte(Crypto1* crypto1, uint8_t in, int is_encrypted); diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 094ea7507..7b0e17975 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -763,39 +763,26 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ uint8_t plain_data[MF_CLASSIC_MAX_DATA_SIZE]; MfClassicKey access_key = MfClassicKeyA; - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; - - FURI_LOG_D(TAG, "Starting mf_classic_emulator"); - // Read command while(!command_processed) { if(!is_encrypted) { crypto1_reset(&emulator->crypto); memcpy(plain_data, tx_rx->rx_data, tx_rx->rx_bits / 8); } else { - tx_rx->rx_bits = 0; if(!furi_hal_nfc_tx_rx(tx_rx, 300)) { FURI_LOG_D( TAG, - "Error in tx rx. Tx :%d bits, Rx: %d bits. Received:", + "Error in tx rx. Tx :%d bits, Rx: %d bits", tx_rx->tx_bits, tx_rx->rx_bits); - - FURI_LOG_D(TAG,"Sent:"); - for(int pos = 0; pos < tx_rx->tx_bits/8; pos++) { - FURI_LOG_D(TAG," %02X", tx_rx->tx_data[pos]); - } - FURI_LOG_D(TAG,"Received:"); - for(int pos = 0; pos < tx_rx->rx_bits/8; pos++) { - FURI_LOG_D(TAG," %02X", tx_rx->rx_data[pos]); - } break; } crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data); } if(plain_data[0] == 0x50 && plain_data[1] == 0x00) { - //furi_hal_nfc_listen_sleep(); + FURI_LOG_T(TAG, "Halt received"); + furi_hal_nfc_listen_sleep(); command_processed = true; break; } else if(plain_data[0] == 0x60 || plain_data[0] == 0x61) { @@ -812,7 +799,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ access_key = MfClassicKeyB; } - uint32_t nonce = prng_successor(DWT->CYCCNT, 2) ^ 0xAA; + uint32_t nonce = prng_successor(DWT->CYCCNT, 32) ^ 0xAA; uint8_t nt[4]; uint8_t nt_keystream[4]; nfc_util_num2bytes(nonce, 4, nt); @@ -820,15 +807,13 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ crypto1_init(&emulator->crypto, key); if(!is_encrypted) { crypto1_word(&emulator->crypto, emulator->cuid ^ nonce, 0); - for(size_t pos = 0; pos < sizeof(nt); pos++) { - tx_rx->tx_data[pos] = nt[pos]; - } + memcpy(tx_rx->tx_data, nt, sizeof(nt)); tx_rx->tx_parity[0] = 0; for(size_t i = 0; i < sizeof(nt); i++) { tx_rx->tx_parity[0] |= nfc_util_odd_parity8(nt[i]) << (7 - i); } tx_rx->tx_bits = sizeof(nt) * 8; - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; } else { crypto1_encrypt( &emulator->crypto, @@ -838,10 +823,10 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ tx_rx->tx_data, tx_rx->tx_parity); tx_rx->tx_bits = sizeof(nt) * 8; - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; } if(!furi_hal_nfc_tx_rx(tx_rx, 500)) { - FURI_LOG_E(TAG, "Error in NT exchange?"); + FURI_LOG_E(TAG, "Error in NT exchange"); command_processed = true; break; } @@ -854,7 +839,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4); uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4); -/* + FURI_LOG_D( TAG, "%08lx key%c block %d nt/nr/ar: %08lx %08lx %08lx", @@ -864,7 +849,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ nonce, nr, ar); -*/ + crypto1_word(&emulator->crypto, nr, 1); uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0); if(cardRr != prng_successor(nonce, 64)) { @@ -885,7 +870,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ tx_rx->tx_data, tx_rx->tx_parity); tx_rx->tx_bits = sizeof(responce) * 8; - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; is_encrypted = true; } else if(is_encrypted && plain_data[0] == 0x30) { @@ -916,7 +901,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ } else { tx_rx->tx_data[0] = nack; } - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; tx_rx->tx_bits = 4; furi_hal_nfc_tx_rx(tx_rx, 300); break; @@ -932,7 +917,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ tx_rx->tx_data, tx_rx->tx_parity); tx_rx->tx_bits = 18 * 8; - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; } else if(is_encrypted && plain_data[0] == 0xA0) { uint8_t block = plain_data[1]; if(block > mf_classic_get_total_block_num(emulator->data.type)) { @@ -941,7 +926,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ // Send ACK uint8_t ack = 0x0A; crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; tx_rx->tx_bits = 4; if(!furi_hal_nfc_tx_rx(tx_rx, 300)) break; @@ -976,10 +961,9 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ // Send ACK ack = 0x0A; crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity); - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; tx_rx->tx_bits = 4; } else { - FURI_LOG_T(TAG, "%02X unknown received", plain_data[0]); // Unknown command break; } @@ -993,7 +977,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_ } else { tx_rx->tx_data[0] = nack; } - tx_rx->tx_rx_type = FuriHalNfcTxRxFullyTransparent; + tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent; tx_rx->tx_bits = 4; furi_hal_nfc_tx_rx(tx_rx, 300); } diff --git a/lib/nfc/protocols/nfca.h b/lib/nfc/protocols/nfca.h index a4928a3eb..82fb3e334 100644 --- a/lib/nfc/protocols/nfca.h +++ b/lib/nfc/protocols/nfca.h @@ -27,4 +27,3 @@ NfcaSignal* nfca_signal_alloc(); void nfca_signal_free(NfcaSignal* nfca_signal); void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, uint8_t* parity); -