Mercurial > mplayer.hg
diff libdvdcss/css.c @ 35952:691431d2289e
Update internal libdvdcss to Git revision 39e0e2b.
| author | diego |
|---|---|
| date | Sat, 23 Mar 2013 14:32:26 +0000 |
| parents | e057379d9360 |
| children |
line wrap: on
line diff
--- a/libdvdcss/css.c Sat Mar 23 00:50:51 2013 +0000 +++ b/libdvdcss/css.c Sat Mar 23 14:32:26 2013 +0000 @@ -2,7 +2,6 @@ * 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> @@ -62,6 +61,8 @@ #include "ioctl.h" #include "device.h" +#define PSZ_KEY_SIZE (KEY_SIZE * 3) + /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -87,44 +88,54 @@ static int AttackPadding ( uint8_t const[], int, uint8_t * ); #endif +static int _dvdcss_titlekey ( dvdcss_t, int , dvd_key_t ); + /***************************************************************************** * _dvdcss_test: check if the disc is encrypted or not ***************************************************************************** - * Sets b_scrambled, b_ioctls + * Return values: + * 1: DVD is scrambled but can be read + * 0: DVD is not scrambled and can be read + * -1: could not get "copyright" information + * -2: could not get RPC information (reading the disc might be possible) + * -3: drive is RPC-II, region is not set, and DVD is scrambled: the RPC + * scheme will prevent us from reading the scrambled data *****************************************************************************/ -void _dvdcss_test( dvdcss_t dvdcss ) +int _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 ); +#ifdef WIN32 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; } } +#endif + + if( i_ret < 0 ) + { + /* 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." ); + + return -1; + } 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); @@ -157,7 +168,10 @@ { print_error( dvdcss, "css error: drive will prevent access to " "scrambled data" ); + return -3; } + + return i_copyright ? 1 : 0; } /***************************************************************************** @@ -205,12 +219,12 @@ if( i_fd >= 0 ) { - char psz_key[KEY_SIZE * 3]; + char psz_key[PSZ_KEY_SIZE]; unsigned int k0, k1, k2, k3, k4; - psz_key[KEY_SIZE * 3 - 1] = '\0'; + psz_key[PSZ_KEY_SIZE - 1] = '\0'; - if( read( i_fd, psz_key, KEY_SIZE * 3 - 1 ) == KEY_SIZE * 3 - 1 + if( read( i_fd, psz_key, PSZ_KEY_SIZE - 1 ) == PSZ_KEY_SIZE - 1 && sscanf( psz_key, "%x:%x:%x:%x:%x", &k0, &k1, &k2, &k3, &k4 ) == 5 ) { @@ -237,7 +251,7 @@ if( i_ret < 0 ) { - print_error( dvdcss, "fatal error in vts css key" ); + print_error( dvdcss, "fatal error in VTS CSS key" ); return i_ret; } @@ -254,13 +268,17 @@ i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT, 0644 ); if( i_fd >= 0 ) { - char psz_key[KEY_SIZE * 3 + 2]; + char psz_key[PSZ_KEY_SIZE + 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 ); + if( write( i_fd, psz_key, PSZ_KEY_SIZE + 1 ) < PSZ_KEY_SIZE + 1 ) + { + print_error( dvdcss, + "Error caching key on disk, continuing..\n" ); + } close( i_fd ); } } @@ -327,7 +345,7 @@ return -1; } - /* This should have invaidated the AGID and got us ASF=1. */ + /* This should have invalidated the AGID and got us ASF=1. */ if( GetASF( dvdcss ) != 1 ) { /* Region mismatch (or region not set) is the most likely source. */ @@ -395,7 +413,7 @@ /***************************************************************************** * _dvdcss_titlekey: get title key. *****************************************************************************/ -int _dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key_t p_title_key ) +static 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 ]; @@ -443,9 +461,9 @@ break; case 1: - /* Drive status is ok. */ + /* 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 + * we might still have the AGID. Other code assumes that we * will not after this so invalidate it(?). */ if( i_ret < 0 ) { @@ -498,7 +516,7 @@ /* 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. */ + /* 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 ); @@ -561,7 +579,7 @@ * It simulates the mutual authentication between logical unit and host, * and stops when a session key (called bus key) has been established. * Always do the full auth sequence. Some drives seem to lie and always - * respond with ASF=1. For instance the old DVD roms on Compaq Armada says + * respond with ASF=1. For instance the old DVD-ROMs on Compaq Armada says * that ASF=1 from the start and then later fail with a 'read of scrambled * block without authentication' error. *****************************************************************************/ @@ -743,7 +761,7 @@ /***************************************************************************** * CryptKey : shuffles bits and unencrypt keys. ***************************************************************************** - * Used during authentication and disc key negociation in GetBusKey. + * Used during authentication and disc key negotiation in GetBusKey. * i_key_type : 0->key1, 1->key2, 2->buskey. * i_variant : between 0 and 31. *****************************************************************************/ @@ -751,13 +769,13 @@ uint8_t const *p_challenge, uint8_t *p_key ) { /* Permutation table for challenge */ - uint8_t pp_perm_challenge[3][10] = + static const 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] = + static const 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, @@ -767,14 +785,14 @@ 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f, 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } }; - uint8_t p_variants[32] = + static const 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 }; + static const 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 */ @@ -824,7 +842,7 @@ * 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: + * The second LFSR 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 @@ -838,7 +856,7 @@ */ /* 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 + * initial values are non-zero. Thus when we initialize them from * the seed, we ensure that a bit is set. */ i_lfsr0 = ( p_tmp1[0] << 17 ) | ( p_tmp1[1] << 9 ) | @@ -947,7 +965,7 @@ * in _dvdcss_titlekey. * The player keys and the resulting disc key are only used as KEKs * (key encryption keys). - * Decryption is slightly dependant on the type of key: + * Decryption is slightly dependent on the type of key: * -for disc key, invert is 0x00, * -for title key, invert if 0xff. *****************************************************************************/ @@ -1182,7 +1200,7 @@ } } - /* Initing our Really big table */ + /* Initializing our really big table */ BigTable = calloc( 16777216, sizeof(int) ); if( BigTable == NULL ) { @@ -1211,7 +1229,7 @@ } /* - * We are done initing, now reverse hash + * We are done initializing, now reverse hash */ tmp5 = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ]; @@ -1229,7 +1247,7 @@ out1[ i ] = p_css_tab4[ tmp ]; } - /* cumpute and cache some variables */ + /* compute and cache some variables */ C[0] = nStepA >> 8; C[1] = nStepA & 0xff; tmp = p_disc_key[3] ^ p_css_tab1[ p_disc_key[4] ]; @@ -1345,7 +1363,7 @@ /* iterate cipher 4 times to reconstruct LFSR2 */ for( i = 0 ; i < 4 ; i++ ) { - /* advance LFSR1 normaly */ + /* advance LFSR1 normally */ 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; @@ -1398,7 +1416,7 @@ { i_t1 = i_t3 & 0xff; i_t3 = ( i_t3 >> 8 ); - /* easy to code, and fast enough bruteforce + /* easy to code, and fast enough brute-force * search for byte shifted in */ for( j = 0 ; j < 256 ; j++ ) { @@ -1446,11 +1464,11 @@ * Various pieces for the title crack engine. ****************************************************************************** * The length of the PES packet is located at 0x12-0x13. - * The the copyrigth protection bits are located at 0x14 (bits 0x20 and 0x10). + * The the copyright protection bits are located at 0x14 (bits 0x20 and 0x10). * The data of the PES packet begins at 0x15 (if there isn't any PTS/DTS) * or at 0x?? if there are both PTS and DTS's. * The seed value used with the unscrambling key is the 5 bytes at 0x54-0x58. - * The scrabled part of a sector begins at 0x80. + * The scrambled part of a sector begins at 0x80. *****************************************************************************/ /* Statistics */ @@ -1594,7 +1612,7 @@ ****************************************************************************** * Tries to find a repeating pattern just before the encrypted part starts. * Then it guesses that the plain text for first encrypted bytes are - * a contiuation of that pattern. + * a continuation of that pattern. *****************************************************************************/ static int AttackPattern( uint8_t const p_sec[ DVDCSS_BLOCK_SIZE ], int i_pos, uint8_t *p_key ) @@ -1655,7 +1673,7 @@ ****************************************************************************** * 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 + * For the last piece of video data before a VOBU boundary there might not * 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 @@ -1670,7 +1688,7 @@ i_pes_length = (p_sec[0x12]<<8) | p_sec[0x13]; - /* Coverd by the test below but usfull for debuging. */ + /* Covered by the test below but useful for debugging. */ if( i_pes_length == DVDCSS_BLOCK_SIZE - 0x14 ) return 0; /* There must be room for at least 4? bytes of padding stream, @@ -1699,7 +1717,7 @@ are also known. */ /* An encrypted SPU PES packet with another encrypted PES packet following. - Normaly if the following was a padding stream that would be in plain + Normally if the following was a padding stream that would be in plain text. So it will be another SPU PES packet. */ if( p_sec[0x11] == 0xbd && p_sec[0x17 + p_sec[0x16]] >= 0x20 && @@ -1709,7 +1727,7 @@ } /* A Video PES packet with another encrypted PES packet following. - * No reason execpt for time stamps to break the data into two packets. + * No reason except for time stamps to break the data into two packets. * So it's likely that the following PES packet is a padding stream. */ if( p_sec[0x11] == 0xe0 ) {
