Search code examples
contactless-smartcardemv

How does one substitute the CVC3, ATC and unpredictable number in EMV contactless track data?


I'm trying to assemble proper track data given a CVC3 and a bunch of positional parameters. But the EMV C-2 Kernel book is about as obtuse as you could imagine (would it kill somebody to include an example!?!). Can anyone help work this example:

9f62 - pcvc3(t1)  - Position of CVC3 in track1: 0x38 (4-6?)
9f63 - punatc(t1) - Unpredictable Number Track1 Pos: 0x3C6 (2-3 7-10?)
9f64 - natc(t1)   - Digits in track1 ATC: 4
9f65 - pcvc3(t2)  - Position of CVC3 in track2: 0x38 (4-6)
9f66 - punatc(t2) - Unpredictable Number Track2 Pos: 0x3C6 (2-3 7-10?)
9f67 - Digits in track2 ATC: 4

After successful checksum generation:

9f61 - track2 CVC3 - 2EF4
9f60 - track1 CVC3 - 609B
9f36 - ATC - 1E47

assuming the discretionary data field starts out as all 0s, how does it end up? The spec says this:

Convert the binary encoded CVC3 (Track2) to the BCD encoding of the corresponding number expressed in base 10. Copy the q least significant digits of the BCD encoded CVC3 (Track2) in the eligible positions of the 'Discretionary Data' in Track 2 Data. The eligible positions are indicated by the q non-zero bits in PCVC3(Track2).

I read that as: CVC3 = 0x609B = 24731 (so copy 731? What does BCD have to do with this? Or are they just saying "copy the 731 as bcd encoded to the byte array"?)


Solution

  • yes you are correct it is rather obtuse. you are correct that you would convert your p values (pCVC3, and PUNATC) to binary. (0011 1000, 0011 1100 0110 for your track1 p values) you then right align the proper values with the discretionary data. example

    Bxxxxxxxxxxxxxxxx^ /^14111014010000000000
                 ....000000000000000000CCC000
                 ....00000000000000AAAA000UU0
    

    so you say that you CVC3 for track 1 is 609B which is 24,731, since you PCVC3 is asking for only 3 characters youd set 731 in. your ATC is 1E47 which is 7,751. your PUNATC is asking for 4 digits so you'd use 7751. FYI... if the ATC is lower than the requested characters you'd pad with 0's. Your unpredictable number is even more tricky... so you make a 4 byte random number. convert it to a uint (base 10) and then mark the 8 most significant bytes as 0. example. lets say your random 4 bytes is 29A6 06AE. in base 10 that is 698,746,542. mark out the first 8 characters with 0. and you are left with 000,000,002. you'd place 02 in for you unpredictable number placment.. so.. all that said your track would look like this

    Bxxxxxxxxxxxxxxxx^ /^14111014017751731020
    

    the last character is equal to the length of the unpredicatable number (numeric) digits. which was 02.. so the last digit is 2 making your final track data

    %Bxxxxxxxxxxxxxxxx^ /^1411014017751731022;
    

    track2 is very similar. good luck with it. I understand your frustrations with this. :)