More compatibility stuff.

cryptography.io wants things exposed out of EVP_get_cipherby* including,
sadly, ECB mode.

Change-Id: I9bac46f8ffad1a79d190cee3b0c0686bf540298e
Reviewed-on: https://boringssl-review.googlesource.com/28464
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/cipher_extra/cipher_extra.c b/crypto/cipher_extra/cipher_extra.c
index fc8e24b..e770489 100644
--- a/crypto/cipher_extra/cipher_extra.c
+++ b/crypto/cipher_extra/cipher_extra.c
@@ -94,20 +94,35 @@
   } else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
     return EVP_des_cbc();
   } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
+             // This is not a name used by OpenSSL, but tcpdump registers it
+             // with |EVP_add_cipher_alias|. Our |EVP_add_cipher_alias| is a
+             // no-op, so we support the name here.
              OPENSSL_strcasecmp(name, "3des") == 0) {
     return EVP_des_ede3_cbc();
   } else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) {
     return EVP_aes_128_cbc();
+  } else if (OPENSSL_strcasecmp(name, "aes-192-cbc") == 0) {
+    return EVP_aes_192_cbc();
   } else if (OPENSSL_strcasecmp(name, "aes-256-cbc") == 0) {
     return EVP_aes_256_cbc();
   } else if (OPENSSL_strcasecmp(name, "aes-128-ctr") == 0) {
     return EVP_aes_128_ctr();
+  } else if (OPENSSL_strcasecmp(name, "aes-192-ctr") == 0) {
+    return EVP_aes_192_ctr();
   } else if (OPENSSL_strcasecmp(name, "aes-256-ctr") == 0) {
     return EVP_aes_256_ctr();
   } else if (OPENSSL_strcasecmp(name, "aes-128-ecb") == 0) {
     return EVP_aes_128_ecb();
+  } else if (OPENSSL_strcasecmp(name, "aes-192-ecb") == 0) {
+    return EVP_aes_192_ecb();
   } else if (OPENSSL_strcasecmp(name, "aes-256-ecb") == 0) {
     return EVP_aes_256_ecb();
+  } else if (OPENSSL_strcasecmp(name, "aes-128-gcm") == 0) {
+    return EVP_aes_128_gcm();
+  } else if (OPENSSL_strcasecmp(name, "aes-192-gcm") == 0) {
+    return EVP_aes_192_gcm();
+  } else if (OPENSSL_strcasecmp(name, "aes-256-gcm") == 0) {
+    return EVP_aes_256_gcm();
   }
 
   return NULL;
diff --git a/crypto/evp/evp.c b/crypto/evp/evp.c
index ad5f85b..4feadb7 100644
--- a/crypto/evp/evp.c
+++ b/crypto/evp/evp.c
@@ -298,6 +298,7 @@
 }
 
 DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) { return NULL; }
+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) { return NULL; }
 
 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
   if (!EVP_PKEY_set_type(pkey, type)) {
diff --git a/crypto/fipsmodule/ec/ec.c b/crypto/fipsmodule/ec/ec.c
index b8a5f55..908e35e 100644
--- a/crypto/fipsmodule/ec/ec.c
+++ b/crypto/fipsmodule/ec/ec.c
@@ -914,7 +914,10 @@
 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
 
 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
-  return NULL;
+  // This function exists purely to give callers a way to call
+  // |EC_METHOD_get_field_type|. cryptography.io crashes if |EC_GROUP_method_of|
+  // returns NULL, so return some other garbage pointer.
+  return (const EC_METHOD *)0x12340000;
 }
 
 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
diff --git a/crypto/rsa_extra/CMakeLists.txt b/crypto/rsa_extra/CMakeLists.txt
index 563a4a4..e5f9e4e 100644
--- a/crypto/rsa_extra/CMakeLists.txt
+++ b/crypto/rsa_extra/CMakeLists.txt
@@ -5,5 +5,6 @@
 
   OBJECT
 
+  print.c
   rsa_asn1.c
 )
diff --git a/crypto/rsa_extra/print.c b/crypto/rsa_extra/print.c
new file mode 100644
index 0000000..71970b8
--- /dev/null
+++ b/crypto/rsa_extra/print.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/rsa.h>
+
+#include <openssl/evp.h>
+
+
+int RSA_print(BIO *bio, const RSA *rsa, int indent) {
+  EVP_PKEY *pkey = EVP_PKEY_new();
+  int ret = pkey != NULL &&
+            EVP_PKEY_set1_RSA(pkey, (RSA *)rsa) &&
+            EVP_PKEY_print_private(bio, pkey, indent, NULL);
+  EVP_PKEY_free(pkey);
+  return ret;
+}
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 69b30c5..989cf56 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -320,7 +320,7 @@
 
 typedef struct ec_method_st EC_METHOD;
 
-// EC_GROUP_method_of returns NULL.
+// EC_GROUP_method_of returns a dummy non-NULL pointer.
 OPENSSL_EXPORT const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
 
 // EC_METHOD_get_field_type returns NID_X9_62_prime_field.
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 1dffb64..bb017f1 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -796,6 +796,9 @@
 // EVP_PKEY_get0_DH returns NULL.
 OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey);
 
+// EVP_PKEY_get1_DH returns NULL.
+OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+
 
 // Preprocessor compatibility section (hidden).
 //
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index 92982b4..7ed5dce 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -589,6 +589,10 @@
                                               const uint8_t *param,
                                               size_t param_len);
 
+// RSA_print prints a textual representation of |rsa| to |bio|. It returns one
+// on success or zero otherwise.
+OPENSSL_EXPORT int RSA_print(BIO *bio, const RSA *rsa, int indent);
+
 
 struct rsa_meth_st {
   struct openssl_method_common_st common;