1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * Mifare Standard Format implementation
19  */
20 
21 #ifndef PHFRINFC_MIFSTDFORMAT_H
22 #define PHFRINFC_MIFSTDFORMAT_H
23 
24 #include <phFriNfc.h>
25 #include <phNfcStatus.h>
26 #include <phNfcTypes.h>
27 #include <phFriNfc_SmtCrdFmt.h>
28 
29 /********************* Definitions and structures *****************************/
30 
31 /*
32  * Mifare standard -progress states
33  */
34 #define PH_FRINFC_MFSTD_FMT_RESET_INIT          0   /* Reset state */
35 #define PH_FRINFC_MFSTD_FMT_AUTH_SECT           1   /* Sector authentication is in progress */
36 #define PH_FRINFC_MFSTD_FMT_DIS_CON             2   /* Disconnect is in progress */
37 #define PH_FRINFC_MFSTD_FMT_CON                 3   /* Connect is in progress */
38 #define PH_FRINFC_MFSTD_FMT_POLL                4   /* Poll is in progress */
39 #define PH_FRINFC_MFSTD_FMT_RD_SECT_TR          5   /* Read sector trailer is in progress */
40 #define PH_FRINFC_MFSTD_FMT_WR_SECT_TR          6   /* Write sector trailer is in progress */
41 #define PH_FRINFC_MFSTD_FMT_WR_TLV              7   /* Write sector trailer is in progress */
42 #define PH_FRINFC_MFSTD_FMT_WR_MAD_BLK          8   /* Write MAD is in progress */
43 #define PH_FRINFC_MFSTD_FMT_UPD_MAD_BLK         9   /* Write MAD is in progress */
44 
45 /*
46  * Mifare standard -Authenticate states
47  */
48 #define PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY        0   /* Trying to authenticate with the default key */
49 #define PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY        1   /* Trying to authenticate with the MAD key */
50 #define PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY        2   /* Trying to authenticate with the NFC forum key */
51 #define PH_FRINFC_MFSTD_FMT_AUTH_KEYB           3   /* Trying to authenticate with key B */
52 #define PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB      4   /* Trying to authenticate with secret key B */
53 
54 /*
55  * Mifare standard - Update MAD block flag
56  */
57 #define PH_FRINFC_MFSTD_FMT_NOT_A_MAD_BLK       0   /* Not a MAD block */
58 #define PH_FRINFC_MFSTD_FMT_MAD_BLK_1           1   /* MAD block number 1 */
59 #define PH_FRINFC_MFSTD_FMT_MAD_BLK_2           2   /* MAD block number 2 */
60 #define PH_FRINFC_MFSTD_FMT_MAD_BLK_64          64  /* MAD block number 64 (only used for Mifare 4k card) */
61 #define PH_FRINFC_MFSTD_FMT_MAD_BLK_65          65  /* MAD block number 65 (only used for Mifare 4k card) */
62 #define PH_FRINFC_MFSTD_FMT_MAD_BLK_66          66  /* MAD block number 66 (only used for Mifare 4k card) */
63 
64 /*
65  * Mifare standard - Update MAD block flag
66 */
67 #define  PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_1K        {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0x78,0x77,0x88,0xC1}
68 #define  PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_2K        {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0x78,0x77,0x88,0xC1}
69 #define  PH_FRINFC_SMTCRDFMT_MSTD_MADSECT_KEYA_ACS_BIT_4K        {0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0x78,0x77,0x88,0xC2}
70 #define  PH_FRINFC_SMTCRDFMT_NFCFORUMSECT_KEYA_ACS_BIT           {0xD3,0xF7,0xD3,0xF7,0xD3,0xF7,0x7F,0x07,0x88,0x40}
71 
72 /*
73  * Mifare standard - Key and access bit constants
74  */
75 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_KEYA0      0xD3    /* NFC forum sector key A */
76 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_KEYA1      0xF7    /* NFC forum sector key A */
77 
78 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA0      0xA0    /* MAD sector key A */
79 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA1      0xA1    /* MAD sector key A */
80 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA2      0xA2    /* MAD sector key A */
81 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA3      0xA3    /* MAD sector key A */
82 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA4      0xA4    /* MAD sector key A */
83 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_KEYA5      0xA5    /* MAD sector key A */
84 
85 #define PH_FRINFC_MFSTD_FMT_DEFAULT_KEY         0xFF    /* Default key A or B */
86 
87 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_ACS6       0x78    /* MAD sector access bits 6 */
88 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_ACS7       0x77    /* MAD sector access bits 7 */
89 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_ACS8       0x88    /* MAD sector access bits 8 */
90 #define PH_FRINFC_MFSTD_FMT_MAD_SECT_GPB        0xC1    /* MAD sector GPB */
91 
92 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RW6    0x7F    /* NFC forum sector access bits 6 for read write */
93 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RW7    0x07    /* NFC forum sector access bits 7 for read write */
94 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RW8    0x88    /* NFC forum sector access bits 8 for read write */
95 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_GPB_RW     0x40    /* NFC forum sector GPB for read write */
96 
97 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RO6    0x07    /* NFC forum sector access bits 6 for read only */
98 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RO7    0x8F    /* NFC forum sector access bits 7 for read only */
99 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_ACS_RO8    0x0F    /* NFC forum sector access bits 8 for read only */
100 #define PH_FRINFC_MFSTD_FMT_NFC_SECT_GPB_R0     0x43    /* NFC forum sector GPB for read only */
101 
102 /*
103  * Enum definition contains Mifare standard values
104  */
105 typedef enum{
106 PH_FRINFC_MFSTD_FMT_VAL_0,
107 PH_FRINFC_MFSTD_FMT_VAL_1,
108 PH_FRINFC_MFSTD_FMT_VAL_2,
109 PH_FRINFC_MFSTD_FMT_VAL_3,
110 PH_FRINFC_MFSTD_FMT_VAL_4,
111 PH_FRINFC_MFSTD_FMT_VAL_5,
112 PH_FRINFC_MFSTD_FMT_VAL_6,
113 PH_FRINFC_MFSTD_FMT_VAL_7,
114 PH_FRINFC_MFSTD_FMT_VAL_8,
115 PH_FRINFC_MFSTD_FMT_VAL_9,
116 PH_FRINFC_MFSTD_FMT_VAL_10,
117 PH_FRINFC_MFSTD_FMT_VAL_11
118 }phFriNfc_MfStdVal;
119 
120 /*
121  * Mifare standard - NDEF information constants
122  */
123 #define PH_FRINFC_MFSTD_FMT_NON_NDEF_COMPL    0       /* Sector is not ndef compliant */
124 #define PH_FRINFC_MFSTD_FMT_NDEF_COMPL        1       /* Sector is ndef compliant */
125 #define PH_FRINFC_MFSTD_FMT_NDEF_INFO1        0x03    /* If sector is ndef compliant, then one of the MAD
126                                                         sector byte is 0x03 */
127 #define PH_FRINFC_MFSTD_FMT_NDEF_INFO2        0xE1    /* If sector is ndef compliant, then one of the MAD
128                                                         sector byte is 0xE1 */
129 
130 /*
131  * Mifare standard - constants
132  */
133 #define PH_FRINFC_MFSTD_FMT_MAX_RECV_LENGTH     252 /* Maximum receive length */
134 #define PH_FRINFC_MFSTD_FMT_WR_SEND_LENGTH      17  /* Send length for write */
135 #define PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K     16  /* Maximum sector index for Mifare 1k = 16 */
136 #define PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_2K     32  /* Maximum sector index for Mifare 2k = 32 */
137 #define PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K     40  /* Maximum sector index for Mifare 4k = 40 */
138 #define PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_1K       64  /* Maximum Number of Blocks for Mifare 1k = 64 */
139 #define PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_2K       128 /* Maximum Number of Blocks for Mifare 2k = 128 */
140 #define PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_4K       256 /* Maximum Number of Blocks for Mifare 4k = 256*/
141 
142 /*
143  * Copy default keyA to send buffer
144  */
145 #define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_DEF(mem)\
146 do\
147 {\
148     memset(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\
149                 PH_FRINFC_MFSTD_FMT_DEFAULT_KEY,\
150                 PH_FRINFC_MFSTD_FMT_VAL_6);\
151     NdefSmtCrdFmt->Cmd.MfCmd = ((NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState == \
152             PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY)? \
153             phHal_eMifareAuthentA: \
154             phHal_eMifareAuthentB); \
155     NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7; \
156 }while(0)
157 
158 /*
159  * NFC forum sector keyA to send buffer
160  */
161 #define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_NFCSECT_KEYA(mem)\
162 do \
163 {\
164     memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\
165         NdefSmtCrdFmt->AddInfo.MfStdInfo.NFCForumSect_KeyA,\
166         PH_FRINFC_MFSTD_FMT_VAL_6);\
167         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareAuthentA;\
168         NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7;\
169 } while(0)
170 
171 /*
172  * Copy MAD sector keyA to send buffer
173  */
174 #define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_MADSECT_KEYA(mem)\
175 do \
176 {\
177     memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\
178         NdefSmtCrdFmt->AddInfo.MfStdInfo.MADSect_KeyA,\
179         PH_FRINFC_MFSTD_FMT_VAL_6);\
180         NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareAuthentA;\
181         NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7;\
182 } while(0)
183 
184 /*
185  * Copy MAD sector keyB to send buffer
186  */
187 #define PH_FRINFC_MFSTD_FMT_AUTH_SEND_BUF_SCRT_KEY(mem) \
188 do \
189 {\
190     (void)memcpy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFSTD_FMT_VAL_1],\
191                NdefSmtCrdFmt->AddInfo.MfStdInfo.ScrtKeyB,\
192                PH_FRINFC_MFSTD_FMT_VAL_6);\
193                NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareAuthentB;\
194                NdefSmtCrdFmt->SendLength = PH_FRINFC_MFSTD_FMT_VAL_7;\
195 } while(0)
196 
197 /*
198  * Get the next block
199  */
200 #define PH_FRINFC_MFSTD_FMT_CUR_BLK_INC() \
201                     NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock += \
202                         ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= 127)?\
203                         16:4)
204 
205 /*
206  * Get the sector index
207  */
208 #define PH_FRINFC_MFSTD_FMT_SECT_INDEX_CALC \
209                     ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= 128)?\
210                     (32 + ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock - 128)/16)):\
211                     (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock/4))
212 
213 /*
214  * Check the sector block
215  */
216 #define PH_FRINFC_MFSTD_FMT_CUR_BLK_CHK\
217                     (((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD) && \
218                     (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= \
219                     PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_1K)) || \
220                     ((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD) && \
221                     (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= \
222                     PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_4K)) || \
223                     ((NdefSmtCrdFmt->CardType == PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD) && \
224                     (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock >= \
225                     PH_FRINFC_MFSTD_FMT_MAX_BLOCKS_2K)))
226 
227 /*
228  * Get the next authenticate state
229  */
230 #define PH_FRINFC_MFSTD_FMT_NXT_AUTH_STATE() \
231 do \
232 {\
233     switch(NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState)\
234     {\
235         case PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY:\
236         {\
237             NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = (uint8_t) \
238                 ((((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock <= 3) || \
239                 ((NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock > 63) && \
240                 (NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock < 67))))? \
241                 PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY: \
242                 PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY);\
243         }\
244         break;\
245         case PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY:\
246         {\
247         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \
248                             PH_FRINFC_MFSTD_FMT_AUTH_KEYB;\
249         }\
250         break;\
251         case PH_FRINFC_MFSTD_FMT_AUTH_MAD_KEY:\
252         {\
253         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \
254                         PH_FRINFC_MFSTD_FMT_AUTH_NFC_KEY;\
255         }\
256         break;\
257         case PH_FRINFC_MFSTD_FMT_AUTH_KEYB:\
258         { \
259         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \
260                         PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB;\
261         } \
262         break;\
263         case PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB:\
264         default:\
265         { \
266         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \
267                         PH_FRINFC_MFSTD_FMT_AUTH_DEF_KEY;\
268         }\
269         break;\
270     }\
271 } while(0)
272 
273 
274 /*
275  * Increment the sector index
276  */
277 #define PH_FRINFC_MFSTD_FMT_INCR_SECT \
278 do \
279 {\
280     SectIndex++;\
281     SectIndex = (uint8_t)((SectIndex == 16)?\
282                         (SectIndex + PH_FRINFC_MFSTD_FMT_VAL_1):\
283                         SectIndex);\
284 } while(0)
285 
286 
287 /*
288  * Increment the sector index
289  */
290 #define PH_FRINFC_MFSTD_FMT_CHK_SECT_ARRAY \
291 do \
292 {\
293     while ((index < PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_4K) && \
294             (memcompare != PH_FRINFC_MFSTD_FMT_VAL_0))\
295     {\
296         /* Compare any one among the sectors is NDEF COMPLIANT */\
297         memcompare = (uint32_t)phFriNfc_MfStd_MemCompare(&Buffer[PH_FRINFC_MFSTD_FMT_VAL_0], \
298         &NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl[index],\
299         PH_FRINFC_MFSTD_FMT_VAL_1);\
300         /* increment the index */\
301         index += (uint8_t)((index == (PH_FRINFC_MFSTD_FMT_MAX_SECT_IND_1K - \
302                             PH_FRINFC_MFSTD_FMT_VAL_1))?\
303                             PH_FRINFC_MFSTD_FMT_VAL_2:\
304                             PH_FRINFC_MFSTD_FMT_VAL_1);\
305     }\
306 } while(0)
307 
308 /*
309  * Complete the sector
310  */
311 #define PH_FRINFC_MFSTD_FMT_CHK_END_OF_CARD() \
312 do \
313 { \
314     phFriNfc_MfStd_H_NdefComplSect(NdefSmtCrdFmt->CardType, \
315                                 NdefSmtCrdFmt->AddInfo.MfStdInfo.SectCompl); \
316     PH_FRINFC_MFSTD_FMT_CHK_SECT_ARRAY; \
317     if(memcompare == PH_FRINFC_MFSTD_FMT_VAL_0) \
318     { \
319         phFriNfc_MfStd_H_StrNdefData(NdefSmtCrdFmt); \
320         NdefSmtCrdFmt->AddInfo.MfStdInfo.CurrentBlock = \
321                                 PH_FRINFC_MFSTD_FMT_VAL_1; \
322         NdefSmtCrdFmt->AddInfo.MfStdInfo.UpdMADBlk = \
323             PH_FRINFC_MFSTD_FMT_MAD_BLK_1; \
324         NdefSmtCrdFmt->AddInfo.MfStdInfo.AuthState = \
325             PH_FRINFC_MFSTD_FMT_AUTH_SCRT_KEYB; \
326         NdefSmtCrdFmt->State = PH_FRINFC_MFSTD_FMT_AUTH_SECT; \
327         Result = phFriNfc_MfStd_H_WrRdAuth(NdefSmtCrdFmt); \
328     } \
329     else \
330     { \
331         Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, \
332                             NFCSTATUS_FORMAT_ERROR); \
333     } \
334 } while(0)
335 
336 void phFriNfc_MfStd_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt);
337 NFCSTATUS phFriNfc_MfStd_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, const uint8_t *ScrtKeyB);
338 void phFriNfc_MfStd_Process(void *Context, NFCSTATUS Status);
339 
340 #endif /* PHFRINFC_MIFSTDFMT_H */
341