Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mifare_ultralight.h « nfc_protocols « lib - github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 77dbd1e4e711c9cfcb7f86e566d9fa3d44af2b62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#pragma once

#include <furi_hal_nfc.h>

// Largest tag is NTAG I2C Plus 2K, both data sectors plus SRAM
#define MF_UL_MAX_DUMP_SIZE ((238 + 256 + 16) * 4)

#define MF_UL_TEARING_FLAG_DEFAULT (0xBD)

#define MF_UL_HALT_START (0x50)
#define MF_UL_GET_VERSION_CMD (0x60)
#define MF_UL_READ_CMD (0x30)
#define MF_UL_FAST_READ_CMD (0x3A)
#define MF_UL_WRITE (0xA2)
#define MF_UL_FAST_WRITE (0xA6)
#define MF_UL_COMP_WRITE (0xA0)
#define MF_UL_READ_CNT (0x39)
#define MF_UL_INC_CNT (0xA5)
#define MF_UL_AUTH (0x1B)
#define MF_UL_READ_SIG (0x3C)
#define MF_UL_CHECK_TEARING (0x3E)
#define MF_UL_READ_VCSL (0x4B)
#define MF_UL_SECTOR_SELECT (0xC2)

#define MF_UL_ACK (0xa)
#define MF_UL_NAK_INVALID_ARGUMENT (0x0)
#define MF_UL_NAK_AUTHLIM_REACHED (0x4)

#define MF_UL_NTAG203_COUNTER_PAGE (41)

// Important: order matters; some features are based on positioning in this enum
typedef enum {
    MfUltralightTypeUnknown,
    MfUltralightTypeNTAG203,
    // Below have config pages and GET_VERSION support
    MfUltralightTypeUL11,
    MfUltralightTypeUL21,
    MfUltralightTypeNTAG213,
    MfUltralightTypeNTAG215,
    MfUltralightTypeNTAG216,
    // Below also have sector select
    // NTAG I2C's *does not* have regular config pages, so it's a bit of an odd duck
    MfUltralightTypeNTAGI2C1K,
    MfUltralightTypeNTAGI2C2K,
    // NTAG I2C Plus has stucture expected from NTAG21x
    MfUltralightTypeNTAGI2CPlus1K,
    MfUltralightTypeNTAGI2CPlus2K,

    // Keep last for number of types calculation
    MfUltralightTypeNum,
} MfUltralightType;

typedef enum {
    MfUltralightSupportNone = 0,
    MfUltralightSupportFastRead = 1 << 0,
    MfUltralightSupportTearingFlags = 1 << 1,
    MfUltralightSupportReadCounter = 1 << 2,
    MfUltralightSupportIncrCounter = 1 << 3,
    MfUltralightSupportSignature = 1 << 4,
    MfUltralightSupportFastWrite = 1 << 5,
    MfUltralightSupportCompatWrite = 1 << 6,
    MfUltralightSupportAuth = 1 << 7,
    MfUltralightSupportVcsl = 1 << 8,
    MfUltralightSupportSectorSelect = 1 << 9,
    // NTAG21x only has counter 2
    MfUltralightSupportSingleCounter = 1 << 10,
    // ASCII mirror is not a command, but handy to have as a flag
    MfUltralightSupportAsciiMirror = 1 << 11,
    // NTAG203 counter that's in memory rather than through a command
    MfUltralightSupportCounterInMemory = 1 << 12,
} MfUltralightFeatures;

typedef enum {
    MfUltralightMirrorNone,
    MfUltralightMirrorUid,
    MfUltralightMirrorCounter,
    MfUltralightMirrorUidCounter,
} MfUltralightMirrorConf;

typedef struct {
    uint8_t header;
    uint8_t vendor_id;
    uint8_t prod_type;
    uint8_t prod_subtype;
    uint8_t prod_ver_major;
    uint8_t prod_ver_minor;
    uint8_t storage_size;
    uint8_t protocol_type;
} MfUltralightVersion;

typedef struct {
    uint8_t sn0[3];
    uint8_t btBCC0;
    uint8_t sn1[4];
    uint8_t btBCC1;
    uint8_t internal;
    uint8_t lock[2];
    uint8_t otp[4];
} MfUltralightManufacturerBlock;

typedef struct {
    MfUltralightType type;
    MfUltralightVersion version;
    uint8_t signature[32];
    uint32_t counter[3];
    uint8_t tearing[3];
    uint16_t curr_authlim;
    uint16_t data_size;
    uint8_t data[MF_UL_MAX_DUMP_SIZE];
} MfUltralightData;

typedef struct __attribute__((packed)) {
    union {
        uint8_t raw[4];
        uint32_t value;
    } pwd;
    union {
        uint8_t raw[2];
        uint16_t value;
    } pack;
} MfUltralightAuth;

// Common configuration pages for MFUL EV1, NTAG21x, and NTAG I2C Plus
typedef struct __attribute__((packed)) {
    union {
        uint8_t value;
        struct {
            uint8_t rfui1 : 2;
            bool strg_mod_en : 1;
            bool rfui2 : 1;
            uint8_t mirror_byte : 2;
            MfUltralightMirrorConf mirror_conf : 2;
        };
    } mirror;
    uint8_t rfui1;
    uint8_t mirror_page;
    uint8_t auth0;
    union {
        uint8_t value;
        struct {
            uint8_t authlim : 3;
            bool nfc_cnt_pwd_prot : 1;
            bool nfc_cnt_en : 1;
            bool nfc_dis_sec1 : 1; // NTAG I2C Plus only
            bool cfglck : 1;
            bool prot : 1;
        };
    } access;
    uint8_t vctid;
    uint8_t rfui2[2];
    MfUltralightAuth auth_data;
    uint8_t rfui3[2];
} MfUltralightConfigPages;

typedef struct {
    uint16_t pages_to_read;
    int16_t pages_read;
    MfUltralightFeatures supported_features;
} MfUltralightReader;

typedef struct {
    MfUltralightData data;
    MfUltralightConfigPages* config;
    // Most config values don't apply until power cycle, so cache config pages
    // for correct behavior
    MfUltralightConfigPages config_cache;
    MfUltralightFeatures supported_features;
    uint16_t page_num;
    bool data_changed;
    bool comp_write_cmd_started;
    uint8_t comp_write_page_addr;
    bool auth_success;
    uint8_t curr_sector;
    bool sector_select_cmd_started;
    bool ntag_i2c_plus_sector3_lockout;
    bool read_counter_incremented;
} MfUltralightEmulator;

bool mf_ul_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);

bool mf_ultralight_read_version(
    FuriHalNfcTxRxContext* tx_rx,
    MfUltralightReader* reader,
    MfUltralightData* data);

bool mf_ultralight_read_pages_direct(
    FuriHalNfcTxRxContext* tx_rx,
    uint8_t start_index,
    uint8_t* data);

bool mf_ultralight_read_pages(
    FuriHalNfcTxRxContext* tx_rx,
    MfUltralightReader* reader,
    MfUltralightData* data);

bool mf_ultralight_fast_read_pages(
    FuriHalNfcTxRxContext* tx_rx,
    MfUltralightReader* reader,
    MfUltralightData* data);

bool mf_ultralight_read_signature(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data);

bool mf_ultralight_read_counters(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data);

bool mf_ultralight_read_tearing_flags(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data);

bool mf_ul_read_card(
    FuriHalNfcTxRxContext* tx_rx,
    MfUltralightReader* reader,
    MfUltralightData* data);

void mf_ul_reset_emulation(MfUltralightEmulator* emulator, bool is_power_cycle);

void mf_ul_prepare_emulation(MfUltralightEmulator* emulator, MfUltralightData* data);

bool mf_ul_prepare_emulation_response(
    uint8_t* buff_rx,
    uint16_t buff_rx_len,
    uint8_t* buff_tx,
    uint16_t* buff_tx_len,
    uint32_t* data_type,
    void* context);