3
votes

I'm trying to read the EF.COM file from an ePassport (a.k.a MRTD).

What I have successfully done:

-Selected the ePassport application using the AID 0xA0,0x00,0x00,0x02,0x47,0x10,0x01 -Requested a challenge nonce from the epassport chip -Successfully authenticated by responding to that challenge as per doc9303 appendix 5. Doc 9303 can be viewed here: http://www.icao.int/publications/Documents/9303_p1_v2_cons_en.pdf

It worked and now I am attempting to read the EF.COM file using the secure messaging protocol as per ISO 7816-4 and I used the doc9303 appendix 6 examples as a guide.

What my secure messaging code does correctly as per the examples in doc9303:

-It generates the exact same secure APDUs, byte for byte, as those in the doc9303 examples given the same inputs. -I have verified that my encryption (3DES w/CBC) is working, as is my MAC algorithm

What I have tried:

So I searched and found two open source implementations of the ePassport/MRTD/doc9303. One in Python (pyPassport-1.0) and the other in Java (JMRTD). I ordered the ACR122 reader (uses the same NFC chipset - PN532) to try it and it does work. So I then looked at the code JMRTD and pyPassport use to generate the secure messaging APDUs and it appears as though I am doing the same thing. Thankfully the JMRTD comes with an option to dump/trace the APDUs to a log file. Sure enough I am creating the secure messaging APDUs exactly as JMRTD is, I even reverse engineered a session (decrypted the RND.IFD, RND.ICC, K.ICC, session keys, etc..), created a test case and my code does in fact generate the same secure APDU output.

So I think I am constructing the secure messaging APDUs and DOs (Data Objects) correctly, but after I perform BAC and authenticate and try to read the EF.COM file with a protected APDU I keep getting a 69 88 error (Incorrect secure messaging (SM) data object). This is similar to the problem reported here although I am not using Android but my own embedded NFC stack: Android NFC read data from ePassport

I think it may be a setting in the PN532 (NXP NFC Chip) that I need to change but I doubt that since I am authenticating correctly and sending and transmitting data without PN532 errors. I tried raising the baud rate to 424 kbits/s but that did not fix it.

Here is an example of a secure (protected) APDU that my code generates.

Raw (unsecured) APDU:
00 A4 02 0C 02 01 1E

Protected (secure) APDU: 0C A4 02 0C 15 87 09 01 5B B0 63 B9 2A 0D 71 C0 8E 08 E0 B6 68 D2 14 4F 28 B5 00

So as per the doc9303 I am constructing a DO87 since command parameters are present, and a DO8E since there is a checksum (MAC) present, but no DO97 since no response payload is expected. I am using 87 09 01 for the DO87 since the 01 means padding type 80 00 00... and the L is 09 (I guess it includes the 01 - padding indicator byte, this is what is in the examples and APDU traces from JMRTD.)

I have tried removing the Le=0x00 from the end since some language in the 7816-4 doc suggests that, as well as making Lc' 0x16 rather than 0x15 as shown above. I have also tried making to DO87 to be 87 08 01 instead of 87 09 01 as shown above. None of that has worked.

I am really desperate here, I've been working on this for some time and just can't figure it out. Is there something wrong with my protected APDU structure? Is there a low level PN532 setting I need to change?

UPDATE ON 19-March-2014 Here is the PN532 command/response trace (I annotated it so it's less gobedy gook):

-> GetFirmwareVersion (test command to verify PN532 is awake and online):
00FF02FED4022A0000 
0000FF00FF0000 ->ACK
-> Response to GetFirwareVersion:
00FF06FAD50332010607E80000 

-> Diagnose, NumTst=0x00:
00FF12EED400000102030405060708090A0B0C0D0E0FB40000 
00FF00FF0000 ->ACK
-> Successfull diagnostic (Data returned):
00FF12EED501000102030405060708090A0B0C0D0E0FB20000 

-> Diagnose NumTst=0x01:
00FF03FDD400012B0000 
00FF00FF0000 ->ACK
-> Successfull diagnostic (0x00):
00FF03FDD501002A0000 

-> Diagnose NumTst=0x02:
00FF03FDD400022A0000 
00FF00FF0000 ->ACK
-> Successfull diagnostic (0x00):
00FF03FDD501002A0000 

-> InListPassiveTarget (max targets one, 106kbit/s Type A anticollision)
00FF04FCD44A0100E10000 
00FF00FF0000 ->ACK
-> Found one target, Tg=0x01, SENS_RES=0x07,0x04, SEL_RES=0x20 
-> UID = 0x08,0x8B,0x05,0xCF, ATS = 0x05,0x78,0x77,0xB4,0x02 DCS=0x9E:
00FF11EFD54B010107042004088B05CF057877B4029E0000 

-> inPSL (change baud to 424kbits/s)
00FF05FBD44E010202D90000
00FF00FF0000 -> ACK
00FF03FDD54F00DC0000 -> Status = 0x00, success

-> inDataExchange (select ePassport application w/ AID in doc9303):
00FF0FF1D4400100A4040C07A0000002471001360000
00FF00FF0000 -> ACK
00FF05FBD5410090005A0000 -> SW1SW2 = 9000 (success)

-> inDataExchange  (get nonce/challenge)
00FF08F8D4400100840000085F0000
00FF00FF0000 -> ACK
00FF0DF3D541008EAF826F89F1E5259000A80000 -> SW1SW2 = 9000 (success), RND.ICC = 0x8E,0xAF,0x82,0x6F,0x89,0xF1,0xE5,0x25

-> inDataExchange  (mutual authenticate)
00FF31CFD4400100820000284782B1700DD4F60373DA6632FCD1AB1E500D46FA11DEBDF9B88C39FCA7FDF8DBBE51F41D52D4B87928310000
00FF00FF0000 -> ACK
00FF2DD3D5410055A930856698D46C2AEF3CEDF3C56E71668150F2FECC75E28F42AB2A57CD2BA2F42727AE656CB3F49000470000 -> SW1SW2 = 9000 (success)

-> inDataExchange  (select EF.COM)
00FF1EE2D440010CA4020C158709012CA8E7AB995D13248E0810061DDC725A159300DB0000
00FF00FF0000 ->ACK
00FF05FBD541006988F90000 -> SW1SW2 = 6988 (Incorrect SM Data Objects)..BAH!!

The Session details are below:

MRZ = GF043591<586012072309062

Computed values from MRZ:

Kenc = BA 43 43 3B F4 7A AE F8 75 23 4F DF 32 08 20 6D
Kmac = EA 64 45 CD 62 2C EA EC BF 7C 9B 7C B0 20 B9 5D


RND.ICC = 8E AF 82 6F 89 F1 E5 25
RND.IFD = 23 E8 5A 99 3A 9A C5 B4
K.IFD = 75 DC 87 E5 0C 8E F3 00 47 D0 B5 32 5E 83 20 4D
SSC = 89 F1 E5 25 3A 9A C5 B4

The computed E.IFD = 47 82 B1 70 0D D4 F6 03 73 DA 66 32 FC D1 AB 1E 50 0D 46 FA 11 DE BD F9 B8 8C 39 FC A7 FD F8 DB

The computed MAC of the above = BE 51 F4 1D 52 D4 B8 79

The tag's response to the mutual authenticate was:

E[Kenc](RND.ICC) =  55 A9 30 85 66 98 D4 6C
E[Kenc](RND.IFD) =  2A EF 3C ED F3 C5 6E 71 
E[Kenc](K.ICC)   =  66 81 50 F2 FE CC 75 E2 8F 42 AB 2A 57 CD 2B A2
MAC              =  F4 27 27 AE 65 6C B3 F4

The computed session keys:
KSenc = 4C E6 EF A8 3D 3E DA FB FB 02 1A F2 D5 E0 6E 4F
KSmac = EA C7 5B 64 D9 80 52 23 4F 64 7A 51 45 7F 40 1A
1
The SM APDU looks correct (if the encrypted value/MAC value is correct). The padding indicator counts towards the length of DO87 and Lc of the SM APDU should be 0x00. The Le of the wrapped APDU should be empty as indicated by DO97 not being present.Michael Roland
@Michael thanks for the response. Could you clarify what is meant by "Lc of the SM APDU should be 0x00". I set byte 5 of the SM APDU to 00 (was ox15) and got a 6700 error. Do you mean that when I compute the MAC of N = SSC||Padded 4 byte CMD Header||87 L 01||Encrypted Padded Data||Padding that L should be 0x00? Right now my code generates the same APDUs that doc9303 does so I'm thinking my secure message building is correct in that the cryptograms match those of doc9303 with the same unprotected APDU inputs and SSCs. If I am incrementing the SSC incorrecty, would that create a 6988 error?Papyrus
Sorry, that was supposed to read "Le of the SM APDU should be 0x00". Lc is fine as it is.Michael Roland
I wouldn't expect this error in that case. Are you incrementing SSC before every MAC calculation?Michael Roland
@MichaelRoland : Yes I am incrementing the SSC before every MAC calculation.Papyrus

1 Answers

2
votes

Okay so I figured it out!! Thanks for making me create a PN532 command trace. When I combined that with the session details from my all purpose debug log, I started to write code to verify it. Half way through I realized my mistake, which was that the session keys are incorrect because I did not decrypt the entire mutual authenticate response as a 32 byte block but rather piecemeal, and since the MRTD's chip uses cipher-block-chaining the K.ICC was decrypted incorrectly, and thus my K.SEED was incorrect, ergo the session keys were wrong. I corrected that mistake and now I can read the EF.COM file!!