aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/rsa')
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp221
-rw-r--r--src/lib/pubkey/rsa/rsa.h71
2 files changed, 175 insertions, 117 deletions
diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp
index 2a0e8253e..9393cb954 100644
--- a/src/lib/pubkey/rsa/rsa.cpp
+++ b/src/lib/pubkey/rsa/rsa.cpp
@@ -5,12 +5,20 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/internal/pk_utils.h>
#include <botan/rsa.h>
#include <botan/parsing.h>
-#include <botan/numthry.h>
#include <botan/keypair.h>
+#include <botan/blinding.h>
+#include <botan/reducer.h>
#include <future>
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#else
+ #include <botan/auto_rng.h>
+#endif
+
namespace Botan {
/*
@@ -59,63 +67,182 @@ bool RSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const
return KeyPair::signature_consistency_check(rng, *this, "EMSA4(SHA-1)");
}
-RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa,
- RandomNumberGenerator& rng) :
- n(rsa.get_n()),
- q(rsa.get_q()),
- c(rsa.get_c()),
- powermod_e_n(rsa.get_e(), rsa.get_n()),
- powermod_d1_p(rsa.get_d1(), rsa.get_p()),
- powermod_d2_q(rsa.get_d2(), rsa.get_q()),
- mod_p(rsa.get_p())
- {
- BigInt k(rng, n.bits() - 1);
- blinder = Blinder(powermod_e_n(k), inverse_mod(k, n), n);
- }
+namespace {
-BigInt RSA_Private_Operation::private_op(const BigInt& m) const
+/**
+* RSA private (decrypt/sign) operation
+*/
+class RSA_Private_Operation
+ {
+ protected:
+ size_t get_max_input_bits() const { return (n.bits() - 1); }
+
+ RSA_Private_Operation(const RSA_PrivateKey& rsa) :
+ n(rsa.get_n()),
+ q(rsa.get_q()),
+ c(rsa.get_c()),
+ m_powermod_e_n(rsa.get_e(), rsa.get_n()),
+ m_powermod_d1_p(rsa.get_d1(), rsa.get_p()),
+ m_powermod_d2_q(rsa.get_d2(), rsa.get_q()),
+ m_mod_p(rsa.get_p())
+ {
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ auto& rng = system_rng();
+#else
+ AutoSeeded_RNG rng;
+#endif
+ BigInt k(rng, n.bits() - 1);
+ m_blinder = Blinder(m_powermod_e_n(k), inverse_mod(k, n), n);
+ }
+
+ BigInt blinded_private_op(const BigInt& m) const
+ {
+ return m_blinder.unblind(private_op(m_blinder.blind(m)));
+ }
+
+ BigInt private_op(const BigInt& m) const
+ {
+ if(m >= n)
+ throw Invalid_Argument("RSA private op - input is too large");
+
+ auto future_j1 = std::async(std::launch::async, m_powermod_d1_p, m);
+ BigInt j2 = m_powermod_d2_q(m);
+ BigInt j1 = future_j1.get();
+
+ j1 = m_mod_p.reduce(sub_mul(j1, j2, c));
+
+ return mul_add(j1, q, j2);
+ }
+
+ const BigInt& n;
+ const BigInt& q;
+ const BigInt& c;
+ Fixed_Exponent_Power_Mod m_powermod_e_n, m_powermod_d1_p, m_powermod_d2_q;
+ Modular_Reducer m_mod_p;
+ Blinder m_blinder;
+ };
+
+class RSA_Signature_Operation : public PK_Ops::Signature,
+ private RSA_Private_Operation
{
- if(m >= n)
- throw Invalid_Argument("RSA private op - input is too large");
+ public:
+ typedef RSA_PrivateKey Key_Type;
+
+ size_t max_input_bits() const override { return get_max_input_bits(); };
+
+ RSA_Signature_Operation(const RSA_PrivateKey& rsa, const std::string&) :
+ RSA_Private_Operation(rsa)
+ {
+ }
+
+ secure_vector<byte> sign(const byte msg[], size_t msg_len,
+ RandomNumberGenerator&) override
+ {
+ /* We don't check signatures against powermod_e_n here because
+ PK_Signer checks verification consistency for all signature
+ algorithms.
+ */
+ const BigInt m(msg, msg_len);
+ const BigInt x = blinded_private_op(m);
+ return BigInt::encode_1363(x, n.bytes());
+ }
+ };
+
+class RSA_Decryption_Operation : public PK_Ops::Decryption,
+ private RSA_Private_Operation
+ {
+ public:
+ typedef RSA_PrivateKey Key_Type;
- auto future_j1 = std::async(std::launch::async, powermod_d1_p, m);
- BigInt j2 = powermod_d2_q(m);
- BigInt j1 = future_j1.get();
+ size_t max_input_bits() const override { return get_max_input_bits(); };
- j1 = mod_p.reduce(sub_mul(j1, j2, c));
+ RSA_Decryption_Operation(const RSA_PrivateKey& rsa, const std::string&) :
+ RSA_Private_Operation(rsa)
+ {
+ }
- return mul_add(j1, q, j2);
- }
+ secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override
+ {
+ const BigInt m(msg, msg_len);
+ const BigInt x = blinded_private_op(m);
+ BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA decrypt consistency check");
+ return BigInt::encode_locked(x);
+ }
+ };
-secure_vector<byte>
-RSA_Private_Operation::sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng)
+
+/**
+* RSA public (encrypt/verify) operation
+*/
+class RSA_Public_Operation
{
- rng.add_entropy(msg, msg_len);
+ public:
+ RSA_Public_Operation(const RSA_PublicKey& rsa) :
+ n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n())
+ {}
+
+ size_t get_max_input_bits() const { return (n.bits() - 1); }
+
+ protected:
+ BigInt public_op(const BigInt& m) const
+ {
+ if(m >= n)
+ throw Invalid_Argument("RSA public op - input is too large");
+ return powermod_e_n(m);
+ }
+
+ const BigInt& n;
+ Fixed_Exponent_Power_Mod powermod_e_n;
+ };
+
+class RSA_Encryption_Operation : public PK_Ops::Encryption,
+ private RSA_Public_Operation
+ {
+ public:
+ typedef RSA_PublicKey Key_Type;
+
+ RSA_Encryption_Operation(const RSA_PublicKey& rsa, const std::string&) :
+ RSA_Public_Operation(rsa)
+ {
+ }
+
+ size_t max_input_bits() const override { return get_max_input_bits(); };
+
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
+ RandomNumberGenerator&)
+ {
+ BigInt m(msg, msg_len);
+ return BigInt::encode_1363(public_op(m), n.bytes());
+ }
+ };
+
+class RSA_Verify_Operation : public PK_Ops::Verification,
+ private RSA_Public_Operation
+ {
+ public:
+ typedef RSA_PublicKey Key_Type;
- /* We don't check signatures against powermod_e_n here because
- PK_Signer checks verification consistency for all signature
- algorithms.
- */
+ size_t max_input_bits() const override { return get_max_input_bits(); };
- const BigInt m(msg, msg_len);
- const BigInt x = blinder.unblind(private_op(blinder.blind(m)));
- return BigInt::encode_1363(x, n.bytes());
- }
+ RSA_Verify_Operation(const RSA_PublicKey& rsa, const std::string&) :
+ RSA_Public_Operation(rsa)
+ {
+ }
-/*
-* RSA Decryption Operation
-*/
-secure_vector<byte>
-RSA_Private_Operation::decrypt(const byte msg[], size_t msg_len)
- {
- const BigInt m(msg, msg_len);
- const BigInt x = blinder.unblind(private_op(blinder.blind(m)));
+ bool with_recovery() const override { return true; }
- BOTAN_ASSERT(m == powermod_e_n(x),
- "RSA decrypt passed consistency check");
+ secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override
+ {
+ BigInt m(msg, msg_len);
+ return BigInt::encode_locked(public_op(m));
+ }
+ };
- return BigInt::encode_locked(x);
- }
+BOTAN_REGISTER_PK_ENCRYPTION_OP("RSA", RSA_Encryption_Operation);
+BOTAN_REGISTER_PK_DECRYPTION_OP("RSA", RSA_Decryption_Operation);
+BOTAN_REGISTER_PK_SIGNATURE_OP("RSA", RSA_Signature_Operation);
+BOTAN_REGISTER_PK_VERIFY_OP("RSA", RSA_Verify_Operation);
+
+}
}
diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h
index 8a599d2ab..67357d859 100644
--- a/src/lib/pubkey/rsa/rsa.h
+++ b/src/lib/pubkey/rsa/rsa.h
@@ -9,9 +9,7 @@
#define BOTAN_RSA_H__
#include <botan/if_algo.h>
-#include <botan/pk_ops.h>
-#include <botan/reducer.h>
-#include <botan/blinding.h>
+
namespace Botan {
@@ -83,73 +81,6 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey,
size_t bits, size_t exp = 65537);
};
-/**
-* RSA private (decrypt/sign) operation
-*/
-class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature,
- public PK_Ops::Decryption
- {
- public:
- RSA_Private_Operation(const RSA_PrivateKey& rsa,
- RandomNumberGenerator& rng);
-
- size_t max_input_bits() const { return (n.bits() - 1); }
-
- secure_vector<byte> sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator& rng);
-
- secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
-
- private:
- BigInt private_op(const BigInt& m) const;
-
- const BigInt& n;
- const BigInt& q;
- const BigInt& c;
- Fixed_Exponent_Power_Mod powermod_e_n, powermod_d1_p, powermod_d2_q;
- Modular_Reducer mod_p;
- Blinder blinder;
- };
-
-/**
-* RSA public (encrypt/verify) operation
-*/
-class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification,
- public PK_Ops::Encryption
- {
- public:
- RSA_Public_Operation(const RSA_PublicKey& rsa) :
- n(rsa.get_n()), powermod_e_n(rsa.get_e(), rsa.get_n())
- {}
-
- size_t max_input_bits() const { return (n.bits() - 1); }
- bool with_recovery() const { return true; }
-
- secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
- RandomNumberGenerator&)
- {
- BigInt m(msg, msg_len);
- return BigInt::encode_1363(public_op(m), n.bytes());
- }
-
- secure_vector<byte> verify_mr(const byte msg[], size_t msg_len)
- {
- BigInt m(msg, msg_len);
- return BigInt::encode_locked(public_op(m));
- }
-
- private:
- BigInt public_op(const BigInt& m) const
- {
- if(m >= n)
- throw Invalid_Argument("RSA public op - input is too large");
- return powermod_e_n(m);
- }
-
- const BigInt& n;
- Fixed_Exponent_Power_Mod powermod_e_n;
- };
-
}
#endif