#ifndef MDS_H #define MDS_H #include #include #include #include "defines.h" // #include "common/crypto.h" #if defined( AES_VAR ) || defined( AES_256 ) #define KS_LENGTH 60 #elif defined( AES_192 ) #define KS_LENGTH 52 #else #define KS_LENGTH 44 #endif #define AES_RETURN int #define TC_LARGEST_COMPILER_UINT uint64_t #define u16 uint16_t typedef union { uint32_t l; uint8_t b[4]; } aes_inf; typedef struct { uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_encrypt_ctx; typedef struct { uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_decrypt_ctx; #ifndef u4byte #define u4byte uint32_t #endif typedef struct { u4byte l_key[40]; u4byte s_key[4]; #if !defined (TC_MINIMIZE_CODE_SIZE) || defined (TC_WINDOWS_BOOT_TWOFISH) u4byte mk_tab[4 * 256]; #endif u4byte k_len; } TwofishInstance; #define AES_KS (sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx)) #define SERPENT_KS (140 * 4) #define TWOFISH_KS sizeof(TwofishInstance) #define MAX_EXPANDED_KEY (AES_KS + SERPENT_KS + TWOFISH_KS) #define MASTER_KEYDATA_SIZE 256 #define PKCS5_SALT_SIZE 64 /* Encryption block length */ #define CBLK_LEN 16 #define CBLK_LEN8 8 typedef struct { /* Union not used to support faster mounting */ uint32_t gf_t128[CBLK_LEN * 2 / 2][16][CBLK_LEN / 4]; uint32_t gf_t64[CBLK_LEN8 * 2][16][CBLK_LEN8 / 4]; } GfCtx; typedef struct CRYPTO_INFO_t { int ea; int mode; uint8_t ks[MAX_EXPANDED_KEY]; uint8_t ks2[MAX_EXPANDED_KEY]; GfCtx gf_ctx; uint8_t master_keydata[MASTER_KEYDATA_SIZE]; uint8_t k2[MASTER_KEYDATA_SIZE]; uint8_t salt[PKCS5_SALT_SIZE]; int noIterations; int pkcs5; } CRYPTO_INFO, *PCRYPTO_INFO; typedef struct Decoder_t { u8 dg[32]; GfCtx gf_ctx; aes_encrypt_ctx encr; aes_decrypt_ctx decr; u8 bsize; int mode; int ctr; } Decoder; enum TRACK_TYPE { TRK_T_MAINTENANCE = 0, TRK_T_AUDIO = 1, TRK_T_MODE1 = 2, TRK_T_MODE2 = 3, TRK_T_MODE2_FORM1 = 4, TRK_T_MODE2_FORM2 = 5 }; enum TRACK_FLAG { TRK_F_TYPE_MASK = 7, TRK_F_EDC = 8, TRK_F_10 = 0x10, TRK_F_HEADER = 0x20, TRK_F_SUBHEADER = 0x40, TRK_F_SYNC = 0x80 }; typedef struct __attribute__((packed)) { u32 f0; u32 f1; u64 f3; //or two u32? } UNK4; typedef struct __attribute__((packed)) { char signature[16]; u8 major; // 0x10 u8 minor; u16 medium_type; // 0x12 u16 num_sessions; // 0x14 u16 _unk1_; u16 _unk2_size_; // 0x18 u16 bca_len; u16 _unk3_size_; // 0x1c u16 _unk4_size_; // 0x1e u32 _unk2_offset_; // 0x20 u32 bca_data_offset; // 0x24 u32 _unk3_offset_; // 0x28 u32 _unk4_offset_; // 0x2c 0x10 byte elements UNK4 u8 _unk5_; // 0x30 u32 _unk6_; // 0x31 u8 _unk7_; // 0x35 u64 _unk8_; // 0x36 u16 _unk9_; // 0x3e u32 disc_structures_offset; // 0x40 u32 _unk10_offset_; // 0x44 u16 _unk10_size_; // 0x48 u8 _dummy1_[6]; // 0x4a not used by DT u32 sessions_blocks_offset; // 0x50 u32 dpm_blocks_offset; // 0x54 u32 encryption_block_offset; // 0x58 u8 _dummy2_[4]; // 0x5c } MDX_Header; // 0x60 typedef struct __attribute__((packed)) { u64 session_start; u16 session_number; // 0x8 u8 num_all_blocks; // 0xa u8 num_nontrack_blocks; // 0xb u16 first_track; // 0xc u16 last_track; // 0xe u32 _dummy_; // 0x10 u32 tracks_blocks_offset; // 0x14 u64 session_end; // 0x18 } MDX_SessionBlock; // 0x20 typedef struct __attribute__((packed)) { u8 mode; u8 subchannel; u8 adr_ctl; u8 tno; u8 point; // 4 u8 min; u8 sec; u8 frame; u8 zero; // 8 u8 pmin; u8 psec; u8 pframe; u32 extra_offset; // 0xc u16 file_block_size; // 0x10 original name. represent full size of data and additional data per sector u8 _unk1_; // 0x12 u8 _dummy1_[5]; // 0x13 u32 _unk2_; // 0x18; u32 _unk3_; // 0x1c; u32 _unk4_; // 0x20; u32 start_sector; // 0x24 u64 start_offset; // 0x28 u32 footer_count; // 0x30 u32 footer_offset; // 0x34 u64 start_sector64; // 0x38 major >= 2 u64 track_size64; // 0x40 major >= 2 u8 _dummy2_[8]; // 0x48 } MDX_TrackBlock; // 0x50 typedef struct __attribute__((packed)) { u32 filename_offset; u8 flags; // 4 u8 _dummy1_; // 5 u16 _unk1_size_; // 6 u32 _unk2_size_; // 8 u32 blocks_in_compression_group; // c major >= 2 u64 track_data_length; // 10 major >= 2 u64 compress_table_offset; // 18 } MDX_Footer; // 0x20 // decode.c #if 0 void DecryptBlock(u8 *buf, TC_LARGEST_COMPILER_UINT len, u32 secSz, u64 secN, u8 flags, PCRYPTO_INFO cryptoInfo); int decode1(u8 *data, const char *pass, PCRYPTO_INFO *ci); void decryptMdxData(Decoder *ctx, u8 *buffer, u32 length, u64 blockSize, u64 blockIndex); #else #ifdef _WIN32 # define MDSXDLLAPI __stdcall #else # define MDSXDLLAPI #endif extern void(MDSXDLLAPI *DecryptBlock)(u8 *buf, TC_LARGEST_COMPILER_UINT len, u32 secSz, u64 secN, u8 flags, PCRYPTO_INFO cryptoInfo); extern int(MDSXDLLAPI *decode1)(u8 *data, const char *pass, PCRYPTO_INFO *ci); extern void(MDSXDLLAPI *decryptMdxData)(Decoder *ctx, u8 *buffer, u32 length, u64 blockSize, u64 blockIndex); extern int(MDSXDLLAPI *Gf128Tab64Init)(uint8_t *a, GfCtx *ctx); extern AES_RETURN(MDSXDLLAPI *aes_encrypt_key)(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); extern AES_RETURN(MDSXDLLAPI *aes_decrypt_key)(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); extern void mdsx_close(void); extern int mdsx_init(void); #endif // utils.c inline static u64 getU64(const void *mem) { const u8 *mem8 = (const u8 *)mem; return ((u64)mem8[0] | ((u64)mem8[1] << 8) | ((u64)mem8[2] << 16) | ((u64)mem8[3] << 24) | ((u64)mem8[4] << 32) | ((u64)mem8[5] << 40) | ((u64)mem8[6] << 48) | ((u64)mem8[7] << 56)); } inline static u32 getU32(const void *mem) { const u8 *mem8 = (const u8 *)mem; return ((u32)mem8[0] | ((u32)mem8[1] << 8) | ((u32)mem8[2] << 16) | ((u32)mem8[3] << 24)); } inline static u16 getU16(const void *mem) { const u8 *mem8 = (const u8 *)mem; return ((u16)mem8[0] | ((u16)mem8[1] << 8)); } inline static u8 getU8(const void *mem) { const u8 *mem8 = (const u8 *)mem; return (u8)mem8[0]; } inline static void setU32(void *mem, u32 val) { u8 *mem8 = (u8 *)mem; mem8[0] = val & 0xff; mem8[1] = (val >> 8) & 0xff; mem8[2] = (val >> 16) & 0xff; mem8[3] = (val >> 24) & 0xff; } u32 freadU32(FILE *f); u64 freadU64(FILE *f); void printHex(void *data, int num); #endif