css.c 60.2 KB
Newer Older
1
/*****************************************************************************
2
 * css.c: Functions for DVD authentication and descrambling
3
 *****************************************************************************
4
 * Copyright (C) 1999-2008 VideoLAN
5
 *
6 7
 * Authors: Stéphane Borel <stef@via.ecp.fr>
 *          Håkan Hjort <d95hjort@dtek.chalmers.se>
8 9 10 11 12
 *
 * 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>
13
 *     (see http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/index.html)
14 15 16
 *  - DeCSSPlus by Ethan Hawke
 *  - DecVOB
 *  see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information.
17
 *
18
 * libdvdcss is free software; you can redistribute it and/or modify
19 20 21 22
 * 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.
 *
23
 * libdvdcss is distributed in the hope that it will be useful,
24 25 26 27
 * 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.
 *
Diego Biurrun's avatar
Diego Biurrun committed
28
 * You should have received a copy of the GNU General Public License along
29
 * with libdvdcss; if not, write to the Free Software Foundation, Inc.,
Diego Biurrun's avatar
Diego Biurrun committed
30
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 32 33 34 35 36 37
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include "config.h"

38
#include <limits.h>
39 40 41
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
42
#include <sys/types.h>
43 44 45
#ifdef HAVE_SYS_PARAM_H
#   include <sys/param.h>
#endif
46 47 48
#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#endif
49
#include <fcntl.h>
50

51
#include "dvdcss/dvdcss.h"
52 53 54 55 56 57

#include "common.h"
#include "css.h"
#include "libdvdcss.h"
#include "csstables.h"
#include "ioctl.h"
58
#include "device.h"
59

60
#define PSZ_KEY_SIZE (DVD_KEY_SIZE * 3)
61

62 63 64
/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
65
static void PrintKey        ( dvdcss_t, const char *, const uint8_t * );
66

67 68
static int  GetBusKey       ( dvdcss_t );
static int  GetASF          ( dvdcss_t );
69

70
static void CryptKey        ( int, int, const uint8_t *, uint8_t * );
71
static void DecryptKey      ( uint8_t,
72
                              const uint8_t *, const uint8_t *, uint8_t * );
73

74
static int  DecryptDiscKey  ( dvdcss_t, const uint8_t *, dvd_key );
75
static int  CrackDiscKey    ( uint8_t * );
76

77
static void DecryptTitleKey ( dvd_key, dvd_key );
78 79
static int  RecoverTitleKey ( int, const uint8_t *,
                              const uint8_t *, const uint8_t *, uint8_t * );
80
static int  CrackTitleKey   ( dvdcss_t, int, int, dvd_key );
81

82
static int  AttackPattern   ( const uint8_t[], uint8_t * );
83
#if 0
84
static int  AttackPadding   ( const uint8_t[] );
85
#endif
86

87
static int  dvdcss_titlekey ( dvdcss_t, int, dvd_key );
88

89
/*****************************************************************************
90
 * dvdcss_test: check if the disc is encrypted or not
91 92 93 94 95
 *****************************************************************************
 * 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
96 97
 *  -2: could not get RPC (Regional Playback Control) information
 *      (reading the disc might be possible)
98 99
 *  -3: drive is RPC-II, region is not set, and DVD is scrambled: the RPC
 *      scheme will prevent us from reading the scrambled data
100
 *****************************************************************************/
101
int dvdcss_test( dvdcss_t dvdcss )
102
{
103
    const char *psz_type, *psz_rpc;
104 105 106
    char psz_region[16];
    char *p_region = psz_region;
    int i_ret, i_copyright, i_type, i_mask, i_rpc, i_region;
107 108 109

    i_ret = ioctl_ReadCopyright( dvdcss->i_fd, 0 /* i_layer */, &i_copyright );

110 111
    if( i_ret < 0 )
    {
112
#ifdef _WIN32
113
        /* Maybe we didn't have enough privileges to read the copyright
114
         * (see ioctl_ReadCopyright comments).
115
         * Apparently, on unencrypted DVDs dvdcss_disckey() always fails, so
116
         * we can check this as a workaround. */
117
        if( dvdcss_disckey( dvdcss ) < 0 )
118
        {
119
            i_copyright = 0;
120
        }
121 122 123 124 125
        else
        {
            i_copyright = 1;
        }
#else
126
        /* Since it's the first ioctl we try to issue, we add a notice */
127
        print_error( dvdcss, "CSS error: could not get \"copyright\""
128 129 130 131
                     " information, make sure there is a DVD in the drive,"
                     " and that you have used the correct device node." );

        return -1;
132
#endif /* _WIN32 */
133 134
    }

135 136 137
    print_debug( dvdcss, "disc reports copyright information 0x%x",
                         i_copyright );

138 139 140 141
    i_ret = ioctl_ReportRPC( dvdcss->i_fd, &i_type, &i_mask, &i_rpc);

    if( i_ret < 0 )
    {
142
        print_error( dvdcss, "CSS error: could not get RPC (Regional Playback "
143
                     "Control) status. Assuming RPC-I drive." );
144
        i_type = i_mask = i_rpc = 0;
145
    }
146

147 148 149 150
    switch( i_rpc )
    {
        case 0: psz_rpc = "RPC-I"; break;
        case 1: psz_rpc = "RPC-II"; break;
151
        default: psz_rpc = "unknown RPC (Regional Playback Control) scheme"; break;
152 153 154 155 156 157 158 159 160 161 162
    }

    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;
    }

163 164 165 166 167 168 169 170 171 172 173
    for( i_region = 0; i_region < 8; i_region++ )
    {
        if( !( i_mask & ( 1 << i_region ) ) )
        {
            sprintf(p_region, " %d", i_region + 1);
            p_region += 2;
        }
    }

    print_debug( dvdcss, "drive region(s)%s, region mask 0x%x, %s, %s",
                 psz_region, i_mask, psz_rpc, psz_type );
174 175 176

    if( i_copyright && i_rpc == 1 && i_type == 0 )
    {
177
        print_error( dvdcss, "CSS error: drive will prevent access to "
178 179
                             "scrambled data" );
        return -3;
180 181
    }

182
    return i_copyright ? 1 : 0;
183 184 185
}

/*****************************************************************************
186
 * dvdcss_title: crack or decrypt the current title key if needed
187
 *****************************************************************************
188
 * This function should only be called by dvdcss->pf_seek and should eventually
189 190
 * not be external if possible.
 *****************************************************************************/
191
int dvdcss_title ( dvdcss_t dvdcss, int i_block )
192
{
193 194 195 196
    struct dvd_title *p_title;
    struct dvd_title *p_newtitle;
    dvd_key p_title_key;
    int i_fd, i_ret = -1, b_cache = 0;
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215

    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 */
216
        memcpy( dvdcss->css.p_title_key, p_title->p_key, sizeof(p_title->p_key) );
217 218 219
        return 0;
    }

220 221 222 223
    /* Check whether the key is in our disk cache */
    if( dvdcss->psz_cachefile[0] )
    {
        /* XXX: be careful, we use sprintf and not snprintf */
224 225
        sprintf( dvdcss->psz_block, "%." CACHE_FILENAME_LENGTH_STRING "x",
                 i_block );
226 227
        i_fd = open( dvdcss->psz_cachefile, O_RDONLY );
        b_cache = 1;
228

229 230
        if( i_fd >= 0 )
        {
231
            char psz_key[PSZ_KEY_SIZE];
Sam Hocevar's avatar
Sam Hocevar committed
232 233
            unsigned int k0, k1, k2, k3, k4;

234
            psz_key[PSZ_KEY_SIZE - 1] = '\0';
Sam Hocevar's avatar
Sam Hocevar committed
235

236
            if( read( i_fd, psz_key, PSZ_KEY_SIZE - 1 ) == PSZ_KEY_SIZE - 1
Sam Hocevar's avatar
Sam Hocevar committed
237 238
                 && sscanf( psz_key, "%x:%x:%x:%x:%x",
                            &k0, &k1, &k2, &k3, &k4 ) == 5 )
239
            {
Sam Hocevar's avatar
Sam Hocevar committed
240 241 242 243 244 245 246
                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 );

247 248 249 250
                /* Don't try to save it again */
                b_cache = 0;
                i_ret = 1;
            }
Sam Hocevar's avatar
Sam Hocevar committed
251

252 253 254 255
            close( i_fd );
        }
    }

256 257
    /* Crack or decrypt Content Scrambling System (CSS) title key
     * for current Video Title Set (VTS). */
258 259
    if( i_ret < 0 )
    {
260
        i_ret = dvdcss_titlekey( dvdcss, i_block, p_title_key );
261 262 263

        if( i_ret < 0 )
        {
264 265
            print_error( dvdcss, "fatal error in Video Title Set (VTS) "
                                 "Content Scrambling System (CSS) key" );
266 267 268 269 270
            return i_ret;
        }

        if( i_ret == 0 )
        {
271
            print_debug( dvdcss, "unencrypted title" );
272 273
            /* We cache this anyway, so we don't need to check again. */
        }
274
    }
275 276

    /* Key is valid, we store it on disk. */
Sam Hocevar's avatar
Sam Hocevar committed
277
    if( dvdcss->psz_cachefile[0] && b_cache )
278
    {
Sam Hocevar's avatar
Sam Hocevar committed
279
        i_fd = open( dvdcss->psz_cachefile, O_RDWR|O_CREAT, 0644 );
280 281
        if( i_fd >= 0 )
        {
282
            char psz_key[PSZ_KEY_SIZE + 2];
Sam Hocevar's avatar
Sam Hocevar committed
283 284 285 286 287

            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] );

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
288
            if( write( i_fd, psz_key, PSZ_KEY_SIZE + 1 ) < PSZ_KEY_SIZE + 1 )
289 290 291 292
            {
                print_error( dvdcss,
                             "Error caching key on disk, continuing..\n" );
            }
293 294
            close( i_fd );
        }
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
    }

    /* 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 */
310
    p_newtitle = malloc( sizeof( *p_newtitle ) );
311 312 313 314
    if( p_newtitle == NULL )
    {
        return -1;
    }
315
    p_newtitle->i_startlb = i_block;
316
    memcpy( p_newtitle->p_key, p_title_key, DVD_KEY_SIZE );
317 318 319 320 321 322 323 324 325 326 327 328 329 330

    /* 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;
    }

331
    memcpy( dvdcss->css.p_title_key, p_title_key, DVD_KEY_SIZE );
332 333 334 335
    return 0;
}

/*****************************************************************************
336
 * dvdcss_disckey: get disc key.
337 338
 *****************************************************************************
 * This function should only be called if DVD ioctls are present.
339
 * It will set dvdcss->i_method = DVDCSS_METHOD_TITLE if it fails to find
340 341
 * a valid disc key.
 * Two decryption methods are offered:
342 343 344
 *  -disc key hash crack,
 *  -decryption with player keys if they are available.
 *****************************************************************************/
345
int dvdcss_disckey( dvdcss_t dvdcss )
346
{
Sam Hocevar's avatar
Sam Hocevar committed
347
    unsigned char p_buffer[ DVD_DISCKEY_SIZE ];
348
    dvd_key p_disc_key;
349 350
    int i;

351
    if( GetBusKey( dvdcss ) < 0 )
352 353 354 355 356 357 358
    {
        return -1;
    }

    /* Get encrypted disc key */
    if( ioctl_ReadDiscKey( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
    {
359
        print_error( dvdcss, "ioctl ReadDiscKey failed" );
360 361 362
        return -1;
    }

363
    /* This should have invalidated the AGID and got us ASF=1. */
364
    if( GetASF( dvdcss ) != 1 )
365
    {
366
        /* Region mismatch (or region not set) is the most likely source. */
367 368
        print_error( dvdcss, "authentication success flag (ASF) not 1 after "
                             "reading disc key (region mismatch?)" );
369 370 371 372
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
        return -1;
    }

Sam Hocevar's avatar
Sam Hocevar committed
373
    /* Shuffle disc key using bus key */
Sam Hocevar's avatar
Sam Hocevar committed
374
    for( i = 0 ; i < DVD_DISCKEY_SIZE ; i++ )
375
    {
376
        p_buffer[i] ^= dvdcss->css.p_bus_key[4 - (i % DVD_KEY_SIZE)];
377 378
    }

Sam Hocevar's avatar
Sam Hocevar committed
379
    /* Decrypt disc key */
380 381 382
    switch( dvdcss->i_method )
    {
        case DVDCSS_METHOD_KEY:
383

384
            /* Decrypt disc key with player key. */
385
            PrintKey( dvdcss, "decrypting disc key ", p_buffer );
386
            if( ! DecryptDiscKey( dvdcss, p_buffer, p_disc_key ) )
387
            {
388
                PrintKey( dvdcss, "decrypted disc key is ", p_disc_key );
389 390
                break;
            }
391 392 393
            print_debug( dvdcss, "failed to decrypt the disc key, "
                                 "faulty drive/kernel? "
                                 "cracking title keys instead" );
394

395
            /* Fallback, but not to DISC as the disc key might be faulty */
396
            memset( p_disc_key, 0, DVD_KEY_SIZE );
397 398
            dvdcss->i_method = DVDCSS_METHOD_TITLE;
            break;
399

400
        case DVDCSS_METHOD_DISC:
401

402
            /* Crack Disc key to be able to use it */
403
            memcpy( p_disc_key, p_buffer, DVD_KEY_SIZE );
404
            PrintKey( dvdcss, "cracking disc key ", p_disc_key );
405
            if( ! CrackDiscKey( p_disc_key ) )
406
            {
407 408
                PrintKey( dvdcss, "cracked disc key is ", p_disc_key );
                break;
409
            }
410
            print_debug( dvdcss, "failed to crack the disc key" );
411
            memset( p_disc_key, 0, DVD_KEY_SIZE );
412
            dvdcss->i_method = DVDCSS_METHOD_TITLE;
413 414 415
            break;

        default:
416

417
            print_debug( dvdcss, "disc key does not need to be decrypted" );
418
            memset( p_disc_key, 0, DVD_KEY_SIZE );
419
            break;
420 421
    }

422
    memcpy( dvdcss->css.p_disc_key, p_disc_key, DVD_KEY_SIZE );
423

424 425 426 427 428
    return 0;
}


/*****************************************************************************
429
 * dvdcss_titlekey: get title key.
430
 *****************************************************************************/
431
static int dvdcss_titlekey( dvdcss_t dvdcss, int i_pos, dvd_key p_title_key )
432
{
Sam Hocevar's avatar
Sam Hocevar committed
433
    static uint8_t p_garbage[ DVDCSS_BLOCK_SIZE ];  /* we never read it back */
434
    uint8_t p_key[DVD_KEY_SIZE];
435
    int i, i_ret = 0;
436

437
    if( dvdcss->b_ioctls && ( dvdcss->i_method == DVDCSS_METHOD_KEY ||
438
                              dvdcss->i_method == DVDCSS_METHOD_DISC ) )
439
    {
440 441
        /* We have a decrypted Disc key and the ioctls are available,
         * read the title key and decrypt it.
442 443
         */

444 445
        print_debug( dvdcss, "getting title key at block %i the classic way",
                             i_pos );
446

447
        /* We need to authenticate again every time to get a new session key */
448
        if( GetBusKey( dvdcss ) < 0 )
449
        {
450
            i_ret = -1;
451
        }
452 453 454 455 456

        /* Get encrypted title key */
        if( ioctl_ReadTitleKey( dvdcss->i_fd, &dvdcss->css.i_agid,
                                i_pos, p_key ) < 0 )
        {
457 458
            print_debug( dvdcss,
                         "ioctl ReadTitleKey failed (region mismatch?)" );
459 460 461 462
            i_ret = -1;
        }

        /* Test ASF, it will be reset to 0 if we got a Region error */
463
        switch( GetASF( dvdcss ) )
464 465 466
        {
            case -1:
                /* An error getting the ASF status, something must be wrong. */
467
                print_debug( dvdcss, "lost authentication success flag (ASF), requesting title key" );
468
                ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
469
                i_ret = -1;
470
                break;
471 472

            case 0:
473
                /* This might either be a title that has no key,
474
                 * or we encountered a region error. */
475
                print_debug( dvdcss, "lost authentication success flag (ASF), requesting title key" );
476
                break;
477 478

            case 1:
479
                /* Drive status is OK. */
480
                /* If the title key request failed, but we did not lose ASF,
481
                 * we might still have the AGID.  Other code assumes that we
482 483 484 485 486
                 * will not after this so invalidate it(?). */
                if( i_ret < 0 )
                {
                    ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
                }
487
                break;
488
        }
489 490 491 492

        if( !( i_ret < 0 ) )
        {
            /* Decrypt title key using the bus key */
493
            for( i = 0 ; i < DVD_KEY_SIZE ; i++ )
494
            {
495
                p_key[i] ^= dvdcss->css.p_bus_key[4 - (i % DVD_KEY_SIZE)];
496 497
            }

Sam Hocevar's avatar
Sam Hocevar committed
498
            /* If p_key is all zero then there really wasn't any key present
499 500 501 502 503 504 505
             * 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
            {
506
                PrintKey( dvdcss, "initial disc key ", dvdcss->css.p_disc_key );
507
                DecryptTitleKey( dvdcss->css.p_disc_key, p_key );
508
                PrintKey( dvdcss, "decrypted title key ", p_key );
509 510 511 512
                i_ret = 1;
            }

            /* All went well either there wasn't a key or we have it now. */
513
            memcpy( p_title_key, p_key, DVD_KEY_SIZE );
514 515 516 517 518 519
            PrintKey( dvdcss, "title key is ", p_title_key );

            return i_ret;
        }

        /* The title key request failed */
520
        print_debug( dvdcss, "resetting drive and cracking title key" );
521

522
        /* Read an unscrambled sector and reset the drive */
523 524 525
        dvdcss->pf_seek( dvdcss, 0 );
        dvdcss->pf_read( dvdcss, p_garbage, 1 );
        dvdcss->pf_seek( dvdcss, 0 );
526
        dvdcss_disckey( dvdcss );
527 528

        /* Fallback */
529
    }
530

531 532
    /* 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. */
533

534
    /* For now, the read limit is 9GB / 2048 =  4718592 sectors. */
535
    i_ret = CrackTitleKey( dvdcss, i_pos, 4718592, p_key );
536

537
    memcpy( p_title_key, p_key, DVD_KEY_SIZE );
538
    PrintKey( dvdcss, "title key is ", p_title_key );
539

540
    return i_ret;
541 542 543
}

/*****************************************************************************
544
 * dvdcss_unscramble: does the actual descrambling of data
545
 *****************************************************************************
546 547
 * sec: sector to unscramble
 * key: title key for this sector
548
 *****************************************************************************/
549
int dvdcss_unscramble( dvd_key p_key, uint8_t *p_sec )
550 551
{
    unsigned int    i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
Sam Hocevar's avatar
Sam Hocevar committed
552
    uint8_t        *p_end = p_sec + DVDCSS_BLOCK_SIZE;
553 554

    /* PES_scrambling_control */
555
    if( !(p_sec[0x14] & 0x30) )
556
    {
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
        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;
        *p_sec = p_css_tab1[*p_sec] ^ ( i_t5 & 0xff );
        p_sec++;
        i_t5 >>= 8;
    }

    return 0;
}
588

589 590 591
/* Following functions are local */

/*****************************************************************************
592
 * GetBusKey: Go through the Content Scrambling System (CSS) authentication process
593 594 595 596
 *****************************************************************************
 * 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
597
 * respond with ASF=1. For instance the old DVD-ROMs on Compaq Armada say
598 599 600 601 602 603
 * that ASF=1 from the start and then later fail with a 'read of scrambled
 * block without authentication' error.
 *****************************************************************************/
static int GetBusKey( dvdcss_t dvdcss )
{
    uint8_t   p_buffer[10];
604
    uint8_t   p_challenge[2 * DVD_KEY_SIZE];
605 606 607
    dvd_key   p_key1;
    dvd_key   p_key2;
    dvd_key   p_key_check;
608 609 610 611
    uint8_t   i_variant = 0;
    int       i_ret = -1;
    int       i;

612
    print_debug( dvdcss, "requesting authentication grant ID (AGID)" );
613 614 615
    i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );

    /* We might have to reset hung authentication processes in the drive
616 617 618
     * by invalidating the corresponding authentication grant ID (AGID)'.
     * As long as we haven't got an AGID, invalidate one (in sequence)
     * and try again. */
619 620
    for( i = 0; i_ret == -1 && i < 4 ; ++i )
    {
621 622
        print_debug( dvdcss, "ioctl ReportAgid failed, invalidating "
                             "authentication grant ID (AGID) %d", i );
623 624 625 626 627 628 629

        /* This is really _not good_, should be handled by the OS.
         * Invalidating an AGID could make another process fail somewhere
         * in its authentication process. */
        dvdcss->css.i_agid = i;
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );

630
        print_debug( dvdcss, "requesting authentication grant ID (AGID)" );
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
        i_ret = ioctl_ReportAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
    }

    /* Unable to authenticate without AGID */
    if( i_ret == -1 )
    {
        print_error( dvdcss, "ioctl ReportAgid failed, fatal" );
        return -1;
    }

    /* Setup a challenge, any values should work */
    for( i = 0 ; i < 10; ++i )
    {
        p_challenge[i] = i;
    }

    /* Get challenge from host */
    for( i = 0 ; i < 10 ; ++i )
    {
        p_buffer[9-i] = p_challenge[i];
    }

    /* Send challenge to LU */
    if( ioctl_SendChallenge( dvdcss->i_fd,
                             &dvdcss->css.i_agid, p_buffer ) < 0 )
    {
        print_error( dvdcss, "ioctl SendChallenge failed" );
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
        return -1;
    }

    /* Get key1 from LU */
    if( ioctl_ReportKey1( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0)
    {
        print_error( dvdcss, "ioctl ReportKey1 failed" );
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
        return -1;
    }

    /* Send key1 to host */
671
    for( i = 0 ; i < DVD_KEY_SIZE ; i++ )
672 673 674 675 676 677 678 679
    {
        p_key1[i] = p_buffer[4-i];
    }

    for( i = 0 ; i < 32 ; ++i )
    {
        CryptKey( 0, i, p_challenge, p_key_check );

680
        if( memcmp( p_key_check, p_key1, DVD_KEY_SIZE ) == 0 )
681
        {
682 683 684
            print_debug( dvdcss, "drive authenticated, using variant %d", i );
            i_variant = i;
            break;
685 686 687
        }
    }

688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
    if( i == 32 )
    {
        print_error( dvdcss, "drive would not authenticate" );
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
        return -1;
    }

    /* Get challenge from LU */
    if( ioctl_ReportChallenge( dvdcss->i_fd,
                               &dvdcss->css.i_agid, p_buffer ) < 0 )
    {
        print_error( dvdcss, "ioctl ReportKeyChallenge failed" );
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
        return -1;
    }

    /* Send challenge to host */
    for( i = 0 ; i < 10 ; ++i )
    {
        p_challenge[i] = p_buffer[9-i];
    }

    CryptKey( 1, i_variant, p_challenge, p_key2 );

    /* Get key2 from host */
713
    for( i = 0 ; i < DVD_KEY_SIZE ; ++i )
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
    {
        p_buffer[4-i] = p_key2[i];
    }

    /* Send key2 to LU */
    if( ioctl_SendKey2( dvdcss->i_fd, &dvdcss->css.i_agid, p_buffer ) < 0 )
    {
        print_error( dvdcss, "ioctl SendKey2 failed" );
        ioctl_InvalidateAgid( dvdcss->i_fd, &dvdcss->css.i_agid );
        return -1;
    }

    /* The drive has accepted us as authentic. */
    print_debug( dvdcss, "authentication established" );

729 730
    memcpy( p_challenge, p_key1, DVD_KEY_SIZE );
    memcpy( p_challenge + DVD_KEY_SIZE, p_key2, DVD_KEY_SIZE );
731 732 733

    CryptKey( 2, i_variant, p_challenge, dvdcss->css.p_bus_key );

734 735 736
    return 0;
}

737
/*****************************************************************************
738
 * PrintKey: debug function that dumps a key value
739
 *****************************************************************************/
740
static void PrintKey( dvdcss_t dvdcss, const char *prefix, const uint8_t *data )
741 742 743 744
{
    print_debug( dvdcss, "%s%02x:%02x:%02x:%02x:%02x", prefix,
                 data[0], data[1], data[2], data[3], data[4] );
}
745 746

/*****************************************************************************
747
 * GetASF: Get authentication success flag (ASF)
748
 *****************************************************************************
749
 * Returns:
750 751 752 753
 *  -1 on ioctl error,
 *  0 if the device needs to be authenticated,
 *  1 either.
 *****************************************************************************/
754
static int GetASF( dvdcss_t dvdcss )
755 756 757
{
    int i_asf = 0;

758
    if( ioctl_ReportASF( dvdcss->i_fd, &i_asf ) != 0 )
759
    {
760
        /* The ioctl process has failed */
761
        print_error( dvdcss, "GetASF fatal error" );
762 763
        return -1;
    }
764

765 766
    if( i_asf )
    {
767
        print_debug( dvdcss, "authentication success flag set, ASF=1" );
768 769 770
    }
    else
    {
771
        print_debug( dvdcss, "authentication success flag not set, ASF=0" );
772 773
    }

774
    return i_asf;
775 776 777
}

/*****************************************************************************
778
 * CryptKey: shuffle bits and decrypt keys.
779
 *****************************************************************************
780
 * Used during authentication and disc key negotiation in GetBusKey.
781 782
 * i_key_type: 0->key1, 1->key2, 2->buskey.
 * i_variant: between 0 and 31.
783
 *****************************************************************************/
784
static void CryptKey( int i_key_type, int i_variant,
785
                      const uint8_t *p_challenge, uint8_t *p_key )
786 787
{
    /* Permutation table for challenge */
788
    static const uint8_t pp_perm_challenge[3][10] =
789 790 791 792
            { { 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 } };

793
    /* Permutation table for variant table for key2 and buskey */
794
    static const uint8_t pp_perm_variant[2][32] =
795 796 797 798 799 800 801 802 803
            { { 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 } };

804
    static const uint8_t p_variants[32] =
805 806 807 808 809 810
            {   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 */
811
    static const uint8_t p_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 };
812 813 814 815 816 817 818 819 820 821

    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;
822 823 824 825

    for (i = 9; i >= 0; --i)
        p_scratch[i] = p_challenge[pp_perm_challenge[i_key_type][i]];

826 827
    i_css_variant = ( i_key_type == 0 ) ? i_variant :
                    pp_perm_variant[i_key_type-1][i_variant];
828 829 830 831

    /*
     * This encryption engine implements one of 32 variations
     * one the same theme depending upon the choice in the
832
     * variant parameter (0 - 31).
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
     *
     * 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
     *
861
     * The second LFSR is of degree 17,  and has a (primitive) polynomial of:
862 863 864 865 866 867 868 869 870 871 872
     * 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.
     *
     */
873

874
    /* In order to ensure that the LFSR works we need to ensure that the
875
     * initial values are non-zero.  Thus when we initialize them from
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901
     * 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;
        }
902

903 904 905 906 907 908 909
        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.
     */
910
    i_cse = p_variants[i_css_variant] ^ p_crypt_tab2[i_css_variant];
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976

    /* 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];
        i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;

        p_tmp2[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
    }
    p_tmp2[4] ^= p_tmp2[0];

    for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp2[i] )
    {
        i_index = p_bits[15 + i] ^ p_tmp2[i];
        i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;
        i_index = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;

        p_tmp1[i] = p_crypt_tab0[i_index] ^ p_crypt_tab2[i_index];
    }
    p_tmp1[4] ^= p_tmp1[0];

    for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp1[i] )
    {
        i_index = p_bits[10 + i] ^ p_tmp1[i];
        i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;

        i_index = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;

        p_tmp2[i] = p_crypt_tab0[i_index] ^ p_crypt_tab2[i_index];
    }
    p_tmp2[4] ^= p_tmp2[0];

    for( i = 5, i_term = 0 ; --i >= 0 ; i_term = p_tmp2[i] )
    {
        i_index = p_bits[5 + i] ^ p_tmp2[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[i] ^ p_tmp1[i];
        i_index = p_crypt_tab1[i_index] ^ ~p_crypt_tab2[i_index] ^ i_cse;

        p_key[i] = p_crypt_tab2[i_index] ^ p_crypt_tab3[i_index] ^ i_term;
    }

    return;
}

/*****************************************************************************
977
 * DecryptKey: decrypt p_crypted with p_key.
978
 *****************************************************************************
979
 * Used to decrypt the disc key, with a player key, after requesting it
980 981
 * in dvdcss_disckey and to decrypt title keys, with a disc key, requested
 * in dvdcss_titlekey.
982
 * The player keys and the resulting disc key are only used as KEKs
983
 * (key encryption keys).
984
 * Decryption is slightly dependent on the type of key:
985
 *  -for disc key, invert is 0x00,
986
 *  -for title key, invert if 0xff.
987
 *****************************************************************************/
988 989
static void DecryptKey( uint8_t invert, const uint8_t *p_key,
                        const uint8_t *p_crypted, uint8_t *p_result )
990 991 992 993 994
{
    unsigned int    i_lfsr1_lo;
    unsigned int    i_lfsr1_hi;
    unsigned int    i_lfsr0;
    unsigned int    i_combined;
995 996 997
    uint8_t         o_lfsr0;
    uint8_t         o_lfsr1;
    uint8_t         k[5];
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
    int             i;

    i_lfsr1_lo = p_key[0] | 0x100;
    i_lfsr1_hi = p_key[1];

    i_lfsr0    = ( ( p_key[4] << 17 )
                 | ( p_key[3] << 9 )
                 | ( p_key[2] << 1 ) )
                 + 8 - ( p_key[2] & 7 );
    i_lfsr0    = ( p_css_tab4[i_lfsr0 & 0xff] << 24 ) |
                 ( p_css_tab4[( i_lfsr0 >> 8 ) & 0xff] << 16 ) |
                 ( p_css_tab4[( i_lfsr0 >> 16 ) & 0xff] << 8 ) |
                   p_css_tab4[( i_lfsr0 >> 24 ) & 0xff];

    i_combined = 0;
1013
    for( i = 0 ; i < DVD_KEY_SIZE ; ++i )
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
    {
        o_lfsr1     = p_css_tab2[i_lfsr1_hi] ^ p_css_tab3[i_lfsr1_lo];
        i_lfsr1_hi  = i_lfsr1_lo >> 1;
        i_lfsr1_lo  = ( ( i_lfsr1_lo & 1 ) << 8 ) ^ o_lfsr1;
        o_lfsr1     = p_css_tab4[o_lfsr1];

        o_lfsr0 = ((((((( i_lfsr0 >> 8 ) ^ i_lfsr0 ) >> 1 )
                        ^ i_lfsr0 ) >> 3 ) ^ i_lfsr0 ) >> 7 );
        i_lfsr0 = ( i_lfsr0 >> 8 ) | ( o_lfsr0 << 24 );

        i_combined += ( o_lfsr0 ^ invert ) + o_lfsr1;
        k[i] = i_combined & 0xff;
        i_combined >>= 8;
    }

1029 1030 1031 1032 1033
    p_result[4] = k[4] ^ p_css_tab1[p_crypted[4]] ^ p_crypted[3];
    p_result[3] = k[3] ^ p_css_tab1[p_crypted[3]] ^ p_crypted[2];
    p_result[2] = k[2] ^ p_css_tab1[p_crypted[2]] ^ p_crypted[1];
    p_result[1] = k[1] ^ p_css_tab1[p_crypted[1]] ^ p_crypted[0];
    p_result[0] = k[0] ^ p_css_tab1[p_crypted[0]] ^ p_result[4];
1034

1035 1036 1037 1038 1039
    p_result[4] = k[4] ^ p_css_tab1[p_result[4]] ^ p_result[3];
    p_result[3] = k[3] ^ p_css_tab1[p_result[3]] ^ p_result[2];
    p_result[2] = k[2] ^ p_css_tab1[p_result[2]] ^ p_result[1];
    p_result[1] = k[1] ^ p_css_tab1[p_result[1]] ^ p_result[0];
    p_result[0] = k[0] ^ p_css_tab1[p_result[0]];
1040 1041 1042 1043

    return;
}

1044 1045 1046 1047 1048 1049 1050
/*****************************************************************************
 * player_keys: alternate DVD player keys
 *****************************************************************************
 * These player keys were generated using Frank A. Stevenson's PlayerKey
 * cracker. A copy of his article can be found here:
 * http://www-2.cs.cmu.edu/~dst/DeCSS/FrankStevenson/mail2.txt
 *****************************************************************************/
1051
static const dvd_key player_keys[] =
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
{
    { 0x01, 0xaf, 0xe3, 0x12, 0x80 },
    { 0x12, 0x11, 0xca, 0x04, 0x3b },
    { 0x14, 0x0c, 0x9e, 0xd0, 0x09 },
    { 0x14, 0x71, 0x35, 0xba, 0xe2 },
    { 0x1a, 0xa4, 0x33, 0x21, 0xa6 },
    { 0x26, 0xec, 0xc4, 0xa7, 0x4e },
    { 0x2c, 0xb2, 0xc1, 0x09, 0xee },
    { 0x2f, 0x25, 0x9e, 0x96, 0xdd },
    { 0x33, 0x2f, 0x49, 0x6c, 0xe0 },
    { 0x35, 0x5b, 0xc1, 0x31, 0x0f },
    { 0x36, 0x67, 0xb2, 0xe3, 0x85 },
    { 0x39, 0x3d, 0xf1, 0xf1, 0xbd },
    { 0x3b, 0x31, 0x34, 0x0d, 0x91 },
    { 0x45, 0xed, 0x28, 0xeb, 0xd3 },
    { 0x48, 0xb7, 0x6c, 0xce, 0x69 },
    { 0x4b, 0x65, 0x0d, 0xc1, 0xee },
    { 0x4c, 0xbb, 0xf5, 0x5b, 0x23 },
    { 0x51, 0x67, 0x67, 0xc5, 0xe0 },
    { 0x53, 0x94, 0xe1, 0x75, 0xbf },
    { 0x57, 0x2c, 0x8b, 0x31, 0xae },
    { 0x63, 0xdb, 0x4c, 0x5b, 0x4a },
    { 0x7b, 0x1e, 0x5e, 0x2b, 0x57 },
    { 0x85, 0xf3, 0x85, 0xa0, 0xe0 },
    { 0xab, 0x1e, 0xe7, 0x7b, 0x72 },
    { 0xab, 0x36, 0xe3, 0xeb, 0x76 },
    { 0xb1, 0xb8, 0xf9, 0x38, 0x03 },
    { 0xb8, 0x5d, 0xd8, 0x53, 0xbd },
    { 0xbf, 0x92, 0xc3, 0xb0, 0xe2 },
    { 0xcf, 0x1a, 0xb2, 0xf8, 0x0a },
    { 0xec, 0xa0, 0xcf, 0xb3, 0xff },
    { 0xfc, 0x95, 0xa9, 0x87, 0x35 }
};

1086
/*****************************************************************************
1087
 * DecryptDiscKey
1088
 *****************************************************************************
1089 1090
 * Decryption of the disc key with player keys: try to decrypt the disc key
 * from every position with every player key.
1091 1092 1093
 * p_struct_disckey: the 2048 byte DVD_STRUCT_DISCKEY data
 * p_disc_key: result, the 5 byte disc key
 *****************************************************************************/
1094
static int DecryptDiscKey( dvdcss_t dvdcss, const uint8_t *p_struct_disckey,
1095
                           dvd_key p_disc_key )
1096
{
1097
    uint8_t p_verify[DVD_KEY_SIZE];
1098
    unsigned int i, n = 0;
1099

1100
    /* Decrypt disc key with the above player keys */
1101
    for( n = 0; n < sizeof(player_keys) / sizeof(*player_keys); n++ )
1102
    {
1103 1104
        PrintKey( dvdcss, "trying player key ", player_keys[n] );

1105 1106 1107
        for( i = 1; i < 409; i++ )
        {
            /* Check if player key n is the right key for position i. */
1108 1109
            DecryptKey( 0, player_keys[n], p_struct_disckey + 5 * i,
                        p_disc_key );
1110

1111
            /* The first part in the struct_disckey block is the
1112
             * 'disc key' encrypted with itself.  Using this we
1113
             * can check if we decrypted the correct key. */
1114
            DecryptKey( 0, p_disc_key, p_struct_disckey, p_verify );
1115 1116

            /* If the position / player key pair worked then return. */
1117
            if( memcmp( p_disc_key, p_verify, DVD_KEY_SIZE ) == 0 )
1118 1119 1120 1121 1122
            {
                return 0;
            }
        }
    }
1123

1124
    /* Have tried all combinations of positions and keys,
1125
     * and we still didn't succeed. */
1126
    memset( p_disc_key, 0, DVD_KEY_SIZE );
1127 1128 1129 1130
    return -1;
}

/*****************************************************************************
1131
 * DecryptTitleKey
1132 1133 1134 1135 1136
 *****************************************************************************
 * Decrypt the title key using the disc key.
 * p_disc_key: result, the 5 byte disc key
 * p_titlekey: the encrypted title key, gets overwritten by the decrypted key
 *****************************************************************************/
1137
static void DecryptTitleKey( dvd_key p_disc_key, dvd_key p_titlekey )
1138
{
1139
    DecryptKey( 0xff, p_disc_key, p_titlekey, p_titlekey );
1140 1141
}

1142
/*****************************************************************************
1143
 * CrackDiscKey: brute force disc key
1144 1145
 * CSS hash reversal function designed by Frank Stevenson
 *****************************************************************************
1146
 * This function uses a big amount of memory to crack the disc key from the
1147 1148
 * disc key hash, if player keys are not available.
 *****************************************************************************/
1149
#define K1TABLESIZE  65536
1150 1151
#define K1TABLEWIDTH 10

1152 1153
#define BIGTABLESIZE 16777216

1154 1155 1156
/*
 * Simple function to test if a candidate key produces the given hash
 */
1157
static int investigate( unsigned char *hash, unsigned char *ckey )
1158
{
1159
    unsigned char key[DVD_KEY_SIZE];
1160

1161
    DecryptKey( 0, ckey, hash, key );
1162

1163
    return memcmp( key, ckey, DVD_KEY_SIZE );
1164 1165
}

1166
static int CrackDiscKey( uint8_t *p_disc_key )
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
{
    unsigned char B[5] = { 0,0,0,0,0 }; /* Second Stage of mangle cipher */
    unsigned char C[5] = { 0,0,0,0,0 }; /* Output Stage of mangle cipher
                                         * IntermediateKey */
    unsigned char k[5] = { 0,0,0,0,0 }; /* Mangling cipher key
                                         * Also output from CSS( C ) */
    unsigned char out1[5];              /* five first output bytes of LFSR1 */
    unsigned char out2[5];              /* five first output bytes of LFSR2 */
    unsigned int lfsr1a;                /* upper 9 bits of LFSR1 */
    unsigned int lfsr1b;                /* lower 8 bits of LFSR1 */
    unsigned int tmp, tmp2, tmp3, tmp4,tmp5;
1178
    int i, j, ret = 0;
1179 1180 1181 1182 1183
    unsigned int nStepA;        /* iterator for LFSR1 start state */
    unsigned int nStepB;        /* iterator for possible B[0]     */
    unsigned int nTry;          /* iterator for K[1] possibilities */
    unsigned int nPossibleK1;   /* #of possible K[1] values */
    unsigned char* K1table;     /* Lookup table for possible K[1] */
1184
    unsigned int*  BigTable;    /* LFSR2 startstate indexed by
1185 1186 1187 1188 1189 1190 1191
                                 * 1,2,5 output byte */

    /*
     * Prepare tables for hash reversal
     */

    /* initialize lookup tables for k[1] */
1192
    K1table = calloc( K1TABLESIZE, K1TABLEWIDTH );
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215
    if( K1table == NULL )
    {
        return -1;
    }

    tmp = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ];
    for( i = 0 ; i < 256 ; i++ ) /* k[1] */
    {
        tmp2 = p_css_tab1[ tmp ^ i ]; /* p_css_tab1[ B[1] ]*/

        for( j = 0 ; j < 256 ; j++ ) /* B[0] */
        {
            tmp3 = j ^ tmp2 ^ i; /* C[1] */
            tmp4 = K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ]; /* count of entries  here */
            tmp4++;
            if( tmp4 < K1TABLEWIDTH )
            {
                K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) +    tmp4 ] = i;
            }
            K1table[ K1TABLEWIDTH * ( 256 * j + tmp3 ) ] = tmp4;
        }
    }

1216
    /* Initializing our really big table */
1217
    BigTable = calloc( BIGTABLESIZE, sizeof(*BigTable) );
1218 1219
    if( BigTable == NULL )
    {
1220
        free( K1table );
1221 1222 1223 1224 1225
        return -1;
    }

    tmp3 = 0;

1226
    for( i = 0 ; i < BIGTABLESIZE ; i++ )
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
    {
        tmp = (( i + i ) & 0x1fffff0 ) | 0x8 | ( i & 0x7 );

        for( j = 0 ; j < 5 ; j++ )
        {
            tmp2=((((((( tmp >> 3 ) ^ tmp ) >> 1 ) ^ tmp ) >> 8 )
                                    ^ tmp ) >> 5 ) & 0xff;
            tmp = ( tmp << 8) | tmp2;
            out2[j] = p_css_tab4[ tmp2 ];
        }

        j = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4];
1239 1240 1241 1242 1243
        if ( j >= BIGTABLESIZE )
        {
            ret = -1;
            goto error;
        }
1244 1245 1246 1247
        BigTable[j] = i;
    }

    /*
1248
     * We are done initializing, now reverse hash
1249 1250 1251
     */
    tmp5 = p_disc_key[0] ^ p_css_tab1[ p_disc_key[1] ];

1252
    for( nStepA = 0 ; nStepA < K1TABLESIZE ; nStepA ++ )
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
    {
        lfsr1a = 0x100 | ( nStepA >> 8 );
        lfsr1b = nStepA & 0xff;

        /* Generate 5 first output bytes from lfsr1 */
        for( i = 0 ; i < 5 ; i++ )
        {
            tmp = p_css_tab2[ lfsr1b ] ^ p_css_tab3[ lfsr1a ];
            lfsr1b = lfsr1a >> 1;
            lfsr1a = ((lfsr1a&1)<<8) ^ tmp;
            out1[ i ] = p_css_tab4[ tmp ];
        }

1266
        /* compute and cache some variables */
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298
        C[0] = nStepA >> 8;
        C[1] = nStepA & 0xff;
        tmp = p_disc_key[3] ^ p_css_tab1[ p_disc_key[4] ];
        tmp2 = p_css_tab1[ p_disc_key[0] ];

        /* Search through all possible B[0] */
        for( nStepB = 0 ; nStepB < 256 ; nStepB++ )
        {
            /* reverse parts of the mangling cipher */
            B[0] = nStepB;
            k[0] = p_css_tab1[ B[0] ] ^ C[0];
            B[4] = B[0] ^ k[0] ^ tmp2;
            k[4] = B[4] ^ tmp;
            nPossibleK1 = K1table[ K1TABLEWIDTH * (256 * B[0] + C[1]) ];

            /* Try out all possible values for k[1] */
            for( nTry = 0 ; nTry < nPossibleK1 ; nTry++ )
            {
                k[1] = K1table[ K1TABLEWIDTH * (256 * B[0] + C[1]) + nTry + 1 ];
                B[1] = tmp5 ^ k[1];

                /* reconstruct output from LFSR2 */
                tmp3 = ( 0x100 + k[0] - out1[0] );
                out2[0] = tmp3 & 0xff;
                tmp3 = tmp3 & 0x100 ? 0x100 : 0xff;
                tmp3 = ( tmp3 + k[1] - out1[1] );
                out2[1] = tmp3 & 0xff;
                tmp3 = ( 0x100 + k[4] - out1[4] );
                out2[4] = tmp3 & 0xff;  /* Can be 1 off  */

                /* test first possible out2[4] */
                tmp4 = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4];
1299 1300 1301 1302 1303
                if ( tmp4 >= BIGTABLESIZE )
                {
                    ret = -1;
                    goto error;
                }
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
                tmp4 = BigTable[ tmp4 ];
                C[2] = tmp4 & 0xff;
                C[3] = ( tmp4 >> 8 ) & 0xff;
                C[4] = ( tmp4 >> 16 ) & 0xff;
                B[3] = p_css_tab1[ B[4] ] ^ k[4] ^ C[4];
                k[3] = p_disc_key[2] ^ p_css_tab1[ p_disc_key[3] ] ^ B[3];
                B[2] = p_css_tab1[ B[3] ] ^ k[3] ^ C[3];
                k[2] = p_disc_key[1] ^ p_css_tab1[ p_disc_key[2] ] ^ B[2];

                if( ( B[1] ^ p_css_tab1[ B[2] ] ^ k[ 2 ]  ) == C[ 2 ] )
                {
                    if( ! investigate( &p_disc_key[0] , &C[0] ) )
                    {
                        goto end;
                    }
                }

                /* Test second possible out2[4] */
                out2[4] = ( out2[4] + 0xff ) & 0xff;
                tmp4 = ( out2[0] << 16 ) | ( out2[1] << 8 ) | out2[4];
1324 1325 1326 1327 1328
                if ( tmp4 >= BIGTABLESIZE )
                {
                    ret = -1;
                    goto error;
                }
1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349
                tmp4 = BigTable[ tmp4 ];
                C[2] = tmp4 & 0xff;
                C[3] = ( tmp4 >> 8 ) & 0xff;</