MifareClassic.java revision 74fe6c6b245ebe7d3b3d96962c32980d88dca4f5
1/* 2 * Copyright (C) 2010 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 17package android.nfc.tech; 18 19import android.nfc.Tag; 20import android.nfc.TagLostException; 21import android.os.RemoteException; 22 23import java.io.IOException; 24import java.nio.ByteBuffer; 25import java.nio.ByteOrder; 26 27/** 28 * Provides access to MIFARE Classic properties and I/O operations on a {@link Tag}. 29 * 30 * <p>Acquire a {@link MifareClassic} object using {@link #get}. 31 * 32 * <p>MIFARE Classic is also known as MIFARE Standard. 33 * <p>MIFARE Classic tags are divided into sectors, and each sector is sub-divided into 34 * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies. 35 * <ul> 36 * <li>MIFARE Classic Mini are 320 bytes ({@link #SIZE_MINI}), with 5 sectors each of 4 blocks. 37 * <li>MIFARE Classic 1k are 1024 bytes ({@link #SIZE_1K}), with 16 sectors each of 4 blocks. 38 * <li>MIFARE Classic 2k are 2048 bytes ({@link #SIZE_2K}), with 32 sectors each of 4 blocks. 39 * <li>MIFARE Classic 4k} are 4096 bytes ({@link #SIZE_4K}). The first 32 sectors contain 4 blocks 40 * and the last 8 sectors contain 16 blocks. 41 * </ul> 42 * 43 * <p>MIFARE Classic tags require authentication on a per-sector basis before any 44 * other I/O operations on that sector can be performed. There are two keys per sector, 45 * and ACL bits determine what I/O operations are allowed on that sector after 46 * authenticating with a key. {@see #authenticateSectorWithKeyA} and 47 * {@see #authenticateSectorWithKeyB}. 48 * 49 * <p>Three well-known authentication keys are defined in this class: 50 * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY}, 51 * {@link #KEY_NFC_FORUM}. 52 * <ul> 53 * <li>{@link #KEY_DEFAULT} is the default factory key for MIFARE Classic. 54 * <li>{@link #KEY_MIFARE_APPLICATION_DIRECTORY} is the well-known key for 55 * MIFARE Classic cards that have been formatted according to the 56 * MIFARE Application Directory (MAD) specification. 57 * <li>{@link #KEY_NFC_FORUM} is the well-known key for MIFARE Classic cards that 58 * have been formatted according to the NFC 59 * 60 * <p>Implementation of this class on a Android NFC device is optional. 61 * If it is not implemented, then 62 * {@link MifareClassic} will never be enumerated in {@link Tag#getTechList}. 63 * If it is enumerated, then all {@link MifareClassic} I/O operations will be supported, 64 * and {@link Ndef#MIFARE_CLASSIC} NDEF tags will also be supported. In either case, 65 * {@link NfcA} will also be enumerated on the tag, because all MIFARE Classic tags are also 66 * {@link NfcA}. 67 */ 68public final class MifareClassic extends BasicTagTechnology { 69 /** 70 * The default factory key. 71 */ 72 public static final byte[] KEY_DEFAULT = 73 {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}; 74 /** 75 * The well-known key for tags formatted according to the 76 * MIFARE Application Directory (MAD) specification. 77 */ 78 public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY = 79 {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5}; 80 /** 81 * The well-known key for tags formatted according to the 82 * NDEF on Mifare Classic specification. 83 */ 84 public static final byte[] KEY_NFC_FORUM = 85 {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7}; 86 87 /** A Mifare Classic compatible card of unknown type */ 88 public static final int TYPE_UNKNOWN = -1; 89 /** A MIFARE Classic tag */ 90 public static final int TYPE_CLASSIC = 0; 91 /** A MIFARE Plus tag */ 92 public static final int TYPE_PLUS = 1; 93 /** A MIFARE Pro tag */ 94 public static final int TYPE_PRO = 2; 95 96 /** Tag contains 16 sectors, each with 4 blocks. */ 97 public static final int SIZE_1K = 1024; 98 /** Tag contains 32 sectors, each with 4 blocks. */ 99 public static final int SIZE_2K = 2048; 100 /** 101 * Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors 102 * contain 16 blocks. 103 */ 104 public static final int SIZE_4K = 4096; 105 /** Tag contains 5 sectors, each with 4 blocks. */ 106 public static final int SIZE_MINI = 320; 107 108 /** Size of a MIFARE Classic block (in bytes) */ 109 public static final int BLOCK_SIZE = 16; 110 111 private static final int MAX_BLOCK_COUNT = 256; 112 private static final int MAX_SECTOR_COUNT = 40; 113 114 private boolean mIsEmulated; 115 private int mType; 116 private int mSize; 117 118 /** 119 * Get an instance of {@link MifareClassic} for the given tag. 120 * <p>Does not cause any RF activity and does not block. 121 * <p>Returns null if {@link MifareClassic} was not enumerated in {@link Tag#getTechList}. 122 * This indicates the tag is not MIFARE Classic compatible, or this Android 123 * device does not support MIFARE Classic. 124 * 125 * @param tag an MIFARE Classic compatible tag 126 * @return MIFARE Classic object 127 */ 128 public static MifareClassic get(Tag tag) { 129 if (!tag.hasTech(TagTechnology.MIFARE_CLASSIC)) return null; 130 try { 131 return new MifareClassic(tag); 132 } catch (RemoteException e) { 133 return null; 134 } 135 } 136 137 /** @hide */ 138 public MifareClassic(Tag tag) throws RemoteException { 139 super(tag, TagTechnology.MIFARE_CLASSIC); 140 141 NfcA a = NfcA.get(tag); // Mifare Classic is always based on NFC a 142 143 mIsEmulated = false; 144 145 switch (a.getSak()) { 146 case 0x08: 147 mType = TYPE_CLASSIC; 148 mSize = SIZE_1K; 149 break; 150 case 0x09: 151 mType = TYPE_CLASSIC; 152 mSize = SIZE_MINI; 153 break; 154 case 0x10: 155 mType = TYPE_PLUS; 156 mSize = SIZE_2K; 157 // SecLevel = SL2 158 break; 159 case 0x11: 160 mType = TYPE_PLUS; 161 mSize = SIZE_4K; 162 // Seclevel = SL2 163 break; 164 case 0x18: 165 mType = TYPE_CLASSIC; 166 mSize = SIZE_4K; 167 break; 168 case 0x28: 169 mType = TYPE_CLASSIC; 170 mSize = SIZE_1K; 171 mIsEmulated = true; 172 break; 173 case 0x38: 174 mType = TYPE_CLASSIC; 175 mSize = SIZE_4K; 176 mIsEmulated = true; 177 break; 178 case 0x88: 179 mType = TYPE_CLASSIC; 180 mSize = SIZE_1K; 181 // NXP-tag: false 182 break; 183 case 0x98: 184 case 0xB8: 185 mType = TYPE_PRO; 186 mSize = SIZE_4K; 187 break; 188 default: 189 // Stack incorrectly reported a MifareClassic. We cannot handle this 190 // gracefully - we have no idea of the memory layout. Bail. 191 throw new RuntimeException( 192 "Tag incorrectly enumerated as Mifare Classic, SAK = " + a.getSak()); 193 } 194 } 195 196 /** 197 * Return the type of this MIFARE Classic compatible tag. 198 * <p>One of {@link #TYPE_UNKNOWN}, {@link #TYPE_CLASSIC}, {@link #TYPE_PLUS} or 199 * {@link #TYPE_PRO}. 200 * <p>Does not cause any RF activity and does not block. 201 * 202 * @return type 203 */ 204 public int getType() { 205 return mType; 206 } 207 208 /** 209 * Return the size of the tag in bytes 210 * <p>One of {@link #SIZE_MINI}, {@link #SIZE_1K}, {@link #SIZE_2K}, {@link #SIZE_4K}. 211 * These constants are equal to their respective size in bytes. 212 * <p>Does not cause any RF activity and does not block. 213 * @return size in bytes 214 */ 215 public int getSize() { 216 return mSize; 217 } 218 219 /** 220 * Return true if the tag is emulated, determined at discovery time. 221 * These are actually smart-cards that emulate a Mifare Classic interface. 222 * They can be treated identically to a Mifare Classic tag. 223 * @hide 224 */ 225 public boolean isEmulated() { 226 return mIsEmulated; 227 } 228 229 /** 230 * Return the number of MIFARE Classic sectors. 231 * <p>Does not cause any RF activity and does not block. 232 * @return number of sectors 233 */ 234 public int getSectorCount() { 235 switch (mSize) { 236 case SIZE_1K: 237 return 16; 238 case SIZE_2K: 239 return 32; 240 case SIZE_4K: 241 return 40; 242 case SIZE_MINI: 243 return 5; 244 default: 245 return 0; 246 } 247 } 248 249 /** 250 * Return the total number of MIFARE Classic blocks. 251 * <p>Does not cause any RF activity and does not block. 252 * @return total number of blocks 253 public int getBlockCount() { 254 return mSize / BLOCK_SIZE; 255 } 256 257 /** 258 * Return the number of blocks in the given sector. 259 * <p>Does not cause any RF activity and does not block. 260 * 261 * @param sectorIndex index of sector, starting from 0 262 * @return number of blocks in the sector 263 */ 264 public int getBlockCountInSector(int sectorIndex) { 265 validateSector(sectorIndex); 266 267 if (sectorIndex < 32) { 268 return 4; 269 } else { 270 return 16; 271 } 272 } 273 274 /** 275 * Return the sector that contains a given block. 276 * <p>Does not cause any RF activity and does not block. 277 * 278 * @param blockIndex index of block to lookup, starting from 0 279 * @return sector index that contains the block 280 */ 281 public int blockToSector(int blockIndex) { 282 validateBlock(blockIndex); 283 284 if (blockIndex < 32 * 4) { 285 return blockIndex / 4; 286 } else { 287 return 32 + (blockIndex - 32 * 4) / 16; 288 } 289 } 290 291 /** 292 * Return the first block of a given sector. 293 * <p>Does not cause any RF activity and does not block. 294 * 295 * @param sectorIndex index of sector to lookup, starting from 0 296 * @return block index of first block in sector 297 */ 298 public int sectorToBlock(int sectorIndex) { 299 if (sectorIndex < 32) { 300 return sectorIndex * 4; 301 } else { 302 return 32 * 4 + (sectorIndex - 32) * 16; 303 } 304 } 305 306 /** 307 * Authenticate a sector with key A. 308 * 309 * <p>Successful authentication of a sector with key A enables other 310 * I/O operations on that sector. The set of operations granted by key A 311 * key depends on the ACL bits set in that sector. For more information 312 * see the MIFARE Classic specification on {@see http://www.nxp.com}. 313 * 314 * <p>A failed authentication attempt causes an implicit reconnection to the 315 * tag, so authentication to other sectors will be lost. 316 * 317 * <p>This is an I/O operation and will block until complete. It must 318 * not be called from the main application thread. A blocked call will be canceled with 319 * {@link IOException} if {@link #close} is called from another thread. 320 * 321 * @param sectorIndex index of sector to authenticate, starting from 0 322 * @param key 6-byte authentication key 323 * @return true on success, false on authentication failure 324 * @throws TagLostException if the tag leaves the field 325 * @throws IOException if there is an I/O failure, or the operation is canceled 326 */ 327 public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException { 328 return authenticate(sectorIndex, key, true); 329 } 330 331 /** 332 * Authenticate a sector with key B. 333 * 334 * <p>Successful authentication of a sector with key B enables other 335 * I/O operations on that sector. The set of operations granted by key B 336 * depends on the ACL bits set in that sector. For more information 337 * see the MIFARE Classic specification on {@see http://www.nxp.com}. 338 * 339 * <p>A failed authentication attempt causes an implicit reconnection to the 340 * tag, so authentication to other sectors will be lost. 341 * 342 * <p>This is an I/O operation and will block until complete. It must 343 * not be called from the main application thread. A blocked call will be canceled with 344 * {@link IOException} if {@link #close} is called from another thread. 345 * 346 * @param sectorIndex index of sector to authenticate, starting from 0 347 * @param key 6-byte authentication key 348 * @return true on success, false on authentication failure 349 * @throws TagLostException if the tag leaves the field 350 * @throws IOException if there is an I/O failure, or the operation is canceled 351 */ 352 public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException { 353 return authenticate(sectorIndex, key, false); 354 } 355 356 private boolean authenticate(int sector, byte[] key, boolean keyA) throws IOException { 357 validateSector(sector); 358 checkConnected(); 359 360 byte[] cmd = new byte[12]; 361 362 // First byte is the command 363 if (keyA) { 364 cmd[0] = 0x60; // phHal_eMifareAuthentA 365 } else { 366 cmd[0] = 0x61; // phHal_eMifareAuthentB 367 } 368 369 // Second byte is block address 370 // Authenticate command takes a block address. Authenticating a block 371 // of a sector will authenticate the entire sector. 372 cmd[1] = (byte) sectorToBlock(sector); 373 374 // Next 4 bytes are last 4 bytes of UID 375 byte[] uid = getTag().getId(); 376 System.arraycopy(uid, uid.length - 4, cmd, 2, 4); 377 378 // Next 6 bytes are key 379 System.arraycopy(key, 0, cmd, 6, 6); 380 381 try { 382 if (transceive(cmd, false) != null) { 383 return true; 384 } 385 } catch (TagLostException e) { 386 throw e; 387 } catch (IOException e) { 388 // No need to deal with, will return false anyway 389 } 390 return false; 391 } 392 393 /** 394 * Read 16-byte block. 395 * 396 * <p>This is an I/O operation and will block until complete. It must 397 * not be called from the main application thread. A blocked call will be canceled with 398 * {@link IOException} if {@link #close} is called from another thread. 399 * 400 * @param blockIndex index of block to read, starting from 0 401 * @return 16 byte block 402 * @throws TagLostException if the tag leaves the field 403 * @throws IOException if there is an I/O failure, or the operation is canceled 404 */ 405 public byte[] readBlock(int blockIndex) throws IOException { 406 validateBlock(blockIndex); 407 checkConnected(); 408 409 byte[] cmd = { 0x30, (byte) blockIndex }; 410 return transceive(cmd, false); 411 } 412 413 /** 414 * Write 16-byte block. 415 * 416 * <p>This is an I/O operation and will block until complete. It must 417 * not be called from the main application thread. A blocked call will be canceled with 418 * {@link IOException} if {@link #close} is called from another thread. 419 * 420 * @param blockIndex index of block to write, starting from 0 421 * @param data 16 bytes of data to write 422 * @throws TagLostException if the tag leaves the field 423 * @throws IOException if there is an I/O failure, or the operation is canceled 424 */ 425 public void writeBlock(int blockIndex, byte[] data) throws IOException { 426 validateBlock(blockIndex); 427 checkConnected(); 428 if (data.length != 16) { 429 throw new IllegalArgumentException("must write 16-bytes"); 430 } 431 432 byte[] cmd = new byte[data.length + 2]; 433 cmd[0] = (byte) 0xA0; // MF write command 434 cmd[1] = (byte) blockIndex; 435 System.arraycopy(data, 0, cmd, 2, data.length); 436 437 transceive(cmd, false); 438 } 439 440 /** 441 * Increment a value block, storing the result in the temporary block on the tag. 442 * 443 * <p>This is an I/O operation and will block until complete. It must 444 * not be called from the main application thread. A blocked call will be canceled with 445 * {@link IOException} if {@link #close} is called from another thread. 446 * 447 * @param blockIndex index of block to increment, starting from 0 448 * @param value non-negative to increment by 449 * @throws TagLostException if the tag leaves the field 450 * @throws IOException if there is an I/O failure, or the operation is canceled 451 */ 452 public void increment(int blockIndex, int value) throws IOException { 453 validateBlock(blockIndex); 454 validateValueOperand(value); 455 checkConnected(); 456 457 ByteBuffer cmd = ByteBuffer.allocate(6); 458 cmd.order(ByteOrder.LITTLE_ENDIAN); 459 cmd.put( (byte) 0xC1 ); 460 cmd.put( (byte) blockIndex ); 461 cmd.putInt(value); 462 463 transceive(cmd.array(), false); 464 } 465 466 /** 467 * Decrement a value block, storing the result in the temporary block on the tag. 468 * 469 * <p>This is an I/O operation and will block until complete. It must 470 * not be called from the main application thread. A blocked call will be canceled with 471 * {@link IOException} if {@link #close} is called from another thread. 472 * 473 * @param blockIndex index of block to decrement, starting from 0 474 * @param value non-negative to decrement by 475 * @throws TagLostException if the tag leaves the field 476 * @throws IOException if there is an I/O failure, or the operation is canceled 477 */ 478 public void decrement(int blockIndex, int value) throws IOException { 479 validateBlock(blockIndex); 480 validateValueOperand(value); 481 checkConnected(); 482 483 ByteBuffer cmd = ByteBuffer.allocate(6); 484 cmd.order(ByteOrder.LITTLE_ENDIAN); 485 cmd.put( (byte) 0xC0 ); 486 cmd.put( (byte) blockIndex ); 487 cmd.putInt(value); 488 489 transceive(cmd.array(), false); 490 } 491 492 /** 493 * Copy from the temporary block to a value block. 494 * 495 * <p>This is an I/O operation and will block until complete. It must 496 * not be called from the main application thread. A blocked call will be canceled with 497 * {@link IOException} if {@link #close} is called from another thread. 498 * 499 * @param blockIndex index of block to copy to 500 * @throws TagLostException if the tag leaves the field 501 * @throws IOException if there is an I/O failure, or the operation is canceled 502 */ 503 public void transfer(int blockIndex) throws IOException { 504 validateBlock(blockIndex); 505 checkConnected(); 506 507 byte[] cmd = { (byte) 0xB0, (byte) blockIndex }; 508 509 transceive(cmd, false); 510 } 511 512 /** 513 * Copy from a value block to the temporary block. 514 * 515 * <p>This is an I/O operation and will block until complete. It must 516 * not be called from the main application thread. A blocked call will be canceled with 517 * {@link IOException} if {@link #close} is called from another thread. 518 * 519 * @param blockIndex index of block to copy from 520 * @throws TagLostException if the tag leaves the field 521 * @throws IOException if there is an I/O failure, or the operation is canceled 522 */ 523 public void restore(int blockIndex) throws IOException { 524 validateBlock(blockIndex); 525 checkConnected(); 526 527 byte[] cmd = { (byte) 0xC2, (byte) blockIndex }; 528 529 transceive(cmd, false); 530 } 531 532 /** 533 * Send raw NfcA data to a tag and receive the response. 534 * 535 * <p>This is equivalent to connecting to this tag via {@link NfcA} 536 * and calling {@link NfcA#transceive}. Note that all MIFARE Classic 537 * tags are based on {@link NfcA} technology. 538 * 539 * <p>This is an I/O operation and will block until complete. It must 540 * not be called from the main application thread. A blocked call will be canceled with 541 * {@link IOException} if {@link #close} is called from another thread. 542 * 543 * @see NfcA#transceive 544 */ 545 public byte[] transceive(byte[] data) throws IOException { 546 return transceive(data, true); 547 } 548 549 private static void validateSector(int sector) { 550 // Do not be too strict on upper bounds checking, since some cards 551 // have more addressable memory than they report. For example, 552 // Mifare Plus 2k cards will appear as Mifare Classic 1k cards when in 553 // Mifare Classic compatibility mode. 554 // Note that issuing a command to an out-of-bounds block is safe - the 555 // tag should report error causing IOException. This validation is a 556 // helper to guard against obvious programming mistakes. 557 if (sector < 0 || sector >= MAX_SECTOR_COUNT) { 558 throw new IndexOutOfBoundsException("sector out of bounds: " + sector); 559 } 560 } 561 562 private static void validateBlock(int block) { 563 // Just looking for obvious out of bounds... 564 if (block < 0 || block >= MAX_BLOCK_COUNT) { 565 throw new IndexOutOfBoundsException("block out of bounds: " + block); 566 } 567 } 568 569 private static void validateValueOperand(int value) { 570 if (value < 0) { 571 throw new IllegalArgumentException("value operand negative"); 572 } 573 } 574} 575