From 7a58bc01979b9de4cfc942805bed8cab923c2ff6 Mon Sep 17 00:00:00 2001 From: arpi Date: Sat, 30 Aug 2003 13:35:25 +0000 Subject: synced to libdvdcss 1.2.8 (except the DVDCSS_PATH guessing, we use our get_path() instead). anyway it's mostly cosmetics only. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10721 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpdvdkit2/common.h | 4 +++ libmpdvdkit2/css.c | 55 ++++++++++++++++++++++------------- libmpdvdkit2/error.c | 1 + libmpdvdkit2/libdvdcss.c | 75 ++++++++++++++++++++++-------------------------- 4 files changed, 75 insertions(+), 60 deletions(-) diff --git a/libmpdvdkit2/common.h b/libmpdvdkit2/common.h index f99a67b2d8..2cd0aab8e2 100644 --- a/libmpdvdkit2/common.h +++ b/libmpdvdkit2/common.h @@ -31,6 +31,10 @@ #if defined( WIN32 ) +#ifndef PATH_MAX +# define PATH_MAX MAX_PATH +#endif + /* several type definitions */ # if defined( __MINGW32__ ) # if !defined( _OFF_T_ ) diff --git a/libmpdvdkit2/css.c b/libmpdvdkit2/css.c index 59870b8099..ed3aa4a25a 100644 --- a/libmpdvdkit2/css.c +++ b/libmpdvdkit2/css.c @@ -405,7 +405,7 @@ int _dvdcss_title ( dvdcss_t dvdcss, int i_block ) *****************************************************************************/ int _dvdcss_disckey( dvdcss_t dvdcss ) { - unsigned char p_buffer[2048]; + unsigned char p_buffer[ DVD_DISCKEY_SIZE ]; dvd_key_t p_disc_key; int i; @@ -432,7 +432,7 @@ int _dvdcss_disckey( dvdcss_t dvdcss ) } /* Decrypt disc key using bus key */ - for( i = 0 ; i < 2048 ; i++ ) + for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ ) { p_buffer[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ]; } @@ -490,7 +490,7 @@ int _dvdcss_disckey( dvdcss_t dvdcss ) *****************************************************************************/ int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) { - static uint8_t p_garbage[ 2048 ]; /* static because we never read it */ + static uint8_t p_garbage[ DVDCSS_BLOCK_SIZE ]; /* we never read it back */ uint8_t p_key[ KEY_SIZE ]; int i, i_ret = 0; @@ -523,7 +523,7 @@ int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) { case -1: /* An error getting the ASF status, something must be wrong. */ - _dvdcss_debug( dvdcss, "lost ASF reqesting title key" ); + _dvdcss_debug( dvdcss, "lost ASF requesting title key" ); ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); i_ret = -1; break; @@ -531,7 +531,7 @@ int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) case 0: /* This might either be a title that has no key, * or we encountered a region error. */ - _dvdcss_debug( dvdcss, "lost ASF reqesting title key" ); + _dvdcss_debug( dvdcss, "lost ASF requesting title key" ); break; case 1: @@ -554,7 +554,7 @@ int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) p_key[ i ] ^= dvdcss->css.p_bus_key[ 4 - (i % KEY_SIZE) ]; } - /* If p_key is all zero then there realy wasn't any key pressent + /* 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] ) ) { @@ -606,7 +606,7 @@ int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) 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 + 0x800; + uint8_t *p_end = p_sec + DVDCSS_BLOCK_SIZE; /* PES_scrambling_control */ if( p_sec[0x14] & 0x30) @@ -990,7 +990,7 @@ static int DecryptDiscKey( uint8_t const *p_struct_disckey, { 0xfc, 0x95, 0xa9, 0x87, 0x35 } }; - /* Decrypt disc key with player keys from csskeys.h */ + /* Decrypt disc key with the above player keys */ while( n < sizeof(player_keys) / sizeof(dvd_key_t) ) { for( i = 1; i < 409; i++ ) @@ -1000,7 +1000,7 @@ static int DecryptDiscKey( uint8_t const *p_struct_disckey, p_disc_key ); /* The first part in the struct_disckey block is the - * 'disc key' encrypted with it self. Using this we + * 'disc key' encrypted with itself. Using this we * can check if we decrypted the correct key. */ DecryptKey( 0, p_disc_key, p_struct_disckey, p_verify ); @@ -1247,7 +1247,7 @@ end: * Function designed by Frank Stevenson ***************************************************************************** * Called from Attack* which are in turn called by CrackTitleKey. Given - * a guessed(?) plain text and the chiper text. Returns -1 on failure. + * a guessed(?) plain text and the cipher text. Returns -1 on failure. *****************************************************************************/ static int RecoverTitleKey( int i_start, uint8_t const *p_crypted, uint8_t const *p_decrypted, @@ -1397,11 +1397,12 @@ static int i_tries = 0, i_success = 0; static int CrackTitleKey( dvdcss_t dvdcss, int i_pos, int i_len, dvd_key_t p_titlekey ) { - uint8_t p_buf[0x800]; + uint8_t p_buf[ DVDCSS_BLOCK_SIZE ]; const uint8_t p_packstart[4] = { 0x00, 0x00, 0x01, 0xba }; int i_reads = 0; int i_encrypted = 0; int b_stop_scanning = 0; + int b_read_error = 0; int i_ret; _dvdcss_debug( dvdcss, "cracking title key" ); @@ -1428,6 +1429,18 @@ static int CrackTitleKey( dvdcss_t dvdcss, int i_pos, int i_len, { _dvdcss_debug( dvdcss, "read returned 0 (end of device?)" ); } + else if( !b_read_error ) + { + _dvdcss_debug( dvdcss, "read error, resorting to secret " + "arcanes to recover" ); + + /* Reset the drive before trying to continue */ + _dvdcss_close( dvdcss ); + _dvdcss_open( dvdcss ); + + b_read_error = 1; + continue; + } break; } @@ -1478,8 +1491,10 @@ static int CrackTitleKey( dvdcss_t dvdcss, int i_pos, int i_len, } while( !b_stop_scanning && i_len > 0); - if( i_len <= 0 ) + if( !b_stop_scanning ) + { _dvdcss_debug( dvdcss, "end of title reached" ); + } { /* Print some statistics. */ char psz_info[128]; @@ -1514,7 +1529,7 @@ static int CrackTitleKey( dvdcss_t dvdcss, int i_pos, int i_len, * Then it guesses that the plain text for first encrypted bytes are * a contiuation of that pattern. *****************************************************************************/ -static int AttackPattern( uint8_t const p_sec[0x800], +static int AttackPattern( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ], int i_pos, uint8_t *p_key ) { unsigned int i_best_plen = 0; @@ -1574,13 +1589,13 @@ static int AttackPattern( uint8_t const p_sec[0x800], * DVD specifies that there must only be one type of data in every sector. * Every sector is one pack and so must obviously be 2048 bytes long. * For the last pice of video data before a VOBU boundary there might not - * be exactly the right amount of data to fill a sector. They one has to - * pad the pack to 2048 bytes. For just a few bytes this is doen in the + * be exactly the right amount of data to fill a sector. Then one has to + * pad the pack to 2048 bytes. For just a few bytes this is done in the * header but for any large amount you insert a PES packet from the * Padding stream. This looks like 0x00 00 01 be xx xx ff ff ... * where xx xx is the length of the padding stream. *****************************************************************************/ -static int AttackPadding( uint8_t const p_sec[0x800], +static int AttackPadding( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ], int i_pos, uint8_t *p_key ) { unsigned int i_pes_length; @@ -1589,18 +1604,18 @@ static int AttackPadding( uint8_t const p_sec[0x800], i_pes_length = (p_sec[0x12]<<8) | p_sec[0x13]; /* Coverd by the test below but usfull for debuging. */ - if( i_pes_length == 0x800 - 0x14 ) return 0; + if( i_pes_length == DVDCSS_BLOCK_SIZE - 0x14 ) return 0; /* There must be room for at least 4? bytes of padding stream, * and it must be encrypted. * sector size - pack/pes header - padding startcode - padding length */ - if( ( 0x800 - 0x14 - 4 - 2 - i_pes_length < 4 ) || + if( ( DVDCSS_BLOCK_SIZE - 0x14 - 4 - 2 - i_pes_length < 4 ) || ( p_sec[0x14 + i_pes_length + 0] == 0x00 && p_sec[0x14 + i_pes_length + 1] == 0x00 && p_sec[0x14 + i_pes_length + 2] == 0x01 ) ) { fprintf( stderr, "plain %d %02x:%02x:%02x:%02x (type %02x sub %02x)\n", - 0x800 - 0x14 - 4 - 2 - i_pes_length, + DVDCSS_BLOCK_SIZE - 0x14 - 4 - 2 - i_pes_length, p_sec[0x14 + i_pes_length + 0], p_sec[0x14 + i_pes_length + 1], p_sec[0x14 + i_pes_length + 2], @@ -1610,7 +1625,7 @@ static int AttackPadding( uint8_t const p_sec[0x800], } /* If we are here we know that there is a where in the pack a - encrypted PES header is (startcode + lenght). It's never more + encrypted PES header is (startcode + length). It's never more than two packets in the pack, so we 'know' the length. The plaintext at offset (0x14 + i_pes_length) will then be 00 00 01 e0/bd/be xx xx, in the case of be the following bytes diff --git a/libmpdvdkit2/error.c b/libmpdvdkit2/error.c index c289fd98ee..3cbccd08af 100644 --- a/libmpdvdkit2/error.c +++ b/libmpdvdkit2/error.c @@ -24,6 +24,7 @@ #include "config.h" #include +#include #include #include "dvdcss.h" diff --git a/libmpdvdkit2/libdvdcss.c b/libmpdvdkit2/libdvdcss.c index 4ea767ea9c..32bfbfcfd4 100644 --- a/libmpdvdkit2/libdvdcss.c +++ b/libmpdvdkit2/libdvdcss.c @@ -151,6 +151,7 @@ char * dvdcss_interface_2 = VERSION; */ extern dvdcss_t dvdcss_open ( char *psz_target ) { + char psz_buffer[PATH_MAX]; int i_ret; char *psz_method = getenv( "DVDCSS_METHOD" ); @@ -190,15 +191,10 @@ extern dvdcss_t dvdcss_open ( char *psz_target ) */ if( psz_verbose != NULL ) { - switch( atoi( psz_verbose ) ) - { - case 2: - dvdcss->b_debug = 1; - case 1: - dvdcss->b_errors = 1; - case 0: - break; - } + int i = atoi( psz_verbose ); + + if( i >= 2 ) dvdcss->b_debug = 1; + if( i >= 1 ) dvdcss->b_errors = 1; } /* @@ -292,19 +288,12 @@ extern dvdcss_t dvdcss_open ( char *psz_target ) } } -#ifndef WIN32 - if( psz_raw_device != NULL ) - { - _dvdcss_raw_open( dvdcss, psz_raw_device ); - } -#endif - /* If the cache is enabled, extract a unique disc ID */ if( psz_cache ) { uint8_t p_sector[DVDCSS_BLOCK_SIZE]; unsigned char psz_debug[PATH_MAX+30]; - unsigned char * psz_data; + unsigned char * psz_title, * psz_serial; int i; /* We read sector 0. If it starts with 0x000001ba (BE), we are @@ -345,40 +334,37 @@ extern dvdcss_t dvdcss_open ( char *psz_target ) } /* Get the disc title */ - psz_data = p_sector + 40; - psz_data[32] = '\0'; + psz_title = p_sector + 40; + psz_title[32] = '\0'; for( i = 0 ; i < 32 ; i++ ) { - if( psz_data[i] <= ' ' ) + if( psz_title[i] <= ' ' ) { - psz_data[i] = '\0'; + psz_title[i] = '\0'; break; } - else if( psz_data[i] == '/' || psz_data[i] == '\\' ) + else if( psz_title[i] == '/' || psz_title[i] == '\\' ) { - psz_data[i] = '-'; + psz_title[i] = '-'; } } - /* If it's not long enough, try the date + serial */ - if( strlen( psz_data ) < 6 ) - { - psz_data = p_sector + 813; - psz_data[16] = '\0'; + /* Get the date + serial */ + psz_serial = p_sector + 813; + psz_serial[16] = '\0'; - /* Check that all characters are digits, otherwise convert. */ - for( i = 0 ; i < 16 ; i++ ) + /* Check that all characters are digits, otherwise convert. */ + for( i = 0 ; i < 16 ; i++ ) + { + if( psz_serial[i] < '0' || psz_serial[i] > '9' ) { - if( psz_data[i] < '0' || psz_data[i] > '9' ) - { - sprintf( psz_data, - "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X", - psz_data[0], psz_data[1], psz_data[2], - psz_data[3], psz_data[4], psz_data[5], - psz_data[6], psz_data[7] ); - break; - } + sprintf( psz_serial, + "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X", + psz_serial[0], psz_serial[1], psz_serial[2], + psz_serial[3], psz_serial[4], psz_serial[5], + psz_serial[6], psz_serial[7] ); + break; } } @@ -395,8 +381,10 @@ extern dvdcss_t dvdcss_open ( char *psz_target ) dvdcss->psz_cachefile[0] = '\0'; goto nocache; } + i += sprintf( dvdcss->psz_cachefile + i, "/"); - i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_data ); +// i += sprintf( dvdcss->psz_cachefile + i, "/%s", psz_data ); + i += sprintf( dvdcss->psz_cachefile + i, "/%s#%s", psz_title, psz_serial ); #if !defined( WIN32 ) || defined( SYS_CYGWIN ) i_ret = mkdir( dvdcss->psz_cachefile, 0755 ); #else @@ -419,6 +407,13 @@ extern dvdcss_t dvdcss_open ( char *psz_target ) } nocache: +#ifndef WIN32 + if( psz_raw_device != NULL ) + { + _dvdcss_raw_open( dvdcss, psz_raw_device ); + } +#endif + /* Seek at the beginning, just for safety. */ dvdcss->pf_seek( dvdcss, 0 ); -- cgit v1.2.3