diff options
Diffstat (limited to 'src/lib/pubkey/rsa')
-rw-r--r-- | src/lib/pubkey/rsa/rsa.cpp | 221 | ||||
-rw-r--r-- | src/lib/pubkey/rsa/rsa.h | 71 |
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 |