aboutsummaryrefslogtreecommitdiff
path: root/mysql/extra/yassl/taocrypt/include/rsa.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'mysql/extra/yassl/taocrypt/include/rsa.hpp')
-rw-r--r--mysql/extra/yassl/taocrypt/include/rsa.hpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/mysql/extra/yassl/taocrypt/include/rsa.hpp b/mysql/extra/yassl/taocrypt/include/rsa.hpp
new file mode 100644
index 0000000..ee3e378
--- /dev/null
+++ b/mysql/extra/yassl/taocrypt/include/rsa.hpp
@@ -0,0 +1,250 @@
+/*
+ Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+/* rsa.hpp provides RSA ES encrypt/decrypt, SSL (block type 1) sign and verify
+*/
+
+#ifndef TAO_CRYPT_RSA_HPP
+#define TAO_CRYPT_RSA_HPP
+
+#include "integer.hpp"
+#include "random.hpp"
+
+
+namespace TaoCrypt {
+
+class Source;
+
+
+// Public Key Length helper
+class PK_Lengths {
+ const Integer& image_;
+public:
+ explicit PK_Lengths(const Integer& i) : image_(i) {}
+
+ word32 PaddedBlockBitLength() const {return image_.BitCount() - 1;}
+ word32 PaddedBlockByteLength() const
+ {return BitsToBytes(PaddedBlockBitLength());}
+
+ word32 FixedCiphertextLength() const {return image_.ByteCount();}
+ word32 FixedMaxPlaintextLength() const
+ {return SaturatingSubtract(PaddedBlockBitLength() / 8, 10U); }
+};
+
+
+// RSA Public Key
+class RSA_PublicKey {
+protected:
+ Integer n_;
+ Integer e_;
+public:
+ RSA_PublicKey() {}
+ explicit RSA_PublicKey(Source&);
+
+ void Initialize(const Integer& n, const Integer& e) {n_ = n; e_ = e;}
+ void Initialize(Source&);
+
+ Integer ApplyFunction(const Integer& x) const;
+
+ const Integer& GetModulus() const {return n_;}
+ const Integer& GetPublicExponent() const {return e_;}
+
+ void SetModulus(const Integer& n) {n_ = n;}
+ void SetPublicExponent(const Integer& e) {e_ = e;}
+
+ word32 FixedCiphertextLength()
+ {
+ return PK_Lengths(n_).FixedCiphertextLength();
+ }
+
+ RSA_PublicKey(const RSA_PublicKey& other) : n_(other.n_), e_(other.e_) {}
+ RSA_PublicKey& operator=(const RSA_PublicKey& that)
+ {
+ RSA_PublicKey tmp(that);
+ Swap(tmp);
+ return *this;
+ }
+
+ void Swap(RSA_PublicKey& other)
+ {
+ n_.Swap(other.n_);
+ e_.Swap(other.e_);
+ }
+};
+
+
+// RSA Private Key
+class RSA_PrivateKey : public RSA_PublicKey {
+ Integer d_;
+ Integer p_;
+ Integer q_;
+ Integer dp_;
+ Integer dq_;
+ Integer u_;
+public:
+ RSA_PrivateKey() {}
+ explicit RSA_PrivateKey(Source&);
+
+ void Initialize(const Integer& n, const Integer& e, const Integer& d,
+ const Integer& p, const Integer& q, const Integer& dp,
+ const Integer& dq, const Integer& u)
+ {n_ = n; e_ = e; d_ = d; p_ = p; q_ = q; dp_ = dp; dq_ = dq; u_ = u;}
+ void Initialize(Source&);
+
+ Integer CalculateInverse(RandomNumberGenerator&, const Integer&) const;
+
+ const Integer& GetPrime1() const {return p_;}
+ const Integer& GetPrime2() const {return q_;}
+ const Integer& GetPrivateExponent() const {return d_;}
+ const Integer& GetModPrime1PrivateExponent() const {return dp_;}
+ const Integer& GetModPrime2PrivateExponent() const {return dq_;}
+ const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const
+ {return u_;}
+
+ void SetPrime1(const Integer& p) {p_ = p;}
+ void SetPrime2(const Integer& q) {q_ = q;}
+ void SetPrivateExponent(const Integer& d) {d_ = d;}
+ void SetModPrime1PrivateExponent(const Integer& dp) {dp_ = dp;}
+ void SetModPrime2PrivateExponent(const Integer& dq) {dq_ = dq;}
+ void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer& u) {u_ = u;}
+private:
+ RSA_PrivateKey(const RSA_PrivateKey&); // hide copy
+ RSA_PrivateKey& operator=(const RSA_PrivateKey&); // and assign
+};
+
+
+// block type 2 padding
+class RSA_BlockType2 {
+public:
+ void Pad(const byte*, word32, byte*, word32,
+ RandomNumberGenerator&) const;
+ word32 UnPad(const byte*, word32, byte*) const;
+};
+
+
+// block type 1 padding
+class RSA_BlockType1 {
+public:
+ void Pad(const byte*, word32, byte*, word32,
+ RandomNumberGenerator&) const;
+ word32 UnPad(const byte*, word32, byte*) const;
+};
+
+
+// RSA Encryptor, can use any padding
+template<class Pad = RSA_BlockType2>
+class RSA_Encryptor {
+ const RSA_PublicKey& key_;
+ Pad padding_;
+public:
+ explicit RSA_Encryptor(const RSA_PublicKey& k) : key_(k) {}
+
+ void Encrypt(const byte*, word32, byte*, RandomNumberGenerator&);
+ bool SSL_Verify(const byte* msg, word32 sz, const byte* sig);
+};
+
+
+// RSA Decryptor, can use any padding
+template<class Pad = RSA_BlockType2>
+class RSA_Decryptor {
+ const RSA_PrivateKey& key_;
+ Pad padding_;
+public:
+ explicit RSA_Decryptor(const RSA_PrivateKey& k) : key_(k) {}
+
+ word32 Decrypt(const byte*, word32, byte*, RandomNumberGenerator&);
+ void SSL_Sign(const byte*, word32, byte*, RandomNumberGenerator&);
+};
+
+
+// Public Encrypt
+template<class Pad>
+void RSA_Encryptor<Pad>::Encrypt(const byte* plain, word32 sz, byte* cipher,
+ RandomNumberGenerator& rng)
+{
+ PK_Lengths lengths(key_.GetModulus());
+ if (sz > lengths.FixedMaxPlaintextLength())
+ return;
+
+ ByteBlock paddedBlock(lengths.PaddedBlockByteLength());
+ padding_.Pad(plain, sz, paddedBlock.get_buffer(),
+ lengths.PaddedBlockBitLength(), rng);
+
+ key_.ApplyFunction(Integer(paddedBlock.get_buffer(), paddedBlock.size())).
+ Encode(cipher, lengths.FixedCiphertextLength());
+}
+
+
+// Private Decrypt
+template<class Pad>
+word32 RSA_Decryptor<Pad>::Decrypt(const byte* cipher, word32 sz, byte* plain,
+ RandomNumberGenerator& rng)
+{
+ PK_Lengths lengths(key_.GetModulus());
+
+ if (sz != lengths.FixedCiphertextLength())
+ return 0;
+
+ ByteBlock paddedBlock(lengths.PaddedBlockByteLength());
+ Integer x = key_.CalculateInverse(rng, Integer(cipher,
+ lengths.FixedCiphertextLength()).Ref());
+ if (x.ByteCount() > paddedBlock.size())
+ x = Integer::Zero(); // don't return false, prevents timing attack
+ x.Encode(paddedBlock.get_buffer(), paddedBlock.size());
+ return padding_.UnPad(paddedBlock.get_buffer(),
+ lengths.PaddedBlockBitLength(), plain);
+}
+
+
+// Private SSL type (block 1) Encrypt
+template<class Pad>
+void RSA_Decryptor<Pad>::SSL_Sign(const byte* message, word32 sz, byte* sig,
+ RandomNumberGenerator& rng)
+{
+ RSA_PublicKey inverse;
+ inverse.Initialize(key_.GetModulus(), key_.GetPrivateExponent());
+ RSA_Encryptor<RSA_BlockType1> enc(inverse); // SSL Type
+ enc.Encrypt(message, sz, sig, rng);
+}
+
+
+word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain);
+
+
+// Public SSL type (block 1) Decrypt
+template<class Pad>
+bool RSA_Encryptor<Pad>::SSL_Verify(const byte* message, word32 sz,
+ const byte* sig)
+{
+ ByteBlock plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength());
+ if (SSL_Decrypt(key_, sig, plain.get_buffer()) != sz)
+ return false; // not right justified or bad padding
+
+ if ( (memcmp(plain.get_buffer(), message, sz)) == 0)
+ return true;
+ return false;
+}
+
+
+typedef RSA_Encryptor<> RSAES_Encryptor;
+typedef RSA_Decryptor<> RSAES_Decryptor;
+
+
+} // namespace
+
+#endif // TAO_CRYPT_RSA_HPP