sony_clear.c

00001 /*
00002    Completely decrypt a Sony DSC-F828 raw file.
00003    by Dave Coffin  1/4/2004
00004  */
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <netinet/in.h>
00010 
00011 typedef unsigned char uchar;
00012 
00013 void sony_decrypt (void *buf, int len, int key)
00014 {
00015   unsigned pad[128], *data=buf;
00016   int i;
00017 
00018   for (i=0; i < 4; i++)
00019     pad[i] = key = key * 48828125 + 1;
00020   pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
00021   for (i=4; i < 127; i++)
00022     pad[i] = (pad[i-4]^pad[i-2]) << 1 | (pad[i-3]^pad[i-1]) >> 31;
00023   for (i=0; i < 127; i++)
00024     pad[i] = htonl(pad[i]);
00025   for ( ; i < len+127; i++,data++)
00026     *data ^= pad[i & 127] = pad[(i+1) & 127] ^ pad[(i+65) & 127];
00027 }
00028 
00029 void sony_clear (uchar *buffer, int length)
00030 {
00031   unsigned *ip, key0, key1=0, key2=0, i;
00032   uchar *cp;
00033 
00034   ip = (void *) cp = buffer+200896;
00035   key0 = ntohl(ip[*cp]);
00036   sony_decrypt (buffer+164600, 9074, key0);
00037   for (i=4; i--; ) {
00038     key1 = key1 << 8 | buffer[164610+i];
00039     key2 = key2 << 8 | buffer[164622+i];
00040   }
00041   sony_decrypt (buffer+164640, 174376, key1);
00042   sony_decrypt (buffer+862144, (length-862144)/4, key2);
00043 }
00044 
00045 int main (int argc, char **argv)
00046 {
00047   FILE *fp;
00048   char name[512], *buffer;
00049   int arg, length;
00050 
00051   for (arg=1; arg < argc; arg++) {
00052     fp = fopen (argv[arg], "rb");
00053     if (!fp) {
00054       perror (argv[arg]);
00055       continue;
00056     }
00057     fseek (fp, 0, SEEK_END);
00058     length = ftell (fp);
00059     if (length < 0x100000) {
00060       fprintf (stderr, "%s is too small!\n", argv[arg]);
00061       fclose(fp);
00062       continue;
00063     }
00064     buffer = malloc (length);
00065     if (!buffer) {
00066       fprintf (stderr, "%s is too big!\n", argv[arg]);
00067       fclose(fp);
00068       continue;
00069     }
00070     fseek (fp, 0, SEEK_SET);
00071     fread (buffer, 1, length, fp);
00072     fclose (fp);
00073     sony_clear (buffer, length);
00074     strcpy (name, argv[arg]);
00075     strcat (name, ".clear");
00076     fp = fopen (name, "wb");
00077     fwrite (buffer, 1, length, fp);
00078     free (buffer);
00079     fclose(fp);
00080   }
00081   return 0;
00082 }

Generated on Sat Jan 27 11:36:13 2007 for libopenraw by  doxygen 1.4.7