emukeys_layout.txt

(7 KB) Pobierz
	EMU data management (new EMU keys storage format)
	-------------------------------------------------
	
In order to unify and improve the way we keep EMU related data 
the following structure was implemented:

- all data items are separated in two parts: keys (data for ECM/EMM decrypt) 
  and service data (all the rest, e.g. SOIDs, provider attributes, addresses of MHW variables, etc.);
- each part has its own MHW buffer (keys buffer, service buffer) and MHW flash file. 
  Both buffers are of 0x1000 bytes length, keys are stored in RSA/RSA_KEYS, service data 
  in EMU/EMU respectively.

Both buffers have the same flexible structure: each record in buffer has a header 
of 4 bytes and a payload which length is pointed at the header's last byte.
8 trailing bytes of both buffers are reserved for service needs (now we store here 
some configuration settings).

 	1. Structure of a single record in service buffer (bufsrv).
 	
--- start of header -- 	00 - CA_SYSTEM according to emu.h
         		01 - record ID for given CA_SYSTEM (auto-incremented value for SOID records)
         		02 - record type (e.g. TYPE_SOID, TYPE_UA, TYPE_ADDRESS, etc.)
--- end of header --	03 - length of following payload
         		04 ... data

The following pre-defined record types are in use now:
#define TYPE_SOID 0xff  // this value is reserved for SOID records and should not be used for key indexes
#define TYPE_UA 0xf1	// Unique Address (UA), Serial number, etc.
#define TYPE_SA 0xf2	// Shared Address, PPUA, etc.
#define TYPE_FLAGS 0x10 // 1 byte record, may be used for 1 bit flags like sharing, preferred, etc.
#define TYPE_INFO  0x11 // text data (null terminated)

// for use with undefined CA ID (CAS_NULL)
#define TYPE_ADDRESS 0xAA // addresses of MHW variables for HDL.
         		

 	2. Structure of a single record in keys buffer (bufkeys).
 	
--- start of header -- 	00 - CA_SYSTEM according to emu.h
         		01 - provider ID for given CA_SYSTEM (the same one as for SOID records in bufsrv)
         		02 - key index for given provider ID
--- end of header --	03 - length of following payload
         		04 ... data
pointer to bufkeys is stored in bufsrv record as {CAS_NULL BUFKEYS TYPE_ADDRESS 4 [ADDRESS] }

	3. Trailing bytes.
	
8 trailing bytes of each buffer are reserved for service needs
#define DATA_END 	0xff7 // last byte of dynamic data
// 2 last bytes of buffer, contain ptr to free buffer space
#define BUF_END 	0xffe 

The following bytes of bufsrv are occupied by MHW flags

#define ECM2CARD_LOCK	0xffa	// 1: no sending ecm to card if do_ecm() fails. 
#define SECA_EMM_LOCK	0xffb	// 0: seca emms disabled, 1: SA/UA emms enabled, 2: SA emms enabled 
#define EMM_DISP_FLAG 	0xffc	// MHW flag to switch on/off displaying of EMM info
#define EMM_UPD_FLAG 	0xffd	// EMM processing mode (if 0 then no emm processing, 1: display all keys, 2: display new keys)

	4. EMU API.

In order to simplify and speed up requests to EMU data the new MHW API function func_277() added. 
Source code can be found in getput_key.c.

int manage_keys(byte* request, byte* bufemu, int mode, int* offset);
	
  request contains data related to calling 'mode', 
  bufemu points to emu buffer (either bufsrv or bufkeys), 
  offset is a return value.
  
Working modes
-------------
end_of_keys = peeks(bufemu,BUF_END);

#define MODE_GETKEY 0
search for existing record by its first 3 bytes
input:
	request[0] = CA system
	request[1] = Provider ID
	request[2] = record type or key index
	bufemu = bufsrv for service data search, bufkeys for key search
output:
	offset = offset of existing record if found, else end_of_keys	
	

#define MODE_PUTKEY 1
update of existing record or insertion of new one, don't use this for SOID update
input:
	request[0] = CA system
	request[1] = Provider ID
	request[2] = record type or key index
	request[3] = length of following data
	request+4 - data to write into buffer
	bufemu = bufsrv for service data update, bufkeys for key update
output:
	offset = 0x1000 in case of insufficient room in bufemu, else offset of updated/inserted record	
	
#define MODE_DELKEY 2
remove existing record
input:
	request[0] = CA system
	request[1] = Provider ID
	request[2] = record type or key index
	bufemu = bufsrv for service data delete, bufkeys for key delete
output:
	offset = old end_of_keys if record doesn't exist, else new end_of_keys	
	
#define MODE_GETPROV 3
search for existing SOID record by its value
input:
	request[0] = CA system
	request[3] = length of following data
	request+4 - SOID
	bufemu = bufsrv
output:
	offset = offset of existing record if found, else end_of_keys
		
#define MODE_PUTPROV 4
insert new SOID record (or return the offset of existing one)
input:
	request[0] = CA system
	request[3] = length of following data
	request+4 - data to write into buffer
	bufemu = bufsrv 
output:
	offset = 0x1000 in case of insufficient room in bufemu, else offset of inserted record
	bufemu[offset+1] = index of new record (Provider ID)	

#define MODE_DELPROV 5
delete SOID and all provider attributes in bufsrv (don't know if this is useful)
input:
	request[0] = CA system
	request[3] = length of following data
	request+4 - SOID
	bufemu = bufsrv
output:
	offset = old end_of_keys if record doesn't exist, else new end_of_keys

#define MODE_GETNEXT 6
enumerate records for given CA ID and Prov ID
input:
  -- to enumerate providers --
	request[0] = CA system
	request[3] = 1
	bufemu = bufsrv
  -- to enumerate keys --
	request[0] = CA system
	request[1] = Provider ID
	request[3] = 2
	offset = start position in bufemu 
	bufemu = bufsrv for provi attributes, bufkeys for keys
output:
	offset = offset of 1st found record, else end_of_keys

#define MODE_DELALL 7
remove all provider's records in given buffer
input:
	request[0] = CA system
	request[1] = Provider ID
	bufemu = bufsrv for service data deletion, bufkeys for key deletion
output:
	offset = end_of_keys after execution
	

	5. Examples of usage.

One can find examples of usage inside OFM firmware starting from PI724aXX HDL release. 
Open it in Defiant and have a look at scripts emubok.cpi, kdsav.cpi, lstattr.cpi, 
lstsoid.cpi, lstkey.cpi in folder /install.
basic.BUFEMU_E_HDL acts here as bufsrv, emukeys.RSA_KEYS acts as bufkeys.		

	6. Related modifications in HDL.

6.1. New algo of EMM filtering.
SOIDs and address data (UA/PPUA) of providers are no more placed at fixed positions of BUFEMU_E.
Therefore, functions like Get_Ca_Pid, EMM_Set_Filter have to be modified according to new EMU buffer layout.
Examples can be found in emm_ecm.c

6.2. New key management in emulator.
Developers can use the same API to work with keys in emulator. However,I for one preferred to make 
another set of functions for this purpose inside emu16.c due to number of reasons.
Additionally, we used a small MHW buffer emukeys.EMUINFO in order to exchange data between MHW and emulator.
These data are volatile and we don't need to save them into flash file. 
Examples of usage can be found in emu16.c.



 	
Zgłoś jeśli naruszono regulamin