Last active
July 3, 2023 23:02
-
-
Save danielkucera/fa9df248f6e0ea5dc2908743360d5cb7 to your computer and use it in GitHub Desktop.
compal-decrypt.c
This file contains 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 <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
Thanks for your work.
Is it possible to make an encryption program using this method?
I'm interested in putting a non-encrypted private key from a different modem to this one.