Highlighted in red is what i assume is the problem, and why it is giving you a bad response. i cant test this unfortunatly, because i wont have my linux machine for a couple weeks.
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#ifndef FALSE
#define FALSE (1==0)
#endif
#ifndef TRUE
#define TRUE (0==0)
#endif
#define CRONVERSION "v1.3"
unsigned short xkey<64>;
void rc2_keyschedule(unsigned short xkey<64>, const unsigned char *key, unsigned len, unsigned bits);
void rc2_encrypt(const unsigned short xkey<64>, const unsigned char *plain, unsigned char *cipher );
void rc2_decrypt(const unsigned short xkey<64>, unsigned char *plain, const unsigned char *cipher );
void apply_iv(unsigned char *block, unsigned char *ivdata, int blocksize);
void encrypt(char *challenge, char *response);
int LoadKey(unsigned char *challenge);
int main(int argc, char** argv) {
unsigned char inbuf<256>;
unsigned char outbuf<256>;
FILE *outfile;
char *outname<32>= {"unknownkeys.txt", "pv2keys.txt", "saturnkeys.txt", "saturnkeys.txt", "m510keys.txt", "unknownkeys.txt", "pv2keys.txt", "saturnkeys.txt", "saturnkeys.txt", "m510keys.txt", "unknownkeys.txt", "unknownkeys.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt"};
int s,t;
fprintf(stderr,"firedecryptKey %s\n",CRONVERSION);
if(LoadKey(inbuf)==FALSE)
{
fprintf(stderr,"Error: couldn't load key. Exiting.\n");
exit(1);
}
memset(outbuf,0,256);
if((inbuf<0><1) || (inbuf<0>>32))
{
fprintf(stderr,"the challenge isn't one of the known types(1-32). exiting.\n\n");
#ifdef WIN32
system("pause");
#endif
exit(1);
}
encrypt(inbuf,outbuf);
printf("\n");
outfile=fopen(outname-1>,"a");
printf("S firedecryptKey\n");
if(outfile!=NULL)
fprintf(outfile,"S firedecryptKey\n");
for(t=0;t<4;t++)
{
printf("C ");
if(outfile!=NULL)
fprintf(outfile,"C ");
for(s=0;s<32;s++)
{
printf("%02x",inbuf<(t*32)+s>);
if(outfile!=NULL)
fprintf(outfile,"%02x",inbuf<(t*32)+s>);
}
printf("\n");
if(outfile!=NULL)
fprintf(outfile,"\n");
}
for(t=0;t<4;t++)
{
printf("R ");
if(outfile!=NULL)
fprintf(outfile,"R ");
for(s=0;s<32;s++)
{
printf("%02x",outbuf<(t*32)+s>);
if(outfile!=NULL)
fprintf(outfile,"%02x",outbuf<(t*32)+s>);
}
printf("\n");
if(outfile!=NULL)
fprintf(outfile,"\n");
}
printf("\n");
if(outfile!=NULL)
{
fprintf(outfile,"\n");
fclose(outfile);
printf("\nThis information has been stored for you in: %s\n", outname-1>);
}
#ifdef WIN32
system("pause");
#endif
}
void encrypt(char *_challenge, char *response)
{
unsigned char key<32><16> = {
{0xf7, 0x87, 0xdf, 0xe5, 0x26, 0xc6, 0x6b, 0x20, 0xe4, 0x46, 0xb7, 0x9b, 0x48, 0x70, 0xe3, 0x8d}, //01
{0xfd, 0xf2, 0x94, 0xee, 0x89, 0xcf, 0xb8, 0xe1, 0xe0, 0x6a, 0xf1, 0xf5, 0x14, 0xd3, 0xbb, 0xde}, //02
{0xa8, 0x9a, 0xfb, 0xb7, 0x0e, 0x20, 0x06, 0x43, 0x64, 0xee, 0xff, 0xa3, 0x5f, 0xc9, 0x52, 0x35}, //03
{0xe8, 0x6f, 0x3a, 0x8c, 0x0a, 0x8d, 0xf1, 0x78, 0x59, 0x91, 0x08, 0xc0, 0x29, 0x57, 0x95, 0xba}, //04
{0x13, 0xa0, 0x87, 0x20, 0x3a, 0xf5, 0xc2, 0x35, 0x5e, 0x12, 0xb3, 0x23, 0x76, 0x96, 0xdc, 0x74}, //05
{0x00, 0x8e, 0x84, 0x63, 0xe0, 0x16, 0x04, 0x53, 0xb0, 0x71, 0xbf, 0xbf, 0xa0, 0x6e, 0x9d, 0x8a}, //06
{0x57, 0x06, 0x0f, 0x8b, 0xd0, 0xb7, 0x09, 0x92, 0x8d, 0x08, 0x84, 0x20, 0xf2, 0x06, 0x4a, 0xbc}, //07
{0xdd, 0xc8, 0x94, 0x57, 0xd7, 0x8b, 0xe3, 0x04, 0x2f, 0xcb, 0xcc, 0xfb, 0xc8, 0x89, 0x4f, 0x9f}, //08
{0x88, 0xc5, 0x88, 0x27, 0x06, 0x08, 0x46, 0xe9, 0x65, 0x9b, 0x9f, 0x5e, 0x03, 0xbe, 0xde, 0x86}, //09
{0xa6, 0x07, 0xfd, 0x0d, 0x99, 0xc0, 0x14, 0x55, 0x69, 0x9d, 0xbe, 0xf2, 0x65, 0x56, 0x96, 0x59}, //10
{0x99, 0xc3, 0x60, 0xf1, 0xdf, 0xef, 0x92, 0x72, 0x0d, 0x89, 0x7a, 0x7d, 0x35, 0xda, 0x8b, 0xdf}, //11
{0x7f, 0x26, 0xdb, 0xc9, 0x5f, 0x0d, 0x4a, 0x48, 0x0f, 0xe9, 0x12, 0xb1, 0x1f, 0x4e, 0xf2, 0xa2}, //12
{0x2A, 0x09, 0xD3, 0x9C, 0x39, 0x4E, 0x66, 0x01, 0x51, 0x32, 0x15, 0xC8, 0xE7, 0xA8, 0x49, 0x1C}, //13
{0x19, 0xFB, 0xEE, 0xAA, 0x81, 0xC0, 0x83, 0x14, 0x2F, 0x1C, 0xFE, 0xFA, 0x2A, 0x0C, 0xDA, 0x72}, //14
{0x34, 0x19, 0x44, 0xD9, 0x49, 0x43, 0xA8, 0x51, 0xF0, 0x36, 0x08, 0xBB, 0xD5, 0x20, 0x9C, 0xCD}, //15
{0xFB, 0x20, 0x9C, 0x24, 0x90, 0x66, 0x5A, 0x1E, 0xCA, 0x12, 0x50, 0x07, 0x79, 0xB5, 0x45, 0xE9}, //16
{0x86, 0xEA, 0x69, 0x49, 0x5A, 0x92, 0xA3, 0x84, 0xF5, 0x89, 0xBD, 0x21, 0x7F, 0x25, 0xA3, 0x3C}, //17
{0xEB, 0x5D, 0xFE, 0xC4, 0xDE, 0x9E, 0xE5, 0x02, 0x22, 0x35, 0x16, 0xEC, 0xBF, 0xD6, 0xC4, 0xA6}, //18
{0x0A, 0x82, 0x14, 0xAA, 0x56, 0x56, 0x50, 0x63, 0x2C, 0x15, 0x60, 0x59, 0x4A, 0x0B, 0xC1, 0xCC}, //19
{0xA4, 0xE7, 0xAF, 0x1A, 0x4B, 0x1D, 0x14, 0xEC, 0x78, 0xA1, 0x83, 0x24, 0xA4, 0xCC, 0xF8, 0xB6}, //20
{0xA4, 0xE7, 0xAF, 0x1A, 0x4B, 0x1D, 0x14, 0xEC, 0x78, 0xA1, 0x83, 0x24, 0xA4, 0xCC, 0xF8, 0xB6}, //21
{0xC6, 0x90, 0x31, 0x3F, 0x06, 0xB0, 0x49, 0x4B, 0x1F, 0xE7, 0xED, 0x96, 0xEF, 0x97, 0x7B, 0x22}, //22
{0xA0, 0xD9, 0x84, 0x6B, 0xF1, 0xEA, 0x38, 0x45, 0x96, 0x8D, 0xA2, 0x41, 0xE9, 0x5A, 0xF2, 0x8E}, //23
{0x85, 0x0E, 0xD9, 0xF8, 0xBE, 0xBD, 0x67, 0xA4, 0x63, 0x93, 0xEB, 0x3A, 0x0F, 0x3A, 0xF2, 0x08}, //24
{0x24, 0x9F, 0x48, 0x66, 0x21, 0x72, 0x56, 0xE7, 0xE4, 0x25, 0x64, 0xA7, 0x8E, 0x8C, 0xBE, 0x35}, //25
{0xC3, 0x7E, 0x0E, 0xE2, 0x5C, 0x91, 0x94, 0xBE, 0xB5, 0x90, 0xF9, 0x32, 0x9A, 0xD4, 0xA6, 0x5D}, //26
{0xAD, 0xCA, 0xA4, 0xB3, 0x00, 0x86, 0x88, 0x0B, 0xF5, 0x97, 0x77, 0x15, 0x3E, 0x59, 0x69, 0x0A}, //27
{0xB1, 0x94, 0x77, 0x0F, 0x13, 0x0A, 0x4D, 0xB8, 0x34, 0x9F, 0xE0, 0x37, 0x2E, 0x81, 0xCA, 0xC2}, //28
{0x90, 0x4F, 0x23, 0x43, 0x99, 0x1E, 0x9A, 0x0C, 0x86, 0xA7, 0x0B, 0x09, 0x78, 0x0F, 0x12, 0xFE}, //29
{0x84, 0xDB, 0x58, 0x7C, 0x00, 0xCA, 0x5B, 0x67, 0xCF, 0x91, 0xBF, 0x93, 0x8E, 0xCD, 0xA2, 0x34}, //30
{0xF4, 0x5D, 0x36, 0xB3, 0xEF, 0x03, 0x8B, 0x59, 0xF0, 0x12, 0xA8, 0x06, 0x12, 0x79, 0x0F, 0xA6}, //31
{0x6A, 0x14, 0x5E, 0xE2, 0x11, 0xB0, 0xC7, 0xC3, 0x86, 0x2D, 0x56, 0xDA, 0xE6, 0x3F, 0x30, 0xBB} //32
};
unsigned char iv<32><8> =
{
{0xFE,0x2A,0x60,0xFD,0x10,0x38,0x1E,0x7F}, //01
{0x5D,0x18,0xFB,0x0C,0xAF,0x31,0xB7,0x02}, //02
{0x2D,0x48,0x77,0xDC,0x72,0xA6,0x8F,0xBC}, //03
{0xC6,0xDB,0x61,0xA5,0x61,0x13,0x03,0x07}, //04
{0x56,0xaf,0x19,0x31,0xec,0x8f,0x77,0x22}, //05
{0xc5,0xf2,0x71,0x4c,0xf1,0xa7,0x19,0x7b}, //06
{0xe4,0xb6,0xb0,0xb4,0x2b,0x1c,0x71,0xd5}, //07
{0xec,0x6d,0x98,0x43,0x76,0xdf,0xe0,0x13}, //08
{0x27,0x9a,0xb7,0x10,0x94,0xde,0x08,0x0d}, //09
{0x85,0x92,0xc6,0xc5,0x3b,0x88,0xb7,0xcd}, //10
{0xbd,0x50,0xd7,0xdb,0xe8,0x9f,0x79,0x4e}, //11
{0xdb,0xb9,0xe8,0x95,0x5e,0x1a,0x47,0x1e}, //12
{0x96,0x30,0xfd,0xbf,0x27,0xbe,0x5e,0xce}, //13
{0x7e,0x29,0xf2,0x76,0xe4,0x53,0xbf,0x1b}, //14
{0xb1,0xa5,0xfe,0x76,0x5a,0x08,0xd6,0x4e}, //15
{0x01,0x73,0xb1,0xb0,0x8e,0xb8,0xbe,0x7d}, //16
{0xbe,0x3b,0x2b,0x57,0x1a,0xa1,0xb2,0xfa}, //17
{0x2a,0xc8,0xc1,0xc9,0x5b,0xd7,0xda,0x27}, //18
{0xd3,0x41,0x41,0xa2,0x94,0x93,0xdc,0x90}, //19
{0x71,0x93,0xc6,0x95,0x24,0xb9,0xe3,0x6f}, //20
{0x77,0x70,0x26,0x8a,0x51,0xbf,0xa9,0xb2}, //21
{0x89,0x9a,0xd0,0xde,0x67,0x24,0x82,0x23}, //22
{0x2f,0x7d,0xb7,0xa4,0xa5,0xca,0x73,0x4c}, //23
{0x30,0xd2,0x2b,0x33,0x2b,0xa4,0x0d,0x74}, //24
{0x98,0xae,0x10,0xaa,0xaa,0xd3,0x4f,0x0f}, //25
{0x3b,0x9a,0x24,0xc6,0x07,0x39,0x62,0xf8}, //26
{0x38,0x10,0xa6,0x13,0x1a,0xbe,0xb0,0x3a}, //27
{0xe4,0xfc,0x7c,0x9a,0x46,0x18,0x3e,0xbc}, //28
{0xb2,0x79,0x2f,0x14,0x20,0x4e,0x40,0x1a}, //29
{0xb2,0x25,0xa6,0xcc,0x1c,0x9a,0xcb,0x88}, //30
{0x31,0xa4,0x88,0xbc,0x0f,0xc5,0x7a,0x81}, //31
{0x5d,0x0e,0x9d,0x40,0xb7,0xe5,0x85,0xda} //32
};
int t;
unsigned char challenge<256>;
memcpy(challenge,_challenge,128);
challenge<128>=1; //the last block is actually 7 bytes,
//so we add the standard one-byte CBC pad.
apply_iv(challenge+1,iv-1>,8);
rc2_keyschedule(xkey, key-1>,16,128);
for(t=0;t<120;t=t+8)
{
rc2_encrypt(xkey, challenge+1+t, response+t);
apply_iv(challenge+1+t+8,response+t,8);
}
rc2_encrypt(xkey, challenge+1+t, response+t);
return;
}
void apply_iv(unsigned char *block, unsigned char *ivdata, int blocksize)
{
int t;
for(t=0;t<blocksize;t++)
block=block^ivdata;
}
int LoadKey(unsigned char *challengekey)
{
FILE *in;
unsigned int sline,cline,val,t;
unsigned char tmp_challenge_key<128>;
unsigned char line<130>;
unsigned char sval<3>;
int fudge;
in=fopen("cronuskeys.txt","r");
if(in==NULL)
{
fprintf(stderr,"Couldn't open cronuskeys.txt\n");
return(FALSE);
}
fprintf(stderr,"Opened cronuskeys.txt\n");
cline=0;
while(fgets(line,127,in)!=NULL)
{
if(line==0x0a)
line=0;
if(cline<4)
{
if(line<0>!='C')
{
continue;
}
if(line<1>==' ')
fudge=1;
else
fudge=0;
for(t=0;t<32;t++)
{
sval<0>=line<1+fudge+(t*2)>;
sval<1>=line<2+fudge+(t*2)>;
sval<2>=0;
val=strtoul(sval,NULL,16);
tmp_challenge_key=val;
}
cline++;
}
if(cline==4)
{
sline=0;cline=0;
memcpy(challengekey,tmp_challenge_key,128);
fclose(in);
return(TRUE);
}
}
fclose(in);
return(FALSE);
}
/**********************************************************************\
* To commemorate the 1996 RSA Data Security Conference, the following *
* code is released into the public domain by its author. Prost! *
* *
* This cipher uses 16-bit words and little-endian byte ordering. *
* I wonder which processor it was optimized for? *
* *
* Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
* the public. *
\**********************************************************************/
/**********************************************************************\
* Expand a variable-length user key (between 1 and 128 bytes) to a *
* 64-short working rc2 key, of at most "bits" effective key bits. *
* The effective key bits parameter looks like an export control hack. *
* For normal use, it should always be set to 1024. For convenience, *
* zero is accepted as an alias for 1024. *
\**********************************************************************/
void rc2_keyschedule( unsigned short xkey<64>, const unsigned char *key, unsigned len, unsigned bits )
{
unsigned char x;
unsigned i;
/* 256-entry permutation table, probably derived somehow from pi */
static const unsigned char permute<256> = {
217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
};
assert(len > 0 && len <= 128);
assert(bits <= 1024);
if (!bits)
bits = 1024;
memcpy(xkey, key, len);
/* Phase 1: Expand input key to 128 bytes */
if (len < 128) {
i = 0;
x = ((unsigned char *)xkey);
do {
x = permute<(x + ((unsigned char *)xkey)) & 255>;
((unsigned char *)xkey) = x;
} while (len < 128);
}
/* Phase 2 - reduce effective key size to "bits" */
len = (bits+7) >> 3;
i = 128-len;
x = permute<((unsigned char *)xkey) & (255 >> (7 & -bits))>;
((unsigned char *)xkey) = x;
while (i--) {
x = permute< x ^ ((unsigned char *)xkey) >;
((unsigned char *)xkey) = x;
}
/* Phase 3 - copy to xkey in little-endian order */
i = 63;
do {
xkey = ((unsigned char *)xkey)<2*i> +
(((unsigned char *)xkey)<2*i+1> << 8);
} while (i--);
}
/**********************************************************************\
* Encrypt an 8-byte block of plaintext using the given key. *
\**********************************************************************/
void rc2_encrypt( const unsigned short xkey<64>, const unsigned char *plain, unsigned char *cipher )
{
unsigned x76, x54, x32, x10, i;
x76 = (plain<7> << 8) + plain<6>;
x54 = (plain<5> << 8) + plain<4>;
x32 = (plain<3> << 8) + plain<2>;
x10 = (plain<1> << 8) + plain<0>;
for (i = 0; i < 16; i++) {
x10 += (x32 & ~x76) + (x54 & x76) + xkey<4*i+0>;
x10 = (x10 << 1) + (x10 >> 15 & 1);
x32 += (x54 & ~x10) + (x76 & x10) + xkey<4*i+1>;
x32 = (x32 << 2) + (x32 >> 14 & 3);
x54 += (x76 & ~x32) + (x10 & x32) + xkey<4*i+2>;
x54 = (x54 << 3) + (x54 >> 13 & 7);
x76 += (x10 & ~x54) + (x32 & x54) + xkey<4*i+3>;
x76 = (x76 << 5) + (x76 >> 11 & 31);
if (i == 4 || i == 10) {
x10 += xkey;
x32 += xkey;
x54 += xkey;
x76 += xkey;
}
}
cipher<0> = (unsigned char)x10;
cipher<1> = (unsigned char)(x10 >> 8);
cipher<2> = (unsigned char)x32;
cipher<3> = (unsigned char)(x32 >> 8);
cipher<4> = (unsigned char)x54;
cipher<5> = (unsigned char)(x54 >> 8);
cipher<6> = (unsigned char)x76;
cipher<7> = (unsigned char)(x76 >> 8);
}
/**********************************************************************\
* Decrypt an 8-byte block of ciphertext using the given key. *
\**********************************************************************/
void rc2_decrypt( const unsigned short xkey<64>, unsigned char *plain, const unsigned char *cipher )
{
unsigned x76, x54, x32, x10, i;
x76 = (cipher<7> << 8) + cipher<6>;
x54 = (cipher<5> << 8) + cipher<4>;
x32 = (cipher<3> << 8) + cipher<2>;
x10 = (cipher<1> << 8) + cipher<0>;
i = 15;
do {
x76 &= 65535;
x76 = (x76 << 11) + (x76 >> 5);
x76 -= (x10 & ~x54) + (x32 & x54) + xkey<4*i+3>;
x54 &= 65535;
x54 = (x54 << 13) + (x54 >> 3);
x54 -= (x76 & ~x32) + (x10 & x32) + xkey<4*i+2>;
x32 &= 65535;
x32 = (x32 << 14) + (x32 >> 2);
x32 -= (x54 & ~x10) + (x76 & x10) + xkey<4*i+1>;
x10 &= 65535;
x10 = (x10 << 15) + (x10 >> 1);
x10 -= (x32 & ~x76) + (x54 & x76) + xkey<4*i+0>;
if (i == 5 || i == 11) {
x76 -= xkey;
x54 -= xkey;
x32 -= xkey;
x10 -= xkey;
}
} while (i--);
plain<0> = (unsigned char)x10;
plain<1> = (unsigned char)(x10 >> 8);
plain<2> = (unsigned char)x32;
plain<3> = (unsigned char)(x32 >> 8);
plain<4> = (unsigned char)x54;
plain<5> = (unsigned char)(x54 >> 8);
plain<6> = (unsigned char)x76;
plain<7> = (unsigned char)(x76 >> 8);
}
That is where the actual conversion of challenge-to-response takes place, and if you compare it to the code in the original Firedecrypt, you`ll see that its very different.
Here is the fixed version (unless im wrong or missing something else, which i probably am)
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#ifndef FALSE
#define FALSE (1==0)
#endif
#ifndef TRUE
#define TRUE (0==0)
#endif
#define CRONVERSION "v1.3"
unsigned short xkey[64];
void rc2_keyschedule(unsigned short xkey[64], const unsigned char *key, unsigned len, unsigned bits);
void rc2_encrypt(const unsigned short xkey[64], const unsigned char *plain, unsigned char *cipher );
void rc2_decrypt(const unsigned short xkey[64], unsigned char *plain, const unsigned char *cipher );
void apply_iv(unsigned char *block, unsigned char *ivdata, int blocksize);
void encrypt(char *challenge, char *response);
int LoadKey(unsigned char *challenge);
int main(int argc, char** argv) {
unsigned char inbuf[256];
unsigned char outbuf[256];
FILE *outfile;
char *outname[32]= {"unknownkeys.txt", "pv2keys.txt", "saturnkeys.txt", "saturnkeys.txt", "m510keys.txt", "unknownkeys.txt", "pv2keys.txt", "saturnkeys.txt", "saturnkeys.txt", "m510keys.txt", "unknownkeys.txt", "unknownkeys.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt", "firedecrypt.txt"};
int s,t;
fprintf(stderr,"firedecryptKey %s\n",CRONVERSION);
if(LoadKey(inbuf)==FALSE)
{
fprintf(stderr,"Error: couldn't load key. Exiting.\n");
exit(1);
}
memset(outbuf,0,256);
if((inbuf[0]<1) || (inbuf[0]>32))
{
fprintf(stderr,"the challenge isn't one of the known types(1-32). exiting.\n\n");
#ifdef WIN32
system("pause");
#endif
exit(1);
}
encrypt(inbuf,outbuf);
printf("\n");
outfile=fopen(outname[inbuf[0]-1],"a");
printf("S firedecryptKey\n");
if(outfile!=NULL)
fprintf(outfile,"S firedecryptKey\n");
for(t=0;t<4;t++)
{
printf("C ");
if(outfile!=NULL)
fprintf(outfile,"C ");
for(s=0;s<32;s++)
{
printf("%02x",inbuf[(t*32)+s]);
if(outfile!=NULL)
fprintf(outfile,"%02x",inbuf[(t*32)+s]);
}
printf("\n");
if(outfile!=NULL)
fprintf(outfile,"\n");
}
for(t=0;t<4;t++)
{
printf("R ");
if(outfile!=NULL)
fprintf(outfile,"R ");
for(s=0;s<32;s++)
{
printf("%02x",outbuf[(t*32)+s]);
if(outfile!=NULL)
fprintf(outfile,"%02x",outbuf[(t*32)+s]);
}
printf("\n");
if(outfile!=NULL)
fprintf(outfile,"\n");
}
printf("\n");
if(outfile!=NULL)
{
fprintf(outfile,"\n");
fclose(outfile);
printf("\nThis information has been stored for you in: %s\n", outname[inbuf[0]-1]);
}
#ifdef WIN32
system("pause");
#endif
}
void encrypt(char *_challenge, char *response)
{
unsigned char key[32][16] = {
{0x97,0x9B,0xFD,0xEA,0x2E,0x81,0x56,0x24,0x08,0xD6,0x74,0xEC,0x6B,0xBE,0xCE,0xB7}, //01
{0x06,0x18,0x6e,0xe3,0x2a,0x8b,0x7d,0x03,0x40,0x74,0xd6,0x09,0x4a,0x44,0xd1,0x21}, //02
{0xd0,0xa4,0x24,0x46,0x3d,0xd4,0xb9,0x45,0x8b,0x01,0x46,0x4c,0x19,0x2c,0xf3,0x58}, //03
{0x81,0xbc,0x56,0x18,0x4e,0xc5,0x2d,0xb2,0x63,0x06,0x10,0x5c,0x4e,0x41,0xda,0x42}, //04
{0xde,0x71,0xe6,0x63,0xe9,0xb6,0x2d,0x4e,0x8f,0x88,0x03,0x94,0xbf,0x55,0x6d,0x48}, //05
{0xb0,0x82,0xe8,0x2d,0xb8,0x88,0x36,0xcc,0x26,0xbc,0x34,0x23,0x0e,0x8b,0x9a,0xba}, //06
{0x74,0x26,0x3f,0x34,0x28,0xa1,0x94,0xfe,0xea,0x02,0xc3,0x0b,0xd4,0xce,0x1b,0x78}, //07
{0x48,0x9c,0x64,0xdc,0x8c,0xb2,0xa4,0x41,0x08,0x16,0xe4,0x7d,0x32,0x92,0x2d,0x5d}, //08
{0x8a,0xd5,0xb2,0xb8,0x2a,0x0c,0x36,0x06,0xd4,0x1d,0x5f,0x0e,0x18,0x3f,0xe7,0xca}, //09
{0x79,0x62,0xa4,0x59,0x64,0xa0,0xbf,0x8d,0xac,0x73,0x24,0x0f,0x45,0x74,0x72,0x71}, //10
{0x06,0x46,0x61,0x57,0x53,0xf7,0x63,0x43,0xa6,0xb8,0xbc,0x91,0xb2,0x88,0xfe,0x32}, //11
{0x0a,0x58,0x9d,0x5c,0x2e,0x94,0x66,0xcf,0x2c,0x05,0x7e,0x39,0x66,0xc4,0x54,0x27}, //12
{0xf4,0xdd,0x85,0xcf,0xce,0x1e,0xe2,0xd1,0x31,0x71,0x65,0x09,0x38,0xab,0xd2,0xb7}, //13
{0x43,0xf3,0x06,0x77,0x62,0x51,0xe8,0x2a,0x80,0xbc,0x47,0xc0,0x48,0xcb,0x2f,0xd2}, //14
{0x1b,0x34,0xc2,0xe1,0x41,0x30,0xcc,0x3c,0x84,0x2d,0xa1,0x61,0x92,0xd3,0xc8,0xa1}, //15
{0x46,0x74,0xed,0x39,0x70,0xd8,0xf3,0xb8,0xd3,0x31,0x86,0xa8,0xb9,0xa1,0x64,0x9a}, //16
{0x5c,0x6b,0xbb,0x1b,0xa7,0x68,0x43,0x43,0xa3,0xe8,0x41,0x9b,0x5f,0x31,0x86,0x67}, //17
{0x12,0x5a,0x4e,0x66,0x4c,0x1d,0xf3,0xe6,0x6d,0xd7,0xb4,0x10,0xd3,0xe6,0xc9,0xda}, //18
{0x10,0x3b,0x62,0xf0,0x9e,0x6e,0x93,0x36,0x9d,0x06,0xc9,0x05,0xa8,0x1c,0x7c,0x5c}, //19
{0x02,0xf7,0x52,0xc2,0xab,0x3a,0xd4,0x6f,0xa3,0x69,0x5a,0xd9,0x67,0xb9,0x87,0x1d}, //20
{0x6c,0x9c,0x3a,0x8b,0x9a,0x32,0xe8,0x51,0x9e,0x5a,0xa0,0xfc,0x0d,0x07,0x37,0xce}, //21
{0xb3,0x84,0x71,0x25,0x13,0x45,0x3e,0x5a,0xfd,0xf5,0x65,0x83,0x66,0xa4,0x01,0x38}, //22
{0xdf,0x01,0x5d,0x34,0xb6,0xd1,0xec,0xeb,0xaa,0xd9,0xf1,0xfe,0x63,0xb1,0x75,0x39}, //23
{0x94,0x96,0x82,0x59,0xfa,0x3a,0x1d,0xb7,0x19,0x43,0x2f,0x02,0xdf,0x84,0xc2,0x2d}, //24
{0xbb,0x54,0x79,0x28,0xbe,0xfa,0xd3,0xa4,0xe5,0x39,0x9c,0x4e,0xcc,0x70,0x0a,0x62}, //25
{0x87,0x85,0xff,0x21,0xdf,0xf4,0xab,0xa4,0xe5,0xd5,0x5f,0x64,0x39,0x49,0x44,0x54}, //26
{0x41,0x97,0xf5,0xf4,0xc9,0xd6,0x26,0x80,0xa7,0x16,0x43,0xe6,0x57,0xa6,0x8c,0xf7}, //27
{0xa2,0x84,0x54,0x35,0xad,0xbc,0x66,0xc3,0xc9,0x15,0x8e,0xc7,0x8d,0x36,0x3e,0x90}, //28
{0x59,0x7a,0x6a,0x00,0x5d,0x66,0xea,0x5a,0x94,0x8b,0x77,0x3b,0x4c,0x02,0x1f,0x6e}, //29
{0x0a,0x5e,0xb1,0x02,0x49,0x18,0xa7,0xa7,0xda,0x3a,0xdf,0xab,0x77,0xe2,0x26,0xff}, //30
{0x1e,0x1e,0xb4,0x81,0xf6,0xd3,0x9e,0x96,0xb7,0x34,0x84,0xa8,0x73,0x9b,0x61,0xc7}, //31
{0x1c,0x0d,0x4d,0x81,0x4c,0xc5,0xd1,0x7e,0xd7,0xc8,0x09,0x3f,0x70,0x54,0x96,0xad} //32
};
unsigned char iv[32][8] =
{
{0xFE,0x2A,0x60,0xFD,0x10,0x38,0x1E,0x7F}, //01
{0x5D,0x18,0xFB,0x0C,0xAF,0x31,0xB7,0x02}, //02
{0x2D,0x48,0x77,0xDC,0x72,0xA6,0x8F,0xBC}, //03
{0xC6,0xDB,0x61,0xA5,0x61,0x13,0x03,0x07}, //04
{0x56,0xaf,0x19,0x31,0xec,0x8f,0x77,0x22}, //05
{0xc5,0xf2,0x71,0x4c,0xf1,0xa7,0x19,0x7b}, //06
{0xe4,0xb6,0xb0,0xb4,0x2b,0x1c,0x71,0xd5}, //07
{0xec,0x6d,0x98,0x43,0x76,0xdf,0xe0,0x13}, //08
{0x27,0x9a,0xb7,0x10,0x94,0xde,0x08,0x0d}, //09
{0x85,0x92,0xc6,0xc5,0x3b,0x88,0xb7,0xcd}, //10
{0xbd,0x50,0xd7,0xdb,0xe8,0x9f,0x79,0x4e}, //11
{0xdb,0xb9,0xe8,0x95,0x5e,0x1a,0x47,0x1e}, //12
{0x96,0x30,0xfd,0xbf,0x27,0xbe,0x5e,0xce}, //13
{0x7e,0x29,0xf2,0x76,0xe4,0x53,0xbf,0x1b}, //14
{0xb1,0xa5,0xfe,0x76,0x5a,0x08,0xd6,0x4e}, //15
{0x01,0x73,0xb1,0xb0,0x8e,0xb8,0xbe,0x7d}, //16
{0xbe,0x3b,0x2b,0x57,0x1a,0xa1,0xb2,0xfa}, //17
{0x2a,0xc8,0xc1,0xc9,0x5b,0xd7,0xda,0x27}, //18
{0xd3,0x41,0x41,0xa2,0x94,0x93,0xdc,0x90}, //19
{0x71,0x93,0xc6,0x95,0x24,0xb9,0xe3,0x6f}, //20
{0x77,0x70,0x26,0x8a,0x51,0xbf,0xa9,0xb2}, //21
{0x89,0x9a,0xd0,0xde,0x67,0x24,0x82,0x23}, //22
{0x2f,0x7d,0xb7,0xa4,0xa5,0xca,0x73,0x4c}, //23
{0x30,0xd2,0x2b,0x33,0x2b,0xa4,0x0d,0x74}, //24
{0x98,0xae,0x10,0xaa,0xaa,0xd3,0x4f,0x0f}, //25
{0x3b,0x9a,0x24,0xc6,0x07,0x39,0x62,0xf8}, //26
{0x38,0x10,0xa6,0x13,0x1a,0xbe,0xb0,0x3a}, //27
{0xe4,0xfc,0x7c,0x9a,0x46,0x18,0x3e,0xbc}, //28
{0xb2,0x79,0x2f,0x14,0x20,0x4e,0x40,0x1a}, //29
{0xb2,0x25,0xa6,0xcc,0x1c,0x9a,0xcb,0x88}, //30
{0x31,0xa4,0x88,0xbc,0x0f,0xc5,0x7a,0x81}, //31
{0x5d,0x0e,0x9d,0x40,0xb7,0xe5,0x85,0xda} //32
};
int t;
unsigned char challenge[256];
memcpy(challenge,_challenge,128);
challenge[128]=1; //the last block is actually 7 bytes,
//so we add the standard one-byte CBC pad.
apply_iv(challenge+1,iv[challenge[0]-1],8);
rc2_keyschedule(xkey, key[challenge[0]-1],16,128);
for(t=0;t<120;t=t+8)
{
rc2_encrypt(xkey, challenge+1+t, response+t);
apply_iv(challenge+1+t+8,response+t,8);
}
rc2_encrypt(xkey, challenge+1+t, response+t);
return;
}
void apply_iv(unsigned char *block, unsigned char *ivdata, int blocksize)
{
int t;
for(t=0;t<blocksize;t++)
block[t]=block[t]^ivdata[t];
}
int LoadKey(unsigned char *challengekey)
{
FILE *in;
unsigned int sline,cline,val,t;
unsigned char tmp_challenge_key[128];
unsigned char line[130];
unsigned char sval[3];
int fudge;
in=fopen("cronuskeys.txt","r");
if(in==NULL)
{
fprintf(stderr,"Couldn't open cronuskeys.txt\n");
return(FALSE);
}
fprintf(stderr,"Opened cronuskeys.txt\n");
cline=0;
while(fgets(line,127,in)!=NULL)
{
if(line[strlen(line)-1]==0x0a)
line[strlen(line)-1]=0;
if(cline<4)
{
if(line[0]!='C')
{
continue;
}
if(line[1]==' ')
fudge=1;
else
fudge=0;
for(t=0;t<32;t++)
{
sval[0]=line[1+fudge+(t*2)];
sval[1]=line[2+fudge+(t*2)];
sval[2]=0;
val=strtoul(sval,NULL,16);
tmp_challenge_key[cline*32+t]=val;
}
cline++;
}
if(cline==4)
{
sline=0;cline=0;
memcpy(challengekey,tmp_challenge_key,128);
fclose(in);
return(TRUE);
}
}
fclose(in);
return(FALSE);
}
/**********************************************************************\
* To commemorate the 1996 RSA Data Security Conference, the following *
* code is released into the public domain by its author. Prost! *
* *
* This cipher uses 16-bit words and little-endian byte ordering. *
* I wonder which processor it was optimized for? *
* *
* Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
* the public. *
\**********************************************************************/
/**********************************************************************\
* Expand a variable-length user key (between 1 and 128 bytes) to a *
* 64-short working rc2 key, of at most "bits" effective key bits. *
* The effective key bits parameter looks like an export control hack. *
* For normal use, it should always be set to 1024. For convenience, *
* zero is accepted as an alias for 1024. *
\**********************************************************************/
void rc2_keyschedule( unsigned short xkey[64], const unsigned char *key, unsigned len, unsigned bits )
{
unsigned char x;
unsigned i;
/* 256-entry permutation table, probably derived somehow from pi */
static const unsigned char permute[256] = {
217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
};
assert(len > 0 && len <= 128);
assert(bits <= 1024);
if (!bits)
bits = 1024;
memcpy(xkey, key, len);
/* Phase 1: Expand input key to 128 bytes */
if (len < 128) {
i = 0;
x = ((unsigned char *)xkey)[len-1];
do {
x = permute[(x + ((unsigned char *)xkey)[i++]) & 255];
((unsigned char *)xkey)[len++] = x;
} while (len < 128);
}
/* Phase 2 - reduce effective key size to "bits" */
len = (bits+7) >> 3;
i = 128-len;
x = permute[((unsigned char *)xkey)[i] & (255 >> (7 & -bits))];
((unsigned char *)xkey)[i] = x;
while (i--) {
x = permute[ x ^ ((unsigned char *)xkey)[i+len] ];
((unsigned char *)xkey)[i] = x;
}
/* Phase 3 - copy to xkey in little-endian order */
i = 63;
do {
xkey[i] = ((unsigned char *)xkey)[2*i] +
(((unsigned char *)xkey)[2*i+1] << 8);
} while (i--);
}
/**********************************************************************\
* Encrypt an 8-byte block of plaintext using the given key. *
\**********************************************************************/
void rc2_encrypt( const unsigned short xkey[64], const unsigned char *plain, unsigned char *cipher )
{
unsigned x76, x54, x32, x10, i;
x76 = (plain[7] << 8) + plain[6];
x54 = (plain[5] << 8) + plain[4];
x32 = (plain[3] << 8) + plain[2];
x10 = (plain[1] << 8) + plain[0];
for (i = 0; i < 16; i++) {
x10 += (x32 & ~x76) + (x54 & x76) + xkey[4*i+0];
x10 = (x10 << 1) + (x10 >> 15 & 1);
x32 += (x54 & ~x10) + (x76 & x10) + xkey[4*i+1];
x32 = (x32 << 2) + (x32 >> 14 & 3);
x54 += (x76 & ~x32) + (x10 & x32) + xkey[4*i+2];
x54 = (x54 << 3) + (x54 >> 13 & 7);
x76 += (x10 & ~x54) + (x32 & x54) + xkey[4*i+3];
x76 = (x76 << 5) + (x76 >> 11 & 31);
if (i == 4 || i == 10) {
x10 += xkey[x76 & 63];
x32 += xkey[x10 & 63];
x54 += xkey[x32 & 63];
x76 += xkey[x54 & 63];
}
}
cipher[0] = (unsigned char)x10;
cipher[1] = (unsigned char)(x10 >> 8);
cipher[2] = (unsigned char)x32;
cipher[3] = (unsigned char)(x32 >> 8);
cipher[4] = (unsigned char)x54;
cipher[5] = (unsigned char)(x54 >> 8);
cipher[6] = (unsigned char)x76;
cipher[7] = (unsigned char)(x76 >> 8);
}
/**********************************************************************\
* Decrypt an 8-byte block of ciphertext using the given key. *
\**********************************************************************/
void rc2_decrypt( const unsigned short xkey[64], unsigned char *plain, const unsigned char *cipher )
{
unsigned x76, x54, x32, x10, i;
x76 = (cipher[7] << 8) + cipher[6];
x54 = (cipher[5] << 8) + cipher[4];
x32 = (cipher[3] << 8) + cipher[2];
x10 = (cipher[1] << 8) + cipher[0];
i = 15;
do {
x76 &= 65535;
x76 = (x76 << 11) + (x76 >> 5);
x76 -= (x10 & ~x54) + (x32 & x54) + xkey[4*i+3];
x54 &= 65535;
x54 = (x54 << 13) + (x54 >> 3);
x54 -= (x76 & ~x32) + (x10 & x32) + xkey[4*i+2];
x32 &= 65535;
x32 = (x32 << 14) + (x32 >> 2);
x32 -= (x54 & ~x10) + (x76 & x10) + xkey[4*i+1];
x10 &= 65535;
x10 = (x10 << 15) + (x10 >> 1);
x10 -= (x32 & ~x76) + (x54 & x76) + xkey[4*i+0];
if (i == 5 || i == 11) {
x76 -= xkey[x54 & 63];
x54 -= xkey[x32 & 63];
x32 -= xkey[x10 & 63];
x10 -= xkey[x76 & 63];
}
} while (i--);
plain[0] = (unsigned char)x10;
plain[1] = (unsigned char)(x10 >> 8);
plain[2] = (unsigned char)x32;
plain[3] = (unsigned char)(x32 >> 8);
plain[4] = (unsigned char)x54;
plain[5] = (unsigned char)(x54 >> 8);
plain[6] = (unsigned char)x76;
plain[7] = (unsigned char)(x76 >> 8);
}
Hope that works!
And if you think you can make a GUI for it, that`d be great.