00001 /* rsa.hpp 00002 * 00003 * Copyright (C) 2003 Sawtooth Consulting Ltd. 00004 * 00005 * This file is part of yaSSL. 00006 * 00007 * yaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * There are special exceptions to the terms and conditions of the GPL as it 00013 * is applied to yaSSL. View the full text of the exception in the file 00014 * FLOSS-EXCEPTIONS in the directory of this software distribution. 00015 * 00016 * yaSSL is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00024 */ 00025 00026 /* rsa.hpp provides RSA ES encrypt/decrypt, SSL (block type 1) sign and verify 00027 */ 00028 00029 #ifndef TAO_CRYPT_RSA_HPP 00030 #define TAO_CRYPT_RSA_HPP 00031 00032 #include "integer.hpp" 00033 #include "random.hpp" 00034 00035 00036 namespace TaoCrypt { 00037 00038 class Source; 00039 00040 00041 // Public Key Length helper 00042 class PK_Lengths { 00043 const Integer& image_; 00044 public: 00045 explicit PK_Lengths(const Integer& i) : image_(i) {} 00046 00047 word32 PaddedBlockBitLength() const {return image_.BitCount() - 1;} 00048 word32 PaddedBlockByteLength() const 00049 {return BitsToBytes(PaddedBlockBitLength());} 00050 00051 word32 FixedCiphertextLength() const {return image_.ByteCount();} 00052 word32 FixedMaxPlaintextLength() const 00053 {return SaturatingSubtract(PaddedBlockBitLength() / 8, 10U); } 00054 }; 00055 00056 00057 // RSA Public Key 00058 class RSA_PublicKey { 00059 protected: 00060 Integer n_; 00061 Integer e_; 00062 public: 00063 RSA_PublicKey() {} 00064 explicit RSA_PublicKey(Source&); 00065 00066 void Initialize(const Integer& n, const Integer& e) {n_ = n; e_ = e;} 00067 void Initialize(Source&); 00068 00069 Integer ApplyFunction(const Integer& x) const; 00070 00071 const Integer& GetModulus() const {return n_;} 00072 const Integer& GetPublicExponent() const {return e_;} 00073 00074 void SetModulus(const Integer& n) {n_ = n;} 00075 void SetPublicExponent(const Integer& e) {e_ = e;} 00076 00077 word32 FixedCiphertextLength() 00078 { 00079 return PK_Lengths(n_).FixedCiphertextLength(); 00080 } 00081 00082 RSA_PublicKey(const RSA_PublicKey& other) : n_(other.n_), e_(other.e_) {} 00083 RSA_PublicKey& operator=(const RSA_PublicKey& that) 00084 { 00085 RSA_PublicKey tmp(that); 00086 Swap(tmp); 00087 return *this; 00088 } 00089 00090 void Swap(RSA_PublicKey& other) 00091 { 00092 n_.Swap(other.n_); 00093 e_.Swap(other.e_); 00094 } 00095 }; 00096 00097 00098 // RSA Private Key 00099 class RSA_PrivateKey : public RSA_PublicKey { 00100 Integer d_; 00101 Integer p_; 00102 Integer q_; 00103 Integer dp_; 00104 Integer dq_; 00105 Integer u_; 00106 public: 00107 RSA_PrivateKey() {} 00108 explicit RSA_PrivateKey(Source&); 00109 00110 void Initialize(const Integer& n, const Integer& e, const Integer& d, 00111 const Integer& p, const Integer& q, const Integer& dp, 00112 const Integer& dq, const Integer& u) 00113 {n_ = n; e_ = e; d_ = d; p_ = p; q_ = q; dp_ = dp; dq_ = dq; u_ = u;} 00114 void Initialize(Source&); 00115 00116 Integer CalculateInverse(RandomNumberGenerator&, const Integer&) const; 00117 00118 const Integer& GetPrime1() const {return p_;} 00119 const Integer& GetPrime2() const {return q_;} 00120 const Integer& GetPrivateExponent() const {return d_;} 00121 const Integer& GetModPrime1PrivateExponent() const {return dp_;} 00122 const Integer& GetModPrime2PrivateExponent() const {return dq_;} 00123 const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const 00124 {return u_;} 00125 00126 void SetPrime1(const Integer& p) {p_ = p;} 00127 void SetPrime2(const Integer& q) {q_ = q;} 00128 void SetPrivateExponent(const Integer& d) {d_ = d;} 00129 void SetModPrime1PrivateExponent(const Integer& dp) {dp_ = dp;} 00130 void SetModPrime2PrivateExponent(const Integer& dq) {dq_ = dq;} 00131 void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer& u) {u_ = u;} 00132 private: 00133 RSA_PrivateKey(const RSA_PrivateKey&); // hide copy 00134 RSA_PrivateKey& operator=(const RSA_PrivateKey&); // and assign 00135 }; 00136 00137 00138 // block type 2 padding 00139 class RSA_BlockType2 { 00140 public: 00141 void Pad(const byte*, word32, byte*, word32, 00142 RandomNumberGenerator&) const; 00143 word32 UnPad(const byte*, word32, byte*) const; 00144 }; 00145 00146 00147 // block type 1 padding 00148 class RSA_BlockType1 { 00149 public: 00150 void Pad(const byte*, word32, byte*, word32, 00151 RandomNumberGenerator&) const; 00152 word32 UnPad(const byte*, word32, byte*) const; 00153 }; 00154 00155 00156 // RSA Encryptor, can use any padding 00157 template<class Pad = RSA_BlockType2> 00158 class RSA_Encryptor { 00159 const RSA_PublicKey& key_; 00160 Pad padding_; 00161 public: 00162 explicit RSA_Encryptor(const RSA_PublicKey& k) : key_(k) {} 00163 00164 void Encrypt(const byte*, word32, byte*, RandomNumberGenerator&); 00165 bool SSL_Verify(const byte* msg, word32 sz, const byte* sig); 00166 }; 00167 00168 00169 // RSA Decryptor, can use any padding 00170 template<class Pad = RSA_BlockType2> 00171 class RSA_Decryptor { 00172 const RSA_PrivateKey& key_; 00173 Pad padding_; 00174 public: 00175 explicit RSA_Decryptor(const RSA_PrivateKey& k) : key_(k) {} 00176 00177 word32 Decrypt(const byte*, word32, byte*, RandomNumberGenerator&); 00178 void SSL_Sign(const byte*, word32, byte*, RandomNumberGenerator&); 00179 }; 00180 00181 00182 // Public Encrypt 00183 template<class Pad> 00184 void RSA_Encryptor<Pad>::Encrypt(const byte* plain, word32 sz, byte* cipher, 00185 RandomNumberGenerator& rng) 00186 { 00187 PK_Lengths lengths(key_.GetModulus()); 00188 assert(sz <= lengths.FixedMaxPlaintextLength()); 00189 00190 ByteBlock paddedBlock(lengths.PaddedBlockByteLength()); 00191 padding_.Pad(plain, sz, paddedBlock.get_buffer(), 00192 lengths.PaddedBlockBitLength(), rng); 00193 00194 key_.ApplyFunction(Integer(paddedBlock.get_buffer(), paddedBlock.size())). 00195 Encode(cipher, lengths.FixedCiphertextLength()); 00196 } 00197 00198 00199 // Private Decrypt 00200 template<class Pad> 00201 word32 RSA_Decryptor<Pad>::Decrypt(const byte* cipher, word32 sz, byte* plain, 00202 RandomNumberGenerator& rng) 00203 { 00204 PK_Lengths lengths(key_.GetModulus()); 00205 assert(sz == lengths.FixedCiphertextLength()); 00206 00207 if (sz != lengths.FixedCiphertextLength()) 00208 return 0; 00209 00210 ByteBlock paddedBlock(lengths.PaddedBlockByteLength()); 00211 Integer x = key_.CalculateInverse(rng, Integer(cipher, 00212 lengths.FixedCiphertextLength()).Ref()); 00213 if (x.ByteCount() > paddedBlock.size()) 00214 x = Integer::Zero(); // don't return false, prevents timing attack 00215 x.Encode(paddedBlock.get_buffer(), paddedBlock.size()); 00216 return padding_.UnPad(paddedBlock.get_buffer(), 00217 lengths.PaddedBlockBitLength(), plain); 00218 } 00219 00220 00221 // Private SSL type (block 1) Encrypt 00222 template<class Pad> 00223 void RSA_Decryptor<Pad>::SSL_Sign(const byte* message, word32 sz, byte* sig, 00224 RandomNumberGenerator& rng) 00225 { 00226 RSA_PublicKey inverse; 00227 inverse.Initialize(key_.GetModulus(), key_.GetPrivateExponent()); 00228 RSA_Encryptor<RSA_BlockType1> enc(inverse); // SSL Type 00229 enc.Encrypt(message, sz, sig, rng); 00230 } 00231 00232 00233 word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain); 00234 00235 00236 // Public SSL type (block 1) Decrypt 00237 template<class Pad> 00238 bool RSA_Encryptor<Pad>::SSL_Verify(const byte* message, word32 sz, 00239 const byte* sig) 00240 { 00241 ByteBlock plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength()); 00242 SSL_Decrypt(key_, sig, plain.get_buffer()); 00243 00244 if ( (memcmp(plain.get_buffer(), message, sz)) == 0) 00245 return true; 00246 return false; 00247 } 00248 00249 00250 typedef RSA_Encryptor<> RSAES_Encryptor; 00251 typedef RSA_Decryptor<> RSAES_Decryptor; 00252 00253 00254 } // namespace 00255 00256 #endif // TAO_CRYPT_RSA_HPP
1.4.7

