Make RSA opaque

Three years of updating calling code are finally complete!

Update-Note: Accessing the RSA struct directly is no longer supported.
Use accessors instead.

Bug: 316, 325
Change-Id: I27b4c9899cb96f5807075b8fe351eaf72a9a9d44
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60610
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
main-with-bazel
David Benjamin 1 year ago committed by Boringssl LUCI CQ
parent 23ed9d3852
commit d4553e0538
  1. 56
      crypto/fipsmodule/rsa/internal.h
  2. 2
      crypto/fipsmodule/service_indicator/service_indicator_test.cc
  3. 61
      include/openssl/rsa.h
  4. 8
      tool/speed.cc

@ -68,6 +68,62 @@ extern "C" {
#endif #endif
typedef struct bn_blinding_st BN_BLINDING;
struct rsa_st {
RSA_METHOD *meth;
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
// be careful using this if the RSA structure is shared
CRYPTO_EX_DATA ex_data;
CRYPTO_refcount_t references;
int flags;
CRYPTO_MUTEX lock;
// Used to cache montgomery values. The creation of these values is protected
// by |lock|.
BN_MONT_CTX *mont_n;
BN_MONT_CTX *mont_p;
BN_MONT_CTX *mont_q;
// The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively,
// but with the correct widths to prevent side channels. These must use
// separate copies due to threading concerns caused by OpenSSL's API
// mistakes. See https://github.com/openssl/openssl/issues/5158 and
// the |freeze_private_key| implementation.
BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed;
// inv_small_mod_large_mont is q^-1 mod p in Montgomery form, using |mont_p|,
// if |p| >= |q|. Otherwise, it is p^-1 mod q in Montgomery form, using
// |mont_q|.
BIGNUM *inv_small_mod_large_mont;
// num_blindings contains the size of the |blindings| and |blindings_inuse|
// arrays. This member and the |blindings_inuse| array are protected by
// |lock|.
size_t num_blindings;
// blindings is an array of BN_BLINDING structures that can be reserved by a
// thread by locking |lock| and changing the corresponding element in
// |blindings_inuse| from 0 to 1.
BN_BLINDING **blindings;
unsigned char *blindings_inuse;
uint64_t blinding_fork_generation;
// private_key_frozen is one if the key has been used for a private key
// operation and may no longer be mutated.
unsigned private_key_frozen:1;
};
#define RSA_PKCS1_PADDING_SIZE 11 #define RSA_PKCS1_PADDING_SIZE 11
// Default implementations of RSA operations. // Default implementations of RSA operations.

@ -1065,7 +1065,7 @@ TEST(ServiceIndicatorTest, RSAKeyGen) {
EXPECT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED( EXPECT_TRUE(CALL_SERVICE_AND_CHECK_APPROVED(
approved, RSA_generate_key_fips(rsa.get(), bits, nullptr))); approved, RSA_generate_key_fips(rsa.get(), bits, nullptr)));
EXPECT_EQ(approved, FIPSStatus::APPROVED); EXPECT_EQ(approved, FIPSStatus::APPROVED);
EXPECT_EQ(bits, BN_num_bits(rsa->n)); EXPECT_EQ(bits, RSA_bits(rsa.get()));
} }
// Test running the EVP_PKEY_keygen interfaces one by one directly, and check // Test running the EVP_PKEY_keygen interfaces one by one directly, and check

@ -818,67 +818,6 @@ struct rsa_meth_st {
}; };
// Private functions.
typedef struct bn_blinding_st BN_BLINDING;
struct rsa_st {
RSA_METHOD *meth;
// Access to the following fields was historically allowed, but
// deprecated. Use |RSA_get0_*| and |RSA_set0_*| instead. Access to all other
// fields is forbidden and will cause threading errors.
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
// be careful using this if the RSA structure is shared
CRYPTO_EX_DATA ex_data;
CRYPTO_refcount_t references;
int flags;
CRYPTO_MUTEX lock;
// Used to cache montgomery values. The creation of these values is protected
// by |lock|.
BN_MONT_CTX *mont_n;
BN_MONT_CTX *mont_p;
BN_MONT_CTX *mont_q;
// The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively,
// but with the correct widths to prevent side channels. These must use
// separate copies due to threading concerns caused by OpenSSL's API
// mistakes. See https://github.com/openssl/openssl/issues/5158 and
// the |freeze_private_key| implementation.
BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed;
// inv_small_mod_large_mont is q^-1 mod p in Montgomery form, using |mont_p|,
// if |p| >= |q|. Otherwise, it is p^-1 mod q in Montgomery form, using
// |mont_q|.
BIGNUM *inv_small_mod_large_mont;
// num_blindings contains the size of the |blindings| and |blindings_inuse|
// arrays. This member and the |blindings_inuse| array are protected by
// |lock|.
size_t num_blindings;
// blindings is an array of BN_BLINDING structures that can be reserved by a
// thread by locking |lock| and changing the corresponding element in
// |blindings_inuse| from 0 to 1.
BN_BLINDING **blindings;
unsigned char *blindings_inuse;
uint64_t blinding_fork_generation;
// private_key_frozen is one if the key has been used for a private key
// operation and may no longer be mutated.
unsigned private_key_frozen:1;
};
#if defined(__cplusplus) #if defined(__cplusplus)
} // extern C } // extern C

@ -367,15 +367,11 @@ static bool SpeedRSA(const std::string &selected) {
// construct a new RSA key, with a new |BN_MONT_CTX| for the // construct a new RSA key, with a new |BN_MONT_CTX| for the
// public modulus. If we were to use |key| directly instead, then // public modulus. If we were to use |key| directly instead, then
// these costs wouldn't be accounted for. // these costs wouldn't be accounted for.
bssl::UniquePtr<RSA> verify_key(RSA_new()); bssl::UniquePtr<RSA> verify_key(RSA_new_public_key(
RSA_get0_n(key.get()), RSA_get0_e(key.get())));
if (!verify_key) { if (!verify_key) {
return false; return false;
} }
verify_key->n = BN_dup(key->n);
verify_key->e = BN_dup(key->e);
if (!verify_key->n || !verify_key->e) {
return false;
}
return RSA_verify(NID_sha256, fake_sha256_hash, return RSA_verify(NID_sha256, fake_sha256_hash,
sizeof(fake_sha256_hash), sig, sig_len, sizeof(fake_sha256_hash), sig, sig_len,
verify_key.get()); verify_key.get());

Loading…
Cancel
Save