diff options
-rw-r--r-- | Copyright | 8 | ||||
-rw-r--r-- | libdvdcss/bsdi_dvd.h | 344 | ||||
-rw-r--r-- | libdvdcss/common.h | 85 | ||||
-rw-r--r-- | libdvdcss/css.c | 1731 | ||||
-rw-r--r-- | libdvdcss/css.h | 63 | ||||
-rw-r--r-- | libdvdcss/csstables.h | 395 | ||||
-rw-r--r-- | libdvdcss/device.c | 1090 | ||||
-rw-r--r-- | libdvdcss/device.h | 64 | ||||
-rw-r--r-- | libdvdcss/dvdcss/dvdcss.h | 107 | ||||
-rw-r--r-- | libdvdcss/error.c | 68 | ||||
-rw-r--r-- | libdvdcss/ioctl.c | 2123 | ||||
-rw-r--r-- | libdvdcss/ioctl.h | 434 | ||||
-rw-r--r-- | libdvdcss/libdvdcss.c | 814 | ||||
-rw-r--r-- | libdvdcss/libdvdcss.h | 111 |
14 files changed, 0 insertions, 7437 deletions
@@ -20,14 +20,6 @@ Copyright: Many, see individual files for copyright notices. License: GNU Lesser General Public License -Name: libdvdcss -Version: Subversion r237 + local changes -URL: http://developers.videolan.org/libdvdcss/ -Directory: libdvdcss -Copyright: 1998-2008 VideoLAN -License: GNU General Public License - - Name: mpg123 Version: 0.59s + significant changes URL: http://www.mpg123.de/ diff --git a/libdvdcss/bsdi_dvd.h b/libdvdcss/bsdi_dvd.h deleted file mode 100644 index 2c50c898b1..0000000000 --- a/libdvdcss/bsdi_dvd.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * $Id$ -*/ - -#ifndef DVDCSS_BSDI_DVD_H -#define DVDCSS_BSDI_DVD_H - -#include <sys/cdefs.h> -#include <machine/endian.h> -#include <sys/ioctl.h> - -__BEGIN_DECLS -int dvd_cdrom_ioctl(int, unsigned long, void *); -int cdrom_blocksize(int, int); -void dvd_cdrom_debug(int); -__END_DECLS - -#define ioctl(a,b,c) dvd_cdrom_ioctl((a),(b),(c)) - -typedef unsigned char __u8; -typedef unsigned short __u16; -typedef unsigned int __u32; - -#define DVD_READ_STRUCT 0x5390 /* Read structure */ -#define DVD_WRITE_STRUCT 0x5391 /* Write structure */ -#define DVD_AUTH 0x5392 /* Authentication */ - -#define DVD_STRUCT_PHYSICAL 0x00 -#define DVD_STRUCT_COPYRIGHT 0x01 -#define DVD_STRUCT_DISCKEY 0x02 -#define DVD_STRUCT_BCA 0x03 -#define DVD_STRUCT_MANUFACT 0x04 - -struct dvd_layer { - __u8 book_version : 4; - __u8 book_type : 4; - __u8 min_rate : 4; - __u8 disc_size : 4; - __u8 layer_type : 4; - __u8 track_path : 1; - __u8 nlayers : 2; - __u8 track_density : 4; - __u8 linear_density : 4; - __u8 bca : 1; - __u32 start_sector; - __u32 end_sector; - __u32 end_sector_l0; -}; - -struct dvd_physical { - __u8 type; - __u8 layer_num; - struct dvd_layer layer[4]; -}; - -struct dvd_copyright { - __u8 type; - - __u8 layer_num; - __u8 cpst; - __u8 rmi; -}; - -struct dvd_disckey { - __u8 type; - - unsigned agid : 2; - __u8 value[2048]; -}; - -struct dvd_bca { - __u8 type; - - int len; - __u8 value[188]; -}; - -struct dvd_manufact { - __u8 type; - - __u8 layer_num; - int len; - __u8 value[2048]; -}; - -typedef union { - __u8 type; - - struct dvd_physical physical; - struct dvd_copyright copyright; - struct dvd_disckey disckey; - struct dvd_bca bca; - struct dvd_manufact manufact; -} dvd_struct; - -/* - * DVD authentication ioctl - */ - -/* Authentication states */ -#define DVD_LU_SEND_AGID 0 -#define DVD_HOST_SEND_CHALLENGE 1 -#define DVD_LU_SEND_KEY1 2 -#define DVD_LU_SEND_CHALLENGE 3 -#define DVD_HOST_SEND_KEY2 4 - -/* Termination states */ -#define DVD_AUTH_ESTABLISHED 5 -#define DVD_AUTH_FAILURE 6 - -/* Other functions */ -#define DVD_LU_SEND_TITLE_KEY 7 -#define DVD_LU_SEND_ASF 8 -#define DVD_INVALIDATE_AGID 9 -#define DVD_LU_SEND_RPC_STATE 10 -#define DVD_HOST_SEND_RPC_STATE 11 - -/* State data */ -typedef __u8 dvd_key[5]; /* 40-bit value, MSB is first elem. */ -typedef __u8 dvd_challenge[10]; /* 80-bit value, MSB is first elem. */ - -struct dvd_lu_send_agid { - __u8 type; - unsigned agid : 2; -}; - -struct dvd_host_send_challenge { - __u8 type; - unsigned agid : 2; - - dvd_challenge chal; -}; - -struct dvd_send_key { - __u8 type; - unsigned agid : 2; - - dvd_key key; -}; - -struct dvd_lu_send_challenge { - __u8 type; - unsigned agid : 2; - - dvd_challenge chal; -}; - -#define DVD_CPM_NO_COPYRIGHT 0 -#define DVD_CPM_COPYRIGHTED 1 - -#define DVD_CP_SEC_NONE 0 -#define DVD_CP_SEC_EXIST 1 - -#define DVD_CGMS_UNRESTRICTED 0 -#define DVD_CGMS_SINGLE 2 -#define DVD_CGMS_RESTRICTED 3 - -struct dvd_lu_send_title_key { - __u8 type; - unsigned agid : 2; - - dvd_key title_key; - int lba; - unsigned cpm : 1; - unsigned cp_sec : 1; - unsigned cgms : 2; -}; - -struct dvd_lu_send_asf { - __u8 type; - unsigned agid : 2; - - unsigned asf : 1; -}; - -struct dvd_host_send_rpcstate { - __u8 type; - __u8 pdrc; -}; - -struct dvd_lu_send_rpcstate { - __u8 type : 2; - __u8 vra : 3; - __u8 ucca : 3; - __u8 region_mask; - __u8 rpc_scheme; -}; - -typedef union { - __u8 type; - - struct dvd_lu_send_agid lsa; - struct dvd_host_send_challenge hsc; - struct dvd_send_key lsk; - struct dvd_lu_send_challenge lsc; - struct dvd_send_key hsk; - struct dvd_lu_send_title_key lstk; - struct dvd_lu_send_asf lsasf; - struct dvd_host_send_rpcstate hrpcs; - struct dvd_lu_send_rpcstate lrpcs; -} dvd_authinfo; - - -typedef struct { - __u16 report_key_length; - __u8 reserved1; - __u8 reserved2; -#if BYTE_ORDER == BIG_ENDIAN - __u8 type_code : 2; - __u8 vra : 3; - __u8 ucca : 3; -#elif BYTE_ORDER == LITTLE_ENDIAN - __u8 ucca : 3; - __u8 vra : 3; - __u8 type_code : 2; -#endif - __u8 region_mask; - __u8 rpc_scheme; - __u8 reserved3; -} rpc_state_t; - -/* - * Stuff for the CDROM ioctls -*/ - -#define CDROMREADTOCHDR 0x5305 /* Read TOC header (cdrom_tochdr) */ -#define CDROMREADTOCENTRY 0x5306 /* Read TOC entry (cdrom_tocentry) */ -#define CDROMEJECT 0x5309 /* Ejects the cdrom media */ -#define CDROMCLOSETRAY 0x5319 /* Reverse of CDROMEJECT */ -#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ -#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */ -#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes) */ -#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes) */ -#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 bytes) */ - -#define CD_MINS 74 /* max. minutes per CD, not really a limit */ -#define CD_SECS 60 /* seconds per minute */ -#define CD_FRAMES 75 /* frames per second */ -#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */ - -#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */ -#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame */ -#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ -#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */ -#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/ -#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/ - -/* CD-ROM address types (cdrom_tocentry.cdte_format) */ -#define CDROM_LBA 0x01 /* logical block: first frame is #0 */ -#define CDROM_MSF 0x02 /* minute-second-frame: binary. not bcd here!*/ - -/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */ -#define CDROM_DATA_TRACK 0x04 - -/* The leadout track is always 0xAA, regardless of # of tracks on disc */ -#define CDROM_LEADOUT 0xAA - -/* drive status returned by CDROM_DRIVE_STATUS ioctl */ -#define CDS_NO_INFO 0 /* if not implemented */ -#define CDS_NO_DISC 1 -#define CDS_TRAY_OPEN 2 -#define CDS_DRIVE_NOT_READY 3 -#define CDS_DISC_OK 4 - -/* - * Return values for CDROM_DISC_STATUS ioctl. - * Can also return CDS_NO_INFO and CDS_NO_DISC from above -*/ -#define CDS_AUDIO 100 -#define CDS_DATA_1 101 -#define CDS_DATA_2 102 -#define CDS_XA_2_1 103 -#define CDS_XA_2_2 104 -#define CDS_MIXED 105 - -/* For compile compatibility only - we don't support changers */ -#define CDSL_NONE ((int) (~0U>>1)-1) -#define CDSL_CURRENT ((int) (~0U>>1)) - -struct cdrom_msf -{ - __u8 cdmsf_min0; /* start minute */ - __u8 cdmsf_sec0; /* start second */ - __u8 cdmsf_frame0; /* start frame */ - __u8 cdmsf_min1; /* end minute */ - __u8 cdmsf_sec1; /* end second */ - __u8 cdmsf_frame1; /* end frame */ -}; - -struct cdrom_tochdr - { - __u8 cdth_trk0; /* start track */ - __u8 cdth_trk1; /* end track */ - }; - -struct cdrom_msf0 -{ - __u8 minute; - __u8 second; - __u8 frame; -}; - -union cdrom_addr -{ - struct cdrom_msf0 msf; - int lba; -}; - -struct cdrom_tocentry -{ - __u8 cdte_track; - __u8 cdte_adr :4; - __u8 cdte_ctrl :4; - __u8 cdte_format; - union cdrom_addr cdte_addr; - __u8 cdte_datamode; -}; - -struct modesel_head -{ - __u8 reserved1; - __u8 medium; - __u8 reserved2; - __u8 block_desc_length; - __u8 density; - __u8 number_of_blocks_hi; - __u8 number_of_blocks_med; - __u8 number_of_blocks_lo; - __u8 reserved3; - __u8 block_length_hi; - __u8 block_length_med; - __u8 block_length_lo; -}; - -typedef struct -{ - int data; - int audio; - int cdi; - int xa; - int error; -} tracktype; - -#endif /* DVDCSS_BSDI_DVD_H */ diff --git a/libdvdcss/common.h b/libdvdcss/common.h deleted file mode 100644 index bee5aadd50..0000000000 --- a/libdvdcss/common.h +++ /dev/null @@ -1,85 +0,0 @@ -/***************************************************************************** - * common.h: common definitions - * Collection of useful common types and macros definitions - ***************************************************************************** - * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id$ - * - * Authors: Sam Hocevar <sam@via.ecp.fr> - * Vincent Seguin <seguin@via.ecp.fr> - * Gildas Bazin <gbazin@netcourrier.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with libdvdcss; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *****************************************************************************/ - -#ifndef DVDCSS_COMMON_H -#define DVDCSS_COMMON_H - -/***************************************************************************** - * Basic types definitions - *****************************************************************************/ -#if defined( HAVE_STDINT_H ) -# include <stdint.h> -#elif defined( HAVE_INTTYPES_H ) -# include <inttypes.h> -#elif defined( SYS_CYGWIN ) -# include <sys/types.h> - /* Cygwin only defines half of these... */ - typedef u_int8_t uint8_t; - typedef u_int32_t uint32_t; -#else - /* Fallback types (very x86-centric, sorry) */ - typedef unsigned char uint8_t; - typedef signed char int8_t; - typedef unsigned int uint32_t; - typedef signed int int32_t; -#endif - -#if defined( WIN32 ) - -# ifndef PATH_MAX -# define PATH_MAX MAX_PATH -# endif - -/* several type definitions */ -# if defined( __MINGW32__ ) -# define lseek _lseeki64 -# if !defined( _OFF_T_ ) -typedef long long _off_t; -typedef _off_t off_t; -# define _OFF_T_ -# else -# define off_t long long -# endif -# endif - -# if defined( _MSC_VER ) -# define lseek _lseeki64 -# if !defined( _OFF_T_DEFINED ) -typedef __int64 off_t; -# define _OFF_T_DEFINED -# else -# define off_t __int64 -# endif -# define stat _stati64 -# endif - -# ifndef snprintf -# define snprintf _snprintf /* snprintf not defined in mingw32 (bug?) */ -# endif - -#endif - -#endif /* DVDCSS_COMMON_H */ diff --git a/libdvdcss/css.c b/libdvdcss/css.c deleted file mode 100644 index 886a803efd..0000000000 --- a/libdvdcss/css.c +++ /dev/null @@ -1,1731 +0,0 @@ -/***************************************************************************** - * css.c: Functions for DVD authentication and descrambling - ***************************************************************************** - * Copyright (C) 1999-2008 VideoLAN - * $Id$ - * - * Authors: Stéphane Borel <stef@via.ecp.fr> - * Håkan Hjort <d95hjort@dtek.chalmers.se> - * - * based on: - * - css-auth by Derek Fawcus <derek@spider.com> - * - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net> - * - The Divide and conquer attack by Frank A. Stevenson <frank@funcom.com> - * (see http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/index.html) - * - DeCSSPlus by Ethan Hawke - * - DecVOB - * see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#ifdef HAVE_SYS_PARAM_H -# include <sys/param.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -#include <fcntl.h> - -#ifdef HAVE_LIMITS_H -# include <limits.h> -#endif - -#include "dvdcss/dvdcss.h" - -#include "common.h" -#include "css.h" -#include "libdvdcss.h" -#include "csstables.h" -#include "ioctl.h" -#include "device.h" - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static void PrintKey ( dvdcss_t, char *, uint8_t const * ); - -static int GetBusKey ( dvdcss_t ); -static int GetASF ( dvdcss_t ); - -static void CryptKey ( int, int, uint8_t const *, uint8_t * ); -static void DecryptKey ( uint8_t, - uint8_t const *, uint8_t const *, uint8_t * ); - -static int DecryptDiscKey ( dvdcss_t, uint8_t const *, dvd_key_t ); -static int CrackDiscKey ( dvdcss_t, uint8_t * ); - -static void DecryptTitleKey ( dvd_key_t, dvd_key_t ); -static int RecoverTitleKey ( int, uint8_t const *, - uint8_t const *, uint8_t const *, uint8_t * ); -static int CrackTitleKey ( dvdcss_t, int, int, dvd_key_t ); - -static int AttackPattern ( uint8_t const[], int, uint8_t * ); -#if 0 -static int AttackPadding ( uint8_t const[], int, uint8_t * ); -#endif - -/***************************************************************************** - * _dvdcss_test: check if the disc is encrypted or not - ***************************************************************************** - * Sets b_scrambled, b_ioctls - *****************************************************************************/ -void _dvdcss_test( dvdcss_t dvdcss ) -{ - char const *psz_type, *psz_rpc; - int i_ret, i_copyright, i_type, i_mask, i_rpc; - - i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright ); - - if( i_ret < 0 ) - { - /* Maybe we didn't have enough privileges to read the copyright - * (see ioctl_ReadCopyright comments). - * Apparently, on unencrypted DVDs _dvdcss_disckey() always fails, so - * we can check this as a workaround. */ -#ifdef WIN32 - i_ret = 0; -#else - /* Since it's the first ioctl we try to issue, we add a notice */ - print_error( dvdcss, "css error: could not get \"copyright\"" - " information, make sure there is a DVD in the drive," - " and that you have used the correct device node." ); - /* Try without ioctls */ - dvdcss->b_ioctls = 0; -#endif - i_copyright = 1; - if( _dvdcss_disckey( dvdcss ) < 0 ) - { - i_copyright = 0; - } - } - - print_debug( dvdcss, "disc reports copyright information 0x%x", - i_copyright ); - dvdcss->b_scrambled = i_copyright; - - i_ret = ioctl_ReportRPC( dvdcss->i_fd, &i_type, &i_mask, &i_rpc); - - if( i_ret < 0 ) - { - print_error( dvdcss, "css error: could not get RPC status, region-free drive?" ); - return; - } - - switch( i_rpc ) - { - case 0: psz_rpc = "RPC-I"; break; - case 1: psz_rpc = "RPC-II"; break; - default: psz_rpc = "unknown RPC scheme"; break; - } - - switch( i_type ) - { - case 0: psz_type = "no region code set"; break; - case 1: psz_type = "region code set"; break; - case 2: psz_type = "one region change remaining"; break; - case 3: psz_type = "region code set permanently"; break; - default: psz_type = "unknown status"; break; - } - - print_debug( dvdcss, "drive region mask 0x%x, %s, %s", - i_mask, psz_rpc, psz_type ); - - if( i_copyright && i_rpc == 1 && i_type == 0 ) - { - print_error( dvdcss, "css error: drive will prevent access to " - "scrambled data" ); - } -} - -/***************************************************************************** - * _dvdcss_title: crack or decrypt the current title key if needed - ***************************************************************************** - * This function should only be called by dvdcss->pf_seek and should eventually - * not be external if possible. - *****************************************************************************/ -int _dvdcss_title ( dvdcss_t dvdcss, int i_block ) -{ - dvd_title_t *p_title; - dvd_title_t *p_newtitle; - dvd_key_t p_title_key; - int i_fd, i_ret = -1, b_cache = 0; - - if( ! dvdcss->b_scrambled ) - { - return 0; - } - - /* Check if we've already cracked this key */ - p_title = dvdcss->p_titles; - while( p_title != NULL - && p_title->p_next != NULL - && p_title->p_next->i_startlb <= i_block ) - { - p_title = p_title->p_next; - } - - if( p_title != NULL - && p_title->i_startlb == i_block ) - { - /* We've already cracked this key, nothing to do */ - memcpy( dvdcss->css.p_title_key, p_title->p_key, sizeof(dvd_key_t) ); - return 0; - } - - /* Check whether the key is in our disk cache */ - if( dvdcss->psz_cachefile[0] ) - { - /* XXX: be careful, we use sprintf and not snprintf */ - sprintf( dvdcss->psz_block, "%.10x", i_block ); - i_fd = open( dvdcss->psz_cachefile, O_RDONLY ); - b_cache = 1; - - if( i_fd >= 0 ) - { - char psz_key[KEY_SIZE * 3]; - unsigned int k0, k1, k2, k3, k4; - - psz_key[KEY_SIZE * 3 - 1] = '\0'; - - if( read( i_fd, psz_key, KEY_SIZE * 3 - 1 ) == KEY_SIZE * 3 - 1 - && sscanf( psz_key, "%x:%x:%x:%x:%x", - &k0, &k1, &k2, &k3, &k4 ) == 5 ) - { - p_title_key[0] = k0; - p_title_key[1] = k1; - p_title_key[2] = k2; - p_title_key[3] = k3; - p_title_key[4] = k4; - PrintKey( dvdcss, "title key found in cache ", p_title_key ); - - /* Don't try to save it again */ - b_cache = 0; - i_ret = 1; - } - - close( i_fd ); - } - } - - /* Crack or decrypt CSS title key for current VTS */ - if( i_ret < 0 ) - { - i_ret = _dvdcss_titlekey( dvdcss, i_block, p_title_key ); - - if( i_ret < 0 ) - { - print_error( dvdcss, "fatal error in vts css key" ); - return i_ret; - } - - if( i_ret == 0 ) - { - print_debug( dvdcss, "unencrypted title" ); - /* We cache this anyway, so we don't need to check again. */ - } - } - - /* Key is valid, we store it on disk. */ - if( dvdcss->psz_cachefile[0] && b_cache ) - { - i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT, 0644 ); - if( i_fd >= 0 ) - { - char psz_key[KEY_SIZE * 3 + 2]; - - sprintf( psz_key, "%02x:%02x:%02x:%02x:%02x\r\n", - p_title_key[0], p_title_key[1], p_title_key[2], - p_title_key[3], p_title_key[4] ); - - write( i_fd, psz_key, KEY_SIZE * 3 + 1 ); - close( i_fd ); - } - } - - /* Find our spot in the list */ - p_newtitle = NULL; - p_title = dvdcss->p_titles; - while( ( p_title != NULL ) && ( p_title->i_startlb < i_block ) ) - { - p_newtitle = p_title; - p_title = p_title->p_next; - } - - /* Save the found title */ - p_title = p_newtitle; - - /* Write in the new title and its key */ - p_newtitle = malloc( sizeof( dvd_title_t ) ); - p_newtitle->i_startlb = i_block; - memcpy( p_newtitle->p_key, p_title_key, KEY_SIZE ); - - /* Link it at the head of the (possibly empty) list */ - if( p_title == NULL ) - { - p_newtitle->p_next = dvdcss->p_titles; - dvdcss->p_titles = p_newtitle; - } - /* Link the new title inside the list */ - else - { - p_newtitle->p_next = p_title->p_next; - p_title->p_next = p_newtitle; - } - - memcpy( dvdcss->css.p_title_key, p_title_key, KEY_SIZE ); - return 0; -} - -/***************************************************************************** - * _dvdcss_disckey: get disc key. - ***************************************************************************** - * This function should only be called if DVD ioctls are present. - * It will set dvdcss->i_method = DVDCSS_METHOD_TITLE if it fails to find - * a valid disc key. - * Two decryption methods are offered: - * -disc key hash crack, - * -decryption with player keys if they are available. - *****************************************************************************/ -int _dvdcss_disckey( dvdcss_t dvdcss ) -{ - unsigned char p_buffer[ DVD_DISCKEY_SIZE ]; - dvd_key_t p_disc_key; - int i; - - if( GetBusKey( dvdcss ) < 0 ) - { - return -1; - } - - /* Get encrypted disc key */ - if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 ) - { - print_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. */ - print_error( dvdcss, - "ASF not 1 after reading disc key (region mismatch?)" ); - ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid ); - return -1; - } - - /* Shuffle 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) ]; - } - - /* Decrypt disc key */ - switch( dvdcss->i_method ) - { - case DVDCSS_METHOD_KEY: - - /* Decrypt disc key with player key. */ - PrintKey( dvdcss, "decrypting disc key ", p_buffer ); - if( ! DecryptDiscKey( dvdcss, p_buffer, p_disc_key ) ) - { - PrintKey( dvdcss, "decrypted disc key is ", p_disc_key ); - break; - } - print_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 */ - memset( p_disc_key, 0, KEY_SIZE ); - dvdcss->i_method = DVDCSS_METHOD_TITLE; - break; - - case DVDCSS_METHOD_DISC: - - /* Crack Disc key to be able to use it */ - memcpy( p_disc_key, p_buffer, KEY_SIZE ); - PrintKey( dvdcss, "cracking disc key ", p_disc_key ); - if( ! CrackDiscKey( dvdcss, p_disc_key ) ) - { - PrintKey( dvdcss, "cracked disc key is ", p_disc_key ); - break; - } - print_debug( dvdcss, "failed to crack the disc key" ); - memset( p_disc_key, 0, KEY_SIZE ); - dvdcss->i_method = DVDCSS_METHOD_TITLE; - break; - - default: - - print_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. - */ - - print_debug( dvdcss, "getting title key at block %i the classic way", - i_pos ); - - /* We need to authenticate again every time to get a new session key */ - if( GetBusKey( dvdcss ) < 0 ) - { - i_ret = -1; - } - - /* Get encrypted title key */ - if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid, - i_pos, p_key ) < 0 ) - { - print_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. */ - print_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. */ - print_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 - { - PrintKey( dvdcss, "initial disc key ", dvdcss->css.p_disc_key ); - DecryptTitleKey( dvdcss->css.p_disc_key, p_key ); - PrintKey( dvdcss, "decrypted title 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 */ - print_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) ) - { - return 0; - } - - 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; - |