-
-
Save EsEnZeT/ea81bd79d0df0929f1ff6e7d33b767de to your computer and use it in GitHub Desktop.
compal-decrypt.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Program for decrypting Compal CH7465LG private key | |
Compilation: | |
gcc -o compal-decrypt compal-decrypt.c -lcrypto | |
Running: | |
./compal-decrypt | |
usage: ./compal-decrypt <infile> <outfile> | |
Author: Carlo Meijer <[email protected]> | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/stat.h> | |
#include <string.h> | |
#include <openssl/des.h> | |
static unsigned char g_abKey[] = { | |
0xBE, 0x26, 0x01, 0xC4, 0x52, 0x76, 0x84, 0x4C, 0x9C, 0xDE, | |
0x13, 0x4D, 0xE7, 0x60, 0x2B, 0xD1, 0xDC, 0xA3, 0xAB, 0x87, | |
0x9A | |
}; | |
int sprinkle(unsigned char *a1, unsigned char *a2) // straight from IDA decompiler | |
{ | |
int result; // r0 | |
signed int v3; // r3 | |
int v4; // r2 | |
*a2 = *a1 & 0xFE; | |
a2[1] = (*a1 << 7) + ((a1[1] >> 1) & 0x7E); | |
a2[2] = (a1[1] << 6) + ((a1[2] >> 2) & 0x3E); | |
a2[3] = 0x20 * a1[2] + ((a1[3] >> 3) & 0x1E); | |
a2[4] = 0x10 * a1[3] + ((a1[4] >> 4) & 0xE); | |
a2[5] = 8 * a1[4] + ((a1[5] >> 5) & 6); | |
a2[6] = 4 * a1[5] + ((a1[6] >> 6) & 2); | |
a2[7] = 2 * a1[6]; | |
result = 0; | |
do | |
{ | |
v3 = 1; | |
v4 = (unsigned char)(a2[result] ^ 1); | |
for ( a2[result] = v4; ; v4 = (unsigned char)a2[result] ) | |
{ | |
if ( (v4 >> v3) & 1 ) | |
a2[result] = v4 ^ 1; | |
if ( ++v3 == 8 ) | |
break; | |
} | |
++result; | |
} | |
while ( result != 8 ); | |
return result; | |
} | |
void des3ABC_CBC_decrypt( | |
unsigned char *lpKey1, | |
unsigned char *lpKey2, | |
unsigned char *lpKey3, | |
unsigned char *lpIv, | |
unsigned char *lpInput, | |
unsigned int dwLength, | |
unsigned char *lpOutput | |
) { | |
int v12; // r7 | |
int v13; // r2 | |
int v14; // r2 | |
unsigned char abKey1[8]; // [sp+8h] [bp-40h] | |
unsigned char abKey2[8]; // [sp+10h] [bp-38h] | |
unsigned char abKey3[8]; // [sp+18h] [bp-30h] | |
char v18[40]; // [sp+20h] [bp-28h] | |
DES_key_schedule stKey1, stKey2, stKey3; | |
sprinkle(lpKey1, abKey1); | |
sprinkle(lpKey2, abKey2); | |
sprinkle(lpKey3, abKey3); | |
DES_set_key((DES_cblock *)abKey1, &stKey1); | |
DES_set_key((DES_cblock *)abKey2, &stKey2); | |
DES_set_key((DES_cblock *)abKey3, &stKey3); | |
if ( (dwLength + 7) >> 3 ) | |
{ | |
v12 = 0; | |
do | |
{ | |
DES_ecb3_encrypt((const_DES_cblock *)lpInput, (DES_cblock *)v18, &stKey1, &stKey2, &stKey3, DES_DECRYPT); | |
v13 = 0; | |
if ( v12 ) | |
{ | |
do | |
{ | |
lpOutput[v13] = v18[v13] ^ lpInput[v13 - 8]; | |
++v13; | |
} | |
while ( v13 != 8 ); | |
} | |
else | |
{ | |
do | |
{ | |
lpOutput[v13] = v18[v13] ^ lpIv[v13]; | |
v14 = v13 + 1; | |
if ( v14 == 8 ) | |
break; | |
lpOutput[v14] = v18[v14] ^ lpIv[v14]; | |
v13 = v14 + 1; | |
} | |
while ( v13 != 8 ); | |
} | |
++v12; | |
lpInput += 8; | |
lpOutput += 8; | |
} | |
while ( (dwLength + 7) >> 3 != v12 ); | |
} | |
} | |
int main(int argc, char **argv) { | |
if(argc != 3) { | |
goto _usage; | |
} | |
struct stat stInfile; | |
FILE *hInfile, *hOutfile; | |
unsigned char *lpInput, *lpOutput; | |
unsigned char abIv[8]; | |
memset(abIv, 0, 8); | |
unsigned int dwLength, dwOutLength; | |
hInfile = fopen(argv[1], "rb"); | |
if (hInfile == NULL) { | |
perror(argv[1]); | |
return 1; | |
} | |
fstat(fileno(hInfile), &stInfile); | |
dwLength = stInfile.st_size; | |
lpInput = malloc((dwLength + 7) & ~7); | |
lpOutput = malloc((dwLength + 7) & ~7); | |
fread(lpInput, dwLength, 1, hInfile); | |
if (dwLength & 8) { | |
memset(lpInput + dwLength, 0, 8 - (dwLength & 8)); | |
} | |
des3ABC_CBC_decrypt(g_abKey, &g_abKey[7], &g_abKey[14], abIv, lpInput, dwLength, lpOutput); | |
if (lpOutput[20] != 0x30 || lpOutput[21] != 0x82) { | |
printf ("[-] invalid format\n"); | |
return 1; | |
} | |
dwOutLength = lpOutput[23] + 4 + (lpOutput[22] << 8); | |
hOutfile = fopen(argv[2], "wb"); | |
if (hOutfile == NULL) { | |
perror(argv[2]); | |
return 1; | |
} | |
fwrite(lpOutput + 20, dwOutLength, 1, hOutfile); | |
fclose(hInfile); | |
fclose(hOutfile); | |
free(lpInput); | |
free(lpOutput); | |
printf ("[+] success!\n"); | |
return 0; | |
_usage: | |
printf("usage: %s <infile> <outfile>\n", argv[0]); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment