📄 css.c
字号:
if( GetBusKey( dvdcss ) < 0 )
{
return -1;
}
/* Get encrypted disc key */
if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
{
_dvdcss_error( dvdcss, "ioctl ReadDiscKey failed" );
return -1;
}
/* This should have invaidated the AGID and got us ASF=1. */
if( GetASF( dvdcss ) != 1 )
{
/* Region mismatch (or region not set) is the most likely source. */
_dvdcss_error( dvdcss,
"ASF not 1 after reading disc key (region mismatch?)" );
ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
return -1;
}
/* Decrypt disc key using bus key */
for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ )
{
p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ];
}
switch( dvdcss->i_method )
{
case DVDCSS_METHOD_KEY:
/* Decrypt disc key with player key. */
_dvdcss_debug( dvdcss, "decrypting disc key with player keys" );
if( ! DecryptDiscKey( p_buffer, p_disc_key ) )
{
PrintKey( dvdcss, "decrypted disc key is ", p_disc_key );
break;
}
_dvdcss_debug( dvdcss, "failed to decrypt the disc key, "
"faulty drive/kernel? "
"cracking title keys instead" );
/* Fallback, but not to DISC as the disc key might be faulty */
dvdcss->i_method = DVDCSS_METHOD_TITLE;
break;
case DVDCSS_METHOD_DISC:
/* Crack Disc key to be able to use it */
_dvdcss_debug( dvdcss, "cracking disc key from key hash ..."
" this will take some time" );
memcpy( p_disc_key, p_buffer, KEY_SIZE );
if( ! CrackDiscKey( dvdcss, p_disc_key ) )
{
PrintKey( dvdcss, "cracked disc key is ", p_disc_key );
break;
}
_dvdcss_debug( dvdcss, "failed to crack the disc key" );
memset( p_disc_key, 0, KEY_SIZE );
dvdcss->i_method = DVDCSS_METHOD_TITLE;
break;
default:
_dvdcss_debug( dvdcss, "disc key needs not be decrypted" );
memset( p_disc_key, 0, KEY_SIZE );
break;
}
memcpy( dvdcss->css.p_disc_key, p_disc_key, KEY_SIZE );
return 0;
}
/*****************************************************************************
* _dvdcss_titlekey: get title key.
*****************************************************************************/
int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key )
{
static uint8_t p_garbage[ DVDCSS_BLOCK_SIZE ]; /* we never read it back */
uint8_t p_key[ KEY_SIZE ];
int i, i_ret = 0;
if( dvdcss->b_ioctls && ( dvdcss->i_method == DVDCSS_METHOD_KEY ||
dvdcss->i_method == DVDCSS_METHOD_DISC ) )
{
/* We have a decrypted Disc key and the ioctls are available,
* read the title key and decrypt it.
*/
_dvdcss_debug( dvdcss, "getting title key the classic way" );
/* We need to authenticate again every time to get a new session key */
if( GetBusKey( dvdcss ) < 0 )
{
return -1;
}
/* Get encrypted title key */
if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid,
i_pos, p_key ) < 0 )
{
_dvdcss_debug( dvdcss,
"ioctl ReadTitleKey failed (region mismatch?)" );
i_ret = -1;
}
/* Test ASF, it will be reset to 0 if we got a Region error */
switch( GetASF( dvdcss ) )
{
case -1:
/* An error getting the ASF status, something must be wrong. */
_dvdcss_debug( dvdcss, "lost ASF requesting title key" );
ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
i_ret = -1;
break;
case 0:
/* This might either be a title that has no key,
* or we encountered a region error. */
_dvdcss_debug( dvdcss, "lost ASF requesting title key" );
break;
case 1:
/* Drive status is ok. */
/* If the title key request failed, but we did not loose ASF,
* we might stil have the AGID. Other code assume that we
* will not after this so invalidate it(?). */
if( i_ret < 0 )
{
ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
}
break;
}
if( !( i_ret < 0 ) )
{
/* Decrypt title key using the bus key */
for( i = 0 ; i < KEY_SIZE ; i++ )
{
p_key[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ];
}
/* If p_key is all zero then there really wasn't any key present
* even though we got to read it without an error. */
if( !( p_key[0] | p_key[1] | p_key[2] | p_key[3] | p_key[4] ) )
{
i_ret = 0;
}
else
{
DecryptTitleKey( dvdcss->css.p_disc_key, p_key );
i_ret = 1;
}
/* All went well either there wasn't a key or we have it now. */
memcpy( p_title_key, p_key, KEY_SIZE );
PrintKey( dvdcss, "title key is ", p_title_key );
return i_ret;
}
/* The title key request failed */
_dvdcss_debug( dvdcss, "resetting drive and cracking title key" );
/* Read an unscrambled sector and reset the drive */
dvdcss->pf_seek( dvdcss, 0 );
dvdcss->pf_read( dvdcss, p_garbage, 1 );
dvdcss->pf_seek( dvdcss, 0 );
_dvdcss_disckey( dvdcss );
/* Fallback */
}
/* METHOD is TITLE, we can't use the ioctls or requesting the title key
* failed above. For these cases we try to crack the key instead. */
/* For now, the read limit is 9Gb / 2048 = 4718592 sectors. */
i_ret = CrackTitleKey( dvdcss, i_pos, 4718592, p_key );
memcpy( p_title_key, p_key, KEY_SIZE );
PrintKey( dvdcss, "title key is ", p_title_key );
return i_ret;
}
/*****************************************************************************
* _dvdcss_unscramble: does the actual descrambling of data
*****************************************************************************
* sec : sector to unscramble
* key : title key for this sector
*****************************************************************************/
int _dvdcss_unscramble( dvd_key_t p_key, uint8_t *p_sec )
{
unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
uint8_t *p_end = p_sec + DVDCSS_BLOCK_SIZE;
/* PES_scrambling_control */
if( p_sec[0x14] & 0x30)
{
i_t1 = (p_key[0] ^ p_sec[0x54]) | 0x100;
i_t2 = p_key[1] ^ p_sec[0x55];
i_t3 = (p_key[2] | (p_key[3] << 8) |
(p_key[4] << 16)) ^ (p_sec[0x56] |
(p_sec[0x57] << 8) | (p_sec[0x58] << 16));
i_t4 = i_t3 & 7;
i_t3 = i_t3 * 2 + 8 - i_t4;
p_sec += 0x80;
i_t5 = 0;
while( p_sec != p_end )
{
i_t4 = p_css_tab2[i_t2] ^ p_css_tab3[i_t1];
i_t2 = i_t1>>1;
i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
i_t4 = p_css_tab5[i_t4];
i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
i_t3 = (i_t3 << 8 ) | i_t6;
i_t6 = p_css_tab4[i_t6];
i_t5 += i_t6 + i_t4;
*p_sec = p_css_tab1[*p_sec] ^ ( i_t5 & 0xff );
p_sec++;
i_t5 >>= 8;
}
}
return 0;
}
/* Following functions are local */
/*****************************************************************************
* GetASF : Get Authentication success flag
*****************************************************************************
* Returns :
* -1 on ioctl error,
* 0 if the device needs to be authenticated,
* 1 either.
*****************************************************************************/
static int GetASF( dvdcss_t dvdcss )
{
int i_asf = 0;
if( ioctl_ReportASF( dvdcss->i_fd, NULL, &i_asf ) != 0 )
{
/* The ioctl process has failed */
_dvdcss_error( dvdcss, "GetASF fatal error" );
return -1;
}
if( i_asf )
{
_dvdcss_debug( dvdcss, "GetASF authenticated, ASF=1" );
}
else
{
_dvdcss_debug( dvdcss, "GetASF not authenticated, ASF=0" );
}
return i_asf;
}
/*****************************************************************************
* CryptKey : shuffles bits and unencrypt keys.
*****************************************************************************
* Used during authentication and disc key negociation in GetBusKey.
* i_key_type : 0->key1, 1->key2, 2->buskey.
* i_variant : between 0 and 31.
*****************************************************************************/
static void CryptKey( int i_key_type, int i_variant,
uint8_t const *p_challenge, uint8_t *p_key )
{
/* Permutation table for challenge */
uint8_t pp_perm_challenge[3][10] =
{ { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
{ 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
{ 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
/* Permutation table for variant table for key2 and buskey */
uint8_t pp_perm_variant[2][32] =
{ { 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 },
{ 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 } };
uint8_t p_variants[32] =
{ 0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73,
0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42,
0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B,
0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 };
/* The "secret" key */
uint8_t p_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 };
uint8_t p_bits[30], p_scratch[10], p_tmp1[5], p_tmp2[5];
uint8_t i_lfsr0_o; /* 1 bit used */
uint8_t i_lfsr1_o; /* 1 bit used */
uint8_t i_css_variant, i_cse, i_index, i_combined, i_carry;
uint8_t i_val = 0;
uint32_t i_lfsr0, i_lfsr1;
int i_term = 0;
int i_bit;
int i;
for (i = 9; i >= 0; --i)
p_scratch[i] = p_challenge[pp_perm_challenge[i_key_type][i]];
i_css_variant = ( i_key_type == 0 ) ? i_variant :
pp_perm_variant[i_key_type-1][i_variant];
/*
* This encryption engine implements one of 32 variations
* one the same theme depending upon the choice in the
* variant 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.
*/
/* 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 ; )
{
p_tmp1[i] = p_scratch[5 + i] ^ p_secret[i] ^ p_crypt_tab2[i];
}
/*
* 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.
*
*/
/* 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.
*/
i_lfsr0 = ( p_tmp1[0] << 17 ) | ( p_tmp1[1] << 9 ) |
(( p_tmp1[2] & ~7 ) << 1 ) | 8 | ( p_tmp1[2] & 7 );
i_lfsr1 = ( p_tmp1[3] << 9 ) | 0x100 | p_tmp1[4];
i_index = sizeof(p_bits);
i_carry = 0;
do
{
for( i_bit = 0, i_val = 0 ; i_bit < 8 ; ++i_bit )
{
i_lfsr0_o = ( ( i_lfsr0 >> 24 ) ^ ( i_lfsr0 >> 21 ) ^
( i_lfsr0 >> 20 ) ^ ( i_lfsr0 >> 12 ) ) & 1;
i_lfsr0 = ( i_lfsr0 << 1 ) | i_lfsr0_o;
i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1;
i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o;
i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o;
/* taking bit 1 */
i_carry = ( i_combined >> 1 ) & 1;
i_val |= ( i_combined & 1 ) << i_bit;
}
p_bits[--i_index] = i_val;
} while( i_index > 0 );
/* This term is used throughout the following to
* select one of 32 different variations on the
* algorithm.
*/
i_cse = p_variants[i_css_variant] ^ p_crypt_tab2[i_css_variant];
/* Now the actual blocks doing the encryption. Each
* of these works on 40 bits at a time and are quite
* similar.
*/
i_index = 0;
for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_scratch[i] )
{
i_index = p_bits[25 + i] ^ p_scratch[i];
i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
p_tmp1[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
}
p_tmp1[4] ^= p_tmp1[0];
for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] )
{
i_index = p_bits[20 + i] ^ p_tmp1[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -