Hello openssl Hackers.
I try to explain thread started message and I hope to find any comments/ideas
to solve related problems.
There is more general problem than indicated earlier. You can find more
unfounded results in more tests and different platforms. Executing
crypt/decrypt cycle on FreeBSD and CentOS is not equivalent, although test
completed successfully (accidentals?):
Successful test; CentOS; openssl-0.9.8k; passw: `123'
7f5d48574e5612219abef351bb14bda3 plaintext
5c9231cbd339d228582ccf486b44aea1 encrypt
7f5d48574e5612219abef351bb14bda3 plaintext.out
Successful test; FreeBSD; openssl-0.9.8k; passw: `123'
7f5d48574e5612219abef351bb14bda3 plaintext
ad68a43241b2e660c9c2e6f9167995d4 encrypt
7f5d48574e5612219abef351bb14bda3 plaintext.out
What are you thinking about decryption message in FreeBSD encrypted in CentOS?
And more `sexual' behavior under Win32/MinGW system; openssl-0.9.8k; passw:
`123'.
7f5d48574e5612219abef351bb14bda3 plaintext
c1720d3a0e5e0948422248d015d1f956 encrypt
dc2f8e8d1c40af27ffe6c5ea6c23b304 plaintext.out
No comments.
Uninterested completion of tests using password `0123456789ABCDEF':
Win32/MinGW:
7f5d48574e5612219abef351bb14bda3 plaintext
b37945f24828d8e95e182a91f33b60ba encrypt
7f5d48574e5612219abef351bb14bda3 plaintext.out
FreeBSD:
7f5d48574e5612219abef351bb14bda3 plaintext
b37945f24828d8e95e182a91f33b60ba encrypt
7f5d48574e5612219abef351bb14bda3 plaintext.out
CentOS:
7f5d48574e5612219abef351bb14bda3 plaintext
b37945f24828d8e95e182a91f33b60ba encrypt
7f5d48574e5612219abef351bb14bda3 plaintext.out
All right. Now we have cross-platform code execution :-).
As you understand now, troubles in key generation. It's time to dip into
sources.
Cipher context initialization (and simultaneous key definition) perform in call
of EVP_EncryptInit() (in consideration code of crypto_test.cpp). Key-material
and initialization vector defines in
bf_skey.c, FIPS_NON_FIPS_VCIPHER_Init(BF) (unwrapped: BF_set_key() ):
FIPS_NON_FIPS_VCIPHER_Init(BF)
{
int i;
BF_LONG *p,ri,in[2];
const unsigned char *d,*end;
memcpy(key,&bf_init,sizeof(BF_KEY));
p=key->P;
if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
d=data;
end= &(data[len]);
for (i=0; i<(BF_ROUNDS+2); i++)
{
ri= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
p[i]^=ri;
}
in[0]=0L;
in[1]=0L;
for (i=0; i<(BF_ROUNDS+2); i+=2)
{
BF_encrypt(in,key);
p[i ]=in[0];
p[i+1]=in[1];
}
p=key->S;
for (i=0; i<4*256; i+=2)
{
BF_encrypt(in,key);
p[i ]=in[0];
p[i+1]=in[1];
}
}
We see initial initialization of `key' with predefined `bf_init' values and
next computing over `data' (range: {0 - len}, len - cipher key length). Cipher
key length set to 16 bytes (initialization vector length 8 bytes). `Human' key
(asciiz-string password) is barely 3 byte length. Computing key material over
next 12 bytes is wrong, because it contain undefined data (it was not
zero-filled under win32).
Zeroing memory is simplest way but it bring down cryptographic strength of
password. I seems we need in unique data block (block length must be equal to
cipher key length) that can be computed over password-string. We should use so
message digest algorithm, output data length of that is equal to cipher key
length. IV can be set in default behavior, for example, with digest data or
part of them.
I seems it is good idea to insert code of correct initialization key-material
and iv-data into {ALG}_set_key functions, or describe this situation (and EVP_
- api) in user's FAQ minimum (man-pages?).
Also, default initialization of iv should not be null-padding and we can
compute it over password string (require message digest algorithm, output
string length of that is equal to cipher iv-length).
Thank you.
Nick.
P.S.: Sorry for my ugly english. It will fine.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]