Re: 0.9.8e changes BF cfb encryption

2007-04-11 Thread Nils Larsch

Valient Gough wrote:


My previous mail doesn't seem to have appeared on the list, so sending 
again:



Hello,

As the maintainer of a package which uses OpenSSL, I've received some 
reports
of 0.9.8e failing to decrypt data which was encrypted by previous 
versions of

OpenSSL.

Attached is a small bit of C++ code which demonstrates the problem.  It 
uses

the EVP interface with EVP_bf_cfb as the cipher and a 256 bit key (the
reports all point to Blowfish with key length  128 bits).  What it does is
set a key, an IV, and run an encryption pass, then a decryption and compute
checksums of the three arrays (original, encrypted, decrypted).

When built against 0.9.8c, I get:
ort:tmp g++ -Wall -g -o ssltest ssltest.cpp -lssl -lcrypto -lz
ort:tmp ./ssltest
src chksum = 698614540
stage2 chksum = 2266501868
final chksum = 698614540

Another machine with 0.9.7a gives an identical result.  On a machine I
upgraded to 0.9.8e, I get the following output:

src chksum = 698614540
stage2 chksum = 2108297998
final chksum = 698614540


stage2 is the encrypted data, and it differs on 0.9.8e.  What this 
means in

practice is that the program I'm using can encrypt/decrypt data just fine
when run in either version of OpenSSL, but if data is encrypted in an 
earlier

version and then OpenSSL is upgraded to 0.9.8e, then decryption fails.

The nearest I've narrowed down is to something changing between 0.9.8c and
0.9.8e, but I've received reports that 0.9.8d - 0.9.8e also fails.  I've
been looking at the diffs between 0.9.8d - 0.9.8e, but I'm not seeing any
obvious problem.  Reports are that only Blowfish with key  128 bits has a
problem, and AES users are not affected.

Any ideas what's wrong, and if there's a way to get 0.9.8e output to match
earlier versions?


it's a bug in openssl 0.9.8e (see [1]).

Nils

[1] http://cvs.openssl.org/chngview?cn=15978

__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   [EMAIL PROTECTED]


0.9.8e changes BF cfb encryption

2007-04-10 Thread Valient Gough

My previous mail doesn't seem to have appeared on the list, so sending
again:


Hello,

As the maintainer of a package which uses OpenSSL, I've received some
reports
of 0.9.8e failing to decrypt data which was encrypted by previous versions
of
OpenSSL.

Attached is a small bit of C++ code which demonstrates the problem.  It uses

the EVP interface with EVP_bf_cfb as the cipher and a 256 bit key (the
reports all point to Blowfish with key length  128 bits).  What it does is
set a key, an IV, and run an encryption pass, then a decryption and compute
checksums of the three arrays (original, encrypted, decrypted).

When built against 0.9.8c, I get:
ort:tmp g++ -Wall -g -o ssltest ssltest.cpp -lssl -lcrypto -lz
ort:tmp ./ssltest
src chksum = 698614540
stage2 chksum = 2266501868
final chksum = 698614540

Another machine with 0.9.7a gives an identical result.  On a machine I
upgraded to 0.9.8e, I get the following output:

src chksum = 698614540
stage2 chksum = 2108297998
final chksum = 698614540


stage2 is the encrypted data, and it differs on 0.9.8e.  What this means
in
practice is that the program I'm using can encrypt/decrypt data just fine
when run in either version of OpenSSL, but if data is encrypted in an
earlier
version and then OpenSSL is upgraded to 0.9.8e, then decryption fails.

The nearest I've narrowed down is to something changing between 0.9.8c and
0.9.8e, but I've received reports that 0.9.8d - 0.9.8e also fails.  I've
been looking at the diffs between 0.9.8d - 0.9.8e, but I'm not seeing any
obvious problem.  Reports are that only Blowfish with key  128 bits has a
problem, and AES users are not affected.

Any ideas what's wrong, and if there's a way to get 0.9.8e output to match
earlier versions?

regards,
Valient

/*
Build using:

g++ -g -o ssltest ssltest.cpp -lssl -lcrypto -lz

*/

#include openssl/evp.h
#include zlib.h
#include assert.h
#include string.h


int main()
{
const int keySize = 32; // 256 bit key
unsigned char keyBytes[keySize];

const EVP_CIPHER *cipher = EVP_bf_cfb();
EVP_CIPHER_CTX stream_enc;
EVP_CIPHER_CTX stream_dec;

// init key to known value
for(int i=0; ikeySize; ++i)
keyBytes[i] = (unsigned char)i;

// setup IV
int ivLen = EVP_CIPHER_iv_length( cipher );
assert(ivLen == 8);

unsigned char ivec[8];
for(int i=0; i8; ++i)
ivec[i] = (unsigned char)i;

// setup cipher and a context for encryption and decryption
EVP_CIPHER_CTX_init( stream_enc );
EVP_CIPHER_CTX_init( stream_dec );

EVP_EncryptInit_ex( stream_enc, cipher, NULL, NULL, NULL );
EVP_DecryptInit_ex( stream_dec, cipher, NULL, NULL, NULL );

EVP_CIPHER_CTX_set_key_length( stream_enc, keySize );
EVP_CIPHER_CTX_set_key_length( stream_dec, keySize );

EVP_CIPHER_CTX_set_padding( stream_enc, 0 );
EVP_CIPHER_CTX_set_padding( stream_dec, 0 );

// initialize key
EVP_EncryptInit_ex( stream_enc, NULL, NULL, keyBytes, NULL );
EVP_DecryptInit_ex( stream_dec, NULL, NULL, keyBytes, NULL );

// Encode src - stage2, then decode state2 - final
const int size = 40;
unsigned char src[size];
unsigned char stage2[size];
unsigned char final[size];

for(int i=0; isize; ++i)
src[i] = (unsigned char)i;
memset(stage2, 0, sizeof(stage2));
memset(final, 0, sizeof(final));

int dstLen;
int tmpLen;

uLong chksum1 = adler32(0L, src, size);
printf(src chksum = %lu\n, chksum1);

/* encrypt some data */
EVP_EncryptInit_ex( stream_enc, NULL, NULL, NULL, ivec );
EVP_EncryptUpdate( stream_enc, stage2, dstLen, src, size );
EVP_EncryptFinal_ex( stream_enc, stage2+dstLen, tmpLen );
assert(dstLen == size);
assert(tmpLen == 0);

uLong chksum2 = adler32(0L, stage2, size);
printf(stage2 chksum = %lu\n, chksum2);

/* decrypt */
EVP_DecryptInit_ex( stream_dec, NULL, NULL, NULL, ivec );
EVP_DecryptUpdate( stream_dec, final, dstLen, stage2, size );
EVP_DecryptFinal_ex( stream_dec, final+dstLen, tmpLen );
assert(dstLen == size);
assert(tmpLen == 0);

uLong chksum3 = adler32(0L, final, size);
printf(final chksum = %lu\n, chksum3);

/* compare */
int res = memcmp(src, final, size);
assert(res == 0);

return res;
}