From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 31 May 2023 11:36:48 +0200
Subject: feat: expose several extra cipher functions

This patch exposes the following ciphers:

AES_CFB Ciphers: aes-128-cfb, aes-256-cfb

Implementations for these ciphers exist but aren't exposed, so they're
unusable without this patch. We should upstream this as similar
patches for implemented cipher functions have been accepted.

Blowfish Ciphers: bf-cbc, bf-cfb, bf-ecb

The addition of Blowfish ciphers adds references decrepit code
from non-decrepit code, so upstream is unlikely to take the patch.

DES Ciphers: des-ede3

An implementation for this cipher exists but isn't exposed, so it's
unusable without this patch. Akin to the AES_CFB exposures, we should
upstream this as similar patches for implemented cipher functions have
been accepted.

RC2 Ciphers: rc2-40-cbc

It's unclear whether this would be accepted upstream. We should try regardless.

diff --git a/crypto/cipher/get_cipher.cc b/crypto/cipher/get_cipher.cc
index dabc54aa13745600a62e57ecbb427e48a4565282..ce213e00573102ce9405a794d3c140d9ef499ec1 100644
--- a/crypto/cipher/get_cipher.cc
+++ b/crypto/cipher/get_cipher.cc
@@ -31,6 +31,7 @@ static const struct {
   const EVP_CIPHER *(*func)();
 } kCiphers[] = {
     {NID_aes_128_cbc, "aes-128-cbc", EVP_aes_128_cbc},
+    {NID_aes_128_cfb128, "aes-128-cfb", EVP_aes_128_cfb128},
     {NID_aes_128_ctr, "aes-128-ctr", EVP_aes_128_ctr},
     {NID_aes_128_ecb, "aes-128-ecb", EVP_aes_128_ecb},
     {NID_aes_128_gcm, "aes-128-gcm", EVP_aes_128_gcm},
@@ -41,17 +42,23 @@ static const struct {
     {NID_aes_192_gcm, "aes-192-gcm", EVP_aes_192_gcm},
     {NID_aes_192_ofb128, "aes-192-ofb", EVP_aes_192_ofb},
     {NID_aes_256_cbc, "aes-256-cbc", EVP_aes_256_cbc},
+    {NID_aes_256_cfb128, "aes-256-cfb", EVP_aes_256_cfb128},
     {NID_aes_256_ctr, "aes-256-ctr", EVP_aes_256_ctr},
     {NID_aes_256_ecb, "aes-256-ecb", EVP_aes_256_ecb},
     {NID_aes_256_gcm, "aes-256-gcm", EVP_aes_256_gcm},
     {NID_aes_256_ofb128, "aes-256-ofb", EVP_aes_256_ofb},
+    {NID_bf_cbc, "bf-cbc", EVP_bf_cbc},
+    {NID_bf_cfb64, "bf-cfb", EVP_bf_cfb},
+    {NID_bf_ecb, "bf-ecb", EVP_bf_ecb},
     {NID_des_cbc, "des-cbc", EVP_des_cbc},
     {NID_des_ecb, "des-ecb", EVP_des_ecb},
     {NID_des_ede_cbc, "des-ede-cbc", EVP_des_ede_cbc},
     {NID_des_ede_ecb, "des-ede", EVP_des_ede},
+    {NID_des_ede3_ecb, "des-ede3", EVP_des_ede3},
     {NID_des_ede3_cbc, "des-ede3-cbc", EVP_des_ede3_cbc},
     {NID_rc2_cbc, "rc2-cbc", EVP_rc2_cbc},
     {NID_rc4, "rc4", EVP_rc4},
+    {NID_rc2_40_cbc, "rc2-40-cbc", EVP_rc2_40_cbc}
 };
 
 const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
diff --git a/decrepit/evp/evp_do_all.cc b/decrepit/evp/evp_do_all.cc
index 891a73f229e3f0838cb2fa99b8fb24fdeac1962b..f7d0c5dc66f016eb9338c15e7f5ef59e6de2969d 100644
--- a/decrepit/evp/evp_do_all.cc
+++ b/decrepit/evp/evp_do_all.cc
@@ -20,8 +20,10 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
                                                const char *unused, void *arg),
                               void *arg) {
   callback(EVP_aes_128_cbc(), "AES-128-CBC", nullptr, arg);
+  callback(EVP_aes_128_cfb128(), "AES-128-CFB", nullptr, arg);
   callback(EVP_aes_192_cbc(), "AES-192-CBC", nullptr, arg);
   callback(EVP_aes_256_cbc(), "AES-256-CBC", nullptr, arg);
+  callback(EVP_aes_256_cfb128(), "AES-256-CFB", nullptr, arg);
   callback(EVP_aes_128_ctr(), "AES-128-CTR", nullptr, arg);
   callback(EVP_aes_192_ctr(), "AES-192-CTR", nullptr, arg);
   callback(EVP_aes_256_ctr(), "AES-256-CTR", nullptr, arg);
@@ -34,9 +36,13 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
   callback(EVP_aes_128_gcm(), "AES-128-GCM", nullptr, arg);
   callback(EVP_aes_192_gcm(), "AES-192-GCM", nullptr, arg);
   callback(EVP_aes_256_gcm(), "AES-256-GCM", nullptr, arg);
+  callback(EVP_bf_cbc(), "BF-CBC", nullptr, arg);
+  callback(EVP_bf_cfb(), "BF-CFB", nullptr, arg);
+  callback(EVP_bf_ecb(), "BF-ECB", nullptr, arg);
   callback(EVP_des_cbc(), "DES-CBC", nullptr, arg);
   callback(EVP_des_ecb(), "DES-ECB", nullptr, arg);
   callback(EVP_des_ede(), "DES-EDE", nullptr, arg);
+  callback(EVP_des_ede3(), "DES-EDE3", nullptr, arg);
   callback(EVP_des_ede_cbc(), "DES-EDE-CBC", nullptr, arg);
   callback(EVP_des_ede3_cbc(), "DES-EDE3-CBC", nullptr, arg);
   callback(EVP_rc2_cbc(), "RC2-CBC", nullptr, arg);
@@ -44,8 +50,10 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
 
   // OpenSSL returns everything twice, the second time in lower case.
   callback(EVP_aes_128_cbc(), "aes-128-cbc", nullptr, arg);
+  callback(EVP_aes_128_cfb128(), "aes-128-cfb", nullptr, arg);
   callback(EVP_aes_192_cbc(), "aes-192-cbc", nullptr, arg);
   callback(EVP_aes_256_cbc(), "aes-256-cbc", nullptr, arg);
+  callback(EVP_aes_256_cfb128(), "aes-256-cfb", nullptr, arg);
   callback(EVP_aes_128_ctr(), "aes-128-ctr", nullptr, arg);
   callback(EVP_aes_192_ctr(), "aes-192-ctr", nullptr, arg);
   callback(EVP_aes_256_ctr(), "aes-256-ctr", nullptr, arg);
@@ -58,9 +66,13 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,
   callback(EVP_aes_128_gcm(), "aes-128-gcm", nullptr, arg);
   callback(EVP_aes_192_gcm(), "aes-192-gcm", nullptr, arg);
   callback(EVP_aes_256_gcm(), "aes-256-gcm", nullptr, arg);
+  callback(EVP_bf_cbc(), "bf-cbc", nullptr, arg);
+  callback(EVP_bf_cfb(), "bf-cfb", nullptr, arg);
+  callback(EVP_bf_ecb(), "bf-ecb", nullptr, arg);
   callback(EVP_des_cbc(), "des-cbc", nullptr, arg);
   callback(EVP_des_ecb(), "des-ecb", nullptr, arg);
   callback(EVP_des_ede(), "des-ede", nullptr, arg);
+  callback(EVP_des_ede3(), "des-ede3", nullptr, arg);
   callback(EVP_des_ede_cbc(), "des-ede-cbc", nullptr, arg);
   callback(EVP_des_ede3_cbc(), "des-ede3-cbc", nullptr, arg);
   callback(EVP_rc2_cbc(), "rc2-cbc", nullptr, arg);
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index ed2eeab57779d827eb19edcd435b4664d4079859..74bb77e03b562698cb887b25cc8a779631a809fb 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -552,6 +552,7 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_ecb(void);
 
 // EVP_aes_128_cfb128 is only available in decrepit.
 OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cfb128(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cfb128(void);
 
 // EVP_aes_128_cfb is an alias for |EVP_aes_128_cfb128| and is only available in
 // decrepit.
