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