M5Unit-NFC 0.1.0 git rev:93745b5
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 * 4U + 3U) : (128U + (sector - 32) * 16U + 15U);
117}
118
126bool decode_value_block(int32_t& value, uint8_t& addr, const uint8_t buf[16]);
134const uint8_t* encode_value_block(uint8_t buf[16], const int32_t value, const uint8_t addr);
135
147bool encode_access_bits(uint8_t abits[3], const uint8_t p0, const uint8_t p1, const uint8_t p2, const uint8_t p3);
156inline bool encode_access_bits(uint8_t abits[3], const uint8_t permissions[4])
157{
158 return encode_access_bits(abits, permissions[0], permissions[1], permissions[2], permissions[3]);
159}
173bool decode_access_bits(uint8_t permissions[4], const uint8_t ab0, const uint8_t ab1, const uint8_t ab2);
181inline bool decode_access_bits(uint8_t permissions[4], const uint8_t abits[3])
182{
183 return decode_access_bits(permissions, abits[0], abits[1], abits[2]);
184}
185
186} // namespace classic
187
192namespace desfire {
193
194constexpr uint32_t DESFIRE_NDEF_APP_ID{0x000001};
195constexpr uint8_t DESFIRE_CC_FILE_NO{0x01};
196constexpr uint8_t DESFIRE_NDEF_FILE_NO{0x02};
197constexpr uint8_t DESFIRE_NDEF_AID[] = {0x00, 0x00, 0x01};
198
199constexpr uint8_t DESFIRE_LIGHT_DF_NAME[] = {
200 0xA0, 0x00, 0x00, 0x03, 0x96, 0x56, 0x43, 0x41, 0x03, 0xF0, 0x15, 0x40, 0x00, 0x00, 0x00, 0x0B};
201constexpr uint16_t DESFIRE_LIGHT_DF_FID{0xDF01};
202constexpr uint8_t DESFIRE_LIGHT_CC_FILE_NO{0x00};
203constexpr uint8_t DESFIRE_LIGHT_NDEF_FILE_NO{0x04};
204constexpr uint16_t DESFIRE_LIGHT_CC_FILE_ID{0xEF00};
205constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_ID{0xEF04};
206constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_SIZE{256};
207
208constexpr uint8_t DESFIRE_DEFAULT_KEY[16]{};
209
212constexpr int8_t access_denied{-1};
213constexpr int8_t access_free{-2};
221inline int8_t required_read_key_no_from_access_rights(const uint16_t access_rights)
222{
223 const uint8_t read_key = (access_rights >> 12) & 0x0F;
224 const uint8_t rw_key = (access_rights >> 4) & 0x0F;
225 if (read_key == 0x0E) {
226 return access_free;
227 }
228 if (read_key != 0x0F) {
229 return read_key;
230 }
231 if (rw_key == 0x0E) {
232 return access_free;
233 }
234 if (rw_key != 0x0F) {
235 return rw_key;
236 }
237 return access_denied;
238}
246inline int8_t required_write_key_no_from_access_rights(const uint16_t access_rights)
247{
248 const uint8_t write_key = (access_rights >> 8) & 0x0F; // Write
249 const uint8_t rw_key = (access_rights >> 4) & 0x0F; // Read/Write
250 if (write_key == 0x0E) {
251 return access_free;
252 }
253 if (write_key != 0x0F) {
254 return write_key;
255 }
256 if (rw_key == 0x0E) {
257 return access_free;
258 }
259 if (rw_key != 0x0F) {
260 return rw_key;
261 }
262 return access_denied;
263}
265
266} // namespace desfire
267
272namespace plus {
273
278using AESKey = std::array<uint8_t, 16>;
280constexpr AESKey DEFAULT_KEY{}; // All 0x00
282constexpr AESKey DEFAULT_FF_KEY = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
283 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
284
285} // namespace plus
286
287} // namespace mifare
288} // namespace a
289} // namespace nfc
290} // namespace m5
291#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:55
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:71
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:195
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:278
constexpr uint8_t DESFIRE_NDEF_FILE_NO
AN11004 default NDEF file number.
Definition mifare.hpp:196
constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_ID
DESFire Light NDEF file ID.
Definition mifare.hpp:205
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:204
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:202
constexpr AESKey DEFAULT_FF_KEY
Default AES sector key (as classic DEFAULT_KEY)
Definition mifare.hpp:282
constexpr uint16_t DESFIRE_LIGHT_DF_FID
DESFire Light default DF FID.
Definition mifare.hpp:201
constexpr uint32_t DESFIRE_NDEF_APP_ID
DESFire NDEF application AID.
Definition mifare.hpp:194
constexpr uint8_t DESFIRE_LIGHT_NDEF_FILE_NO
DESFire Light NDEF file number.
Definition mifare.hpp:203
constexpr uint16_t DESFIRE_LIGHT_NDEF_FILE_SIZE
DESFire Light NDEF file size (bytes)
Definition mifare.hpp:206
constexpr uint8_t DESFIRE_NDEF_AID[]
DESFire NDEF AID (3 bytes)
Definition mifare.hpp:197
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.