We have multiple versions of an application using blowfish that
already shipped to customers. This legacy code uses the low level
blowfish primitives and I'm trying to port it to the high level EVP
APIs but I'm not getting the same results.
Old code:
BF_set_key(&key, plen, passwd);
BF_cfb64_encrypt(data, out, dlen, &key, iv, &offset,
BF_ENCRYPT);
New code (return code checking omitted for clarity):
ctx = EVP_CIPHER_CTX_new();
EVP_CipherInit_ex(ctx, EVP_bf_cfb64(), NULL, passwd, iv,
BF_ENCRYPT);
EVP_CIPHER_CTX_set_key_length(ctx, plen);
EVP_CipherUpdate(ctx, out, &outlen, data, dlen);
EVP_CipherFinal_ex(ctx, out+outlen, &outlen);
I expected the "out" buffer to contain the same value for both
implementations. It doesn't. The problem appears to center around
the length of the key but I'm not sure what's going wrong.
Unfortunately, a bug in the legacy code is effectively setting plen
to strlen(passwd)+1 rather than strlen(passwd), causing the null
terminator to be included in the length passed to BF_set_key(). For
backward compatibility with code that already shipped, I attempted
to preserve this buggy semantic in the new code by calling
EVP_CIPHER_CTX_set_key_length() with the same value that was
originally getting passed to BF_set_key().
If my key is more than 15 bytes long (e.g. "GoodMorningWorld") or
less than 15 bytes long (e.g. "GoodMorningWor") then the old &
new code produce different results. However, if the key is exactly
15 bytes long (e.g. "GoodMorningWorl") then the old & new code
both produce the same result. In fact, the call to
EVP_CIPHER_CTX_set_key_length() does not appear to have any impact
on the result (even though a subsequent EVP_CIPHER_CTX_key_length()
returns this new value instead of the default 16). I don't
understand this. What am I missing?
Thanks,
Tom.III