devicesal
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
devicesal [2009/05/05 07:35] – created dummy megadiscman | devicesal [2009/06/02 01:44] (current) – document dictionary marcus | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | dummy | + | < |
+ | DeviceSal Dict 000 (EKB) -> (status): Verify EKB file. For version 1, check SHA-1 of first 176 bytes. | ||
+ | DeviceSal Dict 001 | ||
+ | DeviceSal Dict 002 | ||
+ | DeviceSal Dict 003 | ||
+ | DeviceSal Dict 159 (EKB) -> (status): Verify EKB file with version > 1. Checks ECC signature, returns 0 if OK, otherwise an error code. | ||
+ | DeviceSal Dict 160 | ||
+ | DeviceSal Dict 165 | ||
+ | DeviceSal Dict 170 | ||
+ | DeviceSal Dict 171 | ||
+ | DeviceSal Dict 172: Dispatch table for D171. | ||
+ | DeviceSal Dict 173 | ||
+ | DeviceSal Dict 174 | ||
+ | DeviceSal Dict 175 | ||
+ | DeviceSal Dict 177 | ||
+ | DeviceSal Dict 178: Dispatch table for D177. | ||
+ | DeviceSal Dict 180 (a,b,c) -> (1): Returns 1. | ||
+ | DeviceSal Dict 181 (deskey, | ||
+ | DeviceSal Dict 182 | ||
+ | DeviceSal Dict 183 | ||
+ | DeviceSal Dict 184 (msg, | ||
+ | DeviceSal Dict 185 (cipher, | ||
+ | DeviceSal Dict 186 (plain, | ||
+ | DeviceSal Dict 187 | ||
+ | DeviceSal Dict 189 (key,value) -> (): Use D191 as a map and enter (key, value) into it. | ||
+ | DeviceSal Dict 190 (key, | ||
+ | DeviceSal Dict 191: Variable to pass mapping to helper functions. | ||
+ | DeviceSal Dict 193 | ||
+ | DeviceSal Dict 194 | ||
+ | DeviceSal Dict 195 | ||
+ | DeviceSal Dict 196 | ||
+ | DeviceSal Dict 197: Dispatch table for 196. | ||
+ | DeviceSal Dict 198: (Decrypto with hook D249, reencrypt with DES-OCM) | ||
+ | DeviceSal Dict 199 | ||
+ | DeviceSal Dict 207 (encobj, objkey) -> (...): DES-OCM-Decrypt encobj with objkey and unpack an ASN.1 encoded array (stripping off the length parameter) | ||
+ | DeviceSal Dict 208 (o1, o2, objkey) -> (encobj): DES-OCM-Encrypt an ASN.1 encoded array containing the first 8 bytes of o1 and o2 each. | ||
+ | DeviceSal Dict 209 (version) -> (ekbpath): Return the local EKB path. | ||
+ | DeviceSal Dict 210 () -> (1): Produce 1. | ||
+ | DeviceSal Dict 211 | ||
+ | DeviceSal Dict 212 | ||
+ | DeviceSal Dict 213 | ||
+ | DeviceSal Dict 214 (encobj, protokey) -> (obj): Descramble cipher and OCM-Decrypt with SHA-1(protokey) and ASN.1-decode the result. | ||
+ | DeviceSal Dict 215 (obj, protokey) -> (encobj): OCM-Encrypt the serialized obj with SHA-1(protokey) and scramble the result. | ||
+ | DeviceSal Dict 216 (encobj, xorprotokey) -> (obj): DES-OCM-Decrypt with SHA-1(xorprotokey XOR D252++D252) and ASN.1-decode the result. | ||
+ | DeviceSal Dict 217 (obj, xorprotokey) -> (encobj): DES-OCM-Encrypt the serialized obj with SHA-1(xorprotokey XOR D252++D252). | ||
+ | DeviceSal Dict 220 (cipher, key) -> (plain): Decrypt with some weird SHA-1 based stream cipher. | ||
+ | DeviceSal Dict 221 (plain, key) -> (cipher): Encrypt with some weird SHA-1 based stream cipher. | ||
+ | </ | ||
+ | |||
+ | Missing Info: | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | |||
+ | Dict 0xfc - contains an unknown 8 byte key, used in dev_0xd8, dev_0xd9. | ||
+ | |||
+ | </ | ||
+ | |||
+ | Native modules: | ||
+ | < | ||
+ | // CBC Encrypt/ | ||
+ | // Block size of the cipher is 64 bit, key length is 160 bit. | ||
+ | blob_t | ||
+ | native:: | ||
+ | { | ||
+ | if (decrypt) | ||
+ | ocmmod_cbc_decrypt (in, out, key, len); | ||
+ | else | ||
+ | ocmmod_cbc_encrypt (in, out, key, blob_len (in)); | ||
+ | |||
+ | return out; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | int | ||
+ | dev_0x01 (blob_t someblob, bool_t somebool) | ||
+ | { | ||
+ | int res; | ||
+ | |||
+ | if (somebool == 1) | ||
+ | { | ||
+ | res = dev_0x00 (someblob); | ||
+ | if (res != 0) | ||
+ | return res; | ||
+ | } | ||
+ | int some_nr = (unsigned) SubBlob (someblob, 0, 4); | ||
+ | int some_nr2 = (unsigned) dev_0xd1 (some_nr); | ||
+ | res = " | ||
+ | // FIXME: Don't know the stack layout after this. | ||
+ | |||
+ | if (res != 0) | ||
+ | return; | ||
+ | |||
+ | blob_t someblob2; | ||
+ | |||
+ | int some_nr3 = (signed) SubBlob (someblob2, 0, 4) + 1; | ||
+ | vector< | ||
+ | do | ||
+ | { | ||
+ | vec.append (SubBlob (some_nr3 * 16, 24)); | ||
+ | } | ||
+ | while (some_nr3-- >= 0); | ||
+ | |||
+ | |||
+ | int some_nr3 = (signed) SubBlob (someblob2, 0, 4); | ||
+ | res = dev_0xc1 (some_nr3); | ||
+ | if (res != 0) | ||
+ | | ||
+ | |||
+ | int some_nr4 = (signed) SubBlob (someblob2, 16, 4); | ||
+ | if (some_nr3 == some_nr4) | ||
+ | return 0; | ||
+ | else | ||
+ | return 8; | ||
+ | |||
+ | // is vec returned as well? it's still on the stack. | ||
+ | } | ||
+ | |||
+ | |||
+ | int | ||
+ | dev_0xb7 (any_t thing) | ||
+ | { | ||
+ | if (get_type (thing) != TYPE_BLOB) | ||
+ | return 0; | ||
+ | if (thing[2] == 0x31) | ||
+ | return 2; | ||
+ | else | ||
+ | { | ||
+ | if (! strncmp (thing, " | ||
+ | return 1; | ||
+ | else | ||
+ | return 0; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | block_t | ||
+ | dev_0xd1 (int nr) | ||
+ | { | ||
+ | if (nr > 1) | ||
+ | { | ||
+ | 0x80 (" | ||
+ | return 0; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | return 00 81 00 00 00 00 00 00; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | // Some decrypt function. | ||
+ | // KEYBLOB seems to be 16 byte in practice. | ||
+ | any_t | ||
+ | dev_0xd8 (blob_t ciphertext, blob_t keyblob) | ||
+ | { | ||
+ | blob_t key = keyblob XOR concat (dict[0xfc], | ||
+ | // Side-effect. | ||
+ | dict[0xdb] = key; | ||
+ | |||
+ | blob_t hashed_key = SHA1 (key[0..14]); | ||
+ | blob_t des_iv = hashed_key[0..7]; | ||
+ | blob_t des_key = hashed_key[8..15] | ||
+ | |||
+ | blob_t data = DES_CBC_Decrypt (ciphertext, | ||
+ | |||
+ | // Decrypt with ocmmod cipher. | ||
+ | int len = blob_length (data); | ||
+ | // Round up to multiple of 8. | ||
+ | len = (len + 7) / 8 * 8; | ||
+ | blob_t plaintext = repeat_nul (len); | ||
+ | plaintext = native:: | ||
+ | |||
+ | // Return deserialized object. | ||
+ | return decode_asn1 (plaintext); | ||
+ | } | ||
+ | |||
+ | |||
+ | // Some encrypt function. | ||
+ | // KEYBLOB seems to be 16 byte in practice. | ||
+ | blob_t | ||
+ | dev_0xd9 (any_t plainobj, blob_t keyblob) | ||
+ | { | ||
+ | blob_t key = keyblob XOR concat (dict[0xfc], | ||
+ | // Side-effect. | ||
+ | dict[0xdb] = key; | ||
+ | |||
+ | // Serialization. | ||
+ | plaintext = encode_asn1 (plaintext); | ||
+ | |||
+ | // Encrypt with ocmmod cipher. | ||
+ | int len = blob_length (data); | ||
+ | // Round up to multiple of 8. | ||
+ | len = (len + 7) / 8 * 8; | ||
+ | blob_t data = repeat_nul (len); | ||
+ | blob_t hashed_key = SHA1 (key[0..14]); | ||
+ | data = native:: | ||
+ | |||
+ | // Encrypt DES. | ||
+ | blob_t des_iv = hashed_key[0..7]; | ||
+ | blob_t des_key = hashed_key[8..15] | ||
+ | blob_t ciphertext = DES_CBC_Decrypt (data, des_iv, des_key, 0xd7_DESEncrypt); | ||
+ | |||
+ | return ciphertext; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | NOT part of device.sal, but for lack of a better place, here an example of SsaTrans on updater.ocm: | ||
+ | |||
+ | < | ||
+ | $ SsaTrans updater.ocm | ||
+ | BCSeedRand63 (1, " | ||
+ | BCSetCryptTable (" | ||
+ | v_39 = BCNewBlob (8); | ||
+ | v_41 = BCDES_SetKey (" | ||
+ | arg_0 = Unknown | ||
+ | v_43 = BCDES_CBC BCDDecrypt (arg_0, v_39, v_41, " | ||
+ | v_44 = BCBlobLength (v_43); | ||
+ | v_46 = BCBlobLength ("< | ||
+ | v_49 = BCSubBlob (v_43, v_44 - v_46, -1); | ||
+ | v_51 = BCCompareBlob (v_49, "< | ||
+ | if (v_51 == 0) [1 -> 1] | ||
+ | { | ||
+ | return [v_43, 1]; | ||
+ | } | ||
+ | else [1 -> 1] | ||
+ | { | ||
+ | return [0]; | ||
+ | } | ||
+ | v_56 = BCIfElse (v_43); | ||
+ | v_57 = BCSerialize (v_56); | ||
+ | return v_57; | ||
+ | </ |
devicesal.1241508941.txt.gz · Last modified: 2009/05/05 07:35 (external edit)