You are on page 1of 162

The NagraVision hacking FAQ

by StuntGuy

Revision: 12282000
CONTENTS:

1: The T=1 protocol ............................................................................................................................6


1.1- The NagraVision ATR ...........................................................................................................6
1.2- NagraVision's packet structure I: The ISO-specified portion ...........................................8
1.2.1- Chained messages............................................................................................................10
1.3- NagraVision's packet structure II: The IRD-to-CAM information field........................10
1.4- NagraVision's packet structure III: The CAM-to-IRD information field ......................11
1.5- The status word ....................................................................................................................12
2: Commands ....................................................................................................................................13
2.1- Known command list............................................................................................................13
2.2- Command lengths, expected replies, and reply lengths ....................................................13
2.3- Command breakdown..........................................................................................................14
2.3.1- Command $00/Response $80..........................................................................................14
2.3.2- Command $01/Response $81..........................................................................................15
2.3.3- Command $02/Response $82..........................................................................................16
2.3.4- Command $03/Response $83..........................................................................................17
2.3.5- Command $12/Response $92..........................................................................................22
2.3.6- Command $13/Response $93..........................................................................................23
2.3.7- Command $14/Response $94..........................................................................................24
2.3.8- Command $20/Response $A0 .........................................................................................24
2.3.9- Command $21/Response $A1 .........................................................................................24
2.3.10- Command $30/Response $F0........................................................................................26
2.3.11- Command $31/Response $F1........................................................................................27
2.3.12- Command $40/Response $70........................................................................................29
2.3.13- Command $41/Response $71........................................................................................30
2.3.14- Command $42/Response $72........................................................................................30
2.3.15- Command $55/Response $D5 .......................................................................................31
2.3.16- Command $56/Response $D6 .......................................................................................32
2.3.17- Command $60/Response $E0 .......................................................................................32
2.3.18- Command $61/Response $E1 .......................................................................................33
2.3.19- Command $99/Response $99........................................................................................33
2.3.20- Command $C0/Response $B0.......................................................................................34
2.3.21- Command $C1/Response $B1.......................................................................................35
2.4- Basic command sequences ...................................................................................................36
2.4.1- Finding out if the card is busy or has any new information ............................................36
2.4.2- Finding out what data types in the card's database have changed...................................36
2.4.3- Retrieving a specific data item from the card..................................................................36
2.4.4- Getting the data required to decrypt the video stream.....................................................37
3: EMM commands ..........................................................................................................................39
3.1- EMM command list..............................................................................................................39
3.2: EMM command breakdown................................................................................................40
3.2.1- EMM command $00........................................................................................................40
3.2.2- EMM command $10........................................................................................................40
3.2.3- EMM command $11........................................................................................................40
3.2.4- EMM command $12........................................................................................................41
3.2.5- EMM command $13........................................................................................................42
3.2.6- EMM command $14........................................................................................................43
3.2.7- EMM command $15........................................................................................................43
3.2.8- EMM command $20........................................................................................................43
3.2.9- EMM command $21........................................................................................................45
3.2.10- EMM command $22......................................................................................................45
3.2.11- EMM command $23......................................................................................................46
3.2.12- EMM command $24......................................................................................................46
3.2.13- EMM command $25......................................................................................................47
3.2.14- EMM command $26......................................................................................................48
3.2.16- EMM command $30......................................................................................................49
3.2.18- EMM command $32......................................................................................................49
3.2.19- EMM command $40......................................................................................................50
3.2.20- EMM command $41......................................................................................................50
3.2.22- EMM command $43......................................................................................................51
3.2.23- EMM command $44......................................................................................................51
3.2.24- EMM command $45......................................................................................................53
3.2.25- EMM command $50......................................................................................................53
3.2.26- EMM command $51......................................................................................................54
3.2.27- EMM command $52......................................................................................................54
3.2.28- EMM command $53......................................................................................................54
3.2.29- EMM command $54......................................................................................................54
3.2.30- EMM command $60......................................................................................................55
3.2.31- EMM command $61......................................................................................................55
3.2.32- EMM command $62......................................................................................................56
3.2.33- EMM command $63......................................................................................................56
3.2.34- EMM command $64......................................................................................................57
3.2.35- EMM command $80......................................................................................................57
3.2.36- EMM command $81......................................................................................................58
3.2.37- EMM command $82......................................................................................................58
3.2.39- EMM command $84......................................................................................................59
3.2.40- EMM command $85......................................................................................................59
3.2.41- EMM command $86......................................................................................................59
3.2.42- EMM command $F0 (ROM2/288-01)/EMM command $F3 (ROM3/288-02)/ EMM
command $FA (ROM10)...........................................................................................................60
3.3- EMM filter command list ....................................................................................................61
3.4: EMM filter command breakdown ......................................................................................61
3.4.1- EMM filter command $00...............................................................................................61
3.4.2- EMM filter commands $01..$20 .....................................................................................62
3.4.3- EMM filter command $3D ..............................................................................................62
3.4.4- EMM filter command $3E ..............................................................................................63
3.4.5- EMM filter command $3F...............................................................................................63
4: 21-xx data types ............................................................................................................................64
4.1- Data type list .........................................................................................................................64
4.2: Data type breakdown ...........................................................................................................64
4.2.1- Data type $01...................................................................................................................65
4.2.2- Data type $02...................................................................................................................66
4.2.3- Data type $03...................................................................................................................66
4.2.4- Data type $04...................................................................................................................66
4.2.5- Data type $05...................................................................................................................66
4.2.6- Data type $06...................................................................................................................67
4.2.7- Data type $07...................................................................................................................67
4.2.8- Data type $08...................................................................................................................68
4.2.9- Data type $09...................................................................................................................69
4.2.10- Data type $0A................................................................................................................69
4.2.11- Data type $0B................................................................................................................70
4.2.12- Data type $0C................................................................................................................70
4.2.13- Data type $10.................................................................................................................71
4.2.14- Data type $11.................................................................................................................71
4.3- How data is stored in the cards ...........................................................................................71
4.3.1- ROM2 headers.................................................................................................................72
4.3.2- ROM3 headers.................................................................................................................72
5: The backdoors...............................................................................................................................75
5.1- The backdoor passwords .....................................................................................................75
5.1.1- The ROM-based password ..............................................................................................75
5.1.2- The EEPROM-based password .......................................................................................75
5.2- The backdoor commands.....................................................................................................76
5.2.1- Backdoor command $0E: Erase EEPROM .....................................................................76
5.2.2- Backdoor command $20: Login ......................................................................................76
5.2.3- Backdoor command $B0: Dump memory.......................................................................77
5.2.4- Backdoor command $D6: Execute code/Write EEPROM..............................................77
6: Inside NagraVision cards.............................................................................................................79
6.1- The MCU core ......................................................................................................................79
6.2- 288-01 vs. 288-02 vs. 288-09, or ROM2 vs. ROM3 vs. ROM10........................................81
6.3- Other cards based on the same code...................................................................................82
7: Glossary.........................................................................................................................................83
7.1- Glossary.................................................................................................................................83
8: Encryption.....................................................................................................................................92
8.1- ECM encryption ...................................................................................................................92
8.1.1- The encryption algorithm ................................................................................................92
8.1.2- Correlation between DES and EDES s-boxes:................................................................93
8.1.3- Key permutation ..............................................................................................................94
8.2- EMM encryption ..................................................................................................................98
8.3- The valid hash.......................................................................................................................98
9: Hacks...........................................................................................................................................100
9.1- Commands added to the E3M, AVR2, and GAP ............................................................100
9.1.1- Command $05: Write IRD key (Version 3.0: Write config item).................................100
9.1.2- Command $06: Read IRD key (Version 3.0: Read config item) ..................................101
9.1.3- Command $07: Write ZIP code and time zone .............................................................101
9.1.4- Command $08: Update EEPROM ................................................................................102
9.1.5- Command $09: Update keys .........................................................................................103
10: Firmware versions of the various E* cards.............................................................................104
10.1- ROM2 firmware versions ................................................................................................104
10.2- ROM3 firmware versions ................................................................................................104
10.3- ROM10 firmware versions ..............................................................................................104
11- Writing code for NagraVision cards........................................................................................105
11.1- ROM2 cards (this section under construction)..............................................................105
11.2- ROM3 cards......................................................................................................................105
11.2.1- Bug-catcher modules...................................................................................................105
11.2.2- Hooking in a bug-catcher ............................................................................................113
11.2.3- Useful routines ............................................................................................................113
11.2.3.1- Utility routines......................................................................................................113
11.2.3.2- Database routines .................................................................................................136
11.2.3.3- Low-level routines................................................................................................141
11.2.3.4- Encryption/decryption routines ............................................................................145
11.2.4- Memory usage .............................................................................................................151
11.2.4.1- ZP RAM ...............................................................................................................151
11.2.4.2- Other RAM...........................................................................................................154
11.2.4.3- Tables in ROM and EEPROM .............................................................................155
11.3- ROM10 cards (this section under construction)............................................................159
12: Epilogue ....................................................................................................................................160
12.1- Change log.........................................................................................................................160
12.2- Coming soon......................................................................................................................162
12.3- Contacting me ...................................................................................................................162
1: The T=1 protocol

1.1- The NagraVision ATR


Most DSS cards use the “T=0” format. This protocol calls for the master device
(the receiver or IRD) to send a 5-byte header block to the card. The card (or
CAM) must then send back one of the bytes from the header (specifically, the
second byte, which is the INS byte) to acknowledge receipt of the header. At
this point, the IRD will either send the rest of the message to the CAM as one
large packet, send the rest of the packet one byte at a time, awaiting an
acknowledgment after each byte, or await the data return from the CAM.

The NagraVision cards, on the other hand, use a variant of the ISO-7816 protocol
called the "T=1" or "asynchronous half-duplex block transfer" format.

This “T=1” protocol is defined such that any of 7 devices all connected to the
same ISO-7816 bus may initiate a transmission to any of the other devices on the
bus. In addition, the message will either be sent all at once (if it is short
enough to fit in the destination device's receive buffer), or broken into
smaller packets if the message is too long to be sent all at once.

The protocol used by the NagraVision smartcards (and in fact, by any ISO-7816
compliant smart card) is requested by the card when it is reset by a master
device. After reset, the card will send a sequence of data at a fixed baud rate
(input clock frequency/372 so for a 3.579545 MHz clock the baud rate will be
9622 bps) and this data will include information about the data format the card
wants to use, the baud rate at which it will want to communicate, and so on. To
better understand the NagraVision cards, let's look at the ATR sent by a ROM10
Nagra.

3F FF 95 00 FF 91 81 71 A0 47 00 44 4E 41 53 50
30 31 30 20 52 65 76 41 33 42 3B

If we break this ATR up into its constituent parts, we can decode it as


follows:

3F ... Convention definition


|
|_____________ Inverse convention (data is inverted)

FF 95 00 FF 91 ... Initial parm setup


| | | | |
| | | | |_ Td1=91 (Ta2 and Td2 will be sent, Protocol is async
| | | | half duplex block format)
| | | |____ Tc1=FF (Guard time=257 bits)
| | |_______ Tb1=00 (No Vpp)
| |__________ Ta1=95 (F=512, D=16; Bit period=(512/16) (32) clocks)
|_____________ T0=FF (Ta1, Tb1, Tc1, and Td1 will be sent, 15
historical characters will be sent)

81 71 ... Secondary parameters


| |
| |__________ Td2=71 (Ta3, Tb3, and Tc3 will be sent, protocol is async
| half duplex block format)
|_____________ Ta2=81 (Mode change not allowed, Protocol is async half
duplex block format)
A0 47 00 ... T=1 specific parameters
| | |
| | |_______ Tc3=00 (LRC (XOR-type) error checking to be used)
| |__________ Tb3=47 (Char wait time is 25 bit times, block wait time
| is 634.9 mSec + 11 bit times) (1 bit time=7.111
| uSec)
|_____________ Ta3=160 (Receive block size=0xA0 bytes (160 bytes decimal)

44 4E 41 53 50 30 31 30 20 52 65 76 41 33 42 ... Historical bytes


| |
|_____ ___________________________________|
|
|_______ ASCII text: "DNASP010 RevA3B". This is just an eye-catcher
and/or ego boost for the Echo and Nagra boys. It's the
ROM version and EEPROM revision level of the firmware in
the CAM.

3B Checksum character
|_____________ Checksum (all other bytes XORed together)

The data format is selected by bytes Td1, Td2, and Ta2.

The baud rate is defined by byte Ta1. The upper nibble of this byte defines
parameter F (frequency) as being 512, while the lower nibble defines parameter D
(divisor) as being 16. The bit rate is found by dividing the card's input clock
frequency by the quantity (F/D) (in the case of NagraVision cards, F/D = 512/16
= 32). If we check the clock being fed to the smartcard by an EchoStar IRD, we
find that the master clock frequency, f, is either 4.5 MHz or 4.0 MHz, depending
on the model IRD being used. Thus, the final baud rate for communication
between an EchoStar IRD and smartcard is 4,500,000/32 (140,625) bps, or
4,000,000/32 (125,000) bps .

Note that this bit rate is only necessarily 140,625 bps when the card is in an
EchoStar IRD. If the card is in a programmer that feeds a 3.6864 MHz clock to
the card, the final baud rate will be 115,200 bps (though the ATR baud rate will
become 9909 bps).

The parameters such as "guard time", "character wait time", and "block wait
time" apply only to messages being sent to the card from the IRD. These delays
exist to allow the card enough time to move received data into its internal
buffers and perform any necessary decryption on the received data before the
next byte is received. It is assumed that the master device will not need such
delays, since the master device most likely has a great deal more processing
horsepower than the smartcard. In the case of the NagraVision smartcard, a
delay of at least 25 bit times (178 microseconds) is required between bytes, and
a delay of at least 635 milliseconds is required between whole blocks.

The Tc3 byte specifies that the card is going to use LRC (Longitudinal
Redundancy Checking) as its means of error correction. This means that for any
message sent, the final byte of the message will be the XOR-sum of all of the
other bytes in the message. The other possibility for error checking (which is
required by the ISO-7816 spec) is CRC checking, which would be selected if Tc3
was equal to 1.

The Ta3 byte specifies that the maximum message size that the card can accept is
0xA0 (160 decimal) bytes. If the receiver wants to send a message that's longer
than this, it has to break it up into smaller packets. In NagraVision ROM
version 1 cards, Ta3 was 0x60 (96 decimal). One interesting thing to note,
however, is that the first thing most IRDs I've seen do after they reset the
smartcard is request that the smartcard shrink its buffer size to 0x68 (104
decimal) bytes.

The historical bytes are really nothing more than superfluous identification
bytes that are used by the master device to learn additional information about
the smartcard. In this case, the card sends ASCII text indicating that it is a
Nagra/Dish Network smartcard, ("DNASP"), with ROM version 10("010"), and its
current EEPROM code revision ("RevA3B").

Finally, the ATR is terminated by a checksum, which is the XOR-sum of all


of the other bytes in the ATR.

1.2- NagraVision's packet structure I: The ISO-specified portion


The T=1 protocol has a very specific format for the data packets. The first 3
bytes of the packet, as well as the last byte (or the last two bytes if CRC
checking is used) of the packet are defined specifically as follows:

Byte 1: Node address byte (NAD)


Byte 2: Procedure control byte (PCB)
Byte 3: Length byte (LEN)
Last byte: Checksum (LRC)

Thus, an ISO-7816 compliant T=1 message looks like this:

NAD PCB LEN <information field> LRC

The NAD is used to route messages. The upper nibble of the NAD is defined
as the target address, and the lower nibble is defined as the source address.
In the NagraVision system, only two addresses are defined: Address 1 is the
receiver, and address 2 is the smartcard. Although 4 bits appear to be
available for addressing, in reality, only the lower 3 bits of each nibble are
available for addresses. The upper bit of each nibble is reserved for Vpp
control requests. Since the NagraVision system doesn't use these bits, they
won't be discussed here. Actually, it's also interesting to note that the
smartcarts don't do any sanity checking on the NAD...they just assume that
whatever NAD they received was the correct one and swap its nibbles when they
send a response.

The PCB is used to identify what type of data is being sent, whether it's part
of a block that's been broken up due to buffer size restrictions, if it's a
special type of control request, and so forth. There are 3 basic formats for
the PCB, as follows:

A standard "instruction" block has a PCB that looks like this:

% 0 N C 0 0 0 0 0
| | |
| | |____________ "Chain" bit. If this bit is set, it means that this
| | packet requires at least one more packet before the
| | entire message is considered "sent".
| |______________ "sequence Number" bit. This bit should toggle between
| messages. It's used to help ensure that packets were
| not missed if the chain bit is set...if the smartcard
| misses a single packet (or any odd number of packets)
| from the master, it will know that data is corrupt.
|________________ "0" in bit 7 indicates "instruction block".
A standard ISO 7816 T=1 response block from will have a PCB like this:

% 1 0 0 N 0 0 O E
|_| | | |__ Errors detected either in LRC byte or in parity.
| | |____ Other errors occurred
| |__________ "sequence Number" bit. This bit should match the N
| bit for the message to which the smartcard is
| responding.
|_______________ "10" in bits 7-6 indicates "response block"

One would ordinarily expect that the CAM responses would be sent in a response
block as defined by the ISO 7816 T=1 spec, but it turns out that for the most
part, when the CAM responds, it responds with an instruction block of its own.
And as if that deviation from the ISO spec weren't enough, the CAM's instruction
block responses don't have INS, CLA, P1, P2, or P3 bytes at the start of the
information field (though the IRD's messages do).

Note that if a command is sent with an incorrect checksum, the CAM will respond
with one of the following messages:

12 81 00 93 -or-
12 91 00 83
| | | |_ Checksum
| | |____ Info field size (no data in this response)
| |_______ Error response: Parity/LRC error
|__________ NAD

This is an indication of an error condition either in the LRC or a parity error


with one of the bytes of the message.

Other control requests all follow a common format as follows:

% 1 1 R 0 0 0 T T
|_| | |_|
| | |___ Request type as follows:
| | 00=Resync (complete reset)
| | 01=IFS (Information Field Size)
| | 10=Abort
| | 11=WTX (Wait time)
| |____________ Request/Response (0=request, 1=response)
|_______________ "11" in bits 7-6 indicates "control request"

For an IFS request, a single byte of data will be included that tells the target
what size the source would like it to change its IFS to. Note that although it
is theoretically possible to request that the card change its IFS to a value
larger than the one specified in the ATR, the target would probably not respond
favorably to such a request. A sample IFS request might look like this:

21 C1 01 68 89 Receiver requests card change its IFS to 0x58 bytes


12 E1 01 68 9A Card acknowledges request
|
|________ Requested IFS

Note that it is necessary to command the card to adjust its IFS after resetting
it, since the NagraVision cards default their IFS to $20 when they are reset.
As a result, any commands whose response is > $20 bytes either have deal with a
response that is chained, or the IFS has to be adjusted upwards. Note that the
cards don't do any sort of sanity checking against the IFS on received messages.
Oops.

For a WTX request, a single byte of data will be included that tells the target
what new value the source would like it to use as a block wait time when the
target is sending data to the source. This value is a multiple of the Block
Wait Time (BWT) specified by the source in its ATR.

The LEN byte is fairly straightforward: It specifies the total number of bytes
to be included in the information field.

The LRC byte is the checksum for the message. Note that this can either be an
LRC (which is what NagraVision uses) or a CRC.

1.2.1- Chained messages


When chained messages are used (either from the IRD to the CAM or from the CAM
to the IRD), the device receiving the split-up message must return a response
block to the sending device indicating that it received each block of data
correctly, so that the sending device knows that it's okay to move on to the
next block of data. The response block that must be sent depends on the NAD and
PCB of the message being ACKed, as follows:

NAD and PCB of source message Response message


----------------------------- --------------------------------
21 20 12 80 00 92
21 60 12 90 00 82
12 20 21 80 00 A1
12 60 21 90 00 B1

If the receiving device sends a response whose PCB indicates that an error of
some sort was detected, the sending device will resend the block that was in
error. If the receiving device sends some message that performs a request of
any kind, it can expect the sending device to abort the remainder of the
transmission and respond to its request.

1.3- NagraVision's packet structure II: The IRD-to-CAM information field


For the most part, all NagraVision messages will have an information field with
a common structure. Since the IRD and the CAM have free reign over the use of
the information field of an information block, we have to make guesses as to the
definition of certain fields. Fortunately, the data is repetitive enough that
we can make some pretty good guesses.

For data being transferred from the IRD to the CAM, the information field (not
including the checksum) will always look like this:

A0 CA 00 00 CL CN DL <data0..dataDL-1> RL
|____ ____| | | | | |_ Expected length of response
| | | | |_____ Command data...total of DL bytes
| | | | will be sent, including RL
| | | |______________________ Command Data length
| | |_________________________ Command Number
| |____________________________ Command Length. Note that this
| is essentially the ISO-7816 T=0
| "P3" (or length) byte.
|____________________________________ Header: Always A0 CA 00 00. Note
that these are essentially the
ISO-7816 T=0 "CLA INS P1 P2"
bytes.

Note that there are two length bytes. Command Length (CL) and command Data
Length (DL). In actual practice, DL should always be equal to CL minus 2, since
CL counts the Command Number (CN) and the command Data Length byte (DL) in its
total.

Note also that although CL and DL define the number of bytes that will be
present in the entire message, these numbers may be larger than the overall size
of the receive buffer in the smartcard. These bytes are what the card uses to
determine how many bytes the entire packet will contain after being put back
together (the LEN byte always specifies the total number of bytes to be sent in
a single burst).

Note also that the IRD indicates how much data it wants to see back from the
CAM. The Response Length byte (RL) specifies how many bytes of data the IRD
expects to see in the CAM's response, not including the 3-byte ISO-7816 header
and the SW1/SW2/LRC trailer. Thus, if the IRD specifies a value of 03 for the
RL, the CAM will send a total of 9 bytes back (3 bytes of ISO-7816 header, 1
byte of response type, 1 byte of data length, 1 byte of data, 2 bytes of SW1/SW2
info, and 1 byte of LRC). Note that the only time the response length byte is
actually used to determine how many bytes of data will be sent back to the IRD
is for command $21. All other commands have fixed-length responses which they
send without regard to that value of the value of the response length byte.

1.4- NagraVision's packet structure III: The CAM-to-IRD information field


When the CAM responds to a command from the IRD, its information field also
has a rigidly defined structure. Although this structure is different from that
of the IRD-to-CAM messages, it's not too tough to figure out.

Messages sent from the CAM to the IRD look like this:

CC AL <data1..dataAL> SW1 SW2


| | | |_____|__________ Standard ISO-7816 status word.
| | | Usually 90 00. For further
| | | information about the status word,
| | | see section 1.5, "The status word".
| | |__________________ Data being returned to IRD. This
| | data field may have several data
| | elements embedded within.
| |__________________________________ Length of data field in bytes.
| This byte will usually be equal
| to RL-2 (see section 1.3 for an
| explanation of the value of RL).
|_____________________________________ Command response code. This is
related directly to the command
number for which this message is a
response. There's no apparent
set relationship between the
response code and the command no.,
but each command number does
relate to a specific response code
(see section 2: Commands)
1.5- The status word
At the end of the information field in any response from the CAM to the IRD,
there are two bytes defined by the ISO-7816 specification as the "Status word".
The status word's intent is to give the host some idea of how well the card was
able to comply with the host's request. Usually, you hope to see a status word
of "90 00", which indicates a successful completion of the host command. In
some cases, however, other responses may be seen. If the first byte of the
status word has a "6" as its upper nibble, the status word indicates an error
condition. Status words that are likely to be returned by the EchoStar/Nagra
smartcards are as follows:

SW1 SW2 Meaning


------ ------ -----------------------------------------------
63 00 Password(s) incorrect
69 82 Need password for access to backdoor commands
69 85 EEPROM data area pointer no good (Doesn't point to
an address in the $Exxx range)
69 86 Bad address in backdoor read/write memory command
6A 00 P1 and/or P2 byte incorrect
6B 00 Incorrect reference
6C FF Requested too few data bytes in $21 command
6D 00 Instruction not supported
6E 00 CLA not supported
6E 00 P1 and/or P2 byte incorrect (note: This is a bug in
the ROM3 code...in theory, this situation should
produce an SW1/SW2 of 6A 00, but it doesn't (in fact,
nothing does))
6F 00 Command not supported
90 00 Command completed successfully
2: Commands

2.1- Known command list


Following is a list of all the commands I know about at this point. It's a real
good bet there's others, and as I find them (or as they're pointed out to me),
they'll be added here.

Cmd # Function
----- ------------------------------------------------------------------
$00 Entitlement Management Message (EMM)
$01 PPV Entitlement Management Message
$02 MECM key update
$03 Entitlement Control Message
$12 Serial Number Request
$13 Control Word Request (video decryption key request)
$14 Processing cycle request
$20 Data items available request
$21 Data item request
$30 Request for encryption of data to be sent in callback
$31 Request for data encrypted by previous command $30
$40 EEPROM data space available request
$41 PPV buy write
$42 PPV buy link
$55 Read email
$56 Delete email
$60 Get IRD command
$61 Write IRD info
$99 Anti-piracy message
$C0 CAM status request
$C1 Request for ID of updated data items

2.2- Command lengths, expected replies, and reply lengths


Most NagraVision commands are fixed-length, though there are some (like command
$03) whose length varies depending on the data in the command. In addition, for
any command that the IRD sends to the CAM, there's a specific response that the
IRD expects. In most cases, the IRD specifies the total length of data it
expects back to the response as the last byte of the information field.

Expected Response
Cmd # Length response length
----- ------ -------- --------
$00 $53 $80 $07
$01 $56 $81 $07
$02 $53 $82 $07
$03 variable $83 $07
$12 $08 $92 $08
$13 $09 $93 $1B
$14 $08 $94 $08
$20 $0C $A0 $05
$21 $0D $A1 variable
$30 $0B $F0 $07
$31 $08 $F1 $54
$40 $08 $70 $04
$41 variable $71 $05
$42 $0F $72 $05
$55 $0B $D5 $08
$56 $0B $D6 $08
$60 $08 $E0 $44
$61 $1C $E1 $03
$99 $20 $99 $1C
$C0 $08 $B0 $08
$C1 $08 $B1 $06

2.3- Command breakdown


Here, we'll be examining each command in detail, discussing their functions,
data structures, etc.

2.3.1- Command $00/Response $80


This command is used to perform all manner of changes to the card: Updates to
code in EEPROM, attacks against hacked cards, key changes, customer
subscription, customer desubscription, and so on. The data for this command is
a 64-byte block which contains subcommands of its own. These subcommands can be
anything from "change spending limit" to "execute embedded code from RAM".

Note that although the data block is always 64 bytes long, not all of the bytes
are necessarily used. The data block is padded to 64 bytes, probably with
random data, prior to encryption. Immediately preceding the 64 byte data block
is an 8-byte signature which is computed based on the unencrypted data to
confirm that the data is authentic before the commands within are executed. In
the DVB world, this type of message is referred to as an Entitlement Management
Message, or EMM. The 00 EMM is a public EMM, though it may be directed at a
specific group of cards.

Example of a $00 command and its response:

21 40 53 ; A0 CA 00 00 ;Standard header
4D ;Command length
00 ;Command
4B ;Command data length
01 01 ;System ID ($0101=EchoStar)
82 ;Key select byte (see below)
DC E9 1B 55 89 A0 D5 22 ;Signature
16 48 08 B1 A4 84 8F 2B ;Encrypted packet number 1
3B DA AC 07 A2 31 B0 83 ;Encrypted packet number 2
E2 27 5D 47 C8 27 D5 0E ;Encrypted packet number 3
7C 9C A6 51 E5 0D FE 18 ;Encrypted packet number 4
54 04 80 26 49 FC A6 71 ;Encrypted packet number 5
B2 F4 69 51 0C 22 B7 24 ;Encrypted packet number 6
BF 7E 3F 64 D0 1A BC 24 ;Encrypted packet number 7
F3 6E 88 6E 69 0F 0F 61 ;Encrypted packet number 8
05 ;Expected response length
EB ;Checksum

12 40 07 ; 80 ;Standard header, response code


03 ;Response data length
B1 01 ;Decode succeeded
04 ;Sequence number
90 00 ;SW1/SW2
F2 ;Checksum
And a decrypted 00 packet (not the one above, though):

3F 01 01 ;EMM filter: All cards whose


; primary provider has a system
; ID of 0101.
60 0A ;NOP on ROM3 cards
42 05 88 4E 25 22 BF 91 4A E4 ;Update key 0
42 85 DF 6A 21 6A 46 A8 19 2D ;Update key 1
20 00 33 00 00 00 0F 06 08 ;Update expiration + rights date
21 0C 21 0C 21 ; for all type $08..$0B data
; items with a rights ID of
; $000000 to $0C21 (1/1/98)
00 ;End of EMM commands

03 B5 4C 31 71 19 5A 9B ;Random data to make attack more


C0 C5 C9 32 88 03 8D B2 ; difficult
E6 8C 45 CA 20 A1 06 CD

Key select byte: This byte is used to select which EMM decrypt key set is used
(EMMKEY0 or EMMKEY1), and which parity key within that EMM key is used (0, 1, or
2). This byte is encoded as follows:

% x x x x x x x x
| | | | | | |_|__ Parity key select: 0, 1, or 2. Note: No sanity
| | | | | | checking is done on this. (see below)
| | | | | |______ unknown
| | | | |________ Key type select bit. (see below)
| | | |__________ unknown
| | |____________ unknown
| |______________ unknown
|________________ unknown

Parity key select: These two bits allow one of three 15-byte parity keys within
the selected EMM key to be used. No sanity checking is done on this data, so a
value of 3 is also valid, and causes the verify key plus the first 7 bytes of
the EMM key to be used as the parity key.

Key type select bit: This bit is used to match against the "key type" byte in
the type $07 data item. If this bit is clear, a key type byte of 0 will be
matched, if it is set, a key type byte of $01 will be matched.

As you can see, the first $28 bytes of decrypted data are EMM commands (see
section 3, EMM commands), and the last $18 bytes are just random data that
exists only to reduce the chances of two encrypted 00 commands looking even
remotely alike.

2.3.2- Command $01/Response $81


Command 01 is a PPV purchase-related EMM message. Like command $00, it contains
a 64-byte encrypted data field, which contains the EMM commands required to
enable the viewing of the purchased PPV (ie., add PPV data item). The format
for this command is as follows:

21 00 53 ; A0 CA 00 00 ;Standard header
4D ;Command length
01 ;Command
4B ;Command data length
01 01 ;System ID
82 ;Key select byte
00 00 00 00 00 00 00 00 ;Unused
00 11 22 33 44 55 66 77 ;Encrypted packet number 1
88 99 AA BB CC DD EE FF ;Encrypted packet number 2
00 11 22 33 44 55 66 77 ;Encrypted packet number 3
88 99 AA BB CC DD EE FF ;Encrypted packet number 4
00 11 22 33 44 55 66 77 ;Encrypted packet number 5
88 99 AA BB CC DD EE FF ;Encrypted packet number 6
00 11 22 33 44 55 66 77 ;Encrypted packet number 7
88 99 AA BB CC DD EE FF ;Encrypted packet number 8: valid hash
05 ;Expected response length
80 ;Checksum

12 00 07 ; 81 ;Response type
03 ;Response data length
B1 01 ;Decode succeeded
05 ;Sequence number
90 00 ;SW1/SW2
B2 ;Checksum

2.3.3- Command $02/Response $82


Command 02 is the command used to update MECM decryption keys in the CAM. MECM
decryption is used in conjunction with the standard command $03 decryption:
After the control words in a given $03 command are decrypted, they are XORed
with an 8-byte hunk of the MECM key before re-encrypting them and returning them
to the IRD. The format for the $02 command is as follows:

21 00 53 ; A0 CA 00 00 ;Standard header
4D ;Command length
02 ;Command
4B ;Command data length
01 01 ;System ID
01 ;Key select byte
00 00 00 00 00 00 00 00 ;Unused
00 11 22 33 44 55 66 77 ;Encrypted packet 1
88 99 AA BB CC DD EE FF ;Encrypted packet 2
00 11 22 33 44 55 66 77 ;Encrypted packet 3
88 99 AA BB CC DD EE FF ;Encrypted packet 4
00 11 22 33 44 55 66 77 ;Encrypted packet 5
88 99 AA BB CC DD EE FF ;Encrypted packet 6
00 11 22 33 44 55 66 77 ;Encrypted packet 7
88 99 AA BB CC DD EE FF ;Encrypted packet 8: valid hash
05 ;Expected response length
08 ;Checksum

Once the ciphertext block is decrypted, the computed hash value of the first 7
blocks of decrypted data is compared to the valid hash, which is stored in the
last 8 bytes of encrypted data. If the valid hash matches, 17 bytes of the
decrypted data are then used as MECM decrypt data. The structure of the data
within the encrypted block is as follows:

00 00 ;Probably system ID
00 ;Probably key select byte
01 ;MECM data start address (see below)
00 11 22 33 44 55 66 77 ;MECM key data (16 bytes)
88 99 AA BB CC DD EE FF
00 00 00 00 ;Unknown, probably random data
00 00 00 00 00 00 00 00 ;Unknown, probably random data
00 00 00 00 00 00 00 00 ;Unknown, probably random data
00 00 00 00 00 00 00 00 ;Unknown, probably random data
00 00 00 00 00 00 00 00 ;Unknown, probably random data
01 23 45 67 89 AB CD EF ;Valid hash

MECM start address: This byte tells the CAM the addresses within the full 256-
byte MECM key the 16-byte block of data included with this command $02
represents. It appears as though the CAM is able to hold 16 only bytes of the
full 256 byte MECM key, so the MECM start address is used to tell the CAM which
byte of the overall key is the first one it has in its 16-byte buffer. So, for
example, a MECM start address of 0x12 specifies that the 02 command includes
bytes 0x24 thru 0x33 of the entire MECM key.

Since the CAM always remembers only 16 bytes of the overall MECM key, the 03
commands that intend to use the MECM data also include a start address which
tells the CAM the address within the full 256-byte MECM key at which the 8-byte
block the CAM should XOR a decrypted control word with starts.

Note that the start address requested by a 03 command can only ever be larger in
magnatude than the start address in the most recent 02 command by a value of 4
(ie., if the start address in the most recent 02 command was 0x12 (MECM bytes
0x24 thru 0x33), the maximum start address allowed in a 03 command is 0x16 (MECM
bytes 0x2C thru 0x33).

2.3.4- Command $03/Response $83


This command is used to prime the card to return video decryption keys to the
IRD. Contained within this command's encrypted packets are information
pertaining to the program tier the user is attempting to view, the correct audio
and video decryption keys for the channel, current date and time, and so forth.
When a card receives a $13 command, it will re-encrypt the decryption keys using
the IRD's 8-byte key and return them to the IRD if it (the card) believes that
the program tier that the user is attempting to watch is one for which they are
authorized.

In addition to information about the program that the user is attempting to


watch, the 03 command contains information about the encryption method used, how
many encrypted video keys are present, and so forth. For a detailed explanation
of the control bytes, see the breakdown of the decrypted packets, below.

Example of a $03 command, both encrypted and decrypted, and its response:

21 00 35 ; A0 CA 00 00 ;Standard header
2F ;Instruction length
03 ;Command
2D ;Command data length
01 01 ;System ID
10 ;ECM type
29 ;Data field length
05 ;Key select byte (see below)
12 D4 70 4D 34 FB 3C DF ;Valid hash (signature)
90 DD 23 D3 7B A9 79 DC ;Encrypted packet 1
CF DE 68 4E A4 43 0F 1B ;Encrypted packet 2
F5 E0 9B B3 30 58 FB 75 ;Encrypted packet 3
4F 3E AB EB 4C 8F F0 6F ;Encrypted packet 4
05 ;Expected response length
29 ;Checksum
12 00 07 ; 83 ;Response code
03 ;Response data length
B1 01 ;Decode succeeded
03 ;Sequence number
90 00 ;SW1/SW2: Successful completion
B6 ;Checksum

Here's what the data in the encrypted packets looks like after decryption:

10 ;Control word control byte (see below)


80 ;MECM index byte 1 (see below)
39 31 33 9D 31 32 35 98 ;Control word 1
80 ;MECM index byte 2 (see below)
34 30 32 96 34 35 34 9D ;Control word 2
24 ;Tier info tag byte: Group access
01 ;Group ID
0D 86 ;Current date
B3 54 ;Current time
00 ;End of standard data marker
55 55 55 55 55 55 ;Pad bytes to make encrypted data come
;out to a multiple of 8 bytes

Key select byte: This byte is used to tell the $03 decode routine which public
key (if any) was used to encrypt the data in the 03 command. If the low 3 bits
of this byte are "101", then the CAM uses the standard E* DES-like decrypt on
the data. If the low 3 bits are "111", the CAM doesn't perform any decryption
on the data at all. If the low 3 bits are anything other than "101" or "111",
the CAM discards the packet. Bit 4 of this byte indicates which public key was
used: 0 for key 0, 1 for key 1. Bit 3 is a flag which selects which verify key
is used to compute the signature for the message.

Control word control byte: If this byte is $10, then the CAM knows that two
control words are present. If this byte is $11, then the CAM only tries to
decrypt the first control word, but it returns it as the second return word
in the next command 13.

MECM index byte: If bit 7 of this byte is clear, then before the CAM re-encrypts
the control words for return to the IRD, it XORs them with a sequence of bytes
that come from a $02 command. The $02 command includes 16 bytes of MECM data
and an address byte which tells the CAM which 16 bytes of the 256-byte MECM key
the CAM currently knows about. The 03 command's MECM index byte specifies the
address within the full 256-byte MECM key of the first of 8 bytes to be XORed
with its control word. So, for example, a MECM index byte in a 03 command with
a value of 0x14 specifies that bytes 0x28 thru 0x2F (0x14*2 thru (0x14*2)+7) are
to be XORed with the decrypted control words before re-encryption and return to
the IRD. If the index byte in the 03 command refers to any data that is outside
the range of MECM data currently known to the CAM, the CAM will invalidate its
current MECM data and set the "CAM suggests $02 command" bit in the C0 status
response, prompting the IRD to provide it with the most recent 02 command it
(the IRD) knows about.

Note that the above version of the 03 packet is a "group access" packet, which
is usually used to provide access to free informational channels (with programs
like Charlie Chat). An example of a $03 command that requires a specific
program tier might look like this:

21 00 3D ; A0 CA 00 00 ;Standard header
37 ;Instruction length
03 ;Command
35 ;Command data length
01 01 ;System ID. $0101=EchoStar
10 ;Control word tag byte
31 ;Data field length
05 ;Key select byte
B8 2E A0 FF B4 F9 2C 2F ;Valid hash (signature)
3C 4F C7 CB 26 E1 FF 3E ;Encrypted packet 1
C0 4D F2 6F 37 C3 22 8D ;Encrypted packet 2
4B 42 B2 BC 99 15 3B D4 ;Encrypted packet 3
5D 95 0D 0A 93 57 0F 7A ;Encrypted packet 4
69 50 D7 4E 2C B5 ED CB ;Encrypted packet 5
05 ;Expected response length
A6 ;Checksum

12 00 07 ; 83 ;Response code
03 ;Response data length
B1 01 ;Decode succeeded
03 ;Sequence number
90 00 ;SW1/SW2: Successful completion
B6 ;Checksum

And the decrypted data...

10 ;Control word tag byte


80 ;MECM index byte 1
33 36 34 9D 34 30 35 99 ;Control word 1
80 ;MECM index byte 2
36 31 32 99 30 33 39 9C ;Control word 2
20 ;Tier info tag byte: Straight sub
00 1D ;Tier ID
80 00 ;Component (?)
FF ;Theme (?)
00 ;Level (?)
0D 8C ;Program start date (12 Dec 1998)
88 00 ;Program start time (17:00:00 GMT)
0D 8C ;Current date (12 Dec 1998)
92 16 ;Current time (18:16:22 GMT)
00 ;End of data marker
55 55 55 55 55 ;Pad bytes

Time-of-day info: The E* time of day seems to be encoded as follows:

Date Time
---------------------------- ------------------------------
Bits 0..4=day 1-31 Bits 0..4=second/2 0-29
Bits 5..8=month 1-12 Bits 5..10=minute 0-59
Bits 9..15=year-1992 0-127 Bits 11..15=hour 0-23

Further notes about the 03 packet: The two control words, the MECM control
bytes, and the control word control byte must ALWAYS be located at the start of
the encrypted data as shown above. The NagraVision CAM is hard-coded to expect
the control word data and associated control bytes to be in those locations.

Within the ECM, lots of commands and filters are possible. The first variable
is the ECM type:

21 00 35 ; A0 CA 00 00 ;Standard header
2F ;Instruction length
03 ;Command
2D ;Command data length
01 01 ;System ID
>>> 10 ;ECM type
29 ;Data field length
05 ;Key select byte (see below)
12 D4 70 4D 34 FB 3C DF ;Valid hash (signature)
90 DD 23 D3 7B A9 79 DC ;Encrypted packet 1
CF DE 68 4E A4 43 0F 1B ;Encrypted packet 2
F5 E0 9B B3 30 58 FB 75 ;Encrypted packet 3
4F 3E AB EB 4C 8F F0 6F ;Encrypted packet 4
05 ;Expected response length
29 ;Checksum

Valid ECM types are:

Type Description
---- ---------------------------------------------------------
$10 Double control-word ECM
$11 Even control-word-only ECM
$12 Odd control-word-only ECM

ECM types $10, $11, and $12 all have packets that should look pretty much the
same, except that type 10 contains even and odd control words, type 11 only
contains an even control word, and type 12 only contains an odd control word.
In addition to the control words, ECM types 10, 11, and 12 also can contain a
variety of data filtering fields. These fields allow the CAM to decide if the
user is authorized to view the program of not. Below is an example of a
decrypted type 10 ECM:

10 ;Control word control byte (see below)


80 ;MECM index byte 1
39 31 33 9D 31 32 35 98 ;Even control word
80 ;MECM index byte 2 (see below)
34 30 32 96 34 35 34 9D ;Odd control word
>>> 24 ;Filter type byte
01 ;Access group ID
0D 86 ;Current date (6 Dec 1998)
B3 54 ;Current time (22:26:20 GMT)
00 ;End of standard data marker
55 55 55 55 55 55 ;Pad bytes to make encrypted data come
;out to a multiple of 8 bytes

In this case, the ECM command is 24, which indicates group-controlled


access. Valid ECM commands and their formats are:

Type Description/Format
---- ----------------------------------------------------------
$20 Straight subscription
20 ;Filter type
01 02 ;Tier ID
01 02 ;"Component"
01 ;Theme (program type?)
01 ;Level (Rating?)
01 02 ;Program start date
03 04 ;Program start time
01 02 ;Current date
03 04 ;Current time

$21 Pay-per-view (see notes below)


21 ;Filter type
01 02 03 ;PPV ID
01 ;"Watched" odometer threshold (see
; below)
01 02 ;PPV token cost in units (hex) per ECM
03 ;PPV token cost in 1/100 units per ECM
01 02 ;PPV cash cost in units (hex) per ECM
03 ;PPV cash cost in 1/100 units per ECM

$22 Program type blackout (see notes below)

$23 Regional blackout (see notes below)

$24 Group access


24 ;Filter type
01 ;Group ID
01 02 ;Current date
03 04 ;Current time

For ECM command 21, it appears that various charge options are available: The
program provider can choose to charge once for the impulse buy and leave it at
that (which is the most common mode of usage), or allow "tokens" to be bought
which can be deducted in varying amounts when the user tunes to the event. In
addition, both cash and tokens can be applied per unit of time, so the longer
the user watches, the more they have to pay.

The "watched" odometer threshold tells the card how many ECMs may be processed
for a given PPV data item before that PPV is considered "watched" and must
therefore be charged to the customer.

Note that although ECM command $21 contains sufficient information to validate
an ECM, it will usually be preceded by an ECM command $20 which provides a tier
ID, component, theme, level, and time/date info. Presumably, this is so that
employees of program providers can have subscriptions in their cards which allow
them to watch any PPV they want at any time.

The two blackout ECM commands ($22 and $23) allow the card to decide whether or
not to return the control words for a given channel based on the blackout
information stored in the type $06 data item whose system ID high matches the
system ID high of the ECM. Note that if a blackout ECM command is used, no tier
ID is needed. The two blackout ECM commands are formatted as follows:

22 ;ECM command: Program type blackout


41 ;Blackout category (see below)
01 ;Program type

23 ;ECM command: Regional blackout


43 ;Blackout category (see below)
00 00 80 00 00 00 00 00 ;Blackout bitmap (16 bytes)
00 00 00 00 04 00 00 00

Blackout category: This byte controls the blackout command. It consists of


three fields, as follows:

% x 1 x x x x x x
| | |_________|__ Bits 0..5: Blackout data byte pointer
| |______________ Bit 6: Sanity flag
|________________ Bit 7: Viewability flag

The blackout data pointer specifies which of the 12 bytes of blackout info in
the appropriate type $06 data item is to be used to determine whether the
program is blacked out. This value is sanity-checked, and if it is found to be
greater than $0C (the total number of blackout info bytes in a type $06 data
item), the blackout command is assumed to have reached a "program not viewable"
conclusion, and the next ECM command is executed. If this pointer is found to
be valid, the byte it specifies within the blackout info bytes is retrieved and
operated on to determine whether the program is blacked out.

For example, a blackout data byte pointer of $00 would mean that the first
blackout info byte in the appropriate type $06 data item is to be used to
determine whether the program is blacked out. How that byte is used depends on
whether the blackout command was $22 (program type) or $23 (regional).

For a $22 ECM command (program type blackout), the byte identified by this
pointer is compared to the "program type" byte included in the ECM command. If
the two match, a blackout match is declared (see "viewability flag", below for
further information on what happens in the event of a blackout match). This
would allow, for example, programming which is illegal (say, hard-core
pornography) in a customer's city/county/state to be rendered unviewable.

For a $23 ECM command (regional blackout), the byte identified by the blackout
category byte is treated as a bit number within the blackout bitmap which is to
be tested. If the specified bit is set, then a blackout match is declared.
This would allow sporting events to be blacked out in their local markets in the
event the event did not sell out, and so on. It could also be used to allow (or
disallow) specific types of program by region. The blackout data byte pointer
in this case would point to a byte in the blackout info data which contains a
region code. The ECM command contains a 256-bit bitmap which indicates for
which regions a blackout match should be declared (see "viewability flag", below
for further information on what happens in the event of a blackout match).

The sanity flag bit must always be set. If it is found to be clear, the
entire ECM is treated as insane and discarded.

The viewability flag determines the default (no match) "viewability" state of
the program. If the viewability flag is 0 and no match occurs, the card moves
on to the next ECM command to decide whether the program is viewable. If the
viewability flag is 0 and a blackout match occurs, the card declares a "program
valid" condition, and returns the control words to the IRD. Note that the
viewability flag can be set to '1' by default. In this event, the program is
viewable (and control words are returned) if a blackout match does NOT occur,
and a blackout match would cause the program to be unviewable.

2.3.5- Command $12/Response $92


This command is used by the IRD to request the CAM's serial number. If you look
at the underside of your CAM, you'll see a 12-digit, bar-coded number. This
number is your CAM ID, and every CAM has a unique one. The first 10 digits of
the number are significant, and the last 2 are a 2-digit check code. If you take
the 10-digit serial number and convert it to hex, you'll have your card's hex
CAM ID. For example, let's say your card's serial number is 00 5738 6394 07.
In this case, the serial number is 57386934. In hex, that would be 36BA59A.
The $12 packet and its response for this CAM would look like this:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
12 ;Command
00 ;Command data length
06 ;Expected response length
55 ;Checksum

12 00 08 ; 92 ;Response code
04 ;Response data length
03 6B A5 9A ;CAM ID: 036BA59A (00 5738 6394 07)
90 00 ;SW1/SW2: Successful completion
4B ;Checksum

Note that the two-digit check code isn't included as part of the response. This
check code is only used by the Dish Network customer service drone to ensure
that you do (or at one time did), in fact, have physical possession of the card
when you call to subscribe.

2.3.6- Command $13/Response $93


This command is used by the IRD to request the decryption keys for the channel
to which the IRD is currently tuned. This command is a counterpart to command
$03- The decryption keys are sent from the IRD to the CAM in an encrypted form
that the IRD doesn't know how to decode along with information that tells the
CAM which channel the IRD is tuned to. If the CAM decides that the user should
be able to view the specified channel (ie., if there is a valid subscription
tier in the CAM for the specified channel), then when the next $13 command is
issued, the CAM will decrypt the data it was given in the $03 command, re-
encrypt it using a key and method known to the IRD, and send the data back to
the IRD, which will then decrypt the data and use it to decrypt the video and
audio data streams. A typical $13 packet and it's associated response would
look like this:

21 00 09 ; A0 CA 00 00 ;Standard header
03 ;Instruction length
13 ;Command
01 ;Command data length
03 ;Command data
19 ;Expected response length
48 ;Checksum

12 00 1B ; 93 ;Response code
17 ;Response data
B1 01 ;Decode succeeded
06 ;Sequence number
11 ;Video key 1 header
08 ;Video key length
11 22 33 44 55 66 77 88 ;Encrypted even control word
12 ;Video key 2 header
08 ;Video key length
11 22 33 44 55 66 77 88 ;Encrypted odd control word
90 00 ;SW1/SW2: Successful completion
A8 ;Checksum

Note: If the card is using the MECM extension, once the box has finished
decoding the 13 command, it will need to XOR the video keys with the same data
the CAM did, if it expects to recover the raw data that was present in the 03
command. Note also that regardless of whether the 03 command had a $10 or $11
control byte (indicating the presence of two or one control words,
respectively), the 13 command will ALWAYS have two control words in it, and
will always be formatted as above.

Also note: If the IRD is requesting keys for a channel that the CAM thinks it's
not authorized for, the CAM will return all 00s for the encrypted video keys.
2.3.7- Command $14/Response $94
I don't know much about this command, other than the fact that it's always the
same in virgin cards. An example of a virgin $14 command is:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
14 ;Command
00 ;Command data length
06 ;Expected response length
53 ;Checksum

12 00 08 ; 94 ;Response code
04 ;Response data length
0F 4C 54 60 ;Data
90 00 ;SW1/SW2: Successful completion
6D ;Checksum

The last byte of the 4-byte block of returned data is the CAM's firmware
revision status flag. This byte changes as firmware updates happen.

2.3.8- Command $20/Response $A0


This command is used by the IRD to ask the CAM whether it has any data of a
specific type stored inside it. Basically, the $20 command is a poll for
"number of data items to report". If the CAM responds with a non-zero value,
the IRD will then proceed with appropriate $21 commands to get the data from the
CAM. An example of the $20 command would look like this:

21 00 0C ; A0 CA 00 00 ;Standard header
06 ;Instruction length
20 ;Command
04 ;Command data length
01 ;Data type being queried
;(see section 4, "data types")
02 ;Second data field length
FF FF ;Misc. data
03 ;Expected response length
65 ;Checksum

12 00 05 ; A0 ;Response code
01 ;Response data length
01 ;Number of data items to return
90 00 ;SW1/SW2: Successful completion
27 ;Checksum

For further information on data types, see section 4, "data types".

2.3.9- Command $21/Response $A1


This command is used by the IRD to actually request data from the CAM. The IRD
should only send this command if it receives a non-zero value from the CAM in
response to the $20 command for the requested data type. Each data type has its
own response length and structure. An example of a 21 command is as follows:

21 00 0D ; A0 CA 00 00 ;Standard header
07 ;Instruction length
21 ;Command
05 ;Command data length
01 ;Data type being requested
;(see section 4, "data types")
03 ;Second data field length
FF FF ;Misc. data
00 ;Element number being requested
20 ;Expected response length
47 ;Checksum

Note that the IRD already knows how long the response to its query should be.
This is because most data types are fixed-length. For data types that are NOT
fixed-length, the data will always have a fixed-length field to start, and one
or more variable-length fields to follow. An example of a series of 21 commands
that retrieve a variable-length data item is as follows:

21 40 0D ; A0 CA 00 00 ;Standard header
07 ;Instruction length
21 ;Command
05 ;Command data length
11 ;Data type
03 ;Second data field length
FF FF ;Misc. data
00 ;Element number being requested
04 ;Expected response length
33 ;Checksum

12 40 06 ; A1 ;Response code
02 ;Response data length
01 ;Subtype of data in this element
11 ;Length of this element
90 00 ;SW1/SW2: Successful completion
69 ;Checksum

21 00 0D ; A0 CA 00 00 ;Standard header
07 ;Instruction length
21 ;Command
05 ;Command data length
11 ;Data type
03 ;Second data field length
FF FF ;Misc. data
00 ;Element number being requested
15 ;Expected response length (note:
;Equals length reported by CAM above
;plus 4, to account for command
;overhead
64 ;Checksum

12 00 17 ; A1 ;Response code
13 ;Response data length
01 ;Data type to follow: date/time
0F 0E ;Purchase date: 14 Aug, 1999
35 28 :Purchase time: 06:41:16 GMT
00 ;End of date/time
44 65 65 70 20 49 6D
70 61 63 74 90 ;"Deep Impact" in ASCII
00 ;End of PPV title
90 00 ;SW1/SW2: Successful completion
0C ;Checksum (note no SW1/SW2)
21 40 0D ; A0 CA 00 00 ;Standard header
07 ;Instruction length
21 ;Command
05 ;Command data length
11 ;Data type
03 ;Second data field length
FF FF ;Misc. data
01 ;Element number being requested
04 ;Expected response length
32 ;Checksum

12 40 06 ; A1 ;Response code
02 ;Response data length
02 ;Subtype of data in this element
05 ;Length of this element
90 00 ;SW1/SW2: Successful completion
60 ;Checksum

21 00 0D ; A0 CA 00 00 ;Standard header
07 ;Instruction length
21 ;Command
05 ;Command data length
11 ;Data type
03 ;Second data field length
FF FF ;Misc. data
01 ;Element number being requested
09 ;Expected response length
7F ;Checksum

12 00 0B ; A1 ;Response code
07 ;Response data length
02 ;Data type to follow: Channel
05 ;Length of channel ID
50 50 56 31 31 ;"PPV11" in ASCII
90 00 ;SW1/SW2: Successful completion
7E ;Checksum

2.3.10- Command $30/Response $F0


This command seems to be a request for callback information. The IRD sends this
command to the CAM, then waits until the CAM has a response ready. When the
response is ready, the IRD requests the encoded callback data using the $31
command. An example of the $30 command looks like this:

21 00 0B ; A0 CA 00 00 ;Standard header
05 ;Instruction length
30 ;Command
03 ;Command data length
01 01 ;System ID for callback data
00 ;Block number being requested
05 ;Expected response length
73 ;Checksum

12 00 07 ; F0 ;Response code
03 ;Response data length
B1 01 ;Packet OK
01 ;Sequence number
90 00 ;SW1/SW2: Successful completion
C7 ;Checksum

For the "block number being requested", note that if a block number less than
$80 is requested, the card will perform it's callback initialization sequence.
In theory, the sequence of blocks requested would be $00, $81, $82, and so on.

2.3.11- Command $31/Response $F1


This command requests the return of the encoded callback data whose preparation
was requested by a $30 command. A total of $48 bytes of data are returned, the
first 8 of which are a valid hash value. I'm relatively certain that this
information is encrypted using the same algorithm as 00 and 01 commands, though
I don't know what key is used. The data in the example below is censored
because it may contain card-specific data. An example of the $31 command is as
follows:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
31 ;Command
00 ;Command data length
52 ;Expected response length
22 ;Checksum

12 00 54 ; F1 ;Response code
50 ;Response data length
B1 01 ;Decode succeeded
01 ;Sequence number
04 ;Length of status bytes
4B ;Length of callback data
01 01 ;System ID for callback data
xx ;Key select byte indicating which
; key was used to encrypt the data
xx xx xx xx xx xx xx xx ;Valid hash
xx xx xx xx xx xx xx xx ;Encrypted packet 1
xx xx xx xx xx xx xx xx ;Encrypted packet 2
xx xx xx xx xx xx xx xx ;Encrypted packet 3
xx xx xx xx xx xx xx xx ;Encrypted packet 4
xx xx xx xx xx xx xx xx ;Encrypted packet 5
xx xx xx xx xx xx xx xx ;Encrypted packet 6
xx xx xx xx xx xx xx xx ;Encrypted packet 7
xx xx xx xx xx xx xx xx ;Encrypted packet 8
90 00 ;SW1/SW2: Successful completion
xx ;Checksum

The encrypted packets contain the actual callback information to be sent to the
program provider. The information is encrypted using the same algorithm and key
that would be used to decrypt an EMM (command 00) with the same system ID as the
one included in the $30 command that produced the callback data. This means that
the data would be decrypted using the same algorithm and key as those used to
encrypt EMMs (most likely, the algorithm is the same for both encryption and
decryption, only the key differs). The format of the data, prior to encryption,
is as follows:

First packet:

04 ;Flag byte indicating next 7 bytes


; are CAM or provider information
xx xx ;System ID of provider
xx xx xx xx ;CAM ID
xx ;Block number passed in $30 command
10 ;Flag byte indicating next byte is
; packet number
xx ;Packet number
11 ;Flag byte indicating next byte is
; total # packets to be sent
xx ;Total # packets to be sent
50 ;Flag byte indicating next 20 bytes
; are IRD information
xx xx xx xx ;IRD number from type $01 data
xx xx xx xx xx xx xx xx ;IRD bootstrap version from type $01
xx xx xx xx xx xx xx xx ;IRD firmware version from type $01
51 ;Flag byte indicating next byte is
; CAM firmware update status byte
xx ;CAM firmware update status byte
52 ;Flag byte indicating next 11 bytes
; are spending limit info
xx xx xx ;Spending limit rights ID
xx xx xx ;Credit in cash
xx xx xx xx ;Debit in cash
xx xx ;Phone home threshold
53 ;If any PPVs exist to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date
00 00 00 00 00 00 00 ;These bytes are unused, and always 00

Packets 2 through N:

04 ;Flag byte indicating next 7 bytes


; are CAM or provider information
xx xx ;System ID of provider
xx xx xx xx ;CAM ID
xx ;Block number passed in $30 command
10 ;Flag byte indicating next byte is
; first PPV # reported in this packet
xx ;First PPV # reported in this packet
53 ;If a PPV exists to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date
53 ;If a PPV exists to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date
53 ;If a PPV exists to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date
53 ;If a PPV exists to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date
53 ;If a PPV exists to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date
53 ;If a PPV exists to be reported,
; 53 is a flag byte indicating that
; the next 8 bytes are PPV information
xx ;PPV's IRD flags byte
xx xx xx ;PPV rights ID
xx xx ;PPV purchase date
xx xx ;PPV expiration date

Note that up to 6 PPVs can be reported in packets after the first, and that the
packets are always padded to the end with 00s.

2.3.12- Command $40/Response $70


This command is a request for the CAM to tell us how much EEPROM space is
available for data storage. The CAM figures this out by starting at the
beginning of its data area, going through every data item it can find, adding
the length of each as it finds it, and subtracting the final result from the
total amount of EEPROM space known to be available. The result is returned in
the $70 response. An example of the $40 command might look like this:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
40 ;Command
00 ;Command data length
04 ;Expected response length
05 ;Checksum

12 00 06 ; 70 ;Response code
02 ;Response data length
0A 52 ;EEPROM space available: $A52 bytes
90 00 ;SW1/SW2: Successful completion
AE ;Checksum

Note that the returned value does not necessarily reflect the amount of
contiguous data space available in the card's EEPROM...the data storage
mechanism used in the E* CAM is sort of a crude flash file system kind of thing,
so when a data item is removed, the space it once occupied is considered to be
"available", even though that space may be wedged between two other active data
items. This approach makes the E* CAMs more flexible than the DSS CAMs, but
also means that the amount of code required to support the data storage system
is much larger.
2.3.13- Command $41/Response $71
The $41 command is used to create type $11 data items with various text
information such as movie title of PPV items, channel description of channel
records, etc. After a $41 command, a $42 command will be issued to link the
data from the $41 command to a specific data item of type $08..$0B so that when
the data item that the type $11 data item is linked to is deleted, the type $11
data item can be deleted as well. After a command $41 is issued to create a
type $11 data item, a command $42 (see below) should be issued to link the
newly-created string to a specific type $08..$0B data item within the card. If
no command $42 is issued to link a type $11 data item to a specific type
$08..$0B data item, then the unlinked type $11 data item will be deleted the
next time the card performs garbage collection.

An example of a type $41 command might look like this:

21 00 0B ; A0 CA 00 00 ;Standard header
05 ;Instruction length
41 ;Command
03 ;Command data length (note: I believe
;that if this value is >$7F, no data
;item is created
50 50 56 ;Command data (in this case, "PPV" in
; ASCII
03 ;Expected response length
52 ;Checksum

12 00 05 ; 71 ;Response code
01 ;Response data length
14 ;String ID of newly-created type $11
; data item
90 00 ;SW1/SW2: Successful completion
E3 ;Checksum

2.3.14- Command $42/Response $72


This command links a type $11 data item created with a command $41 to a specific
data type $08..$0B data item within the card. It does this by writing a user-
supplied string ID byte into the "string ID" field of the data item to be
linked. The string ID byte that should be sent with the $42 command is the
string ID that is returned in the response to the $41 command.

To link a type $11 item to a particular type $08..$0B data item, the SYSTEM ID
and RIGHTS IDENTIFIER of the data item to be linked to the type $11 item must be
supplied (so that the card can find the item to be linked), and the card must be
told what string ID to write to the item to be linked, and whether the string ID
byte should be written to the field at byte 7 (STRING ID for types $08..$0A, PPV
ID WITHIN CARD for type $0B), or byte F (STRING ID for type $0B). Note that
writing to byte F is not allowed for data types other than $0B.

An example of a 42 command that writes to a string ID at byte $07 is as follows:

21 00 0F ; A0 CA 00 00 ;Standard header
09 ;Instruction length
42 ;Command
07 ;Command data length
01 01 ;System ID of data item to link
7F 08 14 ;Rights identifier of data item to
; link
01 ;String ID to write
00 ;$00=String ID stored at byte 7
03 ;Expected response length
69 ;Checksum

12 00 05 ; 72 ;Response code
01 ;Response data length
01 ;String ID that was written
90 00 ;SW1/SW2: Successful completion
F5 ;Checksum

An example of a 42 command that writes to a string ID at byte $0F is as follows:

21 00 0F ; A0 CA 00 00 ;Standard header
09 ;Instruction length
42 ;Command
07 ;Command data length
01 01 ;System ID of data item to link
7F 08 14 ;Rights identifier of data item to
; link
01 ;String ID to write
01 ;non-zero=String ID stored at byte F
03 ;Expected response length
68 ;Checksum

12 00 05 ; 72 ;Response code
01 ;Response data length
01 ;String ID that was written
90 00 ;SW1/SW2: Successful completion
F5 ;Checksum

2.3.15- Command $55/Response $D5


The $55 command, is "mail read". It looks to me as though it marks a particular
type $10 data item as having been looked at. Three parameter bytes are passed
to the CAM and are used to search for the relevant type $10 entry:

The system ID and the Email ID (00..FF). If a matching EMail entry is found,
it is marked as "read" by setting bit 4 of the data item's "received" flags
byte. An example of a $55 command is as follows:

21 00 0B ; A0 CA 00 00 ;Standard header
05 ;Instruction length
55 ;Command
03 ;Command data length
01 01 ;System ID
01 ;Email entry to locate
06 ;Expected response length
14 ;Checksum

12 00 08 ; D5 ;Response code
04 ;Response data length
01 01 ;System ID
01 ;Email entry requested
00 ;00=match found, FF=no match
90 00 ;SW1/SW2: Successful completion
5A ;Checksum
2.3.16- Command $56/Response $D6
The $56 command's function is "delete mail". Like the $55 command, the $56
command is passed a system ID and mail ID to locate. If a matching entry is
found, the it will be marked such that the EEPROM space it had been occupying is
shown as "unused", and the Email itself is shown as "read and deleted". One
interesting thing to note is that there is an apparant bug with this command in
the ROM2 and ROM3 cards: if a matching entry is not found, the card will respond
with a $D5 command instead of the $D6 command that the IRD should be expecting.
An example of a $56 command is as follows:

21 00 0B ; A0 CA 00 00 ;Standard header
05 ;Instruction length
56 ;Command
03 ;Command data length
01 01 ;System ID
01 ;Email ID to locate
06 ;Expected response length
17 ;Checksum

12 00 08 ; D6 ;Response code
04 ;Response data length
01 01 ;System ID
01 ;Email entry requested
00 ;00=match found
90 00 ;SW1/SW2: Successful completion
59 ;Checksum

Note: If a match is not found, the response will look like this:

12 00 08 ; D5 ;Response code
04 ;Response data length
01 01 ;System ID
01 ;Email entry requested
FF ;00=match found
90 00 ;SW1/SW2: Successful completion
A5 ;Checksum

2.3.17- Command $60/Response $E0


The $60 command is a follow-up to some EMM commands. The function of the $60
command is probably "Get IRD command": Though I can't be certain, it would
appear that certain EMM commands can contain a command which is meant to be
decrypted and then interpreted by the IRD. This command could include such
functions as "write to EEPROM" (serial EEPROM, not flash memory), "phone home
and dump memory", etc. NOTE: It's possible that the phone home and dump memory
command could be used to get secret IRD keys. An example of the $60 command
might look like this:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
60 ;Command
00 ;Command data length
42 ;Expected response length
63 ;Checksum

12 00 44 ; E0 ;Response code
40 ;Response data length
xx xx xx xx xx xx xx xx ;Response data
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
90 00 ;SW1/SW2: Successful completion
xx ;Checksum

2.3.18- Command $61/Response $E1


The $61 command is used to write IRD-specific information to the CAM. It can be
used to write the serial number of the IRD as well as 16 bytes of miscellaneous
data that E* uses to store the version numbers of the bootstrap and firmware in
the IRD. The format of the 61 command is as follows:

21 00 1C ; A0 CA 00 00 ;Standard header
16 ;Instruction length
61 ;Command
14 ;Command data length
33 22 11 00 ;IRD serial number
aa aa aa aa aa aa aa aa ;IRD firmware info in ASCII
aa aa aa aa aa aa aa aa
03 ;Expected response length
xx ;Checksum

12 00 05 ; E1 ;Response code
01 ;Response data length
00 ;Response data (always 00)
90 00 ;SW1/SW2: Successful completion
67 ;Checksum

2.3.19- Command $99/Response $99


The $99 command is NagraVision's equivalent of the ZKT test that DTV IRDs
perform on their cards to verify their authenticity. Note that because ROM2
cards don't support this command, the IRDs must do some sort of version number
check to decide whether or not this command should be sent. The authenticity
check is performed by XORing the 24 bytes of input data with the ASCII string
"NipPEr Is a buTt liCkeR!", then DES encrypts the result with a special command
99 key, which is stored in EEPROM following the "NipPEr..." string. The key is
0x45 0x71 0xF6 0x01 0x9A 0xD8 0x5D 0x86. If you send the "NipPEr..." string as
the 24 bytes of input data, you get 3 identical 8-byte response blocks back from
the card. Nagra's check isn't nearly as robust as NDS's though...NDS's not only
convinces the receiver of the card's authenticity, but also convinces the card
of the receiver's authenticity. Unfortunately, Nagra couldn't use the same
method DTV used, because Adi Shamir has a patent on it, and Adi Shamir works for
NDS. An example of the $99 command is as follows:

21 00 1F ; A0 CA 00 00 ;Standard header
1A ;Command length
99 ;Command
18 ;Command data length
4E 69 70 50 45 72 20 49 ;ASCII string:
73 20 61 20 62 75 54 74 ; "NipPEr Is a buTt liCkeR!"
20 6C 69 43 6B 65 52 21
A8 ;Checksum
12 00 1C ; 99 ;Response code
18 ;Resposne data length
72 13 A7 7A 92 B4 49 34 ;Response block 1
72 13 A7 7A 92 B4 49 34 ;Response block 2
72 13 A7 7A 92 B4 49 34 ;Response block 3
90 00 ;SW1/SW2: Successful completion
F8 ;Checksum

Note that because ROM2 cards don't support this command, it's possible to keep
an IRD from attempting to use it by reporting a firmware revision level of
Rev052.

2.3.20- Command $C0/Response $B0


This command returns 4 bytes of CAM status bits. Some are completion codes for
the last command sent, some are to signal that the CAM has finished processing
the last command (as in the $03), some indicate that the CAM has been updated by
an EMM ($00) and the IRD should poll for the new info. A detailed breakdown of
the bits I understand follows the example:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
C0 ;Command
00 ;Command data length
06 ;Expected response length
87 ;Checksum

12 00 08 ; B0 ;Response code
04 ;Response data length
08 ;Response byte 1
00 ;CAM status flags 1
00 ;CAM status flags 2
16 ;CAM status flags 3
90 00 ;SW1/SW2: Successful completion
20 ;Checksum

Bit-by-bit breakdown of CAM status flags bytes:

Bit Flags 1 Flags 2 Flags 3


--- --------------------- --------------------- ------------------------
0 CAM suggests $C1 cmd CAM suggests $02 cmd Cmd $03 in progress
1 CAM has been reset Cmd 00/01 received Encrypted ECM data ready
2 CAM suggests $31 cmd Cmd 00/01 complete Cleartext ECM data ready
3 CAM suggests $30 cmd Cmd $30 in progress ECM decrypt failed
4 Cmd $31 data ready
5 Cmd $60 allowed Cmd $02 in progress
6 Cmd $02 complete
7 Cmd $02 failed

The following list details the bit definitions in plain english:

Bit Flags 1 Flags 2 Flags 3


--- --------------------- --------------------- -----------------------
0 Database updated CAM requests MECM data ECM being processed
1 CAM has been reset EMM being processed Even control word ready
2 Memory full EMM processing done Odd control word ready
3 Credit low CC being processed ECM decrypt failed
4 CC processing done
5 IRD command waiting MECM being processed
6 MECM data ready
7 CAM tamper detected MECM decrypt failed

Notes: CC="Callback", flags 1 bit 4 and flags 2 bits 6+7 not supported by
current EchoStar IRDs.

CAM tamper detected: This bit is only present in ROM3 cards, and it is only ever
set by EMM F3 commands that check for other flags set in OTP memory. At resent,
only location E010 is used to contain those flags, but in theory, any location
from E010 to E01F could be used. The EMM F3 commands that set flags in OTP
memory do so based on sanity checks of the card's EEPROM data, checking such
things as the CAM ID, making sure that no data is present in the portion of code
space set aside for bug-catchers, but which has not been specifically used by
"official" bug-catchers, and so on.

2.3.21- Command $C1/Response $B1


This command queries the CAM as to the existence of data items that have changed
since they were last polled. The return data is a bit mapped field, with each
bit representing whether or not a particular type of data has changed since the
last check. When the CAM first powers up, it will respond to this command with
$CF FF in the return so that the IRD will request all available data. An
example of the $C1 command is as follows:

21 00 08 ; A0 CA 00 00 ;Standard header
02 ;Instruction length
C1 ;Command
00 ;Command data length
04 ;Expected response length
84 ;Checksum

12 00 06 ; B1 ;Response code
02 ;Response data length
CF ;Response data byte 1 (see below)
FF ;Response data byte 2 (see below)
90 00 ;SW1/SW2: Successful completion
07 ;Checksum

Format for response data bytes:

Bit # Data byte 1 Data byte 2


----- ------------------------- -------------------------
7 Data type $10 has changed Data type $08 has changed
6 Data type $11 has changed Data type $07 has changed
5 n/a Data type $06 has changed
4 n/a Data type $05 has changed
3 Data type $0C has changed Data type $04 has changed
2 Data type $0B has changed Data type $03 has changed
1 Data type $0A has changed Data type $02 has changed
0 Data type $09 has changed Data type $01 has changed
2.4- Basic command sequences

In order to better understand the overall operation of the EchoStar system, it's
important to understand which commands relate to each other, and in what way.
In this section, I'll provide overviews of which commands would be used by the
IRD to accomplish some common tasks.

2.4.1- Finding out if the card is busy or has any new information
Often, it's useful for the receiver to know if the card is busy, or if the card
has received (or computed) some new information that the receiver might find
useful. When this happens, the receiver polls the card for its current status,
and examines the card's response to determine whether further commands are
necessary. The sequence for this operation is:

1: IRD sends command $C0 to card


2: Card returns $B0 resposne to receiver
3: IRD examines response and acts accordingly.

For detailed information on the $C0 command and $B0 response, see section
2.3.31, "CAM status request".

2.4.2- Finding out what data types in the card's database have changed
When data in the card's internal database has changed, the card will set one
of the status bits sent in the response to command $C0. When this bit is set,
the receiver will understand that data of some kind has been changed in the card
(or that for whatever reason, the card doesn't think the receiver has current
knowledge of the information in its database), so the receiver will poll the
card to find out what data types have changed. The sequence for this operation
is:

1: IRD sends command $C0 to card


2: Card returns $B0 response with "database has been updated" bit set
3: IRD examines response
4: IRD sends command $C1 to card
5: Card returns $B1 response to receiver

For detailed information on the $C1 command and $B1 response, see section
2.3.32, "Request for ID of updated data items".

2.4.3- Retrieving a specific data item from the card


When the receiver decides that it needs information from the card's database to
complete a task, it must poll the card to get the information it wants. It must
first find out if data of the type it wants exists, and then, if the data is
present in the card, it must request the data itself. The sequence for this
operation is:

1: IRD sends command $20 to card


2: Card returns $A0 response to receiver
3: IRD examines response
4: If response indicates no data of the requested type exists,
sequence ends
5: IRD sends command $21 to card
6: Card returns $A1 response to receiver

For detailed information on the $20 command and $A0 resposne, and the $21
command and $A1 response, see sections 2.3.10 and 2.3.11, "Data items available
request", and "Data item request", respectively.

In general, when a $C1 command sequence (see section 2.4.2, above) indicates
that the card has new data that the receiver might be interested in, the
receiver will immediately do a whole series of data retrieval commands and
download the card's entire database. A good example of this can be observed by
logging the interaction between a card and the receiver when the card is first
inserted.

2.4.4- Getting the data required to decrypt the video stream


Since the primary function of the receiver is to provide a video so that the
end-user can sit back in his armchair and wait for his ass to grow some more, it
(the receiver, not the end-user's ass) requires as its input a digital
datastream from which can be produced the video images. However, since the
program provider's primary function is to provide more money for the owner of
the service so that he can sit on his boat and wait for his ass to grow some
more, the program provider wants to prevent the general public from being able
to watch the video images that they broadcast. To this end, the data for the
video stream is encrypted. In order to decrypt the video stream, the receiver
must have the proper keys (which are 64 bits in length). However, because it
wouldn't be a good idea to make the receiver capable of producing the keys on
its own (since this would allow an easy receiver hack to always force the
receiver to produce the correct keys), the task of computing the video
decryption keys falls to the smartcard, since it is (theoretically, anyway) the
most secure element in the system.

The process, in english, is this: The IRD receives one or two encrypted video
decryption keys which it doesn't know how to decrypt from the satellite, along
with encrypted information which can be used to determine the specific channel
service to which the customer must be subscribed to watch the video images.
Because the IRD doesn't know how to decrypt this information, it passes it along
to the card. The card decrypts the information and examines the embedded
subscription requirement data to decide whether the customer is allowed to watch
the program. If the card decides that the customer should be allowed to watch
the program, it re-encrypts the video decryption keys in such a way that the IRD
into which the card is inserted (and theoretically, no other IRD) can decrypt
them, allowing it to successfully decrypt the video stream and contribute to the
overall expansion of everyone's ass. Step-by- step, the process is as follows:

1: IRD receives encrypted video stream information from the satellite


2: IRD sends command $03 to card, giving it encrypted information
required to decrypt video stream
3: Card sends $83 response to receiver, informing IRD that processing
of video decrypt information is in progress
4: Card decrypts information, decides whether program should be
viewable or not. If program should be viewable, card re-encrypts
video decryption keys (control words) using the DES encryption
algorithm and the receiver's unique DES key.
5: IRD sends command $C0 to card to determine whether processing of
$03 command is complete
6: Card sends $B0 response back to receiver.
7: IRD examines $B0 response. If response indicates that processing
of $03 command is not yet complete, return to step 5.
8: IRD sends command $13 to card, requesting the control words that
had been passed in command $03 in step 2.
9: If, in step 4, the card decided that the program should be
viewable, card sends $93 resposne, including re-encrypted video
decrypt keys. Otherwise, card sends $93 response with all $00s
in the space where the decrypt keys should be.

For detailed information on the $03 command and $83 response, and the $13
command and $93 response, see sections 2.3.4 and 2.3.8, "Entitlement control
message" and "Control word request", respectively.
3: EMM commands

3.1- EMM command list


As mentioned in section 2.3.1, the EMM (Entitlement Management Messages) in the
NagraVision system include an encrypted 64-byte block of data which, after
decryption, is interpreted as a list of EMM commands. In this section, each EMM
command will be addressed individually, and their functions and formats will be
explained (where known).

Note that although I think I know what all of the valid EMM commands are, I
don't know what they all do. Also note that because of the differences in the
ROM2, ROM3 and ROM10 cards' ROM images, there are at least three EMM commands
which will work on one of the cards, but not the others (see section 5, inside
NagraVision cards).

EMM CMD Function


------- ---------------------------------------------------------
$00 End of EMM sequence
$10 Spending limit item create
$11 Item purchase setup
$12 Valid channel services item (subscription tier) create
$13 PPV theme item create
$14 PPV number item create
$15 PPV service item create
$20 Update type $08..$0B begin/expiration/rights dates
$21 Invalidate system info item
$22 Validate system info item
$23 Delete type $08..$0C items
$24 Update PPV-by-number or PPV- or subscribe-by-theme
$25 Update spending limit info
$26 Mark subscription item as "phoned in"
$2F Update subscription item info
$30 Kill key information
$31 Expire all subscription items and indirection data
$32 Expire subscription items and indirection data for this system
$40 Write shared address, customer word ptr, EMM address to
public service, write key info to public key
$41 Update secondary provider information
$42 Update public service decrypt key/verify key
$43 Update public keys
$44 Update IRD info
$45 Update EMM decrypt key
$50 Update ZIP code
$51 Update time zone by ZIP code
$52 Update time zone
$53 Update blackout bytes by ZIP code
$54 Update blackout bytes
$60 2-byte EMM NOP
$61 Write email
$62 Update callback schedule
$63 Update callback phone #
$64 Encrypt IRD command
$80 End of EMM seqyebce
$81 Master program provider activation
$82 End of EMM sequence
$83 Change EMM system ID
$84 Desubscribe card from specified system
$85 Create indirection info
$86 Delete indirection info
$F0 Execute code from RAM (ROM2-based cards)
$F3 Execute code from RAM (ROM3-based cards)
$FA Execute code from RAM (ROM10-based cards)

3.2: EMM command breakdown


3.2.1- EMM command $00
This EMM command is used to let the CAM know that no more EMM commands are
contained in the 64-byte block. This is necessary because the encrypted data
block is padded to 64 bytes with random data, so a mechanism needs to be defined
to prevent the random data from being interpreted as commands. This command does
not include any parameters.

3.2.2- EMM command $10


This EMM command is used to create a spending limit data item (type $0C) if one
doesn't already exist for the system ID sent with the EMM. It includes the
rights identifier of the spending limit item (presumably some sort of customer
ID), customer spending limit, and phone home threshold. The format for this EMM
command is as follows:

10 ;EMM command
00 50 53 ;Rights identifier
00 32 ;Spending limit in units (hex)
25 ;Spending limit in 1/100 units
; (BCD)
04 99 ;Phone home threshold

In this example, the rights identifier for the newly-created spending limit item
will be 005053, the customer will be given a spending limit of $50.25, and the
"phone home threshold" (the point at which a call to E* to report PPV purchases)
will be forced if the amount of credit remaining falls below $4.99. This is a
fixed-length EMM command with a length of 9 bytes.

3.2.3- EMM command $11


This EMM command is used to set up for the creation of a subscription record of
any kind (normal subscription, impulse subscription, PPV buy, etc.) It includes
information as to the event start or expiration date, the cost of the item being
purchased, the rights identifier for the item, and the text string that should
be associated with the item. The format for this EMM command is as follows:

11 ;EMM command
00 02 ;Cost of this item in units (hex)
99 ;Cost of this item in 1/100 of
; units (BCD): This item is $2.99
20 ;Item attribute byte (see below)
03 ;String length byte
50 50 56 ;String associated with this
; item ("PPV" in ASCII")
xx ;Next EMM command: $12, $13, $14,
; or $15. Any other EMM command
; here will abort EMM processing
; (see below for details on EMM
; commands $12..$15)
01 02 03 ;Rights ID/PPV ID for next EMM
; command
00 00 ;Unused data for EMM commands
; $12..$14, expiration date for
; EMM command $15
FF FF ;Begin date
00 00 ;Data item lifespan/expire date
; for next EMM command if
; $12..$14
00 00 ;Rights date for next EMM command
; if $12..$14

As you can see, this EMM command is actually only the first half of a 2-part EMM
sequence. It requires that the EMM command that follows be $12..$15, or EMM
processing is aborted. Note that successful processing of EMM commands $12..$15
requires they be preceded by an EMM $11 command, since the cost of the item to
be purchased is provided by the EMM $11 command. As the type $11 command is
processed, a number of tests occur to make sure that the EMM command will be
creating a valid purchase item. First the 'begin date' is checked. If the
begin date is $FFFF, the rights date is checked to see if the rights date
represents a date that is in the past, and if so, EMM processing is aborted.

Next, we check the IRD status data item to see if the IRD's subscription is
suspended, and if so, EMM processing is aborted.

Next, we make sure that there will be sufficient space in EEPROM for both the
type $11 item created by the $11 EMM command, but also the data item that will
be created by the follow-up command, and if sufficient space does not exist, EMM
processing is aborted.

Next, bit 5 of the item attribute byte is checked to see if this is an impulse
purchase. If this EMM represents an impulse purchase, then the cost associated
with this EMM command is checked against the spending limit data (type $0C data
item) in the card, and if sufficient credit is not available, or if this
purchase would cause the "credit used" count to roll over past 0, then EMM
processing is aborted. If sufficient credit is available, the cost of the item
is added to the "credit used" count. At this point, the EMM has been determined
to be valid, so the string length byte is checked to see if a string was sent
with this EMM command. If one was, then a type $11 data item (string) is
created, a string ID is assigned, and the string included with this EMM command
is written to the new string data item. Once all this is finished, EMM
processing continues with the next EMM command.

This is a variable-length EMM command, whose length is equal to 6 plus the value
of the STRING LENGTH BYTE.

3.2.4- EMM command $12


This command is used to write valid channel services data items to the CAM.
These data items are what enable normal subscription channels. This EMM command
must be preceded by an EMM command $11, since the $11 EMM command sets up some
of the data for the $12 EMM command. The format for this EMM command is as
follows:

12 ;EMM command
01 02 03 ;Rights identifier
00 00 ;Unused data
FF FF ;Begin date
00 00 ;Data item lifespan/expire date
00 00 ;Rights date
00 00 ;Min channel
7F FF ;Max channel
00 00 ;Component
00 ;Min theme
00 FF ;Max theme
00 ;Level

The 'begin date' field is used to determine if the date fields are valid at
all: If the 'begin date' field contains $FFFF, the rights date is checked to see
if it represents a date that happened before today, and if so, the data item is
not created (note that this check is superfluous- if this check fails here, it
would also have failed when the preceding $11 EMM command was processed, causing
EMM processing to be aborted). If the begin date contains a valid date, then
the information in the begin date field is taken as absolute. If the begin date
was $FFFF, the data item's expire date is calculated by adding the "data item
lifespen" field (which is expressed as an encoded number of years, months, and
days) to yesterday's date, otherwise the absolute expire date is taken directly
from the received EMM data. This is a fixed-length EMM command with a length of
$16.

3.2.5- EMM command $13


This command is used to write PPV theme data items to the CAM. I'm not really
sure what these data items are used for, but I would guess that they allow the
purchase of a group of subscription channels that are all showing different
events of a single event (like, say, a sports package). As with EMM command
$12, this command must be preceded by an EMM command $11. The format for this
EMM command is as follows:

13 ;EMM command
01 02 03 ;Rights identifier
00 00 ;Unused data
FF FF ;Begin date
00 00 ;Data item lifespan/expire date
00 00 ;Rights date
00 00 00 ;Debit in tokens
00 ;Rights ID high byte low bit
00 00 ;Min channel
7F FF ;Max channel
00 00 ;Component
00 ;Min theme
00 FF ;Max theme
00 ;Level

As with EMM command $12, the 'begin date' field is checked for validity, and the
expiration date is calculated before the data item is created. One minor change
from the way EMM command $12 operates is that the low bit of the rights
identifier is ORed with the low bit of the "Rights ID high byte low bit" field.
This is a fixed-length EMM command with a length of $1A.
3.2.6- EMM command $14
This command is used to write PPV-by-number data items to the CAM. I'm not
really sure what these data items are used for, but I would guess that they
allow the purchase of a group of PPV channels that are all broadcasting
different aspects of a single event (like, say, the olympics). As with EMM
command $12, this command must be preceded by an EMM command $11. The format
for this EMM command is as follows:

13 ;EMM command
01 02 03 ;Rights identifier
00 00 ;Unused data
FF FF ;Begin date
00 00 ;Data item lifespan/expire date
00 00 ;Rights date
00 00 00 ;Debit in tokens
00 ;Rights ID high byte low bit
00 00 ;Min channel
7F FF ;Max channel
00 00 ;Component
00 00 00 ;Min PPV ID
7F FF FF FF ;Max PPV ID

As with EMM command $12, the 'begin date' field is checked for validity, and the
expiration date is calculated before the data item is created. One minor change
from the way EMM command $12 operates is that the low bit of the rights
identifier is ORed with the low bit of the "Rights ID high byte low bit" field.
This is a fixed-length EMM command with a length of $1D.

3.2.7- EMM command $15


This command is used to write single PPV data items to the CAM. These data
items represent discrete PPV events (like a movie) that may be viewed. As with
EMM command $12, this command must be preceded by an EMM command $11. The format
for this EMM command is as follows:

13 ;EMM command
01 02 03 ;PPV ID
00 00 ;Expiration date
00 ;Rights ID high byte low bit
00 00 ;Min channel
7F FF ;Max channel
00 00 ;Component
00 00 00 ;Min PPV ID
7F FF FF FF ;Max PPV ID

Unlike EMM command $12, the date fields in this EMM command are not checked for
validity. The expiration date is not calculated, but instead is simply taken
from the received data, as is the purchase date. Another change from the way
EMM command $12 operates is that the low bit of the rights identifier is ORed
with the low bit of the "Rights ID high byte low bit" field. This is a fixed-
length EMM command with a length of $14.

3.2.8- EMM command $20


This command is used to update the begin date, expiration date, and rights dates
for single type $08..$0B data items, or entire groups of type $08..$09 data
items. Presumably, this is useful for extending channel subscriptions. The
format for this EMM command is as follows:

20 ;EMM command
20 ;Search type/Begin date op type
; (see below)
B0 ;Expiration date op type/
; Rights date op type (see below)
00 00 00 ;Rights ID to match
FF FF ;Date to compare to mod date
00 00 ;Date factor for begin date
; (see below)
00 20 ;Date factor for expiration date
00 00 ;Date factor for rights date

Search type/begin date operation type byte: This byte specifies two things. In
the upper nibble is a value which tells the card what type of data to search
for, and how broadly the data types to be modified should be filtered. This data
is stored in the upper nibble of the search type/begin date operation type byte,
and is encoded as follows:

0=Modify all data items of type 08..0B whose system ID and rights
ID match (should only be one item)
2=Modify all data items of type 08..09 whose full system ID matches
3=Modify all data items of type 08..09 whose system ID hi matches
4=Modify all data items of type 08..09

The begin date operation type data is stored in the lower nibble of the search
type/begin date operation type byte, and is a series of binary flags encoded as
follows:

% - - - - x x x x
|_____| |_| |_|__ Item begin date replacement condition
| | 00=never
| | 01=replace if item date >= compare date
| | 10=replace if item date < compare date
| | 11=always replace
| |
| |________ Operation type for computing begin date compare date:
| 0x=none: use absolute date in "EMM date" field
| 10=compare date=item begin date+EMM date
| 11=compare date=item begin date-EMM date
|
|______________ search type

The expiration date operation type/rights date operation type byte is encoded
exactly like the begin date operation type, with the operation to be performed
on the expiration date stored in the upper nibble, and the operation to be
performed on the rights date stored in the lower nibble.

Date factors: The date factors contain either an absolute date to be compared
against and possibly replace the appropriate data item date or an offset from
the current date's value. If the operation type for, say, the expiration date
specified that the compare date is computed by adding the EMM date to the data
item expiration date (operation type %10xx), then the offset factor stored in
the expiration date factor (in years, months, and days) is added to any matching
data item's current expiration date. I'm not really sure why this option is
available, since if the operation specifies that the date factor in the EMM is
to be added to the current item date, the "replace if item date >= compare date"
action will always be performed, and the "replace if item date < compare date"
action will never be performed.

In the example above, the EMM command specifies that all data items of type
$08/$09 whose system ID matches the EMM system ID will have their expiration
dates extended by one month. Another possible EMM command of this type that we
might see is:

20 ;EMM command
01 ;Search type/Begin date op type
00 ;Expiration date op type/
; Rights date op type
12 34 56 ;Rights ID to match
FF FF ;Date to compare to mod date
10 FE ;Date factor for begin date
00 00 ;Date factor for expiration date
00 00 ;Date factor for rights date

In this case, any type $08..$0B data item with a rights identifier of $123456
will have its begin date replaced with 10 FE (July 30, 2000) if the item's begin
date is further in the future than July 30, 2000. This is a fixed-length EMM
command with a length of $0E.

3.2.9- EMM command $21


This EMM command is used to invalidate various types of system information
items. This is done by setting the "subscription suspended" bit of the status
byte in the type of item to be invalidated. Note that this EMM command always
finds the first item of a given type in EEPROM. This EMM command is formatted
as follows:

21 ;EMM command
00 ;Item type byte (see below)
12 34 56 ;Rights ID byte

Item type byte: This byte tells the CAM which type of system information item is
being invalidated by this commmand. Valid values for this byte are:

$00: Invalidate type $08..$0B data item, match system ID+rights ID


$20: Invalidate type $02 data item, match system ID
$30: Invalidate type $06 data item, match system ID high
$40: Invalidate type $01 data item, match system ID

In the example above, the CAM will invalidate the next type $08..$0B data item
it finds with a rights ID of $123456 and a system ID that matches the EMM's
system ID. This is a fixed-length EMM with a length of $05.

3.2.10- EMM command $22


This EMM command is used to validate various types of system information items.
This is done by clearing the "subscription suspended" bit of the status byte in
the type of item to be invalidated. Note that this EMM command always finds the
first item of a given type in EEPROM. This EMM command is formatted as follows:

22 ;EMM command
00 ;Item type byte (see below)
12 34 56 ;Rights ID byte
Item type byte: This byte tells the CAM which type of system information item is
being invalidated by this commmand. Valid values for this byte are:

$00: Validate type $08..$0B data item, match system ID+rights ID


$20: Validate type $02 data item, match system ID
$30: Validate type $06 data item, match system ID high
$40: Validate type $01 data item, match system ID

In the example above, the CAM will validate the next type $08..$0B data item it
finds with a rights ID of $123456 and a system ID that matches the EMM's system
ID. This is a fixed-length EMM command with a length of $05.

3.2.11- EMM command $23


This EMM command is used to delete subscription or PPV data items from memory.
It can be used to either delete the first type $08..$0C item in EEPROM, or to
search for and delete all items that match specific parameters. This EMM command
is formatted as follows:

23 ;EMM command
00 ;Search type (see below)
12 34 56 ;Rights ID
00 02 99 ;Item cost

Search type: This byte tells the CAM what type of data we're going to look for
and how to identify data items that we want to delete. It is encoded as
follows:

00=Search for the item of type 08..0C whose rights ID matches the rights
ID in the EMM command and delete it. In addition, add the value of the
item cost field to the "debit paid" field of the spending limit item
if the deleted item was an impluse buy that was not watched.
20=Delete all data items of type 08..0C whose full system ID matches
30=Delete all data items of type 08..0C whose system ID hi matches
40=Delete all data items of type 08..0C

In the example above, only the type 08..0C data item whose rights ID is $123456
will be deleted. In addition, the card will record a credit of $2.99 if the
item was an impulse buy that was not watched. Another example of this type of
EMM command might be:

23 ;EMM command
20 ;Search type
00 00 00 ;Rights ID
00 00 00 ;Item cost

This example does a search and destroy on all type $08..$0C items with a system
ID that matches the system ID sent in the EMM. Note that no item cost is
specified, since it's likely that more than one item will be deleted. This is s
fixed-length EMM command with a length of $08.

3.2.12- EMM command $24


This EMM command allows PPV-by-number and PPV- or subscribe-by-theme records to
be updated. It can update the amount of credit or debit used on them, or alter
the minimum authorized channel for the item. Note that the action is only taken
if the modification date included in the EMM command represents a date that
falls after the "date of last token operation" for the item to be modified.
This EMM command is formatted as follows:

24 ;EMM command
12 34 56 ;Rights ID
00 ;Action byte (see below)
00 02 99 ;Token offset/new min channel
10 FE ;Modification date

Action byte: The value of this byte determines the action that will be taken if
a matching item with a valid date can be found. It is encoded as follows:

00=Add token offset to "debit in tokens"


01=Subtract token offset from "debit in tokens"
02=Replace the "debit in tokens" value with the token offset value
03=Clear "credit in tokens" to 0, replace "debit in tokens" value with
the token offset value
04=Subtract token offset from "credit in tokens" and "debit in tokens"
05..FF=Replace minimum channel with new minimum channel value (see below)

In the example above, if a PPV-by-number or PPV- or subscribe-by-theme item with


a rights ID of $123456 and a "date of last token operation" prior to July 30,
2000 can be found, the value 00 02 99 will be added to the items "debit in
tokens" field. Another example of this EMM could be:

24 ;EMM command
12 34 56 ;Rights ID
05 ;Action byte (see below)
01 FE ;Token offset/new min channel
00 ;unused date
10 FE ;Modification date

In the second example, if a PPV-by-number or PPV- or subscribe-by-theme item


with a rights ID of $123456 and a "date of last token operation" prior to July
30, 2000 can be found, its minimum authorized channel will be replaced with
$01FE. This is a fixed-length EMM command with a length of $0A.

3.2.13- EMM command $25


This EMM command allows the spending limit item in the CAM to be updated. It
works much like EMM command $24, in that it includes an action byte, and its
fields are formatted the same as EMM command $24. The difference is that EMM
command $25 only works on the spending limit data type, and for EMM command $25,
action byte values greater than $05 are insane and cause the EMM command to be
ignored. As with EMM command $24, the "modification date" field must represent
a date that falls after the spending limit item's "last cash modification date"
field. This EMM command is formatted as follows:

25 ;EMM command
12 34 56 ;Rights ID
00 ;Action byte (see below)
00 02 99 ;Cash offset/phone home threshold
10 FE ;Modification date

Action byte: The value of this byte determines the action that will be taken if
a spending limit item with a valid date can be found. It is encoded as follows:

00=Add cash offset to "debit in cash"


01=Subtract cash offset from "debit in cash"
02=Replace the "debit in cash" value with the cash offset value
03=Clear "credit in cash" to 0, replace "debit in cash" value with
the cash offset value
04=Subtract cash offset from "credit in cash" and "debit in cash"
05=Replace phone home threshold with phone home value (see below)

In the example above, the amount $2.99 is being added to the "debit paid" field.
Other possible examples of this command could be:

25 ;EMM command
12 34 56 ;Rights ID
03 ;Action byte
00 32 00 ;Cash offset
10 FE ;Modification date

In the above example, the "credit used" figure will be set to 0, and the "debit
paid" will be set to $32.00 (hex), which is $50.00 decimal.

25 ;EMM command
12 34 56 ;Rights ID
05 ;Action byte
00 06 ;New phone home threshold
00 ;unused data
10 FE ;Modification date

In the above example, the "phone home threshold" will be replaced with a value
of 00 06. This is a fixed-length EMM command with a length of $0A.

3.2.14- EMM command $26


This EMM command allows impulse-purchased PPV items to be marked as "phoned in".
This allows those items to be deleted from the EEPROM data area. A specific PPV
item is selected according to the "rights ID" field that is sent with the EMM
command. This EMM command is formatted as follows:

26 ;EMM command
12 34 56 ;Rights ID

In this example, the first subscription item (type $08..$0C) with a rights ID of
$123456 will be marked as "phoned in". Note that no check is performed to
ensure that a matching item was actually located. This is a fixed-length EMM
command with a length of $04.

3.2.15- EMM command $2F

This EMM command allows the information in an arbitrary data field of a type
$08..$0C data item to be updated. As with EMM command $26, a specific item is
chosen according to its rights ID field. If a suitable item is found, the EMM
is parsed to determine the offset within the data item where the update is to
begin, the length of the update, and the actual data values that are to replace
the data in the existing item. This EMM command is formatted as follows:

2F ;EMM command
12 34 56 ;Rights ID
13 ;Data offset
04 ;Data length
00 00 7F FF ;Updated data
In this example, a data item with a rights ID of $123456 will have the 4 bytes
starting at its offset $13 replaced with the values 00 00 7F FF (if the matching
data item is a type $08 item, this would change the minimum channel for that
item to $0000, and the maximum channel for that item to $7FFF. Note that
haphazard use of this command can cause data corruption, since the command
doesn't perform any kind of field position validity checking. For example, if
the data item found by the above command were a type $0C item rather than a type
$08 item, the resultant write would cause the header of the _next_ data item to
become corrupted. Persumably, the providers who use NagraVision work around
this limitation by assigning ranges of rights ID values to specific data types
(ie., $000000..$2FFFFF would be type $08, $300000..$3FFFFF would be type $09,
etc.) This is a variable-length EMM command whose length is equal to 6 plus
the value of the DATA LENGTH byte.

3.2.16- EMM command $30


This EMM command deletes all public key information from the card. First,
all type $07 data items whose system ID high does not match the system ID high
of the EMM are removed, then all type $06 data items have their public keys
removed from them, and finally, any type $07 data items which were allowed to
remain during the first pass of this command are deleted. Presumably, this
two-pass deletion of the $07 data is to ensure that if the card is pulled or
reset or crashes before all of the type $06 data is removed, the CAM will
still contain keys to allow it to decode the EMM if it is resent so that
recovery is possible. This EMM command is formatted as follows:

30 ;EMM command

Following execution of this EMM command, the remainder of the EMM buffer is
discarded, so this EMM command should always be the last EMM command in a
given EMM.
This is a fixed-length EMM command with a length of $01.

3.2.17- EMM command $31

This EMM command checks all type $08..$0B and type $04 data items in EEPROM
to see if they've expired, and if they have (and if they're not impulse buys
that haven't been phoned in), it deletes them. This EMM command is formatted
as follows:

31 ;EMM command
00 FE ;Begin date to compare
10 FE ;Expiration date to compare

In almost all cases, the begin date will probably be the date on which
subscription items were last expired so that only items which have been
created since that time will be expired. In addition, the expiration date
probably always be the date on which the command was broadcast so that items
which had expired as of that day will be deleted.
This is a fixed-length EMM command with a length of $05.

3.2.18- EMM command $32


This EMM command checks all type $08..$0B and type $04 data items in EEPROM
whose system ID matches the EMM's system ID to see if they've expired, and if
they have (and if they're not impulse buys that haven't been phoned in), it
deletes them. This EMM command is formatted as follows:
32 ;EMM command
00 FE ;Begin date to compare
10 FE ;Expiration date to compare

In almost all cases, the begin date will probably be the date on which
subscription items were last expired so that only items which have been
created since that time will be expired. In addition, the expiration date
probably always be the date on which the command was broadcast so that items
which had expired as of that day will be deleted.
This is a fixed-length EMM command with a length of $05.

3.2.19- EMM command $40


This EMM command is used to update several pieces of data in the CAM that
relate to public service information. If successful, it will update the
shared address (usually hi 3 bytes of CAM ID), customer word pointer (usually
low byte of CAM ID), and EMM address pointer (no idea) in the first matching
type $06 data item, and a 15-byte block of a matching type $07 data item (or
it will create a type $07 data item to hold the information, if necessary).
I'm not sure at this point what the EMM address pointer or the 15-byte block
of data written to the type $07 data item are for. This EMM command is
formatted as follows:

40 ;EMM command
00 ;New EMM address pointer
12 34 56 ;New shared address
78 ;New customer word pointer
01 ;New key type byte (see below)
11 22 33 44 55 66 77 88 ;New 15-byte block of key info
99 AA BB CC DD EE FF ; (see below)

Key type byte: The low 3 bits of this byte must be %001 for this EMM command
to be processed. If the high bit of this byte is clear, a type $07 data item
whose 3rd data byte is 00 will be selected (or created), otherwise a type $07
data item whose 3rd data byte is 01 will be selected (or created).
Key info block: This data is written to the second 15-byte block of key
data in the selected/created type $07 data item.
In the above example, a type $06 data item with a system ID high matching
the EMM's system ID high will be sought, and a type $07 data item with a
matching system ID high and a key type byte of 00 will be sought. If both
items are located (or if the type $06 item is located and a type $07 item
can be created), the type $06 item's EMM address pointer will be changed to
00, its shared address will be changed to $123456, and its customer data
pointer will be changed to $78. In addition, the second 15-byte block of key
info in the type $07 item will be changed to $112233445566778899AABBCCDDEEFF.
This is a fixed-length EMM command with a length of $16.

3.2.20- EMM command $41


This EMM command updates secondary programming provider information. It is
formatted as follows:

41 ;EMM command
0A ;New provider category

In this example, the card will search for the first type $02 data item whose
system ID matches the system ID of the EMM, then it will update its provider
category byte with the byte in the EMM command.
This is a fixed-length EMM command with a length of $02.

3.2.21- EMM command $42

This command is used to change the public keys that are used to decrypt
the $03 command data. It takes two data fields: One byte to tell it which
key to change, and 8 bytes of new key data. The $42 command looks like this:

42 ;EMM command
05 ;Key ID byte (see below)
11 22 33 44 55 66 77 88 ;New key

Key ID byte: This byte is used to select which key is updated by the
$42 command, as follows:

$04=Verify key for key type 0


$05=Channel decrypt key 0
$84=Verify key for key type 1
$85=Channel decrypt key 1

The key types associated with the verify keys refer to the "key type byte"
of the type $07 data item (since this is the data type where verify keys are
stored).
In the above example, decrypt key 0 will be changed to 1122334455667788.
This is a fixed-length EMM command with a length of $0A.

3.2.22- EMM command $43


This EMM command allows the updating of any of the 3 15-byte blocks of key
information in a type $07 data item. It is formatted as follows:

43 ;EMM command
01 ;Key select byte (see below)
11 22 33 44 55 66 77 88 ;Updated key information
99 AA BB CC DD EE FF

Key select byte: This byte selects which of the 3 15-byte blocks of key
information in the type $07 data item whose system ID hi matches the system ID
hi of the EMM will be updated. The upper 5 bits of this byte are don't-case
bits, and the low 3 bits are encoded as follows:

$0: Update key block 0


$1: Update key block 1
$2: Update key block 2
$3..$7: Invalid, command will be ignored

In the above example, key block 1 of the matching type $07 data item will be
updated to 112233445566778899AABBCCDDEEFF.
This is a fixed-length EMM command with a length of $11.

3.2.23- EMM command $44


This command is used to write IRD info into the CAM. It's like the $61
command, but this command is more selective and also allows access to the
IRD's box key. This is the key that's used to encrypt the data for the $13
command. The IRD's box key is stored in the $01 data type, in a field that's
not dumped by the 21-01 command. This command includes $1D bytes of data and
looks like this:
44 ;EMM command
nn ;Control byte (see below)
01 02 03 04 05 06 07 08 ;New IRD data ($1C bytes)
09 0A 0B 0C 0D 0E 0F 10
11 12 13 14 15 16 17 18
19 1A 1B 1C

Control byte: It seems as though this byte is used to control which 4-byte
blocks of the $1C byte data block are actually written to the 21-01 data in
the CAM. The breakdown of the bits appears to me to be as follows:

Bit # Data block to be written


----- ----------------------------------------------------------
0 Bytes 15..18 and 19..1C (Suspect IRD key)
1 Bytes 01..04 (Suspect IRD serial #)
2 Bytes 05..08 (Suspect bytes 1..4 of IRD version info)
3 Bytes 09..0C (Suspect bytes 5..8 of IRD version info)
4 Bytes 0D..10 (Suspect bytes 9..12 of IRD version info)
5 Bytes 11..14 (Suspect bytes 13..16 of IRD version info)
6 Bytes 15..18 (Suspect first four bytes of IRD key)
7 Bytes 19..1C (Suspect last four bytes of IRD key)

Note that the command will always have $1C bytes of data, regardless of how
many bytes are actually going to be written to EEPROM...blocks that aren't
written are simply ignored. Thus, if you wanted to set your box key to, let's
say 11 22 33 44 55 66 77 88, you could send either of the following EMM
messages:

44 ;EMM command
01 ;Control byte
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx 11 22 33 44 ;Discarded data+1st 4 bytes
; of IRD key
55 66 77 88 ;Last 4 bytes of IRD key

44 ;EMM command
C0 ;Control byte
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx 11 22 33 44 ;Discarded data+1st 4 bytes
; of IRD key
55 66 77 88 ;Last 4 bytes of IRD key

Or, you could do it in two passes:

44 ;EMM command
40 ;Control byte
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx 11 22 33 44 ;Discarded data+1st 4 bytes
; of IRD key
xx xx xx xx ;Discarded data

44 ;EMM command
80 ;Control byte
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx xx xx xx xx ;Discarded data
xx xx xx xx xx xx xx xx ;Discarded data
55 66 77 88 ;Last 4 bytes of IRD key

Note that although the 2-pass key change _could_ fit entirely in a single
EMM, it's unlikely that E* would change the key that way...I only offer the
example to further illustrate the workings of the command.
This is a fixed-length EMM command with a length of $1E.

3.2.24- EMM command $45


This EMM command allows EMM decrypt keys to be updated. A search is
performed for a type $07 data item whose system ID high matches the system ID
high for the EMM and whose key type matches the key type selected by the EMM
command. Then, either the first half or the second half of the EMM key is
updated based on the data in the EMM command. Note that two seperate EMM
messages are required to fully update an EMM key, since EMM keys are $40
bytes in length, but the maximum number of data bytes that can be passed in a
single EMM command is $3C (since there are always at least 3 bytes of data
associated with the mandatory EMM filter, and one byte of overhead associated
with the EMM command itself). This EMM command is formatted as follows:

45 ;EMM command
C3 ;Key select byte (see below)
11 22 33 44 55 66 77 88 ;Updated EMM key information
99 AA BB CC DD EE FF 00
11 22 33 44 55 66 77 88
99 AA BB CC DD EE FF 00

Key select byte: This byte determines not only which EMM key type is
updated, but also which half of the EMM key is updated. It is encoded as
follows:

Bits 0..2: Must be 011, or command is ignored


Bit 6: 0 to update 1st half of EMM key (bytes 00..1F)
1 to update 2nd half of EMM key (bytes 20..3F)
Bit 7: 0 to update key with key type byte of 00
1 to update key with key type byte of 01

In the above example, a type $07 data item with a matching system ID hi and
a key type byte of 01 will be sought (and created if necessary). The upper
half of the EMM key in the located (or created) item will be updated with
the key information from the EMM command.
This is a fixed-length EMM command with a length of $22.

3.2.25- EMM command $50


This EMM command updates the ZIP code in the IRD information data item. It
is formatted as follows:

50 ;EMM command
00 01 38 F0 ;New ZIP code

In the above example, the ZIP code in the IRD information data item will be
changed to $000138F0, which is the hex equivalent of 80112.
This is a fixed-length EMM command with a length of $05.
3.2.26- EMM command $51
This EMM command updates the time zone in the IRD information data item if
the ZIP code in the IRD information data item falls between the two ZIP codes
sent with the EMM command. This command is formatted as follows:

51 ;EMM command
00 01 38 80 ;Lowest ZIP for this EMM
00 01 40 4F ;Highest ZIP for this EMM
E8 ;New time zone

In the above example, the IRD's time zone will be updated if the ZIP code
stored in the IRD information data item is between $00013880 and $0001404F,
inclusive (80000..81999). In this case, the time zone would be updated to
$E8 (mountain daylight time). Note that the high byte of the highest ZIP code
may not be greater than $7F, or the means by which the EMM command is handled
will fail and unexpected results may occur.
This is a fixed-length EMM command with a length of $0A.

3.2.27- EMM command $52


This EMM command updates the time zone in the IRD information data item. It
is formatted as follows:

52 ;EMM command
E8 ;New time zone

In the above example, the IRD's time zone will be updated to $E8 (mountain
daylight time).
This is a fixed-length EMM command with a length of $02.

3.2.28- EMM command $53


This EMM command updates the blackout information in the type $06 data item
whose system ID high matches the EMM's system ID high if the ZIP code in the
IRD information item is within the range specified by the EMM command. This
command is formatted as follows:

53 ;EMM command
00 01 38 80 ;Lowest ZIP for this EMM
00 01 40 4F ;Highest ZIP for this EMM
03 ;Blackout byte to update
04 ;New blackout byte

In the above example, if the ZIP code in the IRD information data item is
between $00013880 and $0001404F, inclusive (80000..80199), byte 3 of the
blackout data in the type $06 data item whose system ID high matches the
system ID high of the EMM will be updated to be $04. Note that the "blackout
byte to update" must be less than $0C, since there are only 12 blackout bytes
stored in the type $06 data item.
This is a fixed-length EMM command with a length of $0B.

3.2.29- EMM command $54


This EMM command updates the blackout information in the type $06 data item
whose system ID high matches the EMM's system ID high. This command is
formatted as follows:

54 ;EMM command
03 ;Blackout byte to update
04 ;New blackout byte

In the above example, byte 3 of the blackout data in the type $06 data item
whose system ID high matches the system ID high of the EMM will be updated to
be $04. Note that the "blackout byte to update" must be less than $0C, since
there are only 12 blackout bytes stored in the type $06 data item.
This is a fixed-length EMM command with a length of $03.

3.2.30- EMM command $60


I know nothing of this command, other than it seems to have a 1-byte data
field associated with it. No action is associated with this EMM command in
ROM2 or ROM3 cards.
This is a fixed-length EMM command with a length of $02.

3.2.31- EMM command $61


This command allows emails to be written to or updated in the card. It is
formatted as follows:

61 ;EMM command
01 FE ;Email postmark date
7C A2 ;Email postmark time
08 ;Email status byte
01 ;Email ID
0D ;Overall email length
FF ;Email received bits (see below)
00 ;Offset to email text
0D ;Email text length
43 68 65 72 6C 69 65 20 ;Email text: "Charlie sucks"
73 75 63 6B 73

Email received bits: This is a bit-mapped byte which allows an email to be


sent in chunks before is it considered active. An email is not considered
active until all 8 bits of the "email received" byte are set, and the email
text of a $61 EMM command will be written to an email item only if the
"received bits" byte in the EMM command contains bits set that are not
currently set in the existing email item. This allows the email text to be
sent in up to 8 seperate EMM commands.
In this case, assuming that no email with an ID of 01 already existed in
the card, an email with an ID of 01 will be created with a postmark date of
$01FE (Jul 30, 2000) and time of $7CA2 (15:37:04 GMT) will be created with
the "high priority" bit set. Email text of "Charlie sucks" will be written
to the email, and the email will be flagged as received.
If an email with a matching ID is found in the card, then the card will
check the "email received" byte of the EMM command against the "email
received" byte in the existing email item, and if the "email received" byte
in the EMM command has bits set that are not set in the existing email
message, the email text from the received EMM will be written to the
existing item at the offset specified in the EMM command. So, for example,
if the above email were sent in two parts, it might look like this:

61 ;EMM command
01 FE ;Email postmark date
7C A2 ;Email postmark time
08 ;Email status byte
01 ;Email ID
0D ;Overall email length
01 ;Email received bits
00 ;Offset to email text
08 ;Email text length
43 68 65 72 6C 69 65 20 ;Email text: "Charlie "

61 ;EMM command
01 FE ;Email postmark date
7C A2 ;Email postmark time
08 ;Email status byte
01 ;Email ID
0D ;Overall email length
FE ;Email received bits
00 ;Offset to email text
05 ;Email text length
73 75 63 6B 73 ;Email text: "sucks"

Note that the "received bits" in the second packet fill the bits that
the first packet didn't, causing the value of the "received bits" byte to
become $FF. Note also that even though the second EMM assumes that the
first EMM has already been received, it includes redundant data from the
first EMM in case the first EMM was missed. Most likely, the first n EMMs
that make up an email would have bits 0 to n-1 set, progressively (1st EMM
would have bit 0 set, 2nd would have bit 1 set, and so on) in the "received
bits" byte, and the final EMM would have bits n through 7 set to complete the
"received bits" byte.
This is a variable-length EMM command whose length is equal to $0B plus the
value of the "email text length" byte.

3.2.32- EMM command $62


This EMM command updates various data relating to callback scheduling. It
searches for a type $06 data item whose system ID high matches the system ID
high of the EMM, then updates various callback information, depending on the
select bytes sent in the EMM command. This command is formatted as follows:

62 ;EMM command
0C ;Callback period in hours
01 FE ;Callback date
7C A2 ;Callback time
00 ;Callback retry period

In the above example, the callback period will be set to $0C (12 hours),
and the regular callback date and time will be set to $01FE and $7CA2,
respectively. The callback retry period will not be altered. If the callback
period value had been $00, then rather than updating the "regular callback"
date and time, the EMM command would have updated the "immediate callback"
date and time. In addition, if the callback retry period value is anything
other than $00, the callback retry period will be updated with the value from
the EMM as well.
this is a fixed-length EMM command with a length of $07.

3.2.33- EMM command $63


This EMM command updates the callback phone number in a given type $06 data
item. This is the phone number the IRD will call when reporting PPVs and so
forth for a given broadcast system. It is formatted as follows:

63 ;EMM command
18 00 55 51 21 2F FF FF ;New callback phone #
FF FF

In the above example, the callback phone number for the type $06 data item
whose system ID high matches the EMM's system ID high will be changed to
1-800-555-1212. Note that the maximum length of the phone number is 20
digits, and the phone number is padded to the right with Fs.
This is a fixed-length EMM command with a length of $0B.

3.2.34- EMM command $64


This command allows a command to be encrypted to be sent back to the IRD
for processing. The IRD commands include such things as "force callback",
"unlock and reset password", "modify EEPROM", etc. It is formatted as
follows:

64 ;EMM command
xx ;Length of IRD command
xx xx xx xx xx xx xx xx ;IRD command

The CAM will first compute an LRC for all of the bytes in the IRD command,
including the EMM command byte and the length byte and store that LRC in the
byte immediately following the IRD command. The CAM will then pad the command
to a total length of $40 bytes with random data. After all this, the CAM will
DES encrypt the entire EMM buffer using the IRD key, and set the "IRD command
waiting" bit in status byte 2 (returned by command $C0). An example of a
complete IRD command EMM might look like this:

64 ;EMM command
0C ;Length of IRD command
55 ;IRD command: Sequence #=00000001
00 00 00 01
06 ;IRD command: Filter for IRD
12 34 56 78 ; number 12345678
09 ;IRD command: Reset password and
; unlock receiver

At some point, detailed information about IRD commands may be found in a


seperate section of this document.
This is a variable-length EMM command whose length is equal to $01 plus the
value of the "length of IRD command" byte, and no EMM commands may follow it.
EMM processing is aborted once this command is handled.

3.2.35- EMM command $80


In ROM2 cards, this command has a handler, and is treated as an "end of EMM
commands" command.
In ROM3 cards, this command has no handler, but ends up being treated as
an "end of EMM commands" command, since all invalid command bytes cause EMM
processing to stop.
3.2.36- EMM command $81
This command performs initial data item creation for a new program service
provider. It will create type $06 and $02 data items for the program provider
whose ID information is included in the EMM command if they don't already
exist, and populate those data items with default data. This command is
formatted as follows:

81 ;EMM command
01 01 ;System ID

In the above exmaple, if type $06 and/or type $02 data items for a program
provider with a system ID of $0101 doesn't exist, it will create them and
populate them with default information. For example, if the above command
were executed by a CAM with a CAM ID of $11223344, the following data items
would be created:

Type $06: 01 ;Program provider class


00 ;Address pointer in EMM header
00 ;Status byte
11 22 33 ;Shared address (High 3 bytes of
; CAM ID)
44 ;Customer word pointer (low byte
; of CAM ID)
FF FF FF FF FF FF FF FF ;Callback phone #
FF FF
FF ;Callback period (in hours)
FF FF ;Next regular callback date
FF FF ;Next regular callback time
FF FF ;Immediate callback date
FF FF ;Immediate callback time
FF ;Callback retry period (in hours)
00 00 00 00 00 00 00 00 ;Blackout info
00 00 00 00
00 00 00 00 00 00 00 00 ;Key 0 (hidden)
00 00 00 00 00 00 00 00 ;Key 1 (hidden)

Type $02: 01 01 ;System ID.


00 ;Status byte
00 ;Provider category

Note that either data item, both data items, or neither data item may be
created by this command.
This is a fixed-length EMM command with a length of $03.

3.2.37- EMM command $82


In ROM2 cards, this command has a handler, and is treated as an "end of EMM
commands" command.
In ROM3 cards, this command has no handler, but ends up being treated as
an "end of EMM commands" command, since all invalid command bytes cause EMM
processing to stop.

3.2.38- EMM command $83

This command changes the effective system ID for the remainder of the EMM
commands in a given EMM. If IRD information (type $01) data and secondary
provider information (type $02) data does not exist for the new system ID,
EMM processing is aborted. This command is formatted as follows:

83 ;EMM command
41 01 ;New system ID

In the above example, the system ID for the remainder of the EMM commands
would be changed to $4101, provided type $01 and $02 items with that system
ID exist in the CAM's EEPROM.
This is a fixed-length EMM command with a length of $03.

3.2.39- EMM command $84


This command is used to completely obliterate all data items associated
with a particular system ID, other than key information, public service
information, and IRD information. It is formatted as follows:

84 ;EMM command
01 01 ;System ID to kill

In this example, all type $01, $03, $04, $05, $08, $09, $0A, $0B, $0C, and
$10 data items with a system ID matching the system ID in the EMM command
will be deleted. Note that the system ID in the EMM command must differ from
the system ID in the EMM itself. Also note that not only are type $04 items
whose source system ID matches the EMM command's system ID deleted, so are
type $04 items whose target system ID matches the EMM command's system ID.
This is a fixed-length EMM command with a length of $03.

3.2.40- EMM command $85


This EMM command creates or updates type $04 (indirection) data items. It
is formatted as follows:

85 ;EMM command
41 01 ;Target system ID
00 00 ;Min channel to alias
7F FF ;Max channel to alias
01 FE ;Last date of validity for this
; indirection information

In the above example, an indirection item with a source system ID matching


the EMM's system ID, a target system ID of $4101, min channel of $0000, and
max channel of $7FFF will be searched for, and if one is not found, it will be
created. If a matching item _were_ found, its "last date of validity" would
be updated with the info from the EMM command.
This is a fixed-length EMM command with a length of $09.

3.2.41- EMM command $86


This command deletes type $04 (indirection) data items. It will only ever
delete a single indirection item, and all of the bytes from the EMM command
must match the associated bytes in an indirection item for it to be
deleted. This command is formatted as follows:

86 ;EMM command
41 01 ;Target system ID
00 00 ;Min channel to alias
7F FF ;Max channel to alias

In the above example, an indirection item with a source system ID matching


the EMM's system ID, a target system ID of $4101, min channel of $0000, and
max channel of $7FFF will be searched for, and if one is found, it will be
deleted.
This is a fixed-length EMM command with a length of $07.

3.2.42- EMM command $F0 (ROM2/288-01)/EMM command $F3 (ROM3/288-


02)/ EMM command $FA (ROM10)
This is the most powerful EMM command of all. It allows EchoStar/Nagra to
actually upload a code fragment to the card, and have that code fragment
executed from RAM. It is the existence of this command that makes a stable,
widely available NagraVision 3M card unlikely: If this command is left enabled
in the card, E*/Nagra can use it to detect the foreign 3M code and attack the
card. If this command is disabled, E*/Nagra can use it to make changes to
the public keys for command $03, so even though the card wants to work, it
won't be able to. This is a variable-length command, so it will likely be
the last command in an EMM message. The format is as follows:

ROM2-based card (288-01):

Address Data Description


-------- ----------------------------- ------------------------------
$80 F0 ;EMM command
$81 <16CF54A object code here> ;Code to be executed
(varies) 81 ;Last instruction is usually
; an RTS

ROM3-based card:

Address Data Description


-------- ----------------------------- ------------------------------
$80 F3 ;EMM command
$81 <16CF54A object code here> ;Code to be executed
(varies) 81 ;Last instruction is usually
; an RTS. Alternatively,
; the following code fragment
; can be used to embed further
; EMM commands after the code
; fragment:
(varies) 9C ;RSP ;Reset stack ptr
3C F8 ;INC $F8 ;Smash sys ID
A6 nn ;LDA #$nn ;Get length of code
CC 5B 19 ;JMP $5B19 ;Do next EMM command

ROM10-based card:

Address Data Description


-------- ----------------------------- ------------------------------
$80 FA ;EMM command
$81 <19CFxx object code here> ;Code to be executed
(varies) 81 ;Last instruction is usually
; an RTS

The reason the ROM2-, ROM3-, and ROM10-based cards have different EMM
commands for the same function is because the ROM2 cards and ROM3 cards have
different ROM code inside them. The code is very similar (see section 5,
inside NagraVision cards), but because it's not identical, a mechanism is
needed to ensure that code fragments that are calling routines in the ROM2 ROM
won't be executed on a ROM3 or ROM10 card, and vice-versa. When the code is
executed, the first instruction is always at address $81 in RAM.
This is the command that is used to perform EEPROM updates to the card.
This is accomplished by checking a special "sequence" byte (in ROM3 cards,
this byte is stored at $E050) to see if it has been loaded with a value that
indicates that the data in a particular Fx command is "next in line", and if
the value matches, the code fragment writes whatever data it can to EEPROM
and then updates the "sequence" byte. The final code fragment in an EEPROM
update generally hooks in the code that was added by all the other fragments
and updates the ascii firmware revision number in EEPROM.

3.3- EMM filter command list


In addition to the mass of EMM commands which perform the various card
management functions, there are a few EMM commands which are used solely to
filter the EMMs so that EMMs can be directed against specific cards, groups
of cards, or the entire universe of cards within a system. These filter
commands must appear as the first command in an EMM, and every EMM has _some_
sort of filter command (even if it's the "all cards" filter). In all cases,
the filter command will include a system ID which corresponds to the system
ID of the broadcast system for which the EMM is intended. In addition, the
system ID that's passed with the EMM filter command must match the system ID
that's sent in the cleartext portion of the EMM message. The EMM filter
commands on the ROM3 card are as follows:

Filter CMD Function


---------- ----------------------------------------------------------
$00 Filter based on CAM ID (EMM targeted at a single card)
$01..$20 Filter based on shared address and bitmask (EMM targeted
at a group of up to 256 cards)
$3D All cards, message includes an 8-byte signature at the end
$3E Filter based on provider category (EMM targeted at cards
which are subscribed to a particular broadcast service,
or to customers with a specific programming interest)
$3F All cards

3.4: EMM filter command breakdown

3.4.1- EMM filter command $00


If the EMM filter command is $00, this tells the CAM that it should filter
the EMM based on its CAM ID, and execute the EMM if and only if the CAM ID
in the EMM filter command matches the CAM's CAM ID in EEPROM. The format of
this EMM filter command is:

00 ;EMM filter command


01 01 ;System ID
11 22 33 44 ;CAM ID

In this example, only a CAM with a CAM ID of 11223344 will execute the
remainder of the EMM. This is a fixed-length command with a length of 7.
3.4.2- EMM filter commands $01..$20
If the EMM filter command is $01..$20, this tells the CAM that there are
three conditions that must be met for the EMM to be executed. First, the
CAM's shared access group (which is usually the same as the 3 high bytes of
the CAM ID) for the type $06 data item whose system ID high byte matches the
filter command's system ID high byte must match the data in the EMM command.
Second, the CAM's customer word pointer (which is usually the same as the low
byte of the CAM ID) must be in the range of cliques being addressed by the
EMM filter (lowest cust word ptr allowed = lowest clique times 8, highest
cust word ptr allowed = lowest clique times 8 + number of cliques times 8).
Third, the bit in the "CAM address bitmap" which corresponds to the CAM's
customer word pointer must be set. The format of this EMM filter command is:

20 ;EMM filter command (Number of


; cliques addressed in this
; filter)
01 01 ;System ID
01 02 03 ;Shared access group to match
00 ;Lowest clique being addressed
01 00 00 00 00 40 00 00 ;Clique bitmap
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 01

In this case, in order for a CAM to execute the remainder of the EMM, its
shared access group for the system ID hi 01 must be 010203, and its customer
word pointer must be either $07 (enabled by the set bit in byte 0 of the CAM
address bitmap), $29 (enabled by the set bit in byte 5 of the CAM address
bitmap) or $FF (enabled by the set bit in byte 31 of the CAM address bitmap).
Note that an entire group of 256 CAMs are potentially addressed by this
filter. A similar filter for a CAM whose customer word pointer is $29 or $2F
could be done in fewer bytes like this:

01
01 01
01 02 03
05
41

Because this filter only intends to address two cards whose customer word
pointers are in a common clique, only a single byte of bitmap information is
required. This is a variable-length command with a length of $07 plus the
filter number (which is also the number of cliques being addressed).

3.4.3- EMM filter command $3D


If the EMM filter command is $3D, this tells the CAM two things: First, that
the EMM is addressed to all cards associated within the master broadcast
system. Second, that the actual maximum length of the EMM is $38 bytes
instead of the standard $40. Presumably, this filter command is used to
modify the EMM processing in the event that a command $01 EMM is being
executed, since command $01 EMMs are only $38 bytes long, but include an
8-byte signature at the end of the EMM. The format of this EMM filter command
is:

3D ;EMM filter command


01 01 ;System ID
In this case, the EMM will be executed by all cards with a master system
ID of 0101. This is a fixed-length command with a length of 3.

3.4.4- EMM filter command $3E


If the EMM filter command is $3E, this tells the CAM that in order for the
remainder of the EMM to be executed, the CAM must be subscribed to a specific
broadcast service. Included in the filter are upper and lower limits for
broadcast service IDs which this message may refer to, and if the CAM is
subscribed to a broadcast service which falls between the lower and upper
bounds specified by the filter, the EMM is executed. Broadcast services
(other than that provided by the master system ID provider) are stored in type
$02 data items, and the field which specifies the ID of a broadcast service is
the PROVIDER CATEGORY byte. Note that this type of EMM could also be used to
broadcast EMMs specifically to people who are subscribing to a specific type
of programming...it does not necessarily require a broadcaster other than the
master system broadcaster to be involved...this allows type $02 data items to
specify not only alternate programming providers, but also customer groups.
The format of this EMM filter comand is:

3E ;EMM filter command


01 01 ;System ID
05 ;Minimum provider category
00 0A ;Maximum provider category

In this case, the EMM will be executed if the CAM contains a type $02 data
item with a system ID of 0101 and a provider category no less than 5 but
no greater than 0A. Note that although the provider category field in the
type 02 data item is a single-byte field, the maximum provider category field
in this EMM filter command must be a two-byte value, because the routine in
the CAM that does the range-checking has a special case that gets executed
in the event the byte that immediately follows the first comparison value (in
this case, the minimum provider category) has its high bit set. Therefore,
in order to be able to check the entire 8-bit range of provider categories,
the maximum provider category value must be treated as a 16-bit number whose
high byte will always be 00 (actually, any value less than $80 would work,
but 00 will be the norm). This is a fixed-length command with a length of 6.

3.4.5- EMM filter command $3F


If the EMM filter command is $3F, this tells the CAM that the EMM is
addressed to all cards within the master broadcast system. The format of this
EMM filter command is:

3F ;EMM filter command


01 01 ;System ID

In this case, the EMM will be executed bu all cards with a master system
ID of 0101. This is a fixed-length command with a length of 3.
4: 21-xx data types

4.1- Data type list


NagraVision cards manage subscription, PPV, and encryption information using
what is essentially a crude flash file system. Their data engine can deal
with 12 known fixed-length data types and 2 known variable-length data types.
These data items are all stored in a single, large area of the EEPROM which is
given over entirely to this purpose. As new data items are added, they may be
added to the end of existing data or stuck in a hole that was created by the
elimination of another data entry. Commands $20 and $21 are used to determine
the existence and values, respectively, of the data items stored in the card's
EEPROM. In this section, I'll be describing the functions and structures of
the data items that I know about.
There are at least 14 types of data that can be polled from the card, each
having a unique data structure. Note that not all data for a given data type
is necessarily available to a 21-xx command. Also, it appears as though the
first two bytes of data for fixed-length data types are overhead and not
actually returned in a 21-xx command. Known data types are as follows:

Type Len Avail Data description


---- --- ----- -------------------------------------------------------
$01 $28 $1E Married IRD info. Includes such information as the
married IRD's serial number, subscriber's ZIP code,
(for sports blackouts), subscriber's time zone, IRD
box key, etc. Note: Contains hidden info (box key)
$02 $06 $04 Secondary programming provider information
$03 $0E $0C Last PPV paid
$04 $0C $0A Indirection information (channel aliasing)
$05 $0E $0C Date information
$06 $39 $26 Public service info. Includes blackout information
and public decryption keys for $03 commands (on ROM2
cards, anyway). Note: Contains hidden info (decrypt
keys)
$07 $7A $03 Key information. Includes the decrypt verify key, and
possibly the 00/01/02 keys
$08 $1E $1C Valid channel services (enables channels in the program
guide, allows the IRD to decide on its own if a channel
is subscribed, and if not, to display the "this channel
is not subscribed" dialog)
$09 $27 $25 PPV theme/level information
$0A $2A $28 PPV number information
$0B $24 $22 Valid PPV services (enables the IRD to decide on its own
whether or not to display the "this PPV has not been
purchased" dialog)
$0C $13 $11 Credit/spending limit information
$10 var var Email
$11 var var Misc. strings

Details on each data type are included below.

4.2: Data type breakdown


4.2.1- Data type $01
This is information on the IRD that the CAM is married to. It includes such
information as the married IRD's serial number, the ZIP code and time zone
where the subscriber is located, information on the IRD's software revision
level, and the IRD box keys. The structure of the $01 data type is as
follows:

00 01 ;System type. 0001=EchoStar/Sky Vista


0801=ExpressVu
4001=Via Digital
00 ;IRD status byte (see below)
01 ;Free access group
00 01 38 F0 ;ZIP code in HEX (80112)
E4 ;Time zone (see below)
00 ;DVB deviation byte
33 22 11 00 ;IRD # (00112233 = 00 0112 2867 71)
31 30 30 42 42 54 45 41 ;IRD bootstrap revision: "110BBTEA"
35 32 30 50 31 31 44 4E ;IRD firmware revision: "520P11DN"
11 22 33 44 55 66 77 88 ;IRD box key (hidden)

It's interesting to note that the "system type" field is pretty much the
same as the "system ID" field that appears in other data types, except that
in "system ID", the low bit of the high byte seems to be always set, while in
"system type" it seems always to be clear.

IRD status byte: Several status flags relating to the IRD and/or
subscription are passed in this byte as follows:

Bit Description
--- ------------------------------------------------------------
7 Subscription suspended (1=yes) if type $01, $02, $06, or $07
Item suspended if type $08, $09, $0A, or $0B
Email deleted if type $10
6 Callback performed for this item ($08..$0B only)
5 Impulse subscription channel ($08 only)
4 PPV watched if type $09..$0B
Email read if type $10
3 High priority (type $10 only)
2 Predefined message (type $10 only)
1 Data item compressed
0 PPV charge applies per unit time (1=yes) ($08..$0B only)

Time zone encoding: The time zone is expressed as an 8-bit signed integer
which represents the number of 15-minute ticks that need to be added or sub-
tracted from GMT. Thus, 00 is GMT, FF is GMT minus 15 minutes, etc. The
following table details CONUS time zones:

Time Offset Offset Time zone Time zone


Zone (hours) (ticks) byte (dst) byte (std)
---- ------- ------- ---------- ----------
PST GMT-8 GMT-32 E4 E0
MST GMT-7 GMT-28 E8 E4
CST GMT-6 GMT-24 EC E8
EST GMT-5 GMT-20 F0 EC

Note that NagraVision handles daylight savings time by simply adjusting the
time zone byte for all IRDs in areas that are affected by daylight savings
time, causing the time to shift an hour back in the fall/winter (on the last
Sunday in October, in fact) and an hour forward in the spring/summer (on the
first Sunday in April).
Note also that the data that is returned for a 21-01 request is NOT the
raw type 01 data: The IRD key field is omitted.

4.2.2- Data type $02


Type $02 is information about alternate programming providers and/or
customer-specific interests. This data type seems to be used only to allow
filtering of EMM commands to specific groups of cards, which could either be
cards subscribed to a particular package or programming provider (this would
be similar to the old situation with DirecTV where DirecTV and USSB both
provided programming to DSS customers), or cards belonging to customers that
have been itentified by their master programming provider as having specific
interests (ie., ethnic channels, sports packages, porn channels, religious
programming, etc.). Data type $02 breaks down as follows:

01 01 ;System ID. 0101=EchoStar/Sky Vista


0901=ExpressVu
4101=Via Digital (Spain)
00 ;IRD status byte (see data type 1)
01 ;Provider category

4.2.3- Data type $03


Type $03 data looks like it relates to the last-paid-for PPV event. I've
never seen it show up in a log, though, so I can't be sure how it's used. The
data item itself breaks down as follows:

01 01 ;System ID
01 02 03 ;PPV Event ID
01 02 ;System ID of event provider
01 02 03 ;Rights identifier
01 02 ;Purchase date

4.2.4- Data type $04


Type $04 data seems to allow "aliasing" of channels. With this data type,
channels that are broadcast by provider A can be aliased to appear to also
be broadcast by provider B. The data item looks like this:

01 02 ;Source system ID (subscriber's


; system ID)
01 02 ;Target system ID (System ID of
; provider that actually broadcasts
; the channel)
01 02 ;Service identifier (Lowest channel
; to alias)
01 02 ;Service identifier extension (Highest
; channel to alias)
01 02 ;Last date for alias validity

Note that the service identifier here is the same type of service identifier
that is associated with data type $08.

4.2.5- Data type $05


Data type $05 is referred to as a "Date record". I'm not real sure what
use this data has, but the data type breaks down as follows:

01 01 ;System ID
01 ;IRD Status flag (see data type $01)
01 ;Date identifier (cluster number) (?)
01 02 ;Modification date
01 02 ;Begin date
01 02 ;End date
01 02 ;Rights date

4.2.6- Data type $06


This data type contains information about programming in general, so its
likely some sort of "programming provider" data type. Included in this is
information about blackouts (which seems to be a bit mapped field), as
well as (on ROM2 cards, anyway) the public keys used to decrypt the $03
commands (even though they're not returned for a 21-06 command). In addition,
some type $06 data (one entry per card, as far as I can tell) seems to include
a telephone number...this is possibly the phone number that the IRD is
supposed to call when it wants to report PPV purchases and so on. This data
has the following structure:

00 ;Program provider class


00 ;Address pointer in EMM header
00 ;IRD status flag (see data type $01)
00 BC 61 ;Shared address (High 3 bytes of CAM
; ID)
4E ;Customer word pointer (low byte of
; CAM ID)
18 00 45 42 50 ;Callback phone # (1-800-454-2504)
4F FF FF FF FF
FC ;Callback period (in hours?)
FF FF ;Next regular callback date
00 FF ;Next regular callback time
FF 00 ;Immediate callback date
00 00 ;Immediate callback time
00 ;Callback retry period (in hours?)
00 00 00 00 00 00 00 00 ;Blackout info
00 00 00 00
00 00 00 00 00 00 00 00 ;Key 0 (hidden)
11 11 11 11 11 11 11 11 ;Key 1 (hidden)

As you can see, there's lots of information in the type $06 data that gets
used for billing, etc.
Note that when type $06 data is returned, key 0 and key 1 are omitted.

4.2.7- Data type $07


Data type $07 contains data on various keys used to decrypt EMMs and
validate the authenticity of received messages. Every type $07 data item
includes a series of EMM decryption keys (the 512-bit public key as well as
several 4-byte keys whose function I don't yet understand), and a verify key.
The specific type $07 data item from which keys are selected is determined
by bit fields in the messages to which the keys are to be applied. The two
type $07 data items that can be found in EchoStar smart cards are:

01 ;Key set number


3F
00 ;Key type byte of some sort
00 00 00 00 00 00 00 00 ;Parity key 0
00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 ;Parity key 1
00 00 00 00 FF FF FF
FF FF FF FF FF FF FF AF ;Parity key 2
9D 5E C6 6D 02 FF FF
1E FF 75 45 4C FD 2D 93 ;Verify key
19 84 D7 CA 6A 61 24 4E ;512-bit EMM decrypt key
0F C5 42 15 84 9E A3 08
BA 63 F8 E4 4A EC EF 69
7D 91 AF 54 86 3F 3F F3
95 2A 98 46 11 14 CE 3D
43 2C A7 C9 F2 1F 5B 9C
DA 44 42 F4 52 D5 C5 4A
39 1F EB 53 CB AE 54 D2

00 ;Key set number


3F
00 ;Key type byte of some sort
FF FF FF FF FF FF FF FF ;Parity key 0
FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF ;Parity key 1
FF FF FF FF FF FF FF
10 E6 78 2B E2 7A 02 E1 ;Parity key 2
90 D9 CD DA 12 21 C4
56 BF 16 B8 44 85 04 CF ;Verify key
33 1E F8 FE CE 2E 96 43 ;512-bit EMM decrypt key
89 7B 36 83 40 19 51 8C
8A 7A B7 91 D7 AF C5 DE
7F 77 52 55 FD 1D 4E 9C
FE 26 79 13 C8 D3 8D 8F
CF 4D 0E C6 49 B6 02 F8
74 7B E3 BA E3 11 F6 E3
01 DE 29 1B E4 86 A3 C3

Note that the verify key in key set 1 is the one that's used to validate
most ECMs received by the EchoStar cards, but that for EMMs, the verify key
that goes with the selected EMM key is used to validate the decrypted EMM.
Also note that only the first byte of type $07 data is ever returned.

4.2.8- Data type $08


This data type contains information relating to the standard channel
services which the customer is subscribed to. This information is used by the
CAM to decide whether a program whose data is passed in a $03 command is
viewable, and by the IRD to decide which channels to show in its EPG. In a
typical subscribed card, this data type will have many entries. An example
that would allow viewing of all available channels in the program guide is:

01 01 ;System ID
00 ;IRD status byte (see data type 1)
00 00 00 ;Rights identifier
00 ;String ID (Optional: 00=no string)
00 00 00 ;Impulse subscription price
00 00 ;Modification date
00 00 ;Begin date
4C 21 ;Expire date
4C 21 ;Rights date
00 00 ;Min. channel authorized by this
; packet
7F FF ;Max. channel authorized by this
; packet
80 00 ;Component (?)
FF ;Theme (?)
00 FF ;Theme extension (?)
00 ;Level (?)

Note that presenting this data to the IRD is not enough to receive
programming: the IRD will still depend on the CAM to provide the video
decryption keys, and if the CAM knows that a channel for which the IRD is
requesting information isn't subscribed, it won't return the proper keys.

4.2.9- Data type $09


This data type seems to relate to purchased PPVs based on theme. My guess
is that this allows, for example, a blanket PPV to cover, say, the Olympics or
something, and each event you watch would be covered by the same PPV buy. The
data item breaks down as follows:

01 01 ;System ID
01 ;IRD flags (see data type $01)
01 02 03 ;Rights identifier (pay-per-view
; event ID)
01 ;String ID (optional: 0=no string)
01 02 03 ;Impulse buy price
01 02 ;Modification Date
01 02 ;Begin Date
01 02 ;Expiration Date
01 02 ;Rights Date
01 02 ;Last date of operation on token
01 02 03 ;Credit in tokens
01 02 03 04 ;Debit in tokens
01 02 ;Min. channel authorized by this
; packet
01 02 ;Max. channel authorized by this
; packet
01 02 ;Component
01 ;Theme (lowest theme for this event)
01 02 ;Theme extension (highest theme for
; this event)
01 ;Level

4.2.10- Data type $0A


Data type $0A seems to refer to PPV events that have been pre-paid. The IRD
source refers to this as "PPV per number" data. The data item breaks down as
follows:

01 01 ;System ID
01 ;IRD flags (see data type $01)
01 02 03 ;Rights identifier (pay-per-view
; event ID
01 ;String ID (optional: 0=no string)
01 02 03 ;Impulse buy price
01 02 ;Modification Date
01 02 ;Begin Date
01 02 ;Expiration Date
01 02 ;Rights Date
01 02 ;Last date of operation on token
01 02 03 ;Credit in tokens
01 02 03 04 ;Debit in tokens
01 02 ;Min. channel authorized by this
; packet
01 02 ;Max. channel authorized by this
; packet
01 02 ;Component
01 02 03 ;Pay-per-view number (lowest PPV ID
; for this event)
01 02 03 04 ;Pay-per-view extension (highest PPV
; ID for this event)

4.2.11- Data type $0B


This data type is much like the $08 data type, except that it relates to
PPV events rather than normal channels. A type $0B data item that authorizes
all PPVs would look like this:

01 01 ;System ID
00 ;IRD flags
00 00 00 ;Pay-per-view event ID 000000..7FFFFF
01 ;PPV ID within card
00 02 99 ;Event price (BCD dollars+cents)
00 00 ;Purchase date
80 00 ;Event expiration date
00 ;Service string ID (optional: 0=no
; string)
00 00 ;Min. channel authorized by this
; packet
7F FF ;Max. channel authorized by this
; packet
80 00 ;Component (?)
00 00 00 ;Lowest PPV ID for this event
7F FF FF FF ;Highest PPV ID for this event
00 00 ;ECM odometer (allows decision as to
; whether or not enough of the event
; was watched to merit charging the
; user for it)
00 01 ;View start date
0F 51 ;View start time

Note that presenting this packet to the IRD is not enough to receive
programming: the IRD will still depend on the CAM to provide the video and
audio decryption keys, and if the CAM knows that a PPV for which the IRD is
requesting information isn't authorized, it won't return the proper keys.

4.2.12- Data type $0C

This data type relates to the user's spending limit and credit with the
program provider. It's used to determine whether or not an impulse PPV
purchase will be allowed. The data breaks down as follows:

01 01 ;System ID
01 ;IRD status byte (see data type $01)
01 02 03 ;Rights identifier
01 02 ;Last date of operation on cash
01 02 03 ;Credit in cash
01 02 03 04 ;Debit in cash
01 02 ;Phone home threshold

4.2.13- Data type $10


Data type $10 is used to store email in the CAM. Although I personally have
never seen this data type used by EchoStar, its structure is as follows:

01 01 ;System ID
01 ;IRD status byte (see data type $01)
01 ;Mail item ID within CAM
01 ;Received flags ($FF=received)
<var> ;Email data

4.2.14- Data type $11


This data type contains information about purchased PPV events. The
individual elements are variable-length, and seem to be able to contain
anything from the date and time the event was purchased to the name of the
event to the channel on which the event was broadcast. There's no set pattern
I can see to the data in this data type, other than the event name seems to be
set between 00 bytes.
According to the CA_NASP.H file, the data breaks down as follows:

01 ;PPV ID within card


01 ;PPV data length
<var> ;PPV data

It would appear that the information in these data items is linked to the
type $0B data items that actually enable the viewing of the PPVs through the
"PPV ID within card" field.

4.3- How data is stored in the cards


Because the data storage facility of the NagraVision smartcards uses a
simple flash file system type of approach, any type of data can be found at
any location within the card's data EEPROM space. There is a pointer in
EEPROM at address E030:E031 (high byte at E030) that defines the first EEPROM
address that may be used for data storage. By definition, the last EEPROM
address that may be used for data storage is the last byte of EEPROM (which is
at address EFFF).
Each data item is stored in EEPROM along with a header which tells the
card some things about the data. The headers for data stored in ROM2-based
cards and ROM3-based cards differ, however: The ROM2-based header includes
some rudimentary error-detection information that allows the card to determine
(with a reasonable degree of certainty) that when searching for data, it has
located the start of a data record. In ROM3-based cards, this error-detection
information has been discarded, apparantly in favor of a byte which allows the
card's flash file system to determine some things about the data itself. Each
ROM version's header structure will be discussed individually below:
4.3.1- ROM2 headers
The header for a data item in a ROM2 card can be either 2 bytes long or 4
bytes long, depending on the data type: Data types 01..0E have a 2 byte
header, while data types 10..7F have a 4 byte header. The format is as
follows:

2 byte header 4 byte header


---------------------------- -----------------------------------------
Byte 0: Encoded data type Byte 0: Always $7F
Byte 1: Raw data type Byte 1: Encoded upper nibble of data length
Byte 2: Encoded lower nibble of data length
Byte 3: Raw data type

Example of a 2 byte header: Type $01: 31 01


Example of a 4 byte header: Type $11, length of $08: 7F 00 78 11

The encoded data bytes encode a single nibble of data into a 7-bit data
byte in which the lower nibble is the raw data, and the low 3 bits of the
upper nibble contain parity information about the data in the lower nibble as
shown below:

Parity bit Calculation


---------- -------------------------
Bit 4 Bit 0 XOR Bit 1 XOR Bit 3
Bit 5 Bit 0 XOR Bit 2 XOR bit 3
Bit 6 Bit 1 XOR Bit 2 XOR bit 3

This type of encoding is called Hamming encoding (named after the guy who
invented it). It allows correction of any single-bit error in a byte. It's
not entirely clear why the guys who wrote the NagraVision code decided to do
this with the data headers in the ROM2 cards (and apparantly, they decided
it wasn't worthwhile, see section 4.3.2: ROM3 headers, below), since they
just store the data in raw format, with no way to correct it if a problem
should come up. In a ROM2 card, the data area should generally start at
$E933, meaning that at best, a ROM2 card can hold $06CD (1741) bytes' worth
of data items and headers. This number is actually quite small, but it is
necessary since almost all of the other EEPROM space is taken up by various
bug-catchers which have been installed in the EEPROM to correct problems
with the card's ROM-based code. It's pretty clear that Kudelski wasn't very
happy with this number, since they expended the time, effort, and money to
create the ROM3 version of the card, which incorporates most of the bug
fixes contained in the ROM2 cards' EEPROM, as well as other improvements
to things like the EEPROM data storage system.
Note that in an earlier version of this FAQ I incorrectly reported that
bytes 1 and 2 of the 4-byte header were an encoded version of the data type.
I'm not real sure what led me to that conclusion...I can only assume that I
must have been _really_ tired when I wrote it (and commented the CAM
disassembly to match). I've since had occasion to look over that piece of
code again, and noticed the error, which I still can't explain; the code is
really straightforward...I have no idea what would have caused me to make
that mistake.

4.3.2- ROM3 headers


After the ROM2 card's release, the guys who wrote the NagraVision code
apparantly decided that they didn't need to be able to error-correct the
data in a data record's header (or improve their chances of random detection
of the start of a data record). Instead, it appears that they decided that
what they needed was a way to allow the flash file system to recover more
gracefully from a catastrophic error (like a power failure) that occurred
while doing updates to any data item stored in EEPROM. To this end, they
reformatted the data header in the card such that all data items have a 2-byte
header, formatted as follows:

Byte 0: Flags byte (See below)


Byte 1: Data item length+1

The flags byte indicates the current "state of being" of the data item with
which it is associated. By looking at the value of the flags byte, the
card can hopefully figure out what addresses in EEPROM were being used by the
associated data item, and what was being done to the data item when the
problem occurred. The structure of the flags byte is as follows:

Bit 0: Header being created


Bit 1: Header created successfully
Bit 2: Data written successfully
Bit 3: Data no longer in use
Bit 4: Header being erased
Bit 7: Modified data item

Each of the first 5 bits implies certain things about the other fields in
the data item, and if any of the low 5 bits of the flags byte is set, all of
the other bits below it should be set as well (for example, if bit 2 [data
written successfully] is set, then bits 1 and 0 should also be set, if the
flags byte is to be treated as valid. Assuming that we're examining a FLAGS
byte at address ADDR, based on the value of the FLAGS byte, we can assume the
following about the other data fields:

Highest flag set Implications / recovery possiblities


---------------------------- ---------------------------------------------
Header being created If this bit is the only one set, it can be
assumed that starting at address ADDR+2, the
EEPROM will contain all $00 bytes until the
start of the next known valid data item header.
If this bit is the only one set, recovery is
possible by writing to the length byte the size
of the erased block, and then writing a value
of $0F to the FLAGS byte, indicating that the
data area is reusable.

Header created successfully If this bit is set, it can be assumed that the
length byte is a valid one, and can be used to
calculate the position of the next valid data
item header. If this bit is set, recovery is
possible simply by writing a value of $0F to
the flags byte, indicating that the data area
is reusable. The card, however, goes a step
further: It erases the data field of the data
item to all 00s, then it erases the length
byte, followed by the FLAGS byte.

Data written successfully If this bit is set, it indicates that all of


the data in this data item can be treated as
valid, and that the memory occupied by this
data item is not eligible for reuse. No
recovery is necessary.

Data no longer in use If this bit is set, it indicates that the data
in this data item is no longer in use, and can
therefore be treated as reusable space. In
some cases, this bit indicates that the data
area of this data item has been filled with all
$00 bytes.

Header being erased If this bit is set, as with "Header being


created", it can be assumed that starting at
address ADDR+2, the EEPROM will contain all $00
bytes until the start of the next known valid
data item header. If this bit is set, recovery
is possible by writing to the length byte the
size of the erased block, and then writing a
value of $0F to the FLAGS byte, indicating that
the data area is reusable.

Modified data item If this bit is set, it indicates that this


data item is a modified version of a data item
that had existed previously in EEPROM. In the
case of a modified data item, the length byte
is immediately followed by the address in
EEPROM where the original data was located,
as well as the length of the original data
item. If this bit is set, but the "Data no
longer in use" bit isn't, it means that the
process of copying the modified data to the
original data item was interrupted, so the
copy process should be completed and this
data item's "data no longer in use" bit should
be set, indicating the copy was completed.

The length byte's value of "data item length+1" is derived from the fact
that it actually represents the total number of data field bytes that follow
the 2-byte header. The first byte of the data field contains the data item
type identifier, hence the +1.
When a ROM3 card is reset, it scans its EEPROM area, looking for data items
that appear to need to have some sort of recovery performed. If any such
items are found, the necessary recovery steps are taken to try and ensure that
the EEPROM is always "healthy". After data items that appear to have suffered
an interruption have had their recovery performed, the card checks through all
of the "linked" data items (type $11 data) to ensure that every type $11 item
that exists in the EEPROM has a link to a valid type $8, $9, $A, or $B data
item. The link is established through the "PPV ID within card" field of the
type $11 data item: It must match the "String ID" byte of a type $8, $9, or $A
item, or the "PPV ID within card" or "Service string ID" byte of a type $11
data item. Any type $11 items that are found to not have valid links are
erased.
As a final initialization step, the card goes through the EEPROM space and
converts all of the reusable (or unused) data space it finds into reusable
data items with lengths no longer than $FE bytes. Presumably, this is so that
the card can more easily search for data item space when a "write data item"
operation is performed.
Whenever a data item is created, the card will always attempt to ensure
that at least $2E bytes of data space remain in the EEPROM. Presumably, this
is so that a modification of up to $28 bytes of data can always be performed.
Lastly, in a ROM3 card, the data area generally should start at $E400. Note
that this number is "soft", and may change if a large number of bug-catchers
are installed in the EEPROM area.

==============================================================================
5: The backdoors

5.1- The backdoor passwords


The NagraVision cards apparantly have several backdoor commands built in to
allow factory loading of EEPROM and other utility functions. These backdoors
require two 16-byte passwords before they will work. The first password is
stored in ROM, and is the same for all NagraVision smart cards with the same
ROM version. The second password is stored in EEPROM, and is presumably
unique to each card. In this section, I'll provide all the details I have
on the backdoor passwords and the backdoor commands.

5.1.1- The ROM-based password


The ROM-based password is the first password required by the backdoors. The
received password must exactly match the password in ROM, or the password
check fails. Known ROM-based passwords are as follows:

ROM ver Password


------- ---------------------------------------------------------------
ROM2 $8F $AB $C2 $64 $44 $9A $FE $70 $1D $E7 $62 $FA $B1 $4C $31 $06
ROM3 $8F $AB $C2 $64 $44 $9A $FE $70 $1D $E7 $62 $FA $B1 $4C $31 $06

5.1.2- The EEPROM-based password


The EEPROM-based password is included for further security in case the
ROM-based password were to somehow be revealed to the public. It is not
certain whether the password is computed based on the card's CAM ID, or
whether the password is randomly generated at production time, and the
password stored in a database which is delivered, along with the cards, to
the factory for EEPROM loading. Based on the fact that if the EEPROM-based
password contains too many '0' bits, it is initialized to be the same as the
ROM-base password, however, it seems likely that cards are shipped with the
EEPROM-based password set to all 0's, so that the first time the card is
reset, the EEPROM-based password will be set to a known value that is not easy
for a hacker to guess.
The EEPROM-based password is different from the ROM-based password in that
the programmers at Kudelski took into account the fact that EEPROM is less
robust than ROM and made the requirements for a successful password check
more relaxed than on the ROM-based password: The received password can differ
from the actual EEPROM-based password by up to 2 bits and still be considered
a good match. Presumably, this is because the programmers recognize that
EEPROM data has a degree of volatility to it.
The programmers at Kudelski also added some requirements to the EEPROM-based
password that don't exist for the ROM-based password. These requirements
exist to help ensure that the EEPROM-based password contains a sufficiently
random pattern of bits to make it reasonably secure. The requirements are
as follows:

-The EEPROM-based password must contain no fewer than 32 '1' bits. If


fewer than 32 '1' bits are found in the EEPROM-based password when the
card is reset, the EEPROM-based password will be replaced with the
ROM-based password.
-The EEPROM-based password must contain no more than $60 '1' bits. If
more than $60 '1' bits are found in the EEPROM-based password when the
card tries to verify the received passwords, the EEPROM-based password
is immediately considered invalid, and backdoor access is blocked.

5.2- The backdoor commands


Once one knows what the backdoor passwords are (or knows how to glitch the
card so that the card THINKS one knows the backdoor passwords), several
utility commands become available that theoretically should only be used for
testing the card and loading its EEPROM at the factory. For a hacker,
however, the backdoors provide an easy way of dumping the card, getting
3M code into the card, and so on. Here, I'll detail the backdoor passwords
that I know of. Note that so far, I can only be sure these commands will
work on ROM3 cards. Presumably, however, these commands would not change
with ROM versions.

5.2.1- Backdoor command $0E: Erase EEPROM


This command is used to erase a block of EEPROM. Format is as follows:

21 00 07 ; A0 0E ;Backdoor command: Erase EEPROM


<addrhi> <addrlo> ;Start address for erasure
02 ;Command data length
<endh> <endl> ;Offset to last address to erase
; plus one
<checksum> ;Checksum

The start address for the EEPROM erasure must be set as with the D6 backdoor
command, below.
The end address is defined as an offset from the base address generated by
the "init" address set the first time this command is sent. An example of
this command would be:

21 00 07 ; A0 0E ;Backdoor command: Erase EEPROM


94 30 ;Start address for erasure
; (base to $E000, start at E030)
02 ;Command data length
10 00 ;Last byte to erase is at
; base addr+$1000-1, or $EFFF
3E ;Checksum

This command will erase EEPROM from $E030 to $EFFF.

5.2.2- Backdoor command $20: Login


This password is used to tell the CAM what you think the passwords are. The
passwords that are sent with this command are checked and used prior to
executing any other backdoor commands, so the passwords only need to be
sent once. The format of this command is as follows:

21 00 25 ; A0 20 00 00 ;Backdoor command: Login


20 ;Command data length
8F AB C2 64 44 9A FE 70 ;ROM-based password
1D E7 62 FA B1 4C 31 06
00 11 22 33 44 55 66 77 ;EEPROM-based password
88 99 AA BB CC DD EE FF
DE ;Checksum
5.2.3- Backdoor command $B0: Dump memory
This password is used to make the CAM output the contents of a specified
memory area. In theory, any memory address can be dumped, but I suspect that
the card's MACM will prevent dumping system ROM. This command has two
formats:

21 00 05 ; A0 B0 ;Backdoor command: Dump


94 00 ;Start address (see below)
40 ;Number of bytes to dump
E0 ;Checksum

21 00 07 ; A0 B0 ;Backdoor command: Dump


94 00 ;Start address (see below)
00 ;filler
00 40 ;Number of bytes to dump
E2 ;Checksum

Note that although the second form of this command theoretically allows up
to $FFFF bytes of memory to be dumped, dumping more than about $50 or so bytes
of data will result in a chained message sequence, whereby the host device
(that's you) must respond to each chunk of data as the card provides it. The
proper resposne to get the CAM to continue with the message depends on the
header for the most recently-received block, as shown below:

Received
NAD and PCB Correct response
----------- ----------------
12 20 21 80 00 A1
12 60 21 90 00 B1

The start address has two possible means of encoding. The first means,
illustrated above, causes the address pointers in the card to be initialized.
Five different possible values are useful for this:

90 xx: Initialize address to $0000


91 xx: Initialize address to $8000 (not at all useful, really)
92 xx: Initialize address to $0020
93 xx: Initialize address to $4000 (useful for dumping ROM)
94 xx: Initialize address to $E000 (useful for dumping EEPROM)

Note that although the addresses are initialized to the absolute addresses
shown, the effective address for the first command will be the initialization
address plus xx, so a value of $9320 will result in the address being
initialized to $4000, and an effective address for that command of $4020.
Similarly, a value of $9438 will result in the address being initialized to
$E000, and an effective address for that command of $E038.

Once the address pointers in the card have been initialized using one of the
five constants above, the address bytes can be filled with an offset from the
address with which the pointers were initialized. Thus, if the pointers were
initialized to $4000 by sending $90 $00, if the next dump specifies an address
of $3040, the start address will actually be $4000+$3040, or $7040.

5.2.4- Backdoor command $D6: Execute code/Write EEPROM


This is probably the most useful backdoor command. It has two possible
functions. The first allows the user to send a code fragment up to $5E or so
bytes long to the card and have the card execute that code from RAM. The
format for this function of the command is as follows:

21 00 nn ; A0 D6 98 00 ;Backdoor command: Execute code


<len> ;Command length. Never checked,
; so can probably be $00
<code fragment here> ;The code to be executes is sent
; here in the clear. The code
; will be executed at address
; $1A1 for a ROM3 card, or $1A5
; for a ROM2 card.
<checksum> ;Checksum

The second function that this command provides is an absolute write of up to


$5B bytes to EEPROM, starting at any valid EEPROM address. Note that in
theory, any address could be passed as the destination address, but only
EEPROM addresses can be written to. The format of the write EEPROM version
of this command is as follows:

21 00 nn ; A0 D6 ;Backdoor command: Write EEPROM


<addrh> <addrl> ;Start address (see below)
<len> ;Number of bytes to write (up
; to $5B), must be equal to nn-8
<data to write> ;Data to be written to EEPROM
<checksum> ;Checksum

The start address has two possible means of encoding. As with backdoor
command A0 B0, the first means causes the address pointers in the card to be
initialized. The only useful initialization value for the write EEPROM
command is:

94 xx: Initialize address to $E000

Note that although the address is initialized to $E000, the effective


address for the first command will be the $E0xx, so a value of $9420 will
result in the address being initialized to $E000, and an effective address for
that command of $E020.
After the address pointer is initialized, an offset from $E000 can be passed
in the address field. Examples are as follows:

21 00 15 ; A0 D6 ;Backdoor command: Write EEPROM


94 20 ;Init address to $E020
10 ;Write $10 bytes
00 11 22 33 44 55 66 77 ;Data to write
88 99 AA BB CC DD EE FF
E6 ;Checksum

21 00 15 ; A0 D6 ;Backdoor command: Write EEPROM


04 43 ;Effective address: $E443
; (assumes address was init'ed
; as above)
10 ;Write $10 bytes
00 11 22 33 44 55 66 77 ;Data to write
88 99 AA BB CC DD EE FF
15 ;Checksum
6: Inside NagraVision cards

6.1- The MCU core


The microcontroller in the NagraVision smartcards is an ST Micro (SGS
Thomson at the time they were first released) ST16CF54A. It's basically a
6805, but with a couple of additional features...it has a cryptoprocessor
built in which allows high-speed (well, relatively so) modular multiplication
and exponentiation, and it has one additional instruction: TSA (transfer stack
to A: Opcode $9E). The cryptoprocessor allows it to do some kinds of math
pretty quickly, and the TSA instruction allows the firmware to easily figure
out the value of the stack pointer. The card has 8K of library ROM that came
from SGS, 16K of user ROM which was written by Nagra, 4K of EEPROM space that
can be used to hold additional code or data, and 512 bytes of RAM. If you
want to understand how the firmware works, I strongly suggest learning about
the 6805 (because information on it is plentiful, whereas information on the
16CF54A is sparse at best). Here's a little bit of information about the
internal registers of the 16CF54A:

Addr Description
----- -------------------------------------------------------------
$00 I/O register
$01 Security register
$03 EEPROM control register
$04 Test status register
$06 Random number generator high byte
$07 Random number generator low byte
$0A Cryptoprocessor I/O byte 1
$0B Cryptoprocessor I/O byte 2
$0C Cryptoprocessor control byte 1
$0D Cryptoprocessor control byte 2

By default, the stack occupies the RAM space from $40 through $7F (the RSP
instruction resets the stack pointer to $7F). If the stack overflows, it
will wrap around, destroying the least-recently-used data on the stack.
However, there's no rule that says that the lower end of the stack can't be
used to store variables: The firmware just has to be written so that JSRs and
interrupts never nest deeply enough to destroy the variables that are stored
in stack space.
The processor's reset and interrupt vectors are as follows:

Addr Description
----- -------------------------------------------------------------
$4000 Reset vector. Execution starts here on reset.
$4008 SWI vector. SWI interrupt begins execution here.
$4010 NMI vector. Security interrupt begins execution here.
$4018 INT interrupt vector. Maskable interrupt begins execution
here.

Note that ST Micro has "recommended code" that they like to see placed at
the vector locations. If you get hold of the SECA ROM dump that's floating
around the 'net, you'll see code that's pretty much straight out of the ST
Micro manual at $4000..$401F.

The processor's memory map:

Addr Segment name Description


----------- --------------- --------------------------------
$0000-$001F REGISTERS Peripheral registers
$0020-$003F RAM General-purpose RAM
$0040-$007F RAM Stack
$0080-$021F RAM General-purpose RAM
$1E00-$27FF SYSROM ST Micro test ROM
$2800-$33FF SYSROM ST Micro MAP ROM
$4000-$5FFF ROMA User ROM (NagraVision main code)
$6000-$7FFF ROMB User ROM (NagraVision main code)
$E000-$E7FF EEPROMA EEPROM (NagraVision patches+sub information)
$E000-$EFFF EEPROMB EEPROM (NagraVision patches+sub information)
(note: Overlaps EEPROM A)

The cryptoprocessor in the 16CF54 basically is geared towards performing


the operation (x ^ y mod z) very quickly. Depending on whether the card is a
16CF54A or 16CF54B (ROM2 and ROM3 cards use the 16CF54A), the cryptoprocessor
can accept operands up to 768 (for 16CF54A) or 1024 (for 16CF54B) bits in
length. It seems likely, however, that the NagraVision cards only use the
lowest supported operand size: 512 bits (64 bytes). The cryptographic
functions for performing the math are actually implemented as a ROM library
which feeds the necessary data to the cryptoprocessor module. This ROM
library is located in the ST Micro MAP ROM area, and is generally not readable
by any code running outside the address range from $2800 to $33FF.
One thing to note about the EEPROM in the cards is that the EEPROM area from
E000 to E01F is actually not EEPROM, but OTPROM. Once any bit of a given
address in that range is programmed to a '1', it can not be erased back to
a '0'. Nagra takes advantage of this by having their 3M "sniffer" F0/F3/FA
commands write non-zero values to address E010 (in "normal" cards, E010..E01F
is all 00s), with the value written to E010 indicating exactly which type of
3M sniffer packet decided that 3M code was present in the card (ie., 1st digit
of firmware revision not "3", checksum of memory from F180..F3FF indicated
presence of suspected code, CAM ID not in valid range, etc.). They then
have other 3M sniffer packets that cause certain EEPROM areas to be updated
(like the bug-catcher addresses), and even inform the IRD that the card is
suspected to have been tampered with. Because the data at E010 cannot be
erased back to 0, once the card has been "tagged" in this manner, it will
always retain the mark of a tampered card.
In addition to the cryptoprocessor, the MCU has another peripheral module
whose function is solely to enhance the security of the MCU itself. This
module is called the Memory Access Control Matrix (MACM). The MACM allows the
developer of the smartcard to specify which areas of the smartcard's memory
can be accessed from which other areas. For example, the MACM for the
NagraVision card most likely looks something like this:

START END
RAM SYSROM ROMA ROMB EEPROMA EEPROMB ADDR ADDR
--- ------ ---- ---- ------- ------- ----- ----
REGISTERS ? X X X X X 0000 001F
RAM X X X X X X 0020 021F
SYSROM X 2000 3FFF
ROMA X X X X X X 4000 5FFF
ROMB X X X X X X 6000 7FFF
EEPROMA X X X X X X E000 E7FF
EEPROMB X X X X X X E000 FFFF
EXECUTE X X X X X X

In this example, code may execute from any of the memory areas, and all
memory areas may read from all other memory areas, except for SYSROM, which
is only readable by code executing within the SYSROM area. In theory, this
mechanism should be able to provide a fair level of security for a smartcard
based on the 16CF54. Fortunately for us, the Nagra guys decided they wanted
to take advantage of the TSA instruction to embed parameters right in the
code, so their MACM setup is pretty weak. In fact, the only thing that's
protected is the system ROM area where the crypto libraries are stored.
From a hacking standpoint, the worst-case scenario, as I see it, for the
NagraVision MACM is:

START END
RAM SYSROM ROMA ROMB EEPROMA EEPROMB ADDR ADDR
--- ------ ---- ---- ------- ------- ----- ----
REGISTERS ? X X X X X 0000 001F
RAM X X X X X X 0020 021F
SYSROM 2000 3FFF
ROMA X 4000 5FFF
ROMB X 6000 7FFF
EEPROMA X E000 E7FF
EEPROMB X E000 FFFF
EXECUTE X X X X X X

In this example, code may execute from any of the memory areas, and no
memory area may read from any other memory areas, except for RAM, which is
allowed to read from everything except SYSROM. In theory, this arrangement
doesn't restrict us any more than the best-case scenario (see above), since
we'd probably use RAM-based code to get a byte of data from the ROM or
EEPROM before sending it out the serial port anyway.
Finally, new information released to the public (and which I've verified
personally) indicates that there's a bug in the 16CF54 silicon. It seems as
though the addressing hardware for the RAM in the card doesn't fully decode
the address being requested, and as a result, reads and writes to RAM at
addresses above $021F wrap to $0020. So, for example, executing a STA $1FF,X
instruction with X=$41 will result not in a useless write to $240 (which isn't
a valid RAM address), but rather a perfectly fine write to $0040. Although
this might not seem terribly useful, this in fact allows a very handy backdoor
into the EchoStar cards: Due to the fact that the serial I/O buffer is located
where it is, it's possible to take advantage of this shortcoming and cause the
"receive message" routine to write received serial data into the stack area,
where you could then replace the return address that's normally there (to get
back to the main idle loop from the interrupt-driven message receive routine)
with an address that would cause raw code that you sent as part of your
message to be executed. Obviously, this allows lots of interesting things to
happen, such as dumping the EEPROM-based password, which would effectively
allow unlimited access to the factory backdoors.

6.2- 288-01 vs. 288-02 vs. 288-09, or ROM2 vs. ROM3 vs. ROM10
There are three known versions of the NagraVision smartcard. They can be
identified by a number printed on the back of the card (the side with the
contacts) in fine print. If you hold the card so that the contacts are at the
top, near the bottom right corner of the card, you should see a release code.
This should be a 288-xx number or an A20xx number. It seems like xx is the
release number in both cases. Cards with a release of 288-01 are referred to
as ROM2 cards, while cards with a release of 288-02 and higher, as well as all
of the A20xx cards that I'm aware of are ROM3 cards. Presumably, there was a
ROM1 as well, but was so bad that it never saw the light of day.
In September of 2000, I became aware of a new version of Nagra's ROM code:
ROM10. The first cards I was told use this code are EchoStar cards marked
"288-09". From examination of photomicrographs of the ROM10 die, it appears
that the ROM10 cards are based on the ST19 series of microcontrollers.
The 288-01 cards were the first release. Their code was quite buggy, and
had a large amount of patched code (and code that just wouldn't fit in the ROM
area) in the EEPROM (about $900 bytes). Most of the NagraVision ROM dumps
you'll see on the 'net came from these cards.
The later cards have basically the same code, but with all of the fixes
that were in the 288-01 EEPROM area integrated back into the ROM.
Although the code in the two cards does the same thing (and in many cases
is identical), because of the differences in lengths of some of the routines,
the ROMs are not identical. This is the reason for separate EMM "execute
code" commands.

6.3- Other cards based on the same code


Because NagraVision is the conditional access system of choice for many
satellite and pay-tv providers around the world, there are lots of cards
around based on the same code as the EchoStar cards. Unfortunately, not all
cards based on this code have a 288-xx number printed on them. Here, I'll try
to provide a list of release code numbers as printed on the card versus the
version of ROM code inside the card and the card's provider.

Code Rom version Provider


------ ------------- -------------------------------
288-01 ROM2 EchoStar (original release)
288-02 ROM3 EchoStar (second release)
288-04 ROM3 ExpressVu
288-05 ROM3 ExpressVu
288-06 ROM3 ExpressVu
288-07 ROM3 Sky Vista
288-08 ROM3 ExpressVu
288-09 ROM10 EchoStar
325-01 ROM3 Via Digital (Spain)
A2012 ROM3 EchoStar (third release) [288-12?]

It's not entirely clear to me why there are so many releases of cards that
are dedicated to ExpressVu. My suspicion is that each came pre-loaded with
different data in the EEPROM area.
These cards are used by ExpressVu, Sky Vista, Via Digital, and several other
services. Check your cards...you never know what you might find. Each
service should have a unique system ID (though EchoStar and Sky Vista seem to
share the system ID of 0101, probably because Sky Vista is actually operated
by EchoStar (with Loral)). Known system IDs are as follows:

ID Provider
----- -----------------------------------------------
$0101 EchoStar
$0101 Sky Vista
$0901 ExpressVu
$4101 Via Digital (Spain)
7: Glossary

7.1- Glossary
This is just a list of terms that are frequently used when talking about
EchoStar, NagraVision, DVB, and the related hacks.

110: The orbital slot located at 110 degrees west longitude. EchoStar has
one satellite (EchoStar V) in this location. EchoStar VIII, which is
scheduled for launch in early 2002, will be placed in this slot,
augmenting the programming provided by EchoStar V.
119: The orbital slot located at 119 degrees west longitude. EchoStar has
three satellites (EchoStar I, II, and IV) in this location. EchoStar
plans to replace EchoStar I, which is nearing the end of its useful
life, with the recently-launched EchoStar VI. EchoStar VII, which is
planned for launch in early 2002, will be placed in this slot, replacing
EchoStar II, which is also nearing the end of its useful life.
121: The orbital slot located at 121 degrees west longitude. EchoStar does
not currently have a satellite located in this position, but EchoStar IX.
which is scheduled for launch in mid-2002, will be located in this
position.
148: The orbital slot located at 148 degrees west longitude. EchoStar does
not currently have a satellite permanently located in this position, but
it's likely that a future satellite will go here. In the meantime,
however, EchoStar uses this orbital slot as a test slot for newly-
launched satellites. Currently, EchoStar VI is located in this slot
undergoing testing prior to being moved to the 119 slot where it will
replace the aging EchoStar I.
175: The orbital slot located at 175 degrees west longiture. EchoStar does
not currently have a satellite in this location, but it does own the
right to control 22 out of a possible 32 transponders that may operate
from this slot, should a satellite (or satellites) ever be positioned
there.
2313: A microcontroller that's somewhat popular for use in EchoStar hacks.
Its full part number is AT90S2313. It's one of the AVR family of
microcontrollers from Atmel. Primarily used only in the dual-AVR
hack, but also seen in some versions of the EchoStar logger. See also
AVR, Atmel, dual-AVR, logger.
61.5: The orbital slot located at 61.5 degrees west longitude. EchoStar has
one satellite (EchoStar III) in this location. It is likely that
EchoStar III will be replaced or augmented sometime in 2003, possibly
by EchoStar X.
6805: A microcontroller whose instruction set is nearly identical to the
instruction set in the microcontroller used in the NagraVision
smartcards. See also ST16CF54.
8515: A microcontroller that's very popular for use in NagraVision hacks. Its
full part number is AT90S8515. It's one of the AVR family of
microcontrollers manufactured by Atmel. See also AVR, Atmel, Xfile,
Jethro, logger.
Able: An EchoStar internal code name for one of their IRD platforms. IRDs
based on this platform include the model 2000.
Atmel: The company that manufactures one of the more popular microcontroller
families for NagraVision hacks, See also AVR.
ATR: Answer To Reset. A string of data sent by an ISO7816-compliant
smartcard when it comes out of reset. The data tells the host device
what communication parameters the card expects, what type of card it
is, and so on.
Attacker: A person, program, or entity that is attempting to breach some
form of security. In the context of NagraVision hacking, an
attacker is someone who wants to circumvent the card's security,
either for the purposes of watching TV for free or just for looking
at the code in the ROMs.
Autoroll: 1: A hack that can update itself to include current decryption
keys or other dynamically-changing information that the hack
requires in order to function.
2: The process of determining current decryption keys or other
dynamically-changing information that a hack requires in order
to function.
AVR: A family of microcontrollers manufactured by Atmel. They are very
popular for use in EchoStar hacks because of their high ratio of
instructions per clock cycle as compared to other microcontrollers.
AVR2: A commercial enabler-style EchoStar hack. It does not auto-roll, and
requires frequent key updates using TALK or WINTALK. See also
enabler, talk, and wintalk.
Baker: An EchoStar internal code name for one of their IRD platforms. IRDs
based on this platform include the model 3000, 4000, 5000, and the
JVC HM-DSR100 DVHS unit.
Batt card: A commercial and freeware emulator-style enabler NagraVision hack.
It was based on the batt card hacks for the DSS 'F' card. It is no
longer viable because the commercial dealer who was trying to
make money with it found that too many people had batt cards
lying around from the F card days and were simply applying his
code to their cards without paying him any money, so he stopped
supplying keys for it.
Blocker: A freeware wedge-style NagraVision semi-hack. It doesn't actually
provide unlimited TV and PPVs as with most other hacks...instead,
the blocker tries to prevent the normal NagraVision EMM messages
which would expire a subscription from getting to the card. In
theory, someone who is using a blocker should be able to cancel
their subscription to EchoStar (or ExVu or SkyVista or ...) and have
their card continue to work. In practice, however, the blocker is
impractical because the same type of EMM messages that expire
subscriptions also carry key updates, to the blocker prevents the
card from getting the information it needs to be able to properly
decrypt the ECM messages that it receives. Some more recent blockers
have attempted, with limited success, to add some intelligence to the
logic that blocks the EMM messages, but the results so far have been
less than a total success. See also wedge, EMM, ECM.
Bones: An EchoStar internal code name for one of their IRD platforms. IRDs
based on this platform include the model 1000.
CAM: Conditional Access Module. Strictly speaking, the conditional access
module is the portion of any DVB-compliant system which allows the
set-top box to decide whether or not to allow the user to view a given
program. For some DVB systems, the CAM is a two-piece unit, with one
piece resembling a PCMCIA card, and the other being a smartcard which
fits inside the PCMCIA card-type piece. For the NagraVision system, the
CAM is the smartcard.
Charlie: Charlie Ergen, CEO of EchoStar Communications, among other
companies. He's the guy who's getting rich off EchoStar.
Charlie Chat: Charlie Ergen's periodic elbow-rubbing with the public. Every
now and again, he does an hour-long broadcast wherein he tells
the EchoStar subscriber base (those of them who tune in,
anyway) how much he appreciates their business, how great
everything is at EchoStar, and so on. Basically, just PR.
Cheyenne: The city in Wyoming where EchoStar's uplink center is located. See
also Wyoming, uplink center
Clipper: An EchoStar internal code name for one of their IRD platforms. IRDs
based on this platform include the model 2700 and 3700.
Colorado: The state where EchoStar is headquartered.
CRC: Cyclic Redudancy Check. A checksum method specified by the ISO-7816
T=1 protocol. The means by which a CRC is computed is fairly complex
and we won't go into it here because the NagraVision smart cards use the
LRC checksum method. See also ISO-7816, LRC.
Cutter: An EchoStar internal code name for one of their IRD platforms. IRDs
based on this platform include the model 4700.
DES: Data Encryption Standard. The encryption scheme used to obscure the
data in NagraVision's ECM messages as well as the return of the data
extracted from the ECMs to the IRD. See also ECM.
DirecTV: A company owned by General Motors and (at one time, anyway), coveted
by Rupert Murdock. DirecTV is a digital satellite television
provider that is in direct competition with EchoStar in the United
States. Until late 2000, DirecTV IRDs all used CAMs provided by
News Datacom (NDC), and incorporating NDC's VideoGuard security
system to secure their programming. In late 2000, however, DirecTV
IRDs began to appear with NagraVision CAMs. Presumably, this shift
to NagraVision was the result of NDC's botched job on DirecTVs
second-generation satellite cards, known as the 'H' card. DirecTV's
satellite system is generally known as "DSS". See also DSS, H card,
News Datacom, VideoGuard.
DishNetwork: The programming branch of EchoStar. EchoStar provides the
receivers, DishNetwork provides the programming, much like
RCA, Hughes, Sony, and others provide DSS receivers, but
DirecTV provides the DSS programming. In theory, DishNetwork
programming is available only to American subscribers, but in
practice, it's also available to viewers in Canada, Mexico, and
pretty much most other countries north of the equator and on
our side of the planet.
DishPlayer: One of the latest IRDs from EchoStar. The DishPlayer provides
not only satellite TV programming, but also web access and digital
time-shifting of programming: The DishPlayer has an integrated
hard drive which can be used to capture the MPEG data stream
coming from the satellite so that a user can, in effect, "pause" a
broadcast in progress while they make a sandwich, walk the dog,
strain the 'tatos, or whatever.
DSS: Digital Satellite System. The digital satellite programming service
provided by DirecTV. See also DirecTV, H card.
Dual-AVR: A freeware emulator-style enable NagraVision hack which used two
2313s: One to communicate with the IRD, and the other to perform the
cumbersome decryption functions. See also emulator, enabler, Atmel,
2313.
DVB: Digital Video Broadcasting. A standard established by the European
Broadcasting Union which specifies various means for digital transmission
of video signals, control over access to said signals, and so forth. If
you have some time on your hands and their website is up, you might want
to try going to http://www.dvb.org and seeing if you can download any
of their standards...they're great for battling those bouts with
insomnia.
E3M: EchoStar 3M. A commercial hack for the NagraVision system that involves
reprogramming a real NagraVision smartcard so that it will always return
valid channel decrypt keys to the IRD in response to an ECM.
Unfortunately, because of the architecture of the NagraVision smartcard's
microcontroller, this hack is unstable because protecting it from
attacks would prevent it from being able to autoroll. See also autoroll.
E*: A common abbreviation for EchoStar.
EchoSphere: One of many companies owned by Charlie Ergen. See also Charlie.
EchoStar: Yet another company owned by Charlie Ergen. EchoStar is responsible
for the design and manufacture of most of the IRDs that you see used
with the DishNetwork satellite programming service as well as IRDs
used for DVB satellite systems in other countries, including such
services as ExpressVu, VIA Digital, and Sky Vista. EchoStar also
makes FTA DVB receivers. See also Charlie, ExpressVu, VIA Digital,
Sky Vista, DishNetwork, FTA, and DVB.
ECM: 1: Entitlement Control Message. A message which contains the information
necessary to allow the IRD to decode an encoded datastream for some
period of time. The IRD sends the ECM to the card, the card extracts
the necessary information, then returns the data to the IRD if it thinks
the user should be allowed to watch the program that the IRD is trying
to decode. This term was coined by the DVB standards committee. For
NagraVision systems, command $03 is an ECM message. See also IRD.
2: Electronic Counter Measure. An attack sent by EchoStar and/or Nagra,
the intent of which is to disable a hack or otherwise render it
inoperable.
Unfortunately, the two very diverse definitions for ECM here often cause
a great deal of confusion. For this reason, it's generally preferable
to refer to an Electronic Counter Measure as an attack.
EMM: Entitlement Management Message. A message which contains the information
required to transfer subscription information and EEPROM updates to the
CAM. For NagraVision systems, command $00 contains most EMMs.
Emulator: 1: A hack which performs all (or a significant subset) of the
functions of a real CAM.
2: A hack which simulates the function of the MCU inside a smartcard
and uses an image of a genuine CAM to do most of its work, but which
also has sufficient smarts to substitute spoofed subscription
information to the ROM code that it is executing so that it will
think that the user is authorized to view every channel avaiable
to the CAM.
Enabler: A freeware wedge-style or stand-alone hack. For NagraVision, the
enabler can either be a stand-alone device (XFile is an example of
this) or a device which also requires a real CAM to operate (the
Jethro enabler is an example of this). An enabler's real job is to
decode ECMs and return the decrypted control words when the IRD next
sends a $13 command. See also Jethro, XFile, batt card, wedge,
emulator.
ExpressVu: A digital satellite service provided to Canadian residents.
ExpressVu uses IRDs, antennae, and CAMs provided by Nagra.
FTA: Free-to-air. A satellite television or audio broadcast which is not
a subscription service.
GAP: General Access Plastic (or Generic Access Plastic). A commercial
emulator-style enabler hack for NagraVision. GAP is basically XFile in a
smartcard. The MCU used in the GAP is a PIC 16C622A. See also XFile.
H card: The second generation of access cards used with the DirecTV digital
satellite system. H cards were produced by News Datacom (NDC), and
were based on the Siemens SLE44 series of smartcard controllers. The
H cards' firmware was very poorly written, not well thought out, had
many bugs that were exploited by DSS hackers, and was based on an
architecture that made counterattacks against hacked cards very
difficult. As a result of these deficiencies, DirecTV was widely
hacked. The follow-up to the H card was the HU card, which was based
on the Siemens SLE66 series of smartcard controllers, and which was
basically just a somewhat enhanced version of the H card,
incorporating many of the security fixes applied to H cards via
EEPROM update in the field. See also NDC, Siemens, SLE44, SLE66.
HTS: Houston Tracker Systems. Yet another of Charlie Ergen's companies. See
also Charlie.
Internal mod: A NagraVision hack which has been made completely internal to
the IRD in an effort to improve the aesthetics of the hack (most
NagraVision hacks involve a PC board hanging out of the IRD's
CAM slot). XFile is the most commonly internalized NagraVision
hack. See also XFile.
IRD: Integrated Receiver-Decoder. The set-top box which takes the
downconverted signal from the LNB and converts it to video and audio
for your enjoyment.
ISO: International Standards Organization. The standards organization that
established the ISO-7816 protocol used by most of the smartcards on the
planet today, including the CAMs used by NagraVision. See also ISO-7816.
ISO-7816: The international standard for interfacing with smartcards. The
ISO-7816 includes standards relating to the physical properties of
smartcards (including susceptibility to radiation, bendability,
contact locations, etc.), the electrical specifications, and
communications protocols. The ISO-7816 standard is in several
parts, but the most relevant to anything you're likely to want to
do is ISO-7816-3. It's not a terribly well-written standard, but
understanding it is pretty important for doing any serious hacking
with smartcards in general, so you should probably look for it...
there are typically several web sites with links to it or local
copies of it.
Jethro: A freeware enabler-style NagraVision hack. In particular, the Jethro
enabler is a wedge-style hack, because it relies on a real CAM to
handle most commands coming from the IRD, and the enabler itself only
deals with specific commands (like $03, $13, $21-08, $21-0B, etc.).
See also wedge, enabler.
Karl Osen: One of the guys at Kudelski who wrote the code in the NagraVision
cards. See also Marco Sasselli.
Key: A set of bytes used to encrypt or decrypt a message. The key and a
block of data to be encrypted or decrypted are fed into an encryption
or decryption routine, and the result is encrypted or decrypted data.
Key change: The process of altering the key used to encrypt or decrypt a
message. For our purposes, a key change will typically refer to
the changing of one of the keys that can be used to decrypt ECMs.
The EchoStar/Nagra system allows selection of one of two keys
(called KEY0 and KEY1) as the decryption key for a given ECM. If
the current key being used to encrypt ECMs is KEY0, EchoStar/Nagra
can change KEY1 without affecting the video decryption process,
and when they're pretty sure most valid subscribers' cards have
accepted the new KEY1, they switch the ECMs to use KEY1 for
decryption. It is the frequency of key changes that make all
current publicially-available NagraVision hacks cumbersome to use.
See also DES.
Kudelski: See S.A. Kudelski.
Littleton: The city in Colorado where EchoStar is headquartered.
LNB: Low-Noise Block. Technically, a specific circuit within the horn that's
mounted on the end of a digital satellite antenna, but more commonly used
to refer to the whole signal horn. A dual-LNB antenna has two connectors
on the horn, each of which can supply a distinct signal to an IRD or
multi-dish switch.
Logger: 1: A wedge-style device whose function is to eavesdrop on the data
being transferred between and IRD and smartcard. See also wedge.
2: A piece of software running on a host computer which takes the
data provided by (1) and saves it to a file for later examination.
The software may or may not filter the data so that only unusual or
otherwise interesting information is saved.
LRC: Longitudinal Redundancy Check. A checksum method specified by the
ISO-7816 T=1 smartcard communication protocol. The LRC of a given
message is computed by XORing all of the other bytes of the message
together. XORing all of the bytes of a message with an LRC appeneded to
it would produce a result of 0. Another possible checksum method that
can be used with the T=1 protocol is the CRC protocol. See also CRC,
ISO-7816.
Marco Sasselli: One of the guys at Kudelski who wrote the code in the
NagraVision cards. See also Karl Osen.
MECM: A further layer of encryption present in the NagraVision cards, whereby
once a $03 command is decrypted, the key data within is further decoded
by XORing it with data that had been transferred to the CAM in a
previous $02 command. EchoStar began using the MECM extension in
November of 2000.
Multi-dish switch: A device which allows one or more IRDs to be connected to
more than one antenna. This is critical for EchoStar,
because EchoStar splits their programming between
satellites in more than one orbital slot such that their
core programming can be received from satellites in one
slot, local-into-local programming can be received from
satellites in another, and specialty programming can be
received from satellites in a third or fourth slot. At
present, EchoStar offers multi-dish switches that can
multiples 2 dishes to 1 IRD (the SW21), 2 dishes to 2 IRDs
(the SW42), and 3 dishes to 4 IRDs (the SW64) See also
slot, 110, 119, 148, and 61.5.
Nagra: Short for "NagraVision". Many people (myself included) refer to the
makers of the EchoStar smartcard as Nagra or NagraVision, even though
the actual name of the company that produced the EchoStar smartcard is
S.A. Kudelski. See also NagraVision.
NagraVision: The name of the conditional access system used by EchoStar (and
many other digital satellite service providers). It was
developed by S.A. Kudelski (a Swiss company), and has been
licensed to each provider that uses it. As part of the security
of the system, there are certain aspects of the encryption
schemes and messaging that are (theoretically, anyway) known only
to employees of S.A. Kudelski.
News Datacom: The company that produced the original smartcards used with
DirecTV's DSS digital satellite programming service. News
Datacom is frequently abbreviated NDC. See also DirecTV,
VideoGuard.
Nipper: A hacker who was involved in much of the early release of information
about the EchoStar/NagraVision conditional access system. If the
CAM EEPROM dumps that have been released on the internet are to be
believed, then the guys at S.A. Kudelski are already familiar with
Nipper (or someone else called Nipper), because there is ASCII text
inside the Rev313 and higher EEPROM images that reads "Nipper is a
buttlicker", which leads me to believe that for one reason or another,
the people at Kudelski don't like him very much. See also ScP.
OTP: An acronym for One Time Programmable. This refers to a type of memory
(usually PROM) which comes from the factory in its erased state, and in
which, any bit that is programmed to the inverse of its erased state may
never be returned to its erased state. In some cases (such as the
NagraVision smartcards), some ranges of EEPROM are treated as OTP (by
causing the address logic to select whether Vpp may be applied to a
cell when an erase operation is attempted. This is to allow some areas
of the card to be written one (usually by the issuer, or as a test during
manufacturing), but never again. The 'erased' state of a bit varies,
depending on the particular implementation of PROM or EEPROM, but in the
NagraVision smartcards, their EEPROM implementation causes the erased
state of a bit to be '0'. This means that any '0' bit in the OTP area
can be programmed to a '1', but '1' bits in the OTP area may never be
erased to a '0'. Note: In this case, 'never' is an exaggeration: In
theory the bits could be erased, but extreme measures would be required.
Permuted key: A DES encryption/decryption key which has already passed through
the initial permutation algorithm. See also DES, raw key.
Pirate Girl: The name by which many hackers refer to the woman who did most
of the announcements on the EchoStar Pirate channel. This was a
channel which EchoStar began to broadcast shortly after a lot of
freeware hacks became available which allowed hackers to view
channels on the EchoStar system that were not available to normal
EchoStar subscribers. The main intent of the Pirate channel
was to convince the hackers that they were awful, awful people
who should repent and pay for their subscriptions.
PPV: Pay-Per-View. An event (or group of events) which is presented to the
viewer at a fixed cost for a single viewing (or single day of viewing).
The conditional access system that the NagraVision system uses transfers
PPV information to and from the CAM using commands $01, $41, $42, and
data types $0B, $0C, and $11.
Raw key: A DES encryption/decryption key which has not yet been passed through
the initial permutation algorithm. See also DES, permuted key.
ROM2: The name of the ROM image inside 288-01 NagraVision cards.
ROM3: The name of the ROM image inside 288-02 and later NagraVision cards.
ROM10: The name of the ROM image inside 288-09 NagraVision cards.
S.A. Kudelski: The name of the Swiss company which produced the NagraVision
conditional access system, which is the conditional access
system used by EchoStar and many other satellite systems
worldwide.
Scenix: The manufacturer of a microcontroller which was purported to have been
used in an auto-roll hack for NagraVision. The Scenix microcontroller
is basically a very high-speed knock-off of the Microchip PIC 16C54 or
16C57, with a few additional instructions and a larger stack. The
big advantage of Scenix microcontrollers is that they're available
rated to run at speeds up to 100 MHz.
ScP: Swiss Cheese Productions. The name of a group (or perhaps a single
individual) which was responsible for much of the technical information
initially released pertaining to the EchoStar/NagraVision conditional
access system and CAMs. See also Nipper.
SGS Thomson: The name of the company that produced the smartcard MCU used in
the EchoStar/NagraVision smartcards. See also ST Micro.
Siemens: The name of the company that produced the smartcard MCU used in the
second- and third-generation DirecTV/NDC smartcards.
Sky Vista: The name of a digital satellite service available to subscribers
in the United States, Puerto Rico, and other territories in the
Carribean. Sky Vista doesn't offer a very large selection of
programming, but they do offer a lot of specialty Ethnic channels.
They're really only mentioned here because, being operated by
EchoStar (with Loral), they use the same CAMs and IRDs as
EchoStar.
SLE44: A family of smartcard microcontrollers manufactured by Siemens. The
SLE44 is, at heart, a RISC processor with a unique instruction set
(probably known to few people outside Siemens), but which is made thru
the use of microcode to emulate an 8051 microcontroller. This is the
family of smartcard microcontrollers that was used in second generation
DSS smartcards. See also News Datacom, Siemens.
SLE66: A family of smartcard microcontrollers manufactured by Siemens. The
SLE66 is, at heart, a RISC processor with a unique instruction set
(probably known to few people outside Siemens), but which is made thru
the use of microcode to emulate an 8051 microcontroller. This is the
family of smartcard microcontrollers that was used in third generation
DSS smartcards. See also News Datacom, Siemens.
Slot: A geosynchronous orbital position where satellites may be stationed for
an indefinite period of time to provide a fixed location from which to
brodcast signals to the Earth. In our case, these signals would be
digital television and/or audio programming.
ST16: A family of smartcard microcontrollers manufactured by ST Micro. The
ST16 family of smartcard MCUs have a processor core that is basically
a slightly-modified 6805 and some additional peripherals to enhance
the card's security, provide high-speed math capability, and so on. See
also ST16CF54, ST19, ST Micro.
ST16CF54: The smartcard microcontroller used in ROM2 and ROM3 NagraVision
smartcards. See also ST Micro, ST16, ST19, ST7.
ST19: A family of smartcard microcontrollers manufactured by ST Micro. The
ST19 family of smartcard MCUs have a processor core that is based on the
ST Micro ST7 MCU and some additional peripherals to enhance the card's
security, provide high-speed math capability, and so on. It's likely
that this is the microcontroller family used in ROM10 NagraVision
smartcards. Note that like the ST16 series, the ST7/ST19 MCU core is
basically an enhanced 6805 (though the ST7/ST19 is much more heavily
augmented than the ST16). See also ST16, ST7, ST Micro.
ST7: A family of microcontrollers produced by ST Micro. Their MCU core is a
vastly improved 6805 with additional addressing modes and additional
registers. It is the MCU core on which the ST19 family of smartcard
MCUs is based.
ST Micro: The name of the company that produced the smartcard MCU used in the
NagraVision smartcards. ST Micro is really just a new name for SGS
Thomson.
SW21: A 2-dish-to-one-IRD antenna switchbox sold by EchoStar (21=2 inputs (one
for each dish, since only one receiver), one output).
SW42: A 2-dish-to-two-IRD antenna switchbox sold by EchoStar (42=4 inputs (two
for each dish, since more than one receiver), two outputs).
SW64: A 3-dish-to-four-IRD antenna switchbox sold by EchoStar (64=6 inputs
(two for each dish since more than one receiver), four outputs).
SWAJ: A 2-dish-to-one-IRD antenna switch sold by EchoStar. The SWAJ is really
just a relay which physically connects one antenna or the other using
a signal supplied by the IRD's accessory jack. (AJ=accessory jack).
Swiss Cheese Productions: See ScP.
Talk: The name of a PC-based host program which is used to upload key updates
and patches to the commercial GAP, AVR2, and E3M hacks. There is a
windows version of this program called WinTalk.
Uplink center: The central location from which all of a program provider's
programming and control information is managed. In addition,
the uplink center is usually also the location from which the
various datastreams are uplinked to the programming provider's
satellites, as well as the location from which the programming
provider receives the various signal feeds from their original
sources (ie., when EchoStar broadcasts HBO, the HBO feed isn't
sent directly to EchoStar's satellite by HBO. Instead, HBO
uplinks their signal to a satellite where they have leased
transponder space (in this case, HBO's digital uplink goes to
Galaxy 1R at 133 degrees west). HBO's signal is then received
from Galaxy 1R by the dishes at the EchoStar uplink center.
HBO's signal is then descrambled (most actual channel providers
scramble their feeds in one way or another), converted into
the DVB stream required by EchoStar's IRDs, rescrambled using
a key generated either by EchoStar or Nagra, then uplinked to
one of EchoStar's satellites (in this case, it's either
EchoStar I, II, or IV at 119 degrees west). That signal is
then beamed back down to earth where it's picked up by your
small dish and converted into moving pictures on your
television screen, as if by magic.
Valid hash: An 8-byte signature that is used to verify the authenticity of
an EMM or ECM. For further information about the valid hash,
see section 7, "Encryption"
VIA Digital: The name of a digital satellite service available to subcribers
in Spain (and probably most of the rest of Europe and northern
Africa). They're mentioned here because they use IRDs and
antennae provided by EchoStar and CAMs provided by Nagra.
VideoGuard: News Datacom's name for their digital video encryption and
security system. The most unique feature of the VideoGuard system
is its use of a zero-knowledge truth (ZKT) algorithm to allow the
IRD to decide whether or not the CAM is actually a genuine
NDC-produced device. Although Kudelski would like to incorporate
such an algorithm in the NagraVision system, they are unable to
do so because patents governing the use of ZKT algorithms are
held by News Datacom and its employees. See also ZKT.
Wedge: A style of hack or other device which involves a PC board that plugs
into the smartcard slot on the IRD and into which a CAM is plugged.
Wedge-style hacks offer an advantage not generally available to most
other hacks: Because they have a genuine CAM plugged into them, they
have the ability to use the CAM to perform complex tasks that would
be otherwise difficult to deal with in their own microcontroller.
Wintalk: The windows-based version of Talk. See also Talk.
Wyoming: The state where EchoStar's uplink center is located. See also
Cheyenne, uplink center
Xfile: A freeware emulator-styler enabler hack for NagraVision. Xfile runs in
an Atmel 90S8515 microcontroller, and attempts to mimic most known
commands of the genuine NagraVision CAM. Newer versions of Xfile
include such features as a keypad for entry of updated keys as they
become available, enhanced reset circuitry that allows them to work
with a wider range of EchoStar receivers, and so on.
ZKT: An means by which two entities (in our case, an IRD and a CAM) can
independently verify the authenticity of the other without divulging
data which would allow an attacker to pose as either entity and reliably
forge an authentication for the other entity. Patents governing ZKT
algorithms are held by employees of News Datacom, and as a result, ZKT
technology is incorporated into News Datacom's VideoGuard system, but
cannot be incorporated into Kudelski's NagraVision system. See also
NagraVision, News Datacom, S.A. Kudelski, VideoGuard.
8: Encryption

8.1- ECM encryption

8.1.1- The encryption algorithm


There has been much discussion about the Nagra ECM encryption algorithm
in the past. For a while, it seemed like someone was asking what form of DES
E* is using on a weekly basis. There've been many responses to these posts
that state flatly that Nagra doesn't use DES (and, in fact, some of those
posts came from me).
After a great deal of analysis, I've determined conclusively that the
encryption algorithm used in Nagra's ECM messages is, in fact, DES. The Nagra
implementation of DES simply happens in reverse byte order from standard DES:
Taking an E* key and an 8-byte data block, reversing the byte order of each,
then feeding it through a "standard" DES encoder/decoder, then reversing the
byte order of the result will get you the same data as if you fed the key and
data block into the EDES encode/decode routine. For the remainder of this
section, however, DES refers to the more "traditional" DES implementations,
while EDES will refer to DES as implemented by Nagra in the EchoStar smart
cards. If you really want to learn more about DES, there was once a pretty
good page on it at

http://www.thoic.com/keyblitz/html/tkp__the_des_document.html

Unfortunately, that page has now moved, and I don't know where it is. If
you know where it is, please let me know.
Also note that the term "encryption" here will mean either encryption or
decryption, since DES and EDES are essentially symmetric algorithms.

It's pretty easy to understand how one might draw the conclusion that the
ECM encryption algorithm isn't DES. The routine as it was implemented in
publically available source code (and, one must conclude, the CAM) has been
optimized for size and for speed (in the AVR, anyway...in the CAM, speed seems
to bave been the major motivating factor), and as such, there are a couple of
things that obscured the origin of the algorithm.

-With DES, the data to be encrypted is broken into a left half and a right
half, with the right half being bits 0 through 31, and the left half being
bits 32 through 63. These bits are then passed through an initial
permutation which effectively interleaves the bytes. With EDES, the data
to be encrypted is operated upon in an interleaved fashion, simplifying
the initial permutation and making it faster.
-With DES, the key is split into left and right halves, each of which is
rotated either 1 or 2 bits to the left, depending on the round number, the
halves are put back together, and the resultant 56-bit key is passed
through a permutation which jumbles the bits. With EDES, the permutation
and rotation are combined into a single routine, making it faster.
-With DES, there are 8 64-byte s-boxes which are used to perform a
substitution on the data being encrypted. This arrangement is not terribly
efficient, however, since the values are only 4 bits long each. With EDES,
to save some space, the 8 64-byte s-boxes were compacted into a single
256-byte table, each entry of which contains an entry for DES s-box n in
the lower nibble, and an entry for DES s-box n+4 in the upper nibble.
-With DES, the substitution operation is performed by XORing a selected
portion of the key for a given round with an expanded version of the right-
half data for that round, and the resultant data is grouped into 8 6-bit
values, each of which is fed into a specific s-box to get the appropriate
substitution value. With EDES, the s-box (and its location within the
256-byte lookup table) for a given 6-bit portion of the data is pre-
determined by pre-loading the permuted output with values of 0, 1, 2, and 3
alternately in the upper and lower 2 bits. This effectively splits the
256-byte lookup table into 8 64-nibble lookup tables, organized as 4 4x16
s-boxes coded into the lower nibbles and 4 16x4 s-boxes coded into the
upper nibbles.
-With EDES, the s-boxes do not appear to match the DES s-boxes, because of
the pre-permutation (and, in some cases, the lack of permutation) of the
data to be encrypted. The EDES s-boxes are, however, exactly like the DES
s-boxes, as long as you read them in the correct order.
-Once all 16 rounds of encryption have been performed in DES, the data is
fed through final permutation. Again, due to the pre-interleaving of the
data bytes, this permutation in EDES is much more straightforward and
easier to implement.
-"Traditional" DES implementations perform a "key scheduling" step at the
start of the encryption process (or, more often, as part of system
initialization, since it's assumed that the encryption key won't be
changing frequently), which generates a unique key to be used for each
round of encryption. Unfortunately, this procedure is quite RAM-intensive,
requiring more RAM than can be practically applied in a microcontroller.
EDES gets around this by generating each round's key at the beginning of
the round, so that only 8 bytes of RAM are required to store the key.

The DES and EDES algorithms encrypt 8 bytes of data at a time. For this
reason, all encrypted messages in the EchoStar/Nagra system will consist of
a multiple of 8 bytes: This is because the EDES algorithm is used to compute
the valid hash data which the CAM uses to verify a message's authenticity, so
even though the EMM algorithm might not decrypt data in 8-byte blocks, the
routine that validates the data produced by that decryption does. For more
information on the valid hash, see section 7.3, "The valid hash". Note that
packets which do not include an exact multiple of 8 bytes to be encrypted
will usually be padded to the requisite number of bytes, usually with random
data, although Nagra has been known to use a value of $55 as a pad byte.

8.1.2- Correlation between DES and EDES s-boxes:


As I mentioned above, the EDES s-boxes and "traditional" DES s-boxes are not
exactly identical, but they do contain the exact same data, just in a
different order which makes the EDES implementation faster.

DES structure:

a c gg ii q s ww yy i k oo qq y aa eee ggg
b d hh jj r t xx zz j l pp rr z bb fff hhh
e g kk mm u w aaa ccc m o ss uu cc ee iii kkk
f h ll nn v x bbb ddd n p tt vv dd ff jjj lll

EDES structure:

a e i m q u y cc gg kk oo ss ww aaa eee iii


b f j n r v z dd hh ll pp tt xx bbb fff jjj
c g k o s w aa ee ii mm qq uu yy ccc ggg kkk
d h l p t x bb ff jj nn rr vv zz ddd hhh lll

In addition, the EDES entries are bit-flopped, left-to-right, probably to


counteract the effect of the E* CAM's inverse data convention (whereby data
is sent msb first rather than lsb first).

EDES s-boxes below:

S-box 1
14 4 3 15 2 13 5 3 13 14 6 9 11 2 0 5
0 15 10 5 14 4 9 10 7 8 12 3 13 1 3 6
4 1 10 12 15 6 9 10 1 8 12 7 8 11 7 0
15 12 6 11 2 9 5 0 4 2 11 14 1 7 8 13

S-box 2
15 0 9 5 6 10 12 9 8 7 2 12 3 13 5 2
3 13 12 11 15 3 6 0 4 10 1 7 8 4 11 14
1 14 7 8 11 4 0 3 14 11 13 6 4 1 10 15
13 8 0 6 2 15 9 5 7 1 10 12 14 2 5 9

S-box 3
10 13 1 11 6 8 11 5 9 4 12 2 15 3 2 14
13 1 2 4 3 6 12 11 0 13 5 14 6 8 15 2
0 6 13 1 3 15 4 10 14 9 7 12 5 0 8 7
7 10 8 15 4 9 11 5 9 0 14 3 10 7 1 12

S-box 4
7 10 1 15 0 12 11 5 14 9 8 3 9 7 4 8
13 3 4 9 6 10 1 12 11 0 2 5 0 13 14 2
13 6 2 1 6 11 12 2 3 0 5 14 10 13 15 4
8 15 7 4 15 1 10 7 5 6 12 11 3 8 9 14

S-box 5
2 4 8 15 7 10 13 6 4 1 3 12 11 7 14 0
14 11 5 6 4 1 3 10 2 12 15 0 13 2 8 5
12 2 5 9 10 13 0 3 1 11 15 5 6 8 9 14
11 8 0 15 7 14 9 4 12 7 10 9 1 13 6 3

S-box 6
12 9 0 7 9 2 14 1 10 15 3 4 6 12 5 11
10 4 6 11 7 9 0 6 4 2 13 1 9 15 3 8
1 14 13 0 2 8 7 13 15 5 4 10 8 3 11 6
15 3 1 14 12 5 11 0 2 12 14 7 5 10 8 13

S-box 7
4 1 3 10 15 12 5 0 2 11 9 6 8 7 6 9
13 6 14 9 4 1 2 14 11 13 5 0 1 10 8 3
11 4 12 15 0 3 10 5 14 13 7 8 13 14 1 2
0 11 3 5 9 4 15 2 7 8 12 15 10 7 6 12

S-box 8
13 7 10 0 6 9 5 15 8 4 3 10 11 14 12 5
1 2 12 15 10 4 0 3 13 14 6 9 7 8 9 6
2 11 9 6 15 12 0 3 4 1 14 13 1 2 7 8
15 1 5 12 3 10 14 5 8 7 11 0 4 13 2 11

8.1.3- Key permutation


As used in the currently available hacks, there are two variants of the
NagraVision channel decryption keys that are used. One is the raw key, which
is the key value used by XFILE, the ScP logger, and bona fide NagraVision
smartcards. The other is the permuted key, which is used by the Jethro
enabler and most of the available batt card hacks. The two variants actually
represent the same key value, but the permuted key slightly reduces the
amount of computing time required by those hacks that use it, because the
permuted key is derived from the raw key. That is, although XFILE, the ScP
logger, and Nagravision smartcards use the raw key, they must transform it
into the permuted key before they can decrypt a message with it. This section
describes the process by which the raw key is transformed into the permuted
key. In addition, at the end of this section, an original EchoStar channel
decryption key used in the smartcards and XFILE will be shown permuted into
the key used by the Jethro enabler.

The raw key is an 8-byte (64-bit) number. The low bit of each byte is
defined by the DES specification as a parity bit, but for EDES, it's actually
random. This is irrelevant, however, because these bits are discarded in step
2 of the key's initial permutation.

The permuted key is a 72-bit value, which contains 54 bits of the raw key,
plus 16 bits of known, preselected data.

Assuming the key is: FE DC BA 98 76 54 32 10


Key byte number: 0 1 2 3 4 5 6 7

The key in binary would be...

Key: 1111 1110 1101 1100 1011 1010 1001 1000

Bit: 6666 5555 5555 5544 4444 4444 3333 3333


3210 9876 5432 1098 7654 3210 9876 5432

Key: 0111 0110 0101 0100 0011 0010 0001 0000

Bit: 3322 2222 2222 1111 1111 11


1098 7654 3210 9876 5432 1098 7654 3210

First, the bits of each byte of the key are reversed

The reversed key in binary would be...

Key: 0111 1111 0011 1011 0101 1101 0001 1001

Bit: 5555 6666 4455 5555 4444 4444 3333 3333


6789 0123 8901 2345 0123 4567 2345 6789

Key: 0110 1110 0010 1010 0100 1100 0000 1000

Bit: 2222 2233 1111 2222 11 1111


4567 8901 6789 0123 8901 2345 0123 4567

After the parity bits (the former low bits, now the high bits) are
discarded, the key becomes...

Compressed, reversed key: FE EE E9 9D CA A6 08


Key byte number: 0 1 2 3 4 5 6

And, in binary...

Key: 1111 1110 1110 1110 1110 1001 1001 1101

Bit: 5556 6664 5555 5544 4444 4333 3333 2222


7890 1239 0123 4512 3456 7345 6789 5678
Key: 1100 1010 1010 0110 0000 1000

Bit: 2331 1122 22 1 1111 1


9017 8901 2390 1234 5123 4567

Next, the permutation process happens by initializing the permuted key to:

Permuted key: 00 00 40 01 80 02 C0 03 00
Key byte number: 0 1 2 3 4 5 6 7 8

Which, in binary looks like this...

0000 0000
0000 0000
0100 0000
0000 0001
1000 0000
0000 0010
1100 0000
0000 0011
0000 0000

Note that only certain bits of the permuted key are filled from the
compressed, reversed key. As a result, certain bits of the permuted key are
always the same, as shown below (a '-' represents a bit that gets filled from
the compressed, reversed key, a 1 or a 0 indicates a bit that's always a known
value). These bits are used to select the appropriate S-box for each 6-bit
word during enryption/decryption. In addition, this action participates in
the interleaving of the bytes.

00-- ---- Select S-box 1


---- --00 Select S-box 5
01-- ---- Select S-box 2
---- --01 Select S-box 6
10-- ---- Select S-box 3
---- --10 Select S-box 7
11-- ---- Select S-box 4
---- --11 Select S-box 8
---- ----

Since 16 of the 72 bits of the permuted key are preset, 56 bits remain that
need to be filled from the compressed, reversed key. As it happens, the
compressed, reversed key contains exactly 56 bits, so each bit from the
compressed, reversed key gets moved to one and only one bit within the
permuted key. This step is the permutation, which happens next, according to
the following map:

----- bit within permuted key byte ----


byte 7 6 5 4 3 2 1 0
---- ---- ---- ---- ---- ---- ---- ---- ----
0 -0- -0- 31 63 5 46 61 22
1 54 29 23 14 36 47 -0- -0-
2 -0- -1- 7 52 39 38 45 13
3 55 30 37 44 15 6 -0- -1-
4 -1- -0- 12 43 58 41 3 26
5 35 25 59 11 34 49 -1- -0-
6 -1- -1- 28 17 4 42 27 2
7 33 57 1 19 18 51 -1- -1-
8 20 10 50 9 60 21 53 62

Notes: Bits with a known value are shown as -1- or -0-


Bit numbers refer to bit numbers in the RAW KEY

At this point, we have the permuted key.

Example: Original EchoStar channel encryption key.

Raw key: 00 C7 CF EC 71 A8 3E 65

In binary: 0000 0000 1100 0111 1100 1111 1110 1100

Bit: 6666 5555 5555 5544 4444 4444 3333 3333


3210 9876 5432 1098 7654 3210 9876 5432

0111 0001 1010 1000 0011 1110 0110 0101

Bit: 3322 2222 2222 1111 1111 11


1098 7654 3210 9876 5432 1098 7654 3210

Step 1: Reverse bits

In binary: 0000 0000 1110 0011 1111 0011 0011 0111

Bit: 5555 6666 4455 5555 4444 4444 3333 3333


6789 0123 8901 2345 0123 4567 2345 6789

In binary: 1000 1110 0001 0101 0111 1100 1010 0110

Bit: 2222 2233 1111 2222 11 1111


4567 8901 6789 0123 8901 2345 0123 4567

Step 2: Strip parity bits

In binary: 0000 0001 1000 1111 1001 1011 0111 0001


Bit: 5556 6664 5555 5544 4444 4333 3333 2222
7890 1239 0123 4512 3456 7345 6789 5678

In binary: 1100 0101 0111 1110 0010 0110


Bit: 2331 1122 22 1 1111 1
9017 8901 2390 1234 5123 4567

Step 3: S-box prep/permutation

----- bit within permuted key byte ----


byte 7 6 5 4 3 2 1 0
---- ---- ---- ---- ---- ---- ---- ---- ----
0 -0- -0- -0- -0- -1- -1- -0- -0-
1 -1- -1- -1- -0- -0- -1- -0- -0-
2 -0- -1- -0- -0- -1- -1- -0- -1-
3 -1- -1- -1- -0- -0- -1- -0- -1-
4 -1- -0- -1- -1- -0- -1- -0- -0-
5 -1- -0- -0- -1- -1- -1- -1- -0-
6 -1- -1- -1- -0- -0- -1- -0- -1-
7 -0- -0- -0- -1- -0- -0- -1- -1-
8 -0- -1- -1- -1- -0- -1- -0- -0-

Converting these binary values to hex, we have a permuted key of:

Permuted key in hex: 0C E4 4D E5 B4 9E E5 13 74

Which is the permuted key that appears in the Jethro enabler as well as
the public batt card hacks.

In addition to permuting the channel en/decryption keys to decrypt the $03


commands, there's a permutation that happens to the keys when encryption
happens. The procedure is similar to the permutation that happens for
decryption. In fact, the only difference is the final step, when the 56 key
bits are permuted into the 72-bit permuted key. For the encryption process,
the permutation table is:

----- bit within permuted key byte ----


byte 7 6 5 4 3 2 1 0
---- ---- ---- ---- ---- ---- ---- ---- ----
0 -0- -0- 23 55 60 38 53 14
1 46 21 15 6 63 39 -0- -0-
2 -0- -1- 62 44 31 30 37 5
3 47 22 29 36 7 61 -0- -1-
4 -1- -0- 4 35 50 33 28 18
5 27 17 51 3 26 41 -1- -0-
6 -1- -1- 20 9 57 34 19 59
7 25 49 58 11 10 43 -1- -1-
8 12 2 42 1 52 13 45 54

Note that the permutation of the key is not the only difference between the
encryption and decryption processes- it's merely the only difference in the
key preparation processes.

8.2- EMM encryption


Unfortunately, at this time, I have very little information about the EMM
(command $00/$01/$31 and possibly $02) encryption algorithm. My impression,
though, is that it's not a symmetric algorithm like the ECM uses...instead,
it's a public-key algorithm. This type of algorithm would have two different
keys, one of which is a public key (which is in the CAM), and one of which
is a private key (which is known only to Nagra). A block of data encrypted
with the private key can only be decrypted with the public key, and
vice-versa. In this way, the system is protected such that only Nagra can
produce an encrypted EMM message that will be correctly decrypted by the CAMs,
and they can be the only ones who are able to decrypt messages encrypted with
the public key (like the $31 message).

8.3- The valid hash


In each 00, 01, 02, 03, and 31 command, the NagraVision data stream includes
an 8-byte "valid hash" value. The purpose of this value is to authenticate
the message. A correct valid hash suggests strongly that the sender of the
message had knowledge of the following information:

-The plaintext of each of the 8-byte encrypted packets


-The verification key, which is different from the encryption key
-The order in which the 8-byte packets were encrypted
-The encryption and decryption algorithms

The valid hash value is a result of combinative encryption of the plaintext


of each of the 8-byte data packets, in the following manner (in very bad
'C'-like pseudocode):

hash=verification_key; //The key used to generate the valid


//hash packet
hash=encrypt(packet[1],hash); //Initialize the hash
for (i=2 ; i<numpackets ; i++) //Include each additional packet in
// the hash
hash=encrypt(packet[i],packet[i-1]^hash);

At the end of this process, hash contains the valid hash result.
9: Hacks

9.1- Commands added to the E3M, AVR2, and GAP


The E3M, AVR2, and GAP hacks from Discount Satellite all have a few extra
commands thrown in to make things like key updates and so forth easier to do
from the outside. In order to make the addition of these commands easier to
implement, the new commands follow the format of "standard" NagraVision
commands.
The added E3M commands, in my view, represent a massive hole in the security
of the card, because the fact that a legit card reacts differently to them
than an E3M card means that an IRD can detect if a card that's been inserted
is an E3M card by simply attempting to use one of the E3M commands and seeing
if the card generates the proper "error" response. Later versions of E3M code
attempt to rectify this shortcoming by only allowing E3M commands to be used
if no command other than T=1 control commands (set IFS, etc.) have been used,
but since the most likely place for E* to put such a check is during card
initialization, this restriction provides little actual protection.

9.1.1- Command $05: Write IRD key (Version 3.0: Write config item)
This command is used to write the 8-byte IRD key to the E3M card.

Example of a $05 command:

21 40 12 ; A0 CA 00 00 ;Standard header
0D ;Command length
05 ;Command (Write IRD key)
0B ;Command data length
95 01 ;Misc. data (probably ignored)
DC E9 1B 55 89 A0 D5 22 ;New IRD key
03 ;Expected response length
29 ;Checksum

Response from an E3M, AVR2, or GAP card:

12 40 05 ; E1 ;Standard header, response code


01 ;Response data length
00 ;Response data
90 00 ;SW1/SW2
27 ;Checksum

Response from "standard" NagraVision card:

12 40 02 ; 6F 00 ;SW1/SW2: Command not supported

Note that starting with version 3.0 (or maybe earlier), E3M cards allowed
the $05 command to update items other than the IRD key using this command.
The item to be updated is selected by putting the item number to be updated
in the "command data length" field of the command. The data for the item is
always stored starting at byte 9 of the information field. Values for the
item select byte and the length of the associated data item are as follows:

Item select byte Item length Item description


---------------- ----------- -----------------------------------
0 8 IRD boxkey
1 16 Blackout info from type $6 data
2 invalid invalid
3 2 E3M version number

9.1.2- Command $06: Read IRD key (Version 3.0: Read config item)
This command is used to read the 8-byte IRD key from the hack. I'm not
real sure why this command exists, because getting the IRD key out isn't a
very useful thing to do (unless, I suppose, you just want to know your IRD's
box key out of curiosity).

Example of a $06 command:

21 40 08 ; A0 CA 00 00 ;Standard header
02 ;Command length
06 ;Command (Read IRD key)
00 ;Command data length
08 ;Expected response length
0F ;Checksum

Response from an E3M, AVR2, or GAP card:

DC E9 1B 55 89 A0 D5 22 ;IRD key

Response from a "standard" NagraVision card:

12 40 02 ; 6F 00 ;SW1/SW2: Command not supported

Note that starting with version 3.0 (or maybe earlier), E3M cards allowed
the $06 command to read items other than the IRD key using this command. The
item to be updated is selected by putting the item number to be updated in the
"command data length" field of the command. The amount of data returned
depends on the data item being requested. Values for the item select byte
and the length of the associated data item are as follows:

Item select byte Item length Item description


---------------- ----------- -----------------------------------
0 8 IRD boxkey
1 16 Blackout info from type $6 data
2 17 MECM data
3 2 E3M version number

9.1.3- Command $07: Write ZIP code and time zone


This command is used to write the ZIP code (3 of the 4 bytes, anyway) and
time zone bytes to the hack. See section 4.2.1 for details on the encoding of
the ZIP code and time zone bytes.

Example of a $07 command:

21 40 0E ; A0 CA 00 00 ;Standard header
09 ;Command length
07 ;Command (Write ZIP code/TZ)
07 ;Command data length
nn nn ;Misc. data (probably ignored)
Z2 Z3 Z4 ;Bytes 2..4 of ZIP code
TZ ;Time zone byte
03 ;Expected response length
xx ;Checksum

Response from an E3M, AVR2, or GAP card:

12 40 05 ; E1 ;Standard header, response code


01 ;Response data length
00 ;Response data
90 00 ;SW1/SW2
27 ;Checksum

Response from "standard" NagraVision card:

12 40 02 ; 6F 00 ;SW1/SW2: Command not supported

9.1.4- Command $08: Update EEPROM


This command is used to update the EEPROM in the E3M, AVR2, and GAP cards.
The data for this command is DES encrypted: Depending on the version of the
E3M code, the DES encrypt routine may be used to decrypt the data, or the
DES decrypt routine may be used, and the decrypted data bit-flopped. Also,
the key used to encrypt/decrypt the data varies with the version of the E3M
code. Data on the keys and encryption method used are below. In addition, to
the data encryption, asignature for the message is included, and the signtaure
is calculated using the same routine as the 00, 01, 02, 03, and 31 commands.
The key used for generating the valid hash seems to be the same for all E3M
versions, and is A0 CA 00 00 02 C0 00 06. Much like the 05, 06, and 07
commands, this command represents a massive hole in the security of the hacks,
since "standard" NagraVision cards will react differently to this command than
the hacks, giving E* a way to detect if the device plugged into the smartcard
slot is a legitimate smartcard or not. Later versions of E3M code attempt to
rectify this situation by only allowing E3M commands

Example of a $08 command:

21 40 23 ; A0 CA 00 00 ;Standard header
1D ;Command length
08 ;Command (Write EEPROM)
1B ;Command data length
nn nn ;Misc. data, ignored
11 22 33 44 55 66 77 88 ;Valid hash
11 22 33 44 55 66 77 88 ;Encrypted block
11 22 33 44 55 66 77 88 ;Encrypted block
03 ;Expected response length
xx ;Checksum

Response from an E3M, AVR2, or GAP card:

12 40 05 ; E1 ;Standard header, response code


01 ;Response data length
00 ;Response data
90 00 ;SW1/SW2
27 ;Checksum

Response from "standard" NagraVision card:

12 40 02 ; 6F 00 ;SW1/SW2: Command not supported

Encryption keys and methods:


E3M version Encryption method Decryption method Key
----------- ----------------- ----------------- -----------------------
1.x, 2.x DECRYPT ENCRYPT D6 00 2C 7A 3C 80 2C 54
3.x Bit-flop+ENCRYPT DECRYPT+bit-flop 38 8E 64 3E F2 18 70 2C

Note that the keys above are what I believe to be the correct keys. The
actual data used in the E3M code is assumed to be "pre-prepared", and I have
not yet verified that I correctly calculated the "raw" keys from which can be
derived the "prepared" data that is used by the code.

9.1.5- Command $09: Update keys


This command was intended to be used to update only the ECM keys in the card
without requiring a full-blown $08 command. It only includes two encrypted
keys as its data. The key used to encrypt the encryption keys is the same for
all E3M cards that support this command. At this point, I believe that the
key is 0C BA A8 44 32 D2 58 30, but I haven't verified it yet. The key is
based on the fact that the actual data used to decrypt the key information is
the first 7 bytes of the echostar S-box data table, XORed with $96. The above
key is the result of reversing the "preparation" process to arrive at an
8-byte "raw" key.

Example of a $09 command:

21 40 1B ; A0 CA 00 00 ;Standard header
15 ;Command length
09 ;Command (update keys)
13 ;Command data length
nn nn ;Misc. data, ignored
11 22 33 44 55 66 77 88 ;Encrypted KEY0 data
99 AA BB CC DD EE FF 00 ;Encrypted KEY1 data
03 ;Expected response length
xx ;Checksum

Note that only early E3M cards support this command, and it was never really
used in the real world.
10: Firmware versions of the various E* cards

10.1- ROM2 firmware versions

10.2- ROM3 firmware versions


As of this writing, there are 11 known firmware revisions which can exist
in a ROM3-based card. Not all of the firmware revisions actually represent
code changes- some of them indicate that the card has failed a test that is
required in order for it to reach the next firmware revision that actually
does represent a code change. The known firmware revisions and the card
status that each represents are listed below.

Rev307 Virgin card


Rev309 Adds bug-catcher $29 (Bug fix/enhancement to command $30)
Rev313 Modifies bug-catcher $22 (Enhancement to "find free space")
Rev365 Adds to bug-catcher $0F (Security enhancement)
Rev366 No data change, but card has passed checksum of
EEPROM from $E030..$E037 and $E03E..$E3FF (correct
checksum is $6F9A)
Rev367 No data change, but card has passed checksum of
EEPROM data areas as follows:
$E400..$E407 and $E429..$E430: $0076
$E463..$E469 and $E487..$E4EC: $2E2B
$E51F..$E534 and $E543..$E59A: $2C63
Rev368 Never-accessed code written at $E150..$E157
Rev369 MAP functionality checked, never-accessed code
written at $E158..$E159
Rev370 No data change, but card has passed checksum of
EEPROM from $E030..$E037 and $E03E..$E14F (correct
checksum is $6FA2)
Rev371 No data change, but card has passed checksum of
EEPROM data areas as follows:
$E400..$E407 and $E429..$E430: $0076
$E463..$E469 and $E543..$E59A: $2C62
$E487..$E4E5 and $E518..$E534: $2E3C -or-
$E487..$E4EC and $E51F..$E534: $2E3C
Rev372 Adds to bug-catcher $29 (Trigger EEPROM cleanup on first command
other than $12, $14, or $C1)
Adds bug-catcher $0D (Bypass EEPROM cleanup on reset)
Adds bug-catcher $A0 (Disable cleartext ECMs)

10.3- ROM10 firmware versions


11- Writing code for NagraVision cards
In this section, I hope to provide information which will be helpful to
individuals wanting to write 3M code (or other hacks) for NagraVision cards.
There are three sections, one for each known ROM version of NagraVision cards,
since each is different enough from the others that although the concepts
translate across ROM versions, actual addresses, bug-catcher numbers, and so
on do not.

11.1- ROM2 cards (this section under construction)


ROM2 is the first known public version I know of of the NagraVision smart
cards. The code in ROM2 cards was not well-optimized, and as a result,
support for many commands had to be added in the form of bug-catchers to the
EEPROM area.

11.1.1- Bug-catcher modules


11.1.2- Hooking in a bug-catcher
11.1.3- Useful routines and memory locations
11.1.3.1- Utility routines
11.1.3.2- Database routines
11.1.3.3- Low-level routines
11.1.3.4- Encryption/decryption routines

When adding backdoor commands to the card (or when intercepting $03 commands
or other information that's DES encrypted), a hacker may wish to use the DES
encrypt or decrypt routines that are included in the NagraVision cards. The
basic DES routines will be listed here, both in summary form and detailed
form, along with examples of how to call the more useful routines.

11.1.4- Memory usage


11.1.4.1- ZP RAM
11.1.4.2- Other RAM
11.1.4.3- Tables in ROM and EEPROM

11.2- ROM3 cards


ROM3 is the second version I know of of the NagraVision smart cards. The
code in ROM3 cards is optimized much better than that in the ROM2 cards, and
as a result the amount of code in the EEPROM area is greatly reduced. Among
the enhancements added with ROM3 cards is a new data storage system which
allows the card to recover from errors that occur while updating data items
in EEPROM.

11.2.1- Bug-catcher modules


A total of 68 bug-catcher modules are defined in the ROM3 code. Note that
the module numbers that were used are not continuous, and follow no specific
pattern. While some related functions seem to have their bug-catcher module
numbers grouped closely together, others are scattered throughout the range
of possible values. Below is a quick-reference list of the bug-catcher
modules available in ROM3 cards, followed by a more lengthy list, which
includes a brief description of what activity is associated with each module.

ROM3 bug-catcher quick reference

Addr Num Description


----- --- ---------------------------------------------------------------
$4026 $01 Reset vector
$402D $02 SWI vector
$7314 $0A Peripheral init
$7323 $0B RAM clear
$734F $0C Variable init
$736A $0D ATR send
$7385 $0E Main idle loop entry pt 2
$7389 $0F Main idle loop entry pt 1
$7833 $14 EEPROM write failure occurred
$7925 $15 Security violation during EEPROM write
$79D9 $16 EEPROM erase failure occurred
$45C3 $1E KILLDATAITEM
$4601 $1F GETDATAITEM
$46FF $20 GETMATCHINGITEM
$4744 $21 CREATEDATAITEM
$47A8 $22 FINDABLOCK: Find free space in EEPROM
$47C4 $23 WRITEDATAAREA: Write EEPROM
$4875 $24 ACTIVATEITEM
$4886 $25 RANGECOMPARE
$492D $26 ADD3BYTEBCD
$499E $27 BCDSUBTRACT
$73B7 $28 INS byte handler (got INS byte in A). Hook here to close
Kudelski's backdoors
$73D6 $29 Main command handler (got command number in A)
$75C0 $2A Main response handler
$4AC6 $32 Check low byte of current date
$5A8A $64 EMM filter command handler
$5B3B $65 Main EMM command handler
$5B5A $66 EMM command $11
$5B83 $67 EMM command $11 check rights identifier in received EMM
$5BCE $68 EMM command $11 add item price to credit used so far
$5BE3 $69 EMM command $11 bad follow-up EMM command-must be $12..$15
$5BF0 $6A EMM command $11 create string item
$5C51 $6B EMM command $20 just got data item type, about to go and modify
dates as necessary
$5C5D $6C EMM command $20 modify dates routine
$5CE2 $6D UPDATEDATE
$5D74 $6E YMDTODATE
$5D8E $6F MAKEYEARMONTH
$5EAD $70 EMMCMD15 (create PPV service)
$5F53 $71 KILLFOUNDITEM
$5FA8 $72 UPDATETOKENS
$60CD $73 EMM 31/32 (expire sub / redirection info) end
$6137 $74 FINDKEYINFO
$630E $75 EMM command $61 calculate EMAIL text write offset
$650C $76 FINDCUSTITEM
$6528 $77 FINDSUBITEM
$6558 $78 SEARCHANDMOD
$65C1 $79 EXPIREFOUNDITEM
$65FC $7A BILDSUBTIER main data move
$661C $7B BILDSUBTIER date check
$665F $7C VERFPPVLINKS
$7A53 $8C Response output redirection setup
$56FD $96 ECM main interpreter (command byte is in A)
$57B4 $97 ECM command $20 (straight sub) handler
$57E8 $98 ECM command $22 (program type blackout/$23 (regional blackout)
handler. A=command length
$583E $99 ECM command $21-Search by valid PPV service
$58B5 $9A ECM command $21-Search by "last paid PPV
$58FA $9B ECM command $21-Search by "PPV by theme"
$5928 $9C Service active for received system ID check
$5995 $9D ECM command $21-PPV by theme or PPV by number valid match
$66A9 $A0 ECM decode phase 1 (pre-decrypt)
$6703 $A1 ECM decode phase 2 (post-decrypt)
$6731 $A2 ECM decode phase 3 (post-interpret, only if just a single
control word was requested)
$67EC $A3 EMM decode phase 1
$442B $AA ATR built, not yet sent
$4489 $B4 Callback build find data
$4536 $B5 Callback build encode data
$4572 $B6 Callback build PPV lookup
$459D $BE Message processing setup

ROM3 Bug-catcher details

Addr Num Description


----- --- ---------------------------------------------------------------
$4026 $01 Reset vector: This bug-catcher is triggered just after the CAM
resets, but before the normal ROM initialization happens.
$402D $02 SWI vector: This bug-catacher is triggered whenever an SWI
instruction is executed.
$7314 $0A Peripheral init: This bug-catcher is triggered following the
initialization of the on-board peripherals as part of the
normal reset code. See notes for bug-catcher $0D.
$7323 $0B RAM clear: This bug-catcher is triggered following the clearing
of RAM as part of the normal reset code. See notes for
bug-catcher $0D.
$734F $0C Variable init: This bug-catcher is triggered following the
initialization of CAM status flags and setup of serial I/O
parameters for sending the ATR. See notes for bug-catcher
$0D.
$736A $0D ATR send: This bug-catcher is triggered following the
transmission of the ATR, setup of serial I/O parameters for
the working data rate, and the verification of the EEPROM
backdoor password. Note that if bug-catchers are added which
cause too much time to be taken before the card will respond
to commands from the receiver, the receiver may reset the
card endlessly. This is due to an anti-hack feature that
was added to EchoStar IRDs to combat some public-domain hacks
that were identifiable by the amount of processing time they
required between sending the ATR and being ready to respond to
commands from the IRD.
$7385 $0E Main idle loop entry pt 2: This bug-catcher is triggered
following the routine in ROM3 cards that cleans up EEPROM
(backing out of incomplete modifications that were interrupted
by a power failure or other catastrophe, as well as reclaiming
space taken by type $11 data items that are not linked to a
specific type $08, $09, $0A, or $0B data item.
$7389 $0F Main idle loop entry pt 1: This bug-catcher is triggered
on entry to the main idle loop.
$7833 $14 EEPROM write failure occurred: This bug-catcher is triggered
when an attempt to write to EEPROM fails.
$7925 $15 Security violation during EEPROM write: This bug-catcher is
triggered when a security violation is detected during an
attempt to write to EEPROM or erase EEPROM.
$79D9 $16 EEPROM erase failure occurred: This bug-catcher is triggered
when an attempt to erase EEPROM fails.
$45C3 $1E KILLDATAITEM: This bug-catcher is triggered when the routine
that kills the data item being pointed to by RC1ADDRH:L is
called, prior to the actual deletion of the data item.
$4601 $1F GETDATAITEM: This bug-catcher is triggered when the routine to
search for a data item based only on data type is called,
prior to searching for the data.
$46FF $20 GETMATCHINGITEM: This bug-catcher is triggered when the routine
to search for a data item of a specific data type whose
first few bytes of data matches a pattern is called, prior to
searching for the data.
$4744 $21 CREATEDATAITEM: This bug-catcher is triggered when the routine
to create a data item is called, prior to creation of the
item.
$47A8 $22 FINDABLOCK: This bug-catcher is triggered when the routine to
find a free block of EEPROM memory is found, prior to the
start of the search.
$47C4 $23 WRITEDATAAREA: This bug-catcher is triggered when the routine
to modify an existing data item is called, prior to the
writing of the new data.
$4875 $24 ACTIVATEITEM: This bug-catcher is triggered when the routine to
mark a data item as "active and in use" is called, prior to
setting the bit in the header byte that indicates that the
data item is active.
$4886 $25 RANGECOMPARE: This bug-catcher is triggered when the routine to
perform a range comparison of a variable-length parameter is
called, prior to performing the comparison.
$492D $26 ADD3BYTEBCD: This bug-catcher is triggered when the routine to
add two 3-byte pseudo-BCD values (such as PPV purchase prices)
is called, prior to the addition.
$499E $27 BCDSUBTRACT: This bug-catcher is triggered when the routine to
subtract one 3-byte pseudo-BCD value from another is called,
prior to the subtraction.
$73B7 $28 INS byte handler: This bug-catcher is triggered when a command
has been received and the INS byte is about to be processed.
When the bug-catcher is called, the received INS byte is in A.
This bug-catcher would be the one to hook to close the
standard Kudelski backdoors (A0 20, A0 B0, etc.)
$73D6 $29 Main command handler: This bug-catcher is triggered when a
command has been receieved and the command byte is about to be
processed. When the bug-catcher is called, the received
command byte is in A. This bug-catcher would be the one to
hook to add new "standard format" commands.
$75C0 $2A Main response handler: This bug-catcher is called when the
RESPOND routine is called to finish building the response to
a command. Note that not all commands exit through RESPOND;
some (such as command $21) have their own handlers through
which the response is directed. When the bug-cathcer gets
called, the response byte will be in A and the length of the
response will be in X.
$4AC6 $32 Check low byte of current date: This bug-catcher is called when
the routine to verify the sanity of the current date (as
stored in EEPROM) is called, prior to checking the date.
$5A8A $64 EMM setup: This bug-catcher is triggered when an EMM (command
$00) has been decrypted and is about to be processed. The
bug-catcher is called prior to performing any verification or
processing of the decrypted EMM data. This would be the
bug-catcher to hook to avoid any processing of EMMs (for
example, to produce a card that decrypts EMMs and then returns
them to a host device for analysis), or to add EMM filter
commands. When this bug-catcher is called, the EMM filter
command for the decrypted EMM is stored at $80.
$5B3B $65 Main EMM command handler: This bug-catcher is triggered when
an EMM command is about to be processed. When the bug-catcher
is called, the EMM command number is in A. This would be the
bug-catcher to hook to avoid processing specific EMM commands
(such as $F3), to modify the way specific EMM commands are
processed (such as $21, $23, $31, or $33), or to add new
EMM commands.
$5B5A $66 EMM command $11: This bug-catcher is triggered when EMM command
$11 (setup for EMM commands $12..$15) begins to be processed.
When the bug-catcher is called, bytes 2..4 of the EMM command
(typically item cost) have been moved to $EF..$F1, byte 4 of
the EMM command (typically value to match on item status byte)
has been moved to $EA, and the current date from EEPROM has
been moved to $F2..$F3.
$5B83 $67 EMM command $11: This bug-catcher is triggered during EMM
command $11 processing. The EMM command following this
command $11 has been determined before triggering this bug-
catcher, and if EMM command $15 follows this command $11,
then no further processing has taken place. If the EMM
command that follows this command $11 is $12..$14, then the
rights date and begin date from the EMM command have been
checked.
$5BCE $68 EMM command $11 add item price to credit used so far: This
bug-catcher is triggered just before EMM command $11 adds the
purchase price of a subscription item about to be added by
EMM command $12..$15 to the amount of credit used so far in
the card. This would probably be one of the bug-catchers to
hook to make a card that allows an unlimited number of
purchases. In addition to stopping the accumulation of credit
used so far, it would also be necessary to add a means for
deleting used-up PPV events.
$5BE3 $69 EMM command $11 bad follow-up EMM command-must be $12..$15:
This bug-catcher is triggered if the command that immediately
follows a $11 command isn't $12, $13, $14, or $15. If you
were working for Kudelski, this would be the bug-catcher to
hook if you wanted to add other "add subscription item" type
EMM commands.
$5BF0 $6A EMM command $11 create string item: This bug-catcher is
triggered just before EMM command $11 tries to create a type
$11 data item with the string information contained in the
$11 command.
$5C51 $6B EMM command $20 just got data item type, about to go and modify
dates as necessary: This bug-catcher is triggered once EMM
command $20 has determined what type of data items it is to
modify, but prior to actually performing any modification.
This would be the bug-catcher to hook in order to prevent
a programming provider from expiring bogus subscription items
that cause the card to operate in a "full open" mode.
$5C5D $6C EMM command $20 modify dates routine: This bug-catcher is
triggered when EMM command $20 is actually attempting to
modify the dates associated with a particular subscription
item. This bug-catcher would be an alternate choice to hook
to prevent a programming provider from expiring bogus
subscription items that cause the card to operate in a "full
open" mode.
$5CE2 $6D UPDATEDATE: This bug-catcher is triggered immediately prior to
actually performing the date update for EMM command $20.
$5D74 $6E YMDTODATE: This bug-catcher is triggered when the routine that
converts an absolute year/month/day into a 16-bit encoded
date is called.
$5D8E $6F MAKEYEARMONTH: This bug-catcher is triggered when the routine
that converts a 16-bit encoded date into an absolute year/
month/day is called.
$5EAD $70 EMMCMD15 (create PPV service): This bug-catcher is triggered
when EMM command $15 is executed. It is triggered after the
card determines that the PPV item that the EMM command wants
to create doesn't already exist in the card, but before the
item is actually created.
$5F53 $71 KILLFOUNDITEM: This bug-catcher is triggered when EMM command
$23 attempts to delete a subscription item. This bug-catcher
probably needs to be hooked in order to prevent a programming
provider from deleting bugus subscription items that cause a
card to operate in the "full open" mode.
$5FA8 $72 UPDATETOKENS: This bug-catcher is triggered when an EMM command
that wants to update spending limit or token information (EMM
commands $24 and $25) actually attempts to update the data in
the card.
$60CD $73 EMM 31/32 (expire sub / redirection info) end: This bug-catcher
is triggered when EMM commands $31 and $32 have finished
removing all subscription and indirection information that
they were supposed to remove. Presumably, this bug-catcher
is where they would add code to delete additional data items
that, at a later date, they decide are related to subscription
or indirection information for a system.
$6137 $74 FINDKEYINFO: This bug-catcher is triggered when any operation
attempts to search for a type $07 data item for a specific
system ID.
$630E $75 EMM command $61 calculate EMAIL text write offset: This
bug-catcher is triggered when EMM command $61 believes that it
has successfully calculated the offset to email data in an
email data item. Presumably, it exists so that if the header
information for an email message needs to be expanded in the
future, the card will have a way to handle it.
$650C $76 FINDCUSTITEM: This bug-catcher is triggered whenever the
routine that searches for a specified type of customer-
specific data is called. It exists to allow new types of
customer-specific data to be added to the list of types that
are located by the command.
$6528 $77 FINDSUBITEM: This bug-catcher is triggered whenever the routine
that searches for a subscription item (a data item of type
$08, $09, $0A, or $0B) is called.
$6558 $78 SEARCHANDMOD: This bug-catcher is triggered whenever the
routine that searches for subscription data items and modifies
them is called. This routine is called by EMM commands $20
and $23.
$65C1 $79 EXPIREFOUNDITEM: This bug-catcher is triggered whenever the
routine to modify a subscription data item attempts to
expire the data item it has just found.
$65FC $7A BILDSUBTIER main data move: This bug-catcher is triggered when
the routine to build a subscription item is called by EMM
commands $12..$15. It is triggered prior to moving any of the
subscription item data from the EMM command to the RAM area
where the data item is being built.
$661C $7B BILDSUBTIER date check: This bug-catcher is triggered when EMM
commands $12..$15 are attempting to create a data item and the
begin date of the received EMM command is being checked.
$665F $7C VERFPPVLINKS: This bug-catcher is triggered when the routine
that deletes orphaned type $11 data items from EEPROM is
called. This bug-catcher would be a good one to hook to
ensure that cards that hide their E3M code inside type $11
data items don't get their code deleted.
$7A53 $8C Response output redirection setup: This bug-catcher is
triggered when the routine to direct the activity of the
"build response" routine is called. The address of the
routine which should build the response is in X:A.
$56FD $96 ECM main interpreter (command byte is in A): This bug-catcher
is triggered when the main ECM interpreter loop is about to
interpret an ECM command. The ECM command just retrieved
from the ECM buffer is in A. An E3M card might need to hook
this routine to prevent blackout bits from affecting the
ability of the card to authorize a particular channel.
$57B4 $97 ECM command $20 (straight sub) handler: This bug-catcher is
triggered when ECM command $20 is executed. It is called
after the ECM command data has been moved to the working
area and the current date has been extracted from it and
written to EEPROM.
$57E8 $98 ECM command $22 (program type blackout/$23 (regional blackout)
handler. A=command length: This bug-catcher is triggered
when ECM commands $22 and $23 are executed. No processing
has yet taken place, but the length of the ECM command that
caused the bug-catcher to trigger is in A ($03 if it was
ECM command $22, $12 if it was ECM command $23).
$583E $99 ECM command $21-Search by valid PPV service: This bug-catcher
is triggered when ECM command $21 is executed. It is called
after the $21 command has been determined to be "sane", but
prior to searching for any data. The search that this bug-
catcher would be useful for augmenting or avoiding is the
search by PPV ID.
$58B5 $9A ECM command $21-Search by "last paid PPV": This bug-catcher is
triggered when ECM command $21 has failed to find a matching
PPV item by matching a PPV ID. The next search the card will
attempt is a search based on "last paid PPV".
$58FA $9B ECM command $21-Search by "PPV by theme": This bug-catcher is
triggered when ECM command $21 has failed to find a matching
PPV item by either matching a PPV ID or "last paid PPV". The
next search the card will attempt is a search based on the
"theme" entry of PPV items.
$5928 $9C Service active for received system ID check: This bug-catcher
is triggered when the routine to verify that the system ID
we received for a given ECM command is valid for this card.
$5995 $9D ECM command $21-PPV by theme or PPV by number valid match: This
bug-catcher is triggered when ECM command $21 has determined
that a PPV item for the ECM does indeed exist.
$66A9 $A0 ECM decode phase 1 (pre-decrypt): This bug-catcher is triggered
when an attempt is being made to decrypt an ECM. When it is
called, the flags indicating that ECM decode is in progress
have been set, but no decrypt has yet been performed.
$6703 $A1 ECM decode phase 2 (post-decrypt): This bug-catcher is
triggered after an ECM has been decrypted and its signature
verified. Nothing has yet been done with the decrypted data.
$6731 $A2 ECM decode phase 3 (post-interpret, only if just a single
control word was requested): This bug-catcher is triggered
when an ECM has been decrypted and verified, and found to
contain only a single control word.
$67EC $A3 EMM decode phase 1: This bug-catcher is triggered when an
EMM command is about to be decrypted. When it is called, the
flags indicating that EMM decrypt is in progress have been
set, but no decryption has yet been performed.
$442B $AA ATR built, not yet sent: This bug-catcher is triggered when
the reset code has built the ATR message, but before the
message itself has been sent. This would allow modifications
to the ATR itself (useful, since most of the ATR data is
stored in ROM).
$4489 $B4 Callback build find data: This bug-catcher is triggered when
a $30 command causes callback data to begin to be built.
When it is called, the flags indicating that a callback
message is being built have been set, but no callback data
has yet been stuffed into the buffer.
$4536 $B5 Callback build encode data: This bug-catcher is triggered when
a $30 command has caused a callback message to be built, but
the message has not yet been encrypted for return to the IRD.
$4572 $B6 Callback build PPV lookup: This bug-catcher is triggered when
a $30 command is searching for a PPV item to be included in
the callback message.
$459D $BE Message processing setup: This bug-catcher is triggered when
a complete message with an information field has been received
and is ready to be dealt with. When it is called, SW1 and SW2
have been initialized to 90 00, and the flag indicating that
a message needs to be processed has been cleared.

Most useful bug-catchers

$7389 $0F Main idle loop entry pt 1: This bug-catcher is triggered


on entry to the main idle loop.
$73B7 $28 INS byte handler: This bug-catcher is triggered when a command
has been received and the INS byte is about to be processed.
When the bug-catcher is called, the received INS byte is in A.
This bug-catcher would be the one to hook to close the
standard Kudelski backdoors (A0 20, A0 B0, etc.)
$73D6 $29 Main command handler: This bug-catcher is triggered when a
command has been receieved and the command byte is about to be
processed. When the bug-catcher is called, the received
command byte is in A. This bug-catcher would be the one to
hook to add new "standard format" commands.
$5B3B $65 Main EMM command handler: This bug-catcher is triggered when
an EMM command is about to be processed. When the bug-catcher
is called, the EMM command number is in A. This would be the
bug-catcher to hook to avoid processing specific EMM commands
(such as $F3), to modify the way specific EMM commands are
processed (such as $21, $23, $31, or $33), or to add new
EMM commands.
$5C51 $6B EMM command $20 just got data item type, about to go and modify
dates as necessary: This bug-catcher is triggered once EMM
command $20 has determined what type of data items it is to
modify, but prior to actually performing any modification.
This would be the bug-catcher to hook in order to prevent
a programming provider from expiring bogus subscription items
that cause the card to operate in a "full open" mode.
$5F53 $71 KILLFOUNDITEM: This bug-catcher is triggered when EMM command
$23 attempts to delete a subscription item. This bug-catcher
probably needs to be hooked in order to prevent a programming
provider from deleting bugus subscription items that cause a
card to operate in the "full open" mode.
$6558 $78 SEARCHANDMOD: This bug-catcher is triggered whenever the
routine that searches for subscription data items and modifies
them is called. This routine is called by EMM commands $20
and $23.
$665F $7C VERFPPVLINKS: This bug-catcher is triggered when the routine
that deletes orphaned type $11 data items from EEPROM is
called. This bug-catcher would be a good one to hook to
ensure that cards that hide their E3M code inside type $11
data items don't get their code deleted.
$56FD $96 ECM main interpreter (command byte is in A): This bug-catcher
is triggered when the main ECM interpreter loop is about to
interpret an ECM command. The ECM command just retrieved
from the ECM buffer is in A. An E3M card might need to hook
this routine to prevent blackout bits from affecting the
ability of the card to authorize a particular channel.
$459D $BE Message processing setup: This bug-catcher is triggered when
a complete message with an information field has been received
and is ready to be dealt with. When it is called, SW1 and SW2
have been initialized to 90 00, and the flag indicating that
a message needs to be processed has been cleared.

11.2.2- Hooking in a bug-catcher


When hooking a bug-catcher, the only real thing to keep in mind is that at
some point, the code you add is going to need to return control either to the
original CAM code, or to the routine that called the routine that you're
trying to replace. Returning control to the original CAM code is easy: Just
make sure that all the registers the original code uses are set up properly
(usually, this just means preserving A and X, but sometimes, pointers like
RC1ADDRH:L and RC2ADDRH:L are used, too), and end your code with an RTS. In
general, control should be returned to the original code when you're doing
things like adding new commands, disabling existing commands, and so on.
The other option for exiting from a bug-catcher is to cause the original
code to be bypassed, either in part, or in whole. The first step in this
process is to perform a JSR KILLRETADDR ($6C26). This routine effectively
removes the return address that would return control to the routine that
called CATCHBUG from the stack. Once the return address that would get
control back from CATCHBUG has been removed from the stack, the new code can
exit in one of two ways: It can simply perform an RTS, which will return
control to the routine whose bug-catcher you hooked, or you can perform a JMP
to some instruction in the original routine that is past the code that you
wish to bypass.

11.2.3- Useful routines


As with the ROM2 cards, the ROM3 cards include a large number of utility
routines to perform basic operations on certain pointers stored in zero page,
as well as the stack, database routines to update, search for, create and
delete data items in the EEPROM, and low-level routines to perform such
functions as I/O, delays, encryption/decryption, and so on. Below, useful
routines of each of these types will be detailed.

11.2.3.1- Utility routines


Utility routines fall into three basic categories: Routines to perform
modification and maintenance to the stack, routines to perform basic
operations on certain zero-page pointers, and routines to set up for a
command response. By far, the second category of routines is the largest,
comprising over 200 subroutines. One interesting thing to note about these
utility routines is that not all of them are actually called by the existing
code- many seem to exist as preparation for the possibility that an EMM F3
command may someday need them. For the most part, the actual operation of
each of these routines will not be detailed here; in most cases, a one-line
description of what each routine does is sufficient to get the point across.
When further detail is warranted, however, it will be provided. The first
table below simply lists the utility routines in the order they appear in ROM.
The second table groups the routines by the registers they affect.

Utility routines sorted by address:

Addr Name Description


---- ------------------ --------------------------------------------------
6838 RAMCODE12RTS Puts an RTS opcode at RAMCODE1+3 and RAMCODE2+3
683F PUSHXA Replaces the return address on the stack with
X:A, then JMPs to the former return address
685E PUSHRC1 Replaces the return address on the stack with
the contents of RC1ADDRH:L, then JMPs to the
former return address. Usually, this routine
is used to preserve the value in RC1ADDRH:L
687E POPXA Pulls the 16-bit value just below the current
return address off the stack, places it in X:A
689C POPRC1 Pulls the 16-bit value just below the current
return address off the stack, places it in
RC1ADDRH:L
68AD XARC1 Places the 16-bit value in X:A into RC1ADDRH:L
68B2 XARC2 Places the 16-bit value in X:A into RC2ADDRH:L
68B7 XTORC1 Places a value of $00xx into RC1ADDRH:L, where
xx is the value of the X register
68BC XTORC2 Places a value of $00xx into RC2ADDRH:L, where
xx is the value of the X register
68C1 RC1XA Gets the 16-bit value in RC1ADDRH:L into X:A
68C6 MOVERC1TORC2 Moves the 16-bit value in RC1ADDRH:L to RC2ADDRH:L
68D3 RC2XA Gets the 16-bit value in RC2ADDRH:L into X:A
68D8 MOVERC2TORC1 Moves the 16-bit value in RC2ADDRH:L to RC1ADDRH:L
68E5 SWAPAX Swaps the values in A and X
68EB SWAPXARC1 Swaps the 16-bit value in X:A with the 16-bit
value in RC1ADDRH:L
68FC SWAPXARC2 Swaps the 16-bit value in X:A with the 16-bit
value in RC2ADDRH:L
690D SWAPZPRC1 Swaps the 16-bit value pointed to by X in ZP
with the 16-bit value in RC1ADDRH:L
6928 SWAPZPRC2 Swaps the 16-bit value pointed to by X in ZP
with the 16-bit value in RC2ADDRH:L
6943 SWAPRC2RC1 Swaps the 16-bit value in RC1ADDRH:L with the
16-bit value in RC2ADDRH:L
695C LDARC1 Gets the value in the memory address pointed to
by RC1ADDRH:L into A
6962 LDARC1IX Gets the value in the memory address pointed to
by (RC1ADDRH:L+X) into A
6968 LDARC2 Gets the value in the memory address pointed to
by RC2ADDRH:L into A
696E LDARC2IX Gets the value in the memory address pointed to
by (RC2ADDRH:L+X) into A
6974 ZPX_XA Gets the 16-bit value pointed to by X in ZP into
X:A
6978 XAFROMXA Gets the 16-bit value pointed to by X:A into X:A
698E RC1_XA Gets the 16-bit value pointed to by RC1ADDRH:L
into X:A
699A RC2_XA Gets the 16-bit value pointed to by RC2ADDRH:L
into X:A
69A6 XFROMXA Gets the byte pointed to by X:A into X
69B4 LDXRC1 Gets the byte pointed to by RC1ADDRH:L into X
69BA LDXRC1IX Gets the byte pointed to by (RC1ADDRH:L+X) into X
69C4 LDXRC2 Gets the byte pointed to by RC2ADDRH:L into X
69CA LDXRC2IX Gets the byte pointed to by (RC2ADDRH:L+X) into X
69D4 ZPTORC1 Gets the 16-bit value pointed to by the parameter
embedded after the JSR/BSR to PARMTORC1
into RC1ADDRH:L. For example, the following
code...

SUB1: JSR PARMTORC1 ;Get the 16-bit value


; into RC1ADDRH:L
DB $F0 ;Pointer to 16-bit
; value for RC1

would get the 16-bit value stored at F0:F1 into


RC1ADDRH:L
69E2 MOVE1XXTORC1 Moves the 16-bit value offset from $100 by the
parameter embedded after the JSR/BSR to
MOVE1XXTORC1 into RC1ADDRH:L. For example, the
following code...

SUB1: JSR MOVE1XXTORC1 ;Get the 16-bit value


; into RC1ADDRH:L
DB $3A ;Offset from $100 of
; 16-bit value for RC1

would get the 16-bit value at 13A:13B into


RC1ADDRH:L
69EC GET1FROMCALLER Gets a single embedded parameter byte that
followed the JSR/BSR to the routine that
called GET1FROMCALLER, and returns with that
byte in X. For example, the following code...

JSR SUB1 ;Call subroutine


DB $68 ;Embedded parameter

SUB1: JSR GET1FROMCALLER ;Get the embedded


; parameter sent
; to us
RTS ;And return

would end up getting a value of $68 into X.


6A0A GET2PARMSTORC1 Gets the 16-bit value embedded after the call
to GET2PARMSTORC1 into RC1ADDRH:L. For example,
the following code...

JSR GET2PARMSTORC1 ;Get pointer to


; current data in
; EEPROM into RC1
DW $E03C ;Current date stored
; at E03C:E03D

would get a value of $E0 into RC1ADDRH and a


value of $3C into RC1ADDRL
6A36 ZPX_RC1 Gets the 16-bit value pointed to by X in ZP
into RC1ADDRH:L
6A42 PTRRC2_RC1 Gets the 16-bit value pointed to by RC2ADDRH:L
into RC1ADDRH:L
6A59 PTRRC2X_RC1 Gets the 16-bit value pointed to by
(RC2ADDRH:L+X) into RC1ADDRH:L
6A5D ZPTORC2 Gets the 16-bit value pointed to by the parameter
embedded after the JSR/BSR to PARMTORC2
into RC2ADDRH:L. For example, the following
code...

SUB1: JSR PARMTORC2 ;Get the 16-bit value


; into RC2ADDRH:L
DB $F0 ;Pointer to 16-bit
; value for RC2

would get the 16-bit value stored at F0:F1 into


RC2ADDRH:L
6A6C MOVE1XXTORC2 Moves the 16-bit value offset from $100 by the
parameter embedded after the JSR/BSR to
MOVE1XXTORC2 into RC2ADDRH:L. For example, the
following code...

SUB1: JSR MOVE1XXTORC2 ;Get the 16-bit value


; into RC2ADDRH:L
DB $3A ;Offset from $100 of
; 16-bit value for RC2

would get the 16-bit value at 13A:13B into


RC2ADDRH:L
6A77 GET2PARMSTORC2 Gets the 16-bit value embedded after the call
to GET2PARMSTORC2 into RC2ADDRH:L. For example,
the following code...

JSR GET2PARMSTORC2 ;Get pointer to


; current data in
; EEPROM into RC2
DW $E03C ;Current date stored
; at E03C:E03D

would get a value of $E0 into RC2ADDRH and a


value of $3C into RC2ADDRL
6AA3 ZPX_RC2 Gets the 16-bit value pointed to by X in ZP
into RC2ADDRH:L
6AAF PTRRC1_RC2 Gets the 16-bit value pointed to by RC1ADDRH:L
into RC2ADDRH:L
6AC6 PTRRC1X_RC2 Gets the 16-bit value pointed to by
(RC1ADDRH:L+X) into RC2ADDRH:L
6ACA STA_RC1 Stores the value in A to the address pointed to
by RC1ADDRH:L
6AD4 STA_RC1X Stores the value in A to the address pointed to
by (RC1ADDRH:L+X)
6ADE STA_RC2 Stores the value in A to the address pointed to
by RC2ADDRH:L
6AE8 STA_RC2X Stores the value in A to the address pointed to
by (RC2ADDRH:L+X)
6AF2 STAX_RC1 Stores the value in X:A to the address pointed to
by RC1ADDRH:L
6B04 STAX_RC2 Stores the value in X:A to the address pointed to
by RC2ADDRH:L
6B16 STX_RC1 Stores the value in X to the address pointed to
by RC1ADDRH:L
6B20 STX_RC2 Stores the value in X to the address pointed to
by RC2ADDRH:L
6B2A MOVERC1TO0XX Moves the 16-bit value stored at RC1ADDRH:L to
ZP, starting at the address passed to
MOVERC1TO0XX as an embedded parameter. For
example, the following code...

JSR MOVERC1TO0XX ;Move RC1ADDRH:L to


; someplace where we
; can work with it
DB $C8
would move the 16-bit value stored at RC1ADDRH:L
to C8:C9
6B39 MOVERC1TO1XX Moves the 16-bit value stored at RC1ADDRH:L to
$100 plus the offset passed to MOVRC1TO1XX
as an embedded parameter. For
example, the following code...

JSR MOVERC1TO1XX ;Move RC1ADDRH:L to


; someplace where we
; can work with it
DB $40

would move the 16-bit value stored at RC1ADDRH:L


to 140:141
6B4B RC1_ZPX Moves the 16-bit value in RC1ADDRH:L to ZP RAM
pointed to by X
6B57 RC1_TO_XA Moves the 16-bit value in RC1ADDRH:L to the
address pointed to by X:A
6B72 RC1_TO_RC2PTR Moves the 16-bit value in RC1ADDRH:L to the
address pointed to by RC2ADDRH:L
6B8A MOVERC2TO0XX Moves the 16-bit value stored at RC2ADDRH:L to
ZP, starting at the address passed to
MOVERC2TO0XX as an embedded parameter. For
example, the following code...

JSR MOVERC1TO0XX ;Move RC2ADDRH:L to


; someplace where we
; can work with it
DB $C8

would move the 16-bit value stored at RC2ADDRH:L


to C8:C9
6B99 MOVERC2TO1XX Moves the 16-bit value stored at RC2ADDRH:L to
$100 plus the offset passed to MOVRC2TO1XX
as an embedded parameter. For
example, the following code...

JSR MOVERC2TO1XX ;Move RC2ADDRH:L to


; someplace where we
; can work with it
DB $40

would move the 16-bit value stored at RC2ADDRH:L


to 140:141
6BAB RC2_ZPX Moves the 16-bit value in RC2ADDRH:L to ZP RAM
pointed to by X
6BB7 RC2_TO_XA Moves the 16-bit value in RC2ADDRH:L to the
address pointed to by X:A
6BD2 RC2_TO_RC1PTR Moves the 16-bit value in RC2ADDRH:L to the
address pointed to by RC1ADDRH:L
6BEA CLEARRC1 Sets RC1ADDRH:L equal to 0000
6BEF CLEARRC2 Sets RC2ADDRH:L equal to 0000
6BF4 JMPTOPSTACK JMPs to the routine whose address is on top of
the stack.
6C14 DECRC1 Subtracts 1 from the 16-bit value at RC1ADDRH:L
6C1D DECRC2 Subtracts 1 from the 16-bit value at RC2ADDRH:L
6C26 KILLRETADDR Removes the return address that was on top of
the stack before KILLRETADDR was called. For
example, the following code...
L1: JSR L3 ;Call routine L3
L2: xxx ;Routine L1 continues
; here

L3: JSR L5 ;Routine L3 start


L4: xxx ;Routine L3 continues
; here

L5: JSR KILLRETADDR ;Kill return address


RTS

would result in L5 returning to L2, since L5


removes the return address that would have taken
it back to the caller (L4)
6C5B INCRC1 Adds 1 to the 16-bit value at RC1ADDRH:L
6C62 INCRC2 Adds 1 to the 16-bit value at RC2ADDRH:L
6C69 ADD_X_TO_A Adds value of X to value of A, places result in A
6C6E ADD_A_TO_X Adds value of A to value of X, places result in X
6C77 ADDATORC1 Adds the value of A to the 16-bit value stored
at RC1ADDRH:L
6C84 ADDXTORC1 Adds the value of X to the 16-bit value stored
at RC1ADDRH:L
6C92 ADDXATORC1 Adds the 16-bit value in X:A to the 16-bit value
stored at RC1ADDRH:L
6CA4 ADDXTIMESATORC1 Adds the 16-bit result of X*A to the 16-bit value
stored at RC1ADDRH:L
6CAB ADDRC3APLUSXTORC1 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L
6CB9 ADDRC2TORC1 Adds the 16-bit value stored at RC2ADDRH:L to the
16-bit value stored at RC1ADDRH:L, places result
in RC1ADDRH:L
6CCE ADDATORC2 Adds the value of A to the 16-bit value stored
at RC2ADDRH:L
6CDB ADDXATORC2 Adds the 16-bit value in X:A to the 16-bit value
stored at RC2ADDRH:L
6CED ADDXATORC1INRC2 Adds the 16-bit value in X:A to the 16-bit value
stored at RC1ADDRH:L, places result in
RC2ADDRH:L
6CFB ADDXTIMESATORC2 Adds the 16-bit result of X*A to the 16-bit value
stored at RC2ADDRH:L
6D02 RC1PLXPLRC3ARC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L, places result
in RC2ADDRH:L
6D0E ADDRC3APLUSXTORC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC2ADDRH:L
6D1C SUBXFROMA Subtracts value of X from value of A, places
result in A
6D21 SUBAFROMX Subtracts value of A from value of X, places
result in X. Note: Z flag does not reflect
the result of the operation on exit from this
routine.
6D2A SUB_RC1_FROM_XA Subtracts the 16-bit value stored at RC1ADDRH:L
from the 16-bit value in X:A, places result in
X:A
6D35 SUB_RC2_FROM_XA Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value in X:A, places result in
X:A
6D40 SUB_A_FROMRC1 Subtracts the value of A from the 16-bit value
stored at RC1ADDRH:L
6D4F SUB_X_FROMRC1 Subtracts the value of X from the 16-bit value
stored at RC1ADDRH:L
6D60 SUB_XA_FROMRC1 Subtracts the 16-bit value of X:A from the 16-bit
value stored at RC1ADDRH:L
6D73 SUBRC2FROMRC1 Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value stored at RC1ADDRH:L,
places result in RC1ADDRH:L
6D84 SUB_A_FROMRC2 Subtracts the value of A from the 16-bit value
stored at RC2ADDRH:L
6D93 CMP_XA_TO_RC1 Compares the 16-bit value in X:A with the 16-bit
value stored at RC1ADDRH:L. On exit, all
conditional branches will work properly.
6D9A CMP_XA_TO_RC2 Compares the 16-bit value in X:A with the 16-bit
value stored at RC2ADDRH:L. On exit, all
conditional branches will work properly.
6DA1 CMP_ZPX_TO_RC1 Compares the 16-bit value pointed to by X in ZP
from the 16-bit value stored at RC1ADDRH:L.
On exit, all conditional branches will work
properly.
6DB3 COMPARE_RC1_RC2 Compares the 16-bit value stored at RC1ADDRH:L
with the 16-bit value stored at RC2ADDRH:L. On
exit, all conditional brances will work
properly.
6DC1 CMP_ZPX_TO_RC2 Compares the 16-bit value pointed to by X in ZP
from the 16-bit value stored at RC2ADDRH:L.
On exit, all conditional branches will work
properly.
6DCC GETNPARMS Advances the return address for the routine that
called the routine that called GETNPARMS past
any embedded parameters that were passed to it.
The number of bytes by which to advance the
return address is passed to GETNPARMS as an
embedded parameter. Code example:

SUB1: JSR SUB2 ;Call SUB2


DB $01,$02,$03 ;3 parameters
: :

SUB2: JSR GETNPARMS ;Point to parameters


DB $03 ;Expect 3 parameters

On exit from GETNPARMS, RC1ADDRH:L will point


at the parameters passed to the routine that
called GETNPARMS, and when the routine that
called GETNPARMS executes its RTS, control will
return to the instruction immediately following
the embedded parameters.
6DFE CLEARA_AT_X Clears A bytes of RAM pointed to by X in ZP to
$00. Note: Wraps from $FF to $00.
6E0F CLR_ZP Clears n bytes of RAM starting at ZP address a.
Both n and a are passed as embedded parameters:

JSR CLR_ZP ;Clear ZP from C1..C8


DB $C1,$07

Note: Wraps from $FF to $00.


6E3F MOVERC3FROMATOX Moves the number of bytes of data specified by
the value stored at RC3ADDR pointed to by A in
ZP to ZP RAM pointed to by X. Note: Wraps from
$FF to $00 on both the load and store side of
the move.
6E6A MVRC2FROMRC1_RC0 Moves the number of bytes of data specified by
the value stored at RAMCODE2 and pointed to by
RAMCODE1 to ZP RAM starting at RC0ADDRL. Note:
Wraps from $FF to $00 on both the load and
store side of the move.
6E7D MOVEZPTOZP3P Moves a block of data starting at one ZP RAM
location to a block starting at another ZP RAM
location. Source and destination addresses and
block length are all passed as embedded
parameters:

JSR MOVEZPTOZP3P ;Move ZP RAM


DB $C0,$80,$40 ;Source=$C0
;Dest=$80
;Size=$40
Note: Wraps from $FF to $00 on both the load
and store side of the move.
6EB7 ZPX_TO_RC1 Moves the byte in ZP pointed to by X to the
address pointed to by (RC1ADDRH:L). On exit,
the Z flag reflects the value of the byte that
was moved.
6EC1 MOVE_A_X_TO_RC1 Moves A bytes of data pointed to by X in ZP to
memory beginning at the address pointed to by
(RC1ADDRH:L). Note: Load side wraps from $FF
to $100
6ED9 MOVE_RC3_X_TO_RC1 Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
X in ZP to memory beginning at the address
pointed to by (RC1ADDRH:L). Note: Load side
wraps from $FF to $100
6EDF ZPX_TO_RC2 Moves the byte in ZP pointed to by X to the
address pointed to by (RC2ADDRH:L). On exit,
the Z flag reflects the value of the byte that
was moved.
6EE9 MOVE_A_X_TO_RC2 Moves A bytes of data pointed to by X in ZP to
memory beginning at the address pointed to by
(RC2ADDRH:L). Note: Load side wraps from $FF
to $100
6F0D MOVE_RC3_X_TO_RC2 Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
X in ZP to memory beginning at the address
pointed to by (RC2ADDRH:L). Note: Load side
wraps from $FF to $100
6F13 MOVE_RC1_TO_X Moves the byte stored in memory at the address
pointed to by (RC1ADDRH:L) to the ZP RAM
location pointed to by X
6F1D MOVE_A_RC1_TO_X Moves A bytes of data stored in memory starting
at the address pointed to by (RC1ADDRH:L) to
ZP RAM starting at the location pointed to by X.
Note: Wraps from $FF to $100
6F45 MVRCFROMRC1TOX Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
(RC1ADDRH:L) to ZP RAM starting at the location
pointed to by X. Note: Wraps from $FF to $100
6F4B MOVE_RC2_TO_X Moves the byte stored in memory at the address
pointed to by (RC2ADDRH:L) to the ZP RAM
location pointed to by X
6F52 MOVE_A_RC2_TO_X Moves A bytes of data stored in memory starting
at the address pointed to by (RC2ADDRH:L) to
ZP RAM starting at the location pointed to by X.
Note: Wraps from $FF to $100
6F83 MVRCFROMRC2TOX Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
(RC2ADDRH:L) to ZP RAM starting at the location
pointed to by X. Note: Wraps from $FF to $100
6F8E CMPRC3ZPATOZPX Compares two blocks of data stored in ZP RAM,
one pointed to by A, the other pointed to by X,
whose size is specified by the value stored at
RC3ADDR. On exit, if the two blocks were
identical, the Z flag will be set.
6FB3 CMPZPTOZP3P Compares two blocks of data stored in ZP RAM.
Start addresses of the two blocks, as well as
the size of the blocks, are passed as embedded
parameters:

JSR CMPZPTOZP3P ;Compare blocks


DB $80,$C0,$40 ;1st block @ $80
;2nd block @ $C0
;Blocks are $40 bytes
On exit, BLO will be taken if the value of the
first non-equal byte of the 1st block was less
than the value of the first non-equal byte of
the 2nd block. BHI would indicate that the 1st
non-equal byte of the 1st block was larger then
the 1st non-equal byte of the 2nd block. A BEQ
will be taken if all bytes of both blocks match.
6FEF CMP_X_TO_RC1 Compares the value in memory pointed to by
(RC1ADDRH:L) with the value in ZP RAM pointed
to by X. On exit, BLO will be taken if the
value pointed to by (RC1ADDRH:L) is less than
the value pointed to by X. BHI would indicate
that the value pointed to by (RC1ADDRH:L) is
greater than the value pointed to by X.
7000 CMP_A_ZPX_TO_RC1 Compares A bytes of memory pointed to by X in ZP
to A bytes of memory pointed to by (RC1ADDRH:L).
On exit, BLO will be taken if the 1st non-equal
byte stored starting at X is less than the
1st non-equal byte stored starting at
(RC1ADDRH:L). BHI would indicate that the 1st
non-equal byte starting at X is greater than the
1st non-equal byte stored starting at
(RC1ADDRH:L)
701F TST_A_AT_X_FORZERO Checks to see if A bytes of RAM pointed to by X
are all zero. If so, BEQ will be taken on
exit. Note that 0 is not a valid value for X
on entry to this routine: It will cause a
false report that all bytes were 0.
7034 TST_A_RC1_FORZERO Checks to see if A bytes of memory pointed to
by (RC1ADDRH:L) are all zero. If so, BEQ will
be taken on exit. Note that if a value of 0 is
passed in A (to check 256 bytes) and the first
byte doesn't match, this routine will mistakenly
report that all bytes matched.
7050 TST_A_RC1_FORX Checks to see if A bytes of memory pointed to
by (RC1ADDRH:L) all equal X. If so, BEQ will
be taken on exit. Note that if a value of 0 is
passed in A (to check 256 bytes) and the first
byte doesn't match, this routine will mistakenly
report that all bytes matched.
7057 CLRMATRIXBIT_A Clears bit A of the bit matrix pointed to by X
in ZP. See section 11.2.4.4 for information on
the structure of bit matrices.
705D TOGMATRIXBIT_A Toggles bit A of the bit matrix pointed to by X
in ZP. See section 11.2.4.4 for information on
the structure of bit matrices.
7062 SETCLRMATRIXBIT_A Sets or clears bit A of the bit matrix pointed to
by X in ZP, depending on the state of the Z bit
in the processor status flags. If the Z bit is
set, this routine clears the bit in the bit
matrix, if the Z bit is clear, this routine sets
the bit in the bit matrix. See section 11.2.4.4
for information on the structure of bit
matrices.
7064 SETMATRIXBIT_A Sets bit A of the bit matrix pointed to by X
in ZP. See section 11.2.4.4 for information on
the structure of bit matrices.
706D TESTMATRIXBIT_A Tests the state of bit A of the bit matrix
pointed to by X in ZP. On exit, BEQ will be
taken if the bit was clear, otherwise, BNE will
be taken. See section 11.2.4.4 for information
on the structure of bit matrices.
7076 TESTROMMATRIXXA Tests the state of bit A of the bit matrix
in ROM or EEPROM pointed to by (RC1ADDRH:L). On
exit, BEQ will be taken if the bit was clear,
otherwise, BNE will be taken. See section
11.2.4.4 for information on the structure of bit
matrices.
708D FINDBITADDR Finds the address in ZP and bitmask for bit A of
the bit matrix pointed to by X. On exit, X
contains the ZP address of the byte containing
the bit we're interested in, and A contains the
bitmask required to isolate (AND), set (ORA), or
toggle (XOR) the bit. To clear the bit, use the
COMA instruction to invert the bitmask, then AND
the bitmask with the ZP RAM location.
70A3 TEST256FORX Tests 256 bytes of memory pointed to by
(RC1ADDRH:L) to see if they are all equal to the
value of X. If so, BEQ will be taken on exit,
if not, BNE will be taken. BLO and BHI indicate
that the value of X was less than or greater
than the first byte that did not equal X,
respectively.
70B8 BYTEFLOPRAM Byte-flops (reverses the byte order of) A bytes
of ZP RAM pointed to by X. For example, if
RAM at $F0 contains $11 $22 $33 $44 $55 $66,
and BYTEFLOPRAM is called with a value of 6 in A
and a value of F0 in X, after BYTEFLOPRAM is
finished, $F0 would be altered such that it
contains $66 $55 $44 $33 $22 $11. Under the
same starting conditions, calling BYTEFLOPRAM
with values of 4 and F1 for A and X would
result in RAM at F0 being altered such that it
contains $11 $55 $44 $33 $22 $66.
70E2 BITBYTEFLOP_A_AT_X Byte-flops A bytes of ZP RAM pointed to by X
(see BYTEFLOPRAM, above), then bit-flops the
same data (see BITFLOP_A_AT_X, below).
70E4 BITFLOP_A_AT_X Bit-flops A bytes of ZP RAM pointed to by X.
The bit-flop operation reverses the order of
the bits in each byte of RAM so that an input
byte whose bits are numbered 76543210 will
result in an output byte whose bits are
rearranged as 01234567.

Utility routines grouped by modified registers and function (note: In this


table, some routines are listed more than once, because they affect or are
affected by more than one pointer in ZP RAM)

Addr Name Description


---- ------------------ --------------------------------------------------
Miscellaneous setup:
6838 RAMCODE12RTS Puts an RTS opcode at RAMCODE1+3 and RAMCODE2+3
6BEA CLEARRC1 Sets RC1ADDRH:L equal to 0000
6BEF CLEARRC2 Sets RC2ADDRH:L equal to 0000

Stack manipulation:
683F PUSHXA Replaces the return address on the stack with
X:A, then JMPs to the former return address
687E POPXA Pulls the 16-bit value just below the current
return address off the stack, places it in X:A
685E PUSHRC1 Replaces the return address on the stack with
the contents of RC1ADDRH:L, then JMPs to the
former return address. Usually, this routine
is used to preserve the value in RC1ADDRH:L
689C POPRC1 Pulls the 16-bit value just below the current
return address off the stack, places it in
RC1ADDRH:L
6943 SWAPRC2RC1 Swaps the 16-bit value in RC1ADDRH:L with the
16-bit value in RC2ADDRH:L
69EC GET1FROMCALLER Gets a single embedded parameter byte that
followed the JSR/BSR to the routine that
called GET1FROMCALLER, and returns with that
byte in X. For example, the following code...

JSR SUB1 ;Call subroutine


DB $68 ;Embedded parameter

SUB1: JSR GET1FROMCALLER ;Get the embedded


; parameter sent
; to us
RTS ;And return

would end up getting a value of $68 into X.


6BF4 JMPTOPSTACK JMPs to the routine whose address is on top of
the stack.
6C26 KILLRETADDR Removes the return address that was on top of
the stack before KILLRETADDR was called. For
example, the following code...

L1: JSR L3 ;Call routine L3


L2: xxx ;Routine L1 continues
; here

L3: JSR L5 ;Routine L3 start


L4: xxx ;Routine L3 continues
; here

L5: JSR KILLRETADDR ;Kill return address


RTS

would result in L5 returning to L2, since L5


removes the return address that would have taken
it back to the caller (L4)
6DCC GETNPARMS Advances the return address for the routine that
called the routine that called GETNPARMS past
any embedded parameters that were passed to it.
The number of bytes by which to advance the
return address is passed to GETNPARMS as an
embedded parameter. Code example:

SUB1: JSR SUB2 ;Call SUB2


DB $01,$02,$03 ;3 parameters
: :

SUB2: JSR GETNPARMS ;Point to parameters


DB $03 ;Expect 3 parameters

On exit from GETNPARMS, RC1ADDRH:L will point


at the parameters passed to the routine that
called GETNPARMS, and when the routine that
called GETNPARMS executes its RTS, control will
return to the instruction immediately following
the embedded parameters.

Operations affecting RC1ADDRH:L:


689C POPRC1 Pulls the 16-bit value just below the current
return address off the stack, places it in
RC1ADDRH:L
68AD XARC1 Places the 16-bit value in X:A into RC1ADDRH:L
68B7 XTORC1 Places a value of $00xx into RC1ADDRH:L, where
xx is the value of the X register
68D8 MOVERC2TORC1 Moves the 16-bit value in RC2ADDRH:L to RC1ADDRH:L
68EB SWAPXARC1 Swaps the 16-bit value in X:A with the 16-bit
value in RC1ADDRH:L
690D SWAPZPRC1 Swaps the 16-bit value pointed to by X in ZP
with the 16-bit value in RC1ADDRH:L
6943 SWAPRC2RC1 Swaps the 16-bit value in RC1ADDRH:L with the
16-bit value in RC2ADDRH:L
69D4 ZPTORC1 Gets the 16-bit value pointed to by the parameter
embedded after the JSR/BSR to PARMTORC1
into RC1ADDRH:L. For example, the following
code...

SUB1: JSR PARMTORC1 ;Get the 16-bit value


; into RC1ADDRH:L
DB $F0 ;Pointer to 16-bit
; value for RC1

would get the 16-bit value stored at F0:F1 into


RC1ADDRH:L
69E2 MOVE1XXTORC1 Moves the 16-bit value offset from $100 by the
parameter embedded after the JSR/BSR to
MOVE1XXTORC1 into RC1ADDRH:L. For example, the
following code...

SUB1: JSR MOVE1XXTORC1 ;Get the 16-bit value


; into RC1ADDRH:L
DB $3A ;Offset from $100 of
; 16-bit value for RC1

would get the 16-bit value at 13A:13B into


RC1ADDRH:L
6A0A GET2PARMSTORC1 Gets the 16-bit value embedded after the call
to GET2PARMSTORC1 into RC1ADDRH:L. For example,
the following code...

JSR GET2PARMSTORC1 ;Get pointer to


; current data in
; EEPROM into RC1
DW $E03C ;Current date stored
; at E03C:E03D

would get a value of $E0 into RC1ADDRH and a


value of $3C into RC1ADDRL
6A36 ZPX_RC1 Gets the 16-bit value pointed to by X in ZP
into RC1ADDRH:L
6A42 PTRRC2_RC1 Gets the 16-bit value pointed to by RC2ADDRH:L
into RC1ADDRH:L
6A59 PTRRC2X_RC1 Gets the 16-bit value pointed to by
(RC2ADDRH:L+X) into RC1ADDRH:L
6BEA CLEARRC1 Sets RC1ADDRH:L equal to 0000
6C14 DECRC1 Subtracts 1 from the 16-bit value at RC1ADDRH:L
6C5B INCRC1 Adds 1 to the 16-bit value at RC1ADDRH:L
6C77 ADDATORC1 Adds the value of A to the 16-bit value stored
at RC1ADDRH:L
6C84 ADDXTORC1 Adds the value of X to the 16-bit value stored
at RC1ADDRH:L
6C92 ADDXATORC1 Adds the 16-bit value in X:A to the 16-bit value
stored at RC1ADDRH:L
6CA4 ADDXTIMESATORC1 Adds the 16-bit result of X*A to the 16-bit value
stored at RC1ADDRH:L
6CAB ADDRC3APLUSXTORC1 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L
6CB9 ADDRC2TORC1 Adds the 16-bit value stored at RC2ADDRH:L to the
16-bit value stored at RC1ADDRH:L, places result
in RC1ADDRH:L
6D40 SUB_A_FROMRC1 Subtracts the value of A from the 16-bit value
stored at RC1ADDRH:L
6D4F SUB_X_FROMRC1 Subtracts the value of X from the 16-bit value
stored at RC1ADDRH:L
6D60 SUB_XA_FROMRC1 Subtracts the 16-bit value of X:A from the 16-bit
value stored at RC1ADDRH:L
6D73 SUBRC2FROMRC1 Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value stored at RC1ADDRH:L,
places result in RC1ADDRH:L

Operations affected by RC1ADDRH:L


685E PUSHRC1 Replaces the return address on the stack with
the contents of RC1ADDRH:L, then JMPs to the
former return address. Usually, this routine
is used to preserve the value in RC1ADDRH:L
68C1 RC1XA Gets the 16-bit value in RC1ADDRH:L into X:A
68C6 MOVERC1TORC2 Moves the 16-bit value in RC1ADDRH:L to RC2ADDRH:L
68EB SWAPXARC1 Swaps the 16-bit value in X:A with the 16-bit
value in RC1ADDRH:L
690D SWAPZPRC1 Swaps the 16-bit value pointed to by X in ZP
with the 16-bit value in RC1ADDRH:L
6943 SWAPRC2RC1 Swaps the 16-bit value in RC1ADDRH:L with the
16-bit value in RC2ADDRH:L
695C LDARC1 Gets the value in the memory address pointed to
by RC1ADDRH:L into A
6962 LDARC1IX Gets the value in the memory address pointed to
by (RC1ADDRH:L+X) into A
698E RC1_XA Gets the 16-bit value pointed to by RC1ADDRH:L
into X:A
69B4 LDXRC1 Gets the byte pointed to by RC1ADDRH:L into X
69BA LDXRC1IX Gets the byte pointed to by (RC1ADDRH:L+X) into X
6AAF PTRRC1_RC2 Gets the 16-bit value pointed to by RC1ADDRH:L
into RC2ADDRH:L
6AC6 PTRRC1X_RC2 Gets the 16-bit value pointed to by
(RC1ADDRH:L+X) into RC2ADDRH:L
6ACA STA_RC1 Stores the value in A to the address pointed to
by RC1ADDRH:L
6AD4 STA_RC1X Stores the value in A to the address pointed to
by (RC1ADDRH:L+X)
6AF2 STAX_RC1 Stores the value in X:A to the address pointed to
by RC1ADDRH:L
6B16 STX_RC1 Stores the value in X to the address pointed to
by RC1ADDRH:L
6B2A MOVERC1TO0XX Moves the 16-bit value stored at RC1ADDRH:L to
ZP, starting at the address passed to
MOVERC1TO0XX as an embedded parameter. For
example, the following code...

JSR MOVERC1TO0XX ;Move RC1ADDRH:L to


; someplace where we
; can work with it
DB $C8

would move the 16-bit value stored at RC1ADDRH:L


to C8:C9
6B39 MOVERC1TO1XX Moves the 16-bit value stored at RC1ADDRH:L to
$100 plus the offset passed to MOVRC1TO1XX
as an embedded parameter. For
example, the following code...

JSR MOVERC1TO1XX ;Move RC1ADDRH:L to


; someplace where we
; can work with it
DB $40

would move the 16-bit value stored at RC1ADDRH:L


to 140:141
6B4B RC1_ZPX Moves the 16-bit value in RC1ADDRH:L to ZP RAM
pointed to by X
6B57 RC1_TO_XA Moves the 16-bit value in RC1ADDRH:L to the
address pointed to by X:A
6B72 RC1_TO_RC2PTR Moves the 16-bit value in RC1ADDRH:L to the
address pointed to by RC2ADDRH:L
6BD2 RC2_TO_RC1PTR Moves the 16-bit value in RC2ADDRH:L to the
address pointed to by RC1ADDRH:L
6CED ADDXATORC1INRC2 Adds the 16-bit value in X:A to the 16-bit value
stored at RC1ADDRH:L, places result in
RC2ADDRH:L
6D02 RC1PLXPLRC3ARC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L, places result
in RC2ADDRH:L
6D2A SUB_RC1_FROM_XA Subtracts the 16-bit value stored at RC1ADDRH:L
from the 16-bit value in X:A, places result in
X:A
6D73 SUBRC2FROMRC1 Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value stored at RC1ADDRH:L,
places result in RC1ADDRH:L
6D93 CMP_XA_TO_RC1 Compares the 16-bit value in X:A with the 16-bit
value stored at RC1ADDRH:L. On exit, all
conditional branches will work properly.
6DA1 CMP_ZPX_TO_RC1 Compares the 16-bit value pointed to by X in ZP
from the 16-bit value stored at RC1ADDRH:L.
On exit, all conditional branches will work
properly.
6DB3 COMPARE_RC1_RC2 Compares the 16-bit value stored at RC1ADDRH:L
with the 16-bit value stored at RC2ADDRH:L. On
exit, all conditional brances will work
properly.

Operations affecting RC2ADDRH:L:


68B2 XARC2 Places the 16-bit value in X:A into RC2ADDRH:L
68BC XTORC2 Places a value of $00xx into RC2ADDRH:L, where
xx is the value of the X register
68C6 MOVERC1TORC2 Moves the 16-bit value in RC1ADDRH:L to RC2ADDRH:L
68FC SWAPXARC2 Swaps the 16-bit value in X:A with the 16-bit
value in RC2ADDRH:L
6928 SWAPZPRC2 Swaps the 16-bit value pointed to by X in ZP
with the 16-bit value in RC2ADDRH:L
6943 SWAPRC2RC1 Swaps the 16-bit value in RC1ADDRH:L with the
16-bit value in RC2ADDRH:L
6A5D ZPTORC2 Gets the 16-bit value pointed to by the parameter
embedded after the JSR/BSR to PARMTORC2
into RC2ADDRH:L. For example, the following
code...

SUB1: JSR PARMTORC2 ;Get the 16-bit value


; into RC2ADDRH:L
DB $F0 ;Pointer to 16-bit
; value for RC2

would get the 16-bit value stored at F0:F1 into


RC2ADDRH:L
6A6C MOVE1XXTORC2 Moves the 16-bit value offset from $100 by the
parameter embedded after the JSR/BSR to
MOVE1XXTORC2 into RC2ADDRH:L. For example, the
following code...

SUB1: JSR MOVE1XXTORC2 ;Get the 16-bit value


; into RC2ADDRH:L
DB $3A ;Offset from $100 of
; 16-bit value for RC2

would get the 16-bit value at 13A:13B into


RC2ADDRH:L
6A77 GET2PARMSTORC2 Gets the 16-bit value embedded after the call
to GET2PARMSTORC2 into RC2ADDRH:L. For example,
the following code...

JSR GET2PARMSTORC2 ;Get pointer to


; current data in
; EEPROM into RC2
DW $E03C ;Current date stored
; at E03C:E03D

would get a value of $E0 into RC2ADDRH and a


value of $3C into RC2ADDRL
6AA3 ZPX_RC2 Gets the 16-bit value pointed to by X in ZP
into RC2ADDRH:L
6AAF PTRRC1_RC2 Gets the 16-bit value pointed to by RC1ADDRH:L
into RC2ADDRH:L
6AC6 PTRRC1X_RC2 Gets the 16-bit value pointed to by
(RC1ADDRH:L+X) into RC2ADDRH:L
6BEF CLEARRC2 Sets RC2ADDRH:L equal to 0000
6C1D DECRC2 Subtracts 1 from the 16-bit value at RC2ADDRH:L
6C62 INCRC2 Adds 1 to the 16-bit value at RC2ADDRH:L
6CCE ADDATORC2 Adds the value of A to the 16-bit value stored
at RC2ADDRH:L
6CDB ADDXATORC2 Adds the 16-bit value in X:A to the 16-bit value
stored at RC2ADDRH:L
6CED ADDXATORC1INRC2 Adds the 16-bit value in X:A to the 16-bit value
stored at RC1ADDRH:L, places result in
RC2ADDRH:L
6CFB ADDXTIMESATORC2 Adds the 16-bit result of X*A to the 16-bit value
stored at RC2ADDRH:L
6D02 RC1PLXPLRC3ARC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L, places result
in RC2ADDRH:L
6D0E ADDRC3APLUSXTORC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC2ADDRH:L
6D84 SUB_A_FROMRC2 Subtracts the value of A from the 16-bit value
stored at RC2ADDRH:L

Operations affected by RC2ADDRH:L


68D3 RC2XA Gets the 16-bit value in RC2ADDRH:L into X:A
68D8 MOVERC2TORC1 Moves the 16-bit value in RC2ADDRH:L to RC1ADDRH:L
68FC SWAPXARC2 Swaps the 16-bit value in X:A with the 16-bit
value in RC2ADDRH:L
6928 SWAPZPRC2 Swaps the 16-bit value pointed to by X in ZP
with the 16-bit value in RC2ADDRH:L
6943 SWAPRC2RC1 Swaps the 16-bit value in RC1ADDRH:L with the
16-bit value in RC2ADDRH:L
6968 LDARC2 Gets the value in the memory address pointed to
by RC2ADDRH:L into A
696E LDARC2IX Gets the value in the memory address pointed to
by (RC2ADDRH:L+X) into A
699A RC2_XA Gets the 16-bit value pointed to by RC2ADDRH:L
into X:A
69C4 LDXRC2 Gets the byte pointed to by RC2ADDRH:L into X
69CA LDXRC2IX Gets the byte pointed to by (RC2ADDRH:L+X) into X
6A42 PTRRC2_RC1 Gets the 16-bit value pointed to by RC2ADDRH:L
into RC1ADDRH:L
6A59 PTRRC2X_RC1 Gets the 16-bit value pointed to by
(RC2ADDRH:L+X) into RC1ADDRH:L
6ADE STA_RC2 Stores the value in A to the address pointed to
by RC2ADDRH:L
6AE8 STA_RC2X Stores the value in A to the address pointed to
by (RC2ADDRH:L+X)
6B04 STAX_RC2 Stores the value in X:A to the address pointed to
by RC2ADDRH:L
6B20 STX_RC2 Stores the value in X to the address pointed to
by RC2ADDRH:L
6B72 RC1_TO_RC2PTR Moves the 16-bit value in RC1ADDRH:L to the
address pointed to by RC2ADDRH:L
6B8A MOVERC2TO0XX Moves the 16-bit value stored at RC2ADDRH:L to
ZP, starting at the address passed to
MOVERC2TO0XX as an embedded parameter. For
example, the following code...

JSR MOVERC1TO0XX ;Move RC2ADDRH:L to


; someplace where we
; can work with it
DB $C8

would move the 16-bit value stored at RC2ADDRH:L


to C8:C9
6B99 MOVERC2TO1XX Moves the 16-bit value stored at RC2ADDRH:L to
$100 plus the offset passed to MOVRC2TO1XX
as an embedded parameter. For
example, the following code...

JSR MOVERC2TO1XX ;Move RC2ADDRH:L to


; someplace where we
; can work with it
DB $40

would move the 16-bit value stored at RC2ADDRH:L


to 140:141
6BAB RC2_ZPX Moves the 16-bit value in RC2ADDRH:L to ZP RAM
pointed to by X
6BB7 RC2_TO_XA Moves the 16-bit value in RC2ADDRH:L to the
address pointed to by X:A
6BD2 RC2_TO_RC1PTR Moves the 16-bit value in RC2ADDRH:L to the
address pointed to by RC1ADDRH:L
6CB9 ADDRC2TORC1 Adds the 16-bit value stored at RC2ADDRH:L to the
16-bit value stored at RC1ADDRH:L, places result
in RC1ADDRH:L
6D35 SUB_RC2_FROM_XA Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value in X:A, places result in
X:A
6D73 SUBRC2FROMRC1 Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value stored at RC1ADDRH:L,
places result in RC1ADDRH:L
6D84 SUB_A_FROMRC2 Subtracts the value of A from the 16-bit value
stored at RC2ADDRH:L
6D9A CMP_XA_TO_RC2 Compares the 16-bit value in X:A with the 16-bit
value stored at RC2ADDRH:L. On exit, all
conditional branches will work properly.
6DB3 COMPARE_RC1_RC2 Compares the 16-bit value stored at RC1ADDRH:L
with the 16-bit value stored at RC2ADDRH:L. On
exit, all conditional brances will work
properly.
6DC1 CMP_ZPX_TO_RC2 Compares the 16-bit value pointed to by X in ZP
from the 16-bit value stored at RC2ADDRH:L.
On exit, all conditional branches will work
properly.

Operations affecting A:
68E5 SWAPAX Swaps the values in A and X
695C LDARC1 Gets the value in the memory address pointed to
by RC1ADDRH:L into A
6962 LDARC1IX Gets the value in the memory address pointed to
by (RC1ADDRH:L+X) into A
6968 LDARC2 Gets the value in the memory address pointed to
by RC2ADDRH:L into A
696E LDARC2IX Gets the value in the memory address pointed to
by (RC2ADDRH:L+X) into A
6C69 ADD_X_TO_A Adds value of X to value of A, places result in A
6D1C SUBXFROMA Subtracts value of X from value of A, places
result in A

Operations affected by A:
68E5 SWAPAX Swaps the values in A and X
6ACA STA_RC1 Stores the value in A to the address pointed to
by RC1ADDRH:L
6AD4 STA_RC1X Stores the value in A to the address pointed to
by (RC1ADDRH:L+X)
6ADE STA_RC2 Stores the value in A to the address pointed to
by RC2ADDRH:L
6AE8 STA_RC2X Stores the value in A to the address pointed to
by (RC2ADDRH:L+X)
6C69 ADD_X_TO_A Adds value of X to value of A, places result in A
6C6E ADD_A_TO_X Adds value of A to value of X, places result in X
6C77 ADDATORC1 Adds the value of A to the 16-bit value stored
at RC1ADDRH:L
6CA4 ADDXTIMESATORC1 Adds the 16-bit result of X*A to the 16-bit value
stored at RC1ADDRH:L
6CAB ADDRC3APLUSXTORC1 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L
6CCE ADDATORC2 Adds the value of A to the 16-bit value stored
at RC2ADDRH:L
6CFB ADDXTIMESATORC2 Adds the 16-bit result of X*A to the 16-bit value
stored at RC2ADDRH:L
6D02 RC1PLXPLRC3ARC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L, places result
in RC2ADDRH:L
6D0E ADDRC3APLUSXTORC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC2ADDRH:L
6D1C SUBXFROMA Subtracts value of X from value of A, places
result in A
6D21 SUBAFROMX Subtracts value of A from value of X, places
result in X. Note: Z flag does not reflect
the result of the operation on exit from this
routine.
6D40 SUB_A_FROMRC1 Subtracts the value of A from the 16-bit value
stored at RC1ADDRH:L
6D84 SUB_A_FROMRC2 Subtracts the value of A from the 16-bit value
stored at RC2ADDRH:L

Operations affecting X:
68E5 SWAPAX Swaps the values in A and X
69A6 XFROMXA Gets the byte pointed to by X:A into X
69B4 LDXRC1 Gets the byte pointed to by RC1ADDRH:L into X
69BA LDXRC1IX Gets the byte pointed to by (RC1ADDRH:L+X) into X
69C4 LDXRC2 Gets the byte pointed to by RC2ADDRH:L into X
69CA LDXRC2IX Gets the byte pointed to by (RC2ADDRH:L+X) into X
6C6E ADD_A_TO_X Adds value of A to value of X, places result in X
6D21 SUBAFROMX Subtracts value of A from value of X, places
result in X. Note: Z flag does not reflect
the result of the operation on exit from this
routine.

Operations affected by X:
68B7 XTORC1 Places a value of $00xx into RC1ADDRH:L, where
xx is the value of the X register
68BC XTORC2 Places a value of $00xx into RC2ADDRH:L, where
xx is the value of the X register
68E5 SWAPAX Swaps the values in A and X
6962 LDARC1IX Gets the value in the memory address pointed to
by (RC1ADDRH:L+X) into A
696E LDARC2IX Gets the value in the memory address pointed to
by (RC2ADDRH:L+X) into A
6974 ZPX_XA Gets the 16-bit value pointed to by X in ZP into
X:A
69BA LDXRC1IX Gets the byte pointed to by (RC1ADDRH:L+X) into X
69CA LDXRC2IX Gets the byte pointed to by (RC2ADDRH:L+X) into X
69EC GET1FROMCALLER Gets a single embedded parameter byte that
followed the JSR/BSR to the routine that
called GET1FROMCALLER, and returns with that
byte in X. For example, the following code...

JSR SUB1 ;Call subroutine


DB $68 ;Embedded parameter

SUB1: JSR GET1FROMCALLER ;Get the embedded


; parameter sent
; to us
RTS ;And return

would end up getting a value of $68 into X.


6A59 PTRRC2X_RC1 Gets the 16-bit value pointed to by
(RC2ADDRH:L+X) into RC1ADDRH:L
6AC6 PTRRC1X_RC2 Gets the 16-bit value pointed to by
(RC1ADDRH:L+X) into RC2ADDRH:L
6AD4 STA_RC1X Stores the value in A to the address pointed to
by (RC1ADDRH:L+X)
6AE8 STA_RC2X Stores the value in A to the address pointed to
by (RC2ADDRH:L+X)
6B16 STX_RC1 Stores the value in X to the address pointed to
by RC1ADDRH:L
6B20 STX_RC2 Stores the value in X to the address pointed to
by RC2ADDRH:L
6B4B RC1_ZPX Moves the 16-bit value in RC1ADDRH:L to ZP RAM
pointed to by X
6BAB RC2_ZPX Moves the 16-bit value in RC2ADDRH:L to ZP RAM
pointed to by X
6C69 ADD_X_TO_A Adds value of X to value of A, places result in A
6C6E ADD_A_TO_X Adds value of A to value of X, places result in X
6C84 ADDXTORC1 Adds the value of X to the 16-bit value stored
at RC1ADDRH:L
6CA4 ADDXTIMESATORC1 Adds the 16-bit result of X*A to the 16-bit value
stored at RC1ADDRH:L
6CAB ADDRC3APLUSXTORC1 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L
6CFB ADDXTIMESATORC2 Adds the 16-bit result of X*A to the 16-bit value
stored at RC2ADDRH:L
6D02 RC1PLXPLRC3ARC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L, places result
in RC2ADDRH:L
6D0E ADDRC3APLUSXTORC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC2ADDRH:L
6D1C SUBXFROMA Subtracts value of X from value of A, places
result in A
6D21 SUBAFROMX Subtracts value of A from value of X, places
result in X. Note: Z flag does not reflect
the result of the operation on exit from this
routine.
6D4F SUB_X_FROMRC1 Subtracts the value of X from the 16-bit value
stored at RC1ADDRH:L
6DA1 CMP_ZPX_TO_RC1 Compares the 16-bit value pointed to by X in ZP
from the 16-bit value stored at RC1ADDRH:L.
On exit, all conditional branches will work
properly.
6DC1 CMP_ZPX_TO_RC2 Compares the 16-bit value pointed to by X in ZP
from the 16-bit value stored at RC2ADDRH:L.
On exit, all conditional branches will work
properly.
Operations affecting X:A
687E POPXA Pulls the 16-bit value just below the current
return address off the stack, places it in X:A
68C1 RC1XA Gets the 16-bit value in RC1ADDRH:L into X:A
68EB SWAPXARC1 Swaps the 16-bit value in X:A with the 16-bit
value in RC1ADDRH:L
68FC SWAPXARC2 Swaps the 16-bit value in X:A with the 16-bit
value in RC2ADDRH:L
6974 ZPX_XA Gets the 16-bit value pointed to by X in ZP into
X:A
6978 XAFROMXA Gets the 16-bit value pointed to by X:A into X:A
698E RC1_XA Gets the 16-bit value pointed to by RC1ADDRH:L
into X:A
699A RC2_XA Gets the 16-bit value pointed to by RC2ADDRH:L
into X:A
6D2A SUB_RC1_FROM_XA Subtracts the 16-bit value stored at RC1ADDRH:L
from the 16-bit value in X:A, places result in
X:A
6D35 SUB_RC2_FROM_XA Subtracts the 16-bit value stored at RC2ADDRH:L
from the 16-bit value in X:A, places result in
X:A

Operations affected by X:A


683F PUSHXA Replaces the return address on the stack with
X:A, then JMPs to the former return address
68AD XARC1 Places the 16-bit value in X:A into RC1ADDRH:L
68B2 XARC2 Places the 16-bit value in X:A into RC2ADDRH:L
68EB SWAPXARC1 Swaps the 16-bit value in X:A with the 16-bit
value in RC1ADDRH:L
68FC SWAPXARC2 Swaps the 16-bit value in X:A with the 16-bit
value in RC2ADDRH:L
6978 XAFROMXA Gets the 16-bit value pointed to by X:A into X:A
69A6 XFROMXA Gets the byte pointed to by X:A into X
6AF2 STAX_RC1 Stores the value in X:A to the address pointed to
by RC1ADDRH:L
6B04 STAX_RC2 Stores the value in X:A to the address pointed to
by RC2ADDRH:L
6B57 RC1_TO_XA Moves the 16-bit value in RC1ADDRH:L to the
address pointed to by X:A
6BB7 RC2_TO_XA Moves the 16-bit value in RC2ADDRH:L to the
address pointed to by X:A
6C92 ADDXATORC1 Adds the 16-bit value in X:A to the 16-bit value
stored at RC1ADDRH:L
6CDB ADDXATORC2 Adds the 16-bit value in X:A to the 16-bit value
stored at RC2ADDRH:L
6D60 SUB_XA_FROMRC1 Subtracts the 16-bit value of X:A from the 16-bit
value stored at RC1ADDRH:L
6D93 CMP_XA_TO_RC1 Compares the 16-bit value in X:A with the 16-bit
value stored at RC1ADDRH:L. On exit, all
conditional branches will work properly.
6D9A CMP_XA_TO_RC2 Compares the 16-bit value in X:A with the 16-bit
value stored at RC2ADDRH:L. On exit, all
conditional branches will work properly.

Operations affected by RC3ADDR:


6CAB ADDRC3APLUSXTORC1 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L
6D02 RC1PLXPLRC3ARC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC1ADDRH:L, places result
in RC2ADDRH:L
6D0E ADDRC3APLUSXTORC2 Adds the 16-bit result of ((RC3ADDR*A)+X) to the
16-bit value stored at RC2ADDRH:L

Operations that perform memory move/init:


6DFE CLEARA_AT_X Clears A bytes of RAM pointed to by X in ZP to
$00. Note: Wraps from $FF to $00.
6E0F CLR_ZP Clears n bytes of RAM starting at ZP address a.
Both n and a are passed as embedded parameters:

JSR CLR_ZP ;Clear ZP from C1..C8


DB $C1,$07

Note: Wraps from $FF to $00.


6E3F MOVERC3FROMATOX Moves the number of bytes of data specified by
the value stored at RC3ADDR pointed to by A in
ZP to ZP RAM pointed to by X. Note: Wraps from
$FF to $00 on both the load and store side of
the move.
6E6A MVRC2FROMRC1_RC0 Moves the number of bytes of data specified by
the value stored at RAMCODE2 and pointed to by
RAMCODE1 to ZP RAM starting at RC0ADDRL. Note:
Wraps from $FF to $00 on both the load and
store side of the move.
6E7D MOVEZPTOZP3P Moves a block of data starting at one ZP RAM
location to a block starting at another ZP RAM
location. Source and destination addresses and
block length are all passed as embedded
parameters:

JSR MOVEZPTOZP3P ;Move ZP RAM


DB $C0,$80,$40 ;Source=$C0
;Dest=$80
;Size=$40
Note: Wraps from $FF to $00 on both the load
and store side of the move.
6EB7 ZPX_TO_RC1 Moves the byte in ZP pointed to by X to the
address pointed to by (RC1ADDRH:L). On exit,
the Z flag reflects the value of the byte that
was moved.
6EC1 MOVE_A_X_TO_RC1 Moves A bytes of data pointed to by X in ZP to
memory beginning at the address pointed to by
(RC1ADDRH:L). Note: Load side wraps from $FF
to $100
6ED9 MOVE_RC3_X_TO_RC1 Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
X in ZP to memory beginning at the address
pointed to by (RC1ADDRH:L). Note: Load side
wraps from $FF to $100
6EDF ZPX_TO_RC2 Moves the byte in ZP pointed to by X to the
address pointed to by (RC2ADDRH:L). On exit,
the Z flag reflects the value of the byte that
was moved.
6EE9 MOVE_A_X_TO_RC2 Moves A bytes of data pointed to by X in ZP to
memory beginning at the address pointed to by
(RC2ADDRH:L). Note: Load side wraps from $FF
to $100
6F0D MOVE_RC3_X_TO_RC2 Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
X in ZP to memory beginning at the address
pointed to by (RC2ADDRH:L). Note: Load side
wraps from $FF to $100
6F13 MOVE_RC1_TO_X Moves the byte stored in memory at the address
pointed to by (RC1ADDRH:L) to the ZP RAM
location pointed to by X
6F1D MOVE_A_RC1_TO_X Moves A bytes of data stored in memory starting
at the address pointed to by (RC1ADDRH:L) to
ZP RAM starting at the location pointed to by X.
Note: Wraps from $FF to $100
6F45 MVRCFROMRC1TOX Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
(RC1ADDRH:L) to ZP RAM starting at the location
pointed to by X. Note: Wraps from $FF to $100
6F4B MOVE_RC2_TO_X Moves the byte stored in memory at the address
pointed to by (RC2ADDRH:L) to the ZP RAM
location pointed to by X
6F52 MOVE_A_RC2_TO_X Moves A bytes of data stored in memory starting
at the address pointed to by (RC2ADDRH:L) to
ZP RAM starting at the location pointed to by X.
Note: Wraps from $FF to $100
6F83 MVRCFROMRC2TOX Moves the number of bytes of data specified by
the value stored at RC3ADDR and pointed to by
(RC2ADDRH:L) to ZP RAM starting at the location
pointed to by X. Note: Wraps from $FF to $100

Operations that compare blocks of memory:


6F8E CMPRC3ZPATOZPX Compares two blocks of data stored in ZP RAM,
one pointed to by A, the other pointed to by X,
whose size is specified by the value stored at
RC3ADDR. On exit, if the two blocks were
identical, the Z flag will be set.
6FB3 CMPZPTOZP3P Compares two blocks of data stored in ZP RAM.
Start addresses of the two blocks, as well as
the size of the blocks, are passed as embedded
parameters:

JSR CMPZPTOZP3P ;Compare blocks


DB $80,$C0,$40 ;1st block @ $80
;2nd block @ $C0
;Blocks are $40 bytes
On exit, BLO will be taken if the value of the
first non-equal byte of the 1st block was less
than the value of the first non-equal byte of
the 2nd block. BHI would indicate that the 1st
non-equal byte of the 1st block was larger then
the 1st non-equal byte of the 2nd block. A BEQ
will be taken if all bytes of both blocks match.
6FEF CMP_X_TO_RC1 Compares the value in memory pointed to by
(RC1ADDRH:L) with the value in ZP RAM pointed
to by X. On exit, BLO will be taken if the
value pointed to by (RC1ADDRH:L) is less than
the value pointed to by X. BHI would indicate
that the value pointed to by (RC1ADDRH:L) is
greater than the value pointed to by X.
7000 CMP_A_ZPX_TO_RC1 Compares A bytes of memory pointed to by X in ZP
to A bytes of memory pointed to by (RC1ADDRH:L).
On exit, BLO will be taken if the 1st non-equal
byte stored starting at X is less than the
1st non-equal byte stored starting at
(RC1ADDRH:L). BHI would indicate that the 1st
non-equal byte starting at X is greater than the
1st non-equal byte stored starting at
(RC1ADDRH:L)
701F TST_A_AT_X_FORZERO Checks to see if A bytes of RAM pointed to by X
are all zero. If so, BEQ will be taken on
exit. Note that 0 is not a valid value for X
on entry to this routine: It will cause a
false report that all bytes were 0.
7034 TST_A_RC1_FORZERO Checks to see if A bytes of memory pointed to
by (RC1ADDRH:L) are all zero. If so, BEQ will
be taken on exit. Note that if a value of 0 is
passed in A (to check 256 bytes) and the first
byte doesn't match, this routine will mistakenly
report that all bytes matched.
7050 TST_A_RC1_FORX Checks to see if A bytes of memory pointed to
by (RC1ADDRH:L) all equal X. If so, BEQ will
be taken on exit. Note that if a value of 0 is
passed in A (to check 256 bytes) and the first
byte doesn't match, this routine will mistakenly
report that all bytes matched.
70A3 TEST256FORX Tests 256 bytes of memory pointed to by
(RC1ADDRH:L) to see if they are all equal to the
value of X. If so, BEQ will be taken on exit,
if not, BNE will be taken. BLO and BHI indicate
that the value of X was less than or greater
than the first byte that did not equal X,
respectively.

Operations involving bit matrices:


7057 CLRMATRIXBIT_A Clears bit A of the bit matrix pointed to by X
in ZP. See section 11.2.4.4 for information on
the structure of bit matrices.
705D TOGMATRIXBIT_A Toggles bit A of the bit matrix pointed to by X
in ZP. See section 11.2.4.4 for information on
the structure of bit matrices.
7062 SETCLRMATRIXBIT_A Sets or clears bit A of the bit matrix pointed to
by X in ZP, depending on the state of the Z bit
in the processor status flags. If the Z bit is
set, this routine clears the bit in the bit
matrix, if the Z bit is clear, this routine sets
the bit in the bit matrix. See section 11.2.4.4
for information on the structure of bit
matrices.
7064 SETMATRIXBIT_A Sets bit A of the bit matrix pointed to by X
in ZP. See section 11.2.4.4 for information on
the structure of bit matrices.
706D TESTMATRIXBIT_A Tests the state of bit A of the bit matrix
pointed to by X in ZP. On exit, BEQ will be
taken if the bit was clear, otherwise, BNE will
be taken. See section 11.2.4.4 for information
on the structure of bit matrices.
7076 TESTROMMATRIXXA Tests the state of bit A of the bit matrix
in ROM or EEPROM pointed to by (RC1ADDRH:L). On
exit, BEQ will be taken if the bit was clear,
otherwise, BNE will be taken. See section
11.2.4.4 for information on the structure of bit
matrices.
708D FINDBITADDR Finds the address in ZP and bitmask for bit A of
the bit matrix pointed to by X. On exit, X
contains the ZP address of the byte containing
the bit we're interested in, and A contains the
bitmask required to isolate (AND), set (ORA), or
toggle (XOR) the bit. To clear the bit, use the
COMA instruction to invert the bitmask, then AND
the bitmask with the ZP RAM location.
Operations that byte- or bit- reverse RAM:
70B8 BYTEFLOPRAM Byte-flops (reverses the byte order of) A bytes
of ZP RAM pointed to by X. For example, if
RAM at $F0 contains $11 $22 $33 $44 $55 $66,
and BYTEFLOPRAM is called with a value of 6 in A
and a value of F0 in X, after BYTEFLOPRAM is
finished, $F0 would be altered such that it
contains $66 $55 $44 $33 $22 $11. Under the
same starting conditions, calling BYTEFLOPRAM
with values of 4 and F1 for A and X would
result in RAM at F0 being altered such that it
contains $11 $55 $44 $33 $22 $66.
70E2 BITBYTEFLOP_A_AT_X Byte-flops A bytes of ZP RAM pointed to by X
(see BYTEFLOPRAM, above), then bit-flops the
same data (see BITFLOP_A_AT_X, below).
70E4 BITFLOP_A_AT_X Bit-flops A bytes of ZP RAM pointed to by X.
The bit-flop operation reverses the order of
the bits in each byte of RAM so that an input
byte whose bits are numbered 76543210 will
result in an output byte whose bits are
rearranged as 01234567.

11.2.3.2- Database routines


The ROM3 code includes a series of routines related to the creation,
maintenance, location, and deletion of data items in the EEPROM data space.
These routines generally operate using RC1ADDRH:L as a pointer to EEPROM data,
and require embedded parameters after the JSR to them in order to pass the
required information. A short summary of these routines is below, followed by
a more detailed list which includes a description of the input and output
data for each, as well as the data structures they require for operation.

Summary
Addr Name Description
---- ------------------ --------------------------------------------------
45BF KILLDATAITEM Deletes the data item pointed to by RC1ADDRH:L
45DF SETDBUPDATEFLAG Indicates that a specific type of data in the
database has been updated and should therefore
be re-polled by the host device
45FD GETDATAITEM Finds a data item of a specific type, returns
some number of its data bytes in a ZP buffer
46E3 FINDNEXTACTIVE Advances RC1ADDRH:L to point to the next active
data item of a specified type
46FB GETMATCHINGITEM Finds a data item of a specific type, matching
any combination of the first 8 bytes with a
pattern stored in RAM
4740 CREATEDATAITEM Creates a data item of a specified type
4779 CREATEHEADER Creates a data item header
47A4 FINDABLOCK Finds a block of memory of a minimum specified
size in EEPROM
47C0 WRITEDATAAREA Writes data to the data area of a data item
4871 ACTIVATEITEM Activates a data item, marks its space as used
4B8B INITRC1TOEESTRT Initializes RC1ADDRH:L to point at the start of
EEPROM data space

Detail
Addr Name Description
---- ------------------ --------------------------------------------------
45BF KILLDATAITEM Deletes the data item pointed to by RC1ADDRH:L.
This routine programs the bits in the data item's
flags byte such that bit 3 (data item no longer
in use) is set. Setting this bit allows the
data space occupied by the data item to be
reclaimed so that new data can be stored there.

Entry: RC1ADDRH:L points to data item to be


deleted

Exit: Carry clear if data item deleted


Carry set if an error occurred

45DF SETDBUPDATEFLAG Indicates that a specific type of data in the


database has been updated and should therefore
be re-polled by the host device.
This routine sets bit 0 of the "CAM status flags
1" byte in the C0 resposne, informing the host
device that the database status command (C1)
should be sent. In addition, if, on entry, A
is non-zero, the bit corresponding to the data
type in A in the C1 response data will be set,
indicating the type of data that has changed.

Entry: A=Data type for which update is to be


indicated, or 0 if no specific data
type is to be flagged as modified

Exit: n/a

45FD GETDATAITEM Finds a data item of a specific type, returns


some number of its data bytes in a ZP buffer.
This routine searches for a data item in EEPROM
data space, and if it finds a matching item, it
can return data bytes starting at the beginning
of the item's data into a zero-page buffer.

Entry: RC1ADDRH:L=address at which to start


searching for data items. Usually
points either to the last item found,
or to some address below EEPROM data
space, which will cause the search to
begin at the start of EEPROM data space.
A=Data type to search for if embedded
parameter for data type is 0.

Embedded parameters:
PARM1: Data type to search for, or 0 to
use the data type in A. If both PARM1
and A are 0, this routine will match
the first active data item it finds.
PARM2: Destination of data in ZP RAM.
This is the first location where data
from the data item will be moved, if
PARM3 is non-zero. Note that the first
byte of data moved is the byte that
immediately follows the data type byte
in memory.
PARM3: Number of bytes to be retrieved
from data item. If this byte is zero,
no data is moved.
Exit: RC1ADDRH:L points to data item if found
Carry=clear if data item found
set if no matching data item found

46E3 FINDNEXTACTIVE Advances RC1ADDRH:L to point to the next active


data item of a specified type.
This routine begins a search forward in memory
from the location pointed to by RC1ADDRH:L for
an active data item. If a value other than 0
is stored at PARM1 ($57), then this routine will
only match data items with the specified type.

Entry: RC1ADDRH:L=address at which to start


searching for data items. Usually
points either to the last item found,
or to some address below EEPROM data
space, which will cause the search to
begin at the start of EEPROM data space.
PARM1=Data type to search for, or 0 to
match any.

Exit: RC1ADDRH:L points to data item if found


Carry=clear if data item found
set if no matching item found

46FB GETMATCHINGITEM Finds a data item of a specific type, matching


any combination of the first 8 bytes with a
pattern stored in RAM
This routine is similar to GETDATAITEM, except
that its search can be further refined by
requiring any combination of the first 8 bytes
of data in a candidate data item to match a
pattern of bytes in ZP RAM at $F8..$FF.

Entry: RC1ADDRH:L=address at which to start


searching for data items. Usually
points either to the last item found,
or to some address below EEPROM data
space, which will cause the search to
begin at the start of EEPROM data space.
A=Data type to search for if embedded
parameter for data type is 0.
$F8..$FF=Match criteria data for data
items. Byte to match with first byte
of data item stored at $F8, byte to
match with last byte of data item stored
at $FF.

Embedded parameters:
PARM1: Data type to search for, or 0 to
use the data type in A. If both PARM1
and A are 0, this routine will match
the first active data item it finds.
PARM2: Destination of data in ZP RAM.
This is the first location where data
from the data item will be moved, if
PARM3 is non-zero. Note that the first
byte of data moved is the byte that
immediately follows the data type byte
in memory.
PARM3: Number of bytes to be retrieved
from data item. If this byte is zero,
no data is moved.
PARM4: Compare mask. Each bit in this
byte is a flag indicating whether the
corresponding data byte and match byte
in the table below should be checked to
determine whether the correct data item
has been found.

Bit in PARM4 Data byte Match byte


------------ --------- ----------
7 1 $F8
6 2 $F9
5 3 $FA
4 4 $FB
3 5 $FC
2 6 $FD
1 7 $FE
0 8 $FF

Note that data byte 1 is the data byte


immediately following the data type byte
in memory.

Exit: RC1ADDRH:L points to data item if found


Carry=clear if data item found
set if no matching data item found

4740 CREATEDATAITEM Creates a data item of a specified type.


This routine finds space for a data item of the
specified type, clears the block of space that
it finds, creates a data item header, and writes
the data type byte into the data item. It does
not activate the data item, however, so after
calling CREATEDATAITEM to create the item and
its header, it's necessary to call ACTIVATEITEM
to mark the data as "in use". Generally, this
is only done after all of the initial data for
the data item has been written to EEPROM. This
allows the data space to be reclaimed if some
catastrophe befalls the card while the data is
being written, as well as preventing the card
from treating a half-created data item as valid
data.

Entry: A=Length of data item to create if


PARM1 does not indicate a data type
whose length is fixed (types $01..$0E
are fixed-length types).

Embedded parameters:
PARM1: Data type to create. Note that
it is necessary to specify a data item
type to create.

Exit: RC1ADDRH:L points to new data item if


one was created
Carry=clear if data item created
set if error occurred
$111:$112 points to first EEPROM data
location past newly-created data item

4779 CREATEHEADER Creates a data item header.


This routine creates a data item header in EEPROM,
starting at the address pointed to by RC1ADDRH:L.
The header created by this routine will have
a flags byte indicating that the header is
valid, but it will not indicate that the data
is active. To set that bit, it is necessary
to call the ACTIVATEITEM routine. Note that
generally, there is no reason to call this
routine by itself: CREATEDATAITEM will call
CREATEHEADER to create the data item's header.

Entry: RC1ADDRH:L=Address in EEPROM where data


item is to be created.
$110 = Length of data item to place in
the header
PARM1=Data type to place in header

Exit: Carry=clear if header created


set if error occurred
$111:$112 points to first EEPROM data
location past newly-created data item

47A4 FINDABLOCK Finds a block of memory of a minimum specified


size in EEPROM.
This routine finds a block of free memory in
EEPROM data space whose minimum size was
specified by the calling routine.

Entry: A=Length of block to find if PARM1 is 0

Embedded parameters:
PARM1: Length of block to find, or 0 if
length is to be passed in A.

Exit: Carry=clear if header created


set if error occurred
$100:$101 points to the first address
of the data block if found

47C0 WRITEDATAAREA Writes data to the data area of a data item.


This routine writes data to an existing data item.
If the data item being written was marked as "in
use" prior to the write, a copy of the data is
first created, along with a pointer to where the
data should be written in EEPROM (a pointer to
the data item being written), so that if some
catastrophe happens while data is being updated,
recovery is possible.

Entry: RC1ADDRH:L points to flags byte in header


of data item to be updated

Embedded parameters:
PARM1: Address in ZP RAM where data to
be written to EEPROM begins
PARM2: Offset from RC1ADDRH:L where data
is to be written to EEPROM
PARM3: Number of bytes of data to write
Exit: Carry=clear if data written
set if error occurred

4871 ACTIVATEITEM Activates a data item, marks its space as used.


This routine sets the "data item in use" bit in
a the flags byte of a data item's header. This
routine should be called to activate a newly-
created data item only after all of the initial
data is written to the item.

Entry: RC1ADDRH:L points to flags byte in header


of data item to be activated

Exit: Carry=clear if data written


set if error occurred

4B8B INITRC1TOEESTRT Initializes RC1ADDRH:L to point at the start of


EEPROM data space.
This routine initializes the data pointer at
RC1ADDRH:L to point at the first byte of data
space in EEPROM.

Entry: Pointer to EEPROM data spaced stored at


$E030:$E031

Exit: RC1ADDRH:L points to 1st byte of EEPROM


data space

11.2.3.3- Low-level routines


In addition to the utility function library and the database functions, an
attacker wanting to write code for NagraVision cards can also make use of a
variety of low-level routines to accomplish his task. Many functions are
available, including ones to write data to EEPROM, move data from place in
EEPROM (or, for that matter, ROM) to another, perform delays, output blocks
of data, and so on. These routines will be listed here in no particular
order, and since the routines are not all related in some way, no summary will
be presented.

Addr Name Description


---- ------------------ --------------------------------------------------
7803 WRITEATOEEFROMX Writes data to EEPROM

Entry: A=# of bytes to write to EEPROM


X=1st ZP RAM location where data to write
is stored
RC1ADDRH:L=destination address in EEPROM
EEWRITEOKBITS=$96

Exit: Carry=clear if write succeeded


set if not
EEWRITEOKBITS=$4B

Example:
JSR GET2PARMSTORC1 ;Get destination address
DW $E050 ;Destination addr=$E050
LDA #$10 ;16 bytes to write
LDX #$80 ;Data to write at $80..$8F
ASL EEWRITEOKBITS ;Enable writes
JSR WRITEATOEEFROMX ;Write the data

Note that EEWRITEOKBITS must be set up properly


in order for the write to occur. The card
initializes EEWRITEOKBITS to $4B, so the ASL
instruction will make the value $96. Before
WRITEATOEEFROMX exits, it will perform an LSR
instruction on EEWRITEOKBITS, forcing the value
back to $4B, so each call to WRITEATOEEFROMX
must be preceded by an ASL EEWRITEOKBITS.

7A0B MOVEEETOEE Moves a block of data from anywhere in memory


to EEPROM at a specified address. This routine
can be used to move a block of memory from one
place in EEPROM to another, and the source block
and destination block may overlap, as long as the
source block's start address is higher than the
destination block's.

Entry: A=# bytes to move


RC1ADDRH:L=destination address in EEPROM
RC2ADDRH:L=source address
EEWRITEOKBITS=$96

Exit: Carry=clear if write succeeded


set if not
EEWRITEOKBITS=$4B

Example:
JSR GET2PARMSTORC1 ;Get destination address
DW $E020 ;Destination addr=$E050
JSR GET2PARMSTORC2 ;Get source address
DW $7AFC ;Source addr=$7AFC
LDA #$10 ;16 bytes to move
ASL WRITEEEOKBITS ;Enable writes
JSR WRITEEETOEE ;Move the data

75AE RESPOND Finish building a standard response and send it.

Entry: Response data stored starting at IOBUFF+2


if response data is present
SW1=SW1 byte for response
SW2=SW2 byte for response

Embedded parameters:
PARM1: Response header byte (P1)
PARM2: Response data length (P2)

Format of output:
12 PCB ELEN P1 P2 <DATA0..DATAN> SW1 SW2 LRC

Notes:
MLEN is usually equal to P2+4, unless P2
exceeds the maximum IFS. In this case,
MLEN will equal the maximum IFS, and the output
will be chained. For details concerning the
chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

N's maximum value is the size of the info field.


For ROM3 cards, it defaults to $20 bytes, but
EchoStar IRDs request that the card change it's
IFS to $58 as part of the initialization
process. The maximum size to which the IFS can
be set on ROM3 cards is $64. If the number of
bytes to be dumped exceeds the IFS, then the
output will be chained. For details concerning
the chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

7A35 DOBLOCKOUT1 Outputs a raw block of data from memory as the


information field of a response message. No
superfluous data other than the header, SW1/SW2,
and LRC are added to the data. The length byte
for the header is computed as the data to be
output is moved into the output buffer.

Entry: RC1ADDRH:L=1st address to dump


RC2ADDRH:L=Last address to dump+1

Format of output:
12 PCB LEN <DATA0..DATAN> SW1 SW2 LRC

Notes:
N's maximum value is the size of the info field.
For ROM3 cards, it defaults to $20 bytes, but
EchoStar IRDs request that the card change it's
IFS to $58 as part of the initialization
process. The maximum size to which the IFS can
be set on ROM3 cards is $64. If the number of
bytes to be dumped exceeds the IFS, then the
output will be chained. For details concerning
the chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

7A3B CMD21RESPSETUP Outputs a block of data from memory as though it


was a response to a $21 command. A response
header and length byte are prepended to the
block of data, and SW1/SW2 and the LRC will be
appended.

Entry: RC1ADDRH:L=1st address to output


RC3RTS=# bytes to send

Format of output:
12 PCB MLEN 21 LEN <DATA0..DATAN> SW1 SW2 LRC

Notes:
MLEN is usually equal to LEN+4, unless LEN
exceeds the maximum IFS. In this case,
MLEN will equal the maximum IFS, and the output
will be chained. For details concerning the
chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

N's maximum value is the size of the info field.


For ROM3 cards, it defaults to $20 bytes, but
EchoStar IRDs request that the card change it's
IFS to $58 as part of the initialization
process. The maximum size to which the IFS can
be set on ROM3 cards is $64. If the number of
bytes to be dumped exceeds the IFS, then the
output will be chained. For details concerning
the chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

7A41 SENDBUILT Outputs a response message which was manually


built starting at IOBUFF. It assumes that SW1/SW2
have been included as part of the pre-built
message.

Entry: Message to send stored at IOBUFF


A=Total # bytes in message, including
SW1/SW2, but not including the standard
header and LRC

Format of output:
12 PCB MLEN <DATA0..DATAN> LRC

Notes:
MLEN is usually equal to LEN+4, unless LEN
exceeds the maximum IFS. In this case,
MLEN will equal the maximum IFS, and the output
will be chained. For details concerning the
chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

N's maximum value is the size of the info field.


For ROM3 cards, it defaults to $20 bytes, but
EchoStar IRDs request that the card change it's
IFS to $58 as part of the initialization
process. The maximum size to which the IFS can
be set on ROM3 cards is $64. If the number of
bytes to be dumped exceeds the IFS, then the
output will be chained. For details concerning
the chaining of output data, see section 5.2.3,
which covers the "dump memory" backdoor command.

In most cases, DATAN-1 will be SW1, DATAN will


be SW2, DATA0 will be a response header byte,
and DATA1 will be a response data length byte.

In general, the format of IOBUFF will be as


follows:

Addr Description
---------- ----------------------------------
IOBUFF Response header byte
IOBUFF+1 Response data length byte (N)
IOBUFF+2 1st data byte (if present)
IOBUFF+1+N last data byte (if present)
IOBUFF+2+N SW1
IOBUFF+3+N SW2

xxxx DELAYnn Delay 14+2*N cycles, where N is 0..17. The


address for the routine is $4E78-N. The delay is
performed with NOPs, and so has a resolution of
2 cycles. In addition, the cycles taken by the
JSR to get to DELAYnn as well as the RTS to get
back have been included in the number of cycles
delayed. To achieve a single cycle of additional
delay, it is only necessary to follow (or precede)
the JSR to DELAYnn with a SEC or CLC instruction,
which takes only 1 cycle to execute on the 16CF54.

4E7A DELAY11 Delay 11 cycles.

4E50 FINEDELAY Delay 44 to 65580 cycles. This figure includes


the cycles taken by the JSR to get to FINEDELAY,
as well as the RTS to get back.

Entry: X:A=# cycles to delay

Notes:
Minimum value for X:A on entry is $002C (44
decimal). Entering with a value less than
$002C will result in a delay of $10000+X:A
cycles.

4E26 DELAYAMINUS33 Delay 33..289 cycles. This figure includes the


cycles taken by the JSR to get to DELAYAMINUS33,
as well as the RTS to get back.

Entry: A=# cycles to delay

Notes:
Minimum value of A on entry is $21 (33 decimal).
Entering with a value less than $21 will result
in a delay of $100+A cycles.

11.2.3.4- Encryption/decryption routines


When adding backdoor commands to the card (or when intercepting $03 commands
or other information that's DES encrypted), a hacker may wish to use the DES
encrypt or decrypt routines that are included in the NagraVision cards. The
basic DES routines will be listed here, both in summary form and detailed
form, along with examples of how to call the more useful routines.
Note that DES is a symmetric algorithm, so encryption and decryption are
subjective. In actuality,if a block of data B is DES decrypted using key K,
producing 'decrypted' block D, the original data B can be recovered by DES
encrypting D using key K. Similarly, if a block of data B is DES encrypted
using key K, producing encrypted block E, the original data B can be recovered
by DES decrypting E using key K. For further information about the DES
encryption/decryption algorithm, see section 8.1: ECM encryption.

DES encrypt/decrypt summary

Addr Name Description


---- ------------------ --------------------------------------------------
4EA2 PREPKEY Prepares a raw DES key for use
4EA8 PREPFLOPPEDKEY Prepares a byte-reversed DES key for use
4EB6 BYTEFLOPBITFLOP Byte-reverses and bit-flops a block of DES data
4EBF DESDECRYPT Performs DES decryption of a block of data using
a prepared key
4EC9 DESDECRYPFLOPPED Performs DES decryption of a block of byte-
reversed data using a prepared key
4ED0 DESDECFLOPPED Performs DES decryption of a block of byte-
reversed data using a raw byte-reversed key
5331 DESENCRYPTRAW Performs DES encryption of a block of data using
a raw key
5334 DESENCRYPTPREP Performs DES encryption of a block of data using
a prepared key
7DF2 COMPUTESIG Performs chained DES encryption of a block of data
to compute the message's signature

Notes: Data to be encrypted/decrypted always stored at $E8..$EF


Raw key for encryption / preparation always stored at $F0..$F7
Prepared keys for encryption / decryption always stored at $F0..$F6

DES encrypt/decrypt detail

Addr Name Description


---- ------------------ --------------------------------------------------
4EA2 PREPKEY Prepares a raw DES key for use. This routine will
transform a raw DES key stored at $F0..$F7 into a
prepared (parity-stripped and compressed) key at
$F0..$F6.

Entry: Raw key stored at $F0..$F7

Exit: Prepared key stored at $F0..$F6

Notes:
It is generally necessary to call this routine
prior to performing DES decryption, unless the
key that has been stored at $F0..$F6 is already
parity-stripped, bit-reversed, and compressed.

4EA8 PREPFLOPPEDKEY Prepares a byte-reversed DES key for use. This


routine will transform a byte-reversed DES key
stored at $F0..$F7 into a prepared (parity-
stripped and compressed) key at $F0..$F6. It does
so by first byte-reversing the raw data at
$F0..$F7, then performing the parity removal and
compression.

Entry: Raw key stored, byte-reversed, at $F0..$F7

Exit: Prepared key stored at $F0..$F6

4EB6 BYTEFLOPBITFLOP Byte-reverses and bit-flops a block of DES data.


This routine byte-reverses, then bit-flops the 8
bytes of data at $E8..$EF

Entry: Data to be reversed stored at $E8..$EF

Exit: Reversed data stored at $E8..$EF

4EBF DESDECRYPT Performs DES decryption of a block of data using


a prepared key. This is the "standard" entry
point for DES decrypting a block of data.

Entry: Data to be decrypted stored at $E8..$EF


Prepared key stored at $F0..$F6

Exit: Decrypted data stored at $E8..$EF


Key unaltered

4EC9 DESDECRYPFLOPPED Performs DES decryption of a block of byte-


reversed data using a prepared key. This routine
would be called if the data to be decrypted is
byte-reversed.
Entry: Data to be decrypted stored at $E8..$EF
Prepared key stored at $F0..$F6

Exit: Decrypted data stored at $E8..$EF


Key unaltered

4ED0 DESDECFLOPPED Performs DES decryption of a block of byte-


reversed data using a raw byte-reversed key. This
routine would be called if both the data to be
decrypted and the raw key are byte-reversed. It
will first prepare the byte-reversed key, then
decrypt the data using DESDECRYPFLOPPED.

Entry: Data to be decrypted stored at $E8..$EF


Raw key stored at $F0..$F7

Exit: Decrypted data stored at $E8..$EF


Prepared key stored at $F0..$F6

Notes:
When decrypting a block of data using this
routine, only the first block should be
decrypted using DESDECFLOPPED. Subsequent
calls should be to DESDECRYPFLOPPED, since
DESDECFLOPPED will alter the key data, so
further calls to DESDECFLOPPED will result in
a mutation of the key data with each block of
decryption (which may or may not be desirable).

5331 DESENCRYPTRAW Performs DES encryption of a block of data using


a raw key. This routine first prepares the raw
DES key, then uses the prepared key to encrypt
a block of data.

Entry: Data to be encrypted stored at $E8..$EF


Raw key stored at $F0..$F7

Exit: Encrypted data stored at $E8..$EF


Prepared key stored at $F0..$F6

Notes:
When encrypting a block of data using this
routine, only the first block should be
encrypted using DESENCRYPTRAW. Subsequent
calls should be to DESENCRYPTPREPPED, since
DESENCRYPTRAW will alter the key data, so
further calls to DESENCRYPTRAW will result in
a mutation of the key data with each block of
encryption (which may or may not be desirable).
This function's primary use is in performing
chained DES encryption for the purpose of
computing a message's signature.

5334 DESENCRYPTPREP Performs DES encryption of a block of data using


a prepared key. This is the "standard" entry
point for DES encrypting a block of data.

Entry: Data to be encrypted stored at $E8..$EF


Prepared key stored at $F0..$F7
Exit: Encrypted data stored at $E8..$EF
Key unaltered

7DF2 COMPUTESIG Performs chained DES encryption of a block of data


to compute the message's signature. This routine
is generally used to compute the signature of a
message. This signature is often referred to as
the "valid hash". The block of data for which a
signature is to be produced must be a multiple of
8 bytes in length, since COMPUTESIG takes as its
input a value which indicates the length of the
data in 8-byte blocks.

Entry: RC1ADDRH:L points to the block of data


for which the signature is to be computed
RC2ADDRH:L points to key to use for
encryption of 1st block of data
A=# 8-byte blocks in the data for which
the signature is to be computed

Exit: Signature stored at $F0..$F7

Notes:
In actuality, what this routine is doing is
performing chained DES encryption. It could
be used either to encrypt data which is
decrypted using chained decryption, or to
decrypt data which was encrypted using chained
decryption.

DES encrypt/decrypt code examples:

DES decryption of a block of data:

;
; Entry: DES key stored at RAWDESKEY
; Data to be decrypted stored starting at $80 (up to $58 bytes)
; A=# 8-byte blocks to decrypt
;
; Exit: Encrypted data replaced with decrypted data
;
; Notes: Uses $DE as loop counter for # blocks to decrypt because that's
; the location the $03 decrypt routine uses.
;
DECRYPTBLOCK:
STA $DE ;Save # blocks to decrypt

LDX #$07 ;8 bytes in key


MVRAWKEYLP:
LDA RAWDESKEY,X ;Get a byte of the key
STA $F0,X ;Move it to ZP
DECX ;One less byte to move
BPL MVRAWKEYLP ;Loop if more bytes to move

JSR PREPKEY ;Prepare the key

JSR GET2PARMSTORC1 ;Point RC1 at data to decrypt


DW $0080 ;Data stored starting at $80

LDX #$E8 ;Move encrypted data to E8


LDA #$08 ;8 bytes to move
;Note that we can put the loop point
; after these instructions, since A and X
; will always be 08 and E8, respectively,
; when we get back from ADDATORC1, below.
DCRYPLP:
JSR MOVE_A_RC1_TO_X ;Move a block of encrypted data

JSR DESDECRYPT ;Decrypt it

LDX #$E8 ;Move decrypted data from E8


LDA #$08 ;8 bytes to move
JSR MOVE_A_X_TO_RC1 ;Move a block of decrypted data

JSR ADDATORC1 ;Point to next block

DEC $DE ;One less block to move


BNE DCRYPLP ;Loop if more blocks

RTS ;And exit


;
; Raw DES key stored here
;
RAWDESKEY:
DB $01,$02,$03,$04,$05,$06,$07,$08
;
; Total: 45 bytes of code, 8 bytes of data for key
;

DES encryption of a block of data:

;
; Entry: DES key stored at RAWDESKEY
; Data to be encrypted stored starting at $80 (up to $58 bytes)
; A=# 8-byte blocks to encrypt
;
; Exit: Decrypted data replaced with encrypted data
;
; Notes: Uses $DE as loop counter for # blocks to encrypt because that's
; the location the $03 decrypt routine uses.
;
ENCRYPTBLOCK:
STA $DE ;Save # blocks to encrypt

LDX #$07 ;8 bytes in key


MVRAWKEYLP:
LDA RAWDESKEY,X ;Get a byte of the key
STA $F0,X ;Move it to ZP
DECX ;One less byte to move
BPL MVRAWKEYLP ;Loop if more bytes to move

JSR PREPKEY ;Prepare the key

JSR GET2PARMSTORC1 ;Point RC1 at data to encrypt


DW $0080 ;Data stored starting at $80

LDX #$E8 ;Move decrypted data to E8


LDA #$08 ;8 bytes to move
;Note that we can put the loop point
; after these instructions, since A and X
; will always be 08 and E8, respectively,
; when we get back from ADDATORC1, below.
NCRYPLP:
JSR MOVE_A_RC1_TO_X ;Move a block of decrypted data

JSR DESENCRYPPREP ;Encrypt it

LDX #$E8 ;Move encrypted data from E8


LDA #$08 ;8 bytes to move
JSR MOVE_A_X_TO_RC1 ;Move a block of encrypted data

JSR ADDATORC1 ;Point to next block

DEC $DE ;One less block to move


BNE NCRYPLP ;Loop if more blocks

RTS ;And exit


;
; Raw DES key stored here
;
RAWDESKEY:
DB $01,$02,$03,$04,$05,$06,$07,$08
;
; Total: 45 bytes of code, 8 bytes of data for key
;
; Note: If the code for DECRYPTBLOCK is also present, the code to move the
; DES key to the DES key buffer can be reused, resulting in a savings
; of 9 bytes.
;

Signature check for a block of cleartext data:


;
; Entry: Data for which signature to be computed stored starting at
; $80 (up to $50 bytes)
; A=# 8-byte blocks for which to compute signature
; Correct signature stored at $D0..$D7
;
; Exit: BEQ will be taken if signature matches
; BNE will be taken if signature is in error
;
; Notes: Uses $DE as loop counter for # blocks to encrypt because that's
; the location the $03 decrypt routine uses.
;
CHECKSIG:

JSR GET2PARMSTORC1 ;Point RC1 at data to compute signature on


DW $0080 ;Address of data for which signature is to
; be computed

JSR GET2PARMSTORC2 ;Point RC2 at initial signature key


DW SIGKEY ;Address of initial signature key

JSR COMPUTESIG ;Compute the signature of the data

JSR CMPZPTOZP3P ;Check the computed signature against the


; known good signature
DB $D0 ;Known good signature at $D0..$D7
DB $F0 ;Computed signature at $F0..$F7
DB $08 ;8 bytes in signature

RTS ;And return. Note that we can't just do


; a JMP to CMPZPTOZP3P, because it expects
; 3 embedded parameters. We could get
; around this by putting the 3 embedded
; parameters after the JSR to CHECKSIG,
; but that would be confusing, and we'd
; only end up saving one byte.
;
; Raw DES key stored here
;
SIGKEY:
DB $01,$02,$03,$04,$05,$06,$07,$08
;
; Total: 20 bytes of code, 8 bytes of data for key
;

11.2.4- Memory usage


The MCU in the ROM3 NagraVision smart cards has a total of 512 bytes of RAM
available to the user. Of this RAM, 64 bytes are usable by the stack
($40..$7F), 32 bytes are "low" general purpose zero-page RAM ($20..$3F),
128 bytes are "high" general purpose zero-page RAM ($80..$FF), and 288 bytes
are general purpose RAM ($100..$21F). Descriptions of important variables and
buffers in each of the RAM areas are below.
In addition, there are several data tables in ROM and EEPROM that an
attacker might find useful. Those will be detailed below as well.

11.2.4.1- ZP RAM
Zero-page (or, as Motorola and most other manufacturers of 6805-based
microcontrollers call it, direct page) RAM is a prime resource in the
NagraVision smart card. This is because there are certain instructions that
only work on zero-page RAM locations (like BSET, BCLR, and so on), because
instructions that access zero-page RAM take fewer bytes of code space than
instructions that access non-zero-page RAM, and because instructions that
access zero-page RAM execute more quickly than instructions that access
non-zero-page RAM (because they save the CPU cycle that would otherwise be
taken to fetch the high byte of the operand address). As a result, usage
of zero-page RAM is generally pretty carefully thought out in large programs
for 6805s or 6805-based MCUs (like the 16CF54A). In this section, details
concerning important zero-page RAM variables for ROM3 cards can be found.
Unless otherwise noted, it's not safe to store volatile information in any
of these RAM locations, since lots of routines in the card use them in one
way or another, and it's very difficult to keep track of which ones are safe
and which ones aren't. When in doubt, just use the RAM the same way the code
in the card would.

Addr Name Description


---- ------------------ --------------------------------------------------
0024 RC1ADDRH RAM code 1 operand high byte. Generally used as
a pointer to data with which work is being done,
or a pointer to EEPROM data.
0025 RC1ADDRL RAM code 1 operand low byte. Generally used as
a pointer to data with which work is being done,
or a pointer to EEPROM data.
0028 RC2ADDRH RAM code 2 operand high byte. Generally used as
a pointer to data with which work is being done,
or a pointer to EEPROM data.
0029 RC2ADDRL RAM code 2 operand low byte. Generally used as
a pointer to data with which work is being done,
or a pointer to EEPROM data.
002B RC3ADDR RAM code 3 operand. Sometimes used as a count
byte for loops in some ROM subroutines.
0030 FLAGS0 Miscellaneous flags:
Bit 0=Inverse data convention (1=yes)
Bit 1=
Bit 2=Parity error on received data
Bit 3=Chain bit was set
Bit 4=Message ready for processing
Bit 5=Message sequence flag to use
for next response
Bit 6=Message sequence flag expected
for next message
Bit 7=Receiving T=1 header (1=yes)
0031 FLAGS1 More misc. flags:
Bit 0=Receiving information field (1=yes)
Bit 1=Next received byte will be LRC
Bit 2=EEPROM erase in progress
Bit 3=EEPROM erase error occurred
Bit 4=EEPROM write in progress
Bit 5=EEPROM write error occurred
Bit 6=
Bit 7=
0032 FLAGS2 More misc. flags:
Bit 0=About to initiate EEPROM write/erase
Bit 1=Writing to EEPROM (1) or Erasing EEPROM (0)
Bit 2=Setting up for EMM decrypt
Bit 3=Interpreting an EMM/ECM
Bit 4=Decrypting an EMM/ECM
Bit 5=Callback data ready
Bit 6=
Bit 7=
0033 FLAGS3 More misc. flags:
Bit 0=EEPROM erase/write unnecessary
Bit 1=Valid message received (at least, a message
whose LRC computed OK)
Bit 2=MAP operation was interrupted
Bit 3=At least one EEPROM write/erase completed
(though data may not have actually been
changed...this flag simply indicates that
the operation made it all the way through
without interruption at least once)
Bit 4=EEPROM write/erase was interrupted
Bit 5=EEPROM data item links need to be validated
Bit 6=EEPROM cleanup has been done by Rev372
bug-catcher $29
Bit 7=
0034 NAD NAD for received messages stored here
0035 PCB PCB for received messages stored here
0036 LEN LEN for received messages stored here
0038 LRC LRC for received messages stored here
0039 IFS Current info field size limit stored here
0042 BITDLYHI High byte of bit rate in # cycles stored here
0043 BITDLYLO Low byte of bit rate in # cycles stored here
0044 BYTEGUARD Byte guard time stored here. Delay is
3+10*BYTEGUARD cycles
0045 CWT Character wait time (max dead time between
consecutive received characters) stored here
0046 SERBYTE Serial byte just received/serial byte to transmit
0047 NUMBITS # bits to send stored here
0049 STATS1 CAM status flags byte 1:
Bit 0=Database has been updated
(CAM suggests $C1 command)
Bit 1=CAM has been reset
Bit 2=Memory full (CAM suggests $31 command)
Bit 3=Credit low (CAM suggests $30 command)
Bit 4=
Bit 5=
Bit 6=
Bit 7=
004A STATS2 CAM status flags byte 2:
Bit 0=CAM requests MECM data
(CAM suggests $02 command)
Bit 1=EMM being processed
Bit 2=EMM processing complete
Bit 3=Callback req being processed
(Command $30 in progress)
Bit 4=Callback req processing done
(CAM suggests command $31)
Bit 5=IRD command waiting
(CAM suggests command $60)
Bit 6
Bit 7
004B STATS3 CAM status flags byte 3:
Bit 0=ECM being processed (Cmd $03 in progress)
Bit 1=Even control word ready
Bit 2=Odd control word ready
Bit 3
Bit 4
Bit 5=MECM being processed (Cmd $02 in progress)
Bit 6=MECM decrypt complete (Cmd $02 finished)
Bit 7=MECM decrypt failed (Cmd $02 failed)
004C DBFLAGSH Data items have changed flags high
Bit 0: Data type $09 has changed
Bit 1: Data type $0A has changed
Bit 2: Data type $0B has changed
Bit 3: Data type $0C has changed
Bit 4:
Bit 5:
Bit 6: Data type $11 has changed
Bit 7: Data type $10 has changed
004D DBFLAGSL Data items have changed flags low
Bit 0: Data type $08 has changed
Bit 1: Data type $07 has changed
Bit 2: Data type $06 has changed
Bit 3: Data type $05 has changed
Bit 4: Data type $04 has changed
Bit 5: Data type $03 has changed
Bit 6: Data type $02 has changed
Bit 7: Data type $01 has changed
004E EEWRITEOKBITS The contents of this RAM location must be $96 in
order for the EEPROM write routines to actually
attempt to write to EEPROM. If an EEPROM write
or erase routine is called and this location does
NOT contain $96, a security violation will occur,
and the card will hang in an infinite loop.
004F EEWRITEDELAYFAC EEPROM erase/write delay factor in usec
0050 SW1 SW1 stored here in preparation for calling RESPOND
0051 SW2 SW2 stored here in preparation for calling RESPOND
0057 PARM1 Embedded parameter 1 moved here by GET4PARMS
0058 PARM2 Embedded parameter 2 moved here by GET4PARMS
0059 PARM3 Embedded parameter 3 moved here by GET4PARMS
005A PARM4 Embedded parameter 4 moved here by GET4PARMS
Note: Although GET4PARMS always moves 4 bytes to
RAM starting at PARM1, not all routines
that call GET4PARMS expect 4 embedded
parameters. For routines that expect
less than 4 embedded parameters, the
PARMx bytes corresponding to embedded
parameters that were not expected will
actually contain copies of the opcodes
of the instructions that followed the
embedded parameters that WERE present,
and, in some cases, their operands.
005F STACKRIM Lowest address usable by the stack before the
stack starts to overwrite variables
007F STACKBASE Highest address usable by the stack
0080 EMMBUFF General-purpose 64-byte buffer. Lots of routines
: use this area. In particular, messages to be
00BF decrypted or encrypted (EMMs, ECMs, and callback
data) are stored here, decrypted EMMs and ECMs
are stored and interpreted from here, and
message signatures are calculated on data stored
here.
00C0 misc General-purpose variable storage area. Lots of
: routines use this area. One of the more common
00E7 uses for this area is as a buffer for EEPROM
data (both returned from EEPROM data searches,
as well as to be written to EEPROM data items).
Of particular note in this area is that location
$DE is used by the card as a block loop counter
when DES decrypting or encrypting a block of
data, or when computing a signature.
00E8 DESDATA DES data block. Data to be encrypted or decrypted
: using the card's DES en/decrypt routines is
00EF stored here. In general, the de/encrypted data
replaces the en/decrypted data.
00F0 DESKEY DES key area. The key to use for DES encryption/
: decryption is stored here. Note that some of the
00F7 DES en/decrypt routines perform a preparation
step on the key which alters the data in this
buffer, but others do not.
00F8 MATCHBYTES Bytes to match in GETMATCHINGITEM are stored here.
: Up to 8 bytes, in any combination, at the
00FF beginning of a data item can be stored here and
compared against to ensure that GETMATCHINGITEM
has found the correct data item. The combination
of bytes that is checked depends on one of the
embedded parameters for GETMATCHINGITEM. For
further details on this, see section 11.2.3.2,
above.

11.2.4.2- Other RAM


Besides zero-page RAM, the 16CF54A has 288 bytes of other general-purpose
RAM available to the user. In this section, details concerning some of the
more interesting variables stored in this RAM will be provided.

Addr Name Description


---- ------------------ --------------------------------------------------
0180 CMDSEQNUM Command sequence number returned by command 00,
01, 02, 03, 13, 30, and 31 stored here. The
value of this byte might be useful for deciding
when to trigger a routine to mutate 3M code.
018B MECMINDEX Index byte for MECM data stored here.
018C MECMKEYBLOCK 16-byte MECM key block stored here.
For details concerning the MECM index and MECM
key block, see section 2.3.3.
019C IOBUFF Info field I/O buffer. The info field for
: incoming messages as well as outgoing messages
01FF stored here. The maximum length of the info
field that the card will accept is $64 bytes,
but in theory, the info field could stretch
all the way to $21F.
The first byte following the standard header
is stored at IOBUFF, as follows:

Incoming message example:


21 00 08 A0 CA 00 00 02 C0 00 06 87

Addr Value
--------- --------------------------
NAD 21
PCB 00
LEN 08
IOBUFF A0
IOBUFF+1 CA
IOBUFF+2 00
IOBUFF+3 00
IOBUFF+4 02
IOBUFF+5 C0
IOBUFF+6 00
IOBUFF+7 06
LRC 87

Outgoing message example:


12 00 08 B0 04 08 03 00 00 90 00 35

Addr Value
--------- --------------------------
NAD 12
PCB 00
LEN 08
IOBUFF B0
IOBUFF+1 04
IOBUFF+2 08
IOBUFF+3 03
IOBUFF+4 00
IOBUFF+5 00
IOBUFF+6 90 (also could be at SW1)
IOBUFF+7 00 (also could be at SW2)
LRC 35

11.2.4.3- Tables in ROM and EEPROM


Finally, as with most microcontroller-based applications, the NagraVision
firmware has certain needs for static data (which is stored in the ROM area
of the card), as well as needs for system data that may change from time to
time (which is stored in the EEPROM area of the card). This section details
the more useful ROM data tables and EEPROM data areas that are not handled by
the card's database routines.
Addr Name Description
---- ------------------ --------------------------------------------------
4221 CMDC0 This 8-byte table contains the exact sequence
of bytes that a host would send for command
$C0. It is used to allow an incoming message
to be checked to see if it's command $C0 prior
to performing any complex processing, since
command $C0 is the only command that's allowed to
happen while EMM decrypt/interpret and ECM
decrypt/interpret are happening. This is because
command $C0 is the "check status" command, and
having the card abort processing of an EMM or ECM
simply because the host wanted to see if it was
finished would be counter-productive.
43FD ARE This 11-byte table is where the fixed data for
the card's ATR is stored.
4408 ROMVERSION This 9-byte ASCII text string is sent as part of
the ATR, and it identifies the ROM version of
the card (in the case of ROM3, cards, this text
is 'DNASP003 '). See also REVLEVEL, below.
4A2F DAYSL This 16-byte table holds the low bytes of the
number of days that have passed when the first
day of each month of the year is the current
date. Note that this table is zero-based, so
using an index of 1 gets the data for January,
an index of 2 gets the data for February, and
so on. Also note that this table says that
February has 29 days in it (getting the value
for March indicates that 60 days have passed),
so for years that are not leap years, figures
for months>2 must be reduced by 1.
4A3F DAYSF This 16-byte table holds the high bytes of the
number of days that have passed when the first
day of each month of the year is the current
date. Note that this table is zero-based, so
using an index of 1 gets the data for January,
an index of 2 gets the data for February, and
so on. Also note that this table says that
February has 29 days in it (getting the value
for March indicates that 60 days have passed),
so for years that are not leap years, figures
for months>2 must be reduced by 1.
55DC SBOXES This 256-byte table holds the S-boxes used by
the card's DES encrypt and decrypt routines.
70FD ORMASK This 8-byte table holds the values required
to individually set each bit of a byte. ORing
a byte with the value of entry 0 of this table
will set bit 0 of that byte, and so on. This
data can also be used to create an AND mask which
can be used to clear any individual bit an a byte
by XORing the value extracted from this table
with $FF, and ANDing the result with the byte
whose bit is to be cleared.
7105 BITFLOP This 256-byte table holds the bit-flopped values
of every possible value from 0 to FF.
7205 ONEBITS This 256-byte table holds the number of '1' bits
present in the binary representation of every
value from 0 to FF.
7AFC BACKDOORKEY0 This 16-byte table is the ROM-based portion of the
backdoor key. It is the same in all ROM2 and
ROM3 cards. See also BACKDOORKEY1, below.
7B0C PUBKEYPRIME This one-byte value is the base prime used in the
public-key decryption portion of the EMM decrypt
routine. If you're curious, its value is 3.
E000 MFGINFO This 8-byte table contains manufacturing tracking
information such as the manufacturing lot number
and wafer number from which a given die came,
the die's position on the wafer, etc. This
information is unique for all cards. Note that
this portion of EEPROM is OTP, so once a given
bit in this area is set to a '1', it can never
be erased back to a zero.
E007 MAPNABLE This byte, in addition to being a part of the
MFGINFO data is also used as a flag to disable
the MAP functions in the card: If this byte is
$00 or $FF, calling the MAP main entry point at
$2800 will cause the card to hang.
E010 OTPDATA This 16-byte area is a general-purpose OTP EEPROM
data area. At present, the only thing this area
is used for in NagraVision cards is to store
"tags" which mark a card as having been found to
contain one or more inconsistencies which imply
that it has been tampered with.
E020 BACKDOORKEY1 This 16-byte table is the EEPROM-based portion of
the backdoor key. It is probably unique for
all cards. See also BACKDOORKEY0, above.
E030 DATAAREAPTR This 16-bit value is a pointer to the first byte
of EEPROM that can be used to store database-
handled data items. EEPROM below this address
is reserved for code patches, system data areas,
and so on.
E032 REVLEVEL This 6-byte ASCII string contains text identifying
the card's current firmware revision level. This
text is sent as part of the ATR, right after the
ROMVERSION string, and is usually of the form
'Rev3xx'. Note that changing the '3' in REVLEVEL
to any other character will subject the card to
tamper detection: F3 commands have been found in
the datastream which tag cards as tampered if the
4th character of the REVLEVEL string is not '3'.
See also ROMVERSION, above.
E038 CAMID This 4-byte value contains the card's CAM ID (the
card's serial number). This value is unique for
each card, and is stored high byte first. The
CAM ID is also printed on the card itself, in
decimal in the form 'ab cdef ghij xx', where
the CAM ID is abcdefghij, and xx is a pair of
check digits. Note that although the CAM ID can
be changed, it is inadvisable to do so: There are
keys in the card that are unique to each card,
and changing the CAM ID will result in keys that
don't match the CAM ID. Also note that if the
high byte (first byte) of the CAM ID is changed
to $80 or $01 in a ROM3 card, the card will be
subjected to tamper detection: F3 commands have
been found in the datastream which tag cards as
tampered if the high byte of the CAM ID is $80 or
$01.
E03C CURRENTDATE The 16-bit encoded version of today's date. When
the card decrypts an ECM (command $03), if the
data within the encrypted portion includes a
"current time" field, the card will write the
date from that field into EEPROM at this
location.
E03E DATALENGTHS The predefined fixed lengths of data items whose
data types are $01..$0E. Note that this is a
1-based table, so the first entry (with an index
of 0) is for data type $01, and so on.
E04D PROCCYCLE This 4-byte value contains what Kudelski refers to
as the processing cycle. I don't know much about
what it's for, other than the fact that the low
byte (4th byte) of this value is often used in
F3 commands to determine which F3 command should
be the next one executed in a series of EEPROM
update commands.
E051 NUMBUGS The maximum number of bug-catchers the card is
capable of supporting. In ROM3 cards, this value
is 10. See also BTNUMS and BTADDRS, below.
E052 CMD99XOR This 24-byte string is the data that is XORed
with the received data from a 99 command prior
to encrypting the XORed data with the command
99 key. See also CMD99KEY, below.
E06A CMD99KEY This 8-byte key is used to DES encrypt the result
of XORing the 24 bytes of data sent to the card
in a 99 command with the 24-byte CMD99XOR data
block. See also CMD99XOR, above.
E072 BTNUMS This table is where the numbers of the bug-
triggers that have been hooked in the card are
stored. This is a variable-length table, but in
ROM3 cards, its stock length is 10 bytes. It is
immediately followed by the BTADDRS table, which
points to the handler for each hooked bug-catcher
in the card. Note that CATCHBUG always checks
every value in BTNUMS to see if the module number
it was passed matches, so a 00 byte in the table
does not signal the end of valid data. See also
NUMBUGS, above, and BTADDRS, below.
E07C BTADDRS This table is where the addresses of each of the
hooked bug-catchers are stored. Note that it
does not necessarily start at a fixed address:
Rather, it immediately follows the BTNUMS table,
so, for example, if the value of NUMBUGS were
increased from $0A to $0C, this table would
start at E07E, since the BTNUMS table would be
two bytes longer. Immediately following the
BTADDRS table is where the space for code patches
begins. Note that it's not a good idea to
try and expand the size of the bug-trigger table,
because F3 commands have been found in the
datastream which tag cards as tampered if too
much non-zero data is found in the EEPROM code
space area above the address where Kudelski
expects their "genuine" bug-catchers to end, and
expanding the size of the BTNUMS and BTADDRS
tables would require the genuine bug-catchers to
be moved up in memory, which could cause such a
tamper test to fail. See also NUMBUGS and
BTNUMS, above.
11.3- ROM10 cards (this section under construction)
Unfortunately, at this time, very little information is available about
ROM10 code and entry points. The scarce information we _do_ have was gained
by comparing $FA command packets decrypted from the datastream to their
ROM2- and ROM3-targeted F0 and F3 counterparts. Once a ROM10 ROM dump has
happened, this section will grow considerably.

11.3.1- Bug-catcher modules


11.3.2- Hooking in a bug-catcher
11.3.3- Useful routines and memory locations
11.3.3.1- Utility routines
11.3.3.2- Database routines
11.3.3.3- Low-level routines
11.3.3.4- Encryption/decryption routines

When adding backdoor commands to the card (or when intercepting $03 commands
or other information that's DES encrypted), a hacker may wish to use the DES
encrypt or decrypt routines that are included in the NagraVision cards. The
basic DES routines will be listed here, both in summary form and detailed
form, along with examples of how to call the more useful routines.

11.3.4- Memory usage


11.3.4.1- ZP RAM
11.3.4.2- Other RAM
11.3.4.3- Tables in ROM and EEPROM
12: Epilogue
12.1- Change log
Here's where you'll find a list of changes that have been made to this FAQ
since its creation. Changes may include addition of new data, correction
of errant data, or deletion of errant data.

Release date Changes


------------ --------------------------------------------------------
10/15/99 Initial release.

10/31/99 Updated info on time/date format (tt: BurnOutX)


Updated $C0 command info (tt: BurnOutX)
Added DST info (tt: BurnOutX)
Added info on all CAM data types based on anonymous
donation of file "CA_NASP.H"

11/27/99 Formatted text for 78 columns


Miscellaneous typo corrections
Added example of command $60
Added glossary
Added info on PPV purchase commands $01, $41, $42
(tt: Wolven)
Added encryption section
Added status word section (tt: DishFarmer)
Added section on the $99 command (tt: DishFarmer, ZIP22)
Added additional card types (tt: tnt, DNTMATR, Star,
bplus, Xilicon)
Added more examples to EMM command $44
Corrected checksums in command list examples
Changed most references to 288-01 and 288-02 to ROM2 and
ROM3, respectively, to make information more applicable
to other Nagra cards
Added slight info on EMM commands $60 and $83
(tt: DishFarmer, Nipper)

12/02/99 Updated CAM revision level information: CAM rev changed


to Rev372.
Added notation about CAM using T=1 instruction blocks
instead of T=1 response blocks. (tt: Milo)
Corrected the URL for the Keyblitz DES document (tt: Milo)
Changed all references to the MCU as it exists in the
E* smartcard to refer to the model number as 16CF54A.
Began the long path of converting this FAQ into a
Nagravision hacking FAQ instead of an EchoStar hacking
FAQ.
Added the "data formats within the card" sections.
Added information about possible phone number in
type $06 data.
Added section on commands added for E3M, AVR2, GAP

07/15/2000 Misc. typo corrections, etc.


Further strides toward making this a NagraVision hacking
FAQ rather than an EchoStar hacking FAQ
Completed analysis of all commands based on eROM 288-02
ROM dump
Added information on 288-02 flash file system and data
item internal storage format
Corrected information on commands $41 and $42
Updated IRD status byte info
Added information on EMM filter commands
Corrected information on ECM commands
Added information on ROM10 cards (tt: DF)

11/11/2000 Added information on $02 command and MECMs

11/17/2000 Added information on $FA EMM command


Updated information on $F3 EMM command
Added information on how EEPROM updates happen
Updated information on MECMs

11/18/2000 Updated information on MECMs


Updated glossary
Added information about possible DirecTV use of
NagraVision

11/19/2000 Added information on callback packet formats


Added information on CAM tamper detection bit in
C0 status data

11/20/2000 Corrected information on ROM2 4-byte data headers

11/21/2000 Added section 10 (firmware revs) to unabridged version


Added section 11 (card programming) to unabridged version

11/26/2000 Added information on chained responses from CAM for


backdoor commands

12/01/2000 Added information on callback request packet number


parameter
Updated information on status words
Updated information on A0 0E backdoor command
Added information on ROM3 bug-catcher modules (tt: DF)

12/03/2000 Added information on ROM3 utility routines

12/08/2000 Added information on ROM3 bug-catchers

12/09/2000 Added information on chained messages


Added information on hooking ROM3 bug-catchers
Added information on ROM3 database routines
Added "most useful bug-catchers" section
Added information on # bytes available for $07 data type
with command $21

12/10/2000 Added information on ROM3 low-level routines


Updated glossary

12/11/2000 Added information on ROM3 delay routines


Added information on ROM3 DES encrypt/decrypt routines
Added information on ROM3 RAM usage

12/12/2000 Updated glossary


Added information on ROM3 ROM and EEPROM data areas

12/23/2000 Added "basic command sequences" section

12/26/2000 Added information on RAM addressing bug in 16CF54 silicon


12/28/2000 Tweaks for 1/1/2001 release

12/31/2000 Final tweaks for 1/1/2001 release


Added information on enhanced E3M commands $05 and $06
Added information on E3M command $09
Added information on encryption keys used by E3M cmd $08

12.2- Coming soon


Here's where you'll find a list of topics that I'll be adding to the FAQ as
I get the time and/or come across the info. Or maybe not...it all depends on
how useful they each seem when I finally get around to them.

-The $00/$01/$02 encryption algorithm


-The IRD NVRAM memory map

12.3- Contacting me
I realize that I'm not the ultimate authority on the NagraVision system, and
that there's a lot of information that I don't yet have. If you have any
corrections to the information in this FAQ, or if you have information you'd
like to add to it, email it to me at:

stuntguy@dishplex.com

Let me know how you want to be credited when you send the information.

I'm particularly interested in logs of the initialization sequences that


happen with all the different Nagra cards out there...the ATRs, responses
to the 21-xx commands, etc. If you want to send me those, I'd be grateful.
I've already got info on the 288-01s and 288-02s, so if you've got stuff on
other cards, I'll take it. Be sure to censor the following data:

-The four bytes right before the 90 00 in command 12 responses (CAM ID)
-Bytes 5..8 and B..E in the 21-01 response (ZIP code and IRD #)
-Bytes 4..7 in the 21-06 responses (CAM ID)

NOTE: In the 21-xx responses, the byte numbers I'm referring to are the
actual data bytes...The data starts after the sequence: 12 xx xx A1 xx,
where xx are bytes that vary depending on the the command sequence and/or
data length.

You might also like