Home |  Contact |  Guestbook |  Print Window |   RSS | 

   

     This drawing was made in Singapore in 1997. I was told that it means 'Good Fortune'. Click for the explanation.    

 

 

D2mac page

 

 

 

 

 

 

      



D2MAC page

Table of contents

1. Introduction.
1.1. The processor (PIC16C84).
1.1.1. The decoder <-> card data.
1.1.1.1. ATR (Answer To Reset).
1.1.1.1.1. TS - The initial character.
1.1.1.1.2. T0 - The format character.
1.1.1.1.3. The SendATR function.
1.1.2. The implemented instructions.
1.1.2.1. The Instruction handler.
1.1.2.2. EOL and Instruction lookup.
1.1.2.3. The A4 instruction.
1.1.2.4. The AC instruction.
1.1.2.5. The B8 instruction.
1.1.2.5.1. The Card Label.
1.1.2.5.2. The CTU900 working methode.
1.1.2.6. The GetKey function.
1.1.2.7. The 02 instruction.
1.1.2.8. The 04 instruction.
1.1.2.9. The 06 instruction.
1.1.2.10. The 24 instruction.
1.1.2.10.1. Multimac Hex.
1.1.2.10.2. Hex Multimac.
1.1.2.11. The F0 and 18 instruction.
1.1.2.11.1. Key updating example (Mode-M).
1.1.2.12. The C0 instruction.
1.1.2.13. The variable declaration.
1.1.2.14. The EEprom Read function.
1.1.2.15. The EEprom Write function.
1.1.2.16. The TogleMode function.
1.2. The assembler.

1 Introduction

I have received a request to be more clear about the beginning. If there are specific questions or sugestions please let me know, thanks.
During my holiday I spend more time on this page. I will try to make an overview how the card behaves after the Power On Reset to the part where it starts to decode.

I do not know everything about the system, but my sources are reliable, so I think that we can find an answere to it all. If you have any questions about the system, please mail me.

The last couple of years I studied a lot of PC emulators. I even wrote one myself.

Along the way I have received the standard for smartcards.ISO7816 standard (Thanks J.)

How I will publish the complete code? When you visit this site regulary, you will find a piece of the described code. Adding them together you will have the source code. when you finaly assemble the code with the assembler (mpalc.exe) found at the MicroChip's site, you will have the complete code.

1.1. The processor (PIC16C84).

I will describe the code function by function. The PIC16C84 processor is a 8 bit microcontroller. Don't worry I will not go into the details of the processor. For that you can go to MicroChip. The decoder generates the processor clock. On mostly RB7 (pin13) the bi-directional data communication with the decoder takes place. The format is 1 start bit, 8 data bits, 1 parity bit and 1 stop bit.

1.1.1. The Decoder <-> Card data.

I have received many question about, how the software works from entering the card to the actual decoding of the card. I will explain what communication takes place between the decoder and the card. I studied many logs of many decoders. The communication differes from decoder to decoder. What I will explain is how my software interpretates the data from the decoder.
During the test of several available software versions I have found that some versions put the PIC processor to sleep, waiting for a reset from the decoder. This is not working for all decoders! For instance the STU909 decoder will crash on this.

1.1.1.1. ATR (Answer To Reset).

After inserting the card into the decoder, the card power is connected and the reset of the card processor is activated by the decoder. The card will then send an ATR message to the decoder. This message holds information about the card. I found a program "atr.exe" on the net (you can download it from my tools page. However the software does not decode all ATR's as it should. The ATR I use at the moment was "stolen" from an old TVPlus card (3f 67 2f 00 11 14 00 03 68). During the preparation of making this page, I learned how to decode the information. I will give a short own interpretation of the ATR data.

TS

T0

TA1

TB1

TC1

TD1

TA2

TB2

TC2

TD2

---

T1

---

TK

TCK

TS : Initial character
T0 : Format character
TAi : Interface character [FI, DI]
TBi : Interface character [II, PI1]
TCi : Interface character [N]
TDi : Interface character Yi+1, T]
T1, .. , TK : Historical characters (max 15)
TCK : Check character.

1.1.1.1.1. TS - The initial character.

The two possible values of TS are:
  • 3Fh. Inverse convention, where all data bits are inverted and the most significant bit is send first.
  • 3Bh. Direct convention. Data bytes not inverted and the least significant bit is send first.

1.1.1.1.2. T0 - The format character.

The format character holds the parameters Y1 and K. Y1 is held in b8, b7, b6 and b5. K is held in b4, b3, b2 and b1.

Y1

K

b8

b7

b6

b5

b4

b3

b2

b1

The parameter Y1 indicates the presence of the interface characters. The parameter K indicates the number of historical characters (0..15).

1.1.1.1.3. The SendATR function.

The ATR-message is send to give the decoder information about the card.

Diagram 1: Answer To Reset Flow

The assembly code can be found in SendAtr.txt.

1.1.2. The implemented instructions.

1.1.2.1. The Instruction handler "GotIns".

The first function I will describe, is the instruction scheduler. It handles all instructions known to me. See the "GotIns" Flow. Before this function is called, the instruction is found in a table. The Pre: Icount holds the valid instruction index (1..11). For all instructions where Icount > 10 or when the data length is zero, no acknowledge will be send to the decoder. With exeption for the AC instruction. For this instruction the acknowledgement is always send even when the data length is zero. The acknowledgement means: the processor sends the instruction back to the decoder.

Diagram 2: GotIns Flow

The assembly code can be found in GotIns.txt.

1.1.2.2. EOL and Instruction lookup.

The "Complete" function will send the End Off line (EOL). This can be 9000h, normal. Or 9008h, in case of negative acknowledgement. Or 6D00, 6D08 when the instruction is not implemented.
The next step is receiving the 5 decoder bytes. These bytes will be saved in the "CLA" array. When all bytes are received, the incomming instruction will compared with the valid Instructions in the "InsTab" table. If the instruction is valid, the "GotIns" function will be handled. If the instruction is not implemented 6D0X will be send.

Diagram 3: "Complete" function Flow

The assembly code can be found in Complete.txt.

1.1.2.3. The A4 Instruction.

The A4 instruction uses the sub-instruction "A1". In this code the A1=2, A1=4 and A1=0 are decoded. The A1=0 is used for the "Zero" Entity. This identifies the card entity. After this the decoder often sends the A1=2 sub-instruction. Then the entity is increased by 1 and the next card entity is selected. (I will come to this later). The sub-instruction A1=4 is used when the decoder selects the entity of the channel to decode.

Diagram 4: "Ins A4" function Flow

In the A4_Next function when (sub-instruction A1=2) the local card entity counter is increased. Depending on the Mode where in (M-S or S2) the number of entities is compared with the maximum. For S2 the number is 4: 002b10, 002b30, 002b40 and 002b50. For the M-S channels the number is 4: 000400, 000410, 000430 and 475100. When the maximum number of the entities is reached, 9008 will be send to the decoder, otherwise 9000.

Diagram 5: "A4_Next" function flow

When the decoder wants to select an entity direct, the sub-insruction A1 is 4. In this function the program "LowNib" parameter is loaded with the actual channel Ident. Finaly the EEProm address is calculated by the function "GetKeyAddr" and saved in the "W" register.

Diagram 6: "A4_Dir" function flow

The assembly code can be found in Ins_a4.txt.

1.1.2.4. The AC Instruction.

The "AC" instruction echoes the instruction to the decoder even when the data length is zero???? Then the sub_instruction is saved in SavedA1 and it will handle the rest of the incomming data -if there is any- as in the "02" instuction.

Diagram 7: "AC_Instruction flow

The assembly code can be found in ins_ac.txt.

1.1.2.5. The B8 Instruction.

The B8 instruction uses the previous sub-instruction "A1" from the previous "ac" instruction, saved in the "Saved_A1" variable. For example :

The "a4" sub-instruction askes for the unique customer address. The length is always 5 bytes. This code will always return "03" and a negative EOL.
ca ac a4 00 00 (card answer) ac 90 00
ca b8 00 00 07 (card answer) b8 a4 05 08 08 08 08 08 90 08

The "a5" sub-instruction askes the card programme provider user address. The length is always 4 bytes. This code will always return "02" and a negative EOL.
ca ac a5 00 00 (card answer) ac 90 00
ca b8 00 00 06 (card answer) b8 a5 04 08 08 08 08 90 08

1.1.2.5.1. The Card Label

The "a7" sub-instruction askes for the card entity label(s). The number of characters may vary from 1 to 16 characters. In case of the zero entity this code return the characters "RAS NR". The rest of the characters will be "SPACE" and a postive EOL will be send.
ca ac a7 00 00 (card answer) ac 90 00
ca b8 00 00 12 (card answer) b8 a7 10 52 41 53 20 31 35 20 20 20 20 20 20 20 20 20 20 90 00
In case of the other entities this code will return "00" and a negative EOL.
ca ac a7 00 00 (card answer) ac 90 00
ca b8 00 00 12 (card answer) b8 a7 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 08
I left out the handeling of the card label. The CTU900 has problems with the response above. The present responses looks like: ca ac a7 00 00 (card answer) ac 90 00
ca b8 00 00 12 (card answer) b8 a7 10 08 08 08 08 08 08 08 08 08 08 08 08 08 08 08 08 90 08

1.1.2.5.2. The CTU900 working methode

In The "Ins_B8" function flow and ins_b8.txt both options are given. Option A for simple response and option B for the card label.

Diagram 8: "Ins_B8" function flow

The assembly code can be found in Ins_b8.txt.

1.1.2.6. The GetKey function.

The GetKey function fetches the actual key bytes from the EEProm area. The function "GetKeyAddr" returnes the actual EEProm address of the first key byte in "W". The Array k1..k7 will be filled with the 7 key bytes.

Diagram 9: "GetKey function"

The assembly code can be found in GetKey.txt.

1.1.2.7. The 02 instruction.

The code will absorb all bytes send by the decoder. When "40h" is received (according to the "John MacDonald" paper) a negative EOL must be send.
Testing the e_A1 bit will be explained later.
an example:
87 02 00 00 03 (received) 00 00 28 90 00
87 02 00 00 03 (received) 40 00 28 90 08

Diagram 10: "Ins_02" instruction flow

The assembly code can be found in ins_02.txt.

1.1.2.8. The 04 instruction.

The code will send a constant byte message "Mes_04" (see ins_04.txt).
87 04 00 00 07 (card answer) 04 00 15 00 04 10 02 ca 90 00
The bytes : 10 02 ca, are fetched from the message table of "Mes_06". Due to the efficiency of the code tables are packet together.

Diagram 11: "Ins_04" instruction flow

The assembly code can be found in ins_04.txt.

1.1.2.9. The 06 instruction.

In case of mode M or S:
87 06 00 04 (card answer) 06 10 02 ca 20 90 00

In case of mode S2:
87 06 00 04 (card answer) 06 10 02 ca 30 90 00

In the "Mes_06" table a check is done on the mode bit on EEProm address 3Fh (see ins_06.txt).

Diagram 12: "Ins_06" instruction flow

The assembly code can be found in ins_06.txt.

1.1.2.10. The 24 instruction.

The 24 instruction from the decoder sends remote requested data to the card. In this sofware I will only use the data when the subinstruction is 1 (New code). This is the case when the user updates a key. After study of many logs, it seems that the 2 bytes of MMKey send by the remote are send at the end of the message. ca a4 00 00 00 (card answer) 90 00
for example:

ca 24 01 00 10 (card answer) 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 23 22 90 00

In this example the user entered the MMkey "2322". In case of other subinstructions the received data will be absorbed.
The mode can be switched to M/S with the remote command 1117 and to S2 by the command 2227, just like MultiMac.

Diagram 13: "Ins_24" instruction flow

The assembly code can be found in ins_24.txt.

1.1.2.10.1. Multimac -> Hex.

To explain the Multimac convertion to hex format see the following table.

mm(a,b,c,d) -> hex(a,b)

mm(c) = 0

hex(a,b) = mm(a,b) - 11h

mm(c) = 1

hex(a,b) = mm(a,b) - 11h + 08h

mm(c) = 2

hex(a,b) = mm(a,b) - 11h + 80h

mm(c) = 3

hex(a,b) = mm(a,b) - 11h + 88h

For example I will convert the multimac data 2210:
The base data byte is 22h-11h=11h.
The High nible of the second byte is 1, so just add 08h to the base data 11h+08h=19h. The hex value is 19h. The key byte number is 0 (d).

1.1.2.10.2. Hex -> Multimac.

To explain the hex convertion to Multimac format see the following table.

hex(a,b) -> mm(a,b,c,d)

a<=7 AND b<=7

mm(a,b) = hex(a,b) + 11h

mm(c) = 0

a<=7 AND b> 7

mm(a,b) = hex(a,b) + 11h - 08h

mm(c) = 1

a> 7 AND b<=7

mm(a,b) = hex(a,b) + 11h - 80h

mm(c) = 2

a> 7 AND b> 7

mm(a,b) = hex(a,b) + 11h - 88h

mm(c) = 3

For example I will convert 84h to the Multimac format:
Only the high nible is greater than 7, so mm(c)=2. Then the Multimac data (a,b) will become 84h+11h-80h=15. The mm(d) value is specified by the byte number of the key bytes (0..6).

1.1.2.11. The instruction F0 and 18.

The instructions "F0" and "18" are send by the decoder when a key in the card should be updated, we will just absorb the data from the decoder.

Diagram 14: "Ins_F0 and Ins_18 flow"

The assembly code can be found in ins_F0_18.txt.

1.1.2.11.1. Key updating example (Mode-M).

Recently there was software released on the www, that did autoupdate the active and future keys of TV1000 and TV3. For auto updating you need the a management key. No, I will not give you the Management Key. After some study on that software I extracted the ManagementKey (MK) and the SharedAddress (SA) from it. I used the SA and the MK information in the program "Decrypt" from Paul Arnold. With this program I made the following log:

caa4040003 > 00 04 00 90 00
caaca50000 > 90 00
cab8000006 < a5 04 XX XX XX XX 90 08
caa4040003 > 00 04 00 90 00
caaca50000 > 90 00
cab8000006 < a5 04 XX XX XX XX 90 08
caa4040003 > 00 04 00 90 00
caf000YY22 > 9e 20 a6 de 48 b3 fb db b5 7f 0b 5f 73 4e 3d f6 df 1b bf 63 65 ff ef eb b3 fb bf bf de d2 47 77 ff fe 90 00
ca1801YY19 > a1 03 00 0I Ic
> ef 08 d3 32 db d7 6c f1 5c 16
> f0 08 56 a9 2d 14 ca bd e9 32
> 90 00

Updated Viasat key 0c...
Using Viasat key YY

The XX bytes form the SA address. The YY byte is the MK index. The "ca1801YY19" message explained:
18 = instruction.
01 = addressed to shared group of customers.
YY = Managementkey in use.

The decoder sends the message "a1 03 00 0I Ic", where II is the id of the channel and C the key that is updated.
The next important 8 bytes data bytes are the 8 bytes "d3 32 db d7 6c f1 5c 16". These 8 bytes hold the new encrypted key 0Ch.

I used the information in (Paul Arnold's) program "Find_Des" to check if the MK I had extracted was correct, and it was.

If you have the MK you can fill in the 7 bytes (MM) after "key=". If you are looking for the MK you should fill in a random number (not all zero).

The 8 bytes (d3 32....) from the "ca 18" message should be placed after the "data_88=" part.

Now we fill in the uploaded key 0Ch of 7 bytes at the "data_c0" part. But this key is only 7 bytes long? Just use 00h as the 8th byte.

The mode is M, so the destype=0.

# Data file for FIND_DES
#
# Format is:
#
# key=nnnnnnnnnnnnnn
# data_88=nnnnnnnnnnnnnnnn
# data_c0=nnnnnnnnnnnnnnnn
# destype=n
#
# Where
# Key = The 7 byte encryption key
# data_88 = 8 bytes of data from D2MAC command ca 88
# data_c0 = 8 bytes of data from D2MAC command ca c0
# Destype = DES encryption type: 0 for Eurocrypt-M, 1 Eurocrypt-S2
#
# Default for Destype is Eurocrypt-M
#
key=MMMMMMMMMMMMMM
data_88=d332dbd76cf15c16
data_c0=e9f33436b0bbf800
destype=00

1.1.2.12. The C0 instruction.

The C0 instruction has several functions. The first function it has at start up is sending entity information to the decoder. The other is one of the most important, sending the decoded data to the decoder.
When the decoder asked length (e_LEN) is less than 16 bytes I assume that the decoder askes for the the entities. The software will then send Entities of all channels that can be decoded in the active Mode.
Along the way I got some information about a multi channel card. He told me that at Entity 0 the "Multi" message should be send. In both MS and S2 mode.
In the M/S Mode all "MSEntities" will be send. In the S2 Mode the S2Entities will be send. The function is clear "Hack work". This is the only way when you want to keep the code compact.
When the asked length (e_LEN) is 16 bytes, then I asume that the decoded bytes are asked by the decoder. These bytes are stored in the "ECWO" array. With the data pointer register "FSR"

Diagram 15: "Ins_C0 flow"

The MS_Entity is selected from the MS_IDTable. The entity which is increased by the next A4 instruction will select the Entity. When more bytes are asked, bytes from message 5 will be send, just dump bytes.

Diagram 16: "MS_Entities"

The S2_Entity is selected from the S2_IDTable. The entity which is increased by the next A4 instruction will select the Entity. When more bytes are asked, bytes from message 5 will be send, just dump bytes.

Diagram 17: "S2_Entities"

The assembly code can be found in Ins_C0.txt.

1.1.2.13. The variable declaration.

In this part all constants and variables of the software can be found. The assembly code can be found in Variables.txt.

1.1.2.14. The EEprom Read function.

This function reads a byte from the internal PIC EEProm on the address "EEADR". The "Mode bit" can be read from the EEProm at address 3Fh.

Diagram 18: "The EEProm read Flow"

The assembly code can be found in EE_Read_3Fh.txt.

1.1.2.15. The EEprom Write function.

This function writes a byte to the EEProm.

Diagram 19: "The EEProm write Flow"

The assembly code can be found in EE_Write.txt.

1.1.2.16. The TogleMode function.

This function will Togle the mode, if the configuration bit 6 is set. The configuration bit and the mode bit are stored in the EEProm at address 3Fh. When bit 0 is set the mode is M/S. When it is clear the mode is S2. When bit 6 is set, the mode bit will be toggled and saved in the EEProm at every Power On Reset. This can be very annoying when the decoder is switched on by it's timer. In that case the mode switch should be done by remote.

Diagram 20: "The TogleMode Flow"

The assembly code can be found in TogleMode.txt.

1.2. The assembler.

When all the assembly code is published you can add it together and assemble it with mpalc.zip.

 

 

 

 

Last updated:

 Copyright 2006-2016 ronaldsnoeck.com |  Disclaimer |  Privacy