6 #include <librfid/rfid.h>
7 #include <librfid/rfid_access_mifare_classic.h>
9 /* parse encoded data structure into c1/c2/c3 */
10 int mfcl_compile_access(u_int8_t *encoded,
11 const struct mfcl_access_sect *ac)
18 for (b = 0; b < 4; b++) {
19 if (ac->block[b] & 0x01)
21 if (ac->block[b] & 0x02)
23 if (ac->block[b] & 0x04)
27 DEBUGP("compile: c1=%u c2=%u c3=%u\n", c1, c2, c3);
30 encoded[2] = c2 | (c3 << 4);
31 encoded[1] = (~c3 & 0xf) | (c1 << 4);
32 encoded[0] = (~c1 & 0xf) | ((~c2 & 0xf) << 4);
37 /* parse mifare classic access conditions from card */
38 int mfcl_parse_access(struct mfcl_access_sect *ac, u_int8_t *encoded)
44 DEBUGP("encoded: %s\n", rfid_hexdump(encoded, 4));
47 c2 = encoded[2] & 0xf;
50 DEBUGP("c1=0x%x, c2=0x%x, c3=0x%x\n", c1, c2, c3);
52 memset(ac, 0, sizeof(*ac));
53 for (b = 0; b < 4; b++) {
62 /* FIXME: verify the inverted access bits */
68 /* functions below here are for our own internal decoded (orthogonal)
69 * format of access bits */
71 /* In the order of the table 3.7.3 in MFCL Product Specification Rev. 5.1 */
72 static const struct mfcl_access_exp_block mfcl_exp_data[] = {
74 .read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
75 .write = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
76 .inc = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
77 .dec = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
80 .read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
81 .write = MFCL_ACCESS_NEVER,
82 .inc = MFCL_ACCESS_NEVER,
83 .dec = MFCL_ACCESS_NEVER,
86 .read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
87 .write = MFCL_ACCESS_KEY_B,
88 .inc = MFCL_ACCESS_NEVER,
89 .dec = MFCL_ACCESS_NEVER,
92 .read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
93 .write = MFCL_ACCESS_KEY_B,
94 .inc = MFCL_ACCESS_KEY_B,
95 .dec = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
98 .read = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
99 .write = MFCL_ACCESS_NEVER,
100 .inc = MFCL_ACCESS_NEVER,
101 .dec = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
104 .read = MFCL_ACCESS_KEY_B,
105 .write = MFCL_ACCESS_KEY_B,
106 .inc = MFCL_ACCESS_NEVER,
107 .dec = MFCL_ACCESS_NEVER,
110 .read = MFCL_ACCESS_KEY_B,
111 .write = MFCL_ACCESS_NEVER,
112 .inc = MFCL_ACCESS_NEVER,
113 .dec = MFCL_ACCESS_NEVER,
116 .read = MFCL_ACCESS_NEVER,
117 .write = MFCL_ACCESS_NEVER,
118 .inc = MFCL_ACCESS_NEVER,
119 .dec = MFCL_ACCESS_NEVER,
123 static const struct mfcl_access_exp_acc mfcl_exp_trailer[] = {
125 .key_a_rd = MFCL_ACCESS_NEVER,
126 .key_a_wr = MFCL_ACCESS_KEY_A,
127 .acc_rd = MFCL_ACCESS_KEY_A,
128 .acc_wr = MFCL_ACCESS_NEVER,
129 .key_b_rd = MFCL_ACCESS_KEY_A,
130 .key_b_wr = MFCL_ACCESS_KEY_A,
133 .key_a_rd = MFCL_ACCESS_NEVER,
134 .key_a_wr = MFCL_ACCESS_NEVER,
135 .acc_rd = MFCL_ACCESS_KEY_A,
136 .acc_wr = MFCL_ACCESS_NEVER,
137 .key_b_rd = MFCL_ACCESS_KEY_A,
138 .key_b_wr = MFCL_ACCESS_NEVER,
141 .key_a_rd = MFCL_ACCESS_NEVER,
142 .key_a_wr = MFCL_ACCESS_KEY_B,
143 .acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
144 .acc_wr = MFCL_ACCESS_NEVER,
145 .key_b_rd = MFCL_ACCESS_NEVER,
146 .key_b_wr = MFCL_ACCESS_KEY_B,
149 .key_a_rd = MFCL_ACCESS_NEVER,
150 .key_a_wr = MFCL_ACCESS_NEVER,
151 .acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
152 .acc_wr = MFCL_ACCESS_NEVER,
153 .key_b_rd = MFCL_ACCESS_NEVER,
154 .key_b_wr = MFCL_ACCESS_NEVER,
157 .key_a_rd = MFCL_ACCESS_NEVER,
158 .key_a_wr = MFCL_ACCESS_KEY_A,
159 .acc_rd = MFCL_ACCESS_KEY_A,
160 .acc_wr = MFCL_ACCESS_KEY_A,
161 .key_b_rd = MFCL_ACCESS_KEY_A,
162 .key_b_wr = MFCL_ACCESS_KEY_A,
165 .key_a_rd = MFCL_ACCESS_NEVER,
166 .key_a_wr = MFCL_ACCESS_KEY_B,
167 .acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
168 .acc_wr = MFCL_ACCESS_KEY_B,
169 .key_b_rd = MFCL_ACCESS_NEVER,
170 .key_b_wr = MFCL_ACCESS_KEY_B,
173 .key_a_rd = MFCL_ACCESS_NEVER,
174 .key_a_wr = MFCL_ACCESS_NEVER,
175 .acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
176 .acc_wr = MFCL_ACCESS_KEY_B,
177 .key_b_rd = MFCL_ACCESS_NEVER,
178 .key_b_wr = MFCL_ACCESS_NEVER,
181 .key_a_rd = MFCL_ACCESS_NEVER,
182 .key_a_wr = MFCL_ACCESS_NEVER,
183 .acc_rd = MFCL_ACCESS_KEY_A | MFCL_ACCESS_KEY_B,
184 .acc_wr = MFCL_ACCESS_NEVER,
185 .key_b_rd = MFCL_ACCESS_NEVER,
186 .key_b_wr = MFCL_ACCESS_NEVER,
190 const char *mfcl_access_str[] = {
191 [MFCL_ACCESS_NEVER] = "NEVER",
192 [MFCL_ACCESS_KEY_A] = "A",
193 [MFCL_ACCESS_KEY_B] = "B",
194 [MFCL_ACCESS_KEY_A|MFCL_ACCESS_KEY_B] = "A|B",
197 void mfcl_access_to_exp(struct mfcl_access_exp_sect *exp,
198 const struct mfcl_access_sect *sect)
201 for (b = 0; b < 3; b++)
202 exp->block[b] = mfcl_exp_data[sect->block[b]];
203 exp->acc = mfcl_exp_trailer[sect->block[3]];
206 char *mfcl_access_exp_stringify(const struct mfcl_access_exp_block *exp)
210 sprintf(buf, "READ: %s, WRITE: %s, INC: %s, DEC: %s",
211 mfcl_access_str[exp->read],
212 mfcl_access_str[exp->write],
213 mfcl_access_str[exp->inc],
214 mfcl_access_str[exp->dec]);
218 char *mfcl_access_exp_acc_stringify(const struct mfcl_access_exp_acc *acc)
222 sprintf(buf, "KEY_A_RD: %s, KEY_A_WR: %s, ACC_RD: %s, ACC_WR: %s, "
223 "KEY_B_RD: %s, KEY_B_WR: %s",
224 mfcl_access_str[acc->key_a_rd],
225 mfcl_access_str[acc->key_a_wr],
226 mfcl_access_str[acc->acc_rd],
227 mfcl_access_str[acc->acc_wr],
228 mfcl_access_str[acc->key_b_rd],
229 mfcl_access_str[acc->key_b_wr]);