Log in

View Full Version : libaacs keydb format


gates
30th June 2010, 21:37
This is essentially the format keydb config file that will be used in libaacs. Any feedback is much appreciated : )

; libaacs key database file, format 1.0
; -------------------------------------
;
; This config file format is an augmented form of DumpHD's config file
; format 1.4.
;
; This file is provided as documentation and as an example of the key database
; file used by libaacs, it contains no valid keys or entries.
;
; A config file has four main config entry items. The first items are device key
; entry items, the second is host certificate entry items, the third is
; processing key entry items, and the fourth are title entry items. Details on
; these items are given later.
;
; The encoding of this file is UTF-8 without BOM (if the BOM is present the
; first line will not get recognized). A line delimiter may be either LF (\n) or
; CR (\r). A combination of CR+LF or LF+CR will be considered as a sequence of
; two line delimiters.
;
; Comments can be inserted into the config file. A comment begins with a ';'
; character. Anything after the ';' character, up to the next newline, is
; ignored.
;
; Whitespace in this file is referred to as a single space (' ') or
; a tab ('\t'). Whitespace can be present/ommitted except in the case of
; keywords. Keywords must be delimited by at least one whitespace.
;
; Newlines may be escaped. To escape a newline, prepend a '\' character before
; the newline. Escaped newlines are treated as whitespace.
;
; All hexstrings must begin with '0x'. Hexstrings may be broken up into many
; lines or with whitespace.
;
; NOTE: Users switching from the old keydb config format can use this command
; to convert all hexstrings to the proper format.
;
; $ sed -i 's/\([[:xdigit:]]\)\{5,\}/0x&/g' KEYDB.cfg
;
; Device Key entry
; ----------------
; BEGIN DK_ENTRY
; DEVICE_KEY <HEXSTRING>
; DEVICE_NODE <HEXSTRING>
; END DK_ENTRY
;
; The device key entry begins with "BEGIN DK_ENTRY" and ends with
; "END DK_ENTRY". Within a device key entry are two hexadecimal strings. The
; first hexadecimal string is preceded by the keyword "DEVICE_KEY" and is
; the hexadecimal string representing the device key. The second hexadecimal
; string is preceded by the keyword "DEVICE_NODE" and is the hexadecimal string
; representing the device node number.
;
; Note that each of these entries must end with at least one new line, as
; shown in the example above.
;
; Processing Key entry
; --------------------
; PROCESSING_KEY <HEXSTRING>
;
; A processing key entry begins with the keyword "PROCESSING_KEY" followed by a
; hexstring representing the processing key. Each processing key entry must end
; with a newline.
;
; Host Certificate entry
; ----------------------
; BEGIN HOST_CERT_ENTRY
; HOST_PRIVATE_KEY <HEXSTRING>
; HOST_CERTIFICATE <HEXSTRING>
; HOST_NONCE <HEXSTRING>
; HOST_KEY_POINT <HEXSTRING>
; END HOST_CERT_ENTRY
;
; A Host Certificate entry has a single line that contains
; "BEGIN HOST_CERT_ENTRY" at the beginning and a single line that contains
; "END HOST_CERT_ENTRY" at the end. Each host certificate entry must contain 4
; hexadecimal strings preceded by a keyword that identifies the type of entry
; that the hexadecimal string corresponds to. Each certificate entry must appear
; in one line at a time. The first line is the host private key, the second is
; the host certificate, the third is the host nonce, and the fourth is the host
; key point. A host certificate list block must contain at least one host
; certificate entry.
;
; Title entry
; -----------
; <DISCID> = <TITLE> | <ENTRY ID> | <ENTRY DATA> [ | <ENTRY ID> | <ENTRY DATA> ... ]
;
; DISCID is the calculated identifier of the disc content type, a physical disc
; may have multiple DiscID's (e.g. the disc contains HD-DVD Standard Content and
; HD-DVD Advanced Content). The value is stored as a hexadecimal string and is
; 40 characters long. The DiscID is the SHA-1 hash calculated from the
; following file:
; - HD-DVD Standard Content Audio : AACS\ATKF.AACS
; - HD-DVD Standard Content Video : AACS\VTKF.AACS
; - HD-DVD Advanced Content Audio : AACS\ATKF000.AACS
; - HD-DVD Advanced Content Video : AACS\VTKF000.AACS
; - BD-ROM BDMV : AACS\Unit_Key_RO.inf
; - BD-Recordable BDMV : AACS_mv\Unit_Key_RW.inf
; - BD-Recordable BDAV : AACS\AACS_av\Unit_Key_RW.inf
;
; TITLE is the title of the content.
;
; ENTRY ID describes the type of the following ENTRY DATA, these IDs are valid:
; - D : Date of the DiscID file
; - M : Media Key
; - I : Volume ID
; - B : Binding Nonce
; - V : Volume Unique Key
; - P : Protected Area Key
; - T : Title Key
; - U : CPS Unit Key
;
; ENTRY DATA is specific for each ENTRY ID:
; - D : <YEAR> - <MONTH> - <DAY>
; YEAR must be 4 digits, MONTH and DAY 2 digits. An invalid / non present
; date has the special value 0000-00-00
; - M : <MEK>
; Hexadecimal string of the Media Key, 32 characters long
; - I : <VID>
; Hexadecimal string of the Volume ID, 32 characters long
; This entry applies to prerecorded media only
; - B : <BN NUMBER> - <BN> [ | <BN NUMBER> - <BN> ... ]
; BN NUMBER is the number of the Binding Nonce, it must be 1 to 5 decimal
; digits long and starts at 0
; BN is the hexadecimal string of the Binding Nonce, 32 characters long
; This entry applies to recordable media only, there may be multiple
; Binding Nonces
; For BD recordables BN NUMBER is 0
; - V : <VUK>
; Hexadecimal string of the Volume Unique Key, 32 characters long
; This entry applies to prerecorded media only
; - P : <PAK NUMBER> - <PAK> [ | <PAK NUMBER> - <PAK> ... ]
; PAK NUMBER is the number of the Protected Area Key, it must be 1 to 5
; decimal digits long and starts at 0
; PAK is the hexadecimal string of the Protected Area Key, 32 characters
; long
; This entry applies to recordable media only, there my be multiple
; Protected Area Keys
; For BD recordables PAK NUMBER is 0
; - T : <TK NUMBER> - <TK> [ | <TK NUMBER> - <TK> ... ]
; TK NUMBER is the number of the Title Key, it must be 1 to 5 decimal
; digits long and starts at 1
; TK is the hexadecimal string of the Title Key, 32 characters long
; This entry applies to HD-DVD only, there may be multiple Title Keys
; - U : <UK NUMBER> - <UK> [ | <UK NUMBER> - <UK> ... ]
; UK NUMBER is the number of the CPS Unit Key, it must be 1 to 5 decimal
; digits long and starts at 1
; UK is the hexadecimal string of the CPS Unit Key, 32 characters long
; This entry applies to BD only, there may be multiple CPS Unit Keys
;
; All entries are treated case insensitive, whitespace between the
; values / delimiters may be present / omitted.
; Each entry must be delimited by at least one newline, to include the last
; entry. An unlimited number of entries may be given for any type of entry. The
; ordering of any config entry type can be arbitrary. It is also possible to
; give no entries in the config file, though libaacs will not be able to
; decrypt any disc in such a case.
;
;
; Examples
; --------
;

; foo's device key
BEGIN DK_ENTRY
DEVICE_KEY 0x00000000000000000000000000000000 ; I am a comment
DEVICE_NODE 0x0
END DK_ENTRY

; bar's device key
BEGIN DK_ENTRY
DEVICE_KEY 0x00000000000000000000000000000000
DEVICE_NODE 0x0
END DK_ENTRY

; foo's certificate
BEGIN HOST_CERT_ENTRY
HOST_PRIV_KEY 0x0000000000000000000000000000000000000000 ; host private key
HOST_CERT 0x0000000000000000000000000000000000000000 \
0x0000000000000000000000000000000000000000 \
0x0000000000000000000000000000000000000000 \
0x0000000000000000000000000000000000000000 \
0x000000000000000000000000 ; host certificate
HOST_NONCE 0x0000000000000000000000000000000000000000 ; host nonce
HOST_KEY_POINT 0x0000000000000000000000000000000000000000 ; host key point
END HOST_CERT_ENTRY

; bar's certificate
BEGIN HOST_CERT_ENTRY
HOST_PRIV_KEY 0x0000000000000000000000000000000000000000
HOST_CERT 0x0000000000000000000000000000000000000000 \
0x0000000000000000000000000000000000000000 \
0x0000000000000000000000000000000000000000 \
0x0000000000000000000000000000000000000000 \
0x000000000000000000000000
HOST_NONCE 0x0000000000000000000000000000000000000000
HOST_KEY_POINT 0x0000000000000000000000000000000000000000
END HOST_CERT_ENTRY

; foo processing key
PROCESSING_KEY 0x00000000000000000000000000000000

; single line entries
0x0000000000000000000000000000000000000000 = Movie Title | D | 0000-00-00 | V | 0x00000000000000000000000000000000 ; I am a comment
0x0000000000000000000000000000000000000000 = Movie Title ; I am NOT a comment | D | 1337-08-15 | T | 1-0x00000000000000000000000000000000 | 2-0x00000000000000000000000000000000 | 3-0x00000000000000000000000000000000
0x0000000000000000000000000000000000000000 = Movie Title | D | 2007-04-01 | V | 0x00000000000000000000000000000000 | T | 1-0x00000000000000000000000000000000
0x0000000000000000000000000000000000000000 = Movie Title | D | 1111-11-11 | U | 1-0x00000000000000000000000000000000 | 2-0x00000000000000000000000000000000 | I | 0x00000000000000000000000000000000

; bar processing key
PROCESSING_KEY 0x00000000000000000000000000000000

; multi line entries
0x0000000000000000000000000000000000000000 = \
Movie Title \
| D | 0000-00-00 \
| V | 0x00000000000000000000000000000000 ; I am a comment
0x0000000000000000000000000000000000000000 = \
Movie Title ; I am NOT a comment \
| D | 1337-08-15 \
| T | 1-0x00000000000000000000000000000000 \
| 2-0x00000000000000000000000000000000 \
| 3-0x00000000000000000000000000000000
0x0000000000000000000000000000000000000000 = \
Movie Title \
| D | 2007-04-01 \
| V | 0x00000000000000000000000000000000 \
| T | 1-0x00000000000000000000000000000000
0x0000000000000000000000000000000000000000 = \
Movie Title \
| D | 1111-11-11 \
| U | 1-0x00000000000000000000000000000000 \
| 2-0x00000000000000000000000000000000 \
| I | 0x00000000000000000000000000000000

KenD00
1st July 2010, 05:55
Hmm, why so complicated, these different chapters require different parsers, why don't you use the present scheme for all entry types?

You could misuse one of the invalid DiscID's 00..00 or FF..FF to hold the Device Keys, Certificates and Processing Keys like this:

FF..FF = TITLE IS IGNORED | D | <NODE> - <DEVICE KEY> | C | <PRIVATE KEY> - <CERTIFICATE> | P | <PROCESSING KEY>

This way you can store an arbitrary number of Device Keys, Certificates and Processing Keys and don't need to write a second parser. And the file looks uniform ;). Maybe you should use different Entry ID's to not confuse them with the present ones, maybe it would be a good idea to extent them from single letters to multiple ones like DK, HC, PK.

Oh and there is no need to store HOST_NONCE and HOST_KEY_POINT, these are calculated values (which are only hardcoded into aacskeys because it somehow uses precalculates values instead computing these ones as required by the spec).

:rolleyes:

gates
1st July 2010, 06:20
Hmm, why so complicated, these different chapters require different parsers, why don't you use the present scheme for all entry types?

You could misuse one of the invalid DiscID's 00..00 or FF..FF to hold the Device Keys, Certificates and Processing Keys like this:

FF..FF = TITLE IS IGNORED | D | <NODE> - <DEVICE KEY> | C | <PRIVATE KEY> - <CERTIFICATE> | P | <PROCESSING KEY>

This way you can store an arbitrary number of Device Keys, Certificates and Processing Keys and don't need to write a second parser. And the file looks uniform ;). Maybe you should use different Entry ID's to not confuse them with the present ones, maybe it would be a good idea to extent them from single letters to multiple ones like DK, HC, PK.

Oh and there is no need to store HOST_NONCE and HOST_KEY_POINT, these are calculated values (which are only hardcoded into aacskeys because it somehow uses precalculates values instead computing these ones as required by the spec).

:rolleyes:

Hmmm. Actually, I am using just a single parser. It's a lex/yacc parser that's handling the parsing. It may look complicated, but the grammar is relatively simple, compared to other languages.

Also about HOST_NONCE and HOST_KEY_POINT, I suppose that's an issue with current libaacs where those values are not being calculated. I'll look into it.

About your suggestion on device key, host certificate, and processing key entries, I wanted to use some keywords to distinguish between different entries. Also, I don't want the FFF... = <fake title> stuff to appear for those entries. How about this?


; processing key entries
| PK | <HEXSTRING>

; device key entries
| DK | DEVICE_KEY <HEXSTRING> \
| DEVICE_NODE <HEXSTRING>

; host certificate entries
| HC | HOST_PRIVATE_KEY <HEXSTRING> \
| HOST_CERT <HEXSTRING>


This is an example using multi-line entries, but can also be done as single lines.

KenD00
2nd July 2010, 03:20
I suggested that fake ID entry only to keep the uniform look / format of the file, if you don't want to use it then there is no need to keep that pipe delimited format either imho. And if you enforce a strict format for specific ENTRY DATA sections then there is no need for additional keywords which are just noise then.

That pops up the question why do you want to put these data in the title keyfile at all, it doesn't really belong there and usually it isn't needed if you have a complete title entry. So why don't you put it in a seperate file then? This should make it easier to update the Certs and stuff independend from the title database.

And one note about the pipe delimited format, it is a bad idea to use the pipe symbol inside the ENTRY DATA section as delimiter like i have done for the B, P, T and U sections, this way you can't easily add new ENTRY ID's without breaking old parsers. It would be better to use another delimiter like colon for this, this way a parser only needs to read the ENTRY ID, if it doesn't know it skip to the next pipe. Currently it has to read the ENTRY DATA section and has to decide if the read data is an ENTRY ID or not.

:rolleyes:

gates
2nd July 2010, 06:12
I suggested that fake ID entry only to keep the uniform look / format of the file, if you don't want to use it then there is no need to keep that pipe delimited format either imho. And if you enforce a strict format for specific ENTRY DATA sections then there is no need for additional keywords which are just noise then.

That pops up the question why do you want to put these data in the title keyfile at all, it doesn't really belong there and usually it isn't needed if you have a complete title entry. So why don't you put it in a seperate file then? This should make it easier to update the Certs and stuff independend from the title database.

And one note about the pipe delimited format, it is a bad idea to use the pipe symbol inside the ENTRY DATA section as delimiter like i have done for the B, P, T and U sections, this way you can't easily add new ENTRY ID's without breaking old parsers. It would be better to use another delimiter like colon for this, this way a parser only needs to read the ENTRY ID, if it doesn't know it skip to the next pipe. Currently it has to read the ENTRY DATA section and has to decide if the read data is an ENTRY ID or not.

:rolleyes:

The extra keywords are there solely for the sake of making the config file more readable.

Also about having all keys in one file, I suppose that's just a matter of preference. It's also possible that a user doesn't know, or care, about having all keys for all titles he/she may own and thus just places the various processing keys, device keys, and host certificates in the config file. About using separate files for different config entries, I'll have to see what kind of trade off there is for supporting parsing multiple files. I was asked on IRC to look into this too. I certainly do not want to write multiple parsers for each config entry when one parser suffices.

About the pipe symbol as a delimiter issue, I've ensured the lexer can generates the proper tokens for the entry id's and for the single pipe symbol delimiters. It has no issue distinguishing between the two.