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

📄 mpeg3css.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * We use two LFSR's (seeded from some of the input data bytes) to * generate two streams of pseudo-random bits.  These two bit streams * are then combined by simply adding with carry to generate a final * sequence of pseudo-random bits which is stored in the buffer that * 'output' points to the end of - len is the size of this buffer. * * The first LFSR is of degree 25,  and has a polynomial of: * x^13 + x^5 + x^4 + x^1 + 1 * * The second LSFR is of degree 17,  and has a (primitive) polynomial of: * x^15 + x^1 + 1 * * I don't know if these polynomials are primitive modulo 2,  and thus * represent maximal-period LFSR's. * * * Note that we take the output of each LFSR from the new shifted in * bit,  not the old shifted out bit.  Thus for ease of use the LFSR's * are implemented in bit reversed order. * */#define  BIT0(x) ((x) & 1)#define  BIT1(x) (((x) >> 1) & 1)static void generate_bits(unsigned char *output, int len, struct mpeg3_block const *s){	unsigned long lfsr0, lfsr1;	unsigned char carry;	/* In order to ensure that the LFSR works we need to ensure that the	 * initial values are non-zero.  Thus when we initialise them from	 * the seed,  we ensure that a bit is set.	 */	lfsr0 = (s->b[0] << 17) | (s->b[1] << 9) | ((s->b[2] & ~7) << 1) | 8 | (s->b[2] & 7);	lfsr1 = (s->b[3] << 9) | 0x100 | s->b[4];	++output;	carry = 0;	do{		int bit;		unsigned char val;		for (bit = 0, val = 0; bit < 8; ++bit) 		{			unsigned char o_lfsr0, o_lfsr1;	/* Actually only 1 bit each */			unsigned char combined;			o_lfsr0 = ((lfsr0 >> 24) ^ (lfsr0 >> 21) ^ (lfsr0 >> 20) ^ (lfsr0 >> 12)) & 1;			  lfsr0 = (lfsr0 << 1) | o_lfsr0;			o_lfsr1 = ((lfsr1 >> 16) ^ (lfsr1 >> 2)) & 1;			  lfsr1 = (lfsr1 << 1) | o_lfsr1;			combined = !o_lfsr1 + carry + !o_lfsr0;			carry = BIT1(combined);			val |= BIT0(combined) << bit;		}			*--output = val;	}while (--len > 0);}/* * This encryption engine implements one of 32 variations * one the same theme depending upon the choice in the * varient parameter (0 - 31). * * The algorithm itself manipulates a 40 bit input into * a 40 bit output. * The parameter 'input' is 80 bits.  It consists of * the 40 bit input value that is to be encrypted followed * by a 40 bit seed value for the pseudo random number * generators. */static void css_engine(int varient, unsigned char const *input, struct mpeg3_block *output){	unsigned char cse, term, index;	struct mpeg3_block temp1;	struct mpeg3_block temp2;	unsigned char bits[30];	int i;/* Feed the secret into the input values such that * we alter the seed to the LFSR's used above,  then * generate the bits to play with. */	for(i = 5; --i >= 0; )		temp1.b[i] = input[5 + i] ^ mpeg3css_secret[i] ^ mpeg3css_table2[i];	generate_bits(&bits[29], sizeof bits, &temp1);	/* This term is used throughout the following to	 * select one of 32 different variations on the	 * algorithm.	 */	cse = mpeg3css_varients[varient] ^ mpeg3css_table2[varient];	/* Now the actual blocks doing the encryption.  Each	 * of these works on 40 bits at a time and are quite	 * similar.	 */	for(i = 5, term = 0; --i >= 0; term = input[i]) 	{		index = bits[25 + i] ^ input[i];		index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse;		temp1.b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term;	}	temp1.b[4] ^= temp1.b[0];	for(i = 5, term = 0; --i >= 0; term = temp1.b[i]) 	{		index = bits[20 + i] ^ temp1.b[i];		index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse;		temp2.b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term;	}	temp2.b[4] ^= temp2.b[0];	for (i = 5, term = 0; --i >= 0; term = temp2.b[i]) 	{		index = bits[15 + i] ^ temp2.b[i];		index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse;		index = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term;		temp1.b[i] = mpeg3css_table0[index] ^ mpeg3css_table2[index];	}	temp1.b[4] ^= temp1.b[0];	for (i = 5, term = 0; --i >= 0; term = temp1.b[i]) 	{		index = bits[10 + i] ^ temp1.b[i];		index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse;		index = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term;		temp2.b[i] = mpeg3css_table0[index] ^ mpeg3css_table2[index];	}	temp2.b[4] ^= temp2.b[0];	for (i = 5, term = 0; --i >= 0; term = temp2.b[i]) 	{		index = bits[5 + i] ^ temp2.b[i];		index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse;		temp1.b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term;	}	temp1.b[4] ^= temp1.b[0];	for (i = 5, term = 0; --i >= 0; term = temp1.b[i]) 	{		index = bits[i] ^ temp1.b[i];		index = mpeg3css_table1[index] ^ ~mpeg3css_table2[index] ^ cse;		output->b[i] = mpeg3css_table2[index] ^ mpeg3css_table3[index] ^ term;	}}static void crypt_key1(mpeg3_css_t *css, int varient, unsigned char const *challenge, struct mpeg3_block *key){	static unsigned char perm_challenge[] = {1, 3, 0, 7, 5, 2, 9, 6, 4, 8};	unsigned char scratch[10];	int i;	for (i = 9; i >= 0; i--)		scratch[i] = challenge[perm_challenge[i]];	css_engine(varient, scratch, key);}/* This shuffles the bits in varient to make perm_varient such that *                4 -> !3 *                3 ->  4 * varient bits:  2 ->  0  perm_varient bits *                1 ->  2 *                0 -> !1 */static void crypt_key2(mpeg3_css_t *css, int varient, unsigned char const *challenge, struct mpeg3_block *key){	static unsigned char perm_challenge[] = {6, 1, 9, 3, 8, 5, 7, 4, 0, 2};	static unsigned char perm_varient[] = 	{		0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,		0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,		0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,		0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15	};	unsigned char scratch[10];	int i;	for(i = 9; i >= 0; i--)		scratch[i] = css->challenge[perm_challenge[i]];	css_engine(perm_varient[varient], scratch, key);}/* This shuffles the bits in varient to make perm_varient such that *                4 ->  0 *                3 -> !1 * varient bits:  2 -> !4  perm_varient bits *                1 ->  2 *                0 ->  3 */static void crypt_bus_key(mpeg3_css_t *css, int varient, unsigned char const *challenge, struct mpeg3_block *key){	static unsigned char perm_challenge[] = {4,0,3,5,7, 2,8,6,1,9};	static unsigned char perm_varient[] = {		0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,		0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,		0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,		0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d};	unsigned char scratch[10];	int i;	for(i = 9; i >= 0; i--)		scratch[i] = css->challenge[perm_challenge[i]];	css_engine(perm_varient[varient], scratch, key);}static int get_asf(mpeg3_css_t *css){	dvd_authinfo ai;	ai.type = DVD_LU_SEND_ASF;	ai.lsasf.agid = 0;	ai.lsasf.asf = 0;	if(ioctl(css->fd, DVD_AUTH, &ai))	{/* Exit here for a hard drive or unencrypted CD-ROM. */		return 1;	}	return 0;}static int authenticate_drive(mpeg3_css_t *css, const unsigned char *key){	int i;	for(i = 0; i < 5; i++)		css->key1.b[i] = key[4 - i];	for(i = 0; i < 32; ++i)	{		crypt_key1(css, i, css->challenge, &(css->keycheck));		if(memcmp(css->keycheck.b, css->key1.b, 5) == 0)		{			css->varient = i;			return 0;		}	}	if (css->varient == -1) return 1;	return 0;}/* Simulation of a non-CSS compliant host (i.e. the authentication fails, * but idea is here for a real CSS compliant authentication scheme). */static int hostauth(mpeg3_css_t *css, dvd_authinfo *ai){	int i;	switch(ai->type) 	{/* Host data receive (host changes state) */		case DVD_LU_SEND_AGID:			ai->type = DVD_HOST_SEND_CHALLENGE;			break;		case DVD_LU_SEND_KEY1:/* printf("Key 1: %02x %02x %02x %02x %02x\n",  *//* 			ai->lsk.key[4], ai->lsk.key[3], ai->lsk.key[2], ai->lsk.key[1], ai->lsk.key[0]); */			if(authenticate_drive(css, ai->lsk.key)) 			{				ai->type = DVD_AUTH_FAILURE;				return 1;			}			ai->type = DVD_LU_SEND_CHALLENGE;			break;		case DVD_LU_SEND_CHALLENGE:			for(i = 0; i < 10; i++)				css->challenge[i] = ai->hsc.chal[9-i];			crypt_key2(css, css->varient, css->challenge, &(css->key2));			ai->type = DVD_HOST_SEND_KEY2;			break;/* Host data send */		case DVD_HOST_SEND_CHALLENGE:			for(i = 0; i < 10; i++)				ai->hsc.chal[9 - i] = css->challenge[i];/* Returning data, let LU change state */			break;		case DVD_HOST_SEND_KEY2:			for(i = 0; i < 5; i++)			{				ai->hsk.key[4 - i] = css->key2.b[i];			}/* printf("Key 2: %02x %02x %02x %02x %02x\n",  *//* 			ai->hsk.key[4], ai->hsk.key[3], ai->hsk.key[2], ai->hsk.key[1], ai->hsk.key[0]); *//* Returning data, let LU change state */			break;		default:			fprintf(stderr, "Got invalid state %d\n", ai->type);			return 1;	}	return 0;}static int get_title_key(mpeg3_css_t *css, int agid, int lba, unsigned char *key){	dvd_authinfo ai;	int i;	ai.type = DVD_LU_SEND_TITLE_KEY;	ai.lstk.agid = agid;	ai.lstk.lba = lba;	if(ioctl(css->fd, DVD_AUTH, &ai))	{		//perror("GetTitleKey");		return 1;	}	for (i = 0; i < 5; i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -