Code:
/** written by greg gulrajani
*
* decodes/encodeds Mifare access bits
*
* All text / tables taken from the MF1 IC S50 Specification
* from: http://www.nxp.com/acrobat_download/other/identification/m001052.pdf
*
*/
public class AclTool
{
public static final String[] sector_str_perm = {
"Never\tKey A\tKey A\tNever\tKey A\tKey A | TRAILER :0",
"Never\tNever\tKey A\tKey A\tKey A\tKey A | TRL(TRANSPORT):1",
"Never\tNever\tKey A\tNever\tKey A\tNever | TRAILER :2",
"Never\tKey B\tKyA|B\tKey B\tNever\tKey B | TRAILER :3",
"Never\tKey B\tKyA|B\tNever\tNever\tKey B | TRAILER :4",
"Never\tNever\tKyA|B\tKey B\tNever\tNever | TRAILER :5",
"Never\tNever\tKyA|B\tNever\tNever\tNever | TRAILER :6",
"Never\tNever\tKyA|B\tNever\tNever\tNever | TRAILER :7"
};
public static final String[] data_str_perm = {
"KyA|B\tKA|B1\tKA|B1\tKA|B1\tTransport Config|No KeyB Auth:0",
"KyA|B\tNever\tNever\tKyA|B\tValue Block |No KeyB Auth:1",
"KyA|B\tNever\tNever\tNever\tRead/Write Blk |No KeyB Auth:2",
"Key B\tKey B\tNever\tNever\tRead/Write Blk | :3",
"KyA|B\tKey B\tNever\tNever\tRead/Write Blk | :4",
"Key B\tNever\tNever\tNever\tRead/Write Blk | :5",
"KyA|B\tKey B\tKey B\tKyA|B\tValue Blk | :6",
"Never\tNever\tNever\tNever\tRead/Write Blk | :7",
};
public static final short DATA_BLOCK_0 = 0;
public static final short DATA_BLOCK_1 = 1;
public static final short DATA_BLOCK_2 = 2;
public static final short SECTOR_TRAILER = 3;
static boolean[][] bitarray = new boolean[3][8];
static byte[] blockperm = new byte[4];
static String sargs = "java AclTool [decode|encode] [ff ff ff|0-7 0-7 0-7]\njava AclTool decode 78 77 88\njava AclTool encode 5 5 5 3 (where 5 5 5 are Blocks 0-3 and 3 is the Section Trailer";
public static void main(String[] args)
{
if (args[0].equals("decode"))
{
if (args.length != 4)
{
System.err.println(sargs);
System.exit(-1);
}
byte[] a = new byte[4];
a[0] = (byte) Integer.parseInt(args[1],16);
a[1] = (byte) Integer.parseInt(args[2],16);
a[2] = (byte) Integer.parseInt(args[3],16);
decodeACL(a);
} else if (args[0].equals("encode")) {
if (args.length != 5)
{
System.err.println(sargs);
System.exit(-1);
}
byte[] a = new byte[4];
a[0] = (byte) Integer.parseInt(args[1]);
a[1] = (byte) Integer.parseInt(args[2]);
a[2] = (byte) Integer.parseInt(args[3]);
a[3] = (byte) Integer.parseInt(args[4]);
createACL(a);
} else {
System.err.println(sargs);
System.exit(0);
}
}
public static void decodeACL(byte[] a)
{
for (int j = 0; j < 3;j++)
{
for (int i =0;i < 8;i++)
{
int bit = ( 0x1 & a[j] ) ;
bitarray[j][i] = (bit != 0 );
a[j] = (byte) ( a[j] >> 1 ) ;
}
}
// now place them in our bits into our out of order arrays
blockperm[DATA_BLOCK_0] = bin2byte(bitarray[1][4],bitarray[0][4],bitarray[2][4] );
blockperm[DATA_BLOCK_1] = bin2byte(bitarray[1][5],bitarray[0][5],bitarray[2][5] );
blockperm[DATA_BLOCK_2] = bin2byte(bitarray[1][6],bitarray[0][6],bitarray[2][6] );
blockperm[SECTOR_TRAILER] = bin2byte(bitarray[1][7],bitarray[0][7],bitarray[2][7] );
System.out.println(" C1 C2 C3\tread\twrite\tincrement\tdec/xfer/restor\tApp");
System.out.println("------------------------------------------------------------------------------");
System.out.println("BLK 0:"+bin2str(bitarray[1][4],bitarray[0][4],bitarray[2][4] ) +"\t"+ data_str_perm[blockperm[DATA_BLOCK_0]] );
System.out.println("BLK 1:"+bin2str(bitarray[1][5],bitarray[0][5],bitarray[2][5])+"\t"+data_str_perm[blockperm[DATA_BLOCK_1]]);
System.out.println("BLK 2:"+bin2str(bitarray[1][6],bitarray[0][6],bitarray[2][6])+"\t"+ data_str_perm[blockperm[DATA_BLOCK_2]]);
System.out.println("");
System.out.println("KEY A\t\tAccess Bits\t\tKEY B\t\t\tRem");
System.out.println("read\twrite\tread\twrite\tread\twrite");
System.out.println("------------------------------------------------------------------------------");
System.out.println("STR 4:"+bin2str(bitarray[1][7],bitarray[0][7],bitarray[2][7] )+"\t"+ sector_str_perm[blockperm[SECTOR_TRAILER]] ) ;
System.out.println(" 8 7 6 5 4 3 2 1");
for (int i = 0; i < 3;i++)
{
//for (int j = 0; j < 8;j++)
for (int j = 7; j >=0 ;j--)
{
System.out.print(" "+(bitarray[i][j]==true?1:0));
}
System.out.println("");
}
}
public static void createACL(byte a[])
{
boolean[][] c1c2c3 = new boolean[4][3];
for (int j = 0; j < 4;j++)
{
for (int i =0;i < 3;i++)
{
int bit = ( 0x1 & a[j] );
c1c2c3[j][i] = (bit != 0 );
a[j] = (byte) ( a[j] >> 1 ) ;
}
}
byte byte6 = bin2byte(c1c2c3[3][1],c1c2c3[2][1],c1c2c3[1][1],c1c2c3[0][1],false,false,false,false);
byte byte7 = bin2byte(c1c2c3[3][0],c1c2c3[2][0],c1c2c3[1][0],c1c2c3[0][0],false,false,false,false);
byte byte8 = bin2byte(c1c2c3[3][2],c1c2c3[2][2],c1c2c3[1][2],c1c2c3[0][2],false,false,false,false);
System.out.println("output:".format("%x %x %x",byte6,byte7,byte8));
System.out.println("done");
byte[] ba = { byte6,byte7,byte8 };
decodeACL(ba);
}
public static String bin2str(boolean C1,boolean C2,boolean C3)
{
return "".format("%s %s %s",(C3==true?1:0),(C2==true?1:0),(C1==true?1:0));
}
public static byte bin2byte(boolean C1,boolean C2,boolean C3)
{
byte dd =(byte) (C1==true?1:0) ;
dd =(byte) (dd << 1);
dd = (byte) (dd | (int) (C2==true?1:0) ) ;
dd =(byte) (dd << 1);
dd = (byte) (dd | (int) (C3==true?1:0) ) ;
return dd;
}
public static byte bin2byte(boolean C1,boolean C2,boolean C3,boolean C4,boolean C5,boolean C6, boolean C7 , boolean C8)
{
byte dd = bin2byte(C1,C2,C3);
dd =(byte) (dd << 3);
dd =(byte) (dd | bin2byte(C4,C5,C6) ) ;
dd =(byte) (dd << 1);
dd = (byte) (dd | (int) (C7==true?1:0) ) ;
dd =(byte) (dd << 1);
dd = (byte) (dd | (int) (C8==true?1:0) ) ;
return dd;
}
}