Skip to content

Commit 11f41e2

Browse files
committed
Squashed 'applications/external/' changes from ea5d532d8c..746531bdf1
746531bdf1 VgmTool: Add RGB fw for MNTM VGM options 3da3a125fe Merge picopass from https://github.com/flipperdevices/flipperzero-good-faps 200f9dc382 Merge nfc_magic from https://github.com/flipperdevices/flipperzero-good-faps 573634ece1 Merge air_arkanoid from https://github.com/flipperdevices/flipperzero-good-faps cc9223968d AirArkanoid: Fix python3 on Windows (#155) a70b5c5840 Picopass block tracking (#125) 15c7c2d66e NFC Magic: update with latest API (#167) 3219fe82fa Picopass: update with latest API (#165) git-subtree-dir: applications/external git-subtree-split: 746531bdf1646328448533f1d3c9612ec6c061a1
1 parent 61c1fa8 commit 11f41e2

19 files changed

+85
-77
lines changed

air_arkanoid/application.fam

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ App(
1212
fap_extbuild=(
1313
ExtFile(
1414
path="${FAP_SRC_DIR}/assets",
15-
command=("python" if __import__("sys").platform == "win32" else "python3")
16-
+ " ${FAP_SRC_DIR}/engine/scripts/sprite_builder.py ${FAP_SRC_DIR.abspath}/sprites ${TARGET.abspath}/sprites",
15+
command="${PYTHON3} ${FAP_SRC_DIR}/engine/scripts/sprite_builder.py ${FAP_SRC_DIR.abspath}/sprites ${TARGET.abspath}/sprites",
1716
),
1817
),
1918
)

nfc_magic/.catalog/changelog.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
## 1.4
1+
## 1.6
2+
- Rework with new bit lib API
23

4+
## 1.5
35
- Fix incorrect max sector configuration
46

57
## 1.4
6-
78
- Auth with password option moved into new submenu "Gen4 actions"
89
- New function: Get gen4 card revision
910
- New function: Get gen4 card config (shows only when debug ON)

nfc_magic/application.fam

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ App(
1010
],
1111
stack_size=4 * 1024,
1212
fap_description="Application for writing to NFC tags with modifiable sector 0",
13-
fap_version="1.5",
14-
fap_icon="125_10px.png",
13+
fap_version="1.6",
14+
fap_icon="assets/125_10px.png",
1515
fap_category="NFC",
1616
fap_private_libs=[
1717
Lib(
File renamed without changes.

nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "bit_buffer.h"
44
#include "protocols/gen4/gen4_poller.h"
55
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
6-
#include <bit_lib.h>
76

87
#define GEN4_CMD_PREFIX (0xCF)
98

nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "gen4_poller.h"
44
#include <nfc/nfc_poller.h>
55
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
6+
#include <bit_lib/bit_lib.h>
67

78
#define TAG "Gen4Poller"
89

nfc_magic/scenes/nfc_magic_scene_key_input.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "../nfc_magic_app_i.h"
22

3-
#include <bit_lib.h>
3+
#include <bit_lib/bit_lib.h>
44

55
void nfc_magic_scene_key_input_byte_input_callback(void* context) {
66
NfcMagicApp* instance = context;

picopass/.catalog/changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
## 1.13
2+
- Rework loclass writer with datetime lib
13
## 1.12
24
- Add support for non-secure Picopass
35
- Change Read to use all dictionaries

picopass/application.fam

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ App(
1010
],
1111
stack_size=4 * 1024,
1212
fap_description="App to communicate with NFC tags using the PicoPass(iClass) format",
13-
fap_version="1.12",
13+
fap_version="1.13",
1414
fap_icon="125_10px.png",
1515
fap_category="NFC",
1616
fap_libs=["mbedtls"],

picopass/loclass_writer.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <storage/storage.h>
66
#include <stream/stream.h>
77
#include <stream/buffered_file_stream.h>
8+
#include <datetime/datetime.h>
89

910
struct LoclassWriter {
1011
Stream* file_stream;
@@ -41,7 +42,9 @@ void loclass_writer_free(LoclassWriter* instance) {
4142
bool loclass_writer_write_start_stop(LoclassWriter* instance, bool start) {
4243
furi_assert(instance != NULL);
4344

44-
uint32_t curr_ts = furi_hal_rtc_get_timestamp();
45+
DateTime curr_dt;
46+
furi_hal_rtc_get_datetime(&curr_dt);
47+
uint32_t curr_ts = datetime_datetime_to_timestamp(&curr_dt);
4548

4649
FuriString* str = furi_string_alloc_printf(
4750
"loclass-v1-info ts %lu %s\n", curr_ts, start ? "started" : "finished");
@@ -59,7 +62,9 @@ bool loclass_writer_write_params(
5962
const uint8_t mac[4]) {
6063
furi_assert(instance != NULL);
6164

62-
uint32_t curr_ts = furi_hal_rtc_get_timestamp();
65+
DateTime curr_dt;
66+
furi_hal_rtc_get_datetime(&curr_dt);
67+
uint32_t curr_ts = datetime_datetime_to_timestamp(&curr_dt);
6368

6469
FuriString* str = furi_string_alloc_printf(
6570
"loclass-v1-mac ts %lu no %u "

picopass/picopass_device.c

+1
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ bool picopass_file_select(PicopassDevice* dev) {
371371
void picopass_device_data_clear(PicopassDeviceData* dev_data) {
372372
for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) {
373373
memset(dev_data->card_data[i].data, 0, sizeof(dev_data->card_data[i].data));
374+
dev_data->card_data[i].valid = false;
374375
}
375376
dev_data->pacs.legacy = false;
376377
dev_data->pacs.se_enabled = false;

picopass/picopass_device.h

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct {
9999

100100
typedef struct {
101101
uint8_t data[PICOPASS_BLOCK_LEN];
102+
bool valid;
102103
} PicopassBlock;
103104

104105
typedef struct {

picopass/protocol/picopass_listener.c

+11-13
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,12 @@ static void picopass_listener_loclass_update_csn(PicopassListener* instance) {
4343
// collect LOCLASS_NUM_PER_CSN nonces in a row for each CSN
4444
const uint8_t* csn =
4545
loclass_csns[(instance->key_block_num / LOCLASS_NUM_PER_CSN) % LOCLASS_NUM_CSNS];
46-
memcpy(instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data, csn, sizeof(PicopassBlock));
46+
memcpy(instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data, csn, PICOPASS_BLOCK_LEN);
4747

4848
uint8_t key[PICOPASS_BLOCK_LEN] = {};
4949
loclass_iclass_calc_div_key(csn, picopass_iclass_key, key, false);
5050
memcpy(
51-
instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data,
52-
key,
53-
sizeof(PicopassBlock));
51+
instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, key, PICOPASS_BLOCK_LEN);
5452

5553
picopass_listener_init_cipher_state_key(instance, key);
5654
}
@@ -122,7 +120,7 @@ PicopassListenerCommand
122120
bit_buffer_copy_bytes(
123121
instance->tmp_buffer,
124122
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data,
125-
sizeof(PicopassBlock));
123+
PICOPASS_BLOCK_LEN);
126124
} else {
127125
picopass_listener_write_anticoll_csn(instance, instance->tmp_buffer);
128126
}
@@ -143,7 +141,7 @@ PicopassListenerCommand
143141
bit_buffer_copy_bytes(
144142
instance->tx_buffer,
145143
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data,
146-
sizeof(PicopassBlock));
144+
PICOPASS_BLOCK_LEN);
147145

148146
PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer);
149147
if(error != PicopassErrorNone) {
@@ -181,7 +179,7 @@ PicopassListenerCommand
181179
bit_buffer_copy_bytes(
182180
instance->tx_buffer,
183181
instance->data->card_data[block_num].data,
184-
sizeof(PicopassBlock));
182+
PICOPASS_BLOCK_LEN);
185183
}
186184
PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer);
187185
if(error != PicopassErrorNone) {
@@ -216,7 +214,7 @@ static PicopassListenerCommand
216214

217215
// DATA(8)
218216
bit_buffer_copy_bytes(
219-
instance->tx_buffer, instance->data->card_data[block_num].data, sizeof(PicopassBlock));
217+
instance->tx_buffer, instance->data->card_data[block_num].data, PICOPASS_BLOCK_LEN);
220218
NfcError error = nfc_listener_tx(instance->nfc, instance->tx_buffer);
221219
if(error != NfcErrorNone) {
222220
FURI_LOG_D(TAG, "Failed to tx read check response: %d", error);
@@ -508,15 +506,15 @@ PicopassListenerCommand
508506
case PICOPASS_SECURE_KC_BLOCK_INDEX:
509507
if(!pers_mode && secured) {
510508
new_block = instance->data->card_data[block_num];
511-
for(size_t i = 0; i < sizeof(PicopassBlock); i++) {
509+
for(size_t i = 0; i < PICOPASS_BLOCK_LEN; i++) {
512510
new_block.data[i] ^= rx_data[i + 2];
513511
}
514512
break;
515513
}
516514
// Use default case when in personalisation mode
517515
// fallthrough
518516
default:
519-
memcpy(new_block.data, &rx_data[2], sizeof(PicopassBlock));
517+
memcpy(new_block.data, &rx_data[2], PICOPASS_BLOCK_LEN);
520518
break;
521519
}
522520

@@ -537,7 +535,7 @@ PicopassListenerCommand
537535
bit_buffer_copy_bytes(
538536
instance->tx_buffer,
539537
instance->data->card_data[block_num].data,
540-
sizeof(PicopassBlock));
538+
PICOPASS_BLOCK_LEN);
541539
}
542540

543541
PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer);
@@ -572,12 +570,12 @@ PicopassListenerCommand
572570
for(uint8_t i = block_start; i < block_start + 4; i++) {
573571
if(secured &&
574572
((i == PICOPASS_SECURE_KD_BLOCK_INDEX) || (i == PICOPASS_SECURE_KC_BLOCK_INDEX))) {
575-
for(size_t j = 0; j < sizeof(PicopassBlock); j++) {
573+
for(size_t j = 0; j < PICOPASS_BLOCK_LEN; j++) {
576574
bit_buffer_append_byte(instance->tx_buffer, 0xff);
577575
}
578576
} else {
579577
bit_buffer_append_bytes(
580-
instance->tx_buffer, instance->data->card_data[i].data, sizeof(PicopassBlock));
578+
instance->tx_buffer, instance->data->card_data[i].data, PICOPASS_BLOCK_LEN);
581579
}
582580
}
583581

picopass/protocol/picopass_listener_i.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ void picopass_listener_init_cipher_state_key(PicopassListener* instance, const u
2323
memcpy(
2424
cc,
2525
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data,
26-
sizeof(PicopassBlock));
26+
PICOPASS_BLOCK_LEN);
2727

2828
instance->cipher_state = loclass_opt_doTagMAC_1(cc, key);
2929
}
3030

3131
void picopass_listener_init_cipher_state(PicopassListener* instance) {
3232
uint8_t key[PICOPASS_BLOCK_LEN] = {};
33-
memcpy(key, instance->data->card_data[instance->key_block_num].data, sizeof(PicopassBlock));
33+
memcpy(key, instance->data->card_data[instance->key_block_num].data, PICOPASS_BLOCK_LEN);
3434

3535
picopass_listener_init_cipher_state_key(instance, key);
3636
}

picopass/protocol/picopass_poller.c

+35-47
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@ NfcCommand picopass_poller_select_handler(PicopassPoller* instance) {
7070
return command;
7171
}
7272

73+
void picopass_poller_print_block(char* str, PicopassBlock block) {
74+
FURI_LOG_D(
75+
TAG,
76+
str,
77+
block.data[0],
78+
block.data[1],
79+
block.data[2],
80+
block.data[3],
81+
block.data[4],
82+
block.data[5],
83+
block.data[6],
84+
block.data[7]);
85+
}
86+
7387
NfcCommand picopass_poller_pre_auth_handler(PicopassPoller* instance) {
7488
NfcCommand command = NfcCommandContinue;
7589
PicopassError error = PicopassErrorNone;
@@ -79,17 +93,10 @@ NfcCommand picopass_poller_pre_auth_handler(PicopassPoller* instance) {
7993
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data,
8094
instance->serial_num.data,
8195
sizeof(PicopassSerialNum));
82-
FURI_LOG_D(
83-
TAG,
96+
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].valid = true;
97+
picopass_poller_print_block(
8498
"csn %02x%02x%02x%02x%02x%02x%02x%02x",
85-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[0],
86-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[1],
87-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[2],
88-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[3],
89-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[4],
90-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[5],
91-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[6],
92-
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX].data[7]);
99+
instance->data->card_data[PICOPASS_CSN_BLOCK_INDEX]);
93100

94101
PicopassBlock block = {};
95102
error = picopass_poller_read_block(instance, PICOPASS_CONFIG_BLOCK_INDEX, &block);
@@ -100,18 +107,11 @@ NfcCommand picopass_poller_pre_auth_handler(PicopassPoller* instance) {
100107
memcpy(
101108
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data,
102109
block.data,
103-
sizeof(PicopassBlock));
104-
FURI_LOG_D(
105-
TAG,
110+
PICOPASS_BLOCK_LEN);
111+
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].valid = true;
112+
picopass_poller_print_block(
106113
"config %02x%02x%02x%02x%02x%02x%02x%02x",
107-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0],
108-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[1],
109-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[2],
110-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[3],
111-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[4],
112-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[5],
113-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[6],
114-
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[7]);
114+
instance->data->card_data[PICOPASS_CONFIG_BLOCK_INDEX]);
115115

116116
error = picopass_poller_read_block(instance, PICOPASS_SECURE_EPURSE_BLOCK_INDEX, &block);
117117
if(error != PicopassErrorNone) {
@@ -121,18 +121,11 @@ NfcCommand picopass_poller_pre_auth_handler(PicopassPoller* instance) {
121121
memcpy(
122122
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data,
123123
block.data,
124-
sizeof(PicopassBlock));
125-
FURI_LOG_D(
126-
TAG,
124+
PICOPASS_BLOCK_LEN);
125+
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].valid = true;
126+
picopass_poller_print_block(
127127
"epurse %02x%02x%02x%02x%02x%02x%02x%02x",
128-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[0],
129-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[1],
130-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[2],
131-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[3],
132-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[4],
133-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[5],
134-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[6],
135-
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data[7]);
128+
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX]);
136129

137130
error = picopass_poller_read_block(instance, PICOPASS_SECURE_AIA_BLOCK_INDEX, &block);
138131
if(error != PicopassErrorNone) {
@@ -142,18 +135,11 @@ NfcCommand picopass_poller_pre_auth_handler(PicopassPoller* instance) {
142135
memcpy(
143136
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data,
144137
block.data,
145-
sizeof(PicopassBlock));
146-
FURI_LOG_D(
147-
TAG,
138+
PICOPASS_BLOCK_LEN);
139+
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].valid = true;
140+
picopass_poller_print_block(
148141
"aia %02x%02x%02x%02x%02x%02x%02x%02x",
149-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[0],
150-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[1],
151-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[2],
152-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[3],
153-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[4],
154-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[5],
155-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[6],
156-
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data[7]);
142+
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX]);
157143

158144
instance->state = PicopassPollerStateCheckSecurity;
159145
} while(false);
@@ -188,20 +174,20 @@ NfcCommand picopass_poller_check_security(PicopassPoller* instance) {
188174

189175
// Thank you proxmark!
190176
PicopassBlock temp_block = {};
191-
memset(temp_block.data, 0xff, sizeof(PicopassBlock));
177+
memset(temp_block.data, 0xff, PICOPASS_BLOCK_LEN);
192178
instance->data->pacs.legacy =
193179
(memcmp(
194180
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data,
195181
temp_block.data,
196-
sizeof(PicopassBlock)) == 0);
182+
PICOPASS_BLOCK_LEN) == 0);
197183

198184
temp_block.data[3] = 0x00;
199185
temp_block.data[4] = 0x06;
200186
instance->data->pacs.se_enabled =
201187
(memcmp(
202188
instance->data->card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data,
203189
temp_block.data,
204-
sizeof(PicopassBlock)) == 0);
190+
PICOPASS_BLOCK_LEN) == 0);
205191

206192
if(instance->data->pacs.se_enabled) {
207193
FURI_LOG_D(TAG, "SE enabled");
@@ -401,6 +387,7 @@ NfcCommand picopass_poller_auth_handler(PicopassPoller* instance) {
401387
if(instance->mode == PicopassPollerModeRead) {
402388
memcpy(
403389
instance->data->pacs.key, instance->event_data.req_key.key, PICOPASS_KEY_LEN);
390+
instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].valid = true;
404391
instance->data->pacs.elite_kdf = instance->event_data.req_key.is_elite_key;
405392
picopass_poller_prepare_read(instance);
406393
instance->state = PicopassPollerStateReadBlock;
@@ -457,7 +444,8 @@ NfcCommand picopass_poller_read_block_handler(PicopassPoller* instance) {
457444
memcpy(
458445
instance->data->card_data[instance->current_block].data,
459446
block.data,
460-
sizeof(PicopassBlock));
447+
PICOPASS_BLOCK_LEN);
448+
instance->data->card_data[instance->current_block].valid = true;
461449
instance->current_block++;
462450
} while(false);
463451

0 commit comments

Comments
 (0)