Jump to content
Sign in to follow this  
Guest Kcplus

Seca algo

Recommended Posts

Guest Kcplus

Wie weet er meer over het seca algorithme?

 

Goed, de vraag blijft hoe lang we er nog iets aan hebben, maar het leek mij toch leuk te weten hoe het in elkaar steekt.

 

Dus eindelijk ruim twee jaar na het downloaden heb ik mij er maar aan gewaagd:

ik ben de Media1.doc van John MacDonald (Mediaguard Musings) gaan bestuderen. Ook de excel-sheet "Seca.xls", welke op het www te vinden is, heb ik uitgeplozen.

 

Hoewel ik denk de in de .xls uitgewerkte algo te begrijpen en daadwerkelijk meen dat de daarin neergezette algo overeenkomt met de .doc kom ik niet op de gewenste resultaten.

 

Een CW decrypten leidt nimmer tot het resultaat dat die mooie proggies als MKF voor mij berekenen.

 

Is er iemand, die e.e.a. al eerder bestudeerd heeft en wel tot resultaat is gekomen, die mij op weg wil helpen?

 

Of wil iemand samen met mij deze slag aan?

Share this post


Link to post
Guest Kcplus

De posting wordt wel gelezen......

 

dus:

 

- of het onderwerp is niet interessant :confused: ;

- of ik ben de enige sathobbyist die het algo nog steeds niet kent :rolleyes: ;

- of we hebben het allemaal te "druk" met andere zaken :D ;

- of de echte cracks denken: "zoek het even lekker zelf uit!" :P ;

- of het is echt te moeilijk, dus waar ben ik aan begonnen :(

- of .......................... :eek:

 

Ik ga dus maar gewoon door, en meld mijzelf "ooit" wel met de oplossing.........

hoop ik.........

toch?

 

snif

Share this post


Link to post
Guest petertje

Het probleem is dat je wel enigszins wiskundig onderlegd moet zijn voor deze materie. iets wat bij mij volledig ontbreekt dus.

Ooit ben ik er ook, niet gehinderd door enige vorm van kennis aan begonnen, maar door tijdgebrek, gebrek aan inzicht weer mee gestopt.

Of je er verder echt zo weinig aan zult hebben ?

het seca II algo zal echt niet teveel verschillen van de seca I, hoogstens zijn de hash tabellen anders.

ik kan je dan ook alleen maar succes wensen, en hopen dat je je kennis ooit nog eens kan aanwenden in een leuk programmatje voor een funkaartje ofzo :-)

 

Peter

Share this post


Link to post
satelliet

Nee, eenvoudig is het niet.

Ik heb verscheidene sources bestudeerd zowel van seca als van viaccess. Ik ben nooit verder gekomen als de locatie te vinden waar de providers in vermeld zitten met hun benaming, alsook heb ik het controle systeem kunnen uitdokteren, dit is gewoon een soort optelsom.

Ik ben spijtig genoeg geen programmeur en heb moeten afhaken. Je moet immers zéér goed assembler kennen.

Share this post


Link to post
Guest alexje

Hoi kc+ ben je FAQ van Roland von Gilead al eens tegengekomen? vind ik de duidelijkste die er is.

 

als je wilt mail ik de duits/engels talige wel naar je toe.

 

suc6 met de hobby

Share this post


Link to post
Guest Kcplus

@alexje

Of ik de faq van RvG wel eens ben tegengekomen? Man, ik ken dat ding bijna helemaal uit mijn hoofd ;) :D .

 

@ petertje

@ satelliet

Zoals gezegd heb ik destijds de seca.xls en de doc van John MacDonald gedownload. Toentertijd zag dat er uit als "abacadabra".

Ook ik ben wel eens een source tegengekomen van een seca.hex, maar daar begreep ik weinig tot niets van: geen enkele kennis van progammeren dus.....

Sinds ik van het secasysteem het een en ander weet (RvG-faq!) biedt een seca log of een gemiddelde -Ins nauwelijks meer geheimen.

Het werd dus tijd voor meer diepgang in de hobby.

Dus de seca.xls van stal gehaald.

 

Ik moet zeggen: ik heb daar inmiddels veel kennis uitgehaald met betrekking tot bits en bytes, de samenhang tussen decimale en hexadecimale notatie, de xor-bewerking en andere zaken.

De doc geeft dus inzicht in hoe de seca-algo zou moeten werken, en de xls zet de rekenkundige bewerkingen in een meer helder en praktisch daglicht. Echter: de uitkomsten stroken niet met die van de seca-proggies.

Maar wie weet doe ik hier dus iets geheel fout........

 

Ik ben nu bezig de algo geheel opnieuw "na te bouwen" in Quattro Pro (de spreadsheet van Corel/Wordperfect) omdat de hexadecimale bewerkingen daar n.m.m. eenvoudiger kunnen worden vormgegeven. Tot nu toe zijn de uitkomsten identiek aan die van de excel-sheet. Wie weet kom ik de "kink in de kabel" nu wel toevallig tegen.

 

Een andere mogelijke oplossing is een asm-file eens te vergelijken met de in de spreadsheet uitgewerkte algo. Ook hierbij moeten de verschillen in bewerkingen duidelijk kunnen worden.

 

Bedankt voor jullie reacties.

Ik ben blij dat ik niet de enige ben die het algorithme interessant vindt ;)

Wij zoeken verder................

Share this post


Link to post
Guest Kcplus

Zou het dan toch onbegonnen werk zijn........?

 

Ik heb de seca.xls helemaal nagebouwd in quattropro. Helaas, alle uitkomsten zijn exact gelijk.

Het verhaal is echter wel meer "leesbaar" geworden. Alle binaire notaties heb ik vervangen door hexadecimale en dat leest ff makkelijker.

De oplossing heeft het echter niet gebracht.

 

Een secanix-source zou de oplossing moeten bieden, maar ik moet beamen: die assembler leest wel, maar niet makkelijk ;) .

 

Ik heb mij geconcentreerd op de verwerking van een Ins C1 3C.

Wat ik erg verhelderend vond (denk ik althans ;) ) was in te zien hoe de cam en de card met elkaar communiceren, en welke acties er nu precies in de eepromdata en het RAM plaatsvinden.

 

Het proggie Picachu (met windows voor RAM en Eedata) was mij daarbij ook behulpzaam. Deze soft emuleert (en logt) d.m.v. werkende hexfiles. Ik ben er echter nog niet achter hoe ik met dat proggie alle stappen van het decoderingsproces kan doorlopen. Ik denk dat helaas alleen de "grote" stappen daarmee zichtbaar worden.

 

Het grootste gedeelte van de decrypt-procedure snap ik ook, en leidt niet tot nieuwe inzichten. Laten nu net die gedeelten die gaan over de be- en verwerking van het CW gedeeltelijk onduidelijk blijven.....

 

Met name waar het gaat over de "swap_nibbles" heb ik niet het idee gekregen dat dat overeenstemt met de Media1.doc maar dat zal ik wel mis hebben.

 

Wie leest er (een beetje) assembler en wil mij helpen?

Anders blijft er voor mij niets anders over het geheel weer twee jaar te laten liggen :D .

Share this post


Link to post
Guest FranX

PIC assembler kan ik wel aardig lezen, verder is de rekenkundige kracht van een PIC erg gering, met een beetje basic (N)AND (N)OR

XOR etc kennis kom je een heel eind.

 

Het enige verwarrende kan misschien zijn dat de decrypt routine uit de externe eeprom de hash table leest, en dat gebeurt via I2C

gelukkig wel byte voor byte, maar met goed meetellen kom je een heel eind...:)

 

Post de assembler evt. hier, dan hebben anderen er ook nog wat aan..

 

Grtz FranX

Share this post


Link to post
Guest alexje

hier de secanix assem. voor de liefhebbers.

 

; Version 44.2G

; 2000, November 26

 

; Supports:

; autoupdate

; remote update

; superencription

; LED flashing on CAM comms

; LED set on keys/subscription date update

 

;------------------------------------------------------------------------------------

;

; PIC 16F84/16C84

; _______ _______

; | \/ |

; LED GREEN__RA2 --+ 1 << >> 18 +-- RA1__YELLOW LED

; | |

; LED GREEN2__RA3 --+ 2 >> 17 +-- RA0__RED LED

; | |

; not used__rtcc --+ 3 << 16 +-- OSC1/CLKIN__from CAM (CLOCK)

; | |

; from CAM__MCLR --+ 4 >> 15 +-- OSC2/CLKOUT__not used

; | |

; from CAM__Vss --+ 5 >> << 14 +-- Vdd__from CAM

; | |

; not used__RB0 --+ 6 <> 13 +-- RB7__from /to CAM (data)

; | |

; not used__RB1 --+ 7 << 12 +-- RB6__from CAM (CLOCK)

; | |

; not used__RB2 --+ 8 >> 11 +-- RB5__SCLK to EEprom

; | |

; not used__RB3 --+ 9 <> 10 +-- RB4__SDAta from / to EEprom

; | |

; +----------------+

;

; ">>" and "<<" indicate connected pins.

;

;------------------------------------------------------------------------------------

;

; 24C16/24LC16

; _______ _______

; | \/ |

; Gnd__A0 --+ 1 << 8 +-- VCC (2.5-5.5 24LCXX / 4.75-5.25 24CXX)

; | |

; Gnd__A1 --+ 2 << 7 +-- Write Protection__Gnd

; | |

; Gnd__A2 --+ 3 << 6 +-- SCLK__Serial Clock (max 400 Khz)

; | |

; GND --+ 4 >> <> 5 +-- SDA__Serial Data input/Output

; | |

; +----------------+

;

; Signal Condition

; SCLK ___|---|___|---|___|---|___|---|___|---|___|---|___|---|___|---|__

; SDA ====>-<=====>-<=====>-<=====>-<=====>-<=====>-<=====>-<=====>-<===

;

; Data Transfer

; S = Start Bit

; 1 = hight level logic

; 0 = low level logic

; B = Block Address

; C = Address

; D = Data

; X = dont care

; R = 1Read 0Write

; A = ACK (0 level)

; N = NO ACK (1 level)

; P = Stop Bit

;

; ---Control byte---- ---Address byte-- ---Data byte-----

; | | | | | |

; 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2

; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

; | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

; Byte Write S 1 0 1 0 B B B R A B B B B B B B B A D D D D D D D D A P

;

; ---Control byte---- ---Address byte-- ---Data byte----- ---Data byte-----

; | | | | | | | |

; 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 ---- n n n

; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ---- 1 2 3

; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ---- | | |

; Page Write S 1 0 1 0 B B B R A B B B B B B B B A D D D D D D D D A D D D D D D D D A D D D ---- D A P

; 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 15

;

; ---Control byte---- ---Data byte-----

; | | | |

; 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2

; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0

; | | | | | | | | | | | | | | | | | | | |

; Byte Read S 1 0 1 0 B B B R A D D D D D D D D N P

;

; ---Control byte---- ---Address byte-- ---Control byte---- ---Data byte-----

; | | | | | | | |

; 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3

; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

; Byte Read Add S 1 0 1 0 B B B R A B B B B B B B B A S 1 0 1 0 B B B R A D D D D D D D D N P

;

; ---Control byte---- ---Data byte----- ---Data byte----- ---Data byte-----

; | | | | | | | |

; 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 ---- n n n

; 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 ---- 1 2 3

; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ---- | | |

; Seque. Read S 1 0 1 0 B B B R A D D D D D D D D A D D D D D D D D A D D D D D D D D A ---- D N P

; 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 X

;

;------------------------------------------------------------------------------------

 

LIST P=16F84, F=INHX8M

include "P16F84.inc"

errorlevel 1,-224,-302

 

;******************************************************

 

constant LED=1 ; <===

 

;******************************************************

 

constant T_SERIAL = 0x1A ; 0x1B for Kenwood

constant T_SEND_START = 0x32

constant T_SEND_STOP = 0x4F

constant T_RECEIV_START = 0x2A

constant T_RECEIV_STOP = 0x28

 

; LED policy:

; Green is turned on by start of comms from/to CAM, and it is turned off by end of comms from/to CAM

; Yellow is turned on by Ins 1a and 5a, and it is turned off by Ins 3c

; Red is turned on by key and subscription updates

; Green2 is not used by now

; Yellow, Red and Green2 are turned off by entering PIN menu or by entering 0000 as PIN

 

IF LED

constant LED_RED = 0 ; Red LED (RA0)

constant LED_YELLOW = 1 ; Yellow LED (RA1)

constant LED_GREEN = 2 ; Green LED (RA2)

constant LED_GREEN2 = 3 ; Green2 LED (RA3)

ENDIF

 

;******************************************************

 

ORG 0x0000

 

CALL Std_pause ; Returns W=0

 

; The following is obsolete, but more compact

TRIS PORTA ; Define PORT as all output

 

IF LED ;

MOVWF PORTA ; Init LED ports (RA0,1,2,3)

BSF PORTA,LED_GREEN2 ;\

BSF PORTA,LED_RED ; LED check

BSF PORTA,LED_YELLOW ; start

ENDIF ;/

 

ADDLW 0x7F ; Load OPTION register with 0x7f (PORT B pull-ups enabled)

OPTION

; Code above should be written instead as

; BSF STATUS,RP0 ; Select bank 1

; MOVWF TRISA ; Define PORT A as all output

; IF LED ;\

; MOVWF PORTA ; Init LED ports (RA0,1)

; ENDIF ;/

; BCF OPTION_REG, NOT_RBPU ;PORT B pull-ups enabled, OPTION_REG is set to 0XFF on all resets

; BCF STATUS,RP0 ; Select bank 0

 

; Read the ATR bytes stored in the pic eeprom in reverse order, starting from position 0x0E down to

; position 0x01, 14 bytes total

 

MOVLW 0x0E ; ATR end address

MOVWF 0x10 ; Internal eeprom pointer

 

ATR_loop MOVF 0x10,W ;\

CALL Rd_eeprom ;

CALL Send ; ATR

DECFSZ 0x10,f ;

GOTO ATR_loop ;/

 

IF LED ;\

MOVWF PORTA ; \

BCF PORTA,LED_GREEN2 ; LED check

BCF PORTA,LED_RED ; stop

BCF PORTA,LED_YELLOW ; /

ENDIF ;/

 

; Send status bytes 9000, end of response with no error, or 900D when an error is simulated

; If bit 3 of PCLATH has value 1 then a 901D is sent, else 9000 is sent

; Status bytes 901D are sent on reception of a C1 40 command which does not contain keys

; since this reduces the message traffic between cam and card

 

TX9000 MOVLW 0x90

TX00_1D CALL Send

MOVLW 0x00 ; 9000

BTFSC PCLATH,0x03 ; (use of bits 3:4 of PCLATH is discouraged)

MOVLW 0x1D ; 901D

CALL Send

CLRF PCLATH ; Reset PCLATH

 

; Wait for and receive the first byte of the command (C1)

; THIS CALLS THE MAIN LOOP

CALL Receive ; Get class byte (SECA: C1), discard it

; Read the remaining 4 bytes from the command header and put

; them into RAM starting from RAM position 0x0C,

; that is

; 0x0C: Instruction byte

; 0x0D: P1

; 0x0E: P2

; 0x0F: Length

 

MOVLW 0x0C ; Initialize pointer

MOVWF FSR ; to RAM

 

Com_loop CALL Receive ; Read 1 byte

MOVWF INDF ; store it into RAM

MOVWF 0x10 ; store it into 0x10 also

INCF FSR,f ; Increment pointer to next RAM location

BTFSS FSR,0x04 ; is 0x1F pointed?

GOTO Com_loop ; no, repeat

; yes, the last stored value was in RAM location 0x0F

 

; The instruction to be processed is in RAM position 0x0C, while the list of valid

; instructions is stored in a table in the internal EEPROM starting from position 0x0E

; it contains 0x0E commands in this version

 

MOVLW 0x0E ; We have 0x0E instructions

MOVWF 0x11 ; instructions counter

Comm_scan MOVF 0x11,W

ADDLW 0x0E ; Offset wrt internal EEPROM

CALL Rd_eeprom ; Read an instruction

XORWF 0x0C,W

BTFSC STATUS,Z ; if this is the received instruction

GOTO Send_ack ; then jump to process it

DECFSZ 0x11,f ;\ else decrement the instructions counter

GOTO Comm_scan ;/ and look down in the instruction table

MOVLW 0x6D ; If the received instruction is not found, return 6D00

GOTO TX00_1D

 

Send_ack MOVF 0x0C,W ;\ ACK (echo of instruction byte in 0x0C)

CALL Send ;/

MOVF 0x11,W ; 0x11 contains the instruction index in the EEPROM table

 

; The following has been modified to be position independent

; ADDLW 0x2B ; (2B was the MOVVWF address, substitute to 2B the correct MOVWF address)

ADDLW Tab_instr ; Add the instruction index to the Tab_instr label address

 

; In the following a table is contained which corresponds to the instructions table

; stored in the internal EEPROM, i.e. in the same order

; The program counter is then set to the same offset in this table as the received instruction

; in the instruction table

 

Tab_instr MOVWF PCL ; Jump to the GOTO which actually processes the command

 

GOTO Instr_0A ; Operating system version

GOTO Instr_0E ; Serial number

GOTO Instr_16 ; Number of providers

GOTO Instr_12 ; Provider ID (ident)

GOTO Instr_34 ; Data request specification

GOTO Instr_32 ; Data request

GOTO Instr_22 ; Key update ?

GOTO Instr_30 ; PIN protected transaction

GOTO Instr_21 ; External EEPROM read ?

GOTO Instr_3A ; ECM decoding control word

GOTO Instr_3C ; ECM coding control word

GOTO Instr_40 ; EMM subscription management

GOTO Instr_1A ; Key index selection

GOTO Instr_5A ; CipherText selection

 

; Not supported yet:

; 3E key request

; 68 CSD attack (seems it probes ID 13,14,15)

 

;=======================================================================

; C1 INSTRUCTION PROCESSING

;=======================================================================

 

;*************************************************

; function : 5A C1 CLASS instruction *

; CipherText selection *

;*************************************************

; The (P2+1) values for instr. 5a are stored in a table in the internal EEPROM

; starting at offset 0x30 (this table is indexed by the P1 value)

; The number of bytes to be returned is contained in the register file 0x10

; (copy of 0x0F, command length parameter)

 

Instr_5A

IF LED ;\

BSF PORTA,LED_YELLOW ; Yellow LED on

ENDIF ;/

 

INCF 0x0E,f ; Increment P2 by one

MOVF 0x0D,W ; Load P1 value (0-15) in W

ADDLW 0x30 ; Add table start address to W

CALL Rd_eeprom ; Read the value indexed by P1 from the table

ANDWF 0x0E,W ;\ If ((P2+1) and (value read from 5a answer table))=0

BTFSS STATUS, Z ; then 9000 will be returned as status bytes at end of response

BSF PCLATH,0x03 ;/ else 901D

MOVLW 0xFF ;\ Transmit as many 0xFF as stored in file register 0x10

GOTO send_w_fill ;/ followed by the status bytes

 

;*************************************************

; function : 0E C1 CLASS instruction *

; request smartcard serial number *

; command : C1 0E 00 00 08 *

; answer : 0E 00 03 00 00 00 CA 13 66 90 00 *

; i.e. region is 03, UA is 00 00 00 CA 13 66 *

; It corresponds to serial number 013.243.238 *

;*************************************************

; Instr. 0E: send the byte sequence stored from offset 0x00 in the external EEPROM

; The number of bytes to be sent was stored in file register 0x0F (it should be 8)

 

Instr_0E MOVLW 0x00 ; Offset in the external EEPROM

COMM_EEPR CALL EEPROM_send ; Transmit data from external EEPROM

GOTO TX9000 ; Transmit status bytes

 

;*************************************************

; function : 0A C1 CLASS instruction *

;*************************************************

; Instr. 0A: send the byte sequence stored from offset 0x1BB to offset 0x1FF in the external EEPROM

 

Instr_0A INCF PCLATH,f ; Offset in the external EEPROM, high byte, page 1 (i.e. set PCLATH to 1)

MOVLW 0xBB ; Offset in the external EEPROM, low byte

GOTO COMM_EEPR ; Transmit answer

 

;*************************************************

; function : 1A C1 CLASS instruction *

;*************************************************

; Instr. 1A: send the byte sequence stored from offset 0x1A6 to offset 0x1BA in the external EEPROM

 

Instr_1A

IF LED ;\

BSF PORTA,LED_YELLOW ; Yellow LED on

ENDIF ;/

 

INCF PCLATH,f ; Offset in the external EEPROM, high byte, page 1 (i.e. set PCLATH to 1)

MOVLW 0xA6 ; Offset in the external EEPROM, low byte

GOTO COMM_EEPR ; Transmit answer

 

;*************************************************

; function : 16 C1 CLASS instruction *

; ENTITIES SUPPORTED *

;*************************************************

; Instr. 16: send the byte sequence stored from offset 0x08 in the external EEPROM

 

Instr_16 MOVLW 0x08 ; Offset in the external EEPROM

GOTO COMM_EEPR ; Transmit answer

 

;*************************************************

; function : 12 C1 CLASS instruction *

; this instruction requests an ID CAM *

; command : C1 12 aa 00 18 *

; aa is the ID provider *

; answer : 12 ii ii bb bb bb bb bb bb bb bb bb *

; bb bb bb bb bb bb bb 00 xx xx xx zz *

; zz 90 00 *

; ii ii : provider channel *

; bb..bb : provider name *

; xx..xx : smartcard address (PPUA) * *

; zz zz : termination date ( 7 bits year since *

; 1990 + 4 bits month + 5 bits day ) *

;*************************************************

; Instr. 12: file register 0x0D contains P1, i.e. the provider ID

; W is initialized by -8 (0xF8) and each loop iteration increments W by 0x18 which is the

; length of the ID CAM for each provider. Since the loop starts by incrementing W, the first provider

; data (P1=0) are stored from offset 0x18-0x08=0x10 in the external EEPROM. Moreover a check is provided

; to increment PCLATH when the external EEPROM offset 0x100 has to be reached. Than at the end of the loop

; PCLATH contains the high byte for the external EEPROM address to be read and W the low byte

 

Instr_12 MOVLW 0xF8 ; Initialize offset in the external EEPROM to -8

INCF 0x0D,f ; P1 + 1 loop iterations, since 1st provider corresponds to P1=0

 

instr_12_loop

ADDLW 0x18 ; ID CAM length

BTFSC STATUS,Z ;\ If 0x100 has been reached

INCF PCLATH,f ;/ then increment PCLATH (i.e. set PCLATH to 1)

DECFSZ 0x0D,f ;\ Loop until the provider specified by P1 is reached

GOTO instr_12_loop ;/

 

GOTO COMM_EEPR ; Transmit answer

 

;*************************************************

; function : 3C C1 CLASS instruction *

; ENTITLEMENT CONTROL MESSAGE *

;*************************************************

; command :

; C1

; 3C ; command

; 04 ; 4-th provider on the card

; 0C ; key 0C

; 27 ; 27H bytes long

; answer:

; 3C ; ACK

; 71 00 ; unknown

; 00 10 ; provider

; 07 D0 ; year

; 00 08 ; month

; 27 ; separator

; 15 0C ; complete data

; 13 21 ; boundle

; [D1] ; marker

; EF 44 F8 57 15 A0 A0 A6 ; control word 1

; D0 11 1C 81 87 6E 24 8E ; control word 2

; 82 ; separator

; 23 C0 DF FB 10 19 62 DB ; signature

; 90 00 ; status bytes

;

; This instruction sends encrypted control words to be decrypted

; First GET_CW_loop is called. That routine receives the remaining part of the command,

; reads the 16 bytes key from the external EEPROM according to P1 and P2, and in case of

; superencription it implements the first decription

 

Instr_3C

IF LED ;\

BCF PORTA,LED_YELLOW ; Yellow LED off

ENDIF ;/

 

CALL GET_CW_loop ;

 

; The routine swap_eedat swaps an 8-bytes block with another

; W has to contain the st block starting position and EEADR the offset of the 1st block wrt the 2nd

; In 0x14 GET_CW_loop has stored the first free position following the command just received

 

; Swap the block starting 0x11 bytes before the last byte with the one starting at 0x0C

MOVF 0x14,W ;\

SUBLW 0x1D ; 1st block offset wrt 2nd block (0x1D is used as offset since it is 0x11+0x0C)

MOVWF EEADR ;/

MOVLW 0x0C ; First block start

CALL swap_eedat ; Swap blocks

; Load into 2nd encrypted word position

CALL swap_2C_38 ; Swap bytes 0x0C-0x13 with 0x38-0x3F

 

; Swap the block starting 0x19 bytes before the last byte with the one starting at 0x0C

MOVF 0x14,W ;\

SUBLW 0x25 ; 1st block offset wrt 2nd block (0x25 is used as offset since it is 0x19+0x0C)

MOVWF EEADR ;/

MOVLW 0x0C ; First block start

CALL swap_eedat ; Swap blocks

; Load into 1st encrypted word position

CALL swap_24_30 ; Swap bytes 0x0C-0x13 with 0x30-0x37

 

; Decrypt the two control words

CALL Decrypt ; Decrypt 1st word

CALL swap_F8_30 ; Swap 1st and 2nd word (0x30-0x37 with 0x38-0x3F)

CALL Decrypt ; Decrypt 2nd word

CALL swap_F8_30 ; Swap words again

 

GOTO TX9000 ; That's all, transmit status bytes

 

;-----------------------------------------------------------------------

 

GET_CW_loop MOVLW 0x31 ;\

SUBWF 0x10,W ; If the command contains at most 0x31 bytes (in 0x10 was a copy of the length parameter)

BTFSS STATUS,C ;/

GOTO store18 ; then start storing it from RAM position 0x18

MOVLW 0x08 ;\

SUBWF 0x10,f ; else decrease length by 8

MOVWF 0x0F ; and receive and discard 8 bytes

CALL Rec_skip ;/

GOTO GET_CW_loop ; Repeat until at most 0x31 bytes are left to receive

 

store18 MOVLW 0x18 ;\ Store the remaining part of the command

MOVWF FSR ;/ starting from RAM position 0x18 (at most 0x31 bytes)

 

store18_loop

CALL Receive ; Receive 1 byte

MOVWF INDF ; store it

INCF FSR,f ; Increment pointer

DECFSZ 0x10,f ;\ until the number of bytes contained in 0x10 is received

GOTO store18_loop ;/

 

MOVF FSR,W ;\ Save in 0x14 the pointer to the next free position

MOVWF 0x14 ;/ following the command just received

CALL kaddress ; Compute the external EEPROM address for the key to be used

 

; Since the maximum stored portion of a command starting from offset 0x18 is 0x31 bytes,

; then keys loaded starting from offset 0x40 can overwrite at most the last 9 bytes of the

; stored command (bytes 0x40-0x48), but they are not needed since they contain nano 0x82 (1 byte)

; followed by the signature (8 bytes)

; So 0x40 is the lowest safe RAM position for loading keys

 

MOVLW 0x40 ;\ Load keys into RAM starting from offset 0x40

MOVWF FSR ;/

CALL Get_key_10 ; Read 8 bytes key from external EEPROM

MOVLW 0x40 ;\ If a secundary key is used

BTFSC 0x0D,03 ; then read it from external EEPROM 0x40 bytes forward

ADDWF 0x10,f ;/ that is from the next provider

CALL Get_key_10 ; Either read secundary key or re-read the same key as above

BTFSS PCLATH,04 ;\ If no superencription

GOTO cw_return ;/ then return, else decrypt the entire command stored from 0x18

MOVLW 0x18 ;\ Swap 0x30-0x37 with 0x18-0x1F

CALL swap_xx_30 ;/

CALL Decrypt ; Decrypt

MOVLW 0x18 ;\ Swap 0x30-0x37 with 0x18-0x1F

CALL swap_xx_30 ;/

MOVLW 0x10 ;\ Swap 0x30-0x37 with 0x20-0x27

CALL swap_xx_30 ;/

CALL Decrypt ; Decrypt

MOVLW 0x10 ;\ Swap 0x30-0x37 with 0x20-0x27

CALL swap_xx_30 ;/

MOVLW 0x08 ;\ Swap 0x30-0x37 with 0x28-0x2F

CALL swap_xx_30 ;/

CALL Decrypt ; Decrypt

MOVLW 0x08 ;\ Swap 0x30-0x37 with 0x28-0x2F

CALL swap_xx_30 ;/

CALL swap_F8_30_encr; Swap 0x30-0x37 with 0x38-0x3F and decrypt

swap_F8_30_encr

CALL swap_F8_30 ; Once again

CALL Decrypt

cw_return RETURN

 

; Swap the block 0x30-0x37 with 0x38-0x3f

swap_F8_30 MOVLW 0xF8 ; Load -8 into W

; Swap the block 0x30-0x37 with the 8 bytes block starting at 0x30 minus W

swap_xx_30 MOVWF EEADR ; 1st 8-bytes block offset wrt 2-nd block should be loaded into EEADR

MOVLW 0x30 ; 1st 8-bytes block starting address should be loaded into W

CALL swap_eedat ; Swap the 8 bytes block starting at W with the 8 bytes block starting at W minus EEADR

RETURN

 

; SECA decription routine

; 0x0F points to the key element which is being processed (0x00..0x0F)

; 0c0D is the "C" constant

 

Decrypt CLRF 0x0F

MOVLW 0x02 ;\ Set PCLATH to 2

MOVWF PCLATH ;/ since SECA table 1 starts at offset 0x200

CLRF 0x0D

 

; Key preparation

 

keyprep_loop

CALL kbprep ; Set K=K XOR T1[K[i-1] XOR K[i+1] XOR C] (i is the value in 0x0F)

INCF 0x0F,f ; i=i+1

MOVF 0x0F,W ;\

ANDLW 0x03 ; Every 4 loop iterations the constant "C" is incremented

BTFSC STATUS,Z ;

INCF 0x0D,f ;/

BTFSS 0x0F,0x06 ;\ 64 iterations

GOTO keyprep_loop ;/

 

; Step 1: XOR key bytes with data bytes. Also set initial lookups for Step 2

 

MOVLW 0x0F ;\ Constant "C" is initially set to the value 0x0F

MOVWF 0x0D ;/

MOVLW 0x0C ;\ i=13 (13th key element)

MOVWF 0x0F ;/ so the index in 0..15 (0x00...0xFF) is 12 (0x0C)

keydata_loop

CALL kbget_0f ; Read K and store it into W

XORWF 0x34,W ; W=d[4] XOR K

CALL Get_tab1

MOVWF 0x10 ; [0x10]=T1[d[4] XOR K]

CALL kbget_0f_p1 ; Read K[i+1] and store it into W

XORWF 0x35,W ; W=d[5] XOR K[i+1]

CALL Get_tab1

MOVWF 0x11 ; [0x11]=T1[d[5] XOR K[i+1]]

CALL kbget_0f_p1 ; Read K[i+2] and store it into W

XORWF 0x36,W ; W=d[6] XOR K[i+2]

CALL Get_tab1

MOVWF 0x12 ; [0x12]=T1[d[6] XOR K[i+2]]

CALL kbget_0f_p1 ; Read K[i+3] and store it into W

XORWF 0x37,W ; W=d[7] XOR K[i+3]

CALL Get_tab1

MOVWF 0x13 ; [0x13]=T1[d[7] XOR K[i+3]]

 

; Step 2: core function. The step (T1 table lookup) has been performed in the previous step

; The new values for d[4]..d[7] are stored in 0x10..0x13

; At the end of Step 1 W contains d[7]

 

INCF PCLATH,f ; PCLATH=3, block address of T2 in the external EEPROM is 3 (offset 0x300)

 

XORWF 0x10,f ; d[4]=d[4] XOR d[7]

SWAPF 0x13,W ; Swap nibbles in d[7]

ADDWF 0x12,W ; W=~d[7]+d[6]

CALL Get_tab2 ; W=T2[W]

MOVWF 0x12 ; d[6]=T2[~d[7]+d[6]]

XORWF 0x13,f ; d[7]=d[7] XOR d[6]

SWAPF 0x12,W ; Swap nibbles in d[6]

ADDWF 0x11,W ; W=~d[6]+d[5]

CALL Get_tab2 ; W=T2[W]

MOVWF 0x11 ; d[5]=T2[~d[6]+d[5]]

XORWF 0x12,f ; d[6]=d[6] XOR d[5]

SWAPF 0x11,W ; Swap nibbles in d[5]

ADDWF 0x10,W ; W=~d[5]+d[4]

CALL Get_tab2 ; W=T2[W]

MOVWF 0x10 ; d[4]=T2[~d[5]+d[4]]

 

DECF PCLATH,f ; PCLATH=2, SECA table 1 starts at offset 0x200

 

XORWF 0x11,f ; d[5]=d[5] XOR d[4]

SWAPF 0x10,W ; Swap nibbles in d[4]

ADDWF 0x13,W ; W=~d[4]+d[7]

CALL Get_tab1

MOVWF 0x13 ; d[7]=T1[~d[4]+d[7]]

XORWF 0x10,f ; d[4]=d[4] XOR d[7]

SWAPF 0x13,W ; Swap nibbles in d[7]

ADDWF 0x12,W ; W=~d[7]+d[6]

CALL Get_tab1

MOVWF 0x12 ; d[6]=T1[~d[7]+d[6]]

XORWF 0x13,f ; d[7]=d[7] XOR d[6]

SWAPF 0x12,W ; Swap nibbles in d[6]

ADDWF 0x11,W ; W=~d[6]+d[5]

CALL Get_tab1

MOVWF 0x11 ; d[5]=T1[~d[6]+d[5]]

XORWF 0x12,f ; d[6]=d[6] XOR d[5]

MOVF 0x10,W ;\ d[5]=d[5] XOR d[4]

XORWF 0x11,f ;/

 

;Step 3: get data values for the next iteration

 

INCF PCLATH,f ; PCLATH=3, block address of T2 in the external EEPROM is 3 (offset 0x300)

 

MOVF 0x11,W ;\

CALL Get_tab2 ; d[0]=d[0] XOR T2[d[5]]

XORWF 0x30,f ;/

MOVF 0x13,W ;\

CALL Get_tab2 ; d[1]=d[1] XOR T2[d[7]]

XORWF 0x31,f ;/

MOVF 0x10,W ;\

CALL Get_tab2 ; d[2]=d[2] XOR T2[d[4]]

XORWF 0x32,f ;/

MOVF 0x12,W ;\

CALL Get_tab2 ; d[3]=d[3] XOR T2[d[6]]

XORWF 0x33,f ;/

DECF PCLATH,f ; PCLATH=2, SECA table 1 starts at offset 0x200

 

; At the end there is no swap of d[0]..d[3] with d[4]..d[7].

; It is performed in Step 3.b below, which is reached in case another iteration is needed

 

; Step 4: prepare keys for the next iteration

 

CALL kbprep ; K[i+3]=K[i+3] XOR T1[K[i+4] XOR K[i-2]]

CALL kbprep_im1 ; K[i+2]=K[i+2] XOR T1[K[i+3] XOR K[i-1]]

CALL kbprep_im1 ; K[i+1]=K[i+1] XOR T1[K[i+2] XOR K]

CALL kbprep_im1 ; K=K XOR T1[K[i+1] XOR K[i-1]]

MOVF 0x0D,f ;\ If C=0 then return

BTFSC STATUS,Z ;/

RETURN ; Decription has been performed, return

 

; Step 3.b: Another iteration is needed, swap nibbles and decrement C

 

MOVLW 0x04 ;\ p_swap_nibble offset=4

MOVWF EEADR ;/

MOVLW 0x34 ; p_swap_nibble address=0x34

CALL p_swap_nibble ; Swap d[0]..d[3] with d[4]..d[7]

DECF 0x0D,f ; C=C-1

MOVLW 0xFC ;\ i=i-4

ADDWF 0x0F,f ;/

MOVLW 0x0C ;\

BTFSC 0x0F,07 ; If i <0 set i again to 12 (0x0C)

MOVWF 0x0F ;/

GOTO keydata_loop ; Iterate again

 

; Perform the operation K=K XOR T1[K[i-1] XOR K[i+1] XOR C]

; 0x0F contains the "i" value and 0x0D contains the "C" value

 

kbprep_im1 DECF 0x0F,f ; Entry point for the same function, but with i -> i-1

kbprep INCF 0x0F,W ;\ Load K[i+1] into W

CALL kbget_w ;/

MOVWF 0x0C ; save it also into 0x0C

DECF 0x0F ,W ;\ Load K[i-1] into W

CALL kbget_w ;/

XORWF 0x0C,f ;K[i-1] XOR K[i+1]

CALL kbget_0f ; Read K, the result is not used, but now FSR points to K

MOVF 0x0C,W ;\ XOR with "C"

XORWF 0x0D,W ;/

CALL Get_tab1 ; Get T1[....]

XORWF INDF,f ; and at last K=K XOR ...

RETURN

 

; Routines to read the key byte at a given offset from the key start address 0x40

; the offset is wrapped to lie in 0x00...0x0F

; The key byte is returned in W

 

kbget_0f_p1 INCF 0x0F,f ; The key byte offset minus 1 is contained in 0x0F

kbget_0f MOVF 0x0F,W ; The key byte offset is contained in 0x0F

kbget_w ; The key byte offset is contained in W

ANDLW 0x0F ; Wrap W to lie in 0x00...0x0F

MOVWF FSR ; Set pointer to the byte offset

BSF FSR,0x06 ; Key is stored starting from 0x40

MOVF INDF,W ; Read the key byte value and store it into W

RETURN

 

;-----------------------------------------------------------------------

 

; Computes the external EEPROM address of the key to be used (from P1 in 0x0D)

; Returns in 0x10 the key offset (word address) and in PCLATH the page (block address)

; PCLATH bit 4 is set to indicate superencription

 

kaddress CLRF 0x10 ;\

RRF 0x0D,f ; Move bits 1,0 of P1 (provider number) to bits 7,6 in file register 0x10

RRF 0x10,f ; This is the same as a left shift by 6 bits (each provider uses 64 bytes (2^6))

RRF 0x0D,W ; Moroever put into W(3:0) bits 5-2 of the provider number

RRF 0x10,f ;/

ANDLW 0x03 ; Set W to bits 3-2 of provider number

MOVWF PCLATH ; which identify the page (one external EEPROM (256 bytes) contains 4 providers (4 prov*8 keys*8 bytes/key)

BSF PCLATH,0x02 ; Keys start at block address 4 in the external EEPROM (offset 0x400)

BTFSC 0x0E,07 ;\ If there is superencription

BSF PCLATH,0x04 ;/ then set bit 4 in PCLATH

MOVLW 0x07 ;\ Reduce key number P2 to lie in (0..7)

ANDWF 0x0E,f ;/

kaddr_loop MOVLW 0x08 ; Each key uses 8 bytes

DECF 0x0E,f ; Decrement key number

BTFSC 0x0E,07 ; Loop until 0x0E < 0 (exit from the loop is with 0x0E = -1 (0xff))

RETURN ; Here 0x10 contains the proper word addres for the key

ADDWF 0x10,f ; Increment word address by 8

GOTO kaddr_loop ; as many times as the key number minus one

 

;-----------------------------------------------------------------------

 

; Read a key from the external EEPROM starting from the offset specified in file register 0x10

; The key is stored in RAM starting from where the indirect register points

 

Get_key_10 MOVF 0x10,W

 

; As above, but the offset comes from W

Get_key CALL i2c_wr ; Send address to be read to external EEPROM

MOVLW 0x08 ; 8 bytes are to be read

MOVWF 0x11 ; 0x11 is the loop counter

 

Get_key_loop

CALL i2c_rd ; Read byte from external EEPROM

MOVWF INDF ; Write to RAM

INCF FSR,f ; Increment RAM pointer

DECFSZ 0x11,f ;\ Loop until the entire key is read

GOTO Get_key_loop ;/

RETURN

 

;-----------------------------------------------------------------------

 

; Routine which performs the swap of 2 blocks of eight bytes each

; W contains the starting address of the first block and EEADR contains the offset

; of the first block wrt the second

; A positive offset means the first block is after the second and a negative offset

; means the second block is after the first

 

swap_eedat ; Swap two 8-bytes blocks

CALL p_swap_nibble

GOTO swap_nibble

 

p_swap_nibble

MOVWF FSR ; Set pointer to the first block start address

 

swap_nibble ; Swap two 4-bytes blocks

CALL swap_byte

CALL swap_byte

CALL swap_byte

 

; Swap 1 byte of the first block with 1 byte of the second block

; The byte in the first block is poited by FSR, 1st block offset wrt 2nd block is into EEADR

 

swap_byte MOVF INDF,W ;\ Save 1st block byte pointed by FSR into EEDATA

MOVWF EEDATA ;/

MOVF EEADR,W ;\ Offset FSR by the block offset so it points to the 2nd byte

SUBWF FSR,f ;/

MOVF EEDATA,W ; Load 1st block byte into W

XORWF INDF,f ; Xor the two bytes and save in place of the 2nd block byte

MOVF INDF,W ; and also into W

XORWF EEDATA,f ; Xor again with the 1st block byte, so the 2nd block byte is now into EEDATA

MOVF EEDATA,W ; and also into W

XORWF INDF,f ; Xor again, so now the 1st block byte is in place of the 2nd block byte

MOVF EEADR,W ;\ Now point to the 1st block byte

ADDWF FSR,f ;/

MOVF EEDATA,W ;\ Put the 2nd block byte in place of the 1st block byte

MOVWF INDF ;/

INCF FSR,f ; Move FSR one place forward in the 1st block

RETURN

 

;-----------------------------------------------------------------------

 

;*************************************************

; function : 32 C1 CLASS instruction *

; either startup or *

; extra and general infos (package bitmap) *

;*************************************************

 

Instr_32 INCF PCLATH,f ; External EEPROM page 1 \ The startup answer is stored in

MOVLW 0x99 ; Address 0x99 / external EEPROM address 0x199

BTFSS 0x40,00 ; If the last received byte was not 0x01 (from C1 34)

GOTO pbmap ; then jump to extra and general infos (package bitmap)

GOTO COMM_EEPR ; else transmit data from external EEPROM (startup) starting from 0x199

 

;-----------------------------------------------------------------------

 

; Write a byte sequence to external EEPROM

; The byte sequence is stored starting from RAM address 0x38, and its length is stored in 0x0F

; The external EEPROM internal address pointer should have been set previously

; by a control byte, word address write sequence

 

wr_i2c_string

MOVLW 0x37 ;\ Load pointer (one location lower since the loop starts by incrementing the address)

MOVWF FSR ;/ to RAM

wr_i2c_str_loop

INCF FSR,f ;\ Read next byte

MOVF INDF,W ;/

CALL i2cw_byte ; Send to EEPROM

DECFSZ 0x0F,f ;\ Loop until all bytes are sent

GOTO wr_i2c_str_loop;/

GOTO i2c_stop ; Stop transfer to EEPROM

 

;-----------------------------------------------------------------------

 

Rec_skip_r SUBWF 0x0F,f ; Receive and discard the number of bytes stored at RAM location 0x0F minus the number of bytes stored in W

 

Rec_skip CALL Receive ; Receive and discard the number of bytes stored at RAM location 0x0F

DECFSZ 0x0F,f

GOTO Rec_skip

RETURN

 

;=======================================================================

; RB7 I/O procedures

;=======================================================================

 

; Send the data byte contained in W to RB7

 

Send

 

IF LED ;\

BSF PORTA,LED_GREEN; Green LED on

ENDIF ;/

 

MOVWF 0x16 ; Store the data byte into 0x16

MOVLW T_SEND_START ;\ Pause

CALL Pause ;/

MOVLW 0x7F ;\ Define PORT B I/O RB7=output, all others=input

TRIS PORTB ;/

CLRF 0x17 ; Clear 0x17, used for parity

BCF PORTB,07 ; Send start bit

MOVLW 0x08 ;\ Length = 8, load counter

MOVWF 0x14 ;/

 

send_loop CALL Std_pause ; Wait

RRF 0x16,f ;\ Load bit to be transmitted in bit 7 of W

RRF 0x16,W ;/

ANDLW 0x80 ; Clear bits 6:0 of W

XORWF 0x17,f ; Update parity

XORWF PORTB,W ; Read PORT B data into W xoring bit 7 (RB7) \ merge bit 7 of W

XORWF PORTB,f ; Write W to PORT B xoring bit 7 again / into PORT B

DECFSZ 0x14,f ;\ Cycle

GOTO send_loop ;/

 

CALL Std_pause ; Wait

MOVF 0x17,W ;\

XORWF PORTB,W ; Send parity

XORWF PORTB,f ;/

CALL Std_pause ; Wait

MOVLW 0xFF ;\ Define PORT B I/O = all input

TRIS PORTB ;/

 

IF LED

BCF PORTA,LED_GREEN; Green LED off

ENDIF

 

MOVLW T_SEND_STOP ;\ Pause

GOTO Pause ;/

 

;-----------------------------------------------------------------------

 

; Wait for input on RB7, receive one byte of data from RB7 and return it through W

 

Receive BTFSC PORTB,07 ;\ Read PORT B, loop while 1 on RB7

GOTO Receive ;/ THIS IS THE MAIN LOOP

 

IF LED ;\

BSF PORTA,LED_GREEN; Green LED on

ENDIF ;/

 

MOVLW T_RECEIV_START ;\ 0 (start bit) has been seen on RB7: pause

CALL Pause ;/

MOVLW 0x09 ; Length = 9 (1 byte data + 1 bit parity)

MOVWF 0x14 ; Counter

 

Receive_loop

BCF STATUS,C ; Clear carry flag

BTFSC PORTB,07 ; Read PORT B

BSF STATUS,C ; 1 on RB7, set carry flag

RRF 0x16,f ; 0 on RB7, rotate right

CALL Std_pause

DECFSZ 0x14,f ; Decrement counter

GOTO Receive_loop ; Repeat

 

RLF 0x16,f ; Done, rotate left to skip parity bit

MOVLW T_RECEIV_STOP ;\ Pause

CALL Pause ;/

MOVF 0x16,W ; Return received byte in W

 

IF LED ;\

BCF PORTA,LED_GREEN; Green LED off

ENDIF ;/

 

RETURN

 

;-----------------------------------------------------------------------

 

Std_pause MOVLW T_SERIAL ; Standard pause for reading/writing via serial protocol

 

Pause MOVWF 0x15 ; Pause for the time stored in W

 

Pause_loop DECFSZ 0x15,f ;\ Loop until pause expires

GOTO Pause_loop ;/

RETLW 0x00 ; Return always 0

 

;=======================================================================

; External EEPROM R/W procedures

;=======================================================================

 

; ACK polling, tries to write a control byte until ACK

 

I2C_busy CALL i2c_start

BCF STATUS,C ; Clear carry flag, R/W bit = 0 (write)

CALL i2cw_conbyte ; Write control byte, returns ACK into carry

BTFSC STATUS,C ; Skip if not busy

GOTO I2C_busy ; Loop while busy

 

RETURN

 

;-----------------------------------------------------------------------

 

; Read a byte from the PIC EEPROM

; The address is read from W and the read value is returned in W

 

Rd_eeprom MOVWF EEADR ; Load address

BSF STATUS,RP0 ; Select page 1 (80H - FFH)

BSF EECON1,0x00

BCF STATUS,RP0 ; Select page 0 (00H - 7FH)

MOVF EEDATA,W ; Return value

RETURN

 

;-----------------------------------------------------------------------

 

; Send a byte sequence from the external EEPROM to the serial line

; The block select bits (high address) comes from PCLATH and the word address (low byte) comes from W

; 0x0F contains the number of bytes to be sent

 

EEPROM_send CALL i2c_wr ; Send address

 

eepr_send_loop

DECF 0x0F,f ; Decrement counter

BTFSC 0x0F,07 ;\ If all bytes have been read then return

RETURN ;/

CALL i2c_rd ; Read byte

CALL Send ; Send to serial line

GOTO eepr_send_loop

 

; Returns in W the external EEPROM byte with block address givan by PCLATH(2:0) and

; word address given by W.

; In case PCLATH(2:0) is 3, it returns in W the SECA algorythm table 2 value

; corresponding to the value contained in W (since T2 is in external EEPROM page 3)

Get_tab2 MOVWF EEADR ; Save W into EEADR

CALL i2c_start

BCF STATUS,C ; Clear carry flag, next i2c access is for writing

CALL i2cw_conbyte ; Send control byte to i2c

MOVF EEADR,W ; Reload W from EEADR

CALL i2cw_byte ; Send word address to i2c

 

;-----------------------------------------------------------------------

 

; Read the external EEPROM byte specified by W and PCLATH

; The external EEPROM internal address pointer should have been set previously

; by a control byte, word address write sequence

; The value is returned in W

 

i2c_rd CALL i2c_start

BSF STATUS,C ; Set carry flag, next i2c access is for reading

CALL i2cw_conbyte ; Send again control byte to i2c

CALL i2cr_byte ; Read byte from i2c into EEDATA

CALL i2c_stop

MOVF EEDATA,W ; Return read byte in W

RETURN

 

;-----------------------------------------------------------------------

 

; Writes a complete address (control byte + word address) to the external EEPROM

; block address is in PCLATH(2:0) and word address is in W

 

i2c_wr MOVWF EEADR ; Save word address

CALL I2C_busy ; Loop writing cotrol byte until ACK

MOVF EEADR,W ; Recover word address

GOTO i2cw_byte ; Write it

 

; Write a data byte to external EEPROM

; The external EEPROM internal address pointer should have been set previously

; by a control byte, word address write sequence

 

wr_last CALL i2cw_byte

GOTO i2c_stop

 

;-----------------------------------------------------------------------

 

; Build control byte into W from block address into PCLATH(2:0) and R/W bit into carry flag

 

i2cw_conbyte

RLF PCLATH,W ; Load block select bits from PCLATH and R/W bit from carry into W

ANDLW 0x0F ; Clear space for control code bits

IORLW 0xA0 ; Load control code bits 1010 into W, control byte in W is complete

 

; Send a byte stored in W to external EEPROM

i2cw_byte MOVWF EEDATA ; Store W into EEDATA

MOVLW 0xCF ;\ Define PORT B I/O RB4,RB5=output, all others=input

TRIS PORTB ;/

CALL i2cw_nibble ;\ Write byte contained in EEDATA

CALL i2cw_nibble ;/

GOTO i2cr_bit ; Read ACK

 

; Send a nibble from EEDATA to external EEPROM

i2cw_nibble

CALL i2cw_nibble_2 ; 1st bit

CALL i2cw_nibble_2 ; 2nd bit

CALL i2cw_nibble_2 ; 3rd bit, 4th bit below

 

; Send an EEDATA bit to external EEPROM

i2cw_nibble_2

RLF EEDATA,f ; Put bit to be sent into carry

GOTO i2cw_bit_x ; Send

 

; Read a byte from external EEPROM into EEDATA

i2cr_byte MOVLW 0xDF ;\ Define PORT B I/O RB5=output, all others=input

TRIS PORTB ;/

CALL i2cr_nibble ;\ Read byte

CALL i2cr_nibble ;/

BSF STATUS,C ; Set carry flag

GOTO i2cw_bit ; NACK, stop

 

; Read a nibble form external EEPROM int EEDATA

i2cr_nibble CALL i2cr_nibble_2 ; 1st bit

CALL i2cr_nibble_2 ; 2nd bit

CALL i2cr_nibble_2 ; 3rd bit, 4th bit below

 

; Read a bit from external EEPROM into EEDATA

i2cr_nibble_2

CALL i2cr_bit_x ; Read bot into carry

RLF EEDATA,f ; Store into EEDATA

RETURN

 

;-----------------------------------------------------------------------

 

; Init data transfer from/to external EEPROM

i2c_start BSF PORTB,0x04

MOVLW 0xCF ;\ Define PORT B I/O RB4,RB5=output, all others=input

TRIS PORTB ;/

BSF PORTB,0x05 ; Clock high

NOP

BCF PORTB,0x04 ; Data start

GOTO clock_low

 

;-----------------------------------------------------------------------

 

; Stop data transfer from/to external EEPROM

i2c_stop BCF PORTB,04 ; Data start

MOVLW 0xCF ;\ Define PORT B I/O RB4,RB5=output, all others=input

TRIS PORTB ;/

NOP

BSF PORTB,05 ; Clock high

NOP

BSF PORTB,04 ; Data stop

nclock_low NOP

clock_low BCF PORTB,05 ; Clock low

RETURN

 

i2cw_bit MOVLW 0xCF ;\ Define PORT B I/O RB4,RB5=output, all others=input

TRIS PORTB ;/

 

; Actual bit write to RB4 (external EEPROM)

; Bit to be written is from carry

i2cw_bit_x

BTFSS STATUS,C ; Skip if carry set

BCF PORTB,04

BTFSC STATUS,C ; skip if no carry

BSF PORTB,04

BSF PORTB,05 ; Clock high

GOTO nclock_low

 

;-----------------------------------------------------------------------

 

i2cr_bit MOVLW 0xDF ;\ Define PORT B I/O RB5=output, all others=input

TRIS PORTB ;/

 

; actual bit read from RB4 (external EEPROM)

; bit is read into carry

i2cr_bit_x BSF PORTB,05 ; Clock high

NOP

BSF STATUS,C ; Set carry flag

BTFSS PORTB,04

BCF STATUS,C ; Clear carry flag

GOTO clock_low

 

;=======================================================================

; SECA Table 1

;=======================================================================

 

; Returns in W the SECA algorythm table 1 value corresponding to the value contained in W

; Before calling this routine PCLATH should have the value 2, since the table starts at offset 0x200

 

Get_tab1 MOVWF PCL ; Absolute addressing

 

ORG 0x200

 

dt 0x2A,0xE1,0x0B,0x13,0x3E,0x6E,0x32,0x48

dt 0xD3,0x31,0x08,0x8C,0x8F,0x95,0xBD,0xD0

dt 0xE4,0x6D,0x50,0x81,0x20,0x30,0xBB,0x75

dt 0xF5,0xD4,0x7C,0x87,0x2C,0x4E,0xE8,0xF4

dt 0xBE,0x24,0x9E,0x4D,0x80,0x37,0xD2,0x5F

dt 0xDB,0x04,0x7A,0x3F,0x14,0x72,0x67,0x2D

dt 0xCD,0x15,0xA6,0x4C,0x2E,0x3B,0x0C,0x41

dt 0x62,0xFA,0xEE,0x83,0x1E,0xA2,0x01,0x0E

dt 0x7F,0x59,0xC9,0xB9,0xC4,0x9D,0x9B,0x1B

dt 0x9C,0xCA,0xAF,0x3C,0x73,0x1A,0x65,0xB1

dt 0x76,0x84,0x39,0x98,0xE9,0x53,0x94,0xBA

dt 0x1D,0x29,0xCF,0xB4,0x0D,0x05,0x7D,0xD1

dt 0xD7,0x0A,0xA0,0x5C,0x91,0x71,0x92,0x88

dt 0xAB,0x93,0x11,0x8A,0xD6,0x5A,0x77,0xB5

dt 0xC3,0x19,0xC1,0xC7,0x8E,0xF9,0xEC,0x35

dt 0x4B,0xCC,0xD9,0x4A,0x18,0x23,0x9F,0x52

dt 0xDD,0xE3,0xAD,0x7B,0x47,0x97,0x60,0x10

dt 0x43,0xEF,0x07,0xA5,0x49,0xC6,0xB3,0x55

dt 0x28,0x51,0x5D,0x64,0x66,0xFC,0x44,0x42

dt 0xBC,0x26,0x09,0x74,0x6F,0xF7,0x6B,0x4F

dt 0x2F,0xF0,0xEA,0xB8,0xAE,0xF3,0x63,0x6A

dt 0x56,0xB2,0x02,0xD8,0x34,0xA4,0x00,0xE6

dt 0x58,0xEB,0xA3,0x82,0x85,0x45,0xE0,0x89

dt 0x7E,0xFD,0xF2,0x3A,0x36,0x57,0xFF,0x06

dt 0x69,0x54,0x79,0x9A,0xB6,0x6C,0xDC,0x8B

dt 0xA7,0x1F,0x90,0x03,0x17,0x1C,0xED,0xD5

dt 0xAA,0x5E,0xFE,0xDA,0x78,0xB0,0xBF,0x12

dt 0xA8,0x22,0x21,0x3D,0xC2,0xC0,0xB7,0xA9

dt 0xE7,0x33,0xFB,0xF1,0x70,0xE5,0x17,0x96

dt 0xF8,0x8D,0x46,0xA1,0x86,0xE2,0x40,0x38

dt 0xF6,0x68,0x25,0x16,0xAC,0x61,0x27,0xCB

dt 0x5B,0xC8,0x2B,0x0F,0x99,0xDE,0xCE,0xC5

 

;-----------------------------------------------------------------------

 

;*************************************************

; function : 3A C1 CLASS instruction *

; request for the control word *

; command : C1 3A 00 00 10 *

; answer : 3A 10 10 55 E6 55 54 05 80 04 14 40 *

; 8F 40 41 11 23 90 00 *

;*************************************************

; This instruction asks for the decrypted control words previously issued by an instruction C1 3C

; The decrypted values were stored starting from RAM address 0x30

; Here a loop reads the values through the indirect register and sends them

 

Instr_3A MOVLW 0x30 ;\ Point to RAM address 0x30

MOVWF FSR ;/

instr_3A_loop

MOVF INDF,W ; Read value

CALL Send ; send it

INCF FSR,f ; Next value

DECFSZ 0x0F,f ;\ Loop for the lenght stored in 0x0F

GOTO instr_3A_loop ;/

GOTO TX9000 ; Send status bytes

 

;*************************************************

; function : 34 C1 CLASS instruction *

; request for the control word *

;*************************************************

 

Instr_34 CALL Rec_skip ; Discard the received bytes

MOVWF 0x40 ; Save the last received byte in 0x40 (0x01:startup, 0x00:package bitmap)

GOTO TX9000 ; Transmit OK

 

;*************************************************

; function : 30 C1 CLASS instruction *

; PIN CONTROLLED OPERATIONS *

;*************************************************

 

Instr_30 MOVLW 0x02

CALL Rec_skip_r ; Receive and discard everithing but the last 2 bytes (PIN), returns with 0x0F=0

CALL Receive ; Receive the first PIN byte

IORWF 0x0F,f ; Save it into 0x0F

ANDLW 0x0F ;\ Low nibble into 0x0C

MOVWF 0x0C ;/

CALL Receive ; Receive the second PIN byte

MOVWF 0x0D ; Save it into 0x0D

IORWF 0x0F,f ; IOR with the first PIN byte

MOVF 0x0E,f ;\

BTFSS STATUS,Z ; If P2 is not 0 then transmit status bytes

GOTO TX9000 ;/

INCF PCLATH,f ;\ PCLATH=1 \ Point to 0x190 in the external EEPROM

MOVLW 0x90 ;/ W=0x90 /

; Initialization

MOVF 0x0F,f ;\ If (1st PIN byte) IOR (2nd PIN byte) = 0

BTFSC STATUS,Z ;/ (i.e. if both bytes are 0)

GOTO wr190 ; then write 0x91 to external EEPROM position 0x190 and transmit status bytes

; Load next external EEPROM offset to be written (points to the next byte of the key to be written)

CALL Get_tab2 ; else read external EEPROM position 0x190 into W

MOVWF 0x0F ; and into 0x0F too

 

; Apparently, the byte at offset 0x190 in the external EEPROM (here just loaded into 0x0F)

; contains the offset in page 1 of the next new key byte to be written in 0x191-0x198 (in the external EEPROM).

; Since the new key starts at 0x191, offset 0x190 initially contain 0x91.

; Moreover, if bit 6 of the byte at offset 0x190 is 1, then the high nibble at that offset has

; already been written, so it is re-read, combined with the low nibble of the 1st PIN byte,

; and then rewritten at the following location, writing the 2nd PIN byte in its place

;

; A call with PIN 0000 is needed to initialize external EEPROM offsewt 0x190 to 0x91.

; After that, the key update strategy is 3 nibbles per call, as follows:

;

; 1st call: xx = PIN 2, x=PIN 1 low

; 2nd call: yy = PIN 2, y=PIN 1 low

; 3rd call: zz = PIN 2, z=PIN 1 low

; 4th call: pp = PIN 2, p=PIN 1 low

; 5th call: qq = PIN 2, q=PIN 1 low

; 6th call: rr = PIN 2, r=PIN 1 low

; This is the image of the external EEPROM 0x190-0x198:

; before 1st call: 0x91 00 00 00 00 00 00 00 00

; after 1st call: 0xD2 xx x- -- -- -- -- -- --, since 0x92 XOR 0x40 = 0xD2

; after 2nd call: 0x94 xx yy xy -- -- -- -- --

; after 3rd call: 0xD5 xx yy xy zz z- -- -- --, since 0x95 XOR 0x40 = 0xD5

; after 4th call: 0x97 xx yy xy zz pp zp -- --

; after 5th call: 0xD8 xx yy xy zz pp zp qq q-, since 0x95 XOR 0x40 = 0xD8

; On the 6th call the key is written as

; xx yy xy zz pp zp qq qr

; to the external EEPROM at block address rr(2:0)

; and word address rr(7:3)

;

; PIN 0000 is also used to reset yellow and green LEDs on subscription date update

; and key update respectively

 

BTFSS 0x0F,0x06 ; If bit 6 in W was 0

GOTO wr19x ; then goto wr19x (no spare nibble from the previous call)

 

BTFSC 0x0F,0x03 ;\ If all the 8 key bytes have been received

GOTO Remote_kupdate ;/ then update EEPROM key

 

XORLW 0x40 ; else flip bit 6 in W (set it to 0)

CALL Get_tab2 ; and read external EEPROM byte with word address W and block address 1

; i.e., read previous spare nibble

; Combine previous and current spare nibbles

IORWF 0x0C,f ;\ IOR W (from external EEPROM) and the low nibble of the first PIN byte

SWAPF 0x0C,f ;/ and swap nibbles in the result (in 0x0C)

MOVF 0x0F,W ; Set W to the byte read from external EEPROM position 0x190

XORLW 0x40 ; and flip bit 6 of W (set it to 0)

INCF 0x0F,f ; Increment key bytes pointer

 

wr19x CALL i2c_wr ; set pointer to external EEPROM as specified by W

MOVF 0x0D,W ;\ Write 2nd PIN byte

CALL i2cw_byte ;/

SWAPF 0x0C,W ;\ Write 1st PIN byte low nibble as high nibble on calls 1,3,5

CALL wr_last ;/ or combined with previous 1st PIN byte low nibble on calls 2,4

; CALL i2c_delay

MOVLW 0x40 ;\ Move key bytes pointer to W and flip bit 6

XORWF 0x0F,W ;/

 

; Write W+1 to external EEPROM position 0x190

wr190 MOVWF 0x0F ;\ Save W+1 into 0x0F

INCF 0x0F,f ;/ (increment key bytes pointer)

MOVLW 0x90 ;\ Set external EEPROM pointer to 0x190

CALL i2c_wr ;/

MOVF 0x0F,W ;\ Write there W+1

CALL wr_last ;/

; CALL i2c_delay

IF LED ;\

BCF PORTA,LED_YELLOW ; Yellow LED is set off

BCF PORTA,LED_RED ; Red LED is set off

BCF PORTA,LED_GREEN2 ; Green2 LED is set off

ENDIF ;/

GOTO TX9000 ; Transmit status bytes

 

;-----------------------------------------------------------------------

 

; Actualize a key stored in EEPROM from the key stored into RAM via remote

Remote_kupdate

MOVLW 0x38 ;\ Set pointer to RAM address 0x38

MOVWF FSR ;/

MOVLW 0x91 ;\ Read key starting from external EEPROM offset 0x191

CALL Get_key ;/ (since PCLATH has been set to 1) and store it into RAM from position 0x38

MOVF 0x0C,W ;\ IOR the last byte of the key with the low nibble of the last PIN byte 1 received

IORWF 0x3F,f ;/

CLRF PCLATH ; reset PCLATH to 0

MOVF 0x0D,W ;\

ANDLW 0x07 ; Set external EEPROM block address to bits (2:0) of the last PIN byte 2 received

ADDWF PCLATH,f ;/

MOVF 0x0D,W ;\ Set external EEPROM word address to bits (7:3) of the last PIN byte 2 received

ANDLW 0xF8 ;/

CALL i2c_wr ; Set external EEPROM pointer

MOVLW 0x08 ;\

MOVWF 0x0F ; Write the 8 bytes key from RAM offset 0x38 to external EEPROM

CALL wr_i2c_string ;/

 

IF LED ;\

BSF PORTA,LED_RED ; Red LED is set and left on if key updated

ENDIF ;/

 

GOTO TX9000 ; transmit 9000

 

;**************************************************

; function : C1 40 CLASS instruction *

; ENTITLEMENT MANAGEMENT MESSAGE *

;**************************************************

; c14003814e

;

; 4b c8 7c 75 ab 0b 84 84 96 f1 d3 f7 ee 94 96 c0

; b1 51 cc 39 a7 b6 08 c4 a1 50 39 0d 00 b0 df 73

; e9 d6 6c c3 d5 ec 8e d6 0f 7b 1f 9b 74 48 f7 7b

; cc 97 d8 60 da 91 e9 c3 d7 03 8b b1 a0 7f de 50

; 5c 56 2f 8b b2 c9 e3 39

; da 86 dd a7 34 d1

; 90 00

 

; decoder

; f0 5b 08 02 04 45 02 08 ce b4 01 42 04 50 aa 76

; b7 10 01 42 13 0e 2b 11 a4 50 48 60 32 2c 10 11

 

; 12 22 15 1f

; 21 ;nano data

; 15 5f ;data

; 90 5d ;nano primary key | key d

; d9 5f e0 f4 66 94 29 ab

; 90 5c ;nano primary key | key c

; 15 3f bb df 11 bb e5 30

; 90 5e ;nano primary key | key e

; 68 19 ba 23 4b c4 1b 07

;

; 82 ;\ signature

; 27 c9 da 86 dd a7 34 d1 ;/

;

; Subscription 31/10/2000

; primary key 0d

; primary key 0c

; primary key 0e

 

; index=01

; key=42 22 7b 71 20 34 93 ef

; index=0c

; key=d9 cb b8 5c 57 af 2d 53

; index=0d

; key=61 24 8c d4 1a 39 2a ad

; index=0e

; key=5a 1d b3 dd 48 22 12 31

 

Instr_40

MOVF 0x0D,W ; Save P1 into W

MOVWF 0x17 ; and into file register 0x17

 

BSF PCLATH,0x03 ; Set PCLATH(3) to 1 (next call to TX9000 will transmit 901D)

 

MOVLW 0x34 ;\

SUBWF 0x0F,W ; If length is less than 0x34 bytes

BTFSS STATUS,C ; then jump to process instruction 34 (i.e., discard received data and transmit status bytes)

GOTO Instr_34 ;/

CALL GET_CW_loop ; else receive the remaining part of the command (only the last 0x31 bytes are retained),

; read the 16 bytes key from the external EEPROM according to P1 and P2,

; and in case of superencription implement the first decription

 

BSF PCLATH,0x03 ; Set PCLATH(3) to 1 (next call to TX9000 will transmit 901D)

 

MOVF 0x17,W ; Recover P1 from file register 0x17

ANDLW 0x0F ;\

BTFSC STATUS,Z ; If P1 is 0 (SECA) transmit 901D

 

Share this post


Link to post
Guest dreeke

Maakt niet uit, het is toch al voldoende voor de nodige uurtjes puzzelplezier....

 

Dreeke :)

Share this post


Link to post
Guest Kcplus

Yeah!!!!!!!!!!!!!!!

 

De puzzel is nu toch bijna opgelost.........

 

De sleutel: toch Picachu! Wat een mooi proggie.

 

Eerst de secanix hexfile en eeprom geladen, vervolgens de "break" neergezet in de assemblercode, daar waar de C1 3C instructie wordt "aangepakt", en vervolgens het RAM/EEdata-window geopend.

Dan de emulator gestart (met de season natuurlijk) en zodra de Ins C1 3C binnenkomt met de F10 toets stap voor stap iedere instructie doorlopen (je krijgt er wel een "lam" vingertje van ;) ). De RAM laat dan precies zien wat er gebeurt met het CW en de "round"-key. Wow!

 

Voor een decodering met alleen een primarykey werkt mijn spreadsheet nu al perfect.

Er zat dus echt een heel grote fout in de Media1.doc (je zou ook kunnen zeggen: een zeer grote onduidelijkheid) en in de seca.xls.

Die is er nu UIT. En het werkt :D .

 

Jammergenoeg nog niet met zowel een primary als een secundary key, maar de oplossing is nu wel nabij......

 

We zoeken nog even verder ;)

Share this post


Link to post
Guest Kcplus

De aanhouder wint dus toch...........

Share this post


Link to post
Guest Kcplus

De aanhouder wint dus toch........... :D

 

Nadat ik een darksuca.hex en -.bin in Picachu had geladen (voor de secundaire keys) en nogmaals stap voor stap het decoderingsproces heb doorlopen, bleken er ook nog enkele "overname"-fouten in de hash-tabellen van de originele seca.xls te zitten (en dus ook in mijn quattro pro-sheet :( ).

 

Nu de seca.xls geheel is aangepast werkt-ie perfect, zowel voor coderen als decoderen en zowel met alleen de prim.key als met prim.- en sec.key.

 

Zou de schrijver van de seca.xls een doel hebben gehad met de daarin opgesloten fouten ;) ............

Share this post


Link to post
Sign in to follow this  




  • Hosting Fun

×
×
  • Create New...

Important Information

By clicking the accept button you specifically agree to our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. If you don't agree, please leave this site.