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

📄 psfdemux_drm.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
			type = DEMUX_WRITE_AES_128BITS_KEY_IV;		break;	      	case EMhwlibCipher_RC4:    /* 2 */		RMDBGLOG(( ENABLE, "Unimplemented cipher type \n" ));		status = RM_NOTIMPLEMENTED;		goto error_exit;	case EMhwlibCipher_DVD:    /* 3 */		RMDBGLOG(( ENABLE, "Unimplemented cipher type \n" ));		status = RM_NOTIMPLEMENTED;		goto error_exit;	case EMhwlibCipher_Multi2: /* 4 */		is_multi2 = TRUE; /* special case */		break;	case EMhwlibCipher_DVBCSA: /* 5 */		type = DEMUX_WRITE_DVB_64BITS;		break;	case EMhwlibCipher_C2:      /* 6 */	default:		RMDBGLOG(( ENABLE, "Unknow cipher type \n" ));		status = RM_NOTIMPLEMENTED;		goto error_exit;	}	if( is_multi2 ) {	/*		TODO: write key for multi2 		DEMUX_WRITE_MULTI2_SYSTEM_KEY,		DEMUX_WRITE_MULTI2_256BITS_DATA_KEY,		DEMUX_WRITE_MULTI2_DATA_KEY,		DEMUX_WRITE_MULTI2_IV,		DEMUX_WRITE_MULTI2	*/		RMDBGLOG(( ENABLE, "multi2 not implemented \n" ));		status = RM_NOTIMPLEMENTED;		goto error_exit;	}	/* Allocate an RUA buffer for XRPC commuication */	xrpc_base_addr = RUAMalloc(pRUA, 0, RUA_DRAM_UNPROTECTED, xrpc_size);	if (xrpc_base_addr == 0) {		RMDBGLOG(( ENABLE, "RUAMalloc failed\n" ));		status = RM_ERROR;		goto error_exit;	}	status = initDemuxWriteKey(xrpc_base_addr,xrpc_size,1);	if ( status != RM_OK ) {		RMDBGLOG(( ENABLE, "initDemuxWriteKey error \n" ));		goto error_exit;	}#define GENERATE_KEY#ifdef GENERATE_KEY	if( type != DEMUX_WRITE_AES_128BITS_KEY_IV ){		status = RM_NOTIMPLEMENTED;		goto error_exit;	}	/* harded xpu key index and aes key ram key index */	status = generateInternalDemuxAesKey( context->recipher_xpu_key );	if ( status != RM_OK ) {		status = RM_ERROR;		RMDBGLOG(( ENABLE, "generateDemuxAesKey error \n" ));		/* fall through try to terminate the module */	}	fprintf(stderr, "generateInternalDemuxAesKey xpu_key %ld  %s \n",                          context->recipher_xpu_key, status == RM_OK ? "OK" : "FAIL");	status = setInternalDemuxAesKey( context->recipher_xpu_key, /* key index in xpu's storage */					 key_index ); /* key index in AES cipher's key ram */				   	fprintf(stderr, "SetInternalDemuxAesKey xpu_index %ld to demux_key %ld  %s\n",                         context->recipher_xpu_key, key_index, status == RM_OK ? "OK" : "FAIL");	if ( status != RM_OK ) {		status = RM_ERROR;		RMDBGLOG(( ENABLE, "setInternalDemuxAesKey error \n" ));		/* fall through try to terminate the module */	}#else	status = setDemuxCipherKey( pKey, type, FALSE, key_index );	if ( status != RM_OK ) {		status = RM_ERROR;		RMDBGLOG(( ENABLE, "setDemuxWriteKey error \n" ));		/* fall through try to terminate the module */	}#endif	status = termDemuxWriteKey();	if ( status != RM_OK ) {		RMDBGLOG(( ENABLE, "termDemuxWriteKey error \n" ));		goto error_exit;	} error_exit:	if( xrpc_base_addr )		RUAFree( pRUA, xrpc_base_addr );	return status;}#endif /* #ifdef USE_XPU_WRITE_KEY *//************************************************************************ * A portion of ARIB STD B25.pdf -- Page 20 ************************************************************************/static RMstatus ParseAribECM(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, enum key_type *key_type, RMuint8 *key_code){	/* function assumes to be called on correct ECM boundaries */	RMuint8 *		p = 0;		if (pBuffer1 && size1) 		p = pBuffer1;	if (*p == 0x80) {		*key_type = EVEN_KEY;		RMMemcpy(key_code, p + 11, 16);	/* No spec, use Arib replace 	*/	}	else if (*p == 0x81) {		*key_type = ODD_KEY;		RMMemcpy(key_code, p + 11, 16);	/* No spec, use Arib replace 	*/	}	else if (*p == 0x82) {			/* DVD-Arib			*/		*key_type = PAIR_KEY;		RMMemcpy(key_code, p + 11, 16);	/* odd 8bytes, even 8Bytes	*/	}	else {		*key_type = WRONG_KEY;		fprintf(stderr, "ParseAribECM table_id=%02x instead of 0x8? !\n", *p);		return RM_ERROR;	}	return RM_OK;}static RMstatus ParseECM(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, RMstatus err, RMuint32 mask, void *context_in){	struct  context_per_task *context = (struct context_per_task *)context_in;	RMuint8 *p;	RMuint32 key_i;	RMuint32 section_len, ecm_data_compare_len;	RMuint8 section_table_entry = (mask == ECM0_SECTION_MASK) ? ECM0_SECTION_ENTRY : ECM1_SECTION_ENTRY;	p = pBuffer1;	if ( (*p == 0x80) || (*p == 0x81) ) {		section_len = ((*(p + 1) & 0x0F) << 8) | *(p + 2);		if (section_len > 8)			ecm_data_compare_len = RMmin(section_len - 8, 16);		else			ecm_data_compare_len = 0;#if 0		{			RMuint32 i;			fprintf(stderr, "[%02X][%d]@0x%lX:\t", *p, section_table_entry, context->file_byte_counter);			for (i = 0; i < ecm_data_compare_len; i++)				fprintf(stderr, "0x%02X, ", *(p+11+i));			fprintf(stderr, "\n");		}#endif		if (context->app_type == dvbcsa_decryption) {			/* new key detected, identify based on ecm_data the clear key provided in key specific table */#if 0			// Hard code for wired test stream STREAM-4.ts#if 0			// video uses ecm0 (0x501); audio uses ecm1 (0x502);			if (*p == 0x80) {				key_i = 0 + ((mask == ECM0_SECTION_MASK) ? 0 : 2);			}			else {				key_i = 1 + ((mask == ECM0_SECTION_MASK) ? 0 : 2);			}			fprintf(stderr, "ParseECM DVB-CSA new key [%02x] at byte counter = 0x%lx key_position=%ld\n", *p, context->file_byte_counter, key_i);			((struct dvb_csa_key *)context->pkey_table)[key_i].renew = TRUE;			((struct dvb_csa_key *)context->pkey_table)[key_i].ecm_entry = section_table_entry;			((struct dvb_csa_key *)context->pkey_table)[key_i].key_byte_counter = context->file_byte_counter;			((struct dvb_csa_key *)context->pkey_table)[key_i].scrambling = (*p == 0x80) ? EMhwlibScramblingBits_10 : EMhwlibScramblingBits_11;#else			// video and audio uses ecm0 (0x501)			if (*p == 0x80) {				key_i = 0;			}			else {				key_i = 1;			}			fprintf(stderr, "ParseECM DVB-CSA new key [%02x] at byte counter = 0x%lx key_position=%ld\n", *p, context->file_byte_counter, key_i);			((struct dvb_csa_key *)context->pkey_table)[key_i].renew = TRUE;			((struct dvb_csa_key *)context->pkey_table)[key_i].ecm_entry = section_table_entry;			((struct dvb_csa_key *)context->pkey_table)[key_i].key_byte_counter = context->file_byte_counter;			((struct dvb_csa_key *)context->pkey_table)[key_i].scrambling = (*p == 0x80) ? EMhwlibScramblingBits_10 : EMhwlibScramblingBits_11;			((struct dvb_csa_key *)context->pkey_table)[key_i + 2].renew = TRUE;			((struct dvb_csa_key *)context->pkey_table)[key_i + 2].ecm_entry = section_table_entry + 1;			((struct dvb_csa_key *)context->pkey_table)[key_i + 2].key_byte_counter = context->file_byte_counter;			((struct dvb_csa_key *)context->pkey_table)[key_i + 2].scrambling = (*p == 0x80) ? EMhwlibScramblingBits_10 : EMhwlibScramblingBits_11;#endif#else			for (key_i = 0; key_i < context->key_table_size; key_i++) {				if (RMMemcmp((void*)(p+11), (void *)((struct dvb_csa_key *)context->pkey_table)[key_i].ecm_data, ecm_data_compare_len)==0) {					fprintf(stderr, "ParseECM DVB-CSA new key [%02x] at byte counter = 0x%lx key_position=%ld\n", *p, context->file_byte_counter, key_i);					((struct dvb_csa_key *)context->pkey_table)[key_i].renew = TRUE;					((struct dvb_csa_key *)context->pkey_table)[key_i].ecm_entry = section_table_entry;					((struct dvb_csa_key *)context->pkey_table)[key_i].key_byte_counter = context->file_byte_counter;					((struct dvb_csa_key *)context->pkey_table)[key_i].scrambling = (*p == 0x80) ? EMhwlibScramblingBits_10 : EMhwlibScramblingBits_11;					break;				}			}#endif		}		else if ((context->app_type == aes_cbc_decryption) || 				(context->app_type == aes_ecb_decryption) ||				(context->app_type == aes_nsa_decryption) ||				(context->app_type == aes_ofb_decryption) ) {			/* new key detected, identify based on ecm_data the clear key provided in key specific table */			for (key_i = 0; key_i < context->key_table_size; key_i++) {				if (RMMemcmp((void*)(p+11), (void *)((struct aes_key *)context->pkey_table)[key_i].ecm_data, ecm_data_compare_len)==0) {					fprintf(stderr, "ParseECM AES new key [%02x] at byte counter = 0x%lx key_position=%ld\n", *p, context->file_byte_counter, key_i);					((struct aes_key *)context->pkey_table)[key_i].renew = TRUE;					((struct aes_key *)context->pkey_table)[key_i].ecm_entry = section_table_entry;					((struct aes_key *)context->pkey_table)[key_i].key_byte_counter = context->file_byte_counter;					((struct aes_key *)context->pkey_table)[key_i].scrambling = (*p == 0x80) ? EMhwlibScramblingBits_10 : EMhwlibScramblingBits_11;					break;				}			}		}				{ /* filter only a new ecm version in hardware section filter - in order to optimize CPU usage on standalone */			/* mask ECM for next parity */			struct DemuxTask_MatchSectionEntry_type section_entry;			//fprintf(stderr, "@0x%lX ParseECM tag is 0x%02x for [%d], change to 0x%02x\n", context->file_byte_counter, (*p),  section_table_entry, (*p) ^ 1);			context->match_section_table[section_table_entry].section_entry.mask[0] = 0xFF;			context->match_section_table[section_table_entry].section_entry.comp[0] = (*p) ^ 1;			section_entry.Index = context->match_section_table[section_table_entry].index;			section_entry.SectionEntry = context->match_section_table[section_table_entry].section_entry;			err = RUASetProperty(context->pRUA, context->demux_task, RMDemuxTaskPropertyID_MatchSectionEntry, &section_entry, sizeof(section_entry), 0);			if (RMFAILED(err)) {				fprintf(stderr, "decoder: Error RMDemuxTaskPropertyID_MatchSectionEntry");				return RM_ERROR;			}		}	}	return RM_OK;}void ECMCallback(RMuint8 *pBuffer1, RMuint32 size1, RMuint8 *pBuffer2, RMuint32 size2, RMstatus err, RMuint32 mask, void *context_in){	RMuint8		key_code[16];  // for both EVEN/ODD key inside ECM packet	enum key_type	key_type;		/* EVEN? ODD? PAIR? or BAD key	*/	RMuint32 cipher_i;	struct context_per_task *context = (struct context_per_task *)context_in;	struct arib_key_band *ecm_key = context->arib_key_table; 	struct dvb_arib_key *key_table = (struct dvb_arib_key *)context->pkey_table;	RMuint8	* last_key_code = context->prev_encrypted_key;	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "ECMCallback ERROR\n"));		return;	}#ifdef MULTI2_EIGHT_KEYS	// hard code the mapping between section filters and cipher entry because this mapping is hard coded in psfdemux_parsing	cipher_i = 	(mask == ECM0_SECTION_MASK) ? 0 : 				(mask == ECM1_SECTION_MASK) ? 1 :				(mask == (1<<(DATA_SEC+7 ))) ? 2 :				(mask == (1<<(DATA_SEC+8 ))) ? 3 :				(mask == (1<<(DATA_SEC+9 ))) ? 4 :				(mask == (1<<(DATA_SEC+10 ))) ? 5 :				(mask == (1<<(DATA_SEC+11 ))) ? 6 :				(mask == (1<<(DATA_SEC+12 ))) ? 7 :						0xff;  //bad index causes a crash#else //#ifdef MULTI2_EIGHT_KEYS	cipher_i = 	(mask == ECM0_SECTION_MASK) ? 0 : 1; // two pair of keys#endif 	RMDBGLOG((DISABLE, "ECMCallback for %d\n", cipher_i));	/*	 * TODO --	 * Pass the ECM package to customer's sand box	 * Fox example:	 * 	 * TX4939_ECM(pBuffer1, size1, pBuffer2, size2, &key_type, key_code);	 */	// DVB-Arib: extract EVEV/ODD key from ECM packet	ParseAribECM(pBuffer1, size1, pBuffer2, size2, &key_type, key_code);		if  ((context->app_type == multi2_decryption) && (key_type == PAIR_KEY)) { 		if(RMMemcmp((void*)last_key_code, (void *)key_code, 16) != 0) { // new key arriaved			RMuint32 match;			RMuint32 key_i;						RMMemcpy(last_key_code, key_code, 16);			// find the encrypted key patten in the pattern-clearkey table			for( match = 0; match < context->key_table_size; match++ ) {				if (RMMemcmp((void*)last_key_code, (void *)key_table[match].pair_key, 16) == 0) {					break; // find the real key				}			}			if( match >= context->key_table_size ) { // pattern not found, no clear key				RMDBGLOG((KEYDBG, "cannot find pattern 0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x \n",						key_code[0], key_code[1], key_code[2], key_code[3], key_code[4], key_code[5], key_code[6], key_code[7], 						key_code[8], key_code[9], key_code[10], key_code[11], key_code[12], key_code[13], key_code[14], key_code[15] ));				return;			}			else{				RMDBGLOG((KEYDBG, "found pattern 0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x \n",						key_code[0], key_code[1], key_code[2], key_code[3], key_code[4], key_code[5], key_code[6], key_code[7], 						key_code[8], key_code[9], key_code[10], key_code[11], key_code[12], key_code[13], key_code[14], key_code[15] ));			}			// find which key to load			key_i = cipher_i * 2;			ecm_key[key_i].index_cipher_table = context->cipher_index[cipher_i];			ecm_key[key_i+1].index_cipher_table = context->cipher_index[cipher_i];						// update system key and iv for all ecm  in case they change			RMMemcpy(ecm_key[key_i].multi2_key.system_key, key_table[match].sys_key, 32);			RMMemcpy(ecm_key[key_i].multi2_key.iv, key_table[match].cbc_iv, 8);			RMMemcpy(ecm_key[key_i+1].multi2_key.system_key, key_table[match].sys_key, 32);			RMMemcpy(ecm_key[key_i+1].multi2_key.iv, key_table[match].cbc_iv, 8); 			// Handle EVEN key first -- keep the index of Multi2Table			if (RMMemcmp((void*)(ecm_key[key_i].multi2_key.data_key), (void *)(key_table[match].data + 8), 8) != 0) {				RMMemcpy(ecm_key[key_i].multi2_key.data_key, (key_table[match].data + 8), 8);				RMMemcpy(ecm_key[key_i].cipher_text, (key_table[match].cipher + 32), 32 * sizeof(RMuint32));				ecm_key[key_i].new_key = TRUE;				context->ecm = TRUE;  // inform the main loop to load the key				RMDBGLOG((KEYDBG, "update new even key cipher %ld key %ld\n", context->cipher_index[cipher_i], ecm_key[key_i].multi2_key.key_index));			}			// Then handle ODD key -- keep the index of Multi2Table			if (RMMemcmp((void*)(ecm_key[key_i+1].multi2_key.data_key), (void *)(key_table[match].data), 8) != 0) {				RMMemcpy(ecm_key[key_i+1].multi2_key.data_key, key_table[match].data, 8);				RMMemcpy(ecm_key[key_i+1].cipher_text, key_table[match].cipher, 32 * sizeof(RMuint32));				ecm_key[key_i+1].new_key = TRUE;				context->ec

⌨️ 快捷键说明

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