diff --git a/Buffer.c b/Buffer.c new file mode 100644 index 0000000..769ac8a --- /dev/null +++ b/Buffer.c @@ -0,0 +1,51 @@ +#include "Buffer.h" + +#include +#include +#include +#include + +void Read( struct buffer *buf, size_t length, void *destination ) +{ + assert( buf->next + length < buf->start + buf->length ); + memcpy( destination, buf->next, length ); + buf->next += length; +} + +uint32_t Read32( struct buffer *buf ) +{ + uint32_t result; + Read( buf, sizeof result, &result ); + return CFSwapInt32BigToHost( result ); +} + +uint16_t Read16( struct buffer *buf ) +{ + uint16_t result; + Read( buf, sizeof result, &result ); + return CFSwapInt16BigToHost( result ); +} + +bool OpenFile( struct buffer *buf, const char *fn ) +{ + buf->fd = open( fn, O_RDONLY ); + if (buf->fd < 0) return false; + + struct stat stat; + if (fstat( buf->fd, &stat ) < 0) { + close( buf->fd ); + return false; + } + + buf->length = stat.st_size; + + buf->start = mmap( NULL, buf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, buf->fd, 0 ); + if (!buf->start) { + close( buf->fd ); + return false; + } + + buf->next = buf->start; + + return true; +} \ No newline at end of file diff --git a/Buffer.h b/Buffer.h new file mode 100644 index 0000000..f79f522 --- /dev/null +++ b/Buffer.h @@ -0,0 +1,21 @@ +#ifndef _Buffer_h_included_ +#define _Buffer_h_included_ + +#include +#include +#include + +struct buffer { + uint8_t *start; + size_t length; + uint8_t *next; + int fd; +}; + +void Read( struct buffer *buf, size_t length, void *destination ); +uint32_t Read32( struct buffer *buf ); +uint16_t Read16( struct buffer *buf ); + +bool OpenFile( struct buffer *buf, const char *fn ); + +#endif diff --git a/Common.h b/Common.h new file mode 100644 index 0000000..dad80fd --- /dev/null +++ b/Common.h @@ -0,0 +1,26 @@ +#ifndef _Common_h_included_ +#define _Common_h_included_ + +#include + +struct header +{ + char magic[4]; // magic bytes \x43 \x46 \x47 \x31 (CFG1) + uint32_t payload_size; // length of ciphertext = length of padded plaintext (big endian) + char header_md5[8]; // first 8 bytes of MD5 computed over header (assuming the 8 bytes of "header_md5" are \x00) + char etl[7]; // blank electronic label (etl), always "000000" (null-terminated char array) + char unused1; // not used at the moment + uint16_t password_len; // length of the password used in AES encryption (big endian) + uint16_t padding_len; // number of padding bytes added to plaintext (big endian) + char unused2[4]; // not used at the moment + char plaintext_md5[16]; // MD5 hash of the plaintext +}; + +static const char aes_key[32] = { + 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif diff --git a/Decrypt.c b/Decrypt.c index 38578f1..1cba71d 100644 --- a/Decrypt.c +++ b/Decrypt.c @@ -2,59 +2,12 @@ * Code is under the MIT license, see the LICENSE file. */ +#include "Common.h" +#include "Buffer.h" + #include #include -#include -#include -struct header -{ - char magic[4]; // magic bytes \x43 \x46 \x47 \x31 (CFG1) - uint32_t payload_size; // length of ciphertext = length of padded plaintext (big endian) - char header_md5[8]; // first 8 bytes of MD5 computed over header (assuming the 8 bytes of "header_md5" are \x00) - char etl[7]; // blank electronic label (etl), always "000000" (null-terminated char array) - char unused1; // not used at the moment - uint16_t password_len; // length of the password used in AES encryption (big endian) - uint16_t padding_len; // number of padding bytes added to plaintext (big endian) - char unused2[4]; // not used at the moment - char plaintext_md5[16]; // MD5 hash of the plaintext -}; - -static const char aes_key[32] = { - 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - - -struct buffer { - uint8_t *start; - size_t length; - uint8_t *next; - int fd; -}; - -void Read( struct buffer *buf, size_t length, void *destination ) -{ - assert( buf->next + length < buf->start + buf->length ); - memcpy( destination, buf->next, length ); - buf->next += length; -} - -uint32_t Read32( struct buffer *buf ) -{ - uint32_t result; - Read( buf, sizeof result, &result ); - return CFSwapInt32BigToHost( result ); -} - -uint16_t Read16( struct buffer *buf ) -{ - uint16_t result; - Read( buf, sizeof result, &result ); - return CFSwapInt16BigToHost( result ); -} void ReadHeader( struct buffer *buf, struct header *header ) { @@ -69,30 +22,6 @@ void ReadHeader( struct buffer *buf, struct header *header ) Read( buf, 16, header->plaintext_md5 ); } -bool OpenFile( struct buffer *buf, const char *fn ) -{ - buf->fd = open( fn, O_RDONLY ); - if (buf->fd < 0) return false; - - struct stat stat; - if (fstat( buf->fd, &stat ) < 0) { - close( buf->fd ); - return false; - } - - buf->length = stat.st_size; - - buf->start = mmap( NULL, buf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, buf->fd, 0 ); - if (!buf->start) { - close( buf->fd ); - return false; - } - - buf->next = buf->start; - - return true; -} - int main( int argc, const char *argv[] ) { if (argc != 3) { diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..57fa380 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +all: Decrypt + +Decrypt: Decrypt.o Buffer.o + clang -o $@ Decrypt.o Buffer.o + +Decrypt.o: Decrypt.c Buffer.h Common.h +Buffer.o: Buffer.c Buffer.h + +.c.o: + clang -c -o $@ $< + diff --git a/README.md b/README.md index 762c852..c10ddd4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Thanks to [hph][1] for reverse engineering the details of that config format. ## Compile: - clang Decrypt.c -o Decrypt + make ## Run: