unsigned int -> size_t in some appropriate places.
[librfid] / src / rfid_access_mifare_classic.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <sys/types.h>
5
6 #include <librfid/rfid.h>
7 #include <librfid/rfid_access_mifare_classic.h>
8
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)
12 {
13         int b;
14         u_int8_t c1, c2, c3;
15
16         c1 = c2 = c3 = 0;
17
18         for (b = 0; b < 4; b++) {
19                 if (ac->block[b] & 0x01)
20                         c1 |= (1 << b);
21                 if (ac->block[b] & 0x02)
22                         c2 |= (1 << b);
23                 if (ac->block[b] & 0x04)
24                         c3 |= (1 << b);
25         }
26
27         DEBUGP("compile: c1=%u c2=%u c3=%u\n", c1, c2, c3);
28
29         encoded[3] = 0x00;
30         encoded[2] = c2 | (c3 << 4);
31         encoded[1] = (~c3 & 0xf) | (c1 << 4);
32         encoded[0] = (~c1 & 0xf) | ((~c2 & 0xf) << 4);
33
34         return 0;
35 }
36
37 /* parse mifare classic access conditions from card */
38 int mfcl_parse_access(struct mfcl_access_sect *ac, u_int8_t *encoded)
39 {
40         int b;
41
42         u_int8_t c1, c2, c3;
43
44         DEBUGP("encoded: %s\n", rfid_hexdump(encoded, 4));
45
46         c1 = encoded[1] >> 4;
47         c2 = encoded[2] & 0xf;
48         c3 = encoded[2] >> 4;
49
50         DEBUGP("c1=0x%x, c2=0x%x, c3=0x%x\n", c1, c2, c3);
51         
52         memset(ac, 0, sizeof(*ac));
53         for (b = 0; b < 4; b++) {
54                 if (c1 & (1 << b))
55                         ac->block[b] = 0x1;
56                 if (c2 & (1 << b))
57                         ac->block[b] |= 0x2;
58                 if (c3 & (1 << b))
59                         ac->block[b] |= 0x4;
60         };
61
62         /* FIXME: verify the inverted access bits */
63
64         return 0;
65 }
66
67
68 /* functions below here are for our own internal decoded (orthogonal)
69  * format of access bits */
70
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[] = {
73         [0] = {
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,
78         },
79         [2] = {
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,
84         },
85         [1] = {
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,
90         },
91         [3] = {
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,
96         },
97         [4] = {
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,
102         },
103         [6] = {
104                 .read   = MFCL_ACCESS_KEY_B,
105                 .write  = MFCL_ACCESS_KEY_B,
106                 .inc    = MFCL_ACCESS_NEVER,
107                 .dec    = MFCL_ACCESS_NEVER,
108         },
109         [5] = {
110                 .read   = MFCL_ACCESS_KEY_B,
111                 .write  = MFCL_ACCESS_NEVER,
112                 .inc    = MFCL_ACCESS_NEVER,
113                 .dec    = MFCL_ACCESS_NEVER,
114         },
115         [7] = {
116                 .read   = MFCL_ACCESS_NEVER,
117                 .write  = MFCL_ACCESS_NEVER,
118                 .inc    = MFCL_ACCESS_NEVER,
119                 .dec    = MFCL_ACCESS_NEVER,
120         },
121 };
122
123 static const struct mfcl_access_exp_acc mfcl_exp_trailer[] = {
124         [0] = {
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,
131         },
132         [2] = {
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,
139         },
140         [1] = {
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,
147         },
148         [3] = {
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,
155         },
156         [4] = {
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,
163         },
164         [6] = {
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,
171         },
172         [5] = {
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,
179         },
180         [7] = {
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,
187         },
188 };
189
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",
195 };
196
197 void mfcl_access_to_exp(struct mfcl_access_exp_sect *exp,
198                         const struct mfcl_access_sect *sect)
199 {
200         int b;
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]];
204 }
205
206 char *mfcl_access_exp_stringify(const struct mfcl_access_exp_block *exp)
207 {
208         static char buf[80];
209
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]);
215         return buf;
216 }
217
218 char *mfcl_access_exp_acc_stringify(const struct mfcl_access_exp_acc *acc)
219 {
220         static char buf[80];
221
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]);
230         return buf;
231 }
232