]> git.sesse.net Git - vlc/blob - src/input/dvd_css.c
* Beginning of support for encrypted DVDs.
[vlc] / src / input / dvd_css.c
1 /*****************************************************************************
2  * dvd_css.c: Functions for DVD authentification and unscrambling
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  *
6  * Author: Stéphane Borel <stef@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <malloc.h>
31 #include <netinet/in.h>
32 #include <sys/ioctl.h>
33 //#if defined(__NetBSD__) || defined(__OpenBSD__)
34 //# include <sys/dvdio.h>
35 //#elif defined(__linux__)
36 #include <linux/cdrom.h>
37 //#else
38 //# error "Need the DVD ioctls"
39 //#endif
40
41
42 #include "common.h"
43
44 #include "intf_msg.h"
45 #include "dvd_css.h"
46 #include "css_table.h"
47
48 /*****************************************************************************
49  * CSS tables
50  *****************************************************************************/
51
52 unsigned int pi_css_tab0[11]={5,0,1,2,3,4,0,1,2,3,4};
53
54 unsigned char pi_css_tab1[256]=
55 {   0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76,
56     0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b,
57     0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96,
58     0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b,
59     0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12,
60     0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f,
61     0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90,
62     0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91,
63     0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74,
64     0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75,
65         0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94,
66     0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95,
67     0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10,
68     0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11,
69     0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92,
70     0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f,
71     0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16,
72     0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b,
73     0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6,
74     0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb,
75     0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72,
76     0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f,
77     0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0,
78     0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1,
79     0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14,
80     0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15,
81     0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4,
82     0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5,
83     0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70,
84     0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71,
85     0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2,
86     0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff };
87
88 unsigned char pi_css_tab2[256]=
89 {   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
90     0x09, 0x08, 0x0b, 0x0a, 0x0d, 0x0c, 0x0f, 0x0e,
91     0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
92     0x1b, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x1d, 0x1c,
93     0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23,
94     0x2d, 0x2c, 0x2f, 0x2e, 0x29, 0x28, 0x2b, 0x2a,
95     0x36, 0x37, 0x34, 0x35, 0x32, 0x33, 0x30, 0x31,
96     0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
97     0x49, 0x48, 0x4b, 0x4a, 0x4d, 0x4c, 0x4f, 0x4e,
98     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
99     0x5b, 0x5a, 0x59, 0x58, 0x5f, 0x5e, 0x5d, 0x5c,
100     0x52, 0x53, 0x50, 0x51, 0x56, 0x57, 0x54, 0x55,
101     0x6d, 0x6c, 0x6f, 0x6e, 0x69, 0x68, 0x6b, 0x6a,
102     0x64, 0x65, 0x66, 0x67, 0x60, 0x61, 0x62, 0x63,
103     0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
104     0x76, 0x77, 0x74, 0x75, 0x72, 0x73, 0x70, 0x71,
105     0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
106     0x9b, 0x9a, 0x99, 0x98, 0x9f, 0x9e, 0x9d, 0x9c,
107     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
108     0x89, 0x88, 0x8b, 0x8a, 0x8d, 0x8c, 0x8f, 0x8e,
109     0xb6, 0xb7, 0xb4, 0xb5, 0xb2, 0xb3, 0xb0, 0xb1,
110     0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
111     0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3,
112     0xad, 0xac, 0xaf, 0xae, 0xa9, 0xa8, 0xab, 0xaa,
113     0xdb, 0xda, 0xd9, 0xd8, 0xdf, 0xde, 0xdd, 0xdc,
114     0xd2, 0xd3, 0xd0, 0xd1, 0xd6, 0xd7, 0xd4, 0xd5,
115     0xc9, 0xc8, 0xcb, 0xca, 0xcd, 0xcc, 0xcf, 0xce,
116     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
117     0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
118     0xf6, 0xf7, 0xf4, 0xf5, 0xf2, 0xf3, 0xf0, 0xf1,
119     0xed, 0xec, 0xef, 0xee, 0xe9, 0xe8, 0xeb, 0xea,
120     0xe4, 0xe5, 0xe6, 0xe7, 0xe0, 0xe1, 0xe2, 0xe3
121 };
122
123 unsigned char pi_css_tab3[512]=
124 {
125         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
126         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
127         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
128         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
129         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
130         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
131         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
132         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
133         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
134         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
135         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
136         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
137         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
138         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
139         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
140         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
141         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
142         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
143         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
144         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
145         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
146         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
147         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
148         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
149         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
150         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
151         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
152         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
153         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
154         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
155         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 
156         0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff, 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff
157 };
158
159 unsigned char pi_css_tab4[256]=
160 {
161         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
162         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
163         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
164         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
165         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
166         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
167         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
168         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
169         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
170         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
171         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
172         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
173         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
174         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
175         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
176         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
177 };
178
179 unsigned char pi_css_tab5[256]=
180 {
181         0xff, 0x7f, 0xbf, 0x3f, 0xdf, 0x5f, 0x9f, 0x1f, 0xef, 0x6f, 0xaf, 0x2f, 0xcf, 0x4f, 0x8f, 0x0f, 
182         0xf7, 0x77, 0xb7, 0x37, 0xd7, 0x57, 0x97, 0x17, 0xe7, 0x67, 0xa7, 0x27, 0xc7, 0x47, 0x87, 0x07, 
183         0xfb, 0x7b, 0xbb, 0x3b, 0xdb, 0x5b, 0x9b, 0x1b, 0xeb, 0x6b, 0xab, 0x2b, 0xcb, 0x4b, 0x8b, 0x0b, 
184         0xf3, 0x73, 0xb3, 0x33, 0xd3, 0x53, 0x93, 0x13, 0xe3, 0x63, 0xa3, 0x23, 0xc3, 0x43, 0x83, 0x03, 
185         0xfd, 0x7d, 0xbd, 0x3d, 0xdd, 0x5d, 0x9d, 0x1d, 0xed, 0x6d, 0xad, 0x2d, 0xcd, 0x4d, 0x8d, 0x0d, 
186         0xf5, 0x75, 0xb5, 0x35, 0xd5, 0x55, 0x95, 0x15, 0xe5, 0x65, 0xa5, 0x25, 0xc5, 0x45, 0x85, 0x05, 
187         0xf9, 0x79, 0xb9, 0x39, 0xd9, 0x59, 0x99, 0x19, 0xe9, 0x69, 0xa9, 0x29, 0xc9, 0x49, 0x89, 0x09, 
188         0xf1, 0x71, 0xb1, 0x31, 0xd1, 0x51, 0x91, 0x11, 0xe1, 0x61, 0xa1, 0x21, 0xc1, 0x41, 0x81, 0x01, 
189         0xfe, 0x7e, 0xbe, 0x3e, 0xde, 0x5e, 0x9e, 0x1e, 0xee, 0x6e, 0xae, 0x2e, 0xce, 0x4e, 0x8e, 0x0e, 
190         0xf6, 0x76, 0xb6, 0x36, 0xd6, 0x56, 0x96, 0x16, 0xe6, 0x66, 0xa6, 0x26, 0xc6, 0x46, 0x86, 0x06, 
191         0xfa, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0x9a, 0x1a, 0xea, 0x6a, 0xaa, 0x2a, 0xca, 0x4a, 0x8a, 0x0a, 
192         0xf2, 0x72, 0xb2, 0x32, 0xd2, 0x52, 0x92, 0x12, 0xe2, 0x62, 0xa2, 0x22, 0xc2, 0x42, 0x82, 0x02, 
193         0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0x9c, 0x1c, 0xec, 0x6c, 0xac, 0x2c, 0xcc, 0x4c, 0x8c, 0x0c, 
194         0xf4, 0x74, 0xb4, 0x34, 0xd4, 0x54, 0x94, 0x14, 0xe4, 0x64, 0xa4, 0x24, 0xc4, 0x44, 0x84, 0x04, 
195         0xf8, 0x78, 0xb8, 0x38, 0xd8, 0x58, 0x98, 0x18, 0xe8, 0x68, 0xa8, 0x28, 0xc8, 0x48, 0x88, 0x08, 
196         0xf0, 0x70, 0xb0, 0x30, 0xd0, 0x50, 0x90, 0x10, 0xe0, 0x60, 0xa0, 0x20, 0xc0, 0x40, 0x80, 0x00
197 };
198
199
200 /*
201  * Local functions
202  */
203
204 /*****************************************************************************
205  * CSSGetASF : Get Authentification success flag
206  *****************************************************************************/
207 int CSSGetASF( int i_fd )
208 {
209 #if 0
210         dvd_authinfo    auth;
211
212         auth.type = DVD_LU_SEND_ASF;
213         auth.lsasf.asf = 0;
214
215         for( auth.lsasf.agid = 0 ; auth.lsasf.agid < 4 ; auth.lsasf.agid++ )
216     {
217                 if( ioctl( i_fd, DVD_AUTH, &auth ) )
218         {
219             intf_ErrMsg( "DVD ioctl error in CSSGetASF" );
220                         return -1;
221                 }
222         }
223
224 // ("%sAuthenticated\n", (ai.lsasf.asf) ? "" : "not");
225         return 0;
226 #else
227
228         dvd_authinfo ai;
229
230         ai.type = DVD_LU_SEND_ASF;
231         ai.lsasf.asf = 0;
232
233         for (ai.lsasf.agid = 0; ai.lsasf.agid < 4; ai.lsasf.agid++) {
234                 if (!(ioctl(i_fd, DVD_AUTH, &ai))) {
235                         fprintf( stderr, "%sAuthenticated\n", (ai.lsasf.asf) ? "" : "not");
236                         return 0;
237                 }
238         }
239         intf_ErrMsg( "CSS Error : GetASF" );
240         return -1;
241
242 #endif
243 }
244
245 /*****************************************************************************
246  * CSSCryptKey : shuffles bits and unencrypt keys.
247  * ---
248  * i_key_type : 0->key1, 1->key2, 2->buskey.
249  * i_varient : between 0 and 31.
250  *****************************************************************************/
251 #if 0
252 static void CSSCryptKey( int i_key_type, int i_varient,
253                          u8* pi_challenge, u8* pi_key )
254 {
255     /* Permutation table for challenge */
256     u8      ppi_perm_challenge[3][10] = 
257             { { 1, 3, 0, 7, 5, 2, 9, 6, 4, 8 },
258               { 6, 1, 9, 3, 8, 5, 7, 4, 0, 2 },
259               { 4, 0, 3, 5, 7, 2, 8, 6, 1, 9 } };
260     /* Permutation table for varient table */
261     u8      ppi_perm_varient[2][32] =
262             { { 0x0a, 0x08, 0x0e, 0x0c, 0x0b, 0x09, 0x0f, 0x0d,
263                 0x1a, 0x18, 0x1e, 0x1c, 0x1b, 0x19, 0x1f, 0x1d,
264                 0x02, 0x00, 0x06, 0x04, 0x03, 0x01, 0x07, 0x05,
265                 0x12, 0x10, 0x16, 0x14, 0x13, 0x11, 0x17, 0x15 },
266               { 0x12, 0x1a, 0x16, 0x1e, 0x02, 0x0a, 0x06, 0x0e,
267                 0x10, 0x18, 0x14, 0x1c, 0x00, 0x08, 0x04, 0x0c,
268                 0x13, 0x1b, 0x17, 0x1f, 0x03, 0x0b, 0x07, 0x0f,
269                 0x11, 0x19, 0x15, 0x1d, 0x01, 0x09, 0x05, 0x0d } };
270     u8      pi_css_secret[5] = { 0xE2,0xA3,0x45,0x10,0xF4 };
271     u8      pi_css_varients[32] =
272               { 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15,
273                 0x20, 0x21, 0x24, 0x25, 0x30, 0x31, 0x34, 0x35,
274                 0x80, 0x81, 0x84, 0x85, 0x90, 0x91, 0x94, 0x95,
275                 0xA0, 0xA1, 0xA4, 0xA5, 0xB0, 0xB1, 0xB4, 0xB5 };
276     u8      pi_bits[30];
277     u8      pi_scratch[10];
278     u8      pi_tmp1[5], pi_tmp2[2];
279     u8      i_lfsr0_o, i_lfsr1_o;
280     u32     i_lfsr0, i_lfsr1;
281     u8     i_css_varient;
282     int     i_val = 0;
283     int     i_term = 0;
284     int     i, i_index;
285
286     for( i=0 ; i<10 ; i++ )
287     {
288         pi_scratch[i] = pi_challenge[ppi_perm_challenge[i_key_type][i]];
289     }
290     i_css_varient = i_key_type == 0 ? i_varient
291                     : ppi_perm_varient[i_key_type-1][i_varient];
292     i_css_varient = pi_css_varients[i_css_varient];
293
294     for( i=0 ; i<5 ; i++ )
295     {
296         pi_tmp1[i] = pi_scratch[5+i] ^ pi_css_secret[i];
297     }
298
299     /* In order to ensure that the LFSR works we need to ensure that the
300          * initial values are non-zero.  Thus when we initialise them from
301          * the seed,  we ensure that a bit is set.
302          */
303         i_lfsr0 = ( pi_key[0] << 17 ) | ( pi_key[1] << 9 ) |
304               ( ( pi_key[2] & ~7 ) << 1 ) | 8 | (pi_key[2] & 7);
305
306         /*
307          * reverse lfsr0/1 to simplify calculation in loop
308          */
309         i_lfsr0 = ( pi_reverse[i_lfsr0 & 0xff] << 17 ) |
310               ( pi_reverse[( i_lfsr0 >> 8 ) & 0xff] << 9 ) |
311               ( pi_reverse[( i_lfsr0 >> 16 ) & 0xff] << 1) |
312               ( i_lfsr0 >> 24 );
313
314         i_lfsr1 = ( pi_reverse[pi_key[4]] << 9 ) | 0x100 |
315               ( pi_reverse[pi_key[3]] );
316
317         for( i=0 ; i<30 ; i++ )
318     {
319                 i_lfsr0_o = ( i_lfsr0 >> 12) ^ ( i_lfsr0 >> 4) ^
320                     ( i_lfsr0 >> 3) ^ i_lfsr0;
321
322                 i_lfsr1_o = ( ( i_lfsr1 >> 14 ) & 7) ^ i_lfsr1;
323                 i_lfsr1_o ^= ( i_lfsr1_o << 3 ) ^ ( i_lfsr1_o << 6 );
324
325                 i_lfsr1 = ( i_lfsr1 >> 8) ^ ( i_lfsr1_o << 9);
326                 i_lfsr0 = ( i_lfsr0 >> 8 ) ^ ( i_lfsr0_o << 17);
327
328                 i_lfsr0_o = ~i_lfsr0_o;
329                 i_lfsr1_o = ~i_lfsr1_o;
330
331                 i_val += i_lfsr0_o + i_lfsr1_o;
332         
333                 pi_bits[i] = i_val & 0xFF;
334                 i_val >>= 8;
335         }
336
337     /* 
338      * Mangling
339      */
340     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_scratch[i] )
341     {
342                 i_index = pi_bits[25+i] ^ pi_scratch[i];
343                 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
344                 pi_tmp1[i] = pi_css_mangle2[i_index] ^ i_term;
345     }
346     pi_tmp1[4] ^= pi_tmp1[0];
347     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
348     {
349                 i_index = pi_bits[20+i] ^ pi_tmp1[i];
350                 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
351                 pi_tmp2[i] = pi_css_mangle2[i_index] ^ i_term;
352     }
353     pi_tmp2[4] ^= pi_tmp2[0];
354     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
355     {
356                 i_index = pi_bits[15+i] ^ pi_tmp2[i];
357                 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
358                 i_index = pi_css_mangle2[i_index] ^ i_term;
359         pi_tmp1[i] = pi_css_mangle0[i_index];
360     }
361     pi_tmp1[4] ^= pi_tmp1[0];
362     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
363     {
364                 i_index = pi_bits[10+i] ^ pi_tmp1[i];
365                 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
366                 i_index = pi_css_mangle2[i_index] ^ i_term;
367         pi_tmp2[i] = pi_css_mangle0[i_index];
368     }
369     pi_tmp2[4] ^= pi_tmp2[0];
370     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp2[i] )
371     {
372                 i_index = pi_bits[5+i] ^ pi_tmp2[i];
373                 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
374                 pi_tmp1[i] = pi_css_mangle2[i_index] ^ i_term;
375     }
376     pi_tmp1[4] ^= pi_tmp1[0];
377     for( i = 5, i_term = 0 ; --i >= 0 ; i_term = pi_tmp1[i] )
378     {
379                 i_index = pi_bits[i] ^ pi_tmp1[i];
380                 i_index = pi_css_mangle1[i_index] ^ i_css_varient;
381                 pi_key[i] = pi_css_mangle2[i_index] ^ i_term;
382     }
383
384     return;
385 }
386 #else
387 typedef struct {
388         uint8_t Challenge[10];
389         uint8_t Key1[KEY_SIZE];
390         uint8_t Key2[KEY_SIZE];
391         uint8_t KeyCheck[KEY_SIZE];
392         uint8_t varient;
393 } DiscKeys;
394
395 DiscKeys discKeys;
396
397
398
399 static void _generate_bits (u8 *output, int len,  const u8 *s)
400 {
401         u32 lfsr0, lfsr1;
402         int val;
403         u8 o_lfsr0, o_lfsr1;
404
405         /* In order to ensure that the LFSR works we need to ensure that the
406          * initial values are non-zero.  Thus when we initialise them from
407          * the seed,  we ensure that a bit is set.
408          */
409
410         lfsr0 = (s[0] << 17) | (s[1] << 9) | ((s[2] & ~7) << 1) | 8 | (s[2] & 7);
411
412         /*
413                 reverse lfsr0/1 to simplify calculation in loop
414         */
415         lfsr0 = (pi_reverse[lfsr0&0xff]<<17) | (pi_reverse[(lfsr0>>8)&0xff] << 9)
416                   | (pi_reverse[(lfsr0>>16)&0xff]<<1) |(lfsr0>>24);
417
418         lfsr1 = (pi_reverse[s[4]] << 9) | 0x100 | ( pi_reverse[ s[3]] );
419
420         output++;
421         val = 0;
422
423         do {
424                 o_lfsr0 = (lfsr0 >> 12) ^ (lfsr0 >> 4) ^  (lfsr0 >> 3) ^ lfsr0;
425
426                 o_lfsr1 = ((lfsr1 >> 14) & 7) ^ lfsr1;
427                 o_lfsr1 ^= (o_lfsr1 << 3) ^ (o_lfsr1 << 6);
428
429                 lfsr1 = (lfsr1 >> 8) ^ (o_lfsr1 << 9);
430                 lfsr0 = (lfsr0 >> 8) ^ (o_lfsr0 << 17);
431
432                 o_lfsr0 = ~o_lfsr0;
433                 o_lfsr1 = ~o_lfsr1;
434
435                 val += o_lfsr0 + o_lfsr1;
436         
437                 *--output = val & 0xFF;
438                 val >>= 8;
439                 fprintf(stderr, "lfsr0=%08x lfsr1=%08x\n", lfsr0, lfsr1);
440
441         } while (--len > 0);
442 }
443
444
445 /**
446  * This encryption engine implements one of 32 variations
447  * one the same theme depending upon the choice in the
448  * varient parameter (0 - 31).
449  *
450  * The algorithm itself manipulates a 40 bit input into
451  * a 40 bit output.
452  * The parameter 'input' is 80 bits.  It consists of
453  * the 40 bit input value that is to be encrypted followed
454  * by a 40 bit seed value for the pseudo random number
455  * generators.
456  **/
457
458 static inline void mangle1( u8 *bs, u8 cse, const u8 *ip, u8 *op)
459 {
460         int i, term, index;
461         for (i = 5, term = 0; --i >= 0; term = ip[i]) {
462                 index = bs[i] ^ ip[i];
463                 index = pi_css_mangle1[index] ^ cse;
464                 op[i] = pi_css_mangle2[index] ^ term;
465         }       
466 }
467
468
469 /**
470  *
471  **/
472
473 static inline void mangle2( u8 *bs, u8 cse, const u8 *ip, u8 *op)
474 {
475         int i, term, index;
476         for (i = 5, term = 0; --i >= 0; term = ip[i]) {
477                 index = bs[i] ^ ip[i];
478                 index = pi_css_mangle1[index] ^ cse;
479                 index = pi_css_mangle2[index] ^ term;
480                 op[i] = pi_css_mangle0[index];
481         }       
482 }
483
484
485 /**
486  *
487  **/
488
489 static inline void engine (int varient, u8 const *input, u8 *output)
490 {
491         u8 cse;
492         u8 tmp1[5];
493         u8 tmp2[5];
494         u8 bits[30];
495     u8      pi_css_varients[32] =
496               { 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15,
497                 0x20, 0x21, 0x24, 0x25, 0x30, 0x31, 0x34, 0x35,
498                 0x80, 0x81, 0x84, 0x85, 0x90, 0x91, 0x94, 0x95,
499                 0xA0, 0xA1, 0xA4, 0xA5, 0xB0, 0xB1, 0xB4, 0xB5 };
500     u8      pi_css_secret[5] = { 0xE2,0xA3,0x45,0x10,0xF4 };
501
502
503         int i;
504
505         /* Feed the secret into the input values such that
506          * we alter the seed to the LFSR's used above,  then
507          * generate the bits to play with.
508          */
509         for (i=5; --i>=0; )
510                 tmp1[i] = input[5+i] ^ pi_css_secret[i];
511
512         _generate_bits (&bits[29], sizeof bits, &tmp1[0]);
513
514         /* This term is used throughout the following to
515          * select one of 32 different variations on the
516          * algorithm.
517          */
518         cse = pi_css_varients[varient];
519
520         /* Now the actual blocks doing the encryption.  Each
521          * of these works on 40 bits at a time and are quite
522          * similar.
523          */
524         mangle1( &bits[25], cse, input, tmp1);
525         tmp1[4] ^= tmp1[0];
526
527         mangle1( &bits[20],  cse, tmp1, tmp2);
528         tmp2[4] ^= tmp2[0];
529
530         mangle2( &bits[15],  cse, tmp2, tmp1);
531         tmp1[4] ^= tmp1[0];
532
533         mangle2( &bits[10],  cse, tmp1, tmp2);
534         tmp2[4] ^= tmp2[0];
535
536         mangle1( &bits[5],  cse, tmp2, tmp1);
537         tmp1[4] ^= tmp1[0];
538         mangle1( &bits[0],  cse, tmp1, output);
539 }
540
541
542 /**
543  *
544  **/
545
546 void CryptKey1 (int varient, u8 const *challenge, u8 *key)
547 {
548         u8 perm_challenge[] = {1,3,0,7,5, 2,9,6,4,8};
549
550         u8 scratch[10];
551         int i;
552
553         for (i=9; i>=0; --i)
554                 scratch[i] = challenge[perm_challenge[i]];
555
556         engine (varient, scratch, key);
557 }
558
559
560 /**
561  * This shuffles the bits in varient to make perm_varient such that
562  *                4 -> !3
563  *                3 ->  4
564  * varient bits:  2 ->  0  perm_varient bits
565  *                1 ->  2
566  *                0 -> !1
567  **/
568
569 void CryptKey2 (int varient, u8 const *challenge, u8 *key)
570 {
571         static u8 perm_challenge[] = {
572                 0x06,0x01,0x09,0x03,0x08,0x05,0x07,0x04,
573                 0x00,0x02
574         };
575         static u8 perm_varient[] = {
576                 0x0a,0x08,0x0e,0x0c,0x0b,0x09,0x0f,0x0d,
577                 0x1a,0x18,0x1e,0x1c,0x1b,0x19,0x1f,0x1d,
578                 0x02,0x00,0x06,0x04,0x03,0x01,0x07,0x05,
579                 0x12,0x10,0x16,0x14,0x13,0x11,0x17,0x15
580         };
581         u8 scratch[10];
582         int i;
583
584         for (i=9; i>=0; --i)
585                 scratch[i] = challenge[perm_challenge[i]];
586
587         engine (perm_varient[varient], scratch, key);
588 }
589
590
591 /**
592  * This shuffles the bits in varient to make perm_varient such that
593  *                4 ->  0
594  *                3 -> !1
595  * varient bits:  2 -> !4  perm_varient bits
596  *                1 ->  2
597  *                0 ->  3
598  **/
599
600 void CryptBusKey (int varient, u8 const *challenge, u8 *key)
601 {
602         static u8 perm_challenge[] = {
603                 0x04,0x00,0x03,0x05,0x07,0x02,0x08,0x06,
604                 0x01,0x09
605         };
606         static u8 perm_varient[] = {
607                 0x12,0x1a,0x16,0x1e,0x02,0x0a,0x06,0x0e,
608                 0x10,0x18,0x14,0x1c,0x00,0x08,0x04,0x0c,
609                 0x13,0x1b,0x17,0x1f,0x03,0x0b,0x07,0x0f,
610                 0x11,0x19,0x15,0x1d,0x01,0x09,0x05,0x0d
611         };
612         u8 scratch[10];
613         int i;
614
615         for (i=9; i>=0; --i)
616                 scratch[i] = challenge[perm_challenge[i]];
617
618         engine (perm_varient[varient], scratch, key);
619 }
620
621 static int _CSSAuthDrive (const u8 *key, DiscKeys *disc)
622 {
623         int i;
624
625         for (i=0; i<KEY_SIZE; i++)
626                 disc->Key1[i] = key[4-i];
627
628         for (i=0; i<32; ++i) {
629                 CryptKey1( i, disc->Challenge, disc->KeyCheck);
630
631                 if (memcmp (disc->KeyCheck, disc->Key1, KEY_SIZE ) == 0) {
632                         intf_ErrMsg( "Drive Authentic - using varient %d", i);
633                         disc->varient = i;
634                         return i;
635                 }
636         }
637
638         intf_ErrMsg( "Drive would not Authenticate" );
639
640         return -1;
641 }
642
643
644 static int _CSSAuthHost (dvd_authinfo *ai, DiscKeys *disc)
645 {
646         int i;
647
648         switch (ai->type) {
649         /* Host data receive (host changes state) */
650         case DVD_LU_SEND_AGID:
651 //              _CSSPrintDebug ("AGID %d\n", ai->lsa.agid);
652
653                 ai->type = DVD_HOST_SEND_CHALLENGE;
654                 break;
655
656         case DVD_LU_SEND_KEY1:
657 //              _CSSPrintDebugBytes ("LU sent key1", ai->lsk.key, LEN_KEY);
658
659                 if (_CSSAuthDrive (ai->lsk.key, disc)<0) {
660                         ai->type = DVD_AUTH_FAILURE;
661                         return -22;
662                 }
663                 ai->type = DVD_LU_SEND_CHALLENGE;
664                 break;
665
666         case DVD_LU_SEND_CHALLENGE:
667                 for (i = 0; i < 10; ++i)
668                         disc->Challenge[i] = ai->hsc.chal[9-i];
669
670 //              _CSSPrintDebugBytes ("LU sent challenge", ai->hsc.chal, 10);
671
672                 CryptKey2 (disc->varient, disc->Challenge, disc->Key2);
673                 ai->type = DVD_HOST_SEND_KEY2;
674                 break;
675
676         /* Host data send */
677         case DVD_HOST_SEND_CHALLENGE:
678                 for (i = 0; i < 10; ++i)
679                         ai->hsc.chal[9-i] = disc->Challenge[i];
680
681 //              _CSSPrintDebugBytes ("Host sending challenge", ai->hsc.chal, 10);
682
683                 /* Returning data, let LU change state */
684                 break;
685
686         case DVD_HOST_SEND_KEY2:
687                 for (i = 0; i < KEY_SIZE; ++i)
688                         ai->hsk.key[4-i] = disc->Key2[i];
689
690 //              _CSSPrintDebugBytes ("Host sending key 2", &disc->Key2[0], LEN_KEY);
691
692                 /* Returning data, let LU change state */
693                 break;
694
695         default:
696                 intf_ErrMsg( "Got invalid state %d", ai->type );
697
698                 return -22;
699         }
700
701         return 0;
702 }
703
704
705
706 #endif
707
708 /*****************************************************************************
709  * CSSCracker : title key decryption by cracking
710  *****************************************************************************/
711
712 // FIXME : adapt to vlc
713 #define KEYSTREAMBYTES 10
714
715 static unsigned char invtab4[256];
716
717 static int CSScracker(int StartVal,unsigned char* pCrypted,unsigned char* pDecrypted,DVD40bitKey *StreamKey,DVD40bitKey *pkey)
718 {
719     unsigned char MyBuf[10];
720     unsigned int t1,t2,t3,t4,t5,t6;
721     unsigned int nTry;
722     unsigned int vCandidate;
723     int i;
724     unsigned int j;
725     int i_exit = -1;
726
727
728     for (i=0;i<10;i++)
729     {
730         MyBuf[i] = pi_css_tab1[pCrypted[i]] ^ pDecrypted[i]; 
731     }
732
733     /* Test that CSStab4 is a permutation */
734     memset( invtab4, 0, 256 );
735     for( i = 0 ; i < 256 ; i++ )
736     {
737         invtab4[ pi_css_tab4[i] ] = 1; 
738     }
739
740     for (i = 0 ; i < 256 ; i++)
741     {
742         if (invtab4[ i ] != 1)
743         {
744             printf( "Permutation error\n" );
745             exit( -1 );
746         }
747         }
748
749     /* initialize the inverse of table4 */
750     for( i = 0 ; i < 256 ; i++ )
751     {
752         invtab4[ pi_css_tab4[i] ] = i;
753     }
754
755     for( nTry = StartVal ; nTry < 65536 ; nTry++ )
756     {
757         t1 = nTry >> 8 | 0x100;
758         t2 = nTry & 0xff;
759         t3 = 0;   /* not needed */
760         t5 = 0;
761
762         /* iterate cipher 4 times to reconstruct LFSR2 */
763         for( i = 0 ; i < 4 ; i++ )
764         {
765             /* advance LFSR1 normaly */
766             t4=pi_css_tab2[t2]^pi_css_tab3[t1];
767             t2=t1>>1;
768             t1=((t1&1)<<8)^t4;
769             t4=pi_css_tab5[t4];
770             /* deduce t6 & t5 */
771             t6 = MyBuf[ i ];    
772             if( t5 )
773             {
774                 t6 = ( t6 + 0xff )&0x0ff;
775             }
776             if( t6 < t4 )
777             {
778                 t6 += 0x100;
779             }
780             t6 -= t4;
781             t5 += t6 + t4;
782             t6 = invtab4[ t6 ];
783             /* printf( "%02x/%02x ", t4, t6 ); */
784             /* feed / advance t3 / t5 */
785             t3 = (t3 << 8) | t6;
786             t5 >>= 8;
787         }
788
789         vCandidate = t3;
790
791         /* iterate 6 more times to validate candidate key */
792         for( ; i < KEYSTREAMBYTES ; i++ )
793         {
794             t4=pi_css_tab2[t2]^pi_css_tab3[t1];
795             t2=t1>>1;
796             t1=((t1&1)<<8)^t4;
797             t4=pi_css_tab5[t4];
798             t6=(((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)&0xff;
799             t3=(t3<<8)|t6;
800             t6=pi_css_tab4[t6];
801             t5+=t6+t4;
802             if( (t5 & 0xff) != MyBuf[i] ) break;
803             t5>>=8;
804         }
805
806         if( i == KEYSTREAMBYTES )
807         {
808             /* Do 4 backwards steps of iterating t3 to deduce initial state */
809             t3 = vCandidate;
810             for( i = 0 ; i < 4 ; i++ )
811             {
812                 t1 = t3 & 0xff;
813                 t3 = ( t3 >> 8 );
814                 /* easy to code, and fast enough bruteforce
815                  * search for byte shifted in */
816                 for( j=0 ; j < 256 ; j++ )
817                 {
818                     t3 = (t3 & 0x1ffff) | ( j << 17 );
819                     t6=(((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)&0xff;
820                     if( t6 == t1 ) break;  
821                 }
822             }
823 //          printf( "Candidate: t1=%03x t2=%02x t3=%08x\n", 0x100|(nTry>>8),nTry&0x0ff, t3 );
824
825             t4 = (t3>>1) - 4;
826             for(t5=0;t5<8;t5++)
827             {
828                 if ( ((t4+t5)*2 + 8 - ((t4+t5)&7))==t3 )
829                 {
830                     (*pkey)[0] = nTry>>8;
831                     (*pkey)[1] = nTry & 0xFF;
832                     (*pkey)[2] = ((t4+t5) >> 0) & 0xFF;
833                     (*pkey)[3] = ((t4+t5) >> 8) & 0xFF;
834                     (*pkey)[4] = ((t4+t5) >> 16) & 0xFF;
835                     i_exit = nTry+1;
836                 }
837             }
838         }
839     }
840
841     if (i_exit>=0)
842     {
843         (*pkey)[0] ^= (*StreamKey)[0];
844         (*pkey)[1] ^= (*StreamKey)[1];
845         (*pkey)[2] ^= (*StreamKey)[2];
846         (*pkey)[3] ^= (*StreamKey)[3];
847         (*pkey)[4] ^= (*StreamKey)[4];
848     }
849
850     return i_exit;
851 }
852
853 /*
854  * Authentication and keys
855  */
856
857 /*****************************************************************************
858  * CSSInit : CSS Structure initialisation and DVD authentication.
859  *****************************************************************************/
860
861 css_t CSSInit( int i_fd )
862 {
863 #if 0
864     css_t           css;
865     dvd_authinfo    auth;
866     int             i;
867
868     css.i_fd = i_fd;
869     css.b_error = 0;
870     memset( &auth, 0, sizeof(auth) );
871 fprintf( stderr, "0\n" );
872 #if 0
873         if( CSSGetASF( i_fd ) )
874     {
875         css.b_error = 1;
876                 return css;
877     }
878 #endif
879 fprintf( stderr, "1\n" );
880     /* Get AGID From drive */
881     auth.type = DVD_LU_SEND_AGID;
882     auth.lsa.agid = 0;
883
884     if( ioctl( i_fd, DVD_AUTH, &auth ) < 0 )
885     {
886         intf_ErrMsg( "DVD ioctl error in CSSInit (AGID)" );
887         auth.type = DVD_INVALIDATE_AGID;
888         auth.lsa.agid = 0;
889         ioctl( i_fd, DVD_AUTH, &auth );
890         css.b_error = 1;
891         return css;
892     }
893     css.i_agid = auth.lsa.agid;
894
895 fprintf( stderr, "2\n" );
896     /* Get drive keys */
897     for( i = 0 ; i < 10 ; ++i )
898     {
899                 css.keys.pi_challenge[i] = i;
900     }
901 fprintf( stderr, "3\n" );
902
903     if( ioctl( i_fd, DVD_AUTH, &auth ) < 0 )
904     {
905         intf_ErrMsg( "DVD ioctl error in CSSInit (Drive keys)" );
906         css.b_error = 1;
907         return css;
908     }
909 fprintf( stderr, "4\n" );
910
911     if( ioctl( i_fd, DVD_AUTH, &auth ) < 0 )
912     {
913         intf_ErrMsg( "DVD ioctl error in CSSInit (Drive keys)" );
914         css.b_error = 1;
915         return css;
916     }
917 fprintf( stderr, "5\n" );
918
919     for( i=0 ; i<KEY_SIZE ; i++ )
920     {
921         css.keys.pi_key1[i] = auth.lsk.key[KEY_SIZE -1 -i];
922     }
923 fprintf( stderr, "6\n" );
924
925     i=0;
926     do {
927         CSSCryptKey( 0, i, css.keys.pi_challenge, css.keys.pi_key_check );
928         i++;
929
930         intf_Msg( "Drive Authentic - using varient %d", i-1 );
931             
932     } while( (i<32) &&
933       ( memcmp( css.keys.pi_key_check, css.keys.pi_key1, KEY_SIZE ) != 0 ) );
934 fprintf( stderr, "1\n" );
935
936     css.keys.i_version = i-1;
937
938     auth.type = DVD_LU_SEND_CHALLENGE;
939     if( ioctl( i_fd, DVD_AUTH, &auth ) < 0 )
940     {
941                 intf_ErrMsg( "DVD ioctl error in CSSInit (drive Keys)" );
942         css.b_error = 1;
943                 return css;
944     }
945 fprintf( stderr, "7\n" );
946
947     for( i = 0; i < 2*KEY_SIZE; ++i )
948     {
949         css.keys.pi_challenge[i] = auth.hsc.chal[2*KEY_SIZE -1 -i];
950     }
951     CSSCryptKey( 1, css.keys.i_version,
952                     css.keys.pi_challenge, css.keys.pi_key2 );
953     
954     auth.type = DVD_HOST_SEND_KEY2;
955     for( i = 0 ; i < KEY_SIZE ; ++i )
956     {
957         auth.hsk.key[4-i] = css.keys.pi_key2[i];
958     }
959 fprintf( stderr, "8\n" );
960
961     if( ioctl( i_fd, DVD_AUTH, &auth ) < 0)
962     {
963         intf_ErrMsg( "Send key2 to LU failed (expected)" );
964         css.b_error = 1;
965         return css;
966     }
967 fprintf( stderr, "9\n" );
968
969         memcpy( css.keys.pi_challenge, css.keys.pi_key1, KEY_SIZE );
970         memcpy( css.keys.pi_challenge+KEY_SIZE, css.keys.pi_key2, KEY_SIZE );
971 fprintf( stderr, "10\n" );
972         CSSCryptKey( 2, css.keys.i_version,
973                     css.keys.pi_challenge, css.keys.pi_key_check );
974
975     intf_WarnMsg( 3, "DVD agid : %d", css.i_agid );
976 fprintf( stderr, "11\n" );
977 #else
978
979         DiscKeys *disc = &discKeys;
980
981         dvd_authinfo ai;
982         int i, agid;
983         dvd_struct s;
984     int fd=i_fd;
985         int tries;
986         int rv=-1;
987     css_t   css;
988
989
990
991         memset (&ai, 0, sizeof (ai));
992
993         if (CSSGetASF (fd))
994                 return css;
995
996
997         /* Init sequence, request AGID */
998         for (tries = 1; (tries < 4)&&(rv== -1) ; ++tries) {
999                 intf_ErrMsg( "Request AGID [%d]...", tries );
1000                 ai.type = DVD_LU_SEND_AGID;
1001                 ai.lsa.agid = 0;
1002                 rv =  ioctl (fd, DVD_AUTH, &ai);
1003                 if (rv == -1) {
1004                 intf_ErrMsg( "N/A, invalidating" );
1005                 ai.type = DVD_INVALIDATE_AGID;
1006                     ai.lsa.agid = 0;
1007                 ioctl (fd, DVD_AUTH, &ai);
1008         }
1009         }
1010     if (rv != -1) {
1011         intf_ErrMsg("Cannot get AGID\n");
1012     }
1013
1014         for (i = 0; i < 10; ++i)
1015                 disc->Challenge[i] = i;
1016
1017         /* Send AGID to host */
1018         if (_CSSAuthHost(&ai, disc) < 0) {
1019                 intf_ErrMsg("CSS Error :Send AGID to host failed\n");
1020                 return css;
1021         }
1022         /* Get challenge from host */
1023         if (_CSSAuthHost(&ai, disc) < 0) {
1024                 intf_ErrMsg("CSS Error :Get challenge from host failed\n");
1025                 return css;
1026         }
1027         agid = ai.lsa.agid;
1028         /* Send challenge to LU */
1029         if (ioctl(fd, DVD_AUTH, &ai) < 0) {
1030                 intf_ErrMsg("CSS Error :Send challenge to LU failed\n");
1031                 return css;
1032         }
1033         /* Get key1 from LU */
1034         if (ioctl(fd, DVD_AUTH, &ai) < 0) {
1035                 intf_ErrMsg("CSS Error :Get key1 from LU failed\n");
1036                 return css;
1037         }
1038         /* Send key1 to host */
1039         if (_CSSAuthHost(&ai, disc) < 0) {
1040                 intf_ErrMsg("CSS Error :Send key1 to host failed\n");
1041                 return css;
1042         }
1043         /* Get challenge from LU */
1044         if (ioctl(fd, DVD_AUTH, &ai) < 0) {
1045                 intf_ErrMsg("CSS Error :Get challenge from LU failed\n");
1046                 return css;
1047         }
1048         /* Send challenge to host */
1049         if (_CSSAuthHost (&ai, disc) < 0) {
1050                 intf_ErrMsg("CSS Error :Send challenge to host failed\n");
1051                 return css;
1052         }
1053         /* Get key2 from host */
1054         if (_CSSAuthHost (&ai, disc) < 0) {
1055                 intf_ErrMsg("CSS Error :Get key2 from host failed\n");
1056                 return css;
1057         }
1058         /* Send key2 to LU */
1059         if (ioctl(fd, DVD_AUTH, &ai) < 0) {
1060                 intf_ErrMsg("CSS Error :Send key2 to LU failed (expected)\n");
1061                 return css;
1062         }
1063
1064         if (ai.type == DVD_AUTH_ESTABLISHED)
1065                 intf_ErrMsg("CSS Error :DVD is authenticated\n");
1066         else if (ai.type == DVD_AUTH_FAILURE)
1067                 intf_ErrMsg("CSS Error :DVD authentication failed\n");
1068
1069         memcpy (disc->Challenge, disc->Key1, KEY_SIZE);
1070         memcpy (disc->Challenge+KEY_SIZE, disc->Key2, KEY_SIZE);
1071         CryptBusKey (disc->varient, disc->Challenge, disc->KeyCheck);
1072
1073         intf_Msg( "Received Session Key\n" );
1074     for( i=0 ; i<KEY_SIZE ; i++ )
1075     {
1076         intf_Msg( "%02x", &disc->KeyCheck[i] );
1077     }
1078     intf_Msg( "\n" );
1079
1080         if (agid < 0)
1081                 return css;
1082
1083         if (CSSGetASF (fd) < 0)
1084                 return css;
1085
1086         s.type = DVD_STRUCT_DISCKEY;
1087         s.disckey.agid = agid;
1088         memset (s.disckey.value, 0, 2048);
1089
1090         if (ioctl(fd, DVD_READ_STRUCT, &s)<0) {
1091                 intf_ErrMsg( "Error : Could not read Disc Key" );
1092         css.b_error = 1;
1093                 return css;
1094         }
1095
1096         for (i=0; i<sizeof s.disckey.value; i++)
1097                 s.disckey.value[i] ^= disc->KeyCheck[4 - (i % KEY_SIZE)];
1098
1099 //      _CSSPrintDebugBytes ("Received Disc Key", s.disckey.value, 10);
1100
1101         memcpy (disc->KeyCheck, s.disckey.value, 2048);
1102
1103
1104         if (CSSGetASF (fd) < 0)
1105     {
1106         css.b_error = 1;
1107                 return css;
1108     }
1109
1110
1111
1112 #endif
1113
1114     return css;
1115 }
1116
1117 /*****************************************************************************
1118  * CSSGetKeys : get the disc key of the media en the dvd device, and then
1119  * the title keys.
1120  * The DVD should have been opened before.
1121  *****************************************************************************/
1122
1123 #define MaxKeys 1000
1124
1125 struct
1126 {
1127   int verbosity ; /* 0-9 */
1128         int repetitions ;
1129         int scanall ;
1130         char *infile ;
1131 } params ;
1132
1133 typedef struct
1134 {
1135         int                             occ;
1136         DVD40bitKey             key;
1137 } KeyOcc;
1138
1139
1140 int CSSGetKeys( css_t * p_css )
1141 {
1142 #if 0
1143
1144     /* 
1145      * css_auth/libcss method from Derek Fawcus.
1146      * Get encrypted keys with ioctls and decrypt them
1147      * with cracked player keys
1148      */
1149     dvd_struct      dvd;
1150     dvd_authinfo    auth;
1151     int             i, j;
1152     if( CSSGetASF( p_css->i_fd ) < 0 )
1153     {
1154         return 1;
1155     }
1156
1157     /* Disk key */
1158     dvd.type = DVD_STRUCT_DISCKEY;
1159     dvd.disckey.agid = p_css->i_agid;
1160     memset( dvd.disckey.value, 0, 2048 );
1161     
1162     if( ioctl( p_css->i_fd, DVD_READ_STRUCT, &dvd )<0 )
1163     {
1164         intf_ErrMsg( "DVD ioctl error in CSSGetKeys" );
1165         p_css->b_error = 1;
1166         return 1;
1167     }
1168
1169     for( i=0 ; i<sizeof(dvd.disckey.value) ; i++ )
1170     {
1171         dvd.disckey.value[i] ^=
1172                     p_css->keys.pi_key_check[4 - (i % KEY_SIZE )];
1173     }
1174
1175     memcpy( p_css->pi_disc_key, dvd.disckey.value, 2048 );
1176
1177     if( CSSGetASF( p_css->i_fd ) < 0 )
1178     {
1179         return 1;
1180     }
1181
1182     /* Title keys */
1183     auth.type = DVD_LU_SEND_TITLE_KEY;
1184     auth.lstk.agid = p_css->i_agid;
1185
1186     for( j=0 ; j<p_css->i_title_nb ; j++ )
1187     {
1188         auth.lstk.lba = p_css->p_title_key[j].i_lba;
1189
1190         if( ioctl( p_css->i_fd, DVD_AUTH, &auth )<0 )
1191         {
1192             intf_ErrMsg( "DVD ioctl error in CSSGetKeys" );
1193             p_css->b_error = 1;
1194             return 1;
1195         }
1196     
1197         for( i=0 ; i<KEY_SIZE ; ++i )
1198         {
1199             auth.lstk.title_key[i] ^=
1200                     p_css->keys.pi_key_check[4 - (i % KEY_SIZE)];
1201             memcpy( p_css->p_title_key[j].key, auth.lstk.title_key, KEY_SIZE );
1202         }
1203     }
1204
1205     if( CSSGetASF( p_css->i_fd ) < 0 )
1206     {
1207         return 1;
1208     }
1209
1210 #else
1211
1212     /* 
1213      * Cracking method from Ethan Hawke.
1214      * Does not use key tables and ioctls.
1215      */ 
1216     FILE*   in;
1217     unsigned                     char   buf[0x800] ;
1218         DVD40bitKey              MyKey ;
1219         int                                              pos ;
1220         int                                              BytesRead ;
1221         int                                              BestPLen ;
1222         int                                              BestP ;
1223         int                                              i,j,k ;
1224         int            encrypted=0 ;
1225         int                                      filsize ;
1226         KeyOcc                           PosKey[MaxKeys] ;
1227         int                                              RegisteredKeys = 0 ;
1228         int                                              TotalKeysFound = 0 ;
1229         int                                              StopScanning   = 0 ;
1230         int                                              highest=0 ;
1231
1232
1233 if( (in = fopen( "/dvd/video_ts/vts_01_1.vob", "rb") ) )
1234 {
1235 fprintf( stderr, "CSS:File opened\n" );
1236 pos = 0;
1237 fseek(in,0,SEEK_END);
1238 filsize = ftell(in);
1239 fseek(in,0,SEEK_SET);
1240 do
1241 {
1242 if (params.verbosity >= 1 && filsize > 1024*1024)
1243 {
1244 fprintf(stderr, "%.2f of file read, %i keys found...\r",
1245 pos*100.0/filsize,
1246 TotalKeysFound);
1247 }
1248 BytesRead = fread(buf,1,0x800,in);
1249 if (buf[0x14] & 0x30) // PES_scrambling_control
1250 {
1251 encrypted = 1;
1252 BestPLen = 0;
1253 BestP = 0;
1254 for(i=2;i<0x30;i++)
1255 {
1256 for(j=i; (j < 0x80) && (buf[0x7F - (j%i)] == buf[0x7F-j]); j++);
1257 if ((j>BestPLen) && (j>i))
1258 {
1259 BestPLen = j;
1260 BestP = i;
1261 }
1262 }
1263 if ((BestPLen > 20) && (BestPLen / BestP >= 2))
1264 {
1265 i = CSScracker(0,&buf[0x80],&buf[0x80-(BestPLen/BestP)*BestP],(DVD40bitKey*)&buf[0x54],&MyKey);
1266 while (i>=0)
1267 {
1268 k = 0;
1269 for(j=0;j<RegisteredKeys;j++)
1270 {
1271 if (memcmp(&(PosKey[j].key),&MyKey,sizeof(DVD40bitKey))==0)
1272 {
1273 PosKey[j].occ++ ;
1274 TotalKeysFound++ ;
1275 k = 1 ;
1276 }
1277 }
1278 if (k==0)
1279 {
1280 memcpy(&(PosKey[RegisteredKeys].key), &MyKey, sizeof(DVD40bitKey)) ;
1281 PosKey[RegisteredKeys++].occ = 1 ;
1282 TotalKeysFound++ ;
1283 }
1284 if (params.verbosity >= 2)
1285 {
1286 fprintf(stderr, "\nOfs:%08X - Key: %02X %02X %02X %02X %02X\n",
1287 pos, MyKey[0] ,MyKey[1], MyKey[2],
1288 MyKey[3], MyKey[4]) ;
1289 }
1290 i = CSScracker(i,&buf[0x80],&buf[0x80-(BestPLen/BestP)*BestP],(DVD40bitKey*)&buf[0x54],&MyKey);
1291
1292
1293
1294
1295
1296 }
1297 if (params.scanall==0 && RegisteredKeys==1 && PosKey[0].occ >= params.repetitions)
1298 {
1299 StopScanning = 1;
1300 }
1301 }
1302 }
1303
1304 pos += BytesRead;
1305 } while (BytesRead==0x800 && !StopScanning);
1306 fclose(in);
1307 if (params.verbosity >= 1 && StopScanning)
1308 {
1309 fprintf(stderr, "Found enough occurancies of the same key. Scan stopped.");
1310 }
1311 if (params.verbosity >= 1)
1312 {
1313 fprintf(stderr, "\n\n") ;
1314 }
1315 }
1316 else
1317 {
1318 fprintf(stderr, "FILE ERROR: File could not be opened. [Check if file is readable]\n");
1319 return(1);
1320 }
1321 if (!encrypted)
1322 {
1323 fprintf(stderr, "This file was _NOT_ encrypted!\n");
1324 return(0);
1325 }
1326 if (encrypted && RegisteredKeys==0)
1327 {
1328 fprintf(stderr, "Sorry... Unable to determine keys from file.\n");
1329 return(1);
1330 }
1331 for(i=0;i<RegisteredKeys-1;i++)
1332 {
1333 for(j=i+1;j<RegisteredKeys;j++)
1334 {
1335 if (PosKey[j].occ>PosKey[i].occ)
1336 {
1337 memcpy(&MyKey,&(PosKey[j].key),sizeof(DVD40bitKey));
1338 k = PosKey[j].occ;
1339 memcpy(&(PosKey[j].key),&(PosKey[i].key),sizeof(DVD40bitKey));
1340 PosKey[j].occ = PosKey[i].occ;
1341 memcpy(&(PosKey[i].key),&MyKey,sizeof(DVD40bitKey));
1342 PosKey[i].occ = k;
1343 }
1344 }
1345 }
1346 if (params.verbosity >= 1)
1347 {
1348 fprintf(stderr, " Key(s) & key probability\n--------------------------\n");
1349 highest=0 ;
1350 for(i=0; i<RegisteredKeys; i++)
1351 {
1352 fprintf(stderr, "%d) %02X %02X %02X %02X %02X - %3.2f%%\n", i,
1353 PosKey[i].key[0],PosKey[i].key[1],PosKey[i].key[2],
1354 PosKey[i].key[3],PosKey[i].key[4],
1355 PosKey[i].occ*100.0/TotalKeysFound) ;
1356 if (PosKey[highest].occ*100.0/TotalKeysFound
1357     <= PosKey[i].occ*100.0/TotalKeysFound)
1358 {
1359 highest=i ;
1360 }
1361 }
1362 fprintf(stderr, "\n");
1363 }
1364 /* The "find the key with the highest probability" code
1365 is untested, as I haven't been able to find a VOB that
1366 produces multiple keys (RT)
1367 */
1368 printf("%02X %02X %02X %02X %02X\n", 
1369 PosKey[highest].key[0],PosKey[highest].key[1],PosKey[highest].key[2],
1370 PosKey[highest].key[3],PosKey[highest].key[4]) ;
1371
1372     for( i=0 ; i<5 ; i++ )
1373     {
1374 //        p_css->p_title_key->key[i] = PosKey[highest].key[i];
1375     }
1376
1377 #endif
1378     return 0;
1379 }
1380
1381 /*****************************************************************************
1382  * CSSDescrambleSector
1383  *****************************************************************************/
1384 int CSSDescrambleSector( DVD40bitKey* key, unsigned char * sec )
1385 {
1386 #if 0
1387     FILE                                        *in,*out ;
1388         unsigned                         char   buf[0x800] ;
1389         int                                              pos ;
1390         int                                              BytesRead ;
1391         int                                              BytesWritten ;
1392         int                                      filsize ;
1393
1394     do {
1395     BytesRead = fread(&buf,1,0x800,in);
1396     if (buf[0x14] & 0x30) // PES_scrambling_control
1397     {
1398         unsigned int t1,t2,t3,t4,t5,t6;
1399         unsigned char *end=sec+0x800;
1400
1401         t1=((*key)[0] ^ sec[0x54]) | 0x100;
1402         t2=(*key)[1] ^ sec[0x55];
1403         t3= (((*key)[2]) | ((*key)[3]<<8) |
1404             ((*key)[4]<<16)) ^ ((sec[0x56]) |
1405             (sec[0x57]<<8) | (sec[0x58]<<16));
1406         t4=t3&7;
1407         t3=t3*2+8-t4;
1408         sec+=0x80;
1409         t5=0;
1410
1411         while(sec!=end)
1412         {
1413             t4 = pi_css_tab2[t2] ^ pi_css_tab3[t1];
1414             t2=t1>>1;
1415             t1=((t1&1)<<8)^t4;
1416             t4 = pi_css_tab5[t4];
1417             t6=(((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)&0xff;
1418             t3=(t3<<8)|t6;
1419             t6 = pi_css_tab4[t6];
1420             t5+=t6+t4;
1421             *sec++= pi_css_tab1[*sec]^(t5&0xff);
1422             t5>>=8;
1423         }
1424
1425         buf[0x14] &= 0x8F;
1426     }
1427
1428     BytesWritten = fwrite(&buf,1,BytesRead,out);
1429     if (BytesWritten!=BytesRead)
1430     {
1431         fprintf(stderr, "Could not write to output file.\n");
1432         return(1);
1433     }
1434     pos += BytesRead;
1435     } while (BytesRead==0x800);
1436
1437 #endif
1438         return(0);
1439 }