📄 mpeg3css.c
字号:
{ ai.lstk.title_key[i] ^= key[4 - (i % 5)]; }/* Save the title key */ for(i = 0; i < 5; i++) { css->title_key[i] = ai.lstk.title_key[i]; } return 0;}static int get_disk_key(mpeg3_css_t *css, int agid, unsigned char *key){ dvd_struct s; int index, i; s.type = DVD_STRUCT_DISCKEY; s.disckey.agid = agid; memset(s.disckey.value, 0, MPEG3_DVD_PACKET_SIZE); if(ioctl(css->fd, DVD_READ_STRUCT, &s) < 0) { /*perror("get_disk_key"); */ return 1; } for(index = 0; index < sizeof s.disckey.value; index ++) s.disckey.value[index] ^= key[4 - (index%5)];/* Save disk key */ for(i = 0; i < MPEG3_DVD_PACKET_SIZE; i++) css->disk_key[i] = s.disckey.value[i]; return 0;}static int validate(mpeg3_css_t *css, int lba, int do_title){ dvd_authinfo ai; dvd_struct dvds; int result = 0; int i, rv, tries, agid; memset(&ai, 0, sizeof (ai)); memset(&dvds, 0, sizeof (dvds)); if(get_asf(css)) return 1;/* Init sequence, request AGID */ for(tries = 1, rv = -1; rv == -1 && tries < 4; tries++) { ai.type = DVD_LU_SEND_AGID; ai.lsa.agid = 0; rv = ioctl(css->fd, DVD_AUTH, &ai); if(rv == -1) {/* perror("validate: request AGID"); */ ai.type = DVD_INVALIDATE_AGID; ai.lsa.agid = 0; ioctl(css->fd, DVD_AUTH, &ai); } } if(tries >= 4) return 1; for(i = 0; i < 10; i++) css->challenge[i] = i;/* Send AGID to host */ if(hostauth(css, &ai)) return 1;/* Get challenge from host */ if(hostauth(css, &ai)) return 1; agid = ai.lsa.agid;/* Send challenge to LU */ if(ioctl(css->fd, DVD_AUTH, &ai) < 0) return 1;/* Get key1 from LU */ if(ioctl(css->fd, DVD_AUTH, &ai) < 0) return 1;/* Send key1 to host */ if(hostauth(css, &ai)) return 1;/* Get challenge from LU */ if(ioctl(css->fd, DVD_AUTH, &ai) < 0) return 1;/* Send challenge to host */ if(hostauth(css, &ai)) return 1;/* Get key2 from host */ if(hostauth(css, &ai)) return 1;/* Send key2 to LU */ if(ioctl(css->fd, DVD_AUTH, &ai) < 0) { perror("validate: Send key2 to LU"); return 1; } if(ai.type == DVD_AUTH_FAILURE) { fprintf(stderr, "validate: authorization failed\n"); return 1; } memcpy(css->challenge, css->key1.b, 5); memcpy(css->challenge + 5, css->key2.b, 5); crypt_bus_key(css, css->varient, css->challenge, &(css->keycheck)); get_asf(css); if(do_title) return get_title_key(css, agid, lba, css->keycheck.b); else return get_disk_key(css, agid, css->keycheck.b); return 0;}static int validate_path(mpeg3_css_t *css, int do_title){ int result = 0; int lba = 0, file_fd; if(do_title) { if((file_fd = open(css->path, O_RDONLY)) == -1) { perror("validate_path: open"); return 1; } if(ioctl(file_fd, FIBMAP, &lba) != 0) { perror("validate_path: FIBMAP"); close(file_fd); return 1; } close(file_fd); } result = mpeg3io_device(css->path, css->device_path);//printf("validate_path 1 %d\n", result); if(!result) result = (css->fd = open(css->device_path, O_RDONLY | O_NONBLOCK)) < 0;//printf("validate_path 2 %d\n", result); if(!result) result = validate(css, lba, do_title);//printf("validate_path 3 %d\n", result);/* Definitely encrypted if we got here. */ if(!result) css->encrypted = 1; close(css->fd); return result;}/* * * this function is only used internally when decrypting title key * */static void title_key(unsigned char *key, unsigned char *im, unsigned char invert){ unsigned int lfsr1_lo, lfsr1_hi, lfsr0, combined; unsigned char o_lfsr0, o_lfsr1; unsigned char k[5]; int i; lfsr1_lo = im[0] | 0x100; lfsr1_hi = im[1]; lfsr0 = ((im[4] << 17) | (im[3] << 9) | (im[2] << 1)) + 8 - (im[2]&7); lfsr0 = (bit_reverse[lfsr0 & 0xff] << 24) | (bit_reverse[(lfsr0 >> 8) & 0xff] << 16) | (bit_reverse[(lfsr0 >> 16) & 0xff] << 8) | bit_reverse[(lfsr0 >> 24) & 0xff]; combined = 0; for (i = 0; i < 5; ++i) { o_lfsr1 = lfsr1_bits0[lfsr1_hi] ^ lfsr1_bits1[lfsr1_lo]; lfsr1_hi = lfsr1_lo>>1; lfsr1_lo = ((lfsr1_lo&1)<<8) ^ o_lfsr1; o_lfsr1 = bit_reverse[o_lfsr1]; /*o_lfsr0 = (lfsr0>>7)^(lfsr0>>10)^(lfsr0>>11)^(lfsr0>>19);*/ o_lfsr0 = (((((((lfsr0>>8)^lfsr0)>>1)^lfsr0)>>3)^lfsr0)>>7); lfsr0 = (lfsr0>>8)|(o_lfsr0<<24); combined += (o_lfsr0 ^ invert) + o_lfsr1; k[i] = combined & 0xff; combined >>= 8; } key[4] = k[4] ^ csstab1[key[4]] ^ key[3]; key[3] = k[3] ^ csstab1[key[3]] ^ key[2]; key[2] = k[2] ^ csstab1[key[2]] ^ key[1]; key[1] = k[1] ^ csstab1[key[1]] ^ key[0]; key[0] = k[0] ^ csstab1[key[0]] ^ key[4]; key[4] = k[4] ^ csstab1[key[4]] ^ key[3]; key[3] = k[3] ^ csstab1[key[3]] ^ key[2]; key[2] = k[2] ^ csstab1[key[2]] ^ key[1]; key[1] = k[1] ^ csstab1[key[1]] ^ key[0]; key[0] = k[0] ^ csstab1[key[0]];}/* * * this function decrypts a title key with the specified disk key * * tkey: the unobfuscated title key (XORed with BusKey) * dkey: the unobfuscated disk key (XORed with BusKey) * 2048 bytes in length (though only 5 bytes are needed, see below) * * use the result returned in tkey with css_descramble * */static int decrypt_title_key(mpeg3_css_t *css, unsigned char *dkey, unsigned char *tkey){ unsigned char test[5], pretkey[5]; int i = 0; for(i = 0; mpeg3_playkeys[i]; i++) { memcpy(pretkey, dkey + mpeg3_playkeys[i]->offset, 5); title_key(pretkey, mpeg3_playkeys[i]->key, 0); memcpy(test, dkey, 5); title_key(test, pretkey, 0); if(memcmp(test, pretkey, 5) == 0) break; } if(!mpeg3_playkeys[i]) { fprintf(stderr, "mpeg3_decrypttitlekey: Shit - Need key %d\n", i + 1); return 1; } title_key(css->title_key, pretkey, 0xff); return 0;}/* * * The descrambling core * * sec: encrypted sector (2048 bytes) * key: decrypted title key obtained from css_decrypttitlekey * */#define SALTED(i) (key[i] ^ sec[0x54 - offset + (i)])static void descramble(unsigned char *sec, unsigned char *key, int offset){ unsigned int lfsr1_lo, lfsr1_hi, lfsr0, combined; unsigned char o_lfsr0, o_lfsr1; unsigned char *end = sec + 0x800 - offset; if(offset > 0x54) fprintf(stderr, "mpeg3css.c: descramble: offset > 0x54\n"); lfsr1_lo = SALTED(0) | 0x100; lfsr1_hi = SALTED(1); lfsr0 = ((SALTED(4) << 17) | (SALTED(3) << 9) | (SALTED(2) << 1)) + 8 - (SALTED(2) & 7); lfsr0 = (bit_reverse[lfsr0 & 0xff] << 24) | (bit_reverse[(lfsr0 >> 8) & 0xff] << 16) | (bit_reverse[(lfsr0 >> 16) & 0xff] << 8) | bit_reverse[(lfsr0 >> 24) & 0xff]; sec += 0x80 - offset; combined = 0; while(sec != end) { o_lfsr1 = lfsr1_bits0[lfsr1_hi] ^ lfsr1_bits1[lfsr1_lo]; lfsr1_hi = lfsr1_lo >> 1; lfsr1_lo = ((lfsr1_lo&1) << 8) ^ o_lfsr1; o_lfsr1 = bit_reverse[o_lfsr1]; /*o_lfsr0 = (lfsr0 >> 7) ^ (lfsr0 >> 10) ^ (lfsr0 >> 11) ^ (lfsr0 >> 19);*/ o_lfsr0 = (((((((lfsr0 >> 8) ^ lfsr0) >> 1) ^ lfsr0) >> 3) ^ lfsr0) >> 7); lfsr0 = (lfsr0 >> 8) | (o_lfsr0 << 24); combined += o_lfsr0 + (unsigned char)~o_lfsr1; *sec = csstab1[*sec] ^ (combined & 0xff); sec++; combined >>= 8; }//printf("descramble\n");}/* =============================== Entry Points ================================= */mpeg3_css_t* mpeg3_new_css(){ mpeg3_css_t *css = calloc(1, sizeof(mpeg3_css_t)); css->varient = -1; return css;}int mpeg3_delete_css(mpeg3_css_t *css){ free(css); return 0;}int mpeg3_get_keys(mpeg3_css_t *css, char *path){ int result = 0; strcpy(css->path, path);/* Get disk key */ result = validate_path(css, 0);/* Get title key */ if(!result) result = validate_path(css, 1);/* Descramble the title key */ if(!result) result = decrypt_title_key(css, css->disk_key, css->title_key); return css->encrypted ? result : 0;}/* sector is the full 2048 byte sector */int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector, int offset){//printf("mpeg3_decrypt_packet %d\n", css->encrypted); if(!css->encrypted) return 0; /* Not encrypted */ descramble(sector, css->title_key, offset); return 0;}#else // HAVE_CSS#include "mpeg3css_fake.c"#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -