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 */,
};