Skip site navigation (1)Skip section navigation (2)
Date:      Tue,  4 Jan 2000 19:41:21 -0600 (CST)
From:      Anthony Kimball <alk@pobox.com>
To:        efknight@bellsouth.net
Cc:        multimedia@freebsd.org
Subject:   DeCSS
Message-ID:  <14450.41202.750383.328359@avalon.east>
References:  <38729EF1.B336C84A@bellsouth.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Quoth Ted Knight on Tue, 4 January:
:
: Any comments, suggestions or success stories?
: 

Success:

--- css-auth/dvdinfo.c	Thu Nov  4 20:25:13 1999
+++ css-auth.alk/dvdinfo.c	Fri Dec 24 02:38:12 1999
@@ -5,13 +5,8 @@
 
 #include <stdio.h>
 #include <fcntl.h>
-#if defined(__OpenBSD__)
-# include <sys/dvdio.h>
-#elif defined(__linux__)
-# include <linux/cdrom.h>
-#else
-# error "Need the DVD ioctls"
-#endif
+#include <sys/cdio.h>
+#include <sys/dvdio.h>
 #include <sys/ioctl.h>
 #include <errno.h>
 
@@ -19,53 +14,55 @@
 
 int GetASF(int fd)
 {
-	dvd_authinfo ai;
+	struct dvd_authinfo ai;
 
-	ai.type = DVD_LU_SEND_ASF;
-	ai.lsasf.agid = 0;
-	ai.lsasf.asf = 0;
+	ai.format = DVD_REPORT_ASF;
+	ai.agid = 0;
+	ai.asf = 0;
 
-	if (ioctl(fd, DVD_AUTH, &ai)) {
+	if (ioctl(fd, DVDIOCREPORTKEY, &ai)) {
 		printf("GetASF failed\n");
 		return 0;
 	}
 
-	printf("%sAuthenticated\n", (ai.lsasf.asf) ? "" : "not ");
+	printf("%sAuthenticated\n", (ai.asf) ? "" : "not ");
 
 	return 1;
 }
 
 int GetPhysical(int fd)
 {
-	dvd_struct d;
+        struct dvd_struct d;
 	int layer = 0, layers = 4;
 
-	d.physical.type = DVD_STRUCT_PHYSICAL;
+	d.format = DVD_STRUCT_PHYSICAL;
 	while (layer < layers) {
-		d.physical.layer_num = layer;
+	        struct dvd_layer *lp = (struct dvd_layer *)&d.data[0];
+
+		d.layer_num = layer;
 	
-		if (ioctl(fd, DVD_READ_STRUCT, &d)<0)
+		if (ioctl(fd, DVDIOCREADSTRUCTURE, &d)<0)
 		{
 			printf("Could not read Physical layer %d\n", layer);
 			return 0;
 		}
 
-		layers = d.physical.layer[layer].nlayers + 1;
+		layers = lp->nlayers + 1;
 
 		printf("Layer %d[%d]\n", layer, layers);
-		printf(" Book Version:   %d\n", d.physical.layer[layer].book_version);
-		printf(" Book Type:      %d\n", d.physical.layer[layer].book_type);
-		printf(" Min Rate:       %d\n", d.physical.layer[layer].min_rate);
-		printf(" Disk Size:      %d\n", d.physical.layer[layer].disc_size);
-		printf(" Layer Type:     %d\n", d.physical.layer[layer].layer_type);
-		printf(" Track Path:     %d\n", d.physical.layer[layer].track_path);
-		printf(" Num Layers:     %d\n", d.physical.layer[layer].nlayers);
-		printf(" Track Density:  %d\n", d.physical.layer[layer].track_density);
-		printf(" Linear Density: %d\n", d.physical.layer[layer].linear_density);
-		printf(" BCA:            %d\n", d.physical.layer[layer].bca);
-		printf(" Start Sector    %#x\n", d.physical.layer[layer].start_sector);
-		printf(" End Sector      %#x\n", d.physical.layer[layer].end_sector);
-		printf(" End Sector L0   %#x\n", d.physical.layer[layer].end_sector_l0);
+		printf(" Book Version:   %d\n", lp->book_version);
+		printf(" Book Type:      %d\n", lp->book_type);
+		printf(" Max Rate:       %d\n", lp->max_rate);
+		printf(" Disk Size:      %d\n", lp->disc_size);
+		printf(" Layer Type:     %d\n", lp->layer_type);
+		printf(" Track Path:     %d\n", lp->track_path);
+		printf(" Num Layers:     %d\n", lp->nlayers);
+		printf(" Track Density:  %d\n", lp->track_density);
+		printf(" Linear Density: %d\n", lp->linear_density);
+		printf(" BCA:            %d\n", lp->bca);
+		printf(" Start Sector    %#x\n", lp->start_sector);
+		printf(" End Sector      %#x\n", lp->end_sector);
+		printf(" End Sector L0   %#x\n", lp->end_sector_l0);
 
 		++layer;
 	}
@@ -75,18 +72,18 @@
 
 int GetCopyright(int fd)
 {
-	dvd_struct d;
+	struct dvd_struct d;
 
-	d.copyright.type = DVD_STRUCT_COPYRIGHT;
-	d.copyright.layer_num = 0;
+	d.format = DVD_STRUCT_COPYRIGHT;
+	d.layer_num = 0;
 	
-	if (ioctl(fd, DVD_READ_STRUCT, &d)<0)
+	if (ioctl(fd, DVDIOCREADSTRUCTURE, &d)<0)
 	{
 		printf("Could not read Copyright Struct\n");
 		return 0;
 	}
 
-	printf("Copyright: CPST=%d, RMI=%#02x\n", d.copyright.cpst, d.copyright.rmi);
+	printf("Copyright: CPST=%d, RMI=%#02x\n", d.cpst, d.rmi);
 
 	return 1;
 }
--- css-auth/reset.c	Thu Nov  4 20:25:13 1999
+++ css-auth.alk/reset.c	Fri Dec 24 02:41:54 1999
@@ -4,13 +4,8 @@
 
 #include<stdio.h>
 #include<fcntl.h>
-#if defined(__OpenBSD__)
-# include <sys/dvdio.h>
-#elif defined(__linux__)
-# include <linux/cdrom.h>
-#else
-# error "Need the DVD ioctls"
-#endif
+#include<sys/cdio.h>
+#include<sys/dvdio.h>
 #include<sys/ioctl.h>
 #include<errno.h>
 
@@ -20,7 +15,7 @@
 
 int main(int ac, char **av)
 {
-	dvd_authinfo ai;
+	struct dvd_authinfo ai;
 	char *device = DVD;
 	int i;
 
@@ -30,15 +25,15 @@
 	fd = open(device, O_RDONLY | O_NONBLOCK);
 
 	if (fd < 0) {
-		printf("unable to open dvd drive (%s).\n", device);
-		return 1;
+	        perror("open");
+		errx(1,"unable to open dvd drive (%s).\n", device);
 	}
 
 	for (i = 0; i < 4; i++) {
 		memset(&ai, 0, sizeof(ai));
-		ai.type = DVD_INVALIDATE_AGID;
-		ai.lsa.agid = i;
-		ioctl(fd, DVD_AUTH, &ai);
+		ai.format = DVD_INVALIDATE_AGID;
+		ai.agid = i;
+		ioctl(fd, DVDIOCREPORTKEY, &ai);
 	}
 
 	return 0;
--- css-auth/tstdvd.c	Tue Nov  9 04:46:23 1999
+++ css-auth.alk/tstdvd.c	Fri Dec 24 02:35:38 1999
@@ -27,13 +27,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <errno.h>
-#if defined(__OpenBSD__)
-# include <sys/dvdio.h>
-#elif defined(__linux__)
-# include <linux/cdrom.h>
-#else
-# error "Need the DVD ioctls"
-#endif
+#include <sys/cdio.h>
+#include <sys/dvdio.h>
 #include "css-auth.h"
 
 byte Challenge[10];
@@ -94,23 +89,23 @@
 
 int GetDiscKey(int fd, int agid, char *key)
 {
-	dvd_struct s;
+        struct dvd_struct s;
 	int	index, fdd;
 
-	s.type = DVD_STRUCT_DISCKEY;
-	s.disckey.agid = agid;
-	memset(s.disckey.value, 0, 2048);
-	if (ioctl(fd, DVD_READ_STRUCT, &s)<0)
+	s.format = DVD_STRUCT_DISCKEY;
+	s.agid = agid;
+	memset(s.data, 0, 2048);
+	if (ioctl(fd, DVDIOCREADSTRUCTURE, &s)<0)
 	{
 		printf("Could not read Disc Key\n");
 		return 0;
 	}
 
 	printf ("Received Disc Key:\t");
-	for (index=0; index<sizeof s.disckey.value; index++)
-		s.disckey.value[index] ^= key[4 - (index%5)];
+	for (index=0; index<2048; index++)
+		s.data[index] ^= key[4 - (index%5)];
 	for (index=0; index<10; index++) {
-		printf("%02X ", s.disckey.value[index]);
+		printf("%02X ", s.data[index]);
 	}		
 	printf ("\n");
 
@@ -118,7 +113,7 @@
 	if (fdd < 0)
 		printf("Can't create \"disk-key\"\n");
 	else {
-		if (write(fdd, s.disckey.value, 2048) != 2048)
+		if (write(fdd, &s.data[0], 2048) != 2048)
 			printf("Can't write \"disk-key\"\n");
 		close(fdd);
 	}
@@ -126,35 +121,35 @@
 	return 1;
 }
 
-int GetTitleKey(int fd, int agid, int lba, char *key)
+int GetTitleKey(int fd, int agid, int lba_fd, char *key)
 {
-	dvd_authinfo ai;
+        struct dvd_authinfo ai;
 	int i, fdd;
 
-	ai.type = DVD_LU_SEND_TITLE_KEY;
+	ai.format = DVD_REPORT_TITLE_KEY;
 
-	ai.lstk.agid = agid;
-	ai.lstk.lba = lba;
+	ai.agid = agid;
+	ai.lba = lba_fd;
 
-	if (ioctl(fd, DVD_AUTH, &ai)) {
+	if (ioctl(fd, DVDIOCREPORTKEY, &ai)) {
 		printf("GetTitleKey failed\n");
 		return 0;
 	}
 
 	printf ("Received Title Key:\t");
 	for (i = 0; i < 5; ++i) {
-		ai.lstk.title_key[i] ^= key[4 - (i%5)];
-		printf("%02X ", ai.lstk.title_key[i]);
+		ai.keychal[i] ^= key[4 - (i%5)];
+		printf("%02X ", ai.keychal[i]);
 	}
 	putchar('\n');
 
-	printf(" CPM=%d, CP_SEC=%d, CGMS=%d\n", ai.lstk.cpm, ai.lstk.cp_sec, ai.lstk.cgms);
+	printf(" CPM=%d, CP_SEC=%d, CGMS=%d\n", ai.cpm, ai.cp_sec, ai.cgms);
 
 	fdd = open("title-key", O_WRONLY|O_TRUNC|O_CREAT, 0644);
 	if (fdd < 0)
 		printf("Can't create \"title-key\"\n");
 	else {
-		if (write(fdd, ai.lstk.title_key, 5) != 5)
+		if (write(fdd, &ai.keychal[0], 5) != 5)
 			printf("Can't write \"title-key\"\n");
 		close(fdd);
 	}
@@ -164,80 +159,26 @@
 
 int GetASF(int fd)
 {
-	dvd_authinfo ai;
+	struct dvd_authinfo ai;
 
-	ai.type = DVD_LU_SEND_ASF;
-	ai.lsasf.agid = 0;
-	ai.lsasf.asf = 0;
+	ai.format = DVD_REPORT_ASF;
+	ai.agid = 0;
+	ai.asf = 0;
 
-	if (ioctl(fd, DVD_AUTH, &ai)) {
+	if (ioctl(fd, DVDIOCREPORTKEY, &ai)) {
 		printf("GetASF failed\n");
 		return 0;
 	}
 
-	printf("%sAuthenticated\n", (ai.lsasf.asf) ? "" : "not ");
+	printf("%sAuthenticated\n", (ai.asf) ? "" : "not ");
 
-	return 1;
+	return ai.asf;
 }
 
-/* Simulation of a non-CSS compliant host (i.e. the authentication fails,
- * but idea is here for a real CSS compliant authentication scheme). */
-int
-hostauth (dvd_authinfo *ai)
+int authenticate(int fd, int title, int lba_fd)
 {
-	int i;
-
-	switch (ai->type) {
-	/* Host data receive (host changes state) */
-	case DVD_LU_SEND_AGID:
-		printf("AGID %d\n", ai->lsa.agid);
-		ai->type = DVD_HOST_SEND_CHALLENGE;
-		break;
-
-	case DVD_LU_SEND_KEY1:
-		printf("LU sent key1: "); print_key(ai->lsk.key); printf("\n");
-		if (!authenticate_drive(ai->lsk.key)) {
-			ai->type = DVD_AUTH_FAILURE;
-			return -EINVAL;
-		}
-		ai->type = DVD_LU_SEND_CHALLENGE;
-		break;
-
-	case DVD_LU_SEND_CHALLENGE:
-		for (i = 0; i < 10; ++i)
-			Challenge[i] = ai->hsc.chal[9-i];
-		printf("LU sent challenge: "); print_challenge(Challenge); printf("\n");
-		CryptKey2(varient, Challenge, &Key2);
-		ai->type = DVD_HOST_SEND_KEY2;
-		break;
-
-	/* Host data send */
-	case DVD_HOST_SEND_CHALLENGE:
-		for (i = 0; i < 10; ++i)
-			ai->hsc.chal[9-i] = Challenge[i];
-		printf("Host sending challenge: "); print_challenge(Challenge); printf("\n");
-		/* Returning data, let LU change state */
-		break;
-
-	case DVD_HOST_SEND_KEY2:
-		for (i = 0; i < 5; ++i)
-			ai->hsk.key[4-i] = Key2.b[i];
-		printf("Host sending key 2: "); print_key(Key2.b); printf("\n");
-		/* Returning data, let LU change state */
-		break;
-
-	default:
-		printf("Got invalid state %d\n", ai->type);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-int authenticate(int fd, int title, int lba)
-{
-	dvd_authinfo ai;
-	dvd_struct dvds;
+	struct dvd_authinfo ai;
+	struct dvd_struct dvds;
 	int i, rv, tries, agid;
 
 	memset(&ai, 0, sizeof (ai));
@@ -248,14 +189,14 @@
 	/* Init sequence, request AGID */
 	for (tries = 1, rv = -1; rv == -1 && tries < 4; ++tries) {
 		printf("Request AGID [%d]...\t", tries);
-		ai.type = DVD_LU_SEND_AGID;
-		ai.lsa.agid = 0;
-		rv = ioctl(fd, DVD_AUTH, &ai);
+		ai.format = DVD_REPORT_AGID;
+		ai.agid = 0;
+		rv = ioctl(fd, DVDIOCREPORTKEY, &ai);
 		if (rv == -1) {
 			perror("N/A, invalidating");
-			ai.type = DVD_INVALIDATE_AGID;
-			ai.lsa.agid = 0;
-			ioctl(fd, DVD_AUTH, &ai);
+			ai.format = DVD_INVALIDATE_AGID;
+			ai.agid = 0;
+			ioctl(fd, DVDIOCREPORTKEY, &ai);
 		}
 	}
 	if (tries == 4) {
@@ -266,57 +207,54 @@
 	for (i = 0; i < 10; ++i)
 		Challenge[i] = i;
 
-	/* Send AGID to host */
-	if (hostauth(&ai) < 0) {
-		printf("Send AGID to host failed\n");
-		return -1;
-	}
+	printf("AGID %d\n", ai.agid);
+	agid = ai.agid;
 	/* Get challenge from host */
-	if (hostauth(&ai) < 0) {
-		printf("Get challenge from host failed\n");
-		return -1;
-	}
-	agid = ai.lsa.agid;
+	ai.format = DVD_SEND_CHALLENGE;
+	for (i = 0; i < 10; ++i)
+		ai.keychal[9-i] = Challenge[i];
+	printf("Host sending challenge: "); print_challenge(Challenge); printf("\n");
 	/* Send challenge to LU */
-	if (ioctl(fd, DVD_AUTH, &ai) < 0) {
+	if (ioctl(fd, DVDIOCSENDKEY, &ai) < 0) {
 		printf("Send challenge to LU failed\n");
 		return -1;
 	}
 	/* Get key1 from LU */
-	if (ioctl(fd, DVD_AUTH, &ai) < 0) {
+	ai.format = DVD_REPORT_KEY1;
+	if (ioctl(fd, DVDIOCREPORTKEY, &ai) < 0) {
 		printf("Get key1 from LU failed\n");
 		return -1;
 	}
 	/* Send key1 to host */
-	if (hostauth(&ai) < 0) {
+	printf("LU sent key1: "); print_key(ai.keychal); printf("\n");
+	if (!authenticate_drive(ai.keychal)) {
 		printf("Send key1 to host failed\n");
 		return -1;
 	}
 	/* Get challenge from LU */
-	if (ioctl(fd, DVD_AUTH, &ai) < 0) {
+	ai.format = DVD_REPORT_CHALLENGE;
+	if (ioctl(fd, DVDIOCREPORTKEY, &ai) < 0) {
 		printf("Get challenge from LU failed\n");
 		return -1;
 	}
 	/* Send challenge to host */
-	if (hostauth(&ai) < 0) {
-		printf("Send challenge to host failed\n");
-		return -1;
-	}
+	for (i = 0; i < 10; ++i)
+		Challenge[i] = ai.keychal[9-i];
+	printf("LU sent challenge: "); print_challenge(Challenge); printf("\n");
+	CryptKey2(varient, Challenge, &Key2);
 	/* Get key2 from host */
-	if (hostauth(&ai) < 0) {
-		printf("Get key2 from host failed\n");
-		return -1;
-	}
+	ai.format = DVD_SEND_KEY2;
+	for (i = 0; i < 5; ++i)
+		ai.keychal[4-i] = Key2.b[i];
+	printf("Host sending key 2: "); print_key(Key2.b); printf("\n");
 	/* Send key2 to LU */
-	if (ioctl(fd, DVD_AUTH, &ai) < 0) {
+	if (ioctl(fd, DVDIOCSENDKEY, &ai) < 0) {
 		printf("Send key2 to LU failed (expected)\n");
 		return -1;
 	}
 
-	if (ai.type == DVD_AUTH_ESTABLISHED)
-		printf("DVD is authenticated\n");
-	else if (ai.type == DVD_AUTH_FAILURE)
-		printf("DVD authentication failed\n");
+	printf("DVD will most likely be authenticated soon...\n");
+	GetASF(fd);
 
 	memcpy(Challenge, Key1.b, 5);
 	memcpy(Challenge+5, Key2.b, 5);
@@ -331,7 +269,7 @@
 	GetASF(fd);
 
 	if (title)
-		GetTitleKey(fd, agid, lba, KeyCheck.b);
+		GetTitleKey(fd, agid, lba_fd, KeyCheck.b);
 	else
 		GetDiscKey(fd, agid, KeyCheck.b);
 
@@ -366,7 +304,7 @@
 int main(int ac, char **av)
 {
 	char *device;
-	int fd, title = 0, lba = 0;
+	int fd, title = 0, lba_fd = 0;
 
 	if (ac < 2) {
 		fprintf(stderr, "usage: tstdvd <device> [title_path]\n");
@@ -379,10 +317,13 @@
 		exit(1);
 	}
 	if (ac == 3) {
-		lba = path_to_lba(av[2]);
+		if ((lba_fd = open(av[2], O_RDONLY)) == -1) {
+			perror(av[2]);
+			exit(1);
+		}
 		title = 1;
 	}
-	authenticate(fd, title, lba);
+	authenticate(fd, title, lba_fd);
 	close(fd);
 
 	return 0;


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-multimedia" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?14450.41202.750383.328359>