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