How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How can i enable CMAC, UID, COUNTER and RAND in NTAG424 DNA?

875 Views
rocky2
Contributor I

I'm trying to use the newest Android SDK library to set my dynamic URL based on AES key, but I'm unable to do it.

nxpnfcandroidlib-release-protected.aar

This is my code

override fun onNewIntent(intent: Intent) {
	Log.i("NFC", "Intent action: ${intent.action}")
	super.onNewIntent(intent)

	Log.i("MainActivity", "NFC tag discovered")

	val cardType = libInstance.getCardType(intent)
	Log.i("MainActivity", "Detected card type: $cardType")
	if (cardType == CardType.NTAG424DNA) {
	    val ntag424DNA: INTAG424DNA = DESFireFactory.getInstance().getNTAG424DNA(libInstance.customModules)
	    val reader: IReader = ntag424DNA.reader

	    try {

	        if (!reader.isConnected) {
	            reader.connect()
	        }

	        ntag424DNA.isoSelectApplicationByDFName(NTAG424DNA_APP_NAME)
	        Log.i("NFC", "ISO selected app by DF Name ")

	        authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
		    creatingNDEFmessage(ntag424DNA)
            authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
		    changeFileSettings(ntag424DNA, 0x01)

            authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
	        ntag424DNA.setPICCConfiguration(true)
	        Log.i("MainActivity", " PICC Configuration updated to enable SDM globally.")

	        authenticateTag(ntag424DNA, KEY_AES128_DEFAULT)
	        changeSDMFileSettings(ntag424DNA, 0x01)

	        if (reader.isConnected) {
	            reader.close()
	        }
	    } catch (e: Exception) {
	        e.printStackTrace()
	    }

	}
}

private fun creatingNDEFmessage(ntag424DNA: INTAG424DNA) {
    // 1. Creating URI NDEF message
    val msg = NdefMessageWrapper(
        NdefRecordWrapper(
            NdefRecordWrapper.TNF_ABSOLUTE_URI,
            "https://domain.com?uid=04BB38D2AA1191&ctr=0001&cmac=3ab665b76b795cb9bf76a17956cc9fb3&rand=422def08-8a1c-49c9-9138-434cde858faa".toByteArray(
                Charset.forName("US-ASCII")
            ), ByteArray(0), ByteArray(0)
        )
    )

    ntag424DNA.writeNDEF(msg);
    Log.i("MainActivity", "URI NDEF message written successful ")

    val ndefRead = ntag424DNA.readNDEF()
    Log.i("MainActivity", "Read URI NDEF message ${CustomModules.getUtility().dumpBytes(ndefRead.toByteArray())}")

}

private fun changeFileSettings(ntag424DNA: INTAG424DNA, fileNumber: Int) {
    // 3. Create NTAG 424 DNA file settings for E104
    val fileSettings = NTAG424DNAFileSettings(
        MFPCard.CommunicationMode.Encrypted,    // = 0x03 = Full ENC + CMAC (SUN)
        0x0E.toByte(),             // Read access = key slot 0x00 maybe 0x01
        0x0E.toByte(),             // Write access = always
        0x0E.toByte(),             // RW access = always
        0x0E.toByte()              // Change access = always
    )

    Log.i("MainActivity", "Prepare for saving changes in file $fileNumber")
    ntag424DNA.changeFileSettings(fileNumber, fileSettings)
    Log.i("NFC", " File settings updated $fileNumber")
}


private fun changeSDMFileSettings(ntag424DNA: INTAG424DNA, fileNumber: Int) {
    val fileSettings = ntag424DNA.getFileSettings(fileNumber);

    fileSettings.isSDMEnabled = true;
    fileSettings.isUIDMirroringEnabled = true;

    fileSettings.piccDataOffset = intTo2ByteArray(51)
    fileSettings.sdmMacOffset = intTo2ByteArray(51)
    fileSettings.sdmMacInputOffset = intTo2ByteArray(51)
    fileSettings.sdmReadCounterOffset = intTo2ByteArray(51)
    fileSettings.uidOffset = intTo2ByteArray(51)
    fileSettings.sdmAccessRights = byteArrayOf(0x00, 0x00)

    Log.i("MainActivity", "Prepare for saving SDM changes in file $fileNumber")
    ntag424DNA.changeFileSettings(fileNumber, fileSettings)
    Log.i("NFC", " File settings updated: SUN CMAC enabled on $fileNumber")
}

private fun intTo2ByteArray(value: Int): ByteArray {
    return byteArrayOf(
        ((value shr  and 0xFF).toByte(),
        (value and 0xFF).toByte()
    )
}

I know that the offset number doesn't match the position in the URL but whatever I'm changing, I'm still getting this error. It looks like, for some reason, these settings can not be saved by this method.

ntag424DNA.changeFileSettings(fileNumber, fileSettings)

This is the error message

com.nxp.nfclib.exceptions.UsageException: Invalid Parameters! {Invalid Value for PICC Offset}
Labels (1)
0 Kudos
Reply
5 Replies

117 Views
sushil_adhikari
Contributor II

hey there,

I am following this thread to set up JSON data, but it is not working for me. This is my first time working with hardware, which is making things much more challenging. I am using the NXP Android library and the sample Android application from here: https://www.nxp.com/design/design-center/software/rfid-developer-resources/taplinx-software-developm...

Below is my code inside Sample_Application_Android/src/main/java/com/nxp/sampletaplinx/WriteActivity.java

public static byte[] intTo2ByteArray(int value) {
    return new byte[] {
            (byte) (value & 0xFF),        // LSB
            (byte) ((value >> 8) & 0xFF), // middle byte
            (byte) ((value >> 16) & 0xFF) // MSB
    };
}

private void tag424DNACardLogic(INTAG424DNA ntag424DNA) {
    byte[] KEY_AES128_DEFAULT = new byte[] {
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
            (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
    };
    byte[] NTAG424DNA_APP_NAME =
            {(byte) 0xD2, (byte) 0x76, 0x00, 0x00, (byte) 0x85, 0x01, 0x01};
    byte[] data ={ 0x73, 0x75, 0x73, 0x68, 0x69, 0x6C };

    mStringBuilder.append("\n\n");
    int timeOut = 2000;
    try {
        ntag424DNA.isoSelectApplicationByDFName(NTAG424DNA_APP_NAME);
        KeyData aesKeyData = new KeyData();
        Key keyDefault = new SecretKeySpec(KEY_AES128_DEFAULT, "AES");
        aesKeyData.setKey(keyDefault);
       ntag424DNA.authenticateEV2First(0, aesKeyData, null);

        mStringBuilder.append(getString(R.string.Authentication_status_true));
        mStringBuilder.append("\n\n");

        ntag424DNA.setPICCConfiguration(true);

        String jsonTemplate = "{\"uuid\":\"00000000000000\",\"counter\":\"000000\",\"cmac\":\"0000000000000000\",\"domain1\":" + 1 + ",\"domain2\":" + 1 + "}";
        byte[] jsonBytes = jsonTemplate.getBytes("UTF-8");

        NTAG424DNAFileSettings fs = new NTAG424DNAFileSettings(
                CommunicationMode.Plain,  // or MAC/ENC depending on your security
                (byte) 0x0E, // Read access: Key 0
                (byte) 0x0E, // Write access: Key 0
                (byte) 0x0E, // Read/Write: Key 0
                (byte) 0x00  // Change access: Free
        );

        byte[] type = "U".getBytes("US-ASCII");
        fs.setSDMEnabled(true);
        fs.setUIDMirroringEnabled(true);
        fs.setSDMReadCounterEnabled(true);

        byte[] bytes = new byte[] { (byte)0xE0, (byte)0x00, (byte)0x00 };
        fs.setSdmAccessRights(bytes);

        byte[] uuidOffset = intTo2ByteArray(8);

        fs.setUidOffset(uuidOffset);

        byte[] readCounterOffset = intTo2ByteArray(35);
        fs.setSdmReadCounterOffset(readCounterOffset);

        byte[] macOffset = intTo2ByteArray(51);

        fs.setSdmMacInputOffset(uuidOffset);
        fs.setSdmMacOffset(macOffset);

        ntag424DNA.changeFileSettings(FILE_NUMBER, fs);

        // Create NDEF record
        NdefRecordWrapper record = new NdefRecordWrapper(
                NdefRecordWrapper.TNF_WELL_KNOWN,
                type,
                new byte[0],  // empty ID
                jsonBytes     // payload (your JSON)
        );

        // Wrap record into NDEF message
        NdefMessageWrapper msg = new NdefMessageWrapper(record);

        ntag424DNA.writeNDEF(msg);

        NxpLogUtils.save();
    } catch (Exception e) {
        writeFailedMessage();
        mStringBuilder.append(e.getMessage());

        Log.i("MainActivity", "URI NDEF message written successful $msg " + e.getMessage()  );
        showMessage(mStringBuilder.toString(), PRINT);
        NxpLogUtils.save();
    }

}

 would be great help if someone can assist me with this

0 Kudos
Reply

103 Views
sushil_adhikari
Contributor II

The issue was due to the wrong offset value. It seems ntag reserved 21 default index. Now we are trying to change factory 128 aes key and changekey() function didnt work for us

@ukcas 

0 Kudos
Reply

811 Views
rocky2
Contributor I

Thanks for the help! You are right that my offset has the wrong values. This is what I have changed and now I can save settings. 

override fun onNewIntent(intent: Intent) {
    Log.i("NFC", "Intent action: ${intent.action}")
    super.onNewIntent(intent)

    Log.i("MainActivity", "NFC tag discovered")

    val cardType = libInstance.getCardType(intent)
    Log.i("MainActivity", "Detected card type: $cardType")
    if (cardType == CardType.NTAG424DNA) {
        val ntag424DNA: INTAG424DNA = DESFireFactory.getInstance().getNTAG424DNA(libInstance.customModules)
        val reader: IReader = ntag424DNA.reader

        try {

            if (!reader.isConnected) {
                reader.connect()
            }

            ntag424DNA.isoSelectApplicationByDFName(NTAG424DNA_APP_NAME)
            Log.i("NFC", "ISO selected app by DF Name ")

            authenticateTag(0x00, ntag424DNA, KEY_AES128_DEFAULT)
            creatingNDEFmessage(ntag424DNA)
            authenticateTag(0x00, ntag424DNA, KEY_AES128_DEFAULT)
            changeFileSettings(ntag424DNA, 0x02)

            if (reader.isConnected) {
                reader.close()
            }
        } catch (e: Exception) {
            Log.e("MainActivity", e.localizedMessage ?: "No Error Message");
            e.printStackTrace()
        }

    }
}

private fun changeFileSettings(ntag424DNA: INTAG424DNA, fileNumber: Int) {
    // 3. Create NTAG 424 DNA file settings for E104
    val fileSettings = NTAG424DNAFileSettings(
        MFPCard.CommunicationMode.Plain,    // = 0x03 = Full ENC + CMAC (SUN)
        0x0E.toByte(),             // Read access = key slot 0x00 maybe 0x01
        0x0E.toByte(),             // Write access = always
        0x0E.toByte(),             // RW access = always
        0x00.toByte()              // Change access = always
    )

    fileSettings.isSDMEnabled = true
    fileSettings.isUIDMirroringEnabled = true
    fileSettings.isSDMReadCounterEnabled = true
    fileSettings.sdmAccessRights = byteArrayOf(0xfe.toByte(), 0xe1.toByte())

    fileSettings.uidOffset = byteArrayOf(0x1A, 0x00, 0x00)   
    fileSettings.sdmReadCounterOffset = byteArrayOf(0x2d, 0x00, 0x00) 
    fileSettings.sdmMacOffset = byteArrayOf(0x39, 0x00, 0x00) 
    fileSettings.sdmMacInputOffset = byteArrayOf(0x39, 0x00, 0x00)

    Log.i("MainActivity", "Prepare for saving changes in file $fileNumber")

    ntag424DNA.changeFileSettings(fileNumber, fileSettings)
    Log.i("MainActivity", " File settings updated $fileNumber")
}

private fun creatingNDEFmessage(ntag424DNA: INTAG424DNA) {
    // 1. Creating URI NDEF message
    val payload = byteArrayOf(0x04) + "noexample.xxxx?uid=00000000000000&ctr=000000&cmac=0000000000000000".toByteArray()

    val msg = NdefMessageWrapper(
        NdefRecordWrapper(
            NdefRecordWrapper.TNF_WELL_KNOWN,
            "U".toByteArray(StandardCharsets.US_ASCII),
            ByteArray(0),
            payload
        )
    )

    ntag424DNA.writeNDEF(msg);
    Log.i("MainActivity", "URI NDEF message written successful ")

    val ndefRead = ntag424DNA.readNDEF()
    Log.i("MainActivity", "Read URI NDEF message ${CustomModules.getUtility().dumpBytes(ndefRead.toByteArray())}")

}

 

0 Kudos
Reply

826 Views
ukcas
NXP Employee
NXP Employee

Dear Rocky2,

Please check document refered by jimmyvhan and datasheet. 

 

Your offsets are overlapping, which is not permitted as per datasheet.

Considering your desired URL. You have too less space for NFCCounter, which is 3 bytes. So below settings are suiting corrected URL.

https://domain.com?uid=04BB38D2AA1191&ctr=000001&cmac=3ab665b76b795cb9bf76a17956cc9fb3&rand=422def08...

 You shall use these parameters for SDM Configuration. You decide on Input data for CMAC calculation as well. We used UIDOffset as starting point for this example.

fileSettings.sdmMacOffset = intTo2ByteArray(53)
fileSettings.sdmMacInputOffset = intTo2ByteArray(22)
fileSettings.sdmReadCounterOffset = intTo2ByteArray(41)
fileSettings.uidOffset = intTo2ByteArray(22)

 Best regards,

TapLinx team

0 Kudos
Reply

842 Views
jimmychan
NXP TechSupport
NXP TechSupport

This document could be useful for you.

NTAG 424 DNA and NTAG 424 DNA TagTamper features and hints

0 Kudos
Reply