Here is the patch again, including some code to free the list I created. :( -- Billy Biggs bbiggs@dumbterm.net http://www.billybiggs.com/ wbiggs@uwaterloo.ca -- Attached file included as plaintext by Listar -- diff -urN libdvdcss-0.0.1/extras/libdvdcss/css.c libdvdcss-0.0.1-mod/extras/libdvdcss/css.c --- libdvdcss-0.0.1/extras/libdvdcss/css.c Wed Jun 13 22:47:44 2001 +++ libdvdcss-0.0.1-mod/extras/libdvdcss/css.c Fri Jun 29 11:27:41 2001 @@ -275,12 +275,6 @@ } memcpy( dvdcss->css.disc.pi_key_check, p_buffer, 2048 ); - /* initialize title key to know it empty */ - for( i = 0 ; i < KEY_SIZE ; i++ ) - { - dvdcss->css.pi_title_key[i] = 0; - } - /* Test authentication success */ switch( CSSGetASF( dvdcss ) ) { @@ -309,7 +303,7 @@ ***************************************************************************** * The DVD should have been opened and authenticated before. *****************************************************************************/ -int CSSGetKey( dvdcss_handle dvdcss ) +int CSSGetKey( dvdcss_handle dvdcss, off_t i_pos, dvd_key_t pi_title_key ) { #ifdef HAVE_CSS /* @@ -319,7 +313,6 @@ */ u8 pi_buf[0x800]; dvd_key_t pi_key; - off_t i_pos; boolean_t b_encrypted; boolean_t b_stop_scanning; int i_blocks_read; @@ -335,9 +328,6 @@ b_encrypted = 0; b_stop_scanning = 0; - /* Position of the title on the disc */ - i_pos = (off_t)dvdcss->css.i_title_pos; - do { i_pos = dvdcss_seek( dvdcss, i_pos ); i_blocks_read = dvdcss_read( dvdcss, pi_buf, 1, DVDCSS_NOFLAGS ); @@ -377,7 +367,7 @@ if( b_stop_scanning) { - memcpy( dvdcss->css.pi_title_key, + memcpy( pi_title_key, &pi_key, sizeof(dvd_key_t) ); _dvdcss_debug( dvdcss, "vts key initialized" ); return 0; diff -urN libdvdcss-0.0.1/extras/libdvdcss/css.h libdvdcss-0.0.1-mod/extras/libdvdcss/css.h --- libdvdcss-0.0.1/extras/libdvdcss/css.h Tue Jun 12 18:14:44 2001 +++ libdvdcss-0.0.1-mod/extras/libdvdcss/css.h Fri Jun 29 11:26:43 2001 @@ -39,20 +39,20 @@ u8 i_varient; } disc_t; -typedef struct title_key_s +typedef struct title_key_s title_key_t; + +struct title_key_s { - int i_occ; + int i_startlb; dvd_key_t pi_key; -} title_key_t; + title_key_t *next; +}; typedef struct css_s { int i_agid; disc_t disc; u8 pi_disc_key[2048]; - int i_title; - off_t i_title_pos; - dvd_key_t pi_title_key; } css_t; /***************************************************************************** @@ -62,6 +62,7 @@ int CSSTest ( dvdcss_handle ); int CSSInit ( dvdcss_handle ); -int CSSGetKey ( dvdcss_handle ); +int CSSGetKey ( dvdcss_handle dvdcss, off_t ipos, + dvd_key_t pi_title_key ); int CSSDescrambleSector ( u8 * , u8 * ); diff -urN libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.c libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.c --- libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.c Wed Jun 13 22:47:44 2001 +++ libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.c Fri Jun 29 11:53:02 2001 @@ -94,6 +94,7 @@ } /* Initialize structure */ + dvdcss->pi_key_list = NULL; dvdcss->b_debug = i_flags & DVDCSS_INIT_DEBUG; dvdcss->b_errors = !(i_flags & DVDCSS_INIT_QUIET); dvdcss->psz_error = "no error"; @@ -151,20 +152,36 @@ /***************************************************************************** * dvdcss_crack: crack the current title key *****************************************************************************/ -extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_title, int i_block ) +extern int dvdcss_crack ( dvdcss_handle dvdcss, int i_block ) { - int i_ret; + title_key_t **pi_write_key; + title_key_t **pi_cur_key; + title_key_t *pi_title_key; + dvd_key_t pi_tmp_key; + boolean_t b_empty; + int i_ret, i; if( ! dvdcss->b_encrypted ) { return 0; } - /* Crack CSS title key for current VTS */ - dvdcss->css.i_title = i_title; - dvdcss->css.i_title_pos = i_block; + /* Check if we've already cracked this key */ + pi_title_key = dvdcss->pi_key_list; + while( pi_title_key && pi_title_key->next + && pi_title_key->next->i_startlb < i_block ) + { + pi_title_key = pi_title_key->next; + } + + if( pi_title_key && pi_title_key->i_startlb == i_block ) + { + /* We've already cracked this key, nothing to do */ + return 0; + } - i_ret = CSSGetKey( dvdcss ); + /* Crack CSS title key for current VTS */ + i_ret = CSSGetKey( dvdcss, i_block, pi_tmp_key ); if( i_ret < 0 ) { @@ -177,6 +194,36 @@ return -1; } + /* Add key to keytable if it isn't empty */ + b_empty = 1; + for( i = 0 ; i < KEY_SIZE ; i++ ) + { + if( pi_tmp_key[ i ] ) + { + b_empty = 0; + break; + } + } + + if( !b_empty ) + { + /* Find our spot in the list */ + pi_write_key = &(dvdcss->pi_key_list); + pi_cur_key = pi_write_key; + while( *pi_cur_key && (*pi_cur_key)->i_startlb < i_block ) + { + pi_write_key = pi_cur_key; + pi_cur_key = &((*pi_cur_key)->next); + } + + /* Write in the new key */ + pi_title_key = *pi_write_key; + *pi_write_key = malloc( sizeof( title_key_t ) ); + (*pi_write_key)->i_startlb = i_block; + memcpy( (*pi_write_key)->pi_key, pi_tmp_key, KEY_SIZE ); + (*pi_write_key)->next = pi_title_key; + } + return 0; } @@ -187,6 +234,7 @@ int i_blocks, int i_flags ) { + title_key_t *curpos; int i_ret; i_ret = _dvdcss_read( dvdcss, p_buffer, i_blocks ); @@ -198,9 +246,22 @@ return i_ret; } + /* find our key */ + curpos = dvdcss->pi_key_list; + while( curpos && curpos->next && curpos->next->i_startlb < dvdcss->i_seekpos ) + { + curpos = curpos->next; + } + + if( !curpos ) + { + /* no css key found to use, so no decryption to do */ + return 0; + } + while( i_ret ) { - CSSDescrambleSector( dvdcss->css.pi_title_key, p_buffer ); + CSSDescrambleSector( curpos->pi_key, p_buffer ); ((u8*)p_buffer)[0x14] &= 0x8f; (u8*)p_buffer += DVDCSS_BLOCK_SIZE; i_ret--; @@ -217,6 +278,7 @@ int i_flags ) { #define P_IOVEC ((struct iovec*)p_iovec) + title_key_t *curpos; int i_ret; void *iov_base; size_t iov_len; @@ -230,6 +292,20 @@ return i_ret; } + /* find our key */ + curpos = dvdcss->pi_key_list; + while( curpos && curpos->next && curpos->next->i_startlb < dvdcss->i_seekpos ) + { + curpos = curpos->next; + } + + if( !curpos ) + { + /* no css key found to use, so no decryption to do */ + return 0; + } + + /* Initialize loop for decryption */ iov_base = P_IOVEC->iov_base; iov_len = P_IOVEC->iov_len; @@ -249,7 +325,7 @@ iov_len = P_IOVEC->iov_len; } - CSSDescrambleSector( dvdcss->css.pi_title_key, iov_base ); + CSSDescrambleSector( curpos->pi_key, iov_base ); ((u8*)iov_base)[0x14] &= 0x8f; (u8*)iov_base += DVDCSS_BLOCK_SIZE; @@ -267,8 +343,18 @@ *****************************************************************************/ extern int dvdcss_close ( dvdcss_handle dvdcss ) { + title_key_t *pi_cur_key; int i_ret; + /* Free our list of keys */ + pi_cur_key = dvdcss->pi_key_list; + while( pi_cur_key ) + { + title_key_t *pi_tmp_key = pi_cur_key->next; + free( pi_cur_key ); + pi_cur_key = pi_tmp_key; + } + i_ret = _dvdcss_close( dvdcss ); if( i_ret < 0 ) @@ -346,6 +432,8 @@ { off_t i_read; + dvdcss->i_seekpos = i_blocks; + #if defined( WIN32 ) if( WIN2K ) { @@ -683,9 +771,9 @@ if(ssc.SRB_Status != SS_COMP) { - return -1; + return -1; } - + fd->i_pos += i_len; return i_len; diff -urN libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.h libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.h --- libdvdcss-0.0.1/extras/libdvdcss/libdvdcss.h Wed Jun 13 22:47:44 2001 +++ libdvdcss-0.0.1-mod/extras/libdvdcss/libdvdcss.h Fri Jun 29 11:26:30 2001 @@ -34,10 +34,12 @@ { /* File descriptor */ int i_fd; + int i_seekpos; /* Decryption stuff */ - css_t css; - boolean_t b_encrypted; + css_t css; + boolean_t b_encrypted; + title_key_t *pi_key_list; /* Error management */ char *psz_error; diff -urN libdvdcss-0.0.1/extras/libdvdcss/videolan/dvdcss.h libdvdcss-0.0.1-mod/extras/libdvdcss/videolan/dvdcss.h --- libdvdcss-0.0.1/extras/libdvdcss/videolan/dvdcss.h Wed Jun 13 21:49:44 2001 +++ libdvdcss-0.0.1-mod/extras/libdvdcss/videolan/dvdcss.h Fri Jun 29 11:34:29 2001 @@ -46,7 +46,6 @@ int i_flags ); extern int dvdcss_close ( dvdcss_handle ); extern int dvdcss_crack ( dvdcss_handle, - int i_title, int i_block ); extern int dvdcss_seek ( dvdcss_handle, int i_blocks ); Binary files libdvdcss-0.0.1/lib/libdvdcss.a and libdvdcss-0.0.1-mod/lib/libdvdcss.a differ Binary files libdvdcss-0.0.1/lib/libdvdcss.so and libdvdcss-0.0.1-mod/lib/libdvdcss.so differ Binary files libdvdcss-0.0.1/lib/libdvdcss.so.0 and libdvdcss-0.0.1-mod/lib/libdvdcss.so.0 differ Binary files libdvdcss-0.0.1/lib/libdvdcss.so.0.0.1 and libdvdcss-0.0.1-mod/lib/libdvdcss.so.0.0.1 differ