netmdocm
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
netmdocm [2009/06/16 00:20] – info on maclist marcus | netmdocm [2011/01/16 14:33] – nopsled | ||
---|---|---|---|
Line 138: | Line 138: | ||
0x24, 0x4C, 0x60, 0x26, 0x00, 0x00, | 0x24, 0x4C, 0x60, 0x26, 0x00, 0x00, | ||
} ; | } ; | ||
+ | |||
+ | This is an ASN.1 sequence (0x30) with indeterminate length (0x80) that only contains a single blob (0x04) of 16 bytes (0x10). | ||
===== Process file (OPF) ===== | ===== Process file (OPF) ===== | ||
Line 161: | Line 163: | ||
0x03, 0x02, 0x01, 0x05, 0x02, 0x01, 0x04, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, | 0x03, 0x02, 0x01, 0x05, 0x02, 0x01, 0x04, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, | ||
} ; | } ; | ||
+ | |||
+ | ASN.1 Sequence with a data structure that is setup and manipulated by functions called through DICT 187 (these functions are in DICT 188). | ||
+ | |||
+ | 30 80 | ||
+ | 02 02 03E9 | ||
+ | 04 14 43EA428F71EE7B665D10752E85AB16E5A50C6249 ; MAC | ||
+ | 04 14 638163B82C4E31810FBEE01B2E7FC25B879586E3 ; Enc(CKEY) ? Offset 0x1E according to Jan (// key is at offset 0x1E! (OMGDecrypter.cpp) | ||
+ | 30 80 02 01 6B ; 17 (some time stamp) | ||
+ | 02 04 48C2298F | ||
+ | 02 01 07 ; 7 == creation time of structure | ||
+ | 02 04 48C2298F | ||
+ | 02 01 6D ; 109 | ||
+ | 02 01 00 | ||
+ | 02 01 65 ; 101 | ||
+ | 04 14 C04B513EDE54342D709D0CB8621E646FDDCB345E | ||
+ | 02 01 00 ; 0 == scrambled form of the maclist id == SalOmgId | ||
+ | 04 14 010F50000004000000EFF3C3244C602635178457 | ||
+ | 02 01 68 ; 104 | ||
+ | 02 02 1FD7 | ||
+ | 02 01 06 ; 6 == source name | ||
+ | 04 15 72617720636F6E74656E7420696D706F7274696E67 | ||
+ | r a w c o n t e n t i m p o r t i n g | ||
+ | 02 01 67 ; 103 == flags? | ||
+ | 02 01 02 | ||
+ | 02 01 01 ; 1 == max checkout? | ||
+ | 02 01 03 | ||
+ | 02 01 08 ; 8 == checkout count? | ||
+ | 02 01 03 | ||
+ | 02 01 05 ; 5 == flags (1|2|4) | ||
+ | 02 01 04 | ||
+ | 0000 ; End array | ||
+ | 30 80 0000 ; Empty array | ||
+ | 0000 ; End array | ||
===== maclist1.dat ===== | ===== maclist1.dat ===== | ||
Line 175: | Line 210: | ||
- | There is a 40-byte header (MACLIST\0, followed by 4 DWORDs with unknown meaning, followed by (DWORD)2, followed by the number of operations done on the maclist (in this case 3), followed by the number of MACs (here: 0), followed by 0 (unknown field). | + | There is a 40-byte header (MACLIST\0, followed by 4 DWORDs with unknown meaning, followed by (DWORD)2, followed by the number of operations done on the maclist (in this case 3), followed by the number of MACs (here: 0), followed by 0 (unknown field). |
===== maclist2.dat ===== | ===== maclist2.dat ===== | ||
Line 187: | Line 222: | ||
0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, | 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
} ; | } ; | ||
+ | |||
+ | |||
+ | The update counter is bumped from 3 to 4 here, and the count of macs is 1. Indeed a MAC can be found here, namely 43EA428F71EE7B66. | ||
===== icv.dat ===== | ===== icv.dat ===== | ||
Line 784: | Line 822: | ||
0x3E, 0x0A, 0x00, 0x00, 0x00, 0x00, | 0x3E, 0x0A, 0x00, 0x00, 0x00, 0x00, | ||
} ; | } ; | ||
+ | |||
+ | |||
+ | |||
+ | 30 80 | ||
+ | 30 80 | ||
+ | 06 07 666F70656E4D47 ; " | ||
+ | 02 02 03EB | ||
+ | 04 14 010F50000004000000EFF3C3244C602635178457 | ||
+ | 06 02 6701 | ||
+ | 02 02 3F00 | ||
+ | 06 02 6801 | ||
+ | 02 04 000021C0 | ||
+ | 02 01 01 | ||
+ | 02 03 0101D0 | ||
+ | 02 02 00C0 | ||
+ | 02 01 00 | ||
+ | 0000 | ||
+ | 04 08 1D891A35257C8017 | ||
+ | 04 84000021D0 | ||
+ | 8662B73CCD0D ; 6 | ||
+ | 2EB500000000000000003FCFD3837F35 ; 22 | ||
+ | D23B8041488DE653998A1131B0791B42 ; ... | ||
+ | ... | ||
+ | 0A7721125C0436D158F5800959206C31 | ||
+ | 27BFDD5418344FAEF752 | ||
+ | 30 80 | ||
+ | 04 17 4F4D473A4652494E47453A5553523A757365722E786D6C | ||
+ | ; OMG: | ||
+ | 04 8201E9 | ||
+ | 3C3F786D6C2076 | ||
+ | 657273696F6E203D2022312E30222065 | ||
+ | ... | ||
+ | 6B6C6973743E0A3C2F7061636B616765 | ||
+ | 3E0A | ||
+ | ; < | ||
+ | ; <package version = " | ||
+ | ; < | ||
+ | ; < | ||
+ | ; <track number = " | ||
+ | ; < | ||
+ | ; < | ||
+ | ; </ | ||
+ | ; < | ||
+ | ; <title half-width = " | ||
+ | ; <artist role = " | ||
+ | ; </ | ||
+ | ; < | ||
+ | ; < | ||
+ | ; < | ||
+ | ; </ | ||
+ | ; </ | ||
+ | ; </ | ||
+ | ; </ | ||
+ | ; </ | ||
+ | 0000 | ||
+ | 0000 | ||
===== OMGRIGHT icv values | ===== OMGRIGHT icv values | ||
Line 811: | Line 905: | ||
===== maclist(1) ===== | ===== maclist(1) ===== | ||
- | /* | + | XOR the SalOmgId |
- | Procedure prototype: | + | |
- | | + | |
- | + | ||
- | Input: | + | |
- | + | ||
- | SalNonConstPointer const &, | + | |
- | SalPointer const &, | + | |
- | SalOmgId | + | |
- | long, | + | |
- | SalExtrinsicsProg const & | + | |
- | + | ||
- | Output: | + | |
- | + | ||
- | long | + | |
- | + | ||
- | */ | + | |
===== Sample input: ===== | ===== Sample input: ===== | ||
Line 852: | Line 930: | ||
0x54, 0xB1, 0x2C, 0xC4, | 0x54, 0xB1, 0x2C, 0xC4, | ||
} ; | } ; | ||
+ | |||
===== maclist(8) ===== | ===== maclist(8) ===== | ||
+ | |||
+ | This first does the same integrity check as maclist(1), if that does not succeed, it returns ASN.1 of an array with just the single number " | ||
+ | |||
+ | In other words, this extracts the 0-extension of a MACLIST and an encrypted hash of that. | ||
/* | /* | ||
Line 896: | Line 979: | ||
0xC4, 0xF8, 0xCA, 0x19, 0x2E, 0x38, 0xE2, 0x3E, 0x4C, 0x00, 0x00, | 0xC4, 0xF8, 0xCA, 0x19, 0x2E, 0x38, 0xE2, 0x3E, 0x4C, 0x00, 0x00, | ||
} ; | } ; | ||
+ | / | ||
===== icv(7) ===== | ===== icv(7) ===== | ||
Line 961: | Line 1045: | ||
} ; | } ; | ||
- | ===== nc_omgtomsa(4) ===== | + | ===== nc_omgtomsa(0) ===== |
/* | /* | ||
Line 1055: | Line 1139: | ||
{ | { | ||
0: short int 1001b; | 0: short int 1001b; | ||
- | 1: blob_t key_or_id_20; | + | 1: blob_t key_or_id_20; |
- | 2: blob_t key_or_id_20; | + | // |
- | 3: struct { // 26 | + | // |
+ | 2: blob_t key_or_id_20; | ||
+ | // | ||
+ | 3: struct { // 26 | ||
dd 6Bh const_107 | dd 6Bh const_107 | ||
dd 4400AFA0h timestamp | dd 4400AFA0h timestamp | ||
Line 1108: | Line 1195: | ||
dict[3] = OpfImage; | dict[3] = OpfImage; | ||
- | // Seems to check the integrity of the data in the usage-rights file (.opf). | + | // |
- | // | + | // Calculate HMAC for the opf[3] |
+ | // | ||
+ | // ProcessFile[1]: | ||
blob_t dec_pf2 = devicesal_220_decrypt_hook_249(ProcessFile[2], | blob_t dec_pf2 = devicesal_220_decrypt_hook_249(ProcessFile[2], | ||
blob_t serialized_opf3 = BCSerialize(ProcessFile[3]); | blob_t serialized_opf3 = BCSerialize(ProcessFile[3]); | ||
- | |||
blob_t key = concat ( dec_pf2, serialized_opf3 ); | blob_t key = concat ( dec_pf2, serialized_opf3 ); | ||
blob_t hasked_key = inline:: | blob_t hasked_key = inline:: | ||
- | |||
blob_t key_pf2 = concat ( dec_pf2, hashed_key ); | blob_t key_pf2 = concat ( dec_pf2, hashed_key ); | ||
blob_t hashed_key_pf2 = inline: | blob_t hashed_key_pf2 = inline: | ||
+ | // if( HMAC(opf[3], | ||
+ | // | ||
+ | // | ||
if (compare_blob (hashed_key_pf2, | if (compare_blob (hashed_key_pf2, | ||
// Test_Small_Int_For_Zero -> 0 (acc) | // Test_Small_Int_For_Zero -> 0 (acc) | ||
Line 1135: | Line 1225: | ||
netmd(0) | netmd(0) | ||
- | Process file, unknown blob, Ekb capability table, 00010002ekb, | + | Process file, unknown blob, Ekb capability table, 00010002ekb, |
+ | |||
+ | status = 0: Success, nonce will be used to authenticate NetMD unit, checkout_context contains all data to continue processing. | ||
+ | status != 0: Error, nonce and checkout_context don't exist | ||
Procedure prototype: | Procedure prototype: | ||
Line 1402: | Line 1495: | ||
</ | </ | ||
- | ===== icv.ocm Decompiled ===== | ||
- | |||
- | < | ||
- | |||
- | // | ||
- | // Generate a SalOmgId | ||
- | // | ||
- | // | ||
- | // | ||
- | // < | ||
- | // | ||
- | // Note: When OpenMG is used (trough the UI) for the first time this value is generated, | ||
- | // by calling the salwrap function getSalOmgId. | ||
- | // | ||
- | // const unsigned __int8 *__cdecl getSalOmgId() | ||
- | // | ||
- | blob_t icv(07) | ||
- | { | ||
- | | ||
- | | ||
- | data = BCX_01_Concat(PrefixSalOmgId, | ||
- | Push 1 | ||
- | | ||
- | | ||
- | } | ||
- | </ | ||
- | |||
- | ===== maclist.ocm | ||
- | |||
- | // maclist(1) | ||
- | // | ||
- | // work in progress | ||
- | |||
- | < | ||
- | |||
- | int | ||
- | maclist_0x01(blob_t SalOmgId, blob_t maclist2dat, | ||
- | { | ||
- | static blob_t pad[16] = {0x20, 0xBE, 0xDE, 0x72, 0xA3, 0xB8, 0x62, 0x60, | ||
- | 0x71, 0x44, 0x3A, 0x33, 0xE9, 0xAC, 0x69, 0xCE}; | ||
- | static SHA1state, hash_maclist, | ||
- | |||
- | SHA1state | ||
- | BCX_1A_SHA1AddData(maclist, | ||
- | hash_maclist | ||
- | |||
- | xor_SalOmgId | ||
- | hash_maclist_salomgid = salenc_sha1(SalOmgId_xor, | ||
- | |||
- | hash_maclist == hash_xorSalOmgId? | ||
- | } | ||
- | </ |
netmdocm.txt · Last modified: 2024/05/21 14:50 by nopsled