Beispiel #1
0
        public byte[] WriteData(byte[] sessionKey, byte fileNo, byte dataIn)
        {
            //byte fileNo = 0x01;
            byte[] offset      = new byte[] { 0x00, 0x00, 0x00 }; //offset of 0
            byte[] length      = new byte[] { 0x00, 0x00, 0x01 }; //length of 1
            byte[] dataToWrite = new byte[] { dataIn };

            byte[] dataForCRC32Header = new byte[] { (byte)DesfireCommand.CommandType.WriteData, fileNo, offset[2], offset[1], offset[0], length[2], length[1], length[0] };
            byte[] dataForCRC32       = new byte[dataForCRC32Header.Length + dataToWrite.Length];
            Array.Copy(dataForCRC32Header, dataForCRC32, dataForCRC32Header.Length);
            Array.Copy(dataToWrite, 0, dataForCRC32, dataForCRC32Header.Length, dataToWrite.Length);

            uint   crc32       = Crc32.Compute(dataForCRC32);
            string dataPlusCRC = Formatting.ByteArrayToHexString(dataToWrite) + Formatting.ByteArrayToHexString(BitConverter.GetBytes(crc32));

            byte[] dataPlusCRCPadded = Formatting.HexStringToByteArray(dataPlusCRC);
            Formatting.PadToMultipleOf(ref dataPlusCRCPadded, 16);
            string initialIV = "00000000000000000000000000000000";

            byte[] dataPlusCRCResultPaddedEncrypted = AESCrypto.AESEncrypt(
                sessionKey,
                Formatting.HexStringToByteArray(initialIV),
                dataPlusCRCPadded);
            byte[] extractIV = new byte[16];
            Array.Copy(dataPlusCRCResultPaddedEncrypted, dataPlusCRCResultPaddedEncrypted.Length - 16, extractIV, 0, 16);

            byte[] cmdToSendHeader = new byte[] { fileNo, offset[2], offset[1], offset[0], length[2], length[1], length[0] };
            byte[] cmdToSend       = new byte[cmdToSendHeader.Length + dataPlusCRCResultPaddedEncrypted.Length];
            Array.Copy(cmdToSendHeader, cmdToSend, cmdToSendHeader.Length);
            Array.Copy(dataPlusCRCResultPaddedEncrypted, 0, cmdToSend, cmdToSendHeader.Length, dataPlusCRCResultPaddedEncrypted.Length);

            DesfireCommand desfireCommand = new DesfireCommand()
            {
                Command = (byte)DesfireCommand.CommandType.WriteData,
                Data    = cmdToSend
            };
            DesfireResponse desfireResFile = SendCommand(desfireCommand) as DesfireResponse;

            if (!desfireResFile.Succeeded)
            {
                throw new DesFireException("Error:" + desfireResFile.SW);
            }

            byte[] cmac = AESCMAC.CMAC(
                sessionKey,
                extractIV,
                new byte[] { desfireResFile.SW2 });

            byte[] updatedIV = cmac;

            byte[] data = ReadData(sessionKey, updatedIV, fileNo);

            if (data[0] != dataToWrite[0])
            {
                throw new DesFireException("Data read not the same as data written");
            }
            return(data);
        }
Beispiel #2
0
        public byte[] ReadData(byte[] sessionKey, byte[] updatedIV, byte fileNo)
        {
            byte[] offset = new byte[] { 0x00, 0x00, 0x00 }; //offset of 0
            byte[] length = new byte[] { 0x00, 0x00, 0x01 }; //length of 1

            byte[] dataForCMAC = new byte[] { (byte)DesfireCommand.CommandType.ReadData, fileNo, offset[2], offset[1], offset[0], length[2], length[1], length[0] };
            byte[] cmac        = AESCMAC.CMAC(
                sessionKey,
                updatedIV,
                dataForCMAC);

            updatedIV = cmac;

            byte[]         cmdToSend      = new byte[] { fileNo, offset[2], offset[1], offset[0], length[2], length[1], length[0] };
            DesfireCommand desfireCommand = new DesfireCommand()
            {
                Command = (byte)DesfireCommand.CommandType.ReadData,
                Data    = cmdToSend
            };
            DesfireResponse desfireRes = SendCommand(desfireCommand) as DesfireResponse;

            if (!desfireRes.Succeeded)
            {
                throw new DesFireException("Error:" + desfireRes.SW);
            }

            byte[] dataBytes = AESCrypto.AESDecrypt(
                sessionKey,
                updatedIV,
                desfireRes.ResponseData);

            byte[] extractIV = new byte[16];
            Array.Copy(desfireRes.ResponseData, desfireRes.ResponseData.Length - 16, extractIV, 0, 16);

            int lengthofData = 0x01;

            byte[] data = new byte[lengthofData];
            Array.Copy(dataBytes, data, data.Length);
            byte[] crc = new byte[4];
            Array.Copy(dataBytes, data.Length, crc, 0, crc.Length); //crc is 4 bytes long
            byte[] dataPlusStatus = new byte[data.Length + 1];
            Array.Copy(data, dataPlusStatus, data.Length);
            Array.Copy(new byte[] { 0x00 }, 0, dataPlusStatus, data.Length, 1);
            uint crc32 = Crc32.Compute(dataPlusStatus);

            //compare crc32 to crc
            if (BitConverter.ToUInt32(crc, 0) != crc32)
            {
                throw new DesFireException("CRC32 error");
            }
            return(data);
        }