Can't execute ChangeSettings Command on NTAG 424

cancel
Showing results for 
Search instead for 
Did you mean: 

Can't execute ChangeSettings Command on NTAG 424

Jump to solution
1,058 Views
tinofileccia
Contributor III

Hello,

I'm trying to send the "changeSettings" command as listed in the docs, but I keep getting a 91AE error message. I'm using Node.JS to send APDU commands to the chip and have posted the logs & code below. Not sure exactly what I'm missing, but any information helps!

 

  options = options || {};
  const cls = Buffer.from( '90', 'hex' );
  const cmd = Buffer.from( '5F', 'hex' );
  const p = Buffer.from( '0000', 'hex' );
  const fileNo = toBuffer( options.fileNo, { default: '02', size: 1 } )
  const cmdCtr = toBuffer( options.cmdCtr, { default: '0100', size: 2 } )

  const fileOption = toBuffer( options.fileOption, { default: '40', size: 1 } );
  const accessRights = toBuffer( options.accessRights, { default: '00E0', size: 2 } );
  const fileAR = toBuffer( options.fileAR, { default: 'C1', size: 1 } );
  const SDMAccessRights = toBuffer( options.SDMAccessRights, { default: 'F121', size: 2 } );
  const ENCPICCDataOffset = toBuffer( options.ENCPICCDataOffset, { default: '200000', size: 3 } );
  const SDMMACOffset = toBuffer( options.SDMMACOffset, { default: '430000', size: 3 } );
  const SDMMACInputOffset = toBuffer( options.SDMMACInputOffset, { default: '430000', size: 3 } );
  const settings = Buffer.concat([
    fileOption,
    accessRights,
    fileAR,
    SDMAccessRights,
    ENCPICCDataOffset,
    SDMMACOffset,
    SDMMACInputOffset,
    Buffer.from( '80', 'hex' ) // Add padding
  ])

  const IVcInput = Buffer.concat([
    Buffer.from( 'A55A', 'hex' ),
    auth.TI,
    cmdCtr,
    Buffer.from( '0000000000000000', 'hex' )
  ])
  const IVc = encrypt( auth.KSesAuthENC, IVcInput );

  const CmdDataE = encrypt( auth.KSesAuthENC, settings, IVc );
  const MACInput = Buffer.concat([
    cmd,
    cmdCtr,
    auth.TI,
    fileNo,
    CmdDataE
  ])
  const cmac = new AesCmac( auth.KSesAuthMAC );
  const MAC = cmac.calculate( MACInput )
  const MACt = truncate( MAC ); // Truncate to 8 bytes

  let Lc = fileNo.length + CmdDataE.length + MACt.length; // 9 = length of command header + length of MACt
  Lc = Lc.toString(16);
  Lc = ( Lc.length % 2 ) > 0 ? ( '0' + Lc ) : Lc; //add extra 0 to hex if needed so that it is a complete byte
  Lc = Buffer.from( Lc, 'hex' );

  const apdu = Buffer.concat([
    cls,
    cmd,
    p,
    Lc,
    fileNo,
    CmdDataE,
    MACt,
    Buffer.from( '00', 'hex' )
  ]);

 

Logs:

--AUTHENTICATE EV2 FIRST--
key: 00000000000000000000000000000000
Sending: 9071000002000000
Received: 19E4FC4591CB9E63A95AF3D883F3D88C91AF
Sending: 90AF0000204FE17E1D2711EDE92A68E10E9D5B42D228321858835688683F437AE31F0C385100
Received: D58B415CB564F7758E2325D63CCB6B463C79377E7F95AE53E1A5940C75590B7B9100
Authenticated Successfully


--SELECT APPLICATION--
Sending: 00A4040C07D276000085010100
Received: 9000


--SELECT FILE--
Sending: 00A4000C02E10400
Received: 9000


--GET FILE SETTINGS--
Settings for file 2: {
fileType: <Buffer 00>,
fileOption: <Buffer 00>,
accessRights: <Buffer e0 ee>,
fileSize: <Buffer 00 01 00>,
SDMOptions: <Buffer 91>,
SDMAccessRight: <Buffer 00>,
UIDOffset: <Buffer >,
SDMReadCounterOffset: <Buffer >,
SDMMacInputOffset: <Buffer >,
PICCDataOffset: <Buffer >,
SDMMACInputOffset: <Buffer >,
SDMENCOffset: <Buffer >,
SDMENCLength: <Buffer >,
SDMMACOffset: <Buffer >,
SDMReadCtrLimit: <Buffer >,
response: <Buffer 00 00 e0 ee 00 01 00 91 00>,
success: true,
err: false
}


--CHANGE FILE SETTINGS--
Settings: 4000E0C1F12120000043000043000080
IVc: E1B5A6BE8E55C26396FC2C452D485F52
KSesAuthENC: F4FF8BBEA5B334F3AEEF72DA7C618F3C
KSesAuthMAC: DC42BE6C5890E5B360325EF877CA0800
TI: A979B313
cls: 90
cmd: 5F
p: 0000
Lc: 19
CmdDataE: 15CCA2C2A7CC04285E17CB47A56FA3D6
MAC: 699BA8CF81255D131E04F36805A24E13
MACt: 9BCF25130468A213
Sending: 905F0000190215CCA2C2A7CC04285E17CB47A56FA3D69BCF25130468A21300
Received 91AE

0 Kudos
1 Solution
924 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hello @tinofileccia ,

 

No, the actual value of the CmdCtr is never transmitted. The CmdCtr is reset to 0000h at PCD and
PICC after a successful AuthenticateEV2First authentication and it is maintained as long as the PICC remains authenticated. Please kindly refer to "9.1.2 Command Counter" of the data sheet for more details.

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

10 Replies
985 Views
Jonathan_Iglesias
NXP TechSupport
NXP TechSupport

Hi @tinofileccia , 

Hope you are doing great,

Please accept our apologies for the delay there is an important holiday in my colleague country and that is why there is a little delay in our response, regarding your issue, that error means that the key used to authenticate is not the correct one to modify the file settings, basically whatever you have in your change key settings for the file is the one, I would recommend to double check the process I see you have the settings as E0EE which should require an authentication with key 00 to modify the file settings, also please first select the application then authenticate.  you can check the IV values in your process, that you are using the correct key, and confirm the file settings, check the following log I created for you doing the  Select command>Authenticate with key 01 ( since my card had the settings: Read 00 write 01 Read/Write 03 and change 01) > get file settings > change file settings

 

SELECT command

Send to card: 00A4040C07D276000085010100
Recv from card: 9000



Authenticate EV2 first

Send to card: 9071000002010000

Recv from card: 739CC6604B45430E602EC5283139F1FE91AF

PICC-to->PCD E(Kx, RndB): 739CC6604B45430E602EC5283139F1FE
Plain RNDB = 65EAF88FAF5290623DDCE478ADBE0BC4
Plain RNDA = 25E559236536A90860A28C6571F9F913
Plain RndB'= 60A28C6571F9F913EAF88FAF5290623DDCE478ADBE0BC465
Plain (RndA || RndB')= 25E559236536A90860A28C6571F9F913EAF88FAF5290623DDCE478ADBE0BC465
Encrypted (RndA || RndB'): 1EAC3CCD71A607FA2D474B4845721ADA12F20F9B63C92E1603D630EBA4B9B830



Send to card: 90AF0000201EAC3CCD71A607FA2D474B4845721ADA12F20F9B63C92E1603D630EBA4B9B83000

Recv from card: 4E4F4614CA94263B65E18D31FA6F34C15BFC7C4C499B3FDA90EA8B50A373BFEC9100



PICC-to->PCD E(Kx, TI||RndA'||PDcap2||PCDcap2): 4E4F4614CA94263B65E18D31FA6F34C15BFC7C4C499B3FDA90EA8B50A373BFEC
Plain (TI || RndA' || PDcap2 || PCDcap2)= FB72B311E559236536A90860A28C6571F9F91325000000000000000000000000
Plain RNDA' =


SV1 = 0xA5||0x5A||0x00||0x01||0x00||0x80||RndA[15..14]||(RndA[13..8] ⊕ RndB[15..10])||RndB[9..0]||RndA[7..0] 
SV1 = A55A0001008025E53CC99DB9065A90623DDCE478ADBE0BC460A28C6571F9F913
Encrypted SessionEncKey = AF479E5DFD0B91E1E0B364CB41746088

SV2 = 0x5A||0xA5||0x00||0x01||0x00||0x80||RndA[15..14]||(RndA[13..8] ⊕ RndB[15..10])||RndB[9..0]||RndA[7..0] 
SV2 = 5AA50001008025E53CC99DB9065A90623DDCE478ADBE0BC460A28C6571F9F913
Encrypted SessionMacKey = 795A1CF5300943E758AF53BD5FE5E769

CmdCtr = 0000


Get file settings



IV = 00000000000000000000000000000000

MAC Input Data = Cmd || CmdCtr || TI || CmdHeader || E(CmdData) 
MAC Input Data = F50000FB72B31102
MAC = E2D5F311756E933104D85618A1EE7207

Send to card: 90F500000902D5116E31D818EE0700

Recv from card: 00003102000100BCC4DE8C5817369D9100


IV = 00000000000000000000000000000000

MAC Input Data = Cmd || CmdCtr || TI || CmdHeader || E(CmdData) 
MAC Input Data = 000100FB72B31100003102000100
MAC = 2CBC83C49ADEAC8CA25838175036719D
phalMfNtag42XDna_GetFileSettings--------LEAVE-------- pFSBuffer=00003102000100 bBufferLen=07 [STATUS = SUCCESS]


phalMfNtag42XDna_ChangeFileSettings--------ENTRY-------- bCommMode=30 bFileNo=02 bFileOption=00 bAdditionalInfoLen=00 pAccessRights=3102



Change file settings:


plain stream(in): plain= A55AFB72B31101000000000000000000
Encrypted stream(out): enc= 596A58A577257242F81A425E74FB5F9D
IV = 596A58A577257242F81A425E74FB5F9D
plain stream(in): plain= 00310280000000000000000000000000
Encrypted stream(out): enc= C559F8442B9FD87636A54D09397553F3
IV = 00000000000000000000000000000000

MAC Input Data = Cmd || CmdCtr || TI || CmdHeader || E(CmdData) 
MAC Input Data = 5F0100FB72B31102C559F8442B9FD87636A54D09397553F3
MAC = 74E5F7EA2FF190BD1102D2EA55434D0B

 

Send to card: 905F00001902C559F8442B9FD87636A54D09397553F3E5EAF1BD02EA430B00

Recv from card: 1EE98E904AE6AACD9100
IV = 00000000000000000000000000000000

MAC Input Data = Cmd || CmdCtr || TI || CmdHeader || E(CmdData) 
MAC Input Data = 000200FB72B311
MAC = 751E34E99C8EC490E24A82E683AA91CD


 

BR

 

Jonathan 

1,047 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hello @tinofileccia ,

 

We provide an example in the following link:

https://www.nxp.com/docs/en/application-note/AN12196.pdf

Please refer to section 6 for details.

 

Hope that helps,

Have a great day,


Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

1,020 Views
tinofileccia
Contributor III

@Kan_Licould you possibly provide a real world example log of APDU commands for executing the changeSettings function? (Ex: "Sent: XXXXXX \n Received: XXXX)

0 Kudos
968 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hello @Jonathan_Iglesias , 

 

Thanks for the following up!

 

Hello @tinofileccia ,

 

Is there any progress on your side? I have checked with the expert, and he recommended not using  “80” at the end of ChangeFileSettings Data: 4000E0C1F12120000043000043000080

and he can get APDU with your settings:

905F0000190295DA3AAB53AABA618E20BFC140208CD7238DC0733225B78B00

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

957 Views
tinofileccia
Contributor III

@Kan_Li& @Jonathan_Iglesias,

 

Thank you both very much for the detailed replies! I'm in the middle of moving and am just now comparing the logs to my results in detail. The "80" at the end of the changeSettings data is padding and is necessary for encrypting the data. I'm using the "aes-128-cbc" algorithm that's built into the Node.JS crypto library, should I be using a different algorithm?

 

Thanks again,

Tino

0 Kudos
948 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hello @tinofileccia ,

 

Yes it is AES-128 cipher. 80h is indeed used for padding, but it is not part of Change File Settings, that’s why it is mentioned.

- Maybe problem is with CmdCtr, can you print out command counters at each command after authentication?
- Is it possible to share exact order? Because --SELECT APPLICATION-- cannot be done after --AUTHENTICATE EV2 FIRST--.

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

933 Views
tinofileccia
Contributor III

Hi @Kan_Li ,

I think the cmdCtr may be the issue. Before I post an updated log, I'm assuming that the function to retrieve the cmdCtr value should be the "getFilesCounter" command listed in section 10.7.3 of the datasheet, or is it something else? The length of the SDMReadCtr is 3 but everywhere that I see it is used, it is only 2 bytes.

 

Thanks again,

Tino

0 Kudos
925 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hello @tinofileccia ,

 

No, the actual value of the CmdCtr is never transmitted. The CmdCtr is reset to 0000h at PCD and
PICC after a successful AuthenticateEV2First authentication and it is maintained as long as the PICC remains authenticated. Please kindly refer to "9.1.2 Command Counter" of the data sheet for more details.

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

902 Views
tinofileccia
Contributor III

Hi @Kan_Li ,

 

It looks like I finally resolved my issue! I had to rewrite the portion of my code that generates the SV1 & SV2 values in my authentication function. I also set the cmdCtr to '0000' and was able to finally retrieve a 9100 status message! I'm now attempting to change the keys on the tags, but I'm having issues calculating the CRC32 value. I will start a new thread for that issue. Thank you very much for your help!

0 Kudos
1,038 Views
tinofileccia
Contributor III

Hi @Kan_Li ,

 

This code was written to follow the example you provided, and I have reviewed section 6 (specifically section 6.9) many times already. Is there something that I'm missing?

0 Kudos