Implement encrypting.
This commit is contained in:
parent
f53b189d6c
commit
5d0b4bd0e5
4 changed files with 124 additions and 5 deletions
27
Buffer.c
27
Buffer.c
|
@ -48,4 +48,29 @@ bool OpenFile( struct buffer *buf, const char *fn )
|
|||
buf->next = buf->start;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenBuffer( struct buffer *buf, void *data, size_t length )
|
||||
{
|
||||
buf->start = buf->next = data;
|
||||
buf->length = length;
|
||||
buf->fd = -1;
|
||||
}
|
||||
|
||||
void Write( struct buffer *buf, const void *data, size_t length )
|
||||
{
|
||||
memcpy(buf->next, data, length);
|
||||
buf->next += length;
|
||||
}
|
||||
|
||||
void Write32( struct buffer *buf, uint32_t value )
|
||||
{
|
||||
uint32_t write = CFSwapInt32HostToBig(value);
|
||||
Write(buf, &write, sizeof write);
|
||||
}
|
||||
|
||||
void Write16( struct buffer *buf, uint16_t value )
|
||||
{
|
||||
uint16_t write = CFSwapInt16HostToBig(value);
|
||||
Write(buf, &write, sizeof write);
|
||||
}
|
||||
|
|
6
Buffer.h
6
Buffer.h
|
@ -16,6 +16,12 @@ void Read( struct buffer *buf, size_t length, void *destination );
|
|||
uint32_t Read32( struct buffer *buf );
|
||||
uint16_t Read16( struct buffer *buf );
|
||||
|
||||
void Write( struct buffer *buf, const void *data, size_t length );
|
||||
void Write32( struct buffer *buf, uint32_t value );
|
||||
void Write16( struct buffer *buf, uint16_t value );
|
||||
|
||||
void OpenBuffer( struct buffer *buf, void *data, size_t length );
|
||||
|
||||
bool OpenFile( struct buffer *buf, const char *fn );
|
||||
|
||||
#endif
|
||||
|
|
12
Common.h
12
Common.h
|
@ -7,13 +7,13 @@ 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)
|
||||
uint8_t 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
|
||||
uint8_t 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
|
||||
uint8_t unused2[4]; // not used at the moment
|
||||
uint8_t plaintext_md5[16]; // MD5 hash of the plaintext
|
||||
};
|
||||
|
||||
static const char aes_key[32] = {
|
||||
|
@ -23,4 +23,8 @@ static const char aes_key[32] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
enum {
|
||||
HeaderSize = 48
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
84
Encrypt.c
84
Encrypt.c
|
@ -2,6 +2,8 @@
|
|||
#include "Common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <CommonCrypto/CommonCrypto.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
int main( int argc, const char *argv[] )
|
||||
{
|
||||
|
@ -10,5 +12,87 @@ int main( int argc, const char *argv[] )
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct buffer inputFile = { 0 };
|
||||
if (!OpenFile(&inputFile, argv[1])) {
|
||||
fprintf(stderr, "Cannot open input file %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct header header = { 0 };
|
||||
|
||||
memcpy(header.magic, "CFG1", sizeof header.magic);
|
||||
strcpy(header.etl, "000000");
|
||||
|
||||
CC_MD5_CTX context;
|
||||
CC_MD5_Init(&context);
|
||||
|
||||
// Hash input data.
|
||||
CC_MD5_Update(&context,inputFile.start, inputFile.length);
|
||||
|
||||
// Add PKCS7 padding data to hash. Decoder calculates hash over padded data.
|
||||
uint8_t pad = kCCBlockSizeAES128 - (inputFile.length % kCCBlockSizeAES128);
|
||||
for (uint8_t i = 0; i < pad; i++) {
|
||||
CC_MD5_Update(&context,&pad, sizeof pad);
|
||||
}
|
||||
|
||||
// Finalize hash and store in header.
|
||||
CC_MD5_Final(header.plaintext_md5, &context);
|
||||
|
||||
size_t encryptedBufferSize = inputFile.length + kCCBlockSizeAES128;
|
||||
void *encryptedBuffer = malloc(encryptedBufferSize);
|
||||
if (!encryptedBuffer) {
|
||||
fprintf(stderr, "Not enough memory to encrypt file\n");
|
||||
return 1;
|
||||
}
|
||||
size_t encryptedDataLength = 0;
|
||||
|
||||
CCCryptorStatus status = CCCrypt(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding|kCCOptionECBMode,
|
||||
aes_key, sizeof aes_key,
|
||||
NULL,
|
||||
inputFile.start, inputFile.length,
|
||||
encryptedBuffer, encryptedBufferSize, &encryptedDataLength);
|
||||
|
||||
if (status != kCCSuccess) {
|
||||
fprintf(stderr, "Error encrypting (%d)\n", status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
header.payload_size = encryptedDataLength;
|
||||
header.padding_len = encryptedDataLength - inputFile.length;
|
||||
|
||||
uint8_t headerData[HeaderSize] = {0};
|
||||
struct buffer headerBuf = {0};
|
||||
OpenBuffer(&headerBuf, headerData, sizeof headerData);
|
||||
|
||||
Write(&headerBuf, header.magic, sizeof header.magic);
|
||||
Write32(&headerBuf, header.payload_size);
|
||||
headerBuf.next += sizeof header.header_md5; // Skip header_md5
|
||||
Write(&headerBuf, header.etl, sizeof header.etl);
|
||||
Write(&headerBuf, &header.unused1, sizeof header.unused1);
|
||||
Write16(&headerBuf, header.password_len);
|
||||
Write16(&headerBuf, header.padding_len);
|
||||
Write(&headerBuf, header.unused2, sizeof header.unused2);
|
||||
Write(&headerBuf, header.plaintext_md5, sizeof header.plaintext_md5);
|
||||
|
||||
uint8_t header_md5[CC_MD5_DIGEST_LENGTH];
|
||||
CC_MD5(headerData, sizeof headerData, header_md5);
|
||||
memcpy(&headerData[8], header_md5, sizeof header.header_md5);
|
||||
|
||||
int fdout = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0600 );
|
||||
if (fdout < 0) {
|
||||
fprintf( stderr, "Error: cannot write output file\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool written = write(fdout, headerData, sizeof headerData) == sizeof headerData;
|
||||
written = written && write(fdout, encryptedBuffer, encryptedDataLength) == encryptedDataLength;
|
||||
|
||||
if (!written) {
|
||||
fprintf(stderr, "Cannot write output file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(fdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue