M5Unit-NFC 0.0.3 git rev:59f5362
Loading...
Searching...
No Matches
mifare.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_UNIFIED_NFC_NFC_A_MIFARE_HPP
11#define M5_UNIT_UNIFIED_NFC_NFC_A_MIFARE_HPP
12
13#include <cstdint>
14#include <array>
15
16namespace m5 {
17namespace nfc {
18namespace a {
23namespace mifare {
24
27constexpr std::array<uint8_t, 7> historical_bytes_mifare_plus_s = {0xC1, 0x05, 0x2F, 0x2F, 0x00, 0x35, 0xC7};
28constexpr std::array<uint8_t, 7> historical_bytes_mifare_plus_x_ev = {0xC1, 0x05, 0x2F, 0x2F, 0x01, 0xBC, 0xD6};
29constexpr std::array<uint8_t, 7> historical_bytes_mifare_plus_se0 = {0xC1, 0x05, 0x21, 0x30, 0x00, 0xF6, 0xD1};
30constexpr std::array<uint8_t, 7> historical_bytes_mifare_plus_se1 = {0xC1, 0x05, 0x21, 0x30, 0x10, 0xF6, 0xD1};
31constexpr std::array<uint8_t, 7> historical_bytes_mifare_plus_se2 = {0xC1, 0x05, 0x21, 0x30, 0x00, 0x77, 0xC1};
33
38namespace classic {
39
40constexpr uint16_t MIFARE_CLASSIC_MAX_TX_LEN{32};
41constexpr uint16_t MIFARE_CLASSIC_MAX_RX_LEN{32};
42constexpr uint16_t MIFARE_CLASSIC_MAX_TX_WITH_CRC{MIFARE_CLASSIC_MAX_TX_LEN + 2};
43constexpr uint16_t MIFARE_CLASSIC_MAX_RX_WITH_CRC{MIFARE_CLASSIC_MAX_RX_LEN + 2};
44constexpr uint16_t MIFARE_CLASSIC_MAX_BITSTREAM_LEN{(9 * MIFARE_CLASSIC_MAX_TX_WITH_CRC + 7) / 8};
45
50using Key = std::array<uint8_t, 6>;
51
53constexpr Key DEFAULT_KEY{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
54
57constexpr uint8_t READ_WRITE_BLOCK{0x00};
58constexpr uint8_t VALUE_BLOCK_NON_RECHARGEABLE{0x01};
59constexpr uint8_t VALUE_BLOCK_RECHARGEABLE{0x06};
61
66inline constexpr bool can_value_block_permission(const uint8_t permission)
67{
68 return (permission == 0x00) || // transport configuration
69 (permission == 0x01) || // value block (Only read and decrement)
70 (permission == 0x06); // value block (Full operation)
71}
72
77inline constexpr bool is_sector_trailer_block(const uint16_t block)
78{
79 return (block < 128) ? (block & 0x03) == 0x03 : ((block - 128) & 0x0F) == 0x0F;
80}
81
86inline constexpr uint16_t get_sector_trailer_block(const uint16_t block)
87{
88 return (block < 128) ? (block | 0x03) : (block | 0x0F);
89}
90
95inline constexpr uint16_t get_sector(const uint16_t block)
96{
97 return (block < 128) ? (block >> 2) : 32 + ((block - 128) >> 4);
98}
99
104inline constexpr uint8_t get_permission_offset(const uint16_t block)
105{
106 return ((block < 128) ? (block & 0x03) : ((block - 128) & 0x0F) / 5) & 0x03;
107}
108
114inline constexpr uint16_t get_sector_trailer_block_from_sector(const uint16_t sector)
115{
116 return ((sector < 32) ? sector * ((sector < 32) ? 4U : 16U) : 128U + (sector - 32) * ((sector < 32) ? 4U : 16U)) +
117 ((sector < 32) ? 4U : 16U) - 1;
118}
119
127bool decode_value_block(int32_t& value, uint8_t& addr, const uint8_t buf[16]);
135const uint8_t* encode_value_block(uint8_t buf[16], const int32_t value, const uint8_t addr);
136
148bool encode_access_bits(uint8_t abits[3], const uint8_t p0, const uint8_t p1, const uint8_t p2, const uint8_t p3);
157inline bool encode_access_bits(uint8_t abits[3], const uint8_t permissions[4])
158{
159 return encode_access_bits(abits, permissions[0], permissions[1], permissions[2], permissions[3]);
160}
174bool decode_access_bits(uint8_t permissions[4], const uint8_t ab0, const uint8_t ab1, const uint8_t ab2);
182inline bool decode_access_bits(uint8_t permissions[4], const uint8_t abits[3])
183{
184 return decode_access_bits(permissions, abits[0], abits[1], abits[2]);
185}
186
187} // namespace classic
188
193namespace desfire {
194
195constexpr uint32_t DESFIRE_NDEF_APP_ID{0x000001};
196constexpr uint8_t DESFIRE_CC_FILE_NO{0x01};
197constexpr uint8_t DESFIRE_NDEF_FILE_NO{0x02};
198constexpr uint8_t DESFIRE_NDEF_AID[] = {0x00, 0x00, 0x01};
199
200constexpr uint8_t DESFIRE_LIGHT_DF_NAME[] = {
201 0xA0, 0x00, 0x00, 0x03, 0x96, 0x56, 0x43, 0x41, 0x03, 0xF0, 0x15, 0x40, 0x00, 0x00, 0x00, 0x0B};
202constexpr uint16_t DESFIRE_LIGHT_DF_FID{0xDF01};
203constexpr uint8_t DESFIRE_LIGHT_CC_FILE_NO{0x00};
204constexpr uint8_t DESFIRE_LIGHT_NDEF_FILE_NO{0x04};
205constexpr uint16_t DESFIRE_LIGHT_CC_FILE_ID{0xEF00};
206constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_ID{0xEF04};
207constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_SIZE{256};
208
209constexpr uint8_t DESFIRE_DEFAULT_KEY[16]{};
210
213constexpr int8_t access_denied{-1};
214constexpr int8_t access_free{-2};
222inline int8_t required_read_key_no_from_access_rights(const uint16_t access_rights)
223{
224 const uint8_t read_key = (access_rights >> 12) & 0x0F;
225 const uint8_t rw_key = (access_rights >> 4) & 0x0F;
226 if (read_key == 0x0E) {
227 return access_free;
228 }
229 if (read_key != 0x0F) {
230 return read_key;
231 }
232 if (rw_key == 0x0E) {
233 return access_free;
234 }
235 if (rw_key != 0x0F) {
236 return rw_key;
237 }
238 return access_denied;
239}
247inline int8_t required_write_key_no_from_access_rights(const uint16_t access_rights)
248{
249 const uint8_t write_key = (access_rights >> 8) & 0x0F; // Write
250 const uint8_t rw_key = (access_rights >> 4) & 0x0F; // Read/Write
251 if (write_key == 0x0E) {
252 return access_free;
253 }
254 if (write_key != 0x0F) {
255 return write_key;
256 }
257 if (rw_key == 0x0E) {
258 return access_free;
259 }
260 if (rw_key != 0x0F) {
261 return rw_key;
262 }
263 return access_denied;
264}
266
267} // namespace desfire
268
273namespace plus {
274
279using AESKey = std::array<uint8_t, 16>;
281constexpr AESKey DEFAULT_KEY{}; // All 0x00
283constexpr AESKey DEFAULT_FF_KEY = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
284 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
285
286} // namespace plus
287
288} // namespace mifare
289} // namespace a
290} // namespace nfc
291} // namespace m5
292#endif
bool encode_access_bits(uint8_t abits[3], const uint8_t p0, const uint8_t p1, const uint8_t p2, const uint8_t p3)
Encode access bits from permissions.
Definition mifare.cpp:54
bool decode_access_bits(uint8_t permissions[4], const uint8_t ab0, const uint8_t ab1, const uint8_t ab2)
Decode access bits to permissions.
Definition mifare.cpp:70
constexpr uint8_t READ_WRITE_BLOCK
Read and write block.
Definition mifare.hpp:57
constexpr uint8_t DESFIRE_CC_FILE_NO
AN11004 default CC file number.
Definition mifare.hpp:196
constexpr Key DEFAULT_KEY
Default key for MIFARE classic.
Definition mifare.hpp:53
constexpr uint8_t VALUE_BLOCK_RECHARGEABLE
Value block (rechargeable)
Definition mifare.hpp:59
constexpr bool is_sector_trailer_block(const uint16_t block)
Is this block a sector trailer?
Definition mifare.hpp:77
constexpr uint8_t VALUE_BLOCK_NON_RECHARGEABLE
Value block (debit only)
Definition mifare.hpp:58
std::array< uint8_t, 16 > AESKey
MIFARE Plus SL2/3 Key (AES)
Definition mifare.hpp:279
constexpr uint8_t DESFIRE_NDEF_FILE_NO
AN11004 default NDEF file number.
Definition mifare.hpp:197
constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_ID
DESFire Light NDEF file ID.
Definition mifare.hpp:206
constexpr bool can_value_block_permission(const uint8_t permission)
Can this permission be used as a value block?
Definition mifare.hpp:66
constexpr uint16_t DESFIRE_LIGHT_CC_FILE_ID
DESFire Light CC file ID.
Definition mifare.hpp:205
constexpr uint16_t get_sector(const uint16_t block)
Obtains the sector to which the block belongs from the block address.
Definition mifare.hpp:95
constexpr uint8_t DESFIRE_LIGHT_CC_FILE_NO
DESFire Light CC file number.
Definition mifare.hpp:203
constexpr AESKey DEFAULT_FF_KEY
Default AES sector key (as classic DEFAULT_KEY)
Definition mifare.hpp:283
constexpr uint16_t DESFIRE_LIGHT_DF_FID
DESFire Light default DF FID.
Definition mifare.hpp:202
constexpr uint32_t DESFIRE_NDEF_APP_ID
DESFire NDEF application AID.
Definition mifare.hpp:195
constexpr uint8_t DESFIRE_LIGHT_NDEF_FILE_NO
DESFire Light NDEF file number.
Definition mifare.hpp:204
constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_SIZE
DESFire Light NDEF file size (bytes)
Definition mifare.hpp:207
constexpr uint8_t DESFIRE_NDEF_AID[]
DESFire NDEF AID (3 bytes)
Definition mifare.hpp:198
constexpr uint16_t get_sector_trailer_block_from_sector(const uint16_t sector)
Obtains the block address of the sector trailer from sector.
Definition mifare.hpp:114
constexpr uint8_t get_permission_offset(const uint16_t block)
Get the offset in the permissions of this block.
Definition mifare.hpp:104
std::array< uint8_t, 6 > Key
MIFARE classic Key.
Definition mifare.hpp:50
constexpr uint16_t get_sector_trailer_block(const uint16_t block)
Obtains the block address of the sector to which it belongs from the block address.
Definition mifare.hpp:86
NFC-A definitions.
For MIFARE classic.
Top level namespace of M5stack.
For MIFARE.
NFC related definitions.
For MIFARE Plus.