Add |EVP_rc2_cbc| and implement |EVP_CTRL_SET_RC2_KEY_BITS|.

Add it to |EVP_get_cipherbynid|, along with |EVP_rc2_40_cbc| and
|EVP_aes_192_cbc|.

Change-Id: Iee7621a91262359d1650684652995884a6cef37a
Reviewed-on: https://boringssl-review.googlesource.com/5590
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/cipher/cipher.c b/crypto/cipher/cipher.c
index 1dfcf51..4401867 100644
--- a/crypto/cipher/cipher.c
+++ b/crypto/cipher/cipher.c
@@ -68,12 +68,18 @@
 
 const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
   switch (nid) {
+    case NID_rc2_cbc:
+      return EVP_rc2_cbc();
+    case NID_rc2_40_cbc:
+      return EVP_rc2_40_cbc();
     case NID_des_ede3_cbc:
       return EVP_des_ede3_cbc();
     case NID_des_ede_cbc:
       return EVP_des_cbc();
     case NID_aes_128_cbc:
       return EVP_aes_128_cbc();
+    case NID_aes_192_cbc:
+      return EVP_aes_192_cbc();
     case NID_aes_256_cbc:
       return EVP_aes_256_cbc();
     default:
diff --git a/crypto/cipher/e_rc2.c b/crypto/cipher/e_rc2.c
index c90ab93..8ca7bba 100644
--- a/crypto/cipher/e_rc2.c
+++ b/crypto/cipher/e_rc2.c
@@ -395,13 +395,18 @@
     case EVP_CTRL_INIT:
       key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
       return 1;
+    case EVP_CTRL_SET_RC2_KEY_BITS:
+      /* Should be overridden by later call to |EVP_CTRL_INIT|, but
+       * people call it, so it may as well work. */
+      key->key_bits = arg;
+      return 1;
 
     default:
       return -1;
   }
 }
 
-static const EVP_CIPHER rc2_40_cbc_cipher = {
+static const EVP_CIPHER rc2_40_cbc = {
     NID_rc2_40_cbc,
     8 /* block size */,
     5 /* 40 bit */,
@@ -416,5 +421,23 @@
 };
 
 const EVP_CIPHER *EVP_rc2_40_cbc(void) {
-  return &rc2_40_cbc_cipher;
+  return &rc2_40_cbc;
+}
+
+static const EVP_CIPHER rc2_cbc = {
+    NID_rc2_cbc,
+    8 /* block size */,
+    16 /* 128 bit */,
+    8 /* iv len */,
+    sizeof(EVP_RC2_KEY),
+    EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+    NULL /* app_data */,
+    rc2_init_key,
+    rc2_cbc_cipher,
+    NULL,
+    rc2_ctrl,
+};
+
+const EVP_CIPHER *EVP_rc2_cbc(void) {
+  return &rc2_cbc;
 }
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index 6aab5b1..eb00082 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -102,6 +102,9 @@
  * ciphertext. */
 OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void);
 
+/* EVP_rc2_cbc returns a cipher that implements 128-bit RC2 in CBC mode. */
+OPENSSL_EXPORT const EVP_CIPHER *EVP_rc2_cbc(void);
+
 /* EVP_rc2_40_cbc returns a cipher that implements 40-bit RC2 in CBC mode. This
  * is obviously very, very weak and is included only in order to read PKCS#12
  * files, which often encrypt the certificate chain using this cipher. It is