]> git.sesse.net Git - vlc/blob - plugins/dvd/dvd_css.c
* Ported Glide and MGA plugins to the new module API. MGA never worked,
[vlc] / plugins / dvd / dvd_css.c
1 /*****************************************************************************
2  * dvd_css.c: Functions for DVD authentification and unscrambling
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: dvd_css.c,v 1.12 2001/02/20 07:49:12 sam Exp $
6  *
7  * Author: Stéphane Borel <stef@via.ecp.fr>
8  *
9  * based on:
10  *  - css-auth by Derek Fawcus <derek@spider.com>
11  *  - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net>
12  *  - The Divide and conquer attack by Frank A. Stevenson<frank@funcom.com>
13  *  - DeCSSPlus by Ethan Hawke
14  *  - DecVOB
15  *  see http://www.lemuria.org/DeCSS/ by Tom Vogt for more information.
16  * 
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
30  *****************************************************************************/
31
32 /*****************************************************************************
33  * Preamble
34  *****************************************************************************/
35 #include "defs.h"
36
37 #if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD ) || defined( SYS_BEOS )
38
39 #include <stdio.h>
40 #include <unistd.h>
41 #include <string.h>
42 #include <fcntl.h>
43 #include <netinet/in.h>
44 #ifdef HAVE_SYS_IOCTL_H
45 # include <sys/ioctl.h>
46 #endif
47 #ifdef HAVE_SYS_DVDIO_H
48 # include <sys/dvdio.h>
49 #endif
50 #ifdef LINUX_DVD
51 # include <linux/cdrom.h>
52 #endif
53
54 #include "common.h"
55
56 #include "intf_msg.h"
57
58 #include "dvd_css.h"
59 #include "dvd_ioctl.h"
60 #include "dvd_ifo.h"
61
62 #include "input_dvd.h"
63
64 /*****************************************************************************
65  * CSS tables
66  *****************************************************************************/
67 static u8 pi_css_tab1[256]=
68 {   0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
69     0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b,
70     0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96,
71     0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b,
72     0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12,
73     0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f,
74     0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90,
75     0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91,
76     0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74,
77     0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75,
78     0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94,
79     0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95,
80     0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10,
81     0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11,
82     0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92,
83     0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f,
84     0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16,
85     0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b,
86     0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6,
87     0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb,
88     0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72,
89     0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f,
90     0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0,
91     0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1,
92     0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14,
93     0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15,
94     0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4,
95     0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5,
96     0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70,
97     0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71,
98     0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2,
99     0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
100 };
101
102 static u8 pi_css_tab2[256]=
103 {   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
104     0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e,
105     0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
106     0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c,
107     0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23,
108     0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a,
109     0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31,
110     0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
111     0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e,
112     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
113     0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c,
114     0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55,
115     0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a,
116     0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63,
117     0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
118     0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71,
119     0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
120     0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c,
121     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
122     0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e,
123     0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1,
124     0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
125     0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3,
126     0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa,
127     0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc,
128     0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5,
129     0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce,
130     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
131     0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
132     0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1,
133     0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea,
134     0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3
135 };
136
137 static u8 pi_css_tab3[512]=
138 {   0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
139     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
140     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
141     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
142     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
143     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
144     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
145     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
146     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
147     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
148     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
149     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
150     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
151     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
152     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
153     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
154     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
155     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
156     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
157     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
158     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
159     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
160     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
161     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
162     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
163     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
164     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
165     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
166     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
167     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
168     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
169     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
170     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
171     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
172     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
173     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
174     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
175     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
176     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
177     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
178     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
179     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
180     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
181     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
182     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
183     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
184     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
185     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
186     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
187     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
188     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
189     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
190     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
191     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
192     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
193     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
194     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
195     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
196     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
197     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
198     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
199     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
200     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff,
201     0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff
202 };
203
204 static u8 pi_css_tab4[256]=
205 {   0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
206     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
207     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
208     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
209     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
210     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
211     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
212     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
213     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
214     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
215     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
216     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
217     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
218     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
219     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
220     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
221     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
222     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
223     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
224     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
225     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
226     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
227     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
228     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
229     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
230     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
231     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
232     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
233     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
234     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
235     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
236     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
237 };
238
239 static u8 pi_css_tab5[256]=
240 {   0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f,
241     0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f,
242     0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17,
243     0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07,
244     0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b,
245     0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b,
246     0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13,
247     0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03,
248     0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d,
249     0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d,
250     0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15,
251     0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05,
252     0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19,
253     0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09,
254     0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11,
255     0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01,
256     0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e,
257     0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e,
258     0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16,
259     0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06,
260     0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a,
261     0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a,
262     0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12,
263     0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02,
264     0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c,
265     0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c,
266     0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14,
267     0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04,
268     0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18,
269     0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08,
270     0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10,
271     0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
272 };
273
274 static u8 pi_crypt_tab0[256] = {
275     0xB7, 0xF4, 0x82, 0x57, 0xDA, 0x4D, 0xDB, 0xE2,
276     0x2F, 0x52, 0x1A, 0xA8, 0x68, 0x5A, 0x8A, 0xFF,
277     0xFB, 0x0E, 0x6D, 0x35, 0xF7, 0x5C, 0x76, 0x12,
278     0xCE, 0x25, 0x79, 0x29, 0x39, 0x62, 0x08, 0x24,
279     0xA5, 0x85, 0x7B, 0x56, 0x01, 0x23, 0x68, 0xCF,
280     0x0A, 0xE2, 0x5A, 0xED, 0x3D, 0x59, 0xB0, 0xA9,
281     0xB0, 0x2C, 0xF2, 0xB8, 0xEF, 0x32, 0xA9, 0x40,
282     0x80, 0x71, 0xAF, 0x1E, 0xDE, 0x8F, 0x58, 0x88,
283     0xB8, 0x3A, 0xD0, 0xFC, 0xC4, 0x1E, 0xB5, 0xA0,
284     0xBB, 0x3B, 0x0F, 0x01, 0x7E, 0x1F, 0x9F, 0xD9,
285     0xAA, 0xB8, 0x3D, 0x9D, 0x74, 0x1E, 0x25, 0xDB,
286     0x37, 0x56, 0x8F, 0x16, 0xBA, 0x49, 0x2B, 0xAC,
287     0xD0, 0xBD, 0x95, 0x20, 0xBE, 0x7A, 0x28, 0xD0,
288     0x51, 0x64, 0x63, 0x1C, 0x7F, 0x66, 0x10, 0xBB,
289     0xC4, 0x56, 0x1A, 0x04, 0x6E, 0x0A, 0xEC, 0x9C,
290     0xD6, 0xE8, 0x9A, 0x7A, 0xCF, 0x8C, 0xDB, 0xB1,
291     0xEF, 0x71, 0xDE, 0x31, 0xFF, 0x54, 0x3E, 0x5E,
292     0x07, 0x69, 0x96, 0xB0, 0xCF, 0xDD, 0x9E, 0x47,
293     0xC7, 0x96, 0x8F, 0xE4, 0x2B, 0x59, 0xC6, 0xEE,
294     0xB9, 0x86, 0x9A, 0x64, 0x84, 0x72, 0xE2, 0x5B,
295     0xA2, 0x96, 0x58, 0x99, 0x50, 0x03, 0xF5, 0x38,
296     0x4D, 0x02, 0x7D, 0xE7, 0x7D, 0x75, 0xA7, 0xB8,
297     0x67, 0x87, 0x84, 0x3F, 0x1D, 0x11, 0xE5, 0xFC,
298     0x1E, 0xD3, 0x83, 0x16, 0xA5, 0x29, 0xF6, 0xC7,
299     0x15, 0x61, 0x29, 0x1A, 0x43, 0x4F, 0x9B, 0xAF,
300     0xC5, 0x87, 0x34, 0x6C, 0x0F, 0x3B, 0xA8, 0x1D,
301     0x45, 0x58, 0x25, 0xDC, 0xA8, 0xA3, 0x3B, 0xD1,
302     0x79, 0x1B, 0x48, 0xF2, 0xE9, 0x93, 0x1F, 0xFC,
303     0xDB, 0x2A, 0x90, 0xA9, 0x8A, 0x3D, 0x39, 0x18,
304     0xA3, 0x8E, 0x58, 0x6C, 0xE0, 0x12, 0xBB, 0x25,
305     0xCD, 0x71, 0x22, 0xA2, 0x64, 0xC6, 0xE7, 0xFB,
306     0xAD, 0x94, 0x77, 0x04, 0x9A, 0x39, 0xCF, 0x7C};
307
308 static u8 pi_crypt_tab1[256] = {
309     0x8C, 0x47, 0xB0, 0xE1, 0xEB, 0xFC, 0xEB, 0x56,
310     0x10, 0xE5, 0x2C, 0x1A, 0x5D, 0xEF, 0xBE, 0x4F,
311     0x08, 0x75, 0x97, 0x4B, 0x0E, 0x25, 0x8E, 0x6E,
312     0x39, 0x5A, 0x87, 0x53, 0xC4, 0x1F, 0xF4, 0x5C,
313     0x4E, 0xE6, 0x99, 0x30, 0xE0, 0x42, 0x88, 0xAB,
314     0xE5, 0x85, 0xBC, 0x8F, 0xD8, 0x3C, 0x54, 0xC9,
315     0x53, 0x47, 0x18, 0xD6, 0x06, 0x5B, 0x41, 0x2C,
316     0x67, 0x1E, 0x41, 0x74, 0x33, 0xE2, 0xB4, 0xE0,
317     0x23, 0x29, 0x42, 0xEA, 0x55, 0x0F, 0x25, 0xB4,
318     0x24, 0x2C, 0x99, 0x13, 0xEB, 0x0A, 0x0B, 0xC9,
319     0xF9, 0x63, 0x67, 0x43, 0x2D, 0xC7, 0x7D, 0x07,
320     0x60, 0x89, 0xD1, 0xCC, 0xE7, 0x94, 0x77, 0x74,
321     0x9B, 0x7E, 0xD7, 0xE6, 0xFF, 0xBB, 0x68, 0x14,
322     0x1E, 0xA3, 0x25, 0xDE, 0x3A, 0xA3, 0x54, 0x7B,
323     0x87, 0x9D, 0x50, 0xCA, 0x27, 0xC3, 0xA4, 0x50,
324     0x91, 0x27, 0xD4, 0xB0, 0x82, 0x41, 0x97, 0x79,
325     0x94, 0x82, 0xAC, 0xC7, 0x8E, 0xA5, 0x4E, 0xAA,
326     0x78, 0x9E, 0xE0, 0x42, 0xBA, 0x28, 0xEA, 0xB7,
327     0x74, 0xAD, 0x35, 0xDA, 0x92, 0x60, 0x7E, 0xD2,
328     0x0E, 0xB9, 0x24, 0x5E, 0x39, 0x4F, 0x5E, 0x63,
329     0x09, 0xB5, 0xFA, 0xBF, 0xF1, 0x22, 0x55, 0x1C,
330     0xE2, 0x25, 0xDB, 0xC5, 0xD8, 0x50, 0x03, 0x98,
331     0xC4, 0xAC, 0x2E, 0x11, 0xB4, 0x38, 0x4D, 0xD0,
332     0xB9, 0xFC, 0x2D, 0x3C, 0x08, 0x04, 0x5A, 0xEF,
333     0xCE, 0x32, 0xFB, 0x4C, 0x92, 0x1E, 0x4B, 0xFB,
334     0x1A, 0xD0, 0xE2, 0x3E, 0xDA, 0x6E, 0x7C, 0x4D,
335     0x56, 0xC3, 0x3F, 0x42, 0xB1, 0x3A, 0x23, 0x4D,
336     0x6E, 0x84, 0x56, 0x68, 0xF4, 0x0E, 0x03, 0x64,
337     0xD0, 0xA9, 0x92, 0x2F, 0x8B, 0xBC, 0x39, 0x9C,
338     0xAC, 0x09, 0x5E, 0xEE, 0xE5, 0x97, 0xBF, 0xA5,
339     0xCE, 0xFA, 0x28, 0x2C, 0x6D, 0x4F, 0xEF, 0x77,
340     0xAA, 0x1B, 0x79, 0x8E, 0x97, 0xB4, 0xC3, 0xF4};
341
342 static u8 pi_crypt_tab2[256] = {
343     0xB7, 0x75, 0x81, 0xD5, 0xDC, 0xCA, 0xDE, 0x66,
344     0x23, 0xDF, 0x15, 0x26, 0x62, 0xD1, 0x83, 0x77,
345     0xE3, 0x97, 0x76, 0xAF, 0xE9, 0xC3, 0x6B, 0x8E,
346     0xDA, 0xB0, 0x6E, 0xBF, 0x2B, 0xF1, 0x19, 0xB4,
347     0x95, 0x34, 0x48, 0xE4, 0x37, 0x94, 0x5D, 0x7B,
348     0x36, 0x5F, 0x65, 0x53, 0x07, 0xE2, 0x89, 0x11,
349     0x98, 0x85, 0xD9, 0x12, 0xC1, 0x9D, 0x84, 0xEC,
350     0xA4, 0xD4, 0x88, 0xB8, 0xFC, 0x2C, 0x79, 0x28,
351     0xD8, 0xDB, 0xB3, 0x1E, 0xA2, 0xF9, 0xD0, 0x44,
352     0xD7, 0xD6, 0x60, 0xEF, 0x14, 0xF4, 0xF6, 0x31,
353     0xD2, 0x41, 0x46, 0x67, 0x0A, 0xE1, 0x58, 0x27,
354     0x43, 0xA3, 0xF8, 0xE0, 0xC8, 0xBA, 0x5A, 0x5C,
355     0x80, 0x6C, 0xC6, 0xF2, 0xE8, 0xAD, 0x7D, 0x04,
356     0x0D, 0xB9, 0x3C, 0xC2, 0x25, 0xBD, 0x49, 0x63,
357     0x8C, 0x9F, 0x51, 0xCE, 0x20, 0xC5, 0xA1, 0x50,
358     0x92, 0x2D, 0xDD, 0xBC, 0x8D, 0x4F, 0x9A, 0x71,
359     0x2F, 0x30, 0x1D, 0x73, 0x39, 0x13, 0xFB, 0x1A,
360     0xCB, 0x24, 0x59, 0xFE, 0x05, 0x96, 0x57, 0x0F,
361     0x1F, 0xCF, 0x54, 0xBE, 0xF5, 0x06, 0x1B, 0xB2,
362     0x6D, 0xD3, 0x4D, 0x32, 0x56, 0x21, 0x33, 0x0B,
363     0x52, 0xE7, 0xAB, 0xEB, 0xA6, 0x74, 0x00, 0x4C,
364     0xB1, 0x7F, 0x82, 0x99, 0x87, 0x0E, 0x5E, 0xC0,
365     0x8F, 0xEE, 0x6F, 0x55, 0xF3, 0x7E, 0x08, 0x90,
366     0xFA, 0xB6, 0x64, 0x70, 0x47, 0x4A, 0x17, 0xA7,
367     0xB5, 0x40, 0x8A, 0x38, 0xE5, 0x68, 0x3E, 0x8B,
368     0x69, 0xAA, 0x9B, 0x42, 0xA5, 0x10, 0x01, 0x35,
369     0xFD, 0x61, 0x9E, 0xE6, 0x16, 0x9C, 0x86, 0xED,
370     0xCD, 0x2E, 0xFF, 0xC4, 0x5B, 0xA0, 0xAE, 0xCC,
371     0x4B, 0x3B, 0x03, 0xBB, 0x1C, 0x2A, 0xAC, 0x0C,
372     0x3F, 0x93, 0xC7, 0x72, 0x7A, 0x09, 0x22, 0x3D,
373     0x45, 0x78, 0xA9, 0xA8, 0xEA, 0xC9, 0x6A, 0xF7,
374     0x29, 0x91, 0xF0, 0x02, 0x18, 0x3A, 0x4E, 0x7C};
375
376 static u8 pi_crypt_tab3[288] = {
377     0x73, 0x51, 0x95, 0xE1, 0x12, 0xE4, 0xC0, 0x58,
378     0xEE, 0xF2, 0x08, 0x1B, 0xA9, 0xFA, 0x98, 0x4C,
379     0xA7, 0x33, 0xE2, 0x1B, 0xA7, 0x6D, 0xF5, 0x30,
380     0x97, 0x1D, 0xF3, 0x02, 0x60, 0x5A, 0x82, 0x0F,
381     0x91, 0xD0, 0x9C, 0x10, 0x39, 0x7A, 0x83, 0x85,
382     0x3B, 0xB2, 0xB8, 0xAE, 0x0C, 0x09, 0x52, 0xEA,
383     0x1C, 0xE1, 0x8D, 0x66, 0x4F, 0xF3, 0xDA, 0x92,
384     0x29, 0xB9, 0xD5, 0xC5, 0x77, 0x47, 0x22, 0x53,
385     0x14, 0xF7, 0xAF, 0x22, 0x64, 0xDF, 0xC6, 0x72,
386     0x12, 0xF3, 0x75, 0xDA, 0xD7, 0xD7, 0xE5, 0x02,
387     0x9E, 0xED, 0xDA, 0xDB, 0x4C, 0x47, 0xCE, 0x91,
388     0x06, 0x06, 0x6D, 0x55, 0x8B, 0x19, 0xC9, 0xEF,
389     0x8C, 0x80, 0x1A, 0x0E, 0xEE, 0x4B, 0xAB, 0xF2,
390     0x08, 0x5C, 0xE9, 0x37, 0x26, 0x5E, 0x9A, 0x90,
391     0x00, 0xF3, 0x0D, 0xB2, 0xA6, 0xA3, 0xF7, 0x26,
392     0x17, 0x48, 0x88, 0xC9, 0x0E, 0x2C, 0xC9, 0x02,
393     0xE7, 0x18, 0x05, 0x4B, 0xF3, 0x39, 0xE1, 0x20,
394     0x02, 0x0D, 0x40, 0xC7, 0xCA, 0xB9, 0x48, 0x30,
395     0x57, 0x67, 0xCC, 0x06, 0xBF, 0xAC, 0x81, 0x08,
396     0x24, 0x7A, 0xD4, 0x8B, 0x19, 0x8E, 0xAC, 0xB4,
397     0x5A, 0x0F, 0x73, 0x13, 0xAC, 0x9E, 0xDA, 0xB6,
398     0xB8, 0x96, 0x5B, 0x60, 0x88, 0xE1, 0x81, 0x3F,
399     0x07, 0x86, 0x37, 0x2D, 0x79, 0x14, 0x52, 0xEA,
400     0x73, 0xDF, 0x3D, 0x09, 0xC8, 0x25, 0x48, 0xD8,
401     0x75, 0x60, 0x9A, 0x08, 0x27, 0x4A, 0x2C, 0xB9,
402     0xA8, 0x8B, 0x8A, 0x73, 0x62, 0x37, 0x16, 0x02,
403     0xBD, 0xC1, 0x0E, 0x56, 0x54, 0x3E, 0x14, 0x5F,
404     0x8C, 0x8F, 0x6E, 0x75, 0x1C, 0x07, 0x39, 0x7B,
405     0x4B, 0xDB, 0xD3, 0x4B, 0x1E, 0xC8, 0x7E, 0xFE,
406     0x3E, 0x72, 0x16, 0x83, 0x7D, 0xEE, 0xF5, 0xCA,
407     0xC5, 0x18, 0xF9, 0xD8, 0x68, 0xAB, 0x38, 0x85,
408     0xA8, 0xF0, 0xA1, 0x73, 0x9F, 0x5D, 0x19, 0x0B,
409     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410     0x33, 0x72, 0x39, 0x25, 0x67, 0x26, 0x6D, 0x71,
411     0x36, 0x77, 0x3C, 0x20, 0x62, 0x23, 0x68, 0x74,
412     0xC3, 0x82, 0xC9, 0x15, 0x57, 0x16, 0x5D, 0x81};
413 /*
414  * Local functions
415  */
416
417 /*****************************************************************************
418  * CSSGetASF : Get Authentification success flag
419  * ---
420  * Returns :
421  *  -1 on ioctl error,
422  *  0 if the device needs to be authenticated,
423  *  1 either.
424  *****************************************************************************/
425 static int CSSGetASF( int i_fd )
426 {
427     dvd_authinfo    auth_info;
428
429     auth_info.type = DVD_LU_SEND_ASF;
430     auth_info.lsasf.asf = 0;
431
432     for( auth_info.lsasf.agid = 0 ; auth_info.lsasf.agid < 4 ;
433                                                     auth_info.lsasf.agid++ )
434     {
435         if( !( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) ) )
436         {
437             intf_WarnMsg( 3, "CSS: %sAuthenticated",
438                                     ( auth_info.lsasf.asf ) ? "" : "not " );
439             return auth_info.lsasf.asf;
440         }
441     }
442
443     /* The ioctl process has failed */
444     intf_ErrMsg( "CSS: GetASF Fatal Error" );
445     return -1;
446 }
447
448 /*****************************************************************************
449  * CSSCryptKey : shuffles bits and unencrypt keys.
450  * Used during authentication and disc key negociation in CSSInit.
451  * ---
452  * i_key_type : 0->key1, 1->key2, 2->buskey.
453  * i_varient : between 0 and 31.
454  *****************************************************************************/
455 static void CSSCryptKey( int i_key_type, int i_varient,
456                          u8 const * pi_challenge, u8* pi_key )
457 {
458     /* Permutation table for challenge */
459     u8      ppi_perm_challenge[3][10] =
460             { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
461               { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
462               { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
463
464     /* Permutation table for varient table for key2 and buskey */
465     u8      ppi_perm_varient[2][32] =
466             { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
467                 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
468                 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
469                 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 },
470               { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
471                 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
472                 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
473                 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } };
474
475     u8      pi_varients[32] =
476             {   0xB7, 0x74, 0x85, 0xD0, 0xCC, 0xDB, 0xCA, 0x73,
477                 0x03, 0xFE, 0x31, 0x03, 0x52, 0xE0, 0xB7, 0x42,
478                 0x63, 0x16, 0xF2, 0x2A, 0x79, 0x52, 0xFF, 0x1B,
479                 0x7A, 0x11, 0xCA, 0x1A, 0x9B, 0x40, 0xAD, 0x01 };
480
481     /* The "secret" key */
482     u8      pi_secret[5] = { 0x55, 0xD6, 0xC4, 0xC5, 0x28 };
483
484     u8      pi_bits[30];
485     u8      pi_scratch[10];
486     u8      pi_tmp1[5];
487     u8      pi_tmp2[5];
488     u8      i_lfsr0_o;  /* 1 bit used */
489     u8      i_lfsr1_o;  /* 1 bit used */
490     u32     i_lfsr0;
491     u32     i_lfsr1;
492     u8      i_css_varient;
493     u8      i_cse;
494     u8      i_index;
495     u8      i_combined;
496     u8      i_carry;
497     u8      i_val = 0;
498     int     i_term = 0;
499     int     i_bit;
500     int     i;
501
502     for (i = 9; i >= 0; --i)
503         pi_scratch[i] = pi_challenge[ppi_perm_challenge[i_key_type][i]];
504
505     i_css_varient = ( i_key_type == 0 ) ? i_varient :
506                     ppi_perm_varient[i_key_type-1][i_varient];
507
508     /*
509      * This encryption engine implements one of 32 variations
510      * one the same theme depending upon the choice in the
511      * varient parameter (0 - 31).
512      *
513      * The algorithm itself manipulates a 40 bit input into
514      * a 40 bit output.
515      * The parameter 'input' is 80 bits.  It consists of
516      * the 40 bit input value that is to be encrypted followed
517      * by a 40 bit seed value for the pseudo random number
518      * generators.
519      */
520
521     /* Feed the secret into the input values such that
522      * we alter the seed to the LFSR's used above,  then
523      * generate the bits to play with.
524      */
525     for( i = 5 ; --i >= 0 ; )
526     {
527         pi_tmp1[i] = pi_scratch[5 + i] ^ pi_secret[i] ^ pi_crypt_tab2[i];
528     }
529
530     /*
531      * We use two LFSR's (seeded from some of the input data bytes) to
532      * generate two streams of pseudo-random bits.  These two bit streams
533      * are then combined by simply adding with carry to generate a final
534      * sequence of pseudo-random bits which is stored in the buffer that
535      * 'output' points to the end of - len is the size of this buffer.
536      *
537      * The first LFSR is of degree 25,  and has a polynomial of:
538      * x^13 + x^5 + x^4 + x^1 + 1
539      *
540      * The second LSFR is of degree 17,  and has a (primitive) polynomial of:
541      * x^15 + x^1 + 1
542      *
543      * I don't know if these polynomials are primitive modulo 2,  and thus
544      * represent maximal-period LFSR's.
545      *
546      *
547      * Note that we take the output of each LFSR from the new shifted in
548      * bit,  not the old shifted out bit.  Thus for ease of use the LFSR's
549      * are implemented in bit reversed order.
550      *
551      */
552     
553     /* In order to ensure that the LFSR works we need to ensure that the
554      * initial values are non-zero.  Thus when we initialise them from
555      * the seed,  we ensure that a bit is set.
556      */
557     i_lfsr0 = ( pi_tmp1[0] << 17 ) | ( pi_tmp1[1] << 9 ) |
558               (( pi_tmp1[2] & ~7 ) << 1 ) | 8 | ( pi_tmp1[2] & 7 );
559     i_lfsr1 = ( pi_tmp1[3] << 9 ) | 0x100 | pi_tmp1[4];
560
561     i_index = sizeof(pi_bits);
562     i_carry = 0;
563
564     do
565     {
566         for( i_bit = 0, i_val = 0 ; i_bit < 8 ; ++i_bit )
567         {
568
569             i_lfsr0_o = ( ( i_lfsr0 >> 24 ) ^ ( i_lfsr0 >> 21 ) ^
570                         ( i_lfsr0 >> 20 ) ^ ( i_lfsr0 >> 12 ) ) & 1;
571             i_lfsr0 = ( i_lfsr0 << 1 ) | i_lfsr0_o;
572
573             i_lfsr1_o = ( ( i_lfsr1 >> 16 ) ^ ( i_lfsr1 >> 2 ) ) & 1;
574             i_lfsr1 = ( i_lfsr1 << 1 ) | i_lfsr1_o;
575
576 #define  BIT0(x) ((x) & 1)
577 #define  BIT1(x) (((x) >> 1) & 1)
578
579             i_combined = !i_lfsr1_o + i_carry + !i_lfsr0_o;
580             /* taking bit 1 */
581             i_carry = ( i_combined >> 1 ) & 1;
582             i_val |= ( i_combined & 1 ) << i_bit;
583         }
584     
585         pi_bits[--i_index] = i_val;
586     } while( i_index > 0 );
587
588     /* This term is used throughout the following to
589      * select one of 32 different variations on the
590      * algorithm.
591      */
592     i_cse = pi_varients[i_css_varient] ^ pi_crypt_tab2[i_css_varient];
593
594     /* Now the actual blocks doing the encryption.  Each
595      * of these works on 40 bits at a time and are quite
596      * similar.
597      */
598     i_index = 0;
599     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_scratch[i] )
600     {
601         i_index = pi_bits[25 + i] ^ pi_scratch[i];
602         i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
603
604         pi_tmp1[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
605     }
606     pi_tmp1[4] ^= pi_tmp1[0];
607
608     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
609     {
610         i_index = pi_bits[20 + i] ^ pi_tmp1[i];
611         i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
612
613         pi_tmp2[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
614     }
615     pi_tmp2[4] ^= pi_tmp2[0];
616
617     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
618     {
619         i_index = pi_bits[15 + i] ^ pi_tmp2[i];
620         i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
621         i_index = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
622
623         pi_tmp1[i] = pi_crypt_tab0[i_index] ^ pi_crypt_tab2[i_index];
624     }
625     pi_tmp1[4] ^= pi_tmp1[0];
626
627     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
628     {
629         i_index = pi_bits[10 + i] ^ pi_tmp1[i];
630         i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
631
632         i_index = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
633
634         pi_tmp2[i] = pi_crypt_tab0[i_index] ^ pi_crypt_tab2[i_index];
635     }
636     pi_tmp2[4] ^= pi_tmp2[0];
637
638     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
639     {
640         i_index = pi_bits[5 + i] ^ pi_tmp2[i];
641         i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
642
643         pi_tmp1[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
644     }
645     pi_tmp1[4] ^= pi_tmp1[0];
646
647     for(i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
648     {
649         i_index = pi_bits[i] ^ pi_tmp1[i];
650         i_index = pi_crypt_tab1[i_index] ^ ~pi_crypt_tab2[i_index] ^ i_cse;
651
652         pi_key[i] = pi_crypt_tab2[i_index] ^ pi_crypt_tab3[i_index] ^ i_term;
653     }
654
655     return;
656 }
657
658 /*****************************************************************************
659  * CSSCracker : title key decryption by cracking
660  * ---
661  * This function is called by CSSGetKeys to find a key
662  *****************************************************************************/
663 static int CSSCracker( int i_start,
664                        unsigned char * p_crypted,
665                        unsigned char * p_decrypted,
666                        dvd_key_t * p_sector_key,
667                        dvd_key_t * p_key )
668 {
669     unsigned char pi_buffer[10];
670     unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
671     unsigned int i_try;
672     unsigned int i_candidate;
673     unsigned int i, j;
674     int i_exit = -1;
675
676
677     for( i = 0 ; i < 10 ; i++ )
678     {
679         pi_buffer[i] = pi_css_tab1[p_crypted[i]] ^ p_decrypted[i];
680     }
681
682     for( i_try = i_start ; i_try < 0x10000 ; i_try++ )
683     {
684         i_t1 = i_try >> 8 | 0x100;
685         i_t2 = i_try & 0xff;
686         i_t3 = 0;               /* not needed */
687         i_t5 = 0;
688
689         /* iterate cipher 4 times to reconstruct LFSR2 */
690         for( i = 0 ; i < 4 ; i++ )
691         {
692             /* advance LFSR1 normaly */
693             i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
694             i_t2 = i_t1 >> 1;
695             i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
696             i_t4 = pi_css_tab5[i_t4];
697             /* deduce i_t6 & i_t5 */
698             i_t6 = pi_buffer[i];
699             if( i_t5 )
700             {
701                 i_t6 = ( i_t6 + 0xff ) & 0x0ff;
702             }
703             if( i_t6 < i_t4 )
704             {
705                 i_t6 += 0x100;
706             }
707             i_t6 -= i_t4;
708             i_t5 += i_t6 + i_t4;
709             i_t6 = pi_css_tab4[ i_t6 ];
710             /* feed / advance i_t3 / i_t5 */
711             i_t3 = ( i_t3 << 8 ) | i_t6;
712             i_t5 >>= 8;
713         }
714
715         i_candidate = i_t3;
716
717         /* iterate 6 more times to validate candidate key */
718         for( ; i < 10 ; i++ )
719         {
720             i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
721             i_t2 = i_t1 >> 1;
722             i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
723             i_t4 = pi_css_tab5[i_t4];
724             i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
725                                          i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
726             i_t3 = ( i_t3 << 8 ) | i_t6;
727             i_t6 = pi_css_tab4[i_t6];
728             i_t5 += i_t6 + i_t4;
729             if( ( i_t5 & 0xff ) != pi_buffer[i] )
730             {
731                 break;
732             }
733
734             i_t5 >>= 8;
735         }
736
737         if( i == 10 )
738         {
739             /* Do 4 backwards steps of iterating t3 to deduce initial state */
740             i_t3 = i_candidate;
741             for( i = 0 ; i < 4 ; i++ )
742             {
743                 i_t1 = i_t3 & 0xff;
744                 i_t3 = ( i_t3 >> 8 );
745                 /* easy to code, and fast enough bruteforce
746                  * search for byte shifted in */
747                 for( j = 0 ; j < 256 ; j++ )
748                 {
749                     i_t3 = ( i_t3 & 0x1ffff) | ( j << 17 );
750                     i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
751                                    i_t3 ) >> 8 ) ^ i_t3 ) >> 5 ) & 0xff;
752                     if( i_t6 == i_t1 )
753                     {
754                         break;
755                     }
756                 }
757             }
758
759             i_t4 = ( i_t3 >> 1 ) - 4;
760             for( i_t5 = 0 ; i_t5 < 8; i_t5++ )
761             {
762                 if( ( ( i_t4 + i_t5 ) * 2 + 8 - ( (i_t4 + i_t5 ) & 7 ) )
763                                                                       == i_t3 )
764                 {
765                     (*p_key)[0] = i_try>>8;
766                     (*p_key)[1] = i_try & 0xFF;
767                     (*p_key)[2] = ( ( i_t4 + i_t5 ) >> 0) & 0xFF;
768                     (*p_key)[3] = ( ( i_t4 + i_t5 ) >> 8) & 0xFF;
769                     (*p_key)[4] = ( ( i_t4 + i_t5 ) >> 16) & 0xFF;
770                     i_exit = i_try + 1;
771                 }
772             }
773         }
774     }
775
776     if( i_exit >= 0 )
777     {
778         (*p_key)[0] ^= (*p_sector_key)[0];
779         (*p_key)[1] ^= (*p_sector_key)[1];
780         (*p_key)[2] ^= (*p_sector_key)[2];
781         (*p_key)[3] ^= (*p_sector_key)[3];
782         (*p_key)[4] ^= (*p_sector_key)[4];
783     }
784
785     return i_exit;
786 }
787
788 /*
789  * Authentication and keys
790  */
791
792 /*****************************************************************************
793  * CSSTest : check if the disc is encrypted or not
794  *****************************************************************************/
795 int CSSTest( int i_fd )
796 {
797     dvd_struct dvd;
798
799     dvd.type = DVD_STRUCT_COPYRIGHT;
800     dvd.copyright.layer_num = 0;
801
802     if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
803     {
804         intf_ErrMsg( "DVD ioctl error" );
805         return -1;
806     }
807
808     return dvd.copyright.cpst;
809 }
810
811 /*****************************************************************************
812  * CSSInit : CSS Structure initialisation and DVD authentication.
813  * It simulates the mutual authentication between logical unit and host.
814  * ---
815  * Since we don't need the disc key to find the title key, we just run the
816  * basic unavoidable commands to authenticate device and disc.
817  *****************************************************************************/
818
819 css_t CSSInit( int i_fd )
820 {
821     /* structures defined in cdrom.h or dvdio.h */
822     dvd_authinfo    auth_info;
823     dvd_struct      dvd;
824
825     css_t           css;
826     int             i_error = -1;
827     int             i;
828
829     css.i_fd = i_fd;
830     css.b_error = 0;
831
832     memset( &auth_info, 0, sizeof(auth_info) );
833
834     /* Test authentication success */
835     switch( CSSGetASF( i_fd ) )
836     {
837     case -1:
838         css.b_error = 1;
839     case 1:
840         return css;
841     case 0:
842         intf_WarnMsg( 3, "CSS: Authenticating" );
843     }
844
845     /* Init sequence, request AGID */
846     for( i = 1; i < 4 ; ++i )
847     {
848         intf_WarnMsg( 3, "CSS: Request AGID %d", i );
849         auth_info.type = DVD_LU_SEND_AGID;
850         auth_info.lsa.agid = 0;
851         i_error =  dvd_ioctl( i_fd, DVD_AUTH, &auth_info );
852         if( i_error != -1 )
853         {
854             /* No error during ioctl: we know if device
855              * is authenticated */
856             break;
857         }
858
859         intf_ErrMsg( "CSS: AGID N/A, invalidating" );
860         auth_info.type = DVD_INVALIDATE_AGID;
861         auth_info.lsa.agid = 0;
862         dvd_ioctl( i_fd, DVD_AUTH, &auth_info );
863     }
864
865     /* Unable to authenticate without AGID */
866     if( i_error == -1 )
867     {
868         css.b_error = 1;
869         intf_ErrMsg( "CSS: Cannot get AGID" );
870         return css;
871     }
872
873     for( i = 0 ; i < 10; ++i )
874     {
875         css.disc.pi_challenge[i] = i;
876     }
877
878     /* Send AGID to host */
879     auth_info.type = DVD_HOST_SEND_CHALLENGE;
880
881     /* Get challenge from host */
882     for( i = 0 ; i < 10 ; ++i )
883     {
884         auth_info.hsc.chal[9-i] = css.disc.pi_challenge[i];
885     }
886     /* Returning data, let LU change state */
887     css.i_agid = auth_info.lsa.agid;
888
889     /* Send challenge to LU */
890     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info )<0 )
891     {
892         intf_ErrMsg( "CSS: Send challenge to LU failed ");
893         css.b_error = 1;
894         return css;
895     }
896
897     /* Get key1 from LU */
898     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0)
899     {
900         intf_ErrMsg( "CSS: Get key1 from LU failed ");
901         css.b_error = 1;
902         return css;
903     }
904
905     /* Send key1 to host */
906     for( i = 0 ; i < KEY_SIZE ; i++ )
907     {
908         css.disc.pi_key1[i] = auth_info.lsk.key[4-i];
909     }
910
911     for( i = 0 ; i < 32 ; ++i )
912     {
913         CSSCryptKey( 0, i, css.disc.pi_challenge,
914                            css.disc.pi_key_check );
915
916         if( memcmp( css.disc.pi_key_check,
917                     css.disc.pi_key1, KEY_SIZE ) == 0 )
918         {
919             intf_WarnMsg( 3, "CSS: Drive Authentic - using varient %d", i);
920             css.disc.i_varient = i;
921             auth_info.type = DVD_LU_SEND_CHALLENGE;
922             break;
923         }
924     }
925
926     if( i == 32 )
927     {
928         intf_ErrMsg( "Drive would not Authenticate" );
929         auth_info.type = DVD_AUTH_FAILURE;
930         css.b_error = 1;
931         return css;
932     }
933
934     /* Get challenge from LU */
935     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
936     {
937         intf_ErrMsg( "CSS: Get challenge from LU failed ");
938         css.b_error = 1;
939         return css;
940     }
941
942     /* Send challenge to host */
943     for( i = 0 ; i < 10 ; ++i )
944     {
945         css.disc.pi_challenge[i] = auth_info.hsc.chal[9-i];
946     }
947
948     CSSCryptKey( 1, css.disc.i_varient, css.disc.pi_challenge,
949                                                     css.disc.pi_key2 );
950     auth_info.type = DVD_HOST_SEND_KEY2;
951
952     /* Get key2 from host */
953     for( i = 0 ; i < KEY_SIZE ; ++i )
954     {
955         auth_info.hsk.key[4-i] = css.disc.pi_key2[i];
956     }
957     /* Returning data, let LU change state */
958
959     /* Send key2 to LU */
960     if( dvd_ioctl( i_fd, DVD_AUTH, &auth_info ) < 0 )
961     {
962         intf_ErrMsg( "CSS: Send key2 to LU failed (expected)" );
963         return css;
964     }
965
966     if( auth_info.type == DVD_AUTH_ESTABLISHED )
967     {
968         intf_WarnMsg( 3, "CSS: Authentication established");
969     }
970     else if( auth_info.type == DVD_AUTH_FAILURE )
971     {
972         css.b_error = 1;
973         intf_ErrMsg("CSS: DVD authentication failed");
974     }
975
976     memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE );
977     memcpy( css.disc.pi_challenge+KEY_SIZE, css.disc.pi_key2, KEY_SIZE );
978     CSSCryptKey( 2, css.disc.i_varient,
979                     css.disc.pi_challenge,
980                     css.disc.pi_key_check );
981
982     intf_WarnMsg( 1, "CSS: Received Session Key" );
983
984     if( css.i_agid < 0 )
985     {
986         css.b_error = 1;
987         return css;
988     }
989
990     /* Test authentication success */
991     switch( CSSGetASF( i_fd ) )
992     {
993     case -1:
994         css.b_error = 1;
995     case 1:
996         return css;
997     case 0:
998         intf_WarnMsg( 3, "CSS: Getting disc key" );
999     }
1000
1001     /* Get encrypted disc key */
1002     dvd.type = DVD_STRUCT_DISCKEY;
1003     dvd.disckey.agid = css.i_agid;
1004     memset( dvd.disckey.value, 0, 2048 );
1005
1006     if( dvd_ioctl( i_fd, DVD_READ_STRUCT, &dvd ) < 0 )
1007     {
1008         intf_ErrMsg( "CSS: Could not read Disc Key" );
1009         css.b_error = 1;
1010         return css;
1011     }
1012 #if 1
1013     /* Unencrypt disc key using bus key */
1014     for( i = 0 ; i < sizeof(dvd.disckey.value) ; i++ )
1015     {
1016         dvd.disckey.value[i] ^= css.disc.pi_key_check[4 - (i % KEY_SIZE)];
1017     }
1018     memcpy( css.disc.pi_key_check, dvd.disckey.value, 2048 );
1019 #endif
1020     /* Test authentication success */
1021     switch( CSSGetASF( i_fd ) )
1022     {
1023     case -1:
1024     case 0:
1025         css.b_error = 1;
1026     case 1:
1027         return css;
1028     }
1029
1030     return css;
1031 }
1032
1033 /*****************************************************************************
1034  * CSSGetKey : get title key.
1035  * The DVD should have been opened and authenticated before.
1036  *****************************************************************************/
1037 int CSSGetKey( css_t * p_css )
1038 {
1039     /*
1040      * Title key cracking method from Ethan Hawke,
1041      * with Frank A. Stevenson algorithm.
1042      * Does not use any player key table and ioctls.
1043      */
1044     u8          pi_buf[0x800];
1045     dvd_key_t   pi_key;
1046     title_key_t p_title_key[10];
1047     off_t       i_pos;
1048     boolean_t   b_encrypted;
1049     boolean_t   b_stop_scanning;
1050     int         i_title;
1051     int         i_bytes_read;
1052     int         i_best_plen;
1053     int         i_best_p;
1054     int         i_registered_keys;
1055     int         i_total_keys_found;
1056     int         i_highest;
1057     int         i,j,k;
1058
1059     memset( p_title_key, 0, 10 );
1060     memset( &pi_key, 0, 10 );
1061     b_encrypted = 0;
1062     b_stop_scanning = 0;
1063     i_registered_keys = 0 ;
1064     i_total_keys_found = 0 ;
1065     i_highest = 0;
1066
1067     /* Position of the title on the disc */
1068     i_title = p_css->i_title;
1069     i_pos = p_css->i_title_pos;
1070
1071 //fprintf( stderr, "CSS %d start pos: %lld\n", i_title, i_pos );
1072
1073     do {
1074     i_pos = lseek( p_css->i_fd, i_pos, SEEK_SET );
1075     i_bytes_read = read( p_css->i_fd, pi_buf, 0x800 );
1076
1077     /* PES_scrambling_control */
1078     if( pi_buf[0x14] & 0x30 )
1079     {
1080         b_encrypted = 1;
1081         i_best_plen = 0;
1082         i_best_p = 0;
1083
1084         for( i = 2 ; i < 0x30 ; i++ )
1085         {
1086             for( j = i ; ( j < 0x80 ) &&
1087                    ( pi_buf[0x7F - (j%i)] == pi_buf[0x7F-j] ) ; j++ );
1088             {
1089                 if( ( j > i_best_plen ) && ( j > i ) )
1090                 {
1091                     i_best_plen = j;
1092                     i_best_p = i;
1093                 }
1094             }
1095         }
1096
1097         if( ( i_best_plen > 20 ) && ( i_best_plen / i_best_p >= 2) )
1098         {
1099             i = CSSCracker( 0,  &pi_buf[0x80],
1100                     &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
1101                     (dvd_key_t*)&pi_buf[0x54],
1102                     &pi_key );
1103             while( i>=0 )
1104             {
1105                 k = 0;
1106                 for( j=0 ; j<i_registered_keys ; j++ )
1107                 {
1108                     if( memcmp( &(p_title_key[j].pi_key),
1109                                 &pi_key, sizeof(dvd_key_t) ) == 0 )
1110                     {
1111                         p_title_key[j].i_occ++;
1112                         i_total_keys_found++;
1113                         k = 1;
1114                     }
1115                 }
1116
1117                 if( k == 0 )
1118                 {
1119                     memcpy( &(p_title_key[i_registered_keys].pi_key),
1120                                             &pi_key, sizeof(dvd_key_t) );
1121                     p_title_key[i_registered_keys++].i_occ = 1;
1122                     i_total_keys_found++;
1123                 }
1124                 i = CSSCracker( i, &pi_buf[0x80],
1125                     &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
1126                     (dvd_key_t*)&pi_buf[0x54], &pi_key);
1127             }
1128
1129             /* Stop search if we find one occurance of the key 
1130              * I have never found a DVD for which it is not enough
1131              * but we should take care of that */
1132             if( i_registered_keys == 1 && p_title_key[0].i_occ >= 1 )
1133             {
1134                 b_stop_scanning = 1;
1135             }
1136         }
1137     }
1138
1139     i_pos += i_bytes_read;
1140     } while( i_bytes_read == 0x800 && !b_stop_scanning);
1141
1142     if( b_stop_scanning)
1143     {
1144         intf_WarnMsg( 1,
1145             "CSS: Found enough occurancies of the same key." );
1146     }
1147
1148     if( !b_encrypted )
1149     {
1150         intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
1151         return(0);
1152     }
1153
1154     if( b_encrypted && i_registered_keys == 0 )
1155     {
1156         intf_ErrMsg( "CSS: Unable to determine keys from file.");
1157         return(1);
1158     }
1159
1160     for( i = 0 ; i < i_registered_keys - 1 ; i++ )
1161     {
1162         for( j = i + 1 ; j < i_registered_keys ; j++ )
1163         {
1164             if( p_title_key[j].i_occ > p_title_key[i].i_occ )
1165             {
1166                 memcpy( &pi_key, &(p_title_key[j].pi_key), sizeof(dvd_key_t) );
1167                 k = p_title_key[j].i_occ;
1168
1169                 memcpy( &(p_title_key[j].pi_key),
1170                         &(p_title_key[i].pi_key), sizeof(dvd_key_t) );
1171                 p_title_key[j].i_occ = p_title_key[i].i_occ;
1172
1173                 memcpy( &(p_title_key[i].pi_key),&pi_key, sizeof(dvd_key_t) );
1174                 p_title_key[i].i_occ = k;
1175             }
1176         }
1177     }
1178
1179 #ifdef STATS
1180     intf_WarnMsg( 1, " Key(s) & key probability\n---------------------");
1181 #endif
1182     for( i=0 ; i<i_registered_keys ; i++ )
1183     {
1184 #ifdef STATS
1185         intf_WarnMsg( 1, "%d) %02X %02X %02X %02X %02X - %3.2f%%", i,
1186                     p_title_key[i].key[0], p_title_key[i].key[1],
1187                     p_title_key[i].key[2], p_title_key[i].key[3],
1188                     p_title_key[i].key[4],
1189                     p_title_key[i].i_occ * 100.0 / i_total_keys_found );
1190 #endif
1191         if( p_title_key[i_highest].i_occ * 100.0 / i_total_keys_found
1192                            <= p_title_key[i].i_occ*100.0 / i_total_keys_found )
1193         {
1194             i_highest = i;
1195         }
1196     }
1197
1198
1199     /* The "find the key with the highest probability" code
1200      * is untested, as I haven't been able to find a VOB that
1201      * produces multiple keys (RT)
1202      */
1203     intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
1204                 i_title + 1,
1205                 p_title_key[i_highest].pi_key[0],
1206                 p_title_key[i_highest].pi_key[1],
1207                 p_title_key[i_highest].pi_key[2],
1208                 p_title_key[i_highest].pi_key[3],
1209                 p_title_key[i_highest].pi_key[4] );
1210
1211     memcpy( p_css->pi_title_key,
1212             p_title_key[i_highest].pi_key, KEY_SIZE );
1213
1214     return 0;
1215 }
1216
1217 /*****************************************************************************
1218  * CSSDescrambleSector
1219  * ---
1220  * sec : sector to descramble
1221  * key : title key for this sector
1222  *****************************************************************************/
1223 int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec )
1224 {
1225     unsigned int    i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
1226     u8*             pi_end = pi_sec + 0x800;
1227
1228     /* PES_scrambling_control */
1229     if( pi_sec[0x14] & 0x30)
1230     {
1231         i_t1 = ((pi_key)[0] ^ pi_sec[0x54]) | 0x100;
1232         i_t2 = (pi_key)[1] ^ pi_sec[0x55];
1233         i_t3 = (((pi_key)[2]) | ((pi_key)[3] << 8) |
1234                ((pi_key)[4] << 16)) ^ ((pi_sec[0x56]) |
1235                (pi_sec[0x57] << 8) | (pi_sec[0x58] << 16));
1236         i_t4 = i_t3 & 7;
1237         i_t3 = i_t3 * 2 + 8 - i_t4;
1238         pi_sec += 0x80;
1239         i_t5 = 0;
1240
1241         while( pi_sec != pi_end )
1242         {
1243             i_t4 = pi_css_tab2[i_t2] ^ pi_css_tab3[i_t1];
1244             i_t2 = i_t1>>1;
1245             i_t1 = ( ( i_t1 & 1 ) << 8 ) ^ i_t4;
1246             i_t4 = pi_css_tab5[i_t4];
1247             i_t6 = ((((((( i_t3 >> 3 ) ^ i_t3 ) >> 1 ) ^
1248                                          i_t3 ) >> 8 ) ^ i_t3 ) >> 5) & 0xff;
1249             i_t3 = (i_t3 << 8 ) | i_t6;
1250             i_t6 = pi_css_tab4[i_t6];
1251             i_t5 += i_t6 + i_t4;
1252             *pi_sec++ = pi_css_tab1[*pi_sec] ^( i_t5 & 0xff );
1253             i_t5 >>= 8;
1254         }
1255     }
1256
1257     return(0);
1258 }
1259 #endif