I've got blowfish encryption and decryption working, except that after
the input data gets to around 1kB, it crashes when trying to decrypt
the last encrypted output.
here's the code (pardon/ignore the objective-c stuff)...
#define INBUFFERSIZE 1024
#define OUTBUFFERSIZE 1032
static const unsigned char key[] = { 24, 14, 254, 85,
66, 13, 19, 7,
234, 118, 11, 3,
8, 197, 16, 49 };
static const unsigned char iv[] = { 17, 25, 183, 23,
253, 13, 4, 16 };
@implementation BlackBox
+ (NSData *)encryptString:(NSString *)string
{
NSMutableData * data = nil;
if (string)
{
unsigned int inlength = [string
lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSData * indata = [NSData dataWithBytesNoCopy:(void *)[string
UTF8String] length:inlength freeWhenDone:NO];
if (indata)
{
NSInputStream * stream = [NSInputStream
inputStreamWithData:indata];
if (stream)
{
[stream open];
unsigned char inbuffer[INBUFFERSIZE];
unsigned char outbuffer[OUTBUFFERSIZE];
int outlength;
int tmplength;
int n;
EVP_CIPHER_CTX context;
EVP_CIPHER_CTX_init(&context);
EVP_EncryptInit_ex(&context, EVP_bf_cbc(),
NULL, key, iv);
data = [NSMutableData
dataWithCapacity:inlength*2];
if (data)
{
for (;;)
{
bzero(inbuffer, INBUFFERSIZE);
n = [stream read:inbuffer
maxLength:INBUFFERSIZE];
if ( n <= 0 )
{
break;
}
if ( EVP_EncryptUpdate(&context, outbuffer, &outlength, inbuffer,
n) != 1 )
{
return nil;
}
if ( EVP_EncryptFinal_ex(&context, outbuffer + outlength,
&tmplength) != 1 )
{
return nil;
}
outlength += tmplength;
[data appendBytes:outbuffer
length:outlength];
}
}
EVP_CIPHER_CTX_cleanup(&context);
[stream close];
}
}
}
return data;
}
+ (NSData *)decrypt:(NSData *)scrambled
{
NSMutableData * data = nil;
if (scrambled)
{
unsigned int inlength = [scrambled length];
NSInputStream * stream = [NSInputStream
inputStreamWithData:scrambled];
if (stream)
{
[stream open];
// FLIPPED FOR DECRYPT!!!
unsigned char inbuffer[OUTBUFFERSIZE];
unsigned char outbuffer[INBUFFERSIZE];
int outlength;
int tmplength;
int n;
EVP_CIPHER_CTX context;
EVP_CIPHER_CTX_init(&context);
EVP_DecryptInit_ex(&context, EVP_bf_cbc(), NULL, key,
iv);
data = [NSMutableData dataWithCapacity:inlength*2];
if (data)
{
for (;;)
{
// AGAIN... FLIPPED FOR DECRYPT...
bzero(inbuffer, OUTBUFFERSIZE);
n = [stream read:inbuffer
maxLength:OUTBUFFERSIZE];
if ( n <= 0 )
{
break;
}
// FLIPPED....
bzero(outbuffer, INBUFFERSIZE);
if ( EVP_DecryptUpdate(&context, outbuffer, &outlength, inbuffer,
n) != 1 )
{
return nil;
}
if ( EVP_DecryptFinal_ex(&context, outbuffer + outlength,
&tmplength) != 1 )
{
return nil;
}
outlength += tmplength;
[data appendBytes:outbuffer
length:outlength];
}
}
EVP_CIPHER_CTX_cleanup(&context);
[stream close];
}
}
return data;
}
This was adapted from the following tutorial:
http://www.faqs.org/docs/gazette/encryption.html
It has a dead link to the full source, but it can be found here:
http://archpub20.cs.ccu.edu.tw/cgi-bin/dwww?type=file&location=/usr/share/doc/lg/issue87/misc/vinayak/sym_funcs.c.txt
( http://tinyurl.com/2bmyawm )
His algorithm has one part that doesn't seem right to me, but changing
it made things even worse. It seems weird that the "Final" function is
inside the main for loop. It seems like "final" should mean... final.
(ie: after the looping is done).
Aside from that everything looks great, and like I said, it works
perfectly for the first few hundred bytes of input. Then, once enough
input is fed into the encrypt side, it breaks when trying to decrypt
that data back in.
Anyone see my mistake?
Thanks.
Chuck
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org