⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg3css.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
		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 + -