BF_set_key() vs EVP_CIPHER_CTX_set_key_length()
tomas at openssl.org
Sat Apr 22 08:31:45 UTC 2023
This is the same problem as
You need to call EVP_CipherInit_ex() twice. First with just the
EVP_CIPHER parameter set, then set the key length and then call the
second init with the passwd, iv and NULL EVP_CIPHER.
You can also use the EVP_CipherInit_ex2() with params setting the key
length in the first call instead of calling
EVP_CIPHER_CTX_set_key_length() as a small optimization.
Tomas Mraz, OpenSSL
On Fri, 2023-04-21 at 15:44 -0700, Thomas Dwyer III wrote:
> 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,
> New code (return code checking omitted for clarity):
> ctx = EVP_CIPHER_CTX_new();
> EVP_CipherInit_ex(ctx, EVP_bf_cfb64(), NULL, passwd, iv,
> 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?
Tomáš Mráz, OpenSSL
More information about the openssl-users