Make it possible for a static linker to discard unused RSA functions.

Having a single RSA_METHOD means they all get pulled in. Notably, RSA key
generation pulls in the primality-checking code.

Change-Id: Iece480113754da090ddf87b64d8769f01e05d26c
Reviewed-on: https://boringssl-review.googlesource.com/6389
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/rsa/internal.h b/crypto/rsa/internal.h
index c0044c3..b5b9c89 100644
--- a/crypto/rsa/internal.h
+++ b/crypto/rsa/internal.h
@@ -65,6 +65,29 @@
 #endif
 
 
+/* Default implementations of RSA operations. */
+
+extern const RSA_METHOD RSA_default_method;
+
+int rsa_default_finish(RSA *rsa);
+size_t rsa_default_size(const RSA *rsa);
+int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+                        const uint8_t *in, size_t in_len, int padding);
+int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
+                         size_t max_out, const uint8_t *in, size_t in_len,
+                         int padding);
+int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+                        const uint8_t *in, size_t in_len, int padding);
+int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
+                           size_t max_out, const uint8_t *in, size_t in_len,
+                           int padding);
+int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
+                                  size_t len);
+int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
+                                   BIGNUM *e_value, BN_GENCB *cb);
+int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
+
+
 #define RSA_PKCS1_PADDING_SIZE 11
 
 
diff --git a/crypto/rsa/rsa.c b/crypto/rsa/rsa.c
index 3ea4bff..482a866 100644
--- a/crypto/rsa/rsa.c
+++ b/crypto/rsa/rsa.c
@@ -71,8 +71,6 @@
 #include "../internal.h"
 
 
-extern const RSA_METHOD RSA_default_method;
-
 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
 
 RSA *RSA_new(void) { return RSA_new_method(NULL); }
@@ -178,7 +176,7 @@
     return rsa->meth->keygen(rsa, bits, e_value, cb);
   }
 
-  return RSA_default_method.keygen(rsa, bits, e_value, cb);
+  return rsa_default_keygen(rsa, bits, e_value, cb);
 }
 
 int RSA_generate_multi_prime_key(RSA *rsa, int bits, int num_primes,
@@ -187,8 +185,7 @@
     return rsa->meth->multi_prime_keygen(rsa, bits, num_primes, e_value, cb);
   }
 
-  return RSA_default_method.multi_prime_keygen(rsa, bits, num_primes, e_value,
-                                               cb);
+  return rsa_default_multi_prime_keygen(rsa, bits, num_primes, e_value, cb);
 }
 
 int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
@@ -197,8 +194,7 @@
     return rsa->meth->encrypt(rsa, out_len, out, max_out, in, in_len, padding);
   }
 
-  return RSA_default_method.encrypt(rsa, out_len, out, max_out, in, in_len,
-                                    padding);
+  return rsa_default_encrypt(rsa, out_len, out, max_out, in, in_len, padding);
 }
 
 int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
@@ -222,8 +218,7 @@
     return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
   }
 
-  return RSA_default_method.sign_raw(rsa, out_len, out, max_out, in, in_len,
-                                     padding);
+  return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
 }
 
 int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
@@ -247,8 +242,7 @@
     return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
   }
 
-  return RSA_default_method.decrypt(rsa, out_len, out, max_out, in, in_len,
-                                    padding);
+  return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
 }
 
 int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
@@ -272,8 +266,8 @@
     return rsa->meth->verify_raw(rsa, out_len, out, max_out, in, in_len, padding);
   }
 
-  return RSA_default_method.verify_raw(rsa, out_len, out, max_out, in, in_len,
-                                       padding);
+  return rsa_default_verify_raw(rsa, out_len, out, max_out, in, in_len,
+                                padding);
 }
 
 int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
@@ -296,7 +290,7 @@
     return rsa->meth->size(rsa);
   }
 
-  return RSA_default_method.size(rsa);
+  return rsa_default_size(rsa);
 }
 
 int RSA_is_opaque(const RSA *rsa) {
@@ -808,7 +802,7 @@
     return rsa->meth->private_transform(rsa, out, in, len);
   }
 
-  return RSA_default_method.private_transform(rsa, out, in, len);
+  return rsa_default_private_transform(rsa, out, in, len);
 }
 
 int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) {
diff --git a/crypto/rsa/rsa_impl.c b/crypto/rsa/rsa_impl.c
index b14f7a0..6bb2214 100644
--- a/crypto/rsa/rsa_impl.c
+++ b/crypto/rsa/rsa_impl.c
@@ -73,7 +73,7 @@
   64 /* exponent limit enforced for "large" modulus only */
 
 
-static int finish(RSA *rsa) {
+int rsa_default_finish(RSA *rsa) {
   BN_MONT_CTX_free(rsa->_method_mod_n);
   BN_MONT_CTX_free(rsa->_method_mod_p);
   BN_MONT_CTX_free(rsa->_method_mod_q);
@@ -90,12 +90,12 @@
   return 1;
 }
 
-static size_t size(const RSA *rsa) {
+size_t rsa_default_size(const RSA *rsa) {
   return BN_num_bytes(rsa->n);
 }
 
-static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                   const uint8_t *in, size_t in_len, int padding) {
+int rsa_default_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+                        const uint8_t *in, size_t in_len, int padding) {
   const unsigned rsa_size = RSA_size(rsa);
   BIGNUM *f, *result;
   uint8_t *buf = NULL;
@@ -311,8 +311,9 @@
 }
 
 /* signing */
-static int sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                    const uint8_t *in, size_t in_len, int padding) {
+int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
+                         size_t max_out, const uint8_t *in, size_t in_len,
+                         int padding) {
   const unsigned rsa_size = RSA_size(rsa);
   uint8_t *buf = NULL;
   int i, ret = 0;
@@ -360,8 +361,8 @@
   return ret;
 }
 
-static int decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                   const uint8_t *in, size_t in_len, int padding) {
+int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
+                        const uint8_t *in, size_t in_len, int padding) {
   const unsigned rsa_size = RSA_size(rsa);
   int r = -1;
   uint8_t *buf = NULL;
@@ -425,8 +426,9 @@
   return ret;
 }
 
-static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
-                      const uint8_t *in, size_t in_len, int padding) {
+int rsa_default_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
+                           size_t max_out, const uint8_t *in, size_t in_len,
+                           int padding) {
   const unsigned rsa_size = RSA_size(rsa);
   BIGNUM *f, *result;
   int ret = 0;
@@ -541,8 +543,8 @@
   return ret;
 }
 
-static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
-                             size_t len) {
+int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
+                                  size_t len) {
   BIGNUM *f, *result;
   BN_CTX *ctx = NULL;
   unsigned blinding_index = 0;
@@ -830,8 +832,8 @@
   return ret;
 }
 
-static int keygen_multiprime(RSA *rsa, int bits, int num_primes,
-                             BIGNUM *e_value, BN_GENCB *cb) {
+int rsa_default_multi_prime_keygen(RSA *rsa, int bits, int num_primes,
+                                   BIGNUM *e_value, BN_GENCB *cb) {
   BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
   BIGNUM local_r0, local_d, local_p;
   BIGNUM *pr0, *d, *p;
@@ -1119,11 +1121,15 @@
   return ok;
 }
 
-static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
-  return keygen_multiprime(rsa, bits, 2 /* num primes */, e_value, cb);
+int rsa_default_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
+  return rsa_default_multi_prime_keygen(rsa, bits, 2 /* num primes */, e_value,
+                                        cb);
 }
 
-const struct rsa_meth_st RSA_default_method = {
+/* Many of these methods are NULL to more easily drop unused functions. The
+ * wrapper functions will select the appropriate |rsa_default_*| for all
+ * methods. */
+const RSA_METHOD RSA_default_method = {
   {
     0 /* references */,
     1 /* is_static */,
@@ -1131,27 +1137,27 @@
   NULL /* app_data */,
 
   NULL /* init */,
-  finish,
+  NULL /* finish (defaults to rsa_default_finish) */,
 
-  size,
+  NULL /* size (defaults to rsa_default_size) */,
 
   NULL /* sign */,
   NULL /* verify */,
 
-  encrypt,
-  sign_raw,
-  decrypt,
-  verify_raw,
+  NULL /* encrypt (defaults to rsa_default_encrypt) */,
+  NULL /* sign_raw (defaults to rsa_default_sign_raw) */,
+  NULL /* decrypt (defaults to rsa_default_decrypt) */,
+  NULL /* verify_raw (defaults to rsa_default_verify_raw) */,
 
-  private_transform,
+  NULL /* private_transform (defaults to rsa_default_private_transform) */,
 
-  mod_exp /* mod_exp */,
+  mod_exp,
   BN_mod_exp_mont /* bn_mod_exp */,
 
   RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
 
-  keygen,
-  keygen_multiprime,
+  NULL /* keygen (defaults to rsa_default_keygen) */,
+  NULL /* multi_prime_keygen (defaults to rsa_default_multi_prime_keygen) */,
 
   NULL /* supports_digest */,
 };