This is the same problem as https://github.com/openssl/openssl/issues/20769 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, > 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 > > -- Tomáš Mráz, OpenSSL