Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
compal-decrypt.c
/*
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 <carlo@youcontent.nl>
*/
#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
You can’t perform that action at this time.