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 [email protected] Automated List Manager [email protected]
